|
|
#!/usr/bin/env node |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const redis = require('../src/models/redis') |
|
|
const logger = require('../src/utils/logger') |
|
|
const readline = require('readline') |
|
|
|
|
|
|
|
|
const args = process.argv.slice(2) |
|
|
const params = {} |
|
|
args.forEach((arg) => { |
|
|
const [key, value] = arg.split('=') |
|
|
params[key.replace('--', '')] = value || true |
|
|
}) |
|
|
|
|
|
const DEFAULT_DAYS = params.days ? parseInt(params.days) : 30 |
|
|
const DRY_RUN = params['dry-run'] === true |
|
|
|
|
|
|
|
|
const rl = readline.createInterface({ |
|
|
input: process.stdin, |
|
|
output: process.stdout |
|
|
}) |
|
|
|
|
|
async function askConfirmation(question) { |
|
|
return new Promise((resolve) => { |
|
|
rl.question(`${question} (yes/no): `, (answer) => { |
|
|
resolve(answer.toLowerCase() === 'yes' || answer.toLowerCase() === 'y') |
|
|
}) |
|
|
}) |
|
|
} |
|
|
|
|
|
async function migrateApiKeys() { |
|
|
try { |
|
|
logger.info('🔄 Starting API Key expiry migration...') |
|
|
logger.info(`📅 Default expiry period: ${DEFAULT_DAYS} days`) |
|
|
logger.info(`🔍 Mode: ${DRY_RUN ? 'DRY RUN (no changes will be made)' : 'LIVE RUN'}`) |
|
|
|
|
|
|
|
|
await redis.connect() |
|
|
logger.success('✅ Connected to Redis') |
|
|
|
|
|
|
|
|
const apiKeys = await redis.getAllApiKeys() |
|
|
logger.info(`📊 Found ${apiKeys.length} API Keys in total`) |
|
|
|
|
|
|
|
|
const stats = { |
|
|
total: apiKeys.length, |
|
|
needsMigration: 0, |
|
|
alreadyHasExpiry: 0, |
|
|
migrated: 0, |
|
|
errors: 0 |
|
|
} |
|
|
|
|
|
|
|
|
const keysToMigrate = [] |
|
|
|
|
|
|
|
|
for (const key of apiKeys) { |
|
|
if (!key.expiresAt || key.expiresAt === 'null' || key.expiresAt === '') { |
|
|
keysToMigrate.push(key) |
|
|
stats.needsMigration++ |
|
|
logger.info(`📌 API Key "${key.name}" (${key.id}) needs migration`) |
|
|
} else { |
|
|
stats.alreadyHasExpiry++ |
|
|
const expiryDate = new Date(key.expiresAt) |
|
|
logger.info( |
|
|
`✓ API Key "${key.name}" (${key.id}) already has expiry: ${expiryDate.toLocaleString()}` |
|
|
) |
|
|
} |
|
|
} |
|
|
|
|
|
if (keysToMigrate.length === 0) { |
|
|
logger.success('✨ No API Keys need migration!') |
|
|
return |
|
|
} |
|
|
|
|
|
|
|
|
console.log(`\n${'='.repeat(60)}`) |
|
|
console.log('📋 Migration Summary:') |
|
|
console.log('='.repeat(60)) |
|
|
console.log(`Total API Keys: ${stats.total}`) |
|
|
console.log(`Already have expiry: ${stats.alreadyHasExpiry}`) |
|
|
console.log(`Need migration: ${stats.needsMigration}`) |
|
|
console.log(`Default expiry: ${DEFAULT_DAYS} days from now`) |
|
|
console.log(`${'='.repeat(60)}\n`) |
|
|
|
|
|
|
|
|
if (!DRY_RUN) { |
|
|
const confirmed = await askConfirmation( |
|
|
`⚠️ This will set expiry dates for ${keysToMigrate.length} API Keys. Continue?` |
|
|
) |
|
|
|
|
|
if (!confirmed) { |
|
|
logger.warn('❌ Migration cancelled by user') |
|
|
return |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
const newExpiryDate = new Date() |
|
|
newExpiryDate.setDate(newExpiryDate.getDate() + DEFAULT_DAYS) |
|
|
const newExpiryISO = newExpiryDate.toISOString() |
|
|
|
|
|
logger.info(`\n🚀 Starting migration... New expiry date: ${newExpiryDate.toLocaleString()}`) |
|
|
|
|
|
|
|
|
for (const key of keysToMigrate) { |
|
|
try { |
|
|
if (!DRY_RUN) { |
|
|
|
|
|
|
|
|
await redis.client.hset(`apikey:${key.id}`, 'expiresAt', newExpiryISO) |
|
|
logger.success(`✅ Migrated: "${key.name}" (${key.id})`) |
|
|
} else { |
|
|
logger.info(`[DRY RUN] Would migrate: "${key.name}" (${key.id})`) |
|
|
} |
|
|
stats.migrated++ |
|
|
} catch (error) { |
|
|
logger.error(`❌ Error migrating "${key.name}" (${key.id}):`, error.message) |
|
|
stats.errors++ |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
console.log(`\n${'='.repeat(60)}`) |
|
|
console.log('✅ Migration Complete!') |
|
|
console.log('='.repeat(60)) |
|
|
console.log(`Successfully migrated: ${stats.migrated}`) |
|
|
console.log(`Errors: ${stats.errors}`) |
|
|
console.log(`New expiry date: ${newExpiryDate.toLocaleString()}`) |
|
|
console.log(`${'='.repeat(60)}\n`) |
|
|
|
|
|
if (DRY_RUN) { |
|
|
logger.warn('⚠️ This was a DRY RUN. No actual changes were made.') |
|
|
logger.info('💡 Run without --dry-run flag to apply changes.') |
|
|
} |
|
|
} catch (error) { |
|
|
logger.error('💥 Migration failed:', error) |
|
|
process.exit(1) |
|
|
} finally { |
|
|
|
|
|
rl.close() |
|
|
await redis.disconnect() |
|
|
logger.info('👋 Disconnected from Redis') |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (params.help) { |
|
|
console.log(` |
|
|
API Key Expiry Migration Script |
|
|
|
|
|
This script adds expiry dates to existing API Keys that don't have one. |
|
|
|
|
|
Usage: |
|
|
node scripts/migrate-apikey-expiry.js [options] |
|
|
|
|
|
Options: |
|
|
--days=NUMBER Set default expiry days (default: 30) |
|
|
--dry-run Simulate the migration without making changes |
|
|
--help Show this help message |
|
|
|
|
|
Examples: |
|
|
# Set 30-day expiry for all API Keys without expiry |
|
|
node scripts/migrate-apikey-expiry.js |
|
|
|
|
|
# Set 90-day expiry |
|
|
node scripts/migrate-apikey-expiry.js --days=90 |
|
|
|
|
|
# Test run without making changes |
|
|
node scripts/migrate-apikey-expiry.js --dry-run |
|
|
`) |
|
|
process.exit(0) |
|
|
} |
|
|
|
|
|
|
|
|
migrateApiKeys().catch((error) => { |
|
|
logger.error('💥 Unexpected error:', error) |
|
|
process.exit(1) |
|
|
}) |
|
|
|