refactor(synology-chat): centralize DM auth and fail fast startup

This commit is contained in:
Peter Steinberger
2026-02-24 23:28:24 +00:00
parent e7a5f9f4d8
commit 9fccf60733
7 changed files with 245 additions and 16 deletions

View File

@@ -6,7 +6,7 @@
import type { IncomingMessage, ServerResponse } from "node:http";
import * as querystring from "node:querystring";
import { sendMessage } from "./client.js";
import { validateToken, checkUserAllowed, sanitizeInput, RateLimiter } from "./security.js";
import { validateToken, authorizeUserForDm, sanitizeInput, RateLimiter } from "./security.js";
import type { SynologyWebhookPayload, ResolvedSynologyChatAccount } from "./types.js";
// One rate limiter per account, created lazily
@@ -137,25 +137,23 @@ export function createWebhookHandler(deps: WebhookHandlerDeps) {
return;
}
// User allowlist check
if (account.dmPolicy === "disabled") {
respond(res, 403, { error: "DMs are disabled" });
return;
}
if (account.dmPolicy === "allowlist") {
if (account.allowedUserIds.length === 0) {
// DM policy authorization
const auth = authorizeUserForDm(payload.user_id, account.dmPolicy, account.allowedUserIds);
if (!auth.allowed) {
if (auth.reason === "disabled") {
respond(res, 403, { error: "DMs are disabled" });
return;
}
if (auth.reason === "allowlist-empty") {
log?.warn("Synology Chat allowlist is empty while dmPolicy=allowlist; rejecting message");
respond(res, 403, {
error: "Allowlist is empty. Configure allowedUserIds or use dmPolicy=open.",
});
return;
}
if (!checkUserAllowed(payload.user_id, account.allowedUserIds)) {
log?.warn(`Unauthorized user: ${payload.user_id}`);
respond(res, 403, { error: "User not authorized" });
return;
}
log?.warn(`Unauthorized user: ${payload.user_id}`);
respond(res, 403, { error: "User not authorized" });
return;
}
// Rate limit