From d2d3b69baa10a132792e52416850ae94d0cc89d3 Mon Sep 17 00:00:00 2001 From: Igor Propisnov Date: Sun, 2 Jun 2024 14:17:39 +0200 Subject: [PATCH] fix cors for postman + small tidy up --- backend/src/app.module.ts | 5 +- .../cors-middleware/cors.middlware.ts | 9 +- .../repositories/session.repository.ts | 87 +++++++++---------- .../auth-module/services/session.service.ts | 38 ++++---- 4 files changed, 66 insertions(+), 73 deletions(-) diff --git a/backend/src/app.module.ts b/backend/src/app.module.ts index 24c2884..e6167c8 100644 --- a/backend/src/app.module.ts +++ b/backend/src/app.module.ts @@ -3,6 +3,7 @@ import { ConfigModule } from '@nestjs/config'; import { AppController } from './app.controller'; import { AppService } from './app.service'; +import { CorsMiddleware } from './middleware/cors-middleware/cors.middlware'; import { CspMiddleware } from './middleware/csp-middleware/csp.middleware'; import { HttpsRedirectMiddleware } from './middleware/https-middlware/https-redirect.middleware'; import { SecurityHeadersMiddleware } from './middleware/security-middleware/security.middleware'; @@ -34,8 +35,8 @@ export class AppModule { .apply( CspMiddleware, SecurityHeadersMiddleware, - HttpsRedirectMiddleware - //CorsMiddleware + HttpsRedirectMiddleware, + CorsMiddleware ) .forRoutes({ path: '*', method: RequestMethod.ALL }); } diff --git a/backend/src/middleware/cors-middleware/cors.middlware.ts b/backend/src/middleware/cors-middleware/cors.middlware.ts index 89b990b..653da38 100644 --- a/backend/src/middleware/cors-middleware/cors.middlware.ts +++ b/backend/src/middleware/cors-middleware/cors.middlware.ts @@ -8,10 +8,13 @@ export class CorsMiddleware implements NestMiddleware { public use(req: Request, res: Response, next: NextFunction): void { if (this.configService.get('NODE_ENV') === 'development') { - const allowedOrigin = this.configService.get('CORS_ALLOW_ORIGIN'); + const allowedOrigins = this.configService + .get('CORS_ALLOW_ORIGIN') + .split(','); + const requestOrigin = req.headers.origin; - if (req.headers.origin === allowedOrigin) { - res.header('Access-Control-Allow-Origin', allowedOrigin); + if (!requestOrigin || allowedOrigins.includes(requestOrigin)) { + res.header('Access-Control-Allow-Origin', requestOrigin || '*'); res.header( 'Access-Control-Allow-Methods', this.configService.get('CORS_ALLOW_METHODS') diff --git a/backend/src/modules/auth-module/repositories/session.repository.ts b/backend/src/modules/auth-module/repositories/session.repository.ts index d2de7ee..b329765 100644 --- a/backend/src/modules/auth-module/repositories/session.repository.ts +++ b/backend/src/modules/auth-module/repositories/session.repository.ts @@ -2,24 +2,22 @@ import { Injectable } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { Response } from 'express'; import { Session } from 'src/entities'; -import { LessThan, Repository } from 'typeorm'; +import { DeleteResult, Repository } from 'typeorm'; +import { LessThan } from 'typeorm'; import { v4 as uuidv4 } from 'uuid'; @Injectable() export class SessionRepository { public constructor( - @InjectRepository(Session) - private sessionRepository: Repository + @InjectRepository(Session) private sessionRepository: Repository ) {} - public async createSession( - userId: string, - userAgent: string - ): Promise { + public createSession(userId: string, userAgent: string): Promise { const sessionId = uuidv4(); const expirationDate = new Date(); expirationDate.setHours(expirationDate.getHours() + 1); + const session = this.sessionRepository.create({ userCredentials: userId, sessionId, @@ -27,13 +25,12 @@ export class SessionRepository { userAgent, }); - await this.sessionRepository.save(session); - return session; + return this.sessionRepository.save(session); } - public async findSessionBySessionId(sessionId: string): Promise { - return await this.sessionRepository.findOne({ - where: { sessionId: sessionId }, + public findSessionBySessionId(sessionId: string): Promise { + return this.sessionRepository.findOne({ + where: { sessionId }, relations: ['userCredentials'], }); } @@ -46,56 +43,54 @@ export class SessionRepository { }); } - public async validateSessionUserAgent( + public validateSessionUserAgent( sessionId: string, currentUserAgent: string ): Promise { - const session = await this.sessionRepository.findOne({ - where: { sessionId: sessionId }, - select: ['userAgent'], - }); - - if (!session) { - return false; - } - - return session.userAgent === currentUserAgent; + return this.sessionRepository + .findOne({ + where: { sessionId }, + select: ['userAgent'], + }) + .then((session) => + session ? session.userAgent === currentUserAgent : false + ); } - public async checkSessionLimit(userId: string): Promise { - const userSessions = await this.sessionRepository + public checkSessionLimit(userId: string): Promise { + return this.sessionRepository .createQueryBuilder('session') .leftJoinAndSelect('session.userCredentials', 'userCredentials') .where('userCredentials.id = :userId', { userId }) .orderBy('session.expiresAt', 'ASC') - .getMany(); - - if (userSessions.length >= 5) { - await this.sessionRepository.delete(userSessions[0].id); - } + .getMany() + .then((userSessions) => { + if (userSessions.length >= 5) { + return this.sessionRepository.delete(userSessions[0].id); + } + }); } - public async invalidateAllSessionsForUser(userId: string): Promise { - await this.sessionRepository.delete({ userCredentials: userId }); + public invalidateAllSessionsForUser(userId: string): Promise { + return this.sessionRepository.delete({ userCredentials: userId }); } - public async extendSessionExpiration(sessionId: string): Promise { - const session = await this.sessionRepository.findOne({ - where: { sessionId }, - }); - - if (session) { - session.expiresAt = new Date( - session.expiresAt.setMinutes(session.expiresAt.getMinutes() + 30) - ); - await this.sessionRepository.save(session); - } + public extendSessionExpiration(sessionId: string): Promise { + return this.sessionRepository + .findOne({ where: { sessionId } }) + .then((session) => { + if (session) { + session.expiresAt = new Date( + session.expiresAt.setMinutes(session.expiresAt.getMinutes() + 30) + ); + return this.sessionRepository.save(session); + } + }); } - // TODO Add cron job to clear expired sessions - public async clearExpiredSessions(): Promise { + public clearExpiredSessions(): Promise { const now = new Date(); - await this.sessionRepository.delete({ expiresAt: LessThan(now) }); + return this.sessionRepository.delete({ expiresAt: LessThan(now) }); } } diff --git a/backend/src/modules/auth-module/services/session.service.ts b/backend/src/modules/auth-module/services/session.service.ts index 623c976..6dca4f2 100644 --- a/backend/src/modules/auth-module/services/session.service.ts +++ b/backend/src/modules/auth-module/services/session.service.ts @@ -1,52 +1,46 @@ import { Injectable } from '@nestjs/common'; -import { InjectRepository } from '@nestjs/typeorm'; import { Response } from 'express'; import { Session } from 'src/entities'; +import { DeleteResult } from 'typeorm'; import { SessionRepository } from '../repositories/session.repository'; @Injectable() export class SessionService { - public constructor( - @InjectRepository(Session) - private readonly sessionRepository: SessionRepository - ) {} + public constructor(private readonly sessionRepository: SessionRepository) {} - public async createSession( - userId: string, - userAgent: string - ): Promise { - return await this.sessionRepository.createSession(userId, userAgent); + public createSession(userId: string, userAgent: string): Promise { + return this.sessionRepository.createSession(userId, userAgent); } - public async validateSessionUserAgent( + public validateSessionUserAgent( sessionId: string, currentUserAgent: string ): Promise { - return await this.sessionRepository.validateSessionUserAgent( + return this.sessionRepository.validateSessionUserAgent( sessionId, currentUserAgent ); } - public async checkSessionLimit(userId: string): Promise { - await this.sessionRepository.checkSessionLimit(userId); + public checkSessionLimit(userId: string): Promise { + return this.sessionRepository.checkSessionLimit(userId); } - public async invalidateAllSessionsForUser(userId: string): Promise { - await this.sessionRepository.invalidateAllSessionsForUser(userId); + public invalidateAllSessionsForUser(userId: string): Promise { + return this.sessionRepository.invalidateAllSessionsForUser(userId); } - public async clearExpiredSessions(): Promise { - await this.sessionRepository.clearExpiredSessions(); + public clearExpiredSessions(): Promise { + return this.sessionRepository.clearExpiredSessions(); } - public async extendSessionExpiration(sessionId: string): Promise { - await this.sessionRepository.extendSessionExpiration(sessionId); + public extendSessionExpiration(sessionId: string): Promise { + return this.sessionRepository.extendSessionExpiration(sessionId); } - public async findSessionBySessionId(sessionId: string): Promise { - return await this.sessionRepository.findSessionBySessionId(sessionId); + public findSessionBySessionId(sessionId: string): Promise { + return this.sessionRepository.findSessionBySessionId(sessionId); } public attachSessionToResponse(response: Response, sessionId: string): void {