fix: OAuth client API returned client_id: undefined; unknown id 500'd

The ORM Model.toJSON() serializes only schema fields, so the mapped
client_id/scopes/redirect_uris/... that OAuthClient.get() attaches to
the wrapped Resource were stripped from GET /api/oauth/client[/:id]
responses. client_id came back undefined; the theta-env bootstrap then
POSTed /api/oauth/client/undefined/rotate and got a 500, aborting stack
bring-up whenever proxy-secrets.js lacked a usable secret.

- OAuthClient.get() now emits an explicit public toJSON (client_id, name,
  slug, scopes, redirect_uris, allowed_groups, token_lifetime, is_valid),
  deliberately omitting client_secret_hash so it can't leak over the API.
- OAuthClient.get() null-guards Resource.get() (which returns null, not
  throws) and returns a clean 404 for an unknown/undefined id instead of
  crashing on r.kind.
- Regression tests: list/get expose client_id + hide the secret hash, the
  list-then-rotate bootstrap path, and unknown-id -> 4xx not 500.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-23 16:06:55 -04:00
parent 14b6ed5ae0
commit 0ee6825a01
5 changed files with 101 additions and 5 deletions
+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "t42-sso-manager",
"version": "1.3.1",
"version": "1.3.2",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "t42-sso-manager",
"version": "1.3.1",
"version": "1.3.2",
"license": "MIT",
"dependencies": {
"@fortawesome/fontawesome-free": "^7.3.0",