Skip to content

Commit feb593d

Browse files
authored
Merge pull request #1018 from refly-ai/fix/template-list-auth
feat: add OptionalJwtAuthGuard to listCanvasTemplates endpoint for en…
2 parents 28eb9a7 + b8cf2d7 commit feb593d

File tree

2 files changed

+71
-0
lines changed

2 files changed

+71
-0
lines changed
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import { Injectable, CanActivate, ExecutionContext, Logger } from '@nestjs/common';
2+
import { Request } from 'express';
3+
import { ConfigService } from '@nestjs/config';
4+
import { JwtService } from '@nestjs/jwt';
5+
import { ACCESS_TOKEN_COOKIE } from '@refly/utils';
6+
import { isDesktop } from '../../../utils/runtime';
7+
8+
@Injectable()
9+
export class OptionalJwtAuthGuard implements CanActivate {
10+
private readonly logger = new Logger(OptionalJwtAuthGuard.name);
11+
12+
constructor(
13+
private jwtService: JwtService,
14+
private configService: ConfigService,
15+
) {}
16+
17+
async canActivate(context: ExecutionContext): Promise<boolean> {
18+
const request: Request = context.switchToHttp().getRequest();
19+
20+
// If we are in desktop mode, we don't need to check the JWT token
21+
if (isDesktop()) {
22+
request.user = { uid: this.configService.get('local.uid') };
23+
return true;
24+
}
25+
26+
const token = this.extractTokenFromRequest(request);
27+
if (!token) {
28+
// No token found, but we allow the request to proceed
29+
// The user will be null in the controller
30+
request.user = null;
31+
return true;
32+
}
33+
34+
try {
35+
const payload = await this.jwtService.verifyAsync(token, {
36+
secret: this.configService.get('auth.jwt.secret'),
37+
});
38+
39+
// 💡 We're assigning the payload to the request object here
40+
// so that we can access it in our route handlers
41+
request.user = payload;
42+
} catch (error) {
43+
this.logger.warn(`jwt verify not valid: ${error}`);
44+
// Token is invalid, but we still allow the request to proceed
45+
// The user will be null in the controller
46+
request.user = null;
47+
}
48+
return true;
49+
}
50+
51+
private extractTokenFromRequest(request: Request): string | undefined {
52+
// Try to get token from Authorization header
53+
const authHeader = request.headers?.authorization;
54+
if (authHeader) {
55+
const [type, token] = authHeader.split(' ');
56+
if (type === 'Bearer') {
57+
return token;
58+
}
59+
}
60+
61+
// Try to get token from cookie
62+
const token = request.cookies?.[ACCESS_TOKEN_COOKIE];
63+
if (token) {
64+
return token;
65+
}
66+
67+
return undefined;
68+
}
69+
}

apps/api/src/modules/template/template.controller.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
ParseIntPipe,
1010
} from '@nestjs/common';
1111
import { JwtAuthGuard } from '../auth/guard/jwt-auth.guard';
12+
import { OptionalJwtAuthGuard } from '../auth/guard/optional-jwt-auth.guard';
1213
import { LoginedUser } from '../../utils/decorators/user.decorator';
1314
import { canvasTemplateCategoryPO2DTO, canvasTemplatePO2DTO } from './template.dto';
1415
import { buildSuccessResponse } from '../../utils';
@@ -23,6 +24,7 @@ import { TemplateService } from './template.service';
2324
export class TemplateController {
2425
constructor(private templateService: TemplateService) {}
2526

27+
@UseGuards(OptionalJwtAuthGuard)
2628
@Get('list')
2729
async listCanvasTemplates(
2830
@LoginedUser() user: User | null,

0 commit comments

Comments
 (0)