From 09a39b69a9c8992d1b9d256165ccc83de7d73e9e Mon Sep 17 00:00:00 2001 From: SrGooglo Date: Tue, 4 Apr 2023 12:30:23 +0000 Subject: [PATCH] improve auth behavior --- .../middlewares/withAuthentication/index.js | 175 +++++++++--------- 1 file changed, 92 insertions(+), 83 deletions(-) diff --git a/packages/server/src/middlewares/withAuthentication/index.js b/packages/server/src/middlewares/withAuthentication/index.js index 182a8ffb..0092d5c3 100755 --- a/packages/server/src/middlewares/withAuthentication/index.js +++ b/packages/server/src/middlewares/withAuthentication/index.js @@ -12,111 +12,120 @@ export default async (req, res, next) => { try { const tokenAuthHeader = req.headers?.authorization?.split(" ") - const serverTokenHeader = req.headers?.server_token - if (!serverTokenHeader && !tokenAuthHeader) { + if (!tokenAuthHeader) { return reject("Missing token header") } - if (serverTokenHeader) { - const [client_id, token] = serverTokenHeader.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() + if (!tokenAuthHeader[1]) { + return reject("Recived header, missing token") } - if (!serverTokenHeader && tokenAuthHeader && tokenAuthHeader[0] === "Bearer") { - const token = tokenAuthHeader[1] - let decoded = null + 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") + try { + decoded = jwt.decode(token) + } catch (error) { + console.error(error) } - const userData = await User.findOne({ _id: currentSession.user_id }).select("+refreshToken") - - if (!userData) { - return res.status(404).json({ error: "No user data found" }) + if (!decoded) { + return reject("Cannot decode token") } - // 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") + 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") } - let regenerationToken = null + const userData = await User.findOne({ _id: currentSession.user_id }).select("+refreshToken") - // check if this expired token has a regeneration token associated - const associatedRegenerationToken = await Token.getRegenerationToken(token) + if (!userData) { + return res.status(404).json({ error: "No user data found" }) + } - 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) + // 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") + } - 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 res.status(401).json({ - error: "Token expired", - refreshToken: regenerationToken.refreshToken, - }) + return next() + }) + + break + } + case "Server": { + const [client_id, token] = tokenAuthHeader[1].split(":") + + if (client_id === "undefined" || token === "undefined") { + return reject("Invalid server token") } - - req.user = userData - req.jwtToken = token - req.decodedToken = decoded - req.currentSession = currentSession - + + 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)