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-fileinfo (used for MIME-type validation of file uploads)

Database Update 

After updating, run the database analyser in the TYPO3 Install Tool to apply the required schema changes.

A new field tx_femanager_confirmation_required is added to the fe_users 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_femanager_confirmation_required:

  • The resend action only (re)sends the user confirmation mail when the account still has an outstanding user confirmation (User::isUserConfirmationResendable()). 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 (User::isAdminConfirmationMissing()).
  • 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, processUpdateWorkflow): 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 ({confirmUrl}, {refuseUrl}, {refuseSilentUrl}) already carry it, so customised UpdateRequest.html templates that use those variables need no change; only templates that build the link manually must pass the admin hash in the hash argument.

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 (UserGroupSanitizationService). The form is secure by default / fail closed:

  • Forced groups - if settings.<form>.overrideUserGroup is set, the configured group(s) win and the submitted value is ignored (unchanged behaviour).
  • Field not editable - if usergroup is not part of the configured fields, any submitted usergroup change is reverted.
  • Allowlist - if settings.<form>.validation.usergroup.inList is set, the submitted uids are reduced to that list. This is the recommended way to let users choose a group.
  • Opt-in for unrestricted selection - if no allowlist is configured but settings.<form>.misc.allowUnrestrictedUserGroupSelection = 1 is set, every offered group may be selected (legacy behaviour).
  • 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.

If you override Resources/Private/Partials/Fields/Usergroup.html, note that the field is now rendered depending on the new usergroupFieldMode 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: {confirmUrl}, {refuseUrl}, {refuseSilentUrl}

Old (custom template):

<f:link.action action="confirmCreateRequest" controller="New" absolute="1"
    arguments="{user:user, hash:hash, adminHash:adminHash, status:'adminConfirmation'}">
Copied!

New:

<a href="{confirmUrl}">Confirm</a>
Copied!

CreateUserConfirmation.html

New variables: {confirmByUserUrl}, {refuseByUserUrl}

UpdateRequest.html

New variables: {confirmUrl}, {refuseUrl}, {refuseSilentUrl}

CreateNotify.html

New variables: {refuseUrl}, {refuseSilentUrl}

Renamed Controller Actions 

Several controller actions involved in confirmation workflows have been renamed or replaced. If you have customised templates that use f:link.action to build workflow links, update the action and workflowAction argument values accordingly.

NewController (plugin tx_femanager_registration)

The single confirmCreateRequest action has been split into two actions to support an optional intermediate confirmation dialog:

Old action New action Purpose
confirmCreateRequest registrationWorkflowDialog Shows an optional confirmation dialog before executing the workflow step (rendered when the corresponding TypoScript option is enabled)
confirmCreateRequest processRegistrationWorkflow Executes the workflow step directly, without a confirmation dialog

The status argument has been replaced by workflowAction. The following values are accepted:

Workflow step workflowAction value
User confirms registration userConfirmation
User refuses registration userConfirmationRefused
Admin confirms registration adminConfirmation
Admin refuses registration adminConfirmationRefused
Admin refuses registration silently adminConfirmationRefusedSilent

EditController (plugin tx_femanager_edit)

Old action New action
confirmUpdateRequest processUpdateWorkflow

The workflowAction parameter values for update workflows are: adminConfirmation, adminConfirmationRefused, adminConfirmationRefusedSilent.

Workflow Architecture Refactoring 

The confirmation and update workflow logic has been extracted from the controllers into dedicated, injectable service classes:

  • RegistrationWorkflowService — handles new user registration confirmation flows (user and admin)
  • UpdateWorkflowService — handles profile update confirmation flows
  • InvitationWorkflowService — handles invitation flows
  • MailWorkflowLinkService — builds absolute workflow URLs using TYPO3's SiteFinder and site router

The MailWorkflowLinkService 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.yaml.

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
            }
        }
    }
}
Copied!

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
    }
}
Copied!

Removed and Deprecated TypoScript / TSconfig Options 

Removed TSconfig keys

The file Configuration/UserTsConfig/BackendModule.typoscript and its TSconfig namespace have been removed entirely. The following keys no longer have any effect:

Removed TSconfig key Replacement
tx_femanager.UserBackend.confirmation.filter.userConfirmation 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_femanager.UserBackend.confirmation.ResendUserConfirmationRequest Replaced by the tx_femanager:userConfirmationReminder backend user group permission.
tx_femanager.UserBackend.enableLoginAs Replaced by the tx_femanager:loginAs backend user group permission.

Removed TypoScript settings

Removed setting Replacement
module.tx_femanager.settings.configPID Use plugin.tx_femanager.settings.backend.workflow.registrationPageUid instead.

Deprecated TypoScript settings

The following setting is deprecated and will be removed in v15:

Deprecated setting Replacement
plugin.tx_femanager.settings.showResendUserConfirmationRequestView Use plugin.tx_femanager.settings.backend.workflow.registrationPageUid instead.

Custom Finishers 

If you have implemented custom finishers, the FinisherInterface has changed as follows:

Old method signature New method signature
getSettings(): mixed getTypoScriptSettings(): array
setSettings($settings) setTypoScriptSettings(array $typoScriptSettings): FinisherInterface
setUser($user) setUser(User $user): FinisherInterface
initializeFinisher() initializeFinisher(): void

Custom DataProcessors 

The process() method in DataProcessorInterface now requires an explicit array return type:

// Old
public function process(array $data, array $settings);

// New
public function process(array $data, array $settings): array;
Copied!

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
UserUtility::getCurrentUser() UserSessionService::getCurrentUser()
UserUtility::login() UserSessionService::login()
UserUtility::removeSession() UserSessionService::removeSession()
UserUtility::convertPassword() PasswordHashingService::convertPassword()
UserUtility::hashPassword() PasswordHashingService::hashPassword()
UserUtility::getDirtyPropertiesFromUser() UserDirtyPropertiesService::getDirtyPropertiesFromUser()
UserUtility::forceValues() FrontendUserService::forceValues()
UserUtility::overrideUserGroup() FrontendUserService::overrideUserGroup()
UserUtility::fallbackUsernameAndPassword() FrontendUserService::fallbackUsernameAndPassword()

BackendUtility — numerous static methods have been removed (including loadTS(), isConfirmationModuleActive(), isEnableLoginAsActive(), getConfiguration(), 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/Service/Mail/ and renamed:

Old class New class
In2code\Femanager\Domain\Service\SendMailService In2code\Femanager\Domain\Service\Mail\MailService
In2code\Femanager\Domain\Service\Mail\AbstractMailService In2code\Femanager\Domain\Service\Mail\AbstractFluidMailService
In2code\Femanager\Domain\Service\Mail\MailMessageService Removed, FluidMailService is the only implementation (see drop sendMail above)

In addition, send() no longer takes a RequestInterface 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;
Copied!

If you inject one of these services, extend AbstractFluidMailService or implement MailServiceInterface, 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\Femanager\ViewHelpers\Condition\IsBackendAdministratorAuthenticationViewHelper Use the template variable {isAdmin}, which the backend module assigns
In2code\Femanager\ViewHelpers\Be\GetClassNameOnActionViewHelper No replacement, the unified backend list does not need it any more
In2code\Femanager\ViewHelpers\Misc\BackendEditLinkViewHelper Use TYPO3's <be:uri.editRecord> / <be:link.editRecord>
In2code\Femanager\ViewHelpers\Misc\BackendNewLinkViewHelper Use TYPO3's <be:uri.newRecord> / <be:link.newRecord>
In2code\Femanager\ViewHelpers\Misc\GetFirstViewHelper Access the first object directly ({objects.0}) or use <f:first>
In2code\Femanager\ViewHelpers\Misc\RequestViewHelper No replacement, workflow URLs are built server-side by MailWorkflowLinkService

Changed Method Visibility 

The following methods of AbstractFrontendController are protected now and can no longer be called from outside the controller hierarchy: createAllConfirmed(), updateAllConfirmed(), updateRequest(), finalCreate() and sendCreateUserConfirmationMail().

Removed PSR-14 Event 

BeforeMailBodyRenderEvent 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
Copied!

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_femanager:loginAs Shows the Login as frontend user button in the list view
tx_femanager:logoutUser Shows the Logout frontend user button in the list view
tx_femanager:adminConfirmation Shows the Confirm and Refuse buttons for pending admin confirmations
tx_femanager:userConfirmationReminder 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() 

MailServiceInterface::sendSimple() (and its implementation in MailService) 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 MailServiceInterface can drop sendSimple() with v15.

Deprecation: FluidMailService and AbstractFluidMailService 

The mail logic of FluidMailService has been merged into MailService. FluidMailService and AbstractFluidMailService 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.

MailServiceInterface is now registered as an alias of MailService in the dependency injection container and the workflow services inject the interface. Migration:

  • Inject In2code\Femanager\Domain\Service\Mail\MailServiceInterface instead of FluidMailService.
  • Instead of extending FluidMailService or AbstractFluidMailService, implement MailServiceInterface (or extend MailService) and register your class as alias in the Services.yaml of your extension:

    In2code\Femanager\Domain\Service\Mail\MailServiceInterface:
      alias: Vendor\MyExtension\Service\MyMailService
    Copied!
  • To modify the mail only, listen to BeforeMailSendEvent instead.

The $mailService property of DataController and UserBackendController 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->mailService, inject MailServiceInterface in your own controller instead.

Deprecation: TypoScript option embedImage 

The TypoScript option embedImage of the mail configuration (e.g. plugin.tx_femanager.settings.new.email.createAdminConfirmation.embedImage) and the template variable {embedImages} are deprecated and will be removed with femanager v15.

In v14 nothing changes: the default configuration still embeds the user image into the mails createAdminConfirmation and createAdminNotify, and {embedImages.0} keeps working in own templates.

Migration: show images with <f:image>

The partial UserProperties shows the user image with <f:image> as soon as embedImage 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 >
Copied!

Additional images are added directly to an own mail template:

<f:image src="fileadmin/image.jpg" maxWidth="200" absolute="1" alt="" />
Copied!

Note that <f:image> 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 BeforeMailSendEvent. 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');
        }
    }
}
Copied!
<img src="{logo}" alt="" />
Copied!

to version 13.0.0 

Deprecations

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/
   }
}
Copied!

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}"/>
Copied!

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
    }
}
Copied!

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/Misc/DeleteLink.html

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>
Copied!

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>
Copied!

/Templates/Edit/Edit.html

You need to add: <f:form.hidden name="token" value="{token}" /> 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>
Copied!

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:

  1. Backend Module: Login as User feature
feManagerLoginAs.typeNum = 1548943013
Copied!

see the complete config in file ext_typoscript_setup.txt

  1. Frontend Validation via JS
feManagerLoginAs.typeNum = 1548935210
Copied!

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