fix(security): resolve audit findings — secrets, env contract, migrations
Removes hardcoded fallback secrets and makes a misconfigured deploy fail loudly instead of silently falling back to development defaults. - Remove insecure JWT fallback secrets (messages.module, configuration) - Remove the 'default-secret' fallback for the 2FA TOTP encryption key and allow a dedicated TWO_FACTOR_ENCRYPTION_KEY so rotating JWT_SECRET no longer locks out every 2FA user (see docs/2fa-key-rotation.md) - Require EMAIL_API_URL; drop the hardcoded vendor email endpoint - Drive WebSocket CORS from CORS_ORIGINS instead of origin:'*' - Load .env before any Nest module is imported (src/load-env.ts). Decorator arguments evaluate at import time, so the gateway previously froze its CORS config to the localhost fallback even when CORS_ORIGINS was set - Add boot-time env validation: missing required vars, weak JWT_SECRET, and inverted access/refresh token lifetimes now abort startup - Enable Redis TLS certificate verification - Require ADMIN_EMAIL/ADMIN_PASSWORD for the seed; remove the published default super-admin credentials and stop printing them - Add the initial Prisma migration and stop gitignoring prisma/migrations - Make .env.example an accurate configuration contract (admin bootstrap, REDIS_TLS, S3_ENDPOINT, 2FA key, Firebase path; drop the dead SMTP block) - Add handover documentation: architecture, ER model, sequence and data-flow diagrams, 2FA key rotation runbook Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -20,6 +20,22 @@ async function main() {
|
||||
|
||||
const prisma = new PrismaClient({ adapter });
|
||||
|
||||
// Validate up front so a misconfigured run fails before it writes anything.
|
||||
// No defaults: a seed run without these would create a super-admin whose
|
||||
// credentials are published in this file.
|
||||
const adminEmail = process.env.ADMIN_EMAIL;
|
||||
const adminPassword = process.env.ADMIN_PASSWORD;
|
||||
|
||||
if (!adminEmail || !adminPassword) {
|
||||
throw new Error(
|
||||
'ADMIN_EMAIL and ADMIN_PASSWORD must be set to seed the super-admin account',
|
||||
);
|
||||
}
|
||||
|
||||
if (adminPassword.length < 12) {
|
||||
throw new Error('ADMIN_PASSWORD must be at least 12 characters');
|
||||
}
|
||||
|
||||
console.log('🌱 Starting database seeding...\n');
|
||||
|
||||
// =============================================
|
||||
@@ -1256,9 +1272,7 @@ async function main() {
|
||||
// =============================================
|
||||
console.log('👤 Seeding Admin User...');
|
||||
|
||||
const adminEmail = process.env.ADMIN_EMAIL || 'admin@re-quest.com';
|
||||
const adminPassword = process.env.ADMIN_PASSWORD || 'Admin@123456';
|
||||
|
||||
// adminEmail / adminPassword are validated at the top of main().
|
||||
// Hash password with Argon2 (more secure than bcrypt)
|
||||
const hashedPassword = await argon2.hash(adminPassword);
|
||||
|
||||
@@ -1286,7 +1300,6 @@ async function main() {
|
||||
console.log(' ✅ Admin user created successfully!');
|
||||
console.log(' ───────────────────────────────');
|
||||
console.log(` 📧 Email: ${adminEmail}`);
|
||||
console.log(` 🔑 Password: ${adminPassword}`);
|
||||
console.log(` 👤 Role: ${admin.role}`);
|
||||
console.log(` 🆔 ID: ${admin.id}`);
|
||||
console.log(' ───────────────────────────────\n');
|
||||
|
||||
Reference in New Issue
Block a user