Deploy Stride with encrypted manual and scheduled Garmin sync

This commit is contained in:
Peter Stockings
2026-10-01 20:42:28 +10:00
parent 24c7fc2c6a
commit 8555695c5e
28 changed files with 900 additions and 56 deletions
+14 -3
View File
@@ -5,7 +5,7 @@ from pathlib import Path
from zoneinfo import ZoneInfo
import click
from flask import Flask, render_template
from flask import Flask, render_template, request
from .extensions import csrf, db, limiter, login_manager, migrate
@@ -13,7 +13,7 @@ ROOT = Path(__file__).resolve().parents[1]
def create_app(config=None):
app = Flask(__name__, instance_path=str(ROOT / "instance"))
app = Flask(__name__, instance_path=os.environ.get("INSTANCE_PATH", str(ROOT / "instance")))
production = os.environ.get("APP_ENV") == "production"
app.config.from_mapping(
SQLALCHEMY_DATABASE_URI=os.environ.get("DATABASE_URL", "sqlite:///dashboard.db"),
@@ -24,10 +24,15 @@ def create_app(config=None):
PERMANENT_SESSION_LIFETIME=timedelta(days=7),
MAX_CONTENT_LENGTH=16 * 1024 * 1024,
LOCAL_SETUP=not production,
DATA_ROOT=str(ROOT / "data" / "garmin"),
DATA_ROOT=os.environ.get("DATA_ROOT", str(ROOT / "data" / "garmin")),
TOKEN_ENCRYPTION_KEY=os.environ.get("TOKEN_ENCRYPTION_KEY"),
RATELIMIT_STORAGE_URI=os.environ.get("RATELIMIT_STORAGE_URI", "memory://"),
)
app.config.update(config or {})
if production:
from werkzeug.middleware.proxy_fix import ProxyFix
app.wsgi_app = ProxyFix(app.wsgi_app, x_for=1, x_proto=1)
if production and (not app.config["SECRET_KEY"] or not os.environ.get("DATABASE_URL")):
raise RuntimeError("Production requires SECRET_KEY and DATABASE_URL.")
if not app.config["SECRET_KEY"]:
@@ -59,6 +64,9 @@ def create_app(config=None):
from .routes import web
app.register_blueprint(web)
from .sync import register_cli
register_cli(app)
@login_manager.user_loader
def load_user(user_id):
@@ -84,6 +92,9 @@ def create_app(config=None):
response.headers["X-Content-Type-Options"] = "nosniff"
response.headers["X-Frame-Options"] = "DENY"
response.headers["Referrer-Policy"] = "strict-origin-when-cross-origin"
if request.path.startswith("/shared/runs/"):
response.headers["Referrer-Policy"] = "no-referrer"
response.headers["X-Robots-Tag"] = "noindex, nofollow"
return response
for code in (400, 403, 404, 413, 429):