From 6f31c3bdd397b38f54ca94b6a11b8b8511559c63 Mon Sep 17 00:00:00 2001 From: panteliselef Date: Fri, 24 May 2024 17:24:19 +0300 Subject: [PATCH 1/2] feat(remix): Support new redirect urls as environment variables or options to rootAuthLoader As options - signInForceRedirectUrl - signUpForceRedirectUrl - signInFallbackRedirectUrl - signUpFallbackRedirectUrl As environment variables - CLERK_SIGN_IN_FORCE_REDIRECT_URL - CLERK_SIGN_UP_FORCE_REDIRECT_URL - CLERK_SIGN_IN_FALLBACK_REDIRECT_URL - CLERK_SIGN_UP_FALLBACK_REDIRECT_URL --- .changeset/eighty-rabbits-yawn.md | 17 ++++++++++++ .../remix/src/client/RemixClerkProvider.tsx | 8 ++++++ packages/remix/src/client/types.ts | 4 +++ packages/remix/src/ssr/loadOptions.ts | 12 +++++++++ packages/remix/src/ssr/rootAuthLoader.ts | 3 ++- packages/remix/src/ssr/types.ts | 27 +++++++++++++++---- packages/remix/src/ssr/utils.ts | 12 ++++++--- 7 files changed, 73 insertions(+), 10 deletions(-) create mode 100644 .changeset/eighty-rabbits-yawn.md diff --git a/.changeset/eighty-rabbits-yawn.md b/.changeset/eighty-rabbits-yawn.md new file mode 100644 index 00000000000..ddc48ccd8ee --- /dev/null +++ b/.changeset/eighty-rabbits-yawn.md @@ -0,0 +1,17 @@ +--- +'@clerk/remix': minor +--- + +Support new redirect urls as environment variables or options to rootAuthLoader + +As options +- signInForceRedirectUrl +- signUpForceRedirectUrl +- signInFallbackRedirectUrl +- signUpFallbackRedirectUrl + +As environment variables +- CLERK_SIGN_IN_FORCE_REDIRECT_URL +- CLERK_SIGN_UP_FORCE_REDIRECT_URL +- CLERK_SIGN_IN_FALLBACK_REDIRECT_URL +- CLERK_SIGN_UP_FALLBACK_REDIRECT_URL diff --git a/packages/remix/src/client/RemixClerkProvider.tsx b/packages/remix/src/client/RemixClerkProvider.tsx index 6dfdef264d2..521fb2a29c1 100644 --- a/packages/remix/src/client/RemixClerkProvider.tsx +++ b/packages/remix/src/client/RemixClerkProvider.tsx @@ -57,6 +57,10 @@ export function ClerkProvider({ children, ...rest }: ClerkProviderPropsWithState __signUpUrl, __afterSignInUrl, __afterSignUpUrl, + __signInForceRedirectUrl, + __signUpForceRedirectUrl, + __signInFallbackRedirectUrl, + __signUpFallbackRedirectUrl, __clerkJSUrl, __clerkJSVersion, __telemetryDisabled, @@ -80,6 +84,10 @@ export function ClerkProvider({ children, ...rest }: ClerkProviderPropsWithState signUpUrl: __signUpUrl, afterSignInUrl: __afterSignInUrl, afterSignUpUrl: __afterSignUpUrl, + signInForceRedirectUrl: __signInForceRedirectUrl, + signUpForceRedirectUrl: __signUpForceRedirectUrl, + signInFallbackRedirectUrl: __signInFallbackRedirectUrl, + signUpFallbackRedirectUrl: __signUpFallbackRedirectUrl, clerkJSUrl: __clerkJSUrl, clerkJSVersion: __clerkJSVersion, telemetry: { diff --git a/packages/remix/src/client/types.ts b/packages/remix/src/client/types.ts index 7ac8d137ad6..ef4f1ed1770 100644 --- a/packages/remix/src/client/types.ts +++ b/packages/remix/src/client/types.ts @@ -14,6 +14,10 @@ export type ClerkState = { __signUpUrl: string | undefined; __afterSignInUrl: string | undefined; __afterSignUpUrl: string | undefined; + __signInForceRedirectUrl: string | undefined; + __signUpForceRedirectUrl: string | undefined; + __signInFallbackRedirectUrl: string | undefined; + __signUpFallbackRedirectUrl: string | undefined; __clerk_debug: any; __clerkJSUrl: string | undefined; __clerkJSVersion: string | undefined; diff --git a/packages/remix/src/ssr/loadOptions.ts b/packages/remix/src/ssr/loadOptions.ts index 5af4f2d57c9..4753006d7d4 100644 --- a/packages/remix/src/ssr/loadOptions.ts +++ b/packages/remix/src/ssr/loadOptions.ts @@ -34,6 +34,14 @@ export const loadOptions = (args: LoaderFunctionArgs, overrides: RootAuthLoaderO ); const signInUrl = overrides.signInUrl || getEnvVariable('CLERK_SIGN_IN_URL', context) || ''; const signUpUrl = overrides.signUpUrl || getEnvVariable('CLERK_SIGN_UP_URL', context) || ''; + const signInForceRedirectUrl = + overrides.signInForceRedirectUrl || getEnvVariable('CLERK_SIGN_IN_FORCE_REDIRECT_URL', context) || ''; + const signUpForceRedirectUrl = + overrides.signUpForceRedirectUrl || getEnvVariable('CLERK_SIGN_UP_FORCE_REDIRECT_URL', context) || ''; + const signInFallbackRedirectUrl = + overrides.signInFallbackRedirectUrl || getEnvVariable('CLERK_SIGN_IN_FALLBACK_REDIRECT_URL', context) || ''; + const signUpFallbackRedirectUrl = + overrides.signUpFallbackRedirectUrl || getEnvVariable('CLERK_SIGN_UP_FALLBACK_REDIRECT_URL', context) || ''; const afterSignInUrl = overrides.afterSignInUrl || getEnvVariable('CLERK_AFTER_SIGN_IN_URL', context) || ''; const afterSignUpUrl = overrides.afterSignUpUrl || getEnvVariable('CLERK_AFTER_SIGN_UP_URL', context) || ''; @@ -68,5 +76,9 @@ export const loadOptions = (args: LoaderFunctionArgs, overrides: RootAuthLoaderO signUpUrl, afterSignInUrl, afterSignUpUrl, + signInForceRedirectUrl, + signUpForceRedirectUrl, + signInFallbackRedirectUrl, + signUpFallbackRedirectUrl, }; }; diff --git a/packages/remix/src/ssr/rootAuthLoader.ts b/packages/remix/src/ssr/rootAuthLoader.ts index 73a9cd22181..17b27452b5c 100644 --- a/packages/remix/src/ssr/rootAuthLoader.ts +++ b/packages/remix/src/ssr/rootAuthLoader.ts @@ -49,7 +49,8 @@ export const rootAuthLoader: RootAuthLoader = async ( const loadedOptions = loadOptions(args, opts); // Note: authenticateRequest() will throw a redirect if the auth state is determined to be handshake - const requestState = await authenticateRequest(args, loadedOptions); + const _requestState = await authenticateRequest(args, loadedOptions); + const requestState = { ...loadedOptions, ..._requestState }; if (!handler) { // if the user did not provide a handler, simply inject requestState into an empty response diff --git a/packages/remix/src/ssr/types.ts b/packages/remix/src/ssr/types.ts index dc7b6c2f0aa..be39cee0eaf 100644 --- a/packages/remix/src/ssr/types.ts +++ b/packages/remix/src/ssr/types.ts @@ -1,6 +1,13 @@ import type { Organization, Session, User, VerifyTokenOptions } from '@clerk/backend'; -import type { AuthObject } from '@clerk/backend/internal'; -import type { MultiDomainAndOrProxy } from '@clerk/types'; +import type { AuthObject, RequestState } from '@clerk/backend/internal'; +import type { + LegacyRedirectProps, + MultiDomainAndOrProxy, + SignInFallbackRedirectUrl, + SignInForceRedirectUrl, + SignUpFallbackRedirectUrl, + SignUpForceRedirectUrl, +} from '@clerk/types'; import type { DataFunctionArgs, LoaderFunction } from '@remix-run/server-runtime'; export type GetAuthReturn = Promise; @@ -15,10 +22,20 @@ export type RootAuthLoaderOptions = { authorizedParties?: []; signInUrl?: string; signUpUrl?: string; - afterSignInUrl?: string; - afterSignUpUrl?: string; } & Pick & - MultiDomainAndOrProxy; + MultiDomainAndOrProxy & + SignInForceRedirectUrl & + SignInFallbackRedirectUrl & + SignUpForceRedirectUrl & + SignUpFallbackRedirectUrl & + LegacyRedirectProps; + +export type RequestStateWithRedirectUrls = RequestState & + SignInForceRedirectUrl & + SignInFallbackRedirectUrl & + SignUpForceRedirectUrl & + SignUpFallbackRedirectUrl & + LegacyRedirectProps; export type RootAuthLoaderCallback = ( args: LoaderFunctionArgsWithAuth, diff --git a/packages/remix/src/ssr/utils.ts b/packages/remix/src/ssr/utils.ts index 63d9ee1187a..5ac35891801 100644 --- a/packages/remix/src/ssr/utils.ts +++ b/packages/remix/src/ssr/utils.ts @@ -1,4 +1,3 @@ -import type { RequestState } from '@clerk/backend/internal'; import { constants, debugRequestState } from '@clerk/backend/internal'; import { isTruthy } from '@clerk/shared/underscore'; import type { AppLoadContext, defer } from '@remix-run/server-runtime'; @@ -6,6 +5,7 @@ import { json } from '@remix-run/server-runtime'; import cookie from 'cookie'; import { getEnvVariable } from '../utils/utils'; +import type { RequestStateWithRedirectUrls } from './types'; export function isResponse(value: any): value is Response { return ( @@ -33,7 +33,7 @@ export function assertValidHandlerResult(val: any, error?: string): asserts val export const injectRequestStateIntoResponse = async ( response: Response, - requestState: RequestState, + requestState: RequestStateWithRedirectUrls, context: AppLoadContext, ) => { const clone = new Response(response.body, response); @@ -53,7 +53,7 @@ export const injectRequestStateIntoResponse = async ( export function injectRequestStateIntoDeferredData( data: ReturnType, - requestState: RequestState, + requestState: RequestStateWithRedirectUrls, context: AppLoadContext, ) { const { clerkState, headers } = getResponseClerkState(requestState, context); @@ -78,7 +78,7 @@ export function injectRequestStateIntoDeferredData( * * @internal */ -export function getResponseClerkState(requestState: RequestState, context: AppLoadContext) { +export function getResponseClerkState(requestState: RequestStateWithRedirectUrls, context: AppLoadContext) { const { reason, message, isSignedIn, ...rest } = requestState; const clerkState = wrapWithClerkState({ __clerk_ssr_state: rest.toAuth(), @@ -90,6 +90,10 @@ export function getResponseClerkState(requestState: RequestState, context: AppLo __signUpUrl: requestState.signUpUrl, __afterSignInUrl: requestState.afterSignInUrl, __afterSignUpUrl: requestState.afterSignUpUrl, + __signInForceRedirectUrl: requestState.signInForceRedirectUrl, + __signUpForceRedirectUrl: requestState.signUpForceRedirectUrl, + __signInFallbackRedirectUrl: requestState.signInFallbackRedirectUrl, + __signUpFallbackRedirectUrl: requestState.signUpFallbackRedirectUrl, __clerk_debug: debugRequestState(requestState), __clerkJSUrl: getEnvVariable('CLERK_JS', context), __clerkJSVersion: getEnvVariable('CLERK_JS_VERSION', context), From c171685e24f749404c3addc2f021c654a6987347 Mon Sep 17 00:00:00 2001 From: panteliselef Date: Wed, 5 Jun 2024 14:02:39 +0300 Subject: [PATCH 2/2] Add todo --- packages/remix/src/ssr/rootAuthLoader.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/remix/src/ssr/rootAuthLoader.ts b/packages/remix/src/ssr/rootAuthLoader.ts index 17b27452b5c..0146794a078 100644 --- a/packages/remix/src/ssr/rootAuthLoader.ts +++ b/packages/remix/src/ssr/rootAuthLoader.ts @@ -50,6 +50,7 @@ export const rootAuthLoader: RootAuthLoader = async ( const loadedOptions = loadOptions(args, opts); // Note: authenticateRequest() will throw a redirect if the auth state is determined to be handshake const _requestState = await authenticateRequest(args, loadedOptions); + // TODO: Investigate if `authenticateRequest` needs to return the loadedOptions (the new request urls in particular) const requestState = { ...loadedOptions, ..._requestState }; if (!handler) {