完成50%
This commit is contained in:
@@ -0,0 +1,164 @@
|
||||
(function attachJiapuTacAdapter(global) {
|
||||
"use strict";
|
||||
|
||||
var SUPPORTED_TYPES = ["SLIDER", "ROTATE", "CONCAT", "WORD_IMAGE_CLICK"];
|
||||
|
||||
function fail(message, code) {
|
||||
var error = new Error(message);
|
||||
error.code = code || "TAC_PROTOCOL_INVALID";
|
||||
throw error;
|
||||
}
|
||||
|
||||
function text(value, label) {
|
||||
if (typeof value !== "string" || !value.trim()) fail(label + "不能为空");
|
||||
return value.trim();
|
||||
}
|
||||
|
||||
function positiveInteger(value, label) {
|
||||
var number = Number(value);
|
||||
if (!Number.isInteger(number) || number < 1) fail(label + "必须是正整数");
|
||||
return number;
|
||||
}
|
||||
|
||||
function assertContext(context) {
|
||||
if (!context || typeof context !== "object") fail("TAC 请求上下文无效");
|
||||
return {
|
||||
tenantId: text(context.tenantId, "租户标识"),
|
||||
clientId: text(context.clientId, "客户端标识"),
|
||||
sceneCode: text(context.sceneCode, "验证场景"),
|
||||
subject: text(context.subject, "验证主体"),
|
||||
providerCode: text(context.providerCode, "验证服务商").toUpperCase(),
|
||||
captchaType: text(context.captchaType, "验证码类型").toUpperCase(),
|
||||
};
|
||||
}
|
||||
|
||||
function assertChallengePayload(type, payload) {
|
||||
if (!payload || typeof payload !== "object" || Array.isArray(payload)) {
|
||||
fail("行为验证挑战缺少渲染载荷");
|
||||
}
|
||||
if (type === "CONCAT") {
|
||||
text(payload.backgroundImage, "拼图背景图片");
|
||||
positiveInteger(payload.backgroundImageHeight, "拼图背景高度");
|
||||
if (!payload.data || !Number.isFinite(Number(payload.data.randomY))) {
|
||||
fail("拼图挑战缺少 randomY");
|
||||
}
|
||||
return;
|
||||
}
|
||||
text(payload.backgroundImage, "行为验证背景图片");
|
||||
text(payload.templateImage, "行为验证模板图片");
|
||||
}
|
||||
|
||||
function normalizeChallengeResponse(response, expectedContext) {
|
||||
var context = assertContext(expectedContext);
|
||||
if (!response || typeof response !== "object" || Number(response.code) !== 200) {
|
||||
fail((response && response.msg) || "行为验证挑战请求失败", "TAC_CHALLENGE_FAILED");
|
||||
}
|
||||
var data = response.data;
|
||||
if (!data || typeof data !== "object" || data.required !== true) {
|
||||
fail("行为验证挑战未处于强制验证状态", "TAC_CHALLENGE_NOT_REQUIRED");
|
||||
}
|
||||
var providerCode = text(data.providerCode, "挑战服务商").toUpperCase();
|
||||
var captchaType = text(data.captchaType, "挑战验证码类型").toUpperCase();
|
||||
if (providerCode !== "TIANAI" || providerCode !== context.providerCode) {
|
||||
fail("行为验证挑战服务商不匹配", "TAC_PROVIDER_MISMATCH");
|
||||
}
|
||||
if (SUPPORTED_TYPES.indexOf(captchaType) < 0 || captchaType !== context.captchaType) {
|
||||
fail("行为验证挑战类型不匹配", "TAC_TYPE_MISMATCH");
|
||||
}
|
||||
var challengeId = text(data.challengeId, "行为验证挑战标识");
|
||||
var expireSeconds = positiveInteger(data.expireSeconds, "行为验证挑战有效期");
|
||||
assertChallengePayload(captchaType, data.payload);
|
||||
return {
|
||||
challenge: {
|
||||
required: true,
|
||||
providerCode: providerCode,
|
||||
captchaType: captchaType,
|
||||
challengeId: challengeId,
|
||||
expireSeconds: expireSeconds,
|
||||
},
|
||||
sdkResponse: {
|
||||
code: 200,
|
||||
msg: typeof response.msg === "string" ? response.msg : "操作成功",
|
||||
data: Object.assign({}, data.payload, {
|
||||
type: captchaType,
|
||||
id: challengeId,
|
||||
}),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function assertTrack(track) {
|
||||
if (!track || typeof track !== "object" || Array.isArray(track)) fail("行为验证轨迹无效");
|
||||
positiveInteger(track.bgImageWidth, "轨迹背景宽度");
|
||||
positiveInteger(track.bgImageHeight, "轨迹背景高度");
|
||||
var startTime = Number(track.startTime);
|
||||
var stopTime = Number(track.stopTime);
|
||||
if (!Number.isFinite(startTime) || !Number.isFinite(stopTime) || stopTime < startTime) {
|
||||
fail("行为验证轨迹时间无效");
|
||||
}
|
||||
if (!Array.isArray(track.trackList) || track.trackList.length < 1) {
|
||||
fail("行为验证轨迹不能为空");
|
||||
}
|
||||
track.trackList.forEach(function validatePoint(point) {
|
||||
if (!point || !Number.isFinite(Number(point.x)) || !Number.isFinite(Number(point.y)) ||
|
||||
!Number.isFinite(Number(point.t)) || typeof point.type !== "string" || !point.type) {
|
||||
fail("行为验证轨迹点无效");
|
||||
}
|
||||
});
|
||||
return track;
|
||||
}
|
||||
|
||||
function buildVerifyBody(libraryRequest, expectedContext, challenge) {
|
||||
var context = assertContext(expectedContext);
|
||||
if (!challenge || typeof challenge !== "object") fail("行为验证挑战上下文缺失");
|
||||
var challengeId = text(challenge.challengeId, "行为验证挑战标识");
|
||||
if (!libraryRequest || libraryRequest.id !== challengeId) {
|
||||
fail("行为验证 challenge 标识与当前挑战不匹配", "TAC_CHALLENGE_MISMATCH");
|
||||
}
|
||||
if (challenge.providerCode !== context.providerCode || challenge.captchaType !== context.captchaType) {
|
||||
fail("行为验证挑战上下文已变化", "TAC_CONTEXT_MISMATCH");
|
||||
}
|
||||
return {
|
||||
tenantId: context.tenantId,
|
||||
clientId: context.clientId,
|
||||
sceneCode: context.sceneCode,
|
||||
subject: context.subject,
|
||||
challengeId: challengeId,
|
||||
providerCode: challenge.providerCode,
|
||||
captchaType: challenge.captchaType,
|
||||
// 受保护 OpenAPI 的唯一合同是 payload.track;SDK 回调 id 已提升为 challengeId,
|
||||
// 不得再次混入 payload,也不得退回“直接传 track”的兼容分支。
|
||||
payload: { track: assertTrack(libraryRequest.data) },
|
||||
};
|
||||
}
|
||||
|
||||
function normalizeVerifyResponse(response) {
|
||||
if (!response || typeof response !== "object" || Number(response.code) !== 200) {
|
||||
fail((response && response.msg) || "行为验证请求失败", "TAC_VERIFY_REQUEST_FAILED");
|
||||
}
|
||||
var data = response.data;
|
||||
if (!data || data.passed !== true) {
|
||||
fail((data && data.message) || "行为验证未通过", "TAC_VERIFY_REJECTED");
|
||||
}
|
||||
var validToken = text(data.validToken, "行为验证票据");
|
||||
var expireSeconds = positiveInteger(data.expireSeconds, "行为验证票据有效期");
|
||||
return {
|
||||
code: 200,
|
||||
data: { passed: true, validToken: validToken, expireSeconds: expireSeconds },
|
||||
};
|
||||
}
|
||||
|
||||
function toSdkFailure(error) {
|
||||
return {
|
||||
code: 4001,
|
||||
msg: error && error.message ? error.message : "行为验证失败,请重试",
|
||||
};
|
||||
}
|
||||
|
||||
global.JiapuTacAdapter = Object.freeze({
|
||||
normalizeChallengeResponse: normalizeChallengeResponse,
|
||||
buildVerifyBody: buildVerifyBody,
|
||||
normalizeVerifyResponse: normalizeVerifyResponse,
|
||||
toSdkFailure: toSdkFailure,
|
||||
});
|
||||
})(typeof window !== "undefined" ? window : globalThis);
|
||||
Vendored
+1
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user