Comparing version 2.3.0 to 2.3.1
@@ -0,1 +1,7 @@ | ||
/** | ||
* Copyright 2018 Google LLC | ||
* | ||
* Distributed under MIT license. | ||
* See file LICENSE for detail or copy at https://opensource.org/licenses/MIT | ||
*/ | ||
export interface Credentials { | ||
@@ -58,4 +64,4 @@ privateKey: string; | ||
getCredentials(keyFile: string): Promise<Credentials>; | ||
private getTokenAsync(); | ||
private ensureEmail(); | ||
private getTokenAsync; | ||
private ensureEmail; | ||
/** | ||
@@ -68,3 +74,3 @@ * Revoke the token if one is set. | ||
revokeToken(callback: (err?: Error) => void): void; | ||
private revokeTokenAsync(); | ||
private revokeTokenAsync; | ||
/** | ||
@@ -74,7 +80,7 @@ * Configure the GoogleToken for re-use. | ||
*/ | ||
private configure(options?); | ||
private configure; | ||
/** | ||
* Request the token from Google. | ||
*/ | ||
private requestToken(); | ||
private requestToken; | ||
} |
"use strict"; | ||
var __extends = (this && this.__extends) || (function () { | ||
var extendStatics = Object.setPrototypeOf || | ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || | ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; | ||
return function (d, b) { | ||
extendStatics(d, b); | ||
function __() { this.constructor = d; } | ||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); | ||
}; | ||
})(); | ||
/** | ||
* Copyright 2018 Google LLC | ||
* | ||
* Distributed under MIT license. | ||
* See file LICENSE for detail or copy at https://opensource.org/licenses/MIT | ||
*/ | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
@@ -20,50 +16,19 @@ return new (P || (P = Promise))(function (resolve, reject) { | ||
}; | ||
var __generator = (this && this.__generator) || function (thisArg, body) { | ||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; | ||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; | ||
function verb(n) { return function (v) { return step([n, v]); }; } | ||
function step(op) { | ||
if (f) throw new TypeError("Generator is already executing."); | ||
while (_) try { | ||
if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t; | ||
if (y = 0, t) op = [0, t.value]; | ||
switch (op[0]) { | ||
case 0: case 1: t = op; break; | ||
case 4: _.label++; return { value: op[1], done: false }; | ||
case 5: _.label++; y = op[1]; op = [0]; continue; | ||
case 7: op = _.ops.pop(); _.trys.pop(); continue; | ||
default: | ||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } | ||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } | ||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } | ||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } | ||
if (t[2]) _.ops.pop(); | ||
_.trys.pop(); continue; | ||
} | ||
op = body.call(thisArg, _); | ||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } | ||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; | ||
} | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var axios_1 = require("axios"); | ||
var fs = require("fs"); | ||
var jws = require("jws"); | ||
var mime = require("mime"); | ||
var pify = require("pify"); | ||
var querystring = require("querystring"); | ||
var readFile = pify(fs.readFile); | ||
var GOOGLE_TOKEN_URL = 'https://www.googleapis.com/oauth2/v4/token'; | ||
var GOOGLE_REVOKE_TOKEN_URL = 'https://accounts.google.com/o/oauth2/revoke?token='; | ||
var ErrorWithCode = /** @class */ (function (_super) { | ||
__extends(ErrorWithCode, _super); | ||
function ErrorWithCode(message, code) { | ||
var _this = _super.call(this, message) || this; | ||
_this.code = code; | ||
return _this; | ||
const fs = require("fs"); | ||
const gaxios_1 = require("gaxios"); | ||
const jws = require("jws"); | ||
const mime = require("mime"); | ||
const pify = require("pify"); | ||
const readFile = pify(fs.readFile); | ||
const GOOGLE_TOKEN_URL = 'https://www.googleapis.com/oauth2/v4/token'; | ||
const GOOGLE_REVOKE_TOKEN_URL = 'https://accounts.google.com/o/oauth2/revoke?token='; | ||
class ErrorWithCode extends Error { | ||
constructor(message, code) { | ||
super(message); | ||
this.code = code; | ||
} | ||
return ErrorWithCode; | ||
}(Error)); | ||
var getPem; | ||
var GoogleToken = /** @class */ (function () { | ||
} | ||
let getPem; | ||
class GoogleToken { | ||
/** | ||
@@ -74,3 +39,3 @@ * Create a GoogleToken. | ||
*/ | ||
function GoogleToken(options) { | ||
constructor(options) { | ||
this.token = null; | ||
@@ -87,4 +52,4 @@ this.expiresAt = null; | ||
*/ | ||
GoogleToken.prototype.hasExpired = function () { | ||
var now = (new Date()).getTime(); | ||
hasExpired() { | ||
const now = (new Date()).getTime(); | ||
if (this.token && this.expiresAt) { | ||
@@ -96,7 +61,7 @@ return now >= this.expiresAt; | ||
} | ||
}; | ||
GoogleToken.prototype.getToken = function (callback) { | ||
} | ||
getToken(callback) { | ||
if (callback) { | ||
this.getTokenAsync() | ||
.then(function (t) { | ||
.then(t => { | ||
callback(null, t); | ||
@@ -108,3 +73,3 @@ }) | ||
return this.getTokenAsync(); | ||
}; | ||
} | ||
/** | ||
@@ -115,105 +80,88 @@ * Given a keyFile, extract the key and client email if available | ||
*/ | ||
GoogleToken.prototype.getCredentials = function (keyFile) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var mimeType, _a, key, body, privateKey, clientEmail, privateKey, privateKey; | ||
return __generator(this, function (_b) { | ||
switch (_b.label) { | ||
case 0: | ||
mimeType = mime.getType(keyFile); | ||
_a = mimeType; | ||
switch (_a) { | ||
case 'application/json': return [3 /*break*/, 1]; | ||
case 'application/x-x509-ca-cert': return [3 /*break*/, 3]; | ||
case 'application/x-pkcs12': return [3 /*break*/, 5]; | ||
} | ||
return [3 /*break*/, 9]; | ||
case 1: return [4 /*yield*/, readFile(keyFile, 'utf8')]; | ||
case 2: | ||
key = _b.sent(); | ||
body = JSON.parse(key); | ||
privateKey = body.private_key; | ||
clientEmail = body.client_email; | ||
if (!privateKey || !clientEmail) { | ||
throw new ErrorWithCode('private_key and client_email are required.', 'MISSING_CREDENTIALS'); | ||
} | ||
return [2 /*return*/, { privateKey: privateKey, clientEmail: clientEmail }]; | ||
case 3: return [4 /*yield*/, readFile(keyFile, 'utf8')]; | ||
case 4: | ||
privateKey = _b.sent(); | ||
return [2 /*return*/, { privateKey: privateKey }]; | ||
case 5: | ||
if (!!getPem) return [3 /*break*/, 7]; | ||
return [4 /*yield*/, Promise.resolve().then(function () { return require('google-p12-pem'); })]; | ||
case 6: | ||
getPem = (_b.sent()).getPem; | ||
_b.label = 7; | ||
case 7: return [4 /*yield*/, getPem(keyFile)]; | ||
case 8: | ||
privateKey = _b.sent(); | ||
return [2 /*return*/, { privateKey: privateKey }]; | ||
case 9: throw new ErrorWithCode('Unknown certificate type. Type is determined based on file extension. ' + | ||
getCredentials(keyFile) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const mimeType = mime.getType(keyFile); | ||
switch (mimeType) { | ||
case 'application/json': { | ||
// *.json file | ||
const key = yield readFile(keyFile, 'utf8'); | ||
const body = JSON.parse(key); | ||
const privateKey = body.private_key; | ||
const clientEmail = body.client_email; | ||
if (!privateKey || !clientEmail) { | ||
throw new ErrorWithCode('private_key and client_email are required.', 'MISSING_CREDENTIALS'); | ||
} | ||
return { privateKey, clientEmail }; | ||
} | ||
case 'application/x-x509-ca-cert': { | ||
// *.pem file | ||
const privateKey = yield readFile(keyFile, 'utf8'); | ||
return { privateKey }; | ||
} | ||
case 'application/x-pkcs12': { | ||
// *.p12 file | ||
// NOTE: The loading of `google-p12-pem` is deferred for performance | ||
// reasons. The `node-forge` npm module in `google-p12-pem` adds a fair | ||
// bit time to overall module loading, and is likely not frequently | ||
// used. In a future release, p12 support will be entirely removed. | ||
if (!getPem) { | ||
getPem = (yield Promise.resolve().then(() => require('google-p12-pem'))).getPem; | ||
} | ||
const privateKey = yield getPem(keyFile); | ||
return { privateKey }; | ||
} | ||
default: | ||
throw new ErrorWithCode('Unknown certificate type. Type is determined based on file extension. ' + | ||
'Current supported extensions are *.json, *.pem, and *.p12.', 'UNKNOWN_CERTIFICATE_TYPE'); | ||
} | ||
}); | ||
} | ||
}); | ||
}; | ||
GoogleToken.prototype.getTokenAsync = function () { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var creds; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
if (!this.hasExpired()) { | ||
return [2 /*return*/, Promise.resolve(this.token)]; | ||
} | ||
if (!this.key && !this.keyFile) { | ||
throw new Error('No key or keyFile set.'); | ||
} | ||
if (!(!this.key && this.keyFile)) return [3 /*break*/, 2]; | ||
return [4 /*yield*/, this.getCredentials(this.keyFile)]; | ||
case 1: | ||
creds = _a.sent(); | ||
this.key = creds.privateKey; | ||
this.iss = creds.clientEmail || this.iss; | ||
if (!creds.clientEmail) { | ||
this.ensureEmail(); | ||
} | ||
_a.label = 2; | ||
case 2: return [2 /*return*/, this.requestToken()]; | ||
} | ||
getTokenAsync() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
if (!this.hasExpired()) { | ||
return Promise.resolve(this.token); | ||
} | ||
if (!this.key && !this.keyFile) { | ||
throw new Error('No key or keyFile set.'); | ||
} | ||
if (!this.key && this.keyFile) { | ||
const creds = yield this.getCredentials(this.keyFile); | ||
this.key = creds.privateKey; | ||
this.iss = creds.clientEmail || this.iss; | ||
if (!creds.clientEmail) { | ||
this.ensureEmail(); | ||
} | ||
}); | ||
} | ||
return this.requestToken(); | ||
}); | ||
}; | ||
GoogleToken.prototype.ensureEmail = function () { | ||
} | ||
ensureEmail() { | ||
if (!this.iss) { | ||
throw new ErrorWithCode('email is required.', 'MISSING_CREDENTIALS'); | ||
} | ||
}; | ||
GoogleToken.prototype.revokeToken = function (callback) { | ||
} | ||
revokeToken(callback) { | ||
if (callback) { | ||
this.revokeTokenAsync().then(function () { return callback(); }).catch(callback); | ||
this.revokeTokenAsync().then(() => callback()).catch(callback); | ||
return; | ||
} | ||
return this.revokeTokenAsync(); | ||
}; | ||
GoogleToken.prototype.revokeTokenAsync = function () { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var _this = this; | ||
return __generator(this, function (_a) { | ||
if (!this.token) { | ||
throw new Error('No token to revoke.'); | ||
} | ||
return [2 /*return*/, axios_1.default.get(GOOGLE_REVOKE_TOKEN_URL + this.token).then(function (r) { | ||
_this.configure({ | ||
email: _this.iss, | ||
sub: _this.sub, | ||
key: _this.key, | ||
keyFile: _this.keyFile, | ||
scope: _this.scope, | ||
additionalClaims: _this.additionalClaims, | ||
}); | ||
})]; | ||
} | ||
revokeTokenAsync() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
if (!this.token) { | ||
throw new Error('No token to revoke.'); | ||
} | ||
return gaxios_1.request({ url: GOOGLE_REVOKE_TOKEN_URL + this.token }).then(r => { | ||
this.configure({ | ||
email: this.iss, | ||
sub: this.sub, | ||
key: this.key, | ||
keyFile: this.keyFile, | ||
scope: this.scope, | ||
additionalClaims: this.additionalClaims, | ||
}); | ||
}); | ||
}); | ||
}; | ||
} | ||
/** | ||
@@ -223,4 +171,3 @@ * Configure the GoogleToken for re-use. | ||
*/ | ||
GoogleToken.prototype.configure = function (options) { | ||
if (options === void 0) { options = {}; } | ||
configure(options = {}) { | ||
this.keyFile = options.keyFile; | ||
@@ -238,53 +185,52 @@ this.key = options.key; | ||
} | ||
}; | ||
} | ||
/** | ||
* Request the token from Google. | ||
*/ | ||
GoogleToken.prototype.requestToken = function () { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var _this = this; | ||
var iat, additionalClaims, payload, signedJWT; | ||
return __generator(this, function (_a) { | ||
iat = Math.floor(new Date().getTime() / 1000); | ||
additionalClaims = this.additionalClaims || {}; | ||
payload = Object.assign({ | ||
iss: this.iss, | ||
scope: this.scope, | ||
aud: GOOGLE_TOKEN_URL, | ||
exp: iat + 3600, | ||
iat: iat, | ||
sub: this.sub | ||
}, additionalClaims); | ||
signedJWT = jws.sign({ header: { alg: 'RS256' }, payload: payload, secret: this.key }); | ||
return [2 /*return*/, axios_1.default | ||
.post(GOOGLE_TOKEN_URL, querystring.stringify({ | ||
grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer', | ||
assertion: signedJWT | ||
}), { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }) | ||
.then(function (r) { | ||
_this.rawToken = r.data; | ||
_this.token = r.data.access_token; | ||
_this.expiresAt = | ||
(r.data.expires_in === null || r.data.expires_in === undefined) ? | ||
null : | ||
(iat + r.data.expires_in) * 1000; | ||
return _this.token; | ||
}) | ||
.catch(function (e) { | ||
_this.token = null; | ||
_this.tokenExpires = null; | ||
var body = (e.response && e.response.data) ? e.response.data : {}; | ||
var err = e; | ||
if (body.error) { | ||
var desc = body.error_description ? ": " + body.error_description : ''; | ||
err = new Error("" + body.error + desc); | ||
} | ||
throw err; | ||
})]; | ||
requestToken() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const iat = Math.floor(new Date().getTime() / 1000); | ||
const additionalClaims = this.additionalClaims || {}; | ||
const payload = Object.assign({ | ||
iss: this.iss, | ||
scope: this.scope, | ||
aud: GOOGLE_TOKEN_URL, | ||
exp: iat + 3600, | ||
iat, | ||
sub: this.sub | ||
}, additionalClaims); | ||
const signedJWT = jws.sign({ header: { alg: 'RS256' }, payload, secret: this.key }); | ||
return gaxios_1.request({ | ||
method: 'POST', | ||
url: GOOGLE_TOKEN_URL, | ||
data: { | ||
grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer', | ||
assertion: signedJWT | ||
}, | ||
headers: { 'Content-Type': 'application/x-www-form-urlencoded' } | ||
}) | ||
.then(r => { | ||
this.rawToken = r.data; | ||
this.token = r.data.access_token; | ||
this.expiresAt = | ||
(r.data.expires_in === null || r.data.expires_in === undefined) ? | ||
null : | ||
(iat + r.data.expires_in) * 1000; | ||
return this.token; | ||
}) | ||
.catch(e => { | ||
this.token = null; | ||
this.tokenExpires = null; | ||
const body = (e.response && e.response.data) ? e.response.data : {}; | ||
let err = e; | ||
if (body.error) { | ||
const desc = body.error_description ? `: ${body.error_description}` : ''; | ||
err = new Error(`${body.error}${desc}`); | ||
} | ||
throw err; | ||
}); | ||
}); | ||
}; | ||
return GoogleToken; | ||
}()); | ||
} | ||
} | ||
exports.GoogleToken = GoogleToken; | ||
//# sourceMappingURL=index.js.map |
{ | ||
"name": "gtoken", | ||
"version": "2.3.0", | ||
"version": "2.3.1", | ||
"description": "Node.js Google Authentication Service Account Tokens", | ||
"main": "./build/src/index.js", | ||
"types": "./build/src/index.d.ts", | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/google/node-gtoken.git" | ||
"engines": { | ||
"node": ">=6.0.0" | ||
}, | ||
"repository": "google/node-gtoken", | ||
"scripts": { | ||
"check": "gts check", | ||
"lint": "gts check", | ||
"clean": "gts clean", | ||
@@ -17,7 +17,8 @@ "codecov": "nyc report --reporter=json && codecov -f coverage/*.json", | ||
"compile": "tsc -p .", | ||
"test": "nyc mocha build/test --timeout 5000 --require source-map-support/register", | ||
"test": "nyc mocha build/test", | ||
"prepare": "npm run compile", | ||
"pretest": "npm run compile", | ||
"posttest": "npm run check && npm run license-check", | ||
"license-check": "jsgl --local ." | ||
"system-test": "echo no system tests 👻", | ||
"samples-test": "cd samples/ && npm link ../ && npm test && cd ../", | ||
"docs": "echo no docs 👻" | ||
}, | ||
@@ -38,7 +39,7 @@ "keywords": [ | ||
"dependencies": { | ||
"axios": "^0.18.0", | ||
"gaxios": "^1.0.2", | ||
"google-p12-pem": "^1.0.0", | ||
"jws": "^3.1.4", | ||
"jws": "^3.1.5", | ||
"mime": "^2.2.0", | ||
"pify": "^3.0.0" | ||
"pify": "^4.0.0" | ||
}, | ||
@@ -50,24 +51,21 @@ "devDependencies": { | ||
"@types/nock": "^9.1.2", | ||
"@types/node": "^9.4.6", | ||
"@types/node": "^10.0.3", | ||
"@types/pify": "^3.0.0", | ||
"codecov": "^3.0.0", | ||
"gts": "^0.5.3", | ||
"codecov": "^3.0.2", | ||
"gts": "^0.9.0", | ||
"intelli-espower-loader": "^1.0.1", | ||
"js-green-licenses": "^0.5.0", | ||
"mocha": "^5.0.1", | ||
"js-green-licenses": "^0.5.0", | ||
"nock": "^9.1.6", | ||
"nyc": "^11.4.1", | ||
"source-map-support": "^0.5.3", | ||
"typescript": "~2.7.2" | ||
"nock": "^10.0.0", | ||
"nyc": "^13.0.0", | ||
"source-map-support": "^0.5.6", | ||
"typescript": "~3.2.0" | ||
}, | ||
"files": [ | ||
"build/src", | ||
"!build/src/**/*.map", | ||
"LICENSE", | ||
"packge.json", | ||
"README.md" | ||
], | ||
"nyc": { | ||
"exclude": [ | ||
"build/test" | ||
] | ||
} | ||
] | ||
} |
@@ -9,3 +9,2 @@ # node-gtoken | ||
[![codecov][codecov-image]][codecov-url] | ||
[![Greenkeeper badge][greenkeeper-image]][greenkeeper-url] | ||
[![style badge][gts-image]][gts-url] | ||
@@ -194,4 +193,2 @@ | ||
[gdevconsole]: https://console.developers.google.com | ||
[greenkeeper-image]: https://badges.greenkeeper.io/google/node-gtoken.svg | ||
[greenkeeper-url]: https://greenkeeper.io/ | ||
[gts-image]: https://img.shields.io/badge/code%20style-Google%20%E2%98%82%EF%B8%8F-blue.svg | ||
@@ -198,0 +195,0 @@ [gts-url]: https://www.npmjs.com/package/gts |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
24012
15
310
198
2
1
+ Addedgaxios@^1.0.2
+ Addedabort-controller@3.0.0(transitive)
+ Addedagent-base@4.3.0(transitive)
+ Addeddebug@3.2.7(transitive)
+ Addedes6-promise@4.2.8(transitive)
+ Addedes6-promisify@5.0.0(transitive)
+ Addedevent-target-shim@5.0.1(transitive)
+ Addedextend@3.0.2(transitive)
+ Addedgaxios@1.8.4(transitive)
+ Addedhttps-proxy-agent@2.2.4(transitive)
+ Addedms@2.1.3(transitive)
+ Addednode-fetch@2.7.0(transitive)
+ Addedtr46@0.0.3(transitive)
+ Addedwebidl-conversions@3.0.1(transitive)
+ Addedwhatwg-url@5.0.0(transitive)
- Removedaxios@^0.18.0
- Removedaxios@0.18.1(transitive)
- Removedfollow-redirects@1.5.10(transitive)
- Removedis-buffer@2.0.5(transitive)
- Removedpify@3.0.0(transitive)
Updatedjws@^3.1.5
Updatedpify@^4.0.0