Skip to content

saas-ui cannot connect a generic OAuth api source: beginAccountLink has no source_id, DatasourceAccountLinks is GitHub-only #1199

Closed

Description

@antoinetoussaint-byte

The UI half of #1049 ("callable sources"), which kept saas-ui out of scope ("the connect form for OAuth is the sibling of #966 and out of scope unless trivial"); #966 does not cover it either.

What is missing

A person cannot connect a generic OAuth api source through the kit, so every surface that needs one rebuilds the flow itself. Observed against @codefly-dev/saas-ui 0.12.5 and host v0.0.102:

  • DatasourceClient.beginAccountLink?(orgId, connector, redirectUri) carries no source. The host's BeginDatasourceAccountLink requires source_id for generic OAuth ("Required for generic OAuth: the personal source created by this caller"), so the kit's client cannot begin an api link at all.
  • DatasourceAccountLinks defaults connector = "github" and calls beginAccountLink(orgId, connector, back) — the same gap.
  • DatasourcesPanel / ConnectGitHubForm add GitHub files sources only; nothing adds an api source with API_CREDENTIAL_KIND_OAUTH2 + GRANT_AUTHORIZATION_CODE (which the host makes personal to the caller).
  • AppInstallPrompt drives the host's GitHub files App setup, a different flow.

So the three steps the host already serves — add the person's api source (OAuth2, authorization code), begin the link with that source_id, complete it on return — each have a client method or a component on the host side and none together in the kit.

Proposal

  1. DatasourceClient.beginAccountLink takes an optional sourceId (passed through to BeginDatasourceAccountLink.source_id); createDatasourceClient / datasourceClientOverTransport implement it.
  2. DatasourceAccountLinks accepts the source it links (sourceId, and connector="api"), begins the link with it, completes it on the page the provider returns to (it already says "Mount it on the page the provider returns to"), and lists the person's link for that source.
  3. A kit surface that creates the person's own api source for a given base URL with the authorization-code grant when they have none — the api counterpart of DeclaredSourceCard, where the surface fixes the API and the person supplies only the sign-in. Where the declaration of that API and its operations comes from is Callable sources: OAuth2 (authorization code + client_credentials) for an API source, and InvokeSourceOperation — a connected API is called through the host, as the person, under receipts and audit #1049's open question; this component takes it as props and decides nothing about it.

Placement follows where the backend lives: the datasource service is the host's, so the UI that connects to it is the host's kit.

Done means

A surface mounts the kit, names an API base URL, and a person connects it over OAuth — source created, link begun with its source_id, completed on return, listed — with no hand-written datasource calls. Unit tests per piece in saas-ui; the kit-version gate bumped as scripts/ci/kit-version.mjs requires. Do not release; the release is the owner's.

Activity

  1. antoinetoussaint-byte commented on Oct 21, 2026

    @antoinetoussaint-byte
    ContributorAuthor

    A lazybox agent is working on this. claude (Opus 5.5) started at 2026-10-21 15:16 UTC, last renewed the claim at 2026-10-29 16:10 UTC, and the claim lapses at 2026-10-29 17:10 UTC unless it is renewed again. A claim is an assertion with an expiry, not proof that a process is alive.

    claim detail
    Lazybox-Claim-Device: effacd542b611010656e
    Lazybox-Claim-Session: ec5fda5a58
    Lazybox-Claim-Workspace: github-codefly-dev-module-saas-starter-1199
    Lazybox-Claim-Agent: claude
    Lazybox-Claim-Model: Opus 5.5
    Lazybox-Claim-Started: 2026-10-21T15:16:25Z
    Lazybox-Claim-Heartbeat: 2026-10-29T16:10:35Z
    Lazybox-Claim-Expires: 2026-10-29T17:10:35Z
    
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    workingClaimed by a lazybox agent; cleared when the session ends.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions