Optimize metadata queries (#7013)
In this PR: 1. Refactor guards to avoid duplicated queries: WorkspaceAuthGuard and UserAuthGuard only check for existence of workspace and user in the request without querying the database
This commit is contained in:
committed by
Charles Bochet
parent
cf8b1161cc
commit
523df5398a
@ -1,27 +1,27 @@
|
||||
import {
|
||||
Injectable,
|
||||
CanActivate,
|
||||
ExecutionContext,
|
||||
Injectable,
|
||||
UnauthorizedException,
|
||||
} from '@nestjs/common';
|
||||
import { AuthGuard } from '@nestjs/passport';
|
||||
import { GqlExecutionContext } from '@nestjs/graphql';
|
||||
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
|
||||
import { getRequest } from 'src/utils/extract-request';
|
||||
|
||||
@Injectable()
|
||||
export class DemoEnvGuard extends AuthGuard(['jwt']) {
|
||||
constructor(private readonly environmentService: EnvironmentService) {
|
||||
super();
|
||||
}
|
||||
export class DemoEnvGuard implements CanActivate {
|
||||
constructor(private readonly environmentService: EnvironmentService) {}
|
||||
|
||||
getRequest(context: ExecutionContext) {
|
||||
return getRequest(context);
|
||||
}
|
||||
canActivate(
|
||||
context: ExecutionContext,
|
||||
): boolean | Promise<boolean> | Observable<boolean> {
|
||||
const ctx = GqlExecutionContext.create(context);
|
||||
const request = ctx.getContext().req;
|
||||
|
||||
// TODO: input should be typed
|
||||
handleRequest(err: any, user: any) {
|
||||
const demoWorkspaceIds = this.environmentService.get('DEMO_WORKSPACE_IDS');
|
||||
const currentUserWorkspaceId = user?.workspace?.id;
|
||||
const currentUserWorkspaceId = request.workspace?.id;
|
||||
|
||||
if (!currentUserWorkspaceId) {
|
||||
throw new UnauthorizedException('Unauthorized for not logged in user');
|
||||
@ -31,6 +31,6 @@ export class DemoEnvGuard extends AuthGuard(['jwt']) {
|
||||
throw new UnauthorizedException('Unauthorized for demo workspace');
|
||||
}
|
||||
|
||||
return user;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
35
packages/twenty-server/src/engine/guards/jwt-auth.guard.ts
Normal file
35
packages/twenty-server/src/engine/guards/jwt-auth.guard.ts
Normal file
@ -0,0 +1,35 @@
|
||||
import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';
|
||||
|
||||
import { TokenService } from 'src/engine/core-modules/auth/services/token.service';
|
||||
import { WorkspaceCacheStorageService } from 'src/engine/workspace-cache-storage/workspace-cache-storage.service';
|
||||
|
||||
@Injectable()
|
||||
export class JwtAuthGuard implements CanActivate {
|
||||
constructor(
|
||||
private readonly tokenService: TokenService,
|
||||
private readonly workspaceStorageCacheService: WorkspaceCacheStorageService,
|
||||
) {}
|
||||
|
||||
async canActivate(context: ExecutionContext): Promise<boolean> {
|
||||
const request = context.switchToHttp().getRequest();
|
||||
|
||||
try {
|
||||
const data = await this.tokenService.validateToken(request);
|
||||
const metadataVersion =
|
||||
await this.workspaceStorageCacheService.getMetadataVersion(
|
||||
data.workspace.id,
|
||||
);
|
||||
|
||||
request.user = data.user;
|
||||
request.apiKey = data.apiKey;
|
||||
request.workspace = data.workspace;
|
||||
request.workspaceId = data.workspace.id;
|
||||
request.workspaceMetadataVersion = metadataVersion;
|
||||
request.workspaceMemberId = data.workspaceMemberId;
|
||||
|
||||
return true;
|
||||
} catch (error) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,40 +0,0 @@
|
||||
import {
|
||||
ExecutionContext,
|
||||
Injectable,
|
||||
UnauthorizedException,
|
||||
} from '@nestjs/common';
|
||||
import { AuthGuard } from '@nestjs/passport';
|
||||
|
||||
import { JsonWebTokenError } from 'jsonwebtoken';
|
||||
|
||||
import { assert } from 'src/utils/assert';
|
||||
import { getRequest } from 'src/utils/extract-request';
|
||||
|
||||
@Injectable()
|
||||
export class JwtAuthGuard extends AuthGuard(['jwt']) {
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
getRequest(context: ExecutionContext) {
|
||||
return getRequest(context);
|
||||
}
|
||||
|
||||
handleRequest(err: any, user: any, info: any) {
|
||||
assert(user, '', UnauthorizedException);
|
||||
|
||||
if (err) {
|
||||
throw err;
|
||||
}
|
||||
|
||||
if (info && info instanceof Error) {
|
||||
if (info instanceof JsonWebTokenError) {
|
||||
info = String(info);
|
||||
}
|
||||
|
||||
throw new UnauthorizedException(info);
|
||||
}
|
||||
|
||||
return user;
|
||||
}
|
||||
}
|
||||
@ -1,23 +0,0 @@
|
||||
import { ExecutionContext, Injectable } from '@nestjs/common';
|
||||
import { AuthGuard } from '@nestjs/passport';
|
||||
|
||||
import { getRequest } from 'src/utils/extract-request';
|
||||
|
||||
@Injectable()
|
||||
export class OptionalJwtAuthGuard extends AuthGuard(['jwt']) {
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
getRequest(context: ExecutionContext) {
|
||||
const request = getRequest(context);
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
handleRequest(err, user, info) {
|
||||
if (err || info) return null;
|
||||
|
||||
return user;
|
||||
}
|
||||
}
|
||||
15
packages/twenty-server/src/engine/guards/user-auth.guard.ts
Normal file
15
packages/twenty-server/src/engine/guards/user-auth.guard.ts
Normal file
@ -0,0 +1,15 @@
|
||||
import { CanActivate, ExecutionContext } from '@nestjs/common';
|
||||
import { GqlExecutionContext } from '@nestjs/graphql';
|
||||
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
export class UserAuthGuard implements CanActivate {
|
||||
canActivate(
|
||||
context: ExecutionContext,
|
||||
): boolean | Promise<boolean> | Observable<boolean> {
|
||||
const ctx = GqlExecutionContext.create(context);
|
||||
const request = ctx.getContext().req;
|
||||
|
||||
return request.user !== undefined;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,15 @@
|
||||
import { CanActivate, ExecutionContext } from '@nestjs/common';
|
||||
import { GqlExecutionContext } from '@nestjs/graphql';
|
||||
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
export class WorkspaceAuthGuard implements CanActivate {
|
||||
canActivate(
|
||||
context: ExecutionContext,
|
||||
): boolean | Promise<boolean> | Observable<boolean> {
|
||||
const ctx = GqlExecutionContext.create(context);
|
||||
const request = ctx.getContext().req;
|
||||
|
||||
return request.workspace !== undefined;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user