Files
wehub-resource-sync 70bf21e064
Deploy (to testing) and Test Playground Preview Worker / Deploy Playground Preview Worker (testing) (push) Has been skipped
Deploy Workers Shared Staging / Deploy Workers Shared Staging (push) Failing after 0s
Prerelease / build (push) Has been skipped
Handle Changesets / Handle Changesets (push) Has been cancelled
Semgrep OSS scan / semgrep-oss (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:30:11 +08:00

400 lines
11 KiB
TypeScript

import { existsSync, mkdirSync, writeFileSync } from "node:fs";
import path from "node:path";
import { getGlobalConfigPath } from "@cloudflare/workers-utils";
import { runInTempDir } from "@cloudflare/workers-utils/test-helpers";
import { afterEach, beforeEach, describe, it, vi } from "vitest";
import { setKeyProviderFactoryForTesting } from "../../src/credential-store/key-providers/factory";
import {
getKeyringInstallDir,
setNpmRunner,
} from "../../src/credential-store/key-providers/lazy-installer";
import { setLinuxSecretToolRunner } from "../../src/credential-store/key-providers/linux-secret-tool";
import { setMacSecurityCommandRunner } from "../../src/credential-store/key-providers/mac-security";
import { createCredentialStorageContext } from "../../src/credential-store/resolver";
import { resetCredentialStorageState } from "../../src/credential-store/state";
import type { OAuthFlowLogger } from "../../src/context";
import type { CredentialStore } from "../../src/credential-store/interface";
import type { KeyProvider } from "../../src/credential-store/key-providers/interface";
import type { SpawnSyncReturns } from "node:child_process";
function mockResult({
status = 0,
stdout = "",
stderr = "",
}: {
status?: number | null;
stdout?: string;
stderr?: string;
} = {}): SpawnSyncReturns<string> {
return {
status,
stdout,
stderr,
signal: null,
output: [null, stdout, stderr],
pid: 1,
} as SpawnSyncReturns<string>;
}
class InMemoryKeyProvider implements KeyProvider {
private key: Uint8Array | undefined;
getKey() {
return this.key;
}
setKey(key: Uint8Array) {
this.key = key;
}
deleteKey() {
this.key = undefined;
}
describe() {
return "in-memory test keyring";
}
}
const ORIGINAL_PLATFORM = process.platform;
function stubPlatform(platform: NodeJS.Platform): void {
Object.defineProperty(process, "platform", {
value: platform,
configurable: true,
});
}
function restorePlatform(): void {
Object.defineProperty(process, "platform", {
value: ORIGINAL_PLATFORM,
configurable: true,
});
}
const warn = vi.fn();
const log = vi.fn();
const silentLogger: OAuthFlowLogger = {
debug: () => {},
info: () => {},
log,
warn,
error: () => {},
};
interface StateOptions {
isKeyringEnabled?: boolean;
isNonInteractiveOrCI?: boolean;
}
function resolveStore(opts: StateOptions = {}): CredentialStore {
const { getActiveStore } = createCredentialStorageContext({
serviceName: "wrangler",
getConfigPath: () => getGlobalConfigPath(),
isKeyringEnabled: () => opts.isKeyringEnabled ?? true,
logger: silentLogger,
isNonInteractiveOrCI: () => opts.isNonInteractiveOrCI ?? false,
cliName: "wrangler",
});
return getActiveStore();
}
describe("createCredentialStorageContext — resolver", () => {
runInTempDir();
beforeEach(() => {
warn.mockClear();
log.mockClear();
resetCredentialStorageState();
});
afterEach(() => {
setKeyProviderFactoryForTesting(undefined);
setMacSecurityCommandRunner(undefined);
setLinuxSecretToolRunner(undefined);
setNpmRunner(undefined);
resetCredentialStorageState();
restorePlatform();
});
describe("precedence", () => {
it("defaults to FileCredentialStore when keyring is disabled in preferences", ({
expect,
}) => {
expect(resolveStore({ isKeyringEnabled: false }).kind).toBe("file");
});
it("CLOUDFLARE_AUTH_USE_KEYRING=false forces FileCredentialStore", ({
expect,
}) => {
vi.stubEnv("CLOUDFLARE_AUTH_USE_KEYRING", "false");
expect(resolveStore({ isKeyringEnabled: true }).kind).toBe("file");
});
it("CLOUDFLARE_AUTH_USE_KEYRING=true forces the encrypted store even when the preference is off", ({
expect,
}) => {
vi.stubEnv("CLOUDFLARE_AUTH_USE_KEYRING", "true");
setKeyProviderFactoryForTesting(() => new InMemoryKeyProvider());
expect(resolveStore({ isKeyringEnabled: false }).kind).toBe(
"encrypted-file"
);
});
it("uses the encrypted store when keyring is enabled and a provider is available", ({
expect,
}) => {
setKeyProviderFactoryForTesting(() => new InMemoryKeyProvider());
expect(resolveStore({ isKeyringEnabled: true }).kind).toBe(
"encrypted-file"
);
});
it("CLOUDFLARE_AUTH_USE_KEYRING=true with an unavailable backend throws a UserError", ({
expect,
}) => {
vi.stubEnv("CLOUDFLARE_AUTH_USE_KEYRING", "true");
stubPlatform("freebsd" as NodeJS.Platform);
expect(() => resolveStore({ isKeyringEnabled: true })).toThrow(
/CLOUDFLARE_AUTH_USE_KEYRING is set but no keyring backend is available on `freebsd`/
);
});
});
describe("darwin", () => {
it("returns an encrypted store backed by MacSecurityKeyProvider", ({
expect,
}) => {
stubPlatform("darwin");
setMacSecurityCommandRunner(() => mockResult({ status: 44 }));
const store = resolveStore({ isKeyringEnabled: true });
expect(store.kind).toBe("encrypted-file");
expect(store.describe()).toContain("macOS Keychain");
});
});
describe("linux", () => {
it("returns an encrypted store backed by LinuxSecretToolKeyProvider when secret-tool is present", ({
expect,
}) => {
stubPlatform("linux");
setLinuxSecretToolRunner((args) => {
if (args[0] === "--version") {
return mockResult({ stdout: "secret-tool 0.21.7" });
}
return mockResult({ status: 1 });
});
const store = resolveStore({ isKeyringEnabled: true });
expect(store.kind).toBe("encrypted-file");
expect(store.describe()).toContain("secret-tool");
});
it("warns and falls back to FileCredentialStore when secret-tool is missing (interactive)", ({
expect,
}) => {
stubPlatform("linux");
setLinuxSecretToolRunner(() => {
throw new Error("ENOENT");
});
const store = resolveStore({
isKeyringEnabled: true,
isNonInteractiveOrCI: false,
});
expect(store.kind).toBe("file");
expect(warn).toHaveBeenCalledWith(expect.stringContaining("secret-tool"));
});
it("hard-errors when secret-tool is missing in a non-interactive context", ({
expect,
}) => {
stubPlatform("linux");
setLinuxSecretToolRunner(() => {
throw new Error("ENOENT");
});
expect(() =>
resolveStore({ isKeyringEnabled: true, isNonInteractiveOrCI: true })
).toThrow(/`secret-tool` is required for OS keyring storage on Linux/);
});
it("hard-errors with the CLOUDFLARE_AUTH_USE_KEYRING-prefixed message when forced and missing", ({
expect,
}) => {
stubPlatform("linux");
vi.stubEnv("CLOUDFLARE_AUTH_USE_KEYRING", "true");
setLinuxSecretToolRunner(() => mockResult({ status: 127 }));
expect(() => resolveStore({ isKeyringEnabled: true })).toThrow(
/CLOUDFLARE_AUTH_USE_KEYRING is set but `secret-tool` is required/
);
});
it("warns at most once per process about the secret-tool fallback", ({
expect,
}) => {
stubPlatform("linux");
setLinuxSecretToolRunner(() => {
throw new Error("ENOENT");
});
const { getActiveStore } = createCredentialStorageContext({
serviceName: "wrangler",
getConfigPath: () => getGlobalConfigPath(),
isKeyringEnabled: () => true,
logger: silentLogger,
isNonInteractiveOrCI: () => false,
cliName: "wrangler",
});
getActiveStore();
getActiveStore();
getActiveStore();
const matches = warn.mock.calls.filter(
(call) => typeof call[0] === "string" && call[0].includes("secret-tool")
);
expect(matches.length).toBe(1);
});
});
describe("win32", () => {
it("returns an encrypted store when the binding is already installed", ({
expect,
}) => {
stubPlatform("win32");
// Seed the lazy install dir so findKeyringBinding() picks it up.
const bindingDir = path.join(
getKeyringInstallDir(getGlobalConfigPath()),
"node_modules",
"@napi-rs",
"keyring"
);
mkdirSync(bindingDir, { recursive: true });
writeFileSync(path.join(bindingDir, "index.js"), "module.exports = {};");
const store = resolveStore({ isKeyringEnabled: true });
expect(store.kind).toBe("encrypted-file");
expect(store.describe()).toContain("Windows Credential Manager");
});
it("hard-errors when the binding is missing in a non-interactive context", ({
expect,
}) => {
stubPlatform("win32");
setNpmRunner(() => mockResult({ status: 0, stdout: "/nonexistent\n" }));
expect(() =>
resolveStore({ isKeyringEnabled: true, isNonInteractiveOrCI: true })
).toThrow(
/`@napi-rs\/keyring` is required for OS keyring storage on Windows/
);
});
it("includes the pinned version in the global-install hint", ({
expect,
}) => {
stubPlatform("win32");
setNpmRunner(() => mockResult({ status: 0, stdout: "/nowhere\n" }));
expect(() =>
resolveStore({ isKeyringEnabled: true, isNonInteractiveOrCI: true })
).toThrow(/@napi-rs\/keyring@\d+\.\d+\.\d+/);
});
it("invokes the lazy installer when interactive and binding is missing", ({
expect,
}) => {
stubPlatform("win32");
let installCalls = 0;
setNpmRunner((args) => {
if (args[0] === "install") {
installCalls += 1;
// Seed the install dir as if npm had just run successfully.
const bindingDir = path.join(
getKeyringInstallDir(getGlobalConfigPath()),
"node_modules",
"@napi-rs",
"keyring"
);
mkdirSync(bindingDir, { recursive: true });
writeFileSync(
path.join(bindingDir, "index.js"),
"module.exports = {};"
);
return mockResult({});
}
if (args[0] === "root") {
return mockResult({ status: 0, stdout: "/nowhere\n" });
}
return mockResult({ status: 1 });
});
const store = resolveStore({
isKeyringEnabled: true,
isNonInteractiveOrCI: false,
});
expect(store.kind).toBe("encrypted-file");
expect(installCalls).toBe(1);
});
it("memoizes install failures so the install is not retried within the session", ({
expect,
}) => {
stubPlatform("win32");
let installCalls = 0;
setNpmRunner((args) => {
if (args[0] === "install") {
installCalls += 1;
return mockResult({ status: 1, stderr: "boom" });
}
return mockResult({ status: 0, stdout: "/nowhere\n" });
});
const { getActiveStore } = createCredentialStorageContext({
serviceName: "wrangler",
getConfigPath: () => getGlobalConfigPath(),
isKeyringEnabled: () => true,
logger: silentLogger,
isNonInteractiveOrCI: () => false,
cliName: "wrangler",
});
expect(getActiveStore().kind).toBe("file");
expect(getActiveStore().kind).toBe("file");
expect(getActiveStore().kind).toBe("file");
expect(installCalls).toBe(1);
});
it("hard-errors when CLOUDFLARE_AUTH_USE_KEYRING=true and install fails", ({
expect,
}) => {
stubPlatform("win32");
vi.stubEnv("CLOUDFLARE_AUTH_USE_KEYRING", "true");
setNpmRunner((args) => {
if (args[0] === "install") {
return mockResult({ status: 1, stderr: "boom" });
}
return mockResult({ status: 0, stdout: "/nowhere\n" });
});
expect(() =>
resolveStore({ isKeyringEnabled: true, isNonInteractiveOrCI: false })
).toThrow();
});
});
describe("unsupported platform", () => {
it("falls back to file with a warning by default", ({ expect }) => {
stubPlatform("freebsd" as NodeJS.Platform);
const store = resolveStore({ isKeyringEnabled: true });
expect(store.kind).toBe("file");
expect(warn).toHaveBeenCalledWith(
expect.stringContaining("not supported on `freebsd`")
);
});
});
});
it("existsSync import is preserved for type-narrow checks", ({ expect }) => {
// Sanity test to keep linters from removing the import in the future.
expect(typeof existsSync).toBe("function");
});