From cdb8e31c545892cd39d5aba1a6194667950fd0a8 Mon Sep 17 00:00:00 2001 From: Thea Kindinger Date: Wed, 8 Apr 2026 20:00:01 -0400 Subject: [PATCH] feat: scaffold v0.3.0 mailcow integration and plugin hook structure --- deploy/nginx/mailcow-plugin-runtime.conf | 1 + docs/v0.3.0-mailcow-integration.md | 1 + plugins/owncloud-attach/api/README.md | 1 + plugins/owncloud-attach/ui/index.html | 1 + scripts/next-steps.sh | 1 + src/hooks/mailcow-hooks.ts | 1 + src/integrations/mailcow/bootstrap-loader.ts | 1 + src/integrations/mailcow/dom-targets.ts | 1 + src/integrations/mailcow/install.ts | 1 + 9 files changed, 9 insertions(+) create mode 100644 deploy/nginx/mailcow-plugin-runtime.conf create mode 100644 docs/v0.3.0-mailcow-integration.md create mode 100644 plugins/owncloud-attach/api/README.md create mode 100644 plugins/owncloud-attach/ui/index.html create mode 100755 scripts/next-steps.sh create mode 100644 src/hooks/mailcow-hooks.ts create mode 100644 src/integrations/mailcow/bootstrap-loader.ts create mode 100644 src/integrations/mailcow/dom-targets.ts create mode 100644 src/integrations/mailcow/install.ts diff --git a/deploy/nginx/mailcow-plugin-runtime.conf b/deploy/nginx/mailcow-plugin-runtime.conf new file mode 100644 index 0000000..82f2ff2 --- /dev/null +++ b/deploy/nginx/mailcow-plugin-runtime.conf @@ -0,0 +1 @@ +# Mailcow plugin runtime reverse proxy\n# Include this from the Mailcow nginx site or merge into the active server block.\n# Adjust upstream address if the runtime is not on localhost:4110.\n\nlocation /plugins-runtime/ {\n proxy_pass http://127.0.0.1:4110/;\n proxy_http_version 1.1;\n\n proxy_set_header Host $host;\n proxy_set_header X-Real-IP $remote_addr;\n proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n proxy_set_header X-Forwarded-Proto $scheme;\n\n proxy_request_buffering off;\n proxy_buffering off;\n client_max_body_size 100m;\n}\n \ No newline at end of file diff --git a/docs/v0.3.0-mailcow-integration.md b/docs/v0.3.0-mailcow-integration.md new file mode 100644 index 0000000..c386597 --- /dev/null +++ b/docs/v0.3.0-mailcow-integration.md @@ -0,0 +1 @@ +# mailcow-plugin-runtime v0.3.0 integration plan\n\n## Scope\n- Proxy runtime behind Mailcow at \n- Load runtime bootstrap into Mailcow UI\n- Render compose toolbar and attachment hooks\n- Wire plugin end to end\n\n## Deployment notes\n1. Start runtime on port .\n2. Add to the Mailcow nginx server block.\n3. Ensure is reachable from Mailcow.\n4. Inject the bootstrap loader into the Mailcow compose page.\n\n## Expected follow-up\n- Replace placeholders in with actual selectors and injection logic.\n- Implement attachment token exchange and ownCloud file listing here.\n \ No newline at end of file diff --git a/plugins/owncloud-attach/api/README.md b/plugins/owncloud-attach/api/README.md new file mode 100644 index 0000000..2562638 --- /dev/null +++ b/plugins/owncloud-attach/api/README.md @@ -0,0 +1 @@ +# owncloud-attach API placeholders\n\nExpected endpoints:\n- GET /plugins/owncloud-attach/api/files\n- POST /plugins/owncloud-attach/api/attach\n- GET /plugins/owncloud-attach/api/health\n\nImplement the runtime-side token exchange and ownCloud file listing here.\n \ No newline at end of file diff --git a/plugins/owncloud-attach/ui/index.html b/plugins/owncloud-attach/ui/index.html new file mode 100644 index 0000000..d06ca82 --- /dev/null +++ b/plugins/owncloud-attach/ui/index.html @@ -0,0 +1 @@ +\n\n \n \n \n owncloud-attach\n \n \n \n
\n

owncloud-attach

\n

Placeholder UI for the ownCloud picker modal.

\n \n
\n \n\n \ No newline at end of file diff --git a/scripts/next-steps.sh b/scripts/next-steps.sh new file mode 100755 index 0000000..054c964 --- /dev/null +++ b/scripts/next-steps.sh @@ -0,0 +1 @@ +#!/usr/bin/env bash\nset -euo pipefail\n\necho 'Next manual steps:'\necho '1. Wire deploy/nginx/mailcow-plugin-runtime.conf into the Mailcow nginx server block.'\necho '2. Make Mailcow load src/integrations/mailcow/install.ts output on compose pages.'\necho '3. Replace placeholder selectors in src/integrations/mailcow/dom-targets.ts.'\necho '4. Build owncloud-attach picker API and file attachment flow.'\n \ No newline at end of file diff --git a/src/hooks/mailcow-hooks.ts b/src/hooks/mailcow-hooks.ts new file mode 100644 index 0000000..3801512 --- /dev/null +++ b/src/hooks/mailcow-hooks.ts @@ -0,0 +1 @@ +import { MAILCOW_SELECTORS } from "../integrations/mailcow/dom-targets";\n\nfunction ensureHookContainer(selector: string, id: string): HTMLElement | null {\n const host = document.querySelector(selector);\n if (!host) return null;\n\n let node = document.getElementById(id);\n if (!node) {\n node = document.createElement("div");\n node.id = id;\n node.dataset.pluginHookContainer = id;\n host.appendChild(node);\n }\n\n return node;\n}\n\nexport function mountComposeToolbarHook(): void {\n ensureHookContainer(MAILCOW_SELECTORS.composeToolbar, "mailcow-plugin-hook-compose-toolbar");\n}\n\nexport function mountComposeAttachmentsHook(): void {\n ensureHookContainer(MAILCOW_SELECTORS.composeAttachments, "mailcow-plugin-hook-compose-attachments");\n}\n \ No newline at end of file diff --git a/src/integrations/mailcow/bootstrap-loader.ts b/src/integrations/mailcow/bootstrap-loader.ts new file mode 100644 index 0000000..7ea1d0f --- /dev/null +++ b/src/integrations/mailcow/bootstrap-loader.ts @@ -0,0 +1 @@ +export interface MailcowBootstrapOptions {\n runtimeBaseUrl?: string;\n}\n\nexport function loadPluginRuntimeBootstrap(options: MailcowBootstrapOptions = {}): HTMLScriptElement {\n const runtimeBaseUrl = options.runtimeBaseUrl ?? "/plugins-runtime";\n const script = document.createElement("script");\n script.src = `\${runtimeBaseUrl}/runtime/bootstrap.js`;\n script.async = true;\n script.dataset.runtimeBaseUrl = runtimeBaseUrl;\n document.head.appendChild(script);\n return script;\n}\n \ No newline at end of file diff --git a/src/integrations/mailcow/dom-targets.ts b/src/integrations/mailcow/dom-targets.ts new file mode 100644 index 0000000..9c67ed6 --- /dev/null +++ b/src/integrations/mailcow/dom-targets.ts @@ -0,0 +1 @@ +export const MAILCOW_SELECTORS = {\n composeToolbar: "[data-mailcow-compose-toolbar], .compose-toolbar, .toolbar",\n composeAttachments: "[data-mailcow-compose-attachments], .compose-attachments, .attachments",\n};\n \ No newline at end of file diff --git a/src/integrations/mailcow/install.ts b/src/integrations/mailcow/install.ts new file mode 100644 index 0000000..9ffc33a --- /dev/null +++ b/src/integrations/mailcow/install.ts @@ -0,0 +1 @@ +import { loadPluginRuntimeBootstrap } from "./bootstrap-loader";\nimport { mountComposeToolbarHook, mountComposeAttachmentsHook } from "../hooks/mailcow-hooks";\n\nexport function installMailcowPluginRuntime(): void {\n loadPluginRuntimeBootstrap();\n\n window.addEventListener("DOMContentLoaded", () => {\n mountComposeToolbarHook();\n mountComposeAttachmentsHook();\n });\n}\n \ No newline at end of file