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
17 changes: 2 additions & 15 deletions src/auth/auth.module.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,10 @@
import { Module } from '@nestjs/common';
import { PassportModule } from '@nestjs/passport';
import { JwtStrategy } from '@/common/guards/keycloak.strategy';
import { RbacJwtStrategy } from '@/common/guards/rbac.strategy';

/**
* Auth module — mirrors user-microservice auth pattern.
*
* Auth flow:
* 1. User authenticates via user-microservice (Keycloak login → /auth/login)
* 2. User gets RBAC token from user-microservice (/auth/rbac/token)
* 3. Survey service validates both tokens:
* - Authorization: Bearer <keycloak_jwt> → validated by JwtStrategy (RSA public key)
* - rbac_token: <rbac_jwt> → validated by RbacJwtStrategy (RBAC_JWT_SECRET)
*
* No login/logout endpoints here — those live in user-microservice.
*/
@Module({
imports: [PassportModule],
providers: [JwtStrategy, RbacJwtStrategy],
exports: [JwtStrategy, RbacJwtStrategy],
providers: [JwtStrategy],
exports: [JwtStrategy],
})
export class AuthModule {}
8 changes: 6 additions & 2 deletions src/common/guards/keycloak.strategy.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
import { ExtractJwt, Strategy } from 'passport-jwt';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable } from '@nestjs/common';
import { Injectable, Logger } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy, 'jwt-keycloak') {
constructor(configService: ConfigService) {
const publicKey = configService.get('KEYCLOAK_REALM_RSA_PUBLIC_KEY');
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The ConfigService should access the configuration using the namespaced key 'auth.keycloakRsaPublicKey' as defined in src/config/auth.config.ts. This ensures consistency with the application's configuration pattern and leverages the default values or transformations defined in the configuration file. Additionally, providing the type parameter <string> improves type safety.

Suggested change
const publicKey = configService.get('KEYCLOAK_REALM_RSA_PUBLIC_KEY');
const publicKey = configService.get<string>('auth.keycloakRsaPublicKey');

new Logger('JwtStrategy').log(
`KEYCLOAK_REALM_RSA_PUBLIC_KEY loaded: ${publicKey ? publicKey.substring(0, 80) + '...' : 'NOT SET / EMPTY'}`,
);
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
ignoreExpiration: false,
secretOrKey: configService.get('KEYCLOAK_REALM_RSA_PUBLIC_KEY'),
secretOrKey: publicKey,
});
}

Expand Down
30 changes: 0 additions & 30 deletions src/common/guards/rbac.guard.ts

This file was deleted.

48 changes: 0 additions & 48 deletions src/common/guards/rbac.strategy.ts

This file was deleted.

5 changes: 0 additions & 5 deletions src/config/auth.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,6 @@ export default registerAs('auth', () => ({
// Keycloak JWT validation
keycloakRsaPublicKey: process.env.KEYCLOAK_REALM_RSA_PUBLIC_KEY || '',

// RBAC JWT validation
rbacJwtSecret: process.env.RBAC_JWT_SECRET || '',
rbacIssuer: process.env.RBAC_JWT_ISSUER || 'survey-service',
rbacAudience: process.env.RBAC_JWT_AUDIENCE || 'survey-service',

// Legacy (kept for backward compatibility)
jwtSecret: process.env.JWT_SECRET || 'default-secret-change-me',
jwtExpiration: parseInt(process.env.JWT_EXPIRATION || '3600', 10),
Expand Down
1 change: 0 additions & 1 deletion src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ async function bootstrap() {
'Authorization',
'tenantid',
'academicyearid',
'rbac_token',
],
});

Expand Down