mirror of
https://github.com/ragestudio/comty.git
synced 2025-06-11 19:44:15 +00:00
improve auth behavior
This commit is contained in:
parent
1536573dd5
commit
09a39b69a9
@ -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)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user