diff --git a/prisma/migrations/20250604135348_add_is_admin_to_user/migration.sql b/prisma/migrations/20250604135348_add_is_admin_to_user/migration.sql new file mode 100644 index 0000000..7db3f39 --- /dev/null +++ b/prisma/migrations/20250604135348_add_is_admin_to_user/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE "User" ADD COLUMN "isAdmin" BOOLEAN NOT NULL DEFAULT false; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 6e8df3f..38206de 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -15,6 +15,7 @@ model User { pollsCreatedCount Int @default(0) pollsParticipatedCount Int @default(0) createdAt DateTime @default(now()) + isAdmin Boolean @default(false) createdPolls Poll[] @relation("PollAuthor") actions UserAction[] votes Vote[] diff --git a/src/poll/poll.service.ts b/src/poll/poll.service.ts index 0322c92..f099189 100644 --- a/src/poll/poll.service.ts +++ b/src/poll/poll.service.ts @@ -550,7 +550,7 @@ export class PollService { async deletePoll(pollId: number, worldID: string) { const user = await this.databaseService.user.findUnique({ where: { worldID }, - select: { id: true }, + select: { id: true, isAdmin: true }, }) if (!user) { throw new UserNotFoundException() @@ -561,7 +561,8 @@ export class PollService { if (!poll) { throw new PollNotFoundException() } - if (poll.authorUserId !== user.id) { + // Allow deletion if user is admin or if user is the poll author + if (!user.isAdmin && poll.authorUserId !== user.id) { throw new UnauthorizedActionException() } diff --git a/src/user/user.controller.ts b/src/user/user.controller.ts index bb5d869..74fbb92 100644 --- a/src/user/user.controller.ts +++ b/src/user/user.controller.ts @@ -71,4 +71,9 @@ export class UserController { async getUserCount(@Query() query: GetCountDto): Promise { return await this.userService.getUserCount(query) } + + @Get('listAdmins') + async listAdmins(): Promise { + return await this.userService.listAdmins() + } } diff --git a/src/user/user.dto.ts b/src/user/user.dto.ts index 7f95fe2..4af634a 100644 --- a/src/user/user.dto.ts +++ b/src/user/user.dto.ts @@ -40,6 +40,10 @@ export class UserDataResponseDto { @IsString() @IsOptional() name?: string | null + + @IsBoolean() + @IsNotEmpty() + isAdmin: boolean } export class GetUserActivitiesDto { diff --git a/src/user/user.service.ts b/src/user/user.service.ts index fc4d3d0..c405ad6 100644 --- a/src/user/user.service.ts +++ b/src/user/user.service.ts @@ -97,6 +97,7 @@ export class UserService { worldID: true, name: true, profilePicture: true, + isAdmin: true, pollsCreatedCount: true, pollsParticipatedCount: true, }, @@ -110,6 +111,7 @@ export class UserService { worldID: user.worldID, worldProfilePic: user.profilePicture, name: user.name, + isAdmin: user.isAdmin, } } @@ -456,4 +458,12 @@ export class UserService { return await this.databaseService.user.count({ where }) } + + async listAdmins(): Promise { + const admins = await this.databaseService.user.findMany({ + where: { isAdmin: true }, + select: { worldID: true }, + }) + return admins.map(admin => admin.worldID) + } }