Fix linting errors
This commit is contained in:
16
src/index.ts
16
src/index.ts
@@ -1,9 +1,7 @@
|
|||||||
import dotenv from "dotenv";
|
import dotenv from "dotenv";
|
||||||
import * as core from "@actions/core";
|
import * as core from "@actions/core";
|
||||||
import { validateCli } from "@1password/op-js";
|
|
||||||
import { installCliOnGithubActionRunner } from "./op-cli-installer";
|
|
||||||
import { loadSecrets, unsetPrevious, validateAuth } from "./utils";
|
import { loadSecrets, unsetPrevious, validateAuth } from "./utils";
|
||||||
import { envFilePath, envConnectHost, envConnectToken } from "./constants";
|
import { envFilePath } from "./constants";
|
||||||
|
|
||||||
const loadSecretsAction = async () => {
|
const loadSecretsAction = async () => {
|
||||||
try {
|
try {
|
||||||
@@ -42,16 +40,4 @@ const loadSecretsAction = async () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// This function's name is an exception from the naming convention
|
|
||||||
// since we refer to the 1Password CLI here.
|
|
||||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
||||||
const installCLI = async (): Promise<void> => {
|
|
||||||
// validateCli checks if there's an existing 1Password CLI installed on the runner.
|
|
||||||
// If there's no CLI installed, then validateCli will throw an error, which we will use
|
|
||||||
// as an indicator that we need to execute the installation script.
|
|
||||||
await validateCli().catch(async () => {
|
|
||||||
await installCliOnGithubActionRunner();
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
void loadSecretsAction();
|
void loadSecretsAction();
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import * as core from "@actions/core";
|
|||||||
import * as exec from "@actions/exec";
|
import * as exec from "@actions/exec";
|
||||||
import { read, setClientInfo } from "@1password/op-js";
|
import { read, setClientInfo } from "@1password/op-js";
|
||||||
import { createClient, Secrets } from "@1password/sdk";
|
import { createClient, Secrets } from "@1password/sdk";
|
||||||
|
import { OnePasswordConnect } from "@1password/connect";
|
||||||
import {
|
import {
|
||||||
extractSecret,
|
extractSecret,
|
||||||
loadSecrets,
|
loadSecrets,
|
||||||
@@ -15,7 +16,6 @@ import {
|
|||||||
envManagedVariables,
|
envManagedVariables,
|
||||||
envServiceAccountToken,
|
envServiceAccountToken,
|
||||||
} from "./constants";
|
} from "./constants";
|
||||||
import { OnePasswordConnect } from "@1password/connect";
|
|
||||||
|
|
||||||
jest.mock("@actions/core");
|
jest.mock("@actions/core");
|
||||||
jest.mock("@actions/exec", () => ({
|
jest.mock("@actions/exec", () => ({
|
||||||
@@ -154,12 +154,6 @@ describe("extractSecret", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("loadSecrets when using Connect", () => {
|
describe("loadSecrets when using Connect", () => {
|
||||||
beforeEach(() => {
|
|
||||||
process.env[envConnectHost] = "https://localhost:8000";
|
|
||||||
process.env[envConnectToken] = "token";
|
|
||||||
process.env[envServiceAccountToken] = "";
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
process.env[envConnectHost] = "https://connect.example";
|
process.env[envConnectHost] = "https://connect.example";
|
||||||
process.env[envConnectToken] = "test-token";
|
process.env[envConnectToken] = "test-token";
|
||||||
|
|||||||
88
src/utils.ts
88
src/utils.ts
@@ -11,8 +11,8 @@ import {
|
|||||||
envManagedVariables,
|
envManagedVariables,
|
||||||
} from "./constants";
|
} from "./constants";
|
||||||
|
|
||||||
// Types for parsed op ref
|
// #region Op ref parsing
|
||||||
export interface ParsedOpRef {
|
interface ParsedOpRef {
|
||||||
vault: string;
|
vault: string;
|
||||||
item: string;
|
item: string;
|
||||||
section: string | undefined;
|
section: string | undefined;
|
||||||
@@ -69,7 +69,9 @@ const parseOpRef = (ref: string): ParsedOpRef => {
|
|||||||
section,
|
section,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
// #endregion
|
||||||
|
|
||||||
|
// #region Connect item resolution
|
||||||
const getSecretFromConnectItem = async (
|
const getSecretFromConnectItem = async (
|
||||||
client: OPConnect,
|
client: OPConnect,
|
||||||
item: FullItem,
|
item: FullItem,
|
||||||
@@ -129,8 +131,6 @@ const findSectionIdsByQuery = (
|
|||||||
return ids;
|
return ids;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const findMatchingFieldAndFile = (
|
const findMatchingFieldAndFile = (
|
||||||
item: FullItem,
|
item: FullItem,
|
||||||
fieldOrFileQuery: string,
|
fieldOrFileQuery: string,
|
||||||
@@ -150,7 +150,7 @@ const findMatchingFieldAndFile = (
|
|||||||
const matchingFields = fields.filter((f) => {
|
const matchingFields = fields.filter((f) => {
|
||||||
const fieldIdOrLabelMatchesQuery = f.id === fieldOrFileQuery || f.label === fieldOrFileQuery;
|
const fieldIdOrLabelMatchesQuery = f.id === fieldOrFileQuery || f.label === fieldOrFileQuery;
|
||||||
const sectionId = f.section?.id;
|
const sectionId = f.section?.id;
|
||||||
const fieldSectionIsInRefSections = sectionId != null && sectionIds.includes(sectionId);
|
const fieldSectionIsInRefSections = sectionId !== null && sectionId !== undefined && sectionIds.includes(sectionId);
|
||||||
return fieldIdOrLabelMatchesQuery && fieldSectionIsInRefSections;
|
return fieldIdOrLabelMatchesQuery && fieldSectionIsInRefSections;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -163,7 +163,7 @@ const findMatchingFieldAndFile = (
|
|||||||
const matchingFiles = files.filter((f) => {
|
const matchingFiles = files.filter((f) => {
|
||||||
const fileIdOrNameMatchesQuery = f.id === fieldOrFileQuery || f.name === fieldOrFileQuery;
|
const fileIdOrNameMatchesQuery = f.id === fieldOrFileQuery || f.name === fieldOrFileQuery;
|
||||||
const sectionId = f.section?.id;
|
const sectionId = f.section?.id;
|
||||||
const fileSectionIsInRefSections = sectionId != null && sectionIds.includes(sectionId);
|
const fileSectionIsInRefSections = sectionId !== null && sectionId !== undefined && sectionIds.includes(sectionId);
|
||||||
return fileIdOrNameMatchesQuery && fileSectionIsInRefSections;
|
return fileIdOrNameMatchesQuery && fileSectionIsInRefSections;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -173,9 +173,9 @@ const findMatchingFieldAndFile = (
|
|||||||
}
|
}
|
||||||
matchedFile = matchingFiles[0];
|
matchedFile = matchingFiles[0];
|
||||||
} else {
|
} else {
|
||||||
let matchingFields = fields.filter((f) => {
|
const matchingFields = fields.filter((f) => {
|
||||||
const fieldIdOrLabelMatchesQuery = f.id === fieldOrFileQuery || f.label === fieldOrFileQuery;
|
const fieldIdOrLabelMatchesQuery = f.id === fieldOrFileQuery || f.label === fieldOrFileQuery;
|
||||||
const fieldHasNoSection = f.section?.id == null;
|
const fieldHasNoSection = (f.section?.id === null || f.section?.id === undefined);
|
||||||
return fieldIdOrLabelMatchesQuery && fieldHasNoSection;
|
return fieldIdOrLabelMatchesQuery && fieldHasNoSection;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -188,7 +188,7 @@ const findMatchingFieldAndFile = (
|
|||||||
// If no field was found with no section, find a field in any section
|
// If no field was found with no section, find a field in any section
|
||||||
if (!matchedField) {
|
if (!matchedField) {
|
||||||
const matchingFieldsInAnySection = fields.filter((f) => {
|
const matchingFieldsInAnySection = fields.filter((f) => {
|
||||||
const fieldIdOrLabelMatchesQuery =f.id === fieldOrFileQuery || f.label === fieldOrFileQuery;
|
const fieldIdOrLabelMatchesQuery = f.id === fieldOrFileQuery || f.label === fieldOrFileQuery;
|
||||||
return fieldIdOrLabelMatchesQuery;
|
return fieldIdOrLabelMatchesQuery;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -198,9 +198,9 @@ const findMatchingFieldAndFile = (
|
|||||||
matchedField = matchingFieldsInAnySection[0];
|
matchedField = matchingFieldsInAnySection[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
let matchingFiles = files.filter((f) => {
|
const matchingFiles = files.filter((f) => {
|
||||||
const fileIdOrNameMatchesQuery = f.id === fieldOrFileQuery || f.name === fieldOrFileQuery;
|
const fileIdOrNameMatchesQuery = f.id === fieldOrFileQuery || f.name === fieldOrFileQuery;
|
||||||
const fileHasNoSection = f.section?.id == null;
|
const fileHasNoSection = (f.section?.id === null || f.section?.id === undefined);
|
||||||
return fileIdOrNameMatchesQuery && fileHasNoSection;
|
return fileIdOrNameMatchesQuery && fileHasNoSection;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -246,26 +246,9 @@ const findMatchingFieldAndFile = (
|
|||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
// #endregion
|
||||||
|
|
||||||
export const validateAuth = (): void => {
|
// #region Shared helpers and auth
|
||||||
const isConnect = process.env[envConnectHost] && process.env[envConnectToken];
|
|
||||||
const isServiceAccount = process.env[envServiceAccountToken];
|
|
||||||
|
|
||||||
if (isConnect && isServiceAccount) {
|
|
||||||
core.warning(
|
|
||||||
"WARNING: Both service account and Connect credentials are provided. Connect credentials will take priority.",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isConnect && !isServiceAccount) {
|
|
||||||
throw new Error(authErr);
|
|
||||||
}
|
|
||||||
|
|
||||||
const authType = isConnect ? "Connect" : "Service account";
|
|
||||||
|
|
||||||
core.info(`Authenticated with ${authType}.`);
|
|
||||||
};
|
|
||||||
|
|
||||||
const getEnvVarNamesWithSecretRefs = (): string[] =>
|
const getEnvVarNamesWithSecretRefs = (): string[] =>
|
||||||
Object.keys(process.env).filter(
|
Object.keys(process.env).filter(
|
||||||
(key) =>
|
(key) =>
|
||||||
@@ -313,6 +296,25 @@ const setResolvedSecret = (
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const validateAuth = (): void => {
|
||||||
|
const isConnect = process.env[envConnectHost] && process.env[envConnectToken];
|
||||||
|
const isServiceAccount = process.env[envServiceAccountToken];
|
||||||
|
|
||||||
|
if (isConnect && isServiceAccount) {
|
||||||
|
core.warning(
|
||||||
|
"WARNING: Both service account and Connect credentials are provided. Connect credentials will take priority.",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isConnect && !isServiceAccount) {
|
||||||
|
throw new Error(authErr);
|
||||||
|
}
|
||||||
|
|
||||||
|
const authType = isConnect ? "Connect" : "Service account";
|
||||||
|
|
||||||
|
core.info(`Authenticated with ${authType}.`);
|
||||||
|
};
|
||||||
|
|
||||||
export const extractSecret = (
|
export const extractSecret = (
|
||||||
envName: string,
|
envName: string,
|
||||||
shouldExportEnv: boolean,
|
shouldExportEnv: boolean,
|
||||||
@@ -330,6 +332,19 @@ export const extractSecret = (
|
|||||||
setResolvedSecret(envName, secretValue, shouldExportEnv);
|
setResolvedSecret(envName, secretValue, shouldExportEnv);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const unsetPrevious = (): void => {
|
||||||
|
if (process.env[envManagedVariables]) {
|
||||||
|
core.info("Unsetting previous values ...");
|
||||||
|
const managedEnvs = process.env[envManagedVariables].split(",");
|
||||||
|
for (const envName of managedEnvs) {
|
||||||
|
core.info(`Unsetting ${envName}`);
|
||||||
|
core.exportVariable(envName, "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// #endregion
|
||||||
|
|
||||||
|
// #region Load secrets
|
||||||
// Connect loads secrets via the Connect JS SDK
|
// Connect loads secrets via the Connect JS SDK
|
||||||
const loadSecretsViaConnect = async (
|
const loadSecretsViaConnect = async (
|
||||||
shouldExportEnv: boolean,
|
shouldExportEnv: boolean,
|
||||||
@@ -351,6 +366,7 @@ const loadSecretsViaConnect = async (
|
|||||||
let client;
|
let client;
|
||||||
try {
|
try {
|
||||||
client = OnePasswordConnect({
|
client = OnePasswordConnect({
|
||||||
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||||
serverURL: host,
|
serverURL: host,
|
||||||
token,
|
token,
|
||||||
});
|
});
|
||||||
@@ -435,14 +451,4 @@ export const loadSecrets = async (shouldExportEnv: boolean): Promise<void> => {
|
|||||||
|
|
||||||
await loadSecretsViaServiceAccount(shouldExportEnv);
|
await loadSecretsViaServiceAccount(shouldExportEnv);
|
||||||
};
|
};
|
||||||
|
// #endregion
|
||||||
export const unsetPrevious = (): void => {
|
|
||||||
if (process.env[envManagedVariables]) {
|
|
||||||
core.info("Unsetting previous values ...");
|
|
||||||
const managedEnvs = process.env[envManagedVariables].split(",");
|
|
||||||
for (const envName of managedEnvs) {
|
|
||||||
core.info(`Unsetting ${envName}`);
|
|
||||||
core.exportVariable(envName, "");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|||||||
Reference in New Issue
Block a user