Add secret ref validation

This commit is contained in:
Jill Regan
2026-02-18 17:24:55 -05:00
parent 24235f3b6b
commit 6911316fe3
2 changed files with 80 additions and 3 deletions

View File

@@ -1,7 +1,7 @@
import * as core from "@actions/core";
import * as exec from "@actions/exec";
import { read, setClientInfo } from "@1password/op-js";
import { createClient } from "@1password/sdk";
import { createClient, Secrets } from "@1password/sdk";
import {
extractSecret,
loadSecrets,
@@ -25,6 +25,9 @@ jest.mock("@actions/exec", () => ({
jest.mock("@1password/op-js");
jest.mock("@1password/sdk", () => ({
createClient: jest.fn(),
Secrets: {
validateSecretReference: jest.fn(),
},
}));
beforeEach(() => {
@@ -170,11 +173,24 @@ describe("loadSecrets when using Connect", () => {
expect(core.exportVariable).not.toHaveBeenCalled();
});
it("fails with clear message when a secret reference is invalid", async () => {
(Secrets.validateSecretReference as jest.Mock).mockImplementationOnce(
() => {
throw new Error("invalid reference format");
},
);
process.env.MOCK_SECRET = "op://bad/invalid-ref";
await expect(loadSecrets(true)).rejects.toThrow(
"Invalid secret reference(s): MOCK_SECRET",
);
});
describe("core.exportVariable", () => {
it("is called when shouldExportEnv is true", async () => {
await loadSecrets(true);
expect(core.exportVariable).toHaveBeenCalledTimes(1);
expect(core.exportVariable).toHaveBeenCalledTimes(2);
});
it("is not called when shouldExportEnv is false", async () => {
@@ -334,6 +350,40 @@ describe("loadSecrets when using Service Account", () => {
expect(core.setSecret).toHaveBeenCalledTimes(3);
});
});
describe("secret reference validation", () => {
it("fails with clear message when a secret reference is invalid", async () => {
process.env.MY_SECRET = "op://invalid/ref/form";
(Secrets.validateSecretReference as jest.Mock).mockImplementationOnce(
() => {
throw new Error("invalid reference format");
},
);
await expect(loadSecrets(true)).rejects.toThrow(
"Invalid secret reference(s): MY_SECRET",
);
expect(mockResolve).not.toHaveBeenCalled();
});
it("validates all refs before resolving any secrets", async () => {
process.env.MY_SECRET = "op://vault/item/field";
process.env.OTHER = "op://vault/other/item";
(Secrets.validateSecretReference as jest.Mock).mockImplementation(
(ref: string) => {
if (ref === "op://vault/other/item") {
throw new Error("invalid");
}
},
);
mockResolve.mockResolvedValue("value1");
await expect(loadSecrets(false)).rejects.toThrow(
"Invalid secret reference(s): OTHER",
);
expect(mockResolve).not.toHaveBeenCalled();
});
});
});
describe("unsetPrevious", () => {