Changelog
1.0.1
Bugfixes
- The admin module, the passkey panel in the user settings, the login help box, the passkey setup interstitial and the adoption widget use only classes and tokens that the TYPO3 backend defines in 12.4, 13.4 and 14.3, so they follow the backend's light and dark scheme. Bootstrap alerts in the module body are replaced by core callouts, and outline buttons, secondary text and badges by their core counterparts.
- The setup interstitial resolves its colour scheme the way core does: from
the user setting, then from
setup.in TSconfig, forced when that field is disabled. Its button text meets 4.5:1 contrast.fields. color Scheme - The adoption bar in the admin module is a native
<progress>element with an accessible name, drawn with core tokens. On TYPO3 14.3 it previously showed no track at all. - The adoption widget uses colours with at least 3:1 contrast in both schemes, a legend that names every segment of both rings, and a title that fits the widget. Its segment labels are read from the dashboard language file, and its description names the rings in the order Chart.js draws them.
- Links inside callouts and inside the Help text are underlined.
- The Help table and the passkey table declare their column headers, the passkey panel heading follows the tab's heading level, and the inline rename input and the admin module's menu have accessible names.
Tests
- Continuous integration runs the JavaScript unit tests on every pull request and every push to the main branch, and reports their coverage under its own Codecov flag.
1.0.0
Important
- The extension state changes from
betatostable. From this release on the public API follows semantic versioning: a removal or an incompatible change to a public class, method or configuration setting needs a new major version. - Run the database schema update after upgrading from 0.12.x. The
tx_table gained thenrpasskeysbe_ credential discoverablecolumn (see Features below). Use Admin Tools > Maintenance > Analyze Database Structure, orvendor/.bin/ typo3 extension: setup - Removed the deprecated
RateandLimiter Service:: check Rate Limit () Rate. Callers useLimiter Service:: record Attempt () Rate, which performs the limit check and the increment in one critical section. The removed pair left a check-then-record window in which concurrent requests could all pass the check before any of them incremented, overshooting the limit by the number of requests in flight. No code inside this extension called either method.Limiter Service:: consume Rate Limit ()
Features
- Registration records whether the browser stored the passkey as a
discoverable (resident) credential. The value is kept in the new
Credentialenum, so a later release can tell a discoverable-login-capable credential from one that needs a username.Discoverability
Bugfixes
- The conditional-UI ceremony on the login screen no longer retries without
bound when the browser cannot serve it. A browser that declines with
Notis treated as declining rather than as an error, a ceremony that lost its turn while awaiting is dropped, a pending retry is cancelled when the button ceremony takes over, and the challenge refresh stops instead of looping.Supported Error
Tests
- The test suite runs on PHPUnit 12 and 13 in addition to 11.
- The end-to-end suite runs in continuous integration, against TYPO3 13 and TYPO3 14, on every pull request and every push to the main branch. It ran only on developer machines before, so a regression in the browser-side ceremonies reached the main branch with every other check green.
- All 69 end-to-end tests run. Seven were disabled, among them both full WebAuthn ceremonies and the check that a passkey login never passes through the multi-factor challenge, so the suite reported success without ever performing a passkey login.
0.12.1
Important
- This section documents the 0.12.1 release, which shipped without a changelog entry.
Bugfixes
- Closed nine findings of a security scan: a switch-user escalation, missing Sudo Mode declarations, a login token whose expiry was not enforced in the token value, and user-enumeration oracles. Passkey write routes now declare Sudo Mode, and passkey writes are refused while an administrator is in switch-user mode.
- Decoy credentials for unknown users are indistinguishable from real ones: the decoy credential IDs no longer encode their own shape, and both login-options branches are padded to one timing budget.
- A non-UTF-8 request body returns HTTP 400 instead of crashing the controller.
- Assertion verification catches every failure, not only
Runtime.Exception - The nonce cache defaults to a backend that honours the TTL, so a challenge nonce expires as intended.
- The passkey autofill ceremony stays usable and no longer reports a false failure.
- Local DDEV tooling treats git ref names as untrusted input.
0.12.0
Features
- Consolidated the passkey dashboard widgets into a single, unified Core
widget set owned by this extension. The two widgets (adoption doughnut,
active-credentials count) now gather their data from an extensible,
cross-extension provider collection instead of querying the backend
tables directly. When
nr_is installed the same two widgets additionally show the frontend audience, replacing the previous duplicate frontend widget pair — the dashboard shows two passkey widgets instead of four.passkeys_ fe - Added a public extension point: the
Passkeyand the immutableAdoption Stats Provider Interface PasskeyDTO. Any service implementing the interface is collected under the DI tagAudience Stats nr_and contributes one audience segment. This extension registers the backend (passkeys_ be. adoption_ stats_ provider be_) provider;users nr_registers the frontend (passkeys_ fe fe_) provider without this extension depending on it.users - The adoption doughnut now renders one ring per audience with a distinct colour family (backend green/orange, frontend teal/magenta) and localised segment labels, so the two populations are unmistakable and never summed into a single ratio. The credentials tile sums the homogeneous credential counts across audiences.
- Added two purpose-specific dashboard icons (
passkeys-,adoption passkeys-) so the widgets no longer borrow the module icon.credentials
Important
- The dashboard widget identifiers were renamed from
nrpasskeysbe-/adoption nrpasskeysbe-tocredentials nrpasskeys-/adoption nrpasskeys-(thecredentials beinfix was dropped now that this is the single Core widget set). Backend users who had manually placed the old widgets on a dashboard will need to add the renamed widgets again; the placement of the old identifiers no longer resolves. Acceptable for a pre-1.0 minor.
0.9.4
Features
- Replaced the generic Netresearch logo with the official FIDO passkey
mark for the backend module and login icons. The icon is
version-aware: TYPO3 v12/v13 use a colored tile, while v14 uses a flat
two-tone mark (a Netresearch turquoise key on a
currentbody) that adapts to the light and dark backend. Authored with SVG presentation attributes so it stays clean under a hardened backend Content Security Policy.Color
Tests
- The end-to-end suite now targets the backend module iframe by id for a more robust selector.
0.9.3
Tests
- Added regression coverage for the TYPO3 14 User Settings passkey
panel. A functional test asserts that the FormEngine
Noderesolves theFactory nrrender type toPasskey Settings Panel Passkeyand that theSettings Panel Element passkeysuser-setting column declares the render type on v14 (and uses the legacyuserpath on v12/v13). The end-to-end test now pierces the backend module iframe and asserts the management panel actually renders, instead of suppressing the console errors a broken panel would emit.Func
Note
0.9.1 and 0.9.2 were tagged but never published as complete releases (their release pipelines failed before producing artifacts). The fixes they introduced are listed below for completeness and ship in 0.9.3.
0.9.2
Bugfixes
- TYPO3 14 logged a warning when opening User Settings: the
passkeyspanel column was registered astype="user"without a specific render type, which also triggered aSingleField Container Type. IntroducedError Passkey(a FormEngineSettings Panel Element Abstract) registered as render typeForm Element nrand registered it as a public service so thePasskey Settings Panel Nodecan resolve its dependencies via DI. TYPO3 12/13 continue to use the existingFactory userpath unchanged.Func
0.9.1
Bugfixes
- Registered the User Settings passkey panel via the TCA-based user
settings API on TYPO3 14+, where the column requires a
configkey. TYPO3 12/13 keep the legacy$GLOBALSregistration.['TYPO3_ USER_ SETTINGS']
0.9.0
Features
- TYPO3 14.3 LTS support. The composer constraints, CI matrix and DDEV
environment for v14 are now pinned to
^14.. The previous blocker (3 phpdocumentor/requirement conflict between v14.3 andreflection- docblock web-) was resolved upstream in webauthn-lib 5.3, see web-auth/webauthn-framework#830.auth/ webauthn- lib 5. 2
Internal
- Migrated to
web-^5.3 and the newauth/ webauthn- lib Credentialbase class.Record Publicis deprecated in 5.3 and removed in 6.0; the WebAuthn assertion validator'sKey Credential Source $publickeyword argument has been renamed toKey Credential Source $credential. No behaviour change for stored credentials -- the wire format is unchanged.Record - Replaced the deprecated
General(deprecated in TYPO3 v14.3, removed in v15.0) withUtility:: get Indp Env () Normalizedfrom the PSR-7 request across six call sites (Params Passkey,Authentication Service Login,Controller Extension).Configuration Service Normalizedhas been part of TYPO3 since v9.4, so this works across the whole supported range without compatibility shims.Params
CI / build
- Reusable workflow callers now forward
actions: readso the upstreamnetresearch/preflight gate (which skips duplicate post-merge runs) can call the GitHub Actions API. Without this the CI workflow fails immediately withtypo3- ci- workflows startup_.failure
0.8.2
Fixes
Documentation/converted from a symlink to a real file. The TYPO3 render-guides pipeline aborts on symlinks withCLAUDE. md League\, so the v0.8.1 docs render failed and noFlysystem\ Symbolic Link Encountered /0.tree was published. Other symlinks in the repository are outside the render scope and are untouched.8/ en- us/
Internal
- Release orchestrator now verifies the docs build by polling the
upstream
TYPO3-workflow run instead of the rendered URL. Failures are reported immediately (previously we would time out after 45 minutes without being able to distinguish "still rendering" from "render failed").Documentation/ t3docs- ci- deploy - Release evidence block in the GitHub release body now uses the
correct
/major.docs URL (Intercept maps tags to major.minor branches).minor/ en- us/
0.8.1
Internal
- Release pipeline consolidated into a single orchestrator workflow
(
netresearch/). Tag push now runs build + TER publish + Packagist verification + docs.typo3.org verification + atomic GitHub release creation in one workflow run, replacing the previous split that relied on atypo3- ci- workflows/. github/ workflows/ release- typo3- extension. yml release: publishedchain-trigger (which broke silently under workflow-created releases). Newrepublishmanual workflow allows re-running any subset of {TER, docs, Packagist} verification against an existing tag without mutating the release. No runtime behaviour change; the extension code shipped in 0.8.1 is identical to 0.8.0. - E2E test triage: six pre-existing broken Playwright specs marked
.fixmewith root-cause TODOs. Unblocks the CI matrix after the shared reusable workflow was repaired to actually execute specs (netresearch/typo3-ci-workflows#60, netresearch/typo3-ci-workflows#61, netresearch/typo3-ci-workflows#62).()
0.8.0
Features
- New
skipextension setting (default enabled): when a user authenticates with a passkey, the TYPO3 MFA challenge is skipped for that session. A passkey is already multi-factor, so requiring TOTP on top is redundant. Password-based logins are unaffected and still go through MFA as configured. This resolves the MFA-policy dilemma where forcing MFA for password users also forced passkey users through a second factor they had already provided.Mfa On Passkey Auth - Help tab "Passkeys & MFA" section rewritten to name the password-only
loophole (disabling
requirelets password-only logins through without any second factor) and document the recommended production combination ofMfa require+Mfa skip+Mfa On Passkey Auth disable.Password Login
0.7.0
Features
- Help icon button in DocHeader (question-mark icon via TYPO3 ButtonBar API) so the Help tab is discoverable without the dropdown menu
- Adoption rate gamification badges on Dashboard: Getting started, Bronze (25%), Silver (50%), Gold (75%), Platinum (100%) with icons
- Quick Start guide on Dashboard for new installations with step-by-step setup instructions and auto-detected rpId display
- MFA hint on Dashboard informing admins that passkeys are inherently multi-factor and TOTP may be redundant
- Configuration status hints when rpId and origin are both auto-detected
- Enhanced Help page MFA section: renamed to "Passkeys & MFA", added prominent infobox answering "Are passkeys secure enough without MFA?"
- README: Quick Start section, Passkeys & MFA guidance, TER docs link, rpId/rpName/origin in configuration table
Fixes
- Use
Infoboxinteger constants for cross-versionView Helper:: STATE_* f:compatibility (v12/v13/v14)be. infobox - Use
enum_runtime check forexists (Icon Size:: class) getv12 compatibility (v12 uses string, v13+ usesIcon () Iconenum)Size - Badge labels are translatable via
TranslationTrait
0.6.0
Features
- Per-group passkey enforcement with 4 levels: Off, Encourage, Required, Enforced
- Configurable grace periods for Required enforcement (1--365 days)
- PSR-15 interstitial middleware prompting users to register passkeys (skippable during grace period, mandatory after expiry)
- Encourage-stage dismissible banner with passkey explanation, docs link, and administrator contact guidance (supports TYPO3 v12/v13/v14)
- Admin dashboard backend module (Admin Tools > Passkey Management) with adoption statistics, per-group enforcement controls, and user list
- Admin actions: Send Reminder (nudge), Clear Nudge, Revoke All
Enforcementenum,Level EnforcementDTO,Status Enforcement,Service AdoptionStats Service Passkey,Banner. js PasskeyJavaScript modulesDashboard. js - TCA fields
passkey_andenforcement passkey_ongrace_ period_ days be_groups - 5 new admin AJAX endpoints for enforcement and nudge management
- 153 i18n translation units across 4 XLF files
- Context-sensitive help tab in admin module with rollout guide, recovery procedures, MFA coexistence, and FAQ
0.5.0
Features
- Per-user password login enforcement:
disablenow blocks passwords only for users who have registered passkeys, enabling gradual onboarding without locking out new usersPassword Login - Deployment Scenarios documentation chapter covering multi-environment setup, database sync, user onboarding, and local DDEV development
0.4.0
Features
- TYPO3 12.4 LTS support (PHP 8.2+ required)
- Event listener registered via Services.yaml tag for v12 compatibility
(
#attribute retained for v13+)[As Event Listener] PasskeyDI-aware FormEngine node withInfo Element setfor v12Data () NodecompatibilityFactory - CI matrix expanded with TYPO3 v12.4 test jobs
- DDEV development environment includes v12 installation
0.3.0
Features
- Inline name input for passkey registration -- users can name their passkey before registering (defaults to "Passkey")
- Accessible
aria-on the name input fieldlabel - Input is disabled during registration and reset after success
Refactoring
- Rewrote
Passkeyfrom IIFE to ES module using TYPO3 native APIs:Management. js Ajax,Request Notification,Modal,Severity,Enum sudo,Mode Interceptor DocumentService - Replaced
PagewithRenderer:: add Js File () loadJava Script Module () - Replaced inline style with CSS class
Fixes
- Escape label in removal confirmation modal (XSS prevention)
- Defer DOM initialization with
DocumentService. ready () - Resolve
Ajaxresponses and check status before showing success notificationsRequest
0.2.0
Features
- Warn about short or missing TYPO3 encryption key in the passkey settings panel (minimum 32 characters required)
- Include exception details in management API error responses for authenticated users
Documentation
- Added Troubleshooting section covering encryption key issues, HTTPS requirements, log location, and debug mode
0.1.0
Initial release.
Features
- Passwordless backend authentication via WebAuthn/FIDO2 Passkeys
- Passkey button injected into the standard TYPO3 login form via PSR-14 event listener (no login provider switching)
- Support for TouchID, FaceID, YubiKey, Windows Hello, and other FIDO2-compliant authenticators
- Authentication service at priority 80 (above standard password service)
- Authentication data packed into
useridentfield as JSON ($GLOBALSis null during auth chain)['TYPO3_ REQUEST'] - Credential registration, listing, renaming, and removal for users
- Admin API for listing, revoking credentials and unlocking accounts
- HMAC-SHA256 signed challenge tokens with nonce replay protection
- Per-endpoint rate limiting by IP address
- Account lockout after configurable failed attempt threshold
- Discoverable login (usernameless, Conditional UI) behind feature flag
- Option to disable password login entirely (passkey-only mode)
- Configurable signing algorithms (ES256, ES384, ES512, RS256)
- Configurable user verification requirement
- User enumeration prevention with randomized timing
- Soft delete and admin revocation with audit trails
- Signature counter tracking for clone detection
- Passkey-specific error message on failed login attempts via sessionStorage detection
- Default audit log writer (WARNING+ to
typo3temp/)var/ log/ passkey_ auth. log - TYPO3 13.4 LTS and TYPO3 14.x compatibility
- PHP 8.2, 8.3, 8.4, and 8.5 support
- Comprehensive test suite (unit, fuzz, functional, JavaScript)
- PSR-3 logging for all significant events