PHP WebShell
Текущая директория: /opt/BitGoJS/modules/express/dist/test/unit/clientRoutes/lightning
Просмотр файла: lightningSignerRoutes.js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const sdk_test_1 = require("@bitgo/sdk-test");
const bitgo_1 = require("bitgo");
const sdk_core_1 = require("@bitgo/sdk-core");
const nock = require("nock");
const sinon = require("sinon");
const fs = require("fs");
const lightningSignerFixture_1 = require("./lightningSignerFixture");
const lightningSignerRoutes_1 = require("../../../../src/lightning/lightningSignerRoutes");
describe('Lightning signer routes', () => {
let bitgo;
let bgUrl;
before(async function () {
if (!nock.isActive()) {
nock.activate();
}
bitgo = sdk_test_1.TestBitGo.decorate(bitgo_1.BitGo, { env: 'test' });
bitgo.initializeTestVars();
bgUrl = sdk_core_1.common.Environments[bitgo.getEnv()].uri;
nock.disableNetConnect();
nock.enableNetConnect('127.0.0.1');
});
after(() => {
if (nock.isActive()) {
nock.restore();
}
});
for (const includingOptionalFields of [true, false]) {
it(`should initialize lightning signer wallet ${includingOptionalFields ? 'with' : 'without'} optional fields`, async () => {
const readFileStub = sinon.stub(fs.promises, 'readFile').resolves(JSON.stringify(lightningSignerFixture_1.lightningSignerConfigs));
const wpWalletnock = nock(bgUrl)
.get(`/api/v2/tlnbtc/wallet/${lightningSignerFixture_1.apiData.wallet.id}`)
.query({ includeBalance: false })
.reply(200, lightningSignerFixture_1.apiData.wallet);
const wpKeychainNocks = [
nock(bgUrl).get(`/api/v2/tlnbtc/key/${lightningSignerFixture_1.apiData.userKey.id}`).reply(200, lightningSignerFixture_1.apiData.userKey),
nock(bgUrl).get(`/api/v2/tlnbtc/key/${lightningSignerFixture_1.apiData.userAuthKey.id}`).reply(200, lightningSignerFixture_1.apiData.userAuthKey),
nock(bgUrl).get(`/api/v2/tlnbtc/key/${lightningSignerFixture_1.apiData.nodeAuthKey.id}`).reply(200, lightningSignerFixture_1.apiData.nodeAuthKey),
nock(bgUrl).get(`/api/v2/tlnbtc/key/${lightningSignerFixture_1.apiData.userAuthKey.id}`).reply(200, lightningSignerFixture_1.apiData.userAuthKey),
nock(bgUrl).get(`/api/v2/tlnbtc/key/${lightningSignerFixture_1.apiData.nodeAuthKey.id}`).reply(200, lightningSignerFixture_1.apiData.nodeAuthKey),
];
const signerInitWalletNock = nock(lightningSignerFixture_1.lightningSignerConfigs.fakeid.url)
.post(`/v1/initwallet`)
.reply(200, lightningSignerFixture_1.signerApiData.initWallet);
const wpWalletUpdateNock = nock(bgUrl).put(`/api/v2/tlnbtc/wallet/${lightningSignerFixture_1.apiData.wallet.id}`).reply(200);
const req = {
bitgo: bitgo,
body: includingOptionalFields
? lightningSignerFixture_1.apiData.initWalletRequestBody
: { ...lightningSignerFixture_1.apiData.initWalletRequestBody, expressHost: undefined },
params: {
coin: 'tlnbtc',
id: 'fakeid',
},
config: {
lightningSignerFileSystemPath: 'lightningSignerFileSystemPath',
},
};
await (0, lightningSignerRoutes_1.handleInitLightningWallet)(req);
wpWalletUpdateNock.done();
signerInitWalletNock.done();
wpKeychainNocks.forEach((s) => s.done());
wpWalletnock.done();
readFileStub.calledOnceWith('lightningSignerFileSystemPath').should.be.true();
readFileStub.restore();
});
}
for (const addIpCaveatToMacaroon of [true, false]) {
for (const includeWatchOnlyIp of [true, false]) {
it(`create signer macaroon ${addIpCaveatToMacaroon ? 'with' : 'without'} including IP caveat when it ${includeWatchOnlyIp ? 'does' : `doesn't`} exist`, async () => {
const readFileStub = sinon.stub(fs.promises, 'readFile').resolves(JSON.stringify(lightningSignerFixture_1.lightningSignerConfigs));
const wpWalletnock = nock(bgUrl)
.get(`/api/v2/tlnbtc/wallet/${lightningSignerFixture_1.apiData.wallet.id}`)
.query({ includeBalance: false })
.reply(200, {
...lightningSignerFixture_1.apiData.wallet,
...(includeWatchOnlyIp ? {} : { watchOnlyExternalIp: null }),
});
const wpKeychainNocks = [
nock(bgUrl).get(`/api/v2/tlnbtc/key/${lightningSignerFixture_1.apiData.userAuthKey.id}`).reply(200, lightningSignerFixture_1.apiData.userAuthKey),
nock(bgUrl).get(`/api/v2/tlnbtc/key/${lightningSignerFixture_1.apiData.nodeAuthKey.id}`).reply(200, lightningSignerFixture_1.apiData.nodeAuthKey),
];
const signerMacaroon = nock(lightningSignerFixture_1.lightningSignerConfigs.fakeid.url)
.post(`/v1/macaroon`)
.reply(200, lightningSignerFixture_1.signerApiData.bakeMacaroon);
const wpWalletUpdateNock = nock(bgUrl).put(`/api/v2/tlnbtc/wallet/${lightningSignerFixture_1.apiData.wallet.id}`).reply(200);
const req = {
bitgo: bitgo,
body: { ...lightningSignerFixture_1.apiData.signerMacaroonRequestBody, addIpCaveatToMacaroon },
params: {
coin: 'tlnbtc',
id: 'fakeid',
},
config: {
lightningSignerFileSystemPath: 'lightningSignerFileSystemPath',
},
};
try {
await (0, lightningSignerRoutes_1.handleCreateSignerMacaroon)(req);
}
catch (e) {
if (!includeWatchOnlyIp || addIpCaveatToMacaroon) {
throw e;
}
}
wpWalletUpdateNock.done();
signerMacaroon.done();
wpKeychainNocks.forEach((s) => s.done());
wpWalletnock.done();
readFileStub.calledOnceWith('lightningSignerFileSystemPath').should.be.true();
readFileStub.restore();
});
}
}
it('should get signer wallet state', async () => {
const readFileStub = sinon.stub(fs.promises, 'readFile').resolves(JSON.stringify(lightningSignerFixture_1.lightningSignerConfigs));
const walletStateNock = nock(lightningSignerFixture_1.lightningSignerConfigs.fakeid.url)
.get(`/v1/state`)
.reply(200, lightningSignerFixture_1.signerApiData.walletState);
const req = {
bitgo: bitgo,
params: {
coin: 'tlnbtc',
id: lightningSignerFixture_1.apiData.wallet.id,
},
config: {
lightningSignerFileSystemPath: 'lightningSignerFileSystemPath',
},
};
await (0, lightningSignerRoutes_1.handleGetLightningWalletState)(req);
walletStateNock.done();
readFileStub.calledOnceWith('lightningSignerFileSystemPath').should.be.true();
readFileStub.restore();
});
it('should unlock lightning wallet', async () => {
const readFileStub = sinon.stub(fs.promises, 'readFile').resolves(JSON.stringify(lightningSignerFixture_1.lightningSignerConfigs));
const unlockwalletNock = nock(lightningSignerFixture_1.lightningSignerConfigs.fakeid.url).post(`/v1/unlockwallet`).reply(200);
const req = {
bitgo: bitgo,
body: lightningSignerFixture_1.apiData.unlockWalletRequestBody,
params: {
coin: 'tlnbtc',
id: 'fakeid',
},
config: {
lightningSignerFileSystemPath: 'lightningSignerFileSystemPath',
},
};
await (0, lightningSignerRoutes_1.handleUnlockLightningWallet)(req);
unlockwalletNock.done();
readFileStub.calledOnceWith('lightningSignerFileSystemPath').should.be.true();
readFileStub.restore();
});
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGlnaHRuaW5nU2lnbmVyUm91dGVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vdGVzdC91bml0L2NsaWVudFJvdXRlcy9saWdodG5pbmcvbGlnaHRuaW5nU2lnbmVyUm91dGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsOENBQTBEO0FBQzFELGlDQUE4QjtBQUM5Qiw4Q0FBeUM7QUFDekMsNkJBQTZCO0FBRTdCLCtCQUErQjtBQUMvQix5QkFBeUI7QUFFekIscUVBQTBGO0FBQzFGLDJGQUt5RDtBQUV6RCxRQUFRLENBQUMseUJBQXlCLEVBQUUsR0FBRyxFQUFFO0lBQ3ZDLElBQUksS0FBbUIsQ0FBQztJQUN4QixJQUFJLEtBQUssQ0FBQztJQUVWLE1BQU0sQ0FBQyxLQUFLO1FBQ1YsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsRUFBRTtZQUNwQixJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7U0FDakI7UUFFRCxLQUFLLEdBQUcsb0JBQVMsQ0FBQyxRQUFRLENBQUMsYUFBSyxFQUFFLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUM7UUFDbkQsS0FBSyxDQUFDLGtCQUFrQixFQUFFLENBQUM7UUFFM0IsS0FBSyxHQUFHLGlCQUFNLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQztRQUVoRCxJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztRQUN6QixJQUFJLENBQUMsZ0JBQWdCLENBQUMsV0FBVyxDQUFDLENBQUM7SUFDckMsQ0FBQyxDQUFDLENBQUM7SUFFSCxLQUFLLENBQUMsR0FBRyxFQUFFO1FBQ1QsSUFBSSxJQUFJLENBQUMsUUFBUSxFQUFFLEVBQUU7WUFDbkIsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1NBQ2hCO0lBQ0gsQ0FBQyxDQUFDLENBQUM7SUFFSCxLQUFLLE1BQU0sdUJBQXVCLElBQUksQ0FBQyxJQUFJLEVB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QUUsQ0FBQztJQUN6QixDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgVGVzdEJpdEdvLCBUZXN0Qml0R29BUEkgfSBmcm9tICdAYml0Z28vc2RrLXRlc3QnO1xuaW1wb3J0IHsgQml0R28gfSBmcm9tICdiaXRnbyc7XG5pbXBvcnQgeyBjb21tb24gfSBmcm9tICdAYml0Z28vc2RrLWNvcmUnO1xuaW1wb3J0ICogYXMgbm9jayBmcm9tICdub2NrJztcbmltcG9ydCAqIGFzIGV4cHJlc3MgZnJvbSAnZXhwcmVzcyc7XG5pbXBvcnQgKiBhcyBzaW5vbiBmcm9tICdzaW5vbic7XG5pbXBvcnQgKiBhcyBmcyBmcm9tICdmcyc7XG5cbmltcG9ydCB7IGxpZ2h0bmluZ1NpZ25lckNvbmZpZ3MsIGFwaURhdGEsIHNpZ25lckFwaURhdGEgfSBmcm9tICcuL2xpZ2h0bmluZ1NpZ25lckZpeHR1cmUnO1xuaW1wb3J0IHtcbiAgaGFuZGxlQ3JlYXRlU2lnbmVyTWFjYXJvb24sXG4gIGhhbmRsZUdldExpZ2h0bmluZ1dhbGxldFN0YXRlLFxuICBoYW5kbGVJbml0TGlnaHRuaW5nV2FsbGV0LFxuICBoYW5kbGVVbmxvY2tMaWdodG5pbmdXYWxsZXQsXG59IGZyb20gJy4uLy4uLy4uLy4uL3NyYy9saWdodG5pbmcvbGlnaHRuaW5nU2lnbmVyUm91dGVzJztcblxuZGVzY3JpYmUoJ0xpZ2h0bmluZyBzaWduZXIgcm91dGVzJywgKCkgPT4ge1xuICBsZXQgYml0Z286IFRlc3RCaXRHb0FQSTtcbiAgbGV0IGJnVXJsO1xuXG4gIGJlZm9yZShhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKCFub2NrLmlzQWN0aXZlKCkpIHtcbiAgICAgIG5vY2suYWN0aXZhdGUoKTtcbiAgICB9XG5cbiAgICBiaXRnbyA9IFRlc3RCaXRHby5kZWNvcmF0ZShCaXRHbywgeyBlbnY6ICd0ZXN0JyB9KTtcbiAgICBiaXRnby5pbml0aWFsaXplVGVzdFZhcnMoKTtcblxuICAgIGJnVXJsID0gY29tbW9uLkVudmlyb25tZW50c1tiaXRnby5nZXRFbnYoKV0udXJpO1xuXG4gICAgbm9jay5kaXNhYmxlTmV0Q29ubmVjdCgpO1xuICAgIG5vY2suZW5hYmxlTmV0Q29ubmVjdCgnMTI3LjAuMC4xJyk7XG4gIH0pO1xuXG4gIGFmdGVyKCgpID0+IHtcbiAgICBpZiAobm9jay5pc0FjdGl2ZSgpKSB7XG4gICAgICBub2NrLnJlc3RvcmUoKTtcbiAgICB9XG4gIH0pO1xuXG4gIGZvciAoY29uc3QgaW5jbHVkaW5nT3B0aW9uYWxGaWVsZHMgb2YgW3RydWUsIGZhbHNlXSkge1xuICAgIGl0KGBzaG91bGQgaW5pdGlhbGl6ZSBsaWdodG5pbmcgc2lnbmVyIHdhbGxldCAke1xuICAgICAgaW5jbHVkaW5nT3B0aW9uYWxGaWVsZHMgPyAnd2l0aCcgOiAnd2l0aG91dCdcbiAgICB9IG9wdGlvbmFsIGZpZWxkc2AsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHJlYWRGaWxlU3R1YiA9IHNpbm9uLnN0dWIoZnMucHJvbWlzZXMsICdyZWFkRmlsZScpLnJlc29sdmVzKEpTT04uc3RyaW5naWZ5KGxpZ2h0bmluZ1NpZ25lckNvbmZpZ3MpKTtcbiAgICAgIGNvbnN0IHdwV2FsbGV0bm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgIC5nZXQoYC9hcGkvdjIvdGxuYnRjL3dhbGxldC8ke2FwaURhdGEud2FsbGV0LmlkfWApXG4gICAgICAgIC5xdWVyeSh7IGluY2x1ZGVCYWxhbmNlOiBmYWxzZSB9KVxuICAgICAgICAucmVwbHkoMjAwLCBhcGlEYXRhLndhbGxldCk7XG5cbiAgICAgIGNvbnN0IHdwS2V5Y2hhaW5Ob2NrcyA9IFtcbiAgICAgICAgbm9jayhiZ1VybCkuZ2V0KGAvYXBpL3YyL3RsbmJ0Yy9rZXkvJHthcGlEYXRhLnVzZXJLZXkuaWR9YCkucmVwbHkoMjAwLCBhcGlEYXRhLnVzZXJLZXkpLFxuICAgICAgICBub2NrKGJnVXJsKS5nZXQoYC9hcGkvdjIvdGxuYnRjL2tleS8ke2FwaURhdGEudXNlckF1dGhLZXkuaWR9YCkucmVwbHkoMjAwLCBhcGlEYXRhLnVzZXJBdXRoS2V5KSxcbiAgICAgICAgbm9jayhiZ1VybCkuZ2V0KGAvYXBpL3YyL3RsbmJ0Yy9rZXkvJHthcGlEYXRhLm5vZGVBdXRoS2V5LmlkfWApLnJlcGx5KDIwMCwgYXBpRGF0YS5ub2RlQXV0aEtleSksXG4gICAgICAgIG5vY2soYmdVcmwpLmdldChgL2FwaS92Mi90bG5idGMva2V5LyR7YXBpRGF0YS51c2VyQXV0aEtleS5pZH1gKS5yZXBseSgyMDAsIGFwaURhdGEudXNlckF1dGhLZXkpLFxuICAgICAgICBub2NrKGJnVXJsKS5nZXQoYC9hcGkvdjIvdGxuYnRjL2tleS8ke2FwaURhdGEubm9kZUF1dGhLZXkuaWR9YCkucmVwbHkoMjAwLCBhcGlEYXRhLm5vZGVBdXRoS2V5KSxcbiAgICAgIF07XG5cbiAgICAgIGNvbnN0IHNpZ25lckluaXRXYWxsZXROb2NrID0gbm9jayhsaWdodG5pbmdTaWduZXJDb25maWdzLmZha2VpZC51cmwpXG4gICAgICAgIC5wb3N0KGAvdjEvaW5pdHdhbGxldGApXG4gICAgICAgIC5yZXBseSgyMDAsIHNpZ25lckFwaURhdGEuaW5pdFdhbGxldCk7XG5cbiAgICAgIGNvbnN0IHdwV2FsbGV0VXBkYXRlTm9jayA9IG5vY2soYmdVcmwpLnB1dChgL2FwaS92Mi90bG5idGMvd2FsbGV0LyR7YXBpRGF0YS53YWxsZXQuaWR9YCkucmVwbHkoMjAwKTtcblxuICAgICAgY29uc3QgcmVxID0ge1xuICAgICAgICBiaXRnbzogYml0Z28sXG4gICAgICAgIGJvZHk6IGluY2x1ZGluZ09wdGlvbmFsRmllbGRzXG4gICAgICAgICAgPyBhcGlEYXRhLmluaXRXYWxsZXRSZXF1ZXN0Qm9keVxuICAgICAgICAgIDogeyAuLi5hcGlEYXRhLmluaXRXYWxsZXRSZXF1ZXN0Qm9keSwgZXhwcmVzc0hvc3Q6IHVuZGVmaW5lZCB9LFxuICAgICAgICBwYXJhbXM6IHtcbiAgICAgICAgICBjb2luOiAndGxuYnRjJyxcbiAgICAgICAgICBpZDogJ2Zha2VpZCcsXG4gICAgICAgIH0sXG4gICAgICAgIGNvbmZpZzoge1xuICAgICAgICAgIGxpZ2h0bmluZ1NpZ25lckZpbGVTeXN0ZW1QYXRoOiAnbGlnaHRuaW5nU2lnbmVyRmlsZVN5c3RlbVBhdGgnLFxuICAgICAgICB9LFxuICAgICAgfSBhcyB1bmtub3duIGFzIGV4cHJlc3MuUmVxdWVzdDtcblxuICAgICAgYXdhaXQgaGFuZGxlSW5pdExpZ2h0bmluZ1dhbGxldChyZXEpO1xuXG4gICAgICB3cFdhbGxldFVwZGF0ZU5vY2suZG9uZSgpO1xuICAgICAgc2lnbmVySW5pdFdhbGxldE5vY2suZG9uZSgpO1xuICAgICAgd3BLZXljaGFpbk5vY2tzLmZvckVhY2goKHMpID0+IHMuZG9uZSgpKTtcbiAgICAgIHdwV2FsbGV0bm9jay5kb25lKCk7XG4gICAgICByZWFkRmlsZVN0dWIuY2FsbGVkT25jZVdpdGgoJ2xpZ2h0bmluZ1NpZ25lckZpbGVTeXN0ZW1QYXRoJykuc2hvdWxkLmJlLnRydWUoKTtcbiAgICAgIHJlYWRGaWxlU3R1Yi5yZXN0b3JlKCk7XG4gICAgfSk7XG4gIH1cblxuICBmb3IgKGNvbnN0IGFkZElwQ2F2ZWF0VG9NYWNhcm9vbiBvZiBbdHJ1ZSwgZmFsc2VdKSB7XG4gICAgZm9yIChjb25zdCBpbmNsdWRlV2F0Y2hPbmx5SXAgb2YgW3RydWUsIGZhbHNlXSkge1xuICAgICAgaXQoYGNyZWF0ZSBzaWduZXIgbWFjYXJvb24gJHthZGRJcENhdmVhdFRvTWFjYXJvb24gPyAnd2l0aCcgOiAnd2l0aG91dCd9IGluY2x1ZGluZyBJUCBjYXZlYXQgd2hlbiBpdCAke1xuICAgICAgICBpbmNsdWRlV2F0Y2hPbmx5SXAgPyAnZG9lcycgOiBgZG9lc24ndGBcbiAgICAgIH0gZXhpc3RgLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHJlYWRGaWxlU3R1YiA9IHNpbm9uLnN0dWIoZnMucHJvbWlzZXMsICdyZWFkRmlsZScpLnJlc29sdmVzKEpTT04uc3RyaW5naWZ5KGxpZ2h0bmluZ1NpZ25lckNvbmZpZ3MpKTtcbiAgICAgICAgY29uc3Qgd3BXYWxsZXRub2NrID0gbm9jayhiZ1VybClcbiAgICAgICAgICAuZ2V0KGAvYXBpL3YyL3RsbmJ0Yy93YWxsZXQvJHthcGlEYXRhLndhbGxldC5pZH1gKVxuICAgICAgICAgIC5xdWVyeSh7IGluY2x1ZGVCYWxhbmNlOiBmYWxzZSB9KVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIC4uLmFwaURhdGEud2FsbGV0LFxuICAgICAgICAgICAgLi4uKGluY2x1ZGVXYXRjaE9ubHlJcCA/IHt9IDogeyB3YXRjaE9ubHlFeHRlcm5hbElwOiBudWxsIH0pLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHdwS2V5Y2hhaW5Ob2NrcyA9IFtcbiAgICAgICAgICBub2NrKGJnVXJsKS5nZXQoYC9hcGkvdjIvdGxuYnRjL2tleS8ke2FwaURhdGEudXNlckF1dGhLZXkuaWR9YCkucmVwbHkoMjAwLCBhcGlEYXRhLnVzZXJBdXRoS2V5KSxcbiAgICAgICAgICBub2NrKGJnVXJsKS5nZXQoYC9hcGkvdjIvdGxuYnRjL2tleS8ke2FwaURhdGEubm9kZUF1dGhLZXkuaWR9YCkucmVwbHkoMjAwLCBhcGlEYXRhLm5vZGVBdXRoS2V5KSxcbiAgICAgICAgXTtcblxuICAgICAgICBjb25zdCBzaWduZXJNYWNhcm9vbiA9IG5vY2sobGlnaHRuaW5nU2lnbmVyQ29uZmlncy5mYWtlaWQudXJsKVxuICAgICAgICAgIC5wb3N0KGAvdjEvbWFjYXJvb25gKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHNpZ25lckFwaURhdGEuYmFrZU1hY2Fyb29uKTtcblxuICAgICAgICBjb25zdCB3cFdhbGxldFVwZGF0ZU5vY2sgPSBub2NrKGJnVXJsKS5wdXQoYC9hcGkvdjIvdGxuYnRjL3dhbGxldC8ke2FwaURhdGEud2FsbGV0LmlkfWApLnJlcGx5KDIwMCk7XG5cbiAgICAgICAgY29uc3QgcmVxID0ge1xuICAgICAgICAgIGJpdGdvOiBiaXRnbyxcbiAgICAgICAgICBib2R5OiB7IC4uLmFwaURhdGEuc2lnbmVyTWFjYXJvb25SZXF1ZXN0Qm9keSwgYWRkSXBDYXZlYXRUb01hY2Fyb29uIH0sXG4gICAgICAgICAgcGFyYW1zOiB7XG4gICAgICAgICAgICBjb2luOiAndGxuYnRjJyxcbiAgICAgICAgICAgIGlkOiAnZmFrZWlkJyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGNvbmZpZzoge1xuICAgICAgICAgICAgbGlnaHRuaW5nU2lnbmVyRmlsZVN5c3RlbVBhdGg6ICdsaWdodG5pbmdTaWduZXJGaWxlU3lzdGVtUGF0aCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSBhcyB1bmtub3duIGFzIGV4cHJlc3MuUmVxdWVzdDtcblxuICAgICAgICB0cnkge1xuICAgICAgICAgIGF3YWl0IGhhbmRsZUNyZWF0ZVNpZ25lck1hY2Fyb29uKHJlcSk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICBpZiAoIWluY2x1ZGVXYXRjaE9ubHlJcCB8fCBhZGRJcENhdmVhdFRvTWFjYXJvb24pIHtcbiAgICAgICAgICAgIHRocm93IGU7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgd3BXYWxsZXRVcGRhdGVOb2NrLmRvbmUoKTtcbiAgICAgICAgc2lnbmVyTWFjYXJvb24uZG9uZSgpO1xuICAgICAgICB3cEtleWNoYWluTm9ja3MuZm9yRWFjaCgocykgPT4gcy5kb25lKCkpO1xuICAgICAgICB3cFdhbGxldG5vY2suZG9uZSgpO1xuICAgICAgICByZWFkRmlsZVN0dWIuY2FsbGVkT25jZVdpdGgoJ2xpZ2h0bmluZ1NpZ25lckZpbGVTeXN0ZW1QYXRoJykuc2hvdWxkLmJlLnRydWUoKTtcbiAgICAgICAgcmVhZEZpbGVTdHViLnJlc3RvcmUoKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIGl0KCdzaG91bGQgZ2V0IHNpZ25lciB3YWxsZXQgc3RhdGUnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgcmVhZEZpbGVTdHViID0gc2lub24uc3R1Yihmcy5wcm9taXNlcywgJ3JlYWRGaWxlJykucmVzb2x2ZXMoSlNPTi5zdHJpbmdpZnkobGlnaHRuaW5nU2lnbmVyQ29uZmlncykpO1xuICAgIGNvbnN0IHdhbGxldFN0YXRlTm9jayA9IG5vY2sobGlnaHRuaW5nU2lnbmVyQ29uZmlncy5mYWtlaWQudXJsKVxuICAgICAgLmdldChgL3YxL3N0YXRlYClcbiAgICAgIC5yZXBseSgyMDAsIHNpZ25lckFwaURhdGEud2FsbGV0U3RhdGUpO1xuXG4gICAgY29uc3QgcmVxID0ge1xuICAgICAgYml0Z286IGJpdGdvLFxuICAgICAgcGFyYW1zOiB7XG4gICAgICAgIGNvaW46ICd0bG5idGMnLFxuICAgICAgICBpZDogYXBpRGF0YS53YWxsZXQuaWQsXG4gICAgICB9LFxuICAgICAgY29uZmlnOiB7XG4gICAgICAgIGxpZ2h0bmluZ1NpZ25lckZpbGVTeXN0ZW1QYXRoOiAnbGlnaHRuaW5nU2lnbmVyRmlsZVN5c3RlbVBhdGgnLFxuICAgICAgfSxcbiAgICB9IGFzIHVua25vd24gYXMgZXhwcmVzcy5SZXF1ZXN0O1xuXG4gICAgYXdhaXQgaGFuZGxlR2V0TGlnaHRuaW5nV2FsbGV0U3RhdGUocmVxKTtcblxuICAgIHdhbGxldFN0YXRlTm9jay5kb25lKCk7XG4gICAgcmVhZEZpbGVTdHViLmNhbGxlZE9uY2VXaXRoKCdsaWdodG5pbmdTaWduZXJGaWxlU3lzdGVtUGF0aCcpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgcmVhZEZpbGVTdHViLnJlc3RvcmUoKTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCB1bmxvY2sgbGlnaHRuaW5nIHdhbGxldCcsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCByZWFkRmlsZVN0dWIgPSBzaW5vbi5zdHViKGZzLnByb21pc2VzLCAncmVhZEZpbGUnKS5yZXNvbHZlcyhKU09OLnN0cmluZ2lmeShsaWdodG5pbmdTaWduZXJDb25maWdzKSk7XG5cbiAgICBjb25zdCB1bmxvY2t3YWxsZXROb2NrID0gbm9jayhsaWdodG5pbmdTaWduZXJDb25maWdzLmZha2VpZC51cmwpLnBvc3QoYC92MS91bmxvY2t3YWxsZXRgKS5yZXBseSgyMDApO1xuXG4gICAgY29uc3QgcmVxID0ge1xuICAgICAgYml0Z286IGJpdGdvLFxuICAgICAgYm9keTogYXBpRGF0YS51bmxvY2tXYWxsZXRSZXF1ZXN0Qm9keSxcbiAgICAgIHBhcmFtczoge1xuICAgICAgICBjb2luOiAndGxuYnRjJyxcbiAgICAgICAgaWQ6ICdmYWtlaWQnLFxuICAgICAgfSxcbiAgICAgIGNvbmZpZzoge1xuICAgICAgICBsaWdodG5pbmdTaWduZXJGaWxlU3lzdGVtUGF0aDogJ2xpZ2h0bmluZ1NpZ25lckZpbGVTeXN0ZW1QYXRoJyxcbiAgICAgIH0sXG4gICAgfSBhcyB1bmtub3duIGFzIGV4cHJlc3MuUmVxdWVzdDtcblxuICAgIGF3YWl0IGhhbmRsZVVubG9ja0xpZ2h0bmluZ1dhbGxldChyZXEpO1xuXG4gICAgdW5sb2Nrd2FsbGV0Tm9jay5kb25lKCk7XG4gICAgcmVhZEZpbGVTdHViLmNhbGxlZE9uY2VXaXRoKCdsaWdodG5pbmdTaWduZXJGaWxlU3lzdGVtUGF0aCcpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgcmVhZEZpbGVTdHViLnJlc3RvcmUoKTtcbiAgfSk7XG59KTtcbiJdfQ==Выполнить команду
Для локальной разработки. Не используйте в интернете!