firebase-admin 6.2.0 → 6.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- /*! firebase-admin v6.2.0 */
1
+ /*! firebase-admin v6.5.1 */
2
2
  "use strict";
3
3
  /*!
4
4
  * Copyright 2017 Google Inc.
@@ -1,4 +1,4 @@
1
- /*! firebase-admin v6.2.0 */
1
+ /*! firebase-admin v6.5.1 */
2
2
  "use strict";
3
3
  /*!
4
4
  * Copyright 2017 Google Inc.
@@ -26,12 +26,12 @@ var __extends = (this && this.__extends) || (function () {
26
26
  };
27
27
  })();
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
- var deep_copy_1 = require("./deep-copy");
30
29
  var error_1 = require("./error");
31
30
  var validator = require("./validator");
32
31
  var http = require("http");
33
32
  var https = require("https");
34
33
  var url = require("url");
34
+ var events_1 = require("events");
35
35
  var DefaultHttpResponse = /** @class */ (function () {
36
36
  /**
37
37
  * Constructs a new HttpResponse from the given LowLevelResponse.
@@ -129,11 +129,10 @@ exports.HttpClient = HttpClient;
129
129
  * Sends an HTTP request based on the provided configuration. This is a wrapper around the http and https
130
130
  * packages of Node.js, providing content processing, timeouts and error handling.
131
131
  */
132
- function sendRequest(httpRequestConfig) {
133
- var config = deep_copy_1.deepCopy(httpRequestConfig);
132
+ function sendRequest(config) {
134
133
  return new Promise(function (resolve, reject) {
135
134
  var data;
136
- var headers = config.headers || {};
135
+ var headers = Object.assign({}, config.headers);
137
136
  var fullUrl = config.url;
138
137
  if (config.data) {
139
138
  // GET and HEAD do not support body in request.
@@ -142,13 +141,14 @@ function sendRequest(httpRequestConfig) {
142
141
  return reject(createError(config.method + " requests cannot have a body", config));
143
142
  }
144
143
  // Parse URL and append data to query string.
145
- var configUrl = new url.URL(fullUrl);
146
- for (var key in config.data) {
147
- if (config.data.hasOwnProperty(key)) {
148
- configUrl.searchParams.append(key, config.data[key]);
144
+ var parsedUrl = new url.URL(fullUrl);
145
+ var dataObj = config.data;
146
+ for (var key in dataObj) {
147
+ if (dataObj.hasOwnProperty(key)) {
148
+ parsedUrl.searchParams.append(key, dataObj[key]);
149
149
  }
150
150
  }
151
- fullUrl = configUrl.toString();
151
+ fullUrl = parsedUrl.toString();
152
152
  }
153
153
  else if (validator.isObject(config.data)) {
154
154
  data = Buffer.from(JSON.stringify(config.data), 'utf-8');
@@ -173,11 +173,16 @@ function sendRequest(httpRequestConfig) {
173
173
  var parsed = url.parse(fullUrl);
174
174
  var protocol = parsed.protocol || 'https:';
175
175
  var isHttps = protocol === 'https:';
176
+ var port = parsed.port;
177
+ if (!port) {
178
+ port = isHttps ? '443' : '80';
179
+ }
176
180
  var options = {
177
181
  hostname: parsed.hostname,
178
- port: parsed.port,
182
+ port: port,
179
183
  path: parsed.path,
180
184
  method: config.method,
185
+ agent: config.httpAgent,
181
186
  headers: headers,
182
187
  };
183
188
  var transport = isHttps ? https : http;
@@ -278,10 +283,13 @@ var AuthorizedHttpClient = /** @class */ (function (_super) {
278
283
  AuthorizedHttpClient.prototype.send = function (request) {
279
284
  var _this = this;
280
285
  return this.app.INTERNAL.getToken().then(function (accessTokenObj) {
281
- var requestCopy = deep_copy_1.deepCopy(request);
282
- requestCopy.headers = requestCopy.headers || {};
286
+ var requestCopy = Object.assign({}, request);
287
+ requestCopy.headers = Object.assign({}, request.headers);
283
288
  var authHeader = 'Authorization';
284
289
  requestCopy.headers[authHeader] = "Bearer " + accessTokenObj.accessToken;
290
+ if (!requestCopy.httpAgent && _this.app.options.httpAgent) {
291
+ requestCopy.httpAgent = _this.app.options.httpAgent;
292
+ }
285
293
  return _super.prototype.send.call(_this, requestCopy);
286
294
  });
287
295
  };
@@ -340,3 +348,110 @@ var ApiSettings = /** @class */ (function () {
340
348
  return ApiSettings;
341
349
  }());
342
350
  exports.ApiSettings = ApiSettings;
351
+ /**
352
+ * Class used for polling an endpoint with exponential backoff.
353
+ *
354
+ * Example usage:
355
+ * ```
356
+ * const poller = new ExponentialBackoffPoller();
357
+ * poller
358
+ * .poll(() => {
359
+ * return myRequestToPoll()
360
+ * .then((responseData: any) => {
361
+ * if (!isValid(responseData)) {
362
+ * // Continue polling.
363
+ * return null;
364
+ * }
365
+ *
366
+ * // Polling complete. Resolve promise with final response data.
367
+ * return responseData;
368
+ * });
369
+ * })
370
+ * .then((responseData: any) => {
371
+ * console.log(`Final response: ${responseData}`);
372
+ * });
373
+ * ```
374
+ */
375
+ var ExponentialBackoffPoller = /** @class */ (function (_super) {
376
+ __extends(ExponentialBackoffPoller, _super);
377
+ function ExponentialBackoffPoller(initialPollingDelayMillis, maxPollingDelayMillis, masterTimeoutMillis) {
378
+ if (initialPollingDelayMillis === void 0) { initialPollingDelayMillis = 1000; }
379
+ if (maxPollingDelayMillis === void 0) { maxPollingDelayMillis = 10000; }
380
+ if (masterTimeoutMillis === void 0) { masterTimeoutMillis = 60000; }
381
+ var _this = _super.call(this) || this;
382
+ _this.initialPollingDelayMillis = initialPollingDelayMillis;
383
+ _this.maxPollingDelayMillis = maxPollingDelayMillis;
384
+ _this.masterTimeoutMillis = masterTimeoutMillis;
385
+ _this.numTries = 0;
386
+ _this.completed = false;
387
+ return _this;
388
+ }
389
+ /**
390
+ * Poll the provided callback with exponential backoff.
391
+ *
392
+ * @param {() => Promise<object>} callback The callback to be called for each poll. If the
393
+ * callback resolves to a falsey value, polling will continue. Otherwise, the truthy
394
+ * resolution will be used to resolve the promise returned by this method.
395
+ * @return {Promise<object>} A Promise which resolves to the truthy value returned by the provided
396
+ * callback when polling is complete.
397
+ */
398
+ ExponentialBackoffPoller.prototype.poll = function (callback) {
399
+ var _this = this;
400
+ if (this.pollCallback) {
401
+ throw new Error('poll() can only be called once per instance of ExponentialBackoffPoller');
402
+ }
403
+ this.pollCallback = callback;
404
+ this.on('poll', this.repoll);
405
+ this.masterTimer = setTimeout(function () {
406
+ if (_this.completed) {
407
+ return;
408
+ }
409
+ _this.markCompleted();
410
+ _this.reject(new Error('ExponentialBackoffPoller deadline exceeded - Master timeout reached'));
411
+ }, this.masterTimeoutMillis);
412
+ return new Promise(function (resolve, reject) {
413
+ _this.resolve = resolve;
414
+ _this.reject = reject;
415
+ _this.repoll();
416
+ });
417
+ };
418
+ ExponentialBackoffPoller.prototype.repoll = function () {
419
+ var _this = this;
420
+ this.pollCallback()
421
+ .then(function (result) {
422
+ if (_this.completed) {
423
+ return;
424
+ }
425
+ if (!result) {
426
+ _this.repollTimer =
427
+ setTimeout(function () { return _this.emit('poll'); }, _this.getPollingDelayMillis());
428
+ _this.numTries++;
429
+ return;
430
+ }
431
+ _this.markCompleted();
432
+ _this.resolve(result);
433
+ })
434
+ .catch(function (err) {
435
+ if (_this.completed) {
436
+ return;
437
+ }
438
+ _this.markCompleted();
439
+ _this.reject(err);
440
+ });
441
+ };
442
+ ExponentialBackoffPoller.prototype.getPollingDelayMillis = function () {
443
+ var increasedPollingDelay = Math.pow(2, this.numTries) * this.initialPollingDelayMillis;
444
+ return Math.min(increasedPollingDelay, this.maxPollingDelayMillis);
445
+ };
446
+ ExponentialBackoffPoller.prototype.markCompleted = function () {
447
+ this.completed = true;
448
+ if (this.masterTimer) {
449
+ clearTimeout(this.masterTimer);
450
+ }
451
+ if (this.repollTimer) {
452
+ clearTimeout(this.repollTimer);
453
+ }
454
+ };
455
+ return ExponentialBackoffPoller;
456
+ }(events_1.EventEmitter));
457
+ exports.ExponentialBackoffPoller = ExponentialBackoffPoller;
@@ -1,4 +1,4 @@
1
- /*! firebase-admin v6.2.0 */
1
+ /*! firebase-admin v6.5.1 */
2
2
  "use strict";
3
3
  /*!
4
4
  * Copyright 2017 Google Inc.
@@ -1,4 +1,4 @@
1
- /*! firebase-admin v6.2.0 */
1
+ /*! firebase-admin v6.5.1 */
2
2
  "use strict";
3
3
  /*!
4
4
  * Copyright 2017 Google Inc.
@@ -158,10 +158,19 @@ var FirebaseAuthError = /** @class */ (function (_super) {
158
158
  * @return {FirebaseAuthError} The corresponding developer-facing error.
159
159
  */
160
160
  FirebaseAuthError.fromServerError = function (serverErrorCode, message, rawServerResponse) {
161
+ // serverErrorCode could contain additional details:
162
+ // ERROR_CODE : Detailed message which can also contain colons
163
+ var colonSeparator = (serverErrorCode || '').indexOf(':');
164
+ var customMessage = null;
165
+ if (colonSeparator !== -1) {
166
+ customMessage = serverErrorCode.substring(colonSeparator + 1).trim();
167
+ serverErrorCode = serverErrorCode.substring(0, colonSeparator).trim();
168
+ }
161
169
  // If not found, default to internal error.
162
170
  var clientCodeKey = AUTH_SERVER_TO_CLIENT_CODE[serverErrorCode] || 'INTERNAL_ERROR';
163
171
  var error = deep_copy_1.deepCopy(AuthClientErrorCode[clientCodeKey]);
164
- error.message = message || error.message;
172
+ // Server detailed message should have highest priority.
173
+ error.message = customMessage || message || error.message;
165
174
  if (clientCodeKey === 'INTERNAL_ERROR' && typeof rawServerResponse !== 'undefined') {
166
175
  try {
167
176
  error.message += " Raw server response: \"" + JSON.stringify(rawServerResponse) + "\"";
@@ -288,6 +297,21 @@ var FirebaseMessagingError = /** @class */ (function (_super) {
288
297
  return FirebaseMessagingError;
289
298
  }(PrefixedFirebaseError));
290
299
  exports.FirebaseMessagingError = FirebaseMessagingError;
300
+ /**
301
+ * Firebase project management error code structure. This extends PrefixedFirebaseError.
302
+ *
303
+ * @param {ProjectManagementErrorCode} code The error code.
304
+ * @param {string} message The error message.
305
+ * @constructor
306
+ */
307
+ var FirebaseProjectManagementError = /** @class */ (function (_super) {
308
+ __extends(FirebaseProjectManagementError, _super);
309
+ function FirebaseProjectManagementError(code, message) {
310
+ return _super.call(this, 'project-management', code, message) || this;
311
+ }
312
+ return FirebaseProjectManagementError;
313
+ }(PrefixedFirebaseError));
314
+ exports.FirebaseProjectManagementError = FirebaseProjectManagementError;
291
315
  /**
292
316
  * App client error codes and their default messages.
293
317
  */
@@ -317,6 +341,10 @@ var AuthClientErrorCode = /** @class */ (function () {
317
341
  code: 'claims-too-large',
318
342
  message: 'Developer claims maximum payload size exceeded.',
319
343
  };
344
+ AuthClientErrorCode.CONFIGURATION_NOT_FOUND = {
345
+ code: 'configuration-not-found',
346
+ message: 'There is no configuration corresponding to the provided identifier.',
347
+ };
320
348
  AuthClientErrorCode.ID_TOKEN_EXPIRED = {
321
349
  code: 'id-token-expired',
322
350
  message: 'The provided Firebase ID token is expired.',
@@ -663,8 +691,8 @@ exports.InstanceIdClientErrorCode = InstanceIdClientErrorCode;
663
691
  var AUTH_SERVER_TO_CLIENT_CODE = {
664
692
  // Claims payload is too large.
665
693
  CLAIMS_TOO_LARGE: 'CLAIMS_TOO_LARGE',
666
- // Project not found.
667
- CONFIGURATION_NOT_FOUND: 'PROJECT_NOT_FOUND',
694
+ // Configuration not found.
695
+ CONFIGURATION_NOT_FOUND: 'CONFIGURATION_NOT_FOUND',
668
696
  // Provided credential has insufficient permissions.
669
697
  INSUFFICIENT_PERMISSION: 'INSUFFICIENT_PERMISSION',
670
698
  // ActionCodeSettings missing continue URL.
@@ -1,4 +1,4 @@
1
- /*! firebase-admin v6.2.0 */
1
+ /*! firebase-admin v6.5.1 */
2
2
  "use strict";
3
3
  /*!
4
4
  * Copyright 2017 Google Inc.
@@ -1,4 +1,4 @@
1
- /*! firebase-admin v6.2.0 */
1
+ /*! firebase-admin v6.5.1 */
2
2
  "use strict";
3
3
  /*!
4
4
  * Copyright 2017 Google Inc.
@@ -77,6 +77,19 @@ function isString(value) {
77
77
  return typeof value === 'string';
78
78
  }
79
79
  exports.isString = isString;
80
+ /**
81
+ * Validates that a value is a base64 string.
82
+ *
83
+ * @param {any} value The value to validate.
84
+ * @return {boolean} Whether the value is a base64 string or not.
85
+ */
86
+ function isBase64String(value) {
87
+ if (!isString(value)) {
88
+ return false;
89
+ }
90
+ return /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(value);
91
+ }
92
+ exports.isBase64String = isBase64String;
80
93
  /**
81
94
  * Validates that a value is a non-empty string.
82
95
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "firebase-admin",
3
- "version": "6.2.0",
3
+ "version": "6.5.1",
4
4
  "description": "Firebase admin SDK for Node.js",
5
5
  "author": "Firebase <firebase-support@google.com> (https://firebase.google.com/)",
6
6
  "license": "Apache-2.0",
@@ -95,7 +95,7 @@
95
95
  "minimist": "^1.2.0",
96
96
  "mocha": "^5.2.0",
97
97
  "nock": "^9.6.0",
98
- "npm-run-all": "^4.1.2",
98
+ "npm-run-all": "^4.1.5",
99
99
  "nyc": "^11.5.0",
100
100
  "request": "^2.75.0",
101
101
  "request-promise": "^4.1.1",