mirror of
https://github.com/ragestudio/comty.git
synced 2025-06-09 10:34:17 +00:00
119 lines
3.9 KiB
JavaScript
Executable File
119 lines
3.9 KiB
JavaScript
Executable File
import { Session, User, authorizedServerTokens } from "@db_models"
|
|
|
|
import createTokenRegeneration from "@utils/createTokenRegeneration"
|
|
|
|
import SecureEntry from "@lib/secureEntry"
|
|
|
|
import jwt from "jsonwebtoken"
|
|
|
|
export default async (req, res, next) => {
|
|
function reject(description) {
|
|
return res.status(401).json({ error: `${description ?? "Invalid session"}` })
|
|
}
|
|
|
|
try {
|
|
const tokenAuthHeader = req.headers?.authorization?.split(" ")
|
|
|
|
if (!tokenAuthHeader) {
|
|
return reject("Missing token header")
|
|
}
|
|
|
|
if (!tokenAuthHeader[1]) {
|
|
return reject("Recived header, missing token")
|
|
}
|
|
|
|
switch (tokenAuthHeader[0]) {
|
|
case "Bearer": {
|
|
const token = tokenAuthHeader[1]
|
|
let decoded = null
|
|
|
|
try {
|
|
decoded = jwt.decode(token)
|
|
} catch (error) {
|
|
console.error(error)
|
|
}
|
|
|
|
if (!decoded) {
|
|
return reject("Cannot decode token")
|
|
}
|
|
|
|
jwt.verify(token, global.jwtStrategy.secretOrKey, async (err) => {
|
|
const sessions = await Session.find({ user_id: decoded.user_id })
|
|
const currentSession = sessions.find((session) => session.token === token)
|
|
|
|
if (!currentSession) {
|
|
return reject("Cannot find session")
|
|
}
|
|
|
|
const userData = await User.findOne({ _id: currentSession.user_id }).select("+refreshToken")
|
|
|
|
if (!userData) {
|
|
return reject("Cannot find user")
|
|
}
|
|
|
|
// if cannot verify token, start regeneration process
|
|
if (err) {
|
|
// first check if token is only expired, if is corrupted, reject
|
|
if (err.name !== "TokenExpiredError") {
|
|
return reject("Invalid token, cannot regenerate")
|
|
}
|
|
|
|
const refreshToken = await createTokenRegeneration(token)
|
|
|
|
// now send the regeneration token to the client (start Expired Exception Event [EEE])
|
|
return res.status(401).json({
|
|
error: "Token expired",
|
|
refreshToken: refreshToken,
|
|
})
|
|
}
|
|
|
|
req.user = userData
|
|
req.jwtToken = token
|
|
req.decodedToken = decoded
|
|
req.currentSession = currentSession
|
|
|
|
return next()
|
|
})
|
|
|
|
break
|
|
}
|
|
case "Server": {
|
|
const [client_id, token] = tokenAuthHeader[1].split(":")
|
|
|
|
if (client_id === "undefined" || token === "undefined") {
|
|
return reject("Invalid server token")
|
|
}
|
|
|
|
const secureEntries = new SecureEntry(authorizedServerTokens)
|
|
|
|
const serverTokenEntry = await secureEntries.get(client_id, undefined, {
|
|
keyName: "client_id",
|
|
valueName: "token",
|
|
})
|
|
|
|
if (!serverTokenEntry) {
|
|
return reject("Invalid server token")
|
|
}
|
|
|
|
if (serverTokenEntry !== token) {
|
|
return reject("Missmatching server token")
|
|
}
|
|
|
|
req.user = {
|
|
__server: true,
|
|
_id: client_id,
|
|
roles: ["server"],
|
|
}
|
|
|
|
return next()
|
|
}
|
|
default: {
|
|
return reject("Invalid token type")
|
|
}
|
|
}
|
|
} catch (error) {
|
|
console.error(error)
|
|
return res.status(500).json({ error: "This endpoint needs authentication, but an error occurred." })
|
|
}
|
|
}
|