mirror of
https://github.com/fabro-sh/fabro.git
synced 2026-08-28 05:27:41 +00:00
Tighten the browser-based install flow after correctness and adversarial review, without changing the external wizard shape. - Persist the actual bind in server.listen, not the canonical URL - Reject concurrent /install/finish and rapid GitHub App retries - Keep the prior GitHub Token strategy until App callback succeeds - Recover from poisoned install locks instead of propagating panics - Rollback both settings and vault on failed persistence - Redirect GitHub callback errors back into the wizard UI - Validate LLM keys via /models probe instead of a billed generate() - Reject canonical URLs with trailing slash, path, query, or fragment - Accept any valid install-token source, not just the first present one - Redact the install token in structured logs - Assert install-mode SPA marker injection at startup - Warn on suspected concurrent operators via UA + X-Forwarded-For - Add component-level test for the GitHub callback error banner Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
67 lines
2.4 KiB
TypeScript
67 lines
2.4 KiB
TypeScript
import { describe, expect, test } from "bun:test";
|
|
|
|
import {
|
|
consumeInstallGithubErrorFromUrl,
|
|
consumeInstallTokenFromUrl,
|
|
resolveFabroMode,
|
|
shouldConsumeInstallGithubErrorForPath,
|
|
} from "./mode";
|
|
|
|
describe("resolveFabroMode", () => {
|
|
test("returns install only for the explicit install marker", () => {
|
|
expect(resolveFabroMode("install")).toBe("install");
|
|
expect(resolveFabroMode("normal")).toBe("normal");
|
|
expect(resolveFabroMode(undefined)).toBe("normal");
|
|
});
|
|
});
|
|
|
|
describe("consumeInstallTokenFromUrl", () => {
|
|
test("extracts the install token and preserves other query params", () => {
|
|
expect(
|
|
consumeInstallTokenFromUrl("https://fabro.example.com/install?token=abc123&step=welcome"),
|
|
).toEqual({
|
|
token: "abc123",
|
|
sanitizedUrl: "https://fabro.example.com/install?step=welcome",
|
|
});
|
|
});
|
|
|
|
test("returns the original url when no install token is present", () => {
|
|
expect(
|
|
consumeInstallTokenFromUrl("https://fabro.example.com/install?step=welcome"),
|
|
).toEqual({
|
|
token: null,
|
|
sanitizedUrl: "https://fabro.example.com/install?step=welcome",
|
|
});
|
|
});
|
|
});
|
|
|
|
describe("consumeInstallGithubErrorFromUrl", () => {
|
|
test("extracts the callback error and preserves other query params", () => {
|
|
expect(
|
|
consumeInstallGithubErrorFromUrl(
|
|
"https://fabro.example.com/install/github?error=github-app-manifest-conversion-failed&step=github",
|
|
),
|
|
).toEqual({
|
|
error: "GitHub App setup failed before Fabro could save the app credentials. Continue again to retry the callback.",
|
|
sanitizedUrl: "https://fabro.example.com/install/github?step=github",
|
|
});
|
|
});
|
|
|
|
test("returns the original url when no callback error is present", () => {
|
|
expect(
|
|
consumeInstallGithubErrorFromUrl("https://fabro.example.com/install/github?step=github"),
|
|
).toEqual({
|
|
error: null,
|
|
sanitizedUrl: "https://fabro.example.com/install/github?step=github",
|
|
});
|
|
});
|
|
});
|
|
|
|
describe("shouldConsumeInstallGithubErrorForPath", () => {
|
|
test("only consumes GitHub callback errors on GitHub install routes", () => {
|
|
expect(shouldConsumeInstallGithubErrorForPath("/install/github")).toBe(true);
|
|
expect(shouldConsumeInstallGithubErrorForPath("/install/github/done")).toBe(true);
|
|
expect(shouldConsumeInstallGithubErrorForPath("/install/llm")).toBe(false);
|
|
expect(shouldConsumeInstallGithubErrorForPath("/install/server")).toBe(false);
|
|
});
|
|
});
|