Seed with the token production is actually reachable with

secrets/amber.env holds PB_ADMIN_TOKEN and no superuser password, so the
email/password-only seeder could not be pointed at the live instance
without inventing a credential to satisfy it.

The token is also verified up front against a superuser-only endpoint,
because listing records cannot answer whether it is valid: PocketBase
applies a listRule as a FILTER, so a stale token returns 200 with zero
rows, indistinguishable from an empty collection. The seeder then decided
all four providers were missing and the first visible error was
"[FAIL] prehrajto: HTTP 403 Only superusers can perform this action",
blaming the row instead of the token. Found by trying it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Claude 2026-08-12 19:24:25 +02:00
parent 57585d8ad2
commit 9dd677b442

View file

@ -14,13 +14,21 @@ Without `--force` an existing row is left alone and reported as `kept`, which
makes this safe to run after any deploy the collection gets populated on a makes this safe to run after any deploy the collection gets populated on a
fresh instance and untouched on one that is already looked after. fresh instance and untouched on one that is already looked after.
Never reads secrets/amber.env: the superuser credentials come from the Authenticates one of two ways, in this order:
environment or from the local defaults, the same way scripts/verify.py takes
them, so nothing here needs access to the family's credential file. PB_ADMIN_TOKEN an existing superuser token, used as-is
PB_ADMIN_EMAIL/PB_ADMIN_PASS a superuser sign-in (local default below)
The token path exists because that is what the production instance is reachable
with: `secrets/amber.env` holds `PB_ADMIN_TOKEN` and no superuser password, and
inventing one to satisfy this script would be the wrong way round. Never reads that
file itself, so nothing here needs access to the family's credentials, and never
prints the token.
""" """
import json, os, pathlib, sys, urllib.error, urllib.request import json, os, pathlib, sys, urllib.error, urllib.request
BASE = os.environ.get("PB_BASE", "http://localhost:8090").rstrip("/") BASE = os.environ.get("PB_BASE", "http://localhost:8090").rstrip("/")
ADMIN_TOKEN = os.environ.get("PB_ADMIN_TOKEN", "").strip()
ADMIN_EMAIL = os.environ.get("PB_ADMIN_EMAIL", "admin@myanime.local") ADMIN_EMAIL = os.environ.get("PB_ADMIN_EMAIL", "admin@myanime.local")
ADMIN_PASS = os.environ.get("PB_ADMIN_PASS", "Sup3rSecret!123") ADMIN_PASS = os.environ.get("PB_ADMIN_PASS", "Sup3rSecret!123")
FORCE = "--force" in sys.argv FORCE = "--force" in sys.argv
@ -53,12 +61,30 @@ def main():
if unknown: if unknown:
sys.exit(f"unknown slug(s) {sorted(unknown)} — the page has no wiring for these") sys.exit(f"unknown slug(s) {sorted(unknown)} — the page has no wiring for these")
if ADMIN_TOKEN:
token = ADMIN_TOKEN
else:
st, auth = req("POST", "/api/collections/_superusers/auth-with-password", st, auth = req("POST", "/api/collections/_superusers/auth-with-password",
body={"identity": ADMIN_EMAIL, "password": ADMIN_PASS}) body={"identity": ADMIN_EMAIL, "password": ADMIN_PASS})
if st != 200: if st != 200:
sys.exit(f"superuser auth failed against {BASE}: HTTP {st} {auth}") sys.exit(f"superuser auth failed against {BASE}: HTTP {st} {auth}")
token = auth["token"] token = auth["token"]
# Prove the token is really a superuser BEFORE reading anything, against an
# endpoint only a superuser may touch.
#
# Listing records cannot answer this. PocketBase applies a collection's listRule
# as a *filter*, so a stale token comes back HTTP 200 with zero rows — identical
# to a collection that is simply empty. The seeder then decides every provider is
# missing and tries to create all four, and the first thing you see is
# "[FAIL] prehrajto: HTTP 403 Only superusers can perform this action", which
# points at the row instead of at the token. Measured, not assumed.
st, who = req("GET", "/api/collections?perPage=1", token)
if st != 200:
sys.exit(f"HTTP {st} against {BASE}: this is not a valid superuser token. "
"Refresh PB_ADMIN_TOKEN in secrets/amber.env and do not work "
"around it.")
st, existing = req("GET", "/api/collections/providers/records?perPage=200", token) st, existing = req("GET", "/api/collections/providers/records?perPage=200", token)
if st != 200: if st != 200:
sys.exit(f"cannot list providers (is the migration applied?): HTTP {st} {existing}") sys.exit(f"cannot list providers (is the migration applied?): HTTP {st} {existing}")