/*! firebase-admin v8.7.0 */
"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 deep_copy_1 = require("../utils/deep-copy");
var utils = require("../utils");
var error_1 = require("../utils/error");
/**
 * 'REDACTED', encoded as a base64 string.
 */
var B64_REDACTED = Buffer.from('REDACTED').toString('base64');
/**
 * Parses a time stamp string or number and returns the corresponding date if valid.
 *
 * @param {any} time The unix timestamp string or number in milliseconds.
 * @return {string} The corresponding date as a UTC string, if valid.
 */
function parseDate(time) {
    try {
        var date = new Date(parseInt(time, 10));
        if (!isNaN(date.getTime())) {
            return date.toUTCString();
        }
    }
    catch (e) {
        // Do nothing. null will be returned.
    }
    return null;
}
/**
 * User metadata class that provides metadata information like user account creation
 * and last sign in time.
 *
 * @param {object} response The server side response returned from the getAccountInfo
 *     endpoint.
 * @constructor
 */
var UserMetadata = /** @class */ (function () {
    function UserMetadata(response) {
        // Creation date should always be available but due to some backend bugs there
        // were cases in the past where users did not have creation date properly set.
        // This included legacy Firebase migrating project users and some anonymous users.
        // These bugs have already been addressed since then.
        utils.addReadonlyGetter(this, 'creationTime', parseDate(response.createdAt));
        utils.addReadonlyGetter(this, 'lastSignInTime', parseDate(response.lastLoginAt));
    }
    /** @return {object} The plain object representation of the user's metadata. */
    UserMetadata.prototype.toJSON = function () {
        return {
            lastSignInTime: this.lastSignInTime,
            creationTime: this.creationTime,
        };
    };
    return UserMetadata;
}());
exports.UserMetadata = UserMetadata;
/**
 * User info class that provides provider user information for different
 * Firebase providers like google.com, facebook.com, password, etc.
 *
 * @param {object} response The server side response returned from the getAccountInfo
 *     endpoint.
 * @constructor
 */
var UserInfo = /** @class */ (function () {
    function UserInfo(response) {
        // Provider user id and provider id are required.
        if (!response.rawId || !response.providerId) {
            throw new error_1.FirebaseAuthError(error_1.AuthClientErrorCode.INTERNAL_ERROR, 'INTERNAL ASSERT FAILED: Invalid user info response');
        }
        utils.addReadonlyGetter(this, 'uid', response.rawId);
        utils.addReadonlyGetter(this, 'displayName', response.displayName);
        utils.addReadonlyGetter(this, 'email', response.email);
        utils.addReadonlyGetter(this, 'photoURL', response.photoUrl);
        utils.addReadonlyGetter(this, 'providerId', response.providerId);
        utils.addReadonlyGetter(this, 'phoneNumber', response.phoneNumber);
    }
    /** @return {object} The plain object representation of the current provider data. */
    UserInfo.prototype.toJSON = function () {
        return {
            uid: this.uid,
            displayName: this.displayName,
            email: this.email,
            photoURL: this.photoURL,
            providerId: this.providerId,
            phoneNumber: this.phoneNumber,
        };
    };
    return UserInfo;
}());
exports.UserInfo = UserInfo;
/**
 * User record class that defines the Firebase user object populated from
 * the Firebase Auth getAccountInfo response.
 *
 * @param {any} response The server side response returned from the getAccountInfo
 *     endpoint.
 * @constructor
 */
var UserRecord = /** @class */ (function () {
    function UserRecord(response) {
        // The Firebase user id is required.
        if (!response.localId) {
            throw new error_1.FirebaseAuthError(error_1.AuthClientErrorCode.INTERNAL_ERROR, 'INTERNAL ASSERT FAILED: Invalid user response');
        }
        utils.addReadonlyGetter(this, 'uid', response.localId);
        utils.addReadonlyGetter(this, 'email', response.email);
        utils.addReadonlyGetter(this, 'emailVerified', !!response.emailVerified);
        utils.addReadonlyGetter(this, 'displayName', response.displayName);
        utils.addReadonlyGetter(this, 'photoURL', response.photoUrl);
        utils.addReadonlyGetter(this, 'phoneNumber', response.phoneNumber);
        // If disabled is not provided, the account is enabled by default.
        utils.addReadonlyGetter(this, 'disabled', response.disabled || false);
        utils.addReadonlyGetter(this, 'metadata', new UserMetadata(response));
        var providerData = [];
        for (var _i = 0, _a = (response.providerUserInfo || []); _i < _a.length; _i++) {
            var entry = _a[_i];
            providerData.push(new UserInfo(entry));
        }
        utils.addReadonlyGetter(this, 'providerData', providerData);
        // If the password hash is redacted (probably due to missing permissions)
        // then clear it out, similar to how the salt is returned. (Otherwise, it
        // *looks* like a b64-encoded hash is present, which is confusing.)
        if (response.passwordHash === B64_REDACTED) {
            utils.addReadonlyGetter(this, 'passwordHash', undefined);
        }
        else {
            utils.addReadonlyGetter(this, 'passwordHash', response.passwordHash);
        }
        utils.addReadonlyGetter(this, 'passwordSalt', response.salt);
        try {
            utils.addReadonlyGetter(this, 'customClaims', JSON.parse(response.customAttributes));
        }
        catch (e) {
            // Ignore error.
            utils.addReadonlyGetter(this, 'customClaims', undefined);
        }
        var validAfterTime = null;
        // Convert validSince first to UTC milliseconds and then to UTC date string.
        if (typeof response.validSince !== 'undefined') {
            validAfterTime = parseDate(response.validSince * 1000);
        }
        utils.addReadonlyGetter(this, 'tokensValidAfterTime', validAfterTime || undefined);
        utils.addReadonlyGetter(this, 'tenantId', response.tenantId);
    }
    /** @return {object} The plain object representation of the user record. */
    UserRecord.prototype.toJSON = function () {
        var json = {
            uid: this.uid,
            email: this.email,
            emailVerified: this.emailVerified,
            displayName: this.displayName,
            photoURL: this.photoURL,
            phoneNumber: this.phoneNumber,
            disabled: this.disabled,
            // Convert metadata to json.
            metadata: this.metadata.toJSON(),
            passwordHash: this.passwordHash,
            passwordSalt: this.passwordSalt,
            customClaims: deep_copy_1.deepCopy(this.customClaims),
            tokensValidAfterTime: this.tokensValidAfterTime,
            tenantId: this.tenantId,
        };
        json.providerData = [];
        for (var _i = 0, _a = this.providerData; _i < _a.length; _i++) {
            var entry = _a[_i];
            // Convert each provider data to json.
            json.providerData.push(entry.toJSON());
        }
        return json;
    };
    return UserRecord;
}());
exports.UserRecord = UserRecord;
