improve auth behavior

This commit is contained in:
SrGooglo 2023-04-04 12:30:23 +00:00
parent 1536573dd5
commit 09a39b69a9

View File

@ -12,111 +12,120 @@ export default async (req, res, next) => {
try { try {
const tokenAuthHeader = req.headers?.authorization?.split(" ") const tokenAuthHeader = req.headers?.authorization?.split(" ")
const serverTokenHeader = req.headers?.server_token
if (!serverTokenHeader && !tokenAuthHeader) { if (!tokenAuthHeader) {
return reject("Missing token header") return reject("Missing token header")
} }
if (serverTokenHeader) { if (!tokenAuthHeader[1]) {
const [client_id, token] = serverTokenHeader.split(":") return reject("Recived header, missing token")
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()
} }
if (!serverTokenHeader && tokenAuthHeader && tokenAuthHeader[0] === "Bearer") { switch (tokenAuthHeader[0]) {
const token = tokenAuthHeader[1] case "Bearer": {
let decoded = null const token = tokenAuthHeader[1]
let decoded = null
try { try {
decoded = jwt.decode(token) decoded = jwt.decode(token)
} catch (error) { } catch (error) {
console.error(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 (!decoded) {
return reject("Cannot decode token")
if (!userData) {
return res.status(404).json({ error: "No user data found" })
} }
// if cannot verify token, start regeneration process jwt.verify(token, global.jwtStrategy.secretOrKey, async (err) => {
if (err) { const sessions = await Session.find({ user_id: decoded.user_id })
// first check if token is only expired, if is corrupted, reject const currentSession = sessions.find((session) => session.token === token)
if (err.name !== "TokenExpiredError") {
return reject("Invalid token, cannot regenerate") if (!currentSession) {
return reject("Cannot find session")
} }
let regenerationToken = null const userData = await User.findOne({ _id: currentSession.user_id }).select("+refreshToken")
// check if this expired token has a regeneration token associated if (!userData) {
const associatedRegenerationToken = await Token.getRegenerationToken(token) return res.status(404).json({ error: "No user data found" })
}
if (associatedRegenerationToken) { // if cannot verify token, start regeneration process
regenerationToken = associatedRegenerationToken.refreshToken if (err) {
} else { // first check if token is only expired, if is corrupted, reject
// create a new regeneration token with the expired token if (err.name !== "TokenExpiredError") {
regenerationToken = await Token.createNewRegenerationToken(token).catch((error) => { return reject("Invalid token, cannot regenerate")
// in case of error, reject }
reject(error.message)
return null let regenerationToken = null
// check if this expired token has a regeneration token associated
const associatedRegenerationToken = await Token.getRegenerationToken(token)
if (associatedRegenerationToken) {
regenerationToken = associatedRegenerationToken.refreshToken
} else {
// create a new regeneration token with the expired token
regenerationToken = await Token.createNewRegenerationToken(token).catch((error) => {
// in case of error, reject
reject(error.message)
return null
})
}
if (!regenerationToken) return
// now send the regeneration token to the client (start Expired Exception Event [EEE])
return res.status(401).json({
error: "Token expired",
refreshToken: regenerationToken.refreshToken,
}) })
} }
if (!regenerationToken) return req.user = userData
req.jwtToken = token
req.decodedToken = decoded
req.currentSession = currentSession
// now send the regeneration token to the client (start Expired Exception Event [EEE]) return next()
return res.status(401).json({ })
error: "Token expired",
refreshToken: regenerationToken.refreshToken, break
}) }
case "Server": {
const [client_id, token] = tokenAuthHeader[1].split(":")
if (client_id === "undefined" || token === "undefined") {
return reject("Invalid server token")
} }
req.user = userData const secureEntries = new SecureEntry(authorizedServerTokens)
req.jwtToken = token
req.decodedToken = decoded const serverTokenEntry = await secureEntries.get(client_id, undefined, {
req.currentSession = currentSession 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() return next()
}) }
default: {
return reject("Invalid token type")
}
} }
} catch (error) { } catch (error) {
console.error(error) console.error(error)