Add OTP sign-in option + Account Linking (#276)

* feat(accounts): allow linking email password
* feat(auth): add OTP sign-in
* refactor(accounts): remove 'sonner' dependency and update toast imports
* feat(supabase): enable analytics and configure database seeding
* feat(auth): update email templates and add OTP template
* feat(auth): add last sign in method hints
* feat(config): add devIndicators position to bottom-right
* feat(auth): implement comprehensive last authentication method tracking tests
This commit is contained in:
Giancarlo Buomprisco
2025-06-13 16:47:35 +07:00
committed by GitHub
parent 856e9612c4
commit 9033155fcd
87 changed files with 2580 additions and 1172 deletions

View File

@@ -4,7 +4,6 @@ import { zodResolver } from '@hookform/resolvers/zod';
import { CheckIcon, ExclamationTriangleIcon } from '@radix-ui/react-icons';
import { useForm } from 'react-hook-form';
import { useTranslation } from 'react-i18next';
import { toast } from 'sonner';
import { z } from 'zod';
import { useAppEvents } from '@kit/shared/events';
@@ -21,9 +20,11 @@ import {
} from '@kit/ui/form';
import { If } from '@kit/ui/if';
import { Input } from '@kit/ui/input';
import { toast } from '@kit/ui/sonner';
import { Trans } from '@kit/ui/trans';
import { useCaptchaToken } from '../captcha/client';
import { useLastAuthMethod } from '../hooks/use-last-auth-method';
import { TermsAndConditionsFormField } from './terms-and-conditions-form-field';
export function MagicLinkAuthContainer({
@@ -46,6 +47,7 @@ export function MagicLinkAuthContainer({
const { t } = useTranslation();
const signInWithOtpMutation = useSignInWithOtp();
const appEvents = useAppEvents();
const { recordAuthMethod } = useLastAuthMethod();
const form = useForm({
resolver: zodResolver(
@@ -77,6 +79,8 @@ export function MagicLinkAuthContainer({
},
});
recordAuthMethod('magic_link', { email });
if (shouldCreateUser) {
appEvents.emit({
type: 'user.signedUp',
@@ -90,7 +94,7 @@ export function MagicLinkAuthContainer({
toast.promise(promise, {
loading: t('auth:sendingEmailLink'),
success: t(`auth:sendLinkSuccessToast`),
error: t(`auth:errors.link`),
error: t(`auth:errors.linkTitle`),
});
resetCaptchaToken();
@@ -103,11 +107,11 @@ export function MagicLinkAuthContainer({
return (
<Form {...form}>
<form className={'w-full'} onSubmit={form.handleSubmit(onSubmit)}>
<If condition={signInWithOtpMutation.error}>
<ErrorAlert />
</If>
<div className={'flex flex-col space-y-4'}>
<If condition={signInWithOtpMutation.error}>
<ErrorAlert />
</If>
<FormField
render={({ field }) => (
<FormItem>
@@ -171,11 +175,11 @@ function ErrorAlert() {
<ExclamationTriangleIcon className={'h-4'} />
<AlertTitle>
<Trans i18nKey={'auth:errors.generic'} />
<Trans i18nKey={'auth:errors.linkTitle'} />
</AlertTitle>
<AlertDescription>
<Trans i18nKey={'auth:errors.link'} />
<Trans i18nKey={'auth:errors.linkDescription'} />
</AlertDescription>
</Alert>
);