From 8456bb74853053458a8c83ba17907462e53a4ba5 Mon Sep 17 00:00:00 2001 From: alikia2x Date: Sat, 10 May 2025 21:48:02 +0800 Subject: [PATCH] add: route for validation --- bun.lock | 3 +++ packages/backend/middleware/index.ts | 2 +- packages/backend/middleware/rateLimiters.ts | 12 ++++++--- packages/backend/package.json | 1 + .../backend/routes/validation/token/GET.ts | 25 +++++++++++++++++++ .../backend/routes/validation/token/index.ts | 1 + packages/backend/src/routing.ts | 3 +++ 7 files changed, 42 insertions(+), 5 deletions(-) create mode 100644 packages/backend/routes/validation/token/GET.ts create mode 100644 packages/backend/routes/validation/token/index.ts diff --git a/bun.lock b/bun.lock index 5dee910..848c9da 100644 --- a/bun.lock +++ b/bun.lock @@ -19,6 +19,7 @@ "hono": "^4.7.8", "hono-rate-limiter": "^0.4.2", "ioredis": "^5.6.1", + "limiter": "^3.0.0", "postgres": "^3.4.5", "rate-limit-redis": "^4.2.0", "yup": "^1.6.1", @@ -845,6 +846,8 @@ "lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.29.2", "", { "os": "win32", "cpu": "x64" }, "sha512-EdIUW3B2vLuHmv7urfzMI/h2fmlnOQBk1xlsDxkN1tCWKjNFjfLhGxYk8C8mzpSfr+A6jFFIi8fU6LbQGsRWjA=="], + "limiter": ["limiter@3.0.0", "", {}, "sha512-hev7DuXojsTFl2YwyzUJMDnZ/qBDd3yZQLSH3aD4tdL1cqfc3TMnoecEJtWFaQFdErZsKoFMBTxF/FBSkgDbEg=="], + "lines-and-columns": ["lines-and-columns@1.2.4", "", {}, "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="], "locate-character": ["locate-character@3.0.0", "", {}, "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA=="], diff --git a/packages/backend/middleware/index.ts b/packages/backend/middleware/index.ts index 4bd98af..932daf0 100644 --- a/packages/backend/middleware/index.ts +++ b/packages/backend/middleware/index.ts @@ -1,7 +1,7 @@ import { Hono } from "hono"; import { Variables } from "hono/types"; import { bodyLimitForPing } from "./bodyLimits.ts"; -import { pingHandler } from "../routes/ping.ts"; +import { pingHandler } from "routes/ping"; import { registerRateLimiter } from "./rateLimiters.ts"; import { preetifyResponse } from "./preetifyResponse.ts"; import { logger } from "./logger.ts"; diff --git a/packages/backend/middleware/rateLimiters.ts b/packages/backend/middleware/rateLimiters.ts index c9e444a..a065f4c 100644 --- a/packages/backend/middleware/rateLimiters.ts +++ b/packages/backend/middleware/rateLimiters.ts @@ -11,14 +11,18 @@ export const registerRateLimiter = rateLimiter({ limit: 10, standardHeaders: "draft-6", keyGenerator: (c) => { + let ipAddr = crypto.randomUUID() as string; const info = getConnInfo(c as unknown as Context); - if (!info.remote || !info.remote.address) { - return crypto.randomUUID(); + if (info.remote && info.remote.address) { + ipAddr = info.remote.address; + } + const forwardedFor = c.req.header("X-Forwarded-For"); + if (forwardedFor) { + ipAddr = forwardedFor.split(",")[0]; } - const addr = info.remote.address; const path = new URL(c.req.url).pathname; const method = c.req.method; - return `${method}-${path}@${addr}`; + return `${method}-${path}@${ipAddr}`; }, store: new RedisStore({ // @ts-expect-error - Known issue: the `c`all` function is not present in @types/ioredis diff --git a/packages/backend/package.json b/packages/backend/package.json index 16bbc0a..2cc883d 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -10,6 +10,7 @@ "hono": "^4.7.8", "hono-rate-limiter": "^0.4.2", "ioredis": "^5.6.1", + "limiter": "^3.0.0", "postgres": "^3.4.5", "rate-limit-redis": "^4.2.0", "yup": "^1.6.1", diff --git a/packages/backend/routes/validation/token/GET.ts b/packages/backend/routes/validation/token/GET.ts new file mode 100644 index 0000000..ad392ed --- /dev/null +++ b/packages/backend/routes/validation/token/GET.ts @@ -0,0 +1,25 @@ +import { createHandlers } from "src/utils.ts"; + +const DIFFICULTY = 200000; + +const createNewChallenge = async (difficulty: number) => { + const baseURL = process.env["UCAPTCHA_URL"]; + const url = new URL(baseURL); + url.pathname = "/challenge"; + const res = await fetch(url.toString(), { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + difficulty: difficulty, + }) + }); + const data = await res.json(); + return data; +} + +export const createValidationSessionHandler = createHandlers(async (c) => { + const challenge = await createNewChallenge(DIFFICULTY); + return c.json(challenge); +}); diff --git a/packages/backend/routes/validation/token/index.ts b/packages/backend/routes/validation/token/index.ts new file mode 100644 index 0000000..e11870e --- /dev/null +++ b/packages/backend/routes/validation/token/index.ts @@ -0,0 +1 @@ +export * from "./GET.ts"; \ No newline at end of file diff --git a/packages/backend/src/routing.ts b/packages/backend/src/routing.ts index 300e19d..783961f 100644 --- a/packages/backend/src/routing.ts +++ b/packages/backend/src/routing.ts @@ -4,6 +4,7 @@ import { registerHandler } from "routes/user"; import { videoInfoHandler, getSnapshotsHanlder } from "routes/video"; import { Hono } from "hono"; import { Variables } from "hono/types"; +import { createValidationSessionHandler } from "routes/validation/token"; export function configureRoutes(app: Hono<{ Variables: Variables }>) { app.get("/", ...rootHandler); @@ -13,4 +14,6 @@ export function configureRoutes(app: Hono<{ Variables: Variables }>) { app.post("/user", ...registerHandler); app.get("/video/:id/info", ...videoInfoHandler); + + app.get("/validation/token", ...createValidationSessionHandler) }