refactor(auth): streamline allowFrom normalization
This commit is contained in:
@@ -14,31 +14,6 @@ export type CommandAuthorization = {
|
|||||||
to?: string;
|
to?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
function resolveSenderId(params: {
|
|
||||||
dock?: ChannelDock;
|
|
||||||
cfg: ClawdbotConfig;
|
|
||||||
accountId?: string | null;
|
|
||||||
ctx: MsgContext;
|
|
||||||
}): string | undefined {
|
|
||||||
const { dock, cfg, accountId, ctx } = params;
|
|
||||||
|
|
||||||
const senderCandidates = [ctx.SenderId, ctx.SenderE164, ctx.From]
|
|
||||||
.map((value) => (value ?? "").trim())
|
|
||||||
.filter(Boolean);
|
|
||||||
|
|
||||||
for (const sender of senderCandidates) {
|
|
||||||
const normalized = formatAllowFromList({
|
|
||||||
dock,
|
|
||||||
cfg,
|
|
||||||
accountId,
|
|
||||||
allowFrom: [sender],
|
|
||||||
})[0];
|
|
||||||
if (normalized) return normalized;
|
|
||||||
}
|
|
||||||
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
function resolveProviderFromContext(ctx: MsgContext, cfg: ClawdbotConfig): ChannelId | undefined {
|
function resolveProviderFromContext(ctx: MsgContext, cfg: ClawdbotConfig): ChannelId | undefined {
|
||||||
const direct =
|
const direct =
|
||||||
normalizeChannelId(ctx.Provider) ??
|
normalizeChannelId(ctx.Provider) ??
|
||||||
@@ -81,6 +56,42 @@ function formatAllowFromList(params: {
|
|||||||
return allowFrom.map((entry) => String(entry).trim()).filter(Boolean);
|
return allowFrom.map((entry) => String(entry).trim()).filter(Boolean);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function normalizeAllowFromEntry(params: {
|
||||||
|
dock?: ChannelDock;
|
||||||
|
cfg: ClawdbotConfig;
|
||||||
|
accountId?: string | null;
|
||||||
|
value: string;
|
||||||
|
}): string | undefined {
|
||||||
|
return formatAllowFromList({
|
||||||
|
dock: params.dock,
|
||||||
|
cfg: params.cfg,
|
||||||
|
accountId: params.accountId,
|
||||||
|
allowFrom: [params.value],
|
||||||
|
})[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
function resolveSenderId(params: {
|
||||||
|
dock?: ChannelDock;
|
||||||
|
cfg: ClawdbotConfig;
|
||||||
|
accountId?: string | null;
|
||||||
|
senderId?: string | null;
|
||||||
|
senderE164?: string | null;
|
||||||
|
from?: string | null;
|
||||||
|
}): string | undefined {
|
||||||
|
const { dock, cfg, accountId } = params;
|
||||||
|
|
||||||
|
const senderCandidates = [params.senderId, params.senderE164, params.from]
|
||||||
|
.map((value) => (value ?? "").trim())
|
||||||
|
.filter(Boolean);
|
||||||
|
|
||||||
|
for (const sender of senderCandidates) {
|
||||||
|
const normalized = normalizeAllowFromEntry({ dock, cfg, accountId, value: sender });
|
||||||
|
if (normalized) return normalized;
|
||||||
|
}
|
||||||
|
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
export function resolveCommandAuthorization(params: {
|
export function resolveCommandAuthorization(params: {
|
||||||
ctx: MsgContext;
|
ctx: MsgContext;
|
||||||
cfg: ClawdbotConfig;
|
cfg: ClawdbotConfig;
|
||||||
@@ -105,12 +116,7 @@ export function resolveCommandAuthorization(params: {
|
|||||||
|
|
||||||
const ownerCandidates = allowAll ? [] : allowFromList.filter((entry) => entry !== "*");
|
const ownerCandidates = allowAll ? [] : allowFromList.filter((entry) => entry !== "*");
|
||||||
if (!allowAll && ownerCandidates.length === 0 && to) {
|
if (!allowAll && ownerCandidates.length === 0 && to) {
|
||||||
const normalizedTo = formatAllowFromList({
|
const normalizedTo = normalizeAllowFromEntry({ dock, cfg, accountId: ctx.AccountId, value: to });
|
||||||
dock,
|
|
||||||
cfg,
|
|
||||||
accountId: ctx.AccountId,
|
|
||||||
allowFrom: [to],
|
|
||||||
})[0];
|
|
||||||
if (normalizedTo) ownerCandidates.push(normalizedTo);
|
if (normalizedTo) ownerCandidates.push(normalizedTo);
|
||||||
}
|
}
|
||||||
const ownerList = ownerCandidates;
|
const ownerList = ownerCandidates;
|
||||||
@@ -119,10 +125,9 @@ export function resolveCommandAuthorization(params: {
|
|||||||
dock,
|
dock,
|
||||||
cfg,
|
cfg,
|
||||||
accountId: ctx.AccountId,
|
accountId: ctx.AccountId,
|
||||||
ctx: {
|
senderId: ctx.SenderId,
|
||||||
...ctx,
|
senderE164: ctx.SenderE164,
|
||||||
From: from,
|
from,
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const enforceOwner = Boolean(dock?.commands?.enforceOwnerForCommands);
|
const enforceOwner = Boolean(dock?.commands?.enforceOwnerForCommands);
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { describe, expect, it } from "vitest";
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
isWhatsAppGroupJid,
|
isWhatsAppGroupJid,
|
||||||
isWhatsAppUserJid,
|
isWhatsAppUserTarget,
|
||||||
normalizeWhatsAppTarget,
|
normalizeWhatsAppTarget,
|
||||||
} from "./normalize.js";
|
} from "./normalize.js";
|
||||||
|
|
||||||
@@ -45,6 +45,7 @@ describe("normalizeWhatsAppTarget", () => {
|
|||||||
|
|
||||||
it("normalizes LID JIDs to E.164", () => {
|
it("normalizes LID JIDs to E.164", () => {
|
||||||
expect(normalizeWhatsAppTarget("123456789@lid")).toBe("+123456789");
|
expect(normalizeWhatsAppTarget("123456789@lid")).toBe("+123456789");
|
||||||
|
expect(normalizeWhatsAppTarget("123456789@LID")).toBe("+123456789");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("rejects invalid targets", () => {
|
it("rejects invalid targets", () => {
|
||||||
@@ -52,6 +53,7 @@ describe("normalizeWhatsAppTarget", () => {
|
|||||||
expect(normalizeWhatsAppTarget("whatsapp:")).toBeNull();
|
expect(normalizeWhatsAppTarget("whatsapp:")).toBeNull();
|
||||||
expect(normalizeWhatsAppTarget("@g.us")).toBeNull();
|
expect(normalizeWhatsAppTarget("@g.us")).toBeNull();
|
||||||
expect(normalizeWhatsAppTarget("whatsapp:group:@g.us")).toBeNull();
|
expect(normalizeWhatsAppTarget("whatsapp:group:@g.us")).toBeNull();
|
||||||
|
expect(normalizeWhatsAppTarget("abc@s.whatsapp.net")).toBeNull();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("handles repeated prefixes", () => {
|
it("handles repeated prefixes", () => {
|
||||||
@@ -60,13 +62,16 @@ describe("normalizeWhatsAppTarget", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("isWhatsAppUserJid", () => {
|
describe("isWhatsAppUserTarget", () => {
|
||||||
it("detects user JIDs with various formats", () => {
|
it("detects user JIDs with various formats", () => {
|
||||||
expect(isWhatsAppUserJid("41796666864:0@s.whatsapp.net")).toBe(true);
|
expect(isWhatsAppUserTarget("41796666864:0@s.whatsapp.net")).toBe(true);
|
||||||
expect(isWhatsAppUserJid("1234567890@s.whatsapp.net")).toBe(true);
|
expect(isWhatsAppUserTarget("1234567890@s.whatsapp.net")).toBe(true);
|
||||||
expect(isWhatsAppUserJid("123456789@lid")).toBe(true);
|
expect(isWhatsAppUserTarget("123456789@lid")).toBe(true);
|
||||||
expect(isWhatsAppUserJid("123456789-987654321@g.us")).toBe(false);
|
expect(isWhatsAppUserTarget("123456789@LID")).toBe(true);
|
||||||
expect(isWhatsAppUserJid("+1555123")).toBe(false);
|
expect(isWhatsAppUserTarget("123@lid:0")).toBe(false);
|
||||||
|
expect(isWhatsAppUserTarget("abc@s.whatsapp.net")).toBe(false);
|
||||||
|
expect(isWhatsAppUserTarget("123456789-987654321@g.us")).toBe(false);
|
||||||
|
expect(isWhatsAppUserTarget("+1555123")).toBe(false);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -25,9 +25,9 @@ export function isWhatsAppGroupJid(value: string): boolean {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if value looks like a WhatsApp user JID (e.g. "41796666864:0@s.whatsapp.net" or "123@lid").
|
* Check if value looks like a WhatsApp user target (e.g. "41796666864:0@s.whatsapp.net" or "123@lid").
|
||||||
*/
|
*/
|
||||||
export function isWhatsAppUserJid(value: string): boolean {
|
export function isWhatsAppUserTarget(value: string): boolean {
|
||||||
const candidate = stripWhatsAppTargetPrefixes(value);
|
const candidate = stripWhatsAppTargetPrefixes(value);
|
||||||
return WHATSAPP_USER_JID_RE.test(candidate) || WHATSAPP_LID_RE.test(candidate);
|
return WHATSAPP_USER_JID_RE.test(candidate) || WHATSAPP_LID_RE.test(candidate);
|
||||||
}
|
}
|
||||||
@@ -53,7 +53,7 @@ export function normalizeWhatsAppTarget(value: string): string | null {
|
|||||||
return `${localPart}@g.us`;
|
return `${localPart}@g.us`;
|
||||||
}
|
}
|
||||||
// Handle user JIDs (e.g. "41796666864:0@s.whatsapp.net")
|
// Handle user JIDs (e.g. "41796666864:0@s.whatsapp.net")
|
||||||
if (isWhatsAppUserJid(candidate)) {
|
if (isWhatsAppUserTarget(candidate)) {
|
||||||
const phone = extractUserJidPhone(candidate);
|
const phone = extractUserJidPhone(candidate);
|
||||||
if (!phone) return null;
|
if (!phone) return null;
|
||||||
const normalized = normalizeE164(phone);
|
const normalized = normalizeE164(phone);
|
||||||
|
|||||||
Reference in New Issue
Block a user