Skip to content

Conversation

@johanib
Copy link

@johanib johanib commented Jan 13, 2026

Prior to this change, there was no way to determine if a two-factor provider needed preparation before authentication.

This change introduces the needsPreparation method in the TwoFactorProviderInterface and its implementations, allowing the system to skip the preparation process for providers that do not require it. The preparation process requires state.

For example:
Prior to this change, if no state was available, the Totp and Google authenticators would fail, even if they are stateless.

Now, non-bc breaking.

Fixes #306

Prior to this change, there was no way to determine if a two-factor provider needed preparation before authentication.

This change introduces the needsPreparation method in the TwoFactorProviderInterface and its implementations, allowing the system to skip the preparation process for providers that do not require it. The preparation process requires state.

For example:
Prior to this change, if no state was available, the  Totp and Google authenticators would fail, even if they are stateless.

Co-authored-by: Tjeerd <tjeerd@ibuildings.nl>
@johanib johanib force-pushed the optional-preparation-4-non-breaking branch from d7a1bf2 to 2df4f9c Compare January 13, 2026 07:45
@johanib johanib marked this pull request as ready for review January 13, 2026 07:46
Prior to this change, the needsPreparation method would break existing
implementations.

This change makes the change not break existing TwoFactorProviders by not actually defining the `needsPreparation` in the interface.
This is to be implemented in version 9 of the 2fa package.
@johanib johanib force-pushed the optional-preparation-4-non-breaking branch from 2df4f9c to 81f6039 Compare January 13, 2026 07:49
Copy link
Owner

@scheb scheb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for going through the effort adjusting the implementation. I believe we can improve the test case a bit. Other than that, I'm happy to merge that in.

* In version 9, this method will be introduced, and all providers will need to implement it.
* Currently, it will be called, but is not required.
*
* public function needsPreparation(): bool;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add @method bool needsPreparation() annotation on the interface.

Comment on lines +27 to +28
$this->provider1 = new MockTwoFactorProvider(needsPreparation: true);
$this->provider2 = new MockTwoFactorProvider(needsPreparation: false);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this is to introduce the needsPreparation method, the better thing you could do is a TwoFactorProviderWithNeedsPreparationInterface extends TwoFactorProviderInterface to "materialize" the method. Then you can use normal PHPUnit mocking. No need for custom assertion/return value stubbing in that case. The less custom code, the better.

Would also introduce a 3rd provider that is a mock of TwoFactorProviderInterface without the needsPreparation method, which should behave like the needsPreparation returning true case.

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.

Add support for 2FA in applications without state

2 participants