fix(iframe): validate trusted parent messages
This commit is contained in:
@@ -5,9 +5,10 @@ import { useEffect, useCallback, type ReactNode } from "react";
|
||||
import { usePlayerSessionStore } from "@/stores/player-session-store";
|
||||
import { setPlayerBearerToken } from "@/lib/lottery-auth";
|
||||
import {
|
||||
isIframeOriginAllowed,
|
||||
loadIframeAllowedOrigins,
|
||||
messageToken,
|
||||
resolvePostMessageTargetOrigin,
|
||||
resolveTrustedParentMessage,
|
||||
} from "@/lib/iframe-origins";
|
||||
|
||||
function sanitizeUrlForParent(href: string): string {
|
||||
@@ -123,39 +124,38 @@ export function IframeBridge({ children }: { children: ReactNode }): ReactNode {
|
||||
console.log("[IframeBridge] Setting up iframe communication");
|
||||
|
||||
const handleMessage = async (event: MessageEvent): Promise<void> => {
|
||||
if (!isIframeOriginAllowed(event.origin)) {
|
||||
await loadIframeAllowedOrigins(true);
|
||||
if (!isIframeOriginAllowed(event.origin)) {
|
||||
console.warn("[IframeBridge] Rejected message from:", event.origin);
|
||||
return;
|
||||
}
|
||||
const data = await resolveTrustedParentMessage(event);
|
||||
if (data === null) {
|
||||
console.warn("[IframeBridge] Rejected untrusted parent message from:", event.origin);
|
||||
return;
|
||||
}
|
||||
|
||||
const { data } = event;
|
||||
if (!data || typeof data !== "object") return;
|
||||
|
||||
console.log("[IframeBridge] Received message:", data.type);
|
||||
|
||||
switch (data.type) {
|
||||
// 主站发送初始化 Token
|
||||
case "MAIN_INIT_TOKEN":
|
||||
if (data.token) {
|
||||
case "MAIN_INIT_TOKEN": {
|
||||
const token = messageToken(data);
|
||||
if (token !== null) {
|
||||
console.log("[IframeBridge] Received initial token");
|
||||
setBearerToken(data.token);
|
||||
setPlayerBearerToken(data.token);
|
||||
setBearerToken(token);
|
||||
setPlayerBearerToken(token);
|
||||
// 勿再 notifyReady(),否则主站会重复 MAIN_INIT_TOKEN 导致消息刷屏
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// 主站刷新 Token
|
||||
case "MAIN_REFRESH_TOKEN":
|
||||
if (data.token) {
|
||||
case "MAIN_REFRESH_TOKEN": {
|
||||
const token = messageToken(data);
|
||||
if (token !== null) {
|
||||
console.log("[IframeBridge] Received refreshed token");
|
||||
setBearerToken(data.token);
|
||||
setPlayerBearerToken(data.token);
|
||||
setBearerToken(token);
|
||||
setPlayerBearerToken(token);
|
||||
notifyTokenRefreshed();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// 主站通知 Token 即将过期
|
||||
case "MAIN_TOKEN_EXPIRING":
|
||||
@@ -173,7 +173,7 @@ export function IframeBridge({ children }: { children: ReactNode }): ReactNode {
|
||||
|
||||
// 主站导航请求
|
||||
case "MAIN_NAVIGATE":
|
||||
if (data.path && typeof data.path === "string") {
|
||||
if (typeof data.path === "string") {
|
||||
const nextPath = resolveSafeInAppPath(data.path);
|
||||
if (nextPath) {
|
||||
window.history.pushState({}, "", nextPath);
|
||||
|
||||
Reference in New Issue
Block a user