mirror of
https://github.com/J3vb/OwnCord.git
synced 2026-09-03 03:50:00 +03:00
api.setConfig spread the new config over the old, so switching hosts carried the previous server's session token forward and the login request to the next server went out holding a live credential for the first one. The token is now dropped in the shared setConfig when host changes without an accompanying token, covering login, register and auto-connect at once. Also fixes a packaged-build-only failure: the CSP omitted blob: from img-src, so avatar upload validation (which measures the image via URL.createObjectURL) always failed in release and never in dev. Smaller connection and IPC fixes: ws_disconnect now bumps the connection generation instead of nulling the sender slot, so an in-flight handshake cannot install after a disconnect; a dead LiveKit proxy listener deregisters itself instead of being reused forever; httpProxy no longer caches an origin the Rust side may have torn down; logPersistence stopped looping on its own flush-failure logs; ConnectPage subscribes to transientError instead of reading it once; cert-mismatch accept/reject only act when the event host matches the live session. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
74 lines
3.1 KiB
TypeScript
74 lines
3.1 KiB
TypeScript
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
|
|
const { invokeMock } = vi.hoisted(() => ({ invokeMock: vi.fn() }));
|
|
|
|
vi.mock("@tauri-apps/api/core", () => ({ invoke: invokeMock }));
|
|
vi.mock("@lib/logger", () => ({
|
|
createLogger: () => ({ debug: vi.fn(), info: vi.fn(), warn: vi.fn(), error: vi.fn() }),
|
|
}));
|
|
|
|
import { ensureHttpProxy, stopHttpProxy } from "../../src/lib/httpProxy";
|
|
|
|
describe("ensureHttpProxy", () => {
|
|
beforeEach(() => {
|
|
invokeMock.mockReset();
|
|
// Clear per-host cache between tests by stopping any previously started host.
|
|
return stopHttpProxy("cache.example:8443").then(() => invokeMock.mockReset());
|
|
});
|
|
|
|
it("starts a tunnel and returns the loopback origin", async () => {
|
|
invokeMock.mockResolvedValue(51234);
|
|
const origin = await ensureHttpProxy("host-a.example:8443");
|
|
expect(origin).toBe("http://127.0.0.1:51234");
|
|
expect(invokeMock).toHaveBeenCalledWith("start_http_proxy", {
|
|
remoteHost: "host-a.example:8443",
|
|
});
|
|
});
|
|
|
|
// B4_conn_ipc-11: the origin must NOT be cached in JS. Only Rust knows
|
|
// whether its listener is still alive (it deregisters itself after 5
|
|
// consecutive accept errors), so a JS-side cache would keep pointing every
|
|
// REST call at a dead tunnel forever. Every call re-invokes start_http_proxy;
|
|
// the Rust reuse branch dedups an unchanged, still-live host cheaply.
|
|
it("does not cache the origin — every call re-invokes so a self-terminated tunnel can be rebound", async () => {
|
|
invokeMock.mockResolvedValue(40000);
|
|
const a = await ensureHttpProxy("host-b.example:8443");
|
|
// Simulates the Rust side rebinding a fresh port after the old tunnel's
|
|
// accept loop gave up (fd exhaustion, etc.) and deregistered itself.
|
|
invokeMock.mockResolvedValue(40001);
|
|
const b = await ensureHttpProxy("host-b.example:8443");
|
|
expect(a).toBe("http://127.0.0.1:40000");
|
|
expect(b).toBe("http://127.0.0.1:40001");
|
|
expect(invokeMock).toHaveBeenCalledTimes(2);
|
|
});
|
|
|
|
it("de-duplicates concurrent starts for the same host", async () => {
|
|
let resolvePort: (p: number) => void = () => {};
|
|
invokeMock.mockReturnValue(new Promise<number>((r) => (resolvePort = r)));
|
|
const p1 = ensureHttpProxy("host-c.example:8443");
|
|
const p2 = ensureHttpProxy("host-c.example:8443");
|
|
resolvePort(45000);
|
|
const [o1, o2] = await Promise.all([p1, p2]);
|
|
expect(o1).toBe("http://127.0.0.1:45000");
|
|
expect(o2).toBe("http://127.0.0.1:45000");
|
|
expect(invokeMock).toHaveBeenCalledTimes(1);
|
|
});
|
|
|
|
it("stopHttpProxy invokes stop and drops the cache so a restart re-invokes", async () => {
|
|
invokeMock.mockResolvedValue(46000);
|
|
await ensureHttpProxy("host-d.example:8443");
|
|
await stopHttpProxy("host-d.example:8443");
|
|
expect(invokeMock).toHaveBeenCalledWith("stop_http_proxy", {
|
|
remoteHost: "host-d.example:8443",
|
|
});
|
|
|
|
invokeMock.mockReset();
|
|
invokeMock.mockResolvedValue(46001);
|
|
const origin = await ensureHttpProxy("host-d.example:8443");
|
|
expect(origin).toBe("http://127.0.0.1:46001");
|
|
expect(invokeMock).toHaveBeenCalledWith("start_http_proxy", {
|
|
remoteHost: "host-d.example:8443",
|
|
});
|
|
});
|
|
});
|