Skip to content

feat: MFA-4417/MFA-4751 read configurable phone OTP length from the transaction#96

Open
sebadoom wants to merge 2 commits into
auth0:masterfrom
sebadoom:mfa-4417/otp-length-in-transaction-response
Open

feat: MFA-4417/MFA-4751 read configurable phone OTP length from the transaction#96
sebadoom wants to merge 2 commits into
auth0:masterfrom
sebadoom:mfa-4417/otp-length-in-transaction-response

Conversation

@sebadoom

@sebadoom sebadoom commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

Summary

Make the phone factor (SMS/voice) OTP length configurable instead of hardcoding it to 6, sourcing the length from the transaction start-flow response. The library self-sources the length from the transaction it already fetches — the hosting application passes nothing, and the public API (auth0GuardianJS(options)) is unchanged.

Changes

  • lib/utils/validations.jsvalidateOtp(otp, otpLength) (an internal helper, not part of the public API) accepts an optional expected length, defaulting to 6 when omitted or non-numeric. Exposes DEFAULT_OTP_LENGTH.
  • lib/transaction/factory.js — reads the length from the start-flow response at factorSettings.phone.otpLength and carries it into the transaction; restores it from serialized state in fromTransactionState.
  • lib/transaction/index.js — applies the length only to the SMS auth and SMS enrollment strategies (TOTP and recovery codes keep their fixed lengths), and persists it in serialize() so resumed transactions validate the same length.
  • lib/auth_strategies/{sms,otp}_auth_strategy.js and lib/enrollment_strategies/sms_enrollment_strategy.js — validate the OTP against the configured length.

Public API

No change. The package entry (auth0GuardianJS) takes no new option and exposes no new method; validateOtp is an internal helper not reachable from the public surface. The configured length flows in entirely from the mfa-api start-flow response, so the library never asks the embedder to provide it.

Backwards compatibility

Purely additive. When the start-flow response does not include factorSettings.phone.otpLength, the SMS strategies fall back to length 6 — existing behaviour is unchanged. validateOtp(otp) called without a length behaves exactly as before. No public signatures removed or reordered.

Testing

  • npm test (mocha): 244 passing (+8 new), covering the validation primitive with explicit/omitted lengths and a transaction-factory suite that asserts the length is threaded into the SMS strategies, falls back to 6 when absent, and survives a serialize / fromTransactionState round-trip.

Notes

  • ⚠️ Standalone build: npm run build currently fails to minify (guardian-js.min.js) because socket.io-client@4.x ships ES6 that the pinned UglifyJS (webpack 1.x) cannot parse. Pre-existing (introduced when socket.io-client was bumped v2→v4), not caused by this change, but must be resolved before publishing a standalone release. Tracking separately.
  • Supersedes feat: MFA-4417 support configurable OTP length for phone factor #95 (which passed the length as a widget/constructor input).

…response

Source the configurable phone (SMS/voice) OTP length from the mfa-api
transaction start-flow response (factor_settings.phone.otp_length,
camelCased to factorSettings.phone.otpLength) instead of a caller-supplied
constructor option. The length is threaded only into the SMS auth and SMS
enrollment strategies; TOTP and recovery codes keep their fixed lengths.

- validateOtp(otp, otpLength) accepts an optional expected length and
  defaults to 6, so existing callers are unaffected. Exposes
  DEFAULT_OTP_LENGTH.
- The length is persisted in transaction.serialize() and restored by
  fromTransactionState, so resumed transactions validate the same length.
- When factor_settings is absent (older mfa-api, or the
  mfa_advanced_factor_config flag off), the strategies fall back to 6.

This is the v2 (mfa-api response channel) design from the RFD. Unlike the
superseded host-page attribute approach, no host page (widget.ejs or a
tenant custom MFA page) needs to change.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@sebadoom sebadoom changed the title feat: MFA-4417 read configurable phone OTP length from the transaction feat: MFA-4417/MFA-4751 read configurable phone OTP length from the transaction Jun 22, 2026
…n factory

Assert the configured phone OTP length is threaded into the SMS
enrollment strategy (enrollmentStrategies.sms.confirm), not just the SMS
auth strategy: a code of the wrong length is rejected and a correct one
is accepted, mirroring the existing auth-strategy coverage.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@sebadoom sebadoom marked this pull request as ready for review June 24, 2026 00:28
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