Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
60 changes: 0 additions & 60 deletions backend/docs/RBAC.md

This file was deleted.

3 changes: 1 addition & 2 deletions backend/src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ import {
ApiVersionService,
} from './common/versioning';
import { DocsController } from './docs/docs.controller';
import { RolesGuard } from './roles/roles.guard';

// const ENV = process.env.NODE_ENV;
// console.log('NODE_ENV:', process.env.NODE_ENV);
Expand Down Expand Up @@ -110,7 +109,7 @@ import { RolesGuard } from './roles/roles.guard';
HealthModule,
],
controllers: [AppController, DocsController],
providers: [AppService, ApiVersionService, RolesGuard],
providers: [AppService, ApiVersionService],
})
export class AppModule implements NestModule {
/**
Expand Down
5 changes: 0 additions & 5 deletions backend/src/auth/interfaces/activeInterface.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,8 @@
import { userRole } from '../../users/enums/userRole.enum';

/**Active user data interface */
export interface ActiveUserData {
/**sub of type number */
sub: string;

/**email of type string */
email?: string;

/**authenticated user role */
userRole?: userRole;
}
5 changes: 2 additions & 3 deletions backend/src/auth/middleware/jwt-auth.middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import {
} from '@nestjs/common';
import { Request, Response, NextFunction } from 'express';
import * as jwt from 'jsonwebtoken';
import { userRole } from '../../users/enums/userRole.enum';

/**
* Interface for the Redis client to support token blacklisting.
Expand Down Expand Up @@ -41,7 +40,7 @@ export interface JwtAuthMiddlewareOptions {
export interface DecodedUserPayload {
userId: string;
email: string;
userRole: userRole;
userRole: string;
[key: string]: any;
}

Expand Down Expand Up @@ -125,7 +124,7 @@ export class JwtAuthMiddleware implements NestMiddleware {
const userPayload: DecodedUserPayload = {
userId,
email: decoded.email,
userRole: (decoded.userRole || decoded.role || userRole.USER) as userRole,
userRole: decoded.userRole || decoded.role,
};

if (!userPayload.userId || !userPayload.email) {
Expand Down
5 changes: 0 additions & 5 deletions backend/src/progress/controllers/progress.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@ import { CategoryStatsDto } from '../dtos/category-stats.dto';
import { OverallStatsDto } from '../dtos/overall-stats.dto';
import { ActiveUser } from '../../auth/decorators/activeUser.decorator';
import { ActiveUserData } from '../../auth/interfaces/activeInterface';
import { Roles } from '../../roles/roles.decorator';
import { userRole } from '../../users/enums/userRole.enum';

@Controller('progress')
@ApiTags('Progress')
Expand All @@ -37,7 +35,6 @@ export class ProgressController {
) {}

@Get()
@Roles(userRole.USER)
@ApiOperation({
summary: 'Get paginated progress history',
description:
Expand Down Expand Up @@ -65,7 +62,6 @@ export class ProgressController {
}

@Get('stats')
@Roles(userRole.USER)
@ApiOperation({
summary: 'Get overall user statistics',
description:
Expand All @@ -85,7 +81,6 @@ export class ProgressController {
}

@Get('category/:id')
@Roles(userRole.USER)
@ApiOperation({
summary: 'Get category-specific statistics',
description:
Expand Down
3 changes: 0 additions & 3 deletions backend/src/puzzles/controllers/puzzles-v1.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ import { PuzzlesService } from '../providers/puzzles.service';
import { CreatePuzzleDto } from '../dtos/create-puzzle.dto';
import { Puzzle } from '../entities/puzzle.entity';
import { PuzzleQueryDto } from '../dtos/puzzle-query.dto';
import { Roles } from '../../roles/roles.decorator';
import { userRole } from '../../users/enums/userRole.enum';

@Controller('puzzles')
@Version('1')
Expand All @@ -30,7 +28,6 @@ export class PuzzlesV1Controller {
constructor(private readonly puzzlesService: PuzzlesService) {}

@Post()
@Roles(userRole.ADMIN)
@ApiOperation({ summary: 'Create a new puzzle (v1 contract)' })
@ApiResponse({
status: 201,
Expand Down
3 changes: 0 additions & 3 deletions backend/src/puzzles/controllers/puzzles-v2.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@ import { PuzzlesService } from '../providers/puzzles.service';
import { CreatePuzzleDto } from '../dtos/create-puzzle.dto';
import { Puzzle } from '../entities/puzzle.entity';
import { PuzzleDifficulty } from '../enums/puzzle-difficulty.enum';
import { Roles } from '../../roles/roles.decorator';
import { userRole } from '../../users/enums/userRole.enum';

class PuzzleV2QueryDto {
@IsOptional()
Expand Down Expand Up @@ -102,7 +100,6 @@ export class PuzzlesV2Controller {
constructor(private readonly puzzlesService: PuzzlesService) {}

@Post()
@Roles(userRole.ADMIN)
@ApiOperation({ summary: 'Create a new puzzle (v2 contract)' })
@ApiResponse({
status: 201,
Expand Down
44 changes: 2 additions & 42 deletions backend/src/roles/roles.decorator.ts
Original file line number Diff line number Diff line change
@@ -1,45 +1,5 @@
import { applyDecorators, SetMetadata, UseGuards } from '@nestjs/common';
import { ApiBearerAuth, ApiForbiddenResponse } from '@nestjs/swagger';
import { SetMetadata } from '@nestjs/common';
import { userRole } from '../users/enums/userRole.enum';
import { RolesGuard } from './roles.guard';

export const ROLES_KEY = 'roles';

export interface OwnershipRequirement {
param: string;
userIdField?: string;
}

export interface RolesOptions {
roles: userRole[];
ownership?: OwnershipRequirement;
}

export function Roles(...roles: userRole[]): MethodDecorator & ClassDecorator;
export function Roles(
options: RolesOptions,
): MethodDecorator & ClassDecorator;
export function Roles(
...rolesOrOptions: [RolesOptions] | userRole[]
): MethodDecorator & ClassDecorator {
const options =
typeof rolesOrOptions[0] === 'object' && !Array.isArray(rolesOrOptions[0])
? (rolesOrOptions[0] as RolesOptions)
: ({
roles: rolesOrOptions as userRole[],
} satisfies RolesOptions);

const readableRoles = options.roles.map((role) => role.toUpperCase()).join(' or ');
const forbiddenMessage = options.ownership
? `Access denied. Required role: ${readableRoles} or ownership of this resource`
: `Access denied. Required role: ${readableRoles}`;

return applyDecorators(
SetMetadata(ROLES_KEY, options),
UseGuards(RolesGuard),
ApiBearerAuth(),
ApiForbiddenResponse({
description: forbiddenMessage,
}),
);
}
export const Roles = (...roles: userRole[]) => SetMetadata(ROLES_KEY, roles);
100 changes: 0 additions & 100 deletions backend/src/roles/roles.guard.spec.ts

This file was deleted.

Loading
Loading