Skip to content

Secure invite acceptance + fix the trial's connector dead end - #815

Merged
keysersoft merged 4 commits into
mainfrom
keysersoft/trial-activation-security-fixes
Oct 1, 2026
Merged

keysersoft merged 4 commits into
mainfrom
keysersoft/trial-activation-security-fixes

Conversation

@keysersoft

Copy link
Copy Markdown
Contributor

Why

Audit of the Cloud + self-hosted login / registration / trial / activation flows (against production). Two things stood out: a way to take over any account through invitations, and the trial's connector limit turning onboarding into a dead end.

P0 — Security

  • Invite account takeover. accept-invite attached an existing account to the inviting org and returned a session for it on the strength of the invite link alone. Since every signup is the admin of its own workspace and POST /invite returns the inviteUrl, anyone could invite an arbitrary address and accept the invite themselves to get a valid session for that account (SSO-only accounts included). Now the invitee must prove ownership — a live session for that address, or its current password; SSO-only accounts are told to sign in first. verifyInvite reports whether the address already exists so the page asks to sign in instead of silently ignoring a typed password.
  • OAuth login dead end. The MCP OAuth /auth/login page (where people land from the Claude directory) had no way to sign up or recover a password. Added Create an account (cloud) and Forgot your password? links.

P1 — Trial activation

  • The starter pack preselected 3 connectors while the trial allows 2, so the one-click install always failed its last item, and the two keyless demos ate the slots meant for the user's own connector. The starter-pack endpoint now returns the plan's connector allowance; the page preselects at most what fits, shows the cap and remaining slots, and disables extra picks.
  • A trial-limit error on connector / MCP-server create now renders an actionable notice (add a card / remove a connector) instead of a raw red toast (store, custom wizard, MCP-server create).
  • /start-trial states the no-card trial has a lower connector limit.
  • /welcome no longer offers the starter pack to viewers (who cannot install).

Paired with the trial allowance change in the website repo (trial → 5/3). This PR is safe on its own; it also makes legacy 2/2 trials behave (preselect ≤ remaining).

Tests

  • New accept-invite ownership suite (password / session / SSO-only / new account).
  • Starter-pack cap: backend unit + /welcome e2e (preselects 2 on a 2-cap trial, never offers 3).
  • Full backend suite (6311) + starter-pack & card-trial e2e suites pass locally.

Not merged / not deployed — awaiting review.

…e instead of a dead end

Security (P0):
- accept-invite no longer attaches an EXISTING account (and hands back its
  session) on the strength of the invite link alone. The invitee must prove
  ownership with a live session for that address or its current password;
  SSO-only accounts are told to sign in first. Any admin could otherwise take
  over an arbitrary account by inviting it and accepting the invite themselves.
  verifyInvite now reports whether the address already exists so the page can
  ask to sign in rather than silently ignore a typed password.
- The MCP OAuth login page now offers 'Create an account' (cloud) and 'Forgot
  your password?' links, so someone arriving from an AI client without an
  account is not stuck.

Trial activation (P1):
- The starter pack preselected 3 connectors while the trial allows 2, so the
  one-click install always failed its last item and the two keyless demos ate
  the slots meant for the user's own connector. The starter-pack endpoint now
  returns the plan's connector allowance; the page preselects at most what
  fits, shows the cap and how many slots remain, and disables extra picks.
- A trial-limit error on connector/MCP-server create now renders an actionable
  notice (add a card / remove a connector) instead of a raw red toast.
- /start-trial states the no-card trial is limited to 2 connectors / 2 servers.
- /welcome no longer offers the starter pack to viewers (who can't install).

Tests: new accept-invite ownership suite, starter-pack cap unit + e2e; full
backend suite and the starter-pack/card-trial e2e suites pass.
…ial vintage)

The exact no-card cap now differs between legacy (2/2) and new (5/3) trials, so
the offer page says 'a lower connector limit' instead of a hardcoded number.
…thout SMTP)

Self-hosted does not enforce email verification server-side, but the verify
step only offered 'Skip for now' to the first user, so a later user (or a
returning one) with no SMTP configured had no way past it. Any self-hosted user
can now skip; the first user still goes on to licence setup, everyone else into
the app. Cloud is unchanged (verification still required).
@keysersoft
keysersoft enabled auto-merge (squash) October 1, 2026 12:35
@keysersoft
keysersoft merged commit f4b5664 into main Oct 1, 2026
13 checks passed
@keysersoft
keysersoft deleted the keysersoft/trial-activation-security-fixes branch October 1, 2026 12:38
@github-actions github-actions Bot locked and limited conversation to collaborators Oct 1, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant