mirror of
https://github.com/ragestudio/comty.git
synced 2025-06-09 10:34:17 +00:00
implement basic decode
This commit is contained in:
parent
be0c61a028
commit
35282dc1cd
@ -2,184 +2,214 @@ import jwt from "jsonwebtoken"
|
|||||||
import { Session, RefreshToken, User, TosViolations } from "@db_models"
|
import { Session, RefreshToken, User, TosViolations } from "@db_models"
|
||||||
|
|
||||||
export default class Token {
|
export default class Token {
|
||||||
static get authStrategy() {
|
static get authStrategy() {
|
||||||
return {
|
return {
|
||||||
secret: process.env.JWT_SECRET,
|
secret: process.env.JWT_SECRET,
|
||||||
expiresIn: process.env.JWT_EXPIRES_IN ?? "24h",
|
expiresIn: process.env.JWT_EXPIRES_IN ?? "24h",
|
||||||
algorithm: process.env.JWT_ALGORITHM ?? "HS256",
|
algorithm: process.env.JWT_ALGORITHM ?? "HS256",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static get refreshStrategy() {
|
static get refreshStrategy() {
|
||||||
return {
|
return {
|
||||||
secret: process.env.JWT_SECRET,
|
secret: process.env.JWT_SECRET,
|
||||||
expiresIn: process.env.JWT_REFRESH_EXPIRES_IN ?? "30d",
|
expiresIn: process.env.JWT_REFRESH_EXPIRES_IN ?? "30d",
|
||||||
algorithm: process.env.JWT_ALGORITHM ?? "HS256",
|
algorithm: process.env.JWT_ALGORITHM ?? "HS256",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static async signToken(payload, strategy = "authStrategy") {
|
static async signToken(payload, strategy = "authStrategy") {
|
||||||
const { secret, expiresIn, algorithm } = Token[strategy] ?? Token.authStrategy
|
const { secret, expiresIn, algorithm } =
|
||||||
|
Token[strategy] ?? Token.authStrategy
|
||||||
|
|
||||||
const token = jwt.sign(payload,
|
const token = jwt.sign(payload, secret, {
|
||||||
secret,
|
expiresIn: expiresIn,
|
||||||
{
|
algorithm: algorithm,
|
||||||
expiresIn: expiresIn,
|
})
|
||||||
algorithm: algorithm
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
return token
|
return token
|
||||||
}
|
}
|
||||||
|
|
||||||
static async createAuthToken(payload) {
|
static async createAuthToken(payload) {
|
||||||
const jwt_token = await this.signToken(payload, "authStrategy")
|
const jwt_token = await this.signToken(payload, "authStrategy")
|
||||||
|
|
||||||
const session = new Session({
|
const session = new Session({
|
||||||
token: jwt_token,
|
token: jwt_token,
|
||||||
username: payload.username,
|
username: payload.username,
|
||||||
user_id: payload.user_id,
|
user_id: payload.user_id,
|
||||||
sign_location: payload.sign_location,
|
sign_location: payload.sign_location,
|
||||||
ip_address: payload.ip_address,
|
ip_address: payload.ip_address,
|
||||||
client: payload.client,
|
client: payload.client,
|
||||||
date: new Date().getTime(),
|
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) {
|
static async createRefreshToken(user_id, authToken) {
|
||||||
const jwt_token = await this.signToken({
|
const jwt_token = await this.signToken(
|
||||||
user_id,
|
{
|
||||||
}, "refreshStrategy")
|
user_id,
|
||||||
|
},
|
||||||
|
"refreshStrategy",
|
||||||
|
)
|
||||||
|
|
||||||
const refreshRegistry = new RefreshToken({
|
const refreshRegistry = new RefreshToken({
|
||||||
authToken: authToken,
|
authToken: authToken,
|
||||||
refreshToken: jwt_token,
|
refreshToken: jwt_token,
|
||||||
})
|
})
|
||||||
|
|
||||||
await refreshRegistry.save()
|
await refreshRegistry.save()
|
||||||
|
|
||||||
return jwt_token
|
return jwt_token
|
||||||
}
|
}
|
||||||
|
|
||||||
static async validate(token) {
|
static async basicDecode(token) {
|
||||||
let result = {
|
const { secret } = Token.authStrategy
|
||||||
expired: false,
|
|
||||||
valid: true,
|
|
||||||
error: null,
|
|
||||||
data: null,
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof token === "undefined") {
|
return new Promise((resolve, reject) => {
|
||||||
result.valid = false
|
jwt.verify(token, secret, async (err, decoded) => {
|
||||||
result.error = "Missing token"
|
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 (typeof token === "undefined") {
|
||||||
if (err) {
|
result.valid = false
|
||||||
result.valid = false
|
result.error = "Missing token"
|
||||||
result.error = err.message
|
|
||||||
|
|
||||||
if (err.message === "jwt expired") {
|
return result
|
||||||
result.expired = true
|
}
|
||||||
}
|
|
||||||
|
|
||||||
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
|
if (err.message === "jwt expired") {
|
||||||
const violation = await TosViolations.findOne({ user_id: decoded.user_id })
|
result.expired = true
|
||||||
|
}
|
||||||
|
|
||||||
if (violation) {
|
return
|
||||||
console.log("violation", violation)
|
}
|
||||||
|
|
||||||
result.valid = false
|
result.data = decoded
|
||||||
result.banned = {
|
|
||||||
reason: violation.reason,
|
|
||||||
expire_at: violation.expire_at,
|
|
||||||
}
|
|
||||||
|
|
||||||
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 })
|
if (violation) {
|
||||||
const currentSession = sessions.find((session) => session.token === token)
|
console.log("violation", violation)
|
||||||
|
|
||||||
if (!currentSession) {
|
result.valid = false
|
||||||
result.valid = false
|
result.banned = {
|
||||||
result.error = "Session token not found"
|
reason: violation.reason,
|
||||||
} else {
|
expire_at: violation.expire_at,
|
||||||
result.session = currentSession
|
}
|
||||||
result.valid = true
|
|
||||||
result.user = async () => await User.findOne({ _id: decoded.user_id })
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
static async handleRefreshToken(payload) {
|
const sessions = await Session.find({ user_id: decoded.user_id })
|
||||||
const { authToken, refreshToken } = payload
|
const currentSession = sessions.find(
|
||||||
|
(session) => session.token === token,
|
||||||
|
)
|
||||||
|
|
||||||
if (!authToken || !refreshToken) {
|
if (!currentSession) {
|
||||||
throw new OperationError(400, "Missing refreshToken or authToken")
|
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 = {
|
return result
|
||||||
error: undefined,
|
}
|
||||||
token: undefined,
|
|
||||||
refreshToken: undefined,
|
|
||||||
}
|
|
||||||
|
|
||||||
await jwt.verify(refreshToken, Token.refreshStrategy.secret, async (err, decoded) => {
|
static async handleRefreshToken(payload) {
|
||||||
if (err) {
|
const { authToken, refreshToken } = payload
|
||||||
result.error = err.message
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!decoded.user_id) {
|
if (!authToken || !refreshToken) {
|
||||||
result.error = "Missing user_id"
|
throw new OperationError(400, "Missing refreshToken or authToken")
|
||||||
return false
|
}
|
||||||
}
|
|
||||||
|
|
||||||
let currentSession = await Session.findOne({
|
let result = {
|
||||||
user_id: decoded.user_id,
|
error: undefined,
|
||||||
token: authToken
|
token: undefined,
|
||||||
}).catch((err) => {
|
refreshToken: undefined,
|
||||||
return null
|
}
|
||||||
})
|
|
||||||
|
|
||||||
if (!currentSession) {
|
await jwt.verify(
|
||||||
result.error = "Session not matching with provided token"
|
refreshToken,
|
||||||
return false
|
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({
|
if (!currentSession) {
|
||||||
...currentSession,
|
result.error = "Session not matching with provided token"
|
||||||
date: new Date().getTime(),
|
return false
|
||||||
})
|
}
|
||||||
result.refreshToken = await this.createRefreshToken(decoded.user_id, result.token)
|
|
||||||
|
|
||||||
return true
|
currentSession = currentSession.toObject()
|
||||||
})
|
|
||||||
|
|
||||||
if (result.error) {
|
await Session.findOneAndDelete({
|
||||||
throw new OperationError(401, result.error)
|
_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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user