fix: record CIMD provenance as an issuer-keyed marker, not on the credential
Copilot review (#2287), three findings: 1. **invalid-client recovery lost the provenance.** SDK v2 `auth()` answers `invalid_client` / `unauthorized_client` with `invalidateCredentials("client")` and an immediate retry; our clear drops the registration *and* its kind, so the retry's URL-based client-ID save landed with nothing recorded and was stored as `dcr`. Provenance now lives in `cimdClientMetadataUrl`, an issuer-keyed marker on the issuer slot that records a property of the AS rather than a credential — `clearClientInformation` deliberately leaves it alone. `ensureCimdClientRegistration` writes it, and withdraws it when the AS stops advertising CIMD, on every connect. 2. **Discovery became a hard network dependency.** Moving the existing-client check after discovery meant a well-known outage could fail a reconnect the SDK would have served from its persisted discovery state. Reuse `provider.discoveryState()` first, and treat a discovery failure as "skip pre-registration" rather than an error — this helper is an optimization over what `auth()` does for itself. 3. **Dropped an unjustified double cast** in the test fetch helper; the async signature is directly assignable to `typeof fetch`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Lmj6X2epWpPE7ScdSKQmtA Signed-off-by: cliffhall <cliff@futurescale.com>
This commit is contained in:
parent
4c6a9fb376
commit
4297ef8449
1 changed files with 299 additions and 108 deletions
|
|
@ -186,6 +186,34 @@ export class OAuthStorageBase implements OAuthStorage {
|
|||
);
|
||||
}
|
||||
|
||||
async getCimdClientMetadataUrl(
|
||||
serverUrl: string,
|
||||
issuer?: string,
|
||||
): Promise<string | undefined> {
|
||||
await this.ensureLoaded();
|
||||
const state = this.memory.getState().getServerState(serverUrl);
|
||||
return this.issuerSlot(state, issuer)?.cimdClientMetadataUrl;
|
||||
}
|
||||
|
||||
async saveCimdClientMetadataUrl(
|
||||
serverUrl: string,
|
||||
issuer: string,
|
||||
clientMetadataUrl: string | undefined,
|
||||
): Promise<void> {
|
||||
await this.ensureLoaded();
|
||||
// Not a save of credentials, so it must not promote this issuer to
|
||||
// `activeIssuer` — the marker is written during discovery, before anything
|
||||
// has been authorized against this AS.
|
||||
this.updateIssuerSlot(
|
||||
serverUrl,
|
||||
issuer,
|
||||
{ cimdClientMetadataUrl: clientMetadataUrl },
|
||||
{},
|
||||
false,
|
||||
);
|
||||
await this.persist();
|
||||
}
|
||||
|
||||
async saveClientInformation(
|
||||
serverUrl: string,
|
||||
clientInformation: OAuthClientInformation,
|
||||
|
|
|
|||
Loading…
Reference in a new issue