From 697854e4068812d80302a2ce99410600efdad344 Mon Sep 17 00:00:00 2001 From: derekc Date: Sun, 22 Mar 2026 01:26:42 -0700 Subject: [PATCH] Add ntfy notification for super admin login Co-Authored-By: Claude Sonnet 4.6 --- README.md | 2 +- backend/app/routers/admin.py | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ac17701..57668c4 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ A self-hosted web app for managing homeschool schedules, tracking daily learning - **Password Change** — Users can change their own account password from Admin → Settings → Reset Password. The form requires the current password before accepting a new one. - **Multi-Child Support** — Manage multiple students under one parent account, each with their own color, schedule, and history. - **JWT Authentication** — Secure parent login with access tokens and httpOnly refresh cookies. TV dashboard is public (no login required). Disabled accounts receive a clear error message explaining the account is disabled rather than a generic "invalid credentials" response. After **5 consecutive failed login attempts**, an account is locked for **15 minutes** — the error message includes the remaining wait time. Locks clear automatically after the cooldown, or immediately when a super admin resets the account's password. -- **Ntfy Push Notifications** — Optional push notifications delivered to the super admin via [Ntfy](https://ntfy.sh). Alerts are sent for: new user registration, account lockout after 5 failed login attempts, and login attempts on an already-locked account. Works with ntfy.sh (public or self-hosted). Configure via `NTFY_URL` and optionally `NTFY_TOKEN` in `.env`. +- **Ntfy Push Notifications** — Optional push notifications delivered to the super admin via [Ntfy](https://ntfy.sh). Alerts are sent for: new user registration, account lockout after 5 failed login attempts, login attempts on an already-locked account, and super admin login. Works with ntfy.sh (public or self-hosted). Configure via `NTFY_URL` and optionally `NTFY_TOKEN` in `.env`. - **Super Admin Panel** — A separate admin interface (at `/super-admin`) for site-wide management. Log in with a dedicated admin username and password (set in `.env`). Provides full control over all registered parent accounts: - **Impersonate** — Enter any user's session to view and manage their data. An impersonation banner is shown at the top of every page with a one-click "Exit to Admin Panel" button. - **Reset Password** — Set a new password for any user without needing the current password. Also clears any active login lockout on the account. diff --git a/backend/app/routers/admin.py b/backend/app/routers/admin.py index 33ff2a3..b91db8e 100644 --- a/backend/app/routers/admin.py +++ b/backend/app/routers/admin.py @@ -9,6 +9,7 @@ from app.auth.jwt import create_admin_token, create_access_token, hash_password from app.config import get_settings from app.dependencies import get_db, get_admin_user from app.models.user import User +from app.utils.ntfy import notify router = APIRouter(prefix="/api/admin", tags=["admin"]) settings = get_settings() @@ -22,6 +23,12 @@ async def admin_login(body: dict): logger.warning("Failed super-admin login attempt for username=%s", username) raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid admin credentials") token = create_admin_token({"sub": "admin"}) + await notify( + title="Super Admin Login", + message=f"Admin logged in as: {username}", + priority="high", + tags=["key"], + ) return {"access_token": token, "token_type": "bearer"}