From 35282dc1cdd87e2c4f8efa6247b8627dd0166995 Mon Sep 17 00:00:00 2001 From: SrGooglo Date: Tue, 25 Feb 2025 23:07:45 +0000 Subject: [PATCH] implement basic decode --- packages/server/classes/AuthToken/index.js | 312 +++++++++++---------- 1 file changed, 171 insertions(+), 141 deletions(-) diff --git a/packages/server/classes/AuthToken/index.js b/packages/server/classes/AuthToken/index.js index 58af0f8c..75ab2c33 100644 --- a/packages/server/classes/AuthToken/index.js +++ b/packages/server/classes/AuthToken/index.js @@ -2,184 +2,214 @@ import jwt from "jsonwebtoken" import { Session, RefreshToken, User, TosViolations } from "@db_models" export default class Token { - static get authStrategy() { - return { - secret: process.env.JWT_SECRET, - expiresIn: process.env.JWT_EXPIRES_IN ?? "24h", - algorithm: process.env.JWT_ALGORITHM ?? "HS256", - } - } + static get authStrategy() { + return { + secret: process.env.JWT_SECRET, + expiresIn: process.env.JWT_EXPIRES_IN ?? "24h", + algorithm: process.env.JWT_ALGORITHM ?? "HS256", + } + } - static get refreshStrategy() { - return { - secret: process.env.JWT_SECRET, - expiresIn: process.env.JWT_REFRESH_EXPIRES_IN ?? "30d", - algorithm: process.env.JWT_ALGORITHM ?? "HS256", - } - } + static get refreshStrategy() { + return { + secret: process.env.JWT_SECRET, + expiresIn: process.env.JWT_REFRESH_EXPIRES_IN ?? "30d", + algorithm: process.env.JWT_ALGORITHM ?? "HS256", + } + } - static async signToken(payload, strategy = "authStrategy") { - const { secret, expiresIn, algorithm } = Token[strategy] ?? Token.authStrategy + static async signToken(payload, strategy = "authStrategy") { + const { secret, expiresIn, algorithm } = + Token[strategy] ?? Token.authStrategy - const token = jwt.sign(payload, - secret, - { - expiresIn: expiresIn, - algorithm: algorithm - } - ) + const token = jwt.sign(payload, secret, { + expiresIn: expiresIn, + algorithm: algorithm, + }) - return token - } + return token + } - static async createAuthToken(payload) { - const jwt_token = await this.signToken(payload, "authStrategy") + static async createAuthToken(payload) { + const jwt_token = await this.signToken(payload, "authStrategy") - const session = new Session({ - token: jwt_token, - username: payload.username, - user_id: payload.user_id, - sign_location: payload.sign_location, - ip_address: payload.ip_address, - client: payload.client, - date: new Date().getTime(), - }) + const session = new Session({ + token: jwt_token, + username: payload.username, + user_id: payload.user_id, + sign_location: payload.sign_location, + ip_address: payload.ip_address, + client: payload.client, + date: new Date().getTime(), + created_at: new Date().getTime(), + }) - await session.save() + await session.save() - return jwt_token - } + return jwt_token + } - static async createRefreshToken(user_id, authToken) { - const jwt_token = await this.signToken({ - user_id, - }, "refreshStrategy") + static async createRefreshToken(user_id, authToken) { + const jwt_token = await this.signToken( + { + user_id, + }, + "refreshStrategy", + ) - const refreshRegistry = new RefreshToken({ - authToken: authToken, - refreshToken: jwt_token, - }) + const refreshRegistry = new RefreshToken({ + authToken: authToken, + refreshToken: jwt_token, + }) - await refreshRegistry.save() + await refreshRegistry.save() - return jwt_token - } + return jwt_token + } - static async validate(token) { - let result = { - expired: false, - valid: true, - error: null, - data: null, - } + static async basicDecode(token) { + const { secret } = Token.authStrategy - if (typeof token === "undefined") { - result.valid = false - result.error = "Missing token" + return new Promise((resolve, reject) => { + jwt.verify(token, secret, async (err, decoded) => { + if (err) { + reject(err) + } - return result - } + resolve(decoded) + }) + }) + } - const { secret } = Token.authStrategy + static async validate(token) { + let result = { + expired: false, + valid: true, + error: null, + data: null, + } - await jwt.verify(token, secret, async (err, decoded) => { - if (err) { - result.valid = false - result.error = err.message + if (typeof token === "undefined") { + result.valid = false + result.error = "Missing token" - if (err.message === "jwt expired") { - result.expired = true - } + return result + } - return - } + const { secret } = Token.authStrategy - result.data = decoded + await jwt.verify(token, secret, async (err, decoded) => { + if (err) { + result.valid = false + result.error = err.message - // check account tos violation - const violation = await TosViolations.findOne({ user_id: decoded.user_id }) + if (err.message === "jwt expired") { + result.expired = true + } - if (violation) { - console.log("violation", violation) + return + } - result.valid = false - result.banned = { - reason: violation.reason, - expire_at: violation.expire_at, - } + result.data = decoded - return result - } + // check account tos violation + const violation = await TosViolations.findOne({ + user_id: decoded.user_id, + }) - const sessions = await Session.find({ user_id: decoded.user_id }) - const currentSession = sessions.find((session) => session.token === token) + if (violation) { + console.log("violation", violation) - if (!currentSession) { - result.valid = false - result.error = "Session token not found" - } else { - result.session = currentSession - result.valid = true - result.user = async () => await User.findOne({ _id: decoded.user_id }) - } - }) + result.valid = false + result.banned = { + reason: violation.reason, + expire_at: violation.expire_at, + } - return result - } + return result + } - static async handleRefreshToken(payload) { - const { authToken, refreshToken } = payload + const sessions = await Session.find({ user_id: decoded.user_id }) + const currentSession = sessions.find( + (session) => session.token === token, + ) - if (!authToken || !refreshToken) { - throw new OperationError(400, "Missing refreshToken or authToken") - } + if (!currentSession) { + result.valid = false + result.error = "Session token not found" + } else { + result.session = currentSession + result.valid = true + result.user = async () => + await User.findOne({ _id: decoded.user_id }) + } + }) - let result = { - error: undefined, - token: undefined, - refreshToken: undefined, - } + return result + } - await jwt.verify(refreshToken, Token.refreshStrategy.secret, async (err, decoded) => { - if (err) { - result.error = err.message - return false - } + static async handleRefreshToken(payload) { + const { authToken, refreshToken } = payload - if (!decoded.user_id) { - result.error = "Missing user_id" - return false - } + if (!authToken || !refreshToken) { + throw new OperationError(400, "Missing refreshToken or authToken") + } - let currentSession = await Session.findOne({ - user_id: decoded.user_id, - token: authToken - }).catch((err) => { - return null - }) + let result = { + error: undefined, + token: undefined, + refreshToken: undefined, + } - if (!currentSession) { - result.error = "Session not matching with provided token" - return false - } + await jwt.verify( + refreshToken, + Token.refreshStrategy.secret, + async (err, decoded) => { + if (err) { + result.error = err.message + return false + } - currentSession = currentSession.toObject() + if (!decoded.user_id) { + result.error = "Missing user_id" + return false + } - await Session.findOneAndDelete({ _id: currentSession._id.toString() }) + let currentSession = await Session.findOne({ + user_id: decoded.user_id, + token: authToken, + }).catch((err) => { + return null + }) - result.token = await this.createAuthToken({ - ...currentSession, - date: new Date().getTime(), - }) - result.refreshToken = await this.createRefreshToken(decoded.user_id, result.token) + if (!currentSession) { + result.error = "Session not matching with provided token" + return false + } - return true - }) + currentSession = currentSession.toObject() - if (result.error) { - throw new OperationError(401, result.error) - } + await Session.findOneAndDelete({ + _id: currentSession._id.toString(), + }) - return result - } -} \ No newline at end of file + result.token = await this.createAuthToken({ + ...currentSession, + date: new Date().getTime(), + }) + result.refreshToken = await this.createRefreshToken( + decoded.user_id, + result.token, + ) + + return true + }, + ) + + if (result.error) { + throw new OperationError(401, result.error) + } + + return result + } +}