mirror of
https://github.com/titanscouting/tra-analysis.git
synced 2025-09-23 05:40:19 +00:00
push all website files
This commit is contained in:
315
website/functions/node_modules/firebase-admin/lib/auth/user-import-builder.js
generated
vendored
Normal file
315
website/functions/node_modules/firebase-admin/lib/auth/user-import-builder.js
generated
vendored
Normal file
@@ -0,0 +1,315 @@
|
||||
/*! firebase-admin v6.0.0 */
|
||||
"use strict";
|
||||
/*!
|
||||
* Copyright 2018 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 deep_copy_1 = require("../utils/deep-copy");
|
||||
var utils = require("../utils");
|
||||
var validator = require("../utils/validator");
|
||||
var error_1 = require("../utils/error");
|
||||
/**
|
||||
* @param {any} obj The object to check for number field within.
|
||||
* @param {string} key The entry key.
|
||||
* @return {number|undefined} The corresponding number if available.
|
||||
*/
|
||||
function getNumberField(obj, key) {
|
||||
if (typeof obj[key] !== 'undefined' && obj[key] !== null) {
|
||||
return parseInt(obj[key].toString(), 10);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
/**
|
||||
* Converts a UserImportRecord to a UploadAccountUser object. Throws an error when invalid
|
||||
* fields are provided.
|
||||
* @param {UserImportRecord} user The UserImportRecord to conver to UploadAccountUser.
|
||||
* @param {ValidatorFunction=} userValidator The user validator function.
|
||||
* @return {UploadAccountUser} The corresponding UploadAccountUser to return.
|
||||
*/
|
||||
function populateUploadAccountUser(user, userValidator) {
|
||||
var result = {
|
||||
localId: user.uid,
|
||||
email: user.email,
|
||||
emailVerified: user.emailVerified,
|
||||
displayName: user.displayName,
|
||||
disabled: user.disabled,
|
||||
photoUrl: user.photoURL,
|
||||
phoneNumber: user.phoneNumber,
|
||||
providerUserInfo: [],
|
||||
customAttributes: user.customClaims && JSON.stringify(user.customClaims),
|
||||
};
|
||||
if (typeof user.passwordHash !== 'undefined') {
|
||||
if (!validator.isBuffer(user.passwordHash)) {
|
||||
throw new error_1.FirebaseAuthError(error_1.AuthClientErrorCode.INVALID_PASSWORD_HASH);
|
||||
}
|
||||
result.passwordHash = utils.toWebSafeBase64(user.passwordHash);
|
||||
}
|
||||
if (typeof user.passwordSalt !== 'undefined') {
|
||||
if (!validator.isBuffer(user.passwordSalt)) {
|
||||
throw new error_1.FirebaseAuthError(error_1.AuthClientErrorCode.INVALID_PASSWORD_SALT);
|
||||
}
|
||||
result.salt = utils.toWebSafeBase64(user.passwordSalt);
|
||||
}
|
||||
if (validator.isNonNullObject(user.metadata)) {
|
||||
if (validator.isNonEmptyString(user.metadata.creationTime)) {
|
||||
result.createdAt = new Date(user.metadata.creationTime).getTime();
|
||||
}
|
||||
if (validator.isNonEmptyString(user.metadata.lastSignInTime)) {
|
||||
result.lastLoginAt = new Date(user.metadata.lastSignInTime).getTime();
|
||||
}
|
||||
}
|
||||
if (validator.isArray(user.providerData)) {
|
||||
user.providerData.forEach(function (providerData) {
|
||||
result.providerUserInfo.push({
|
||||
providerId: providerData.providerId,
|
||||
rawId: providerData.uid,
|
||||
email: providerData.email,
|
||||
displayName: providerData.displayName,
|
||||
photoUrl: providerData.photoURL,
|
||||
});
|
||||
});
|
||||
}
|
||||
// Remove blank fields.
|
||||
for (var key in result) {
|
||||
if (typeof result[key] === 'undefined') {
|
||||
delete result[key];
|
||||
}
|
||||
}
|
||||
if (result.providerUserInfo.length === 0) {
|
||||
delete result.providerUserInfo;
|
||||
}
|
||||
// Validate the constructured user individual request. This will throw if an error
|
||||
// is detected.
|
||||
if (typeof userValidator === 'function') {
|
||||
userValidator(result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
/**
|
||||
* Class that provides a helper for building/validating uploadAccount requests and
|
||||
* UserImportResult responses.
|
||||
*/
|
||||
var UserImportBuilder = /** @class */ (function () {
|
||||
/**
|
||||
* @param {UserImportRecord[]} users The list of user records to import.
|
||||
* @param {UserImportOptions=} options The import options which includes hashing
|
||||
* algorithm details.
|
||||
* @param {ValidatorFunction=} userRequestValidator The user request validator function.
|
||||
* @constructor
|
||||
*/
|
||||
function UserImportBuilder(users, options, userRequestValidator) {
|
||||
this.users = users;
|
||||
this.options = options;
|
||||
this.userRequestValidator = userRequestValidator;
|
||||
this.requiresHashOptions = false;
|
||||
this.validatedUsers = [];
|
||||
this.userImportResultErrors = [];
|
||||
this.indexMap = {};
|
||||
this.validatedUsers = this.populateUsers(this.users, this.userRequestValidator);
|
||||
this.validatedOptions = this.populateOptions(this.options, this.requiresHashOptions);
|
||||
}
|
||||
/**
|
||||
* Returns the corresponding constructed uploadAccount request.
|
||||
* @return {UploadAccountRequest} The constructed uploadAccount request.
|
||||
*/
|
||||
UserImportBuilder.prototype.buildRequest = function () {
|
||||
var users = this.validatedUsers.map(function (user) {
|
||||
return deep_copy_1.deepCopy(user);
|
||||
});
|
||||
return deep_copy_1.deepExtend({ users: users }, deep_copy_1.deepCopy(this.validatedOptions));
|
||||
};
|
||||
/**
|
||||
* Populates the UserImportResult using the client side detected errors and the server
|
||||
* side returned errors.
|
||||
* @return {UserImportResult} The user import result based on the returned failed
|
||||
* uploadAccount response.
|
||||
*/
|
||||
UserImportBuilder.prototype.buildResponse = function (failedUploads) {
|
||||
var _this = this;
|
||||
// Initialize user import result.
|
||||
var importResult = {
|
||||
successCount: this.users.length - this.userImportResultErrors.length,
|
||||
failureCount: this.userImportResultErrors.length,
|
||||
errors: deep_copy_1.deepCopy(this.userImportResultErrors),
|
||||
};
|
||||
importResult.failureCount += failedUploads.length;
|
||||
importResult.successCount -= failedUploads.length;
|
||||
failedUploads.forEach(function (failedUpload) {
|
||||
importResult.errors.push({
|
||||
// Map backend request index to original developer provided array index.
|
||||
index: _this.indexMap[failedUpload.index],
|
||||
error: new error_1.FirebaseAuthError(error_1.AuthClientErrorCode.INVALID_USER_IMPORT, failedUpload.message),
|
||||
});
|
||||
});
|
||||
// Sort errors by index.
|
||||
importResult.errors.sort(function (a, b) {
|
||||
return a.index - b.index;
|
||||
});
|
||||
// Return sorted result.
|
||||
return importResult;
|
||||
};
|
||||
/**
|
||||
* Validates and returns the hashing options of the uploadAccount request.
|
||||
* Throws an error whenever an invalid or missing options is detected.
|
||||
* @param {UserImportOptions} options The UserImportOptions.
|
||||
* @param {boolean} requiresHashOptions Whether to require hash options.
|
||||
* @return {UploadAccountOptions} The populated UploadAccount options.
|
||||
*/
|
||||
UserImportBuilder.prototype.populateOptions = function (options, requiresHashOptions) {
|
||||
var populatedOptions;
|
||||
if (!requiresHashOptions) {
|
||||
return {};
|
||||
}
|
||||
if (!validator.isNonNullObject(options.hash)) {
|
||||
throw new error_1.FirebaseAuthError(error_1.AuthClientErrorCode.MISSING_HASH_ALGORITHM, "\"hash.algorithm\" is missing from the provided \"UserImportOptions\".");
|
||||
}
|
||||
if (typeof options.hash.algorithm === 'undefined' ||
|
||||
!validator.isNonEmptyString(options.hash.algorithm)) {
|
||||
throw new error_1.FirebaseAuthError(error_1.AuthClientErrorCode.INVALID_HASH_ALGORITHM, "\"hash.algorithm\" must be a string matching the list of supported algorithms.");
|
||||
}
|
||||
var rounds;
|
||||
switch (options.hash.algorithm) {
|
||||
case 'HMAC_SHA512':
|
||||
case 'HMAC_SHA256':
|
||||
case 'HMAC_SHA1':
|
||||
case 'HMAC_MD5':
|
||||
if (!validator.isBuffer(options.hash.key)) {
|
||||
throw new error_1.FirebaseAuthError(error_1.AuthClientErrorCode.INVALID_HASH_KEY, "A non-empty \"hash.key\" byte buffer must be provided for " +
|
||||
("hash algorithm " + options.hash.algorithm + "."));
|
||||
}
|
||||
populatedOptions = {
|
||||
hashAlgorithm: options.hash.algorithm,
|
||||
signerKey: utils.toWebSafeBase64(options.hash.key),
|
||||
};
|
||||
break;
|
||||
case 'MD5':
|
||||
case 'SHA1':
|
||||
case 'SHA256':
|
||||
case 'SHA512':
|
||||
case 'PBKDF_SHA1':
|
||||
case 'PBKDF2_SHA256':
|
||||
rounds = getNumberField(options.hash, 'rounds');
|
||||
if (isNaN(rounds) || rounds < 0 || rounds > 120000) {
|
||||
throw new error_1.FirebaseAuthError(error_1.AuthClientErrorCode.INVALID_HASH_ROUNDS, "A valid \"hash.rounds\" number between 0 and 120000 must be provided for " +
|
||||
("hash algorithm " + options.hash.algorithm + "."));
|
||||
}
|
||||
populatedOptions = {
|
||||
hashAlgorithm: options.hash.algorithm,
|
||||
rounds: rounds,
|
||||
};
|
||||
break;
|
||||
case 'SCRYPT':
|
||||
if (!validator.isBuffer(options.hash.key)) {
|
||||
throw new error_1.FirebaseAuthError(error_1.AuthClientErrorCode.INVALID_HASH_KEY, "A \"hash.key\" byte buffer must be provided for " +
|
||||
("hash algorithm " + options.hash.algorithm + "."));
|
||||
}
|
||||
rounds = getNumberField(options.hash, 'rounds');
|
||||
if (isNaN(rounds) || rounds <= 0 || rounds > 8) {
|
||||
throw new error_1.FirebaseAuthError(error_1.AuthClientErrorCode.INVALID_HASH_ROUNDS, "A valid \"hash.rounds\" number between 1 and 8 must be provided for " +
|
||||
("hash algorithm " + options.hash.algorithm + "."));
|
||||
}
|
||||
var memoryCost = getNumberField(options.hash, 'memoryCost');
|
||||
if (isNaN(memoryCost) || memoryCost <= 0 || memoryCost > 14) {
|
||||
throw new error_1.FirebaseAuthError(error_1.AuthClientErrorCode.INVALID_HASH_MEMORY_COST, "A valid \"hash.memoryCost\" number between 1 and 14 must be provided for " +
|
||||
("hash algorithm " + options.hash.algorithm + "."));
|
||||
}
|
||||
if (typeof options.hash.saltSeparator !== 'undefined' &&
|
||||
!validator.isBuffer(options.hash.saltSeparator)) {
|
||||
throw new error_1.FirebaseAuthError(error_1.AuthClientErrorCode.INVALID_HASH_SALT_SEPARATOR, "\"hash.saltSeparator\" must be a byte buffer.");
|
||||
}
|
||||
populatedOptions = {
|
||||
hashAlgorithm: options.hash.algorithm,
|
||||
signerKey: utils.toWebSafeBase64(options.hash.key),
|
||||
rounds: rounds,
|
||||
memoryCost: memoryCost,
|
||||
saltSeparator: utils.toWebSafeBase64(options.hash.saltSeparator || Buffer.from('')),
|
||||
};
|
||||
break;
|
||||
case 'BCRYPT':
|
||||
populatedOptions = {
|
||||
hashAlgorithm: options.hash.algorithm,
|
||||
};
|
||||
break;
|
||||
case 'STANDARD_SCRYPT':
|
||||
var cpuMemCost = getNumberField(options.hash, 'memoryCost');
|
||||
if (isNaN(cpuMemCost)) {
|
||||
throw new error_1.FirebaseAuthError(error_1.AuthClientErrorCode.INVALID_HASH_MEMORY_COST, "A valid \"hash.memoryCost\" number must be provided for " +
|
||||
("hash algorithm " + options.hash.algorithm + "."));
|
||||
}
|
||||
var parallelization = getNumberField(options.hash, 'parallelization');
|
||||
if (isNaN(parallelization)) {
|
||||
throw new error_1.FirebaseAuthError(error_1.AuthClientErrorCode.INVALID_HASH_PARALLELIZATION, "A valid \"hash.parallelization\" number must be provided for " +
|
||||
("hash algorithm " + options.hash.algorithm + "."));
|
||||
}
|
||||
var blockSize = getNumberField(options.hash, 'blockSize');
|
||||
if (isNaN(blockSize)) {
|
||||
throw new error_1.FirebaseAuthError(error_1.AuthClientErrorCode.INVALID_HASH_BLOCK_SIZE, "A valid \"hash.blockSize\" number must be provided for " +
|
||||
("hash algorithm " + options.hash.algorithm + "."));
|
||||
}
|
||||
var dkLen = getNumberField(options.hash, 'derivedKeyLength');
|
||||
if (isNaN(dkLen)) {
|
||||
throw new error_1.FirebaseAuthError(error_1.AuthClientErrorCode.INVALID_HASH_DERIVED_KEY_LENGTH, "A valid \"hash.derivedKeyLength\" number must be provided for " +
|
||||
("hash algorithm " + options.hash.algorithm + "."));
|
||||
}
|
||||
populatedOptions = {
|
||||
hashAlgorithm: options.hash.algorithm,
|
||||
cpuMemCost: cpuMemCost,
|
||||
parallelization: parallelization,
|
||||
blockSize: blockSize,
|
||||
dkLen: dkLen,
|
||||
};
|
||||
break;
|
||||
default:
|
||||
throw new error_1.FirebaseAuthError(error_1.AuthClientErrorCode.INVALID_HASH_ALGORITHM, "Unsupported hash algorithm provider \"" + options.hash.algorithm + "\".");
|
||||
}
|
||||
return populatedOptions;
|
||||
};
|
||||
/**
|
||||
* Validates and returns the users list of the uploadAccount request.
|
||||
* Whenever a user with an error is detected, the error is cached and will later be
|
||||
* merged into the user import result. This allows the processing of valid users without
|
||||
* failing early on the first error detected.
|
||||
* @param {UserImportRecord[]} users The UserImportRecords to convert to UnploadAccountUser
|
||||
* objects.
|
||||
* @param {ValidatorFunction=} userValidator The user validator function.
|
||||
* @return {UploadAccountUser[]} The populated uploadAccount users.
|
||||
*/
|
||||
UserImportBuilder.prototype.populateUsers = function (users, userValidator) {
|
||||
var _this = this;
|
||||
var populatedUsers = [];
|
||||
users.forEach(function (user, index) {
|
||||
try {
|
||||
var result = populateUploadAccountUser(user, userValidator);
|
||||
if (typeof result.passwordHash !== 'undefined') {
|
||||
_this.requiresHashOptions = true;
|
||||
}
|
||||
// Only users that pass client screening will be passed to backend for processing.
|
||||
populatedUsers.push(result);
|
||||
// Map user's index (the one to be sent to backend) to original developer provided array.
|
||||
_this.indexMap[populatedUsers.length - 1] = index;
|
||||
}
|
||||
catch (error) {
|
||||
// Save the client side error with respect to the developer provided array.
|
||||
_this.userImportResultErrors.push({
|
||||
index: index,
|
||||
error: error,
|
||||
});
|
||||
}
|
||||
});
|
||||
return populatedUsers;
|
||||
};
|
||||
return UserImportBuilder;
|
||||
}());
|
||||
exports.UserImportBuilder = UserImportBuilder;
|
Reference in New Issue
Block a user