""" app/admin/__init__.py — Admin app factory (admin.mydomain.com). """ import logging from datetime import timedelta from flask import Flask from app.extensions import db, migrate, csrf, mail, scheduler, admin_login_manager, admin_jwt, limiter from app.security import apply_security_headers, check_admin_ip from config import get_config logger = logging.getLogger(__name__) def create_admin_app(config_override=None): flask_app = Flask( __name__, template_folder="../templates", static_folder="../static", static_url_path="/static/admin", ) # ── Config ──────────────────────────────────────────────── cfg = config_override or get_config() flask_app.config.from_object(cfg) # Admin portal uses a separate secret key and session cookie name import os flask_app.config["SECRET_KEY"] = os.environ.get( "ADMIN_SECRET_KEY", flask_app.config["SECRET_KEY"] ) flask_app.config["SESSION_COOKIE_NAME"] = "salon_pos_admin_session" flask_app.config["PERMANENT_SESSION_LIFETIME"] = timedelta( seconds=int(os.environ.get("SESSION_TIMEOUT_ADMIN", 3600)) ) flask_app.config["SESSION_COOKIE_HTTPONLY"] = True flask_app.config["SESSION_COOKIE_SAMESITE"] = "Lax" # ── Extensions ──────────────────────────────────────────── db.init_app(flask_app) migrate.init_app(flask_app, db) csrf.init_app(flask_app) mail.init_app(flask_app) limiter.init_app(flask_app) # Admin login manager admin_login_manager.login_view = "admin_auth.login" admin_login_manager.login_message_category = "warning" admin_login_manager.session_protection = "strong" admin_login_manager.init_app(flask_app) # Admin JWT admin_jwt.init_app(flask_app) # ── User loader ─────────────────────────────────────────── from app.models.platform import SystemUser @admin_login_manager.user_loader def load_admin_user(user_id: str): if not user_id.startswith("system:"): return None try: uid = int(user_id.split(":")[1]) except (ValueError, IndexError): return None return SystemUser.query.get(uid) # ── Security ────────────────────────────────────────────── apply_security_headers(flask_app) check_admin_ip(flask_app) # ── Blueprints ──────────────────────────────────────────── from app.admin.auth.routes import admin_auth_bp flask_app.register_blueprint(admin_auth_bp) # Placeholder blueprints registered in later phases: # system_users, tenants, plans, billing, settings_override, audit_log, analytics # ── Import all models for Migrate ───────────────────────── import app.models # noqa: F401 logger.info("Admin app created (env=%s)", flask_app.config.get("FLASK_ENV")) return flask_app