mirror of
https://github.com/bluewave-labs/Checkmate.git
synced 2026-05-20 08:28:48 -05:00
Merge pull request #3240 from bluewave-labs/fix/invite-permisisons
fix/invite permisisons
This commit is contained in:
@@ -112,6 +112,13 @@ const requireUserEmail = (userEmail?: string): string => {
|
||||
return userEmail;
|
||||
};
|
||||
|
||||
export const requireUserRoles = (userRoles?: string[]): string[] => {
|
||||
if (!userRoles || userRoles.length === 0) {
|
||||
throw new AppError({ message: "User roles are required", status: 400 });
|
||||
}
|
||||
return userRoles;
|
||||
};
|
||||
|
||||
export {
|
||||
fetchMonitorCertificate,
|
||||
requireString,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Request, Response, NextFunction } from "express";
|
||||
import { inviteBodyValidation, inviteVerificationBodyValidation } from "@/validation/joi.js";
|
||||
import { requireTeamId, requireUserRoles } from "@/controllers/controllerUtils.js";
|
||||
const SERVICE_NAME = "inviteController";
|
||||
|
||||
class InviteController {
|
||||
@@ -14,12 +15,14 @@ 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);
|
||||
const invite = req.body;
|
||||
const teamId = req?.user?.teamId;
|
||||
invite.teamId = teamId;
|
||||
await inviteBodyValidation.validateAsync(invite);
|
||||
const inviteToken = await this.inviteService.getInviteToken({ invite, teamId });
|
||||
const inviteToken = await this.inviteService.getInviteToken({ invite, teamId, userRoles });
|
||||
return res.status(200).json({
|
||||
success: true,
|
||||
msg: "Invite token generated successfully",
|
||||
@@ -32,13 +35,17 @@ class InviteController {
|
||||
|
||||
sendInviteEmail = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
const teamId = requireTeamId(req?.user?.teamId);
|
||||
const userRoles = requireUserRoles(req?.user?.role);
|
||||
|
||||
const inviteRequest = req.body;
|
||||
inviteRequest.teamId = req?.user?.teamId;
|
||||
inviteRequest.teamId = teamId;
|
||||
await inviteBodyValidation.validateAsync(inviteRequest);
|
||||
|
||||
const inviteToken = await this.inviteService.sendInviteEmail({
|
||||
invite: inviteRequest,
|
||||
firstName: req?.user?.firstName,
|
||||
userRoles,
|
||||
});
|
||||
return res.status(200).json({
|
||||
success: true,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { Invite } from "@/types/index.js";
|
||||
import type { Invite, UserRole } from "@/types/index.js";
|
||||
import { canManageRole } from "@/types/user.js";
|
||||
import type { IInvitesRepository } from "@/repositories/index.js";
|
||||
import { AppError } from "@/utils/AppError.js";
|
||||
|
||||
@@ -29,13 +30,42 @@ class InviteService {
|
||||
return InviteService.SERVICE_NAME;
|
||||
}
|
||||
|
||||
getInviteToken = async ({ invite, teamId }: { invite: Partial<Invite>; teamId: string }) => {
|
||||
getInviteToken = async ({ invite, teamId, userRoles }: { invite: Partial<Invite>; teamId: string; userRoles: UserRole[] }) => {
|
||||
invite.teamId = teamId;
|
||||
|
||||
const inviteRoles = invite.role ?? [];
|
||||
|
||||
for (const targetRole of inviteRoles) {
|
||||
const canManage = userRoles.some((actorRole) => canManageRole(actorRole, targetRole));
|
||||
if (!canManage) {
|
||||
throw new AppError({
|
||||
message: "You do not have permission to create this invite",
|
||||
service: SERVICE_NAME,
|
||||
method: "getInviteToken",
|
||||
status: 403,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const inviteToken = await this.invitesRepository.create(invite);
|
||||
return inviteToken;
|
||||
};
|
||||
|
||||
sendInviteEmail = async ({ invite, firstName }: { invite: Partial<Invite>; firstName: any }) => {
|
||||
sendInviteEmail = async ({ invite, firstName, userRoles }: { invite: Partial<Invite>; firstName: any; userRoles: UserRole[] }) => {
|
||||
const inviteRoles = invite.role ?? [];
|
||||
|
||||
for (const targetRole of inviteRoles) {
|
||||
const canManage = userRoles.some((actorRole) => canManageRole(actorRole, targetRole));
|
||||
if (!canManage) {
|
||||
throw new AppError({
|
||||
message: "You do not have permission to create this invite",
|
||||
service: SERVICE_NAME,
|
||||
method: "getInviteToken",
|
||||
status: 403,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const inviteToken = await this.invitesRepository.create(invite);
|
||||
const { clientHost } = this.settingsService.getSettings();
|
||||
|
||||
|
||||
@@ -1,6 +1,17 @@
|
||||
export const UserRoles = ["user", "admin", "superadmin", "demo"] as const;
|
||||
export type UserRole = (typeof UserRoles)[number];
|
||||
|
||||
export const RoleHierarchy: Record<UserRole, number> = {
|
||||
demo: 0,
|
||||
user: 1,
|
||||
admin: 2,
|
||||
superadmin: 3,
|
||||
};
|
||||
|
||||
export const canManageRole = (actorRole: UserRole, targetRole: UserRole): boolean => {
|
||||
return RoleHierarchy[actorRole] > RoleHierarchy[targetRole];
|
||||
};
|
||||
|
||||
export interface UserProfileImage {
|
||||
data?: Buffer;
|
||||
contentType?: string;
|
||||
|
||||
Reference in New Issue
Block a user