feat(admin): delete a whitelist entry, and stop hiding a broken mail setup

Three operator gaps, all found the same way — a person could not sign up and the
app showed nobody anything.

- DELETE /api/admin/invites/{id} with a delete control on both the pending
  requests and the previously-decided list. Deny keeps the row so the person
  cannot immediately re-ask; delete forgets the address. Refused with 409 while
  a User row exists for it, because is_allowed reads that row and removing it
  would revoke a live user's access with no other sign — the list ships
  has_account so the UI withholds the button instead of offering one that fails.
- Email is fail-soft by design, which had come to mean invisible. _send() now
  records an email_undelivered notification for every admin when a message is
  skipped or rejected, naming the message that was lost, throttled to one an
  hour. /api/me carries email_configured, driving a standing warning on
  Configuration → Email / SMTP and above the access-request list.
- The sign-in card's Create account / Forgot password / Didn't get the email
  views are history entries (useHistorySubview), so Back returns to the previous
  view instead of only moving the address bar.

Also: the per-test rate-limiter reset sweeps every loaded app.* module rather
than a hand-kept list of three — this change added a limiter outside it.
This commit is contained in:
2026-09-01 23:09:25 +02:00
parent 24c93cbb83
commit 44f626f732
25 changed files with 636 additions and 23 deletions
@@ -19,5 +19,6 @@
"job_run": "Scheduler job run",
"audit_clear": "Audit log cleared",
"download_credential_set": "Download cookies set",
"download_credential_delete": "Download cookies removed"
"download_credential_delete": "Download cookies removed",
"invite_delete": "Whitelist entry deleted"
}
+2 -1
View File
@@ -216,5 +216,6 @@
"plexPickLibraries": "Libraries to expose:",
"plexPickHint": "Unchecking all is the same as exposing every library. Remember to Save.",
"plexMovies": "Movies",
"plexShows": "TV Shows"
"plexShows": "TV Shows",
"emailOff": "Email sending is not configured — Siftlode silently skips every message: verification links, password resets and access-request notices. Fill in the fields above, then send a test."
}
+5
View File
@@ -28,5 +28,10 @@
"jobDone": {
"titleOk": "{{job}} finished",
"titleError": "{{job}} failed"
},
"emailUndelivered": {
"title": "Email could not be sent",
"notConfigured": "SMTP is not configured, so “{{subject}}” was skipped. Until it is set up, no message leaves this instance.",
"sendFailed": "The mail server rejected “{{subject}}”. Check Configuration → Email / SMTP and send a test."
}
}
+10 -1
View File
@@ -164,6 +164,15 @@
"deny": "Deny",
"denied": "Request denied",
"denyTitle": "Deny access request?",
"denyConfirm": "Deny the access request from {{email}}?"
"denyConfirm": "Deny the access request from {{email}}?",
"delete": "Delete",
"deleteLabel": "Delete {{email}} from the whitelist",
"deleteHint": "Remove this address entirely. A later request from it starts over.",
"deleteTitle": "Delete whitelist entry?",
"deleteConfirm": "Remove {{email}} from the whitelist? If they were approved, they lose access until you add them again.",
"deleteHasAccount": "This address has an account — delete the user instead.",
"deleted": "Whitelist entry removed.",
"deleteFailed": "Could not remove the entry.",
"emailOff": "Email sending is not configured, so nobody gets a verification link and you get no notice when someone signs up. Fix it under Configuration → Email / SMTP."
}
}
@@ -19,5 +19,6 @@
"job_run": "Ütemező job lefutott",
"audit_clear": "Napló ürítve",
"download_credential_set": "Letöltési cookie-k beállítva",
"download_credential_delete": "Letöltési cookie-k eltávolítva"
"download_credential_delete": "Letöltési cookie-k eltávolítva",
"invite_delete": "Whitelista-bejegyzés törölve"
}
+2 -1
View File
@@ -216,5 +216,6 @@
"plexPickLibraries": "Megjelenítendő könyvtárak:",
"plexPickHint": "Ha egyiket sem jelölöd be, az az összes könyvtár megjelenítésével egyenértékű. Ne feledj menteni.",
"plexMovies": "Filmek",
"plexShows": "Sorozatok"
"plexShows": "Sorozatok",
"emailOff": "Az e-mail-küldés nincs beállítva — a Siftlode némán kihagy minden üzenetet: megerősítő linkeket, jelszó-visszaállításokat és hozzáférés-kérés értesítőket. Töltsd ki a fenti mezőket, majd küldj tesztet."
}
+5
View File
@@ -28,5 +28,10 @@
"jobDone": {
"titleOk": "{{job}} kész",
"titleError": "{{job}} hibázott"
},
"emailUndelivered": {
"title": "Egy e-mailt nem sikerült elküldeni",
"notConfigured": "Az SMTP nincs beállítva, ezért a(z) „{{subject}}” kimaradt. Amíg nincs beállítva, egyetlen üzenet sem hagyja el ezt a példányt.",
"sendFailed": "A levelezőszerver visszautasította a(z) „{{subject}}” üzenetet. Nézd meg a Konfiguráció → E-mail / SMTP fület, és küldj tesztet."
}
}
+10 -1
View File
@@ -164,6 +164,15 @@
"deny": "Elutasítás",
"denied": "Kérelem elutasítva",
"denyTitle": "Elutasítod a hozzáférési kérelmet?",
"denyConfirm": "Elutasítod {{email}} hozzáférési kérelmét?"
"denyConfirm": "Elutasítod {{email}} hozzáférési kérelmét?",
"delete": "Törlés",
"deleteLabel": "{{email}} törlése a whitelistáról",
"deleteHint": "A cím teljes eltávolítása. Egy későbbi kérelme elölről indul.",
"deleteTitle": "Törlöd a whitelista-bejegyzést?",
"deleteConfirm": "Eltávolítod {{email}} címet a whitelistáról? Ha jóvá volt hagyva, elveszíti a hozzáférést, amíg újra hozzá nem adod.",
"deleteHasAccount": "Ehhez a címhez már tartozik fiók — a felhasználót töröld helyette.",
"deleted": "Whitelista-bejegyzés eltávolítva.",
"deleteFailed": "A bejegyzést nem sikerült eltávolítani.",
"emailOff": "Az e-mail-küldés nincs beállítva, így senki nem kap megerősítő linket, és te sem kapsz értesítést, ha valaki regisztrál. A Konfiguráció → E-mail / SMTP fülön javítható."
}
}