修复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; return result;
} }
function parseAppHeaders(raw) { function mapHeaderValue(target, key, value) {
const data = JSON.parse(raw); if (value === null || value === undefined || value === "" || target[key]) return;
const appIntel = splitHeaderPairs(data["Req-App-Intel"]); target[key] = String(value);
const sysOrigin = splitHeaderPairs(data["Req-Sys-Origin"]); }
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 { return {
authorization: data.Authorization || data.authorization, authorization: params.get("authorization") || params.get("Authorization") || params.get("token"),
reqLang: data["Req-Lang"] || data.reqLang || data.lang, reqLang: params.get("lang"),
appVersion: appIntel.version || data["App-Version"] || data.appVersion, appVersion: params.get("appVersion"),
buildVersion: appIntel.build || data["Build-Version"] || data.buildVersion, buildVersion: params.get("buildVersion"),
channel: appIntel.channel || data["App-Channel"] || data.appChannel || data.channel, channel: params.get("appChannel") || params.get("channel"),
reqImei: data["Req-Imei"] || data.reqImei || appIntel["Req-Imei"], reqImei: params.get("reqImei"),
origin: sysOrigin.origin || data["Sys-Origin"] || data.sysOrigin, origin: params.get("sysOrigin"),
child: sysOrigin.originChild || sysOrigin.child || data["Sys-Origin-Child"] || data.sysOriginChild 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) { export function setHeadersFromApp(rawOrObject) {
const data = typeof rawOrObject === "string" ? parseAppHeaders(rawOrObject) : rawOrObject || {}; const data = normalizeHeaderCandidate(rawOrObject || {});
const next = {}; 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.reqLang) next["req-lang"] = data.reqLang;
if (data.appVersion || data.buildVersion || data.channel) { if (data.appVersion || data.buildVersion || data.channel) {
next["req-app-intel"] = [ next["req-app-intel"] = [
@ -258,7 +343,6 @@ function requestAccessOrigin() {
if (!isAppEnvironment()) { if (!isAppEnvironment()) {
setHeadersFromApp({ setHeadersFromApp({
authorization: "",
reqLang: lang, reqLang: lang,
appVersion: "1.0.0", appVersion: "1.0.0",
buildVersion: "1", buildVersion: "1",
@ -305,10 +389,12 @@ function requestAccessOrigin() {
export async function connectToApp() { export async function connectToApp() {
if (!appConnectionPromise) { if (!appConnectionPromise) {
applyDiscoveredHeaders();
appConnectionPromise = requestAccessOrigin() appConnectionPromise = requestAccessOrigin()
.then((raw) => { .then((raw) => {
if (raw) setHeadersFromApp(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(() => { .finally(() => {
appConnectionPromise = null; appConnectionPromise = null;
@ -319,7 +405,8 @@ export async function connectToApp() {
} }
export async function request(method, path, body) { 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); if (body !== undefined) options.body = JSON.stringify(body);
const response = await fetch(`${API_BASE_URL}${path}`, options); const response = await fetch(`${API_BASE_URL}${path}`, options);
const data = await response.json().catch(() => ({})); 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 = { const config = {
title: "invite_become_BD", title: "invite_become_BD",
@ -10,6 +10,8 @@ const config = {
let invited = []; let invited = [];
let searchResult = []; let searchResult = [];
let selected = null; let selected = null;
let locked = false;
let appConnected = false;
bindHeader(config.title); bindHeader(config.title);
applyLang(); applyLang();
@ -19,6 +21,11 @@ input.placeholder = t("enter_user_id");
input.addEventListener("input", () => { input.addEventListener("input", () => {
selected = null; selected = null;
clearButton.hidden = !input.value; clearButton.hidden = !input.value;
if (!input.value.trim()) {
searchResult = [];
loadInvited();
return;
}
render(); render();
}); });
input.addEventListener("keyup", (event) => { input.addEventListener("keyup", (event) => {
@ -30,11 +37,22 @@ clearButton.addEventListener("click", () => {
searchResult = []; searchResult = [];
selected = null; selected = null;
clearButton.hidden = true; 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() { async function loadInvited() {
if (!appConnected) return;
try { try {
const response = await get(config.list); const response = await get(config.list);
invited = response.body || []; invited = response.body || [];
@ -45,6 +63,7 @@ async function loadInvited() {
} }
async function search() { async function search() {
if (locked || !appConnected) return;
const account = input.value.trim(); const account = input.value.trim();
selected = null; selected = null;
searchResult = []; searchResult = [];
@ -52,11 +71,15 @@ async function search() {
await loadInvited(); await loadInvited();
return; return;
} }
locked = true;
render();
try { try {
const response = await get(`/user/user-profile/open-search?account=${encodeURIComponent(account)}`); const response = await get(`/user/user-profile/open-search?account=${encodeURIComponent(account)}`);
if (response.status && response.body) searchResult = [{ userProfile: response.body }]; if (response.status && response.body) searchResult = [{ userProfile: response.body }];
} catch (error) { } catch (error) {
toast(error.response?.errorMsg || error.message); toast(error.response?.errorMsg || error.message);
} finally {
locked = false;
} }
render(); render();
} }
@ -102,7 +125,7 @@ function render() {
} }
async function invite() { async function invite() {
if (!selected) return; if (!selected || !appConnected) return;
try { try {
await post(config.invite, { inviteUserId: selected.id }); await post(config.invite, { inviteUserId: selected.id });
toast(t("invitation_submitted")); toast(t("invitation_submitted"));
@ -116,6 +139,7 @@ async function invite() {
} }
async function cancelInvite(id) { async function cancelInvite(id) {
if (!appConnected) return;
try { try {
await post(config.cancel(id)); await post(config.cancel(id));
toast(t("application_cancelled")); toast(t("application_cancelled"));