@heroku-cli/command
Advanced tools
Comparing version 8.0.7 to 8.1.0
@@ -0,1 +1,9 @@ | ||
<a name="8.1.0"></a> | ||
# [8.1.0](https://github.com/heroku/heroku-cli-command/compare/v8.0.7...v8.1.0) (2018-05-06) | ||
### Features | ||
* added login/logout ([#33](https://github.com/heroku/heroku-cli-command/issues/33)) ([c772322](https://github.com/heroku/heroku-cli-command/commit/c772322)) | ||
<a name="8.0.7"></a> | ||
@@ -2,0 +10,0 @@ ## [8.0.7](https://github.com/heroku/heroku-cli-command/compare/v8.0.6...v8.0.7) (2018-05-02) |
import * as Config from '@oclif/config'; | ||
import { CLIError } from '@oclif/errors'; | ||
import { HTTP, HTTPError, HTTPRequestOptions } from 'http-call'; | ||
import { Login } from './login'; | ||
import { Mutex } from './mutex'; | ||
@@ -30,3 +31,5 @@ export interface IOptions { | ||
}; | ||
authPromise?: Promise<HTTP>; | ||
http: typeof HTTP; | ||
private readonly _login; | ||
private _twoFactorMutex; | ||
@@ -36,3 +39,3 @@ private _auth?; | ||
readonly twoFactorMutex: Mutex<string>; | ||
readonly auth: string | undefined; | ||
auth: string | undefined; | ||
twoFactorPrompt(): Promise<string>; | ||
@@ -46,4 +49,6 @@ preauth(app: string, factor: string): Promise<HTTP>; | ||
stream(url: string, options?: HTTPRequestOptions): Promise<HTTP>; | ||
request(url: string, options?: HTTPRequestOptions): Promise<HTTP>; | ||
request(url: string, options?: HTTPRequestOptions): void; | ||
login(opts?: Login.Options): Promise<void>; | ||
logout(): Promise<void>; | ||
readonly defaults: typeof HTTP.defaults; | ||
} |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const errors_1 = require("@oclif/errors"); | ||
const netrc_parser_1 = require("netrc-parser"); | ||
const url = require("url"); | ||
const deps_1 = require("./deps"); | ||
const login_1 = require("./login"); | ||
const vars_1 = require("./vars"); | ||
@@ -32,2 +34,3 @@ class HerokuAPIError extends errors_1.CLIError { | ||
this.options = options; | ||
this._login = new login_1.Login(this.config, this); | ||
this.config = config; | ||
@@ -41,3 +44,2 @@ if (options.required === undefined) | ||
this.preauthPromises = {}; | ||
let auth = this.auth; | ||
let self = this; | ||
@@ -48,4 +50,2 @@ const opts = { | ||
}; | ||
if (auth && !opts.headers.authorization) | ||
opts.headers.authorization = `Bearer ${auth}`; | ||
this.http = class APIHTTPClient extends deps_1.default.HTTP.HTTP.create(opts) { | ||
@@ -70,2 +70,6 @@ static async twoFactorRetry(err, url, opts = {}, retries = 3) { | ||
static async request(url, opts = {}, retries = 3) { | ||
opts.headers = opts.headers || {}; | ||
if (!opts.headers.authorization) { | ||
opts.headers.authorization = `Bearer ${self.auth}`; | ||
} | ||
retries--; | ||
@@ -79,2 +83,9 @@ try { | ||
if (retries > 0) { | ||
if (err.http.statusCode === 401 && err.body.id === 'unauthorized') { | ||
if (!self.authPromise) | ||
self.authPromise = self.login(); | ||
await self.authPromise; | ||
opts.headers.authorization = `Bearer ${self.auth}`; | ||
return this.request(url, opts, retries); | ||
} | ||
if (err.http.statusCode === 403 && err.body.id === 'two_factor') { | ||
@@ -107,2 +118,6 @@ return this.twoFactorRetry(err, url, opts, retries); | ||
} | ||
set auth(token) { | ||
delete this.authPromise; | ||
this._auth = token; | ||
} | ||
twoFactorPrompt() { | ||
@@ -146,4 +161,18 @@ deps_1.default.yubikey.enable(); | ||
request(url, options = {}) { | ||
return this.http.request(url, options); | ||
this.http.request(url, options); | ||
} | ||
login(opts = {}) { | ||
return this._login.login(opts); | ||
} | ||
async logout() { | ||
try { | ||
await this._login.logout(); | ||
} | ||
catch (err) { | ||
errors_1.warn(err); | ||
} | ||
delete netrc_parser_1.default.machines['api.heroku.com']; | ||
delete netrc_parser_1.default.machines['git.heroku.com']; | ||
await netrc_parser_1.default.save(); | ||
} | ||
get defaults() { | ||
@@ -150,0 +179,0 @@ return this.http.defaults; |
@@ -13,10 +13,8 @@ /// <reference types="node" /> | ||
config: CLI.Config; | ||
trace: (...data: any[]) => void; | ||
debug: (...data: any[]) => void; | ||
info: (...data: any[]) => void; | ||
log: (...data: any[]) => void; | ||
warn: (input: string | Error, opts?: CLI.ErrorOptions | undefined) => void; | ||
error: (input: string | Error, opts?: CLI.ErrorOptions | undefined) => void; | ||
fatal: (input: string | Error, opts?: CLI.ErrorOptions | undefined) => void; | ||
exit(code?: number | undefined, error?: Error | undefined): never; | ||
warn: (input: string | Error) => void; | ||
error: (err: string | Error, options?: { | ||
code?: string | undefined; | ||
exit?: number | undefined; | ||
} | undefined) => never; | ||
exit: (code?: number | undefined) => never; | ||
readonly prompt: (name: string, options?: CLI.IPromptOptions | undefined) => Promise<any>; | ||
@@ -30,2 +28,6 @@ readonly confirm: (message: string) => Promise<boolean>; | ||
done(): Promise<void>; | ||
trace(format: string, ...args: string[]): void; | ||
debug(format: string, ...args: string[]): void; | ||
info(format: string, ...args: string[]): void; | ||
log(format: string, ...args: string[]): void; | ||
}; | ||
@@ -32,0 +34,0 @@ readonly HTTP: typeof HTTP; |
@@ -12,2 +12,3 @@ "use strict"; | ||
function exists(f) { | ||
// tslint:disable-next-line | ||
return util_1.promisify(fs.exists)(f); | ||
@@ -14,0 +15,0 @@ } |
{ | ||
"name": "@heroku-cli/command", | ||
"description": "base class for Heroku CLI commands", | ||
"version": "8.0.7", | ||
"version": "8.1.0", | ||
"author": "Jeff Dickey @jdxcode", | ||
"bugs": "https://github.com/heroku/heroku-cli-command/issues", | ||
"dependencies": { | ||
"@oclif/errors": "^1.0.6", | ||
"cli-ux": "^3.4.1", | ||
"@heroku-cli/color": "^1.1.3", | ||
"@oclif/errors": "^1.0.9", | ||
"cli-ux": "^4.0.0", | ||
"debug": "^3.1.0", | ||
"heroku-client": "3.0.6", | ||
"http-call": "^5.1.1", | ||
"netrc-parser": "^3.1.4" | ||
"http-call": "^5.1.2", | ||
"netrc-parser": "^3.1.4", | ||
"opn": "^5.3.0" | ||
}, | ||
"devDependencies": { | ||
"@heroku-cli/tslint": "^1.1.4", | ||
"@oclif/command": "^1.4.17", | ||
"@oclif/config": "^1.6.16", | ||
"@oclif/tslint": "^1.1.0", | ||
"@oclif/command": "^1.4.21", | ||
"@oclif/config": "^1.6.17", | ||
"@oclif/tslint": "^1.1.1", | ||
"@types/ansi-styles": "^2.0.30", | ||
@@ -24,7 +26,9 @@ "@types/chai": "^4.1.3", | ||
"@types/nock": "9.1.3", | ||
"@types/node": "^8.10.11", | ||
"@types/node": "^10.0.4", | ||
"@types/opn": "^5.1.0", | ||
"@types/proxyquire": "^1.3.28", | ||
"@types/sinon": "^4.3.1", | ||
"@types/supports-color": "^5.3.0", | ||
"chai": "^4.1.2", | ||
"fancy-test": "^1.0.5", | ||
"fancy-test": "^1.0.6", | ||
"mocha": "^5.1.1", | ||
@@ -34,6 +38,6 @@ "nock": "9.2.5", | ||
"proxyquire": "^2.0.1", | ||
"sinon": "^5.0.1", | ||
"testdouble": "^3.8.0", | ||
"ts-node": "^6.0.2", | ||
"tslint": "^5.9.1", | ||
"sinon": "^5.0.4", | ||
"testdouble": "^3.8.1", | ||
"ts-node": "^6.0.3", | ||
"tslint": "^5.10.0", | ||
"typescript": "2.8.3" | ||
@@ -40,0 +44,0 @@ }, |
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 2 instances in 1 package
45300
35
1115
8
24
16
13
+ Added@heroku-cli/color@^1.1.3
+ Addedopn@^5.3.0
+ Added@heroku-cli/color@1.1.16(transitive)
+ Addedansi-escapes@3.2.0(transitive)
+ Addedansi-regex@4.1.1(transitive)
+ Addedclean-stack@2.2.0(transitive)
+ Addedcli-ux@4.9.3(transitive)
+ Addedfs-extra@7.0.1(transitive)
+ Addedhas-flag@2.0.0(transitive)
+ Addedhyperlinker@1.0.0(transitive)
+ Addedis-wsl@1.1.0(transitive)
+ Addedopn@5.5.0(transitive)
+ Addedstrip-ansi@5.2.0(transitive)
+ Addedsupports-hyperlinks@1.0.1(transitive)
+ Addedtreeify@1.1.0(transitive)
+ Addedtslib@1.14.1(transitive)
- Removedansi-regex@3.0.1(transitive)
- Removedclean-stack@1.3.0(transitive)
- Removedcli-ux@3.5.0(transitive)
- Removedfs-extra@6.0.1(transitive)
- Removedstrip-ansi@4.0.0(transitive)
Updated@oclif/errors@^1.0.9
Updatedcli-ux@^4.0.0
Updatedhttp-call@^5.1.2