diff options
author | Vitaly Takmazov | 2024-10-24 13:37:32 +0300 |
---|---|---|
committer | Vitaly Takmazov | 2024-10-24 23:40:41 +0300 |
commit | e9464b8a10eb57d9b021251ff97bcbd9c53a1e98 (patch) | |
tree | 6d9d37c1d9b39a667d869fe4f2784e1add2e9959 /vnext/server/middleware | |
parent | 4bb9c0dd855e1f79308908a97106bf173088cfb8 (diff) |
`rememberme` middleware: authorize using Spring Security cookie
Diffstat (limited to 'vnext/server/middleware')
-rw-r--r-- | vnext/server/middleware/rememberme.js | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/vnext/server/middleware/rememberme.js b/vnext/server/middleware/rememberme.js new file mode 100644 index 00000000..1c0a2ee4 --- /dev/null +++ b/vnext/server/middleware/rememberme.js @@ -0,0 +1,50 @@ +import config from 'config' +import { createHash } from 'node:crypto' +import debug from 'debug' +import { getUserByName } from '../db/Users' +const log = debug('auth') + +const auth_key = config.get('service.auth.key') +const JUICK_COOKIE_NAME = 'juick-remember-me' + +export const rememberMeParser = (req, _res, next) => { + if (req.cookies && !!req.cookies[JUICK_COOKIE_NAME]) { + validate_cookie(req.cookies[JUICK_COOKIE_NAME]).then(visitor => { + req.visitor = visitor + setImmediate(next) + }).catch(() => { + setImmediate(next) + }) + } else { + setImmediate(next) + } +} + +const validate_cookie = async (cookie) => { + const [ username, expiry_time, , signature ] = Buffer.from(cookie, 'base64').toString('ascii').split(':', 4) + if (is_token_expired(expiry_time)) { + log(`Token expired at: ${new Date(expiry_time)}`) + return '' + } + const user = await getUserByName(username) + if (!user) { + log(`User not found: ${username}`) + return '' + } + const expected_signature = make_token_signature(expiry_time, username, user['passw']) + if (expected_signature === signature) { + log(`Signature verified: ${username}`) + return username + } + log(`Invalid token signature: ${username}`) + return '' +} + +const make_token_signature = (expiry_time, username, password) => { + const data = `${username}:${expiry_time}:{noop}${password}:${auth_key}` + return createHash('sha256').update(data).digest('hex') +} + +const is_token_expired = (expiry_time) => { + return new Date(expiry_time) < new Date() +} |