/*! firebase-admin v5.2.1 */
"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 user_record_1 = require("./user-record");
var token_generator_1 = require("./token-generator");
var auth_api_request_1 = require("./auth-api-request");
var error_1 = require("../utils/error");
var validator = require("../utils/validator");
/**
 * Internals of an Auth instance.
 */
var AuthInternals = (function () {
    function AuthInternals() {
    }
    /**
     * Deletes the service and its associated resources.
     *
     * @return {Promise<()>} An empty Promise that will be fulfilled when the service is deleted.
     */
    AuthInternals.prototype.delete = function () {
        // There are no resources to clean up
        return Promise.resolve(undefined);
    };
    return AuthInternals;
}());
exports.AuthInternals = AuthInternals;
/**
 * Auth service bound to the provided app.
 */
var Auth = (function () {
    /**
     * @param {Object} app The app for this Auth service.
     * @constructor
     */
    function Auth(app) {
        this.INTERNAL = new AuthInternals();
        if (typeof app !== 'object' || app === null || !('options' in app)) {
            throw new error_1.FirebaseAuthError(error_1.AuthClientErrorCode.INVALID_ARGUMENT, 'First argument passed to admin.auth() must be a valid Firebase app instance.');
        }
        this.app_ = app;
        // TODO (inlined): plumb this into a factory method for tokenGenerator_ once we
        // can generate custom tokens from access tokens.
        var serviceAccount;
        if (typeof app.options.credential.getCertificate === 'function') {
            serviceAccount = app.options.credential.getCertificate();
        }
        if (serviceAccount) {
            // Cert credentials and Application Default Credentials created from a service account file
            // provide a certificate we can use to mint custom tokens and verify ID tokens.
            this.tokenGenerator_ = new token_generator_1.FirebaseTokenGenerator(serviceAccount);
        }
        else if (validator.isNonEmptyString(process.env.GCLOUD_PROJECT)) {
            // Google infrastructure like GAE, GCE, and GCF store the GCP / Firebase project ID in an
            // environment variable that we can use to get verifyIdToken() to work. createCustomToken()
            // still won't work since it requires a private key and client email which we do not have.
            this.tokenGenerator_ = new token_generator_1.FirebaseTokenGenerator({
                projectId: process.env.GCLOUD_PROJECT,
            });
        }
        // Initialize auth request handler with the app.
        this.authRequestHandler = new auth_api_request_1.FirebaseAuthRequestHandler(app);
    }
    Object.defineProperty(Auth.prototype, "app", {
        /**
         * Returns the app associated with this Auth instance.
         *
         * @return {FirebaseApp} The app associated with this Auth instance.
         */
        get: function () {
            return this.app_;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Creates a new custom token that can be sent back to a client to use with
     * signInWithCustomToken().
     *
     * @param {string} uid The uid to use as the JWT subject.
     * @param {Object=} developerClaims Optional additional claims to include in the JWT payload.
     *
     * @return {Promise<string>} A JWT for the provided payload.
     */
    Auth.prototype.createCustomToken = function (uid, developerClaims) {
        if (typeof this.tokenGenerator_ === 'undefined') {
            throw new error_1.FirebaseAuthError(error_1.AuthClientErrorCode.INVALID_CREDENTIAL, 'Must initialize app with a cert credential to call auth().createCustomToken().');
        }
        return this.tokenGenerator_.createCustomToken(uid, developerClaims);
    };
    ;
    /**
     * Verifies a JWT auth token. Returns a Promise with the tokens claims. Rejects
     * the promise if the token could not be verified.
     *
     * @param {string} idToken The JWT to verify.
     * @return {Promise<Object>} A Promise that will be fulfilled after a successful verification.
     */
    Auth.prototype.verifyIdToken = function (idToken) {
        if (typeof this.tokenGenerator_ === 'undefined') {
            throw new error_1.FirebaseAuthError(error_1.AuthClientErrorCode.INVALID_CREDENTIAL, 'Must initialize app with a cert credential or set your Firebase project ID as the ' +
                'GCLOUD_PROJECT environment variable to call auth().verifyIdToken().');
        }
        return this.tokenGenerator_.verifyIdToken(idToken);
    };
    ;
    /**
     * Looks up the user identified by the provided user id and returns a promise that is
     * fulfilled with a user record for the given user if that user is found.
     *
     * @param {string} uid The uid of the user to look up.
     * @return {Promise<UserRecord>} A promise that resolves with the corresponding user record.
     */
    Auth.prototype.getUser = function (uid) {
        return this.authRequestHandler.getAccountInfoByUid(uid)
            .then(function (response) {
            // Returns the user record populated with server response.
            return new user_record_1.UserRecord(response.users[0]);
        });
    };
    ;
    /**
     * Looks up the user identified by the provided email and returns a promise that is
     * fulfilled with a user record for the given user if that user is found.
     *
     * @param {string} email The email of the user to look up.
     * @return {Promise<UserRecord>} A promise that resolves with the corresponding user record.
     */
    Auth.prototype.getUserByEmail = function (email) {
        return this.authRequestHandler.getAccountInfoByEmail(email)
            .then(function (response) {
            // Returns the user record populated with server response.
            return new user_record_1.UserRecord(response.users[0]);
        });
    };
    ;
    /**
     * Looks up the user identified by the provided phone number and returns a promise that is
     * fulfilled with a user record for the given user if that user is found.
     *
     * @param {string} phoneNumber The phone number of the user to look up.
     * @return {Promise<UserRecord>} A promise that resolves with the corresponding user record.
     */
    Auth.prototype.getUserByPhoneNumber = function (phoneNumber) {
        return this.authRequestHandler.getAccountInfoByPhoneNumber(phoneNumber)
            .then(function (response) {
            // Returns the user record populated with server response.
            return new user_record_1.UserRecord(response.users[0]);
        });
    };
    ;
    /**
     * Creates a new user with the properties provided.
     *
     * @param {CreateRequest} properties The properties to set on the new user record to be created.
     * @return {Promise<UserRecord>} A promise that resolves with the newly created user record.
     */
    Auth.prototype.createUser = function (properties) {
        var _this = this;
        return this.authRequestHandler.createNewAccount(properties)
            .then(function (uid) {
            // Return the corresponding user record.
            return _this.getUser(uid);
        })
            .catch(function (error) {
            if (error.code === 'auth/user-not-found') {
                // Something must have happened after creating the user and then retrieving it.
                throw new error_1.FirebaseAuthError(error_1.AuthClientErrorCode.INTERNAL_ERROR, 'Unable to create the user record provided.');
            }
            throw error;
        });
    };
    ;
    /**
     * Deletes the user identified by the provided user id and returns a promise that is
     * fulfilled when the user is found and successfully deleted.
     *
     * @param {string} uid The uid of the user to delete.
     * @return {Promise<void>} A promise that resolves when the user is successfully deleted.
     */
    Auth.prototype.deleteUser = function (uid) {
        return this.authRequestHandler.deleteAccount(uid)
            .then(function (response) {
            // Return nothing on success.
        });
    };
    ;
    /**
     * Updates an existing user with the properties provided.
     *
     * @param {string} uid The uid identifier of the user to update.
     * @param {UpdateRequest} properties The properties to update on the existing user.
     * @return {Promise<UserRecord>} A promise that resolves with the modified user record.
     */
    Auth.prototype.updateUser = function (uid, properties) {
        var _this = this;
        return this.authRequestHandler.updateExistingAccount(uid, properties)
            .then(function (existingUid) {
            // Return the corresponding user record.
            return _this.getUser(existingUid);
        });
    };
    ;
    return Auth;
}());
exports.Auth = Auth;
;
