Set default oAuth scopes for azure and keycloak. Allow passing custom… (#207)

* Set default oAuth scopes for azure and keycloak. Allow passing custom query parameters from the OauthProviders component.

* Pass return path if a next query parameter is provided. Use home path otherwise.
This commit is contained in:
Giancarlo Buomprisco
2025-03-09 11:17:30 +07:00
committed by GitHub
parent 08cd6983f4
commit b265f596da
3 changed files with 28 additions and 21 deletions

View File

@@ -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<Record<Provider, string>> = {
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<string, string>;
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: {
</div>
</>
);
}
};
function getProviderName(providerId: string) {
const capitalize = (value: string) =>

View File

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