New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

cli-engine-heroku

Package Overview
Dependencies
Maintainers
4
Versions
61
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

cli-engine-heroku - npm Package Compare versions

Comparing version

to
1.1.0

lib/mutex.js

73

lib/api_client.js

@@ -12,2 +12,10 @@ 'use strict';

var _yubikey = require('./yubikey');
var _yubikey2 = _interopRequireDefault(_yubikey);
var _mutex = require('./mutex');
var _mutex2 = _interopRequireDefault(_mutex);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

@@ -25,3 +33,4 @@

if (info.length) super([options.message, ''].concat(info).join('\n'));else super(options.message);
this.httpError = httpError;
this.http = httpError;
this.body = options;
}

@@ -32,5 +41,8 @@ }

class Heroku extends _http2.default {
constructor(output, options = {}) {
super(output);
constructor(command, options = {}) {
super(command.out);
if (options.required === undefined) options.required = true;
options.preauth = options.preauth !== false;
this.cmd = command;
this.options = options;

@@ -42,12 +54,37 @@ this.requestOptions.host = 'api.heroku.com';

this.requestOptions.headers['accept'] = 'application/vnd.heroku+json; version=3';
this.twoFactorMutex = new _mutex2.default();
this.preauthPromises = {};
let self = this;
this.http = class extends this.http {
async request() {
self._logRequest(this);
static async twoFactorRetry(err, url, opts = {}, retries = 3) {
const app = err.body.app ? err.body.app.name : null;
if (!app || !options.preauth) {
opts.headers['Heroku-Two-Factor-Code'] = await self.twoFactorPrompt();
return this.request(url, opts, retries);
} else {
// if multiple requests are run in parallel for the same app, we should
// only preauth for the first so save the fact we already preauthed
if (!self.preauthPromises[app]) {
self.preauthPromises[app] = self.twoFactorPrompt().then(factor => self.preauth(app, factor));
}
await self.preauthPromises[app];
return this.request(url, opts, retries);
}
}
static async request(url, opts, retries = 3) {
retries--;
try {
await super.request();
return await super.request(url, opts);
} catch (err) {
if (err.__httpcall) throw new HerokuAPIError(err);else throw err;
if (!err.__httpcall) throw err;
let apiError = new HerokuAPIError(err);
if (retries > 0) {
if (apiError.http.statusCode === 403 && apiError.body.id === 'two_factor') {
return this.twoFactorRetry(apiError, url, opts, retries);
}
}
throw apiError;
}
self._logResponse(this);
}

@@ -67,3 +104,23 @@ };

}
twoFactorPrompt() {
_yubikey2.default.enable();
return this.twoFactorMutex.synchronize(async () => {
try {
let factor = await this.out.prompt('Two-factor code', { mask: true });
_yubikey2.default.disable();
return factor;
} catch (err) {
_yubikey2.default.disable();
throw err;
}
});
}
preauth(app, factor) {
return this.put(`/apps/${app}/pre-authorizations`, {
headers: { 'Heroku-Two-Factor-Code': factor }
});
}
}
exports.default = Heroku;

2

lib/command.js

@@ -26,3 +26,3 @@ 'use strict';

if (this._heroku) return this._heroku;
this._heroku = new _api_client2.default(this.out);
this._heroku = new _api_client2.default(this);
return this._heroku;

@@ -29,0 +29,0 @@ }

{
"name": "cli-engine-heroku",
"description": "heroku specific functionality for the cli-engine",
"version": "1.0.1",
"version": "1.1.0",
"author": "Jeff Dickey @dickeyxxx",

@@ -18,3 +18,3 @@ "bugs": "https://github.com/heroku/cli-engine-heroku/issues",

"babel-plugin-transform-flow-strip-types": "6.22.0",
"cli-engine-command": "^5.0.2",
"cli-engine-command": "5.0.3",
"cli-engine-config": "^1.3.6",

@@ -21,0 +21,0 @@ "eslint": "3.19.0",

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet