feat: handle redirectTo query parameter in middleware

This commit is contained in:
Ephraim Atta-Duncan
2025-05-21 11:31:00 +00:00
parent 44bc769e60
commit d213b378b8
2 changed files with 32 additions and 4 deletions

View File

@ -1,6 +1,7 @@
import { Trans } from '@lingui/react/macro';
import { Link, redirect } from 'react-router';
import { extractCookieFromHeaders } from '@documenso/auth/server/lib/utils/cookies';
import { getOptionalSession } from '@documenso/auth/server/lib/utils/get-session';
import {
IS_GOOGLE_SSO_ENABLED,
@ -20,13 +21,18 @@ export function meta() {
export async function loader({ request }: Route.LoaderArgs) {
const { isAuthenticated } = await getOptionalSession(request);
const redirectToCookie = extractCookieFromHeaders('redirectTo', request.headers);
const redirectToAfterLogin = redirectToCookie ? decodeURIComponent(redirectToCookie) : '';
// SSR env variables.
const isGoogleSSOEnabled = IS_GOOGLE_SSO_ENABLED;
const isOIDCSSOEnabled = IS_OIDC_SSO_ENABLED;
const oidcProviderLabel = OIDC_PROVIDER_LABEL;
if (isAuthenticated) {
if (redirectToAfterLogin) {
throw redirect(redirectToAfterLogin);
}
throw redirect('/documents');
}
@ -34,11 +40,13 @@ export async function loader({ request }: Route.LoaderArgs) {
isGoogleSSOEnabled,
isOIDCSSOEnabled,
oidcProviderLabel,
redirectToAfterLogin,
};
}
export default function SignIn({ loaderData }: Route.ComponentProps) {
const { isGoogleSSOEnabled, isOIDCSSOEnabled, oidcProviderLabel } = loaderData;
const { isGoogleSSOEnabled, isOIDCSSOEnabled, oidcProviderLabel, redirectToAfterLogin } =
loaderData;
return (
<div className="w-screen max-w-lg px-4">
@ -56,6 +64,7 @@ export default function SignIn({ loaderData }: Route.ComponentProps) {
isGoogleSSOEnabled={isGoogleSSOEnabled}
isOIDCSSOEnabled={isOIDCSSOEnabled}
oidcProviderLabel={oidcProviderLabel}
returnTo={redirectToAfterLogin ?? undefined}
/>
{env('NEXT_PUBLIC_DISABLE_SIGNUP') !== 'true' && (

View File

@ -18,13 +18,32 @@ export const appMiddleware = async (c: Context, next: Next) => {
const { req } = c;
const { path } = req;
// PRE-HANDLER CODE: Place code here to execute BEFORE the route handler runs.
const redirectTo = req.query('redirectTo');
if (redirectTo) {
if (redirectTo.startsWith('/') && !redirectTo.startsWith('//') && !redirectTo.includes('..')) {
debug.log('Setting redirectTo cookie to:', redirectTo);
setCookie(c, 'redirectTo', redirectTo, {
path: '/',
httpOnly: true,
sameSite: 'Lax',
maxAge: 150,
// secure: process.env.NODE_ENV === 'production'
});
debug.log('Redirecting to (from param):', redirectTo);
return c.redirect(redirectTo, 307);
} else {
debug.log('Invalid redirectTo parameter encountered:', redirectTo);
}
}
// Paths to ignore.
if (nonPagePathRegex.test(path)) {
return next();
}
// PRE-HANDLER CODE: Place code here to execute BEFORE the route handler runs.
await next();
// POST-HANDLER CODE: Place code here to execute AFTER the route handler completes.