fix(auth): pin native auth storage operations
This commit is contained in:
@@ -7,7 +7,6 @@ import { createAuthenticationConfigProvider } from "../src/auth/config.js";
|
||||
import { createAuthentikGroupCatalog } from "../src/auth/authentik-group-catalog.js";
|
||||
import { createLocalUserRegistry } from "../src/auth/local-registry.js";
|
||||
import { createOidcProtocol, OidcJwksUnavailableError } from "../src/auth/oidc-client.js";
|
||||
import { validateAuthSessionRoot } from "../src/auth/session-store.js";
|
||||
import type { LoadedAuthConfig } from "../src/auth/types.js";
|
||||
|
||||
const sentinels = [
|
||||
@@ -152,7 +151,7 @@ test("distinguishes a valid registry without an enabled admin from a malformed r
|
||||
chmodSync(validUsers, 0o600);
|
||||
const validReport = await createAuthDiagnoser({
|
||||
authMode: "local", authStateRoot: validRoot,
|
||||
sessionRootValidator: validateAuthSessionRoot,
|
||||
sessionRootValidator: acceptSessionRoot,
|
||||
authentication: { current: () => localConfig(join(validRoot, "auth.yaml")) },
|
||||
localUserRegistry: createLocalUserRegistry(validUsers),
|
||||
}).inspect({ live: false });
|
||||
@@ -164,7 +163,7 @@ test("distinguishes a valid registry without an enabled admin from a malformed r
|
||||
chmodSync(malformedUsers, 0o600);
|
||||
const malformedReport = await createAuthDiagnoser({
|
||||
authMode: "local", authStateRoot: malformedRoot,
|
||||
sessionRootValidator: validateAuthSessionRoot,
|
||||
sessionRootValidator: acceptSessionRoot,
|
||||
authentication: { current: () => localConfig(join(malformedRoot, "auth.yaml")) },
|
||||
localUserRegistry: createLocalUserRegistry(malformedUsers),
|
||||
}).inspect({ live: false });
|
||||
@@ -182,7 +181,7 @@ test("maps unsafe auth.yaml storage from the real provider to a redacted config
|
||||
chmodSync(unsafePath, 0o640);
|
||||
const report = await createAuthDiagnoser({
|
||||
authMode: "local", authStateRoot: root,
|
||||
sessionRootValidator: validateAuthSessionRoot,
|
||||
sessionRootValidator: acceptSessionRoot,
|
||||
authentication: createAuthenticationConfigProvider(unsafePath),
|
||||
}).inspect({ live: false });
|
||||
|
||||
@@ -442,73 +441,6 @@ test("redacts exceptional configuration, registry, protocol, and catalog errors"
|
||||
expect(report.checks.every((check) => check.level === "error" || check.level === "info")).toBe(true);
|
||||
});
|
||||
|
||||
test.skipIf(process.platform === "win32")("uses the runtime validator for canonical, private session roots", async () => {
|
||||
const dependencies = (authStateRoot: string) => ({
|
||||
authMode: "none" as const,
|
||||
authStateRoot,
|
||||
sessionRootValidator: validateAuthSessionRoot,
|
||||
});
|
||||
const valid = privateRoot();
|
||||
await expect(createAuthDiagnoser(dependencies(valid)).inspect({ live: false }))
|
||||
.resolves.toMatchObject({ ready: true, checks: [expect.objectContaining({ code: "auth_ready" })] });
|
||||
|
||||
const realRoot = join(privateRoot(), "real-auth");
|
||||
mkdirSync(realRoot, { mode: 0o700 });
|
||||
chmodSync(realRoot, 0o700);
|
||||
const linkedRoot = join(privateRoot(), "linked-auth");
|
||||
symlinkSync(realRoot, linkedRoot);
|
||||
const absent = join(privateRoot(), "absent-auth");
|
||||
const absentParent = join(privateRoot(), "absent-parent");
|
||||
const absentNested = join(absentParent, "auth");
|
||||
const blockedParent = join(privateRoot(), "not-a-directory");
|
||||
writeFileSync(blockedParent, "blocked", { mode: 0o600 });
|
||||
const traversal = `${valid}/../${basename(valid)}`;
|
||||
|
||||
const missingReport = await createAuthDiagnoser(dependencies(absent)).inspect({ live: false });
|
||||
expect(missingReport).toMatchObject({ ready: true, checks: [expect.objectContaining({ code: "auth_ready" })] });
|
||||
expect(existsSync(absent)).toBe(false);
|
||||
|
||||
for (const unsafe of [traversal, linkedRoot, absentNested, join(blockedParent, "auth")]) {
|
||||
const report = await createAuthDiagnoser(dependencies(unsafe)).inspect({ live: false });
|
||||
expect(report).toMatchObject({ ready: false, checks: [expect.objectContaining({ code: "auth_session_store_invalid" })] });
|
||||
expect(JSON.stringify(report)).not.toContain(unsafe);
|
||||
}
|
||||
expect(existsSync(absentParent)).toBe(false);
|
||||
|
||||
chmodSync(valid, 0o750);
|
||||
await expect(createAuthDiagnoser(dependencies(valid)).inspect({ live: false }))
|
||||
.resolves.toMatchObject({ ready: false, checks: [expect.objectContaining({ code: "auth_session_store_invalid" })] });
|
||||
});
|
||||
|
||||
test.skipIf(process.platform === "win32")("diagnoses unsafe existing session-store children without creating missing children", async () => {
|
||||
const root = privateRoot();
|
||||
const outside = privateRoot();
|
||||
symlinkSync(outside, join(root, "sessions"));
|
||||
|
||||
const linked = await createAuthDiagnoser({
|
||||
authMode: "none", authStateRoot: root, sessionRootValidator: validateAuthSessionRoot,
|
||||
}).inspect({ live: false });
|
||||
expect(linked).toMatchObject({
|
||||
ready: false,
|
||||
checks: [expect.objectContaining({ code: "auth_session_store_invalid" })],
|
||||
});
|
||||
expect(existsSync(join(root, "oidc"))).toBe(false);
|
||||
expect(JSON.stringify(linked)).not.toContain(root);
|
||||
|
||||
rmSync(join(root, "sessions"));
|
||||
mkdirSync(join(root, "sessions"), { mode: 0o700 });
|
||||
chmodSync(join(root, "sessions"), 0o700);
|
||||
mkdirSync(join(root, "oidc"), { mode: 0o700 });
|
||||
chmodSync(join(root, "oidc"), 0o750);
|
||||
const nonPrivate = await createAuthDiagnoser({
|
||||
authMode: "none", authStateRoot: root, sessionRootValidator: validateAuthSessionRoot,
|
||||
}).inspect({ live: false });
|
||||
expect(nonPrivate).toMatchObject({
|
||||
ready: false,
|
||||
checks: [expect.objectContaining({ code: "auth_session_store_invalid" })],
|
||||
});
|
||||
});
|
||||
|
||||
test.skipIf(process.platform === "win32")("routes production POSIX static validation through the native auth-storage bridge", async () => {
|
||||
const validateRoot = vi.fn(async () => undefined);
|
||||
const report = await createAuthDiagnoser({
|
||||
|
||||
Reference in New Issue
Block a user