/**
 * config/security.js
 * Tunables for production hardening.
 */

'use strict';

const isProd = process.env.NODE_ENV === 'production';

module.exports = {
  isProd,

  // bcrypt cost factor. 12 is the historical default; 13 is recommended
  // for new deployments in 2026. We keep 12 in dev for speed and bump to
  // 13 in production via env.
  BCRYPT_COST: parseInt(process.env.BCRYPT_COST, 10) || (isProd ? 13 : 12),

  // Session
  SESSION_TTL_MS:      1000 * 60 * 60 * 24,   // 24 hours rolling
  SESSION_ABSOLUTE_MS: 1000 * 60 * 60 * 24 * 7, // 7 days hard cap
  SESSION_COOKIE_NAME: 'ncii.sid',
  SESSION_COOKIE_SECURE: isProd,             // require HTTPS in prod

  // CSRF
  CSRF_COOKIE_NAME:    'ncsrf',
  CSRF_HEADER:         'x-csrf-token',

  // Account lockout
  LOGIN_MAX_ATTEMPTS:   parseInt(process.env.LOGIN_MAX_ATTEMPTS,   10) || 5,
  LOGIN_LOCKOUT_MIN:    parseInt(process.env.LOGIN_LOCKOUT_MINUTES,10) || 15,
  LOGIN_LOCKOUT_GROWTH: 2,                  // each subsequent failure doubles the lockout
  LOGIN_LOCKOUT_MAX:    24 * 60 * 60 * 1000, // 24h absolute cap

  // IP-based throttling
  IP_LOGIN_MAX_PER_HR:  20,                 // distinct accounts that can be tried from one IP per hour
  IP_LOGIN_COOLDOWN_MS: 60 * 1000,          // minimum spacing between failed attempts from same IP

  // API tokens (agency REST)
  API_TOKEN_BYTES:      32,                 // 256-bit

  // Webhook replay protection
  WEBHOOK_REPLAY_MAX_AGE_S: 300,            // 5 minutes — Stripe events older than this are rejected

  // Upload
  UPLOAD_MAX_BYTES:     10 * 1024 * 1024,   // 10 MB
  UPLOAD_ALLOWED_MIME:  ['image/jpeg', 'image/png', 'image/webp'],
  UPLOAD_MAX_PIXELS:    25_000_000,         // 25 MP (5000x5000) — beyond this pHash is unreliable

  // Content security / headers
  CSP_REPORT_URI:       process.env.CSP_REPORT_URI || null,

  // 2FA
  TOTP_ISSUER:          'Shield',
};
