Skip to content

fix(authFlows): persist PUZZLE/FACE step config in the flow builder#238

Merged
ahmetabdullahgultekin merged 1 commit into
mainfrom
fix/puzzle-flow-config-save
Jun 19, 2026
Merged

fix(authFlows): persist PUZZLE/FACE step config in the flow builder#238
ahmetabdullahgultekin merged 1 commit into
mainfrom
fix/puzzle-flow-config-save

Conversation

@ahmetabdullahgultekin

Copy link
Copy Markdown
Contributor

The auth-flow builder renders a PUZZLE layer config (allowed challenge types, count, difficulty, alsoMatchFaceIdentity) and a FACE active-puzzle-liveness toggle, but:

  • Save (AuthFlowsPage.handleSave) never serialized them into FlowStepSpec.config, and
  • Edit-load (getBuilderInitialSteps) never parsed them back.

So a tenant who configured a puzzle layer had that configuration silently dropped on save, and the runtime then rejected the step as unconfigured. The capability already exists end-to-end at the data-model + API + runtime layers (backend AuthFlowPuzzleConfigRoundTripTest); only the builder’s own save/load was unwired.

Change

  • New pure module features/authFlows/stepConfig.ts:
    • serializeStepConfig(step) → PUZZLE: puzzleConfig JSON; FACE: {"requireActivePuzzleLiveness":true}; undefined for ordinary steps (payload shape unchanged).
    • parseStepConfig(config) → hydrates both back; tolerant of undefined / "{}" / malformed (returns {}).
  • Wired into AuthFlowsPage handleSave (serialize) and getBuilderInitialSteps (parse), so config round-trips create → get faithfully and survives editing.

The serialized blob matches the backend round-trip-tested shape exactly:
{"allowedChallengeTypes":[...],"count":N,"difficulty":"medium","alsoMatchFaceIdentity":false}.

Safety

  • The PUZZLE layer is feature-flagged app.auth.puzzle-layer (default OFF); FACE toggle is opt-in. Ordinary flows are byte-identical (config only emitted when present).
  • Additive + reversible.

Tests

  • 10 new unit tests in stepConfig.test.ts (serialize, parse, round-trip, backend-parity, malformed input).
  • Full authFlows suite green (6 files / 48 tests); eslint + tsc --noEmit clean.

The builder rendered the PUZZLE layer config (allowed challenge types, count,
difficulty, alsoMatchFaceIdentity) and the FACE active-puzzle-liveness toggle,
but the save path never serialized them into FlowStepSpec.config and the
edit-load path never parsed them back. A tenant's puzzle configuration was thus
silently dropped on save, and the runtime then rejected the step as unconfigured.

Add a pure, tested stepConfig module (serializeStepConfig/parseStepConfig) and
wire it into AuthFlowsPage handleSave (serialize) and getBuilderInitialSteps
(parse), so the config round-trips create -> get faithfully, matching the
backend AuthFlowPuzzleConfigRoundTripTest blob shape.

- serialize on save: PUZZLE -> puzzleConfig JSON; FACE -> {requireActivePuzzleLiveness}
- parse on edit-load: hydrate both back so re-save does not drop them
- 10 unit tests; tolerant of empty/malformed/absent config
@ahmetabdullahgultekin ahmetabdullahgultekin merged commit cc0c1fb into main Jun 19, 2026
5 checks passed
@ahmetabdullahgultekin ahmetabdullahgultekin deleted the fix/puzzle-flow-config-save branch June 19, 2026 20:51
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.

1 participant