Skip to content

Commit

Permalink
Merge pull request #4875 from neos/bugfix/user-impersonation-with-sub…
Browse files Browse the repository at this point in the history
…folders

BUGFIX: Use a dynamic URL for user impersonation
  • Loading branch information
mhsdesign authored Feb 11, 2024
2 parents 0a234a6 + df81b03 commit 4b137ed
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 17 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 @@ -2,21 +2,35 @@ import { isNil } from '../../Helper'
import {ApiService} from '../../Services'
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._baseModuleUri = this._getBaseModuleUri(userMenuElement)
this._basePath = this._getImpersonationBasePath()
this._root = _root
this._apiService = new ApiService(BASE_PATH, this._csrfToken)
this._apiService = new ApiService(this._basePath, this._csrfToken)

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

_getBaseModuleUri(element) {
let url = '/neos'
if (!isNil(element) && element.hasAttribute('data-module-basepath')) {
url = element.getAttribute('data-module-basepath')
}
return url
}

_getImpersonationBasePath() {
let basePath = this._baseModuleUri
if (!basePath.endsWith('/')) {
basePath += '/'
}
return basePath + 'impersonate/'
}
_renderRestoreButton(user) {
const userMenuDropDown = this._root.querySelector('.neos-dropdown-menu')
if (isNil(userMenuDropDown) || isNil(user)) {
Expand Down Expand Up @@ -64,7 +78,7 @@ export default class UserMenu {
const response = this._apiService.callRestore()
response
.then((data) => {
const { origin, impersonate, status } = data
const { origin, impersonate } = data
const message = window.NeosCMS.I18n.translate(
'impersonate.success.restoreUser',
'Switched back from {0} to the orginal user {1}.',
Expand All @@ -79,7 +93,7 @@ export default class UserMenu {

// load default backend, so we don't need to care for the module permissions.
// because in not every neos version the users have by default the content module or user module
window.location.pathname = '/neos'
window.location.href = this._baseModuleUri
})
.catch(function (error) {
if (window.NeosCMS) {
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 @@ -2,13 +2,14 @@ import {isNil} from '../../Helper'
import {ApiService} from '../../Services'
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._baseModuleUri = this._getBaseModuleUri(userMenuElement)
this._basePath = this._getImpersonationBasePath()
this._apiService = new ApiService(this._basePath, this._csrfToken)

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

_getBaseModuleUri(element) {
let url = '/neos'
if (!isNil(element) && element.hasAttribute('data-module-basepath')) {
url = element.getAttribute('data-module-basepath')
}
return url
}

_getImpersonationBasePath() {
let basePath = this._baseModuleUri
if (!basePath.endsWith('/')) {
basePath += '/'
}
return basePath + 'impersonate/'
}
_renderImpersonateButtons() {
const userTableActionButtons = Array.from(this._root.querySelectorAll('.neos-table .neos-action'))
userTableActionButtons.forEach(_actionContainer => {
Expand Down Expand Up @@ -61,14 +77,14 @@ export default class UserManagement {
const response = this._apiService.callUserChange(identifier);
response
.then((data) => {
const {user, status} = data
const {user} = data
const username = isNil(user) ? '' : user.accountIdentifier
const message = window.NeosCMS.I18n.translate('impersonate.success.impersonateUser', 'Switched to the new user {0}.', 'Neos.Neos', 'Main', {0: username})
window.NeosCMS.Notification.ok(message)

// load default backend, so we don't need to care for the module permissions.
// because in not every neos version the users have by default the content module or user module
window.location.pathname = '/neos'
window.location.href = this._baseModuleUri
})
.catch(function (error) {
if (window.NeosCMS) {
Expand Down

0 comments on commit 4b137ed

Please sign in to comment.