import { InternalSchemaParseError } from '@jolibox/common'; import { reportError } from '../report/errors/report'; interface HeaderJson { ver?: string; channel?: string; subChannel?: string; __mpType?: 'game' | 'miniApp'; } interface PayloadJson { id?: string; testAdsMode?: boolean; // deprecated joliboxEnv?: 'staging' | 'production'; // deprecated sessionId?: string; __mpType?: 'game' | 'miniApp'; __orientation?: 'HORIZONTAL' | 'VERTICAL'; __transparent?: boolean; __entryPath?: string; __showStatusBar?: boolean; __shouldInterupt?: boolean; __from?: number; // 从哪个小程序打开的 __testAdsMode?: boolean; __joliboxEnv?: 'staging' | 'production'; [property: string]: any; } interface Signature { headerSig?: string; payloadSig?: string; } export interface QueryParams { headerJson: HeaderJson; payloadJson: PayloadJson; signature: Signature; } const base64UrlDecode = (input: string): T => { const base64 = input.replace(/-/g, '+').replace(/_/g, '/'); const padding = base64.length % 4 === 0 ? '' : '='.repeat(4 - (base64.length % 4)); const jsonStr = atob(base64 + padding); try { return JSON.parse(jsonStr) as T; } catch (e) { return {} as T; } }; const base64UrlEncode = (input: T): string => { const jsonStr = JSON.stringify(input); const base64 = btoa(jsonStr); return base64.replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, ''); }; export const parseUrlQuery = (url: string): QueryParams => { try { const urlObj = new URL(url); const params = urlObj.searchParams; const joli_source = params.get('joliSource')?.split('.'); if (joli_source?.length) { const [headerJsonStr, payloadJsonStr, signatureJsonStr] = joli_source; return { headerJson: base64UrlDecode(headerJsonStr), payloadJson: base64UrlDecode(payloadJsonStr), signature: base64UrlDecode(signatureJsonStr) }; } else { throw `joli_source is missing`; } } catch (e) { reportError(new InternalSchemaParseError(`${url} not a valid schema: ${e}`)); return { headerJson: {}, payloadJson: {}, signature: {} }; } }; export const encodeJoliSourceQuery = (payloadJson: PayloadJson, originJoliSource: string): string => { const joli_source = originJoliSource.split('.'); if (joli_source && joli_source.length === 3) { const headerJsonStr = joli_source[0]; const payloadJsonStr = base64UrlEncode(payloadJson); const signatureJsonStr = joli_source[2]; return `${headerJsonStr}.${payloadJsonStr}.${signatureJsonStr}`; } return originJoliSource; };