修复bd邀请的问题

This commit is contained in:
ZuoZuo 2026-04-27 00:11:53 +08:00
parent e9b2444418
commit 2d29554d61
2 changed files with 132 additions and 21 deletions

View File

@ -202,26 +202,111 @@ function splitHeaderPairs(value) {
return result;
}
function parseAppHeaders(raw) {
const data = JSON.parse(raw);
const appIntel = splitHeaderPairs(data["Req-App-Intel"]);
const sysOrigin = splitHeaderPairs(data["Req-Sys-Origin"]);
function mapHeaderValue(target, key, value) {
if (value === null || value === undefined || value === "" || target[key]) return;
target[key] = String(value);
}
function normalizeHeaderCandidate(value, depth = 0) {
if (depth > 4 || value === null || value === undefined) return {};
if (typeof value === "string") {
const trimmed = value.trim();
if (!trimmed) return {};
if (trimmed[0] === "{" || trimmed[0] === "[") {
try {
return normalizeHeaderCandidate(JSON.parse(trimmed), depth + 1);
} catch {
return {};
}
}
return /^bearer\s+/i.test(trimmed) ? { authorization: trimmed } : {};
}
if (Array.isArray(value)) {
return value.reduce((result, item) => ({ ...result, ...normalizeHeaderCandidate(item, depth + 1) }), {});
}
if (typeof value !== "object") return {};
const appIntel = splitHeaderPairs(value["Req-App-Intel"] || value["req-app-intel"]);
const sysOrigin = splitHeaderPairs(value["Req-Sys-Origin"] || value["req-sys-origin"]);
const normalized = {};
mapHeaderValue(normalized, "authorization", value.Authorization || value.authorization || value.token || value.accessToken);
mapHeaderValue(normalized, "reqLang", value["Req-Lang"] || value["req-lang"] || value.reqLang || value.lang || value.language);
mapHeaderValue(normalized, "appVersion", appIntel.version || value["App-Version"] || value.appVersion);
mapHeaderValue(normalized, "buildVersion", appIntel.build || value["Build-Version"] || value.buildVersion);
mapHeaderValue(normalized, "channel", appIntel.channel || value["App-Channel"] || value.appChannel || value.channel);
mapHeaderValue(normalized, "reqImei", value["Req-Imei"] || value["req-imei"] || value.reqImei || appIntel["Req-Imei"] || appIntel.reqImei);
mapHeaderValue(normalized, "origin", sysOrigin.origin || value["Sys-Origin"] || value.sysOrigin || value.origin);
mapHeaderValue(normalized, "child", sysOrigin.originChild || sysOrigin.child || value["Sys-Origin-Child"] || value.sysOriginChild || value.child);
["headerInfo", "headers", "auth", "data", "state"].forEach((key) => {
Object.assign(normalized, normalizeHeaderCandidate(value[key], depth + 1));
});
Object.keys(value).forEach((key) => {
if (["headerInfo", "headers", "auth", "data", "state"].includes(key)) return;
if (value[key] && typeof value[key] === "object") {
Object.assign(normalized, normalizeHeaderCandidate(value[key], depth + 1));
}
});
return normalized;
}
function collectHeaderCandidate(collected, value) {
const normalized = normalizeHeaderCandidate(value);
if (Object.keys(normalized).length) collected.push(normalized);
}
function collectHeadersFromStorage(collected, storage) {
if (!storage) return;
["authorization", "Authorization", "token", "accessToken", "headerInfo", "headersFromApp", "appHeaders", "user", "userInfo"].forEach((key) => {
try {
collectHeaderCandidate(collected, storage.getItem(key));
} catch {}
});
try {
for (let index = 0; index < storage.length; index += 1) {
collectHeaderCandidate(collected, storage.getItem(storage.key(index)));
}
} catch {}
}
function queryHeaderCandidate() {
const params = new URLSearchParams(window.location.search);
return {
authorization: data.Authorization || data.authorization,
reqLang: data["Req-Lang"] || data.reqLang || data.lang,
appVersion: appIntel.version || data["App-Version"] || data.appVersion,
buildVersion: appIntel.build || data["Build-Version"] || data.buildVersion,
channel: appIntel.channel || data["App-Channel"] || data.appChannel || data.channel,
reqImei: data["Req-Imei"] || data.reqImei || appIntel["Req-Imei"],
origin: sysOrigin.origin || data["Sys-Origin"] || data.sysOrigin,
child: sysOrigin.originChild || sysOrigin.child || data["Sys-Origin-Child"] || data.sysOriginChild
authorization: params.get("authorization") || params.get("Authorization") || params.get("token"),
reqLang: params.get("lang"),
appVersion: params.get("appVersion"),
buildVersion: params.get("buildVersion"),
channel: params.get("appChannel") || params.get("channel"),
reqImei: params.get("reqImei"),
origin: params.get("sysOrigin"),
child: params.get("sysOriginChild")
};
}
function discoverAppHeaders() {
const collected = [{ reqLang: lang }, queryHeaderCandidate()];
collectHeaderCandidate(collected, window.__APP_HEADERS__);
collectHeaderCandidate(collected, window.__HEADER_INFO__);
collectHeaderCandidate(collected, window.headerInfo);
collectHeadersFromStorage(collected, window.localStorage);
collectHeadersFromStorage(collected, window.sessionStorage);
return collected.reduce((result, item) => ({ ...result, ...item }), {});
}
function applyDiscoveredHeaders() {
const discovered = discoverAppHeaders();
if (headers.authorization) delete discovered.authorization;
if (Object.keys(discovered).length) setHeadersFromApp(discovered);
return discovered;
}
export function setHeadersFromApp(rawOrObject) {
const data = typeof rawOrObject === "string" ? parseAppHeaders(rawOrObject) : rawOrObject || {};
const data = normalizeHeaderCandidate(rawOrObject || {});
const next = {};
if (Object.prototype.hasOwnProperty.call(data, "authorization")) next.authorization = data.authorization || "";
if (data.authorization) next.authorization = data.authorization;
if (data.reqLang) next["req-lang"] = data.reqLang;
if (data.appVersion || data.buildVersion || data.channel) {
next["req-app-intel"] = [
@ -258,7 +343,6 @@ function requestAccessOrigin() {
if (!isAppEnvironment()) {
setHeadersFromApp({
authorization: "",
reqLang: lang,
appVersion: "1.0.0",
buildVersion: "1",
@ -305,10 +389,12 @@ function requestAccessOrigin() {
export async function connectToApp() {
if (!appConnectionPromise) {
applyDiscoveredHeaders();
appConnectionPromise = requestAccessOrigin()
.then((raw) => {
if (raw) setHeadersFromApp(raw);
return { success: true, environment: isAppEnvironment() ? "app" : "browser" };
else applyDiscoveredHeaders();
return { success: true, environment: isAppEnvironment() ? "app" : "browser", authenticated: Boolean(headers.authorization) };
})
.finally(() => {
appConnectionPromise = null;
@ -319,7 +405,8 @@ export async function connectToApp() {
}
export async function request(method, path, body) {
const options = { method, headers };
applyDiscoveredHeaders();
const options = { method, headers: { ...headers } };
if (body !== undefined) options.body = JSON.stringify(body);
const response = await fetch(`${API_BASE_URL}${path}`, options);
const data = await response.json().catch(() => ({}));

View File

@ -1,4 +1,4 @@
import { applyLang, avatarError, bindHeader, connectToApp, get, post, t, toast } from "../bd-static/shared.js";
import { applyLang, avatarError, bindHeader, connectToApp, get, post, t, toast } from "../bd-static/shared.js?v=auth-bridge-2";
const config = {
title: "invite_become_BD",
@ -10,6 +10,8 @@ const config = {
let invited = [];
let searchResult = [];
let selected = null;
let locked = false;
let appConnected = false;
bindHeader(config.title);
applyLang();
@ -19,6 +21,11 @@ input.placeholder = t("enter_user_id");
input.addEventListener("input", () => {
selected = null;
clearButton.hidden = !input.value;
if (!input.value.trim()) {
searchResult = [];
loadInvited();
return;
}
render();
});
input.addEventListener("keyup", (event) => {
@ -30,11 +37,22 @@ clearButton.addEventListener("click", () => {
searchResult = [];
selected = null;
clearButton.hidden = true;
render();
loadInvited();
});
connectToApp().then(loadInvited);
init();
async function init() {
try {
await connectToApp();
appConnected = true;
await loadInvited();
} catch (error) {
toast(error.response?.errorMsg || error.message);
}
}
async function loadInvited() {
if (!appConnected) return;
try {
const response = await get(config.list);
invited = response.body || [];
@ -45,6 +63,7 @@ async function loadInvited() {
}
async function search() {
if (locked || !appConnected) return;
const account = input.value.trim();
selected = null;
searchResult = [];
@ -52,11 +71,15 @@ async function search() {
await loadInvited();
return;
}
locked = true;
render();
try {
const response = await get(`/user/user-profile/open-search?account=${encodeURIComponent(account)}`);
if (response.status && response.body) searchResult = [{ userProfile: response.body }];
} catch (error) {
toast(error.response?.errorMsg || error.message);
} finally {
locked = false;
}
render();
}
@ -102,7 +125,7 @@ function render() {
}
async function invite() {
if (!selected) return;
if (!selected || !appConnected) return;
try {
await post(config.invite, { inviteUserId: selected.id });
toast(t("invitation_submitted"));
@ -116,6 +139,7 @@ async function invite() {
}
async function cancelInvite(id) {
if (!appConnected) return;
try {
await post(config.cancel(id));
toast(t("application_cancelled"));