mirror of https://github.com/buster-so/buster.git
common oauth hanlders
This commit is contained in:
parent
6f1a60d4e5
commit
567142c7fc
|
@ -39,6 +39,35 @@ export const LoginForm: React.FC<{
|
|||
);
|
||||
const [signUpSuccess, setSignUpSuccess] = useState(false);
|
||||
|
||||
// Reusable OAuth handler to reduce code duplication
|
||||
const handleOAuthSignIn = async (
|
||||
provider: 'google' | 'github' | 'azure',
|
||||
signInFn: (data: {
|
||||
data: { redirectTo?: string | null };
|
||||
}) => Promise<{ success: boolean; url?: string; error?: string }>
|
||||
) => {
|
||||
setLoading(provider);
|
||||
try {
|
||||
const result = await signInFn({ data: { redirectTo } });
|
||||
console.log(`${provider} result:`, result);
|
||||
|
||||
if (result && 'success' in result && !result.success) {
|
||||
setErrorMessages([result.error || `An error occurred during ${provider} sign-in`]);
|
||||
setLoading(null);
|
||||
return;
|
||||
}
|
||||
|
||||
if (result && 'success' in result && result.success && result.url) {
|
||||
// Redirect to OAuth provider's URL
|
||||
window.location.href = result.url;
|
||||
}
|
||||
} catch (error: unknown) {
|
||||
console.error(error);
|
||||
setErrorMessages(['An unexpected error occurred. Please try again.']);
|
||||
setLoading(null);
|
||||
}
|
||||
};
|
||||
|
||||
const onSignInWithUsernameAndPassword = useMemoizedFn(
|
||||
async ({ email, password }: { email: string; password: string }) => {
|
||||
setLoading('email');
|
||||
|
@ -61,63 +90,15 @@ export const LoginForm: React.FC<{
|
|||
);
|
||||
|
||||
const onSignInWithGoogle = useMemoizedFn(async () => {
|
||||
setLoading('google');
|
||||
try {
|
||||
const result = await signInWithGoogle({ data: { redirectTo } });
|
||||
console.log('result', result);
|
||||
if (result && 'success' in result && !result.success) {
|
||||
setErrorMessages([result.error || 'An error occurred during sign-in']);
|
||||
setLoading(null);
|
||||
return;
|
||||
}
|
||||
|
||||
if (result && 'success' in result && result.success && result.url) {
|
||||
// Redirect to OAuth provider's URL
|
||||
window.location.href = result.url;
|
||||
}
|
||||
} catch (error: unknown) {
|
||||
console.error(error);
|
||||
setErrorMessages(['An unexpected error occurred. Please try again.']);
|
||||
setLoading(null);
|
||||
}
|
||||
return handleOAuthSignIn('google', signInWithGoogle);
|
||||
});
|
||||
|
||||
const onSignInWithGithub = useMemoizedFn(async () => {
|
||||
setLoading('github');
|
||||
try {
|
||||
const result = await signInWithGithub({ data: { redirectTo } });
|
||||
if (result && 'success' in result && !result.success) {
|
||||
setErrorMessages([result.error]);
|
||||
setLoading(null);
|
||||
}
|
||||
|
||||
if (!result?.error) {
|
||||
navigate({ to: redirectTo || '/' });
|
||||
}
|
||||
} catch (error: unknown) {
|
||||
console.error(error);
|
||||
setErrorMessages(['An unexpected error occurred. Please try again.']);
|
||||
setLoading(null);
|
||||
}
|
||||
return handleOAuthSignIn('github', signInWithGithub);
|
||||
});
|
||||
|
||||
const onSignInWithAzure = useMemoizedFn(async () => {
|
||||
setLoading('azure');
|
||||
try {
|
||||
const result = await signInWithAzure({ data: { redirectTo } });
|
||||
if (result && 'success' in result && !result.success) {
|
||||
setErrorMessages([result.error]);
|
||||
setLoading(null);
|
||||
}
|
||||
|
||||
if (!result?.error) {
|
||||
navigate({ to: redirectTo || '/' });
|
||||
}
|
||||
} catch (error: unknown) {
|
||||
console.error(error);
|
||||
setErrorMessages(['An unexpected error occurred. Please try again.']);
|
||||
setLoading(null);
|
||||
}
|
||||
return handleOAuthSignIn('azure', signInWithAzure);
|
||||
});
|
||||
|
||||
const onSignUp = useMemoizedFn(async (d: { email: string; password: string }) => {
|
||||
|
@ -127,15 +108,17 @@ export const LoginForm: React.FC<{
|
|||
data: { ...d, redirectTo },
|
||||
});
|
||||
|
||||
if ((result && 'success' in result && !result.success) || result.error) {
|
||||
setErrorMessages([result.error]);
|
||||
if (result && 'success' in result && !result.success) {
|
||||
setErrorMessages([result.error || 'An error occurred during sign-up']);
|
||||
setLoading(null);
|
||||
} else {
|
||||
setSignUpSuccess(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!result?.error) {
|
||||
navigate({ to: redirectTo || '/' });
|
||||
if (result && 'success' in result && result.success) {
|
||||
setSignUpSuccess(true);
|
||||
setLoading(null);
|
||||
// For sign-up, we don't need to navigate immediately as the user
|
||||
// needs to check their email for verification
|
||||
}
|
||||
} catch (error: unknown) {
|
||||
console.error(error);
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import { redirect } from '@tanstack/react-router';
|
||||
import { createServerFn } from '@tanstack/react-start';
|
||||
import { z } from 'zod';
|
||||
import { env } from '@/env';
|
||||
|
@ -14,6 +13,37 @@ const isValidRedirectUrl = (url: string): boolean => {
|
|||
}
|
||||
};
|
||||
|
||||
// Common OAuth handler to reduce code duplication
|
||||
const handleOAuthSignIn = async (
|
||||
provider: 'google' | 'github' | 'azure',
|
||||
redirectTo?: string | null,
|
||||
options?: Record<string, string>
|
||||
) => {
|
||||
const supabase = getSupabaseServerClient();
|
||||
|
||||
const callbackUrl = new URL(AuthCallbackRoute.to, env.VITE_PUBLIC_URL);
|
||||
|
||||
if (redirectTo && isValidRedirectUrl(redirectTo)) {
|
||||
callbackUrl.searchParams.set('next', redirectTo);
|
||||
}
|
||||
|
||||
const { data, error } = await supabase.auth.signInWithOAuth({
|
||||
provider,
|
||||
options: {
|
||||
redirectTo: callbackUrl.toString(),
|
||||
...options,
|
||||
},
|
||||
});
|
||||
|
||||
if (error) {
|
||||
return { success: false, error: error.message };
|
||||
}
|
||||
|
||||
console.log(`OAuth ${provider} data:`, data);
|
||||
|
||||
return { success: true, url: data.url };
|
||||
};
|
||||
|
||||
export const signInWithEmailAndPassword = createServerFn({ method: 'POST' })
|
||||
.validator(
|
||||
z.object({
|
||||
|
@ -40,33 +70,6 @@ export const signInWithEmailAndPassword = createServerFn({ method: 'POST' })
|
|||
};
|
||||
});
|
||||
|
||||
export const signInWithGoogle = createServerFn({ method: 'POST' })
|
||||
.validator(z.object({ redirectTo: z.string().nullable().optional() }))
|
||||
.handler(async ({ data: { redirectTo } }) => {
|
||||
const supabase = getSupabaseServerClient();
|
||||
|
||||
const callbackUrl = new URL(AuthCallbackRoute.to, env.VITE_PUBLIC_URL);
|
||||
|
||||
if (redirectTo && isValidRedirectUrl(redirectTo)) {
|
||||
callbackUrl.searchParams.set('next', redirectTo);
|
||||
}
|
||||
|
||||
const { data, error } = await supabase.auth.signInWithOAuth({
|
||||
provider: 'google',
|
||||
options: {
|
||||
redirectTo: callbackUrl.toString(),
|
||||
},
|
||||
});
|
||||
|
||||
if (error) {
|
||||
return { success: false, error: error.message };
|
||||
}
|
||||
|
||||
console.log('OAuth data:', data);
|
||||
|
||||
return { success: true, url: data.url };
|
||||
});
|
||||
|
||||
export const signInWithAnonymousUser = createServerFn({ method: 'POST' }).handler(async () => {
|
||||
const supabase = getSupabaseServerClient();
|
||||
const { data, error } = await supabase.auth.signInAnonymously();
|
||||
|
@ -111,55 +114,24 @@ export const signInWithAnonymousUser = createServerFn({ method: 'POST' }).handle
|
|||
};
|
||||
});
|
||||
|
||||
export const signInWithGithub = createServerFn({ method: 'POST' })
|
||||
.validator(z.object({ redirectTo: z.string().nullable().optional() }))
|
||||
const oAuthRedirectValidator = z.object({ redirectTo: z.string().nullable().optional() });
|
||||
|
||||
export const signInWithGoogle = createServerFn({ method: 'POST' })
|
||||
.validator(oAuthRedirectValidator)
|
||||
.handler(async ({ data: { redirectTo } }) => {
|
||||
const supabase = getSupabaseServerClient();
|
||||
return handleOAuthSignIn('google', redirectTo);
|
||||
});
|
||||
|
||||
const callbackUrl = new URL(AuthCallbackRoute.to, env.VITE_PUBLIC_URL);
|
||||
|
||||
if (redirectTo && isValidRedirectUrl(redirectTo)) {
|
||||
callbackUrl.searchParams.set('next', redirectTo);
|
||||
}
|
||||
|
||||
const { data, error } = await supabase.auth.signInWithOAuth({
|
||||
provider: 'github',
|
||||
options: {
|
||||
redirectTo: callbackUrl.toString(),
|
||||
},
|
||||
});
|
||||
|
||||
if (error) {
|
||||
return { success: false, error: error.message };
|
||||
}
|
||||
|
||||
throw redirect({ to: data.url });
|
||||
export const signInWithGithub = createServerFn({ method: 'POST' })
|
||||
.validator(oAuthRedirectValidator)
|
||||
.handler(async ({ data: { redirectTo } }) => {
|
||||
return handleOAuthSignIn('github', redirectTo);
|
||||
});
|
||||
|
||||
export const signInWithAzure = createServerFn({ method: 'POST' })
|
||||
.validator(z.object({ redirectTo: z.string().nullable().optional() }))
|
||||
.validator(oAuthRedirectValidator)
|
||||
.handler(async ({ data: { redirectTo } }) => {
|
||||
const supabase = getSupabaseServerClient();
|
||||
|
||||
const callbackUrl = new URL(AuthCallbackRoute.to, env.VITE_PUBLIC_URL);
|
||||
|
||||
if (redirectTo && isValidRedirectUrl(redirectTo)) {
|
||||
callbackUrl.searchParams.set('next', redirectTo);
|
||||
}
|
||||
|
||||
const { data, error } = await supabase.auth.signInWithOAuth({
|
||||
provider: 'azure',
|
||||
options: {
|
||||
redirectTo: callbackUrl.toString(),
|
||||
scopes: 'email',
|
||||
},
|
||||
});
|
||||
|
||||
if (error) {
|
||||
return { success: false, error: error.message };
|
||||
}
|
||||
|
||||
throw redirect({ to: data.url });
|
||||
return handleOAuthSignIn('azure', redirectTo, { scopes: 'email' });
|
||||
});
|
||||
|
||||
export const signUpWithEmailAndPassword = createServerFn({ method: 'POST' })
|
||||
|
@ -173,9 +145,7 @@ export const signUpWithEmailAndPassword = createServerFn({ method: 'POST' })
|
|||
.handler(async ({ data }) => {
|
||||
const supabase = getSupabaseServerClient();
|
||||
|
||||
const authURLFull = `${AuthCallbackRoute.to}`;
|
||||
|
||||
console.log(data);
|
||||
console.log('Sign up data:', data);
|
||||
|
||||
const { error } = await supabase.auth.signUp({
|
||||
email: data.email,
|
||||
|
@ -185,7 +155,7 @@ export const signUpWithEmailAndPassword = createServerFn({ method: 'POST' })
|
|||
},
|
||||
});
|
||||
|
||||
console.log('error', error);
|
||||
console.log('Sign up error:', error);
|
||||
|
||||
if (error) {
|
||||
return {
|
||||
|
@ -194,7 +164,8 @@ export const signUpWithEmailAndPassword = createServerFn({ method: 'POST' })
|
|||
};
|
||||
}
|
||||
|
||||
console.log('authURLFull', authURLFull);
|
||||
|
||||
throw redirect({ to: authURLFull });
|
||||
return {
|
||||
success: true,
|
||||
redirectTo: AuthCallbackRoute.to,
|
||||
};
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue