mirror of
https://github.com/musix-org/musix-oss
synced 2025-06-17 10:46:01 +00:00
Modules
This commit is contained in:
833
node_modules/firebase-admin/lib/utils/api-request.js
generated
vendored
Normal file
833
node_modules/firebase-admin/lib/utils/api-request.js
generated
vendored
Normal file
@ -0,0 +1,833 @@
|
||||
/*! firebase-admin v8.9.2 */
|
||||
"use strict";
|
||||
/*!
|
||||
* Copyright 2017 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
var __extends = (this && this.__extends) || (function () {
|
||||
var extendStatics = function (d, b) {
|
||||
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 extendStatics(d, b);
|
||||
};
|
||||
return function (d, b) {
|
||||
extendStatics(d, b);
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
})();
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
var error_1 = require("./error");
|
||||
var validator = require("./validator");
|
||||
var http = require("http");
|
||||
var https = require("https");
|
||||
var url = require("url");
|
||||
var events_1 = require("events");
|
||||
var DefaultHttpResponse = /** @class */ (function () {
|
||||
/**
|
||||
* Constructs a new HttpResponse from the given LowLevelResponse.
|
||||
*/
|
||||
function DefaultHttpResponse(resp) {
|
||||
this.status = resp.status;
|
||||
this.headers = resp.headers;
|
||||
this.text = resp.data;
|
||||
try {
|
||||
if (!resp.data) {
|
||||
throw new error_1.FirebaseAppError(error_1.AppErrorCodes.INTERNAL_ERROR, 'HTTP response missing data.');
|
||||
}
|
||||
this.parsedData = JSON.parse(resp.data);
|
||||
}
|
||||
catch (err) {
|
||||
this.parsedData = undefined;
|
||||
this.parseError = err;
|
||||
}
|
||||
this.request = resp.config.method + " " + resp.config.url;
|
||||
}
|
||||
Object.defineProperty(DefaultHttpResponse.prototype, "data", {
|
||||
get: function () {
|
||||
if (this.isJson()) {
|
||||
return this.parsedData;
|
||||
}
|
||||
throw new error_1.FirebaseAppError(error_1.AppErrorCodes.UNABLE_TO_PARSE_RESPONSE, "Error while parsing response data: \"" + this.parseError.toString() + "\". Raw server " +
|
||||
("response: \"" + this.text + "\". Status code: \"" + this.status + "\". Outgoing ") +
|
||||
("request: \"" + this.request + ".\""));
|
||||
},
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
DefaultHttpResponse.prototype.isJson = function () {
|
||||
return typeof this.parsedData !== 'undefined';
|
||||
};
|
||||
return DefaultHttpResponse;
|
||||
}());
|
||||
/**
|
||||
* Represents a multipart HTTP response. Parts that constitute the response body can be accessed
|
||||
* via the multipart getter. Getters for text and data throw errors.
|
||||
*/
|
||||
var MultipartHttpResponse = /** @class */ (function () {
|
||||
function MultipartHttpResponse(resp) {
|
||||
this.status = resp.status;
|
||||
this.headers = resp.headers;
|
||||
this.multipart = resp.multipart;
|
||||
}
|
||||
Object.defineProperty(MultipartHttpResponse.prototype, "text", {
|
||||
get: function () {
|
||||
throw new error_1.FirebaseAppError(error_1.AppErrorCodes.UNABLE_TO_PARSE_RESPONSE, 'Unable to parse multipart payload as text');
|
||||
},
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
Object.defineProperty(MultipartHttpResponse.prototype, "data", {
|
||||
get: function () {
|
||||
throw new error_1.FirebaseAppError(error_1.AppErrorCodes.UNABLE_TO_PARSE_RESPONSE, 'Unable to parse multipart payload as JSON');
|
||||
},
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
MultipartHttpResponse.prototype.isJson = function () {
|
||||
return false;
|
||||
};
|
||||
return MultipartHttpResponse;
|
||||
}());
|
||||
var HttpError = /** @class */ (function (_super) {
|
||||
__extends(HttpError, _super);
|
||||
function HttpError(response) {
|
||||
var _this = _super.call(this, "Server responded with status " + response.status + ".") || this;
|
||||
_this.response = response;
|
||||
// Set the prototype so that instanceof checks will work correctly.
|
||||
// See: https://github.com/Microsoft/TypeScript/issues/13965
|
||||
Object.setPrototypeOf(_this, HttpError.prototype);
|
||||
return _this;
|
||||
}
|
||||
return HttpError;
|
||||
}(Error));
|
||||
exports.HttpError = HttpError;
|
||||
/**
|
||||
* Default retry configuration for HTTP requests. Retries up to 4 times on connection reset and timeout errors
|
||||
* as well as HTTP 503 errors. Exposed as a function to ensure that every HttpClient gets its own RetryConfig
|
||||
* instance.
|
||||
*/
|
||||
function defaultRetryConfig() {
|
||||
return {
|
||||
maxRetries: 4,
|
||||
statusCodes: [503],
|
||||
ioErrorCodes: ['ECONNRESET', 'ETIMEDOUT'],
|
||||
backOffFactor: 0.5,
|
||||
maxDelayInMillis: 60 * 1000,
|
||||
};
|
||||
}
|
||||
exports.defaultRetryConfig = defaultRetryConfig;
|
||||
/**
|
||||
* Ensures that the given RetryConfig object is valid.
|
||||
*
|
||||
* @param retry The configuration to be validated.
|
||||
*/
|
||||
function validateRetryConfig(retry) {
|
||||
if (!validator.isNumber(retry.maxRetries) || retry.maxRetries < 0) {
|
||||
throw new error_1.FirebaseAppError(error_1.AppErrorCodes.INVALID_ARGUMENT, 'maxRetries must be a non-negative integer');
|
||||
}
|
||||
if (typeof retry.backOffFactor !== 'undefined') {
|
||||
if (!validator.isNumber(retry.backOffFactor) || retry.backOffFactor < 0) {
|
||||
throw new error_1.FirebaseAppError(error_1.AppErrorCodes.INVALID_ARGUMENT, 'backOffFactor must be a non-negative number');
|
||||
}
|
||||
}
|
||||
if (!validator.isNumber(retry.maxDelayInMillis) || retry.maxDelayInMillis < 0) {
|
||||
throw new error_1.FirebaseAppError(error_1.AppErrorCodes.INVALID_ARGUMENT, 'maxDelayInMillis must be a non-negative integer');
|
||||
}
|
||||
if (typeof retry.statusCodes !== 'undefined' && !validator.isArray(retry.statusCodes)) {
|
||||
throw new error_1.FirebaseAppError(error_1.AppErrorCodes.INVALID_ARGUMENT, 'statusCodes must be an array');
|
||||
}
|
||||
if (typeof retry.ioErrorCodes !== 'undefined' && !validator.isArray(retry.ioErrorCodes)) {
|
||||
throw new error_1.FirebaseAppError(error_1.AppErrorCodes.INVALID_ARGUMENT, 'ioErrorCodes must be an array');
|
||||
}
|
||||
}
|
||||
var HttpClient = /** @class */ (function () {
|
||||
function HttpClient(retry) {
|
||||
if (retry === void 0) { retry = defaultRetryConfig(); }
|
||||
this.retry = retry;
|
||||
if (this.retry) {
|
||||
validateRetryConfig(this.retry);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Sends an HTTP request to a remote server. If the server responds with a successful response (2xx), the returned
|
||||
* promise resolves with an HttpResponse. If the server responds with an error (3xx, 4xx, 5xx), the promise rejects
|
||||
* with an HttpError. In case of all other errors, the promise rejects with a FirebaseAppError. If a request fails
|
||||
* due to a low-level network error, transparently retries the request once before rejecting the promise.
|
||||
*
|
||||
* If the request data is specified as an object, it will be serialized into a JSON string. The application/json
|
||||
* content-type header will also be automatically set in this case. For all other payload types, the content-type
|
||||
* header should be explicitly set by the caller. To send a JSON leaf value (e.g. "foo", 5), parse it into JSON,
|
||||
* and pass as a string or a Buffer along with the appropriate content-type header.
|
||||
*
|
||||
* @param {HttpRequest} config HTTP request to be sent.
|
||||
* @return {Promise<HttpResponse>} A promise that resolves with the response details.
|
||||
*/
|
||||
HttpClient.prototype.send = function (config) {
|
||||
return this.sendWithRetry(config);
|
||||
};
|
||||
/**
|
||||
* Sends an HTTP request. In the event of an error, retries the HTTP request according to the
|
||||
* RetryConfig set on the HttpClient.
|
||||
*
|
||||
* @param {HttpRequestConfig} config HTTP request to be sent.
|
||||
* @param {number} retryAttempts Number of retries performed up to now.
|
||||
* @return {Promise<HttpResponse>} A promise that resolves with the response details.
|
||||
*/
|
||||
HttpClient.prototype.sendWithRetry = function (config, retryAttempts) {
|
||||
var _this = this;
|
||||
if (retryAttempts === void 0) { retryAttempts = 0; }
|
||||
return AsyncHttpCall.invoke(config)
|
||||
.then(function (resp) {
|
||||
return _this.createHttpResponse(resp);
|
||||
})
|
||||
.catch(function (err) {
|
||||
var _a = _this.getRetryDelayMillis(retryAttempts, err), delayMillis = _a[0], canRetry = _a[1];
|
||||
if (canRetry && _this.retry && delayMillis <= _this.retry.maxDelayInMillis) {
|
||||
return _this.waitForRetry(delayMillis).then(function () {
|
||||
return _this.sendWithRetry(config, retryAttempts + 1);
|
||||
});
|
||||
}
|
||||
if (err.response) {
|
||||
throw new HttpError(_this.createHttpResponse(err.response));
|
||||
}
|
||||
if (err.code === 'ETIMEDOUT') {
|
||||
throw new error_1.FirebaseAppError(error_1.AppErrorCodes.NETWORK_TIMEOUT, "Error while making request: " + err.message + ".");
|
||||
}
|
||||
throw new error_1.FirebaseAppError(error_1.AppErrorCodes.NETWORK_ERROR, "Error while making request: " + err.message + ". Error code: " + err.code);
|
||||
});
|
||||
};
|
||||
HttpClient.prototype.createHttpResponse = function (resp) {
|
||||
if (resp.multipart) {
|
||||
return new MultipartHttpResponse(resp);
|
||||
}
|
||||
return new DefaultHttpResponse(resp);
|
||||
};
|
||||
HttpClient.prototype.waitForRetry = function (delayMillis) {
|
||||
if (delayMillis > 0) {
|
||||
return new Promise(function (resolve) {
|
||||
setTimeout(resolve, delayMillis);
|
||||
});
|
||||
}
|
||||
return Promise.resolve();
|
||||
};
|
||||
/**
|
||||
* Checks if a failed request is eligible for a retry, and if so returns the duration to wait before initiating
|
||||
* the retry.
|
||||
*
|
||||
* @param {number} retryAttempts Number of retries completed up to now.
|
||||
* @param {LowLevelError} err The last encountered error.
|
||||
* @returns {[number, boolean]} A 2-tuple where the 1st element is the duration to wait before another retry, and the
|
||||
* 2nd element is a boolean indicating whether the request is eligible for a retry or not.
|
||||
*/
|
||||
HttpClient.prototype.getRetryDelayMillis = function (retryAttempts, err) {
|
||||
if (!this.isRetryEligible(retryAttempts, err)) {
|
||||
return [0, false];
|
||||
}
|
||||
var response = err.response;
|
||||
if (response && response.headers['retry-after']) {
|
||||
var delayMillis = this.parseRetryAfterIntoMillis(response.headers['retry-after']);
|
||||
if (delayMillis > 0) {
|
||||
return [delayMillis, true];
|
||||
}
|
||||
}
|
||||
return [this.backOffDelayMillis(retryAttempts), true];
|
||||
};
|
||||
HttpClient.prototype.isRetryEligible = function (retryAttempts, err) {
|
||||
if (!this.retry) {
|
||||
return false;
|
||||
}
|
||||
if (retryAttempts >= this.retry.maxRetries) {
|
||||
return false;
|
||||
}
|
||||
if (err.response) {
|
||||
var statusCodes = this.retry.statusCodes || [];
|
||||
return statusCodes.indexOf(err.response.status) !== -1;
|
||||
}
|
||||
if (err.code) {
|
||||
var retryCodes = this.retry.ioErrorCodes || [];
|
||||
return retryCodes.indexOf(err.code) !== -1;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
/**
|
||||
* Parses the Retry-After HTTP header as a milliseconds value. Return value is negative if the Retry-After header
|
||||
* contains an expired timestamp or otherwise malformed.
|
||||
*/
|
||||
HttpClient.prototype.parseRetryAfterIntoMillis = function (retryAfter) {
|
||||
var delaySeconds = parseInt(retryAfter, 10);
|
||||
if (!isNaN(delaySeconds)) {
|
||||
return delaySeconds * 1000;
|
||||
}
|
||||
var date = new Date(retryAfter);
|
||||
if (!isNaN(date.getTime())) {
|
||||
return date.getTime() - Date.now();
|
||||
}
|
||||
return -1;
|
||||
};
|
||||
HttpClient.prototype.backOffDelayMillis = function (retryAttempts) {
|
||||
if (retryAttempts === 0) {
|
||||
return 0;
|
||||
}
|
||||
if (!this.retry) {
|
||||
throw new error_1.FirebaseAppError(error_1.AppErrorCodes.INTERNAL_ERROR, 'Expected this.retry to exist.');
|
||||
}
|
||||
var backOffFactor = this.retry.backOffFactor || 0;
|
||||
var delayInSeconds = (Math.pow(2, retryAttempts)) * backOffFactor;
|
||||
return Math.min(delayInSeconds * 1000, this.retry.maxDelayInMillis);
|
||||
};
|
||||
return HttpClient;
|
||||
}());
|
||||
exports.HttpClient = HttpClient;
|
||||
/**
|
||||
* Parses a full HTTP response message containing both a header and a body.
|
||||
*
|
||||
* @param {string|Buffer} response The HTTP response to be parsed.
|
||||
* @param {HttpRequestConfig} config The request configuration that resulted in the HTTP response.
|
||||
* @return {HttpResponse} An object containing the parsed HTTP status, headers and the body.
|
||||
*/
|
||||
function parseHttpResponse(response, config) {
|
||||
var responseText = validator.isBuffer(response) ?
|
||||
response.toString('utf-8') : response;
|
||||
var endOfHeaderPos = responseText.indexOf('\r\n\r\n');
|
||||
var headerLines = responseText.substring(0, endOfHeaderPos).split('\r\n');
|
||||
var statusLine = headerLines[0];
|
||||
var status = statusLine.trim().split(/\s/)[1];
|
||||
var headers = {};
|
||||
headerLines.slice(1).forEach(function (line) {
|
||||
var colonPos = line.indexOf(':');
|
||||
var name = line.substring(0, colonPos).trim().toLowerCase();
|
||||
var value = line.substring(colonPos + 1).trim();
|
||||
headers[name] = value;
|
||||
});
|
||||
var data = responseText.substring(endOfHeaderPos + 4);
|
||||
if (data.endsWith('\n')) {
|
||||
data = data.slice(0, -1);
|
||||
}
|
||||
if (data.endsWith('\r')) {
|
||||
data = data.slice(0, -1);
|
||||
}
|
||||
var lowLevelResponse = {
|
||||
status: parseInt(status, 10),
|
||||
headers: headers,
|
||||
data: data,
|
||||
config: config,
|
||||
request: null,
|
||||
};
|
||||
if (!validator.isNumber(lowLevelResponse.status)) {
|
||||
throw new error_1.FirebaseAppError(error_1.AppErrorCodes.INTERNAL_ERROR, 'Malformed HTTP status line.');
|
||||
}
|
||||
return new DefaultHttpResponse(lowLevelResponse);
|
||||
}
|
||||
exports.parseHttpResponse = parseHttpResponse;
|
||||
/**
|
||||
* A helper class for sending HTTP requests over the wire. This is a wrapper around the standard
|
||||
* http and https packages of Node.js, providing content processing, timeouts and error handling.
|
||||
* It also wraps the callback API of the Node.js standard library in a more flexible Promise API.
|
||||
*/
|
||||
var AsyncHttpCall = /** @class */ (function () {
|
||||
function AsyncHttpCall(config) {
|
||||
var _this = this;
|
||||
try {
|
||||
this.config = new HttpRequestConfigImpl(config);
|
||||
this.options = this.config.buildRequestOptions();
|
||||
this.entity = this.config.buildEntity(this.options.headers);
|
||||
this.promise = new Promise(function (resolve, reject) {
|
||||
_this.resolve = resolve;
|
||||
_this.reject = reject;
|
||||
_this.execute();
|
||||
});
|
||||
}
|
||||
catch (err) {
|
||||
this.promise = Promise.reject(this.enhanceError(err, null));
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Sends an HTTP request based on the provided configuration.
|
||||
*/
|
||||
AsyncHttpCall.invoke = function (config) {
|
||||
return new AsyncHttpCall(config).promise;
|
||||
};
|
||||
AsyncHttpCall.prototype.execute = function () {
|
||||
var _this = this;
|
||||
var transport = this.options.protocol === 'https:' ? https : http;
|
||||
var req = transport.request(this.options, function (res) {
|
||||
_this.handleResponse(res, req);
|
||||
});
|
||||
// Handle errors
|
||||
req.on('error', function (err) {
|
||||
if (req.aborted) {
|
||||
return;
|
||||
}
|
||||
_this.enhanceAndReject(err, null, req);
|
||||
});
|
||||
var timeout = this.config.timeout;
|
||||
if (timeout) {
|
||||
// Listen to timeouts and throw an error.
|
||||
req.setTimeout(timeout, function () {
|
||||
req.abort();
|
||||
_this.rejectWithError("timeout of " + timeout + "ms exceeded", 'ETIMEDOUT', req);
|
||||
});
|
||||
}
|
||||
// Send the request
|
||||
req.end(this.entity);
|
||||
};
|
||||
AsyncHttpCall.prototype.handleResponse = function (res, req) {
|
||||
if (req.aborted) {
|
||||
return;
|
||||
}
|
||||
if (!res.statusCode) {
|
||||
throw new error_1.FirebaseAppError(error_1.AppErrorCodes.INTERNAL_ERROR, 'Expected a statusCode on the response from a ClientRequest');
|
||||
}
|
||||
var response = {
|
||||
status: res.statusCode,
|
||||
headers: res.headers,
|
||||
request: req,
|
||||
data: undefined,
|
||||
config: this.config,
|
||||
};
|
||||
var boundary = this.getMultipartBoundary(res.headers);
|
||||
var respStream = this.uncompressResponse(res);
|
||||
if (boundary) {
|
||||
this.handleMultipartResponse(response, respStream, boundary);
|
||||
}
|
||||
else {
|
||||
this.handleRegularResponse(response, respStream);
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Extracts multipart boundary from the HTTP header. The content-type header of a multipart
|
||||
* response has the form 'multipart/subtype; boundary=string'.
|
||||
*
|
||||
* If the content-type header does not exist, or does not start with
|
||||
* 'multipart/', then null will be returned.
|
||||
*/
|
||||
AsyncHttpCall.prototype.getMultipartBoundary = function (headers) {
|
||||
var contentType = headers['content-type'];
|
||||
if (!contentType || !contentType.startsWith('multipart/')) {
|
||||
return null;
|
||||
}
|
||||
var segments = contentType.split(';');
|
||||
var emptyObject = {};
|
||||
var headerParams = segments.slice(1)
|
||||
.map(function (segment) { return segment.trim().split('='); })
|
||||
.reduce(function (curr, params) {
|
||||
// Parse key=value pairs in the content-type header into properties of an object.
|
||||
if (params.length === 2) {
|
||||
var keyValuePair = {};
|
||||
keyValuePair[params[0]] = params[1];
|
||||
return Object.assign(curr, keyValuePair);
|
||||
}
|
||||
return curr;
|
||||
}, emptyObject);
|
||||
return headerParams.boundary;
|
||||
};
|
||||
AsyncHttpCall.prototype.uncompressResponse = function (res) {
|
||||
// Uncompress the response body transparently if required.
|
||||
var respStream = res;
|
||||
var encodings = ['gzip', 'compress', 'deflate'];
|
||||
if (res.headers['content-encoding'] && encodings.indexOf(res.headers['content-encoding']) !== -1) {
|
||||
// Add the unzipper to the body stream processing pipeline.
|
||||
var zlib = require('zlib');
|
||||
respStream = respStream.pipe(zlib.createUnzip());
|
||||
// Remove the content-encoding in order to not confuse downstream operations.
|
||||
delete res.headers['content-encoding'];
|
||||
}
|
||||
return respStream;
|
||||
};
|
||||
AsyncHttpCall.prototype.handleMultipartResponse = function (response, respStream, boundary) {
|
||||
var _this = this;
|
||||
var dicer = require('dicer');
|
||||
var multipartParser = new dicer({ boundary: boundary });
|
||||
var responseBuffer = [];
|
||||
multipartParser.on('part', function (part) {
|
||||
var tempBuffers = [];
|
||||
part.on('data', function (partData) {
|
||||
tempBuffers.push(partData);
|
||||
});
|
||||
part.on('end', function () {
|
||||
responseBuffer.push(Buffer.concat(tempBuffers));
|
||||
});
|
||||
});
|
||||
multipartParser.on('finish', function () {
|
||||
response.data = undefined;
|
||||
response.multipart = responseBuffer;
|
||||
_this.finalizeResponse(response);
|
||||
});
|
||||
respStream.pipe(multipartParser);
|
||||
};
|
||||
AsyncHttpCall.prototype.handleRegularResponse = function (response, respStream) {
|
||||
var _this = this;
|
||||
var responseBuffer = [];
|
||||
respStream.on('data', function (chunk) {
|
||||
responseBuffer.push(chunk);
|
||||
});
|
||||
respStream.on('error', function (err) {
|
||||
var req = response.request;
|
||||
if (req && req.aborted) {
|
||||
return;
|
||||
}
|
||||
_this.enhanceAndReject(err, null, req);
|
||||
});
|
||||
respStream.on('end', function () {
|
||||
response.data = Buffer.concat(responseBuffer).toString();
|
||||
_this.finalizeResponse(response);
|
||||
});
|
||||
};
|
||||
/**
|
||||
* Finalizes the current HTTP call in-flight by either resolving or rejecting the associated
|
||||
* promise. In the event of an error, adds additional useful information to the returned error.
|
||||
*/
|
||||
AsyncHttpCall.prototype.finalizeResponse = function (response) {
|
||||
if (response.status >= 200 && response.status < 300) {
|
||||
this.resolve(response);
|
||||
}
|
||||
else {
|
||||
this.rejectWithError('Request failed with status code ' + response.status, null, response.request, response);
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Creates a new error from the given message, and enhances it with other information available.
|
||||
* Then the promise associated with this HTTP call is rejected with the resulting error.
|
||||
*/
|
||||
AsyncHttpCall.prototype.rejectWithError = function (message, code, request, response) {
|
||||
var error = new Error(message);
|
||||
this.enhanceAndReject(error, code, request, response);
|
||||
};
|
||||
AsyncHttpCall.prototype.enhanceAndReject = function (error, code, request, response) {
|
||||
this.reject(this.enhanceError(error, code, request, response));
|
||||
};
|
||||
/**
|
||||
* Enhances the given error by adding more information to it. Specifically, the HttpRequestConfig,
|
||||
* the underlying request and response will be attached to the error.
|
||||
*/
|
||||
AsyncHttpCall.prototype.enhanceError = function (error, code, request, response) {
|
||||
error.config = this.config;
|
||||
if (code) {
|
||||
error.code = code;
|
||||
}
|
||||
error.request = request;
|
||||
error.response = response;
|
||||
return error;
|
||||
};
|
||||
return AsyncHttpCall;
|
||||
}());
|
||||
/**
|
||||
* An adapter class for extracting options and entity data from an HttpRequestConfig.
|
||||
*/
|
||||
var HttpRequestConfigImpl = /** @class */ (function () {
|
||||
function HttpRequestConfigImpl(config) {
|
||||
this.config = config;
|
||||
}
|
||||
Object.defineProperty(HttpRequestConfigImpl.prototype, "method", {
|
||||
get: function () {
|
||||
return this.config.method;
|
||||
},
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
Object.defineProperty(HttpRequestConfigImpl.prototype, "url", {
|
||||
get: function () {
|
||||
return this.config.url;
|
||||
},
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
Object.defineProperty(HttpRequestConfigImpl.prototype, "headers", {
|
||||
get: function () {
|
||||
return this.config.headers;
|
||||
},
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
Object.defineProperty(HttpRequestConfigImpl.prototype, "data", {
|
||||
get: function () {
|
||||
return this.config.data;
|
||||
},
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
Object.defineProperty(HttpRequestConfigImpl.prototype, "timeout", {
|
||||
get: function () {
|
||||
return this.config.timeout;
|
||||
},
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
Object.defineProperty(HttpRequestConfigImpl.prototype, "httpAgent", {
|
||||
get: function () {
|
||||
return this.config.httpAgent;
|
||||
},
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
HttpRequestConfigImpl.prototype.buildRequestOptions = function () {
|
||||
var parsed = this.buildUrl();
|
||||
var protocol = parsed.protocol;
|
||||
var port = parsed.port;
|
||||
if (!port) {
|
||||
var isHttps = protocol === 'https:';
|
||||
port = isHttps ? '443' : '80';
|
||||
}
|
||||
return {
|
||||
protocol: protocol,
|
||||
hostname: parsed.hostname,
|
||||
port: port,
|
||||
path: parsed.path,
|
||||
method: this.method,
|
||||
agent: this.httpAgent,
|
||||
headers: Object.assign({}, this.headers),
|
||||
};
|
||||
};
|
||||
HttpRequestConfigImpl.prototype.buildEntity = function (headers) {
|
||||
var data;
|
||||
if (!this.hasEntity() || !this.isEntityEnclosingRequest()) {
|
||||
return data;
|
||||
}
|
||||
if (validator.isBuffer(this.data)) {
|
||||
data = this.data;
|
||||
}
|
||||
else if (validator.isObject(this.data)) {
|
||||
data = Buffer.from(JSON.stringify(this.data), 'utf-8');
|
||||
if (typeof headers['content-type'] === 'undefined') {
|
||||
headers['content-type'] = 'application/json;charset=utf-8';
|
||||
}
|
||||
}
|
||||
else if (validator.isString(this.data)) {
|
||||
data = Buffer.from(this.data, 'utf-8');
|
||||
}
|
||||
else {
|
||||
throw new Error('Request data must be a string, a Buffer or a json serializable object');
|
||||
}
|
||||
// Add Content-Length header if data exists.
|
||||
headers['Content-Length'] = data.length.toString();
|
||||
return data;
|
||||
};
|
||||
HttpRequestConfigImpl.prototype.buildUrl = function () {
|
||||
var fullUrl = this.urlWithProtocol();
|
||||
if (!this.hasEntity() || this.isEntityEnclosingRequest()) {
|
||||
return url.parse(fullUrl);
|
||||
}
|
||||
if (!validator.isObject(this.data)) {
|
||||
throw new Error(this.method + " requests cannot have a body");
|
||||
}
|
||||
// Parse URL and append data to query string.
|
||||
var parsedUrl = new url.URL(fullUrl);
|
||||
var dataObj = this.data;
|
||||
for (var key in dataObj) {
|
||||
if (dataObj.hasOwnProperty(key)) {
|
||||
parsedUrl.searchParams.append(key, dataObj[key]);
|
||||
}
|
||||
}
|
||||
return url.parse(parsedUrl.toString());
|
||||
};
|
||||
HttpRequestConfigImpl.prototype.urlWithProtocol = function () {
|
||||
var fullUrl = this.url;
|
||||
if (fullUrl.startsWith('http://') || fullUrl.startsWith('https://')) {
|
||||
return fullUrl;
|
||||
}
|
||||
return "https://" + fullUrl;
|
||||
};
|
||||
HttpRequestConfigImpl.prototype.hasEntity = function () {
|
||||
return !!this.data;
|
||||
};
|
||||
HttpRequestConfigImpl.prototype.isEntityEnclosingRequest = function () {
|
||||
// GET and HEAD requests do not support entity (body) in request.
|
||||
return this.method !== 'GET' && this.method !== 'HEAD';
|
||||
};
|
||||
return HttpRequestConfigImpl;
|
||||
}());
|
||||
var AuthorizedHttpClient = /** @class */ (function (_super) {
|
||||
__extends(AuthorizedHttpClient, _super);
|
||||
function AuthorizedHttpClient(app) {
|
||||
var _this = _super.call(this) || this;
|
||||
_this.app = app;
|
||||
return _this;
|
||||
}
|
||||
AuthorizedHttpClient.prototype.send = function (request) {
|
||||
var _this = this;
|
||||
return this.app.INTERNAL.getToken().then(function (accessTokenObj) {
|
||||
var requestCopy = Object.assign({}, request);
|
||||
requestCopy.headers = Object.assign({}, request.headers);
|
||||
var authHeader = 'Authorization';
|
||||
requestCopy.headers[authHeader] = "Bearer " + accessTokenObj.accessToken;
|
||||
if (!requestCopy.httpAgent && _this.app.options.httpAgent) {
|
||||
requestCopy.httpAgent = _this.app.options.httpAgent;
|
||||
}
|
||||
return _super.prototype.send.call(_this, requestCopy);
|
||||
});
|
||||
};
|
||||
return AuthorizedHttpClient;
|
||||
}(HttpClient));
|
||||
exports.AuthorizedHttpClient = AuthorizedHttpClient;
|
||||
/**
|
||||
* Class that defines all the settings for the backend API endpoint.
|
||||
*
|
||||
* @param {string} endpoint The Firebase Auth backend endpoint.
|
||||
* @param {HttpMethod} httpMethod The http method for that endpoint.
|
||||
* @constructor
|
||||
*/
|
||||
var ApiSettings = /** @class */ (function () {
|
||||
function ApiSettings(endpoint, httpMethod) {
|
||||
if (httpMethod === void 0) { httpMethod = 'POST'; }
|
||||
this.endpoint = endpoint;
|
||||
this.httpMethod = httpMethod;
|
||||
this.setRequestValidator(null)
|
||||
.setResponseValidator(null);
|
||||
}
|
||||
/** @return {string} The backend API endpoint. */
|
||||
ApiSettings.prototype.getEndpoint = function () {
|
||||
return this.endpoint;
|
||||
};
|
||||
/** @return {HttpMethod} The request HTTP method. */
|
||||
ApiSettings.prototype.getHttpMethod = function () {
|
||||
return this.httpMethod;
|
||||
};
|
||||
/**
|
||||
* @param {ApiCallbackFunction} requestValidator The request validator.
|
||||
* @return {ApiSettings} The current API settings instance.
|
||||
*/
|
||||
ApiSettings.prototype.setRequestValidator = function (requestValidator) {
|
||||
var nullFunction = function (_) { return undefined; };
|
||||
this.requestValidator = requestValidator || nullFunction;
|
||||
return this;
|
||||
};
|
||||
/** @return {ApiCallbackFunction} The request validator. */
|
||||
ApiSettings.prototype.getRequestValidator = function () {
|
||||
return this.requestValidator;
|
||||
};
|
||||
/**
|
||||
* @param {ApiCallbackFunction} responseValidator The response validator.
|
||||
* @return {ApiSettings} The current API settings instance.
|
||||
*/
|
||||
ApiSettings.prototype.setResponseValidator = function (responseValidator) {
|
||||
var nullFunction = function (_) { return undefined; };
|
||||
this.responseValidator = responseValidator || nullFunction;
|
||||
return this;
|
||||
};
|
||||
/** @return {ApiCallbackFunction} The response validator. */
|
||||
ApiSettings.prototype.getResponseValidator = function () {
|
||||
return this.responseValidator;
|
||||
};
|
||||
return ApiSettings;
|
||||
}());
|
||||
exports.ApiSettings = ApiSettings;
|
||||
/**
|
||||
* Class used for polling an endpoint with exponential backoff.
|
||||
*
|
||||
* Example usage:
|
||||
* ```
|
||||
* const poller = new ExponentialBackoffPoller();
|
||||
* poller
|
||||
* .poll(() => {
|
||||
* return myRequestToPoll()
|
||||
* .then((responseData: any) => {
|
||||
* if (!isValid(responseData)) {
|
||||
* // Continue polling.
|
||||
* return null;
|
||||
* }
|
||||
*
|
||||
* // Polling complete. Resolve promise with final response data.
|
||||
* return responseData;
|
||||
* });
|
||||
* })
|
||||
* .then((responseData: any) => {
|
||||
* console.log(`Final response: ${responseData}`);
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
var ExponentialBackoffPoller = /** @class */ (function (_super) {
|
||||
__extends(ExponentialBackoffPoller, _super);
|
||||
function ExponentialBackoffPoller(initialPollingDelayMillis, maxPollingDelayMillis, masterTimeoutMillis) {
|
||||
if (initialPollingDelayMillis === void 0) { initialPollingDelayMillis = 1000; }
|
||||
if (maxPollingDelayMillis === void 0) { maxPollingDelayMillis = 10000; }
|
||||
if (masterTimeoutMillis === void 0) { masterTimeoutMillis = 60000; }
|
||||
var _this = _super.call(this) || this;
|
||||
_this.initialPollingDelayMillis = initialPollingDelayMillis;
|
||||
_this.maxPollingDelayMillis = maxPollingDelayMillis;
|
||||
_this.masterTimeoutMillis = masterTimeoutMillis;
|
||||
_this.numTries = 0;
|
||||
_this.completed = false;
|
||||
return _this;
|
||||
}
|
||||
/**
|
||||
* Poll the provided callback with exponential backoff.
|
||||
*
|
||||
* @param {() => Promise<object>} callback The callback to be called for each poll. If the
|
||||
* callback resolves to a falsey value, polling will continue. Otherwise, the truthy
|
||||
* resolution will be used to resolve the promise returned by this method.
|
||||
* @return {Promise<object>} A Promise which resolves to the truthy value returned by the provided
|
||||
* callback when polling is complete.
|
||||
*/
|
||||
ExponentialBackoffPoller.prototype.poll = function (callback) {
|
||||
var _this = this;
|
||||
if (this.pollCallback) {
|
||||
throw new Error('poll() can only be called once per instance of ExponentialBackoffPoller');
|
||||
}
|
||||
this.pollCallback = callback;
|
||||
this.on('poll', this.repoll);
|
||||
this.masterTimer = setTimeout(function () {
|
||||
if (_this.completed) {
|
||||
return;
|
||||
}
|
||||
_this.markCompleted();
|
||||
_this.reject(new Error('ExponentialBackoffPoller deadline exceeded - Master timeout reached'));
|
||||
}, this.masterTimeoutMillis);
|
||||
return new Promise(function (resolve, reject) {
|
||||
_this.resolve = resolve;
|
||||
_this.reject = reject;
|
||||
_this.repoll();
|
||||
});
|
||||
};
|
||||
ExponentialBackoffPoller.prototype.repoll = function () {
|
||||
var _this = this;
|
||||
this.pollCallback()
|
||||
.then(function (result) {
|
||||
if (_this.completed) {
|
||||
return;
|
||||
}
|
||||
if (!result) {
|
||||
_this.repollTimer =
|
||||
setTimeout(function () { return _this.emit('poll'); }, _this.getPollingDelayMillis());
|
||||
_this.numTries++;
|
||||
return;
|
||||
}
|
||||
_this.markCompleted();
|
||||
_this.resolve(result);
|
||||
})
|
||||
.catch(function (err) {
|
||||
if (_this.completed) {
|
||||
return;
|
||||
}
|
||||
_this.markCompleted();
|
||||
_this.reject(err);
|
||||
});
|
||||
};
|
||||
ExponentialBackoffPoller.prototype.getPollingDelayMillis = function () {
|
||||
var increasedPollingDelay = Math.pow(2, this.numTries) * this.initialPollingDelayMillis;
|
||||
return Math.min(increasedPollingDelay, this.maxPollingDelayMillis);
|
||||
};
|
||||
ExponentialBackoffPoller.prototype.markCompleted = function () {
|
||||
this.completed = true;
|
||||
if (this.masterTimer) {
|
||||
clearTimeout(this.masterTimer);
|
||||
}
|
||||
if (this.repollTimer) {
|
||||
clearTimeout(this.repollTimer);
|
||||
}
|
||||
};
|
||||
return ExponentialBackoffPoller;
|
||||
}(events_1.EventEmitter));
|
||||
exports.ExponentialBackoffPoller = ExponentialBackoffPoller;
|
75
node_modules/firebase-admin/lib/utils/deep-copy.js
generated
vendored
Normal file
75
node_modules/firebase-admin/lib/utils/deep-copy.js
generated
vendored
Normal file
@ -0,0 +1,75 @@
|
||||
/*! firebase-admin v8.9.2 */
|
||||
"use strict";
|
||||
/*!
|
||||
* Copyright 2017 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
/**
|
||||
* Returns a deep copy of an object or array.
|
||||
*
|
||||
* @param {object|array} value The object or array to deep copy.
|
||||
* @return {object|array} A deep copy of the provided object or array.
|
||||
*/
|
||||
function deepCopy(value) {
|
||||
return deepExtend(undefined, value);
|
||||
}
|
||||
exports.deepCopy = deepCopy;
|
||||
/**
|
||||
* Copies properties from source to target (recursively allows extension of objects and arrays).
|
||||
* Scalar values in the target are over-written. If target is undefined, an object of the
|
||||
* appropriate type will be created (and returned).
|
||||
*
|
||||
* We recursively copy all child properties of plain objects in the source - so that namespace-like
|
||||
* objects are merged.
|
||||
*
|
||||
* Note that the target can be a function, in which case the properties in the source object are
|
||||
* copied onto it as static properties of the function.
|
||||
*
|
||||
* @param {any} target The value which is being extended.
|
||||
* @param {any} source The value whose properties are extending the target.
|
||||
* @return {any} The target value.
|
||||
*/
|
||||
function deepExtend(target, source) {
|
||||
if (!(source instanceof Object)) {
|
||||
return source;
|
||||
}
|
||||
switch (source.constructor) {
|
||||
case Date:
|
||||
// Treat Dates like scalars; if the target date object had any child
|
||||
// properties - they will be lost!
|
||||
var dateValue = source;
|
||||
return new Date(dateValue.getTime());
|
||||
case Object:
|
||||
if (target === undefined) {
|
||||
target = {};
|
||||
}
|
||||
break;
|
||||
case Array:
|
||||
// Always copy the array source and overwrite the target.
|
||||
target = [];
|
||||
break;
|
||||
default:
|
||||
// Not a plain Object - treat it as a scalar.
|
||||
return source;
|
||||
}
|
||||
for (var prop in source) {
|
||||
if (!source.hasOwnProperty(prop)) {
|
||||
continue;
|
||||
}
|
||||
target[prop] = deepExtend(target[prop], source[prop]);
|
||||
}
|
||||
return target;
|
||||
}
|
||||
exports.deepExtend = deepExtend;
|
942
node_modules/firebase-admin/lib/utils/error.js
generated
vendored
Normal file
942
node_modules/firebase-admin/lib/utils/error.js
generated
vendored
Normal file
@ -0,0 +1,942 @@
|
||||
/*! firebase-admin v8.9.2 */
|
||||
"use strict";
|
||||
/*!
|
||||
* Copyright 2017 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
var __extends = (this && this.__extends) || (function () {
|
||||
var extendStatics = function (d, b) {
|
||||
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 extendStatics(d, b);
|
||||
};
|
||||
return function (d, b) {
|
||||
extendStatics(d, b);
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
})();
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
var deep_copy_1 = require("../utils/deep-copy");
|
||||
/**
|
||||
* Firebase error code structure. This extends Error.
|
||||
*
|
||||
* @param {ErrorInfo} errorInfo The error information (code and message).
|
||||
* @constructor
|
||||
*/
|
||||
var FirebaseError = /** @class */ (function (_super) {
|
||||
__extends(FirebaseError, _super);
|
||||
function FirebaseError(errorInfo) {
|
||||
var _this = _super.call(this, errorInfo.message) || this;
|
||||
_this.errorInfo = errorInfo;
|
||||
/* tslint:disable:max-line-length */
|
||||
// Set the prototype explicitly. See the following link for more details:
|
||||
// https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#extending-built-ins-like-error-array-and-map-may-no-longer-work
|
||||
/* tslint:enable:max-line-length */
|
||||
_this.__proto__ = FirebaseError.prototype;
|
||||
return _this;
|
||||
}
|
||||
Object.defineProperty(FirebaseError.prototype, "code", {
|
||||
/** @return {string} The error code. */
|
||||
get: function () {
|
||||
return this.errorInfo.code;
|
||||
},
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
Object.defineProperty(FirebaseError.prototype, "message", {
|
||||
/** @return {string} The error message. */
|
||||
get: function () {
|
||||
return this.errorInfo.message;
|
||||
},
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
/** @return {object} The object representation of the error. */
|
||||
FirebaseError.prototype.toJSON = function () {
|
||||
return {
|
||||
code: this.code,
|
||||
message: this.message,
|
||||
};
|
||||
};
|
||||
return FirebaseError;
|
||||
}(Error));
|
||||
exports.FirebaseError = FirebaseError;
|
||||
/**
|
||||
* A FirebaseError with a prefix in front of the error code.
|
||||
*
|
||||
* @param {string} codePrefix The prefix to apply to the error code.
|
||||
* @param {string} code The error code.
|
||||
* @param {string} message The error message.
|
||||
* @constructor
|
||||
*/
|
||||
var PrefixedFirebaseError = /** @class */ (function (_super) {
|
||||
__extends(PrefixedFirebaseError, _super);
|
||||
function PrefixedFirebaseError(codePrefix, code, message) {
|
||||
var _this = _super.call(this, {
|
||||
code: codePrefix + "/" + code,
|
||||
message: message,
|
||||
}) || this;
|
||||
_this.codePrefix = codePrefix;
|
||||
/* tslint:disable:max-line-length */
|
||||
// Set the prototype explicitly. See the following link for more details:
|
||||
// https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#extending-built-ins-like-error-array-and-map-may-no-longer-work
|
||||
/* tslint:enable:max-line-length */
|
||||
_this.__proto__ = PrefixedFirebaseError.prototype;
|
||||
return _this;
|
||||
}
|
||||
/**
|
||||
* Allows the error type to be checked without needing to know implementation details
|
||||
* of the code prefixing.
|
||||
*
|
||||
* @param {string} code The non-prefixed error code to test against.
|
||||
* @return {boolean} True if the code matches, false otherwise.
|
||||
*/
|
||||
PrefixedFirebaseError.prototype.hasCode = function (code) {
|
||||
return this.codePrefix + "/" + code === this.code;
|
||||
};
|
||||
return PrefixedFirebaseError;
|
||||
}(FirebaseError));
|
||||
exports.PrefixedFirebaseError = PrefixedFirebaseError;
|
||||
/**
|
||||
* Firebase App error code structure. This extends PrefixedFirebaseError.
|
||||
*
|
||||
* @param {string} code The error code.
|
||||
* @param {string} message The error message.
|
||||
* @constructor
|
||||
*/
|
||||
var FirebaseAppError = /** @class */ (function (_super) {
|
||||
__extends(FirebaseAppError, _super);
|
||||
function FirebaseAppError(code, message) {
|
||||
var _this = _super.call(this, 'app', code, message) || this;
|
||||
/* tslint:disable:max-line-length */
|
||||
// Set the prototype explicitly. See the following link for more details:
|
||||
// https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#extending-built-ins-like-error-array-and-map-may-no-longer-work
|
||||
/* tslint:enable:max-line-length */
|
||||
_this.__proto__ = FirebaseAppError.prototype;
|
||||
return _this;
|
||||
}
|
||||
return FirebaseAppError;
|
||||
}(PrefixedFirebaseError));
|
||||
exports.FirebaseAppError = FirebaseAppError;
|
||||
/**
|
||||
* Firebase Auth error code structure. This extends PrefixedFirebaseError.
|
||||
*
|
||||
* @param {ErrorInfo} info The error code info.
|
||||
* @param {string} [message] The error message. This will override the default
|
||||
* message if provided.
|
||||
* @constructor
|
||||
*/
|
||||
var FirebaseAuthError = /** @class */ (function (_super) {
|
||||
__extends(FirebaseAuthError, _super);
|
||||
function FirebaseAuthError(info, message) {
|
||||
var _this =
|
||||
// Override default message if custom message provided.
|
||||
_super.call(this, 'auth', info.code, message || info.message) || this;
|
||||
/* tslint:disable:max-line-length */
|
||||
// Set the prototype explicitly. See the following link for more details:
|
||||
// https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#extending-built-ins-like-error-array-and-map-may-no-longer-work
|
||||
/* tslint:enable:max-line-length */
|
||||
_this.__proto__ = FirebaseAuthError.prototype;
|
||||
return _this;
|
||||
}
|
||||
/**
|
||||
* Creates the developer-facing error corresponding to the backend error code.
|
||||
*
|
||||
* @param {string} serverErrorCode The server error code.
|
||||
* @param {string} [message] The error message. The default message is used
|
||||
* if not provided.
|
||||
* @param {object} [rawServerResponse] The error's raw server response.
|
||||
* @return {FirebaseAuthError} The corresponding developer-facing error.
|
||||
*/
|
||||
FirebaseAuthError.fromServerError = function (serverErrorCode, message, rawServerResponse) {
|
||||
// serverErrorCode could contain additional details:
|
||||
// ERROR_CODE : Detailed message which can also contain colons
|
||||
var colonSeparator = (serverErrorCode || '').indexOf(':');
|
||||
var customMessage = null;
|
||||
if (colonSeparator !== -1) {
|
||||
customMessage = serverErrorCode.substring(colonSeparator + 1).trim();
|
||||
serverErrorCode = serverErrorCode.substring(0, colonSeparator).trim();
|
||||
}
|
||||
// If not found, default to internal error.
|
||||
var clientCodeKey = AUTH_SERVER_TO_CLIENT_CODE[serverErrorCode] || 'INTERNAL_ERROR';
|
||||
var error = deep_copy_1.deepCopy(AuthClientErrorCode[clientCodeKey]);
|
||||
// Server detailed message should have highest priority.
|
||||
error.message = customMessage || message || error.message;
|
||||
if (clientCodeKey === 'INTERNAL_ERROR' && typeof rawServerResponse !== 'undefined') {
|
||||
try {
|
||||
error.message += " Raw server response: \"" + JSON.stringify(rawServerResponse) + "\"";
|
||||
}
|
||||
catch (e) {
|
||||
// Ignore JSON parsing error.
|
||||
}
|
||||
}
|
||||
return new FirebaseAuthError(error);
|
||||
};
|
||||
return FirebaseAuthError;
|
||||
}(PrefixedFirebaseError));
|
||||
exports.FirebaseAuthError = FirebaseAuthError;
|
||||
/**
|
||||
* Firebase Database error code structure. This extends FirebaseError.
|
||||
*
|
||||
* @param {ErrorInfo} info The error code info.
|
||||
* @param {string} [message] The error message. This will override the default
|
||||
* message if provided.
|
||||
* @constructor
|
||||
*/
|
||||
var FirebaseDatabaseError = /** @class */ (function (_super) {
|
||||
__extends(FirebaseDatabaseError, _super);
|
||||
function FirebaseDatabaseError(info, message) {
|
||||
// Override default message if custom message provided.
|
||||
return _super.call(this, { code: 'database/' + info.code, message: message || info.message }) || this;
|
||||
}
|
||||
return FirebaseDatabaseError;
|
||||
}(FirebaseError));
|
||||
exports.FirebaseDatabaseError = FirebaseDatabaseError;
|
||||
/**
|
||||
* Firebase Firestore error code structure. This extends FirebaseError.
|
||||
*
|
||||
* @param {ErrorInfo} info The error code info.
|
||||
* @param {string} [message] The error message. This will override the default
|
||||
* message if provided.
|
||||
* @constructor
|
||||
*/
|
||||
var FirebaseFirestoreError = /** @class */ (function (_super) {
|
||||
__extends(FirebaseFirestoreError, _super);
|
||||
function FirebaseFirestoreError(info, message) {
|
||||
// Override default message if custom message provided.
|
||||
return _super.call(this, { code: 'firestore/' + info.code, message: message || info.message }) || this;
|
||||
}
|
||||
return FirebaseFirestoreError;
|
||||
}(FirebaseError));
|
||||
exports.FirebaseFirestoreError = FirebaseFirestoreError;
|
||||
/**
|
||||
* Firebase instance ID error code structure. This extends FirebaseError.
|
||||
*
|
||||
* @param {ErrorInfo} info The error code info.
|
||||
* @param {string} [message] The error message. This will override the default
|
||||
* message if provided.
|
||||
* @constructor
|
||||
*/
|
||||
var FirebaseInstanceIdError = /** @class */ (function (_super) {
|
||||
__extends(FirebaseInstanceIdError, _super);
|
||||
function FirebaseInstanceIdError(info, message) {
|
||||
// Override default message if custom message provided.
|
||||
return _super.call(this, { code: 'instance-id/' + info.code, message: message || info.message }) || this;
|
||||
}
|
||||
return FirebaseInstanceIdError;
|
||||
}(FirebaseError));
|
||||
exports.FirebaseInstanceIdError = FirebaseInstanceIdError;
|
||||
/**
|
||||
* Firebase Messaging error code structure. This extends PrefixedFirebaseError.
|
||||
*
|
||||
* @param {ErrorInfo} info The error code info.
|
||||
* @param {string} [message] The error message. This will override the default message if provided.
|
||||
* @constructor
|
||||
*/
|
||||
var FirebaseMessagingError = /** @class */ (function (_super) {
|
||||
__extends(FirebaseMessagingError, _super);
|
||||
function FirebaseMessagingError(info, message) {
|
||||
var _this =
|
||||
// Override default message if custom message provided.
|
||||
_super.call(this, 'messaging', info.code, message || info.message) || this;
|
||||
/* tslint:disable:max-line-length */
|
||||
// Set the prototype explicitly. See the following link for more details:
|
||||
// https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#extending-built-ins-like-error-array-and-map-may-no-longer-work
|
||||
/* tslint:enable:max-line-length */
|
||||
_this.__proto__ = FirebaseMessagingError.prototype;
|
||||
return _this;
|
||||
}
|
||||
/**
|
||||
* Creates the developer-facing error corresponding to the backend error code.
|
||||
*
|
||||
* @param {string} serverErrorCode The server error code.
|
||||
* @param {string} [message] The error message. The default message is used
|
||||
* if not provided.
|
||||
* @param {object} [rawServerResponse] The error's raw server response.
|
||||
* @return {FirebaseMessagingError} The corresponding developer-facing error.
|
||||
*/
|
||||
FirebaseMessagingError.fromServerError = function (serverErrorCode, message, rawServerResponse) {
|
||||
// If not found, default to unknown error.
|
||||
var clientCodeKey = 'UNKNOWN_ERROR';
|
||||
if (serverErrorCode && serverErrorCode in MESSAGING_SERVER_TO_CLIENT_CODE) {
|
||||
clientCodeKey = MESSAGING_SERVER_TO_CLIENT_CODE[serverErrorCode];
|
||||
}
|
||||
var error = deep_copy_1.deepCopy(MessagingClientErrorCode[clientCodeKey]);
|
||||
error.message = message || error.message;
|
||||
if (clientCodeKey === 'UNKNOWN_ERROR' && typeof rawServerResponse !== 'undefined') {
|
||||
try {
|
||||
error.message += " Raw server response: \"" + JSON.stringify(rawServerResponse) + "\"";
|
||||
}
|
||||
catch (e) {
|
||||
// Ignore JSON parsing error.
|
||||
}
|
||||
}
|
||||
return new FirebaseMessagingError(error);
|
||||
};
|
||||
FirebaseMessagingError.fromTopicManagementServerError = function (serverErrorCode, message, rawServerResponse) {
|
||||
// If not found, default to unknown error.
|
||||
var clientCodeKey = TOPIC_MGT_SERVER_TO_CLIENT_CODE[serverErrorCode] || 'UNKNOWN_ERROR';
|
||||
var error = deep_copy_1.deepCopy(MessagingClientErrorCode[clientCodeKey]);
|
||||
error.message = message || error.message;
|
||||
if (clientCodeKey === 'UNKNOWN_ERROR' && typeof rawServerResponse !== 'undefined') {
|
||||
try {
|
||||
error.message += " Raw server response: \"" + JSON.stringify(rawServerResponse) + "\"";
|
||||
}
|
||||
catch (e) {
|
||||
// Ignore JSON parsing error.
|
||||
}
|
||||
}
|
||||
return new FirebaseMessagingError(error);
|
||||
};
|
||||
return FirebaseMessagingError;
|
||||
}(PrefixedFirebaseError));
|
||||
exports.FirebaseMessagingError = FirebaseMessagingError;
|
||||
/**
|
||||
* Firebase project management error code structure. This extends PrefixedFirebaseError.
|
||||
*
|
||||
* @param {ProjectManagementErrorCode} code The error code.
|
||||
* @param {string} message The error message.
|
||||
* @constructor
|
||||
*/
|
||||
var FirebaseProjectManagementError = /** @class */ (function (_super) {
|
||||
__extends(FirebaseProjectManagementError, _super);
|
||||
function FirebaseProjectManagementError(code, message) {
|
||||
var _this = _super.call(this, 'project-management', code, message) || this;
|
||||
/* tslint:disable:max-line-length */
|
||||
// Set the prototype explicitly. See the following link for more details:
|
||||
// https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#extending-built-ins-like-error-array-and-map-may-no-longer-work
|
||||
/* tslint:enable:max-line-length */
|
||||
_this.__proto__ = FirebaseProjectManagementError.prototype;
|
||||
return _this;
|
||||
}
|
||||
return FirebaseProjectManagementError;
|
||||
}(PrefixedFirebaseError));
|
||||
exports.FirebaseProjectManagementError = FirebaseProjectManagementError;
|
||||
/**
|
||||
* App client error codes and their default messages.
|
||||
*/
|
||||
var AppErrorCodes = /** @class */ (function () {
|
||||
function AppErrorCodes() {
|
||||
}
|
||||
AppErrorCodes.APP_DELETED = 'app-deleted';
|
||||
AppErrorCodes.DUPLICATE_APP = 'duplicate-app';
|
||||
AppErrorCodes.INVALID_ARGUMENT = 'invalid-argument';
|
||||
AppErrorCodes.INTERNAL_ERROR = 'internal-error';
|
||||
AppErrorCodes.INVALID_APP_NAME = 'invalid-app-name';
|
||||
AppErrorCodes.INVALID_APP_OPTIONS = 'invalid-app-options';
|
||||
AppErrorCodes.INVALID_CREDENTIAL = 'invalid-credential';
|
||||
AppErrorCodes.NETWORK_ERROR = 'network-error';
|
||||
AppErrorCodes.NETWORK_TIMEOUT = 'network-timeout';
|
||||
AppErrorCodes.NO_APP = 'no-app';
|
||||
AppErrorCodes.UNABLE_TO_PARSE_RESPONSE = 'unable-to-parse-response';
|
||||
return AppErrorCodes;
|
||||
}());
|
||||
exports.AppErrorCodes = AppErrorCodes;
|
||||
/**
|
||||
* Auth client error codes and their default messages.
|
||||
*/
|
||||
var AuthClientErrorCode = /** @class */ (function () {
|
||||
function AuthClientErrorCode() {
|
||||
}
|
||||
AuthClientErrorCode.BILLING_NOT_ENABLED = {
|
||||
code: 'billing-not-enabled',
|
||||
message: 'Feature requires billing to be enabled.',
|
||||
};
|
||||
AuthClientErrorCode.CLAIMS_TOO_LARGE = {
|
||||
code: 'claims-too-large',
|
||||
message: 'Developer claims maximum payload size exceeded.',
|
||||
};
|
||||
AuthClientErrorCode.CONFIGURATION_EXISTS = {
|
||||
code: 'configuration-exists',
|
||||
message: 'A configuration already exists with the provided identifier.',
|
||||
};
|
||||
AuthClientErrorCode.CONFIGURATION_NOT_FOUND = {
|
||||
code: 'configuration-not-found',
|
||||
message: 'There is no configuration corresponding to the provided identifier.',
|
||||
};
|
||||
AuthClientErrorCode.ID_TOKEN_EXPIRED = {
|
||||
code: 'id-token-expired',
|
||||
message: 'The provided Firebase ID token is expired.',
|
||||
};
|
||||
AuthClientErrorCode.INVALID_ARGUMENT = {
|
||||
code: 'argument-error',
|
||||
message: 'Invalid argument provided.',
|
||||
};
|
||||
AuthClientErrorCode.INVALID_CONFIG = {
|
||||
code: 'invalid-config',
|
||||
message: 'The provided configuration is invalid.',
|
||||
};
|
||||
AuthClientErrorCode.EMAIL_ALREADY_EXISTS = {
|
||||
code: 'email-already-exists',
|
||||
message: 'The email address is already in use by another account.',
|
||||
};
|
||||
AuthClientErrorCode.FORBIDDEN_CLAIM = {
|
||||
code: 'reserved-claim',
|
||||
message: 'The specified developer claim is reserved and cannot be specified.',
|
||||
};
|
||||
AuthClientErrorCode.INVALID_ID_TOKEN = {
|
||||
code: 'invalid-id-token',
|
||||
message: 'The provided ID token is not a valid Firebase ID token.',
|
||||
};
|
||||
AuthClientErrorCode.ID_TOKEN_REVOKED = {
|
||||
code: 'id-token-revoked',
|
||||
message: 'The Firebase ID token has been revoked.',
|
||||
};
|
||||
AuthClientErrorCode.INTERNAL_ERROR = {
|
||||
code: 'internal-error',
|
||||
message: 'An internal error has occurred.',
|
||||
};
|
||||
AuthClientErrorCode.INVALID_CLAIMS = {
|
||||
code: 'invalid-claims',
|
||||
message: 'The provided custom claim attributes are invalid.',
|
||||
};
|
||||
AuthClientErrorCode.INVALID_CONTINUE_URI = {
|
||||
code: 'invalid-continue-uri',
|
||||
message: 'The continue URL must be a valid URL string.',
|
||||
};
|
||||
AuthClientErrorCode.INVALID_CREATION_TIME = {
|
||||
code: 'invalid-creation-time',
|
||||
message: 'The creation time must be a valid UTC date string.',
|
||||
};
|
||||
AuthClientErrorCode.INVALID_CREDENTIAL = {
|
||||
code: 'invalid-credential',
|
||||
message: 'Invalid credential object provided.',
|
||||
};
|
||||
AuthClientErrorCode.INVALID_DISABLED_FIELD = {
|
||||
code: 'invalid-disabled-field',
|
||||
message: 'The disabled field must be a boolean.',
|
||||
};
|
||||
AuthClientErrorCode.INVALID_DISPLAY_NAME = {
|
||||
code: 'invalid-display-name',
|
||||
message: 'The displayName field must be a valid string.',
|
||||
};
|
||||
AuthClientErrorCode.INVALID_DYNAMIC_LINK_DOMAIN = {
|
||||
code: 'invalid-dynamic-link-domain',
|
||||
message: 'The provided dynamic link domain is not configured or authorized ' +
|
||||
'for the current project.',
|
||||
};
|
||||
AuthClientErrorCode.INVALID_EMAIL_VERIFIED = {
|
||||
code: 'invalid-email-verified',
|
||||
message: 'The emailVerified field must be a boolean.',
|
||||
};
|
||||
AuthClientErrorCode.INVALID_EMAIL = {
|
||||
code: 'invalid-email',
|
||||
message: 'The email address is improperly formatted.',
|
||||
};
|
||||
AuthClientErrorCode.INVALID_HASH_ALGORITHM = {
|
||||
code: 'invalid-hash-algorithm',
|
||||
message: 'The hash algorithm must match one of the strings in the list of ' +
|
||||
'supported algorithms.',
|
||||
};
|
||||
AuthClientErrorCode.INVALID_HASH_BLOCK_SIZE = {
|
||||
code: 'invalid-hash-block-size',
|
||||
message: 'The hash block size must be a valid number.',
|
||||
};
|
||||
AuthClientErrorCode.INVALID_HASH_DERIVED_KEY_LENGTH = {
|
||||
code: 'invalid-hash-derived-key-length',
|
||||
message: 'The hash derived key length must be a valid number.',
|
||||
};
|
||||
AuthClientErrorCode.INVALID_HASH_KEY = {
|
||||
code: 'invalid-hash-key',
|
||||
message: 'The hash key must a valid byte buffer.',
|
||||
};
|
||||
AuthClientErrorCode.INVALID_HASH_MEMORY_COST = {
|
||||
code: 'invalid-hash-memory-cost',
|
||||
message: 'The hash memory cost must be a valid number.',
|
||||
};
|
||||
AuthClientErrorCode.INVALID_HASH_PARALLELIZATION = {
|
||||
code: 'invalid-hash-parallelization',
|
||||
message: 'The hash parallelization must be a valid number.',
|
||||
};
|
||||
AuthClientErrorCode.INVALID_HASH_ROUNDS = {
|
||||
code: 'invalid-hash-rounds',
|
||||
message: 'The hash rounds must be a valid number.',
|
||||
};
|
||||
AuthClientErrorCode.INVALID_HASH_SALT_SEPARATOR = {
|
||||
code: 'invalid-hash-salt-separator',
|
||||
message: 'The hashing algorithm salt separator field must be a valid byte buffer.',
|
||||
};
|
||||
AuthClientErrorCode.INVALID_LAST_SIGN_IN_TIME = {
|
||||
code: 'invalid-last-sign-in-time',
|
||||
message: 'The last sign-in time must be a valid UTC date string.',
|
||||
};
|
||||
AuthClientErrorCode.INVALID_NAME = {
|
||||
code: 'invalid-name',
|
||||
message: 'The resource name provided is invalid.',
|
||||
};
|
||||
AuthClientErrorCode.INVALID_OAUTH_CLIENT_ID = {
|
||||
code: 'invalid-oauth-client-id',
|
||||
message: 'The provided OAuth client ID is invalid.',
|
||||
};
|
||||
AuthClientErrorCode.INVALID_PAGE_TOKEN = {
|
||||
code: 'invalid-page-token',
|
||||
message: 'The page token must be a valid non-empty string.',
|
||||
};
|
||||
AuthClientErrorCode.INVALID_PASSWORD = {
|
||||
code: 'invalid-password',
|
||||
message: 'The password must be a string with at least 6 characters.',
|
||||
};
|
||||
AuthClientErrorCode.INVALID_PASSWORD_HASH = {
|
||||
code: 'invalid-password-hash',
|
||||
message: 'The password hash must be a valid byte buffer.',
|
||||
};
|
||||
AuthClientErrorCode.INVALID_PASSWORD_SALT = {
|
||||
code: 'invalid-password-salt',
|
||||
message: 'The password salt must be a valid byte buffer.',
|
||||
};
|
||||
AuthClientErrorCode.INVALID_PHONE_NUMBER = {
|
||||
code: 'invalid-phone-number',
|
||||
message: 'The phone number must be a non-empty E.164 standard compliant identifier ' +
|
||||
'string.',
|
||||
};
|
||||
AuthClientErrorCode.INVALID_PHOTO_URL = {
|
||||
code: 'invalid-photo-url',
|
||||
message: 'The photoURL field must be a valid URL.',
|
||||
};
|
||||
AuthClientErrorCode.INVALID_PROJECT_ID = {
|
||||
code: 'invalid-project-id',
|
||||
message: 'Invalid parent project. Either parent project doesn\'t exist or didn\'t enable multi-tenancy.',
|
||||
};
|
||||
AuthClientErrorCode.INVALID_PROVIDER_DATA = {
|
||||
code: 'invalid-provider-data',
|
||||
message: 'The providerData must be a valid array of UserInfo objects.',
|
||||
};
|
||||
AuthClientErrorCode.INVALID_PROVIDER_ID = {
|
||||
code: 'invalid-provider-id',
|
||||
message: 'The providerId must be a valid supported provider identifier string.',
|
||||
};
|
||||
AuthClientErrorCode.INVALID_SESSION_COOKIE_DURATION = {
|
||||
code: 'invalid-session-cookie-duration',
|
||||
message: 'The session cookie duration must be a valid number in milliseconds ' +
|
||||
'between 5 minutes and 2 weeks.',
|
||||
};
|
||||
AuthClientErrorCode.INVALID_TENANT_ID = {
|
||||
code: 'invalid-tenant-id',
|
||||
message: 'The tenant ID must be a valid non-empty string.',
|
||||
};
|
||||
AuthClientErrorCode.INVALID_TENANT_TYPE = {
|
||||
code: 'invalid-tenant-type',
|
||||
message: 'Tenant type must be either "full_service" or "lightweight".',
|
||||
};
|
||||
AuthClientErrorCode.INVALID_UID = {
|
||||
code: 'invalid-uid',
|
||||
message: 'The uid must be a non-empty string with at most 128 characters.',
|
||||
};
|
||||
AuthClientErrorCode.INVALID_USER_IMPORT = {
|
||||
code: 'invalid-user-import',
|
||||
message: 'The user record to import is invalid.',
|
||||
};
|
||||
AuthClientErrorCode.INVALID_TOKENS_VALID_AFTER_TIME = {
|
||||
code: 'invalid-tokens-valid-after-time',
|
||||
message: 'The tokensValidAfterTime must be a valid UTC number in seconds.',
|
||||
};
|
||||
AuthClientErrorCode.MISMATCHING_TENANT_ID = {
|
||||
code: 'mismatching-tenant-id',
|
||||
message: 'User tenant ID does not match with the current TenantAwareAuth tenant ID.',
|
||||
};
|
||||
AuthClientErrorCode.MISSING_ANDROID_PACKAGE_NAME = {
|
||||
code: 'missing-android-pkg-name',
|
||||
message: 'An Android Package Name must be provided if the Android App is ' +
|
||||
'required to be installed.',
|
||||
};
|
||||
AuthClientErrorCode.MISSING_CONFIG = {
|
||||
code: 'missing-config',
|
||||
message: 'The provided configuration is missing required attributes.',
|
||||
};
|
||||
AuthClientErrorCode.MISSING_CONTINUE_URI = {
|
||||
code: 'missing-continue-uri',
|
||||
message: 'A valid continue URL must be provided in the request.',
|
||||
};
|
||||
AuthClientErrorCode.MISSING_DISPLAY_NAME = {
|
||||
code: 'missing-display-name',
|
||||
message: 'The resource being created or edited is missing a valid display name.',
|
||||
};
|
||||
AuthClientErrorCode.MISSING_IOS_BUNDLE_ID = {
|
||||
code: 'missing-ios-bundle-id',
|
||||
message: 'The request is missing an iOS Bundle ID.',
|
||||
};
|
||||
AuthClientErrorCode.MISSING_ISSUER = {
|
||||
code: 'missing-issuer',
|
||||
message: 'The OAuth/OIDC configuration issuer must not be empty.',
|
||||
};
|
||||
AuthClientErrorCode.MISSING_HASH_ALGORITHM = {
|
||||
code: 'missing-hash-algorithm',
|
||||
message: 'Importing users with password hashes requires that the hashing ' +
|
||||
'algorithm and its parameters be provided.',
|
||||
};
|
||||
AuthClientErrorCode.MISSING_OAUTH_CLIENT_ID = {
|
||||
code: 'missing-oauth-client-id',
|
||||
message: 'The OAuth/OIDC configuration client ID must not be empty.',
|
||||
};
|
||||
AuthClientErrorCode.MISSING_PROVIDER_ID = {
|
||||
code: 'missing-provider-id',
|
||||
message: 'A valid provider ID must be provided in the request.',
|
||||
};
|
||||
AuthClientErrorCode.MISSING_SAML_RELYING_PARTY_CONFIG = {
|
||||
code: 'missing-saml-relying-party-config',
|
||||
message: 'The SAML configuration provided is missing a relying party configuration.',
|
||||
};
|
||||
AuthClientErrorCode.MAXIMUM_USER_COUNT_EXCEEDED = {
|
||||
code: 'maximum-user-count-exceeded',
|
||||
message: 'The maximum allowed number of users to import has been exceeded.',
|
||||
};
|
||||
AuthClientErrorCode.MISSING_UID = {
|
||||
code: 'missing-uid',
|
||||
message: 'A uid identifier is required for the current operation.',
|
||||
};
|
||||
AuthClientErrorCode.OPERATION_NOT_ALLOWED = {
|
||||
code: 'operation-not-allowed',
|
||||
message: 'The given sign-in provider is disabled for this Firebase project. ' +
|
||||
'Enable it in the Firebase console, under the sign-in method tab of the ' +
|
||||
'Auth section.',
|
||||
};
|
||||
AuthClientErrorCode.PHONE_NUMBER_ALREADY_EXISTS = {
|
||||
code: 'phone-number-already-exists',
|
||||
message: 'The user with the provided phone number already exists.',
|
||||
};
|
||||
AuthClientErrorCode.PROJECT_NOT_FOUND = {
|
||||
code: 'project-not-found',
|
||||
message: 'No Firebase project was found for the provided credential.',
|
||||
};
|
||||
AuthClientErrorCode.INSUFFICIENT_PERMISSION = {
|
||||
code: 'insufficient-permission',
|
||||
message: 'Credential implementation provided to initializeApp() via the "credential" property ' +
|
||||
'has insufficient permission to access the requested resource. See ' +
|
||||
'https://firebase.google.com/docs/admin/setup for details on how to authenticate this SDK ' +
|
||||
'with appropriate permissions.',
|
||||
};
|
||||
AuthClientErrorCode.QUOTA_EXCEEDED = {
|
||||
code: 'quota-exceeded',
|
||||
message: 'The project quota for the specified operation has been exceeded.',
|
||||
};
|
||||
AuthClientErrorCode.SESSION_COOKIE_EXPIRED = {
|
||||
code: 'session-cookie-expired',
|
||||
message: 'The Firebase session cookie is expired.',
|
||||
};
|
||||
AuthClientErrorCode.SESSION_COOKIE_REVOKED = {
|
||||
code: 'session-cookie-revoked',
|
||||
message: 'The Firebase session cookie has been revoked.',
|
||||
};
|
||||
AuthClientErrorCode.TENANT_NOT_FOUND = {
|
||||
code: 'tenant-not-found',
|
||||
message: 'There is no tenant corresponding to the provided identifier.',
|
||||
};
|
||||
AuthClientErrorCode.UID_ALREADY_EXISTS = {
|
||||
code: 'uid-already-exists',
|
||||
message: 'The user with the provided uid already exists.',
|
||||
};
|
||||
AuthClientErrorCode.UNAUTHORIZED_DOMAIN = {
|
||||
code: 'unauthorized-continue-uri',
|
||||
message: 'The domain of the continue URL is not whitelisted. Whitelist the domain in the ' +
|
||||
'Firebase console.',
|
||||
};
|
||||
AuthClientErrorCode.UNSUPPORTED_TENANT_OPERATION = {
|
||||
code: 'unsupported-tenant-operation',
|
||||
message: 'This operation is not supported in a multi-tenant context.',
|
||||
};
|
||||
AuthClientErrorCode.USER_NOT_FOUND = {
|
||||
code: 'user-not-found',
|
||||
message: 'There is no user record corresponding to the provided identifier.',
|
||||
};
|
||||
AuthClientErrorCode.NOT_FOUND = {
|
||||
code: 'not-found',
|
||||
message: 'The requested resource was not found.',
|
||||
};
|
||||
return AuthClientErrorCode;
|
||||
}());
|
||||
exports.AuthClientErrorCode = AuthClientErrorCode;
|
||||
/**
|
||||
* Messaging client error codes and their default messages.
|
||||
*/
|
||||
var MessagingClientErrorCode = /** @class */ (function () {
|
||||
function MessagingClientErrorCode() {
|
||||
}
|
||||
MessagingClientErrorCode.INVALID_ARGUMENT = {
|
||||
code: 'invalid-argument',
|
||||
message: 'Invalid argument provided.',
|
||||
};
|
||||
MessagingClientErrorCode.INVALID_RECIPIENT = {
|
||||
code: 'invalid-recipient',
|
||||
message: 'Invalid message recipient provided.',
|
||||
};
|
||||
MessagingClientErrorCode.INVALID_PAYLOAD = {
|
||||
code: 'invalid-payload',
|
||||
message: 'Invalid message payload provided.',
|
||||
};
|
||||
MessagingClientErrorCode.INVALID_DATA_PAYLOAD_KEY = {
|
||||
code: 'invalid-data-payload-key',
|
||||
message: 'The data message payload contains an invalid key. See the reference documentation ' +
|
||||
'for the DataMessagePayload type for restricted keys.',
|
||||
};
|
||||
MessagingClientErrorCode.PAYLOAD_SIZE_LIMIT_EXCEEDED = {
|
||||
code: 'payload-size-limit-exceeded',
|
||||
message: 'The provided message payload exceeds the FCM size limits. See the error documentation ' +
|
||||
'for more details.',
|
||||
};
|
||||
MessagingClientErrorCode.INVALID_OPTIONS = {
|
||||
code: 'invalid-options',
|
||||
message: 'Invalid message options provided.',
|
||||
};
|
||||
MessagingClientErrorCode.INVALID_REGISTRATION_TOKEN = {
|
||||
code: 'invalid-registration-token',
|
||||
message: 'Invalid registration token provided. Make sure it matches the registration token ' +
|
||||
'the client app receives from registering with FCM.',
|
||||
};
|
||||
MessagingClientErrorCode.REGISTRATION_TOKEN_NOT_REGISTERED = {
|
||||
code: 'registration-token-not-registered',
|
||||
message: 'The provided registration token is not registered. A previously valid registration ' +
|
||||
'token can be unregistered for a variety of reasons. See the error documentation for more ' +
|
||||
'details. Remove this registration token and stop using it to send messages.',
|
||||
};
|
||||
MessagingClientErrorCode.MISMATCHED_CREDENTIAL = {
|
||||
code: 'mismatched-credential',
|
||||
message: 'The credential used to authenticate this SDK does not have permission to send ' +
|
||||
'messages to the device corresponding to the provided registration token. Make sure the ' +
|
||||
'credential and registration token both belong to the same Firebase project.',
|
||||
};
|
||||
MessagingClientErrorCode.INVALID_PACKAGE_NAME = {
|
||||
code: 'invalid-package-name',
|
||||
message: 'The message was addressed to a registration token whose package name does not match ' +
|
||||
'the provided "restrictedPackageName" option.',
|
||||
};
|
||||
MessagingClientErrorCode.DEVICE_MESSAGE_RATE_EXCEEDED = {
|
||||
code: 'device-message-rate-exceeded',
|
||||
message: 'The rate of messages to a particular device is too high. Reduce the number of ' +
|
||||
'messages sent to this device and do not immediately retry sending to this device.',
|
||||
};
|
||||
MessagingClientErrorCode.TOPICS_MESSAGE_RATE_EXCEEDED = {
|
||||
code: 'topics-message-rate-exceeded',
|
||||
message: 'The rate of messages to subscribers to a particular topic is too high. Reduce the ' +
|
||||
'number of messages sent for this topic, and do not immediately retry sending to this topic.',
|
||||
};
|
||||
MessagingClientErrorCode.MESSAGE_RATE_EXCEEDED = {
|
||||
code: 'message-rate-exceeded',
|
||||
message: 'Sending limit exceeded for the message target.',
|
||||
};
|
||||
MessagingClientErrorCode.THIRD_PARTY_AUTH_ERROR = {
|
||||
code: 'third-party-auth-error',
|
||||
message: 'A message targeted to an iOS device could not be sent because the required APNs ' +
|
||||
'SSL certificate was not uploaded or has expired. Check the validity of your development ' +
|
||||
'and production certificates.',
|
||||
};
|
||||
MessagingClientErrorCode.TOO_MANY_TOPICS = {
|
||||
code: 'too-many-topics',
|
||||
message: 'The maximum number of topics the provided registration token can be subscribed to ' +
|
||||
'has been exceeded.',
|
||||
};
|
||||
MessagingClientErrorCode.AUTHENTICATION_ERROR = {
|
||||
code: 'authentication-error',
|
||||
message: 'An error occurred when trying to authenticate to the FCM servers. Make sure the ' +
|
||||
'credential used to authenticate this SDK has the proper permissions. See ' +
|
||||
'https://firebase.google.com/docs/admin/setup for setup instructions.',
|
||||
};
|
||||
MessagingClientErrorCode.SERVER_UNAVAILABLE = {
|
||||
code: 'server-unavailable',
|
||||
message: 'The FCM server could not process the request in time. See the error documentation ' +
|
||||
'for more details.',
|
||||
};
|
||||
MessagingClientErrorCode.INTERNAL_ERROR = {
|
||||
code: 'internal-error',
|
||||
message: 'An internal error has occurred. Please retry the request.',
|
||||
};
|
||||
MessagingClientErrorCode.UNKNOWN_ERROR = {
|
||||
code: 'unknown-error',
|
||||
message: 'An unknown server error was returned.',
|
||||
};
|
||||
return MessagingClientErrorCode;
|
||||
}());
|
||||
exports.MessagingClientErrorCode = MessagingClientErrorCode;
|
||||
var InstanceIdClientErrorCode = /** @class */ (function () {
|
||||
function InstanceIdClientErrorCode() {
|
||||
}
|
||||
InstanceIdClientErrorCode.INVALID_ARGUMENT = {
|
||||
code: 'invalid-argument',
|
||||
message: 'Invalid argument provided.',
|
||||
};
|
||||
InstanceIdClientErrorCode.INVALID_PROJECT_ID = {
|
||||
code: 'invalid-project-id',
|
||||
message: 'Invalid project ID provided.',
|
||||
};
|
||||
InstanceIdClientErrorCode.INVALID_INSTANCE_ID = {
|
||||
code: 'invalid-instance-id',
|
||||
message: 'Invalid instance ID provided.',
|
||||
};
|
||||
InstanceIdClientErrorCode.API_ERROR = {
|
||||
code: 'api-error',
|
||||
message: 'Instance ID API call failed.',
|
||||
};
|
||||
return InstanceIdClientErrorCode;
|
||||
}());
|
||||
exports.InstanceIdClientErrorCode = InstanceIdClientErrorCode;
|
||||
/** @const {ServerToClientCode} Auth server to client enum error codes. */
|
||||
var AUTH_SERVER_TO_CLIENT_CODE = {
|
||||
// Feature being configured or used requires a billing account.
|
||||
BILLING_NOT_ENABLED: 'BILLING_NOT_ENABLED',
|
||||
// Claims payload is too large.
|
||||
CLAIMS_TOO_LARGE: 'CLAIMS_TOO_LARGE',
|
||||
// Configuration being added already exists.
|
||||
CONFIGURATION_EXISTS: 'CONFIGURATION_EXISTS',
|
||||
// Configuration not found.
|
||||
CONFIGURATION_NOT_FOUND: 'CONFIGURATION_NOT_FOUND',
|
||||
// Provided credential has insufficient permissions.
|
||||
INSUFFICIENT_PERMISSION: 'INSUFFICIENT_PERMISSION',
|
||||
// Provided configuration has invalid fields.
|
||||
INVALID_CONFIG: 'INVALID_CONFIG',
|
||||
// Provided configuration identifier is invalid.
|
||||
INVALID_CONFIG_ID: 'INVALID_PROVIDER_ID',
|
||||
// ActionCodeSettings missing continue URL.
|
||||
INVALID_CONTINUE_URI: 'INVALID_CONTINUE_URI',
|
||||
// Dynamic link domain in provided ActionCodeSettings is not authorized.
|
||||
INVALID_DYNAMIC_LINK_DOMAIN: 'INVALID_DYNAMIC_LINK_DOMAIN',
|
||||
// uploadAccount provides an email that already exists.
|
||||
DUPLICATE_EMAIL: 'EMAIL_ALREADY_EXISTS',
|
||||
// uploadAccount provides a localId that already exists.
|
||||
DUPLICATE_LOCAL_ID: 'UID_ALREADY_EXISTS',
|
||||
// setAccountInfo email already exists.
|
||||
EMAIL_EXISTS: 'EMAIL_ALREADY_EXISTS',
|
||||
// Reserved claim name.
|
||||
FORBIDDEN_CLAIM: 'FORBIDDEN_CLAIM',
|
||||
// Invalid claims provided.
|
||||
INVALID_CLAIMS: 'INVALID_CLAIMS',
|
||||
// Invalid session cookie duration.
|
||||
INVALID_DURATION: 'INVALID_SESSION_COOKIE_DURATION',
|
||||
// Invalid email provided.
|
||||
INVALID_EMAIL: 'INVALID_EMAIL',
|
||||
// Invalid tenant display name. This can be thrown on CreateTenant and UpdateTenant.
|
||||
INVALID_DISPLAY_NAME: 'INVALID_DISPLAY_NAME',
|
||||
// Invalid ID token provided.
|
||||
INVALID_ID_TOKEN: 'INVALID_ID_TOKEN',
|
||||
// Invalid tenant/parent resource name.
|
||||
INVALID_NAME: 'INVALID_NAME',
|
||||
// OIDC configuration has an invalid OAuth client ID.
|
||||
INVALID_OAUTH_CLIENT_ID: 'INVALID_OAUTH_CLIENT_ID',
|
||||
// Invalid page token.
|
||||
INVALID_PAGE_SELECTION: 'INVALID_PAGE_TOKEN',
|
||||
// Invalid phone number.
|
||||
INVALID_PHONE_NUMBER: 'INVALID_PHONE_NUMBER',
|
||||
// Invalid agent project. Either agent project doesn't exist or didn't enable multi-tenancy.
|
||||
INVALID_PROJECT_ID: 'INVALID_PROJECT_ID',
|
||||
// Invalid provider ID.
|
||||
INVALID_PROVIDER_ID: 'INVALID_PROVIDER_ID',
|
||||
// Invalid service account.
|
||||
INVALID_SERVICE_ACCOUNT: 'INVALID_SERVICE_ACCOUNT',
|
||||
// Invalid tenant type.
|
||||
INVALID_TENANT_TYPE: 'INVALID_TENANT_TYPE',
|
||||
// Missing Android package name.
|
||||
MISSING_ANDROID_PACKAGE_NAME: 'MISSING_ANDROID_PACKAGE_NAME',
|
||||
// Missing configuration.
|
||||
MISSING_CONFIG: 'MISSING_CONFIG',
|
||||
// Missing configuration identifier.
|
||||
MISSING_CONFIG_ID: 'MISSING_PROVIDER_ID',
|
||||
// Missing tenant display name: This can be thrown on CreateTenant and UpdateTenant.
|
||||
MISSING_DISPLAY_NAME: 'MISSING_DISPLAY_NAME',
|
||||
// Missing iOS bundle ID.
|
||||
MISSING_IOS_BUNDLE_ID: 'MISSING_IOS_BUNDLE_ID',
|
||||
// Missing OIDC issuer.
|
||||
MISSING_ISSUER: 'MISSING_ISSUER',
|
||||
// No localId provided (deleteAccount missing localId).
|
||||
MISSING_LOCAL_ID: 'MISSING_UID',
|
||||
// OIDC configuration is missing an OAuth client ID.
|
||||
MISSING_OAUTH_CLIENT_ID: 'MISSING_OAUTH_CLIENT_ID',
|
||||
// Missing provider ID.
|
||||
MISSING_PROVIDER_ID: 'MISSING_PROVIDER_ID',
|
||||
// Missing SAML RP config.
|
||||
MISSING_SAML_RELYING_PARTY_CONFIG: 'MISSING_SAML_RELYING_PARTY_CONFIG',
|
||||
// Empty user list in uploadAccount.
|
||||
MISSING_USER_ACCOUNT: 'MISSING_UID',
|
||||
// Password auth disabled in console.
|
||||
OPERATION_NOT_ALLOWED: 'OPERATION_NOT_ALLOWED',
|
||||
// Provided credential has insufficient permissions.
|
||||
PERMISSION_DENIED: 'INSUFFICIENT_PERMISSION',
|
||||
// Phone number already exists.
|
||||
PHONE_NUMBER_EXISTS: 'PHONE_NUMBER_ALREADY_EXISTS',
|
||||
// Project not found.
|
||||
PROJECT_NOT_FOUND: 'PROJECT_NOT_FOUND',
|
||||
// In multi-tenancy context: project creation quota exceeded.
|
||||
QUOTA_EXCEEDED: 'QUOTA_EXCEEDED',
|
||||
// Tenant not found.
|
||||
TENANT_NOT_FOUND: 'TENANT_NOT_FOUND',
|
||||
// Tenant ID mismatch.
|
||||
TENANT_ID_MISMATCH: 'MISMATCHING_TENANT_ID',
|
||||
// Token expired error.
|
||||
TOKEN_EXPIRED: 'ID_TOKEN_EXPIRED',
|
||||
// Continue URL provided in ActionCodeSettings has a domain that is not whitelisted.
|
||||
UNAUTHORIZED_DOMAIN: 'UNAUTHORIZED_DOMAIN',
|
||||
// Operation is not supported in a multi-tenant context.
|
||||
UNSUPPORTED_TENANT_OPERATION: 'UNSUPPORTED_TENANT_OPERATION',
|
||||
// User on which action is to be performed is not found.
|
||||
USER_NOT_FOUND: 'USER_NOT_FOUND',
|
||||
// Password provided is too weak.
|
||||
WEAK_PASSWORD: 'INVALID_PASSWORD',
|
||||
};
|
||||
/** @const {ServerToClientCode} Messaging server to client enum error codes. */
|
||||
var MESSAGING_SERVER_TO_CLIENT_CODE = {
|
||||
/* GENERIC ERRORS */
|
||||
// Generic invalid message parameter provided.
|
||||
InvalidParameters: 'INVALID_ARGUMENT',
|
||||
// Mismatched sender ID.
|
||||
MismatchSenderId: 'MISMATCHED_CREDENTIAL',
|
||||
// FCM server unavailable.
|
||||
Unavailable: 'SERVER_UNAVAILABLE',
|
||||
// FCM server internal error.
|
||||
InternalServerError: 'INTERNAL_ERROR',
|
||||
/* SEND ERRORS */
|
||||
// Invalid registration token format.
|
||||
InvalidRegistration: 'INVALID_REGISTRATION_TOKEN',
|
||||
// Registration token is not registered.
|
||||
NotRegistered: 'REGISTRATION_TOKEN_NOT_REGISTERED',
|
||||
// Registration token does not match restricted package name.
|
||||
InvalidPackageName: 'INVALID_PACKAGE_NAME',
|
||||
// Message payload size limit exceeded.
|
||||
MessageTooBig: 'PAYLOAD_SIZE_LIMIT_EXCEEDED',
|
||||
// Invalid key in the data message payload.
|
||||
InvalidDataKey: 'INVALID_DATA_PAYLOAD_KEY',
|
||||
// Invalid time to live option.
|
||||
InvalidTtl: 'INVALID_OPTIONS',
|
||||
// Device message rate exceeded.
|
||||
DeviceMessageRateExceeded: 'DEVICE_MESSAGE_RATE_EXCEEDED',
|
||||
// Topics message rate exceeded.
|
||||
TopicsMessageRateExceeded: 'TOPICS_MESSAGE_RATE_EXCEEDED',
|
||||
// Invalid APNs credentials.
|
||||
InvalidApnsCredential: 'THIRD_PARTY_AUTH_ERROR',
|
||||
/* FCM v1 canonical error codes */
|
||||
NOT_FOUND: 'REGISTRATION_TOKEN_NOT_REGISTERED',
|
||||
PERMISSION_DENIED: 'MISMATCHED_CREDENTIAL',
|
||||
RESOURCE_EXHAUSTED: 'MESSAGE_RATE_EXCEEDED',
|
||||
UNAUTHENTICATED: 'THIRD_PARTY_AUTH_ERROR',
|
||||
/* FCM v1 new error codes */
|
||||
APNS_AUTH_ERROR: 'THIRD_PARTY_AUTH_ERROR',
|
||||
INTERNAL: 'INTERNAL_ERROR',
|
||||
INVALID_ARGUMENT: 'INVALID_ARGUMENT',
|
||||
QUOTA_EXCEEDED: 'MESSAGE_RATE_EXCEEDED',
|
||||
SENDER_ID_MISMATCH: 'MISMATCHED_CREDENTIAL',
|
||||
THIRD_PARTY_AUTH_ERROR: 'THIRD_PARTY_AUTH_ERROR',
|
||||
UNAVAILABLE: 'SERVER_UNAVAILABLE',
|
||||
UNREGISTERED: 'REGISTRATION_TOKEN_NOT_REGISTERED',
|
||||
UNSPECIFIED_ERROR: 'UNKNOWN_ERROR',
|
||||
};
|
||||
/** @const {ServerToClientCode} Topic management (IID) server to client enum error codes. */
|
||||
var TOPIC_MGT_SERVER_TO_CLIENT_CODE = {
|
||||
/* TOPIC SUBSCRIPTION MANAGEMENT ERRORS */
|
||||
NOT_FOUND: 'REGISTRATION_TOKEN_NOT_REGISTERED',
|
||||
INVALID_ARGUMENT: 'INVALID_REGISTRATION_TOKEN',
|
||||
TOO_MANY_TOPICS: 'TOO_MANY_TOPICS',
|
||||
RESOURCE_EXHAUSTED: 'TOO_MANY_TOPICS',
|
||||
PERMISSION_DENIED: 'AUTHENTICATION_ERROR',
|
||||
DEADLINE_EXCEEDED: 'SERVER_UNAVAILABLE',
|
||||
INTERNAL: 'INTERNAL_ERROR',
|
||||
UNKNOWN: 'UNKNOWN_ERROR',
|
||||
};
|
164
node_modules/firebase-admin/lib/utils/index.js
generated
vendored
Normal file
164
node_modules/firebase-admin/lib/utils/index.js
generated
vendored
Normal file
@ -0,0 +1,164 @@
|
||||
/*! firebase-admin v8.9.2 */
|
||||
"use strict";
|
||||
/*!
|
||||
* Copyright 2017 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
var credential_1 = require("../auth/credential");
|
||||
var validator = require("./validator");
|
||||
/**
|
||||
* Renames properties on an object given a mapping from old to new property names.
|
||||
*
|
||||
* For example, this can be used to map underscore_cased properties to camelCase.
|
||||
*
|
||||
* @param {object} obj The object whose properties to rename.
|
||||
* @param {object} keyMap The mapping from old to new property names.
|
||||
*/
|
||||
function renameProperties(obj, keyMap) {
|
||||
Object.keys(keyMap).forEach(function (oldKey) {
|
||||
if (oldKey in obj) {
|
||||
var newKey = keyMap[oldKey];
|
||||
// The old key's value takes precedence over the new key's value.
|
||||
obj[newKey] = obj[oldKey];
|
||||
delete obj[oldKey];
|
||||
}
|
||||
});
|
||||
}
|
||||
exports.renameProperties = renameProperties;
|
||||
/**
|
||||
* Defines a new read-only property directly on an object and returns the object.
|
||||
*
|
||||
* @param {object} obj The object on which to define the property.
|
||||
* @param {string} prop The name of the property to be defined or modified.
|
||||
* @param {any} value The value associated with the property.
|
||||
*/
|
||||
function addReadonlyGetter(obj, prop, value) {
|
||||
Object.defineProperty(obj, prop, {
|
||||
value: value,
|
||||
// Make this property read-only.
|
||||
writable: false,
|
||||
// Include this property during enumeration of obj's properties.
|
||||
enumerable: true,
|
||||
});
|
||||
}
|
||||
exports.addReadonlyGetter = addReadonlyGetter;
|
||||
/**
|
||||
* Returns the Google Cloud project ID associated with a Firebase app, if it's explicitly
|
||||
* specified in either the Firebase app options, credentials or the local environment.
|
||||
* Otherwise returns null.
|
||||
*
|
||||
* @param {FirebaseApp} app A Firebase app to get the project ID from.
|
||||
*
|
||||
* @return {string} A project ID string or null.
|
||||
*/
|
||||
function getExplicitProjectId(app) {
|
||||
var options = app.options;
|
||||
if (validator.isNonEmptyString(options.projectId)) {
|
||||
return options.projectId;
|
||||
}
|
||||
var credential = app.options.credential;
|
||||
if (credential instanceof credential_1.ServiceAccountCredential) {
|
||||
return credential.projectId;
|
||||
}
|
||||
var projectId = process.env.GOOGLE_CLOUD_PROJECT || process.env.GCLOUD_PROJECT;
|
||||
if (validator.isNonEmptyString(projectId)) {
|
||||
return projectId;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
exports.getExplicitProjectId = getExplicitProjectId;
|
||||
/**
|
||||
* Determines the Google Cloud project ID associated with a Firebase app. This method
|
||||
* first checks if a project ID is explicitly specified in either the Firebase app options,
|
||||
* credentials or the local environment in that order. If no explicit project ID is
|
||||
* configured, but the SDK has been initialized with ComputeEngineCredentials, this
|
||||
* method attempts to discover the project ID from the local metadata service.
|
||||
*
|
||||
* @param {FirebaseApp} app A Firebase app to get the project ID from.
|
||||
*
|
||||
* @return {Promise<string | null>} A project ID string or null.
|
||||
*/
|
||||
function findProjectId(app) {
|
||||
var projectId = getExplicitProjectId(app);
|
||||
if (projectId) {
|
||||
return Promise.resolve(projectId);
|
||||
}
|
||||
var credential = app.options.credential;
|
||||
if (credential instanceof credential_1.ComputeEngineCredential) {
|
||||
return credential.getProjectId();
|
||||
}
|
||||
return Promise.resolve(null);
|
||||
}
|
||||
exports.findProjectId = findProjectId;
|
||||
/**
|
||||
* Encodes data using web-safe-base64.
|
||||
*
|
||||
* @param {Buffer} data The raw data byte input.
|
||||
* @return {string} The base64-encoded result.
|
||||
*/
|
||||
function toWebSafeBase64(data) {
|
||||
return data.toString('base64').replace(/\//g, '_').replace(/\+/g, '-');
|
||||
}
|
||||
exports.toWebSafeBase64 = toWebSafeBase64;
|
||||
/**
|
||||
* Formats a string of form 'project/{projectId}/{api}' and replaces
|
||||
* with corresponding arguments {projectId: '1234', api: 'resource'}
|
||||
* and returns output: 'project/1234/resource'.
|
||||
*
|
||||
* @param {string} str The original string where the param need to be
|
||||
* replaced.
|
||||
* @param {object=} params The optional parameters to replace in the
|
||||
* string.
|
||||
* @return {string} The resulting formatted string.
|
||||
*/
|
||||
function formatString(str, params) {
|
||||
var formatted = str;
|
||||
Object.keys(params || {}).forEach(function (key) {
|
||||
formatted = formatted.replace(new RegExp('{' + key + '}', 'g'), params[key]);
|
||||
});
|
||||
return formatted;
|
||||
}
|
||||
exports.formatString = formatString;
|
||||
/**
|
||||
* Generates the update mask for the provided object.
|
||||
* Note this will ignore the last key with value undefined.
|
||||
*
|
||||
* @param {[key: string]: any} obj The object to generate the update mask for.
|
||||
* @return {Array<string>} The computed update mask list.
|
||||
*/
|
||||
function generateUpdateMask(obj) {
|
||||
var updateMask = [];
|
||||
if (!validator.isNonNullObject(obj)) {
|
||||
return updateMask;
|
||||
}
|
||||
var _loop_1 = function (key) {
|
||||
if (obj.hasOwnProperty(key) && typeof obj[key] !== 'undefined') {
|
||||
var maskList = generateUpdateMask(obj[key]);
|
||||
if (maskList.length > 0) {
|
||||
maskList.forEach(function (mask) {
|
||||
updateMask.push(key + "." + mask);
|
||||
});
|
||||
}
|
||||
else {
|
||||
updateMask.push(key);
|
||||
}
|
||||
}
|
||||
};
|
||||
for (var key in obj) {
|
||||
_loop_1(key);
|
||||
}
|
||||
return updateMask;
|
||||
}
|
||||
exports.generateUpdateMask = generateUpdateMask;
|
237
node_modules/firebase-admin/lib/utils/validator.js
generated
vendored
Normal file
237
node_modules/firebase-admin/lib/utils/validator.js
generated
vendored
Normal file
@ -0,0 +1,237 @@
|
||||
/*! firebase-admin v8.9.2 */
|
||||
"use strict";
|
||||
/*!
|
||||
* Copyright 2017 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
var url = require("url");
|
||||
/**
|
||||
* Validates that a value is a byte buffer.
|
||||
*
|
||||
* @param {any} value The value to validate.
|
||||
* @return {boolean} Whether the value is byte buffer or not.
|
||||
*/
|
||||
function isBuffer(value) {
|
||||
return value instanceof Buffer;
|
||||
}
|
||||
exports.isBuffer = isBuffer;
|
||||
/**
|
||||
* Validates that a value is an array.
|
||||
*
|
||||
* @param {any} value The value to validate.
|
||||
* @return {boolean} Whether the value is an array or not.
|
||||
*/
|
||||
function isArray(value) {
|
||||
return Array.isArray(value);
|
||||
}
|
||||
exports.isArray = isArray;
|
||||
/**
|
||||
* Validates that a value is a non-empty array.
|
||||
*
|
||||
* @param {any} value The value to validate.
|
||||
* @return {boolean} Whether the value is a non-empty array or not.
|
||||
*/
|
||||
function isNonEmptyArray(value) {
|
||||
return isArray(value) && value.length !== 0;
|
||||
}
|
||||
exports.isNonEmptyArray = isNonEmptyArray;
|
||||
/**
|
||||
* Validates that a value is a boolean.
|
||||
*
|
||||
* @param {any} value The value to validate.
|
||||
* @return {boolean} Whether the value is a boolean or not.
|
||||
*/
|
||||
function isBoolean(value) {
|
||||
return typeof value === 'boolean';
|
||||
}
|
||||
exports.isBoolean = isBoolean;
|
||||
/**
|
||||
* Validates that a value is a number.
|
||||
*
|
||||
* @param {any} value The value to validate.
|
||||
* @return {boolean} Whether the value is a number or not.
|
||||
*/
|
||||
function isNumber(value) {
|
||||
return typeof value === 'number' && !isNaN(value);
|
||||
}
|
||||
exports.isNumber = isNumber;
|
||||
/**
|
||||
* Validates that a value is a string.
|
||||
*
|
||||
* @param {any} value The value to validate.
|
||||
* @return {boolean} Whether the value is a string or not.
|
||||
*/
|
||||
function isString(value) {
|
||||
return typeof value === 'string';
|
||||
}
|
||||
exports.isString = isString;
|
||||
/**
|
||||
* Validates that a value is a base64 string.
|
||||
*
|
||||
* @param {any} value The value to validate.
|
||||
* @return {boolean} Whether the value is a base64 string or not.
|
||||
*/
|
||||
function isBase64String(value) {
|
||||
if (!isString(value)) {
|
||||
return false;
|
||||
}
|
||||
return /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(value);
|
||||
}
|
||||
exports.isBase64String = isBase64String;
|
||||
/**
|
||||
* Validates that a value is a non-empty string.
|
||||
*
|
||||
* @param {any} value The value to validate.
|
||||
* @return {boolean} Whether the value is a non-empty string or not.
|
||||
*/
|
||||
function isNonEmptyString(value) {
|
||||
return isString(value) && value !== '';
|
||||
}
|
||||
exports.isNonEmptyString = isNonEmptyString;
|
||||
/**
|
||||
* Validates that a value is a nullable object.
|
||||
*
|
||||
* @param {any} value The value to validate.
|
||||
* @return {boolean} Whether the value is an object or not.
|
||||
*/
|
||||
function isObject(value) {
|
||||
return typeof value === 'object' && !isArray(value);
|
||||
}
|
||||
exports.isObject = isObject;
|
||||
/**
|
||||
* Validates that a value is a non-null object.
|
||||
*
|
||||
* @param {any} value The value to validate.
|
||||
* @return {boolean} Whether the value is a non-null object or not.
|
||||
*/
|
||||
function isNonNullObject(value) {
|
||||
return isObject(value) && value !== null;
|
||||
}
|
||||
exports.isNonNullObject = isNonNullObject;
|
||||
/**
|
||||
* Validates that a string is a valid Firebase Auth uid.
|
||||
*
|
||||
* @param {any} uid The string to validate.
|
||||
* @return {boolean} Whether the string is a valid Firebase Auth uid.
|
||||
*/
|
||||
function isUid(uid) {
|
||||
return typeof uid === 'string' && uid.length > 0 && uid.length <= 128;
|
||||
}
|
||||
exports.isUid = isUid;
|
||||
/**
|
||||
* Validates that a string is a valid Firebase Auth password.
|
||||
*
|
||||
* @param {any} password The password string to validate.
|
||||
* @return {boolean} Whether the string is a valid Firebase Auth password.
|
||||
*/
|
||||
function isPassword(password) {
|
||||
// A password must be a string of at least 6 characters.
|
||||
return typeof password === 'string' && password.length >= 6;
|
||||
}
|
||||
exports.isPassword = isPassword;
|
||||
/**
|
||||
* Validates that a string is a valid email.
|
||||
*
|
||||
* @param {any} email The string to validate.
|
||||
* @return {boolean} Whether the string is valid email or not.
|
||||
*/
|
||||
function isEmail(email) {
|
||||
if (typeof email !== 'string') {
|
||||
return false;
|
||||
}
|
||||
// There must at least one character before the @ symbol and another after.
|
||||
var re = /^[^@]+@[^@]+$/;
|
||||
return re.test(email);
|
||||
}
|
||||
exports.isEmail = isEmail;
|
||||
/**
|
||||
* Validates that a string is a valid phone number.
|
||||
*
|
||||
* @param {any} phoneNumber The string to validate.
|
||||
* @return {boolean} Whether the string is a valid phone number or not.
|
||||
*/
|
||||
function isPhoneNumber(phoneNumber) {
|
||||
if (typeof phoneNumber !== 'string') {
|
||||
return false;
|
||||
}
|
||||
// Phone number validation is very lax here. Backend will enforce E.164
|
||||
// spec compliance and will normalize accordingly.
|
||||
// The phone number string must be non-empty and starts with a plus sign.
|
||||
var re1 = /^\+/;
|
||||
// The phone number string must contain at least one alphanumeric character.
|
||||
var re2 = /[\da-zA-Z]+/;
|
||||
return re1.test(phoneNumber) && re2.test(phoneNumber);
|
||||
}
|
||||
exports.isPhoneNumber = isPhoneNumber;
|
||||
/**
|
||||
* Validates that a string is a valid web URL.
|
||||
*
|
||||
* @param {any} urlStr The string to validate.
|
||||
* @return {boolean} Whether the string is valid web URL or not.
|
||||
*/
|
||||
function isURL(urlStr) {
|
||||
if (typeof urlStr !== 'string') {
|
||||
return false;
|
||||
}
|
||||
// Lookup illegal characters.
|
||||
var re = /[^a-z0-9\:\/\?\#\[\]\@\!\$\&\'\(\)\*\+\,\;\=\.\-\_\~\%]/i;
|
||||
if (re.test(urlStr)) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
var uri = url.parse(urlStr);
|
||||
var scheme = uri.protocol;
|
||||
var slashes = uri.slashes;
|
||||
var hostname = uri.hostname;
|
||||
var pathname = uri.pathname;
|
||||
if ((scheme !== 'http:' && scheme !== 'https:') || !slashes) {
|
||||
return false;
|
||||
}
|
||||
// Validate hostname: Can contain letters, numbers, underscore and dashes separated by a dot.
|
||||
// Each zone must not start with a hyphen or underscore.
|
||||
if (!hostname || !/^[a-zA-Z0-9]+[\w\-]*([\.]?[a-zA-Z0-9]+[\w\-]*)*$/.test(hostname)) {
|
||||
return false;
|
||||
}
|
||||
// Allow for pathnames: (/chars+)*/?
|
||||
// Where chars can be a combination of: a-z A-Z 0-9 - _ . ~ ! $ & ' ( ) * + , ; = : @ %
|
||||
var pathnameRe = /^(\/[\w\-\.\~\!\$\'\(\)\*\+\,\;\=\:\@\%]+)*\/?$/;
|
||||
// Validate pathname.
|
||||
if (pathname &&
|
||||
pathname !== '/' &&
|
||||
!pathnameRe.test(pathname)) {
|
||||
return false;
|
||||
}
|
||||
// Allow any query string and hash as long as no invalid character is used.
|
||||
}
|
||||
catch (e) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
exports.isURL = isURL;
|
||||
/**
|
||||
* Validates that the provided topic is a valid FCM topic name.
|
||||
*
|
||||
* @param {any} topic The topic to validate.
|
||||
* @return {boolean} Whether the provided topic is a valid FCM topic name.
|
||||
*/
|
||||
function isTopic(topic) {
|
||||
if (typeof topic !== 'string') {
|
||||
return false;
|
||||
}
|
||||
var VALID_TOPIC_REGEX = /^(\/topics\/)?(private\/)?[a-zA-Z0-9-_.~%]+$/;
|
||||
return VALID_TOPIC_REGEX.test(topic);
|
||||
}
|
||||
exports.isTopic = isTopic;
|
Reference in New Issue
Block a user