This commit is contained in:
jpmvaz
2026-09-13 20:09:20 +01:00
commit 9b5cc30fb4
482 changed files with 57569 additions and 0 deletions
+81
View File
@@ -0,0 +1,81 @@
"""Configuration loaded from environment variables."""
import os
from datetime import timedelta
def _bool(val: str, default: bool = False) -> bool:
if val is None:
return default
return val.strip().lower() in ("1", "true", "yes", "on")
class Config:
SECRET_KEY = os.environ.get("SECRET_KEY", "dev-only-replace-me")
FLASK_ENV = os.environ.get("FLASK_ENV", "production")
DATABASE_PATH = os.environ.get("DATABASE_PATH", "/data/alerthub.db")
SQLALCHEMY_DATABASE_URI = f"sqlite:///{DATABASE_PATH}"
SQLALCHEMY_TRACK_MODIFICATIONS = False
SQLALCHEMY_ENGINE_OPTIONS = {
"pool_pre_ping": True,
# Wait (instead of erroring) when another process holds the SQLite
# write lock — both gunicorn apps share one database file.
"connect_args": {"timeout": 30},
}
# Bootstrap admin (only used on first DB init)
INITIAL_ADMIN_USERNAME = os.environ.get("INITIAL_ADMIN_USERNAME", "admin")
INITIAL_ADMIN_EMAIL = os.environ.get("INITIAL_ADMIN_EMAIL", "admin@example.com")
INITIAL_ADMIN_PASSWORD = os.environ.get("INITIAL_ADMIN_PASSWORD", "ChangeMeOnFirstLogin!")
# Session security
SESSION_COOKIE_SECURE = _bool(os.environ.get("SESSION_COOKIE_SECURE"), False)
SESSION_COOKIE_HTTPONLY = True
SESSION_COOKIE_SAMESITE = "Lax"
PERMANENT_SESSION_LIFETIME = timedelta(
hours=int(os.environ.get("SESSION_LIFETIME_HOURS", "8"))
)
PASSWORD_MIN_LENGTH = int(os.environ.get("PASSWORD_MIN_LENGTH", "10"))
# MFA
MFA_ISSUER_NAME = os.environ.get("MFA_ISSUER_NAME", "AlertHub")
# Scheduler
SCHEDULER_INTERVAL_MINUTES = int(os.environ.get("SCHEDULER_INTERVAL_MINUTES", "60"))
# Default reminder lead times in days
DEFAULT_REMINDER_DAYS = os.environ.get("DEFAULT_REMINDER_DAYS", "30,14,7,1")
# SMTP defaults (seed only — admins edit live values via backoffice)
# Purelymail outgoing: smtp.purelymail.com : 465 (SSL/TLS)
SMTP_HOST = os.environ.get("SMTP_HOST", "smtp.purelymail.com")
SMTP_PORT = int(os.environ.get("SMTP_PORT", "465"))
SMTP_USERNAME = os.environ.get("SMTP_USERNAME", "")
SMTP_PASSWORD = os.environ.get("SMTP_PASSWORD", "")
SMTP_ENCRYPTION = os.environ.get("SMTP_ENCRYPTION", "ssl")
SMTP_FROM_ADDRESS = os.environ.get("SMTP_FROM_ADDRESS", "")
SMTP_FROM_NAME = os.environ.get("SMTP_FROM_NAME", "AlertHub")
# IMAP defaults (seed only) — used to save a copy of sent mail to the
# mailbox's Sent folder. Purelymail incoming: imap.purelymail.com : 993 (SSL/TLS)
IMAP_HOST = os.environ.get("IMAP_HOST", "imap.purelymail.com")
IMAP_PORT = int(os.environ.get("IMAP_PORT", "993"))
IMAP_USERNAME = os.environ.get("IMAP_USERNAME", "")
IMAP_PASSWORD = os.environ.get("IMAP_PASSWORD", "")
IMAP_SENT_FOLDER = os.environ.get("IMAP_SENT_FOLDER", "Sent")
# Ports (used by run scripts only)
FRONTOFFICE_PORT = int(os.environ.get("FRONTOFFICE_PORT", "8080"))
BACKOFFICE_PORT = int(os.environ.get("BACKOFFICE_PORT", "9001"))
# Optional explicit public URLs for the cross-console links in the top bar.
# If empty, the app derives them from the request host + the ports above
# (e.g. http://<your-host>:9001/). Set these when behind a reverse proxy
# or when the consoles are reached at custom hostnames/paths.
BACKOFFICE_PUBLIC_URL = os.environ.get("BACKOFFICE_PUBLIC_URL", "")
FRONTOFFICE_PUBLIC_URL = os.environ.get("FRONTOFFICE_PUBLIC_URL", "")
# Resource limits
MAX_CONTENT_LENGTH = 2 * 1024 * 1024 # 2MB upload cap
WTF_CSRF_TIME_LIMIT = 3600