diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php
index b46174a23d807..8820d628e080a 100644
--- a/lib/composer/composer/autoload_classmap.php
+++ b/lib/composer/composer/autoload_classmap.php
@@ -1559,6 +1559,7 @@
'OC\\User\\Database' => $baseDir . '/lib/private/User/Database.php',
'OC\\User\\DisplayNameCache' => $baseDir . '/lib/private/User/DisplayNameCache.php',
'OC\\User\\LazyUser' => $baseDir . '/lib/private/User/LazyUser.php',
+ 'OC\\User\\Listeners\\BeforeUserDeletedListener' => $baseDir . '/lib/private/User/Listeners/BeforeUserDeletedListener.php',
'OC\\User\\LoginException' => $baseDir . '/lib/private/User/LoginException.php',
'OC\\User\\Manager' => $baseDir . '/lib/private/User/Manager.php',
'OC\\User\\NoUserException' => $baseDir . '/lib/private/User/NoUserException.php',
diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php
index 2324a9c8ef55e..419394e38b13e 100644
--- a/lib/composer/composer/autoload_static.php
+++ b/lib/composer/composer/autoload_static.php
@@ -1588,6 +1588,7 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c
'OC\\User\\Database' => __DIR__ . '/../../..' . '/lib/private/User/Database.php',
'OC\\User\\DisplayNameCache' => __DIR__ . '/../../..' . '/lib/private/User/DisplayNameCache.php',
'OC\\User\\LazyUser' => __DIR__ . '/../../..' . '/lib/private/User/LazyUser.php',
+ 'OC\\User\\Listeners\\BeforeUserDeletedListener' => __DIR__ . '/../../..' . '/lib/private/User/Listeners/BeforeUserDeletedListener.php',
'OC\\User\\LoginException' => __DIR__ . '/../../..' . '/lib/private/User/LoginException.php',
'OC\\User\\Manager' => __DIR__ . '/../../..' . '/lib/private/User/Manager.php',
'OC\\User\\NoUserException' => __DIR__ . '/../../..' . '/lib/private/User/NoUserException.php',
diff --git a/lib/private/Server.php b/lib/private/Server.php
index a273f56ffff2a..d82e12f288349 100644
--- a/lib/private/Server.php
+++ b/lib/private/Server.php
@@ -151,6 +151,7 @@
use OC\Tagging\TagMapper;
use OC\Talk\Broker;
use OC\Template\JSCombiner;
+use OC\User\Listeners\BeforeUserDeletedListener;
use OCA\Theming\ImageManager;
use OCA\Theming\ThemingDefaults;
use OCA\Theming\Util;
@@ -244,6 +245,7 @@
use OCP\SystemTag\ISystemTagObjectMapper;
use OCP\Talk\IBroker;
use OCP\User\Events\BeforePasswordUpdatedEvent;
+use OCP\User\Events\BeforeUserDeletedEvent;
use OCP\User\Events\BeforeUserLoggedInEvent;
use OCP\User\Events\BeforeUserLoggedInWithCookieEvent;
use OCP\User\Events\BeforeUserLoggedOutEvent;
@@ -1522,6 +1524,7 @@ private function connectDispatcher() {
$eventDispatched = $this->get(IEventDispatcher::class);
$eventDispatched->addServiceListener(LoginFailed::class, LoginFailedListener::class);
$eventDispatched->addServiceListener(PostLoginEvent::class, UserLoggedInListener::class);
+ $eventDispatched->addServiceListener(BeforeUserDeletedEvent::class, BeforeUserDeletedListener::class);
}
/**
diff --git a/lib/private/User/Listeners/BeforeUserDeletedListener.php b/lib/private/User/Listeners/BeforeUserDeletedListener.php
new file mode 100644
index 0000000000000..7fafe697dae95
--- /dev/null
+++ b/lib/private/User/Listeners/BeforeUserDeletedListener.php
@@ -0,0 +1,53 @@
+
+ *
+ * @license AGPL-3.0-or-later
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ *
+ */
+namespace OC\User\Listeners;
+
+use OCP\EventDispatcher\Event;
+use OCP\EventDispatcher\IEventListener;
+use OCP\Security\ICredentialsManager;
+use OCP\User\Events\BeforeUserDeletedEvent;
+use Psr\Log\LoggerInterface;
+
+/**
+ * @template-implements IEventListener
+ */
+class BeforeUserDeletedListener implements IEventListener {
+ private ICredentialsManager $credentialsManager;
+ private LoggerInterface $logger;
+
+ public function __construct(LoggerInterface $logger, ICredentialsManager $credentialsManager) {
+ $this->credentialsManager = $credentialsManager;
+ $this->logger = $logger;
+ }
+
+ public function handle(Event $event): void {
+ if (!($event instanceof BeforeUserDeletedEvent)) {
+ return;
+ }
+
+ $user = $event->getUser();
+ // Delete storages credentials on user deletion
+ $this->credentialsManager->erase($user->getUID());
+ }
+}