UNPKG

envilder

Version:

A CLI and GitHub Action that securely centralizes your environment variables from AWS SSM or Azure Key Vault as a single source of truth

120 lines 4.62 kB
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; import { spawn } from 'node:child_process'; import { createInterface } from 'node:readline'; import { SsoSessionExpiredError } from '../../../core/domain/errors/DomainErrors.js'; import { presentError } from '../errors/CliErrorPresenter.js'; import { SilentExitError } from '../errors/SilentExitError.js'; const AWS_CLI_NOT_FOUND = -1; const LOGIN_FAILED = 1; export function buildLoginArgs(profileName) { if (profileName) { return ['sso', 'login', '--profile', profileName]; } return ['sso', 'login']; } function defaultIsInteractive() { return [process.stdout.isTTY, process.stdin.isTTY].every(Boolean); } function defaultConfirm(question) { const prompt = createInterface({ input: process.stdin, output: process.stdout, }); return new Promise((resolve) => { prompt.question(`${question} `, (answer) => { prompt.close(); resolve(answer.trim().toLowerCase() === 'y'); }); }); } function defaultRunLogin(profileName) { return new Promise((resolve) => { const child = spawn('aws', buildLoginArgs(profileName), { stdio: 'inherit', }); child.on('error', (error) => { resolve(error.code === 'ENOENT' ? AWS_CLI_NOT_FOUND : LOGIN_FAILED); }); child.on('close', (code) => { resolve(code !== null && code !== void 0 ? code : LOGIN_FAILED); }); }); } function defaultWrite(message) { console.error(message); } const defaultDeps = { isInteractive: defaultIsInteractive, confirm: defaultConfirm, runLogin: defaultRunLogin, write: defaultWrite, }; export function executeWithSsoRecovery(run_1) { return __awaiter(this, arguments, void 0, function* (run, deps = {}) { const resolved = Object.assign(Object.assign({}, defaultDeps), deps); try { return yield run(); } catch (error) { if (!(error instanceof SsoSessionExpiredError)) { throw error; } if (!resolved.isInteractive()) { throw error; } yield recoverInteractively(run, error, resolved); } }); } function recoverInteractively(run, error, deps) { return __awaiter(this, void 0, void 0, function* () { deps.write(presentError(error)); const command = error.profileName ? `aws sso login --profile ${error.profileName}` : 'aws sso login'; const accepted = yield deps.confirm(`Run '${command}' now? [y/N]`); if (!accepted) { deps.write('Skipped. Run the command above when ready, then re-run envilder.'); throw new SilentExitError(LOGIN_FAILED); } const exitCode = yield deps.runLogin(error.profileName); ensureLoginSucceeded(exitCode, deps); yield retryOnce(run, deps); }); } function ensureLoginSucceeded(exitCode, deps) { if (exitCode === AWS_CLI_NOT_FOUND) { deps.write('The AWS CLI was not found on your PATH. Install it, then run the command above.'); throw new SilentExitError(LOGIN_FAILED); } if (exitCode !== 0) { deps.write('Login did not complete. Try again, then re-run envilder.'); throw new SilentExitError(LOGIN_FAILED); } } function retryOnce(run, deps) { return __awaiter(this, void 0, void 0, function* () { deps.write('\uD83C\uDF44 1-UP! SSO session restored.'); deps.write('\u21bb Warping back for your secrets\u2026'); try { yield run(); deps.write('\u2b50 Level cleared.'); } catch (retryError) { if (retryError instanceof SsoSessionExpiredError) { deps.write(presentError(retryError)); throw new SilentExitError(LOGIN_FAILED); } throw retryError; } }); } //# sourceMappingURL=SsoLoginRecovery.js.map