digitalzombies / be-invite
Invite backend users via email with password reset link
Package info
github.com/DigitalZombies/be_invite
Type:typo3-cms-extension
pkg:composer/digitalzombies/be-invite
Requires
- typo3/cms-backend: ^14.0
- typo3/cms-beuser: ^14.0
- typo3/cms-core: ^14.0
Requires (Dev)
- typo3/testing-framework: ^9.6
README
Invite backend users by email instead of creating accounts with a password you have to communicate out of band.
An administrator enters an email address, an optional name and one or more backend user
groups. The extension creates the be_users record with a random, never-disclosed
password and emails the invitee a link that lets them set their own password through
TYPO3's regular password reset screen.
- No plaintext password is ever generated, stored in a ticket, or sent over chat.
- The invitation link is valid for 48 hours (TYPO3's own reset links last 2 hours).
- The whole flow is admin-only and protected by TYPO3's sudo mode.
Requirements
| TYPO3 | 14.0 – 14.99 (v14 only) |
| PHP | 8.2+ |
A working mail setup ($GLOBALS['TYPO3_CONF_VARS']['MAIL']) is required — without it the
account is created but the invitation cannot be delivered, and the extension will say so.
Installation
composer require digitalzombies/be-invite
Then flush the caches. No database schema changes, no TypoScript, no configuration.
Usage
- Log in to the TYPO3 backend as an administrator.
- Open System › Backend Users.
- Click Invite user in the docheader.
- Fill in the email address, optionally a name, and select at least one user group.
- Confirm your own password when TYPO3's sudo mode dialog appears.
The invitee receives an email with an activation link. Their username is their email address.
📖 Full documentation with screenshots
How it works
| Step | Where |
|---|---|
| "Invite user" button injected into the docheader | Classes/EventListener/AddInviteButtonListener.php (PSR-14, ModifyButtonBarEvent) |
| Modal + form + AJAX | Resources/Public/JavaScript/invite-module.js |
Endpoints /be-invite/groups (GET), /be-invite/create (POST) |
Configuration/Backend/AjaxRoutes.php → Classes/Controller/InviteController.php |
| Account creation, token generation, mail dispatch | Classes/Service/InviteService.php |
| Email body | Resources/Private/Templates/Email/Invitation.{html,txt} |
The reset link is generated the same way TYPO3 core generates password reset links — same
token layout, same password-reset HMAC scope, same password_reset_token column — so it
is validated by core's untouched password_reset_validate route. Only the lifetime
differs.
Security notes
- Both AJAX endpoints reject non-administrators with a translated
403. This is not redundant withbe_usersbeingadminOnly: the group endpoint would otherwise let any editor enumerate every backend user group. - Creating the account triggers TYPO3's sudo mode, so an unattended session cannot be used to grant backend access.
- Internal failures (DataHandler output, SQL errors, mailer configuration) are logged via PSR-3 and replaced with a generic message before they reach the browser.
- An existing account — including a disabled or time-restricted one — blocks the invitation instead of silently producing a renamed duplicate.
- The invitation link works even when
$GLOBALS['TYPO3_CONF_VARS']['BE']['passwordReset']is disabled, because the corepassword_reset_validateroute only validates the token. If you switched password reset off deliberately, be aware that this extension reopens that path for invited users.
Customising the invitation email
The templates are registered under MAIL/templateRootPaths[1700000000]. Override them by
registering your own path with a higher key:
$GLOBALS['TYPO3_CONF_VARS']['MAIL']['templateRootPaths'][1700000100] = 'EXT:my_sitepackage/Resources/Private/Templates/Email/';
and providing Invitation.html / Invitation.txt. Available variables: name, email,
resetLink.
The shipped templates are English only. The recipient has no backend account language preference yet at invitation time, so no automatic language selection is attempted.
Translations
Backend UI labels ship in English, German and Hungarian
(Resources/Private/Language/{locallang,de.locallang,hu.locallang}.xlf, 24 keys each).
The same file feeds PHP (LLL:EXT:…) and JavaScript (lll() via TYPO3.lang).
Tests
12 unit tests and 28 functional tests. The extension installs its own test environment
into .Build/, so a checkout is enough:
composer install .Build/bin/phpunit -c Build/phpunit/UnitTests.xml
Functional tests create and drop databases, so they need a MySQL/MariaDB server and an account allowed to do that:
typo3DatabaseDriver=mysqli \ typo3DatabaseHost=127.0.0.1 typo3DatabasePort=3306 \ typo3DatabaseUsername=root typo3DatabasePassword=root \ typo3DatabaseName=func_test \ .Build/bin/phpunit -c Build/phpunit/FunctionalTests.xml
Both suites run with failOnDeprecation, failOnNotice, failOnWarning and
failOnRisky, and run in CI on PHP 8.2, 8.3 and 8.4 — which resolve PHPUnit 11, 12 and 13
respectively, so the suites are kept clean on all three.
Contributing
Issues and pull requests are welcome. Please make sure both suites pass and keep them green on every supported PHP version; CI enforces this, and it also fails on TYPO3 deprecations.
License
GPL-2.0-or-later