added 2FA

This commit is contained in:
2024-04-26 22:16:21 +03:00
parent 53cadc289a
commit f17a002ac6
38 changed files with 1036 additions and 414 deletions

View File

@@ -6,7 +6,15 @@ import { signIn } from '@/config/auth'
import { DEFAULT_LOGIN_REDIRECT } from '@/config/routes'
import { AuthError } from 'next-auth'
import { getUserByEmail } from '@/data/user'
import { sendVerificationEmail } from '@/actions/send-verification-email'
import { sendTwoFactorTokenEmail, sendVerificationEmail } from '@/actions/send-verification-email'
import { generateTwoFactorToken } from '@/lib/tokens'
import { deleteTwoFactorToken, getTwoFactorTokenByEmail } from '@/data/two-factor-token'
import {
createTwoFactoComfirmation,
deleteTwoFactoComfirmation,
getTwoFactorConfirmationByUserId,
} from '@/data/two-factor-confirmation'
import journal from '@/actions/logger'
export const login = async (values: zInfer<typeof LoginSchema>) => {
const validatedFields = LoginSchema.safeParse(values)
@@ -15,7 +23,7 @@ export const login = async (values: zInfer<typeof LoginSchema>) => {
return { error: 'auth.form.error.invalid_fields' }
}
const { email, password } = validatedFields.data
const { email, password, code } = validatedFields.data
const existingUser = await getUserByEmail(email)
@@ -27,6 +35,40 @@ export const login = async (values: zInfer<typeof LoginSchema>) => {
return await sendVerificationEmail(existingUser.email, existingUser.name)
}
if (existingUser.isTwoFactorEnabled && existingUser.email) {
if (code) {
const twoFactorToken = await getTwoFactorTokenByEmail(existingUser.email)
if (!twoFactorToken || twoFactorToken.token !== code) {
return { error: 'auth.form.error.invalid_code' }
}
const hasExpired = new Date(twoFactorToken.expires) < new Date()
if (hasExpired) {
return { error: 'auth.form.error.expired_token' }
}
await deleteTwoFactorToken(twoFactorToken.id)
const existingConfirmation = await getTwoFactorConfirmationByUserId(existingUser.id)
if (existingConfirmation) {
await deleteTwoFactoComfirmation(existingConfirmation.id)
}
await createTwoFactoComfirmation(existingUser.id)
} else {
const twoFactorToken = await generateTwoFactorToken(existingUser.email)
if (twoFactorToken) {
const isOk = await sendTwoFactorTokenEmail(twoFactorToken.email, twoFactorToken.token, existingUser.name)
return { twoFactor: isOk }
}
console.error('ERROR.TYPE: could not send token')
return { error: 'common.something_went_wrong' }
}
}
try {
await signIn('credentials', {
email, password, redirectTo: DEFAULT_LOGIN_REDIRECT,