mirror of
https://github.com/shufflewzc/faker3.git
synced 2025-09-17 11:43:18 +08:00
Initial commit
This commit is contained in:
337
utils/baseH5st.js
Normal file
337
utils/baseH5st.js
Normal file
@ -0,0 +1,337 @@
|
||||
const CryptoJS = require("crypto-js");
|
||||
const {BaseUtils} = require("./baseUtils");
|
||||
const os = require('os');
|
||||
|
||||
class BaseH5st {
|
||||
|
||||
constructor(url, cookieStr, userAgent) {
|
||||
global.baseUtils || new BaseUtils();
|
||||
baseUtils.changeEnv(url, cookieStr, userAgent);
|
||||
|
||||
this.ErrCodes = {
|
||||
UNSIGNABLE_PARAMS: 1, APPID_ABSENT: 2, TOKEN_EMPTY: 3, GENERATE_SIGNATURE_FAILED: 4, UNHANDLED_ERROR: -1
|
||||
};
|
||||
|
||||
this._defaultAlgorithm = {};
|
||||
this._debug = false;
|
||||
|
||||
this.settings = {
|
||||
debug: !1, preRequest: !1, timeout: 2,
|
||||
};
|
||||
}
|
||||
|
||||
_log(log) {
|
||||
if (this._debug) {
|
||||
console.log('[sign]', log)
|
||||
}
|
||||
}
|
||||
|
||||
getSync(t) {
|
||||
let item = window.localStorage.getItem(t);
|
||||
if (item) {
|
||||
let r = JSON.parse(item);
|
||||
if (!r || !r.t || !r.e || 0 === r.e || new Date - r.t >= 1e3 * r.e) {
|
||||
this.removeSync(t);
|
||||
return "";
|
||||
}
|
||||
return r.v
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
setSync(t, r, n, e) {
|
||||
let i = {
|
||||
v: r,
|
||||
t: (new Date).getTime(),
|
||||
e: "number" != typeof n.expire ? 0 : n.expire
|
||||
}
|
||||
window.localStorage.setItem(t, JSON.stringify(i));
|
||||
}
|
||||
|
||||
removeSync(t) {
|
||||
window.localStorage.removeItem(t)
|
||||
}
|
||||
|
||||
__genDefaultKey(t, z) {
|
||||
let A = "";
|
||||
let S = CryptoJS.enc.Utf8.stringify(CryptoJS.enc.Base64.parse(baseUtils.decodeBase64URL(this.__parseToken(t, 16, 28)))),
|
||||
B = S.match(/^[123]([x+][123])+/);
|
||||
if (B) {
|
||||
var j = B[0]["split"](""),
|
||||
M = "";
|
||||
j.forEach((r) => {
|
||||
if (isNaN(r)) {
|
||||
if (["+", "x"].includes(r)) M = r;
|
||||
} else {
|
||||
var a = `local_key_${r}`;
|
||||
if (this._defaultAlgorithm[a]) {
|
||||
switch (M) {
|
||||
case "+":
|
||||
A = `${A}${this.__algorithm(a, z, t)}`;
|
||||
break;
|
||||
case "x":
|
||||
A = this.__algorithm(a, A, t);
|
||||
break;
|
||||
default:
|
||||
A = this.__algorithm(a, z, t);
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
this._log(`__genDefaultKey input=${z},express=${S},key=${A}`)
|
||||
return A;
|
||||
}
|
||||
|
||||
__algorithm(t, r, n) {
|
||||
return t === "local_key_3" ? this._defaultAlgorithm[t](r, n).toString(CryptoJS.enc.Hex) : this._defaultAlgorithm[t](r).toString(CryptoJS.enc.Hex);
|
||||
}
|
||||
|
||||
__parseToken(t, r, n) {
|
||||
if (t) return baseUtils.getDefaultMethod(t, 'slice').call(t, r, n);
|
||||
return "";
|
||||
}
|
||||
|
||||
__parseAlgorithm(t, r) {
|
||||
this["_token"] = t || "";
|
||||
this.__genKey = r && new Function(`return ${r}`)() || null;
|
||||
return !(!this["_token"] || !this.__genKey);
|
||||
}
|
||||
|
||||
__genSign(t, r) {
|
||||
var y = baseUtils.getDefaultMethod(r, 'map')["call"](r, function (t) {
|
||||
return t["key"] + ":" + t.value;
|
||||
})["join"]("&");
|
||||
var d = CryptoJS.HmacSHA256(y, t).toString(CryptoJS.enc.Hex);
|
||||
this._log(`__genSign, paramsStr:${y}, signedStr:${d}`);
|
||||
return d;
|
||||
}
|
||||
|
||||
async __requestAlgorithmOnce() {
|
||||
await this.__requestAlgorithm();
|
||||
}
|
||||
|
||||
async __requestAlgorithm() {
|
||||
this._log("__requestAlgorithm start.");
|
||||
var r = this.envCollect(0);
|
||||
r.ai = this._appId;
|
||||
r.fp = this._fingerprint;
|
||||
var n = JSON.stringify(r, null, 2);
|
||||
this._log(`__requestAlgorithm envCollect=${n}`);
|
||||
var e = this.aes(n , 'wm0!@w-s#ll1flo(', "0102030405060708");
|
||||
var dt = {
|
||||
fingerprint: this._fingerprint, appId: this._appId, version: this._version, env: e, debug: this._debug,
|
||||
};
|
||||
|
||||
try {
|
||||
var {data} = await api({
|
||||
url: "https://cactus.jd.com/request_algo",
|
||||
method: "post",
|
||||
data: {
|
||||
version: dt.version,
|
||||
fp: dt.fingerprint,
|
||||
appId: dt.appId,
|
||||
timestamp: Date.now(),
|
||||
platform: "web",
|
||||
expandParams: dt.env,
|
||||
fv: this.v,
|
||||
},
|
||||
headers: {
|
||||
"Content-Type": "application/json;charset=utf-8",
|
||||
Origin: "https://cactus.jd.com",
|
||||
Host: "cactus.jd.com",
|
||||
accept: "*/*",
|
||||
"User-Agent": navigation.userAgent,
|
||||
},
|
||||
});
|
||||
|
||||
if (data && data.status === 200 && data.data && data.data.result) {
|
||||
var c = data.data.result;
|
||||
if (c.algo && c.tk && c.fp) {
|
||||
var l = c.fp === this._fingerprint,
|
||||
p = l ? this.getSync(this._storageFpKey, 1) : "",
|
||||
d = p && c.fp === p;
|
||||
if (d) {
|
||||
var z = this.__parseToken(c.tk, 13, 15);
|
||||
var x = parseInt(z, 16);
|
||||
var w = x * 60 * 60;
|
||||
this.setSync(this._storagetokenKey, CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(c.tk)), {
|
||||
expire: w,
|
||||
});
|
||||
this.setSync(this._storageAlgnKey, CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(c.algo)), {
|
||||
expire: w,
|
||||
});
|
||||
}
|
||||
this._log(`__requestAlgorithm request success!, check memory fp:${l}, check storage fp:${d}, token:${c.tk}, storageFp:${p}, fp:${c.fp}`);
|
||||
} else {
|
||||
throw new Error("data.result format error.");
|
||||
}
|
||||
} else {
|
||||
throw new Error("request params error.");
|
||||
}
|
||||
} catch (error) {
|
||||
throw new Error(`request error, ${error.code}, ${error.message}`);
|
||||
}
|
||||
this._log(this._debug, "__requestAlgorithm end.");
|
||||
}
|
||||
|
||||
__checkParams(t) {
|
||||
let u = null;
|
||||
if (!this._appId) {
|
||||
u = {
|
||||
code: this.ErrCodes.APPID_ABSENT, message: "appId is required"
|
||||
}
|
||||
}
|
||||
if (!baseUtils.isPlainObject(t)) {
|
||||
u = {
|
||||
code: this.ErrCodes.UNSIGNABLE_PARAMS, message: 'params is not a plain object'
|
||||
}
|
||||
}
|
||||
if (baseUtils.isEmpty(t)) {
|
||||
u = {
|
||||
code: this.ErrCodes.UNSIGNABLE_PARAMS, message: 'params is empty'
|
||||
}
|
||||
}
|
||||
if (baseUtils.containsReservedParamName(t)) {
|
||||
u = {
|
||||
code: this.ErrCodes.UNSIGNABLE_PARAMS, message: 'params contains reserved param name.'
|
||||
}
|
||||
}
|
||||
if (u) {
|
||||
this._onSign(u);
|
||||
return null;
|
||||
}
|
||||
let o, e, r, n;
|
||||
o = baseUtils.getDefaultMethod(e = baseUtils.getDefaultMethod(r = baseUtils.getDefaultMethod(n = Object.keys(t), 'sort').call(n), 'map').call(r, (function (e) {
|
||||
return {key: e, value: t[e]}
|
||||
})), 'filter').call(e, (function (t) {
|
||||
return baseUtils.isSafeParamValue(t.value)
|
||||
}))
|
||||
|
||||
if (o.length === 0) {
|
||||
this._onSign({
|
||||
code: this.ErrCodes.UNSIGNABLE_PARAMS, message: 'params is empty after excluding "unsafe" params',
|
||||
});
|
||||
return null;
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
__collect() {
|
||||
var n = this.envCollect(1);
|
||||
n.fp = this._fingerprint;
|
||||
var e = JSON.stringify(n, null, 2);
|
||||
this._log(`__collect envCollect=${e}`);
|
||||
return this.aes(e, this.collectSecret, "0102030405060708");
|
||||
}
|
||||
|
||||
async sign(params) {
|
||||
try {
|
||||
var Ot = Date.now();
|
||||
var e = ["functionId", "appid", "client", "body", "clientVersion", "sign", "t", "jsonp"].reduce((function (e, r) {
|
||||
var n = params[r];
|
||||
return n && ("body" === r && (n = CryptoJS.SHA256(n).toString()), e[r] = n), e
|
||||
}), {});
|
||||
|
||||
var o = this.__checkParams(e);
|
||||
if (o == null) {
|
||||
return e;
|
||||
}
|
||||
await this.__requestDeps();
|
||||
let i = this.__collect();
|
||||
let a = this.__makeSign(o, i);
|
||||
this._log(`sign elapsed time!${Date.now() - Ot}ms`);
|
||||
return Object.assign({}, e, a);
|
||||
} catch (error) {
|
||||
this._onSign({
|
||||
code: this.ErrCodes.UNHANDLED_ERROR, message: 'unknown error'
|
||||
})
|
||||
this._log(`unknown error!${error.message}`);
|
||||
return params;
|
||||
}
|
||||
}
|
||||
|
||||
envCollect(e) {
|
||||
let info = {
|
||||
pp: (() => {
|
||||
let ptPin = baseUtils.extractPtPin(document.cookie);
|
||||
if (ptPin) {
|
||||
return {
|
||||
"p1": ptPin,
|
||||
"p2": ptPin
|
||||
}
|
||||
}
|
||||
return {}
|
||||
})(),
|
||||
extend: {
|
||||
bu1: this.bu1,
|
||||
bu2: 0,
|
||||
bu3: document.head.childElementCount,
|
||||
bu4: 0,
|
||||
bu5: 0,
|
||||
l: 0,
|
||||
ls: 0,
|
||||
wd: 0,
|
||||
wk: 0,
|
||||
},
|
||||
random: baseUtils.getRandomIDPro({size: 12, dictType: 'max', customDict: null}),
|
||||
sua: (() => {
|
||||
var regex = new RegExp("Mozilla/5.0 \\((.*?)\\)");
|
||||
var matches = window.navigator.userAgent.match(regex);
|
||||
return matches && matches[1] ? matches[1] : "";
|
||||
})()
|
||||
}
|
||||
|
||||
if (this.v) {
|
||||
info.v = this.v
|
||||
}
|
||||
|
||||
if (e == 0) {
|
||||
Object.assign(info, {
|
||||
"wc": /Chrome/.test(window.navigator.userAgent) && !window.chrome ? 1 : 0,
|
||||
"wd": 0,
|
||||
"l": navigator.language,
|
||||
"ls": navigator.languages.join(","),
|
||||
"ml": navigator.mimeTypes.length,
|
||||
"pl": navigator.plugins.length,
|
||||
"av": (() => {
|
||||
let av = window.navigator.userAgent.match(/(?<=\/)[0-9]\.0[^'"\n]+/g);
|
||||
return av.length > 0 ? av[0] : "";
|
||||
})(),
|
||||
"ua": window.navigator.userAgent,
|
||||
"w": window.screen.width,
|
||||
"h": window.screen.height,
|
||||
"ow": window.outerWidth,
|
||||
"oh": window.outerHeight,
|
||||
"url": location.href,
|
||||
"og": location.origin,
|
||||
// "pf": os.platform(),
|
||||
// "bu2": " at https://storage.360buyimg.com/webcontainer/js_security_v3_0.1.5.js:3833:21",
|
||||
// "canvas": "07d433e77178ffb3c4358a1a92f3233f",
|
||||
// "webglFp": "d714752d3e7330bcd7e2b332e7cbcb56",
|
||||
"ccn": navigator.hardwareConcurrency,
|
||||
"ai": this._appId,
|
||||
"pr": 1,
|
||||
"re": document.referrer,
|
||||
"referer": (() => {
|
||||
var i = new RegExp("[^?]*"),
|
||||
u = document.referrer.match(i);
|
||||
if (!u || !u[0]) return "";
|
||||
return u[0];
|
||||
})(),
|
||||
"pp1": {
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
aes(message, key, iv) {
|
||||
return CryptoJS.AES.encrypt(message, CryptoJS.enc.Utf8.parse(key), {
|
||||
iv: CryptoJS.enc.Utf8.parse(iv),
|
||||
}).ciphertext.toString();
|
||||
}
|
||||
}
|
||||
|
||||
module.exports.BaseH5st = BaseH5st
|
Reference in New Issue
Block a user