New Captcha Package added

This commit is contained in:
2026-07-25 13:38:18 +05:30
parent d0aded0392
commit 8b728a3e5d
157 changed files with 12092 additions and 1913 deletions
+51
View File
@@ -0,0 +1,51 @@
import type { Context } from "@wrnexus/core";
import type { ObjectSchema, ParseResult } from "@wrnexus/validation";
import type {
CaptchaEngine,
CaptchaProvider,
CaptchaVerificationResult,
} from "./types.ts";
import { selfHostedProvider } from "./providers/self-hosted.ts";
export interface ParseWithCaptchaOptions {
action: string;
provider?: CaptchaProvider;
engine?: CaptchaEngine;
responseField?: string;
bindHostname?: boolean;
bindSession?: boolean;
bindIp?: boolean;
}
export interface CaptchaParseResult<T = Record<string, unknown>> extends ParseResult<T> {
captcha: CaptchaVerificationResult;
}
export async function parseWithCaptcha<T = Record<string, unknown>>(
schema: ObjectSchema,
input: Record<string, unknown>,
ctx: Context,
options: ParseWithCaptchaOptions,
): Promise<CaptchaParseResult<T>> {
const parsed = schema.parse(input) as ParseResult<T>;
const provider = options.provider ?? (options.engine ? selfHostedProvider(options.engine) : undefined);
if (!provider) throw new TypeError("parseWithCaptcha requires provider or engine");
const field = options.responseField ?? provider.client.responseField;
const token = input[field] ?? input.captchaToken ?? input.responseToken;
const captcha = await provider.verify({
action: options.action,
providerToken: token === undefined ? undefined : String(token),
responseToken: token === undefined ? undefined : String(token),
hostname: options.bindHostname === false ? undefined : ctx.url.hostname,
sessionId: options.bindSession === false ? undefined : ctx.session.id(),
ip: options.bindIp ? ctx.ip : undefined,
});
const errors = { ...parsed.errors };
if (!captcha.success) errors[field] = captcha.message ?? "CAPTCHA verification failed";
return {
...parsed,
ok: parsed.ok && captcha.success,
errors,
captcha,
};
}