修复小程序内充值设备识别
为 API 请求和刷新请求补充宿主运行时请求头。 在小程序充值设备身份异常时清理旧 token 并重新拉起小程序登录。 补充小程序充值回归测试并隔离测试 spy。
This commit is contained in:
@@ -8,12 +8,17 @@ import {
|
||||
parseApiErrorMessage,
|
||||
unwrapApiResponse,
|
||||
} from '../../packages/shared/src/http';
|
||||
import { getHostRuntime } from './host-bridge/hostBridge';
|
||||
|
||||
const ACCESS_TOKEN_KEY = 'genarrative.auth.access-token.v1';
|
||||
export const AUTH_STATE_EVENT = 'genarrative-auth-state-changed';
|
||||
const REQUEST_ID_HEADER = 'x-request-id';
|
||||
const API_VERSION_HEADER = 'x-api-version';
|
||||
const ROUTE_VERSION_HEADER = 'x-route-version';
|
||||
const CLIENT_TYPE_HEADER = 'x-client-type';
|
||||
const CLIENT_RUNTIME_HEADER = 'x-client-runtime';
|
||||
const CLIENT_PLATFORM_HEADER = 'x-client-platform';
|
||||
const MINI_PROGRAM_ENV_HEADER = 'x-mini-program-env';
|
||||
const DEFAULT_RETRYABLE_STATUS_CODES = [408, 425, 429, 502, 503, 504];
|
||||
const DEFAULT_SAFE_RETRY_METHODS = new Set(['GET', 'HEAD', 'OPTIONS']);
|
||||
|
||||
@@ -101,6 +106,57 @@ function normalizeHeaders(headers?: HeadersInit) {
|
||||
return nextHeaders;
|
||||
}
|
||||
|
||||
function hasHeader(headers: Record<string, string>, name: string) {
|
||||
const normalizedName = name.toLowerCase();
|
||||
return Object.keys(headers).some((key) => key.toLowerCase() === normalizedName);
|
||||
}
|
||||
|
||||
function setHeaderIfMissing(
|
||||
headers: Record<string, string>,
|
||||
name: string,
|
||||
value: string | null | undefined,
|
||||
) {
|
||||
const trimmedValue = value?.trim();
|
||||
if (!trimmedValue || hasHeader(headers, name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
headers[name] = trimmedValue;
|
||||
}
|
||||
|
||||
function attachHostRuntimeHeaders(headers: Record<string, string>) {
|
||||
let runtime: ReturnType<typeof getHostRuntime>;
|
||||
try {
|
||||
runtime = getHostRuntime();
|
||||
} catch {
|
||||
return headers;
|
||||
}
|
||||
|
||||
if (runtime.kind === 'wechat_mini_program') {
|
||||
setHeaderIfMissing(headers, CLIENT_TYPE_HEADER, 'mini_program');
|
||||
setHeaderIfMissing(
|
||||
headers,
|
||||
CLIENT_RUNTIME_HEADER,
|
||||
runtime.clientRuntime || 'wechat_mini_program',
|
||||
);
|
||||
setHeaderIfMissing(headers, CLIENT_PLATFORM_HEADER, runtime.hostPlatform);
|
||||
setHeaderIfMissing(headers, MINI_PROGRAM_ENV_HEADER, runtime.miniProgramEnv);
|
||||
return headers;
|
||||
}
|
||||
|
||||
if (runtime.kind === 'native_app') {
|
||||
setHeaderIfMissing(headers, CLIENT_TYPE_HEADER, 'native_app');
|
||||
setHeaderIfMissing(
|
||||
headers,
|
||||
CLIENT_RUNTIME_HEADER,
|
||||
runtime.clientRuntime || 'native_app',
|
||||
);
|
||||
setHeaderIfMissing(headers, CLIENT_PLATFORM_HEADER, runtime.hostPlatform);
|
||||
}
|
||||
|
||||
return headers;
|
||||
}
|
||||
|
||||
function buildClientRequestId() {
|
||||
const randomId =
|
||||
typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function'
|
||||
@@ -502,7 +558,7 @@ function withAuthorizationHeaders(
|
||||
headers?: HeadersInit,
|
||||
options: Pick<ApiRequestOptions, 'omitEnvelopeHeader' | 'skipAuth'> = {},
|
||||
) {
|
||||
const nextHeaders = normalizeHeaders(headers);
|
||||
const nextHeaders = attachHostRuntimeHeaders(normalizeHeaders(headers));
|
||||
const token = getStoredAccessToken();
|
||||
if (token && !options.skipAuth) {
|
||||
nextHeaders.Authorization = `Bearer ${token}`;
|
||||
@@ -531,9 +587,9 @@ async function refreshAccessToken() {
|
||||
const response = await fetch('/api/auth/refresh', {
|
||||
method: 'POST',
|
||||
credentials: 'same-origin',
|
||||
headers: {
|
||||
headers: attachHostRuntimeHeaders({
|
||||
[API_RESPONSE_ENVELOPE_HEADER]: API_RESPONSE_ENVELOPE_VERSION,
|
||||
},
|
||||
}),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
|
||||
Reference in New Issue
Block a user