mirror of
https://github.com/sergeyyarkov/yarkov.tech.git
synced 2026-10-12 10:59:08 +03:00
46 lines
1.3 KiB
TypeScript
46 lines
1.3 KiB
TypeScript
import { ActionError, defineAction } from "astro:actions";
|
|
import { z } from "astro/zod";
|
|
import { createAppeal, getLatestAppealsByClientIp } from "../queries";
|
|
|
|
const CREATE_APPEAL_LIMIT_HRS = 1;
|
|
const APPEALS_LAST_HRS_LIMIT = 2;
|
|
|
|
export const server = {
|
|
appeal: defineAction({
|
|
accept: "form",
|
|
input: z.object({
|
|
name: z.string(),
|
|
email: z.string().email(),
|
|
website_url: z.string().optional(), // honeypot field
|
|
subject: z.string(),
|
|
message: z.string(),
|
|
}),
|
|
handler: async (data, ctx) => {
|
|
if (data.website_url && data.website_url.trim() !== "") return true;
|
|
|
|
const currentDate = new Date();
|
|
const latestAppeals = await getLatestAppealsByClientIp(ctx.clientAddress, 5);
|
|
const appealsLastHrs = latestAppeals.filter((a) => {
|
|
const hourDiff = (currentDate.getTime() - new Date(a.date_created).getTime()) / (1000 * 60 * 60);
|
|
return hourDiff <= CREATE_APPEAL_LIMIT_HRS;
|
|
});
|
|
|
|
if (appealsLastHrs.length >= APPEALS_LAST_HRS_LIMIT) {
|
|
throw new ActionError({
|
|
code: "TOO_MANY_REQUESTS",
|
|
message: "Appeal create limit exceeded.",
|
|
});
|
|
}
|
|
|
|
const appeal = await createAppeal({ ...data, client_ip: ctx.clientAddress });
|
|
|
|
if (appeal) return true;
|
|
|
|
throw new ActionError({
|
|
code: "INTERNAL_SERVER_ERROR",
|
|
message: "Unable to create appeal.",
|
|
});
|
|
},
|
|
}),
|
|
};
|