History

Add /connect/<slug> integration deep link

Resolves the slug against the tenant catalog and forwards into the integration detail page's existing add-connection flow. Unknown slugs get a not-found state. Makes the link survive sign-in: reserve connect as an org slug so cloud's callback stops reading it as an org selector, and return self-host's login to the requested path (its gate swaps the page in without ever writing a returnTo).

Rhys Sullivan committed 3 months ago

Commit 587b2cc1 parent 33f410b17 files · +659 −19Browse files

Showing the changes to packages/core/api/src (2 of 17 files). Show all

Unified · Split

2 files
  1. packages/core/api/src/account/org-slug.test.ts +14 −1
  2. packages/core/api/src/account/org-slug.ts +3 −2
packages/core/api/src/account/org-slug.test.ts+14−1
@@ -57,7 +57,20 @@ describe("isValidOrgSlug", () => { · 56 unmodified lines
57 });57 });
58 58
59 it("reserves the segments routing depends on", () => {59 it("reserves the segments routing depends on", () => {
60 for (const critical of ["api", "mcp", "integrations", "policies", "login", "cdn-cgi"]) {60 for (const critical of [
61 "api",
62 "mcp",
63 "integrations",
64 "policies",
65 "login",
66 "cdn-cgi",
67 // The connect deep link's root. Cloud's post-auth callback reads the
68 // first path segment as an org selector, so leaving `connect` claimable
69 // made `/connect/<slug>` look like a request for an org named "connect"
70 // — which suppressed the active-membership fallback and could drop the
71 // deep link into org onboarding after sign-in.
72 "connect",
73 ]) {
61 expect(RESERVED_ORG_SLUGS.has(critical), critical).toBe(true);74 expect(RESERVED_ORG_SLUGS.has(critical), critical).toBe(true);
62 }75 }
63 });76 });
packages/core/api/src/account/org-slug.ts+3−2
@@ -17,8 +17,8 @@ const ORG_SLUG_PATTERN = /^[a-z0-9](?:[a-z0-9]|-(?=[a-z0-9])){1,47}$/; · 16 unmodified lines
17 * predictably will):17 * predictably will):
18 * - App planes: api, mcp, .well-known (cloud `app-paths.ts`, selfhost18 * - App planes: api, mcp, .well-known (cloud `app-paths.ts`, selfhost
19 * envelope, cloudflare `run_worker_first`)19 * envelope, cloudflare `run_worker_first`)
20 * - Console routes: integrations, policies, secrets, tools, resume,20 * - Console routes: connect, integrations, policies, secrets, tools,
21 * plugins (the shared contract), plus host extras:21 * resume, plugins (the shared contract), plus host extras:
22 * api-keys, org, billing, create-org, setup-mcp (cloud),22 * api-keys, org, billing, create-org, setup-mcp (cloud),
23 * admin, join, docs (selfhost), login (Better Auth23 * admin, join, docs (selfhost), login (Better Auth
24 * `mcp({ loginPage })` + cloud/selfhost login UX)24 * `mcp({ loginPage })` + cloud/selfhost login UX)
@@ -41,6 +41,7 @@ export const RESERVED_ORG_SLUGS: ReadonlySet<string> = new Set([ · 16 unmodified lines
41 "mcp",41 "mcp",
42 ".well-known",42 ".well-known",
43 // console + host routes43 // console + host routes
44 "connect",
44 "integrations",45 "integrations",
45 "policies",46 "policies",
46 "secrets",47 "secrets",