feat: configure signed Memos webhooks when supported

This commit is contained in:
2026-07-19 05:14:01 +08:00
parent 3d6d1c03f3
commit 97d4c15407
7 changed files with 26 additions and 6 deletions
+5 -1
View File
@@ -3,7 +3,8 @@ import { requireUser } from "@/lib/auth";
import { decrypt, encrypt } from "@/lib/crypto";
import { db } from "@/lib/db";
import { externalUrl } from "@/lib/http";
import { getMemosIdentity, verifyMemos } from "@/lib/memos";
import { createUserWebhook, getMemosIdentity, verifyMemos } from "@/lib/memos";
import { createWebhookSecret, webhookSecretHash } from "@/lib/webhook";
import { queuePull } from "@/lib/sync";
import { requireSameOrigin } from "@/lib/security";
@@ -25,6 +26,9 @@ export async function POST(req: Request) {
const out = db.prepare("INSERT INTO sources(user_id,name,base_url,token_encrypted,remote_user,sync_status) VALUES(?,?,?,?,?, 'queued')").run(user.id, name, baseUrl, encrypt(token), identity.name);
const sourceId = Number(out.lastInsertRowid);
db.prepare("INSERT INTO source_members(source_id,user_id,role) VALUES(?,?,'owner')").run(sourceId, user.id);
const pathSecret = createWebhookSecret(); const signingSecret = createWebhookSecret(); const publicOrigin = (process.env.NEXT_PUBLIC_APP_URL || new URL(req.url).origin).replace(/\/$/, "");
try { const remote = await createUserWebhook(baseUrl, token, identity.name, { url: `${publicOrigin}/api/sync/webhook/${sourceId}/${pathSecret}`, displayName: "Mebbling", signingSecret }); db.prepare("UPDATE sources SET webhook_secret_hash=?,webhook_mode='signed',webhook_remote_name=?,webhook_signing_secret_encrypted=? WHERE id=?").run(webhookSecretHash(pathSecret), remote.name, encrypt(signingSecret), sourceId); }
catch (webhookError) { const message = webhookError instanceof Error ? webhookError.message : "Webhook unsupported"; db.prepare("UPDATE sources SET webhook_mode=? WHERE id=?").run(message.includes("Memos API 404") ? "manual" : "unavailable", sourceId); }
queuePull(sourceId, "source-created");
return NextResponse.redirect(externalUrl(req, "/dashboard?source=connected"));
} catch (error) { return NextResponse.redirect(externalUrl(req, "/dashboard?error=" + encodeURIComponent(error instanceof Error ? error.message : "source"))); }