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() }