fix(config): coerce numeric Discord IDs to strings instead of rejecting (#45125)

Merged via squash.

Prepared head SHA: 099ba514a1
Co-authored-by: moliendocode <29582793+moliendocode@users.noreply.github.com>
Co-authored-by: altaywtf <9790196+altaywtf@users.noreply.github.com>
Reviewed-by: @altaywtf
This commit is contained in:
Moliendo
2026-04-01 15:07:28 -03:00
committed by GitHub
parent 4f407d2658
commit d076153fc9
9 changed files with 402 additions and 108 deletions

View File

@@ -59,7 +59,7 @@ describe("config discord", () => {
);
});
it("rejects numeric discord allowlist entries", () => {
it("coerces safe-integer numeric discord allowlist entries to strings", () => {
const res = validateConfigObject({
channels: {
discord: {
@@ -79,11 +79,42 @@ describe("config discord", () => {
},
});
expect(res.ok).toBe(false);
if (!res.ok) {
expect(
res.issues.some((issue) => issue.message.includes("Discord IDs must be strings")),
).toBe(true);
expect(res.ok).toBe(true);
if (res.ok) {
expect(res.config.channels?.discord?.allowFrom).toEqual(["123"]);
expect(res.config.channels?.discord?.dm?.allowFrom).toEqual(["456"]);
expect(res.config.channels?.discord?.dm?.groupChannels).toEqual(["789"]);
expect(res.config.channels?.discord?.guilds?.["123"]?.users).toEqual(["111"]);
expect(res.config.channels?.discord?.guilds?.["123"]?.roles).toEqual(["222"]);
expect(res.config.channels?.discord?.guilds?.["123"]?.channels?.general?.users).toEqual([
"333",
]);
expect(res.config.channels?.discord?.guilds?.["123"]?.channels?.general?.roles).toEqual([
"444",
]);
expect(res.config.channels?.discord?.execApprovals?.approvers).toEqual(["555"]);
}
});
it("rejects numeric discord IDs that are not valid non-negative safe integers", () => {
const cases = [106232522769186816, -1, 123.45];
for (const id of cases) {
const res = validateConfigObject({
channels: {
discord: {
allowFrom: [id],
},
},
});
expect(res.ok).toBe(false);
if (!res.ok) {
expect(
res.issues.some((issue) =>
issue.message.includes("not a valid non-negative safe integer"),
),
).toBe(true);
}
}
});
});

View File

@@ -46,9 +46,22 @@ const ToolPolicyBySenderSchema = z.record(z.string(), ToolPolicySchema).optional
const DiscordIdSchema = z
.union([z.string(), z.number()])
.refine((value) => typeof value === "string", {
message: "Discord IDs must be strings (wrap numeric IDs in quotes).",
});
.transform((value, ctx) => {
if (typeof value === "number") {
if (!Number.isSafeInteger(value) || value < 0) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message:
`Discord ID "${String(value)}" is not a valid non-negative safe integer. ` +
`Wrap it in quotes in your config file.`,
});
return z.NEVER;
}
return String(value);
}
return value;
})
.pipe(z.string());
const DiscordIdListSchema = z.array(DiscordIdSchema);
const TelegramInlineButtonsScopeSchema = z.enum(["off", "dm", "group", "all", "allowlist"]);