Skip to content

fix: do not offer sign-up on an instance whose sign-up mode does not allow it - #453

Open
dbeattie71 wants to merge 1 commit into
clerk-community:mainfrom
bytefoo:fix/respect-sign-up-mode
Open

fix: do not offer sign-up on an instance whose sign-up mode does not allow it#453
dbeattie71 wants to merge 1 commit into
clerk-community:mainfrom
bytefoo:fix/respect-sign-up-mode

Conversation

@dbeattie71

Copy link
Copy Markdown

The problem

ClerkAuthentication renders the "Don't have an account? Sign up" toggle unconditionally, so on
a restricted or waitlist instance it offers an account it cannot create. Filling in the form it
leads to ends in the API refusing the sign-up — an affordance whose only possible outcome is a
rejection.

Observed on a production instance whose access mode is Invite-only: the signed-out screen
renders a full sign-up form, First name through Password, for an instance that accepts none of it.

The mode is already parsed — nothing consulted it

user_settings.sign_up.mode is read into SignUpSettings.mode and reachable as
Auth.env.user.signUp.mode. This adds Environment.signUpIsOpen beside hasOauthStrategies, and
_ClerkAuthenticationState.build already reads authState.env for the OAuth panel — so the widget
needs no new dependency to answer the question.

bottomPortion: authState.env.signUpIsOpen ? _BottomPortion(...) : emptyWidget,

Two deliberate choices

Only public reads as open. restricted requires an invitation and waitlist collects an
address for later; the SDK implements neither flow, so on those instances the form cannot succeed.
An unrecognised value is far likelier to be a mode this getter has not heard of than a reason to
offer an account to everyone — so it fails closed.

Only the toggle is gated, never the panel. If something has already put the auth state into
signing-up, ClerkSignUpPanel still renders. A sign-up in flight must not become a blank card, and
hiding a form somebody is part-way through would be a worse failure than showing one that is
refused. _state starts at signingIn and, with no toggle, only the existing coercion from
authState.isSigningUp can move it — so nothing that works today stops working.

Tests

Three cases added to environment_test.dart, following the hasOauthStrategies group: public is
open; restricted and waitlist are not; an unknown mode, an empty mode and Environment.empty
are not. dart test green on clerk_auth, flutter analyze clean on clerk_flutter (one
pre-existing unnecessary_import info in an unrelated test file).

Alternative considered

A signInOnly parameter on the widget. Rejected: the widget's whole design is to take no
parameters and read the instance instead, and the instance already states this. A caller should not
have to restate what Clerk has already said.

`ClerkAuthentication` renders the "Don't have an account? Sign up" toggle
unconditionally, so on a `restricted` or `waitlist` instance it offers an
account it cannot create. Filling in the form it leads to ends in the API
refusing the sign-up — an affordance whose only outcome is a rejection.

Observed on a production instance whose access mode is Invite-only: the
signed-out screen renders a full sign-up form, First name through Password,
for an instance that accepts none of it.

The mode is already here. `user_settings.sign_up.mode` is parsed into
`SignUpSettings.mode` and reachable as `Auth.env.user.signUp.mode`; nothing
consulted it. `Environment.signUpIsOpen` names the question next to
`hasOauthStrategies`, which the same `build` already reads for the OAuth panel,
so the widget needs no new dependency to answer it.

Strict on purpose: only `public` reads as open. `restricted` requires an
invitation and `waitlist` collects an address for later, and this SDK
implements neither flow, so on those instances the form cannot succeed. An
unrecognised value is likelier to be a mode this does not know about than a
reason to offer an account to everyone.

**Only the toggle is gated, never the panel.** If something has already put the
auth state into signing-up, `ClerkSignUpPanel` still renders: a sign-up in
flight must not become a blank card, and hiding a form somebody is part-way
through is a worse failure than showing one that is refused. `_state` starts at
`signingIn` and, with no toggle, only the existing coercion from
`authState.isSigningUp` can move it.
@dbeattie71
dbeattie71 force-pushed the fix/respect-sign-up-mode branch from 2af7f73 to 70371e4 Compare September 10, 2026 03:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants