Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
3e83779
refactor: improve role comparison logic in RoleGuard
Bikilaketema Mar 27, 2025
7d96024
fix es-lint error
Bikilaketema Mar 27, 2025
8dc7783
add Admin role to seed data
Bikilaketema Mar 27, 2025
e7693d8
refactor: remove unused User import in RoleGuard
Bikilaketema Mar 27, 2025
b3610a9
Merge branch 'bug/fixed-role-guard-problem' into feature/allow-admin-…
Bikilaketema Mar 27, 2025
6bc26f6
feat: enhance admin access by adding RoleGuard and supporting ADMIN r…
Bikilaketema Mar 27, 2025
43b9f7d
add isActive field to User model with default value true
Bikilaketema Mar 27, 2025
5f0af5a
Merge branch 'feature/added-admin-role-to-seed.ts' into feature/add-g…
Bikilaketema Mar 27, 2025
55c221f
Merge branch 'bug/fixed-role-guard-problem' into feature/add-get-and-…
Bikilaketema Mar 27, 2025
7a8a033
Merge branch 'feature/allow-admin-to-manage-mentors-and-channels' int…
Bikilaketema Mar 27, 2025
5366a8f
feat: add AdminProfile module with controller, service, and DTOs for …
Bikilaketema Mar 27, 2025
418a3d5
refactor: clean up code formatting and improve readability in AdminPr…
Bikilaketema Mar 27, 2025
53f3ae4
fix: improve role guard logic to support multiple user accounts
Bikilaketema Mar 28, 2025
4bafee3
feat: enhance admin profile management with account-based user activa…
Bikilaketema Mar 28, 2025
0cf541c
feat: update User entity to include optional fields and enhance role …
Bikilaketema Mar 28, 2025
ce94153
fix: remove debug logging from RoleGuard to clean up code
Bikilaketema Mar 28, 2025
bd8fba2
fix: change User entity id field from optional to required
Bikilaketema Mar 28, 2025
918715b
fix: update User entity to remove optional sub field and adjust AuthG…
Bikilaketema Mar 28, 2025
b5f4937
feat: enhance RoleGuard to throw exceptions for inactive accounts and…
Bikilaketema Mar 28, 2025
90bccfe
fix: remove debug logging from RoleGuard to improve code clarity
Bikilaketema Mar 28, 2025
3805a22
fix: update route parameter for findAll method in AdminProfileController
Bikilaketema Mar 29, 2025
faa2e05
feat: add Role module with controller, service, and DTOs for role man…
Bikilaketema Mar 29, 2025
a7dcb2b
feat: implement AdminProfile module with controller, service, DTOs, a…
Bikilaketema Mar 29, 2025
987fcb8
changed adminProfile to profile
Bikilaketema Apr 1, 2025
4765c49
refactor: rename AdminDto to ProfileDto and update roleName to role
Bikilaketema Apr 1, 2025
6d76a6c
fix es lint
Bikilaketema Apr 1, 2025
14c82bb
refactor: remove unnecessary comment from ProfileDto file
Bikilaketema Apr 1, 2025
ef70806
refactor: update ProfileService to use ProfileDto and add RoleDto for…
Bikilaketema Apr 1, 2025
e0c87ce
refactor: format code in RoleService for consistency
Bikilaketema Apr 1, 2025
7316949
refactor: rename RoleController to RolesController for consistency
Bikilaketema Apr 1, 2025
5e5e9f1
refactor: enhance ProfileService to filter by Admin role in account u…
Bikilaketema Apr 1, 2025
b61149e
removed the profile module and moved all logics to the user in admin …
Bikilaketema Apr 1, 2025
285b592
removed the admin profile
Bikilaketema Apr 1, 2025
04a939d
added the owner to returned admins list
Bikilaketema Apr 1, 2025
ec8f1b5
change the some to filter on active acccounts
Bikilaketema Apr 1, 2025
3324d52
fixed pr-comments
Bikilaketema Apr 2, 2025
9700cfb
fixed es lint error
Bikilaketema Apr 2, 2025
73fa9c8
dis-allwoed the owner from deactivating it's own account
Bikilaketema Apr 2, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
168 changes: 0 additions & 168 deletions prisma/migrations/20250218072627_init/migration.sql

This file was deleted.

1 change: 1 addition & 0 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ model AccountUser {
userId String
roleId String
accountId String
isActive Boolean @default(true)

deletedAt DateTime?
createdAt DateTime @default(now())
Expand Down
5 changes: 5 additions & 0 deletions prisma/seed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ async function seedBatchOne() {
type: RoleType.MENTOR,
isDefault: true,
},
{
name: 'Admin',
type: RoleType.ADMIN,
isDefault: true,
},
],
skipDuplicates: true, // Prevent duplicate seeding
});
Expand Down
2 changes: 2 additions & 0 deletions src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { MentorModule } from './modules/mentor/mentor.module';
import { ChatModule } from './modules/chat/chat.module';
import { RabbitmqModule } from './common/rabbitmq/rabbitmq.module';
import { MessageModule } from './modules/message/message.module';
import { RoleModule } from './modules/admin/role/role.module';

@Module({
imports: [
Expand All @@ -25,6 +26,7 @@ import { MessageModule } from './modules/message/message.module';
ChatModule,
RabbitmqModule,
MessageModule,
RoleModule,
],
providers: [PrismaService],
controllers: [],
Expand Down
5 changes: 3 additions & 2 deletions src/modules/admin/channel/channel.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@ import { UpdateChannelDto } from './dto/update-channel.dto';
import { GetChannelDto } from './dto/get-channel.dto';
import { Roles } from 'src/modules/auth/auth.decorator';
import { AuthGuard } from 'src/modules/auth/guard/auth/auth.guard';
import { RoleGuard } from 'src/modules/auth/guard/role/role.guard';

@Controller('admin/channel')
@UseGuards(AuthGuard)
@Roles('OWNER')
@UseGuards(AuthGuard, RoleGuard)
@Roles('OWNER', 'ADMIN')
export class ChannelController {
constructor(private readonly channelService: ChannelService) {}

Expand Down
5 changes: 3 additions & 2 deletions src/modules/admin/mentor/mentor.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,14 @@ import {
import { MentorService } from './mentor.service';
import { Roles } from 'src/modules/auth/auth.decorator';
import { AuthGuard } from 'src/modules/auth/guard/auth/auth.guard';
import { RoleGuard } from 'src/modules/auth/guard/role/role.guard';
import { GetMentorDto } from './dto/get-mentor.dto';
import { CreateMentorDto } from './dto/create-mentor.dto';
import { UpdateMentorDto } from './dto/update-mentor.dto';

@Controller('admin/mentor')
@UseGuards(AuthGuard)
@Roles('OWNER')
@UseGuards(AuthGuard, RoleGuard)
@Roles('OWNER', 'ADMIN')
export class MentorController {
constructor(private readonly mentorService: MentorService) {}

Expand Down
1 change: 1 addition & 0 deletions src/modules/admin/role/dto/create-role.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export class CreateRoleDto {}
20 changes: 20 additions & 0 deletions src/modules/admin/role/dto/role.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { Expose } from 'class-transformer';

export class RoleDto {
@Expose()
id: string;

@Expose()
name: string;

@Expose()
accountId: string;

constructor(partial: Partial<RoleDto>) {
Object.assign(this, {
id: partial.id,
name: partial.name,
accountId: partial.accountId,
});
}
}
4 changes: 4 additions & 0 deletions src/modules/admin/role/dto/update-role.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { PartialType } from '@nestjs/mapped-types';
import { CreateRoleDto } from './create-role.dto';

export class UpdateRoleDto extends PartialType(CreateRoleDto) {}
1 change: 1 addition & 0 deletions src/modules/admin/role/entities/role.entity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export class Role {}
20 changes: 20 additions & 0 deletions src/modules/admin/role/role.controller.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { Test, TestingModule } from '@nestjs/testing';
import { RolesController } from './role.controller';
import { RoleService } from './role.service';

describe('RolesController', () => {
let controller: RolesController;

beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [RolesController],
providers: [RoleService],
}).compile();

controller = module.get<RolesController>(RolesController);
});

it('should be defined', () => {
expect(controller).toBeDefined();
});
});
18 changes: 18 additions & 0 deletions src/modules/admin/role/role.controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Controller, Get, UseGuards } from '@nestjs/common';
import { RoleGuard } from '../../auth/guard/role/role.guard';
import { Roles } from '../../auth/auth.decorator';
import { RoleService } from './role.service';
import { AuthGuard } from 'src/modules/auth/guard/auth/auth.guard';

@Controller('roles')
@UseGuards(AuthGuard)
export class RolesController {
constructor(private readonly roleService: RoleService) {}

@Get('')
@UseGuards(RoleGuard)
@Roles('OWNER', 'ADMIN')
findAll() {
return this.roleService.findAll();
}
}
11 changes: 11 additions & 0 deletions src/modules/admin/role/role.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { Module } from '@nestjs/common';
import { RoleService } from './role.service';
import { RolesController } from './role.controller';
import { PrismaService } from 'src/modules/prisma/prisma.service';
import { JwtService } from '@nestjs/jwt';

@Module({
controllers: [RolesController],
providers: [RoleService, PrismaService, JwtService],
})
export class RoleModule {}
18 changes: 18 additions & 0 deletions src/modules/admin/role/role.service.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Test, TestingModule } from '@nestjs/testing';
import { RoleService } from './role.service';

describe('RoleService', () => {
let service: RoleService;

beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [RoleService],
}).compile();

service = module.get<RoleService>(RoleService);
});

it('should be defined', () => {
expect(service).toBeDefined();
});
});
19 changes: 19 additions & 0 deletions src/modules/admin/role/role.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { Injectable } from '@nestjs/common';
import { PrismaService } from '../../prisma/prisma.service';
import { RoleDto } from './dto/role.dto';

@Injectable()
export class RoleService {
constructor(private readonly prisma: PrismaService) {}

async findAll(): Promise<RoleDto[]> {
const roles = await this.prisma.role.findMany({
select: {
id: true,
name: true,
accountId: true,
},
});
return roles.map((role) => new RoleDto(role));
}
}
3 changes: 2 additions & 1 deletion src/modules/admin/user/dto/create-user.dto.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { IsEmail, IsString } from 'class-validator';
import { IsEmail, IsOptional, IsString } from 'class-validator';

export class CreateUserDto {
@IsString()
Expand All @@ -10,5 +10,6 @@ export class CreateUserDto {
@IsEmail()
email: string;
@IsString()
@IsOptional()
password: string;
}
24 changes: 24 additions & 0 deletions src/modules/admin/user/dto/get-all-users-query.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { IsInt, IsOptional, Min, IsString } from 'class-validator';
import { Type } from 'class-transformer';

export class GetAllUsersQueryDto {
@IsOptional()
@IsString()
accountId?: string;

@IsOptional()
@IsString()
roleId?: string;

@IsOptional()
@Type(() => Number)
@IsInt()
@Min(1)
page?: number = 1;

@IsOptional()
@Type(() => Number)
@IsInt()
@Min(1)
limit?: number = 10;
}
Loading