Files
Termix/src/backend/tests/utils/audit-logger.test.ts
T

118 lines
3.0 KiB
TypeScript

import { describe, it, expect, vi, beforeEach } from "vitest";
const createMock = vi.fn().mockResolvedValue(undefined);
vi.mock("../../database/repositories/factory.js", () => ({
createCurrentAuditLogRepository: vi.fn(() => ({
create: createMock,
})),
}));
import { logAudit, getRequestMeta } from "../../utils/audit-logger.js";
describe("logAudit", () => {
beforeEach(() => {
vi.clearAllMocks();
createMock.mockResolvedValue(undefined);
});
it("inserts an audit log entry with all required fields", async () => {
const params = {
userId: "user-1",
username: "alice",
action: "create_host",
resourceType: "host",
resourceId: "42",
resourceName: "my-server",
ipAddress: "1.2.3.4",
userAgent: "Mozilla/5.0",
success: true,
};
await logAudit(params);
expect(createMock).toHaveBeenCalledOnce();
expect(createMock).toHaveBeenCalledWith(
expect.objectContaining({
userId: "user-1",
username: "alice",
action: "create_host",
resourceType: "host",
resourceId: "42",
resourceName: "my-server",
success: true,
}),
);
});
it("does not throw when insert fails", async () => {
createMock.mockRejectedValue(new Error("db error"));
await expect(
logAudit({
userId: "u",
username: "u",
action: "x",
resourceType: "y",
success: false,
}),
).resolves.toBeUndefined();
});
});
describe("getRequestMeta", () => {
it("uses the proxy-validated Express IP", () => {
const req = {
headers: {
"x-forwarded-for": "10.0.0.1, 10.0.0.2",
"user-agent": "TestAgent/1.0",
},
ip: "127.0.0.1",
socket: {},
};
const meta = getRequestMeta(req as never);
expect(meta.ipAddress).toBe("127.0.0.1");
expect(meta.userAgent).toBe("TestAgent/1.0");
});
it("falls back to req.ip when no forwarded header", () => {
const req = {
headers: { "user-agent": "Bot/2" },
ip: "192.168.1.1",
socket: {},
};
const meta = getRequestMeta(req as never);
expect(meta.ipAddress).toBe("192.168.1.1");
});
it("ignores an unvalidated forwarded header", () => {
const req = {
headers: {
"x-forwarded-for": ["10.0.0.1, 10.0.0.2"],
"user-agent": "TestAgent/1.0",
},
socket: { remoteAddress: "203.0.113.9" },
};
const meta = getRequestMeta(req as never);
expect(meta.ipAddress).toBe("203.0.113.9");
});
it("falls back to the socket peer when there is no forwarded header or req.ip", () => {
const req = {
headers: {},
socket: { remoteAddress: "203.0.113.9" },
};
const meta = getRequestMeta(req as never);
expect(meta.ipAddress).toBe("203.0.113.9");
});
it("returns 'unknown' rather than an empty string when no IP info exists", () => {
const req = {
headers: {},
socket: {},
};
const meta = getRequestMeta(req as never);
expect(meta.ipAddress).toBe("unknown");
});
});