New Captcha Package added
This commit is contained in:
@@ -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,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user