mirror of
https://github.com/SyncrowIOT/backend.git
synced 2025-07-17 11:15:14 +00:00
Refactor user role handling to use single role object
This commit is contained in:
@ -4,5 +4,5 @@ export class AuthInterface {
|
||||
uuid: string;
|
||||
sessionId: string;
|
||||
id: number;
|
||||
roles?: string[];
|
||||
role?: object;
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ export class AuthService {
|
||||
}
|
||||
: undefined,
|
||||
},
|
||||
relations: ['roles.roleType'],
|
||||
relations: ['roleType'],
|
||||
});
|
||||
|
||||
if (!user.isUserVerified) {
|
||||
@ -85,9 +85,8 @@ export class AuthService {
|
||||
email: user.email,
|
||||
userId: user.userId,
|
||||
uuid: user.uuid,
|
||||
type: user.type,
|
||||
sessionId: user.sessionId,
|
||||
roles: user?.roles,
|
||||
role: user?.role,
|
||||
googleCode: user.googleCode,
|
||||
};
|
||||
if (payload.googleCode) {
|
||||
|
@ -31,7 +31,7 @@ export class JwtStrategy extends PassportStrategy(Strategy, 'jwt') {
|
||||
userUuid: payload.uuid,
|
||||
uuid: payload.uuid,
|
||||
sessionId: payload.sessionId,
|
||||
roles: payload?.roles,
|
||||
role: payload?.role,
|
||||
};
|
||||
} else {
|
||||
throw new BadRequestException('Unauthorized');
|
||||
|
@ -34,7 +34,7 @@ export class RefreshTokenStrategy extends PassportStrategy(
|
||||
userUuid: payload.uuid,
|
||||
uuid: payload.uuid,
|
||||
sessionId: payload.sessionId,
|
||||
roles: payload?.roles,
|
||||
role: payload?.role,
|
||||
};
|
||||
} else {
|
||||
throw new BadRequestException('Unauthorized');
|
||||
|
@ -1,4 +1,6 @@
|
||||
export enum RoleType {
|
||||
SUPER_ADMIN = 'SUPER_ADMIN',
|
||||
ADMIN = 'ADMIN',
|
||||
SPACE_OWNER = 'SPACE_OWNER',
|
||||
SPACE_MEMBER = 'SPACE_MEMBER',
|
||||
}
|
||||
|
@ -19,7 +19,12 @@ export class RoleTypeSeeder {
|
||||
if (!roleTypeNames.includes(RoleType.ADMIN)) {
|
||||
missingRoleTypes.push(RoleType.ADMIN);
|
||||
}
|
||||
|
||||
if (!roleTypeNames.includes(RoleType.SPACE_OWNER)) {
|
||||
missingRoleTypes.push(RoleType.SPACE_OWNER);
|
||||
}
|
||||
if (!roleTypeNames.includes(RoleType.SPACE_MEMBER)) {
|
||||
missingRoleTypes.push(RoleType.SPACE_MEMBER);
|
||||
}
|
||||
if (missingRoleTypes.length > 0) {
|
||||
await this.addRoleTypeData(missingRoleTypes);
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { UserRepository } from '@app/common/modules/user/repositories';
|
||||
import { RoleType } from '@app/common/constants/role.type.enum';
|
||||
import { UserRoleRepository } from '@app/common/modules/user/repositories';
|
||||
import { RoleTypeRepository } from '@app/common/modules/role-type/repositories';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
import { HelperHashService } from '../../helper/services';
|
||||
@ -11,19 +10,23 @@ export class SuperAdminSeeder {
|
||||
constructor(
|
||||
private readonly configService: ConfigService,
|
||||
private readonly userRepository: UserRepository,
|
||||
private readonly userRoleRepository: UserRoleRepository,
|
||||
private readonly roleTypeRepository: RoleTypeRepository,
|
||||
private readonly helperHashService: HelperHashService,
|
||||
) {}
|
||||
|
||||
async createSuperAdminIfNotFound(): Promise<void> {
|
||||
try {
|
||||
const superAdminData = await this.userRoleRepository.find({
|
||||
where: { roleType: { type: RoleType.SUPER_ADMIN } },
|
||||
const superAdmin = await this.userRepository.findOne({
|
||||
where: {
|
||||
roleType: { type: RoleType.SUPER_ADMIN },
|
||||
email: this.configService.get<string>(
|
||||
'super-admin.SUPER_ADMIN_EMAIL',
|
||||
),
|
||||
},
|
||||
relations: ['roleType'],
|
||||
});
|
||||
|
||||
if (superAdminData.length <= 0) {
|
||||
if (!superAdmin) {
|
||||
// Create the super admin user if not found
|
||||
console.log('Creating super admin user...');
|
||||
|
||||
@ -48,20 +51,16 @@ export class SuperAdminSeeder {
|
||||
salt,
|
||||
);
|
||||
try {
|
||||
const user = await this.userRepository.save({
|
||||
const defaultUserRoleUuid = await this.getRoleUuidByRoleType(
|
||||
RoleType.SUPER_ADMIN,
|
||||
);
|
||||
await this.userRepository.save({
|
||||
email: this.configService.get<string>('super-admin.SUPER_ADMIN_EMAIL'),
|
||||
password: hashedPassword,
|
||||
firstName: 'Super',
|
||||
lastName: 'Admin',
|
||||
isUserVerified: true,
|
||||
isActive: true,
|
||||
});
|
||||
const defaultUserRoleUuid = await this.getRoleUuidByRoleType(
|
||||
RoleType.SUPER_ADMIN,
|
||||
);
|
||||
|
||||
await this.userRoleRepository.save({
|
||||
user: { uuid: user.uuid },
|
||||
roleType: { uuid: defaultUserRoleUuid },
|
||||
});
|
||||
} catch (err) {
|
||||
|
@ -7,11 +7,12 @@ export class AdminRoleGuard extends AuthGuard('jwt') {
|
||||
if (err || !user) {
|
||||
throw err || new UnauthorizedException();
|
||||
} else {
|
||||
const isAdmin = user.roles.some(
|
||||
(role) =>
|
||||
role.type === RoleType.SUPER_ADMIN || role.type === RoleType.ADMIN,
|
||||
);
|
||||
if (!isAdmin) {
|
||||
if (
|
||||
!(
|
||||
user.role.type === RoleType.ADMIN ||
|
||||
user.role.type === RoleType.SUPER_ADMIN
|
||||
)
|
||||
) {
|
||||
throw new BadRequestException('Only admin role can access this route');
|
||||
}
|
||||
}
|
||||
|
@ -20,10 +20,10 @@ export class CommunityPermissionGuard implements CanActivate {
|
||||
|
||||
if (
|
||||
user &&
|
||||
user.roles &&
|
||||
user.roles.some(
|
||||
(role) =>
|
||||
role.type === RoleType.ADMIN || role.type === RoleType.SUPER_ADMIN,
|
||||
user.role &&
|
||||
!(
|
||||
user.role.type === RoleType.ADMIN ||
|
||||
user.role.type === RoleType.SUPER_ADMIN
|
||||
)
|
||||
) {
|
||||
return true;
|
||||
|
@ -7,10 +7,7 @@ export class SuperAdminRoleGuard extends AuthGuard('jwt') {
|
||||
if (err || !user) {
|
||||
throw err || new UnauthorizedException();
|
||||
} else {
|
||||
const isSuperAdmin = user.roles.some(
|
||||
(role) => role.type === RoleType.SUPER_ADMIN,
|
||||
);
|
||||
if (!isSuperAdmin) {
|
||||
if (!(user.role.type === RoleType.SUPER_ADMIN)) {
|
||||
throw new BadRequestException(
|
||||
'Only super admin role can access this route',
|
||||
);
|
||||
|
@ -36,19 +36,4 @@ export class RoleController {
|
||||
data: roleTypes,
|
||||
};
|
||||
}
|
||||
|
||||
@ApiBearerAuth()
|
||||
@UseGuards(SuperAdminRoleGuard)
|
||||
@Post()
|
||||
@ApiOperation({
|
||||
summary: ControllerRoute.ROLE.ACTIONS.ADD_USER_ROLE_SUMMARY,
|
||||
description: ControllerRoute.ROLE.ACTIONS.ADD_USER_ROLE_DESCRIPTION,
|
||||
})
|
||||
async addUserRoleType(@Body() addUserRoleDto: AddUserRoleDto) {
|
||||
await this.roleService.addUserRoleType(addUserRoleDto);
|
||||
return {
|
||||
statusCode: HttpStatus.OK,
|
||||
message: 'User Role Added Successfully',
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,6 @@ import { RoleController } from './controllers/role.controller';
|
||||
import { DeviceUserPermissionRepository } from '@app/common/modules/device/repositories';
|
||||
import { PermissionTypeRepository } from '@app/common/modules/permission/repositories';
|
||||
import { RoleTypeRepository } from '@app/common/modules/role-type/repositories';
|
||||
import { UserRoleRepository } from '@app/common/modules/user/repositories';
|
||||
|
||||
@Module({
|
||||
imports: [ConfigModule, DeviceRepositoryModule],
|
||||
@ -18,7 +17,6 @@ import { UserRoleRepository } from '@app/common/modules/user/repositories';
|
||||
DeviceRepository,
|
||||
RoleService,
|
||||
RoleTypeRepository,
|
||||
UserRoleRepository,
|
||||
],
|
||||
exports: [RoleService],
|
||||
})
|
||||
|
@ -1,55 +1,16 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { RoleTypeRepository } from './../../../libs/common/src/modules/role-type/repositories/role.type.repository';
|
||||
import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
|
||||
import { AddUserRoleDto } from '../dtos/role.add.dto';
|
||||
import { UserRoleRepository } from '@app/common/modules/user/repositories';
|
||||
import { QueryFailedError } from 'typeorm';
|
||||
import { CommonErrorCodes } from '@app/common/constants/error-codes.enum';
|
||||
import { RoleType } from '@app/common/constants/role.type.enum';
|
||||
|
||||
@Injectable()
|
||||
export class RoleService {
|
||||
constructor(
|
||||
private readonly roleTypeRepository: RoleTypeRepository,
|
||||
private readonly userRoleRepository: UserRoleRepository,
|
||||
) {}
|
||||
|
||||
async addUserRoleType(addUserRoleDto: AddUserRoleDto) {
|
||||
try {
|
||||
const roleType = await this.fetchRoleByType(addUserRoleDto.roleType);
|
||||
|
||||
if (roleType.uuid) {
|
||||
return await this.userRoleRepository.save({
|
||||
user: { uuid: addUserRoleDto.userUuid },
|
||||
roleType: { uuid: roleType.uuid },
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
if (
|
||||
error instanceof QueryFailedError &&
|
||||
error.driverError.code === CommonErrorCodes.DUPLICATE_ENTITY
|
||||
) {
|
||||
// Postgres unique constraint violation error code
|
||||
throw new HttpException(
|
||||
'This role already exists for this user',
|
||||
HttpStatus.CONFLICT,
|
||||
);
|
||||
}
|
||||
throw new HttpException(
|
||||
error.message || 'Internal Server Error',
|
||||
HttpStatus.INTERNAL_SERVER_ERROR,
|
||||
);
|
||||
}
|
||||
}
|
||||
constructor(private readonly roleTypeRepository: RoleTypeRepository) {}
|
||||
|
||||
async fetchRoleTypes() {
|
||||
const roleTypes = await this.roleTypeRepository.find();
|
||||
|
||||
return roleTypes;
|
||||
}
|
||||
private async fetchRoleByType(roleType: string) {
|
||||
return await this.roleTypeRepository.findOne({
|
||||
where: {
|
||||
type: roleType,
|
||||
},
|
||||
});
|
||||
const roles = roleTypes.filter(
|
||||
(roleType) => roleType.type !== RoleType.SUPER_ADMIN,
|
||||
);
|
||||
return roles;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user