diff --git a/backend/src/app.module.ts b/backend/src/app.module.ts index 433e6a0..7915b79 100644 --- a/backend/src/app.module.ts +++ b/backend/src/app.module.ts @@ -1,5 +1,6 @@ import { Module } from '@nestjs/common'; import { ConfigModule } from '@nestjs/config'; +import { APP_GUARD } from '@nestjs/core'; import { AppController } from './app.controller'; import { AppService } from './app.service'; import { DatabaseModule } from './database/database.module'; @@ -8,6 +9,7 @@ import { ProjectsModule } from './modules/projects/projects.module'; import { AuthModule } from './modules/auth/auth.module'; import { GroupsModule } from './modules/groups/groups.module'; import { TagsModule } from './modules/tags/tags.module'; +import { JwtAuthGuard } from './modules/auth/guards/jwt-auth.guard'; @Module({ imports: [ @@ -23,6 +25,12 @@ import { TagsModule } from './modules/tags/tags.module'; TagsModule, ], controllers: [AppController], - providers: [AppService], + providers: [ + AppService, + { + provide: APP_GUARD, + useClass: JwtAuthGuard, + }, + ], }) export class AppModule {} diff --git a/backend/src/modules/auth/controllers/auth.controller.ts b/backend/src/modules/auth/controllers/auth.controller.ts index c18138d..3088212 100644 --- a/backend/src/modules/auth/controllers/auth.controller.ts +++ b/backend/src/modules/auth/controllers/auth.controller.ts @@ -16,6 +16,7 @@ import { GithubAuthGuard } from '../guards/github-auth.guard'; import { JwtAuthGuard } from '../guards/jwt-auth.guard'; import { JwtRefreshGuard } from '../guards/jwt-refresh.guard'; import { GetUser } from '../decorators/get-user.decorator'; +import { Public } from '../decorators/public.decorator'; @Controller('auth') export class AuthController { @@ -27,6 +28,7 @@ export class AuthController { /** * Initiate GitHub OAuth flow */ + @Public() @Get('github') @UseGuards(GithubAuthGuard) githubAuth() { @@ -37,6 +39,7 @@ export class AuthController { /** * Handle GitHub OAuth callback */ + @Public() @Get('github/callback') @UseGuards(GithubAuthGuard) async githubAuthCallback(@Req() req: Request, @Res() res: Response) { @@ -61,6 +64,7 @@ export class AuthController { /** * Refresh tokens */ + @Public() @Post('refresh') @UseGuards(JwtRefreshGuard) async refreshTokens(@GetUser() user) { diff --git a/backend/src/modules/auth/decorators/public.decorator.ts b/backend/src/modules/auth/decorators/public.decorator.ts new file mode 100644 index 0000000..ee683d0 --- /dev/null +++ b/backend/src/modules/auth/decorators/public.decorator.ts @@ -0,0 +1,14 @@ +import { SetMetadata } from '@nestjs/common'; + +/** + * Key for the public metadata + */ +export const IS_PUBLIC_KEY = 'isPublic'; + +/** + * Decorator to mark a route as public (not requiring authentication) + * + * Usage: + * - @Public() - Mark a route as public + */ +export const Public = () => SetMetadata(IS_PUBLIC_KEY, true); \ No newline at end of file diff --git a/backend/src/modules/auth/guards/jwt-auth.guard.ts b/backend/src/modules/auth/guards/jwt-auth.guard.ts index 4df3ddd..1051b17 100644 --- a/backend/src/modules/auth/guards/jwt-auth.guard.ts +++ b/backend/src/modules/auth/guards/jwt-auth.guard.ts @@ -1,11 +1,33 @@ -import { Injectable, UnauthorizedException } from '@nestjs/common'; +import { Injectable, UnauthorizedException, ExecutionContext } from '@nestjs/common'; import { AuthGuard } from '@nestjs/passport'; +import { Reflector } from '@nestjs/core'; +import { IS_PUBLIC_KEY } from '../decorators/public.decorator'; /** * Guard for JWT authentication */ @Injectable() export class JwtAuthGuard extends AuthGuard('jwt') { + constructor(private reflector: Reflector) { + super(); + } + + /** + * Check if the route is public or requires authentication + */ + canActivate(context: ExecutionContext) { + const isPublic = this.reflector.getAllAndOverride(IS_PUBLIC_KEY, [ + context.getHandler(), + context.getClass(), + ]); + + if (isPublic) { + return true; + } + + return super.canActivate(context); + } + /** * Handle unauthorized errors */ @@ -15,4 +37,4 @@ export class JwtAuthGuard extends AuthGuard('jwt') { } return user; } -} \ No newline at end of file +}