add refresh token

This commit is contained in:
Phuoc Nguyen
2025-10-21 16:30:18 +07:00
parent d316362f41
commit 71f0447af7
17 changed files with 2074 additions and 18 deletions

168
OPTIONAL_SETUP.md Normal file
View File

@@ -0,0 +1,168 @@
# 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.