完成50%
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 249 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 1.0 MiB |
@@ -0,0 +1,7 @@
|
||||
#tianai-captcha-parent{box-shadow:0 0 11px 0 #999;width:318px;height:318px;overflow:hidden;position:relative;z-index:997;box-sizing:border-box;border-radius:5px;padding:8px}#tianai-captcha-parent #tianai-captcha-box{height:260px;width:100%;position:relative;overflow:hidden}#tianai-captcha-parent #tianai-captcha-box .loading{width:120px;height:20px;-webkit-mask:linear-gradient(90deg, #000 70%, rgba(0, 0, 0, 0) 0) 0/20%;background:linear-gradient(#f7b645 0 0) 0/0% no-repeat rgba(221,221,221,.4196078431);animation:cartoon 1s infinite steps(6);margin:120px auto}@keyframes cartoon{100%{background-size:120%}}#tianai-captcha-parent #tianai-captcha-box #tianai-captcha{transform-style:preserve-3d;will-change:transform;transition-duration:.45s;transform:translateX(-300px)}#tianai-captcha-parent #tianai-captcha-bg-img{background-color:#fff;background-position:top;background-size:cover;z-index:-1;width:100%;height:100%;top:0;left:0;position:absolute;border-radius:6px}#tianai-captcha-parent .slider-bottom{height:19px;width:100%}#tianai-captcha-parent .slider-bottom .close-btn{width:20px;height:20px;background-image:url(../../tac/images/icon.png);background-repeat:no-repeat;background-position:0 -14px;float:right;margin-right:2px;cursor:pointer}#tianai-captcha-parent .slider-bottom .refresh-btn{width:20px;height:20px;background-image:url(../../tac/images/icon.png);background-position:0 -167px;background-repeat:no-repeat;float:right;margin-right:10px;cursor:pointer}#tianai-captcha-parent .slider-bottom .logo{height:30px;float:left}#tianai-captcha-parent .slider-move-shadow{animation:myanimation 2s infinite;height:100%;width:5px;background-color:#fff;position:absolute;top:0;left:0;filter:opacity(0.5);box-shadow:1px 1px 1px #fff;border-radius:50%}#tianai-captcha-parent #tianai-captcha-slider-move-track-mask{border-width:1px;border-style:solid;border-color:#00f4ab;width:0;height:32px;background-color:#a9ffe5;opacity:.5;position:absolute;top:-1px;left:-1px;border-radius:5px}
|
||||
#tianai-captcha{text-align:left;box-sizing:content-box;width:300px;height:260px;z-index:999}#tianai-captcha .slider-bottom .logo{height:30px}#tianai-captcha .slider-bottom{height:19px;width:100%}#tianai-captcha .content .tianai-captcha-tips{height:25px;width:100%;position:absolute;bottom:-25px;left:0;z-index:999;font-size:15px;line-height:25px;color:#fff;text-align:center;transition:bottom .3s ease-in-out}#tianai-captcha .content .tianai-captcha-tips.tianai-captcha-tips-error{background-color:#ff5d39}#tianai-captcha .content .tianai-captcha-tips.tianai-captcha-tips-success{background-color:#39c522}#tianai-captcha .content .tianai-captcha-tips.tianai-captcha-tips-on{bottom:0}#tianai-captcha .content #tianai-captcha-loading{z-index:9999;background-color:#f5f5f5;text-align:center;height:100%;overflow:hidden;position:relative;display:flex;justify-content:center;align-items:center}#tianai-captcha .content #tianai-captcha-loading img{display:block;width:45px;height:45px}#tianai-captcha #tianai-captcha-slider-bg-canvas{position:absolute;left:0;top:0;width:100%;height:100%;border-radius:5px}#tianai-captcha #tianai-captcha-slider-bg-div{position:absolute;left:0;top:0;width:100%;height:100%;border-radius:5px}#tianai-captcha #tianai-captcha-slider-bg-div .tianai-captcha-slider-bg-div-slice{position:absolute}@keyframes myanimation{from{left:0}to{left:289px}}
|
||||
#tianai-captcha.tianai-captcha-slider{z-index:999;position:absolute;left:0;top:0;user-select:none}#tianai-captcha.tianai-captcha-slider .content{width:100%;height:180px;position:relative;overflow:hidden}#tianai-captcha.tianai-captcha-slider .bg-img-div{width:100%;height:100%;position:absolute;transform:translate(0px, 0px)}#tianai-captcha.tianai-captcha-slider .bg-img-div img{height:100%;width:100%;border-radius:5px}#tianai-captcha.tianai-captcha-slider .slider-img-div{height:100%;position:absolute;left:0;transform:translate(0px, 0px)}#tianai-captcha.tianai-captcha-slider .slider-img-div #tianai-captcha-slider-move-img{height:100%}#tianai-captcha.tianai-captcha-slider .slider-move{height:34px;width:100%;margin:11px 0;position:relative}#tianai-captcha.tianai-captcha-slider .slider-move-track{position:relative;height:32px;line-height:32px;text-align:center;background:#f5f5f5;color:#999;transition:0s;font-size:14px;box-sizing:content-box;border:1px solid #f5f5f5;border-radius:4px}#tianai-captcha.tianai-captcha-slider .refresh-btn,#tianai-captcha.tianai-captcha-slider .close-btn{display:inline-block}#tianai-captcha.tianai-captcha-slider .slider-move{line-height:38px;font-size:14px;text-align:center;white-space:nowrap;color:#88949d;-moz-user-select:none;-webkit-user-select:none;user-select:none;filter:opacity(0.8)}#tianai-captcha.tianai-captcha-slider .slider-move .slider-move-btn{transform:translate(0px, 0px);position:absolute;top:-6px;left:0;width:63px;height:45px;background-color:#fff;background-repeat:no-repeat;background-size:contain;border-radius:5px}#tianai-captcha.tianai-captcha-slider .slider-tip{margin-bottom:5px;font-weight:bold;font-size:15px;line-height:normal;color:#000}#tianai-captcha.tianai-captcha-slider .slider-move-btn:hover{cursor:pointer}
|
||||
#tianai-captcha.tianai-captcha-rotate .rotate-img-div{height:100%;text-align:center}#tianai-captcha.tianai-captcha-rotate .rotate-img-div img{height:100%;transform:rotate(0deg);display:inline-block}
|
||||
#tianai-captcha.tianai-captcha-concat .tianai-captcha-slider-concat-img-div{background-size:100% 180px;position:absolute;transform:translate(0px, 0px);z-index:1;width:100%}#tianai-captcha.tianai-captcha-concat .tianai-captcha-slider-concat-bg-img{width:100%;height:100%;position:absolute;transform:translate(0px, 0px);background-size:100% 180px}
|
||||
#tianai-captcha.tianai-captcha-disable{z-index:999;position:absolute;left:0;top:0}#tianai-captcha.tianai-captcha-disable .content{width:100%;height:180px;position:relative;overflow:hidden}#tianai-captcha.tianai-captcha-disable .content .bg-img-div{background-image:url(../../tac/images/dun.jpeg);width:100%;height:100%;overflow:hidden}#tianai-captcha.tianai-captcha-disable .content .bg-img-div #content-span{color:#fff;overflow:hidden;margin-top:132px;display:block;text-align:center}
|
||||
#tianai-captcha.tianai-captcha-word-click{box-sizing:border-box}#tianai-captcha.tianai-captcha-word-click .click-tip{position:relative;height:40px;width:100%}#tianai-captcha.tianai-captcha-word-click .click-tip .tip-img{height:35px;position:absolute;right:15px}#tianai-captcha.tianai-captcha-word-click .click-tip #tianai-captcha-click-track-font{font-size:18px;display:inline-block;height:40px;line-height:40px;position:absolute}#tianai-captcha.tianai-captcha-word-click .slider-bottom{position:relative;top:6px}#tianai-captcha.tianai-captcha-word-click .content #bg-img-click-mask{width:100%;height:100%;position:absolute;left:0;top:0}#tianai-captcha.tianai-captcha-word-click .content #bg-img-click-mask .click-span{position:absolute;left:0;top:0;border-radius:50px;background-color:#409eff;width:20px;height:20px;text-align:center;line-height:20px;color:#fff;border:2px solid #fff;box-sizing:content-box}#tianai-captcha.tianai-captcha-word-click .click-confirm-btn{width:100%;height:35px;border-radius:4px;background-image:linear-gradient(173deg, hsl(38.09, 91%, 57.89%) 0%, hsl(38.09, 89.38%, 71.74%) 100%);font-size:15px;text-align:center;box-sizing:border-box;line-height:35px;color:#fff;margin-top:3px}#tianai-captcha.tianai-captcha-word-click .click-confirm-btn:hover{cursor:pointer}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 8.1 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 3.0 KiB |
@@ -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