Skip to content

Commit

Permalink
BUGFIX: Use a dynamic url for user impersonation
Browse files Browse the repository at this point in the history
As described in the issue, the impersonation does not work when Neos is running in a subfolder. This change adds a data attribute with a dynamic URL to the DOM, and the user impersonation is using this module URL as base.

Fixes: #4797
  • Loading branch information
markusguenther committed Feb 6, 2024
1 parent 0a234a6 commit d246fea
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 10 deletions.
2 changes: 1 addition & 1 deletion Neos.Neos/Resources/Private/Partials/Backend/UserMenu.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{namespace neos=Neos\Neos\ViewHelpers}
<div class="neos-button-group neos-user-menu" data-csrf-Token="{f:security.csrfToken()}">
<div class="neos-button-group neos-user-menu" data-csrf-Token="{f:security.csrfToken()}" data-module-basepath="{neos:uri.module(path: '')}">
<button class="neos-dropdown-toggle neos-button" data-neos-toggle="dropdown" href="#" title="{neos:backend.translate(id: 'userSettings.usermenu', source: 'Modules', value: 'User Menu')}" data-neos-tooltip data-placement="left">
<i class="fas fa-user"></i> {user.name.fullName} <i class="fas fa-chevron-down"></i>
</button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,30 @@ import { RestoreButton } from '../../Templates/RestoreButton'
const BASE_PATH = '/neos/impersonate/'
export default class UserMenu {
constructor(_root) {
const csfrTokenField = document.querySelector('.neos-user-menu[data-csrf-token]')
this._csrfToken = !isNil(csfrTokenField)
? csfrTokenField.getAttribute('data-csrf-token')
const userMenuElement = document.querySelector('.neos-user-menu[data-csrf-token]')
this._csrfToken = !isNil(userMenuElement)
? userMenuElement.getAttribute('data-csrf-token')
: ''
this._basePath = this._getBasePath(userMenuElement)
this._root = _root
this._apiService = new ApiService(BASE_PATH, this._csrfToken)
this._apiService = new ApiService(this._basePath, this._csrfToken)

if (!isNil(_root)) {
this._checkImpersonateStatus()
}
}

_getBasePath(element) {
let url = BASE_PATH

if (!isNil(element) && element.hasAttribute('data-module-basepath')) {
let moduleBasePath = element.getAttribute('data-module-basepath')
moduleBasePath += moduleBasePath.endsWith('/') ? '' : '/'
url = moduleBasePath + 'impersonate/'
}

return url
}
_renderRestoreButton(user) {
const userMenuDropDown = this._root.querySelector('.neos-dropdown-menu')
if (isNil(userMenuDropDown) || isNil(user)) {
Expand Down
2 changes: 1 addition & 1 deletion Neos.Neos/Resources/Public/JavaScript/Main.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion Neos.Neos/Resources/Public/JavaScript/Main.min.js.map

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@ import {ImpersonateButton} from '../../Templates/ImpersonateButton'
const BASE_PATH = '/neos/impersonate/'
export default class UserManagement {
constructor(_root) {
const csfrTokenField = document.querySelector('.neos-user-menu[data-csrf-token]')
const userMenuElement = document.querySelector('.neos-user-menu[data-csrf-token]')
this._root = _root
this._csrfToken = !isNil(csfrTokenField) ? csfrTokenField.getAttribute('data-csrf-token') : ''
this._apiService = new ApiService(BASE_PATH, this._csrfToken)
this._csrfToken = !isNil(userMenuElement) ? userMenuElement.getAttribute('data-csrf-token') : ''
this._basePath = this._getBasePath(userMenuElement)
this._apiService = new ApiService(this._basePath, this._csrfToken)

if (!isNil(_root)) {
this._initialize()
Expand All @@ -27,6 +28,17 @@ export default class UserManagement {
});
}

_getBasePath(element) {
let url = BASE_PATH

if (!isNil(element) && element.hasAttribute('data-module-basepath')) {
let moduleBasePath = element.getAttribute('data-module-basepath')
moduleBasePath += moduleBasePath.endsWith('/') ? '' : '/'
url = moduleBasePath + 'impersonate/'
}

return url
}
_renderImpersonateButtons() {
const userTableActionButtons = Array.from(this._root.querySelectorAll('.neos-table .neos-action'))
userTableActionButtons.forEach(_actionContainer => {
Expand Down

0 comments on commit d246fea

Please sign in to comment.