Files
dashcaddy/dashcaddy-api/constants.js

163 lines
6.5 KiB
JavaScript

// DashCaddy Shared Constants
// Centralizes configuration values used across the application.
// Edit values here instead of hunting through server.js.
// ── App Identity ──────────────────────────────────────────────
const APP = {
NAME: 'DashCaddy',
VERSION: '1.1',
PORT: 3001,
USER_AGENTS: {
PROBE: 'DashCaddy-Probe/1.0',
API: 'DashCaddy/1.0',
HEALTH: 'DashCaddy-HealthCheck/1.0',
},
DEVICE_IDS: {
SSO: 'dashcaddy-sso', // Backend auth gate (never invalidates browser token)
BROWSER: 'dashcaddy-browser', // Browser-side localStorage token
},
};
// ── Default Ports for Media/Arr Apps ──────────────────────────
const APP_PORTS = {
plex: 32400,
radarr: 7878,
sonarr: 8989,
seerr: 5055,
lidarr: 8686,
prowlarr: 9696,
};
// Arr service discovery config (used by /api/arr/* endpoints)
const ARR_SERVICES = {
plex: { names: ['plex'], port: APP_PORTS.plex, configPath: 'Plex' },
radarr: { names: ['radarr'], port: APP_PORTS.radarr, configPath: 'radarr' },
sonarr: { names: ['sonarr'], port: APP_PORTS.sonarr, configPath: 'sonarr' },
seerr: { names: ['seerr', 'requests'], port: APP_PORTS.seerr, configPath: 'seerr' },
lidarr: { names: ['lidarr'], port: APP_PORTS.lidarr, configPath: 'lidarr' },
prowlarr: { names: ['prowlarr'], port: APP_PORTS.prowlarr, configPath: 'prowlarr' },
};
// ── Timeouts (ms) ─────────────────────────────────────────────
const TIMEOUTS = {
HTTP_DEFAULT: 5000, // Standard fetch/http timeout
HTTP_LONG: 10000, // DNS ops, downloads, login requests
DEPLOY_SETTLE: 3000, // Wait after container start before health check
CADDY_PRE_RELOAD: 2000, // Pause before Caddy reload
RETRY_SHORT: 1000, // Short retry delay
RETRY_MEDIUM: 2000, // Medium retry delay
SHUTDOWN_GRACE: 5000, // Graceful shutdown window
SHUTDOWN_ERROR: 1000, // Error shutdown window
PORT_CHECK: 2000, // TCP port availability check
};
// ── Retry Configuration ───────────────────────────────────────
const RETRIES = {
CADDY_RELOAD: 3, // Max attempts to reload Caddy
};
// ── Session / Cache Expiry (ms) ───────────────────────────────
const SESSION_TTL = {
IP_SESSION: 30 * 60 * 1000, // 30 min — router IP-based sessions
COOKIE_SESSION: 30 * 60 * 1000, // 30 min — cookie-based login sessions
TOKEN_SESSION: 60 * 60 * 1000, // 60 min — JWT/access token sessions (Jellyfin, Plex, etc.)
FAILED_LOGIN: 5 * 60 * 1000, // 5 min — cooldown after failed login
DNS_TOKEN: 6 * 60 * 60 * 1000, // 6 hrs — DNS auto-refresh interval
};
// ── Rate Limiting ─────────────────────────────────────────────
const RATE_LIMITS = {
GENERAL: {
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100,
},
STRICT: {
windowMs: 15 * 60 * 1000,
max: 20,
},
TOTP: {
windowMs: 15 * 60 * 1000,
max: 10,
},
};
// ── Caddy ─────────────────────────────────────────────────────
const CADDY = {
CONTENT_TYPE: 'text/caddyfile',
DEFAULT_DNS_PORT: '5380',
DEFAULT_TTL: 300,
TTL_MIN: 60,
TTL_MAX: 86400,
};
// ── Validation Patterns ─────────────────────────────────────────
const REGEX = {
SUBDOMAIN: /^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$/i,
DOMAIN: /^[a-z0-9]([a-z0-9.-]{0,251}[a-z0-9])?$/i,
};
// ── DNS ─────────────────────────────────────────────────────────
const DNS_RECORD_TYPES = ['A', 'AAAA', 'CNAME', 'MX', 'TXT', 'NS', 'SRV', 'PTR', 'SOA'];
// ── Docker ──────────────────────────────────────────────────────
const DOCKER = {
CONTAINER_PREFIX: 'sami-',
TIMEOUT: 30000, // 30s — timeout for docker pull/create operations
LOG_CONFIG: {
Type: 'json-file',
Config: { 'max-size': '10m', 'max-file': '3' } // 30MB max per container
},
MAINTENANCE: {
INTERVAL: 24 * 60 * 60 * 1000, // 24 hours
DISK_WARN_GB: 20, // Warn when Docker uses more than 20GB
},
DIGEST: {
COLLECT_INTERVAL: 60 * 60 * 1000, // Hourly log collection
DIGEST_HOUR: 0, // Generate daily digest at midnight
MAX_HOURLY_ENTRIES: 24, // Keep 24 hours of hourly summaries
MAX_DIGEST_FILES: 30, // Keep 30 days of daily digests
LOG_TAIL: 500, // Lines to fetch per container per hour
},
};
// ── Emby/Jellyfin Auth Header Builder ─────────────────────────
function buildMediaAuth(deviceId) {
return `MediaBrowser Client="${APP.NAME}", Device="${APP.NAME}", DeviceId="${deviceId}", Version="${APP.VERSION}"`;
}
// ── Plex Auth Headers ─────────────────────────────────────────
const PLEX = {
AUTH_URL: 'https://plex.tv/users/sign_in.json',
};
// ── Tailscale API ────────────────────────────────────────────
const TAILSCALE = {
API_BASE: 'https://api.tailscale.com/api/v2',
OAUTH_TOKEN_URL: 'https://api.tailscale.com/api/v2/oauth/token',
};
// ── Error Log ─────────────────────────────────────────────────
const LIMITS = {
ERROR_LOG_SIZE: 5 * 1024 * 1024, // 5 MB
BODY_DEFAULT: '1mb',
BODY_UPLOAD: '10mb',
};
module.exports = {
APP,
TAILSCALE,
APP_PORTS,
ARR_SERVICES,
TIMEOUTS,
RETRIES,
SESSION_TTL,
RATE_LIMITS,
CADDY,
PLEX,
LIMITS,
REGEX,
DNS_RECORD_TYPES,
DOCKER,
buildMediaAuth,
};