Fix PocketID secret wiped on re-save; log token-exchange failures
Build and push images / validate (push) Successful in 19s
Build and push images / build-backend (push) Successful in 29s
Build and push images / build-worker (push) Successful in 29s
Build and push images / build-frontend (push) Successful in 29s

save_pocketid_config cleared the stored client secret whenever the form was
submitted with a blank secret field — but the UI hint says blank means "keep
existing". Re-saving config (e.g. to set the allowed group) therefore wiped the
secret and broke token exchange ("Token exchange failed"). Now a blank field
keeps the existing secret; only a non-empty value overwrites it.

Also log PocketID's actual token-endpoint response body on failure so the cause
(invalid_client, redirect_uri mismatch, etc.) is visible in backend logs.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-08 13:26:35 +01:00
parent 0dd6eba589
commit 0e18ef2291
4 changed files with 10 additions and 4 deletions
+1
View File
@@ -119,6 +119,7 @@ async def pocketid_callback(code: str, db: AsyncSession = Depends(get_db)):
"client_id": client_id, "client_secret": client_secret}, "client_id": client_id, "client_secret": client_secret},
) )
if resp.status_code != 200: if resp.status_code != 200:
print(f"PocketID token exchange failed ({resp.status_code}): {resp.text}")
raise HTTPException(status_code=400, detail="Token exchange failed") raise HTTPException(status_code=400, detail="Token exchange failed")
tokens = resp.json() tokens = resp.json()
userinfo_resp = await client.get( userinfo_resp = await client.get(
+4 -2
View File
@@ -154,8 +154,10 @@ async def save_pocketid_config(
current_user.pocketid_issuer = body.issuer.rstrip("/") if body.issuer else None current_user.pocketid_issuer = body.issuer.rstrip("/") if body.issuer else None
if body.client_id is not None: if body.client_id is not None:
current_user.pocketid_client_id = body.client_id or None current_user.pocketid_client_id = body.client_id or None
if body.client_secret is not None: # Only overwrite the secret when a non-empty value is supplied; a blank
current_user.pocketid_client_secret = body.client_secret or None # field means "keep the existing secret" (matches the UI hint).
if body.client_secret:
current_user.pocketid_client_secret = body.client_secret
if body.allowed_group is not None: if body.allowed_group is not None:
current_user.pocketid_allowed_group = body.allowed_group.strip() or None current_user.pocketid_allowed_group = body.allowed_group.strip() or None
await db.commit() await db.commit()
+1
View File
@@ -119,6 +119,7 @@ async def pocketid_callback(code: str, db: AsyncSession = Depends(get_db)):
"client_id": client_id, "client_secret": client_secret}, "client_id": client_id, "client_secret": client_secret},
) )
if resp.status_code != 200: if resp.status_code != 200:
print(f"PocketID token exchange failed ({resp.status_code}): {resp.text}")
raise HTTPException(status_code=400, detail="Token exchange failed") raise HTTPException(status_code=400, detail="Token exchange failed")
tokens = resp.json() tokens = resp.json()
userinfo_resp = await client.get( userinfo_resp = await client.get(
+4 -2
View File
@@ -154,8 +154,10 @@ async def save_pocketid_config(
current_user.pocketid_issuer = body.issuer.rstrip("/") if body.issuer else None current_user.pocketid_issuer = body.issuer.rstrip("/") if body.issuer else None
if body.client_id is not None: if body.client_id is not None:
current_user.pocketid_client_id = body.client_id or None current_user.pocketid_client_id = body.client_id or None
if body.client_secret is not None: # Only overwrite the secret when a non-empty value is supplied; a blank
current_user.pocketid_client_secret = body.client_secret or None # field means "keep the existing secret" (matches the UI hint).
if body.client_secret:
current_user.pocketid_client_secret = body.client_secret
if body.allowed_group is not None: if body.allowed_group is not None:
current_user.pocketid_allowed_group = body.allowed_group.strip() or None current_user.pocketid_allowed_group = body.allowed_group.strip() or None
await db.commit() await db.commit()