Skip to content

Commit 23c8759

Browse files
committed
Get user from the request
1 parent 3e2ebbd commit 23c8759

File tree

3 files changed

+73
-17
lines changed

3 files changed

+73
-17
lines changed

backend/src/app.module.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Module, NestModule } from '@nestjs/common';
1+
import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common';
22
import { ConfigModule } from '@nestjs/config';
33
import configuration from './config/configuration';
44
import { AppController } from './app.controller';
@@ -9,6 +9,8 @@ import { PerplexityController } from './controllers/perplexity/perplexity.contro
99
import { UserController } from './user/user.controller';
1010
import { ReportsModule } from './reports/reports.module';
1111
import { HealthController } from './health/health.controller';
12+
import { AuthMiddleware } from './auth/auth.middleware';
13+
1214
@Module({
1315
imports: [
1416
ConfigModule.forRoot({
@@ -21,8 +23,9 @@ import { HealthController } from './health/health.controller';
2123
providers: [AppService, AwsSecretsService, PerplexityService],
2224
})
2325
export class AppModule implements NestModule {
24-
configure() {
25-
// Add your middleware configuration here if needed
26-
// If you don't need middleware, you can leave this empty
26+
configure(consumer: MiddlewareConsumer) {
27+
consumer
28+
.apply(AuthMiddleware)
29+
.forRoutes('*'); // Apply to all routes
2730
}
2831
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import { Injectable, NestMiddleware } from '@nestjs/common';
2+
import { Request, Response, NextFunction } from 'express';
3+
import { ConfigService } from '@nestjs/config';
4+
import * as jwt from 'jsonwebtoken';
5+
6+
// Extend the Express Request interface to include the user property
7+
export interface RequestWithUser extends Request {
8+
user?: {
9+
sub: string;
10+
email?: string;
11+
groups?: string[];
12+
[key: string]: any;
13+
} | null;
14+
}
15+
16+
@Injectable()
17+
export class AuthMiddleware implements NestMiddleware {
18+
constructor(private configService: ConfigService) {}
19+
20+
use(req: RequestWithUser, res: Response, next: NextFunction) {
21+
const authHeader = req.headers.authorization;
22+
23+
if (authHeader && authHeader.startsWith('Bearer ')) {
24+
const token = authHeader.substring(7);
25+
try {
26+
// Verify the JWT token
27+
const decoded = jwt.verify(token, this.configService.get('JWT_SECRET') || 'dev-secret');
28+
29+
// Attach the decoded user to the request
30+
req.user = {
31+
sub: decoded.sub as string,
32+
};
33+
} catch (error) {
34+
// If token verification fails, set user to null
35+
req.user = null;
36+
}
37+
} else {
38+
// No token provided
39+
req.user = null;
40+
}
41+
42+
next();
43+
}
44+
}

backend/src/reports/reports.controller.ts

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,14 @@
1-
import { Controller, Get, Patch, Param, Body, Query, ValidationPipe, Req } from '@nestjs/common';
1+
import {
2+
Controller,
3+
Get,
4+
Patch,
5+
Param,
6+
Body,
7+
Query,
8+
ValidationPipe,
9+
Req,
10+
UnauthorizedException,
11+
} from '@nestjs/common';
212
import {
313
ApiTags,
414
ApiOperation,
@@ -11,7 +21,7 @@ import { ReportsService } from './reports.service';
1121
import { Report } from './models/report.model';
1222
import { GetReportsQueryDto } from './dto/get-reports.dto';
1323
import { UpdateReportStatusDto } from './dto/update-report-status.dto';
14-
import { Request } from 'express';
24+
import { RequestWithUser } from '../auth/auth.middleware';
1525

1626
@ApiTags('reports')
1727
@Controller('reports')
@@ -22,19 +32,19 @@ export class ReportsController {
2232
@ApiOperation({ summary: 'Get all reports' })
2333
@ApiResponse({
2434
status: 200,
25-
description: 'Returns all reports',
35+
description: 'Returns all reports for the authenticated user',
2636
type: [Report],
2737
})
2838
@Get()
29-
async findAll(@Req() request: Request): Promise<Report[]> {
39+
async findAll(@Req() request: RequestWithUser): Promise<Report[]> {
3040
const userId = this.extractUserId(request);
3141
return this.reportsService.findAll(userId);
3242
}
3343

3444
@ApiOperation({ summary: 'Get latest reports' })
3545
@ApiResponse({
3646
status: 200,
37-
description: 'Returns the latest reports',
47+
description: 'Returns the latest reports for the authenticated user',
3848
type: [Report],
3949
})
4050
@ApiQuery({
@@ -45,7 +55,7 @@ export class ReportsController {
4555
@Get('latest')
4656
async findLatest(
4757
@Query(ValidationPipe) queryDto: GetReportsQueryDto,
48-
@Req() request: Request,
58+
@Req() request: RequestWithUser,
4959
): Promise<Report[]> {
5060
const userId = this.extractUserId(request);
5161
return this.reportsService.findLatest(queryDto, userId);
@@ -66,7 +76,7 @@ export class ReportsController {
6676
description: 'Report ID',
6777
})
6878
@Get(':id')
69-
async getReport(@Param('id') id: string, @Req() request: Request): Promise<Report> {
79+
async getReport(@Param('id') id: string, @Req() request: RequestWithUser): Promise<Report> {
7080
const userId = this.extractUserId(request);
7181
return this.reportsService.findOne(id, userId);
7282
}
@@ -89,19 +99,18 @@ export class ReportsController {
8999
async updateStatus(
90100
@Param('id') id: string,
91101
@Body(ValidationPipe) updateDto: UpdateReportStatusDto,
92-
@Req() request: Request,
102+
@Req() request: RequestWithUser,
93103
): Promise<Report> {
94104
const userId = this.extractUserId(request);
95105
return this.reportsService.updateStatus(id, updateDto, userId);
96106
}
97107

98-
private extractUserId(request: Request): string {
99-
console.log(request);
100-
// The user object is attached to the request by the AuthGuard
101-
const user = request.user as any;
108+
private extractUserId(request: RequestWithUser): string {
109+
// The user object is attached to the request by our middleware
110+
const user = request.user;
102111

103112
if (!user || !user.sub) {
104-
throw new Error('User ID not found in token');
113+
throw new UnauthorizedException('User ID not found in request');
105114
}
106115

107116
return user.sub;

0 commit comments

Comments
 (0)