MCPcopy Create free account
hub / github.com/UsefulSoftwareCo/executor / decideDcrClientReuse

Function decideDcrClientReuse

packages/core/sdk/src/oauth-service.ts:766–807  ·  view source on GitHub ↗
(
    input: RegisterDynamicClientInput,
    issuer: string | null,
  )

Source from the content-addressed store, hash-verified

764 );
765
766 const decideDcrClientReuse = (
767 input: RegisterDynamicClientInput,
768 issuer: string | null,
769 ): Effect.Effect<
770 {
771 readonly existingSlug: OAuthClientSlug | null;
772 readonly registrationSlug: OAuthClientSlug;
773 },
774 StorageFailure
775 > =>
776 Effect.gen(function* () {
777 const candidates = yield* dcrCandidatesForIssuer(input.owner, issuer);
778 const resource = input.resource ?? null;
779 if (resource !== null) {
780 const matchingResource = candidates.find((client) => client.resource === resource);
781 if (matchingResource) {
782 return { existingSlug: matchingResource.slug, registrationSlug: matchingResource.slug };
783 }
784 const slug = dcrClientSlug(issuer, candidates.length > 0 ? resource : null, input.slug);
785 return {
786 existingSlug: null,
787 registrationSlug: slug,
788 };
789 }
790
791 // Resource-less request: only reuse a resource-LESS candidate. A client
792 // minted for a specific RFC 8707 resource must NOT be reused for a
793 // resource-less flow (its tokens are bound to that resource), so when only
794 // resource-scoped candidates exist we register a fresh resource-less client
795 // rather than silently borrowing one (the old `?? candidates[0]` bug).
796 const reusable = candidates.find((client) => client.resource === null);
797 if (reusable) return { existingSlug: reusable.slug, registrationSlug: reusable.slug };
798 // Fresh resource-less client. Its slug is the bare `dcr-<host>` base, but
799 // the FIRST resource-scoped registration for an issuer also takes that base
800 // (dcrClientSlug only suffixes once candidates exist). `createClient`
801 // deletes any row with a colliding (owner, slug) first, so reusing the base
802 // here would silently clobber that resource-scoped client. Dedupe against
803 // the existing candidate slugs so the resource-less client keeps its own row.
804 const takenSlugs = new Set(candidates.map((client) => String(client.slug)));
805 const slug = uniqueDcrSlug(dcrClientSlug(issuer, null, input.slug), takenSlugs);
806 return { existingSlug: null, registrationSlug: slug };
807 });
808
809 const registerDynamicClient = (
810 input: RegisterDynamicClientInput,

Callers 1

registerDynamicClientFunction · 0.85

Calls 3

dcrCandidatesForIssuerFunction · 0.85
dcrClientSlugFunction · 0.85
uniqueDcrSlugFunction · 0.85

Tested by

no test coverage detected