PHP WebShell

Текущая директория: /usr/lib/node_modules/bitgo/node_modules/@bitgo/sdk-core/dist/src/bitgo/enterprise

Просмотр файла: enterprise.js

"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.Enterprise = void 0;
/**
 * @prettier
 */
const _ = __importStar(require("lodash"));
const internal_1 = require("../internal");
const wallet_1 = require("../wallet");
const ecdsa_1 = require("../utils/tss/ecdsa");
const sdk_lib_mpc_1 = require("@bitgo/sdk-lib-mpc");
const ecdh_1 = require("../ecdh");
const buffer_1 = require("buffer");
class Enterprise {
    constructor(bitgo, baseCoin, enterpriseData) {
        this.bitgo = bitgo;
        this.baseCoin = baseCoin;
        if (!_.isObject(enterpriseData)) {
            throw new Error('enterpriseData has to be an object');
        }
        if (!_.isString(enterpriseData.id)) {
            throw new Error('enterprise id has to be a string');
        }
        if (!_.isString(enterpriseData.name)) {
            throw new Error('enterprise name has to be a string');
        }
        this._enterprise = enterpriseData;
        this.id = enterpriseData.id;
        this.name = enterpriseData.name;
    }
    /**
     * Enterprise URL for v1 methods, such as getting users
     * @param query
     */
    url(query = '') {
        return this.bitgo.url(`/enterprise/${this.id}${query}`);
    }
    /**
     * Enterprise URL for v2 methods, such as getting fee address balances
     * @param query
     */
    coinUrl(query = '') {
        return this.baseCoin.url(`/enterprise/${this.id}${query}`);
    }
    /**
     * Get the wallets associated with this Enterprise
     * @param params
     */
    async coinWallets(params = {}) {
        if (params.skip && params.prevId) {
            throw new Error('cannot specify both skip and prevId');
        }
        const walletData = (await this.bitgo
            .get(this.baseCoin.url('/wallet/enterprise/' + this.id))
            .query(params)
            .result());
        return walletData.wallets.map((w) => {
            return new wallet_1.Wallet(this.bitgo, this.baseCoin, w);
        });
    }
    /**
     * Get the users associated with this Enterprise
     * @param params
     */
    async users(params = {}) {
        return await this.bitgo.get(this.url('/user')).result();
    }
    /**
     * Get the fee address balance for this Enterprise
     * @param params
     */
    async getFeeAddressBalance(params = {}) {
        return await this.bitgo.get(this.coinUrl('/feeAddressBalance')).result();
    }
    /**
     * Add a user to this Enterprise
     * @param params
     */
    async addUser(params = {}) {
        return await this.bitgo.post(this.url('/user')).send(params).result();
    }
    /**
     * Remove a user from this Enterprise
     * @param params
     */
    async removeUser(params = {}) {
        return await this.bitgo.del(this.url('/user')).send(params).result();
    }
    /**
     * Get the first pending transaction for this Enterprise
     * @param params
     */
    async getFirstPendingTransaction(params = {}) {
        return (0, internal_1.getFirstPendingTransaction)({ enterpriseId: this.id }, this.baseCoin, this.bitgo);
    }
    /**
     * Verifies and signs bitgo proofs for the enterprise
     * @param userPassword - enterprise admin's login password
     */
    async verifyEcdsaBitGoChallengeProofs(userPassword) {
        return ecdsa_1.EcdsaUtils.getVerifyAndSignBitGoChallenges(this.bitgo, this.id, userPassword);
    }
    /**
     * Manages all the challenges and signatures and uploads them to enable
     * ECDSA signing on enterprise. Also generates a client side Ntilde challenge
     * if not provided, but note that can take approx. a minute.
     * @param userPassword
     * @param bitgoInstChallengeProofSignature
     * @param bitgoNitroChallengeProofSignature
     * @param challenge
     */
    async uploadAndEnableTssEcdsaSigning(userPassword, bitgoInstChallengeProofSignature, bitgoNitroChallengeProofSignature, openSSLBytes, challenge) {
        await ecdsa_1.EcdsaUtils.initiateChallengesForEnterprise(this.bitgo, this.id, userPassword, bitgoInstChallengeProofSignature, bitgoNitroChallengeProofSignature, openSSLBytes, challenge);
    }
    /**
     * Fetches the existing TSS ECDSA enterprise challenge if one exists.
     * Can be used with uploadAndEnableTssEcdsaSigning to re-sign the
     * enterprise challenge with new signatures.
     */
    async getExistingTssEcdsaChallenge() {
        const urlPath = `/enterprise/${this.id}/tssconfig`;
        const tssConfig = await this.bitgo.get(this.bitgo.url(urlPath, 2)).send().result();
        const enterpriseChallenge = tssConfig?.ecdsa.challenge?.enterprise;
        if (!enterpriseChallenge) {
            throw new Error('No existing ECDSA challenge on the enterprise.');
        }
        if (!enterpriseChallenge.ntildeProof) {
            throw new Error('Existing ECDSA challenge does not have a proof. Please contact your enterprise admin to set this up.');
        }
        return sdk_lib_mpc_1.EcdsaTypes.deserializeNtildeWithProofs({
            ntilde: enterpriseChallenge.ntilde,
            h1: enterpriseChallenge.h1,
            h2: enterpriseChallenge.h2,
            ntildeProof: enterpriseChallenge.ntildeProof,
        });
    }
    /**
     * Resigns the enterprise and bitgo challenges with a new ECDH keychain.
     * Verifies that the old keychain signed the challenges previously.
     * @param oldEcdhKeypair - the old keychain that signed the challenges
     * @param newEcdhKeypair - the new keychain that will sign the challenges
     * @param entChallenge - existing signed enterprise challenge
     * @param bitgoInstChallenge - existing signed bitgo institutional challenge
     * @param bitgoNitroChallenge - existing signed bitgo nitro challenge
     */
    async resignEnterpriseChallenges(oldEcdhKeypair, newEcdhKeypair, entChallenge, bitgoInstChallenge, bitgoNitroChallenge) {
        // Verify all the challenges were signed by the old keypair
        if (!(0, ecdh_1.verifyEcdhSignature)(ecdsa_1.EcdsaUtils.getMessageToSignFromChallenge(entChallenge), entChallenge.verifiers.adminSignature, buffer_1.Buffer.from(oldEcdhKeypair.derivedPubKey, 'hex'))) {
            throw new Error(`Cannot re-sign. The Enterprise TSS config was signed by another user.`);
        }
        if (!(0, ecdh_1.verifyEcdhSignature)(ecdsa_1.EcdsaUtils.getMessageToSignFromChallenge(bitgoInstChallenge), bitgoInstChallenge.verifiers.adminSignature, buffer_1.Buffer.from(oldEcdhKeypair.derivedPubKey, 'hex'))) {
            throw new Error(`Cannot re-sign. The BitGo Institutional TSS config was signed by another user.`);
        }
        if (!(0, ecdh_1.verifyEcdhSignature)(ecdsa_1.EcdsaUtils.getMessageToSignFromChallenge(bitgoNitroChallenge), bitgoNitroChallenge.verifiers.adminSignature, buffer_1.Buffer.from(oldEcdhKeypair.derivedPubKey, 'hex'))) {
            throw new Error(`Cannot re-sign. The BitGo Nitro TSS config was signed by another user.`);
        }
        // Once all the challenges are verified, we can re-sign them with the new keypair.
        const signedEntChallenge = ecdsa_1.EcdsaUtils.signChallenge(entChallenge, newEcdhKeypair.xprv, newEcdhKeypair.derivationPath);
        const signedBitGoInstChallenge = ecdsa_1.EcdsaUtils.signChallenge(bitgoInstChallenge, newEcdhKeypair.xprv, newEcdhKeypair.derivationPath);
        const signedBitGoNitroChallenge = ecdsa_1.EcdsaUtils.signChallenge(bitgoNitroChallenge, newEcdhKeypair.xprv, newEcdhKeypair.derivationPath);
        await ecdsa_1.EcdsaUtils.uploadChallengesToEnterprise(this.bitgo, this.id, entChallenge, signedEntChallenge.toString('hex'), signedBitGoInstChallenge.toString('hex'), signedBitGoNitroChallenge.toString('hex'));
    }
    /**
     *  Check if the enterprise has a set of featureFlags
     * @param flags
     */
    hasFeatureFlags(flags) {
        return flags.every((targetFlag) => this._enterprise.featureFlags?.includes(targetFlag));
    }
}
exports.Enterprise = Enterprise;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW50ZXJwcmlzZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9iaXRnby9lbnRlcnByaXNlL2VudGVycHJpc2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7O0dBRUc7QUFDSCwwQ0FBNEI7QUFJNUIsMENBQXlEO0FBQ3pELHNDQUFzRDtBQUN0RCw4Q0FBcUc7QUFDckcsb0RBQWdEO0FBQ2hELGtDQUE4QztBQUM5QyxtQ0FBZ0M7QUFHaEMsTUFBYSxVQUFVO0lBT3JCLFlBQVksS0FBZ0IsRUFBRSxRQUFtQixFQUFFLGNBQThCO1FBQy9FLElBQUksQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDO1FBQ25CLElBQUksQ0FBQyxRQUFRLEdBQUcsUUFBUSxDQUFDO1FBQ3pCLElBQUksQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLGNBQWMsQ0FBQyxFQUFFLENBQUM7WUFDaEMsTUFBTSxJQUFJLEtBQUssQ0FBQyxvQ0FBb0MsQ0FBQyxDQUFDO1FBQ3hELENBQUM7UUFDRCxJQUFJLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxjQUFjLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztZQUNuQyxNQUFNLElBQUksS0FBSyxDQUFDLGtDQUFrQyxDQUFDLENBQUM7UUFDdEQsQ0FBQztRQUNELElBQUksQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO1lBQ3JDLE1BQU0sSUFBSSxLQUFLLENBQUMsb0NBQW9DLENBQUMsQ0FBQztRQUN4RCxDQUFDO1FBQ0QsSUFBSSxDQUFDLFdBQVcsR0FBRyxjQUFjLENBQUM7UUFDbEMsSUFBSSxDQUFDLEVBQUUsR0FBRyxjQUFjLENBQUMsRUFBRSxDQUFDO1FBQzVCLElBQUksQ0FBQyxJQUFJLEdBQUcsY0FBYyxDQUFDLElBQUksQ0FBQztJQUNsQyxDQUFDO0lBRUQ7OztPQUdHO0lB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QUM7UUFDRixNQUFNLHdCQUF3QixHQUFHLGtCQUFVLENBQUMsYUFBYSxDQUN2RCxrQkFBa0IsRUFDbEIsY0FBYyxDQUFDLElBQUksRUFDbkIsY0FBYyxDQUFDLGNBQWMsQ0FDOUIsQ0FBQztRQUNGLE1BQU0seUJBQXlCLEdBQUcsa0JBQVUsQ0FBQyxhQUFhLENBQ3hELG1CQUFtQixFQUNuQixjQUFjLENBQUMsSUFBSSxFQUNuQixjQUFjLENBQUMsY0FBYyxDQUM5QixDQUFDO1FBQ0YsTUFBTSxrQkFBVSxDQUFDLDRCQUE0QixDQUMzQyxJQUFJLENBQUMsS0FBSyxFQUNWLElBQUksQ0FBQyxFQUFFLEVBQ1AsWUFBWSxFQUNaLGtCQUFrQixDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsRUFDbEMsd0JBQXdCLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxFQUN4Qyx5QkFBeUIsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQzFDLENBQUM7SUFDSixDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsZUFBZSxDQUFDLEtBQThCO1FBQzVDLE9BQU8sS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLFVBQVUsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxZQUFZLEVBQUUsUUFBUSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUM7SUFDMUYsQ0FBQztDQUNGO0FBNU9ELGdDQTRPQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQHByZXR0aWVyXG4gKi9cbmltcG9ydCAqIGFzIF8gZnJvbSAnbG9kYXNoJztcbmltcG9ydCB7IElCYXNlQ29pbiB9IGZyb20gJy4uL2Jhc2VDb2luJztcbmltcG9ydCB7IEJpdEdvQmFzZSB9IGZyb20gJy4uL2JpdGdvQmFzZSc7XG5pbXBvcnQgeyBFbnRlcnByaXNlRGF0YSwgRW50ZXJwcmlzZUZlYXR1cmVGbGFnLCBJRW50ZXJwcmlzZSB9IGZyb20gJy4uL2VudGVycHJpc2UnO1xuaW1wb3J0IHsgZ2V0Rmlyc3RQZW5kaW5nVHJhbnNhY3Rpb24gfSBmcm9tICcuLi9pbnRlcm5hbCc7XG5pbXBvcnQgeyBMaXN0V2FsbGV0T3B0aW9ucywgV2FsbGV0IH0gZnJvbSAnLi4vd2FsbGV0JztcbmltcG9ydCB7IEJpdEdvUHJvb2ZTaWduYXR1cmVzLCBFY2RzYVV0aWxzLCBTZXJpYWxpemVkTnRpbGRlV2l0aFZlcmlmaWVycyB9IGZyb20gJy4uL3V0aWxzL3Rzcy9lY2RzYSc7XG5pbXBvcnQgeyBFY2RzYVR5cGVzIH0gZnJvbSAnQGJpdGdvL3Nkay1saWItbXBjJztcbmltcG9ydCB7IHZlcmlmeUVjZGhTaWduYXR1cmUgfSBmcm9tICcuLi9lY2RoJztcbmltcG9ydCB7IEJ1ZmZlciB9IGZyb20gJ2J1ZmZlcic7XG5pbXBvcnQgeyBFY2RoRGVyaXZlZEtleXBhaXIgfSBmcm9tICcuLi9rZXljaGFpbic7XG5cbmV4cG9ydCBjbGFzcyBFbnRlcnByaXNlIGltcGxlbWVudHMgSUVudGVycHJpc2Uge1xuICBwcml2YXRlIHJlYWRvbmx5IGJpdGdvOiBCaXRHb0Jhc2U7XG4gIHByaXZhdGUgcmVhZG9ubHkgYmFzZUNvaW46IElCYXNlQ29pbjtcbiAgcHVibGljIHJlYWRvbmx5IGlkOiBzdHJpbmc7XG4gIHB1YmxpYyByZWFkb25seSBuYW1lOiBzdHJpbmc7XG4gIHB1YmxpYyByZWFkb25seSBfZW50ZXJwcmlzZTogRW50ZXJwcmlzZURhdGE7XG5cbiAgY29uc3RydWN0b3IoYml0Z286IEJpdEdvQmFzZSwgYmFzZUNvaW46IElCYXNlQ29pbiwgZW50ZXJwcmlzZURhdGE6IEVudGVycHJpc2VEYXRhKSB7XG4gICAgdGhpcy5iaXRnbyA9IGJpdGdvO1xuICAgIHRoaXMuYmFzZUNvaW4gPSBiYXNlQ29pbjtcbiAgICBpZiAoIV8uaXNPYmplY3QoZW50ZXJwcmlzZURhdGEpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2VudGVycHJpc2VEYXRhIGhhcyB0byBiZSBhbiBvYmplY3QnKTtcbiAgICB9XG4gICAgaWYgKCFfLmlzU3RyaW5nKGVudGVycHJpc2VEYXRhLmlkKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdlbnRlcnByaXNlIGlkIGhhcyB0byBiZSBhIHN0cmluZycpO1xuICAgIH1cbiAgICBpZiAoIV8uaXNTdHJpbmcoZW50ZXJwcmlzZURhdGEubmFtZSkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignZW50ZXJwcmlzZSBuYW1lIGhhcyB0byBiZSBhIHN0cmluZycpO1xuICAgIH1cbiAgICB0aGlzLl9lbnRlcnByaXNlID0gZW50ZXJwcmlzZURhdGE7XG4gICAgdGhpcy5pZCA9IGVudGVycHJpc2VEYXRhLmlkO1xuICAgIHRoaXMubmFtZSA9IGVudGVycHJpc2VEYXRhLm5hbWU7XG4gIH1cblxuICAvKipcbiAgICogRW50ZXJwcmlzZSBVUkwgZm9yIHYxIG1ldGhvZHMsIHN1Y2ggYXMgZ2V0dGluZyB1c2Vyc1xuICAgKiBAcGFyYW0gcXVlcnlcbiAgICovXG4gIHVybChxdWVyeSA9ICcnKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5iaXRnby51cmwoYC9lbnRlcnByaXNlLyR7dGhpcy5pZH0ke3F1ZXJ5fWApO1xuICB9XG5cbiAgLyoqXG4gICAqIEVudGVycHJpc2UgVVJMIGZvciB2MiBtZXRob2RzLCBzdWNoIGFzIGdldHRpbmcgZmVlIGFkZHJlc3MgYmFsYW5jZXNcbiAgICogQHBhcmFtIHF1ZXJ5XG4gICAqL1xuICBjb2luVXJsKHF1ZXJ5ID0gJycpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLmJhc2VDb2luLnVybChgL2VudGVycHJpc2UvJHt0aGlzLmlkfSR7cXVlcnl9YCk7XG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSB3YWxsZXRzIGFzc29jaWF0ZWQgd2l0aCB0aGlzIEVudGVycHJpc2VcbiAgICogQHBhcmFtIHBhcmFtc1xuICAgKi9cbiAgYXN5bmMgY29pbldhbGxldHMocGFyYW1zOiBMaXN0V2FsbGV0T3B0aW9ucyA9IHt9KTogUHJvbWlzZTxXYWxsZXRbXT4ge1xuICAgIGlmIChwYXJhbXMuc2tpcCAmJiBwYXJhbXMucHJldklkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2Nhbm5vdCBzcGVjaWZ5IGJvdGggc2tpcCBhbmQgcHJldklkJyk7XG4gICAgfVxuXG4gICAgY29uc3Qgd2FsbGV0RGF0YSA9IChhd2FpdCB0aGlzLmJpdGdvXG4gICAgICAuZ2V0KHRoaXMuYmFzZUNvaW4udXJsKCcvd2FsbGV0L2VudGVycHJpc2UvJyArIHRoaXMuaWQpKVxuICAgICAgLnF1ZXJ5KHBhcmFtcylcbiAgICAgIC5yZXN1bHQoKSkgYXMgYW55O1xuICAgIHJldHVybiB3YWxsZXREYXRhLndhbGxldHMubWFwKCh3KSA9PiB7XG4gICAgICByZXR1cm4gbmV3IFdhbGxldCh0aGlzLmJpdGdvLCB0aGlzLmJhc2VDb2luLCB3KTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgdGhlIHVzZXJzIGFzc29jaWF0ZWQgd2l0aCB0aGlzIEVudGVycHJpc2VcbiAgICogQHBhcmFtIHBhcmFtc1xuICAgKi9cbiAgYXN5bmMgdXNlcnMocGFyYW1zOiBSZWNvcmQ8c3RyaW5nLCBuZXZlcj4gPSB7fSk6IFByb21pc2U8YW55PiB7XG4gICAgcmV0dXJuIGF3YWl0IHRoaXMuYml0Z28uZ2V0KHRoaXMudXJsKCcvdXNlcicpKS5yZXN1bHQoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgdGhlIGZlZSBhZGRyZXNzIGJhbGFuY2UgZm9yIHRoaXMgRW50ZXJwcmlzZVxuICAgKiBAcGFyYW0gcGFyYW1zXG4gICAqL1xuICBhc3luYyBnZXRGZWVBZGRyZXNzQmFsYW5jZShwYXJhbXM6IFJlY29yZDxzdHJpbmcsIG5ldmVyPiA9IHt9KTogUHJvbWlzZTxhbnk+IHtcbiAgICByZXR1cm4gYXdhaXQgdGhpcy5iaXRnby5nZXQodGhpcy5jb2luVXJsKCcvZmVlQWRkcmVzc0JhbGFuY2UnKSkucmVzdWx0KCk7XG4gIH1cblxuICAvKipcbiAgICogQWRkIGEgdXNlciB0byB0aGlzIEVudGVycHJpc2VcbiAgICogQHBhcmFtIHBhcmFtc1xuICAgKi9cbiAgYXN5bmMgYWRkVXNlcihwYXJhbXM6IGFueSA9IHt9KTogUHJvbWlzZTxhbnk+IHtcbiAgICByZXR1cm4gYXdhaXQgdGhpcy5iaXRnby5wb3N0KHRoaXMudXJsKCcvdXNlcicpKS5zZW5kKHBhcmFtcykucmVzdWx0KCk7XG4gIH1cblxuICAvKipcbiAgICogUmVtb3ZlIGEgdXNlciBmcm9tIHRoaXMgRW50ZXJwcmlzZVxuICAgKiBAcGFyYW0gcGFyYW1zXG4gICAqL1xuICBhc3luYyByZW1vdmVVc2VyKHBhcmFtczogYW55ID0ge30pOiBQcm9taXNlPGFueT4ge1xuICAgIHJldHVybiBhd2FpdCB0aGlzLmJpdGdvLmRlbCh0aGlzLnVybCgnL3VzZXInKSkuc2VuZChwYXJhbXMpLnJlc3VsdCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgZmlyc3QgcGVuZGluZyB0cmFuc2FjdGlvbiBmb3IgdGhpcyBFbnRlcnByaXNlXG4gICAqIEBwYXJhbSBwYXJhbXNcbiAgICovXG4gIGFzeW5jIGdldEZpcnN0UGVuZGluZ1RyYW5zYWN0aW9uKHBhcmFtczogUmVjb3JkPHN0cmluZywgbmV2ZXI+ID0ge30pOiBQcm9taXNlPGFueT4ge1xuICAgIHJldHVybiBnZXRGaXJzdFBlbmRpbmdUcmFuc2FjdGlvbih7IGVudGVycHJpc2VJZDogdGhpcy5pZCB9LCB0aGlzLmJhc2VDb2luLCB0aGlzLmJpdGdvKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBWZXJpZmllcyBhbmQgc2lnbnMgYml0Z28gcHJvb2ZzIGZvciB0aGUgZW50ZXJwcmlzZVxuICAgKiBAcGFyYW0gdXNlclBhc3N3b3JkIC0gZW50ZXJwcmlzZSBhZG1pbidzIGxvZ2luIHBhc3N3b3JkXG4gICAqL1xuICBhc3luYyB2ZXJpZnlFY2RzYUJpdEdvQ2hhbGxlbmdlUHJvb2ZzKHVzZXJQYXNzd29yZDogc3RyaW5nKTogUHJvbWlzZTxCaXRHb1Byb29mU2lnbmF0dXJlcz4ge1xuICAgIHJldHVybiBFY2RzYVV0aWxzLmdldFZlcmlmeUFuZFNpZ25CaXRHb0NoYWxsZW5nZXModGhpcy5iaXRnbywgdGhpcy5pZCwgdXNlclBhc3N3b3JkKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNYW5hZ2VzIGFsbCB0aGUgY2hhbGxlbmdlcyBhbmQgc2lnbmF0dXJlcyBhbmQgdXBsb2FkcyB0aGVtIHRvIGVuYWJsZVxuICAgKiBFQ0RTQSBzaWduaW5nIG9uIGVudGVycHJpc2UuIEFsc28gZ2VuZXJhdGVzIGEgY2xpZW50IHNpZGUgTnRpbGRlIGNoYWxsZW5nZVxuICAgKiBpZiBub3QgcHJvdmlkZWQsIGJ1dCBub3RlIHRoYXQgY2FuIHRha2UgYXBwcm94LiBhIG1pbnV0ZS5cbiAgICogQHBhcmFtIHVzZXJQYXNzd29yZFxuICAgKiBAcGFyYW0gYml0Z29JbnN0Q2hhbGxlbmdlUHJvb2ZTaWduYXR1cmVcbiAgICogQHBhcmFtIGJpdGdvTml0cm9DaGFsbGVuZ2VQcm9vZlNpZ25hdHVyZVxuICAgKiBAcGFyYW0gY2hhbGxlbmdlXG4gICAqL1xuICBhc3luYyB1cGxvYWRBbmRFbmFibGVUc3NFY2RzYVNpZ25pbmcoXG4gICAgdXNlclBhc3N3b3JkOiBzdHJpbmcsXG4gICAgYml0Z29JbnN0Q2hhbGxlbmdlUHJvb2ZTaWduYXR1cmU6IEJ1ZmZlcixcbiAgICBiaXRnb05pdHJvQ2hhbGxlbmdlUHJvb2ZTaWduYXR1cmU6IEJ1ZmZlcixcbiAgICBvcGVuU1NMQnl0ZXM6IFVpbnQ4QXJyYXksXG4gICAgY2hhbGxlbmdlPzogRWNkc2FUeXBlcy5EZXNlcmlhbGl6ZWROdGlsZGVXaXRoUHJvb2ZzXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGF3YWl0IEVjZHNhVXRpbHMuaW5pdGlhdGVDaGFsbGVuZ2VzRm9yRW50ZXJwcmlzZShcbiAgICAgIHRoaXMuYml0Z28sXG4gICAgICB0aGlzLmlkLFxuICAgICAgdXNlclBhc3N3b3JkLFxuICAgICAgYml0Z29JbnN0Q2hhbGxlbmdlUHJvb2ZTaWduYXR1cmUsXG4gICAgICBiaXRnb05pdHJvQ2hhbGxlbmdlUHJvb2ZTaWduYXR1cmUsXG4gICAgICBvcGVuU1NMQnl0ZXMsXG4gICAgICBjaGFsbGVuZ2VcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEZldGNoZXMgdGhlIGV4aXN0aW5nIFRTUyBFQ0RTQSBlbnRlcnByaXNlIGNoYWxsZW5nZSBpZiBvbmUgZXhpc3RzLlxuICAgKiBDYW4gYmUgdXNlZCB3aXRoIHVwbG9hZEFuZEVuYWJsZVRzc0VjZHNhU2lnbmluZyB0byByZS1zaWduIHRoZVxuICAgKiBlbnRlcnByaXNlIGNoYWxsZW5nZSB3aXRoIG5ldyBzaWduYXR1cmVzLlxuICAgKi9cbiAgYXN5bmMgZ2V0RXhpc3RpbmdUc3NFY2RzYUNoYWxsZW5nZSgpOiBQcm9taXNlPEVjZHNhVHlwZXMuRGVzZXJpYWxpemVkTnRpbGRlV2l0aFByb29mcz4ge1xuICAgIGNvbnN0IHVybFBhdGggPSBgL2VudGVycHJpc2UvJHt0aGlzLmlkfS90c3Njb25maWdgO1xuICAgIGNvbnN0IHRzc0NvbmZpZyA9IGF3YWl0IHRoaXMuYml0Z28uZ2V0KHRoaXMuYml0Z28udXJsKHVybFBhdGgsIDIpKS5zZW5kKCkucmVzdWx0KCk7XG4gICAgY29uc3QgZW50ZXJwcmlzZUNoYWxsZW5nZSA9IHRzc0NvbmZpZz8uZWNkc2EuY2hhbGxlbmdlPy5lbnRlcnByaXNlO1xuICAgIGlmICghZW50ZXJwcmlzZUNoYWxsZW5nZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdObyBleGlzdGluZyBFQ0RTQSBjaGFsbGVuZ2Ugb24gdGhlIGVudGVycHJpc2UuJyk7XG4gICAgfVxuICAgIGlmICghZW50ZXJwcmlzZUNoYWxsZW5nZS5udGlsZGVQcm9vZikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAnRXhpc3RpbmcgRUNEU0EgY2hhbGxlbmdlIGRvZXMgbm90IGhhdmUgYSBwcm9vZi4gUGxlYXNlIGNvbnRhY3QgeW91ciBlbnRlcnByaXNlIGFkbWluIHRvIHNldCB0aGlzIHVwLidcbiAgICAgICk7XG4gICAgfVxuICAgIHJldHVybiBFY2RzYVR5cGVzLmRlc2VyaWFsaXplTnRpbGRlV2l0aFByb29mcyh7XG4gICAgICBudGlsZGU6IGVudGVycHJpc2VDaGFsbGVuZ2UubnRpbGRlLFxuICAgICAgaDE6IGVudGVycHJpc2VDaGFsbGVuZ2UuaDEsXG4gICAgICBoMjogZW50ZXJwcmlzZUNoYWxsZW5nZS5oMixcbiAgICAgIG50aWxkZVByb29mOiBlbnRlcnByaXNlQ2hhbGxlbmdlLm50aWxkZVByb29mLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlc2lnbnMgdGhlIGVudGVycHJpc2UgYW5kIGJpdGdvIGNoYWxsZW5nZXMgd2l0aCBhIG5ldyBFQ0RIIGtleWNoYWluLlxuICAgKiBWZXJpZmllcyB0aGF0IHRoZSBvbGQga2V5Y2hhaW4gc2lnbmVkIHRoZSBjaGFsbGVuZ2VzIHByZXZpb3VzbHkuXG4gICAqIEBwYXJhbSBvbGRFY2RoS2V5cGFpciAtIHRoZSBvbGQga2V5Y2hhaW4gdGhhdCBzaWduZWQgdGhlIGNoYWxsZW5nZXNcbiAgICogQHBhcmFtIG5ld0VjZGhLZXlwYWlyIC0gdGhlIG5ldyBrZXljaGFpbiB0aGF0IHdpbGwgc2lnbiB0aGUgY2hhbGxlbmdlc1xuICAgKiBAcGFyYW0gZW50Q2hhbGxlbmdlIC0gZXhpc3Rpbmcgc2lnbmVkIGVudGVycHJpc2UgY2hhbGxlbmdlXG4gICAqIEBwYXJhbSBiaXRnb0luc3RDaGFsbGVuZ2UgLSBleGlzdGluZyBzaWduZWQgYml0Z28gaW5zdGl0dXRpb25hbCBjaGFsbGVuZ2VcbiAgICogQHBhcmFtIGJpdGdvTml0cm9DaGFsbGVuZ2UgLSBleGlzdGluZyBzaWduZWQgYml0Z28gbml0cm8gY2hhbGxlbmdlXG4gICAqL1xuICBhc3luYyByZXNpZ25FbnRlcnByaXNlQ2hhbGxlbmdlcyhcbiAgICBvbGRFY2RoS2V5cGFpcjogRWNkaERlcml2ZWRLZXlwYWlyLFxuICAgIG5ld0VjZGhLZXlwYWlyOiBFY2RoRGVyaXZlZEtleXBhaXIsXG4gICAgZW50Q2hhbGxlbmdlOiBTZXJpYWxpemVkTnRpbGRlV2l0aFZlcmlmaWVycyxcbiAgICBiaXRnb0luc3RDaGFsbGVuZ2U6IFNlcmlhbGl6ZWROdGlsZGVXaXRoVmVyaWZpZXJzLFxuICAgIGJpdGdvTml0cm9DaGFsbGVuZ2U6IFNlcmlhbGl6ZWROdGlsZGVXaXRoVmVyaWZpZXJzXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIC8vIFZlcmlmeSBhbGwgdGhlIGNoYWxsZW5nZXMgd2VyZSBzaWduZWQgYnkgdGhlIG9sZCBrZXlwYWlyXG4gICAgaWYgKFxuICAgICAgIXZlcmlmeUVjZGhTaWduYXR1cmUoXG4gICAgICAgIEVjZHNhVXRpbHMuZ2V0TWVzc2FnZVRvU2lnbkZyb21DaGFsbGVuZ2UoZW50Q2hhbGxlbmdlKSxcbiAgICAgICAgZW50Q2hhbGxlbmdlLnZlcmlmaWVycy5hZG1pblNpZ25hdHVyZSxcbiAgICAgICAgQnVmZmVyLmZyb20ob2xkRWNkaEtleXBhaXIuZGVyaXZlZFB1YktleSwgJ2hleCcpXG4gICAgICApXG4gICAgKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYENhbm5vdCByZS1zaWduLiBUaGUgRW50ZXJwcmlzZSBUU1MgY29uZmlnIHdhcyBzaWduZWQgYnkgYW5vdGhlciB1c2VyLmApO1xuICAgIH1cbiAgICBpZiAoXG4gICAgICAhdmVyaWZ5RWNkaFNpZ25hdHVyZShcbiAgICAgICAgRWNkc2FVdGlscy5nZXRNZXNzYWdlVG9TaWduRnJvbUNoYWxsZW5nZShiaXRnb0luc3RDaGFsbGVuZ2UpLFxuICAgICAgICBiaXRnb0luc3RDaGFsbGVuZ2UudmVyaWZpZXJzLmFkbWluU2lnbmF0dXJlLFxuICAgICAgICBCdWZmZXIuZnJvbShvbGRFY2RoS2V5cGFpci5kZXJpdmVkUHViS2V5LCAnaGV4JylcbiAgICAgIClcbiAgICApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgQ2Fubm90IHJlLXNpZ24uIFRoZSBCaXRHbyBJbnN0aXR1dGlvbmFsIFRTUyBjb25maWcgd2FzIHNpZ25lZCBieSBhbm90aGVyIHVzZXIuYCk7XG4gICAgfVxuICAgIGlmIChcbiAgICAgICF2ZXJpZnlFY2RoU2lnbmF0dXJlKFxuICAgICAgICBFY2RzYVV0aWxzLmdldE1lc3NhZ2VUb1NpZ25Gcm9tQ2hhbGxlbmdlKGJpdGdvTml0cm9DaGFsbGVuZ2UpLFxuICAgICAgICBiaXRnb05pdHJvQ2hhbGxlbmdlLnZlcmlmaWVycy5hZG1pblNpZ25hdHVyZSxcbiAgICAgICAgQnVmZmVyLmZyb20ob2xkRWNkaEtleXBhaXIuZGVyaXZlZFB1YktleSwgJ2hleCcpXG4gICAgICApXG4gICAgKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYENhbm5vdCByZS1zaWduLiBUaGUgQml0R28gTml0cm8gVFNTIGNvbmZpZyB3YXMgc2lnbmVkIGJ5IGFub3RoZXIgdXNlci5gKTtcbiAgICB9XG5cbiAgICAvLyBPbmNlIGFsbCB0aGUgY2hhbGxlbmdlcyBhcmUgdmVyaWZpZWQsIHdlIGNhbiByZS1zaWduIHRoZW0gd2l0aCB0aGUgbmV3IGtleXBhaXIuXG4gICAgY29uc3Qgc2lnbmVkRW50Q2hhbGxlbmdlID0gRWNkc2FVdGlscy5zaWduQ2hhbGxlbmdlKFxuICAgICAgZW50Q2hhbGxlbmdlLFxuICAgICAgbmV3RWNkaEtleXBhaXIueHBydixcbiAgICAgIG5ld0VjZGhLZXlwYWlyLmRlcml2YXRpb25QYXRoXG4gICAgKTtcbiAgICBjb25zdCBzaWduZWRCaXRHb0luc3RDaGFsbGVuZ2UgPSBFY2RzYVV0aWxzLnNpZ25DaGFsbGVuZ2UoXG4gICAgICBiaXRnb0luc3RDaGFsbGVuZ2UsXG4gICAgICBuZXdFY2RoS2V5cGFpci54cHJ2LFxuICAgICAgbmV3RWNkaEtleXBhaXIuZGVyaXZhdGlvblBhdGhcbiAgICApO1xuICAgIGNvbnN0IHNpZ25lZEJpdEdvTml0cm9DaGFsbGVuZ2UgPSBFY2RzYVV0aWxzLnNpZ25DaGFsbGVuZ2UoXG4gICAgICBiaXRnb05pdHJvQ2hhbGxlbmdlLFxuICAgICAgbmV3RWNkaEtleXBhaXIueHBydixcbiAgICAgIG5ld0VjZGhLZXlwYWlyLmRlcml2YXRpb25QYXRoXG4gICAgKTtcbiAgICBhd2FpdCBFY2RzYVV0aWxzLnVwbG9hZENoYWxsZW5nZXNUb0VudGVycHJpc2UoXG4gICAgICB0aGlzLmJpdGdvLFxuICAgICAgdGhpcy5pZCxcbiAgICAgIGVudENoYWxsZW5nZSxcbiAgICAgIHNpZ25lZEVudENoYWxsZW5nZS50b1N0cmluZygnaGV4JyksXG4gICAgICBzaWduZWRCaXRHb0luc3RDaGFsbGVuZ2UudG9TdHJpbmcoJ2hleCcpLFxuICAgICAgc2lnbmVkQml0R29OaXRyb0NoYWxsZW5nZS50b1N0cmluZygnaGV4JylcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqICBDaGVjayBpZiB0aGUgZW50ZXJwcmlzZSBoYXMgYSBzZXQgb2YgZmVhdHVyZUZsYWdzXG4gICAqIEBwYXJhbSBmbGFnc1xuICAgKi9cbiAgaGFzRmVhdHVyZUZsYWdzKGZsYWdzOiBFbnRlcnByaXNlRmVhdHVyZUZsYWdbXSk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBmbGFncy5ldmVyeSgodGFyZ2V0RmxhZykgPT4gdGhpcy5fZW50ZXJwcmlzZS5mZWF0dXJlRmxhZ3M/LmluY2x1ZGVzKHRhcmdldEZsYWcpKTtcbiAgfVxufVxuIl19

Выполнить команду


Для локальной разработки. Не используйте в интернете!