initial commit

This commit is contained in:
Harivansh Rathi 2024-11-24 20:56:03 -05:00
commit ef9ccf22d3
133 changed files with 20802 additions and 0 deletions

62
actions/login.ts Normal file
View file

@ -0,0 +1,62 @@
'use server'
import * as z from 'zod'
import { LoginSchema } from '@/schemas'
import { signIn } from '@/auth'
import { AuthError } from 'next-auth'
import { generateVerificationToken } from '@/lib/tokens'
import { getUserByEmail } from '@/data/user'
import { sendVerificationEmail } from '@/lib/mail'
export const login = async (values: z.infer<typeof LoginSchema>) => {
// Validate fields
const validatedFields = LoginSchema.safeParse(values)
// If fields are not valid
if (!validatedFields.success) {
return { error: 'Invalid fields' }
}
// If fields are valid
const { email, password } = validatedFields.data
const exisitingUser = await getUserByEmail(email)
if (!exisitingUser || !exisitingUser.email || !exisitingUser.password) {
return { error: 'Email does not exisit' }
}
if (!exisitingUser.emailVerified) {
const verificationToken = await generateVerificationToken(
exisitingUser.email
)
await sendVerificationEmail(
verificationToken.email,
verificationToken.token
)
return { success: 'Confirmation email sent!' }
}
try {
const result = await signIn('credentials', {
redirect: false,
email,
password
})
if (result?.error) {
return { error: result.error }
}
return { success: 'Logged In!' }
} catch (error) {
if (error instanceof AuthError) {
switch (error.type) {
case 'CredentialsSignin':
return { error: 'Invalid credentials' }
default:
return { error: 'Something went wrong' }
}
}
throw error
}
}

7
actions/logout.ts Normal file
View file

@ -0,0 +1,7 @@
'use server'
import { signOut } from '@/auth'
export const logout = async () => {
await signOut()
}

70
actions/new-password.ts Normal file
View file

@ -0,0 +1,70 @@
'use server'
import * as z from 'zod'
import { NewPasswordSchema } from '@/schemas'
import { getPasswordResetTokenByToken } from '@/data/password-reset-token'
import { getUserByEmail } from '@/data/user'
import bcrypt from 'bcrypt'
import { db } from '@/lib/db'
export const newPassword = async (
values: z.infer<typeof NewPasswordSchema>,
token?: string | null
) => {
// if error, return error
if (!token) {
return { error: 'Token is required' }
}
// validate fields
const validatedFields = NewPasswordSchema.safeParse(values)
// if not fields are not valid, return error
if (!validatedFields.success) {
return { error: 'Invalid Fields' }
}
// extract password
const { password } = validatedFields.data
// token validation
const existingToken = await getPasswordResetTokenByToken(token)
// if token not found, return error
if (!existingToken) {
return { error: 'Invalid Token' }
}
// check if token is expired (if it is less than the date we set, which is an hour)
const hasExpired = new Date(existingToken.expires) < new Date()
// if expired, return error
if (hasExpired) {
return { error: 'Token has expired' }
}
// check exisiting user
const existingUser = await getUserByEmail(existingToken.email)
// if user not found, return error
if (!existingUser) {
return { error: 'Email not found' }
}
// hash password
const hashedPassword = await bcrypt.hash(password, 10)
// update db
await db.user.update({
where: { id: existingUser.id },
data: {
password: hashedPassword
}
})
// delete token
await db.passwordResetToken.delete({
where: { id: existingToken.id }
})
// return success message
return { success: 'Password updated successfully' }
}

View file

@ -0,0 +1,41 @@
'use server'
import { db } from '@/lib/db'
import { getUserByEmail } from '@/data/user'
import { getVerificationTokenByToken } from '@/data/verification-token'
export const newVerification = async (token: string) => {
// if no token, display message
const exisitingToken = await getVerificationTokenByToken(token)
if (!exisitingToken) {
return { error: 'Token does not exisit!' }
}
// if token has expired, display message
const hasExpired = new Date(exisitingToken.expires) < new Date()
if (hasExpired) {
return { error: 'Token has expired!' }
}
// if user does not exist, display message
const existingUser = await getUserByEmail(exisitingToken.email)
if (!existingUser) {
return { error: 'User does not exisit!' }
}
// update email value when they verify
await db.user.update({
where: { id: existingUser.id },
data: {
emailVerified: new Date(),
email: exisitingToken.email
}
})
// delete token
await db.verificationToken.delete({
where: { id: exisitingToken.id }
})
return { success: 'Email verified! Login to continue' }
}

39
actions/register.ts Normal file
View file

@ -0,0 +1,39 @@
'use server'
import * as z from 'zod'
import { RegisterSchema } from '@/schemas'
import bcrypt from 'bcrypt'
import { db } from '@/lib/db'
import { getUserByEmail } from '@/data/user'
import { generateVerificationToken } from '@/lib/tokens'
import { sendVerificationEmail } from '@/lib/mail'
export const register = async (values: z.infer<typeof RegisterSchema>) => {
const validatedFields = RegisterSchema.safeParse(values)
if (!validatedFields.success) {
return { error: 'Invalid fields' }
}
const { name, email, password } = validatedFields.data
const hashedPassword = await bcrypt.hash(password, 10)
const exisitingUser = await getUserByEmail(email)
if (exisitingUser) {
return { error: 'Email already exists!' }
}
await db.user.create({
data: {
name,
email,
password: hashedPassword
}
})
const verificationToken = await generateVerificationToken(email)
await sendVerificationEmail(verificationToken.email, verificationToken.token)
return { success: 'Email sent!' }
}

32
actions/reset.ts Normal file
View file

@ -0,0 +1,32 @@
'use server'
import * as z from 'zod'
import { getUserByEmail } from '@/data/user'
import { ResetSchema } from '@/schemas'
import { sendPasswordResetEmail } from '@/lib/mail'
import { generatePasswordResetToken } from '@/lib/tokens'
export const reset = async (values: z.infer<typeof ResetSchema>) => {
// validate fields
const validatedFields = ResetSchema.safeParse(values)
// check if fields are valid
if (!validatedFields.success) {
return { error: 'Invalid email!' }
}
// extract email
const { email } = validatedFields.data
// check exisiting user
const existingUser = await getUserByEmail(email)
// if user does not exist
if (!existingUser) {
return { error: 'Email does not exist!' }
}
//send reset email
const passwordResetToken = await generatePasswordResetToken(email)
await sendPasswordResetEmail(
passwordResetToken.email,
passwordResetToken.token
)
// success message
return { success: 'Reset email sent 📫' }
}