mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-02-04 09:13:08 +00:00
fix: sandbox warning persistence and add env var option
Fix race condition where sandbox warning appeared on every refresh even after checking "Do not show again". The issue was that the sandbox check effect ran before settings were hydrated from the server, so skipSandboxWarning was always false (the default). Changes: - Add settingsLoaded to sandbox check dependencies to ensure the user's preference is loaded before checking - Add AUTOMAKER_SKIP_SANDBOX_WARNING env var option to skip the warning entirely (useful for dev/CI environments)
This commit is contained in:
@@ -9,12 +9,14 @@ import type { Request, Response } from 'express';
|
|||||||
|
|
||||||
export interface EnvironmentResponse {
|
export interface EnvironmentResponse {
|
||||||
isContainerized: boolean;
|
isContainerized: boolean;
|
||||||
|
skipSandboxWarning?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createEnvironmentHandler() {
|
export function createEnvironmentHandler() {
|
||||||
return (_req: Request, res: Response): void => {
|
return (_req: Request, res: Response): void => {
|
||||||
res.json({
|
res.json({
|
||||||
isContainerized: process.env.IS_CONTAINERIZED === 'true',
|
isContainerized: process.env.IS_CONTAINERIZED === 'true',
|
||||||
|
skipSandboxWarning: process.env.AUTOMAKER_SKIP_SANDBOX_WARNING === 'true',
|
||||||
} satisfies EnvironmentResponse);
|
} satisfies EnvironmentResponse);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -483,6 +483,7 @@ export const verifySession = async (): Promise<boolean> => {
|
|||||||
*/
|
*/
|
||||||
export const checkSandboxEnvironment = async (): Promise<{
|
export const checkSandboxEnvironment = async (): Promise<{
|
||||||
isContainerized: boolean;
|
isContainerized: boolean;
|
||||||
|
skipSandboxWarning?: boolean;
|
||||||
error?: string;
|
error?: string;
|
||||||
}> => {
|
}> => {
|
||||||
try {
|
try {
|
||||||
@@ -498,7 +499,10 @@ export const checkSandboxEnvironment = async (): Promise<{
|
|||||||
}
|
}
|
||||||
|
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
return { isContainerized: data.isContainerized ?? false };
|
return {
|
||||||
|
isContainerized: data.isContainerized ?? false,
|
||||||
|
skipSandboxWarning: data.skipSandboxWarning ?? false,
|
||||||
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error('Sandbox environment check failed:', error);
|
logger.error('Sandbox environment check failed:', error);
|
||||||
return { isContainerized: false, error: 'Network error' };
|
return { isContainerized: false, error: 'Network error' };
|
||||||
|
|||||||
@@ -252,15 +252,16 @@ function RootLayoutContent() {
|
|||||||
setIsMounted(true);
|
setIsMounted(true);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
// Check sandbox environment only after user is authenticated and setup is complete
|
// Check sandbox environment only after user is authenticated, setup is complete, and settings are loaded
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// Skip if already decided
|
// Skip if already decided
|
||||||
if (sandboxStatus !== 'pending') {
|
if (sandboxStatus !== 'pending') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't check sandbox until user is authenticated and has completed setup
|
// Don't check sandbox until user is authenticated, has completed setup, and settings are loaded
|
||||||
if (!authChecked || !isAuthenticated || !setupComplete) {
|
// CRITICAL: settingsLoaded must be true to ensure skipSandboxWarning has been hydrated from server
|
||||||
|
if (!authChecked || !isAuthenticated || !setupComplete || !settingsLoaded) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -271,8 +272,8 @@ function RootLayoutContent() {
|
|||||||
if (result.isContainerized) {
|
if (result.isContainerized) {
|
||||||
// Running in a container, no warning needed
|
// Running in a container, no warning needed
|
||||||
setSandboxStatus('containerized');
|
setSandboxStatus('containerized');
|
||||||
} else if (skipSandboxWarning) {
|
} else if (result.skipSandboxWarning || skipSandboxWarning) {
|
||||||
// User opted to skip the warning, auto-confirm
|
// Skip if env var is set OR if user preference is set
|
||||||
setSandboxStatus('confirmed');
|
setSandboxStatus('confirmed');
|
||||||
} else {
|
} else {
|
||||||
// Not containerized, show warning dialog
|
// Not containerized, show warning dialog
|
||||||
@@ -290,7 +291,14 @@ function RootLayoutContent() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
checkSandbox();
|
checkSandbox();
|
||||||
}, [sandboxStatus, skipSandboxWarning, authChecked, isAuthenticated, setupComplete]);
|
}, [
|
||||||
|
sandboxStatus,
|
||||||
|
skipSandboxWarning,
|
||||||
|
authChecked,
|
||||||
|
isAuthenticated,
|
||||||
|
setupComplete,
|
||||||
|
settingsLoaded,
|
||||||
|
]);
|
||||||
|
|
||||||
// Handle sandbox risk confirmation
|
// Handle sandbox risk confirmation
|
||||||
const handleSandboxConfirm = useCallback(
|
const handleSandboxConfirm = useCallback(
|
||||||
|
|||||||
Reference in New Issue
Block a user