@aminya/dotenv-vault
Version:
A secrets manager for .env files – from the same people that pioneered dotenv.
137 lines (135 loc) • 5.64 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.LoginService = void 0;
const tslib_1 = require("tslib");
const crypto = tslib_1.__importStar(require("crypto"));
const chalk_1 = tslib_1.__importDefault(require("chalk"));
const axios_1 = tslib_1.__importDefault(require("axios"));
const fs_1 = require("fs");
const vars_1 = require("../vars");
const core_1 = require("@oclif/core");
const append_to_ignore_service_1 = require("../services/append-to-ignore-service");
const log_service_1 = require("../services/log-service");
const abort_service_1 = require("../services/abort-service");
class LoginService {
constructor(attrs = {}) {
this.cmd = attrs.cmd;
this.dotenvMe = attrs.dotenvMe;
this.yes = attrs.yes;
this.log = new log_service_1.LogService({ cmd: attrs.cmd });
this.abort = new abort_service_1.AbortService({ cmd: attrs.cmd });
const rand = crypto.randomBytes(32).toString('hex');
this.requestUid = `req_${rand}`;
this.checkCount = 0;
}
async run() {
new append_to_ignore_service_1.AppendToIgnoreService().run();
if (vars_1.vars.missingEnvVault) {
this.abort.missingEnvVault();
}
if (vars_1.vars.emptyEnvVault) {
this.abort.emptyEnvVault();
}
// Step 2 B
if (this.dotenvMe) {
if (vars_1.vars.invalidMeValue(this.dotenvMe)) {
this.abort.invalidEnvMe();
}
core_1.CliUx.ux.action.start(this.startingMessage());
await core_1.CliUx.ux.wait(1000);
core_1.CliUx.ux.action.stop();
const msg = this.doneMessage(this.dotenvMe); // must be prior to writeFile in order to check for existance of .env.me or not
(0, fs_1.writeFileSync)('.env.me', this.meFileContent(this.dotenvMe));
this.log.local(msg);
this.log.plain('');
this.log.plain(`Next run ${chalk_1.default.bold(`${vars_1.vars.cli} pull`)} or ${chalk_1.default.bold(`${vars_1.vars.cli} push`)}`);
return;
}
await this.login();
}
async login(tip = true) {
if (!this.yes) {
this.log.local(`Login URL: ${this.loginUrl}`);
const answer = await core_1.CliUx.ux.prompt(`${chalk_1.default.dim(this.log.pretextLocal)}Press ${chalk_1.default.green('y')} (or any key) to open up the browser to login and generate credential (.env.me) or ${chalk_1.default.yellow('q')} to exit`);
if (answer === 'q' || answer === 'Q') {
this.abort.quit();
}
}
this.log.local(`Opening browser to ${this.loginUrl}`);
core_1.CliUx.ux.open(this.loginUrl).catch(_ => { });
core_1.CliUx.ux.action.start(`${chalk_1.default.dim(this.log.pretextLocal)}Waiting for login and credential (.env.me) to be generated`);
await this.check(tip);
}
async check(tip = true) {
if (this.controller) {
this.controller.abort();
}
this.controller = new AbortController();
const options = {
method: 'POST',
headers: { 'content-type': 'application/json' },
data: {
vaultUid: vars_1.vars.vaultValue,
requestUid: this.requestUid,
},
url: this.checkUrl,
signal: this.controller.signal,
};
let resp;
try {
this.checkCount += 1;
resp = await (0, axios_1.default)(options);
}
catch (error) {
resp = error.response;
}
finally {
if (resp.status < 300) {
// Step 3
core_1.CliUx.ux.action.stop();
const meUid = resp.data.data.meUid;
const msg = this.doneMessage(meUid); // must be prior to writeFile in order to check for existance of .env.me or not
(0, fs_1.writeFileSync)('.env.me', this.meFileContent(meUid));
this.log.local(msg);
if (tip) {
this.log.plain('');
this.log.plain(`Next run ${chalk_1.default.bold(`${vars_1.vars.cli} open`)}`);
}
}
else if (this.checkCount < 50) {
// 404 - keep trying
await core_1.CliUx.ux.wait(2000); // check every 2 seconds
await this.check(tip); // check again
}
else {
core_1.CliUx.ux.action.stop('giving up');
this.log.local('Things were taking too long... gave up. Please try again.');
}
}
}
meFileContent(value) {
const s = `${vars_1.vars.meFileHeaderComment}
DOTENV_ME="${value}"
`;
return s;
}
startingMessage() {
if ((0, fs_1.existsSync)('.env.me')) {
return `${chalk_1.default.dim(this.log.pretextLocal)}Updating .env.me (DOTENV_ME)`;
}
return `${chalk_1.default.dim(this.log.pretextLocal)}Creating .env.me (DOTENV_ME)`;
}
doneMessage(meUid) {
if ((0, fs_1.existsSync)('.env.me')) {
return `Updated .env.me (DOTENV_ME=${meUid.slice(0, 9)}...)`;
}
return `Created .env.me (DOTENV_ME=${meUid.slice(0, 9)}...)`;
}
get loginUrl() {
return `${vars_1.vars.apiUrl}/login?DOTENV_VAULT=${vars_1.vars.vaultValue}&requestUid=${this.requestUid}`;
}
get checkUrl() {
return `${vars_1.vars.apiUrl}/check?DOTENV_VAULT=${vars_1.vars.vaultValue}&requestUid=${this.requestUid}`;
}
}
exports.LoginService = LoginService;