diff --git a/backend/package.json b/backend/package.json index ea55b01..313a392 100644 --- a/backend/package.json +++ b/backend/package.json @@ -29,6 +29,7 @@ "@nestjs/jwt": "^10.2.0", "@nestjs/passport": "^10.0.3", "@nestjs/platform-express": "^10.0.0", + "@nestjs/schedule": "^4.0.2", "@nestjs/swagger": "^7.3.1", "@nestjs/typeorm": "^10.0.2", "@sendgrid/mail": "^8.1.3", diff --git a/backend/pnpm-lock.yaml b/backend/pnpm-lock.yaml index 80cfa46..6ed72dd 100644 --- a/backend/pnpm-lock.yaml +++ b/backend/pnpm-lock.yaml @@ -23,6 +23,9 @@ dependencies: '@nestjs/platform-express': specifier: ^10.0.0 version: 10.3.7(@nestjs/common@10.3.7)(@nestjs/core@10.3.7) + '@nestjs/schedule': + specifier: ^4.0.2 + version: 4.0.2(@nestjs/common@10.3.7)(@nestjs/core@10.3.7) '@nestjs/swagger': specifier: ^7.3.1 version: 7.3.1(@nestjs/common@10.3.7)(@nestjs/core@10.3.7)(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2) @@ -1051,6 +1054,18 @@ packages: transitivePeerDependencies: - supports-color + /@nestjs/schedule@4.0.2(@nestjs/common@10.3.7)(@nestjs/core@10.3.7): + resolution: {integrity: sha512-po9oauE7fO0CjhDKvVC2tzEgjOUwhxYoIsXIVkgfu+xaDMmzzpmXY2s1LT4oP90Z+PaTtPoAHmhslnYmo4mSZg==} + peerDependencies: + '@nestjs/common': ^8.0.0 || ^9.0.0 || ^10.0.0 + '@nestjs/core': ^8.0.0 || ^9.0.0 || ^10.0.0 + dependencies: + '@nestjs/common': 10.3.7(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1) + '@nestjs/core': 10.3.7(@nestjs/common@10.3.7)(@nestjs/platform-express@10.3.7)(reflect-metadata@0.2.2)(rxjs@7.8.1) + cron: 3.1.7 + uuid: 9.0.1 + dev: false + /@nestjs/schematics@10.1.1(chokidar@3.6.0)(typescript@5.3.3): resolution: {integrity: sha512-o4lfCnEeIkfJhGBbLZxTuVWcGuqDCFwg5OrvpgRUBM7vI/vONvKKiB5riVNpO+JqXoH0I42NNeDb0m4V5RREig==} peerDependencies: @@ -1386,6 +1401,10 @@ packages: '@types/node': 20.12.4 dev: false + /@types/luxon@3.4.2: + resolution: {integrity: sha512-TifLZlFudklWlMBfhubvgqTXRzLDI5pCbGa4P8a3wPyUQSW+1xQ5eDsreP9DWHX3tjq1ke96uYG/nwundroWcA==} + dev: false + /@types/methods@1.1.4: resolution: {integrity: sha512-ymXWVrDiCxTBE3+RIrrP533E70eA+9qu7zdWoHuOmGujkYtzf4HQF96b8nwHLqhuf4ykX61IGRIB38CC6/sImQ==} dev: true @@ -2324,6 +2343,13 @@ packages: /create-require@1.1.1: resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} + /cron@3.1.7: + resolution: {integrity: sha512-tlBg7ARsAMQLzgwqVxy8AZl/qlTc5nibqYwtNGoCrd+cV+ugI+tvZC1oT/8dFH8W455YrywGykx/KMmAqOr7Jw==} + dependencies: + '@types/luxon': 3.4.2 + luxon: 3.4.4 + dev: false + /cross-spawn@7.0.3: resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} engines: {node: '>= 8'} @@ -3982,6 +4008,11 @@ packages: dependencies: yallist: 4.0.0 + /luxon@3.4.4: + resolution: {integrity: sha512-zobTr7akeGHnv7eBOXcRgMeCP6+uyYsczwmeRCauvpvaAltgNyTbLH/+VaEAPUeWBT+1GuNmz4wC/6jtQzbbVA==} + engines: {node: '>=12'} + dev: false + /magic-string@0.30.5: resolution: {integrity: sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==} engines: {node: '>=12'} diff --git a/backend/src/app.module.ts b/backend/src/app.module.ts index e6167c8..aebae39 100644 --- a/backend/src/app.module.ts +++ b/backend/src/app.module.ts @@ -1,8 +1,10 @@ import { MiddlewareConsumer, Module, RequestMethod } from '@nestjs/common'; import { ConfigModule } from '@nestjs/config'; +import { ScheduleModule } from '@nestjs/schedule'; import { AppController } from './app.controller'; import { AppService } from './app.service'; +import { ClearExpiredSessionsCron } from './cron/clear-expired-sesstions.cron'; 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'; @@ -19,6 +21,7 @@ import { VerifyModule } from './modules/verify-module/verify.module'; ConfigModule.forRoot({ isGlobal: true, }), + ScheduleModule.forRoot(), DatabaseModule, AuthModule, UserModule, @@ -26,7 +29,11 @@ import { VerifyModule } from './modules/verify-module/verify.module'; VerifyModule, ], controllers: [AppController], - providers: [AppService, { provide: 'APP_GUARD', useClass: AccessTokenGuard }], + providers: [ + AppService, + { provide: 'APP_GUARD', useClass: AccessTokenGuard }, + ClearExpiredSessionsCron, + ], }) export class AppModule { public configure(consumer: MiddlewareConsumer): void { diff --git a/backend/src/cron/clear-expired-sesstions.cron.ts b/backend/src/cron/clear-expired-sesstions.cron.ts new file mode 100644 index 0000000..7681936 --- /dev/null +++ b/backend/src/cron/clear-expired-sesstions.cron.ts @@ -0,0 +1,19 @@ +import { Injectable, Logger } from '@nestjs/common'; +import { Cron, CronExpression } from '@nestjs/schedule'; +import { SessionService } from 'src/modules/auth-module/services/session.service'; + +@Injectable() +export class ClearExpiredSessionsCron { + private readonly logger: Logger = new Logger(ClearExpiredSessionsCron.name); + + public constructor(private readonly sessionService: SessionService) {} + + @Cron(CronExpression.EVERY_DAY_AT_MIDNIGHT, { + name: 'Clear-Expired-Sessions', + timeZone: 'Europe/Berlin', + }) + public handleCron(): void { + this.logger.log('Cronjob Executed: Clear-Expired-Sessions'); + this.sessionService.clearExpiredSessions(); + } +} diff --git a/backend/src/modules/auth-module/auth.module.ts b/backend/src/modules/auth-module/auth.module.ts index ff76261..fa74b66 100644 --- a/backend/src/modules/auth-module/auth.module.ts +++ b/backend/src/modules/auth-module/auth.module.ts @@ -33,5 +33,6 @@ import { AccessTokenStrategy, RefreshTokenStrategy } from './strategies'; RefreshTokenStrategy, ], controllers: [AuthController], + exports: [SessionService], }) export class AuthModule {}