From 5b775622e16c553c4628dd8a770bec4a6cb90b0f Mon Sep 17 00:00:00 2001 From: CN-JS-HuiBai Date: Tue, 7 Apr 2026 17:46:24 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=AE=A1=E7=90=86=E5=91=98?= =?UTF-8?q?=E9=94=99=E8=AF=AF=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../resources/views/admin-users.blade.php | 134 ++++++++++++++++-- 1 file changed, 124 insertions(+), 10 deletions(-) diff --git a/Xboard/plugins/UserOnlineDevices/resources/views/admin-users.blade.php b/Xboard/plugins/UserOnlineDevices/resources/views/admin-users.blade.php index 5531ad5..e015341 100644 --- a/Xboard/plugins/UserOnlineDevices/resources/views/admin-users.blade.php +++ b/Xboard/plugins/UserOnlineDevices/resources/views/admin-users.blade.php @@ -331,6 +331,10 @@ const ADMIN_HOME_URL = @json($adminHomeUrl); const REFRESH_MS = 30000; const TOKEN_KEYS = [ + 'auth_data', + 'AUTH_DATA', + 'admin_auth_data', + 'ADMIN_AUTH_DATA', 'VUE_NAIVE_ACCESS_TOKEN', 'Vue_Naive_access_token', 'access_token', @@ -361,6 +365,19 @@ return 'Bearer ' + raw; } + function addCandidateToken(bucket, candidate, priority) { + const normalized = normalizeToken(candidate); + if (!normalized) return; + + const existing = bucket.get(normalized); + if (!existing || priority > existing.priority) { + bucket.set(normalized, { + token: normalized, + priority: priority + }); + } + } + function extractTokenFromParsedValue(input) { if (!input) return ''; @@ -398,6 +415,42 @@ return ''; } + function collectTokensFromUnknown(input, bucket, priority) { + if (!input) return; + + if (typeof input === 'string') { + addCandidateToken(bucket, input, priority); + return; + } + + if (Array.isArray(input)) { + input.forEach(function (item) { + collectTokensFromUnknown(item, bucket, priority - 1); + }); + return; + } + + if (!isObject(input)) { + return; + } + + if (input.is_admin === true || input.isAdmin === true) { + addCandidateToken(bucket, input.auth_data || input.authData || input.authorization || input.token, priority + 20); + } + + const directKeys = ['auth_data', 'authData', 'authorization', 'token', 'access_token', 'accessToken', 'value', 'data']; + directKeys.forEach(function (key) { + if (Object.prototype.hasOwnProperty.call(input, key)) { + collectTokensFromUnknown(input[key], bucket, priority - (key === 'data' ? 2 : 0)); + } + }); + + Object.keys(input).forEach(function (key) { + if (directKeys.indexOf(key) !== -1) return; + collectTokensFromUnknown(input[key], bucket, priority - 3); + }); + } + function parseStoredToken(rawValue) { if (!rawValue || typeof rawValue !== 'string') return ''; @@ -416,21 +469,82 @@ return ''; } - function readTokenFromStorage(storage) { - if (!storage) return ''; + function collectStorageCandidates(storage, bucket) { + if (!storage) return; for (const key of TOKEN_KEYS) { - const token = parseStoredToken(storage.getItem(key)); - if (token) return token; + addCandidateToken(bucket, storage.getItem(key), 100); + } + + for (let index = 0; index < storage.length; index += 1) { + const key = storage.key(index); + if (!key) continue; + + const rawValue = storage.getItem(key); + if (!rawValue) continue; + + const normalizedKey = key.toLowerCase(); + const priority = normalizedKey.indexOf('admin') !== -1 + ? 90 + : normalizedKey.indexOf('auth') !== -1 + ? 80 + : normalizedKey.indexOf('token') !== -1 + ? 70 + : 20; + + addCandidateToken(bucket, rawValue, priority); + + const trimmed = rawValue.trim(); + if (trimmed[0] === '{' || trimmed[0] === '[') { + try { + collectTokensFromUnknown(JSON.parse(trimmed), bucket, priority); + } catch (error) { + } + } + } + } + + function buildAuthorizationCandidates() { + const bucket = new Map(); + collectStorageCandidates(window.localStorage, bucket); + collectStorageCandidates(window.sessionStorage, bucket); + + return Array.from(bucket.values()) + .sort(function (left, right) { + return right.priority - left.priority; + }) + .map(function (item) { + return item.token; + }); + } + + async function pickAuthorization() { + const candidates = buildAuthorizationCandidates(); + for (const authorization of candidates) { + try { + const url = new URL(API_ENDPOINT, window.location.origin); + url.searchParams.set('current', '1'); + url.searchParams.set('pageSize', '1'); + + const response = await fetch(url.toString(), { + method: 'GET', + headers: { + 'Accept': 'application/json', + 'Authorization': authorization + }, + credentials: 'same-origin' + }); + + if (response.ok) { + return authorization; + } + } catch (error) { + } } return ''; } - function getAuthorization() { - return readTokenFromStorage(window.localStorage) || readTokenFromStorage(window.sessionStorage); - } - function formatTime(timestamp) { if (!timestamp) return '-'; @@ -543,10 +657,10 @@ } async function loadData() { - const authorization = getAuthorization(); + const authorization = await pickAuthorization(); if (!authorization) { resetTable(); - setError('No usable admin login token was found in Xboard browser storage. Please log in to the admin panel first, then refresh this page.'); + setError('No usable admin login token was found in browser storage. Please log in to the Xboard admin panel first, then refresh this page.'); return; }