fix: issues of OTP login (#92)

This commit is contained in:
Kilu.He
2025-04-10 13:19:31 +08:00
committed by GitHub
parent 37fe114b0f
commit 60627857fb
4 changed files with 71 additions and 35 deletions

View File

@@ -56,28 +56,42 @@ export async function signInOTP ({
access_token: string;
expires_at: number;
refresh_token: string;
code?: number;
msg?: string;
}>('/verify', {
email,
token: code,
type: 'recovery',
});
const newToken = response?.data;
const data = response?.data;
if (newToken) {
refreshSessionToken(JSON.stringify(newToken));
if (data) {
if (data.code !== 0) {
emit(EventType.SESSION_INVALID);
return Promise.reject({
code: data.code,
message: data.msg,
});
}
refreshSessionToken(JSON.stringify(data));
emit(EventType.SESSION_VALID);
afterAuth();
} else {
emit(EventType.SESSION_INVALID);
return Promise.reject('Failed to sign in otp');
return Promise.reject({
code: 'invalid_token',
message: 'Invalid token',
});
}
// eslint-disable-next-line
} catch (e: any) {
emit(EventType.SESSION_INVALID);
return Promise.reject({
code: e.code,
message: e.msg,
message: e.message,
});
}

View File

@@ -1,8 +1,8 @@
import { notify } from '@/components/_shared/notify';
import { AFConfigContext } from '@/components/main/app.hooks';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Progress } from '@/components/ui/progress';
import { createHotkey, HOT_KEY_NAME } from '@/utils/hotkeys';
import React, { useContext, useState } from 'react';
import { ReactComponent as Logo } from '@/assets/icons/logo.svg';
import { useTranslation } from 'react-i18next';
@@ -12,6 +12,7 @@ function CheckEmail ({ email, redirectTo }: {
redirectTo: string;
}) {
const { t } = useTranslation();
const [error, setError] = useState<string>('');
const [isEnter, setEnter] = useState<boolean>(false);
const [code, setCode] = useState<string>('');
const [loading, setLoading] = React.useState<boolean>(false);
@@ -25,8 +26,10 @@ function CheckEmail ({ email, redirectTo }: {
redirectTo,
code,
});
} catch (e) {
notify.error(t('web.signInError'));
// eslint-disable-next-line
} catch (e: any) {
console.log(e);
setError(e.message);
} finally {
setLoading(false);
}
@@ -57,9 +60,19 @@ function CheckEmail ({ email, redirectTo }: {
autoFocus
size={'md'}
className={'w-[320px]'}
onChange={(e) => setCode(e.target.value)}
onChange={(e) => {
setError('');
setCode(e.target.value);
}}
value={code}
placeholder={t('enterCode')}
helpText={error}
variant={error ? 'destructive' : 'default'}
onKeyDown={e => {
if (createHotkey(HOT_KEY_NAME.ENTER)(e.nativeEvent)) {
void handleSubmit();
}
}}
/>
<Button
@@ -70,7 +83,10 @@ function CheckEmail ({ email, redirectTo }: {
>
{loading ? (
<>
<Progress size={'sm'} />
<Progress
size={'sm'}
variant={'theme'}
/>
{t('editor.loading')}...
</>
) : (

View File

@@ -1,16 +1,16 @@
import { toast } from 'sonner';
import { AFConfigContext } from '@/components/main/app.hooks';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Progress } from '@/components/ui/progress';
import { createHotkey, HOT_KEY_NAME } from '@/utils/hotkeys';
import React, { useContext } from 'react';
import { useTranslation } from 'react-i18next';
import { toast } from 'sonner';
import isEmail from 'validator/lib/isEmail';
function MagicLink ({ redirectTo }: { redirectTo: string }) {
const { t } = useTranslation();
const [email, setEmail] = React.useState<string>('');
const [loading, setLoading] = React.useState<boolean>(false);
const [, setLoading] = React.useState<boolean>(false);
const service = useContext(AFConfigContext)?.service;
const handleSubmit = async () => {
const isValidEmail = isEmail(email);
@@ -23,7 +23,7 @@ function MagicLink ({ redirectTo }: { redirectTo: string }) {
setLoading(true);
try {
await service?.signInMagicLink({
void service?.signInMagicLink({
email,
redirectTo,
});
@@ -45,22 +45,19 @@ function MagicLink ({ redirectTo }: { redirectTo: string }) {
onChange={(e) => setEmail(e.target.value)}
value={email}
placeholder={t('signIn.pleaseInputYourEmail')}
onKeyDown={e => {
if (createHotkey(HOT_KEY_NAME.ENTER)(e.nativeEvent)) {
void handleSubmit();
}
}}
/>
<Button
onClick={handleSubmit}
disabled={loading}
size={'lg'}
className={'w-[320px]'}
>
{loading ? (
<>
<Progress />
{t('editor.loading')}...
</>
) : (
t('signIn.signInWithEmail')
)}
{t('signIn.signInWithEmail')}
</Button>
</div>
);

View File

@@ -59,27 +59,36 @@ const inputVariants = cva(
export interface InputProps
extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'size' | 'variant'>,
VariantProps<typeof inputVariants> {}
VariantProps<typeof inputVariants> {
helpText?: string;
}
function Input ({
className,
type,
variant,
size,
helpText,
...props
}: InputProps) {
return (
<input
type={type}
data-slot="input"
className={cn(
inputVariants({ variant, size }),
// Invalid state styling (applied via aria-invalid attribute)
'aria-invalid:ring-border-error-thick aria-invalid:border-border-error-thick',
className,
)}
{...props}
/>
<div className={'flex flex-col gap-1'}>
<input
type={type}
data-slot="input"
className={cn(
inputVariants({ variant, size }),
// Invalid state styling (applied via aria-invalid attribute)
'aria-invalid:ring-border-error-thick aria-invalid:border-border-error-thick',
className,
)}
{...props}
/>
<div className={cn('help-text text-xs', variant === 'destructive' && 'text-text-error')}>
{helpText}
</div>
</div>
);
}