/** * @copyright nhcarrigan * @license Naomi's Public License * @author Naomi Carrigan */ import { blockedIps } from "../cache/blockedIps.js"; import { getIpFromRequest } from "../modules/getIpFromRequest.js"; import type { onRequestHookHandler } from "fastify"; /** * Ensures that form submissions only come from our web application. * @param request - The request payload from the server. * @param response - The reply handler from Fastify. * @returns A Fastify reply if the request is invalid, otherwise undefined. */ // eslint-disable-next-line @typescript-eslint/no-misused-promises -- For reasons I cannot comprehend, Fastify seems to require us to return a request? export const ipHook: onRequestHookHandler = async(request, response) => { const ip = getIpFromRequest(request); const ipRecord = blockedIps.find( (record) => { return record.ip === ip && record.ttl > new Date(); }, ); if (ipRecord && ipRecord.ttl > new Date()) { return await response. status(403). send({ error: `Your IP address (${ipRecord.ip}) has been blocked until ${ipRecord.ttl.toISOString()}, to protect our API against brute-force attacks.`, }); } if (ipRecord && ipRecord.ttl <= new Date()) { blockedIps.splice(blockedIps.indexOf(ipRecord), 1); } return undefined; };