diff --git a/app/main.py b/app/main.py index dafdce1..17d6a2e 100644 --- a/app/main.py +++ b/app/main.py @@ -292,13 +292,17 @@ def get_db() -> sqlite3.Connection: ak_cols = [r[1] for r in conn.execute("PRAGMA table_info(member_api_keys)").fetchall()] if "fingerprint" not in ak_cols: conn.execute("ALTER TABLE member_api_keys ADD COLUMN fingerprint TEXT") - # Backfill fingerprints for keys that already have plaintext stored, - # then purge the plaintext. (fingerprint = last-4 of the key.) - conn.execute( - "UPDATE member_api_keys SET fingerprint = substr(sk_token, -4) " - "WHERE fingerprint IS NULL AND sk_token != ''" - ) + # Backfill fingerprints for any key still holding plaintext (fingerprint = + # last-4 of the key), then purge the plaintext. Idempotent — runs every + # time, affects only rows where plaintext is still present. + conn.execute( + "UPDATE member_api_keys SET fingerprint = substr(sk_token, -4) " + "WHERE (fingerprint IS NULL OR fingerprint = '') AND sk_token != ''" + ) conn.execute("UPDATE member_api_keys SET sk_token = '' WHERE sk_token != ''") + # Commit the DML above — ALTER TABLE auto-commits, but the UPDATEs open an + # implicit transaction that would otherwise roll back when get_db() closes. + conn.commit() return conn