internal-url-allowed.test.ts 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. import { beforeEach, describe, expect, test, vi } from "vitest";
  2. const getSessionMock = vi.fn(async () => ({ user: { role: "admin" } }));
  3. const createWebhookTargetMock = vi.fn(async (input: any) => ({ id: 1, ...input }));
  4. vi.mock("@/lib/auth", () => {
  5. return {
  6. getSession: getSessionMock,
  7. };
  8. });
  9. vi.mock("@/repository/notifications", () => {
  10. return {
  11. getNotificationSettings: vi.fn(async () => ({ useLegacyMode: false })),
  12. updateNotificationSettings: vi.fn(async () => ({})),
  13. };
  14. });
  15. vi.mock("@/repository/webhook-targets", () => {
  16. return {
  17. createWebhookTarget: createWebhookTargetMock,
  18. deleteWebhookTarget: vi.fn(async () => {}),
  19. getAllWebhookTargets: vi.fn(async () => []),
  20. getWebhookTargetById: vi.fn(async () => null),
  21. updateTestResult: vi.fn(async () => {}),
  22. updateWebhookTarget: vi.fn(async () => ({})),
  23. };
  24. });
  25. describe("允许内网地址输入", () => {
  26. beforeEach(() => {
  27. vi.clearAllMocks();
  28. // 默认:管理员可执行
  29. getSessionMock.mockResolvedValue({ user: { role: "admin" } });
  30. createWebhookTargetMock.mockImplementation(async (input: any) => ({ id: 1, ...input }));
  31. });
  32. test("testWebhookAction 不阻止内网 URL(但会因 hostname 不支持而失败)", async () => {
  33. // 该用例验证:输入层允许内网 IP(不会被拦截),但 provider 检测会因 hostname 不受支持而失败
  34. const { testWebhookAction } = await import("@/actions/notifications");
  35. const result = await testWebhookAction("http://127.0.0.1:8080/webhook", "cost-alert");
  36. expect(result.success).toBe(false);
  37. expect(result.error).toContain("Unsupported webhook hostname");
  38. });
  39. test("testWebhookAction 非管理员应被拒绝", async () => {
  40. getSessionMock.mockResolvedValueOnce({ user: { role: "user" } });
  41. const { testWebhookAction } = await import("@/actions/notifications");
  42. const result = await testWebhookAction("http://127.0.0.1:8080/webhook", "cost-alert");
  43. expect(result.success).toBe(false);
  44. expect(result.error).toBe("无权限执行此操作");
  45. });
  46. test("createWebhookTargetAction 允许内网 webhookUrl", async () => {
  47. const { createWebhookTargetAction } = await import("@/actions/webhook-targets");
  48. const internalUrl = "http://127.0.0.1:8080/webhook";
  49. const result = await createWebhookTargetAction({
  50. name: "test-target",
  51. providerType: "wechat",
  52. webhookUrl: internalUrl,
  53. isEnabled: true,
  54. });
  55. expect(result.ok).toBe(true);
  56. expect(createWebhookTargetMock).toHaveBeenCalledTimes(1);
  57. expect(createWebhookTargetMock.mock.calls[0]?.[0]?.webhookUrl).toBe(internalUrl);
  58. });
  59. });