add: route for validation

This commit is contained in:
alikia2x (寒寒) 2025-05-10 21:48:02 +08:00
parent 01f5e57864
commit 8456bb7485
Signed by: alikia2x
GPG Key ID: 56209E0CCD8420C6
7 changed files with 42 additions and 5 deletions

View File

@ -19,6 +19,7 @@
"hono": "^4.7.8", "hono": "^4.7.8",
"hono-rate-limiter": "^0.4.2", "hono-rate-limiter": "^0.4.2",
"ioredis": "^5.6.1", "ioredis": "^5.6.1",
"limiter": "^3.0.0",
"postgres": "^3.4.5", "postgres": "^3.4.5",
"rate-limit-redis": "^4.2.0", "rate-limit-redis": "^4.2.0",
"yup": "^1.6.1", "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=="], "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=="], "lines-and-columns": ["lines-and-columns@1.2.4", "", {}, "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="],
"locate-character": ["locate-character@3.0.0", "", {}, "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA=="], "locate-character": ["locate-character@3.0.0", "", {}, "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA=="],

View File

@ -1,7 +1,7 @@
import { Hono } from "hono"; import { Hono } from "hono";
import { Variables } from "hono/types"; import { Variables } from "hono/types";
import { bodyLimitForPing } from "./bodyLimits.ts"; import { bodyLimitForPing } from "./bodyLimits.ts";
import { pingHandler } from "../routes/ping.ts"; import { pingHandler } from "routes/ping";
import { registerRateLimiter } from "./rateLimiters.ts"; import { registerRateLimiter } from "./rateLimiters.ts";
import { preetifyResponse } from "./preetifyResponse.ts"; import { preetifyResponse } from "./preetifyResponse.ts";
import { logger } from "./logger.ts"; import { logger } from "./logger.ts";

View File

@ -11,14 +11,18 @@ export const registerRateLimiter = rateLimiter<BlankEnv, "/user", {}>({
limit: 10, limit: 10,
standardHeaders: "draft-6", standardHeaders: "draft-6",
keyGenerator: (c) => { keyGenerator: (c) => {
let ipAddr = crypto.randomUUID() as string;
const info = getConnInfo(c as unknown as Context<BlankEnv, "/user", {}>); const info = getConnInfo(c as unknown as Context<BlankEnv, "/user", {}>);
if (!info.remote || !info.remote.address) { if (info.remote && info.remote.address) {
return crypto.randomUUID(); 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 path = new URL(c.req.url).pathname;
const method = c.req.method; const method = c.req.method;
return `${method}-${path}@${addr}`; return `${method}-${path}@${ipAddr}`;
}, },
store: new RedisStore({ store: new RedisStore({
// @ts-expect-error - Known issue: the `c`all` function is not present in @types/ioredis // @ts-expect-error - Known issue: the `c`all` function is not present in @types/ioredis

View File

@ -10,6 +10,7 @@
"hono": "^4.7.8", "hono": "^4.7.8",
"hono-rate-limiter": "^0.4.2", "hono-rate-limiter": "^0.4.2",
"ioredis": "^5.6.1", "ioredis": "^5.6.1",
"limiter": "^3.0.0",
"postgres": "^3.4.5", "postgres": "^3.4.5",
"rate-limit-redis": "^4.2.0", "rate-limit-redis": "^4.2.0",
"yup": "^1.6.1", "yup": "^1.6.1",

View File

@ -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);
});

View File

@ -0,0 +1 @@
export * from "./GET.ts";

View File

@ -4,6 +4,7 @@ import { registerHandler } from "routes/user";
import { videoInfoHandler, getSnapshotsHanlder } from "routes/video"; import { videoInfoHandler, getSnapshotsHanlder } from "routes/video";
import { Hono } from "hono"; import { Hono } from "hono";
import { Variables } from "hono/types"; import { Variables } from "hono/types";
import { createValidationSessionHandler } from "routes/validation/token";
export function configureRoutes(app: Hono<{ Variables: Variables }>) { export function configureRoutes(app: Hono<{ Variables: Variables }>) {
app.get("/", ...rootHandler); app.get("/", ...rootHandler);
@ -13,4 +14,6 @@ export function configureRoutes(app: Hono<{ Variables: Variables }>) {
app.post("/user", ...registerHandler); app.post("/user", ...registerHandler);
app.get("/video/:id/info", ...videoInfoHandler); app.get("/video/:id/info", ...videoInfoHandler);
app.get("/validation/token", ...createValidationSessionHandler)
} }