P2 cleanups: pin deps, prune job-run rows, unmask non-secret creds, enforce allowlist at login
- R11: pin requirements.txt to the versions running in the image, so a rebuild can't pull a breaking upstream release. Documented how to upgrade. - R12: log rotation now also prunes job_runs rows older than 90 days (nulling the manual_imports FK reference first), so the table doesn't grow without bound. dedup/genre candidates are review state and left alone. - U5: credential form shows non-secret fields (URLs, usernames, prefs) as plain text so they can be verified while typing; only real secrets stay masked. Dashboard IP card reworded from gluetun-specific to generic "Outbound IP". - S9: enforce ALLOWED_EMAIL at the OIDC callback, before any user row or session is created, instead of only on later requests. Verified: pinned build resolves; prune deletes only old rows and keeps the manual_imports record; credentials page renders text+password inputs; a disallowed email gets 403 with no user row, an allowed one succeeds. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -44,6 +44,20 @@ SCOPE_DESCRIPTIONS = {
|
||||
CORE_SCOPES = {"spotify", "soulseek", "navidrome"}
|
||||
OPTIONAL_SCOPES = {"bandcamp", "azuracast", "qobuz", "telegram"}
|
||||
|
||||
# The genuinely-secret fields, masked in the UI. Everything else is an
|
||||
# identifier, URL, or preference the user should be able to see while typing
|
||||
# so they can verify it (e.g. the Navidrome base URL or their Soulseek
|
||||
# username). Values are write-only either way -- never sent back to the browser.
|
||||
SECRET_KEYS = {
|
||||
"client_secret",
|
||||
"password",
|
||||
"admin_pass",
|
||||
"cookies_txt",
|
||||
"api_key",
|
||||
"token",
|
||||
"bot_token",
|
||||
}
|
||||
|
||||
|
||||
def _upsert(db: Session, scope: str, key: str, value: str) -> None:
|
||||
row = db.execute(
|
||||
|
||||
Reference in New Issue
Block a user