169 lines
4.0 KiB
Markdown
169 lines
4.0 KiB
Markdown
# 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<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`:
|
|
|
|
```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.
|