Skip to content

Commit d8b5f41

Browse files
committed
chore(changeset): declare the redirect_uris optionality change (#17215)
Claude-Session: https://claude.ai/code/session_01TSf4DV7ziu4V5j73e46b7c Co-authored-by: Claude <noreply@anthropic.com>
1 parent 2d8fd66 commit d8b5f41

1 file changed

Lines changed: 36 additions & 0 deletions

File tree

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
---
2+
"@objectstack/client": minor
3+
---
4+
5+
fix(client): `oauth.applications.register` declares `redirect_uris` optional, matching the body schema of the route it posts to (#17215)
6+
7+
`ObjectStackClient.oauth.applications.register` declared `redirect_uris` **required**. `POST /api/v1/auth/oauth2/create-client` is mounted verbatim from `@better-auth/oauth-provider`, and that route's body schema declares the member **optional** — so a request the route accepts had no spelling through this SDK. The caller never got a wrong answer; they got a call they could not write.
8+
9+
## What changes for a caller
10+
11+
Nothing they have to do. Every existing call still compiles — this only *adds* spellings:
12+
13+
```ts
14+
// now expressible, and accepted by the route:
15+
await client.oauth.applications.register({ client_name: 'My App' });
16+
17+
// unchanged, and still the right call when you have redirect URIs:
18+
await client.oauth.applications.register({
19+
client_name: 'My App',
20+
redirect_uris: ['https://app.example.com/cb'],
21+
});
22+
```
23+
24+
⛔ Not breaking in this direction — relaxing a required member to optional keeps every existing call valid. Tightening it back later would be breaking, which is why the parity is now pinned.
25+
26+
## Measured at runtime, not read off a `.d.ts`
27+
28+
The vendor body schema was re-introspected the way the card's original measurement was taken: instantiate `oauthProvider()`, walk `endpoints`, find the endpoint whose `path` is `/oauth2/create-client`, read `options.body`. At the installed **1.7.3** (the card measured 1.7.2; the package has since moved) the object still declares **21 members and every one of them is optional**, and `body.safeParse({ client_name: '…' })` succeeds with `redirect_uris` absent.
29+
30+
⚠️ Optional does **not** mean an empty array will do: the vendor refuses `[]`, so when the member is present it must be non-empty. Omitting it and passing `[]` are different requests and only the first is legal. Nor does it mean a client registered without redirect URIs is *usable* — it cannot complete an `authorization_code` flow. The type states what the route accepts, never that every accepted call yields a client fit for every grant; the docblock now says both.
31+
32+
## Why it was required, for the record
33+
34+
Not as a guard. It is residue from the method's first commit, which declared `client_name` required too; the same-day follow-up relaxed `client_name` and left this one behind. No comment, test, ADR or review thread ever asserted a reason for it — which is exactly why it read as a defect to the next auditor.
35+
36+
Nothing else on the signature moves: the other ten members are byte-identical.

0 commit comments

Comments
 (0)