feat: enhance iframe communication and caching mechanisms
Some checks failed
lotteryfront CI / build (push) Has been cancelled
Some checks failed
lotteryfront CI / build (push) Has been cancelled
- Improved the entry lifecycle management to prevent duplicate token requests and ensure smooth transitions. - Updated the `resolvePostMessageTargetOrigin` function to return null when no allowed origins are present, enhancing security. - Cached runtime origins to optimize performance and reduce unnecessary API calls. - Added a new error message for frozen lottery wallets in the player notifications.
This commit is contained in:
@@ -28,6 +28,9 @@ export function IframeBridge({ children }: { children: ReactNode }): ReactNode {
|
||||
(type: string, payload?: Record<string, unknown>): void => {
|
||||
if (typeof window === "undefined" || window.parent === window) return;
|
||||
|
||||
const targetOrigin = resolvePostMessageTargetOrigin();
|
||||
if (!targetOrigin) return;
|
||||
|
||||
window.parent.postMessage(
|
||||
{
|
||||
type: `LOTTERY_${type}`,
|
||||
@@ -35,7 +38,7 @@ export function IframeBridge({ children }: { children: ReactNode }): ReactNode {
|
||||
timestamp: Date.now(),
|
||||
source: "lottery-iframe",
|
||||
},
|
||||
resolvePostMessageTargetOrigin(),
|
||||
targetOrigin,
|
||||
);
|
||||
},
|
||||
[],
|
||||
|
||||
@@ -87,12 +87,15 @@ export function useTokenRefresh(): {
|
||||
if (typeof window === "undefined") return;
|
||||
|
||||
// 向主站请求新 Token
|
||||
const targetOrigin = resolvePostMessageTargetOrigin();
|
||||
if (!targetOrigin) return;
|
||||
|
||||
window.parent.postMessage(
|
||||
{
|
||||
type: "LOTTERY_TOKEN_REFRESH_REQUEST",
|
||||
timestamp: Date.now(),
|
||||
},
|
||||
resolvePostMessageTargetOrigin(),
|
||||
targetOrigin,
|
||||
);
|
||||
}, []);
|
||||
|
||||
|
||||
@@ -336,6 +336,7 @@
|
||||
"2008": "Odds or play configuration has changed. Close the preview and try again.",
|
||||
"2009": "This order was refunded or cannot be resubmitted. Close the preview and place a new bet.",
|
||||
"1003": "Stake amount is outside the allowed range for this play type.",
|
||||
"1007": "The lottery wallet is frozen. Betting is temporarily unavailable.",
|
||||
"fallback": "Bet failed. Please try again later."
|
||||
},
|
||||
"amountHint": {
|
||||
|
||||
@@ -4,18 +4,19 @@
|
||||
* 支持 iframe 嵌入场景,允许主站加载彩票系统
|
||||
*/
|
||||
|
||||
// 允许的主站来源
|
||||
// 允许的主站来源(生产须通过环境变量配置)
|
||||
const ALLOWED_PARENT_ORIGINS: string[] = [
|
||||
process.env.NEXT_PUBLIC_MAIN_SITE_URL,
|
||||
process.env.NEXT_PUBLIC_PARENT_ORIGIN,
|
||||
// 开发环境
|
||||
"http://localhost:5173",
|
||||
"http://127.0.0.1:5173",
|
||||
"http://192.168.0.101:5173",
|
||||
"http://localhost:3801",
|
||||
"http://127.0.0.1:3801",
|
||||
"http://192.168.0.101:3801",
|
||||
// 生产环境应从环境变量读取
|
||||
...(process.env.NODE_ENV === "development"
|
||||
? [
|
||||
"http://localhost:5173",
|
||||
"http://127.0.0.1:5173",
|
||||
"http://localhost:3801",
|
||||
"http://127.0.0.1:3801",
|
||||
]
|
||||
: []),
|
||||
].filter((o): o is string => Boolean(o));
|
||||
|
||||
function normalizeOrigin(value: string): string | null {
|
||||
@@ -104,10 +105,9 @@ export function generateCSP(extraParentOrigins: string[] = []): string {
|
||||
* @param parentOrigin 父窗口来源
|
||||
*/
|
||||
export function isAllowedParent(parentOrigin: string): boolean {
|
||||
if (ALLOWED_PARENT_ORIGINS.length === 0) return true; // 未配置时允许所有
|
||||
return ALLOWED_PARENT_ORIGINS.some(
|
||||
(origin) => origin && parentOrigin.startsWith(origin),
|
||||
);
|
||||
const origins = staticAllowedParentOrigins();
|
||||
if (origins.length === 0) return false;
|
||||
return origins.some((origin) => parentOrigin.startsWith(origin));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -111,11 +111,11 @@ export function isIframeOriginAllowed(origin: string): boolean {
|
||||
return allowedOrigins.includes(normalized);
|
||||
}
|
||||
|
||||
/** postMessage 目标:优先 referrer 对应白名单,否则取首个白名单 origin */
|
||||
export function resolvePostMessageTargetOrigin(): string {
|
||||
/** postMessage 目标:优先 referrer 对应白名单,否则取首个白名单 origin;无白名单时拒绝发送 */
|
||||
export function resolvePostMessageTargetOrigin(): string | null {
|
||||
const allowedOrigins = getKnownIframeAllowedOrigins();
|
||||
if (allowedOrigins.length === 0) {
|
||||
return "*";
|
||||
return null;
|
||||
}
|
||||
|
||||
if (typeof document !== "undefined" && document.referrer) {
|
||||
|
||||
Reference in New Issue
Block a user