Repository navigation
Take Hardcover's new API keys, with or without "Bearer" - #1655
Conversation
Hardcover's API page now hands out bare keys (hc_pat_…), but the API still
requires `Authorization: Bearer <key>`, and the app sent the saved text as
the whole header. A key pasted as shown was rejected ("Invalid Authorization
format"). The key is now saved bare (a pasted "Bearer " is dropped) and every
request adds the scheme; tokens saved with it before read without it, so
existing links keep working. The placeholder shows the new key format.
| ThemedSection { | ||
| TextField( | ||
| "Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXV…", | ||
| "hc_pat_…", |
There was a problem hiding this comment.
🔵 INFO — This placeholder is the TextField's only label, so VoiceOver announces the empty field as "hc_pat_…". That tells a VoiceOver user very little (the old Bearer eyJ… placeholder had the same problem). Since this line is changing anyway, consider adding .accessibilityLabel("hardcover_api_access_title".localized) to the TextField, so the field is announced by its section title while the placeholder stays as a format hint.
✅ Claude PR Review —
|
Hardcover's API page now hands out bare API keys (
hc_pat_…) instead of the oldBearer eyJ…token, and the Hardcover settings placeholder still showed the old format. The API itself still requires theBearerscheme, and the app sent whatever was saved as the wholeAuthorizationheader, so a key pasted the way Hardcover shows it now was rejected.What changes
HardcoverService.authorizationkeeps the bare key;HardcoverService.apiKey(from:)trims the input and drops a leadingBearer(any case, any whitespace), and every GraphQL request sendsAuthorization: Bearer <key>.Bearerprefix read without it, so their header is byte-for-byte what it was. Nothing is migrated: the Keychain value is rewritten bare the next time Settings is saved.hc_pat_…. Save stays disabled for input that's onlyBeareror whitespace (before,Beareralone could be saved and sent).How Hardcover answers (probed with fake keys)
Authorizationheaderhc_pat_…(what the app sent for a key pasted as shown)Invalid Authorization format. Use 'Bearer <token>'Bearer hc_pat_…/bearer hc_pat_…Invalid or expired token(format accepted)eyJ…without the schemeInvalid Authorization formatBearer eyJ…(the old tokens)Token is not associated with a user(format accepted)Testing
HardcoverServiceTests(new, 8 tests) pass on Xcode 27.1, iOS 27.0 simulator: a bare key is kept;Bearer/bearer/BEARERwith spaces, several spaces or a tab is dropped; surrounding whitespace and newlines are trimmed;Beareralone and whitespace alone come out empty; a key that only starts with "bearer" is kept; savingBearer hc_pat_…stores the bare key; a token saved asBearer eyJ…reads bare; savingBearerremoves the token.hc_pat_key on a device.