diff --git a/.vscode/launch.json b/.vscode/launch.json
new file mode 100644
index 0000000..317d206
--- /dev/null
+++ b/.vscode/launch.json
@@ -0,0 +1,38 @@
+{
+ // Use IntelliSense to learn about possible attributes.
+ // Hover to view descriptions of existing attributes.
+ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "name": "Launch built-in server and debug",
+ "type": "php",
+ "request": "launch",
+ "runtimeArgs": [
+ "-S",
+ "localhost:8000",
+ "-t",
+ "."
+ ],
+ "port": 9003,
+ "serverReadyAction": {
+ "action": "openExternally"
+ }
+ },
+ {
+ "name": "Debug current script in console",
+ "type": "php",
+ "request": "launch",
+ "program": "${file}",
+ "cwd": "${fileDirname}",
+ "externalConsole": false,
+ "port": 9003
+ },
+ {
+ "name": "Listen for Xdebug",
+ "type": "php",
+ "request": "launch",
+ "port": 9003
+ }
+ ]
+}
\ No newline at end of file
diff --git a/appinfo/info.xml b/appinfo/info.xml
new file mode 100644
index 0000000..722063e
--- /dev/null
+++ b/appinfo/info.xml
@@ -0,0 +1,18 @@
+
+
+ dav_push
+ DAV Push
+ Implements the DAV Push specification
+
+ 0.0.1
+ agpl
+ bitfire web engineering
+ Jonathan Treffler
+ DavPush
+ tools
+ https://github.com/bitfireAT/nc-ext-caldav-carddav-push/issues
+
+
+
+
\ No newline at end of file
diff --git a/appinfo/routes.php b/appinfo/routes.php
new file mode 100644
index 0000000..b9eca4d
--- /dev/null
+++ b/appinfo/routes.php
@@ -0,0 +1,11 @@
+
+// SPDX-License-Identifier: AGPL-3.0-or-later
+
+return [
+ 'resources' => [
+ ],
+ 'routes' => [
+ ]
+];
\ No newline at end of file
diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php
new file mode 100644
index 0000000..43fabd5
--- /dev/null
+++ b/lib/AppInfo/Application.php
@@ -0,0 +1,30 @@
+
+// SPDX-License-Identifier: AGPL-3.0-or-later
+
+namespace OCA\DavPush\AppInfo;
+
+use OCP\AppFramework\App;
+use OCP\AppFramework\Bootstrap\IBootstrap;
+use OCP\AppFramework\Bootstrap\IRegistrationContext;
+use OCP\AppFramework\Bootstrap\IBootContext;
+
+use OCA\DAV\Events\SabrePluginAddEvent;
+
+use OCA\DavPush\Listener\SabrePluginAddListener;
+
+class Application extends App implements IBootstrap {
+ public const APP_ID = 'dav_push';
+
+ public function __construct() {
+ parent::__construct(self::APP_ID);
+ }
+
+ public function register(IRegistrationContext $context): void {
+ $context->registerEventListener(SabrePluginAddEvent::class, SabrePluginAddListener::class);
+ }
+
+ public function boot(IBootContext $context): void {
+ }
+}
\ No newline at end of file
diff --git a/lib/Dav/ServiceDetectionPlugin.php b/lib/Dav/ServiceDetectionPlugin.php
new file mode 100644
index 0000000..c5a4da6
--- /dev/null
+++ b/lib/Dav/ServiceDetectionPlugin.php
@@ -0,0 +1,106 @@
+
+ *
+ * @author Christopher Ng
+ *
+ * @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 .
+ *
+ */
+
+namespace OCA\DavPush\Dav;
+
+use OCP\IUser;
+use OCP\IUserSession;
+
+use OCP\AppFramework\Db\DoesNotExistException;
+use OCA\DAV\Connector\Sabre\Node;
+use OCA\DavPush\Transport\TransportManager;
+
+use Sabre\DAV\INode;
+use Sabre\DAV\PropFind;
+use Sabre\DAV\Server;
+use Sabre\DAV\ServerPlugin;
+
+class ServiceDetectionPlugin extends ServerPlugin {
+
+ public const PUSH_PREFIX = '{DAV:Push}';
+ public const PROPERTY_PUSH_TRANSPORTS = self::PUSH_PREFIX . 'push-transports';
+ public const PROPERTY_PUSH_TOPIC = self::PUSH_PREFIX . 'topic';
+
+
+ public function __construct(
+ private IUserSession $userSession,
+ private TransportManager $transportManager,
+ ) {
+ }
+
+ public function initialize(Server $server): void {
+ $server->on('propFind', [$this, 'propFind']);
+ }
+
+ public function propFind(PropFind $propFind, INode $node) {
+ if (count(array_intersect([self::PROPERTY_PUSH_TRANSPORTS, self::PROPERTY_PUSH_TOPIC], $propFind->getRequestedProperties())) == 0) {
+ return;
+ }
+
+ //if (!($node instanceof Node)) {
+ // return;
+ //}
+
+ $propFind->handle(
+ self::PROPERTY_PUSH_TRANSPORTS,
+ function () use ($node) {
+ //$user = $this->userSession->getUser();
+ //if (!($user instanceof IUser)) {
+ // return [];
+ //}
+
+ $transports = $this->transportManager->getTransports();
+
+ $result = [];
+
+ foreach($transports as $transport) {
+ $result[] = [
+ (self::PUSH_PREFIX . "transport") => [
+ (self::PUSH_PREFIX . $transport->getId()) => $transport->getAdditionalInformation(),
+ ]
+ ];
+ }
+
+ //throw new \Exception( "\$result = " . json_encode($result) );
+
+ return $result;
+ },
+ );
+
+ $propFind->handle(
+ self::PROPERTY_PUSH_TOPIC,
+ //function () use ($node) {
+ //$user = $this->userSession->getUser();
+ //if (!($user instanceof IUser)) {
+ // return [];
+ //}
+
+ // return "test-return-push";
+ //},
+ "test-return-push-topic"
+ );
+ }
+}
\ No newline at end of file
diff --git a/lib/Event/RegisterTransportsEvent.php b/lib/Event/RegisterTransportsEvent.php
new file mode 100644
index 0000000..34a3db9
--- /dev/null
+++ b/lib/Event/RegisterTransportsEvent.php
@@ -0,0 +1,28 @@
+transportManager = $transportManager;
+ }
+
+ public function getTransportManager(): TransportManager {
+ return $this->transportManager;
+ }
+}
\ No newline at end of file
diff --git a/lib/Listener/SabrePluginAddListener.php b/lib/Listener/SabrePluginAddListener.php
new file mode 100644
index 0000000..ef2876d
--- /dev/null
+++ b/lib/Listener/SabrePluginAddListener.php
@@ -0,0 +1,25 @@
+container->get(ServiceDetectionPlugin::class);
+
+ $event->getServer()->addPlugin($serviceDetectionPlugin);
+ }
+ }
+}
\ No newline at end of file
diff --git a/lib/PushTransports/WebPushTransport.php b/lib/PushTransports/WebPushTransport.php
new file mode 100644
index 0000000..6a8333a
--- /dev/null
+++ b/lib/PushTransports/WebPushTransport.php
@@ -0,0 +1,11 @@
+id;
+ }
+
+ public function getAdditionalInformation() {
+ return [];
+ }
+}
\ No newline at end of file
diff --git a/lib/Transport/TransportManager.php b/lib/Transport/TransportManager.php
new file mode 100644
index 0000000..d82fb6e
--- /dev/null
+++ b/lib/Transport/TransportManager.php
@@ -0,0 +1,38 @@
+registerTransport(new WebPushTransport());
+
+ // register transports provided by other apps
+ $event = new RegisterTransportsEvent($this);
+ $dispatcher->dispatchTyped($event);
+ }
+
+ /**
+ * @return Transport[]
+ */
+ public function getTransports(): array {
+ return $this->transports;
+ }
+
+ public function registerTransport(Transport $transport): self {
+ $this->transports[] = $transport;
+ return $this;
+ }
+}
\ No newline at end of file