feat(bdd): magic-link BDD scenarios + bcrypt overflow fix (ADR-0028 Phase A.5) #63

Merged
arcodange merged 1 commits from vibe/phase-a5-bdd-magic-link into main 2026-05-05 11:44:42 +02:00
Owner

Summary

ADR-0028 Phase A.5 — BDD scenarios for the passwordless magic-link flow + a bug fix exposed during verification.

Mistral Vibe authored (in a worktree workspace ICM):

  • features/auth/magic_link.feature (4 scenarios)
  • pkg/bdd/steps/magic_link_steps.go (per-scenario unique recipient per ADR-0030, Mailpit-driven token extraction)
  • pkg/bdd/steps/scenario_state.go (2 fields)
  • pkg/bdd/steps/steps.go (register 5 step regexes)

Claude fixed what verification exposed:

  • bcrypt 72-byte overflow in magic_link_handler.go: random password was 96 hex (48 bytes) -> broke first-link signup. Now 64 hex (32 bytes, 256 bits).
  • pkg/bdd/testserver/server.go createTestConfig now sets Email + MagicLink defaults so the From address is non-empty.

Test plan

  • DLC_DATABASE_*=… go test ./features/auth/... -count=1 → 25 scenarios pass
  • go test ./pkg/... → green across the suite
  • go vet ./... clean
## Summary ADR-0028 Phase A.5 — BDD scenarios for the passwordless magic-link flow + a bug fix exposed during verification. **Mistral Vibe authored** (in a worktree workspace ICM): - features/auth/magic_link.feature (4 scenarios) - pkg/bdd/steps/magic_link_steps.go (per-scenario unique recipient per ADR-0030, Mailpit-driven token extraction) - pkg/bdd/steps/scenario_state.go (2 fields) - pkg/bdd/steps/steps.go (register 5 step regexes) **Claude fixed** what verification exposed: - bcrypt 72-byte overflow in magic_link_handler.go: random password was 96 hex (48 bytes) -> broke first-link signup. Now 64 hex (32 bytes, 256 bits). - pkg/bdd/testserver/server.go createTestConfig now sets Email + MagicLink defaults so the From address is non-empty. ## Test plan - DLC_DATABASE_*=… go test ./features/auth/... -count=1 → 25 scenarios pass - go test ./pkg/... → green across the suite - go vet ./... clean
arcodange added 1 commit 2026-05-05 11:44:37 +02:00
Adds 4 BDD scenarios covering the passwordless magic-link flow:
- Happy path (request -> email arrives -> consume -> JWT)
- Token cannot be consumed twice (single-use guarantee)
- Missing token returns 400
- Unknown token returns 401

Implementation:
- features/auth/magic_link.feature with the gherkin spec
- pkg/bdd/steps/magic_link_steps.go: per-scenario unique recipient
  (`<scenario-key>-<8hex>@bdd.local`, ADR-0030), Mailpit-driven token
  extraction, regex parse of the consume URL
- pkg/bdd/steps/scenario_state.go: 2 fields added (MagicLinkEmail,
  MagicLinkToken)
- pkg/bdd/steps/steps.go: register 5 new step regexes

Bug fix exposed by the BDD run:
- pkg/user/api/magic_link_handler.go: passwordless-signup random password
  was 96 hex chars (48 bytes) which overflowed bcrypt's 72-byte input
  limit, breaking first-link signup. Reduced to 64 hex chars (32 bytes,
  256 bits entropy).

Test infra fix:
- pkg/bdd/testserver/server.go: createTestConfig() builds the
  Config literal directly (no Viper defaults), so add explicit Email +
  MagicLink config so the From address is set when the handler sends
  via local Mailpit.

Mistral wrote the feature file, magic_link_steps.go, scenario_state.go
edit, and steps.go edit autonomously in a worktree workspace. Claude
fixed the bcrypt overflow + the test-config gap exposed during verification.

Most authoring by Mistral Vibe (mistral-vibe-cli-latest).
arcodange merged commit 9072b3e246 into main 2026-05-05 11:44:42 +02:00
arcodange deleted branch vibe/phase-a5-bdd-magic-link 2026-05-05 11:44:43 +02:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: arcodange/dance-lessons-coach#63