implement basic decode

This commit is contained in:
SrGooglo 2025-02-25 23:07:45 +00:00
parent be0c61a028
commit 35282dc1cd

View File

@ -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
}
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
}
}