Move create user to service
This commit is contained in:
parent
7032dcaa42
commit
e2a8b208bc
|
|
@ -5,30 +5,7 @@ import { cookies } from "next/headers";
|
||||||
import { redirect } from "next/navigation";
|
import { redirect } from "next/navigation";
|
||||||
import { hashPassword } from "../utils/hashPassword";
|
import { hashPassword } from "../utils/hashPassword";
|
||||||
import { createJwtToken } from "../utils/createJwtToken";
|
import { createJwtToken } from "../utils/createJwtToken";
|
||||||
|
import createUser from "../services/createUser";
|
||||||
/**
|
|
||||||
* Interface for the schema of a new user.
|
|
||||||
*/
|
|
||||||
interface CreateUserSchema {
|
|
||||||
name: string;
|
|
||||||
email: string;
|
|
||||||
password: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Validation schema for creating a user.
|
|
||||||
*/
|
|
||||||
const createUserSchema = z
|
|
||||||
.object({
|
|
||||||
name: z.string(),
|
|
||||||
email: z.string().email(),
|
|
||||||
password: z.string().min(6),
|
|
||||||
passwordConfirmation: z.string().optional(),
|
|
||||||
})
|
|
||||||
.refine((data) => data.password === data.passwordConfirmation, {
|
|
||||||
message: "Password confirmation must match the password",
|
|
||||||
path: ["passwordConfirmation"],
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new user in the system.
|
* Creates a new user in the system.
|
||||||
|
|
@ -36,7 +13,7 @@ const createUserSchema = z
|
||||||
* @param formData - The form data containing user details.
|
* @param formData - The form data containing user details.
|
||||||
* @returns An object indicating the result of the operation.
|
* @returns An object indicating the result of the operation.
|
||||||
*/
|
*/
|
||||||
export default async function createUser(formData: FormData) {
|
export default async function createUserAction(formData: FormData) {
|
||||||
//TODO: Add Throttling
|
//TODO: Add Throttling
|
||||||
//TODO: Add validation check if the user is already logged in
|
//TODO: Add validation check if the user is already logged in
|
||||||
|
|
||||||
|
|
@ -44,49 +21,12 @@ export default async function createUser(formData: FormData) {
|
||||||
const parsedData = {
|
const parsedData = {
|
||||||
email: formData.get("email")?.toString() ?? "",
|
email: formData.get("email")?.toString() ?? "",
|
||||||
name: formData.get("name")?.toString() ?? "",
|
name: formData.get("name")?.toString() ?? "",
|
||||||
password: formData.get("password")?.toString() ?? "",
|
plainPassword: formData.get("password")?.toString() ?? "",
|
||||||
passwordConfirmation: formData
|
plainPasswordConfirmation:
|
||||||
.get("passwordConfirmation")
|
formData.get("passwordConfirmation")?.toString() ?? "",
|
||||||
?.toString(),
|
|
||||||
};
|
};
|
||||||
const validatedFields = createUserSchema.safeParse(parsedData);
|
await createUser(parsedData);
|
||||||
|
redirect("/dashboard");
|
||||||
if (!validatedFields.success) {
|
|
||||||
return {
|
|
||||||
success: false,
|
|
||||||
error: {
|
|
||||||
message: "",
|
|
||||||
errors: validatedFields.error.flatten().fieldErrors,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const existingUser = await prisma.user.findUnique({
|
|
||||||
where: { email: validatedFields.data.email },
|
|
||||||
});
|
|
||||||
|
|
||||||
if (existingUser) {
|
|
||||||
return {
|
|
||||||
success: false,
|
|
||||||
error: {
|
|
||||||
message: "",
|
|
||||||
errors: {
|
|
||||||
email: ["Email already exists"],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const user = await prisma.user.create({
|
|
||||||
data: {
|
|
||||||
name: validatedFields.data.name,
|
|
||||||
email: validatedFields.data.email,
|
|
||||||
passwordHash: await hashPassword(validatedFields.data.password),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const token = createJwtToken({ id: user.id });
|
|
||||||
cookies().set("token", token);
|
|
||||||
} catch (e: unknown) {
|
} catch (e: unknown) {
|
||||||
// Handle unexpected errors
|
// Handle unexpected errors
|
||||||
console.error(e);
|
console.error(e);
|
||||||
|
|
@ -100,6 +40,4 @@ export default async function createUser(formData: FormData) {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
redirect("/dashboard");
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
23
src/modules/auth/formSchemas/CreateUserFormSchema.ts
Normal file
23
src/modules/auth/formSchemas/CreateUserFormSchema.ts
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
import {z} from "zod"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for the schema of a new user.
|
||||||
|
*/
|
||||||
|
export interface CreateUserSchema {
|
||||||
|
name: string;
|
||||||
|
email: string;
|
||||||
|
plainPassword: string;
|
||||||
|
plainPasswordConfirmation: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const createUserSchema = z
|
||||||
|
.object({
|
||||||
|
name: z.string(),
|
||||||
|
email: z.string().email(),
|
||||||
|
password: z.string().min(6),
|
||||||
|
passwordConfirmation: z.string().optional(),
|
||||||
|
})
|
||||||
|
.refine((data) => data.password === data.passwordConfirmation, {
|
||||||
|
message: "Password confirmation must match the password",
|
||||||
|
path: ["passwordConfirmation"],
|
||||||
|
});
|
||||||
54
src/modules/auth/services/createUser.ts
Normal file
54
src/modules/auth/services/createUser.ts
Normal file
|
|
@ -0,0 +1,54 @@
|
||||||
|
import DashboardError from "@/modules/dashboard/errors/DashboardError";
|
||||||
|
import {
|
||||||
|
CreateUserSchema,
|
||||||
|
createUserSchema,
|
||||||
|
} from "../formSchemas/CreateUserFormSchema";
|
||||||
|
import mapObjectToFirstValue from "@/utils/mapObjectToFirstValue";
|
||||||
|
import db from "@/core/db";
|
||||||
|
import AuthError from "../error/AuthError";
|
||||||
|
import hashPassword from "../utils/hashPassword";
|
||||||
|
import { createJwtToken } from "../utils/createJwtToken";
|
||||||
|
import { cookies } from "next/headers";
|
||||||
|
|
||||||
|
export default async function createUser(userData: CreateUserSchema) {
|
||||||
|
const validatedFields = createUserSchema.safeParse(userData);
|
||||||
|
|
||||||
|
//Validate form input
|
||||||
|
if (!validatedFields.success) {
|
||||||
|
throw new DashboardError({
|
||||||
|
errorCode: "INVALID_FORM_DATA",
|
||||||
|
formErrors: mapObjectToFirstValue(
|
||||||
|
validatedFields.error.flatten().fieldErrors
|
||||||
|
),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
//Check email exists
|
||||||
|
if (
|
||||||
|
await db.user.findFirst({
|
||||||
|
where: { email: validatedFields.data.email },
|
||||||
|
})
|
||||||
|
) {
|
||||||
|
throw new AuthError({
|
||||||
|
errorCode: "USER_ALREADY_EXISTS",
|
||||||
|
message: "This email already exists",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
//Create user
|
||||||
|
const user = await db.user.create({
|
||||||
|
data: {
|
||||||
|
name: validatedFields.data.name,
|
||||||
|
email: validatedFields.data.email,
|
||||||
|
passwordHash: await hashPassword(validatedFields.data.password),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
//Set token
|
||||||
|
const token = createJwtToken({ id: user.id });
|
||||||
|
cookies().set("token", token);
|
||||||
|
|
||||||
|
return {
|
||||||
|
token,
|
||||||
|
};
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user