release: WRNexusJS 0.5.0
This commit is contained in:
@@ -73,11 +73,44 @@ function defaultFailure(options: CaptchaGuardOptions, result: CaptchaVerificatio
|
||||
}
|
||||
|
||||
export function captchaGuard(options: CaptchaGuardOptions) {
|
||||
const verifiedForMs = options.verifiedForMs ?? 0;
|
||||
if (!Number.isFinite(verifiedForMs) || verifiedForMs < 0) {
|
||||
throw new TypeError("captchaGuard verifiedForMs must be a non-negative finite duration");
|
||||
}
|
||||
const sessionKey = options.sessionKey ?? "wrnexus.captcha.grants";
|
||||
|
||||
return async (ctx: Context, next: () => Promise<Response> | Response): Promise<Response> => {
|
||||
const action = resolveAction(options.action, ctx);
|
||||
const now = Date.now();
|
||||
const grants = ctx.session.get<CaptchaSessionGrant[]>(sessionKey) ?? [];
|
||||
const grant = verifiedForMs > 0 ? validCaptchaGrant(grants, action, now) : undefined;
|
||||
if (grant) {
|
||||
ctx.locals.captcha = {
|
||||
success: true,
|
||||
provider: grant.provider,
|
||||
action,
|
||||
};
|
||||
ctx.locals.captchaVerified = true;
|
||||
return next();
|
||||
}
|
||||
|
||||
const result = await verifyRequest(ctx, options);
|
||||
ctx.locals.captcha = result;
|
||||
if (!result.success)
|
||||
return options.onFailure ? options.onFailure(ctx, result) : defaultFailure(options, result);
|
||||
|
||||
if (verifiedForMs > 0) {
|
||||
const fresh: CaptchaSessionGrant = {
|
||||
action,
|
||||
provider: result.provider,
|
||||
expiresAt: now + verifiedForMs,
|
||||
};
|
||||
ctx.session.set(sessionKey, [
|
||||
...grants.filter((item) => item.expiresAt > now && item.action !== action),
|
||||
fresh,
|
||||
]);
|
||||
}
|
||||
|
||||
return next();
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user