import { argon2Verify } from "hash-wasm"; import { RateLimiterMemory } from "rate-limiter-flexible"; import { getSearchToken } from "./searchToken"; import { addVerifiedToken, isVerifiedToken } from "./verifiedTokens"; const rateLimiter = new RateLimiterMemory({ points: 2, duration: 10, }); export async function verifyTokenAndRateLimit(token: string | null): Promise<{ isAuthorized: boolean; statusCode?: number; error?: string; }> { if (!token) { return { isAuthorized: false, statusCode: 401, error: "Missing or invalid token", }; } if (!isVerifiedToken(token)) { let isValidToken = false; try { isValidToken = await argon2Verify({ password: getSearchToken(), hash: token, }); } catch (error) { void error; } if (isValidToken) { addVerifiedToken(token); } else { return { isAuthorized: false, statusCode: 401, error: "Unauthorized.", }; } } try { await rateLimiter.consume(token); } catch { return { isAuthorized: false, statusCode: 429, error: "Too many requests.", }; } return { isAuthorized: true }; }