feat: feature flags for registration, 2FA and passkeys (#66)#79
Merged
Conversation
The consuming app needs to enable/disable identity features via config + an admin-editable store. The affected UI and backend pages/endpoints live here, so the gating is supported in this package; the host owns persistence. Add an IIdentityFeatureProvider abstraction (async snapshot of the three flags) with an options-backed default (MartenIdentityBlazorOptions gains EnableUserRegistration/EnableTwoFactor/EnablePasskey, all default true). A host registers its own provider — whose stored value takes precedence — via the TryAdd seam. IdentityFeatureGateMiddleware (UseMartenIdentityFeatureGate) makes a disabled feature unreachable by direct URL, not just hidden: it maps request paths to features and, when disabled, redirects page navigations to /Account/Login and 404s endpoint/fetch calls (mirrors SetupRedirectMiddleware). Graceful gating — registration entry, 2FA setup/management and passkey management + login/creation endpoints are gated, but the login-time 2FA/recovery challenge stays reachable so already-enrolled users are not locked out (passkey login falls back to password). The Login page hides the register link and passkey button (and skips passkey conditional mediation) per the flags. Adds middleware tests (each gated path blocked / login challenge not gated / unrelated paths pass), provider-through-DI tests, and Login bUnit gating tests; documents the flags, the UseMartenIdentity- FeatureGate wiring and the provider override in the Blazor README.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #66. Companion to andregoepel/app-foundation#49 (host-side store + admin UI).
What
Lets a host enable/disable registration, 2FA and passkeys. Disabling a feature hides its UI and makes its setup pages/endpoints unreachable by direct URL — not merely hidden. This package defines the seam and does the gating; the host owns persistence.
Abstraction
IIdentityFeatureProvider.GetAsync()→IdentityFeatureFlags(async; a host impl reads a DB). EnumIdentityFeature { UserRegistration, TwoFactor, Passkey }.OptionsIdentityFeatureProviderreadsMartenIdentityBlazorOptions(newEnableUserRegistration/EnableTwoFactor/EnablePasskey, all defaulttrue), registered viaTryAddScopedso a host provider wins. DB value takes precedence — the host implements that in its provider.Enforcement
IdentityFeatureGateMiddleware(app.UseMartenIdentityFeatureGate()) maps request paths to features; when disabled it redirects page navigations to/Account/Loginand 404s endpoint/fetch calls (mirrorsSetupRedirectMiddleware, including theSec-Fetch-Destheuristic). Covers both Razor pages and the passkey minimal-API endpoints.Graceful gating (approved behavior)
Register/RegisterConfirmation/ResendEmailConfirmation), 2FA setup/management pages, passkey management + all passkey login/creation endpoints.LoginWith2fa/LoginWithRecoveryCode) — so a user who already enrolled isn't locked out. Passkey login being gated is safe (password fallback).UI
Login.razorhides the register link and passkey button and skips passkey conditional mediation per the flags.Tests
OptionsIdentityFeatureProviderresolved through real DI returns default + configured values.Out of scope (app-foundation#49)
DB store, admin settings page and config binding of the flags; hiding host-owned account-nav links (host reads the same provider); bulk-disabling 2FA for existing users.