mirror of
https://github.com/Termix-SSH/Termix.git
synced 2026-08-29 18:31:33 +00:00
118 lines
3.0 KiB
TypeScript
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");
|
|
});
|
|
});
|