User workspace middleware throws 401 if token is invalid (#5245)

## Context
Currently, this middleware validates the token and stores the user,
workspace and cacheversion in the request object.
It only does so when a token is provided and ignores the middleware
logic if not. If the token is invalid or expired, the exception is
swallowed.

This PR removes the try/catch and adds an allowlist to skip the token
validation for operations executed while not signed-in.
I don't know a better way to do that with Nestjs. We can't easily add
the middleware per resolver without refactoring the flexible schema
engine so I'm doing it the other way around.

Fixes https://github.com/twentyhq/twenty/issues/5224
This commit is contained in:
Weiko 2024-05-02 12:54:01 +02:00 committed by GitHub
parent 27a3d7ec27
commit 9a116b08a4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -1,4 +1,4 @@
import { Injectable, Logger, NestMiddleware } from '@nestjs/common';
import { Injectable, NestMiddleware } from '@nestjs/common';
import { Request, Response, NextFunction } from 'express';
@ -7,28 +7,42 @@ import { WorkspaceCacheVersionService } from 'src/engine/metadata-modules/worksp
@Injectable()
export class UserWorkspaceMiddleware implements NestMiddleware {
private readonly logger = new Logger(UserWorkspaceMiddleware.name);
constructor(
private readonly tokenService: TokenService,
private readonly workspaceCacheVersionService: WorkspaceCacheVersionService,
) {}
async use(req: Request, res: Response, next: NextFunction) {
if (this.tokenService.isTokenPresent(req)) {
try {
const data = await this.tokenService.validateToken(req);
const cacheVersion = await this.workspaceCacheVersionService.getVersion(
data.workspace.id,
);
const body = req.body;
const excludedOperations = [
'GetClientConfig',
'GetCurrentUser',
'GetWorkspaceFromInviteHash',
'Track',
'CheckUserExists',
'Challenge',
'Verify',
'SignUp',
'RenewToken',
];
req.user = data.user;
req.workspace = data.workspace;
req.cacheVersion = cacheVersion;
} catch (error) {
this.logger.error('Error while validating token in middleware.', error);
}
if (
body &&
body.operationName &&
excludedOperations.includes(body.operationName)
) {
return next();
}
const data = await this.tokenService.validateToken(req);
const cacheVersion = await this.workspaceCacheVersionService.getVersion(
data.workspace.id,
);
req.user = data.user;
req.workspace = data.workspace;
req.cacheVersion = cacheVersion;
next();
}
}