Spaces:
Running
Running
Revert "Try Partitioned cookies for OAuth in iframe (SameSite=None + Partitioned)"
Browse filesThis reverts commit 5fa6d003cad54765dbb457c42842aa5fb11c086d.
backend/routes/auth.py
CHANGED
|
@@ -130,35 +130,19 @@ async def oauth_callback(
|
|
| 130 |
except httpx.HTTPError:
|
| 131 |
pass # user_info not required for auth flow
|
| 132 |
|
| 133 |
-
# Set access token as HttpOnly cookie
|
| 134 |
-
#
|
| 135 |
-
# so the cookie works inside the HF iframe (cross-site context).
|
| 136 |
is_production = bool(os.environ.get("SPACE_HOST"))
|
| 137 |
response = RedirectResponse(url="/", status_code=302)
|
| 138 |
-
|
| 139 |
-
|
| 140 |
-
|
| 141 |
-
|
| 142 |
-
|
| 143 |
-
|
| 144 |
-
|
| 145 |
-
|
| 146 |
-
|
| 147 |
-
f"Max-Age={max_age}"
|
| 148 |
-
)
|
| 149 |
-
response.headers.append("Set-Cookie", cookie_value)
|
| 150 |
-
else:
|
| 151 |
-
# Dev mode β simple cookie, no Secure/Partitioned needed
|
| 152 |
-
response.set_cookie(
|
| 153 |
-
key="hf_access_token",
|
| 154 |
-
value=access_token,
|
| 155 |
-
httponly=True,
|
| 156 |
-
secure=False,
|
| 157 |
-
samesite="lax",
|
| 158 |
-
max_age=3600 * 24,
|
| 159 |
-
path="/",
|
| 160 |
-
)
|
| 161 |
-
|
| 162 |
return response
|
| 163 |
|
| 164 |
|
|
|
|
| 130 |
except httpx.HTTPError:
|
| 131 |
pass # user_info not required for auth flow
|
| 132 |
|
| 133 |
+
# Set access token as HttpOnly cookie (not in URL β avoids leaks via
|
| 134 |
+
# Referrer headers, browser history, and server logs)
|
|
|
|
| 135 |
is_production = bool(os.environ.get("SPACE_HOST"))
|
| 136 |
response = RedirectResponse(url="/", status_code=302)
|
| 137 |
+
response.set_cookie(
|
| 138 |
+
key="hf_access_token",
|
| 139 |
+
value=access_token,
|
| 140 |
+
httponly=True,
|
| 141 |
+
secure=is_production, # Secure flag only in production (HTTPS)
|
| 142 |
+
samesite="lax",
|
| 143 |
+
max_age=3600 * 24, # 24 hours
|
| 144 |
+
path="/",
|
| 145 |
+
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 146 |
return response
|
| 147 |
|
| 148 |
|
frontend/src/components/WelcomeScreen/WelcomeScreen.tsx
CHANGED
|
@@ -6,10 +6,11 @@ import {
|
|
| 6 |
CircularProgress,
|
| 7 |
Alert,
|
| 8 |
} from '@mui/material';
|
|
|
|
| 9 |
import { useSessionStore } from '@/store/sessionStore';
|
| 10 |
import { useAgentStore } from '@/store/agentStore';
|
| 11 |
import { apiFetch } from '@/utils/api';
|
| 12 |
-
import { triggerLogin } from '@/hooks/useAuth';
|
| 13 |
|
| 14 |
/** HF brand orange */
|
| 15 |
const HF_ORANGE = '#FF9D00';
|
|
@@ -20,6 +21,7 @@ export default function WelcomeScreen() {
|
|
| 20 |
const [isCreating, setIsCreating] = useState(false);
|
| 21 |
const [error, setError] = useState<string | null>(null);
|
| 22 |
|
|
|
|
| 23 |
const isAuthenticated = user?.authenticated;
|
| 24 |
const isDevUser = user?.username === 'dev';
|
| 25 |
|
|
@@ -28,6 +30,10 @@ export default function WelcomeScreen() {
|
|
| 28 |
|
| 29 |
// Not authenticated and not dev β need to login
|
| 30 |
if (!isAuthenticated && !isDevUser) {
|
|
|
|
|
|
|
|
|
|
|
|
|
| 31 |
triggerLogin();
|
| 32 |
return;
|
| 33 |
}
|
|
@@ -59,7 +65,14 @@ export default function WelcomeScreen() {
|
|
| 59 |
} finally {
|
| 60 |
setIsCreating(false);
|
| 61 |
}
|
| 62 |
-
}, [isCreating, createSession, setPlan, setPanelContent, isAuthenticated, isDevUser]);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 63 |
|
| 64 |
return (
|
| 65 |
<Box
|
|
@@ -116,9 +129,38 @@ export default function WelcomeScreen() {
|
|
| 116 |
and explores <strong>datasets</strong> β all through natural conversation.
|
| 117 |
</Typography>
|
| 118 |
|
| 119 |
-
{/* Action button */}
|
| 120 |
-
{!isAuthenticated && !isDevUser ? (
|
| 121 |
-
//
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 122 |
<Button
|
| 123 |
variant="contained"
|
| 124 |
size="large"
|
|
|
|
| 6 |
CircularProgress,
|
| 7 |
Alert,
|
| 8 |
} from '@mui/material';
|
| 9 |
+
import OpenInNewIcon from '@mui/icons-material/OpenInNew';
|
| 10 |
import { useSessionStore } from '@/store/sessionStore';
|
| 11 |
import { useAgentStore } from '@/store/agentStore';
|
| 12 |
import { apiFetch } from '@/utils/api';
|
| 13 |
+
import { isInIframe, triggerLogin } from '@/hooks/useAuth';
|
| 14 |
|
| 15 |
/** HF brand orange */
|
| 16 |
const HF_ORANGE = '#FF9D00';
|
|
|
|
| 21 |
const [isCreating, setIsCreating] = useState(false);
|
| 22 |
const [error, setError] = useState<string | null>(null);
|
| 23 |
|
| 24 |
+
const inIframe = isInIframe();
|
| 25 |
const isAuthenticated = user?.authenticated;
|
| 26 |
const isDevUser = user?.username === 'dev';
|
| 27 |
|
|
|
|
| 30 |
|
| 31 |
// Not authenticated and not dev β need to login
|
| 32 |
if (!isAuthenticated && !isDevUser) {
|
| 33 |
+
// In iframe: can't redirect (cookies blocked) β user needs to open in new tab
|
| 34 |
+
// This shouldn't happen because we show a different button in iframe
|
| 35 |
+
// But just in case:
|
| 36 |
+
if (inIframe) return;
|
| 37 |
triggerLogin();
|
| 38 |
return;
|
| 39 |
}
|
|
|
|
| 65 |
} finally {
|
| 66 |
setIsCreating(false);
|
| 67 |
}
|
| 68 |
+
}, [isCreating, createSession, setPlan, setPanelContent, isAuthenticated, isDevUser, inIframe]);
|
| 69 |
+
|
| 70 |
+
// Build the direct Space URL for the "open in new tab" link
|
| 71 |
+
const spaceHost = typeof window !== 'undefined'
|
| 72 |
+
? window.location.hostname.includes('.hf.space')
|
| 73 |
+
? window.location.origin
|
| 74 |
+
: `https://smolagents-ml-agent.hf.space`
|
| 75 |
+
: '';
|
| 76 |
|
| 77 |
return (
|
| 78 |
<Box
|
|
|
|
| 129 |
and explores <strong>datasets</strong> β all through natural conversation.
|
| 130 |
</Typography>
|
| 131 |
|
| 132 |
+
{/* Action button β depends on context */}
|
| 133 |
+
{inIframe && !isAuthenticated && !isDevUser ? (
|
| 134 |
+
// In iframe + not logged in β link to open Space directly
|
| 135 |
+
<Button
|
| 136 |
+
variant="contained"
|
| 137 |
+
size="large"
|
| 138 |
+
component="a"
|
| 139 |
+
href={spaceHost}
|
| 140 |
+
target="_blank"
|
| 141 |
+
rel="noopener noreferrer"
|
| 142 |
+
endIcon={<OpenInNewIcon />}
|
| 143 |
+
sx={{
|
| 144 |
+
px: 5,
|
| 145 |
+
py: 1.5,
|
| 146 |
+
fontSize: '1rem',
|
| 147 |
+
fontWeight: 700,
|
| 148 |
+
textTransform: 'none',
|
| 149 |
+
borderRadius: '12px',
|
| 150 |
+
bgcolor: HF_ORANGE,
|
| 151 |
+
color: '#000',
|
| 152 |
+
boxShadow: '0 4px 24px rgba(255, 157, 0, 0.3)',
|
| 153 |
+
textDecoration: 'none',
|
| 154 |
+
'&:hover': {
|
| 155 |
+
bgcolor: '#FFB340',
|
| 156 |
+
boxShadow: '0 6px 32px rgba(255, 157, 0, 0.45)',
|
| 157 |
+
},
|
| 158 |
+
}}
|
| 159 |
+
>
|
| 160 |
+
Open ML Agent
|
| 161 |
+
</Button>
|
| 162 |
+
) : !isAuthenticated && !isDevUser ? (
|
| 163 |
+
// Direct access + not logged in β sign in button
|
| 164 |
<Button
|
| 165 |
variant="contained"
|
| 166 |
size="large"
|