Files
Horux360/apps/api/scripts/create-carlos.ts
Consultoria AS 351b14a78c security: comprehensive security audit and remediation (20 fixes)
CRITICAL fixes:
- Restrict X-View-Tenant impersonation to global admin only (was any admin)
- Add authorization to subscription endpoints (was open to any user)
- Make webhook signature verification mandatory (was skippable)
- Remove databaseName from JWT payload (resolve server-side with cache)
- Reduce body size limit from 1GB to 10MB (50MB for bulk CFDI)
- Restrict .env file permissions to 600

HIGH fixes:
- Add authorization to SAT cron endpoints (global admin only)
- Add Content-Security-Policy and Permissions-Policy headers
- Centralize isGlobalAdmin() utility with caching
- Add rate limiting on auth endpoints (express-rate-limit)
- Require authentication on logout endpoint

MEDIUM fixes:
- Replace Math.random() with crypto.randomBytes for temp passwords
- Remove console.log of temporary passwords in production
- Remove DB credentials from admin notification email
- Add escapeHtml() to email templates (prevent HTML injection)
- Add file size validation on FIEL upload (50KB max)
- Require TLS for SMTP connections
- Normalize email to lowercase before uniqueness check
- Remove hardcoded default for FIEL_ENCRYPTION_KEY

Also includes:
- Complete production deployment documentation
- API reference documentation
- Security audit report with remediation details
- Updated README with v0.5.0 changelog
- New client admin email template
- Utility scripts (create-carlos, test-emails)
- PM2 ecosystem config updates

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 22:32:04 +00:00

27 lines
997 B
TypeScript

import { prisma } from '../src/config/database.js';
import { hashPassword } from '../src/utils/password.js';
async function main() {
const ivan = await prisma.user.findUnique({ where: { email: 'ivan@horuxfin.com' }, include: { tenant: true } });
if (!ivan) { console.error('Ivan not found'); process.exit(1); }
console.log('Tenant:', ivan.tenant.nombre, '(', ivan.tenant.id, ')');
const existing = await prisma.user.findUnique({ where: { email: 'carlos@horuxfin.com' } });
if (existing) { console.log('Carlos already exists:', existing.id); process.exit(0); }
const hash = await hashPassword('Aasi940812');
const carlos = await prisma.user.create({
data: {
tenantId: ivan.tenantId,
email: 'carlos@horuxfin.com',
passwordHash: hash,
nombre: 'Carlos Horux',
role: 'admin',
}
});
console.log('Carlos created:', carlos.id, carlos.email, carlos.role);
}
main().then(() => process.exit(0)).catch(e => { console.error(e); process.exit(1); });