---
title: "Extension Points"
manual: "Passkeys Frontend Authentication"
version: "2.0"
permalink: "https://docs.typo3.org/permalink/netresearch/nr-passkeys-fe:extension-points@2.0"
source: "DeveloperGuide/ExtensionPoints.rst"
rendered: "2026-09-29T22:18:36+00:00"
---

# Extension Points {#extension-points}

Beyond PSR-14 events, the extension provides several extension points.

## Overriding Fluid templates {#overriding-fluid-templates}

All frontend output is rendered via Fluid templates located in
`EXT:nr_passkeys_fe/Resources/Private/`. Override any template by
registering a higher-priority path:

```typoscript
plugin.tx_nrpasskeysfe {
    view {
        templateRootPaths.10 = EXT:my_ext/Resources/Private/Templates/NrPasskeysFe/
        partialRootPaths.10 = EXT:my_ext/Resources/Private/Partials/NrPasskeysFe/
        layoutRootPaths.10 = EXT:my_ext/Resources/Private/Layouts/NrPasskeysFe/
    }
}
```

Available templates:

-   `Login/Index.html` -- Passkey login form, with the recovery code form
-   `Enrollment/Index.html` -- Passkey enrollment form, with its success message
-   `Management/Index.html` -- Self-service management panel, registration
    and recovery codes
-   `Felogin/Login/Login.html` and `Felogin/Login/Logout.html` -- the
    felogin template override
-   `AdminModule/Dashboard.html` and `AdminModule/Help.html` -- backend
    module

Available partials:

-   `NrPasskeysFe/LoginAssets.html` -- CSS, scripts and JavaScript
    translations of the passkey login, rendered by `Login/Index.html` and by
    the felogin override

## Replacing services {#replacing-services}

All services are registered in `Configuration/Services.yaml` with
standard Symfony DI. To replace a service, add an alias in your
extension's `Services.yaml`:

```yaml
# Override the enforcement service
Netresearch\NrPasskeysFe\Service\FrontendEnforcementService:
  class: MyVendor\MyExt\Service\CustomEnforcementService
```

## Custom enforcement via event {#custom-enforcement-via-event}

The recommended approach for custom enforcement logic is to listen to
`EnforcementLevelResolvedEvent` and call `setEffectiveLevel()`:

```php
use Netresearch\NrPasskeysFe\Event\EnforcementLevelResolvedEvent;

final class CustomEnforcementListener
{
    public function __invoke(EnforcementLevelResolvedEvent $event): void
    {
        // Exempt staff members from enforcement
        if ($this->isStaffMember($event->feUserUid)) {
            $event->setEffectiveLevel('off');
        }
    }
}
```

## Adding custom eID endpoints {#adding-custom-eid-endpoints}

The extension's eID dispatcher (`EidDispatcher`) is registered at
`eID=nr_passkeys_fe`. It routes requests to controllers based on
the `action` POST parameter.

To add custom eID actions without modifying the extension, listen to
`BeforePasskeyAuthenticationEvent` for pre-auth hooks, or register
your own eID handler in `ext_localconf.php`:

```php
$GLOBALS['TYPO3_CONF_VARS']['FE']['eID_include']['my_passkey_ext']
    = \MyVendor\MyExt\Eid\MyEidHandler::class . '::handle';
```

## JavaScript module overrides {#javascript-module-overrides}

The extension's JavaScript modules are loaded as TYPO3 ES modules
(`@netresearch/nr-passkeys-fe/*`). To customize behavior, extend the
module via `@typo3/core/event/regular-event.js` hooks or override the
import map in `Configuration/JavaScriptModules.php`.

> [!NOTE]
> Overriding JavaScript modules is an advanced technique. Prefer
> CSS overrides and template overrides for UI customization.

## PasskeyUtils.js shared module {#passkeyutils-js-shared-module}

All frontend JavaScript modules share a common utility module,
`PasskeyUtils.js`, exposed as `window.NrPasskeysFe`. It provides:

-   **base64url encoding/decoding** -- `base64urlToBuffer()` and
    `bufferToBase64url()` for converting between WebAuthn binary
    formats and JSON-safe strings.
-   **DOM helpers** -- `showError()`, `showStatus()`,
    `showLoading()` for consistent UI state management across the
    login, enrollment, management, and recovery modules.
-   **URL validation** -- Shared URL handling utilities.

`PasskeyUtils.js` is loaded before the module-specific scripts via
`f:asset.script` in Fluid templates. If you override templates, ensure
`PasskeyUtils.js` is still included before other passkey scripts.

The eight JavaScript modules are:

-   `PasskeyLogin.js` -- Login form and WebAuthn assertion flow
-   `PasskeyEnrollment.js` -- Enrollment ceremony
-   `PasskeyManagement.js` -- Credential list, rename, remove
-   `PasskeyRecovery.js` -- Recovery code login form
-   `PasskeyRecoveryCodes.js` -- Recovery code generation UI
-   `PasskeyBanner.js` -- Encourage-level dismissible banner
-   `PasskeyFeAdmin.js` -- Backend admin module
-   `PasskeyUtils.js` -- Shared utilities (described above)
