Files
retail-nest/OPTIONAL_SETUP.md
2025-10-21 16:30:18 +07:00

4.0 KiB

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:

npm install @nestjs/schedule

Create TokenCleanupService

Create src/modules/auth/services/token-cleanup.service.ts:

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<void> {
    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<void> {
    this.logger.log('Manual refresh token cleanup triggered');
    await this.refreshTokenService.cleanupTokens();
  }
}

Enable in AppModule

Update src/app.module.ts:

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:

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:

// 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:

// 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:

    -- 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):

    -- 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.