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

Function start

packages/core/sdk/src/oauth-service.ts:1679–2132  ·  view source on GitHub ↗
(
    input: OAuthStartInput,
  )

Source from the content-addressed store, hash-verified

1677 // start — begin a flow through a client to mint a connection.
1678 // -----------------------------------------------------------------------
1679 const start = (
1680 input: OAuthStartInput,
1681 ): Effect.Effect<ConnectResult, OAuthStartError | OrgWriteDeniedError | StorageFailure> =>
1682 Effect.gen(function* () {
1683 // Gate before any session row or upstream exchange: minting a Workspace
1684 // connection (including a reconnect that would replace its credential)
1685 // is a workspace-level change. Personal connections remain member-owned.
1686 yield* deps.guardOrgWrite(input.owner);
1687 const keys = yield* Effect.try({
1688 try: () => deps.ownedKeys(input.owner),
1689 catch: (cause) =>
1690 new StorageError({
1691 message: "Cannot start OAuth flow for owner without a subject",
1692 cause,
1693 }),
1694 });
1695 // The integration must exist BEFORE any session or provider round trip.
1696 // A stale reference (a connection whose integration was removed, or an
1697 // agent replaying an old slug) would otherwise complete authorization at
1698 // the provider and fail only at the mint.
1699 if (!(yield* deps.integrationExists(input.integration))) {
1700 return yield* new OAuthStartError({
1701 message: `Integration not found: ${String(input.integration)}`,
1702 });
1703 }
1704 // Sharing is one-directional (org → members): a Workspace (org) connection
1705 // cannot be backed by a member's private (user) app. The connection owner
1706 // and the app owner are otherwise independent — a Personal connection
1707 // through a shared Workspace app is the supported cross-owner case.
1708 // First-party apps are deployment-owned, outside the owner lattice
1709 // entirely, so the rule does not apply to them.
1710 const firstPartyFlow = isFirstPartyOAuthClientSlug(String(input.client));
1711 yield* Effect.annotateCurrentSpan({
1712 "executor.oauth.client_first_party": firstPartyFlow,
1713 });
1714 if (!firstPartyFlow && input.owner === "org" && input.clientOwner === "user") {
1715 return yield* new OAuthStartError({
1716 message: "A Workspace connection must use a Workspace app.",
1717 });
1718 }
1719 // Load the app by its EXPLICIT owner (the caller knows it — no derivation).
1720 // The connection is still minted under `input.owner`. Storage visibility
1721 // policy hides apps the actor cannot see, so a wrong owner yields null.
1722 const client = yield* loadClient(input.clientOwner, input.client);
1723 if (!client) {
1724 return yield* new OAuthStartError({
1725 message: `OAuth client not found: ${input.client}`,
1726 });
1727 }
1728
1729 // Normalize the name the same way the mint stores it, so the free-name
1730 // guard below compares against the exact stored form.
1731 const requestedName = connectionIdentifier(String(input.name));
1732 // newConnection: resolve the requested name to a FREE one against the
1733 // stored rows (not a client-side, policy-filtered view), so a second
1734 // untyped connect mints `personalGmail2` instead of silently re-minting
1735 // the first account's row. Reconnects omit the flag and keep targeting
1736 // their existing row. Bounded: a pathological owner with 1000 same-named

Callers

nothing calls this directly

Calls 15

connectionIdentifierFunction · 0.90
providerAuthorizeExtrasFunction · 0.90
createPkceCodeVerifierFunction · 0.90
createPkceCodeChallengeFunction · 0.90
createOAuthStateFunction · 0.90
encodeOAuthCallbackStateFunction · 0.90
buildAuthorizationUrlFunction · 0.90
loadClientFunction · 0.85

Tested by

no test coverage detected