114 lines
3.7 KiB
JavaScript
114 lines
3.7 KiB
JavaScript
(function () {
|
||
var TOKEN_KEYS = ['token', 'access_token', 'accessToken'];
|
||
var APP_CODE_KEYS = ['app_code', 'appCode'];
|
||
var USER_READY_EVENT = 'hyapp:user-ready';
|
||
var USER_ERROR_EVENT = 'hyapp:user-error';
|
||
|
||
function query() {
|
||
var params = new URLSearchParams(window.location.search);
|
||
var hash = window.location.hash || '';
|
||
if (hash.indexOf('?') >= 0) {
|
||
new URLSearchParams(hash.split('?').slice(1).join('?')).forEach(
|
||
function (value, key) {
|
||
if (!params.has(key)) params.set(key, value);
|
||
}
|
||
);
|
||
}
|
||
return params;
|
||
}
|
||
|
||
function first(params, keys) {
|
||
for (var i = 0; i < keys.length; i += 1) {
|
||
var value = params.get(keys[i]);
|
||
if (value) return value;
|
||
}
|
||
return '';
|
||
}
|
||
|
||
function normalizeToken(value) {
|
||
var token = String(value || '').trim();
|
||
if (!token) return '';
|
||
if (/^Bearer\s+/i.test(token)) token = token.replace(/^Bearer\s+/i, '');
|
||
var match = token.match(
|
||
/[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+/
|
||
);
|
||
token = match ? match[0] : token;
|
||
return isExpiredToken(token) ? '' : token;
|
||
}
|
||
|
||
function decodeBase64URLJSON(value) {
|
||
try {
|
||
var normalized = String(value || '').replace(/-/g, '+').replace(/_/g, '/');
|
||
while (normalized.length % 4) normalized += '=';
|
||
return JSON.parse(window.atob(normalized));
|
||
} catch (_) {
|
||
return null;
|
||
}
|
||
}
|
||
|
||
function isExpiredToken(token) {
|
||
var parts = String(token || '').split('.');
|
||
if (parts.length < 2) return false;
|
||
var payload = decodeBase64URLJSON(parts[1]);
|
||
if (!payload || !payload.exp) return false;
|
||
// params 是页面入口模式的判定来源;过期 JWT 必须当作无 token,否则充值页会隐藏用户 ID 输入并触发 INVALID_ARGUMENT。
|
||
return Number(payload.exp) * 1000 <= Date.now() + 5000;
|
||
}
|
||
|
||
function parse() {
|
||
var params = query();
|
||
var token = normalizeToken(first(params, TOKEN_KEYS));
|
||
var appCode =
|
||
first(params, APP_CODE_KEYS) ||
|
||
window.localStorage.getItem('hyapp_app_code') ||
|
||
'lalu';
|
||
|
||
if (window.HyAppAPI) {
|
||
if (token) window.HyAppAPI.setAccessToken(token);
|
||
if (appCode) window.HyAppAPI.setAppCode(appCode);
|
||
}
|
||
|
||
return {
|
||
token:
|
||
token ||
|
||
(window.HyAppAPI && window.HyAppAPI.getAccessToken
|
||
? window.HyAppAPI.getAccessToken()
|
||
: ''),
|
||
app_code: appCode,
|
||
raw: params,
|
||
};
|
||
}
|
||
|
||
function emit(name, detail) {
|
||
window.dispatchEvent(new CustomEvent(name, { detail: detail }));
|
||
}
|
||
|
||
function loadUser() {
|
||
var current = parse();
|
||
if (!current.token || !window.HyAppAPI) {
|
||
return Promise.resolve(null);
|
||
}
|
||
return window.HyAppAPI.get('/api/v1/users/me/overview')
|
||
.then(function (userInfo) {
|
||
current.user = userInfo;
|
||
window.HyAppParams.current = current;
|
||
emit(USER_READY_EVENT, current);
|
||
return current;
|
||
})
|
||
.catch(function (error) {
|
||
current.error = error;
|
||
window.HyAppParams.current = current;
|
||
emit(USER_ERROR_EVENT, current);
|
||
throw error;
|
||
});
|
||
}
|
||
|
||
window.HyAppParams = {
|
||
parse: parse,
|
||
loadUser: loadUser,
|
||
current: parse(),
|
||
USER_READY_EVENT: USER_READY_EVENT,
|
||
USER_ERROR_EVENT: USER_ERROR_EVENT,
|
||
};
|
||
})();
|