feat: scheduled Strava sync + admin suspend/delete account
- Add bincio sync-strava command: headless multi-user Strava sync
designed for systemd timer. Discovers users via strava_token.json,
skips users without their own strava_credentials.json, respects
Strava visibility (only_me → unlisted). Treats 404 stream errors as
no-GPS activities rather than retrying every run.
- Add deploy/systemd/bincio-sync.{service,timer}: runs every 3 hours,
Persistent=true to catch up after downtime.
- Add POST /api/internal/rebuild: webhook for sync timer to trigger
site rebuild, authenticated via X-Sync-Secret header.
- Add suspended column to users table with auto-migration on open_db.
Suspended users are blocked at login and session lookup (covers both
activity site and wiki, which share instance.db).
- Add POST /api/admin/users/{handle}/suspend|unsuspend and
DELETE /api/admin/users/{handle}/account endpoints.
- Admin panel: Suspend/Unsuspend toggle, Del account button, suspended
badge on user row.
This commit is contained in:
+5
-1
@@ -22,10 +22,12 @@ console = Console()
|
||||
@click.option("--public-url", default=None, envvar="PUBLIC_URL", help="Public base URL (e.g. https://yourdomain.com). Required for Strava OAuth to work behind a reverse proxy.")
|
||||
@click.option("--webroot", default=None, type=click.Path(), help="Nginx webroot (e.g. /var/www/bincio). When set, uploads trigger a full Astro build + rsync so new activity pages are immediately accessible without a git push.")
|
||||
@click.option("--dem-url", default=None, envvar="DEM_URL", help="Base URL of an Open-Elevation-compatible API (default: https://api.open-elevation.com).")
|
||||
@click.option("--sync-secret", default=None, envvar="BINCIO_SYNC_SECRET", help="Shared secret for POST /api/internal/rebuild (used by the sync-strava systemd timer).")
|
||||
def serve(data_dir: str, site_dir: Optional[str], host: str, port: int,
|
||||
strava_client_id: Optional[str], strava_client_secret: Optional[str],
|
||||
max_users: Optional[int], public_url: Optional[str],
|
||||
webroot: Optional[str], dem_url: Optional[str]) -> None:
|
||||
webroot: Optional[str], dem_url: Optional[str],
|
||||
sync_secret: Optional[str]) -> None:
|
||||
"""Start the bincio multi-user application server.
|
||||
|
||||
Handles auth, user management, and write operations.
|
||||
@@ -61,6 +63,8 @@ def serve(data_dir: str, site_dir: Optional[str], host: str, port: int,
|
||||
srv.webroot = Path(webroot).expanduser().resolve()
|
||||
if dem_url:
|
||||
srv.dem_url = dem_url
|
||||
if sync_secret:
|
||||
srv.sync_secret = sync_secret
|
||||
|
||||
db = open_db(dd)
|
||||
current_limit = get_setting(db, "max_users")
|
||||
|
||||
Reference in New Issue
Block a user