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,
}}
/>