diff --git a/modules/rsocials/components/folk-socials-canvas.ts b/modules/rsocials/components/folk-socials-canvas.ts
index 484289a..eacbfed 100644
--- a/modules/rsocials/components/folk-socials-canvas.ts
+++ b/modules/rsocials/components/folk-socials-canvas.ts
@@ -163,6 +163,10 @@ class FolkSocialsCanvas extends HTMLElement {
return match ? match[0] : "";
}
+ private getSchedulerUrl(): string {
+ return `${this.getApiBase()}/scheduler`;
+ }
+
private buildCanvasNodes() {
this.canvasNodes = [];
for (const c of this.campaigns) {
@@ -403,7 +407,7 @@ class FolkSocialsCanvas extends HTMLElement {
Postiz — Post Scheduler
-
+
@@ -419,7 +423,7 @@ class FolkSocialsCanvas extends HTMLElement {
const panel = this.shadow.getElementById("postiz-panel");
const iframe = panel?.querySelector("iframe");
if (panel) panel.classList.toggle("open", this.postizOpen);
- if (iframe && this.postizOpen) iframe.src = "https://demo.rsocials.online";
+ if (iframe && this.postizOpen) iframe.src = "${this.getSchedulerUrl()}";
if (iframe && !this.postizOpen) iframe.src = "about:blank";
});
this.shadow.getElementById("close-postiz")?.addEventListener("click", () => {
diff --git a/modules/rsocials/mod.ts b/modules/rsocials/mod.ts
index ceab505..f4242cd 100644
--- a/modules/rsocials/mod.ts
+++ b/modules/rsocials/mod.ts
@@ -514,17 +514,84 @@ function renderDemoFeedHTML(): string {
// ── Path-based sub-routes ──
-routes.get("/scheduler", (c) => {
+// ── Postiz reverse proxy at /scheduler/* ──
+// Proxies to the Postiz container on the Docker network, avoiding
+// the Traefik priority conflict with rSpace's rsocials.online catch-all.
+const POSTIZ_UPSTREAM = process.env.POSTIZ_URL || "http://postiz:5000";
+
+routes.all("/scheduler/*", async (c) => {
+ const subPath = c.req.path.replace(/^\/[^/]+\/rsocials\/scheduler/, "") || "/";
+ const upstreamUrl = `${POSTIZ_UPSTREAM}${subPath}`;
+ const url = new URL(upstreamUrl);
+ // Preserve query string
+ const reqUrl = new URL(c.req.url);
+ url.search = reqUrl.search;
+
+ try {
+ const headers = new Headers(c.req.raw.headers);
+ headers.delete("host");
+
+ const resp = await fetch(url.toString(), {
+ method: c.req.method,
+ headers,
+ body: c.req.method !== "GET" && c.req.method !== "HEAD" ? c.req.raw.body : undefined,
+ redirect: "manual",
+ });
+
+ // Rewrite Location headers to stay within /scheduler/
+ const respHeaders = new Headers(resp.headers);
+ const location = respHeaders.get("location");
+ if (location) {
+ try {
+ const locUrl = new URL(location, upstreamUrl);
+ if (locUrl.origin === new URL(POSTIZ_UPSTREAM).origin) {
+ const space = c.req.param("space") || "demo";
+ respHeaders.set("location", `/${space}/rsocials/scheduler${locUrl.pathname}${locUrl.search}`);
+ }
+ } catch { /* keep original */ }
+ }
+
+ return new Response(resp.body, {
+ status: resp.status,
+ headers: respHeaders,
+ });
+ } catch {
+ return c.text("Postiz scheduler unavailable", 502);
+ }
+});
+
+routes.get("/scheduler", async (c) => {
const space = c.req.param("space") || "demo";
- return c.html(renderExternalAppShell({
- title: `${space} — Postiz | rSpace`,
- moduleId: "rsocials",
- spaceSlug: space,
- modules: getModuleInfoList(),
- appUrl: "https://demo.rsocials.online",
- appName: "Postiz",
- theme: "dark",
- }));
+ const upstreamUrl = `${POSTIZ_UPSTREAM}/`;
+ try {
+ const headers = new Headers(c.req.raw.headers);
+ headers.delete("host");
+ const reqUrl = new URL(c.req.url);
+
+ const resp = await fetch(`${upstreamUrl}${reqUrl.search}`, {
+ method: "GET",
+ headers,
+ redirect: "manual",
+ });
+
+ const respHeaders = new Headers(resp.headers);
+ const location = respHeaders.get("location");
+ if (location) {
+ try {
+ const locUrl = new URL(location, upstreamUrl);
+ if (locUrl.origin === new URL(POSTIZ_UPSTREAM).origin) {
+ respHeaders.set("location", `/${space}/rsocials/scheduler${locUrl.pathname}${locUrl.search}`);
+ }
+ } catch { /* keep original */ }
+ }
+
+ return new Response(resp.body, {
+ status: resp.status,
+ headers: respHeaders,
+ });
+ } catch {
+ return c.text("Postiz scheduler unavailable", 502);
+ }
});
routes.get("/feed", (c) => {