Initial commit: DashCaddy v1.0
Full codebase including API server (32 modules + routes), dashboard frontend, DashCA certificate distribution, installer script, and deployment skills.
This commit is contained in:
147
dashcaddy-api/constants.js
Normal file
147
dashcaddy-api/constants.js
Normal file
@@ -0,0 +1,147 @@
|
||||
// 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.0',
|
||||
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
|
||||
};
|
||||
|
||||
// ── 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,
|
||||
};
|
||||
Reference in New Issue
Block a user