Upgrade
to version 14.0.0 | to version 13.0.0 | to version 8.0.0 | to version 7.1.0 | to version 6.0.0 | to version 5.2.0 | to version 5 | to version 4.2.3 / 4.2.4 / 4.2.5 |
to version 14.0.0
System Requirements
The minimum requirements have been raised:
- PHP: 8.2 or higher (previously 8.1)
- TYPO3: ^14.0 (previously ^13.4)
- Symfony: ^7.0 (previously ^6.4 or ^7.0)
- New PHP extension required:
ext-(used for MIME-type validation of file uploads)fileinfo
Database Update
After updating, run the database analyser in the TYPO3 Install Tool to apply the required schema changes.
A new field tx_ is added to the fe_ table. It stores a bitmask value
for confirmation workflows:
0— No confirmation required (User::)CONFIRMATION_ REQUIRED_ NONE 1— User confirmation required (User::)CONFIRMATION_ REQUIRED_ USER 2— Admin confirmation required (User::)CONFIRMATION_ REQUIRED_ ADMIN
Security: registration confirmation bypass
This version closes a registration confirmation bypass via the "Resend Confirmation Mail" plugin. The
resend plugin is a separate content element without the registration plugin's flexform, so the required
confirmation can no longer be derived from the ambient settings at resend time. The workflow now reads
the requirement persisted on the user in tx_:
- The resend action only (re)sends the user confirmation mail when the account still has an outstanding
user confirmation (
User::). Sites that only use admin confirmation no longer hand out a valid user confirmation link, and the user confirmation step can no longer enable an account that still needs admin approval (is User Confirmation Resendable () User::).is Admin Confirmation Missing () - To avoid disclosing whether an account exists for a given email address, the resend form shows the same neutral message for every valid address - regardless of whether a mail was sent, nothing was pending, or no such account exists.
The same hardening applies to the profile change confirmation (Edit controller,
process): confirming, refusing or silently refusing a pending profile change is an admin
action and now always requires a valid admin hash. The pre-built workflow URLs
({confirm, {refuse, {refuse) already carry it, so customised
Update templates that use those variables need no change; only templates that build the
link manually must pass the admin hash in the hash argument.
Important
After updating, run the upgrade wizard
Admin Tools > Upgrade > Run Upgrade Wizard > "EXT:femanager: Migrate required confirmation for pending users".
It populates tx_ for accounts that were still pending at the time of
the update. The fix does not depend on the wizard for its security: for accounts that still carry the
default value 0 the requirement is inferred at runtime from the confirmation state
(User::). For the ambiguous case (a disabled account confirmed by
neither the user nor an admin) the safe option is chosen and an admin confirmation is required; such
accounts can always be released from the femanager backend module.
Security: usergroup privilege escalation
This version closes a privilege escalation in the frontend usergroup selection. The registration, edit
and invitation forms can render a usergroup <select>, but the frontend template is not a security
boundary: a crafted request can submit any usergroup uid regardless of what the form offers, so a logged-in
frontend user could assign any frontend usergroup - including privileged ones - to their own account.
The submitted usergroup relation is now validated on the server before the user is persisted, in a single
place (User). The form is secure by default / fail closed:
- Forced groups - if
settings.<form>.is set, the configured group(s) win and the submitted value is ignored (unchanged behaviour).override User Group - Field not editable - if
usergroupis not part of the configuredfields, any submitted usergroup change is reverted. - Allowlist - if
settings.<form>.is set, the submitted uids are reduced to that list. This is the recommended way to let users choose a group.validation. usergroup. in List - Opt-in for unrestricted selection - if no allowlist is configured but
settings.<form>.is set, every offered group may be selected (legacy behaviour).misc. allow Unrestricted User Group Selection = 1 - Fail closed - if neither an allowlist nor the opt-in is configured, the submitted usergroup change is
ignored and a log entry (
Profile update not authorized) is written.
Important
Installations that previously relied on an unconfigured usergroup selection (no
validation.) will no longer accept user-submitted usergroups by default. This is
intentional. To keep offering a usergroup selection, configure an allowlist per form
(plugin.) or, to
restore the former unrestricted behaviour, set
plugin..
If you override Resources/Private/Partials/Fields/Usergroup.html, note that the field is now
rendered depending on the new usergroup variable (select / hidden / notice).
See Securing the usergroup selection for the full description of the feature.
Custom E-Mail Templates
Mail templates now receive pre-built absolute URLs as template variables instead of constructing action links inline. If you have customised any of the mail templates listed below, you must update them accordingly.
CreateAdminConfirmation.html
New variables: {confirm, {refuse, {refuse
Old (custom template):
<f:link.action action="confirmCreateRequest" controller="New" absolute="1"
arguments="{user:user, hash:hash, adminHash:adminHash, status:'adminConfirmation'}">
New:
<a href="{confirmUrl}">Confirm</a>
CreateUserConfirmation.html
New variables: {confirm, {refuse
UpdateRequest.html
New variables: {confirm, {refuse, {refuse
CreateNotify.html
New variables: {refuse, {refuse
Note
You may still build workflow links manually using f:. Use the updated action names and
workflow parameter values described in the Renamed Controller Actions section below.
Example for an admin confirmation link in Create:
<f:link.action action="registrationWorkflowDialog" controller="New" absolute="1"
arguments="{user:user, hash:hash, workflowAction:'adminConfirmation'}">
Confirm registration
</f:link.action>
Breaking: Confirmation Links Now Expire
Up to femanager 13 the hash in a confirmation link was derived from the username alone, so every link sent by
email stayed valid forever and could be used again at any time. The hash now carries a signed expiration date
and has the format <expiration. The timestamp 0 marks a link that never expires.
The signed value is the uid of the user, the workflow step and the expiration date. Signing the uid instead of
the username closes a gap: every workflow link addresses its user by uid, while usernames are not unique in
TYPO3 - unique is a femanager validation that can be switched off and that backend editors, imports and
other extensions bypass. A link of one user was therefore usable for the record of a namesake. As a side effect
a rename no longer invalidates the links already sent to that user; their lifetime does.
This affects the double-opt-in link, the admin confirmation and refusal links for registrations, the admin confirmation links for profile changes, and the invitation link.
The same hash format is used for the hash parameter that authorises the user detail view of the List
plugin. That hash is rendered into the list view instead of being sent by mail, so it is created without a
lifetime and never expires. Links to a detail view that were bookmarked or published before the update stop
working, because they carry the old hash format; opening the list view again yields a working link.
Links sent before the update stop working. They use the old format and are rejected. Only registrations,
profile changes and invitations that were still unconfirmed at the moment of the update are affected. Those
users can request a new link themselves through the ResendConfirmationMail plugin, an administrator can
resend the confirmation from the backend module, and femanager: sends a new
link to everyone whose registration is still unconfirmed.
The lifetime is configured per workflow, in seconds. The default is one day:
plugin.tx_femanager {
settings {
new.confirmationLinkLifetime = 86400
edit.confirmationLinkLifetime = 86400
invitation.confirmationLinkLifetime = 86400
}
}
Set a value to 0 to restore the previous behaviour of links that never expire.
Visitors who open an expired link get one of the new labels confirmation,
confirmation or confirmation, and are guided to the resend
dialog where the workflow allows it. See Expiring Confirmation Links for the full description.
Mail templates that contain a workflow link additionally receive {link, so they can state how
long the link works. Existing templates keep working unchanged.
Removed: In2code\. Use the injectable
In2code\ instead:
| Old static method | New service method |
|---|---|
Hash | Confirmation |
Hash | Confirmation or validate, which throws
Invalid and Expired |
The suffix 'admin' is now Confirmation, the empty suffix is
Confirmation and the suffix 'show' of the user detail view is
Confirmation.
Unlike the removed utility the service can only sign a user that has been persisted; it throws an
Invalid for a user without a uid.
Abstract and User take the new service as an additional constructor
argument. If you extend one of them, add the argument to your constructor.
Renamed template: Resources/Private/Templates/Edit/ConfirmUpdateRequest.html is now
Process, matching the renamed action below. Without the rename the action cannot
render its response.
Renamed Controller Actions
Several controller actions involved in confirmation workflows have been renamed or replaced. If you have
customised templates that use f: to build workflow links, update the action and
workflow argument values accordingly.
NewController (plugin tx_)
The single confirm action has been split into two actions to support an optional
intermediate confirmation dialog:
| Old action | New action | Purpose |
|---|---|---|
confirm | registration | Shows an optional confirmation dialog before executing the workflow step (rendered when the corresponding TypoScript option is enabled) |
confirm | process | Executes the workflow step directly, without a confirmation dialog |
The status argument has been replaced by workflow. The following values are accepted:
| Workflow step | workflow value |
|---|---|
| User confirms registration | user |
| User refuses registration | user |
| Admin confirms registration | admin |
| Admin refuses registration | admin |
| Admin refuses registration silently | admin |
EditController (plugin tx_)
| Old action | New action |
|---|---|
confirm | process |
The workflow parameter values for update workflows are: admin,
admin, admin.
Workflow Architecture Refactoring
The confirmation and update workflow logic has been extracted from the controllers into dedicated, injectable service classes:
Registration— handles new user registration confirmation flows (user and admin)Workflow Service Update— handles profile update confirmation flowsWorkflow Service Invitation— handles invitation flowsWorkflow Service Mail— builds absolute workflow URLs using TYPO3'sWorkflow Link Service Siteand site routerFinder
The Mail generates all workflow action URLs server-side. This is what enables
femanager to build correct URLs outside of a frontend context (e.g. from the backend module or a CLI
command). The plugin namespaces used for URL generation are:
- Registration:
tx_femanager_ registration - Edit / update:
tx_femanager_ edit - Invitation:
tx_femanager_ invitation
If you have extended or decorated any of these services, register the overrides in your Services..
TypoScript: New Backend Settings
When confirmation mails are generated outside of a frontend request (e.g. from the backend module or via CLI), femanager requires explicit page UIDs to build the correct action URLs. Add the following to your TypoScript setup:
plugin.tx_femanager {
settings {
backend {
workflow {
registrationPageUid = [uid of the page containing the registration plugin]
updatePageUid = [uid of the page containing the edit plugin]
invitationPageUid = [uid of the page containing the invitation plugin]
}
pagination {
itemsPerPage = 50
}
}
}
}
JavaScript: Build process removed
femanager now ships plain JavaScript and CSS files instead of building them with an NPM tool chain, in order to avoid the security issues that come with it.
The default TypoScript includes the files as shown below. If you include the assets yourself, use these paths:
page {
includeCSS {
femanagerMain = EXT:femanager/Resources/Public/Css/Main.css
}
includeJSFooter {
femanagerValidation = EXT:femanager/Resources/Public/JavaScript/Validation.js
femanager = EXT:femanager/Resources/Public/JavaScript/Femanager.js
}
}
Removed and Deprecated TypoScript / TSconfig Options
Removed TSconfig keys
The file Configuration/ and its TSconfig namespace have been
removed entirely. The following keys no longer have any effect:
| Removed TSconfig key | Replacement |
|---|---|
tx_ | No longer needed. The separate Confirmation backend view has been removed. Users pending confirmation are shown inline in the unified list view and can be filtered there. |
tx_ | Replaced by the tx_ backend user group permission. |
tx_ | Replaced by the tx_ backend user group permission. |
Removed TypoScript settings
| Removed setting | Replacement |
|---|---|
module. | Use plugin. instead. |
Deprecated TypoScript settings
The following setting is deprecated and will be removed in v15:
| Deprecated setting | Replacement |
|---|---|
plugin. | Use plugin. instead. |
Custom Finishers
If you have implemented custom finishers, the Finisher has changed as follows:
| Old method signature | New method signature |
|---|---|
get | get |
set | set |
set | set |
initialize | initialize |
Custom DataProcessors
The process method in Data now requires an explicit array return type:
// Old
public function process(array $data, array $settings);
// New
public function process(array $data, array $settings): array;
Removed PHP Classes and Static Methods
UserUtility has been removed entirely. Replace all usages with the corresponding injectable services:
| Old static method | New injectable service |
|---|---|
User | User |
User | User |
User | User |
User | Password |
User | Password |
User | User |
User | Frontend |
User | Frontend |
User | Frontend |
BackendUtility — numerous static methods have been removed (including load,
is, is, get, and others).
Replace these with the corresponding TYPO3 Core APIs or injectable services.
Renamed Mail Service Classes
The mail services have been moved into Domain/ and renamed:
| Old class | New class |
|---|---|
In2code\ | In2code\ |
In2code\ | In2code\ |
In2code\ | Removed, Fluid is the only implementation (see drop sendMail above) |
In addition, send no longer takes a Request as its last argument:
// Old
public function send(string $template, array $receiver, array $sender, string $subject,
array $variables = [], array $typoScript = [], ?RequestInterface $request = null): bool;
// New
public function send(string $template, array $receiver, array $sender, string $subject,
array $variables = [], array $typoScript = []): bool;
If you inject one of these services, extend Abstract or implement
Mail, adjust the class names and the method signature accordingly.
Removed ViewHelpers
The following ViewHelpers have been removed. If you use them in customised templates, replace them:
| Removed ViewHelper | Replacement |
|---|---|
In2code\ | Use the template variable {is, which the backend module assigns |
In2code\ | No replacement, the unified backend list does not need it any more |
In2code\ | Use TYPO3's <be: / <be: |
In2code\ | Use TYPO3's <be: / <be: |
In2code\ | Access the first object directly ({objects.) or use <f: |
In2code\ | No replacement, workflow URLs are built server-side by Mail |
Changed Method Visibility
The following methods of Abstract are protected now and can no longer be called from
outside the controller hierarchy: create, update, update,
final and send.
Removed PSR-14 Event
Before has been removed. It was already deprecated in v13.
New Feature: Confirmation Reminder Command
A new CLI command is available to send reminder mails to users who have not yet confirmed their registration:
vendor/bin/typo3 femanager:sendUserConfirmationReminder
The number of days before a reminder is sent can be configured (default: 7 days).
New Feature: Unified Backend Module
The previously separate backend views have been consolidated into a single list view. Filters for confirmation status, login status, search term, and page tree depth, as well as pagination, are now integrated directly into this view.
New Feature: Custom Backend Permissions
The backend module now supports fine-grained access control via TYPO3's custom permissions system. Four permission options are available and can be assigned per backend user group under Backend User Groups > Custom Permissions > Permissions for Backend Module "Frontend Users":
| Permission key | Effect when granted |
|---|---|
tx_ | Shows the Login as frontend user button in the list view |
tx_ | Shows the Logout frontend user button in the list view |
tx_ | Shows the Confirm and Refuse buttons for pending admin confirmations |
tx_ | Shows the Resend confirmation reminder button for users awaiting e-mail confirmation |
Backend admins always have access to all actions regardless of these permission settings.
Deprecation: MailServiceInterface::sendSimple()
Mail (and its implementation in Mail) is
deprecated and will be removed with femanager v15. It still works as before in v14, but triggers a deprecation
notice. Use send instead.
Note the behaviour difference: send applies the TypoScript overrides for receiver, sender, subject, cc,
replyTo, priority and attachments. If the passed values should be used as they are, do not pass these keys in the
TypoScript configuration.
Custom implementations of Mail can drop send with v15.
Deprecation: FluidMailService and AbstractFluidMailService
The mail logic of Fluid has been merged into Mail. Fluid and
Abstract are no longer used by femanager, are deprecated and will be removed with femanager v15.
They still work in v14, but trigger a deprecation notice when instantiated.
Mail is now registered as an alias of Mail in the dependency injection container and
the workflow services inject the interface. Migration:
- Inject
In2code\instead ofFemanager\ Domain\ Service\ Mail\ Mail Service Interface Fluid.Mail Service -
Instead of extending
FluidorMail Service Abstract, implementFluid Mail Service Mail(or extendService Interface Mail) and register your class as alias in theService Services.of your extension:yaml In2code\Femanager\Domain\Service\Mail\MailServiceInterface: alias: Vendor\MyExtension\Service\MyMailServiceCopied! - To modify the mail only, listen to
Beforeinstead.Mail Send Event
The $mail property of Data and User is not used anymore. It is deprecated
and will be removed together with the constructor argument with femanager v15. If you extend one of these controllers
and use $this->mail, inject Mail in your own controller instead.
Deprecation: TypoScript option embedImage
The TypoScript option embed of the mail configuration (e.g.
plugin.) and the template variable
{embed are deprecated and will be removed with femanager v15.
In v14 nothing changes: the default configuration still embeds the user image into the mails
create and create, and {embed keeps working in own templates.
Migration: show images with <f:image>
The partial User shows the user image with <f: as soon as embed is not configured.
Remove the option to switch to the new behaviour already in v14:
plugin.tx_femanager.settings.new.email.createAdminConfirmation.embedImage >
plugin.tx_femanager.settings.new.email.createAdminNotify.embedImage >
Additional images are added directly to an own mail template:
<f:image src="fileadmin/image.jpg" maxWidth="200" absolute="1" alt="" />
Note that <f: links the image instead of embedding it: the image must be publicly accessible, the URL must
be absolute (absolute="1") and many mail clients only show external images after a confirmation of the recipient.
Migration: embed images with the BeforeMailSendEvent
Embedding images into the mail is still possible with the Before. The mail body is rendered when the
mail is sent, so a listener can embed an image and assign its cid to the template:
use In2code\Femanager\Event\BeforeMailSendEvent;
use TYPO3\CMS\Core\Attribute\AsEventListener;
use TYPO3\CMS\Core\Core\Environment;
use TYPO3\CMS\Core\Mail\FluidEmail;
#[AsEventListener(identifier: 'my-extension/mail-logo')]
final class EmbedLogoEventListener
{
public function __invoke(BeforeMailSendEvent $event): void
{
$email = $event->getEmail();
if ($email instanceof FluidEmail) {
$email->embedFromPath(Environment::getPublicPath() . '/fileadmin/logo.png', 'logo.png', 'image/png');
$email->assign('logo', 'cid:logo.png');
}
}
}
<img src="{logo}" alt="" />
to version 13.0.0
Deprecations
Confirmation links
New TypoScript options are added for this: new.email.createUserConfirmation.confirmUserConfirmation When enabled, a user confirming their profile creation via the email link will show a confirmation dialog beforehand. This prevents unexpected execution f.e. via Virus Scanners new.email.createUserConfirmation.confirmAdminConfirmation When enabled, an admin confirming/refusing/silently refusing someones profile creation via the email link will show a confirmation dialog beforehand This PR also includes adjustments to HashUtility allowing to specify more data while hashing a user, so that another hash can be created to prevent meddling with the admin actions (which by default is already prevented using cHashes).
For new.email.createUserConfirmation.confirmAdminConfirmation, this technically is a breaking change as template adjustments were required to pass the admin hash to the email links. If you have customized templates, please add the variable "adminHash:adminHash" to all action links in Resources/Private/Templates/Email/CreateAdminConfirmation.html
Example: old: <f:link.action action="confirmCreateRequest" controller="New" absolute="1" arguments="{user:user, hash:hash, status:'adminConfirmation'}"> new <f:link.action action="confirmCreateRequest" controller="New" absolute="1" arguments="{user:user, hash:hash, adminHash:adminHash, status:'adminConfirmation'}">
These settings are getting the default settings for V14!
to version 8.0.0
Upgrade Plugins
All Plugins used in your pages must be updated. The Updater is located in Admin Tools > Upgrade > Run Upgrade Wizard > "EXT:femanager: Migrate plugins"
TypoScript Changes
If you use the uploading feature for avatar images, the configuration has to be changed to the combined identifier
Constants:
plugin.tx_femanager {
settings {
uploadFolder = 1:users/
}
}
DataProcessors
The DataProcessors configured under plugin.tx_femanager.settings.dataProcessors are now without a return value, if you need to change data in the request use PSR-15 Middlewares
Autologin
Currently the AutoLogin feature does not work. When we have found a solution the feature will be enabled again, until then a link to the login page could be inserted.
to version 7.1.0
Invitation Template
If you are using customized templates for the invitation function, please check the Resources/Private/Templates/Invitation/Edit.html
You need to add
<f:form.hidden name="hash" value="{hash}"/>
in order,that the function is working.
to version 6.0.0
Version 6.0 support TYPO3 9 LTS and 10 LTS. The support for TYPO3 8 was dropped. No changes on Templates are needed.
Backend Module "Frontend User" - View User Confirmation
If you want to use the Backend Module to confirm or refuse Frontend User, you need to setup the configPID. The extension uses now a frontend call out of the backend, to organise these actions.
module.tx_femanager {
settings {
configPID = 1
}
}
to version 5.2.0
The edit template has to be adjusted, as there is a new parameter 'token' is introduced.
Please update these partials:
/Partials/
The argument token was introduced.
old:
<f:link.action
action="delete"
arguments="{user:user}"
class="btn btn-warning btn-large"
additionalAttributes="{data-confirm:'{f:translate(key:\'UserDeleteConfirmation\')}'}">
<i class="icon-trash icon-white"></i>
<f:translate key="deleteProfile" />
</f:link.action>
new:
<f:link.action
action="delete"
arguments="{user:user, token:token}"
class="btn btn-warning btn-large"
additionalAttributes="{data-confirm:'{f:translate(key:\'UserDeleteConfirmation\')}'}">
<i class="icon-trash icon-white"></i>
<f:translate key="deleteProfile" />
</f:link.action>
/Templates/
You need to add:
<f: between the form tag.
Example:
<f:form
name="user"
object="{user}"
action="update"
enctype="multipart/form-data"
additionalAttributes="{data-femanager-plugin:data.uid}"
class="form-horizontal {f:if(condition:'{settings.edit.validation._enable.client}',then:'feManagerValidation',else:'')}">
<fieldset>
<legend>
<f:translate key="titleUpdateProfile" />
</legend>
<f:form.hidden name="token" value="{token}" />
more stuff here in the template file…
</f:form>
to version 5
There are minor breaking changes include. Main change is, that all eid scripts were replace, by a page num approach.
In order that the js validation works, you need to take care, that you these page typenums are available:
- Backend Module: Login as User feature
feManagerLoginAs.typeNum = 1548943013
see the complete config in file ext_typoscript_setup.txt
- Frontend Validation via JS
feManagerLoginAs.typeNum = 1548935210
see the complete config in file Configuration/TypoScript/setup.ext
to version 4.2.3 / 4.2.4 / 4.2.5
If you use your own HTML templates of new/edit/invitation-templates you should compare them with the one from EXT:femanager. There is a new additional attribute inside the form viewhelper: data-femanager-plugin, which contains the content element id.
If you use a modified version of the Validation.js, there are also changes: plugin and action parameter is send to the eID-Script now