Bug Fixes
This release fixes the root cause behind several open issues: isConfiguredFor() in EmailAuthenticatorCredentialProvider only checked the stored credential store. Users without explicit enrollment (no stored credential) were treated as unconfigured — even when skipSetup=true (the default) and they have a valid email address.
Issues resolved
- #106 — "credential setup required" error on fresh install with Email OTP (REQUIRED)
- #112 — Setup screen shown for admin-enforced 2FA users who never explicitly enrolled
- #100 —
AuthenticationFlowException: authenticator: email-authenticatorwith empty alternative selection - #50 — "Try Another Way" button not showing email OTP as a selectable option
- #98 — "Try Another Way" option missing when email OTP is configured as an alternative
- #108 — Email authenticator always shown as configured in account management UI
Changes
isConfiguredFor()inEmailAuthenticatorCredentialProvidernow falls back to checkingskipSetupconfig + user email presence when no stored credential exists. WhenskipSetup=true(the default) and the user has a non-blank email address, they are considered configured.isSkipSetupEnabled()now searches bothemail-authenticatorandemail-conditional-authenticatorexecution provider IDs, so conditional flows are handled correctly.- Null-safety added to
configuredFor()inEmailAuthenticatorFormforgetCredentialProvider(). - Auto-enrollment removed from
evaluateTriggers()— no longer creates stored credentials at login time, preventing the spurious "configured" state in account management (#108). findAuthenticatorConfig()inEmailAuthenticatorRequiredActionalso extended to include both provider IDs.
Artifact coordinates
<dependency>
<groupId>io.github.mesutpiskin</groupId>
<artifactId>keycloak-2fa-email-authenticator</artifactId>
<version>26.3.1-KC{keycloak_version}</version>
</dependency>Replace {keycloak_version} with your Keycloak version (e.g. 26.6.1).