# Optional Setup for Advanced Features ## 1. Token Cleanup Service (Optional) The `TokenCleanupService` provides automatic cleanup of expired and revoked refresh tokens. This is optional but recommended for production environments. ### Installation Install the required package: ```bash npm install @nestjs/schedule ``` ### Create TokenCleanupService Create `src/modules/auth/services/token-cleanup.service.ts`: ```typescript import { Injectable, Logger } from '@nestjs/common'; import { Cron, CronExpression } from '@nestjs/schedule'; import { RefreshTokenService } from './refresh-token.service'; @Injectable() export class TokenCleanupService { private readonly logger = new Logger(TokenCleanupService.name); constructor(private readonly refreshTokenService: RefreshTokenService) {} /** * Cleanup expired and old refresh tokens * Runs daily at 2:00 AM */ @Cron(CronExpression.EVERY_DAY_AT_2AM) async handleTokenCleanup(): Promise { this.logger.log('Starting refresh token cleanup task...'); try { await this.refreshTokenService.cleanupTokens(); this.logger.log('Refresh token cleanup completed successfully'); } catch (error) { this.logger.error('Refresh token cleanup failed', error); } } /** * Manual trigger for cleanup (useful for testing or admin endpoints) */ async triggerManualCleanup(): Promise { this.logger.log('Manual refresh token cleanup triggered'); await this.refreshTokenService.cleanupTokens(); } } ``` ### Enable in AppModule Update `src/app.module.ts`: ```typescript import { ScheduleModule } from '@nestjs/schedule'; @Module({ imports: [ ScheduleModule.forRoot(), // Add this ConfigModule.forRoot({ isGlobal: true, envFilePath: '.env', }), TypeOrmModule.forRootAsync({ // ... existing config }), // ... other modules ], }) export class AppModule {} ``` ### Enable in AuthModule Update `src/modules/auth/auth.module.ts`: ```typescript import { TokenCleanupService } from './services/token-cleanup.service'; @Module({ imports: [ TypeOrmModule.forFeature([RefreshToken]), PassportModule, UsersModule, JwtModule.registerAsync({ // ... existing config }), ], controllers: [AuthController], providers: [ AuthService, JwtStrategy, LocalStrategy, RefreshTokenRepository, RefreshTokenService, TokenCleanupService, // Add this ], exports: [AuthService], }) export class AuthModule {} ``` ### Schedule Configuration The cleanup runs daily at 2:00 AM by default. To customize: Edit `src/modules/auth/services/token-cleanup.service.ts`: ```typescript // Run every hour @Cron(CronExpression.EVERY_HOUR) // Run at specific time @Cron('0 0 3 * * *') // 3:00 AM // Run every 6 hours @Cron('0 0 */6 * * *') ``` ### Manual Trigger You can also create an admin endpoint to trigger cleanup manually: ```typescript // In auth.controller.ts @Post('admin/cleanup-tokens') @UseGuards(JwtAuthGuard, RolesGuard) @Roles('admin') async cleanupTokens() { await this.tokenCleanupService.triggerManualCleanup(); return { success: true, message: 'Token cleanup completed' }; } ``` ## 2. Without Automatic Cleanup If you prefer not to use automatic cleanup, you can: 1. **Don't install @nestjs/schedule** - The app will work fine without it 2. **Don't add TokenCleanupService** to AuthModule providers 3. **Run manual cleanup** periodically: ```sql -- Connect to database DELETE FROM refresh_tokens WHERE "expiresAt" < NOW(); DELETE FROM refresh_tokens WHERE "isRevoked" = true; DELETE FROM refresh_tokens WHERE "createdAt" < NOW() - INTERVAL '30 days'; ``` 4. **Use database job scheduler** (PostgreSQL cron extension): ```sql -- Install pg_cron CREATE EXTENSION pg_cron; -- Schedule cleanup job SELECT cron.schedule('cleanup-tokens', '0 2 * * *', $$ DELETE FROM refresh_tokens WHERE "expiresAt" < NOW() OR "isRevoked" = true; $$); ``` ## Recommendation For production systems, use automatic cleanup to prevent database bloat and maintain performance.