feat: production-harden app and finalize merge-ready UX/theme baseline
- complete tokenized theme preset system and admin style guide visibility - refine dashboard layout/scroll behavior and shared async/request UI states - add user nav-visibility settings across API, migration, and frontend stores - harden security headers/CSP handling and related test coverage - enforce CI repository hygiene + frontend contract/theme/build quality gates - update docs/env references and make migration smoke test head-aware
This commit is contained in:
parent
ab1d29b203
commit
ae2ca8f149
66 changed files with 5655 additions and 853 deletions
|
|
@ -1,6 +1,33 @@
|
|||
from dataclasses import dataclass
|
||||
import os
|
||||
|
||||
DEFAULT_SECURITY_PERMISSIONS_POLICY = (
|
||||
"accelerometer=(), autoplay=(), camera=(), display-capture=(), "
|
||||
"geolocation=(), gyroscope=(), microphone=(), payment=(), usb=()"
|
||||
)
|
||||
DEFAULT_SECURITY_CSP_POLICY = (
|
||||
"default-src 'self'; "
|
||||
"base-uri 'self'; "
|
||||
"form-action 'self'; "
|
||||
"frame-ancestors 'none'; "
|
||||
"img-src 'self' data: https:; "
|
||||
"script-src 'self'; "
|
||||
"style-src 'self' 'unsafe-inline'; "
|
||||
"font-src 'self' data:; "
|
||||
"connect-src 'self'; "
|
||||
"object-src 'none'"
|
||||
)
|
||||
DEFAULT_SECURITY_CSP_DOCS_POLICY = (
|
||||
"default-src 'self'; "
|
||||
"img-src 'self' data: https:; "
|
||||
"script-src 'self' 'unsafe-inline'; "
|
||||
"style-src 'self' 'unsafe-inline'; "
|
||||
"font-src 'self' data:; "
|
||||
"connect-src 'self' https:; "
|
||||
"object-src 'none'; "
|
||||
"frame-ancestors 'none'"
|
||||
)
|
||||
|
||||
|
||||
def _env_bool(name: str, default: bool) -> bool:
|
||||
value = os.getenv(name)
|
||||
|
|
@ -39,6 +66,42 @@ class Settings:
|
|||
)
|
||||
session_secret_key: str = os.getenv("SESSION_SECRET_KEY", "dev-insecure-session-key")
|
||||
session_cookie_secure: bool = _env_bool("SESSION_COOKIE_SECURE", False)
|
||||
security_headers_enabled: bool = _env_bool("SECURITY_HEADERS_ENABLED", True)
|
||||
security_x_content_type_options: str = _env_str("SECURITY_X_CONTENT_TYPE_OPTIONS", "nosniff")
|
||||
security_x_frame_options: str = _env_str("SECURITY_X_FRAME_OPTIONS", "DENY")
|
||||
security_referrer_policy: str = _env_str("SECURITY_REFERRER_POLICY", "strict-origin-when-cross-origin")
|
||||
security_permissions_policy: str = _env_str(
|
||||
"SECURITY_PERMISSIONS_POLICY",
|
||||
DEFAULT_SECURITY_PERMISSIONS_POLICY,
|
||||
)
|
||||
security_cross_origin_opener_policy: str = _env_str(
|
||||
"SECURITY_CROSS_ORIGIN_OPENER_POLICY",
|
||||
"same-origin",
|
||||
)
|
||||
security_cross_origin_resource_policy: str = _env_str(
|
||||
"SECURITY_CROSS_ORIGIN_RESOURCE_POLICY",
|
||||
"same-origin",
|
||||
)
|
||||
security_csp_enabled: bool = _env_bool("SECURITY_CSP_ENABLED", True)
|
||||
security_csp_policy: str = _env_str("SECURITY_CSP_POLICY", DEFAULT_SECURITY_CSP_POLICY)
|
||||
security_csp_docs_policy: str = _env_str("SECURITY_CSP_DOCS_POLICY", DEFAULT_SECURITY_CSP_DOCS_POLICY)
|
||||
security_csp_report_only: bool = _env_bool("SECURITY_CSP_REPORT_ONLY", False)
|
||||
security_strict_transport_security_enabled: bool = _env_bool(
|
||||
"SECURITY_STRICT_TRANSPORT_SECURITY_ENABLED",
|
||||
False,
|
||||
)
|
||||
security_strict_transport_security_max_age: int = _env_int(
|
||||
"SECURITY_STRICT_TRANSPORT_SECURITY_MAX_AGE",
|
||||
31_536_000,
|
||||
)
|
||||
security_strict_transport_security_include_subdomains: bool = _env_bool(
|
||||
"SECURITY_STRICT_TRANSPORT_SECURITY_INCLUDE_SUBDOMAINS",
|
||||
True,
|
||||
)
|
||||
security_strict_transport_security_preload: bool = _env_bool(
|
||||
"SECURITY_STRICT_TRANSPORT_SECURITY_PRELOAD",
|
||||
False,
|
||||
)
|
||||
login_rate_limit_attempts: int = _env_int("LOGIN_RATE_LIMIT_ATTEMPTS", 5)
|
||||
login_rate_limit_window_seconds: int = _env_int(
|
||||
"LOGIN_RATE_LIMIT_WINDOW_SECONDS",
|
||||
|
|
@ -116,11 +179,11 @@ class Settings:
|
|||
)
|
||||
scholar_name_search_min_interval_seconds: float = _env_float(
|
||||
"SCHOLAR_NAME_SEARCH_MIN_INTERVAL_SECONDS",
|
||||
3.0,
|
||||
8.0,
|
||||
)
|
||||
scholar_name_search_interval_jitter_seconds: float = _env_float(
|
||||
"SCHOLAR_NAME_SEARCH_INTERVAL_JITTER_SECONDS",
|
||||
1.0,
|
||||
2.0,
|
||||
)
|
||||
scholar_name_search_cooldown_block_threshold: int = _env_int(
|
||||
"SCHOLAR_NAME_SEARCH_COOLDOWN_BLOCK_THRESHOLD",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue