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>
27 lines
997 B
TypeScript
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); });
|