diff --git a/apps/web/app/auth/sign-in/page.tsx b/apps/web/app/auth/sign-in/page.tsx index f2cbad471..bb1ee8896 100644 --- a/apps/web/app/auth/sign-in/page.tsx +++ b/apps/web/app/auth/sign-in/page.tsx @@ -13,6 +13,7 @@ import { withI18n } from '~/lib/i18n/with-i18n'; interface SignInPageProps { searchParams: Promise<{ invite_token?: string; + next?: string; }>; } @@ -24,19 +25,19 @@ export const generateMetadata = async () => { }; }; -const paths = { - callback: pathsConfig.auth.callback, - home: pathsConfig.app.home, - joinTeam: pathsConfig.app.joinTeam, -}; - async function SignInPage({ searchParams }: SignInPageProps) { - const inviteToken = (await searchParams).invite_token; + const { invite_token: inviteToken, next = '' } = await searchParams; const signUpPath = pathsConfig.auth.signUp + (inviteToken ? `?invite_token=${inviteToken}` : ''); + const paths = { + callback: pathsConfig.auth.callback, + returnPath: next ?? pathsConfig.app.home, + joinTeam: pathsConfig.app.joinTeam, + }; + return ( <>
diff --git a/packages/features/auth/src/components/oauth-providers.tsx b/packages/features/auth/src/components/oauth-providers.tsx index 11df96881..454b552bb 100644 --- a/packages/features/auth/src/components/oauth-providers.tsx +++ b/packages/features/auth/src/components/oauth-providers.tsx @@ -2,7 +2,10 @@ import { useCallback } from 'react'; -import type { Provider } from '@supabase/supabase-js'; +import type { + Provider, + SignInWithOAuthCredentials, +} from '@supabase/supabase-js'; import { useSignInWithProvider } from '@kit/supabase/hooks/use-sign-in-with-provider'; import { If } from '@kit/ui/if'; @@ -23,19 +26,21 @@ import { AuthProviderButton } from './auth-provider-button'; */ const OAUTH_SCOPES: Partial> = { azure: 'email', + keycloak: 'openid', // add your OAuth providers here }; -export function OauthProviders(props: { +export const OauthProviders: React.FC<{ inviteToken?: string; shouldCreateUser: boolean; enabledProviders: Provider[]; + queryParams?: Record; paths: { callback: string; returnPath: string; }; -}) { +}> = (props) => { const signInWithProviderMutation = useSignInWithProvider(); // we make the UI "busy" until the next page is fully loaded @@ -46,7 +51,7 @@ export function OauthProviders(props: { const credential = await signInRequest(); if (!credential) { - return Promise.reject(new Error('Failed to sign in with provider')); + return Promise.reject(new Error(`No credential returned`)); } }, [], @@ -89,16 +94,16 @@ export function OauthProviders(props: { ].join('?'); const redirectTo = [origin, redirectPath].join(''); - const scopesOpts = OAUTH_SCOPES[provider] ?? {}; + const scopes = OAUTH_SCOPES[provider] ?? undefined; const credentials = { provider, options: { - shouldCreateUser: props.shouldCreateUser, redirectTo, - ...scopesOpts, + queryParams: props.queryParams, + scopes, }, - }; + } satisfies SignInWithOAuthCredentials; return onSignInWithProvider(() => signInWithProviderMutation.mutateAsync(credentials), @@ -120,7 +125,7 @@ export function OauthProviders(props: {
); -} +}; function getProviderName(providerId: string) { const capitalize = (value: string) => diff --git a/packages/features/auth/src/components/sign-in-methods-container.tsx b/packages/features/auth/src/components/sign-in-methods-container.tsx index f536b682f..c2c558e27 100644 --- a/packages/features/auth/src/components/sign-in-methods-container.tsx +++ b/packages/features/auth/src/components/sign-in-methods-container.tsx @@ -1,6 +1,6 @@ 'use client'; -import { useRouter, useSearchParams } from 'next/navigation'; +import { useRouter } from 'next/navigation'; import type { Provider } from '@supabase/supabase-js'; @@ -18,8 +18,8 @@ export function SignInMethodsContainer(props: { paths: { callback: string; - home: string; joinTeam: string; + returnPath: string; }; providers: { @@ -29,13 +29,13 @@ export function SignInMethodsContainer(props: { }; }) { const router = useRouter(); - const nextPath = useSearchParams().get('next') ?? props.paths.home; const redirectUrl = isBrowser() ? new URL(props.paths.callback, window?.location.origin).toString() : ''; const onSignIn = () => { + // if the user has an invite token, we should join the team if (props.inviteToken) { const searchParams = new URLSearchParams({ invite_token: props.inviteToken, @@ -45,7 +45,8 @@ export function SignInMethodsContainer(props: { router.replace(joinTeamPath); } else { - router.replace(nextPath); + // otherwise, we should redirect to the return path + router.replace(props.paths.returnPath); } }; @@ -82,7 +83,7 @@ export function SignInMethodsContainer(props: { shouldCreateUser={false} paths={{ callback: props.paths.callback, - returnPath: props.paths.home, + returnPath: props.paths.returnPath, }} />