diff --git a/apps/user_ldap/css/renewPassword.css b/apps/user_ldap/css/renewPassword.css
deleted file mode 100644
index 8acd97254fa..00000000000
--- a/apps/user_ldap/css/renewPassword.css
+++ /dev/null
@@ -1,148 +0,0 @@
-/**
- * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
- * SPDX-License-Identifier: AGPL-3.0-or-later
- */
-#personal-show + label {
- inset-inline-start: 230px !important;
- margin-top: 8px !important;
- box-sizing: border-box;
-}
-
-#renewpassword .strengthify-wrapper {
- inset-inline-start: 10px;
- margin-top: 65px;
- position: absolute;
- width: 219px;
-}
-
-#cancel-container p.info {
- margin-top: 10px;
- text-align: center;
-}
-
-#renewpassword .title {
- background-color: transparent;
-}
-
-.tooltip {
- position:absolute;
- display:block;
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol';
- font-style:normal;
- font-weight:400;
- letter-spacing:normal;
- line-break:auto;
- line-height:1.6;
- text-align:start;
- text-decoration:none;
- text-shadow:none;
- text-transform:none;
- white-space:normal;
- word-break:normal;
- word-spacing:normal;
- word-wrap:normal;
- font-size:12px;
- opacity:0;
- z-index:100000;
- filter:drop-shadow(0 1px 10px rgba(77, 77, 77, 0.75));
-}
-
-.tooltip.in {
- opacity:1
-}
-
-.tooltip.top {
- margin-top:-3px;
- padding:10px 0
-}
-
-.tooltip.bottom {
- margin-top:3px;
- padding:10px 0
-}
-
-.tooltip.right {
- margin-inline-start:3px;
- padding:0 10px
-}
-
-.tooltip.right .tooltip-arrow {
- top:50%;
- inset-inline-start:0;
- margin-top:-10px;
- border-width:10px 10px 10px 0;
- border-inline-end-color:#fff
-}
-
-.tooltip.left {
- margin-inline-start:-3px;
- padding:0 5px
-}
-
-.tooltip.left .tooltip-arrow {
- top:50%;
- inset-inline-end:0;
- margin-top:-10px;
- border-width:10px 0 10px 10px;
- border-inline-start-color:#fff
-}
-
-.tooltip.top .tooltip-arrow,.tooltip.top-left .tooltip-arrow,.tooltip.top-right .tooltip-arrow {
- bottom:0;
- border-width:10px 10px 0;
- border-top-color:#fff
-}
-
-.tooltip.top .tooltip-arrow {
- inset-inline-start:50%;
- margin-inline-start:-10px
-}
-
-.tooltip.top-left .tooltip-arrow {
- inset-inline-end:10px;
- margin-bottom:-10px
-}
-
-.tooltip.top-right .tooltip-arrow {
- inset-inline-start:10px;
- margin-bottom:-10px
-}
-
-.tooltip.bottom .tooltip-arrow,.tooltip.bottom-left .tooltip-arrow,.tooltip.bottom-right .tooltip-arrow {
- top:0;
- border-width:0 10px 10px;
- border-bottom-color:#fff
-}
-
-.tooltip.bottom .tooltip-arrow {
- inset-inline-start:50%;
- margin-inline-start:-10px
-}
-
-.tooltip.bottom-left .tooltip-arrow {
- inset-inline-end:10px;
- margin-top:-10px
-}
-
-.tooltip.bottom-right .tooltip-arrow {
- inset-inline-start:10px;
- margin-top:-10px
-}
-
-.tooltip-inner {
- max-width:350px;
- padding:5px 8px !important;
- background-color:#fff;
- color:#000 !important;
- text-align:center !important;
- font-weight:normal !important;
- border-radius:3px
-}
-
-.tooltip-arrow {
- position:absolute;
- width:0;
- height:0;
- border-color:transparent;
- border-style:solid
-}
diff --git a/apps/user_ldap/css/vendor/ui-multiselect/jquery.multiselect.css b/apps/user_ldap/css/vendor/ui-multiselect/jquery.multiselect.css
deleted file mode 100644
index 533eb63762f..00000000000
--- a/apps/user_ldap/css/vendor/ui-multiselect/jquery.multiselect.css
+++ /dev/null
@@ -1,27 +0,0 @@
-/**
- * SPDX-FileCopyrightText: 2012 Eric Hynds
- * SPDX-License-Identifier: MIT
- */
-.ui-multiselect { padding:2px 0 2px 4px; text-align:left; }
-.ui-multiselect span.ui-icon { float:right; }
-.ui-multiselect-single .ui-multiselect-checkboxes input { position:absolute !important; top: auto !important; left:-9999px; }
-.ui-multiselect-single .ui-multiselect-checkboxes label { padding:5px !important; }
-
-.ui-multiselect-header { margin-bottom:3px; padding:3px 0 3px 4px; }
-.ui-multiselect-header ul { font-size:14px; }
-.ui-multiselect-header ul li { float:left; padding:0 10px 0 0; }
-.ui-multiselect-header a { text-decoration:none; }
-.ui-multiselect-header a:hover { text-decoration:underline; }
-.ui-multiselect-header span.ui-icon { float:left;}
-.ui-multiselect-header li.ui-multiselect-close { float:right; text-align:right; padding-right:0; }
-
-.ui-multiselect-menu { display:none; padding:3px; position:absolute; z-index:10000; text-align: left; }
-.ui-multiselect-checkboxes { position:relative /* fixes bug in IE6/7 */; overflow-y:scroll; }
-.ui-multiselect-checkboxes label { cursor:default; display:block; border:1px solid transparent; padding:3px 1px; }
-.ui-multiselect-checkboxes label input { position:relative; top:1px; }
-.ui-multiselect-checkboxes li { clear:both; font-size:14px; padding-right:3px; }
-.ui-multiselect-checkboxes li.ui-multiselect-optgroup-label { text-align:center; font-weight:bold; border-bottom:1px solid; }
-.ui-multiselect-checkboxes li.ui-multiselect-optgroup-label a { display:block; padding:3px; margin:1px 0; text-decoration:none; }
-
-/* remove label borders in IE6 because IE6 does not support transparency */
-* html .ui-multiselect-checkboxes label { border:none; }
diff --git a/apps/user_ldap/js/renewPassword.js b/apps/user_ldap/js/renewPassword.js
deleted file mode 100644
index 2db9b8e7cd2..00000000000
--- a/apps/user_ldap/js/renewPassword.js
+++ /dev/null
@@ -1,35 +0,0 @@
-/**
- * SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors
- * SPDX-License-Identifier: AGPL-3.0-or-later
- */
-
-OCA = OCA || {}
-OCA.LDAP = _.extend(OC.LDAP || {}, {
- onRenewPassword: function() {
- $('#submit')
- .removeClass('icon-confirm-white')
- .addClass('icon-loading-small')
- .attr('value', t('core', 'Renewing …'))
- return true
- },
-})
-
-window.addEventListener('DOMContentLoaded', function() {
- $('form[name=renewpassword]').submit(OCA.LDAP.onRenewPassword)
-
- if ($('#newPassword').length) {
- $('#newPassword').showPassword().keyup()
- }
- $('#newPassword').strengthify({
- zxcvbn: OC.linkTo('core', 'vendor/zxcvbn/dist/zxcvbn.js'),
- titles: [
- t('core', 'Very weak password'),
- t('core', 'Weak password'),
- t('core', 'So-so password'),
- t('core', 'Good password'),
- t('core', 'Strong password'),
- ],
- drawTitles: true,
- $addAfter: $('input[name="newPassword-clone"]'),
- })
-})
diff --git a/apps/user_ldap/js/vendor/ui-multiselect/src/jquery.multiselect.js b/apps/user_ldap/js/vendor/ui-multiselect/src/jquery.multiselect.js
deleted file mode 100644
index 844e257ca29..00000000000
--- a/apps/user_ldap/js/vendor/ui-multiselect/src/jquery.multiselect.js
+++ /dev/null
@@ -1,707 +0,0 @@
-/* jshint forin:true, noarg:true, noempty:true, eqeqeq:true, boss:true, undef:true, curly:true, browser:true, jquery:true */
-/*
- * jQuery MultiSelect UI Widget 1.13
- * Copyright (c) 2012 Eric Hynds
- *
- * http://www.erichynds.com/jquery/jquery-ui-multiselect-widget/
- *
- * Depends:
- * - jQuery 1.4.2+
- * - jQuery UI 1.8 widget factory
- *
- * Optional:
- * - jQuery UI effects
- * - jQuery UI position utility
- *
- * Dual licensed under the MIT and GPL licenses:
- * http://www.opensource.org/licenses/mit-license.php
- * http://www.gnu.org/licenses/gpl.html
- *
- * SPDX-FileCopyrightText: 2012 Eric Hynds
- * SPDX-License-Identifier: MIT
- */
-(function($, undefined) {
- let multiselectID = 0
-
- $.widget('ech.multiselect', {
-
- // default options
- options: {
- header: true,
- height: 175,
- minWidth: 225,
- classes: '',
- checkAllText: 'Check all',
- uncheckAllText: 'Uncheck all',
- noneSelectedText: 'Select options',
- selectedText: '# selected',
- selectedList: 0,
- show: null,
- hide: null,
- autoOpen: false,
- multiple: true,
- position: {},
- },
-
- _create: function() {
- const el = this.element.hide(),
- o = this.options
-
- this.speed = $.fx.speeds._default // default speed for effects
- this._isOpen = false // assume no
-
- const
- button = (this.button = $(''))
- .addClass('ui-multiselect ui-widget ui-state-default ui-corner-all')
- .addClass(o.classes)
- .attr({ title: el.attr('title'), 'aria-haspopup': true, tabIndex: el.attr('tabIndex') })
- .insertAfter(el),
-
- buttonlabel = (this.buttonlabel = $(''))
- .html(o.noneSelectedText)
- .appendTo(button),
-
- menu = (this.menu = $('
'))
- .addClass('ui-multiselect-menu ui-widget ui-widget-content ui-corner-all')
- .addClass(o.classes)
- .appendTo(document.body),
-
- header = (this.header = $(''))
- .addClass('ui-widget-header ui-corner-all ui-multiselect-header ui-helper-clearfix')
- .appendTo(menu),
-
- headerLinkContainer = (this.headerLinkContainer = $(''))
- .addClass('ui-helper-reset')
- .html(function() {
- if (o.header === true) {
- return '' + o.checkAllText + '' + o.uncheckAllText + ''
- } else if (typeof o.header === 'string') {
- return '' + o.header + ''
- } else {
- return ''
- }
- })
- .append('')
- .appendTo(header),
-
- checkboxContainer = (this.checkboxContainer = $(''))
- .addClass('ui-multiselect-checkboxes ui-helper-reset')
- .appendTo(menu)
-
- // perform event bindings
- this._bindEvents()
-
- // build menu
- this.refresh(true)
-
- // some addl. logic for single selects
- if (!o.multiple) {
- menu.addClass('ui-multiselect-single')
- }
- },
-
- _init: function() {
- if (this.options.header === false) {
- this.header.hide()
- }
- if (!this.options.multiple) {
- this.headerLinkContainer.find('.ui-multiselect-all, .ui-multiselect-none').hide()
- }
- if (this.options.autoOpen) {
- this.open()
- }
- if (this.element.is(':disabled')) {
- this.disable()
- }
- },
-
- refresh: function(init) {
- let el = this.element,
- o = this.options,
- menu = this.menu,
- checkboxContainer = this.checkboxContainer,
- optgroups = [],
- html = '',
- id = el.attr('id') || multiselectID++ // unique ID for the label & option tags
-
- // build items
- el.find('option').each(function(i) {
- let $this = $(this),
- parent = this.parentNode,
- title = this.innerHTML,
- description = this.title,
- value = this.value,
- inputID = 'ui-multiselect-' + (this.id || id + '-option-' + i),
- isDisabled = this.disabled,
- isSelected = this.selected,
- labelClasses = ['ui-corner-all'],
- liClasses = (isDisabled ? 'ui-multiselect-disabled ' : ' ') + this.className,
- optLabel
-
- // is this an optgroup?
- if (parent.tagName === 'OPTGROUP') {
- optLabel = parent.getAttribute('label')
-
- // has this optgroup been added already?
- if ($.inArray(optLabel, optgroups) === -1) {
- html += '' + optLabel + ''
- optgroups.push(optLabel)
- }
- }
-
- if (isDisabled) {
- labelClasses.push('ui-state-disabled')
- }
-
- // browsers automatically select the first option
- // by default with single selects
- if (isSelected && !o.multiple) {
- labelClasses.push('ui-state-active')
- }
-
- html += ''
-
- // create the label
- html += ''
- })
-
- // insert into the DOM
- checkboxContainer.html(html)
-
- // cache some moar useful elements
- this.labels = menu.find('label')
- this.inputs = this.labels.children('input')
-
- // set widths
- this._setButtonWidth()
- this._setMenuWidth()
-
- // remember default value
- this.button[0].defaultValue = this.update()
-
- // broadcast refresh event; useful for widgets
- if (!init) {
- this._trigger('refresh')
- }
- },
-
- // updates the button text. call refresh() to rebuild
- update: function() {
- let o = this.options,
- $inputs = this.inputs,
- $checked = $inputs.filter(':checked'),
- numChecked = $checked.length,
- value
-
- if (numChecked === 0) {
- value = o.noneSelectedText
- } else {
- if ($.isFunction(o.selectedText)) {
- value = o.selectedText.call(this, numChecked, $inputs.length, $checked.get())
- } else if (/\d/.test(o.selectedList) && o.selectedList > 0 && numChecked <= o.selectedList) {
- value = $checked.map(function() { return $(this).next().html() }).get().join(', ')
- } else {
- value = o.selectedText.replace('#', numChecked).replace('#', $inputs.length)
- }
- }
-
- this.buttonlabel.html(value)
- return value
- },
-
- // binds events
- _bindEvents: function() {
- const self = this, button = this.button
-
- /**
- *
- */
- function clickHandler() {
- self[self._isOpen ? 'close' : 'open']()
- return false
- }
-
- // webkit doesn't like it when you click on the span :(
- button
- .find('span')
- .bind('click.multiselect', clickHandler)
-
- // button events
- button.bind({
- click: clickHandler,
- keypress: function(e) {
- switch (e.which) {
- case 27: // esc
- case 38: // up
- case 37: // left
- self.close()
- break
- case 39: // right
- case 40: // down
- self.open()
- break
- }
- },
- mouseenter: function() {
- if (!button.hasClass('ui-state-disabled')) {
- $(this).addClass('ui-state-hover')
- }
- },
- mouseleave: function() {
- $(this).removeClass('ui-state-hover')
- },
- focus: function() {
- if (!button.hasClass('ui-state-disabled')) {
- $(this).addClass('ui-state-focus')
- }
- },
- blur: function() {
- $(this).removeClass('ui-state-focus')
- },
- })
-
- // header links
- this.header
- .delegate('a', 'click.multiselect', function(e) {
- // close link
- if ($(this).hasClass('ui-multiselect-close')) {
- self.close()
-
- // check all / uncheck all
- } else {
- self[$(this).hasClass('ui-multiselect-all') ? 'checkAll' : 'uncheckAll']()
- }
-
- e.preventDefault()
- })
-
- // optgroup label toggle support
- this.menu
- .delegate('li.ui-multiselect-optgroup-label a', 'click.multiselect', function(e) {
- e.preventDefault()
-
- const $this = $(this),
- $inputs = $this.parent().nextUntil('li.ui-multiselect-optgroup-label').find('input:visible:not(:disabled)'),
- nodes = $inputs.get(),
- label = $this.parent().text()
-
- // trigger event and bail if the return is false
- if (self._trigger('beforeoptgrouptoggle', e, { inputs: nodes, label }) === false) {
- return
- }
-
- // toggle inputs
- self._toggleChecked(
- $inputs.filter(':checked').length !== $inputs.length,
- $inputs,
- )
-
- self._trigger('optgrouptoggle', e, {
- inputs: nodes,
- label,
- checked: nodes[0].checked,
- })
- })
- .delegate('label', 'mouseenter.multiselect', function() {
- if (!$(this).hasClass('ui-state-disabled')) {
- self.labels.removeClass('ui-state-hover')
- $(this).addClass('ui-state-hover').find('input').focus()
- }
- })
- .delegate('label', 'keydown.multiselect', function(e) {
- e.preventDefault()
-
- switch (e.which) {
- case 9: // tab
- case 27: // esc
- self.close()
- break
- case 38: // up
- case 40: // down
- case 37: // left
- case 39: // right
- self._traverse(e.which, this)
- break
- case 13: // enter
- $(this).find('input')[0].click()
- break
- }
- })
- .delegate('input[type="checkbox"], input[type="radio"]', 'click.multiselect', function(e) {
- const $this = $(this),
- val = this.value,
- checked = this.checked,
- tags = self.element.find('option')
-
- // bail if this input is disabled or the event is cancelled
- if (this.disabled || self._trigger('click', e, { value: val, text: this.title, checked }) === false) {
- e.preventDefault()
- return
- }
-
- // make sure the input has focus. otherwise, the esc key
- // won't close the menu after clicking an item.
- $this.focus()
-
- // toggle aria state
- $this.attr('aria-selected', checked)
-
- // change state on the original option tags
- tags.each(function() {
- if (this.value === val) {
- this.selected = checked
- } else if (!self.options.multiple) {
- this.selected = false
- }
- })
-
- // some additional single select-specific logic
- if (!self.options.multiple) {
- self.labels.removeClass('ui-state-active')
- $this.closest('label').toggleClass('ui-state-active', checked)
-
- // close menu
- self.close()
- }
-
- // fire change on the select box
- self.element.trigger('change')
-
- // setTimeout is to fix multiselect issue #14 and #47. caused by jQuery issue #3827
- // http://bugs.jquery.com/ticket/3827
- setTimeout($.proxy(self.update, self), 10)
- })
-
- // close each widget when clicking on any other element/anywhere else on the page
- $(document).bind('mousedown.multiselect', function(e) {
- if (self._isOpen && !$.contains(self.menu[0], e.target) && !$.contains(self.button[0], e.target) && e.target !== self.button[0]) {
- self.close()
- }
- })
-
- // deal with form resets. the problem here is that buttons aren't
- // restored to their defaultValue prop on form reset, and the reset
- // handler fires before the form is actually reset. delaying it a bit
- // gives the form inputs time to clear.
- $(this.element[0].form).bind('reset.multiselect', function() {
- setTimeout($.proxy(self.refresh, self), 10)
- })
- },
-
- // set button width
- _setButtonWidth: function() {
- let width = this.element.outerWidth(),
- o = this.options
-
- if (/\d/.test(o.minWidth) && width < o.minWidth) {
- width = o.minWidth
- }
-
- // set widths
- this.button.width(width)
- },
-
- // set menu width
- _setMenuWidth: function() {
- const m = this.menu,
- width = this.button.outerWidth()
- - parseInt(m.css('padding-left'), 10)
- - parseInt(m.css('padding-right'), 10)
- - parseInt(m.css('border-right-width'), 10)
- - parseInt(m.css('border-left-width'), 10)
-
- m.width(width || this.button.outerWidth())
- },
-
- // move up or down within the menu
- _traverse: function(which, start) {
- const $start = $(start),
- moveToLast = which === 38 || which === 37,
-
- // select the first li that isn't an optgroup label / disabled
- $next = $start.parent()[moveToLast ? 'prevAll' : 'nextAll']('li:not(.ui-multiselect-disabled, .ui-multiselect-optgroup-label)')[moveToLast ? 'last' : 'first']()
-
- // if at the first/last element
- if (!$next.length) {
- const $container = this.menu.find('ul').last()
-
- // move to the first/last
- this.menu.find('label')[moveToLast ? 'last' : 'first']().trigger('mouseover')
-
- // set scroll position
- $container.scrollTop(moveToLast ? $container.height() : 0)
- } else {
- $next.find('label').trigger('mouseover')
- }
- },
-
- // This is an internal function to toggle the checked property and
- // other related attributes of a checkbox.
- //
- // The context of this function should be a checkbox; do not proxy it.
- _toggleState: function(prop, flag) {
- return function() {
- if (!this.disabled) {
- this[prop] = flag
- }
-
- if (flag) {
- this.setAttribute('aria-selected', true)
- } else {
- this.removeAttribute('aria-selected')
- }
- }
- },
-
- _toggleChecked: function(flag, group) {
- const $inputs = (group && group.length) ? group : this.inputs,
- self = this
-
- // toggle state on inputs
- $inputs.each(this._toggleState('checked', flag))
-
- // give the first input focus
- $inputs.eq(0).focus()
-
- // update button text
- this.update()
-
- // gather an array of the values that actually changed
- const values = $inputs.map(function() {
- return this.value
- }).get()
-
- // toggle state on original option tags
- this.element
- .find('option')
- .each(function() {
- if (!this.disabled && $.inArray(this.value, values) > -1) {
- self._toggleState('selected', flag).call(this)
- }
- })
-
- // trigger the change event on the select
- if ($inputs.length) {
- this.element.trigger('change')
- }
- },
-
- _toggleDisabled: function(flag) {
- this.button
- .attr({ disabled: flag, 'aria-disabled': flag })[flag ? 'addClass' : 'removeClass']('ui-state-disabled')
-
- let inputs = this.menu.find('input')
- const key = 'ech-multiselect-disabled'
-
- if (flag) {
- // remember which elements this widget disabled (not pre-disabled)
- // elements, so that they can be restored if the widget is re-enabled.
- inputs = inputs.filter(':enabled')
- .data(key, true)
- } else {
- inputs = inputs.filter(function() {
- return $.data(this, key) === true
- }).removeData(key)
- }
-
- inputs
- .attr({ disabled: flag, 'arial-disabled': flag })
- .parent()[flag ? 'addClass' : 'removeClass']('ui-state-disabled')
-
- this.element
- .attr({ disabled: flag, 'aria-disabled': flag })
- },
-
- // open the menu
- open: function(e) {
- let self = this,
- button = this.button,
- menu = this.menu,
- speed = this.speed,
- o = this.options,
- args = []
-
- // bail if the multiselectopen event returns false, this widget is disabled, or is already open
- if (this._trigger('beforeopen') === false || button.hasClass('ui-state-disabled') || this._isOpen) {
- return
- }
-
- let $container = menu.find('ul').last(),
- effect = o.show,
- pos = button.offset()
-
- // figure out opening effects/speeds
- if ($.isArray(o.show)) {
- effect = o.show[0]
- speed = o.show[1] || self.speed
- }
-
- // if there's an effect, assume jQuery UI is in use
- // build the arguments to pass to show()
- if (effect) {
- args = [effect, speed]
- }
-
- // set the scroll of the checkbox container
- $container.scrollTop(0).height(o.height)
-
- // position and show menu
- if ($.ui.position && !$.isEmptyObject(o.position)) {
- o.position.of = o.position.of || button
-
- menu
- .show()
- .position(o.position)
- .hide()
-
- // if position utility is not available...
- } else {
- menu.css({
- top: pos.top + button.outerHeight(),
- 'inset-inline-start': pos.left,
- })
- }
-
- // show the menu, maybe with a speed/effect combo
- $.fn.show.apply(menu, args)
-
- // select the first option
- // triggering both mouseover and mouseover because 1.4.2+ has a bug where triggering mouseover
- // will actually trigger mouseenter. the mouseenter trigger is there for when it's eventually fixed
- this.labels.eq(0).trigger('mouseover').trigger('mouseenter').find('input').trigger('focus')
-
- button.addClass('ui-state-active')
- this._isOpen = true
- this._trigger('open')
- },
-
- // close the menu
- close: function() {
- if (this._trigger('beforeclose') === false) {
- return
- }
-
- let o = this.options,
- effect = o.hide,
- speed = this.speed,
- args = []
-
- // figure out opening effects/speeds
- if ($.isArray(o.hide)) {
- effect = o.hide[0]
- speed = o.hide[1] || this.speed
- }
-
- if (effect) {
- args = [effect, speed]
- }
-
- $.fn.hide.apply(this.menu, args)
- this.button.removeClass('ui-state-active').trigger('blur').trigger('mouseleave')
- this._isOpen = false
- this._trigger('close')
- },
-
- enable: function() {
- this._toggleDisabled(false)
- },
-
- disable: function() {
- this._toggleDisabled(true)
- },
-
- checkAll: function(e) {
- this._toggleChecked(true)
- this._trigger('checkAll')
- },
-
- uncheckAll: function() {
- this._toggleChecked(false)
- this._trigger('uncheckAll')
- },
-
- getChecked: function() {
- return this.menu.find('input').filter(':checked')
- },
-
- destroy: function() {
- // remove classes + data
- $.Widget.prototype.destroy.call(this)
-
- this.button.remove()
- this.menu.remove()
- this.element.show()
-
- return this
- },
-
- isOpen: function() {
- return this._isOpen
- },
-
- widget: function() {
- return this.menu
- },
-
- getButton: function() {
- return this.button
- },
-
- // react to option changes after initialization
- _setOption: function(key, value) {
- const menu = this.menu
-
- switch (key) {
- case 'header':
- menu.find('div.ui-multiselect-header')[value ? 'show' : 'hide']()
- break
- case 'checkAllText':
- menu.find('a.ui-multiselect-all span').eq(-1).text(value)
- break
- case 'uncheckAllText':
- menu.find('a.ui-multiselect-none span').eq(-1).text(value)
- break
- case 'height':
- menu.find('ul').last().height(parseInt(value, 10))
- break
- case 'minWidth':
- this.options[key] = parseInt(value, 10)
- this._setButtonWidth()
- this._setMenuWidth()
- break
- case 'selectedText':
- case 'selectedList':
- case 'noneSelectedText':
- this.options[key] = value // these all needs to update immediately for the update() call
- this.update()
- break
- case 'classes':
- menu.add(this.button).removeClass(this.options.classes).addClass(value)
- break
- case 'multiple':
- menu.toggleClass('ui-multiselect-single', !value)
- this.options.multiple = value
- this.element[0].multiple = value
- this.refresh()
- }
-
- $.Widget.prototype._setOption.apply(this, arguments)
- },
- })
-})(jQuery)
diff --git a/apps/user_ldap/lib/AppInfo/Application.php b/apps/user_ldap/lib/AppInfo/Application.php
index bc55f907732..76462698280 100644
--- a/apps/user_ldap/lib/AppInfo/Application.php
+++ b/apps/user_ldap/lib/AppInfo/Application.php
@@ -30,6 +30,7 @@ use OCP\AppFramework\Bootstrap\IBootstrap;
use OCP\AppFramework\Bootstrap\IRegistrationContext;
use OCP\AppFramework\IAppContainer;
use OCP\AppFramework\Services\IAppConfig;
+use OCP\AppFramework\Services\IInitialState;
use OCP\Config\IUserConfig;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\IAvatarManager;
@@ -67,6 +68,7 @@ class Application extends App implements IBootstrap {
$appContainer->get(IL10N::class),
$appContainer->get('Session'),
$appContainer->get(IURLGenerator::class),
+ $appContainer->get(IInitialState::class),
);
});
diff --git a/apps/user_ldap/lib/Controller/RenewPasswordController.php b/apps/user_ldap/lib/Controller/RenewPasswordController.php
index 04b919eeb67..d3e89a12d56 100644
--- a/apps/user_ldap/lib/Controller/RenewPasswordController.php
+++ b/apps/user_ldap/lib/Controller/RenewPasswordController.php
@@ -6,6 +6,7 @@
*/
namespace OCA\User_LDAP\Controller;
+use OCA\User_LDAP\AppInfo\Application;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http\Attribute\NoCSRFRequired;
use OCP\AppFramework\Http\Attribute\OpenAPI;
@@ -13,6 +14,7 @@ use OCP\AppFramework\Http\Attribute\PublicPage;
use OCP\AppFramework\Http\Attribute\UseSession;
use OCP\AppFramework\Http\RedirectResponse;
use OCP\AppFramework\Http\TemplateResponse;
+use OCP\AppFramework\Services\IInitialState;
use OCP\Config\IUserConfig;
use OCP\HintException;
use OCP\IConfig;
@@ -20,8 +22,8 @@ use OCP\IL10N;
use OCP\IRequest;
use OCP\ISession;
use OCP\IURLGenerator;
-use OCP\IUser;
use OCP\IUserManager;
+use OCP\Util;
#[OpenAPI(scope: OpenAPI::SCOPE_IGNORE)]
class RenewPasswordController extends Controller {
@@ -34,6 +36,7 @@ class RenewPasswordController extends Controller {
protected IL10N $l10n,
private ISession $session,
private IURLGenerator $urlGenerator,
+ private IInitialState $initialState,
) {
parent::__construct($appName, $request);
}
@@ -51,7 +54,7 @@ class RenewPasswordController extends Controller {
if (!$this->userConfig->getValueBool($user, 'user_ldap', 'needsPasswordReset')) {
return new RedirectResponse($this->urlGenerator->linkToRouteAbsolute('core.login.showLoginForm'));
}
- $parameters = [];
+
$renewPasswordMessages = $this->session->get('renewPasswordMessages');
$errors = [];
$messages = [];
@@ -59,25 +62,23 @@ class RenewPasswordController extends Controller {
[$errors, $messages] = $renewPasswordMessages;
}
$this->session->remove('renewPasswordMessages');
- foreach ($errors as $value) {
- $parameters[$value] = true;
- }
- $parameters['messages'] = $messages;
- $parameters['user'] = $user;
-
- $parameters['canResetPassword'] = true;
- $parameters['resetPasswordLink'] = $this->config->getSystemValue('lost_password_link', '');
- if (!$parameters['resetPasswordLink']) {
- $userObj = $this->userManager->get($user);
- if ($userObj instanceof IUser) {
- $parameters['canResetPassword'] = $userObj->canChangePassword();
- }
- }
- $parameters['cancelLink'] = $this->urlGenerator->linkToRouteAbsolute('core.login.showLoginForm');
+ $this->initialState->provideInitialState('renewPasswordParameters',
+ [
+ 'user' => $user,
+ 'errors' => $errors,
+ 'messages' => $messages,
+ 'cancelRenewUrl' => $this->urlGenerator->linkToRouteAbsolute('core.login.showLoginForm'),
+ 'tryRenewPasswordUrl' => $this->urlGenerator->linkToRouteAbsolute('user_ldap.renewPassword.tryRenewPassword'),
+ ],
+ );
+ Util::addStyle(Application::APP_ID, 'renewPassword');
+ Util::addScript(Application::APP_ID, 'renewPassword');
return new TemplateResponse(
- $this->appName, 'renewpassword', $parameters, 'guest'
+ Application::APP_ID,
+ 'renewpassword',
+ renderAs: 'guest',
);
}
diff --git a/apps/user_ldap/src/LDAPSettingsApp.vue b/apps/user_ldap/src/LDAPSettingsApp.vue
deleted file mode 100644
index d2daeb62de6..00000000000
--- a/apps/user_ldap/src/LDAPSettingsApp.vue
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
diff --git a/apps/user_ldap/src/renewPassword.ts b/apps/user_ldap/src/renewPassword.ts
new file mode 100644
index 00000000000..f9429229a34
--- /dev/null
+++ b/apps/user_ldap/src/renewPassword.ts
@@ -0,0 +1,10 @@
+/**
+ * SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+import { createApp } from 'vue'
+import RenewPasswordView from './views/RenewPassword.vue'
+
+const app = createApp(RenewPasswordView)
+app.mount('#user_ldap-renewPassword')
diff --git a/apps/user_ldap/src/settings-admin.ts b/apps/user_ldap/src/settings-admin.ts
index f7c25e2344a..50a496a571a 100644
--- a/apps/user_ldap/src/settings-admin.ts
+++ b/apps/user_ldap/src/settings-admin.ts
@@ -2,8 +2,9 @@
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
+
import { createApp } from 'vue'
-import LDAPSettingsApp from './LDAPSettingsApp.vue'
+import LDAPSettingsApp from './views/LDAPSettingsApp.vue'
import { pinia } from './store/index.ts'
const app = createApp(LDAPSettingsApp)
diff --git a/apps/user_ldap/src/views/Settings.vue b/apps/user_ldap/src/views/LDAPSettingsApp.vue
similarity index 98%
rename from apps/user_ldap/src/views/Settings.vue
rename to apps/user_ldap/src/views/LDAPSettingsApp.vue
index f913a2e9c85..4d1a0ab1810 100644
--- a/apps/user_ldap/src/views/Settings.vue
+++ b/apps/user_ldap/src/views/LDAPSettingsApp.vue
@@ -87,8 +87,6 @@
+
+
+
+ {{ t('user_ldap', 'Please renew your password') }}
+
+
+ {{ message }}
+
+
+
+
+
+
+
+
+
diff --git a/apps/user_ldap/templates/renewpassword.php b/apps/user_ldap/templates/renewpassword.php
index 3345be29c13..91821896add 100644
--- a/apps/user_ldap/templates/renewpassword.php
+++ b/apps/user_ldap/templates/renewpassword.php
@@ -1,66 +1,9 @@
-
+
diff --git a/build/frontend/vite.config.ts b/build/frontend/vite.config.ts
index 1e416b234bc..086f3c748ea 100644
--- a/build/frontend/vite.config.ts
+++ b/build/frontend/vite.config.ts
@@ -46,6 +46,7 @@ const modules = {
'settings-personal': resolve(import.meta.dirname, 'apps/twofactor_backupcodes/src', 'settings-personal.ts'),
},
user_ldap: {
+ renewPassword: resolve(import.meta.dirname, 'apps/user_ldap/src', 'renewPassword.ts'),
'settings-admin': resolve(import.meta.dirname, 'apps/user_ldap/src', 'settings-admin.ts'),
},
user_status: {