(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, }; })();