3 changed files with 37 additions and 0 deletions
@ -0,0 +1,12 @@ |
|||
import { getRequestIP } from "h3"; |
|||
import { createCaptchaChallenge } from "#server/service/captcha/challenge"; |
|||
import { assertUnderRateLimit } from "#server/utils/simple-rate-limit"; |
|||
|
|||
export default defineWrappedResponseHandler(async (event) => { |
|||
setResponseHeader(event, "cache-control", "no-store"); |
|||
const ip = getRequestIP(event, { xForwardedFor: true }) ?? "unknown"; |
|||
assertUnderRateLimit(`auth-captcha:${ip}`, 60, 60_000); |
|||
|
|||
const { captchaId, imageSvg } = createCaptchaChallenge(); |
|||
return R.success({ captchaId, imageSvg }); |
|||
}); |
|||
@ -0,0 +1,24 @@ |
|||
export type AuthCredentialsAndCaptcha = { |
|||
username: string; |
|||
password: string; |
|||
captchaId: string; |
|||
captchaAnswer: string; |
|||
}; |
|||
|
|||
export function assertLoginRegisterCaptchaFieldsPresent( |
|||
body: unknown, |
|||
): asserts body is AuthCredentialsAndCaptcha { |
|||
if (typeof body !== "object" || body === null) { |
|||
throw createError({ statusCode: 400, statusMessage: "无效请求" }); |
|||
} |
|||
const b = body as Record<string, unknown>; |
|||
if (typeof b.username !== "string" || typeof b.password !== "string") { |
|||
throw createError({ statusCode: 400, statusMessage: "无效请求" }); |
|||
} |
|||
if (typeof b.captchaId !== "string" || b.captchaId.trim() === "") { |
|||
throw createError({ statusCode: 400, statusMessage: "请完成验证码" }); |
|||
} |
|||
if (typeof b.captchaAnswer !== "string" || b.captchaAnswer.trim() === "") { |
|||
throw createError({ statusCode: 400, statusMessage: "请完成验证码" }); |
|||
} |
|||
} |
|||
Loading…
Reference in new issue