diff --git a/core/Application.php b/core/Application.php
index 967e3a62c1ed4687c2e5e182bdc10ca2ed2e0699..97ebae774ddad17346eec0e058d60fc582be00d5 100644
--- a/core/Application.php
+++ b/core/Application.php
@@ -28,12 +28,18 @@
 
 namespace OC\Core;
 
+use OC\Authentication\Events\RemoteWipeFinished;
+use OC\Authentication\Events\RemoteWipeStarted;
+use OC\Authentication\Listeners\RemoteWipeActivityListener;
+use OC\Authentication\Listeners\RemoteWipeNotificationsListener;
 use OC\Authentication\Notifications\Notifier as AuthenticationNotifier;
 use OC\Core\Notification\RemoveLinkSharesNotifier;
 use OC\DB\MissingIndexInformation;
 use OC\DB\SchemaWrapper;
 use OCP\AppFramework\App;
+use OCP\EventDispatcher\IEventDispatcher;
 use OCP\IDBConnection;
+use OCP\IServerContainer;
 use OCP\Util;
 use Symfony\Component\EventDispatcher\GenericEvent;
 
@@ -54,7 +60,8 @@ class Application extends App {
 		});
 
 		$server = $container->getServer();
-		$eventDispatcher = $server->getEventDispatcher();
+		/** @var IEventDispatcher $eventDispatcher */
+		$eventDispatcher = $server->query(IEventDispatcher::class);
 
 		$notificationManager = $server->getNotificationManager();
 		$notificationManager->registerNotifier(function() use ($server) {
@@ -155,5 +162,10 @@ class Application extends App {
 				}
 			}
 		);
+
+		$eventDispatcher->addServiceListener(RemoteWipeStarted::class, RemoteWipeActivityListener::class);
+		$eventDispatcher->addServiceListener(RemoteWipeStarted::class, RemoteWipeNotificationsListener::class);
+		$eventDispatcher->addServiceListener(RemoteWipeFinished::class, RemoteWipeActivityListener::class);
+		$eventDispatcher->addServiceListener(RemoteWipeFinished::class, RemoteWipeNotificationsListener::class);
 	}
 }
diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php
index 439d4c819d15a1b1ded0e51dced9c6dc8a7b736b..80c03a6e63a2676a8416399631e6f6ae46670c74 100644
--- a/lib/composer/composer/autoload_classmap.php
+++ b/lib/composer/composer/autoload_classmap.php
@@ -509,6 +509,9 @@ return array(
     'OC\\Archive\\Archive' => $baseDir . '/lib/private/Archive/Archive.php',
     'OC\\Archive\\TAR' => $baseDir . '/lib/private/Archive/TAR.php',
     'OC\\Archive\\ZIP' => $baseDir . '/lib/private/Archive/ZIP.php',
+    'OC\\Authentication\\Events\\ARemoteWipeEvent' => $baseDir . '/lib/private/Authentication/Events/ARemoteWipeEvent.php',
+    'OC\\Authentication\\Events\\RemoteWipeFinished' => $baseDir . '/lib/private/Authentication/Events/RemoteWipeFinished.php',
+    'OC\\Authentication\\Events\\RemoteWipeStarted' => $baseDir . '/lib/private/Authentication/Events/RemoteWipeStarted.php',
     'OC\\Authentication\\Exceptions\\ExpiredTokenException' => $baseDir . '/lib/private/Authentication/Exceptions/ExpiredTokenException.php',
     'OC\\Authentication\\Exceptions\\InvalidProviderException' => $baseDir . '/lib/private/Authentication/Exceptions/InvalidProviderException.php',
     'OC\\Authentication\\Exceptions\\InvalidTokenException' => $baseDir . '/lib/private/Authentication/Exceptions/InvalidTokenException.php',
@@ -518,6 +521,8 @@ return array(
     'OC\\Authentication\\Exceptions\\TwoFactorAuthRequiredException' => $baseDir . '/lib/private/Authentication/Exceptions/TwoFactorAuthRequiredException.php',
     'OC\\Authentication\\Exceptions\\UserAlreadyLoggedInException' => $baseDir . '/lib/private/Authentication/Exceptions/UserAlreadyLoggedInException.php',
     'OC\\Authentication\\Exceptions\\WipeTokenException' => $baseDir . '/lib/private/Authentication/Exceptions/WipeTokenException.php',
+    'OC\\Authentication\\Listeners\\RemoteWipeActivityListener' => $baseDir . '/lib/private/Authentication/Listeners/RemoteWipeActivityListener.php',
+    'OC\\Authentication\\Listeners\\RemoteWipeNotificationsListener' => $baseDir . '/lib/private/Authentication/Listeners/RemoteWipeNotificationsListener.php',
     'OC\\Authentication\\LoginCredentials\\Credentials' => $baseDir . '/lib/private/Authentication/LoginCredentials/Credentials.php',
     'OC\\Authentication\\LoginCredentials\\Store' => $baseDir . '/lib/private/Authentication/LoginCredentials/Store.php',
     'OC\\Authentication\\Login\\ALoginCommand' => $baseDir . '/lib/private/Authentication/Login/ALoginCommand.php',
diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php
index 7cfca806c067f55ceccf2bf0b32c5e7e70dfad57..0eaa457464c14418e310c5432856b710d1606a66 100644
--- a/lib/composer/composer/autoload_static.php
+++ b/lib/composer/composer/autoload_static.php
@@ -543,6 +543,9 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c
         'OC\\Archive\\Archive' => __DIR__ . '/../../..' . '/lib/private/Archive/Archive.php',
         'OC\\Archive\\TAR' => __DIR__ . '/../../..' . '/lib/private/Archive/TAR.php',
         'OC\\Archive\\ZIP' => __DIR__ . '/../../..' . '/lib/private/Archive/ZIP.php',
+        'OC\\Authentication\\Events\\ARemoteWipeEvent' => __DIR__ . '/../../..' . '/lib/private/Authentication/Events/ARemoteWipeEvent.php',
+        'OC\\Authentication\\Events\\RemoteWipeFinished' => __DIR__ . '/../../..' . '/lib/private/Authentication/Events/RemoteWipeFinished.php',
+        'OC\\Authentication\\Events\\RemoteWipeStarted' => __DIR__ . '/../../..' . '/lib/private/Authentication/Events/RemoteWipeStarted.php',
         'OC\\Authentication\\Exceptions\\ExpiredTokenException' => __DIR__ . '/../../..' . '/lib/private/Authentication/Exceptions/ExpiredTokenException.php',
         'OC\\Authentication\\Exceptions\\InvalidProviderException' => __DIR__ . '/../../..' . '/lib/private/Authentication/Exceptions/InvalidProviderException.php',
         'OC\\Authentication\\Exceptions\\InvalidTokenException' => __DIR__ . '/../../..' . '/lib/private/Authentication/Exceptions/InvalidTokenException.php',
@@ -552,6 +555,8 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c
         'OC\\Authentication\\Exceptions\\TwoFactorAuthRequiredException' => __DIR__ . '/../../..' . '/lib/private/Authentication/Exceptions/TwoFactorAuthRequiredException.php',
         'OC\\Authentication\\Exceptions\\UserAlreadyLoggedInException' => __DIR__ . '/../../..' . '/lib/private/Authentication/Exceptions/UserAlreadyLoggedInException.php',
         'OC\\Authentication\\Exceptions\\WipeTokenException' => __DIR__ . '/../../..' . '/lib/private/Authentication/Exceptions/WipeTokenException.php',
+        'OC\\Authentication\\Listeners\\RemoteWipeActivityListener' => __DIR__ . '/../../..' . '/lib/private/Authentication/Listeners/RemoteWipeActivityListener.php',
+        'OC\\Authentication\\Listeners\\RemoteWipeNotificationsListener' => __DIR__ . '/../../..' . '/lib/private/Authentication/Listeners/RemoteWipeNotificationsListener.php',
         'OC\\Authentication\\LoginCredentials\\Credentials' => __DIR__ . '/../../..' . '/lib/private/Authentication/LoginCredentials/Credentials.php',
         'OC\\Authentication\\LoginCredentials\\Store' => __DIR__ . '/../../..' . '/lib/private/Authentication/LoginCredentials/Store.php',
         'OC\\Authentication\\Login\\ALoginCommand' => __DIR__ . '/../../..' . '/lib/private/Authentication/Login/ALoginCommand.php',
diff --git a/lib/private/Authentication/Events/ARemoteWipeEvent.php b/lib/private/Authentication/Events/ARemoteWipeEvent.php
new file mode 100644
index 0000000000000000000000000000000000000000..f6c088821431464aa43a383fa0420281c7e94027
--- /dev/null
+++ b/lib/private/Authentication/Events/ARemoteWipeEvent.php
@@ -0,0 +1,46 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * @copyright 2019 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @author 2019 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+namespace OC\Authentication\Events;
+
+use OC\Authentication\Token\IToken;
+use OCP\EventDispatcher\Event;
+use Symfony\Component\EventDispatcher\GenericEvent;
+
+abstract class ARemoteWipeEvent extends Event {
+
+	/** @var IToken */
+	private $token;
+
+	public function __construct(IToken $token) {
+		parent::__construct();
+		$this->token = $token;
+	}
+
+	public function getToken(): IToken {
+		return $this->token;
+	}
+
+}
diff --git a/lib/private/Authentication/Events/RemoteWipeFinished.php b/lib/private/Authentication/Events/RemoteWipeFinished.php
new file mode 100644
index 0000000000000000000000000000000000000000..79f6dcbffbe6202eea4d3fdd9aa2d454a13c5a81
--- /dev/null
+++ b/lib/private/Authentication/Events/RemoteWipeFinished.php
@@ -0,0 +1,30 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * @copyright 2019 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @author 2019 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+namespace OC\Authentication\Events;
+
+class RemoteWipeFinished extends ARemoteWipeEvent {
+
+}
diff --git a/lib/private/Authentication/Events/RemoteWipeStarted.php b/lib/private/Authentication/Events/RemoteWipeStarted.php
new file mode 100644
index 0000000000000000000000000000000000000000..f3c0b6287953f3109a13a624bc240e753fec6b73
--- /dev/null
+++ b/lib/private/Authentication/Events/RemoteWipeStarted.php
@@ -0,0 +1,30 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * @copyright 2019 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @author 2019 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+namespace OC\Authentication\Events;
+
+class RemoteWipeStarted extends ARemoteWipeEvent {
+
+}
diff --git a/lib/private/Authentication/Listeners/RemoteWipeActivityListener.php b/lib/private/Authentication/Listeners/RemoteWipeActivityListener.php
new file mode 100644
index 0000000000000000000000000000000000000000..c8cd92d2102048c1c7537c0ba3ad648b128ce5da
--- /dev/null
+++ b/lib/private/Authentication/Listeners/RemoteWipeActivityListener.php
@@ -0,0 +1,80 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * @copyright 2019 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @author 2019 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+namespace OC\Authentication\Listeners;
+
+use BadMethodCallException;
+use OC\Authentication\Events\ARemoteWipeEvent;
+use OC\Authentication\Events\RemoteWipeFinished;
+use OC\Authentication\Events\RemoteWipeStarted;
+use OC\Authentication\Token\IToken;
+use OCP\Activity\IManager as IActvityManager;
+use OCP\EventDispatcher\Event;
+use OCP\EventDispatcher\IEventListener;
+use OCP\ILogger;
+
+class RemoteWipeActivityListener implements IEventListener {
+
+	/** @var IActvityManager */
+	private $activityManager;
+
+	/** @var ILogger */
+	private $logger;
+
+	public function __construct(IActvityManager $activityManager,
+								ILogger $logger) {
+		$this->activityManager = $activityManager;
+		$this->logger = $logger;
+	}
+
+	public function handle(Event $event): void {
+		if ($event instanceof RemoteWipeStarted) {
+			$this->publishActivity('remote_wipe_start', $event->getToken());
+		} else if ($event instanceof RemoteWipeFinished) {
+			$this->publishActivity('remote_wipe_finish', $event->getToken());
+		}
+	}
+
+	private function publishActivity(string $event, IToken $token): void {
+		$activity = $this->activityManager->generateEvent();
+		$activity->setApp('core')
+			->setType('security')
+			->setAuthor($token->getUID())
+			->setAffectedUser($token->getUID())
+			->setSubject($event, [
+				'name' => $token->getName(),
+			]);
+		try {
+			$this->activityManager->publish($activity);
+		} catch (BadMethodCallException $e) {
+			$this->logger->logException($e, [
+				'app' => 'core',
+				'level' => ILogger::WARN,
+				'message' => 'could not publish activity',
+			]);
+		}
+	}
+
+}
diff --git a/lib/private/Authentication/Listeners/RemoteWipeNotificationsListener.php b/lib/private/Authentication/Listeners/RemoteWipeNotificationsListener.php
new file mode 100644
index 0000000000000000000000000000000000000000..ffddddff1d80220644578ee0e6d618dfe1e7c622
--- /dev/null
+++ b/lib/private/Authentication/Listeners/RemoteWipeNotificationsListener.php
@@ -0,0 +1,71 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * @copyright 2019 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @author 2019 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+namespace OC\Authentication\Listeners;
+
+use OC\Authentication\Events\ARemoteWipeEvent;
+use OC\Authentication\Events\RemoteWipeFinished;
+use OC\Authentication\Events\RemoteWipeStarted;
+use OC\Authentication\Token\IToken;
+use OCP\AppFramework\Utility\ITimeFactory;
+use OCP\EventDispatcher\Event;
+use OCP\EventDispatcher\IEventListener;
+use OCP\Notification\IManager as INotificationManager;
+
+class RemoteWipeNotificationsListener implements IEventListener {
+
+	/** @var INotificationManager */
+	private $notificationManager;
+
+	/** @var ITimeFactory */
+	private $timeFactory;
+
+	public function __construct(INotificationManager $notificationManager,
+								ITimeFactory $timeFactory) {
+		$this->notificationManager = $notificationManager;
+		$this->timeFactory = $timeFactory;
+	}
+
+	public function handle(Event $event): void {
+		if ($event instanceof RemoteWipeStarted) {
+			$this->sendNotification('remote_wipe_start', $event->getToken());
+		} else if ($event instanceof RemoteWipeFinished) {
+			$this->sendNotification('remote_wipe_finish', $event->getToken());
+		}
+	}
+
+	private function sendNotification(string $event, IToken $token): void {
+		$notification = $this->notificationManager->createNotification();
+		$notification->setApp('auth')
+			->setUser($token->getUID())
+			->setDateTime($this->timeFactory->getDateTime())
+			->setObject('token', $token->getId())
+			->setSubject($event, [
+				'name' => $token->getName(),
+			]);
+		$this->notificationManager->notify($notification);
+	}
+
+}
diff --git a/lib/private/Authentication/Token/RemoteWipe.php b/lib/private/Authentication/Token/RemoteWipe.php
index 6091d30fc2507d4ef1e124bc339cde6c5ac43364..5534ff1cba186c275a1038f6532dccaa8a8237ad 100644
--- a/lib/private/Authentication/Token/RemoteWipe.php
+++ b/lib/private/Authentication/Token/RemoteWipe.php
@@ -26,39 +26,34 @@ declare(strict_types=1);
 namespace OC\Authentication\Token;
 
 use BadMethodCallException;
+use OC\Authentication\Events\RemoteWipeFinished;
+use OC\Authentication\Events\RemoteWipeStarted;
 use OC\Authentication\Exceptions\InvalidTokenException;
 use OC\Authentication\Exceptions\WipeTokenException;
+use OCP\Activity\IEvent;
 use OCP\Activity\IManager as IActivityManager;
 use OCP\AppFramework\Utility\ITimeFactory;
+use OCP\EventDispatcher\IEventDispatcher;
 use OCP\ILogger;
 use OCP\Notification\IManager as INotificationManager;
+use Symfony\Component\EventDispatcher\EventDispatcher;
 
 class RemoteWipe {
 
 	/** @var IProvider */
 	private $tokenProvider;
 
-	/** @var IActivityManager */
-	private $activityManager;
-
-	/** @var INotificationManager */
-	private $notificationManager;
-
-	/** @var ITimeFactory */
-	private $timeFactory;
+	/** @var IEventDispatcher */
+	private $eventDispatcher;
 
 	/** @var ILogger */
 	private $logger;
 
 	public function __construct(IProvider $tokenProvider,
-								IActivityManager $activityManager,
-								INotificationManager $notificationManager,
-								ITimeFactory $timeFactory,
+								IEventDispatcher $eventDispatcher,
 								ILogger $logger) {
 		$this->tokenProvider = $tokenProvider;
-		$this->activityManager = $activityManager;
-		$this->notificationManager = $notificationManager;
-		$this->timeFactory = $timeFactory;
+		$this->eventDispatcher = $eventDispatcher;
 		$this->logger = $logger;
 	}
 
@@ -83,8 +78,8 @@ class RemoteWipe {
 		$dbToken = $e->getToken();
 
 		$this->logger->info("user " . $dbToken->getUID() . " started a remote wipe");
-		$this->sendNotification('remote_wipe_start', $e->getToken());
-		$this->publishActivity('remote_wipe_start', $e->getToken());
+
+		$this->eventDispatcher->dispatch(RemoteWipeStarted::class, new RemoteWipeStarted($dbToken));
 
 		return true;
 	}
@@ -111,39 +106,9 @@ class RemoteWipe {
 		$this->tokenProvider->invalidateToken($token);
 
 		$this->logger->info("user " . $dbToken->getUID() . " finished a remote wipe");
-		$this->sendNotification('remote_wipe_finish', $e->getToken());
-		$this->publishActivity('remote_wipe_finish', $e->getToken());
+		$this->eventDispatcher->dispatch(RemoteWipeFinished::class, new RemoteWipeFinished($dbToken));
 
 		return true;
 	}
 
-	private function publishActivity(string $event, IToken $token): void {
-		$activity = $this->activityManager->generateEvent();
-		$activity->setApp('core')
-			->setType('security')
-			->setAuthor($token->getUID())
-			->setAffectedUser($token->getUID())
-			->setSubject($event, [
-				'name' => $token->getName(),
-			]);
-		try {
-			$this->activityManager->publish($activity);
-		} catch (BadMethodCallException $e) {
-			$this->logger->warning('could not publish activity', ['app' => 'core']);
-			$this->logger->logException($e, ['app' => 'core']);
-		}
-	}
-
-	private function sendNotification(string $event, IToken $token): void {
-		$notification = $this->notificationManager->createNotification();
-		$notification->setApp('auth')
-			->setUser($token->getUID())
-			->setDateTime($this->timeFactory->getDateTime())
-			->setObject('token', $token->getId())
-			->setSubject($event, [
-				'name' => $token->getName(),
-			]);
-		$this->notificationManager->notify($notification);
-	}
-
 }
diff --git a/tests/lib/Authentication/Events/RemoteWipeFinishedTest.php b/tests/lib/Authentication/Events/RemoteWipeFinishedTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..49e9e79462f1bad8b56ad358eda8c11b95400298
--- /dev/null
+++ b/tests/lib/Authentication/Events/RemoteWipeFinishedTest.php
@@ -0,0 +1,39 @@
+<?php declare(strict_types=1);
+
+/**
+ * @copyright 2019 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @author 2019 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+namespace Test\Authentication\Events;
+
+use OC\Authentication\Events\RemoteWipeFinished;
+use OC\Authentication\Token\IToken;
+use Test\TestCase;
+
+class RemoteWipeFinishedTest extends TestCase {
+
+	public function testGetToken() {
+		$token = $this->createMock(IToken::class);
+		$event = new RemoteWipeFinished($token);
+
+		$this->assertSame($token, $event->getToken());
+	}
+
+}
diff --git a/tests/lib/Authentication/Events/RemoteWipeStartedTest.php b/tests/lib/Authentication/Events/RemoteWipeStartedTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..8fbaa0866563ac65e7aae8c1b61d7192cd1214ce
--- /dev/null
+++ b/tests/lib/Authentication/Events/RemoteWipeStartedTest.php
@@ -0,0 +1,39 @@
+<?php declare(strict_types=1);
+
+/**
+ * @copyright 2019 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @author 2019 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+namespace Test\Authentication\Events;
+
+use OC\Authentication\Events\RemoteWipeStarted;
+use OC\Authentication\Token\IToken;
+use Test\TestCase;
+
+class RemoteWipeStartedTest extends TestCase {
+
+	public function testGetToken() {
+		$token = $this->createMock(IToken::class);
+		$event = new RemoteWipeStarted($token);
+
+		$this->assertSame($token, $event->getToken());
+	}
+
+}
diff --git a/tests/lib/Authentication/Listeners/RemoteWipeActivityListenerTest.php b/tests/lib/Authentication/Listeners/RemoteWipeActivityListenerTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..87a7b03027380e786a8d64680f42d1f169130514
--- /dev/null
+++ b/tests/lib/Authentication/Listeners/RemoteWipeActivityListenerTest.php
@@ -0,0 +1,154 @@
+<?php declare(strict_types=1);
+
+/**
+ * @copyright 2019 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @author 2019 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+namespace Test\Authentication\Events;
+
+use OC\Activity\Event as IActivityEvent;
+use OC\Authentication\Events\RemoteWipeFinished;
+use OC\Authentication\Events\RemoteWipeStarted;
+use OC\Authentication\Listeners\RemoteWipeActivityListener;
+use OC\Authentication\Token\IToken;
+use OCP\Activity\IManager as IActivityManager;
+use OCP\EventDispatcher\Event;
+use OCP\EventDispatcher\IEventListener;
+use OCP\ILogger;
+use OCP\IUser;
+use PHPUnit\Framework\MockObject\MockObject;
+use Test\TestCase;
+
+class RemoteWipeActivityListenerTests extends TestCase {
+
+	/** @var IActivityManager|MockObject */
+	private $activityManager;
+
+	/** @var ILogger|MockObject */
+	private $logger;
+
+	/** @var IEventListener */
+	private $listener;
+
+	protected function setUp() {
+		parent::setUp();
+
+		$this->activityManager = $this->createMock(IActivityManager::class);
+		$this->logger = $this->createMock(ILogger::class);
+
+		$this->listener = new RemoteWipeActivityListener(
+			$this->activityManager,
+			$this->logger
+		);
+	}
+
+	public function testHandleUnrelated() {
+		$event = new Event();
+
+		$this->listener->handle($event);
+
+		$this->addToAssertionCount(1);
+	}
+
+	public function testHandleRemoteWipeStarted() {
+		/** @var IToken|MockObject $token */
+		$token = $this->createMock(IToken::class);
+		$event = new RemoteWipeStarted($token);
+		$activityEvent = $this->createMock(IActivityEvent::class);
+		$this->activityManager->expects($this->once())
+			->method('generateEvent')
+			->willReturn($activityEvent);
+		$activityEvent->expects($this->once())
+			->method('setApp')
+			->with('core')
+			->willReturnSelf();
+		$activityEvent->expects($this->once())
+			->method('setType')
+			->with('security')
+			->willReturnSelf();
+		$token->method('getUID')->willReturn('user123');
+		$activityEvent->expects($this->once())
+			->method('setAuthor')
+			->with('user123')
+			->willReturnSelf();
+		$activityEvent->expects($this->once())
+			->method('setAffectedUser')
+			->with('user123')
+			->willReturnSelf();
+		$token->method('getName')->willReturn('Token 1');
+		$activityEvent->expects($this->once())
+			->method('setSubject')
+			->with('remote_wipe_start', ['name' => 'Token 1'])
+			->willReturnSelf();
+		$this->activityManager->expects($this->once())
+			->method('publish');
+
+		$this->listener->handle($event);
+	}
+
+	public function testHandleRemoteWipeStartedCanNotPublish() {
+		$token = $this->createMock(IToken::class);
+		$event = new RemoteWipeStarted($token);
+		$this->activityManager->expects($this->once())
+			->method('generateEvent');
+		$this->activityManager->expects($this->once())
+			->method('publish')
+			->willThrowException(new \BadMethodCallException());
+
+		$this->listener->handle($event);
+	}
+
+	public function testHandleRemoteWipeFinished() {
+		/** @var IToken|MockObject $token */
+		$token = $this->createMock(IToken::class);
+		$event = new RemoteWipeFinished($token);
+		$activityEvent = $this->createMock(IActivityEvent::class);
+		$this->activityManager->expects($this->once())
+			->method('generateEvent')
+			->willReturn($activityEvent);
+		$activityEvent->expects($this->once())
+			->method('setApp')
+			->with('core')
+			->willReturnSelf();
+		$activityEvent->expects($this->once())
+			->method('setType')
+			->with('security')
+			->willReturnSelf();
+		$token->method('getUID')->willReturn('user123');
+		$activityEvent->expects($this->once())
+			->method('setAuthor')
+			->with('user123')
+			->willReturnSelf();
+		$activityEvent->expects($this->once())
+			->method('setAffectedUser')
+			->with('user123')
+			->willReturnSelf();
+		$token->method('getName')->willReturn('Token 1');
+		$activityEvent->expects($this->once())
+			->method('setSubject')
+			->with('remote_wipe_finish', ['name' => 'Token 1'])
+			->willReturnSelf();
+		$this->activityManager->expects($this->once())
+			->method('publish');
+
+		$this->listener->handle($event);
+	}
+
+}
diff --git a/tests/lib/Authentication/Listeners/RemoteWipeNotificationsListenerTest.php b/tests/lib/Authentication/Listeners/RemoteWipeNotificationsListenerTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..27d386ca5b354f27e8c05922f68d4fd99916da3b
--- /dev/null
+++ b/tests/lib/Authentication/Listeners/RemoteWipeNotificationsListenerTest.php
@@ -0,0 +1,150 @@
+<?php declare(strict_types=1);
+
+/**
+ * @copyright 2019 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @author 2019 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+namespace Test\Authentication\Events;
+
+use DateTime;
+use OC\Authentication\Events\RemoteWipeFinished;
+use OC\Authentication\Events\RemoteWipeStarted;
+use OC\Authentication\Listeners\RemoteWipeNotificationsListener;
+use OC\Authentication\Token\IToken;
+use OCP\AppFramework\Utility\ITimeFactory;
+use OCP\EventDispatcher\Event;
+use OCP\EventDispatcher\IEventListener;
+use OCP\Notification\IManager as INotificationManager;
+use OCP\Notification\INotification;
+use PHPUnit\Framework\MockObject\MockObject;
+use Test\TestCase;
+
+class RemoteWipeNotificationListenerTests extends TestCase {
+
+	/** @var INotificationManager|MockObject */
+	private $notificationManager;
+
+	/** @var ITimeFactory|MockObject */
+	private $timeFactory;
+
+	/** @var IEventListener */
+	private $listener;
+
+	protected function setUp() {
+		parent::setUp();
+
+		$this->notificationManager = $this->createMock(INotificationManager::class);
+		$this->timeFactory = $this->createMock(ITimeFactory::class);
+
+		$this->listener = new RemoteWipeNotificationsListener(
+			$this->notificationManager,
+			$this->timeFactory
+		);
+	}
+
+	public function testHandleUnrelated() {
+		$event = new Event();
+
+		$this->listener->handle($event);
+
+		$this->addToAssertionCount(1);
+	}
+
+	public function testHandleRemoteWipeStarted() {
+		$token = $this->createMock(IToken::class);
+		$event = new RemoteWipeStarted($token);
+		$notification = $this->createMock(INotification::class);
+		$this->notificationManager->expects($this->once())
+			->method('createNotification')
+			->willReturn($notification);
+		$notification->expects($this->once())
+			->method('setApp')
+			->with('auth')
+			->willReturnSelf();
+		$token->method('getUID')->willReturn('user123');
+		$notification->expects($this->once())
+			->method('setUser')
+			->with('user123')
+			->willReturnSelf();
+		$now = new DateTime();
+		$this->timeFactory->method('getDateTime')->willReturn($now);
+		$notification->expects($this->once())
+			->method('setDateTime')
+			->with($now)
+			->willReturnSelf();
+		$token->method('getId')->willReturn(123);
+		$notification->expects($this->once())
+			->method('setObject')
+			->with('token', 123)
+			->willReturnSelf();
+		$token->method('getName')->willReturn('Token 1');
+		$notification->expects($this->once())
+			->method('setSubject')
+			->with('remote_wipe_start', [
+				'name' => 'Token 1'
+			])
+			->willReturnSelf();
+		$this->notificationManager->expects($this->once())
+			->method('notify');
+
+		$this->listener->handle($event);
+	}
+
+	public function testHandleRemoteWipeFinished() {
+		$token = $this->createMock(IToken::class);
+		$event = new RemoteWipeFinished($token);
+		$notification = $this->createMock(INotification::class);
+		$this->notificationManager->expects($this->once())
+			->method('createNotification')
+			->willReturn($notification);
+		$notification->expects($this->once())
+			->method('setApp')
+			->with('auth')
+			->willReturnSelf();
+		$token->method('getUID')->willReturn('user123');
+		$notification->expects($this->once())
+			->method('setUser')
+			->with('user123')
+			->willReturnSelf();
+		$now = new DateTime();
+		$this->timeFactory->method('getDateTime')->willReturn($now);
+		$notification->expects($this->once())
+			->method('setDateTime')
+			->with($now)
+			->willReturnSelf();
+		$token->method('getId')->willReturn(123);
+		$notification->expects($this->once())
+			->method('setObject')
+			->with('token', 123)
+			->willReturnSelf();
+		$token->method('getName')->willReturn('Token 1');
+		$notification->expects($this->once())
+			->method('setSubject')
+			->with('remote_wipe_finish', [
+				'name' => 'Token 1'
+			])
+			->willReturnSelf();
+		$this->notificationManager->expects($this->once())
+			->method('notify');
+
+		$this->listener->handle($event);
+	}
+
+}
diff --git a/tests/lib/Authentication/Token/RemoteWipeTest.php b/tests/lib/Authentication/Token/RemoteWipeTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..e0b3e9fcae9c6d823c1bdf04454ecf5b4e1c48d0
--- /dev/null
+++ b/tests/lib/Authentication/Token/RemoteWipeTest.php
@@ -0,0 +1,131 @@
+<?php declare(strict_types=1);
+
+/**
+ * @copyright 2019 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @author 2019 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+namespace Test\Authentication\Token;
+
+use OC\Authentication\Events\RemoteWipeFinished;
+use OC\Authentication\Events\RemoteWipeStarted;
+use OC\Authentication\Exceptions\WipeTokenException;
+use OC\Authentication\Token\IProvider as ITokenProvider;
+use OC\Authentication\Token\IProvider;
+use OC\Authentication\Token\IToken;
+use OC\Authentication\Token\RemoteWipe;
+use OCP\EventDispatcher\IEventDispatcher;
+use OCP\ILogger;
+use PHPUnit\Framework\MockObject\MockObject;
+use Test\TestCase;
+
+class RemoteWipeTest extends TestCase {
+
+	/** @var ITokenProvider|MockObject */
+	private $tokenProvider;
+
+	/** @var IEventDispatcher|MockObject */
+	private $eventDispatcher;
+
+	/** @var ILogger|MockObject */
+	private $logger;
+
+	/** @var RemoteWipe */
+	private $remoteWipe;
+
+	protected function setUp() {
+		parent::setUp();
+
+		$this->tokenProvider = $this->createMock(IProvider::class);
+		$this->eventDispatcher = $this->createMock(IEventDispatcher::class);
+		$this->logger = $this->createMock(ILogger::class);
+
+		$this->remoteWipe = new RemoteWipe(
+			$this->tokenProvider,
+			$this->eventDispatcher,
+			$this->logger
+		);
+	}
+
+	public function testStartWipingNotAWipeToken() {
+		$token = $this->createMock(IToken::class);
+		$this->tokenProvider->expects($this->once())
+			->method('getToken')
+			->with('tk1')
+			->willReturn($token);
+		$this->eventDispatcher->expects($this->never())
+			->method('dispatch');
+
+		$result = $this->remoteWipe->start('tk1');
+
+		$this->assertFalse($result);
+	}
+
+	public function testStartWiping() {
+		$token = $this->createMock(IToken::class);
+		$this->tokenProvider->expects($this->once())
+			->method('getToken')
+			->with('tk1')
+			->willThrowException(new WipeTokenException($token));
+		$this->eventDispatcher->expects($this->once())
+			->method('dispatch');
+		$this->eventDispatcher->expects($this->once())
+			->method('dispatch')
+			->with(RemoteWipeStarted::class, $this->equalTo(new RemoteWipeStarted($token)));
+
+		$result = $this->remoteWipe->start('tk1');
+
+		$this->assertTrue($result);
+	}
+
+	public function testFinishWipingNotAWipeToken() {
+		$token = $this->createMock(IToken::class);
+		$this->tokenProvider->expects($this->once())
+			->method('getToken')
+			->with('tk1')
+			->willReturn($token);
+		$this->eventDispatcher->expects($this->never())
+			->method('dispatch');
+
+		$result = $this->remoteWipe->finish('tk1');
+
+		$this->assertFalse($result);
+	}
+
+	public function startFinishWiping() {
+		$token = $this->createMock(IToken::class);
+		$this->tokenProvider->expects($this->once())
+			->method('getToken')
+			->with('tk1')
+			->willThrowException(new WipeTokenException($token));
+		$this->eventDispatcher->expects($this->once())
+			->method('dispatch');
+		$this->tokenProvider->expects($this->once())
+			->method('invalidateToken')
+			->with($token);
+		$this->eventDispatcher->expects($this->once())
+			->method('dispatch')
+			->with(RemoteWipeFinished::class, $this->equalTo(new RemoteWipeFinished($token)));
+
+		$result = $this->remoteWipe->finish('tk1');
+
+		$this->assertTrue($result);
+	}
+
+}