fix mini app bot father
This commit is contained in:
@@ -2,8 +2,10 @@
|
||||
|
||||
import { useEffect, useState } from 'react';
|
||||
import { AUTH_REFRESH_KEY, AUTH_SESSION_KEY, AUTH_TOKEN_KEY } from '@/lib/api';
|
||||
import { resolveMiniAppTargetOrigin } from '@/lib/mini-app-url';
|
||||
|
||||
export const EMBEDDED_AUTH_MESSAGE = 'lendry-id-embedded-auth';
|
||||
export const EMBEDDED_AUTH_REQUEST = 'lendry-id-embedded-auth-request';
|
||||
|
||||
export interface EmbeddedAuthPayload {
|
||||
type: typeof EMBEDDED_AUTH_MESSAGE;
|
||||
@@ -12,16 +14,57 @@ export interface EmbeddedAuthPayload {
|
||||
sessionId?: string;
|
||||
}
|
||||
|
||||
export function postEmbeddedAuthToIframe(iframe: HTMLIFrameElement, auth: { token: string; refreshToken?: string | null; sessionId?: string | null }) {
|
||||
function collectTrustedOrigins() {
|
||||
const origins = new Set<string>();
|
||||
if (typeof window === 'undefined') return origins;
|
||||
|
||||
origins.add(window.location.origin);
|
||||
if (document.referrer) {
|
||||
try {
|
||||
origins.add(new URL(document.referrer).origin);
|
||||
} catch {
|
||||
// ignore malformed referrer
|
||||
}
|
||||
}
|
||||
return origins;
|
||||
}
|
||||
|
||||
function resolveParentPostMessageTarget() {
|
||||
if (typeof window === 'undefined' || window.parent === window) {
|
||||
return window.location.origin;
|
||||
}
|
||||
|
||||
if (document.referrer) {
|
||||
try {
|
||||
const referrerOrigin = new URL(document.referrer).origin;
|
||||
if (referrerOrigin !== window.location.origin) {
|
||||
return '*';
|
||||
}
|
||||
return referrerOrigin;
|
||||
} catch {
|
||||
return '*';
|
||||
}
|
||||
}
|
||||
|
||||
return '*';
|
||||
}
|
||||
|
||||
export function postEmbeddedAuthToIframe(
|
||||
iframe: HTMLIFrameElement,
|
||||
auth: { token: string; refreshToken?: string | null; sessionId?: string | null }
|
||||
) {
|
||||
const target = iframe.contentWindow;
|
||||
if (!target || !auth.token) return;
|
||||
|
||||
const payload: EmbeddedAuthPayload = {
|
||||
type: EMBEDDED_AUTH_MESSAGE,
|
||||
token: auth.token,
|
||||
refreshToken: auth.refreshToken ?? undefined,
|
||||
sessionId: auth.sessionId ?? undefined
|
||||
};
|
||||
target.postMessage(payload, window.location.origin);
|
||||
|
||||
const targetOrigin = resolveMiniAppTargetOrigin(iframe.getAttribute('src') || iframe.src, window.location.origin);
|
||||
target.postMessage(payload, targetOrigin);
|
||||
}
|
||||
|
||||
export function useEmbeddedAuthFallback() {
|
||||
@@ -29,7 +72,7 @@ export function useEmbeddedAuthFallback() {
|
||||
|
||||
useEffect(() => {
|
||||
function handleMessage(event: MessageEvent) {
|
||||
if (event.origin !== window.location.origin) return;
|
||||
if (!collectTrustedOrigins().has(event.origin)) return;
|
||||
const data = event.data as Partial<EmbeddedAuthPayload> | null;
|
||||
if (!data || data.type !== EMBEDDED_AUTH_MESSAGE || !data.token?.trim()) return;
|
||||
|
||||
@@ -42,11 +85,12 @@ export function useEmbeddedAuthFallback() {
|
||||
if (data.sessionId) {
|
||||
window.localStorage.setItem(AUTH_SESSION_KEY, data.sessionId);
|
||||
}
|
||||
window.dispatchEvent(new CustomEvent(EMBEDDED_AUTH_MESSAGE, { detail: data }));
|
||||
}
|
||||
|
||||
window.addEventListener('message', handleMessage);
|
||||
if (window.parent !== window) {
|
||||
window.parent.postMessage({ type: 'lendry-id-embedded-auth-request' }, window.location.origin);
|
||||
window.parent.postMessage({ type: EMBEDDED_AUTH_REQUEST }, resolveParentPostMessageTarget());
|
||||
}
|
||||
return () => window.removeEventListener('message', handleMessage);
|
||||
}, []);
|
||||
|
||||
22
apps/frontend/lib/mini-app-url.ts
Normal file
22
apps/frontend/lib/mini-app-url.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
export function normalizeMiniAppUrl(url: string) {
|
||||
if (typeof window === 'undefined') return url;
|
||||
|
||||
try {
|
||||
const parsed = new URL(url, window.location.href);
|
||||
if (parsed.pathname.startsWith('/mini-apps/')) {
|
||||
return `${window.location.origin}${parsed.pathname}${parsed.search}${parsed.hash}`;
|
||||
}
|
||||
return parsed.toString();
|
||||
} catch {
|
||||
return url;
|
||||
}
|
||||
}
|
||||
|
||||
export function resolveMiniAppTargetOrigin(iframeSrc: string | null | undefined, fallback: string) {
|
||||
if (!iframeSrc) return fallback;
|
||||
try {
|
||||
return new URL(iframeSrc, fallback).origin;
|
||||
} catch {
|
||||
return fallback;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user