feat: serve plugin http and websockets from one mount instead of ports

This commit is contained in:
LukeGus committed 2026-09-22 16:39:41 -05:00
1 parent c496a093ca
commit 8431570ff7
102 files changed
+2894 -2308

No files matched your search

@@ -1,6 +1,15 @@
/**
* dispatchLoginEvent used to POST to the metrics service on localhost:30005
* with an internal auth token. Host metrics is a plugin now and has no port,
* so it publishes on the plugin event bus and the plugin subscribes.
*
* What is asserted changed with it: the payload a subscriber receives, and
* that a throwing subscriber cannot fail the login that caused the event.
*/
import { afterEach, describe, expect, it, vi } from "vitest";
import { dispatchLoginEvent } from "../../utils/login-event-dispatch.js";
import { SystemCrypto } from "../../utils/system-crypto.js";
import { pluginEvents, TOPICS } from "../../plugins/events.js";
import { sshLogger } from "../../utils/logger.js";
describe("dispatchLoginEvent", () => {
@@ -8,37 +17,24 @@ describe("dispatchLoginEvent", () => {
vi.restoreAllMocks();
});
it("reports a rejected metrics-service request", async () => {
vi.spyOn(SystemCrypto, "getInstance").mockReturnValue({
getInternalAuthToken: vi.fn().mockResolvedValue("internal-token"),
} as never);
vi.spyOn(globalThis, "fetch").mockResolvedValue(
new Response('{"error":"Missing authentication token"}', {
status: 401,
}),
);
const warn = vi.spyOn(sshLogger, "warn").mockImplementation(() => {});
it("publishes the login details a subscriber needs", async () => {
const received: unknown[] = [];
const unsubscribe = pluginEvents.on(TOPICS.hostLogin, (payload) => {
received.push(payload);
});
await dispatchLoginEvent(7, "user-1", "root", "192.0.2.1");
try {
await dispatchLoginEvent(42, "user-1", "root", "10.0.0.5");
} finally {
unsubscribe();
}
expect(warn).toHaveBeenCalledWith(
"Failed to dispatch login event",
expect.objectContaining({
operation: "login_event_dispatch_error",
hostId: 7,
error:
'Metrics service returned 401: {"error":"Missing authentication token"}',
}),
);
expect(received).toEqual([
{ hostId: 42, userId: "user-1", sshUser: "root", fromIp: "10.0.0.5" },
]);
});
it("does not log a warning when the metrics service accepts the event", async () => {
vi.spyOn(SystemCrypto, "getInstance").mockReturnValue({
getInternalAuthToken: vi.fn().mockResolvedValue("internal-token"),
} as never);
vi.spyOn(globalThis, "fetch").mockResolvedValue(
new Response('{"ok":true}', { status: 200 }),
);
it("does not log a warning on the happy path", async () => {
const warn = vi.spyOn(sshLogger, "warn").mockImplementation(() => {});
await dispatchLoginEvent(7, "user-1", "root", "192.0.2.1");
@@ -46,49 +42,27 @@ describe("dispatchLoginEvent", () => {
expect(warn).not.toHaveBeenCalled();
});
it("sends the internal auth token and login details the metrics service expects", async () => {
vi.spyOn(SystemCrypto, "getInstance").mockReturnValue({
getInternalAuthToken: vi.fn().mockResolvedValue("internal-token"),
} as never);
const fetchSpy = vi
.spyOn(globalThis, "fetch")
.mockResolvedValue(new Response('{"ok":true}', { status: 200 }));
it("never sends the event over the network", async () => {
const fetchSpy = vi.spyOn(globalThis, "fetch");
await dispatchLoginEvent(42, "user-1", "root", "10.0.0.5");
await dispatchLoginEvent(7, "user-1", "root", "192.0.2.1");
expect(fetchSpy).toHaveBeenCalledWith(
"http://localhost:30005/internal/login-alert",
expect.objectContaining({
method: "POST",
headers: expect.objectContaining({
"x-internal-auth": "internal-token",
}),
body: JSON.stringify({
hostId: 42,
userId: "user-1",
sshUser: "root",
fromIp: "10.0.0.5",
}),
}),
);
// The whole point of the move: no service-to-service HTTP call, and no
// internal shared secret to carry on it.
expect(fetchSpy).not.toHaveBeenCalled();
});
it("logs a warning if the fetch itself throws, instead of propagating", async () => {
vi.spyOn(SystemCrypto, "getInstance").mockReturnValue({
getInternalAuthToken: vi.fn().mockResolvedValue("internal-token"),
} as never);
vi.spyOn(globalThis, "fetch").mockRejectedValue(
new Error("connect ECONNREFUSED"),
);
const warn = vi.spyOn(sshLogger, "warn").mockImplementation(() => {});
it("does not propagate a subscriber's throw to the caller", async () => {
const unsubscribe = pluginEvents.on(TOPICS.hostLogin, () => {
throw new Error("subscriber exploded");
});
await expect(
dispatchLoginEvent(1, "user-1", "root", "127.0.0.1"),
).resolves.toBeUndefined();
expect(warn).toHaveBeenCalledWith(
"Failed to dispatch login event",
expect.objectContaining({ hostId: 1 }),
);
try {
await expect(
dispatchLoginEvent(1, "user-1", "root", "127.0.0.1"),
).resolves.toBeUndefined();
} finally {
unsubscribe();
}
});
});