完成80%

This commit is contained in:
2026-07-27 06:50:07 +08:00
parent 8475bbd19a
commit 1eae3bbef4
63 changed files with 13664 additions and 280 deletions
+24 -15
View File
@@ -1,7 +1,8 @@
export const AUTH_TAC_SCENE = Object.freeze({
SMS_LOGIN: "APP_SMS_LOGIN",
REGISTER: "APP_REGISTER",
FORGOT_PASSWORD: "APP_FORGOT_PASSWORD",
export const AUTH_VERIFICATION_OPERATION = Object.freeze({
PASSWORD_LOGIN: "password-login",
SMS_LOGIN: "sms-login",
REGISTER: "register",
FORGOT_PASSWORD: "forgot-password",
});
const SUPPORTED_TAC_TYPES = new Set([
@@ -35,19 +36,24 @@ export const assertSmsCode = (value) => {
return value;
};
export const normalizeCaptchaRequirement = (value, expectedSceneCode) => {
const assertAuthVerificationOperation = (operationCode) => {
if (!Object.values(AUTH_VERIFICATION_OPERATION).includes(operationCode)) {
throw contractError("认证动作不属于当前认证合同", "AUTH_OPERATION_INVALID");
}
return operationCode;
};
export const normalizeCaptchaRequirement = (value) => {
if (!value || typeof value !== "object" || Array.isArray(value)) {
throw contractError("行为验证策略响应无效", "AUTH_TAC_REQUIREMENT_INVALID");
}
const sceneCode = requireText(value.sceneCode, "行为验证场景");
if (sceneCode !== expectedSceneCode) {
throw contractError("行为验证场景与当前操作不匹配", "AUTH_TAC_SCENE_MISMATCH");
if (value.required === false) {
return { required: false, sceneCode };
}
// 短信接口把 validToken 定义为必填,因此 required=false 不能在客户端被解释成
// “跳过验证”。后端必须为短信场景启用 TAC,或另行签发可消费的免验证票据。
if (value.required !== true) {
throw contractError(
"服务端未要求行为验证,无法取得发送短信所需票据",
"行为验证策略缺少 required 布尔值",
"AUTH_TAC_POLICY_INCOMPLETE",
);
}
@@ -71,11 +77,14 @@ export const createTacRenderContext = ({
baseUrl,
clientId,
tenantId,
sceneCode,
operationCode,
subject,
requirement,
}) => {
const normalizedRequirement = normalizeCaptchaRequirement(requirement, sceneCode);
const normalizedRequirement = normalizeCaptchaRequirement(requirement);
if (!normalizedRequirement.required) {
throw contractError("当前认证动作无需行为验证", "AUTH_TAC_NOT_REQUIRED");
}
const normalizedBaseUrl = requireText(baseUrl, "后端地址").replace(/\/+$/, "");
if (!/^https:\/\/[^/]+/i.test(normalizedBaseUrl)) {
throw contractError("行为验证只允许使用 HTTPS 后端地址", "AUTH_TAC_HTTPS_REQUIRED");
@@ -87,11 +96,11 @@ export const createTacRenderContext = ({
return {
requestId: requireText(requestId, "验证请求标识"),
baseUrl: normalizedBaseUrl,
challengeUrl: `${normalizedBaseUrl}/captcha/challenge`,
verifyUrl: `${normalizedBaseUrl}/captcha/verify`,
challengeUrl: `${normalizedBaseUrl}/genealogy/app/auth/verification/${assertAuthVerificationOperation(operationCode)}/challenge`,
verifyUrl: `${normalizedBaseUrl}/genealogy/app/auth/verification/${assertAuthVerificationOperation(operationCode)}/verify`,
clientId: requireText(clientId, "客户端标识"),
tenantId: requireText(tenantId, "租户标识"),
sceneCode: normalizedRequirement.sceneCode,
operationCode,
subject: normalizedSubject,
providerCode: normalizedRequirement.providerCode,
captchaType: normalizedRequirement.captchaType,