💾 Archived View for iich.space › src › util › tokens.ts captured on 2022-03-01 at 16:00:15.
⬅️ Previous capture (2021-12-03)
-=-=-=-=-=-=-
import { createHash } from 'crypto'; import { Status } from '@/gemini'; import { createLogger } from '@/log'; import { Handler } from '@/mission-control'; import db from '~/db'; const insertToken = db.prepare( 'INSERT INTO tokens (token, timestamp) VALUES (?, ?)', ); const queryToken = db.prepare('SELECT token FROM tokens WHERE token = ?'); const tokenCount = db.prepare('SELECT COUNT(*) AS count FROM tokens'); const removeToken = db.prepare('DELETE FROM tokens WHERE token = ?'); const removeTokens = db.prepare('DELETE FROM tokens WHERE timestamp < ?'); export const createToken = (): string => { const hash = createHash('sha256'); hash.update(process.env.SALT! + Date.now() + Math.random()); const token = hash.digest('hex').slice(0, 8); insertToken.run(token, Math.floor(Date.now() / 1000)); return token; }; export const useToken = (token: string): boolean => { const tokenExists = queryToken.get(token) !== undefined; if (tokenExists) { removeToken.run(token); return true; } return false; }; export const withValidToken: Handler = (_, res, { params }) => { if (useToken(params.token) === false) { res.sendStatus(Status.PERMANENT_FAILURE, 'Invalid Token'); return res.end(); } }; const log = createLogger(); export const purgeStaleTokens = (): void => { const stale = Date.now() / 1000 - 6 * 60 * 60; const count = tokenCount.get().count; const query = removeTokens.run(stale); log.info(`purged ${query.changes}/${count} tokens`); }; let interval: NodeJS.Timer; export const startPurgeJob = (): void => { log.info('starting job'); interval = setInterval(purgeStaleTokens, 30 * 60 * 1000); }; export const stopPurgeJob = (): void => { clearInterval(interval); };