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
5757 });
5858
5959 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+ ]) {
6174 expect(RESERVED_ORG_SLUGS.has(critical), critical).toBe(true);
6275 }
6376 });
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
1717 * predictably will):
1818 * - App planes: api, mcp, .well-known (cloud `app-paths.ts`, selfhost
1919 * envelope, cloudflare `run_worker_first`)
20− * - Console routes: integrations, policies, secrets, tools, resume,
21− * plugins (the shared contract), plus host extras:
20+ * - Console routes: connect, integrations, policies, secrets, tools,
21+ * resume, plugins (the shared contract), plus host extras:
2222 * api-keys, org, billing, create-org, setup-mcp (cloud),
2323 * admin, join, docs (selfhost), login (Better Auth
2424 * `mcp({ loginPage })` + cloud/selfhost login UX)
@@ -41,6 +41,7 @@ export const RESERVED_ORG_SLUGS: ReadonlySet<string> = new Set([ · 16 unmodified lines
4141 "mcp",
4242 ".well-known",
4343 // console + host routes
44+ "connect",
4445 "integrations",
4546 "policies",
4647 "secrets",