createUser endpoint
This commit is contained in:
1 parent
264e6f7d1f
commit
8b7fd826b3
6 files changed
+93
-4
No files matched your search
@@ -17,7 +17,11 @@ interface AddTeamMemberDialogProps {
|
||||
}
|
||||
|
||||
interface RegisterPayload {
|
||||
user: Omit<AddTeamMemberFormData, "confirm">;
|
||||
firstName: string;
|
||||
lastName: string;
|
||||
email: string;
|
||||
password: string;
|
||||
role: string[];
|
||||
}
|
||||
|
||||
export const AddTeamMemberDialog = ({
|
||||
@@ -50,9 +54,9 @@ export const AddTeamMemberDialog = ({
|
||||
if (loading) return;
|
||||
|
||||
const { confirm, ...userData } = data;
|
||||
const payload: RegisterPayload = { user: userData };
|
||||
const payload: RegisterPayload = userData;
|
||||
|
||||
const result = await post("/auth/register", payload);
|
||||
const result = await post("/auth/users", payload);
|
||||
|
||||
if (result?.success) {
|
||||
reset();
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
import { Request, Response, NextFunction } from "express";
|
||||
import { AppError } from "@/utils/AppError.js";
|
||||
import { requireTeamId, requireUserRoles } from "./controllerUtils.js";
|
||||
import type { UserRole } from "@/types/user.js";
|
||||
|
||||
import {
|
||||
registrationBodyValidation,
|
||||
loginValidation,
|
||||
editUserBodyValidation,
|
||||
createUserBodyValidation,
|
||||
recoveryValidation,
|
||||
recoveryTokenBodyValidation,
|
||||
newPasswordValidation,
|
||||
@@ -50,6 +53,27 @@ class AuthController {
|
||||
}
|
||||
};
|
||||
|
||||
createUser = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
const userData = req.body;
|
||||
if (userData?.email) {
|
||||
userData.email = userData.email.toLowerCase();
|
||||
}
|
||||
await createUserBodyValidation.validateAsync(userData);
|
||||
|
||||
const teamId = requireTeamId(req.user?.teamId);
|
||||
const actorRoles = requireUserRoles(req.user?.role) as UserRole[];
|
||||
const newUser = await this.userService.createUser(userData, teamId, actorRoles, req.file);
|
||||
res.status(201).json({
|
||||
success: true,
|
||||
msg: "User created successfully",
|
||||
data: newUser,
|
||||
});
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
};
|
||||
|
||||
loginUser = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
if (req.body?.email) {
|
||||
|
||||
@@ -15,7 +15,6 @@ class InviteController {
|
||||
}
|
||||
|
||||
getInviteToken = async (req: Request, res: Response, next: NextFunction) => {
|
||||
console.log(req.body);
|
||||
try {
|
||||
const teamId = requireTeamId(req.user?.teamId);
|
||||
const userRoles = requireUserRoles(req.user?.role);
|
||||
|
||||
@@ -25,6 +25,7 @@ class AuthRoutes {
|
||||
this.router.get("/users/superadmin", this.authController.checkSuperadminExists);
|
||||
|
||||
this.router.get("/users", verifyJWT, isAllowed(["admin", "superadmin"]), this.authController.getAllUsers);
|
||||
this.router.post("/users", verifyJWT, isAllowed(["superadmin"]), upload.single("profileImage"), this.authController.createUser);
|
||||
this.router.get("/users/:userId", verifyJWT, isAllowed(["superadmin"]), this.authController.getUserById);
|
||||
this.router.patch("/users/:userId", verifyJWT, isAllowed(["superadmin"]), this.authController.editUserById);
|
||||
this.router.patch("/users/:userId/password", verifyJWT, isAllowed(["superadmin"]), this.authController.editUserPasswordById);
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
ITeamsRepository,
|
||||
} from "@/repositories/index.js";
|
||||
import type { User } from "@/types/index.js";
|
||||
import { canManageRole, type UserRole } from "@/types/user.js";
|
||||
import bcrypt from "bcryptjs";
|
||||
import { AppError } from "@/utils/AppError.js";
|
||||
import { ISuperSimpleQueue } from "@/service/infrastructure/SuperSimpleQueue/SuperSimpleQueue.js";
|
||||
@@ -153,6 +154,43 @@ class UserService {
|
||||
return { user: newUser, token };
|
||||
};
|
||||
|
||||
createUser = async (userData: Partial<User>, teamId: string, actorRoles: UserRole[], file: any) => {
|
||||
// Validate that the creator can assign the requested roles
|
||||
const targetRoles = userData.role ?? [];
|
||||
for (const targetRole of targetRoles) {
|
||||
const canManage = actorRoles.some((actorRole) => canManageRole(actorRole, targetRole));
|
||||
if (!canManage) {
|
||||
throw new AppError({
|
||||
message: "You do not have permission to assign this role",
|
||||
service: SERVICE_NAME,
|
||||
method: "createUser",
|
||||
status: 403,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
userData.teamId = teamId;
|
||||
|
||||
if (userData.password) {
|
||||
userData.password = this.hashPassword(userData.password);
|
||||
}
|
||||
|
||||
const newUser = await this.usersRepository.create(userData, file);
|
||||
|
||||
this.logger.debug({
|
||||
message: "New user created by superadmin",
|
||||
service: SERVICE_NAME,
|
||||
method: "createUser",
|
||||
details: newUser.id,
|
||||
});
|
||||
|
||||
newUser.profileImage = undefined;
|
||||
newUser.avatarImage = undefined;
|
||||
newUser.password = "";
|
||||
|
||||
return newUser;
|
||||
};
|
||||
|
||||
loginUser = async (email: string, password: string) => {
|
||||
// Check if user exists
|
||||
const user = await this.usersRepository.findByEmail(email);
|
||||
|
||||
@@ -712,6 +712,28 @@ const editUserPasswordByIdBodyValidation = joi.object({
|
||||
password: joi.string().min(8).required().pattern(passwordPattern),
|
||||
});
|
||||
|
||||
const createUserBodyValidation = joi.object({
|
||||
firstName: nameValidation.required(),
|
||||
lastName: nameValidation.required(),
|
||||
email: joi
|
||||
.string()
|
||||
.email()
|
||||
.required()
|
||||
.custom((value, helpers) => {
|
||||
const lowercasedValue = value.toLowerCase();
|
||||
if (value !== lowercasedValue) {
|
||||
return helpers.message({ custom: "Email must be in lowercase" });
|
||||
}
|
||||
return lowercasedValue;
|
||||
}),
|
||||
password: joi.string().min(8).required().pattern(passwordPattern),
|
||||
role: joi
|
||||
.array()
|
||||
.items(joi.string().valid(...UserRoles))
|
||||
.min(1)
|
||||
.required(),
|
||||
});
|
||||
|
||||
export {
|
||||
roleValidatior,
|
||||
loginValidation,
|
||||
@@ -781,4 +803,5 @@ export {
|
||||
editUserByIdBodyValidation,
|
||||
editSuperadminUserByIdBodyValidation,
|
||||
editUserPasswordByIdBodyValidation,
|
||||
createUserBodyValidation,
|
||||
};
|
||||
Reference in new issue
Block a user