Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 16 additions & 2 deletions packages/twenty-front/src/pages/auth/SignInUp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,23 @@ export const SignInUp = () => {
// served separately from the backend. In the unified-image setup
// both share an origin and the absolute URL collapses to the same
// path; in split-deploy mode it correctly hits the API.
window.location.replace(
`${REACT_APP_SERVER_BASE_URL}/auth/sso/proxy-login`,
//
// Thread returnToPath so the server can redirect back after setting
// the JWT cookie -- without this, navigating to /authorize (MCP
// OAuth consent) would land the user on the dashboard instead of
// returning to the consent screen after SSO.
const returnToPath =
window.location.pathname + window.location.search + window.location.hash;
const proxyUrl = new URL(
'/auth/sso/proxy-login',
REACT_APP_SERVER_BASE_URL || window.location.origin,
);

if (returnToPath && returnToPath !== '/') {
proxyUrl.searchParams.set('returnToPath', returnToPath);
}

window.location.replace(proxyUrl.toString());
}
}, [isSsoEnabled]);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,17 @@ export class SsoProxyLoginController {
},
});

return res.redirect(HttpStatus.FOUND, '/');
// Honour returnToPath so callers like the MCP OAuth /authorize page
// can survive the SSO round-trip. Validate that the value is a
// same-origin path (starts with exactly one `/`) to prevent open
// redirect attacks via protocol-relative URLs (`//evil.com`).
const returnToPath = req.query.returnToPath as string | undefined;
const destination =
returnToPath?.startsWith('/') && !returnToPath.startsWith('//')
? returnToPath
: '/';

return res.redirect(HttpStatus.FOUND, destination);
}

private resolveEmail(
Expand Down
Loading