diff --git a/bin/pk.js b/bin/pk.js new file mode 100755 index 000000000..9750b6f5d --- /dev/null +++ b/bin/pk.js @@ -0,0 +1,8 @@ +#!/usr/bin/env node + +// this will be a CLI entrypoint to this library +// we expect that this can be used as a CLI +// application directly as js-polykey + +require('../dist/bin/pk.js')(process.argv) + diff --git a/dist/HandshakeMessage.proto b/dist/HandshakeMessage.proto new file mode 100644 index 000000000..588242348 --- /dev/null +++ b/dist/HandshakeMessage.proto @@ -0,0 +1,9 @@ +package handshakepackage; +syntax = "proto3"; + +message HandshakeMessage { + bytes target_pub_key = 1; + bytes requesting_pub_key = 2; + bytes message = 3; + bytes response_peer_info = 4; +} diff --git a/dist/KeyManager.js b/dist/KeyManager.js deleted file mode 100644 index f83d9ab29..000000000 --- a/dist/KeyManager.js +++ /dev/null @@ -1,310 +0,0 @@ -"use strict"; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -const fs_1 = __importDefault(require("fs")); -const path_1 = __importDefault(require("path")); -const crypto_1 = __importDefault(require("crypto")); -const util_1 = require("util"); -// js imports -const kbpgp = require('kbpgp'); -var F = kbpgp["const"].openpgp; -const zxcvbn = require('zxcvbn'); -class KeyManager { - constructor(polyKeyPath = '~/.polykey/') { - this.keyPair = { private: '', public: '', passphrase: '' }; - this.identity = undefined; - this.storePath = polyKeyPath; - this.derivedKeys = new Map(); - } - // return {private: string, public: string} - async generateKeyPair(name, email, passphrase, numBits = 4096) { - // Validate passphrase - const passValidation = zxcvbn(passphrase); - // The following is an arbitrary delineation of desirable scores - if (passValidation.score < 2) { - throw new Error(`passphrase score for new keypair is below 2!`); - } - // Define options - var options = { - userid: `${name} <${email}>`, - primary: { - nbits: 4096, - flags: F.certify_keys | F.sign_data | F.auth | F.encrypt_comm | F.encrypt_storage, - expire_in: 0 // never expire - }, - subkeys: [ - // { - // nbits: 2048, - // flags: F.sign_data, - // expire_in: 86400 * 365 * 8 // 8 years - // } - ] - }; - this.passphrase = passphrase; - return new Promise((resolve, reject) => { - kbpgp.KeyManager.generate(options, (err, identity) => { - identity.sign({}, (err) => { - if (err) { - reject(err); - } - // Export pub key first - identity.export_pgp_public({}, (err, pubKey) => { - if (err) { - reject(err); - } - // Finally export priv key - identity.export_pgp_private({ passphrase: passphrase }, (err, privKey) => { - if (err) { - reject(err); - } - // Resolve to parent promise - const keypair = { private: privKey, public: pubKey, passphrase: passphrase }; - this.keyPair = keypair; - // Set the new identity - this.identity = identity; - resolve(keypair); - }); - }); - }); - }); - }); - } - getKeyPair() { - return this.keyPair; - } - getPublicKey() { - return this.keyPair.public; - } - getPrivateKey() { - return this.keyPair.private; - } - async loadPrivateKey(privateKey, passphrase = '') { - try { - let keyBuffer; - if (typeof privateKey === 'string') { - keyBuffer = Buffer.from(await fs_1.default.promises.readFile(privateKey)); - } - else { - keyBuffer = privateKey; - } - this.keyPair.private = keyBuffer.toString(); - if (passphrase) { - this.passphrase = passphrase; - } - } - catch (err) { - throw (err); - } - } - async loadPublicKey(publicKey) { - try { - let keyBuffer; - if (typeof publicKey === 'string') { - keyBuffer = Buffer.from(await fs_1.default.promises.readFile(publicKey)); - } - else { - keyBuffer = publicKey; - } - this.keyPair.public = keyBuffer.toString(); - } - catch (err) { - throw (err); - } - } - async loadIdentity(passphrase) { - return new Promise((resolve, reject) => { - const pubKey = this.getPublicKey(); - const privKey = this.getPrivateKey(); - kbpgp.KeyManager.import_from_armored_pgp({ armored: pubKey }, (err, identity) => { - if (err) { - reject(err); - } - identity.merge_pgp_private({ - armored: privKey - }, (err) => { - if (err) { - reject(err); - } - if (identity.is_pgp_locked()) { - identity.unlock_pgp({ - passphrase: passphrase - }, (err) => { - if (err) { - reject(err); - } - this.identity = identity; - resolve(); - }); - } - else { - this.identity = identity; - resolve(); - } - }); - }); - }); - } - async loadKeyPair(publicKey, privateKey, passphrase = '') { - await this.loadPrivateKey(privateKey); - await this.loadPublicKey(publicKey); - await this.loadIdentity(passphrase); - if (passphrase) { - this.passphrase; - } - } - async exportPrivateKey(path) { - await fs_1.default.promises.writeFile(path, this.keyPair.private); - } - async exportPublicKey(path) { - await fs_1.default.promises.writeFile(path, this.keyPair.public); - } - // symmetric key generation - generateKeySync(name, passphrase) { - const salt = crypto_1.default.randomBytes(32); - this.derivedKeys[name] = crypto_1.default.pbkdf2Sync(passphrase, salt, 10000, 256 / 8, 'sha256'); - return this.derivedKeys[name]; - } - async generateKey(name, passphrase) { - const salt = crypto_1.default.randomBytes(32); - this.derivedKeys[name] = await util_1.promisify(crypto_1.default.pbkdf2)(passphrase, salt, 10000, 256 / 8, 'sha256'); - return this.derivedKeys[name]; - } - importKeySync(name, keyPath) { - this.derivedKeys[name] = fs_1.default.readFileSync(keyPath); - } - async importKey(name, keyPath) { - this.derivedKeys[name] = await fs_1.default.promises.readFile(keyPath); - } - importKeyBuffer(name, key) { - this.derivedKeys[name] = key; - } - async exportKey(name, path, createPath) { - if (!this.derivedKeys[name]) { - throw Error(`There is no key loaded for name: ${name}`); - } - if (createPath) { - await fs_1.default.promises.mkdir(path_1.default.dirname(path), { recursive: true }); - } - await fs_1.default.promises.writeFile(path, this.derivedKeys[name]); - } - exportKeySync(path, createPath) { - if (!this.derivedKeys[name]) { - throw Error(`There is no key loaded for name: ${name}`); - } - if (createPath) { - fs_1.default.mkdirSync(path_1.default.dirname(path), { recursive: true }); - } - fs_1.default.writeFileSync(path, this.derivedKeys[name]); - } - async getIdentityFromPublicKey(pubKey) { - return new Promise((resolve, reject) => { - kbpgp.KeyManager.import_from_armored_pgp({ armored: pubKey }, (err, identity) => { - if (err) { - reject(err); - } - resolve(identity); - }); - }); - } - async getIdentityFromPrivateKey(privKey, passphrase) { - return new Promise((resolve, reject) => { - kbpgp.KeyManager.import_from_armored_pgp({ armored: privKey }, (err, identity) => { - if (err) { - reject(err); - } - if (identity.is_pgp_locked()) { - identity.unlock_pgp({ - passphrase: passphrase - }, (err) => { - if (err) { - reject(err); - } - resolve(identity); - }); - } - else { - resolve(identity); - } - }); - }); - } - // Sign data - signData(data, withKey = undefined, keyPassphrase = undefined) { - return new Promise(async (resolve, reject) => { - let resolvedIdentity; - if (withKey !== undefined) { - if (keyPassphrase === undefined) { - reject(Error('passphrase for private key was not provided')); - } - resolvedIdentity = await this.getIdentityFromPrivateKey(withKey, keyPassphrase); - } - else if (this.identity !== undefined) { - resolvedIdentity = this.identity; - } - else { - throw (Error('no identity available for signing')); - } - const params = { - msg: data, - sign_with: resolvedIdentity - }; - kbpgp.box(params, (err, result_string, result_buffer) => { - if (err) { - reject(err); - } - resolve(Buffer.from(result_string)); - }); - }); - } - // Verify data - verifyData(data, signature, withKey = undefined) { - return new Promise(async (resolve, reject) => { - var ring = new kbpgp.keyring.KeyRing; - let resolvedIdentity; - if (withKey !== undefined) { - resolvedIdentity = await this.getIdentityFromPublicKey(withKey); - } - else if (this.identity !== undefined) { - resolvedIdentity = this.identity; - } - else { - throw (Error('no identity available for signing')); - } - ring.add_key_manager(this.identity); - const params = { - armored: signature, - data: data, - keyfetch: ring - }; - kbpgp.unbox(params, (err, literals) => { - if (err) { - reject(err); - } - let ds = literals[0].get_data_signer(); - let km; - if (ds) { - km = ds.get_key_manager(); - } - if (km) { - resolve(km.get_pgp_fingerprint().toString('hex')); - } - else { - reject(Error('could not verify file')); - } - }); - }); - } - getKey(name) { - return this.derivedKeys[name]; - } - isLoaded() { - if (this.derivedKeys[name]) { - return true; - } - return false; - } -} -exports.KeyManager = KeyManager; -//# sourceMappingURL=KeyManager.js.map \ No newline at end of file diff --git a/dist/KeyManager.js.map b/dist/KeyManager.js.map deleted file mode 100644 index 772ee69b2..000000000 --- a/dist/KeyManager.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"KeyManager.js","sourceRoot":"","sources":["../src/KeyManager.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/PeerInfoMessage.proto b/dist/PeerInfoMessage.proto new file mode 100644 index 000000000..45dbd73bd --- /dev/null +++ b/dist/PeerInfoMessage.proto @@ -0,0 +1,8 @@ +package peerinfopackage; +syntax = "proto3"; + +message PeerInfoMessage { + string pub_key = 1; + repeated string addresses = 2; + string connected_addr = 3; +} diff --git a/dist/Polykey.js b/dist/Polykey.js deleted file mode 100644 index f3fe33a42..000000000 --- a/dist/Polykey.js +++ /dev/null @@ -1,379 +0,0 @@ -"use strict"; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -const os_1 = __importDefault(require("os")); -const fs_1 = __importDefault(require("fs")); -const path_1 = __importDefault(require("path")); -const Vault_1 = __importDefault(require("@polykey/Vault")); -const crypto_1 = __importDefault(require("crypto")); -const jsonfile_1 = __importDefault(require("jsonfile")); -const KeyManager_1 = require("@polykey/KeyManager"); -const vaultKeySize = 128 / 8; // in bytes -class Polykey { - constructor(km, polykeyPath = `${os_1.default.homedir()}/.polykey`) { - this.km = km || new KeyManager_1.KeyManager(this.polykeyPath); - this.polykeyPath = polykeyPath; - this.metadataPath = path_1.default.join(this.polykeyPath, 'metadata'); - // Set file system - this.fs = fs_1.default; - // Initialize reamining members - this.vaults = new Map(); - this.metadata = { - vaults: {}, - publicKeyPath: null, - privateKeyPath: null, - passphrase: null - }; - // sync with polykey directory - this.initSync(); - } - static get KeyManager() { - return KeyManager_1.KeyManager; - } - async fileExists(path) { - return this.fs.existsSync(path); - } - fileExistsSync(path) { - return this.fs.existsSync(path); - } - ///////////// - // Secrets // - ///////////// - async secretExists(vaultName, secretName) { - const vault = await this.getVault(vaultName); - const secretExists = vault.secretExists(secretName); - return secretExists; - } - async addSecret(vaultName, secretName, secret) { - let vault; - try { - vault = await this.getVault(vaultName); - vault.addSecret(secretName, secret); - } - catch (err) { - throw err; - } - } - async removeSecret(vaultName, secretName) { - let vault; - try { - vault = await this.getVault(vaultName); - vault.removeSecret(secretName); - } - catch (err) { - throw err; - } - } - async getSecret(vaultName, secretName) { - let vault; - let secret; - try { - vault = await this.getVault(vaultName); - secret = vault.getSecret(secretName); - } - catch (err) { - throw err; - } - return secret; - } - async copySecret(vaultName, secretName) { - let vault; - let secret; - try { - vault = await this.getVault(vaultName); - secret = vault.getSecret(secretName); - } - catch (err) { - throw err; - } - return secret; - } - ///////////// - // Vaults // - ///////////// - async createVault(vaultName, key = undefined) { - const path = path_1.default.join(this.polykeyPath, vaultName); - let vaultExists; - try { - vaultExists = await this.fileExists(path); - } - catch (err) { - throw err; - } - if (vaultExists) { - throw Error('Vault already exists!'); - } - try { - // Directory not present, create one - this.fs.mkdirSync(path, { recursive: true }); - // Create key if not provided - let vaultKey; - if (key === undefined) { - // Generate new key - vaultKey = Buffer.from(crypto_1.default.randomBytes(vaultKeySize)); - } - else { - // Assign key if it is provided - vaultKey = key; - } - this.metadata.vaults[vaultName] = { key: vaultKey, tags: [] }; - await this.writeMetadata(); - const vault = new Vault_1.default(vaultName, vaultKey, this.polykeyPath); - this.vaults.set(vaultName, vault); - return await this.getVault(vaultName); - } - catch (err) { - // Delete vault dir and garbage collect - await this.destroyVault(vaultName); - throw err; - } - } - async vaultExists(vaultName) { - const path = path_1.default.join(this.polykeyPath, vaultName); - const vaultExists = this.fs.existsSync(path); - return vaultExists; - } - async destroyVault(vaultName) { - // this is convenience function for removing all tags - // and triggering garbage collection - // destruction is a better word as we should ensure all traces is removed - const path = path_1.default.join(this.polykeyPath, vaultName); - // Remove directory on file system - if (this.fs.existsSync(path)) { - this.fs.rmdirSync(path, { recursive: true }); - } - // Remaining garbage collection: - // Remove vault from vaults map - if (this.vaults.has(vaultName)) { - this.vaults.delete(vaultName); - } - // Remove from metadata - if (this.metadata.vaults.hasOwnProperty(vaultName)) { - delete this.metadata.vaults[vaultName]; - await this.writeMetadata(); - } - const vaultPathExists = this.fs.existsSync(path); - if (vaultPathExists) { - throw (Error('Vault path could not be destroyed!')); - } - const vaultEntryExists = this.vaults.has(vaultName); - if (vaultEntryExists) { - throw (Error('Vault could not be removed from PolyKey!')); - } - const metaDataHasVault = this.metadata.vaults.hasOwnProperty(vaultName); - if (metaDataHasVault) { - throw (Error('Vault metadata could not be destroyed!')); - } - } - async importKeyPair(privateKeyPath, publicKeyPath, passphrase = '') { - await this.km.loadKeyPair(privateKeyPath, publicKeyPath, passphrase); - this.metadata.publicKeyPath = publicKeyPath; - this.metadata.privateKeyPath = privateKeyPath; - this.metadata.passphrase = passphrase; - this.writeMetadata(); - } - /* Validates whether all the artefacts needed to operate - * a Vault are present. Namely this the vault directory - * and the metadata for the vault containg the key - */ - async validateVault(vaultName) { - const existsMeta = this.metadata.vaults.hasOwnProperty(vaultName); - if (!existsMeta) { - throw Error('Vault metadata does not exist'); - } - const vaultPath = path_1.default.join(this.polykeyPath, vaultName); - const existsFS = await this.fileExists(vaultPath); - if (!existsFS) { - throw Error('Vault directory does not exist'); - } - } - removeItem() { - } - listItems() { - } - listVaults() { - return Array.from(this.vaults.keys()); - } - async listSecrets(vaultName) { - const vault = await this.getVault(vaultName); - return vault.listSecrets(); - } - async verifyFile(filePath, signaturePath, publicKey = undefined) { - try { - // Get key if provided - let keyBuffer; - if (publicKey !== undefined) { - if (typeof publicKey === 'string') { // Path - // Read in from fs - keyBuffer = Buffer.from(this.fs.readFileSync(publicKey)); - } - else { // Buffer - keyBuffer = publicKey; - } - } - else { - // Load keypair into KeyManager from metadata - const publicKeyPath = this.metadata.publicKeyPath; - const privateKeyPath = this.metadata.privateKeyPath; - const passphrase = this.metadata.passphrase; - if (publicKeyPath !== null && privateKeyPath !== null && passphrase !== null) { - await this.km.loadKeyPair(privateKeyPath, publicKeyPath, passphrase); - } - } - // Read in file buffer and signature - const fileBuffer = Buffer.from(this.fs.readFileSync(filePath, undefined)); - const signatureBuffer = Buffer.from(this.fs.readFileSync(signaturePath, undefined)); - const verified = await this.km.verifyData(fileBuffer, signatureBuffer, keyBuffer); - return verified; - } - catch (err) { - throw (err); - } - } - async signFile(path, privateKey = undefined, privateKeyPassphrase = undefined) { - try { - // Get key if provided - let keyBuffer; - if (privateKey !== undefined) { - if (typeof privateKey === 'string') { // Path - // Read in from fs - keyBuffer = Buffer.from(this.fs.readFileSync(privateKey)); - } - else { // Buffer - keyBuffer = privateKey; - } - } - else { - // Load keypair into KeyManager from metadata - const publicKeyPath = this.metadata.publicKeyPath; - const privateKeyPath = this.metadata.privateKeyPath; - const passphrase = this.metadata.passphrase; - if (publicKeyPath !== null && privateKeyPath !== null && passphrase !== null) { - await this.km.loadKeyPair(privateKeyPath, publicKeyPath, passphrase); - } - } - // Read file into buffer - const buffer = Buffer.from(this.fs.readFileSync(path, undefined)); - // Sign the buffer - const signedBuffer = await this.km.signData(buffer, keyBuffer, privateKeyPassphrase); - // Write buffer to signed file - const signedPath = `${path}.sig`; - this.fs.writeFileSync(signedPath, signedBuffer); - return signedPath; - } - catch (err) { - throw (Error(`failed to sign file: ${err}`)); - } - } - // P2P operations - async beginPolyKeyDaemon() { - // const repos = new Git(this.polykeyPath, this.fs, { - // fs: this.fs, - // autoCreate: false - // }); - // const port = 7005; - // repos.on('push', (push) => { - // console.log(`push ${push.repo}/${push.commit} (${push.branch})`); - // push.accept(); - // }); - // repos.on('fetch', (fetch) => { - // console.log(`fetch ${fetch.commit}`); - // fetch.accept(); - // }); - // repos.listen(port, null, () => { - // console.log(`node-git-server running at http://localhost:${port}`) - // }) - // return `ip4/127.0.0.1/tcp/${port}` - } - tagVault() { - } - untagVault() { - } - shareVault() { - } - unshareVault() { - } - /* ============ HELPERS =============== */ - async writeMetadata() { - try { - await jsonfile_1.default.writeFile(this.metadataPath, this.metadata); - } - catch (err) { - throw Error("Error writing vault key to config file"); - } - } - async getVault(vaultName) { - if (this.vaults.has(vaultName)) { - const vault = this.vaults.get(vaultName); - if (vault) { - return vault; - } - } - // vault not in map, create new instance - try { - await this.validateVault(vaultName); - } - catch (err) { - throw err; - } - const vaultKey = this.metadata.vaults[vaultName].key; - const vault = new Vault_1.default(vaultName, vaultKey, this.polykeyPath); - this.vaults.set(vaultName, vault); - return vault; - } - async getNodeAddrs() { - let nodeAddr = []; - // console.log('where is the repo?'); - // console.log(await this.node.repo.stat()) - const addr = await this.node.id(); - addr.addresses.forEach((ma) => { - nodeAddr.push(`${ma.toString()}`); - }); - return nodeAddr; - } - initSync() { - // check if .polykey exists - // make folder if doesn't - if (!this.fs.existsSync(this.polykeyPath)) { - this.fs.mkdirSync(this.polykeyPath, { recursive: true }); - const metadataTemplate = { - vaults: {}, - publicKeyPath: null, - privateKeyPath: null, - passphrase: null - }; - jsonfile_1.default.writeFileSync(this.metadataPath, metadataTemplate); - this.metadata = metadataTemplate; - } - else if (this.fs.existsSync(this.metadataPath)) { - this.metadata = jsonfile_1.default.readFileSync(this.metadataPath); - } - // Load all of the vaults into memory - for (const vaultName in this.metadata.vaults) { - if (this.metadata.vaults.hasOwnProperty(vaultName)) { - const path = path_1.default.join(this.polykeyPath, vaultName); - if (this.fileExistsSync(path)) { - try { - const vaultKey = Buffer.from(this.metadata.vaults[vaultName].key); - const vault = new Vault_1.default(vaultName, vaultKey, this.polykeyPath); - this.vaults.set(vaultName, vault); - } - catch (err) { - throw (err); - } - } - } - } - } - loadKey(path) { - if (path instanceof Buffer) { - return path; - } - const keyBuf = Buffer.from(this.fs.readFileSync(path, undefined)); - return keyBuf; - } -} -exports.default = Polykey; -//# sourceMappingURL=Polykey.js.map \ No newline at end of file diff --git a/dist/Polykey.js.map b/dist/Polykey.js.map deleted file mode 100644 index 382fe96a2..000000000 --- a/dist/Polykey.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"Polykey.js","sourceRoot":"","sources":["../src/Polykey.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/Vault.js b/dist/Vault.js deleted file mode 100644 index 856496359..000000000 --- a/dist/Vault.js +++ /dev/null @@ -1,89 +0,0 @@ -"use strict"; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -const fs_1 = __importDefault(require("fs")); -const path_1 = __importDefault(require("path")); -const futoin_hkdf_1 = __importDefault(require("futoin-hkdf")); -const encryptedfs_1 = require("encryptedfs"); -const vfs = require('virtualfs'); -class Vault { - constructor(name, symKey, baseDir) { - // how do we create pub/priv key pair? - // do we use the same gpg pub/priv keypair - this.keyLen = 32; - this.key = this.genSymKey(symKey, this.keyLen); - // Set filesystem - const vfsInstance = new vfs.VirtualFS; - this.fs = new encryptedfs_1.EncryptedFS(symKey, vfsInstance, vfsInstance, fs_1.default, process); - this.name = name; - this.vaultPath = path_1.default.join(baseDir, name); - // make the vault directory - this.fs.mkdirSync(this.vaultPath, { recursive: true }); - this.secrets = new Map(); - this.loadSecrets(); - } - loadSecrets() { - const secrets = fs_1.default.readdirSync(this.vaultPath, undefined); - for (const secret of secrets) { - this.secrets.set(secret, null); - } - } - genSymKey(asymKey, keyLen) { - return Buffer.from(futoin_hkdf_1.default(asymKey.toString(), keyLen)); - } - secretExists(secretName) { - const secretPath = path_1.default.join(this.vaultPath, secretName); - return this.secrets.has(secretName) && this.fs.existsSync(secretPath); - } - addSecret(secretName, secretBuf) { - // TODO: check if secret already exists - const writePath = path_1.default.join(this.vaultPath, secretName); - // TODO: use aysnc methods - const fd = this.fs.openSync(writePath, 'w'); - this.fs.writeSync(fd, secretBuf, 0, secretBuf.length, 0); - this.secrets.set(secretName, secretBuf); - // TODO: close file or use write file sync - } - getSecret(secretName) { - if (this.secrets.has(secretName)) { - const secret = this.secrets.get(secretName); - if (secret) { - return secret; - } - else { - const secretPath = path_1.default.join(this.vaultPath, secretName); - // TODO: this should be async - const secretBuf = this.fs.readFileSync(secretPath, {}); - this.secrets.set(secretName, secretBuf); - return secretBuf; - } - } - throw Error('Secret: ' + secretName + ' does not exist'); - } - removeSecret(secretName) { - if (this.secrets.has(secretName)) { - const successful = this.secrets.delete(secretName); - if (successful) { - return; - } - throw Error('Secret: ' + secretName + ' was not removed'); - } - throw Error('Secret: ' + secretName + ' does not exist'); - } - listSecrets() { - let secrets = Array.from(this.secrets.keys()); - return secrets; - } - tagVault() { - } - untagVault() { - } - shareVault() { - } - unshareVault() { - } -} -exports.default = Vault; -//# sourceMappingURL=Vault.js.map \ No newline at end of file diff --git a/dist/Vault.js.map b/dist/Vault.js.map deleted file mode 100644 index c919dd437..000000000 --- a/dist/Vault.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"Vault.js","sourceRoot":"","sources":["../src/Vault.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/bin/HandshakeMessage.proto b/dist/bin/HandshakeMessage.proto new file mode 100644 index 000000000..588242348 --- /dev/null +++ b/dist/bin/HandshakeMessage.proto @@ -0,0 +1,9 @@ +package handshakepackage; +syntax = "proto3"; + +message HandshakeMessage { + bytes target_pub_key = 1; + bytes requesting_pub_key = 2; + bytes message = 3; + bytes response_peer_info = 4; +} diff --git a/dist/bin/PeerInfoMessage.proto b/dist/bin/PeerInfoMessage.proto new file mode 100644 index 000000000..45dbd73bd --- /dev/null +++ b/dist/bin/PeerInfoMessage.proto @@ -0,0 +1,8 @@ +package peerinfopackage; +syntax = "proto3"; + +message PeerInfoMessage { + string pub_key = 1; + repeated string addresses = 2; + string connected_addr = 3; +} diff --git a/dist/bin/pk.js b/dist/bin/pk.js new file mode 100644 index 000000000..6f7a3a8db --- /dev/null +++ b/dist/bin/pk.js @@ -0,0 +1 @@ +!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.pk=t():e.pk=t()}(this,(function(){return function(e){var t={};function a(r){if(t[r])return t[r].exports;var s=t[r]={i:r,l:!1,exports:{}};return e[r].call(s.exports,s,s.exports,a),s.l=!0,s.exports}return a.m=e,a.c=t,a.d=function(e,t,r){a.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},a.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},a.t=function(e,t){if(1&t&&(e=a(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(a.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var s in e)a.d(r,s,function(t){return e[t]}.bind(null,s));return r},a.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return a.d(t,"a",t),t},a.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},a.p="",a(a.s=0)}([function(e,t,a){"use strict";var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const s=r(a(6)),i=a(1),o=r(a(12)),n=r(a(13)),u=r(a(34)),d=r(a(35)),l=r(a(36)),c=r(a(37));function p(e){console.error(s.default.red(e.message))}var y;t.actionRunner=function(e){return(...t)=>e(...t).catch(p)},function(e){e[e.SUCCESS=0]="SUCCESS",e[e.INFO=1]="INFO",e[e.WARNING=2]="WARNING"}(y||(y={})),t.PKMessageType=y,t.pkLogger=function(e,t){switch(t){case y.SUCCESS:console.log(s.default.green(e));break;case y.INFO:console.log(s.default.blue(e));break;case y.WARNING:console.log(s.default.yellow(e));break;default:console.log(e)}};const f=new i.program.Command;f.version(a(38).version,"--version","output the current version").addCommand(o.default()).addCommand(u.default()).addCommand(d.default()).addCommand(n.default()).addCommand(c.default()).addCommand(l.default()),e.exports=function(e){f.parse(e)}},function(e,t){e.exports=require("commander")},function(e,t){e.exports=require("fs")},function(e,t,a){"use strict";var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const s=r(a(2)),i=r(a(8)),o=r(a(14)),n=r(a(15)),u=r(a(7)),d=r(a(16)),l=r(a(32)),c=r(a(9)),p=a(0),y=new u.default("PolyKeyConfig");async function f(e){await new Promise((t,a)=>{n.default.prompt(e).then(a=>{for(const t of e)a[t.name]&&y.set(t.name,a[t.name]);t()}).catch(e=>{e.isTtyError,a(e)})})}t.default=async function(){return new Promise(p.actionRunner(async(e,t)=>{await async function(){const e=[];n.default.registerPrompt("fuzzypath",a(33)),y.has("polykeyPath")||e.push({type:"fuzzypath",name:"polykeyPath",message:"Where would you like to store PolyKey?",default:i.default.homedir()+"/.polykey",rootPath:i.default.homedir(),itemType:"directory",suggestOnly:!0,depthLimit:1}),y.has("generateKeyPair")||e.push({type:"confirm",name:"generateKeyPair",message:"Would you like to generate a public/private keypair?",default:!0}),e.length>0&&await f(e);const t=[];y.get("generateKeyPair")?(y.has("keyGenerationName")||t.push({type:"input",name:"keyGenerationName",message:"Please provide your full name for key generation?"}),y.has("keyGenerationEmail")||t.push({type:"input",name:"keyGenerationEmail",message:"Please provide an email for key generation?"}),y.has("keyGenerationPassphrase")||t.push({type:"input",name:"keyGenerationPassphrase",message:"Please provide a secure passphrase for key generation?"})):(y.has("publicKeyPath")||t.push({type:"fuzzypath",name:"publicKeyPath",message:"Please provide the path to your public key?",rootPath:i.default.homedir(),suggestOnly:!0,depthLimit:1}),y.has("privateKeyPath")||t.push({type:"fuzzypath",name:"privateKeyPath",message:"Please providee the path to your private key?",rootPath:i.default.homedir(),suggestOnly:!0,depthLimit:1}),y.has("privatePassphrase")||t.push({type:"input",name:"privatePassphrase",message:"Please provide your private key passphrase?"})),t.length>0&&await f(t)}();const r=y.get("polykeyPath"),u=y.get("generateKeyPair"),h=new c.default(r);if(u){const e=y.get("keyGenerationName"),t=y.get("keyGenerationEmail"),a=y.get("keyGenerationPassphrase");o.default(a).score<2&&p.pkLogger("passphrase score for new keypair is below 2!",p.PKMessageType.WARNING);const r=new l.default.SingleBar({},l.default.Presets.shades_classic);r.start(200,0),r.update(100),r.stop(),await h.generateKeyPair(e,t,a,!0);const n=("~"!==(g=h.storePath)[0]||"/"!==g[1]&&1!==g.length||(g=g.replace("~",i.default.homedir())),g)+"/.keypair";s.default.mkdirSync(n,{recursive:!0});const u=n+"/public_key",d=n+"/private_key";await h.exportPublicKey(u),await h.exportPrivateKey(d),y.set("publicKeyPath",u),y.set("privateKeyPath",d),y.set("privatePassphrase",a),y.set("generateKeyPair",!1),y.delete("keyGenerationName"),y.delete("keyGenerationEmail"),y.delete("keyGenerationPassphrase")}else{const e=y.get("publicKeyPath"),t=y.get("privateKeyPath"),a=y.get("privatePassphrase");await h.loadKeyPair(e,t,a)}var g;e(new d.default(h,r))}))}},function(e,t){e.exports=require("path")},function(e,t){e.exports=require("crypto")},function(e,t){e.exports=require("chalk")},function(e,t){e.exports=require("configstore")},function(e,t){e.exports=require("os")},function(e,t,a){"use strict";var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const s=r(a(2)),i=r(a(4)),o=r(a(22)),n=r(a(5)),u=a(23);t.default=class{constructor(e="~/.polykey/",t=!1,a){this.primaryKeyPair={private:"",public:"",passphrase:""},this.storePath=e,this.useWebWorkers=t,this.workerPool=a,this.derivedKeys=new Map}async generateKeyPair(e,t,a,r=!1,s){const i=o.default.const.openpgp,n={asp:s?new o.default.ASP({progress_hook:s}):void 0,userid:`${e} <${t}>`,primary:{nbits:4096,flags:i.certify_keys|i.sign_data|i.auth|i.encrypt_comm|i.encrypt_storage,expire_in:0},subkeys:[]};return new Promise((e,t)=>{o.default.KeyManager.generate(n,(s,i)=>{s&&t(s),i.sign({},s=>{s&&t(s),i.export_pgp_public({},(s,o)=>{s&&t(s),i.export_pgp_private({passphrase:a},(s,n)=>{s&&t(s);const u={private:n,public:o,passphrase:a};r&&(this.primaryPassphrase=a,this.primaryKeyPair=u,this.primaryIdentity=i),e(u)})})})})})}getKeyPair(){return this.primaryKeyPair}getPublicKey(){return this.primaryKeyPair.public}getPrivateKey(){return this.primaryKeyPair.private}async loadPrivateKey(e,t=""){try{let a;a="string"==typeof e?Buffer.from(await s.default.promises.readFile(e)):e,this.primaryKeyPair.private=a.toString(),t&&(this.primaryPassphrase=t)}catch(e){throw e}}async loadPublicKey(e){try{let t;t="string"==typeof e?Buffer.from(await s.default.promises.readFile(e)):e,this.primaryKeyPair.public=t.toString()}catch(e){throw e}}async loadIdentity(e){return new Promise((t,a)=>{const r=this.getPublicKey(),s=this.getPrivateKey();o.default.KeyManager.import_from_armored_pgp({armored:r},(r,i)=>{r&&a(r),i.merge_pgp_private({armored:s},r=>{r&&a(r),i.is_pgp_locked()?i.unlock_pgp({passphrase:e},e=>{e&&a(e),this.primaryIdentity=i,t()}):(this.primaryIdentity=i,t())})})})}async loadKeyPair(e,t,a=""){await this.loadPrivateKey(t),await this.loadPublicKey(e),await this.loadIdentity(a),a&&this.primaryPassphrase}async exportPrivateKey(e){await s.default.promises.writeFile(e,this.primaryKeyPair.private)}async exportPublicKey(e){await s.default.promises.writeFile(e,this.primaryKeyPair.public)}generateKeySync(e,t){const a=n.default.randomBytes(32);return this.derivedKeys[e]=n.default.pbkdf2Sync(t,a,1e4,32,"sha256"),this.derivedKeys[e]}async generateKey(e,t){const a=n.default.randomBytes(32);return this.derivedKeys[e]=await u.promisify(n.default.pbkdf2)(t,a,1e4,32,"sha256"),this.derivedKeys[e]}importKeySync(e,t){this.derivedKeys[e]="string"==typeof t?s.default.readFileSync(t):t}async importKey(e,t){this.derivedKeys[e]="string"==typeof t?await s.default.promises.readFile(t):t}async exportKey(e,t,a){if(!this.derivedKeys.has(e))throw Error("There is no key loaded for name: "+e);a&&await s.default.promises.mkdir(i.default.dirname(t),{recursive:!0}),await s.default.promises.writeFile(t,this.derivedKeys[e])}exportKeySync(e,t){if(!this.derivedKeys.has(name))throw Error("There is no key loaded for name: "+name);t&&s.default.mkdirSync(i.default.dirname(e),{recursive:!0}),s.default.writeFileSync(e,this.derivedKeys[name])}async getIdentityFromPublicKey(e){return new Promise((t,a)=>{o.default.KeyManager.import_from_armored_pgp({armored:e},(e,r)=>{e&&a(e),t(r)})})}async getIdentityFromPrivateKey(e,t){return new Promise((a,r)=>{o.default.KeyManager.import_from_armored_pgp({armored:e},(e,s)=>{e&&r(e),s.is_pgp_locked()?s.unlock_pgp({passphrase:t},e=>{e&&r(e),a(s)}):a(s)})})}signData(e,t,a){return new Promise(async(r,s)=>{let i;if(t)a||s(Error("passphrase for private key was not provided")),i=await this.getIdentityFromPrivateKey(t,a);else{if(!this.primaryIdentity)throw Error("no identity available for signing");i=this.primaryIdentity}if(this.useWebWorkers&&this.workerPool){const t=await this.workerPool.queue(async t=>await t.signData(e,i));r(t)}else{const t={msg:e,sign_with:i};o.default.box(t,(e,t,a)=>{e&&s(e),r(Buffer.from(t))})}})}verifyData(e,t,a){return new Promise(async(r,s)=>{const i=new o.default.keyring.KeyRing;let n;if(a)n=await this.getIdentityFromPublicKey(a);else{if(!this.primaryIdentity)throw new Error("no identity available for verifying");n=this.primaryIdentity}if(this.useWebWorkers&&this.workerPool){const a=await this.workerPool.queue(async a=>await a.verifyData(e,t,n));r(a)}else{i.add_key_manager(this.primaryIdentity);const a={armored:t,data:e,keyfetch:i};o.default.unbox(a,(e,t)=>{e&&s(e);let a,i=t[0].get_data_signer();i&&(a=i.get_key_manager()),a?r(a.get_pgp_fingerprint().toString("hex")):s(Error("could not verify file"))})}})}async verifyFile(e,t,a){let r;a&&(r="string"==typeof a?s.default.readFileSync(a):a);const i=s.default.readFileSync(e),o=s.default.readFileSync(t);return await this.verifyData(i,o,r)}async signFile(e,t,a){let r;t&&(r="string"==typeof t?Buffer.from(s.default.readFileSync(t)):t);const i=Buffer.from(s.default.readFileSync(e)),o=await this.signData(i,r,a),n=e+".sig";return s.default.writeFileSync(n,o),n}async encryptData(e,t){return new Promise(async(a,r)=>{let s;try{s=await this.getIdentityFromPublicKey(t)}catch(e){throw Error("Identity could not be resolved for encrypting: "+e)}if(this.useWebWorkers&&this.workerPool){const t=await this.workerPool.queue(async t=>await t.encryptData(e,s));a(t)}else{const t={msg:e,encrypt_for:s};o.default.box(t,(e,t,s)=>{e&&r(e),a(t)})}})}async decryptData(e,t){return new Promise(async(a,r)=>{var s=new o.default.keyring.KeyRing;let i;if(t)i=await this.getIdentityFromPublicKey(t);else{if(!this.primaryIdentity)throw Error("no identity available for signing");i=this.primaryIdentity}if(this.useWebWorkers&&this.workerPool){const t=await this.workerPool.queue(async t=>await t.decryptData(e,i));a(t)}else{s.add_key_manager(i);const t={armored:e,keyfetch:s};o.default.unbox(t,(e,t)=>{e&&r(e);try{const e=Buffer.from(t[0].toString());a(e)}catch(e){r(e)}})}})}getKey(e){return this.derivedKeys[e]}isLoaded(){return!!this.derivedKeys[name]}}},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});class r{constructor(e,t){this.ip=e,this.port=t}static parse(e){const t=e.split(":"),a=t[0],s=t[1];return new r(a,s)}}t.Address=r,r.prototype.toString=function(){return`${this.ip}:${this.port}`};t.default=class{constructor(e,t=[],a){this.publicKey=e,this.addresses=new Set(t.map(e=>r.parse(e))),this.connectedAddr=a?r.parse(a):void 0}connect(e){this.addresses.has(e)||this.addresses.add(e),this.connectedAddr=e}disconnect(){this.connectedAddr=void 0}}},function(e,t,a){"use strict";(function(e){var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const s=r(a(4)),i=r(a(25)),o=r(a(10));console.log(e);t.default=class{static loadProto(t){const a=new i.default.Root;return a.resolvePath=(t,a)=>s.default.join(e,a),a.loadSync(t)}static encodePeerInfo(e){var t;const a=this.loadProto("PeerInfoMessage.proto").lookupType("peerinfopackage.PeerInfoMessage"),r=[];for(const t of e.addresses)r.push(t.toString());const s={pubKey:e.publicKey,addresses:r,connectedAddr:null===(t=e.connectedAddr)||void 0===t?void 0:t.toString()},i=a.verify(s);if(i)throw Error(i);const o=a.create(s);return a.encode(o).finish()}static decodePeerInfo(e){const t=this.loadProto("PeerInfoMessage.proto").lookupType("peerinfopackage.PeerInfoMessage"),a=t.decode(e),r=t.toObject(a,{enums:String,longs:String,bytes:String,defaults:!0,arrays:!0,objects:!0,oneofs:!0});return new o.default(r.pubKey,r.addresses,r.connectedAddr)}static encodeHandshakeMessage(e,t,a,r){const s=this.loadProto("HandshakeMessage.proto").lookupType("handshakepackage.HandshakeMessage"),i={targetPubKey:e,requestingPubKey:t,message:a,responsePeerInfo:r?this.encodePeerInfo(r):void 0},o=s.verify(i);if(o)throw Error(o);const n=s.create(i);return s.encode(n).finish()}static decodeHandshakeMessage(e){const t=this.loadProto("HandshakeMessage.proto").lookupType("handshakepackage.HandshakeMessage"),a=t.decode(e),r=t.toObject(a,{enums:String,longs:String,bytes:String,defaults:!0,arrays:!0,objects:!0,oneofs:!0});return{targetPubKey:Buffer.from(r.targetPubKey,"base64"),requestingPubKey:Buffer.from(r.requestingPubKey,"base64"),message:Buffer.from(r.message,"base64"),responsePeerInfo:r.responsePeerInfo?this.decodePeerInfo(Buffer.from(r.responsePeerInfo,"base64")):void 0}}}}).call(this,"/index.js")},function(e,t,a){"use strict";var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const s=r(a(1)),i=r(a(7)),o=a(0);t.default=function(){return new s.default.Command("config").description("configure polykey").option("-pub, --public-key ","provide the path to an existing public key").option("-priv, --private-key ","provide the path to an existing private key").option("-pass, --private-passphrase ","provide the passphrase to the private key").option("-path, --polykey-path ","provide the polykey path. defaults to ~/.polykey").option("-v, --verbose","increase verbosity by one level").action(o.actionRunner(async e=>{const t=new i.default("PolyKeyConfig");e.polykeyPath&&t.set("polykeyPath",e.polykeyPath),e.publicKeyPath&&t.set("publicKeyPath",e.publicKeyPath),e.privateKeyPath&&t.set("privateKeyPath",e.privateKeyPath),e.privatePassphrase&&t.set("privatePassphrase",e.privatePassphrase)})).addCommand(new s.default.Command("clear").description("clear the polykey config store").action(o.actionRunner(async e=>{new i.default("PolyKeyConfig").clear()}))).addCommand(new s.default.Command("list").description("list current polykey config parameters").alias("ls").action(o.actionRunner(async e=>{const t=new i.default("PolyKeyConfig");o.pkLogger("The current config parameters are:",o.PKMessageType.INFO),o.pkLogger("Polykey Path: "+t.get("polykeyPath"),o.PKMessageType.INFO),o.pkLogger("Public Key Path: "+t.get("publicKeyPath"),o.PKMessageType.INFO),o.pkLogger("Private Key Path: "+t.get("privateKeyPath"),o.PKMessageType.INFO),o.pkLogger("Private Key Passphrase: "+t.get("privatePassphrase"),o.PKMessageType.INFO)})))}},function(e,t,a){"use strict";var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const s=r(a(2)),i=r(a(1)),o=r(a(3)),n=a(0);t.default=function(){return new i.default.Command("secrets").description("manipulate secrets for a given vault").addCommand(new i.default.Command("list").description("list all available secrets for a given vault").alias("ls").requiredOption("-n, --vault-name ","the vault name").option("--verbose","increase verbosity level by one").action(n.actionRunner(async e=>{var t;const a=await o.default(),r=null!==(t=e.verbose)&&void 0!==t&&t,s=e.vaultName;try{if(!await a.vaultExists(s))throw new Error(`vault '${s}' does not exist!`);const e=(await a.getVault(s)).listSecrets();r&&n.pkLogger(`secrets contained within the ${s} vault:`,n.PKMessageType.INFO),0==e.length?n.pkLogger(`no secrets found for vault '${s}'`,n.PKMessageType.INFO):e.forEach(e=>{n.pkLogger(e,n.PKMessageType.INFO)})}catch(e){throw new Error("Error when listing secrets: "+e.message)}}))).addCommand(new i.default.Command("add").description("add a secret to a given vault").requiredOption("-n, --vault-name ","the vault name").requiredOption("-s, --secret-name ","the new secret name").requiredOption("-p, --secret-path ","path to the secret to be removed").option("--verbose","increase verbosity level by one").action(n.actionRunner(async e=>{const t=await o.default(),a=(e.verbose,e.vaultName),r=e.secretName,i=e.secretPath;try{if(!await t.vaultExists(a))throw new Error(`vault '${a}' does not exist!`);const e=await t.getVault(r);if(await e.secretExists(r))throw new Error(`secret '${r}' already exists in vault ${a}!`);const o=s.default.readFileSync(i);if(await e.addSecret(r,o),!await e.secretExists(r))throw new Error(`something went wrong, secret '${r}' was not added to vault '${a}'`);n.pkLogger(`secret '${r}' was sucessfully added to vault '${a}'`,n.PKMessageType.SUCCESS)}catch(e){throw new Error("Error when adding secret: "+e.message)}}))).addCommand(new i.default.Command("remove").description("remove a secret from a given vault").requiredOption("-n, --vault-name ","the vault name").requiredOption("-s, --secret-name ","the new secret name").option("--verbose","increase verbosity level by one").action(n.actionRunner(async e=>{const t=await o.default(),a=(e.verbose,e.vaultName),r=e.secretName;try{if(!await t.vaultExists(a))throw new Error(`vault '${a}' does not exist!`);const e=await t.getVault(r);if(await e.removeSecret(r),await e.secretExists(r))throw new Error(`something went wrong, secret '${r}' was not removed from vault '${a}'`);n.pkLogger(`secret '${r}' was sucessfully removed from vault '${a}'`,n.PKMessageType.SUCCESS)}catch(e){throw new Error("Error when removing secret: "+e.message)}})))}},function(e,t){e.exports=require("zxcvbn")},function(e,t){e.exports=require("inquirer")},function(e,t,a){"use strict";var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const s=r(a(8)),i=r(a(2)),o=r(a(4)),n=r(a(5)),u=r(a(17)),d=r(a(18)),l=r(a(9)),c=r(a(24)),p=r(a(10)),y=r(a(11)),f=r(a(26));t.default=class{constructor(e,t,a=s.default.homedir()+"/.polykey"){if(this.polykeyPath=a,this.metadataPath=o.default.join(a,"metadata"),this.fs=i.default,this.keyManager=null!=e?e:new l.default(a),this.peerDiscovery=null!=t?t:new f.default(this.peerStore,this.keyManager),this.fs.existsSync(this.polykeyPath))if(this.fs.existsSync(this.metadataPath)){const e=u.default.readFileSync(this.metadataPath);this.metadata={vaults:e.vaults,peerInfo:e.peerInfo,publicKeyPath:e.publicKeyPath,privateKeyPath:e.privateKeyPath}}else{const e=new p.default(this.keyManager.getPublicKey()),t={vaults:{},peerInfo:y.default.encodePeerInfo(e)};u.default.writeFileSync(this.metadataPath,t),this.metadata=t}else this.fs.mkdirSync(this.polykeyPath,{recursive:!0});this.peerStore=new c.default(y.default.decodePeerInfo(this.metadata.peerInfo)),this.peerDiscovery=new f.default(this.peerStore,this.keyManager),this.vaults=new Map;for(const e in this.metadata.vaults)if(this.metadata.vaults.hasOwnProperty(e)){const t=o.default.join(this.polykeyPath,e);if(this.fs.existsSync(t)){const t=Buffer.from(this.metadata.vaults[e].key),a=new d.default(e,t,this.polykeyPath);this.vaults.set(e,a)}}}async getVault(e){if(this.vaults.has(e)){const t=this.vaults.get(e);if(t)return t}await this.validateVault(e);const t=this.metadata.vaults[e].key,a=new d.default(e,t,this.polykeyPath);return this.vaults.set(e,a),a}async createVault(e,t){const a=o.default.join(this.polykeyPath,e);let r;if(r=this.fs.existsSync(a),r)throw Error("Vault already exists!");try{let r;this.fs.mkdirSync(a,{recursive:!0}),r=t||n.default.randomBytes(16),this.metadata.vaults[e]={key:r,tags:[]},await this.writeMetadata();const s=new d.default(e,r,this.polykeyPath);return this.vaults.set(e,s),await this.getVault(e)}catch(t){throw await this.destroyVault(e),t}}async vaultExists(e){const t=o.default.join(this.polykeyPath,e);return this.fs.existsSync(t)}async destroyVault(e){const t=o.default.join(this.polykeyPath,e);if(this.fs.existsSync(t)&&this.fs.rmdirSync(t,{recursive:!0}),this.vaults.has(e)&&this.vaults.delete(e),this.metadata.vaults.hasOwnProperty(e)&&(delete this.metadata.vaults[e],await this.writeMetadata()),this.fs.existsSync(t))throw new Error("Vault path could not be destroyed!");if(this.vaults.has(e))throw new Error("Vault could not be removed from PolyKey!");if(this.metadata.vaults.hasOwnProperty(e))throw new Error("Vault metadata could not be destroyed!")}async validateVault(e){if(!this.metadata.vaults.hasOwnProperty(e))throw Error("Vault metadata does not exist");const t=o.default.join(this.polykeyPath,e);if(!this.fs.existsSync(t))throw Error("Vault directory does not exist")}listVaults(){return Array.from(this.vaults.keys())}tagVault(){}untagVault(){}shareVault(){}unshareVault(){}async writeMetadata(){try{await u.default.writeFile(this.metadataPath,this.metadata)}catch(e){throw Error("Error writing vault key to config file")}}}},function(e,t){e.exports=require("jsonfile")},function(e,t,a){"use strict";var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const s=r(a(2)),i=r(a(4)),o=r(a(19)),n=a(20);t.default=class{constructor(e,t,r){this.keyLen=32,this.key=this.genSymKey(t,this.keyLen);const o=new(a(21).VirtualFS);this.fs=new n.EncryptedFS(t,o,o,s.default,process),this.name=e,this.vaultPath=i.default.join(r,e),this.fs.mkdirSync(this.vaultPath,{recursive:!0}),this.secrets=new Map,this.loadSecrets()}loadSecrets(){const e=s.default.readdirSync(this.vaultPath,void 0);for(const t of e)this.secrets.set(t,null)}genSymKey(e,t){return Buffer.from(o.default(e.toString(),t))}secretExists(e){const t=i.default.join(this.vaultPath,e);return this.secrets.has(e)&&this.fs.existsSync(t)}addSecret(e,t){const a=i.default.join(this.vaultPath,e),r=this.fs.openSync(a,"w");this.fs.writeSync(r,t,0,t.length,0),this.secrets.set(e,t)}getSecret(e){if(this.secrets.has(e)){const t=this.secrets.get(e);if(t)return t;{const t=i.default.join(this.vaultPath,e),a=this.fs.readFileSync(t,{});return this.secrets.set(e,a),a}}throw Error("Secret: "+e+" does not exist")}removeSecret(e){if(this.secrets.has(e)){if(this.secrets.delete(e))return;throw Error("Secret: "+e+" was not removed")}throw Error("Secret: "+e+" does not exist")}listSecrets(){return Array.from(this.secrets.keys())}tagVault(){}untagVault(){}shareVault(){}unshareVault(){}}},function(e,t){e.exports=require("futoin-hkdf")},function(e,t){e.exports=require("encryptedfs")},function(e,t){e.exports=require("virtualfs")},function(e,t){e.exports=require("kbpgp")},function(e,t){e.exports=require("util")},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.default=class{constructor(e){this.localPeerInfo=e,this.peers=new Map}put(e){this.has(e.publicKey)?this.update(e):this.add(e)}add(e){this.peers.set(e.publicKey,e)}update(e){this.peers.set(e.publicKey,e)}get(e){var t;return null!==(t=this.peers.get(e))&&void 0!==t?t:null}has(e){return this.peers.has(e)}}},function(e,t){e.exports=require("protobufjs")},function(e,t,a){"use strict";var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const s=r(a(27)),i=r(a(28)),o=a(31),n={name:"Keybase",findUser:async(e,t)=>{const a=`https://keybase.io/_/api/1.0/user/lookup.json?${t}=${e}`;try{const e=await s.default(a);return(await e.json()).them[0].public_keys.primary.bundle}catch(e){throw new Error("User was not found: "+e.message)}}};t.default=class{constructor(e,t,a=[]){this.peerStore=e,this.keyManager=t,this.socialDiscoveryServices=a,this.socialDiscoveryServices=[],this.socialDiscoveryServices.push(n);for(const e of a)this.socialDiscoveryServices.push(e);this.multicastBroadcaster=new i.default(this.peerStore,this.keyManager)}async findPubKey(e){return new Promise((t,a)=>{this.multicastBroadcaster.requestPeerContact(e),this.multicastBroadcaster.on("found",a=>{a.publicKey==e&&t(a)}),this.multicastBroadcaster.on("timeout",t=>{t==e&&a("The broadcaster stopped looking")})})}async findSocialUser(e,t){const a=[];for(const r of this.socialDiscoveryServices)try{a.push(r.findUser(e,t))}catch(e){console.log("Could not find user on this discovery service: "+r.name)}const r=await o.firstPromiseFulfilled(a);if(r.length>1)throw new Error("Could not find public key from services");const s=r[0];return await this.findPubKey(s)}}},function(e,t){e.exports=require("node-fetch")},function(e,t,a){"use strict";var r,s,i=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const o=i(a(29)),n=i(a(5)),u=a(30),d=i(a(11)),l=parseInt(null!==(r=process.env.UDP_MULTICAST_PORT)&&void 0!==r?r:"5353"),c=null!==(s=process.env.UDP_MULTICAST_ADDR)&&void 0!==s?s:"224.0.0.251";class p extends u.EventEmitter{constructor(e,t){super(),this.peerPubKeyMessages=new Map,this.peerStore=e,this.keyManager=t,this.interval=1e3,this.queryInterval=null,this.socket=o.default.createSocket({type:"udp4",reuseAddr:!0}),this.socket.bind(l),this.socket.on("listening",(()=>{this.socket.addMembership(c);const e=this.socket.address();console.log(`UDP socket listening on ${e.address}:${e.port} pid: ${process.pid}`)}).bind(this)),this.socket.on("message",this.handleHandshakeMessages.bind(this)),this.queryInterval=this.queryLAN()}queryLAN(){const e=()=>{for(const e of this.peerPubKeyMessages.keys()){const t=this.peerPubKeyMessages.get(e);if(t){const e=d.default.encodeHandshakeMessage(t.encryptedPeerPubKey,t.encryptedLocalPubKey,t.encryptedRandomMessage);this.socket.send(e,0,e.length,l,c,()=>{console.info("Sending message to peer")})}}};return e(),setInterval(e,this.interval)}async handleHandshakeMessages(e,t){var a;try{const r=d.default.decodeHandshakeMessage(e);console.info(`Message from: ${t.address}:${t.port}`);const s=await this.keyManager.decryptData(r.message.toString()),i=await this.keyManager.decryptData(r.targetPubKey.toString()),o=await this.keyManager.decryptData(r.requestingPubKey.toString()),n=this.keyManager.getPublicKey();if(o.toString()==n){const e=null===(a=this.peerPubKeyMessages.get(i.toString()))||void 0===a?void 0:a.rawRandomMessage;if(s.toString()==(null==e?void 0:e.toString())){const e=r.responsePeerInfo;if(e){this.peerStore.add(e);const t=e.publicKey;this.peerPubKeyMessages.delete(t),console.log("New peer added to the store"),this.emit("found",e)}else this.emit("error","I got a validated response. But no peerInfo")}}else{const e=await this.keyManager.encryptData(Buffer.from(n),o),t=await this.keyManager.encryptData(s,o),a=await this.keyManager.encryptData(o,o),r=d.default.encodeHandshakeMessage(Buffer.from(e),Buffer.from(a),Buffer.from(t),this.peerStore.localPeerInfo);this.socket.send(r,0,r.length,l,c)}}catch(e){}}async requestPeerContact(e){const t=Buffer.from(e),a=n.default.randomBytes(16),r=await this.keyManager.encryptData(t,t),s=await this.keyManager.encryptData(a,t),i=await this.keyManager.encryptData(Buffer.from(this.keyManager.getPublicKey()),t);this.peerPubKeyMessages.set(e,{encryptedLocalPubKey:Buffer.from(i),encryptedPeerPubKey:Buffer.from(r),rawRandomMessage:a,encryptedRandomMessage:Buffer.from(s)})}}t.default=p},function(e,t){e.exports=require("dgram")},function(e,t){e.exports=require("events")},function(e,t,a){"use strict";function r(e){return new Promise((t,a)=>e.then(a,t))}Object.defineProperty(t,"__esModule",{value:!0}),t.randomString=function(){return Math.random().toString(36).replace(/[^a-z]+/g,"").substr(0,5)},t.firstPromiseFulfilled=function(e){return r(Promise.all(e.map(r)))}},function(e,t){e.exports=require("cli-progress")},function(e,t){e.exports=require("inquirer-fuzzy-path")},function(e,t,a){"use strict";var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const s=r(a(1)),i=r(a(3)),o=a(0);t.default=function(){return new s.default.Command("keymanager").alias("km").description("manipulate the keymanager").addCommand(new s.default.Command("derive").description("manipulate the keymanager").requiredOption("-n, --key-name ","the name of the new key").requiredOption("-p, --key-passphrase ","the passphrase for the new key").action(o.actionRunner(async e=>{const t=e.keyName,a=e.keyPassphrase;(await i.default()).keyManager.generateKeySync(a,t),o.pkLogger(`'${t}' was added to the Key Manager`,o.PKMessageType.SUCCESS)})))}},function(e,t,a){"use strict";var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const s=r(a(1)),i=a(0);t.default=function(){return new s.default.Command("node").description("control the current polykey node").addCommand(new s.default.Command("start").description("start the polykey node").action(i.actionRunner(async e=>{}))).addCommand(new s.default.Command("stop").description("stop the polykey node").action(i.actionRunner(async e=>{})))}},function(e,t,a){"use strict";var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const s=r(a(1)),i=r(a(3)),o=a(0);t.default=function(){return new s.default.Command("crypto").description("crypto operations").addCommand(new s.default.Command("verify").description("verification operations").option("-k, --verifying-key ","path to public key that will be used to verify files").option("-s, --detach-sig ","path to detached signature for file").arguments("file to be verified").action(o.actionRunner(async e=>{const t=await i.default(),a=e.verifyingKey,r=e.detachedSignature,s=Array.from(e.args.values());if(s.length<1)throw new Error("no file provided");const n=s[0];if(void 0===r)throw new Error("no signature provided");try{const e=await t.keyManager.verifyFile(n,r,a);o.pkLogger(`file '${n}' successfully verified. PGP fingerprint: ${e}`,o.PKMessageType.SUCCESS)}catch(e){throw new Error(`failed to sign '${n}': ${e.message}`)}}))).addCommand(new s.default.Command("sign").description("signing operations").option("-k, --signing-key ","path to private key that will be used to sign files").option("-p, --key-passphrase ","passphrase to unlock the provided signing key").arguments("file(s) to be signed").action(async e=>{const t=await i.default(),a=e.signingKey,r=e.keyPassphrase,s=e.args.values();for(const e of s)try{const s=await t.keyManager.signFile(e,a,r);o.pkLogger(`file '${e}' successfully signed at '${s}'`,o.PKMessageType.SUCCESS)}catch(t){throw new Error(`failed to sign '${e}': ${t}`)}}))}},function(e,t,a){"use strict";var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const s=r(a(6)),i=r(a(1)),o=r(a(3)),n=a(0);t.default=function(){return new i.default.Command("vaults").description("manipulate vaults").addCommand(new i.default.Command("list").description("list all available vaults").alias("ls").option("-v, --verbose","increase verbosity level by one").action(n.actionRunner(async e=>{const t=await o.default();e.verbose&&n.pkLogger("vaults contained within polykey:",n.PKMessageType.INFO);const a=t.listVaults();void 0===a||0==a.length?n.pkLogger("no vaults found",n.PKMessageType.INFO):a.forEach(e=>{n.pkLogger(e,n.PKMessageType.INFO)})}))).addCommand(new i.default.Command("add").description("create new vault(s)").arguments("vault name(s)").action(n.actionRunner(async e=>{const t=await o.default(),a=e.args.values();for(const e of a)await t.createVault(e),n.pkLogger(`vault created at ${t.polykeyPath}/${e}`,n.PKMessageType.SUCCESS)}))).addCommand(new i.default.Command("remove").description("destroy an existing vault").option("-n, --vault-name ","name of vault").option("-a, --all","remove all vaults").option("-v, --verbose","increase verbosity by one level").action(n.actionRunner(async e=>{var t,a;const r=await o.default(),i=null!==(t=e.verbose)&&void 0!==t&&t;if(null!==(a=e.all)&&void 0!==a&&a){const e=r.listVaults();if(void 0===e||0==e.length)n.pkLogger("no vaults found",n.PKMessageType.INFO);else{for(const t of e)await r.destroyVault(t),i&&n.pkLogger("destroyed "+t,n.PKMessageType.SUCCESS);n.pkLogger("all vaults destroyed successfully",n.PKMessageType.SUCCESS)}return}const u=e.vaultName;if(!u)throw new Error(s.default.red("error: did not receive vault name"));if(!await r.vaultExists(u))throw new Error(`vault '${u}' does not exist`);await r.destroyVault(u),n.pkLogger(`vault '${u}' destroyed ${await r.vaultExists(u)?"un-":""}successfully`,n.PKMessageType.SUCCESS)})))}},function(e){e.exports=JSON.parse('{"name":"polykey","bin":"bin/pk.js","version":"0.0.1","author":"Roger Qiu","description":"Polykey Core Library","keywords":["secrets"],"contributors":["Aaashwin Varshney","Robert Cronin"],"license":"Apache-2.0","repository":{"type":"git","url":"https://github.com/MatrixAI/js-polykey.git"},"main":"dist/polykey.js","types":"dist/index.d.ts","module":"dist/polykey.js","scripts":{"develop":"webpack --mode=development --watch & webpack-dev-server --mode=development & wait","build":"webpack --mode=\'production\'","build:types":"tsc src/lib/*.ts -d --declarationDir dist/ --declarationMap --emitDeclarationOnly","test":"jest"},"jest":{"verbose":true},"engines":{"node":">=12.14.0"},"dependencies":{"@grpc/grpc-js":"^1.0.5","@grpc/proto-loader":"^0.5.4","@types/commander":"^2.12.2","@types/configstore":"^4.0.0","@types/inquirer":"^6.5.0","chalk":"^4.0.0","cli-progress":"^3.8.2","commander":"^5.1.0","configstore":"^5.0.1","encryptedfs":"^0.1.0","fs-extra":"^9.0.0","futoin-hkdf":"^1.3.2","inquirer":"^7.1.0","inquirer-fuzzy-path":"^2.3.0","isomorphic-git":"^0.35.1","jsonfile":"^6.0.1","kbpgp":"^2.0.82","moniker":"^0.1.2","node-fetch":"^2.6.0","threads":"^1.6.0","virtualfs":"^2.2.0","zxcvbn":"^4.4.2"},"devDependencies":{"@types/jest":"^25.0.0","@types/node":"^13.13.1","copy-webpack-plugin":"^6.0.2","documentation":"^8.1.2","file-loader":"^6.0.0","jest":"^25.0.0","threads-plugin":"^1.3.1","ts-jest":"^25.0.0","ts-loader":"^6.2.2","ts-node":"^8.8.2","tsconfig-paths":"^3.9.0","tsconfig-paths-webpack-plugin":"^3.2.0","typescript":"^3.8.3","webpack":"^4.42.1","webpack-cli":"^3.3.11","webpack-node-externals":"^1.7.2"},"bugs":{"url":"https://github.com/MatrixAI/js-polykey/issues"},"homepage":"https://github.com/MatrixAI/js-polykey#readme"}')}])})); \ No newline at end of file diff --git a/dist/cli/Config.d.ts b/dist/cli/Config.d.ts new file mode 100644 index 000000000..3280a6611 --- /dev/null +++ b/dist/cli/Config.d.ts @@ -0,0 +1,3 @@ +import commander from 'commander'; +declare function makeConfigCommand(): commander.Command; +export default makeConfigCommand; diff --git a/dist/cli/Crypto.d.ts b/dist/cli/Crypto.d.ts new file mode 100644 index 000000000..bc3d6bef8 --- /dev/null +++ b/dist/cli/Crypto.d.ts @@ -0,0 +1,3 @@ +import commander from 'commander'; +declare function makeCryptoCommand(): commander.Command; +export default makeCryptoCommand; diff --git a/dist/cli/KeyManager.d.ts b/dist/cli/KeyManager.d.ts new file mode 100644 index 000000000..86ffb223d --- /dev/null +++ b/dist/cli/KeyManager.d.ts @@ -0,0 +1,3 @@ +import commander from 'commander'; +declare function makeKeyManagerCommand(): commander.Command; +export default makeKeyManagerCommand; diff --git a/dist/cli/Node.d.ts b/dist/cli/Node.d.ts new file mode 100644 index 000000000..3a7bd3a7c --- /dev/null +++ b/dist/cli/Node.d.ts @@ -0,0 +1,3 @@ +import commander from 'commander'; +declare function makeNodeCommand(): commander.Command; +export default makeNodeCommand; diff --git a/dist/cli/Secrets.d.ts b/dist/cli/Secrets.d.ts new file mode 100644 index 000000000..f68a20046 --- /dev/null +++ b/dist/cli/Secrets.d.ts @@ -0,0 +1,3 @@ +import commander from 'commander'; +declare function makeSecretsCommand(): commander.Command; +export default makeSecretsCommand; diff --git a/dist/cli/Vaults.d.ts b/dist/cli/Vaults.d.ts new file mode 100644 index 000000000..716bbf8cd --- /dev/null +++ b/dist/cli/Vaults.d.ts @@ -0,0 +1,3 @@ +import commander from 'commander'; +declare function makeVaultsCommand(): commander.Command; +export default makeVaultsCommand; diff --git a/dist/cli/initPolykey.d.ts b/dist/cli/initPolykey.d.ts new file mode 100644 index 000000000..181d728d4 --- /dev/null +++ b/dist/cli/initPolykey.d.ts @@ -0,0 +1,4 @@ +import PolyKey from '../lib/Polykey'; +/*******************************************/ +declare function initPolyKey(): Promise; +export default initPolyKey; diff --git a/dist/cli/polykey.d.ts b/dist/cli/polykey.d.ts new file mode 100644 index 000000000..906fe456d --- /dev/null +++ b/dist/cli/polykey.d.ts @@ -0,0 +1,9 @@ +declare function actionRunner(fn: (...args: any[]) => Promise): (...args: any[]) => Promise; +/*******************************************/ +declare enum PKMessageType { + SUCCESS = 0, + INFO = 1, + WARNING = 2 +} +declare function pkLogger(message: string, type?: PKMessageType): void; +export { actionRunner, PKMessageType, pkLogger }; diff --git a/dist/index.browser.umd.js b/dist/index.browser.umd.js deleted file mode 100644 index 7ae3f2270..000000000 --- a/dist/index.browser.umd.js +++ /dev/null @@ -1,130 +0,0 @@ -(function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : - typeof define === 'function' && define.amd ? define(['exports'], factory) : - (factory((global.virtualfs = {}))); -}(this, (function (exports) { 'use strict'; - - function _classCallCheck(instance, Constructor) { - if (!(instance instanceof Constructor)) { - throw new TypeError("Cannot call a class as a function"); - } - } - - var classCallCheck = _classCallCheck; - - function _defineProperties(target, props) { - for (var i = 0; i < props.length; i++) { - var descriptor = props[i]; - descriptor.enumerable = descriptor.enumerable || false; - descriptor.configurable = true; - if ("value" in descriptor) descriptor.writable = true; - Object.defineProperty(target, descriptor.key, descriptor); - } - } - - function _createClass(Constructor, protoProps, staticProps) { - if (protoProps) _defineProperties(Constructor.prototype, protoProps); - if (staticProps) _defineProperties(Constructor, staticProps); - return Constructor; - } - - var createClass = _createClass; - - function _defineProperty(obj, key, value) { - if (key in obj) { - Object.defineProperty(obj, key, { - value: value, - enumerable: true, - configurable: true, - writable: true - }); - } else { - obj[key] = value; - } - - return obj; - } - - var defineProperty = _defineProperty; - - var FirstThing = - /*#__PURE__*/ - function () { - function FirstThing() { - classCallCheck(this, FirstThing); - - defineProperty(this, "_private", void 0); - - this._private = 1; - } - - createClass(FirstThing, [{ - key: "getIt", - value: function getIt() { - return this._private; - } - }]); - - return FirstThing; - }(); - - var Library = - /*#__PURE__*/ - function () { - function Library() { - classCallCheck(this, Library); - - defineProperty(this, "_private", void 0); - - defineProperty(this, "_firstThing", void 0); - - this._private = 1; - this._firstThing = new FirstThing(); - } - - createClass(Library, [{ - key: "getOne", - value: function getOne() { - return this._private; - } - }, { - key: "getFirst", - value: function getFirst() { - this._firstThing.getIt(); - } - }]); - - return Library; - }(); - - var Another = - /*#__PURE__*/ - function () { - function Another() { - classCallCheck(this, Another); - } - - createClass(Another, [{ - key: "doWhatever", - value: function doWhatever() { - console.log('hello!'); - } - }]); - - return Another; - }(); - - var SOME_CONST = 1; - - function addOne(num) { - return num + 1; - } - - exports.default = Library; - exports.Another = Another; - exports.SOME_CONST = SOME_CONST; - exports.addOne = addOne; - - Object.defineProperty(exports, '__esModule', { value: true }); - -}))); diff --git a/dist/index.js b/dist/index.js deleted file mode 100644 index a058c48ea..000000000 --- a/dist/index.js +++ /dev/null @@ -1,5 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var Polykey_1 = require("@polykey/Polykey"); -exports.default = Polykey_1.default; -//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/dist/index.js.map b/dist/index.js.map deleted file mode 100644 index d5fa82ff5..000000000 --- a/dist/index.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;AAAA,4CAA0C;AAAjC,4BAAA,OAAO,CAAA"} \ No newline at end of file diff --git a/dist/index.node.cjs.js b/dist/index.node.cjs.js deleted file mode 100644 index 43fa218b2..000000000 --- a/dist/index.node.cjs.js +++ /dev/null @@ -1,58 +0,0 @@ -'use strict'; - -Object.defineProperty(exports, '__esModule', { value: true }); - -function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } - -var _defineProperty = _interopDefault(require('@babel/runtime/helpers/defineProperty')); - -class FirstThing { - constructor() { - _defineProperty(this, "_private", void 0); - - this._private = 1; - } - - getIt() { - return this._private; - } - -} - -class Library { - constructor() { - _defineProperty(this, "_private", void 0); - - _defineProperty(this, "_firstThing", void 0); - - this._private = 1; - this._firstThing = new FirstThing(); - } - - getOne() { - return this._private; - } - - getFirst() { - this._firstThing.getIt(); - } - -} - -class Another { - doWhatever() { - console.log('hello!'); - } - -} - -const SOME_CONST = 1; - -function addOne(num) { - return num + 1; -} - -exports.default = Library; -exports.Another = Another; -exports.SOME_CONST = SOME_CONST; -exports.addOne = addOne; diff --git a/dist/index.node.es.js b/dist/index.node.es.js deleted file mode 100644 index d03662ec7..000000000 --- a/dist/index.node.es.js +++ /dev/null @@ -1,50 +0,0 @@ -import _defineProperty from '@babel/runtime/helpers/defineProperty'; - -class FirstThing { - constructor() { - _defineProperty(this, "_private", void 0); - - this._private = 1; - } - - getIt() { - return this._private; - } - -} - -class Library { - constructor() { - _defineProperty(this, "_private", void 0); - - _defineProperty(this, "_firstThing", void 0); - - this._private = 1; - this._firstThing = new FirstThing(); - } - - getOne() { - return this._private; - } - - getFirst() { - this._firstThing.getIt(); - } - -} - -class Another { - doWhatever() { - console.log('hello!'); - } - -} - -const SOME_CONST = 1; - -function addOne(num) { - return num + 1; -} - -export default Library; -export { Another, SOME_CONST, addOne }; diff --git a/dist/lib/KeyManager.d.ts b/dist/lib/KeyManager.d.ts new file mode 100644 index 000000000..52cad4920 --- /dev/null +++ b/dist/lib/KeyManager.d.ts @@ -0,0 +1,46 @@ +/// +import { Pool, ModuleThread } from 'threads'; +import { KeyManagerWorker } from '@polykey/KeyManagerWorker'; +declare type KeyPair = { + private: string; + public: string; + passphrase: string; +}; +declare class KeyManager { + private primaryKeyPair; + private primaryPassphrase?; + private primaryIdentity?; + private derivedKeys; + private useWebWorkers; + private workerPool?; + storePath: string; + constructor(polyKeyPath?: string, useWebWorkers?: boolean, workerPool?: Pool>); + generateKeyPair(name: string, email: string, passphrase: string, replacePrimary?: boolean, progressCallback?: (info: any) => void): Promise; + getKeyPair(): KeyPair; + getPublicKey(): string; + getPrivateKey(): string; + loadPrivateKey(privateKey: string | Buffer, passphrase?: string): Promise; + loadPublicKey(publicKey: string | Buffer): Promise; + loadIdentity(passphrase: string): Promise; + loadKeyPair(publicKey: string | Buffer, privateKey: string | Buffer, passphrase?: string): Promise; + exportPrivateKey(path: string): Promise; + exportPublicKey(path: string): Promise; + generateKeySync(name: string, passphrase: string): Buffer; + generateKey(name: string, passphrase: string): Promise; + importKeySync(name: string, key: string | Buffer): void; + importKey(name: string, key: string | Buffer): Promise; + exportKey(name: string, path: string, createPath?: boolean): Promise; + exportKeySync(path: string, createPath?: boolean): void; + getIdentityFromPublicKey(pubKey: Buffer): Promise; + getIdentityFromPrivateKey(privKey: Buffer, passphrase: string): Promise; + signData(data: Buffer | string, withKey?: Buffer, keyPassphrase?: string): Promise; + verifyData(data: Buffer | string, signature: Buffer, withKey?: Buffer): Promise; + verifyFile(filePath: string, signaturePath: string, publicKey?: string | Buffer): Promise; + signFile(path: string, privateKey?: string | Buffer, privateKeyPassphrase?: string): Promise; + encryptData(data: Buffer, forPubKey: Buffer): Promise; + decryptData(data: string, withKey?: Buffer): Promise; + getKey(name: string): Buffer; + isLoaded(): boolean; +} +export default KeyManager; +export { KeyPair }; diff --git a/dist/lib/KeyManagerWorker.d.ts b/dist/lib/KeyManagerWorker.d.ts new file mode 100644 index 000000000..bd08895e8 --- /dev/null +++ b/dist/lib/KeyManagerWorker.d.ts @@ -0,0 +1,9 @@ +/// +declare const keyManagerWorker: { + signData(data: string | Buffer, identity: any): Promise; + verifyData(data: string | Buffer, signature: Buffer, identity: any): Promise; + encryptData(data: Buffer, identity: any): Promise; + decryptData(data: string, identity: any): Promise; +}; +export declare type KeyManagerWorker = typeof keyManagerWorker; +export {}; diff --git a/dist/lib/P2P/MulticastBroadcaster.d.ts b/dist/lib/P2P/MulticastBroadcaster.d.ts new file mode 100644 index 000000000..5ee6966c7 --- /dev/null +++ b/dist/lib/P2P/MulticastBroadcaster.d.ts @@ -0,0 +1,24 @@ +/// +import dgram from 'dgram'; +import { EventEmitter } from 'events'; +import KeyManager from '@polykey/KeyManager'; +import PeerStore from '@polykey/PeerStore/PeerStore'; +declare type PeerMessage = { + encryptedLocalPubKey: Buffer; + encryptedPeerPubKey: Buffer; + rawRandomMessage: Buffer; + encryptedRandomMessage: Buffer; +}; +declare class MulticastBroadcaster extends EventEmitter { + peerStore: PeerStore; + keyManager: KeyManager; + socket: dgram.Socket; + interval: number; + queryInterval: NodeJS.Timeout | null; + peerPubKeyMessages: Map; + constructor(peerStore: PeerStore, keyManager: KeyManager); + queryLAN(): NodeJS.Timeout; + private handleHandshakeMessages; + requestPeerContact(pubKey: string): Promise; +} +export default MulticastBroadcaster; diff --git a/dist/lib/P2P/PeerDiscovery.d.ts b/dist/lib/P2P/PeerDiscovery.d.ts new file mode 100644 index 000000000..7187e06ce --- /dev/null +++ b/dist/lib/P2P/PeerDiscovery.d.ts @@ -0,0 +1,19 @@ +import KeyManager from "@polykey/KeyManager"; +import PeerInfo from "@polykey/PeerStore/PeerInfo"; +import PeerStore from "@polykey/PeerStore/PeerStore"; +import MulticastBroadcaster from "@polykey/P2P/MulticastBroadcaster"; +interface SocialDiscovery { + name: string; + findUser(handle: string, service: string): Promise; +} +declare class PeerDiscovery { + peerStore: PeerStore; + keyManager: KeyManager; + multicastBroadcaster: MulticastBroadcaster; + private socialDiscoveryServices; + constructor(peerStore: PeerStore, keyManager: KeyManager, socialDiscoveryServices?: SocialDiscovery[]); + findPubKey(pubKey: string): Promise; + findSocialUser(handle: string, service: string): Promise; +} +export default PeerDiscovery; +export { SocialDiscovery }; diff --git a/dist/lib/PeerStore/PeerInfo.d.ts b/dist/lib/PeerStore/PeerInfo.d.ts new file mode 100644 index 000000000..5f6d47217 --- /dev/null +++ b/dist/lib/PeerStore/PeerInfo.d.ts @@ -0,0 +1,16 @@ +declare class Address { + ip: string; + port: string; + constructor(ip: string, port: string); + static parse(addr: string): Address; +} +declare class PeerInfo { + publicKey: string; + addresses: Set
; + connectedAddr?: Address; + constructor(pubKey: string, addresses?: string[], connectedAddr?: string); + connect(address: Address): void; + disconnect(): void; +} +export default PeerInfo; +export { Address }; diff --git a/dist/lib/PeerStore/PeerStore.d.ts b/dist/lib/PeerStore/PeerStore.d.ts new file mode 100644 index 000000000..21e27354e --- /dev/null +++ b/dist/lib/PeerStore/PeerStore.d.ts @@ -0,0 +1,31 @@ +import PeerInfo from "@polykey/PeerStore/PeerInfo"; +/** + * Responsible for managing known peers, as well as their addresses and metadata + */ +declare class PeerStore { + localPeerInfo: PeerInfo; + peers: Map; + constructor(peerInfo: PeerInfo); + /** + * Stores the peerInfo of a new peer. + * If already exist, its info is updated. + */ + put(peerInfo: PeerInfo): void; + /** + * Add a new peer to the store. + */ + add(peerInfo: PeerInfo): void; + /** + * Updates an already known peer. + */ + update(peerInfo: PeerInfo): void; + /** + * Get the info to the given id. + */ + get(pubKey: string): PeerInfo | null; + /** + * Has the info to the given id. + */ + has(pubKey: string): boolean; +} +export default PeerStore; diff --git a/dist/lib/Polykey.d.ts b/dist/lib/Polykey.d.ts new file mode 100644 index 000000000..5c2fa9e86 --- /dev/null +++ b/dist/lib/Polykey.d.ts @@ -0,0 +1,28 @@ +/// +import Vault from '@polykey/Vault'; +import KeyManager from '@polykey/KeyManager'; +import PeerStore from '@polykey/PeerStore/PeerStore'; +import PeerDiscovery from '@polykey/P2P/PeerDiscovery'; +declare class Polykey { + polykeyPath: string; + private fs; + private vaults; + private metadata; + private metadataPath; + keyManager: KeyManager; + peerStore: PeerStore; + peerDiscovery: PeerDiscovery; + constructor(keyManager?: KeyManager, peerDiscovery?: PeerDiscovery, polykeyPath?: string); + getVault(vaultName: string): Promise; + createVault(vaultName: string, key?: Buffer): Promise; + vaultExists(vaultName: string): Promise; + destroyVault(vaultName: string): Promise; + private validateVault; + listVaults(): string[]; + tagVault(): void; + untagVault(): void; + shareVault(): void; + unshareVault(): void; + private writeMetadata; +} +export default Polykey; diff --git a/dist/lib/RPC/RPCMessage.d.ts b/dist/lib/RPC/RPCMessage.d.ts new file mode 100644 index 000000000..3dd4b07fe --- /dev/null +++ b/dist/lib/RPC/RPCMessage.d.ts @@ -0,0 +1,17 @@ +/// +import { Root } from 'protobufjs'; +import PeerInfo from '@polykey/PeerStore/PeerInfo'; +declare type HandshakeMessage = { + targetPubKey: Buffer; + requestingPubKey: Buffer; + message: Buffer; + responsePeerInfo?: PeerInfo; +}; +declare class RPCMessage { + static loadProto(name: string): Root; + static encodePeerInfo(peerInfo: PeerInfo): Uint8Array; + static decodePeerInfo(buffer: Uint8Array): PeerInfo; + static encodeHandshakeMessage(targetPubKey: Buffer, requestingPubKey: Buffer, messageBuf: Buffer, responsePeerInfo?: PeerInfo): Uint8Array; + static decodeHandshakeMessage(buffer: Uint8Array): HandshakeMessage; +} +export default RPCMessage; diff --git a/dist/lib/Vault.d.ts b/dist/lib/Vault.d.ts new file mode 100644 index 000000000..4d494cea6 --- /dev/null +++ b/dist/lib/Vault.d.ts @@ -0,0 +1,22 @@ +/// +declare class Vault { + private key; + private keyLen; + name: string; + private fs; + private secrets; + private vaultPath; + constructor(name: string, symKey: Buffer, baseDir: string); + loadSecrets(): void; + genSymKey(asymKey: Buffer, keyLen: number): Buffer; + secretExists(secretName: string): boolean; + addSecret(secretName: string, secretBuf: Buffer): void; + getSecret(secretName: string): Buffer | string; + removeSecret(secretName: string): void; + listSecrets(): string[]; + tagVault(): void; + untagVault(): void; + shareVault(): void; + unshareVault(): void; +} +export default Vault; diff --git a/dist/lib/index.d.ts b/dist/lib/index.d.ts new file mode 100644 index 000000000..f58d6f4b1 --- /dev/null +++ b/dist/lib/index.d.ts @@ -0,0 +1 @@ +export { default } from '@polykey/Polykey'; diff --git a/dist/lib/utils.d.ts b/dist/lib/utils.d.ts new file mode 100644 index 000000000..14be7438f --- /dev/null +++ b/dist/lib/utils.d.ts @@ -0,0 +1,3 @@ +declare function randomString(): string; +declare function firstPromiseFulfilled(ps: Promise[]): Promise; +export { randomString, firstPromiseFulfilled }; diff --git a/dist/polykey.js b/dist/polykey.js index 18613a9d0..2df67f6e6 100644 --- a/dist/polykey.js +++ b/dist/polykey.js @@ -1,9 +1,2 @@ -!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.polykey=e():t.polykey=e()}(this,(function(){return function(t){var e={};function r(n){if(e[n])return e[n].exports;var i=e[n]={i:n,l:!1,exports:{}};return t[n].call(i.exports,i,i.exports,r),i.l=!0,i.exports}return r.m=t,r.c=e,r.d=function(t,e,n){r.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:n})},r.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},r.t=function(t,e){if(1&e&&(t=r(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var i in t)r.d(n,i,function(e){return t[e]}.bind(null,i));return n},r.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return r.d(e,"a",e),e},r.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},r.p="",r(r.s=5)}([function(t,e,r){"use strict";(function(t){ -/*! - * The buffer module from node.js, for the browser. - * - * @author Feross Aboukhadijeh - * @license MIT - */ -var n=r(8),i=r(9),o=r(10);function s(){return u.TYPED_ARRAY_SUPPORT?2147483647:1073741823}function a(t,e){if(s()=s())throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+s().toString(16)+" bytes");return 0|t}function y(t,e){if(u.isBuffer(t))return t.length;if("undefined"!=typeof ArrayBuffer&&"function"==typeof ArrayBuffer.isView&&(ArrayBuffer.isView(t)||t instanceof ArrayBuffer))return t.byteLength;"string"!=typeof t&&(t=""+t);var r=t.length;if(0===r)return 0;for(var n=!1;;)switch(e){case"ascii":case"latin1":case"binary":return r;case"utf8":case"utf-8":case void 0:return V(t).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*r;case"hex":return r>>>1;case"base64":return N(t).length;default:if(n)return V(t).length;e=(""+e).toLowerCase(),n=!0}}function d(t,e,r){var n=!1;if((void 0===e||e<0)&&(e=0),e>this.length)return"";if((void 0===r||r>this.length)&&(r=this.length),r<=0)return"";if((r>>>=0)<=(e>>>=0))return"";for(t||(t="utf8");;)switch(t){case"hex":return x(this,e,r);case"utf8":case"utf-8":return R(this,e,r);case"ascii":return T(this,e,r);case"latin1":case"binary":return k(this,e,r);case"base64":return A(this,e,r);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return D(this,e,r);default:if(n)throw new TypeError("Unknown encoding: "+t);t=(t+"").toLowerCase(),n=!0}}function g(t,e,r){var n=t[e];t[e]=t[r],t[r]=n}function m(t,e,r,n,i){if(0===t.length)return-1;if("string"==typeof r?(n=r,r=0):r>2147483647?r=2147483647:r<-2147483648&&(r=-2147483648),r=+r,isNaN(r)&&(r=i?0:t.length-1),r<0&&(r=t.length+r),r>=t.length){if(i)return-1;r=t.length-1}else if(r<0){if(!i)return-1;r=0}if("string"==typeof e&&(e=u.from(e,n)),u.isBuffer(e))return 0===e.length?-1:v(t,e,r,n,i);if("number"==typeof e)return e&=255,u.TYPED_ARRAY_SUPPORT&&"function"==typeof Uint8Array.prototype.indexOf?i?Uint8Array.prototype.indexOf.call(t,e,r):Uint8Array.prototype.lastIndexOf.call(t,e,r):v(t,[e],r,n,i);throw new TypeError("val must be string, number or Buffer")}function v(t,e,r,n,i){var o,s=1,a=t.length,u=e.length;if(void 0!==n&&("ucs2"===(n=String(n).toLowerCase())||"ucs-2"===n||"utf16le"===n||"utf-16le"===n)){if(t.length<2||e.length<2)return-1;s=2,a/=2,u/=2,r/=2}function f(t,e){return 1===s?t[e]:t.readUInt16BE(e*s)}if(i){var h=-1;for(o=r;oa&&(r=a-u),o=r;o>=0;o--){for(var c=!0,l=0;li&&(n=i):n=i;var o=e.length;if(o%2!=0)throw new TypeError("Invalid hex string");n>o/2&&(n=o/2);for(var s=0;s>8,i=r%256,o.push(i),o.push(n);return o}(e,t.length-r),t,r,n)}function A(t,e,r){return 0===e&&r===t.length?n.fromByteArray(t):n.fromByteArray(t.slice(e,r))}function R(t,e,r){r=Math.min(t.length,r);for(var n=[],i=e;i239?4:f>223?3:f>191?2:1;if(i+c<=r)switch(c){case 1:f<128&&(h=f);break;case 2:128==(192&(o=t[i+1]))&&(u=(31&f)<<6|63&o)>127&&(h=u);break;case 3:o=t[i+1],s=t[i+2],128==(192&o)&&128==(192&s)&&(u=(15&f)<<12|(63&o)<<6|63&s)>2047&&(u<55296||u>57343)&&(h=u);break;case 4:o=t[i+1],s=t[i+2],a=t[i+3],128==(192&o)&&128==(192&s)&&128==(192&a)&&(u=(15&f)<<18|(63&o)<<12|(63&s)<<6|63&a)>65535&&u<1114112&&(h=u)}null===h?(h=65533,c=1):h>65535&&(h-=65536,n.push(h>>>10&1023|55296),h=56320|1023&h),n.push(h),i+=c}return function(t){var e=t.length;if(e<=4096)return String.fromCharCode.apply(String,t);var r="",n=0;for(;n0&&(t=this.toString("hex",0,r).match(/.{2}/g).join(" "),this.length>r&&(t+=" ... ")),""},u.prototype.compare=function(t,e,r,n,i){if(!u.isBuffer(t))throw new TypeError("Argument must be a Buffer");if(void 0===e&&(e=0),void 0===r&&(r=t?t.length:0),void 0===n&&(n=0),void 0===i&&(i=this.length),e<0||r>t.length||n<0||i>this.length)throw new RangeError("out of range index");if(n>=i&&e>=r)return 0;if(n>=i)return-1;if(e>=r)return 1;if(this===t)return 0;for(var o=(i>>>=0)-(n>>>=0),s=(r>>>=0)-(e>>>=0),a=Math.min(o,s),f=this.slice(n,i),h=t.slice(e,r),c=0;ci)&&(r=i),t.length>0&&(r<0||e<0)||e>this.length)throw new RangeError("Attempt to write outside buffer bounds");n||(n="utf8");for(var o=!1;;)switch(n){case"hex":return w(this,t,e,r);case"utf8":case"utf-8":return _(this,t,e,r);case"ascii":return b(this,t,e,r);case"latin1":case"binary":return P(this,t,e,r);case"base64":return E(this,t,e,r);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return S(this,t,e,r);default:if(o)throw new TypeError("Unknown encoding: "+n);n=(""+n).toLowerCase(),o=!0}},u.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};function T(t,e,r){var n="";r=Math.min(t.length,r);for(var i=e;in)&&(r=n);for(var i="",o=e;or)throw new RangeError("Trying to access beyond buffer length")}function K(t,e,r,n,i,o){if(!u.isBuffer(t))throw new TypeError('"buffer" argument must be a Buffer instance');if(e>i||et.length)throw new RangeError("Index out of range")}function O(t,e,r,n){e<0&&(e=65535+e+1);for(var i=0,o=Math.min(t.length-r,2);i>>8*(n?i:1-i)}function I(t,e,r,n){e<0&&(e=4294967295+e+1);for(var i=0,o=Math.min(t.length-r,4);i>>8*(n?i:3-i)&255}function U(t,e,r,n,i,o){if(r+n>t.length)throw new RangeError("Index out of range");if(r<0)throw new RangeError("Index out of range")}function C(t,e,r,n,o){return o||U(t,0,r,4),i.write(t,e,r,n,23,4),r+4}function M(t,e,r,n,o){return o||U(t,0,r,8),i.write(t,e,r,n,52,8),r+8}u.prototype.slice=function(t,e){var r,n=this.length;if((t=~~t)<0?(t+=n)<0&&(t=0):t>n&&(t=n),(e=void 0===e?n:~~e)<0?(e+=n)<0&&(e=0):e>n&&(e=n),e0&&(i*=256);)n+=this[t+--e]*i;return n},u.prototype.readUInt8=function(t,e){return e||B(t,1,this.length),this[t]},u.prototype.readUInt16LE=function(t,e){return e||B(t,2,this.length),this[t]|this[t+1]<<8},u.prototype.readUInt16BE=function(t,e){return e||B(t,2,this.length),this[t]<<8|this[t+1]},u.prototype.readUInt32LE=function(t,e){return e||B(t,4,this.length),(this[t]|this[t+1]<<8|this[t+2]<<16)+16777216*this[t+3]},u.prototype.readUInt32BE=function(t,e){return e||B(t,4,this.length),16777216*this[t]+(this[t+1]<<16|this[t+2]<<8|this[t+3])},u.prototype.readIntLE=function(t,e,r){t|=0,e|=0,r||B(t,e,this.length);for(var n=this[t],i=1,o=0;++o=(i*=128)&&(n-=Math.pow(2,8*e)),n},u.prototype.readIntBE=function(t,e,r){t|=0,e|=0,r||B(t,e,this.length);for(var n=e,i=1,o=this[t+--n];n>0&&(i*=256);)o+=this[t+--n]*i;return o>=(i*=128)&&(o-=Math.pow(2,8*e)),o},u.prototype.readInt8=function(t,e){return e||B(t,1,this.length),128&this[t]?-1*(255-this[t]+1):this[t]},u.prototype.readInt16LE=function(t,e){e||B(t,2,this.length);var r=this[t]|this[t+1]<<8;return 32768&r?4294901760|r:r},u.prototype.readInt16BE=function(t,e){e||B(t,2,this.length);var r=this[t+1]|this[t]<<8;return 32768&r?4294901760|r:r},u.prototype.readInt32LE=function(t,e){return e||B(t,4,this.length),this[t]|this[t+1]<<8|this[t+2]<<16|this[t+3]<<24},u.prototype.readInt32BE=function(t,e){return e||B(t,4,this.length),this[t]<<24|this[t+1]<<16|this[t+2]<<8|this[t+3]},u.prototype.readFloatLE=function(t,e){return e||B(t,4,this.length),i.read(this,t,!0,23,4)},u.prototype.readFloatBE=function(t,e){return e||B(t,4,this.length),i.read(this,t,!1,23,4)},u.prototype.readDoubleLE=function(t,e){return e||B(t,8,this.length),i.read(this,t,!0,52,8)},u.prototype.readDoubleBE=function(t,e){return e||B(t,8,this.length),i.read(this,t,!1,52,8)},u.prototype.writeUIntLE=function(t,e,r,n){(t=+t,e|=0,r|=0,n)||K(this,t,e,r,Math.pow(2,8*r)-1,0);var i=1,o=0;for(this[e]=255&t;++o=0&&(o*=256);)this[e+i]=t/o&255;return e+r},u.prototype.writeUInt8=function(t,e,r){return t=+t,e|=0,r||K(this,t,e,1,255,0),u.TYPED_ARRAY_SUPPORT||(t=Math.floor(t)),this[e]=255&t,e+1},u.prototype.writeUInt16LE=function(t,e,r){return t=+t,e|=0,r||K(this,t,e,2,65535,0),u.TYPED_ARRAY_SUPPORT?(this[e]=255&t,this[e+1]=t>>>8):O(this,t,e,!0),e+2},u.prototype.writeUInt16BE=function(t,e,r){return t=+t,e|=0,r||K(this,t,e,2,65535,0),u.TYPED_ARRAY_SUPPORT?(this[e]=t>>>8,this[e+1]=255&t):O(this,t,e,!1),e+2},u.prototype.writeUInt32LE=function(t,e,r){return t=+t,e|=0,r||K(this,t,e,4,4294967295,0),u.TYPED_ARRAY_SUPPORT?(this[e+3]=t>>>24,this[e+2]=t>>>16,this[e+1]=t>>>8,this[e]=255&t):I(this,t,e,!0),e+4},u.prototype.writeUInt32BE=function(t,e,r){return t=+t,e|=0,r||K(this,t,e,4,4294967295,0),u.TYPED_ARRAY_SUPPORT?(this[e]=t>>>24,this[e+1]=t>>>16,this[e+2]=t>>>8,this[e+3]=255&t):I(this,t,e,!1),e+4},u.prototype.writeIntLE=function(t,e,r,n){if(t=+t,e|=0,!n){var i=Math.pow(2,8*r-1);K(this,t,e,r,i-1,-i)}var o=0,s=1,a=0;for(this[e]=255&t;++o>0)-a&255;return e+r},u.prototype.writeIntBE=function(t,e,r,n){if(t=+t,e|=0,!n){var i=Math.pow(2,8*r-1);K(this,t,e,r,i-1,-i)}var o=r-1,s=1,a=0;for(this[e+o]=255&t;--o>=0&&(s*=256);)t<0&&0===a&&0!==this[e+o+1]&&(a=1),this[e+o]=(t/s>>0)-a&255;return e+r},u.prototype.writeInt8=function(t,e,r){return t=+t,e|=0,r||K(this,t,e,1,127,-128),u.TYPED_ARRAY_SUPPORT||(t=Math.floor(t)),t<0&&(t=255+t+1),this[e]=255&t,e+1},u.prototype.writeInt16LE=function(t,e,r){return t=+t,e|=0,r||K(this,t,e,2,32767,-32768),u.TYPED_ARRAY_SUPPORT?(this[e]=255&t,this[e+1]=t>>>8):O(this,t,e,!0),e+2},u.prototype.writeInt16BE=function(t,e,r){return t=+t,e|=0,r||K(this,t,e,2,32767,-32768),u.TYPED_ARRAY_SUPPORT?(this[e]=t>>>8,this[e+1]=255&t):O(this,t,e,!1),e+2},u.prototype.writeInt32LE=function(t,e,r){return t=+t,e|=0,r||K(this,t,e,4,2147483647,-2147483648),u.TYPED_ARRAY_SUPPORT?(this[e]=255&t,this[e+1]=t>>>8,this[e+2]=t>>>16,this[e+3]=t>>>24):I(this,t,e,!0),e+4},u.prototype.writeInt32BE=function(t,e,r){return t=+t,e|=0,r||K(this,t,e,4,2147483647,-2147483648),t<0&&(t=4294967295+t+1),u.TYPED_ARRAY_SUPPORT?(this[e]=t>>>24,this[e+1]=t>>>16,this[e+2]=t>>>8,this[e+3]=255&t):I(this,t,e,!1),e+4},u.prototype.writeFloatLE=function(t,e,r){return C(this,t,e,!0,r)},u.prototype.writeFloatBE=function(t,e,r){return C(this,t,e,!1,r)},u.prototype.writeDoubleLE=function(t,e,r){return M(this,t,e,!0,r)},u.prototype.writeDoubleBE=function(t,e,r){return M(this,t,e,!1,r)},u.prototype.copy=function(t,e,r,n){if(r||(r=0),n||0===n||(n=this.length),e>=t.length&&(e=t.length),e||(e=0),n>0&&n=this.length)throw new RangeError("sourceStart out of bounds");if(n<0)throw new RangeError("sourceEnd out of bounds");n>this.length&&(n=this.length),t.length-e=0;--i)t[i+e]=this[i+r];else if(o<1e3||!u.TYPED_ARRAY_SUPPORT)for(i=0;i>>=0,r=void 0===r?this.length:r>>>0,t||(t=0),"number"==typeof t)for(o=e;o55295&&r<57344){if(!i){if(r>56319){(e-=3)>-1&&o.push(239,191,189);continue}if(s+1===n){(e-=3)>-1&&o.push(239,191,189);continue}i=r;continue}if(r<56320){(e-=3)>-1&&o.push(239,191,189),i=r;continue}r=65536+(i-55296<<10|r-56320)}else i&&(e-=3)>-1&&o.push(239,191,189);if(i=null,r<128){if((e-=1)<0)break;o.push(r)}else if(r<2048){if((e-=2)<0)break;o.push(r>>6|192,63&r|128)}else if(r<65536){if((e-=3)<0)break;o.push(r>>12|224,r>>6&63|128,63&r|128)}else{if(!(r<1114112))throw new Error("Invalid code point");if((e-=4)<0)break;o.push(r>>18|240,r>>12&63|128,r>>6&63|128,63&r|128)}}return o}function N(t){return n.toByteArray(function(t){if((t=function(t){return t.trim?t.trim():t.replace(/^\s+|\s+$/g,"")}(t).replace(Y,"")).length<2)return"";for(;t.length%4!=0;)t+="=";return t}(t))}function F(t,e,r,n){for(var i=0;i=e.length||i>=t.length);++i)e[i+r]=t[i];return i}}).call(this,r(7))},function(t,e){},function(t,e,r){(function(t){function r(t,e){for(var r=0,n=t.length-1;n>=0;n--){var i=t[n];"."===i?t.splice(n,1):".."===i?(t.splice(n,1),r++):r&&(t.splice(n,1),r--)}if(e)for(;r--;r)t.unshift("..");return t}function n(t,e){if(t.filter)return t.filter(e);for(var r=[],n=0;n=-1&&!i;o--){var s=o>=0?arguments[o]:t.cwd();if("string"!=typeof s)throw new TypeError("Arguments to path.resolve must be strings");s&&(e=s+"/"+e,i="/"===s.charAt(0))}return(i?"/":"")+(e=r(n(e.split("/"),(function(t){return!!t})),!i).join("/"))||"."},e.normalize=function(t){var o=e.isAbsolute(t),s="/"===i(t,-1);return(t=r(n(t.split("/"),(function(t){return!!t})),!o).join("/"))||o||(t="."),t&&s&&(t+="/"),(o?"/":"")+t},e.isAbsolute=function(t){return"/"===t.charAt(0)},e.join=function(){var t=Array.prototype.slice.call(arguments,0);return e.normalize(n(t,(function(t,e){if("string"!=typeof t)throw new TypeError("Arguments to path.join must be strings");return t})).join("/"))},e.relative=function(t,r){function n(t){for(var e=0;e=0&&""===t[r];r--);return e>r?[]:t.slice(e,r-e+1)}t=e.resolve(t).substr(1),r=e.resolve(r).substr(1);for(var i=n(t.split("/")),o=n(r.split("/")),s=Math.min(i.length,o.length),a=s,u=0;u=1;--o)if(47===(e=t.charCodeAt(o))){if(!i){n=o;break}}else i=!1;return-1===n?r?"/":".":r&&1===n?"/":t.slice(0,n)},e.basename=function(t,e){var r=function(t){"string"!=typeof t&&(t+="");var e,r=0,n=-1,i=!0;for(e=t.length-1;e>=0;--e)if(47===t.charCodeAt(e)){if(!i){r=e+1;break}}else-1===n&&(i=!1,n=e+1);return-1===n?"":t.slice(r,n)}(t);return e&&r.substr(-1*e.length)===e&&(r=r.substr(0,r.length-e.length)),r},e.extname=function(t){"string"!=typeof t&&(t+="");for(var e=-1,r=0,n=-1,i=!0,o=0,s=t.length-1;s>=0;--s){var a=t.charCodeAt(s);if(47!==a)-1===n&&(i=!1,n=s+1),46===a?-1===e?e=s:1!==o&&(o=1):-1!==e&&(o=-1);else if(!i){r=s+1;break}}return-1===e||-1===n||0===o||1===o&&e===n-1&&e===r+1?"":t.slice(e,n)};var i="b"==="ab".substr(-1)?function(t,e,r){return t.substr(e,r)}:function(t,e,r){return e<0&&(e=t.length+e),t.substr(e,r)}}).call(this,r(3))},function(t,e){var r,n,i=t.exports={};function o(){throw new Error("setTimeout has not been defined")}function s(){throw new Error("clearTimeout has not been defined")}function a(t){if(r===setTimeout)return setTimeout(t,0);if((r===o||!r)&&setTimeout)return r=setTimeout,setTimeout(t,0);try{return r(t,0)}catch(e){try{return r.call(null,t,0)}catch(e){return r.call(this,t,0)}}}!function(){try{r="function"==typeof setTimeout?setTimeout:o}catch(t){r=o}try{n="function"==typeof clearTimeout?clearTimeout:s}catch(t){n=s}}();var u,f=[],h=!1,c=-1;function l(){h&&u&&(h=!1,u.length?f=u.concat(f):c=-1,f.length&&p())}function p(){if(!h){var t=a(l);h=!0;for(var e=f.length;e;){for(u=f,f=[];++c1)for(var r=1;r{t.push(""+e.toString())}),t}initSync(){if(this.fs.existsSync(this.polykeyPath))this.fs.existsSync(this.metadataPath)&&(this.metadata=f.default.readFileSync(this.metadataPath));else{this.fs.mkdirSync(this.polykeyPath,{recursive:!0});const t={vaults:{},publicKeyPath:null,privateKeyPath:null,passphrase:null};f.default.writeFileSync(this.metadataPath,t),this.metadata=t}for(const e in this.metadata.vaults)if(this.metadata.vaults.hasOwnProperty(e)){const r=s.default.join(this.polykeyPath,e);if(this.fileExistsSync(r))try{const r=t.from(this.metadata.vaults[e].key),n=new a.default(e,r,this.polykeyPath);this.vaults.set(e,n)}catch(t){throw t}}}loadKey(e){if(e instanceof t)return e;return t.from(this.fs.readFileSync(e,void 0))}}}).call(this,r(0).Buffer)},function(t,e){var r;r=function(){return this}();try{r=r||new Function("return this")()}catch(t){"object"==typeof window&&(r=window)}t.exports=r},function(t,e){t.exports=require("base64-js")},function(t,e){t.exports=require("ieee754")},function(t,e){t.exports=require("isarray")},function(t,e){e.endianness=function(){return"LE"},e.hostname=function(){return"undefined"!=typeof location?location.hostname:""},e.loadavg=function(){return[]},e.uptime=function(){return 0},e.freemem=function(){return Number.MAX_VALUE},e.totalmem=function(){return Number.MAX_VALUE},e.cpus=function(){return[]},e.type=function(){return"Browser"},e.release=function(){return"undefined"!=typeof navigator?navigator.appVersion:""},e.networkInterfaces=e.getNetworkInterfaces=function(){return{}},e.arch=function(){return"javascript"},e.platform=function(){return"browser"},e.tmpdir=e.tmpDir=function(){return"/tmp"},e.EOL="\n",e.homedir=function(){return"/"}},function(t,e,r){"use strict";(function(t,n){var i=this&&this.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(e,"__esModule",{value:!0});const o=i(r(1)),s=i(r(2)),a=i(r(13)),u=r(14),f=r(15);e.default=class{constructor(e,r,n){this.keyLen=32,this.key=this.genSymKey(r,this.keyLen);const i=new f.VirtualFS;this.fs=new u.EncryptedFS(r,i,i,o.default,t),this.name=e,this.vaultPath=s.default.join(n,e),this.fs.mkdirSync(this.vaultPath,{recursive:!0}),this.secrets=new Map,this.loadSecrets()}loadSecrets(){const t=o.default.readdirSync(this.vaultPath,void 0);for(const e of t)this.secrets.set(e,null)}genSymKey(t,e){return n.from(a.default(t.toString(),e))}secretExists(t){const e=s.default.join(this.vaultPath,t);return this.secrets.has(t)&&this.fs.existsSync(e)}addSecret(t,e){const r=s.default.join(this.vaultPath,t),n=this.fs.openSync(r,"w");this.fs.writeSync(n,e,0,e.length,0),this.secrets.set(t,e)}getSecret(t){if(this.secrets.has(t)){const e=this.secrets.get(t);if(e)return e;{const e=s.default.join(this.vaultPath,t),r=this.fs.readFileSync(e,{});return this.secrets.set(t,r),r}}throw Error("Secret: "+t+" does not exist")}removeSecret(t){if(this.secrets.has(t)){if(this.secrets.delete(t))return;throw Error("Secret: "+t+" was not removed")}throw Error("Secret: "+t+" does not exist")}listSecrets(){return Array.from(this.secrets.keys())}tagVault(){}untagVault(){}shareVault(){}unshareVault(){}}}).call(this,r(3),r(0).Buffer)},function(t,e){t.exports=require("futoin-hkdf")},function(t,e){t.exports=require("encryptedfs")},function(t,e){t.exports=require("virtualfs")},function(t,e){t.exports=require("randombytes")},function(t,e){t.exports=require("create-hash")},function(t,e){t.exports=require("create-hmac")},function(t,e){t.exports=require("browserify-sign/algos")},function(t,e){t.exports=require("pbkdf2")},function(t,e){t.exports=require("browserify-cipher")},function(t,e){t.exports=require("diffie-hellman")},function(t,e){t.exports=require("browserify-sign")},function(t,e){t.exports=require("create-ecdh")},function(t,e){t.exports=require("public-encrypt")},function(t,e){t.exports=require("randomfill")},function(t,e){t.exports=require("jsonfile")},function(t,e,r){"use strict";(function(t){var n=this&&this.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(e,"__esModule",{value:!0});const i=n(r(1)),o=n(r(2)),s=n(r(4)),a=r(29),u=r(30);var f=u.const.openpgp;const h=r(31);e.KeyManager=class{constructor(t="~/.polykey/"){this.keyPair={private:"",public:"",passphrase:""},this.identity=void 0,this.storePath=t,this.derivedKeys=new Map}async generateKeyPair(t,e,r,n=4096){if(h(r).score<2)throw new Error("passphrase score for new keypair is below 2!");var i={userid:`${t} <${e}>`,primary:{nbits:4096,flags:f.certify_keys|f.sign_data|f.auth|f.encrypt_comm|f.encrypt_storage,expire_in:0},subkeys:[]};return this.passphrase=r,new Promise((t,e)=>{u.KeyManager.generate(i,(n,i)=>{i.sign({},n=>{n&&e(n),i.export_pgp_public({},(n,o)=>{n&&e(n),i.export_pgp_private({passphrase:r},(n,s)=>{n&&e(n);const a={private:s,public:o,passphrase:r};this.keyPair=a,this.identity=i,t(a)})})})})})}getKeyPair(){return this.keyPair}getPublicKey(){return this.keyPair.public}getPrivateKey(){return this.keyPair.private}async loadPrivateKey(e,r=""){try{let n;n="string"==typeof e?t.from(await i.default.promises.readFile(e)):e,this.keyPair.private=n.toString(),r&&(this.passphrase=r)}catch(t){throw t}}async loadPublicKey(e){try{let r;r="string"==typeof e?t.from(await i.default.promises.readFile(e)):e,this.keyPair.public=r.toString()}catch(t){throw t}}async loadIdentity(t){return new Promise((e,r)=>{const n=this.getPublicKey(),i=this.getPrivateKey();u.KeyManager.import_from_armored_pgp({armored:n},(n,o)=>{n&&r(n),o.merge_pgp_private({armored:i},n=>{n&&r(n),o.is_pgp_locked()?o.unlock_pgp({passphrase:t},t=>{t&&r(t),this.identity=o,e()}):(this.identity=o,e())})})})}async loadKeyPair(t,e,r=""){await this.loadPrivateKey(e),await this.loadPublicKey(t),await this.loadIdentity(r),r&&this.passphrase}async exportPrivateKey(t){await i.default.promises.writeFile(t,this.keyPair.private)}async exportPublicKey(t){await i.default.promises.writeFile(t,this.keyPair.public)}generateKeySync(t,e){const r=s.default.randomBytes(32);return this.derivedKeys[t]=s.default.pbkdf2Sync(e,r,1e4,32,"sha256"),this.derivedKeys[t]}async generateKey(t,e){const r=s.default.randomBytes(32);return this.derivedKeys[t]=await a.promisify(s.default.pbkdf2)(e,r,1e4,32,"sha256"),this.derivedKeys[t]}importKeySync(t,e){this.derivedKeys[t]=i.default.readFileSync(e)}async importKey(t,e){this.derivedKeys[t]=await i.default.promises.readFile(e)}importKeyBuffer(t,e){this.derivedKeys[t]=e}async exportKey(t,e,r){if(!this.derivedKeys[t])throw Error("There is no key loaded for name: "+t);r&&await i.default.promises.mkdir(o.default.dirname(e),{recursive:!0}),await i.default.promises.writeFile(e,this.derivedKeys[t])}exportKeySync(t,e){if(!this.derivedKeys[name])throw Error("There is no key loaded for name: "+name);e&&i.default.mkdirSync(o.default.dirname(t),{recursive:!0}),i.default.writeFileSync(t,this.derivedKeys[name])}async getIdentityFromPublicKey(t){return new Promise((e,r)=>{u.KeyManager.import_from_armored_pgp({armored:t},(t,n)=>{t&&r(t),e(n)})})}async getIdentityFromPrivateKey(t,e){return new Promise((r,n)=>{u.KeyManager.import_from_armored_pgp({armored:t},(t,i)=>{t&&n(t),i.is_pgp_locked()?i.unlock_pgp({passphrase:e},t=>{t&&n(t),r(i)}):r(i)})})}signData(e,r,n){return new Promise(async(i,o)=>{let s;if(void 0!==r)void 0===n&&o(Error("passphrase for private key was not provided")),s=await this.getIdentityFromPrivateKey(r,n);else{if(void 0===this.identity)throw Error("no identity available for signing");s=this.identity}const a={msg:e,sign_with:s};u.box(a,(e,r,n)=>{e&&o(e),i(t.from(r))})})}verifyData(t,e,r){return new Promise(async(n,i)=>{var o=new u.keyring.KeyRing;let s;if(void 0!==r)s=await this.getIdentityFromPublicKey(r);else{if(void 0===this.identity)throw Error("no identity available for signing");s=this.identity}o.add_key_manager(this.identity);const a={armored:e,data:t,keyfetch:o};u.unbox(a,(t,e)=>{t&&i(t);let r,o=e[0].get_data_signer();o&&(r=o.get_key_manager()),r?n(r.get_pgp_fingerprint().toString("hex")):i(Error("could not verify file"))})})}getKey(t){return this.derivedKeys[t]}isLoaded(){return!!this.derivedKeys[name]}}}).call(this,r(0).Buffer)},function(t,e){t.exports=require("util")},function(t,e){t.exports=require("kbpgp")},function(t,e){t.exports=require("zxcvbn")}])})); +!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.polykey=t():e.polykey=t()}(this,(function(){return function(e){var t={};function r(s){if(t[s])return t[s].exports;var a=t[s]={i:s,l:!1,exports:{}};return e[s].call(a.exports,a,a.exports,r),a.l=!0,a.exports}return r.m=e,r.c=t,r.d=function(e,t,s){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:s})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var s=Object.create(null);if(r.r(s),Object.defineProperty(s,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var a in e)r.d(s,a,function(t){return e[t]}.bind(null,a));return s},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="",r(r.s=5)}([function(e,t){e.exports=require("path")},function(e,t){e.exports=require("fs")},function(e,t){e.exports=require("crypto")},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0});class s{constructor(e,t){this.ip=e,this.port=t}static parse(e){const t=e.split(":"),r=t[0],a=t[1];return new s(r,a)}}t.Address=s,s.prototype.toString=function(){return`${this.ip}:${this.port}`};t.default=class{constructor(e,t=[],r){this.publicKey=e,this.addresses=new Set(t.map(e=>s.parse(e))),this.connectedAddr=r?s.parse(r):void 0}connect(e){this.addresses.has(e)||this.addresses.add(e),this.connectedAddr=e}disconnect(){this.connectedAddr=void 0}}},function(e,t,r){"use strict";(function(e){var s=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const a=s(r(0)),i=s(r(17)),o=s(r(3));console.log(e);t.default=class{static loadProto(t){const r=new i.default.Root;return r.resolvePath=(t,r)=>a.default.join(e,r),r.loadSync(t)}static encodePeerInfo(e){var t;const r=this.loadProto("PeerInfoMessage.proto").lookupType("peerinfopackage.PeerInfoMessage"),s=[];for(const t of e.addresses)s.push(t.toString());const a={pubKey:e.publicKey,addresses:s,connectedAddr:null===(t=e.connectedAddr)||void 0===t?void 0:t.toString()},i=r.verify(a);if(i)throw Error(i);const o=r.create(a);return r.encode(o).finish()}static decodePeerInfo(e){const t=this.loadProto("PeerInfoMessage.proto").lookupType("peerinfopackage.PeerInfoMessage"),r=t.decode(e),s=t.toObject(r,{enums:String,longs:String,bytes:String,defaults:!0,arrays:!0,objects:!0,oneofs:!0});return new o.default(s.pubKey,s.addresses,s.connectedAddr)}static encodeHandshakeMessage(e,t,r,s){const a=this.loadProto("HandshakeMessage.proto").lookupType("handshakepackage.HandshakeMessage"),i={targetPubKey:e,requestingPubKey:t,message:r,responsePeerInfo:s?this.encodePeerInfo(s):void 0},o=a.verify(i);if(o)throw Error(o);const n=a.create(i);return a.encode(n).finish()}static decodeHandshakeMessage(e){const t=this.loadProto("HandshakeMessage.proto").lookupType("handshakepackage.HandshakeMessage"),r=t.decode(e),s=t.toObject(r,{enums:String,longs:String,bytes:String,defaults:!0,arrays:!0,objects:!0,oneofs:!0});return{targetPubKey:Buffer.from(s.targetPubKey,"base64"),requestingPubKey:Buffer.from(s.requestingPubKey,"base64"),message:Buffer.from(s.message,"base64"),responsePeerInfo:s.responsePeerInfo?this.decodePeerInfo(Buffer.from(s.responsePeerInfo,"base64")):void 0}}}}).call(this,"/index.js")},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var s=r(6);t.default=s.default},function(e,t,r){"use strict";var s=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const a=s(r(7)),i=s(r(1)),o=s(r(0)),n=s(r(2)),u=s(r(8)),d=s(r(9)),c=s(r(13)),l=s(r(16)),y=s(r(3)),f=s(r(4)),h=s(r(18));t.default=class{constructor(e,t,r=a.default.homedir()+"/.polykey"){if(this.polykeyPath=r,this.metadataPath=o.default.join(r,"metadata"),this.fs=i.default,this.keyManager=null!=e?e:new c.default(r),this.peerDiscovery=null!=t?t:new h.default(this.peerStore,this.keyManager),this.fs.existsSync(this.polykeyPath))if(this.fs.existsSync(this.metadataPath)){const e=u.default.readFileSync(this.metadataPath);this.metadata={vaults:e.vaults,peerInfo:e.peerInfo,publicKeyPath:e.publicKeyPath,privateKeyPath:e.privateKeyPath}}else{const e=new y.default(this.keyManager.getPublicKey()),t={vaults:{},peerInfo:f.default.encodePeerInfo(e)};u.default.writeFileSync(this.metadataPath,t),this.metadata=t}else this.fs.mkdirSync(this.polykeyPath,{recursive:!0});this.peerStore=new l.default(f.default.decodePeerInfo(this.metadata.peerInfo)),this.peerDiscovery=new h.default(this.peerStore,this.keyManager),this.vaults=new Map;for(const e in this.metadata.vaults)if(this.metadata.vaults.hasOwnProperty(e)){const t=o.default.join(this.polykeyPath,e);if(this.fs.existsSync(t)){const t=Buffer.from(this.metadata.vaults[e].key),r=new d.default(e,t,this.polykeyPath);this.vaults.set(e,r)}}}async getVault(e){if(this.vaults.has(e)){const t=this.vaults.get(e);if(t)return t}await this.validateVault(e);const t=this.metadata.vaults[e].key,r=new d.default(e,t,this.polykeyPath);return this.vaults.set(e,r),r}async createVault(e,t){const r=o.default.join(this.polykeyPath,e);let s;if(s=this.fs.existsSync(r),s)throw Error("Vault already exists!");try{let s;this.fs.mkdirSync(r,{recursive:!0}),s=t||n.default.randomBytes(16),this.metadata.vaults[e]={key:s,tags:[]},await this.writeMetadata();const a=new d.default(e,s,this.polykeyPath);return this.vaults.set(e,a),await this.getVault(e)}catch(t){throw await this.destroyVault(e),t}}async vaultExists(e){const t=o.default.join(this.polykeyPath,e);return this.fs.existsSync(t)}async destroyVault(e){const t=o.default.join(this.polykeyPath,e);if(this.fs.existsSync(t)&&this.fs.rmdirSync(t,{recursive:!0}),this.vaults.has(e)&&this.vaults.delete(e),this.metadata.vaults.hasOwnProperty(e)&&(delete this.metadata.vaults[e],await this.writeMetadata()),this.fs.existsSync(t))throw new Error("Vault path could not be destroyed!");if(this.vaults.has(e))throw new Error("Vault could not be removed from PolyKey!");if(this.metadata.vaults.hasOwnProperty(e))throw new Error("Vault metadata could not be destroyed!")}async validateVault(e){if(!this.metadata.vaults.hasOwnProperty(e))throw Error("Vault metadata does not exist");const t=o.default.join(this.polykeyPath,e);if(!this.fs.existsSync(t))throw Error("Vault directory does not exist")}listVaults(){return Array.from(this.vaults.keys())}tagVault(){}untagVault(){}shareVault(){}unshareVault(){}async writeMetadata(){try{await u.default.writeFile(this.metadataPath,this.metadata)}catch(e){throw Error("Error writing vault key to config file")}}}},function(e,t){e.exports=require("os")},function(e,t){e.exports=require("jsonfile")},function(e,t,r){"use strict";var s=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const a=s(r(1)),i=s(r(0)),o=s(r(10)),n=r(11);t.default=class{constructor(e,t,s){this.keyLen=32,this.key=this.genSymKey(t,this.keyLen);const o=new(r(12).VirtualFS);this.fs=new n.EncryptedFS(t,o,o,a.default,process),this.name=e,this.vaultPath=i.default.join(s,e),this.fs.mkdirSync(this.vaultPath,{recursive:!0}),this.secrets=new Map,this.loadSecrets()}loadSecrets(){const e=a.default.readdirSync(this.vaultPath,void 0);for(const t of e)this.secrets.set(t,null)}genSymKey(e,t){return Buffer.from(o.default(e.toString(),t))}secretExists(e){const t=i.default.join(this.vaultPath,e);return this.secrets.has(e)&&this.fs.existsSync(t)}addSecret(e,t){const r=i.default.join(this.vaultPath,e),s=this.fs.openSync(r,"w");this.fs.writeSync(s,t,0,t.length,0),this.secrets.set(e,t)}getSecret(e){if(this.secrets.has(e)){const t=this.secrets.get(e);if(t)return t;{const t=i.default.join(this.vaultPath,e),r=this.fs.readFileSync(t,{});return this.secrets.set(e,r),r}}throw Error("Secret: "+e+" does not exist")}removeSecret(e){if(this.secrets.has(e)){if(this.secrets.delete(e))return;throw Error("Secret: "+e+" was not removed")}throw Error("Secret: "+e+" does not exist")}listSecrets(){return Array.from(this.secrets.keys())}tagVault(){}untagVault(){}shareVault(){}unshareVault(){}}},function(e,t){e.exports=require("futoin-hkdf")},function(e,t){e.exports=require("encryptedfs")},function(e,t){e.exports=require("virtualfs")},function(e,t,r){"use strict";var s=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const a=s(r(1)),i=s(r(0)),o=s(r(14)),n=s(r(2)),u=r(15);t.default=class{constructor(e="~/.polykey/",t=!1,r){this.primaryKeyPair={private:"",public:"",passphrase:""},this.storePath=e,this.useWebWorkers=t,this.workerPool=r,this.derivedKeys=new Map}async generateKeyPair(e,t,r,s=!1,a){const i=o.default.const.openpgp,n={asp:a?new o.default.ASP({progress_hook:a}):void 0,userid:`${e} <${t}>`,primary:{nbits:4096,flags:i.certify_keys|i.sign_data|i.auth|i.encrypt_comm|i.encrypt_storage,expire_in:0},subkeys:[]};return new Promise((e,t)=>{o.default.KeyManager.generate(n,(a,i)=>{a&&t(a),i.sign({},a=>{a&&t(a),i.export_pgp_public({},(a,o)=>{a&&t(a),i.export_pgp_private({passphrase:r},(a,n)=>{a&&t(a);const u={private:n,public:o,passphrase:r};s&&(this.primaryPassphrase=r,this.primaryKeyPair=u,this.primaryIdentity=i),e(u)})})})})})}getKeyPair(){return this.primaryKeyPair}getPublicKey(){return this.primaryKeyPair.public}getPrivateKey(){return this.primaryKeyPair.private}async loadPrivateKey(e,t=""){try{let r;r="string"==typeof e?Buffer.from(await a.default.promises.readFile(e)):e,this.primaryKeyPair.private=r.toString(),t&&(this.primaryPassphrase=t)}catch(e){throw e}}async loadPublicKey(e){try{let t;t="string"==typeof e?Buffer.from(await a.default.promises.readFile(e)):e,this.primaryKeyPair.public=t.toString()}catch(e){throw e}}async loadIdentity(e){return new Promise((t,r)=>{const s=this.getPublicKey(),a=this.getPrivateKey();o.default.KeyManager.import_from_armored_pgp({armored:s},(s,i)=>{s&&r(s),i.merge_pgp_private({armored:a},s=>{s&&r(s),i.is_pgp_locked()?i.unlock_pgp({passphrase:e},e=>{e&&r(e),this.primaryIdentity=i,t()}):(this.primaryIdentity=i,t())})})})}async loadKeyPair(e,t,r=""){await this.loadPrivateKey(t),await this.loadPublicKey(e),await this.loadIdentity(r),r&&this.primaryPassphrase}async exportPrivateKey(e){await a.default.promises.writeFile(e,this.primaryKeyPair.private)}async exportPublicKey(e){await a.default.promises.writeFile(e,this.primaryKeyPair.public)}generateKeySync(e,t){const r=n.default.randomBytes(32);return this.derivedKeys[e]=n.default.pbkdf2Sync(t,r,1e4,32,"sha256"),this.derivedKeys[e]}async generateKey(e,t){const r=n.default.randomBytes(32);return this.derivedKeys[e]=await u.promisify(n.default.pbkdf2)(t,r,1e4,32,"sha256"),this.derivedKeys[e]}importKeySync(e,t){this.derivedKeys[e]="string"==typeof t?a.default.readFileSync(t):t}async importKey(e,t){this.derivedKeys[e]="string"==typeof t?await a.default.promises.readFile(t):t}async exportKey(e,t,r){if(!this.derivedKeys.has(e))throw Error("There is no key loaded for name: "+e);r&&await a.default.promises.mkdir(i.default.dirname(t),{recursive:!0}),await a.default.promises.writeFile(t,this.derivedKeys[e])}exportKeySync(e,t){if(!this.derivedKeys.has(name))throw Error("There is no key loaded for name: "+name);t&&a.default.mkdirSync(i.default.dirname(e),{recursive:!0}),a.default.writeFileSync(e,this.derivedKeys[name])}async getIdentityFromPublicKey(e){return new Promise((t,r)=>{o.default.KeyManager.import_from_armored_pgp({armored:e},(e,s)=>{e&&r(e),t(s)})})}async getIdentityFromPrivateKey(e,t){return new Promise((r,s)=>{o.default.KeyManager.import_from_armored_pgp({armored:e},(e,a)=>{e&&s(e),a.is_pgp_locked()?a.unlock_pgp({passphrase:t},e=>{e&&s(e),r(a)}):r(a)})})}signData(e,t,r){return new Promise(async(s,a)=>{let i;if(t)r||a(Error("passphrase for private key was not provided")),i=await this.getIdentityFromPrivateKey(t,r);else{if(!this.primaryIdentity)throw Error("no identity available for signing");i=this.primaryIdentity}if(this.useWebWorkers&&this.workerPool){const t=await this.workerPool.queue(async t=>await t.signData(e,i));s(t)}else{const t={msg:e,sign_with:i};o.default.box(t,(e,t,r)=>{e&&a(e),s(Buffer.from(t))})}})}verifyData(e,t,r){return new Promise(async(s,a)=>{const i=new o.default.keyring.KeyRing;let n;if(r)n=await this.getIdentityFromPublicKey(r);else{if(!this.primaryIdentity)throw new Error("no identity available for verifying");n=this.primaryIdentity}if(this.useWebWorkers&&this.workerPool){const r=await this.workerPool.queue(async r=>await r.verifyData(e,t,n));s(r)}else{i.add_key_manager(this.primaryIdentity);const r={armored:t,data:e,keyfetch:i};o.default.unbox(r,(e,t)=>{e&&a(e);let r,i=t[0].get_data_signer();i&&(r=i.get_key_manager()),r?s(r.get_pgp_fingerprint().toString("hex")):a(Error("could not verify file"))})}})}async verifyFile(e,t,r){let s;r&&(s="string"==typeof r?a.default.readFileSync(r):r);const i=a.default.readFileSync(e),o=a.default.readFileSync(t);return await this.verifyData(i,o,s)}async signFile(e,t,r){let s;t&&(s="string"==typeof t?Buffer.from(a.default.readFileSync(t)):t);const i=Buffer.from(a.default.readFileSync(e)),o=await this.signData(i,s,r),n=e+".sig";return a.default.writeFileSync(n,o),n}async encryptData(e,t){return new Promise(async(r,s)=>{let a;try{a=await this.getIdentityFromPublicKey(t)}catch(e){throw Error("Identity could not be resolved for encrypting: "+e)}if(this.useWebWorkers&&this.workerPool){const t=await this.workerPool.queue(async t=>await t.encryptData(e,a));r(t)}else{const t={msg:e,encrypt_for:a};o.default.box(t,(e,t,a)=>{e&&s(e),r(t)})}})}async decryptData(e,t){return new Promise(async(r,s)=>{var a=new o.default.keyring.KeyRing;let i;if(t)i=await this.getIdentityFromPublicKey(t);else{if(!this.primaryIdentity)throw Error("no identity available for signing");i=this.primaryIdentity}if(this.useWebWorkers&&this.workerPool){const t=await this.workerPool.queue(async t=>await t.decryptData(e,i));r(t)}else{a.add_key_manager(i);const t={armored:e,keyfetch:a};o.default.unbox(t,(e,t)=>{e&&s(e);try{const e=Buffer.from(t[0].toString());r(e)}catch(e){s(e)}})}})}getKey(e){return this.derivedKeys[e]}isLoaded(){return!!this.derivedKeys[name]}}},function(e,t){e.exports=require("kbpgp")},function(e,t){e.exports=require("util")},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.default=class{constructor(e){this.localPeerInfo=e,this.peers=new Map}put(e){this.has(e.publicKey)?this.update(e):this.add(e)}add(e){this.peers.set(e.publicKey,e)}update(e){this.peers.set(e.publicKey,e)}get(e){var t;return null!==(t=this.peers.get(e))&&void 0!==t?t:null}has(e){return this.peers.has(e)}}},function(e,t){e.exports=require("protobufjs")},function(e,t,r){"use strict";var s=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const a=s(r(19)),i=s(r(20)),o=r(23),n={name:"Keybase",findUser:async(e,t)=>{const r=`https://keybase.io/_/api/1.0/user/lookup.json?${t}=${e}`;try{const e=await a.default(r);return(await e.json()).them[0].public_keys.primary.bundle}catch(e){throw new Error("User was not found: "+e.message)}}};t.default=class{constructor(e,t,r=[]){this.peerStore=e,this.keyManager=t,this.socialDiscoveryServices=r,this.socialDiscoveryServices=[],this.socialDiscoveryServices.push(n);for(const e of r)this.socialDiscoveryServices.push(e);this.multicastBroadcaster=new i.default(this.peerStore,this.keyManager)}async findPubKey(e){return new Promise((t,r)=>{this.multicastBroadcaster.requestPeerContact(e),this.multicastBroadcaster.on("found",r=>{r.publicKey==e&&t(r)}),this.multicastBroadcaster.on("timeout",t=>{t==e&&r("The broadcaster stopped looking")})})}async findSocialUser(e,t){const r=[];for(const s of this.socialDiscoveryServices)try{r.push(s.findUser(e,t))}catch(e){console.log("Could not find user on this discovery service: "+s.name)}const s=await o.firstPromiseFulfilled(r);if(s.length>1)throw new Error("Could not find public key from services");const a=s[0];return await this.findPubKey(a)}}},function(e,t){e.exports=require("node-fetch")},function(e,t,r){"use strict";var s,a,i=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const o=i(r(21)),n=i(r(2)),u=r(22),d=i(r(4)),c=parseInt(null!==(s=process.env.UDP_MULTICAST_PORT)&&void 0!==s?s:"5353"),l=null!==(a=process.env.UDP_MULTICAST_ADDR)&&void 0!==a?a:"224.0.0.251";class y extends u.EventEmitter{constructor(e,t){super(),this.peerPubKeyMessages=new Map,this.peerStore=e,this.keyManager=t,this.interval=1e3,this.queryInterval=null,this.socket=o.default.createSocket({type:"udp4",reuseAddr:!0}),this.socket.bind(c),this.socket.on("listening",(()=>{this.socket.addMembership(l);const e=this.socket.address();console.log(`UDP socket listening on ${e.address}:${e.port} pid: ${process.pid}`)}).bind(this)),this.socket.on("message",this.handleHandshakeMessages.bind(this)),this.queryInterval=this.queryLAN()}queryLAN(){const e=()=>{for(const e of this.peerPubKeyMessages.keys()){const t=this.peerPubKeyMessages.get(e);if(t){const e=d.default.encodeHandshakeMessage(t.encryptedPeerPubKey,t.encryptedLocalPubKey,t.encryptedRandomMessage);this.socket.send(e,0,e.length,c,l,()=>{console.info("Sending message to peer")})}}};return e(),setInterval(e,this.interval)}async handleHandshakeMessages(e,t){var r;try{const s=d.default.decodeHandshakeMessage(e);console.info(`Message from: ${t.address}:${t.port}`);const a=await this.keyManager.decryptData(s.message.toString()),i=await this.keyManager.decryptData(s.targetPubKey.toString()),o=await this.keyManager.decryptData(s.requestingPubKey.toString()),n=this.keyManager.getPublicKey();if(o.toString()==n){const e=null===(r=this.peerPubKeyMessages.get(i.toString()))||void 0===r?void 0:r.rawRandomMessage;if(a.toString()==(null==e?void 0:e.toString())){const e=s.responsePeerInfo;if(e){this.peerStore.add(e);const t=e.publicKey;this.peerPubKeyMessages.delete(t),console.log("New peer added to the store"),this.emit("found",e)}else this.emit("error","I got a validated response. But no peerInfo")}}else{const e=await this.keyManager.encryptData(Buffer.from(n),o),t=await this.keyManager.encryptData(a,o),r=await this.keyManager.encryptData(o,o),s=d.default.encodeHandshakeMessage(Buffer.from(e),Buffer.from(r),Buffer.from(t),this.peerStore.localPeerInfo);this.socket.send(s,0,s.length,c,l)}}catch(e){}}async requestPeerContact(e){const t=Buffer.from(e),r=n.default.randomBytes(16),s=await this.keyManager.encryptData(t,t),a=await this.keyManager.encryptData(r,t),i=await this.keyManager.encryptData(Buffer.from(this.keyManager.getPublicKey()),t);this.peerPubKeyMessages.set(e,{encryptedLocalPubKey:Buffer.from(i),encryptedPeerPubKey:Buffer.from(s),rawRandomMessage:r,encryptedRandomMessage:Buffer.from(a)})}}t.default=y},function(e,t){e.exports=require("dgram")},function(e,t){e.exports=require("events")},function(e,t,r){"use strict";function s(e){return new Promise((t,r)=>e.then(r,t))}Object.defineProperty(t,"__esModule",{value:!0}),t.randomString=function(){return Math.random().toString(36).replace(/[^a-z]+/g,"").substr(0,5)},t.firstPromiseFulfilled=function(e){return s(Promise.all(e.map(s)))}}])})); //# sourceMappingURL=polykey.js.map \ No newline at end of file diff --git a/dist/polykey.js.map b/dist/polykey.js.map index 49d0ff362..80c0de5cb 100644 --- a/dist/polykey.js.map +++ b/dist/polykey.js.map @@ -1 +1 @@ -{"version":3,"sources":["webpack://polykey/webpack/universalModuleDefinition","webpack://polykey/webpack/bootstrap","webpack://polykey/./node_modules/node-libs-browser/node_modules/buffer/index.js","webpack://polykey/./node_modules/path-browserify/index.js","webpack://polykey/./node_modules/node-libs-browser/node_modules/process/browser.js","webpack://polykey/./node_modules/crypto-browserify/index.js","webpack://polykey/./src/index.ts","webpack://polykey/./src/Polykey.ts","webpack://polykey/(webpack)/buildin/global.js","webpack://polykey/external \"base64-js\"","webpack://polykey/external \"ieee754\"","webpack://polykey/external \"isarray\"","webpack://polykey/./node_modules/os-browserify/browser.js","webpack://polykey/./src/Vault.ts","webpack://polykey/external \"futoin-hkdf\"","webpack://polykey/external \"encryptedfs\"","webpack://polykey/external \"virtualfs\"","webpack://polykey/external \"randombytes\"","webpack://polykey/external \"create-hash\"","webpack://polykey/external \"create-hmac\"","webpack://polykey/external \"browserify-sign/algos\"","webpack://polykey/external \"pbkdf2\"","webpack://polykey/external \"browserify-cipher\"","webpack://polykey/external \"diffie-hellman\"","webpack://polykey/external \"browserify-sign\"","webpack://polykey/external \"create-ecdh\"","webpack://polykey/external \"public-encrypt\"","webpack://polykey/external \"randomfill\"","webpack://polykey/external \"jsonfile\"","webpack://polykey/./src/KeyManager.ts","webpack://polykey/external \"util\"","webpack://polykey/external \"kbpgp\"","webpack://polykey/external \"zxcvbn\""],"names":["root","factory","exports","module","define","amd","this","installedModules","__webpack_require__","moduleId","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","base64","ieee754","isArray","kMaxLength","Buffer","TYPED_ARRAY_SUPPORT","createBuffer","that","length","RangeError","Uint8Array","__proto__","arg","encodingOrOffset","Error","allocUnsafe","from","TypeError","ArrayBuffer","array","byteOffset","byteLength","undefined","fromArrayLike","fromArrayBuffer","string","encoding","isEncoding","actual","write","slice","fromString","obj","isBuffer","len","checked","copy","buffer","val","type","data","fromObject","assertSize","size","toString","isView","loweredCase","utf8ToBytes","base64ToBytes","toLowerCase","slowToString","start","end","hexSlice","utf8Slice","asciiSlice","latin1Slice","base64Slice","utf16leSlice","swap","b","bidirectionalIndexOf","dir","isNaN","arrayIndexOf","indexOf","lastIndexOf","arr","indexSize","arrLength","valLength","String","read","buf","readUInt16BE","foundIndex","found","j","hexWrite","offset","Number","remaining","strLen","parsed","parseInt","substr","utf8Write","blitBuffer","asciiWrite","str","byteArray","push","charCodeAt","asciiToBytes","latin1Write","base64Write","ucs2Write","units","hi","lo","utf16leToBytes","fromByteArray","Math","min","res","secondByte","thirdByte","fourthByte","tempCodePoint","firstByte","codePoint","bytesPerSequence","codePoints","fromCharCode","apply","decodeCodePointsArray","SlowBuffer","alloc","INSPECT_MAX_BYTES","global","foo","subarray","e","typedArraySupport","poolSize","_augment","species","configurable","fill","allocUnsafeSlow","_isBuffer","compare","a","x","y","concat","list","pos","swap16","swap32","swap64","arguments","equals","inspect","max","match","join","target","thisStart","thisEnd","thisCopy","targetCopy","includes","isFinite","toJSON","Array","_arr","ret","out","toHex","bytes","checkOffset","ext","checkInt","objectWriteUInt16","littleEndian","objectWriteUInt32","checkIEEE754","writeFloat","noAssert","writeDouble","newBuf","sliceLen","readUIntLE","mul","readUIntBE","readUInt8","readUInt16LE","readUInt32LE","readUInt32BE","readIntLE","pow","readIntBE","readInt8","readInt16LE","readInt16BE","readInt32LE","readInt32BE","readFloatLE","readFloatBE","readDoubleLE","readDoubleBE","writeUIntLE","writeUIntBE","writeUInt8","floor","writeUInt16LE","writeUInt16BE","writeUInt32LE","writeUInt32BE","writeIntLE","limit","sub","writeIntBE","writeInt8","writeInt16LE","writeInt16BE","writeInt32LE","writeInt32BE","writeFloatLE","writeFloatBE","writeDoubleLE","writeDoubleBE","targetStart","set","code","INVALID_BASE64_RE","Infinity","leadSurrogate","toByteArray","trim","replace","stringtrim","base64clean","src","dst","normalizeArray","parts","allowAboveRoot","up","last","splice","unshift","filter","xs","f","resolve","resolvedPath","resolvedAbsolute","path","process","cwd","charAt","split","normalize","isAbsolute","trailingSlash","paths","index","relative","to","fromParts","toParts","samePartsLength","outputParts","sep","delimiter","dirname","hasRoot","matchedSlash","basename","extname","startDot","startPart","preDotState","cachedSetTimeout","cachedClearTimeout","defaultSetTimout","defaultClearTimeout","runTimeout","fun","setTimeout","clearTimeout","currentQueue","queue","draining","queueIndex","cleanUpNextTick","drainQueue","timeout","run","marker","runClearTimeout","Item","noop","nextTick","args","title","browser","env","argv","version","versions","on","addListener","once","off","removeListener","removeAllListeners","emit","prependListener","prependOnceListener","listeners","binding","chdir","umask","randomBytes","rng","pseudoRandomBytes","prng","createHash","Hash","createHmac","Hmac","algos","algoKeys","keys","hashes","getHashes","pbkdf2","pbkdf2Sync","aes","Cipher","createCipher","Cipheriv","createCipheriv","Decipher","createDecipher","Decipheriv","createDecipheriv","getCiphers","listCiphers","dh","DiffieHellmanGroup","createDiffieHellmanGroup","getDiffieHellman","createDiffieHellman","DiffieHellman","sign","createSign","Sign","createVerify","Verify","createECDH","publicEncrypt","privateEncrypt","publicDecrypt","privateDecrypt","rf","randomFill","randomFillSync","createCredentials","constants","default","km","polykeyPath","homedir","KeyManager","metadataPath","fs","vaults","Map","metadata","publicKeyPath","privateKeyPath","passphrase","initSync","existsSync","vaultName","secretName","getVault","secretExists","secret","vault","addSecret","err","removeSecret","getSecret","vaultExists","fileExists","vaultKey","mkdirSync","recursive","tags","writeMetadata","destroyVault","rmdirSync","has","delete","loadKeyPair","vaultPath","listSecrets","filePath","signaturePath","publicKey","keyBuffer","readFileSync","fileBuffer","signatureBuffer","verifyData","privateKey","privateKeyPassphrase","signedBuffer","signData","signedPath","writeFileSync","writeFile","validateVault","nodeAddr","node","id","addresses","forEach","ma","metadataTemplate","fileExistsSync","g","Function","window","require","endianness","hostname","location","loadavg","uptime","freemem","MAX_VALUE","totalmem","cpus","release","navigator","appVersion","networkInterfaces","getNetworkInterfaces","arch","platform","tmpdir","tmpDir","EOL","vfs","symKey","baseDir","keyLen","genSymKey","vfsInstance","VirtualFS","EncryptedFS","secrets","loadSecrets","readdirSync","asymKey","secretPath","secretBuf","writePath","fd","openSync","writeSync","kbpgp","F","openpgp","zxcvbn","polyKeyPath","keyPair","private","public","identity","storePath","derivedKeys","email","numBits","score","options","userid","primary","nbits","flags","certify_keys","sign_data","auth","encrypt_comm","encrypt_storage","expire_in","subkeys","Promise","reject","generate","export_pgp_public","pubKey","export_pgp_private","privKey","keypair","promises","readFile","getPublicKey","getPrivateKey","import_from_armored_pgp","armored","merge_pgp_private","is_pgp_locked","unlock_pgp","loadPrivateKey","loadPublicKey","loadIdentity","salt","promisify","keyPath","createPath","mkdir","withKey","keyPassphrase","async","resolvedIdentity","getIdentityFromPrivateKey","params","msg","sign_with","box","result_string","result_buffer","signature","ring","keyring","KeyRing","getIdentityFromPublicKey","add_key_manager","keyfetch","unbox","literals","ds","get_data_signer","get_key_manager","get_pgp_fingerprint"],"mappings":"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","file":"polykey.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"polykey\"] = factory();\n\telse\n\t\troot[\"polykey\"] = factory();\n})(this, function() {\nreturn "," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 5);\n","/*!\n * The buffer module from node.js, for the browser.\n *\n * @author Feross Aboukhadijeh \n * @license MIT\n */\n/* eslint-disable no-proto */\n\n'use strict'\n\nvar base64 = require('base64-js')\nvar ieee754 = require('ieee754')\nvar isArray = require('isarray')\n\nexports.Buffer = Buffer\nexports.SlowBuffer = SlowBuffer\nexports.INSPECT_MAX_BYTES = 50\n\n/**\n * If `Buffer.TYPED_ARRAY_SUPPORT`:\n * === true Use Uint8Array implementation (fastest)\n * === false Use Object implementation (most compatible, even IE6)\n *\n * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,\n * Opera 11.6+, iOS 4.2+.\n *\n * Due to various browser bugs, sometimes the Object implementation will be used even\n * when the browser supports typed arrays.\n *\n * Note:\n *\n * - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances,\n * See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438.\n *\n * - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function.\n *\n * - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of\n * incorrect length in some situations.\n\n * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they\n * get the Object implementation, which is slower but behaves correctly.\n */\nBuffer.TYPED_ARRAY_SUPPORT = global.TYPED_ARRAY_SUPPORT !== undefined\n ? global.TYPED_ARRAY_SUPPORT\n : typedArraySupport()\n\n/*\n * Export kMaxLength after typed array support is determined.\n */\nexports.kMaxLength = kMaxLength()\n\nfunction typedArraySupport () {\n try {\n var arr = new Uint8Array(1)\n arr.__proto__ = {__proto__: Uint8Array.prototype, foo: function () { return 42 }}\n return arr.foo() === 42 && // typed array instances can be augmented\n typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray`\n arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray`\n } catch (e) {\n return false\n }\n}\n\nfunction kMaxLength () {\n return Buffer.TYPED_ARRAY_SUPPORT\n ? 0x7fffffff\n : 0x3fffffff\n}\n\nfunction createBuffer (that, length) {\n if (kMaxLength() < length) {\n throw new RangeError('Invalid typed array length')\n }\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n // Return an augmented `Uint8Array` instance, for best performance\n that = new Uint8Array(length)\n that.__proto__ = Buffer.prototype\n } else {\n // Fallback: Return an object instance of the Buffer class\n if (that === null) {\n that = new Buffer(length)\n }\n that.length = length\n }\n\n return that\n}\n\n/**\n * The Buffer constructor returns instances of `Uint8Array` that have their\n * prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of\n * `Uint8Array`, so the returned instances will have all the node `Buffer` methods\n * and the `Uint8Array` methods. Square bracket notation works as expected -- it\n * returns a single octet.\n *\n * The `Uint8Array` prototype remains unmodified.\n */\n\nfunction Buffer (arg, encodingOrOffset, length) {\n if (!Buffer.TYPED_ARRAY_SUPPORT && !(this instanceof Buffer)) {\n return new Buffer(arg, encodingOrOffset, length)\n }\n\n // Common case.\n if (typeof arg === 'number') {\n if (typeof encodingOrOffset === 'string') {\n throw new Error(\n 'If encoding is specified then the first argument must be a string'\n )\n }\n return allocUnsafe(this, arg)\n }\n return from(this, arg, encodingOrOffset, length)\n}\n\nBuffer.poolSize = 8192 // not used by this implementation\n\n// TODO: Legacy, not needed anymore. Remove in next major version.\nBuffer._augment = function (arr) {\n arr.__proto__ = Buffer.prototype\n return arr\n}\n\nfunction from (that, value, encodingOrOffset, length) {\n if (typeof value === 'number') {\n throw new TypeError('\"value\" argument must not be a number')\n }\n\n if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) {\n return fromArrayBuffer(that, value, encodingOrOffset, length)\n }\n\n if (typeof value === 'string') {\n return fromString(that, value, encodingOrOffset)\n }\n\n return fromObject(that, value)\n}\n\n/**\n * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError\n * if value is a number.\n * Buffer.from(str[, encoding])\n * Buffer.from(array)\n * Buffer.from(buffer)\n * Buffer.from(arrayBuffer[, byteOffset[, length]])\n **/\nBuffer.from = function (value, encodingOrOffset, length) {\n return from(null, value, encodingOrOffset, length)\n}\n\nif (Buffer.TYPED_ARRAY_SUPPORT) {\n Buffer.prototype.__proto__ = Uint8Array.prototype\n Buffer.__proto__ = Uint8Array\n if (typeof Symbol !== 'undefined' && Symbol.species &&\n Buffer[Symbol.species] === Buffer) {\n // Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97\n Object.defineProperty(Buffer, Symbol.species, {\n value: null,\n configurable: true\n })\n }\n}\n\nfunction assertSize (size) {\n if (typeof size !== 'number') {\n throw new TypeError('\"size\" argument must be a number')\n } else if (size < 0) {\n throw new RangeError('\"size\" argument must not be negative')\n }\n}\n\nfunction alloc (that, size, fill, encoding) {\n assertSize(size)\n if (size <= 0) {\n return createBuffer(that, size)\n }\n if (fill !== undefined) {\n // Only pay attention to encoding if it's a string. This\n // prevents accidentally sending in a number that would\n // be interpretted as a start offset.\n return typeof encoding === 'string'\n ? createBuffer(that, size).fill(fill, encoding)\n : createBuffer(that, size).fill(fill)\n }\n return createBuffer(that, size)\n}\n\n/**\n * Creates a new filled Buffer instance.\n * alloc(size[, fill[, encoding]])\n **/\nBuffer.alloc = function (size, fill, encoding) {\n return alloc(null, size, fill, encoding)\n}\n\nfunction allocUnsafe (that, size) {\n assertSize(size)\n that = createBuffer(that, size < 0 ? 0 : checked(size) | 0)\n if (!Buffer.TYPED_ARRAY_SUPPORT) {\n for (var i = 0; i < size; ++i) {\n that[i] = 0\n }\n }\n return that\n}\n\n/**\n * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance.\n * */\nBuffer.allocUnsafe = function (size) {\n return allocUnsafe(null, size)\n}\n/**\n * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance.\n */\nBuffer.allocUnsafeSlow = function (size) {\n return allocUnsafe(null, size)\n}\n\nfunction fromString (that, string, encoding) {\n if (typeof encoding !== 'string' || encoding === '') {\n encoding = 'utf8'\n }\n\n if (!Buffer.isEncoding(encoding)) {\n throw new TypeError('\"encoding\" must be a valid string encoding')\n }\n\n var length = byteLength(string, encoding) | 0\n that = createBuffer(that, length)\n\n var actual = that.write(string, encoding)\n\n if (actual !== length) {\n // Writing a hex string, for example, that contains invalid characters will\n // cause everything after the first invalid character to be ignored. (e.g.\n // 'abxxcd' will be treated as 'ab')\n that = that.slice(0, actual)\n }\n\n return that\n}\n\nfunction fromArrayLike (that, array) {\n var length = array.length < 0 ? 0 : checked(array.length) | 0\n that = createBuffer(that, length)\n for (var i = 0; i < length; i += 1) {\n that[i] = array[i] & 255\n }\n return that\n}\n\nfunction fromArrayBuffer (that, array, byteOffset, length) {\n array.byteLength // this throws if `array` is not a valid ArrayBuffer\n\n if (byteOffset < 0 || array.byteLength < byteOffset) {\n throw new RangeError('\\'offset\\' is out of bounds')\n }\n\n if (array.byteLength < byteOffset + (length || 0)) {\n throw new RangeError('\\'length\\' is out of bounds')\n }\n\n if (byteOffset === undefined && length === undefined) {\n array = new Uint8Array(array)\n } else if (length === undefined) {\n array = new Uint8Array(array, byteOffset)\n } else {\n array = new Uint8Array(array, byteOffset, length)\n }\n\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n // Return an augmented `Uint8Array` instance, for best performance\n that = array\n that.__proto__ = Buffer.prototype\n } else {\n // Fallback: Return an object instance of the Buffer class\n that = fromArrayLike(that, array)\n }\n return that\n}\n\nfunction fromObject (that, obj) {\n if (Buffer.isBuffer(obj)) {\n var len = checked(obj.length) | 0\n that = createBuffer(that, len)\n\n if (that.length === 0) {\n return that\n }\n\n obj.copy(that, 0, 0, len)\n return that\n }\n\n if (obj) {\n if ((typeof ArrayBuffer !== 'undefined' &&\n obj.buffer instanceof ArrayBuffer) || 'length' in obj) {\n if (typeof obj.length !== 'number' || isnan(obj.length)) {\n return createBuffer(that, 0)\n }\n return fromArrayLike(that, obj)\n }\n\n if (obj.type === 'Buffer' && isArray(obj.data)) {\n return fromArrayLike(that, obj.data)\n }\n }\n\n throw new TypeError('First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.')\n}\n\nfunction checked (length) {\n // Note: cannot use `length < kMaxLength()` here because that fails when\n // length is NaN (which is otherwise coerced to zero.)\n if (length >= kMaxLength()) {\n throw new RangeError('Attempt to allocate Buffer larger than maximum ' +\n 'size: 0x' + kMaxLength().toString(16) + ' bytes')\n }\n return length | 0\n}\n\nfunction SlowBuffer (length) {\n if (+length != length) { // eslint-disable-line eqeqeq\n length = 0\n }\n return Buffer.alloc(+length)\n}\n\nBuffer.isBuffer = function isBuffer (b) {\n return !!(b != null && b._isBuffer)\n}\n\nBuffer.compare = function compare (a, b) {\n if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {\n throw new TypeError('Arguments must be Buffers')\n }\n\n if (a === b) return 0\n\n var x = a.length\n var y = b.length\n\n for (var i = 0, len = Math.min(x, y); i < len; ++i) {\n if (a[i] !== b[i]) {\n x = a[i]\n y = b[i]\n break\n }\n }\n\n if (x < y) return -1\n if (y < x) return 1\n return 0\n}\n\nBuffer.isEncoding = function isEncoding (encoding) {\n switch (String(encoding).toLowerCase()) {\n case 'hex':\n case 'utf8':\n case 'utf-8':\n case 'ascii':\n case 'latin1':\n case 'binary':\n case 'base64':\n case 'ucs2':\n case 'ucs-2':\n case 'utf16le':\n case 'utf-16le':\n return true\n default:\n return false\n }\n}\n\nBuffer.concat = function concat (list, length) {\n if (!isArray(list)) {\n throw new TypeError('\"list\" argument must be an Array of Buffers')\n }\n\n if (list.length === 0) {\n return Buffer.alloc(0)\n }\n\n var i\n if (length === undefined) {\n length = 0\n for (i = 0; i < list.length; ++i) {\n length += list[i].length\n }\n }\n\n var buffer = Buffer.allocUnsafe(length)\n var pos = 0\n for (i = 0; i < list.length; ++i) {\n var buf = list[i]\n if (!Buffer.isBuffer(buf)) {\n throw new TypeError('\"list\" argument must be an Array of Buffers')\n }\n buf.copy(buffer, pos)\n pos += buf.length\n }\n return buffer\n}\n\nfunction byteLength (string, encoding) {\n if (Buffer.isBuffer(string)) {\n return string.length\n }\n if (typeof ArrayBuffer !== 'undefined' && typeof ArrayBuffer.isView === 'function' &&\n (ArrayBuffer.isView(string) || string instanceof ArrayBuffer)) {\n return string.byteLength\n }\n if (typeof string !== 'string') {\n string = '' + string\n }\n\n var len = string.length\n if (len === 0) return 0\n\n // Use a for loop to avoid recursion\n var loweredCase = false\n for (;;) {\n switch (encoding) {\n case 'ascii':\n case 'latin1':\n case 'binary':\n return len\n case 'utf8':\n case 'utf-8':\n case undefined:\n return utf8ToBytes(string).length\n case 'ucs2':\n case 'ucs-2':\n case 'utf16le':\n case 'utf-16le':\n return len * 2\n case 'hex':\n return len >>> 1\n case 'base64':\n return base64ToBytes(string).length\n default:\n if (loweredCase) return utf8ToBytes(string).length // assume utf8\n encoding = ('' + encoding).toLowerCase()\n loweredCase = true\n }\n }\n}\nBuffer.byteLength = byteLength\n\nfunction slowToString (encoding, start, end) {\n var loweredCase = false\n\n // No need to verify that \"this.length <= MAX_UINT32\" since it's a read-only\n // property of a typed array.\n\n // This behaves neither like String nor Uint8Array in that we set start/end\n // to their upper/lower bounds if the value passed is out of range.\n // undefined is handled specially as per ECMA-262 6th Edition,\n // Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization.\n if (start === undefined || start < 0) {\n start = 0\n }\n // Return early if start > this.length. Done here to prevent potential uint32\n // coercion fail below.\n if (start > this.length) {\n return ''\n }\n\n if (end === undefined || end > this.length) {\n end = this.length\n }\n\n if (end <= 0) {\n return ''\n }\n\n // Force coersion to uint32. This will also coerce falsey/NaN values to 0.\n end >>>= 0\n start >>>= 0\n\n if (end <= start) {\n return ''\n }\n\n if (!encoding) encoding = 'utf8'\n\n while (true) {\n switch (encoding) {\n case 'hex':\n return hexSlice(this, start, end)\n\n case 'utf8':\n case 'utf-8':\n return utf8Slice(this, start, end)\n\n case 'ascii':\n return asciiSlice(this, start, end)\n\n case 'latin1':\n case 'binary':\n return latin1Slice(this, start, end)\n\n case 'base64':\n return base64Slice(this, start, end)\n\n case 'ucs2':\n case 'ucs-2':\n case 'utf16le':\n case 'utf-16le':\n return utf16leSlice(this, start, end)\n\n default:\n if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)\n encoding = (encoding + '').toLowerCase()\n loweredCase = true\n }\n }\n}\n\n// The property is used by `Buffer.isBuffer` and `is-buffer` (in Safari 5-7) to detect\n// Buffer instances.\nBuffer.prototype._isBuffer = true\n\nfunction swap (b, n, m) {\n var i = b[n]\n b[n] = b[m]\n b[m] = i\n}\n\nBuffer.prototype.swap16 = function swap16 () {\n var len = this.length\n if (len % 2 !== 0) {\n throw new RangeError('Buffer size must be a multiple of 16-bits')\n }\n for (var i = 0; i < len; i += 2) {\n swap(this, i, i + 1)\n }\n return this\n}\n\nBuffer.prototype.swap32 = function swap32 () {\n var len = this.length\n if (len % 4 !== 0) {\n throw new RangeError('Buffer size must be a multiple of 32-bits')\n }\n for (var i = 0; i < len; i += 4) {\n swap(this, i, i + 3)\n swap(this, i + 1, i + 2)\n }\n return this\n}\n\nBuffer.prototype.swap64 = function swap64 () {\n var len = this.length\n if (len % 8 !== 0) {\n throw new RangeError('Buffer size must be a multiple of 64-bits')\n }\n for (var i = 0; i < len; i += 8) {\n swap(this, i, i + 7)\n swap(this, i + 1, i + 6)\n swap(this, i + 2, i + 5)\n swap(this, i + 3, i + 4)\n }\n return this\n}\n\nBuffer.prototype.toString = function toString () {\n var length = this.length | 0\n if (length === 0) return ''\n if (arguments.length === 0) return utf8Slice(this, 0, length)\n return slowToString.apply(this, arguments)\n}\n\nBuffer.prototype.equals = function equals (b) {\n if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')\n if (this === b) return true\n return Buffer.compare(this, b) === 0\n}\n\nBuffer.prototype.inspect = function inspect () {\n var str = ''\n var max = exports.INSPECT_MAX_BYTES\n if (this.length > 0) {\n str = this.toString('hex', 0, max).match(/.{2}/g).join(' ')\n if (this.length > max) str += ' ... '\n }\n return ''\n}\n\nBuffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) {\n if (!Buffer.isBuffer(target)) {\n throw new TypeError('Argument must be a Buffer')\n }\n\n if (start === undefined) {\n start = 0\n }\n if (end === undefined) {\n end = target ? target.length : 0\n }\n if (thisStart === undefined) {\n thisStart = 0\n }\n if (thisEnd === undefined) {\n thisEnd = this.length\n }\n\n if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) {\n throw new RangeError('out of range index')\n }\n\n if (thisStart >= thisEnd && start >= end) {\n return 0\n }\n if (thisStart >= thisEnd) {\n return -1\n }\n if (start >= end) {\n return 1\n }\n\n start >>>= 0\n end >>>= 0\n thisStart >>>= 0\n thisEnd >>>= 0\n\n if (this === target) return 0\n\n var x = thisEnd - thisStart\n var y = end - start\n var len = Math.min(x, y)\n\n var thisCopy = this.slice(thisStart, thisEnd)\n var targetCopy = target.slice(start, end)\n\n for (var i = 0; i < len; ++i) {\n if (thisCopy[i] !== targetCopy[i]) {\n x = thisCopy[i]\n y = targetCopy[i]\n break\n }\n }\n\n if (x < y) return -1\n if (y < x) return 1\n return 0\n}\n\n// Finds either the first index of `val` in `buffer` at offset >= `byteOffset`,\n// OR the last index of `val` in `buffer` at offset <= `byteOffset`.\n//\n// Arguments:\n// - buffer - a Buffer to search\n// - val - a string, Buffer, or number\n// - byteOffset - an index into `buffer`; will be clamped to an int32\n// - encoding - an optional encoding, relevant is val is a string\n// - dir - true for indexOf, false for lastIndexOf\nfunction bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) {\n // Empty buffer means no match\n if (buffer.length === 0) return -1\n\n // Normalize byteOffset\n if (typeof byteOffset === 'string') {\n encoding = byteOffset\n byteOffset = 0\n } else if (byteOffset > 0x7fffffff) {\n byteOffset = 0x7fffffff\n } else if (byteOffset < -0x80000000) {\n byteOffset = -0x80000000\n }\n byteOffset = +byteOffset // Coerce to Number.\n if (isNaN(byteOffset)) {\n // byteOffset: it it's undefined, null, NaN, \"foo\", etc, search whole buffer\n byteOffset = dir ? 0 : (buffer.length - 1)\n }\n\n // Normalize byteOffset: negative offsets start from the end of the buffer\n if (byteOffset < 0) byteOffset = buffer.length + byteOffset\n if (byteOffset >= buffer.length) {\n if (dir) return -1\n else byteOffset = buffer.length - 1\n } else if (byteOffset < 0) {\n if (dir) byteOffset = 0\n else return -1\n }\n\n // Normalize val\n if (typeof val === 'string') {\n val = Buffer.from(val, encoding)\n }\n\n // Finally, search either indexOf (if dir is true) or lastIndexOf\n if (Buffer.isBuffer(val)) {\n // Special case: looking for empty string/buffer always fails\n if (val.length === 0) {\n return -1\n }\n return arrayIndexOf(buffer, val, byteOffset, encoding, dir)\n } else if (typeof val === 'number') {\n val = val & 0xFF // Search for a byte value [0-255]\n if (Buffer.TYPED_ARRAY_SUPPORT &&\n typeof Uint8Array.prototype.indexOf === 'function') {\n if (dir) {\n return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset)\n } else {\n return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset)\n }\n }\n return arrayIndexOf(buffer, [ val ], byteOffset, encoding, dir)\n }\n\n throw new TypeError('val must be string, number or Buffer')\n}\n\nfunction arrayIndexOf (arr, val, byteOffset, encoding, dir) {\n var indexSize = 1\n var arrLength = arr.length\n var valLength = val.length\n\n if (encoding !== undefined) {\n encoding = String(encoding).toLowerCase()\n if (encoding === 'ucs2' || encoding === 'ucs-2' ||\n encoding === 'utf16le' || encoding === 'utf-16le') {\n if (arr.length < 2 || val.length < 2) {\n return -1\n }\n indexSize = 2\n arrLength /= 2\n valLength /= 2\n byteOffset /= 2\n }\n }\n\n function read (buf, i) {\n if (indexSize === 1) {\n return buf[i]\n } else {\n return buf.readUInt16BE(i * indexSize)\n }\n }\n\n var i\n if (dir) {\n var foundIndex = -1\n for (i = byteOffset; i < arrLength; i++) {\n if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) {\n if (foundIndex === -1) foundIndex = i\n if (i - foundIndex + 1 === valLength) return foundIndex * indexSize\n } else {\n if (foundIndex !== -1) i -= i - foundIndex\n foundIndex = -1\n }\n }\n } else {\n if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength\n for (i = byteOffset; i >= 0; i--) {\n var found = true\n for (var j = 0; j < valLength; j++) {\n if (read(arr, i + j) !== read(val, j)) {\n found = false\n break\n }\n }\n if (found) return i\n }\n }\n\n return -1\n}\n\nBuffer.prototype.includes = function includes (val, byteOffset, encoding) {\n return this.indexOf(val, byteOffset, encoding) !== -1\n}\n\nBuffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) {\n return bidirectionalIndexOf(this, val, byteOffset, encoding, true)\n}\n\nBuffer.prototype.lastIndexOf = function lastIndexOf (val, byteOffset, encoding) {\n return bidirectionalIndexOf(this, val, byteOffset, encoding, false)\n}\n\nfunction hexWrite (buf, string, offset, length) {\n offset = Number(offset) || 0\n var remaining = buf.length - offset\n if (!length) {\n length = remaining\n } else {\n length = Number(length)\n if (length > remaining) {\n length = remaining\n }\n }\n\n // must be an even number of digits\n var strLen = string.length\n if (strLen % 2 !== 0) throw new TypeError('Invalid hex string')\n\n if (length > strLen / 2) {\n length = strLen / 2\n }\n for (var i = 0; i < length; ++i) {\n var parsed = parseInt(string.substr(i * 2, 2), 16)\n if (isNaN(parsed)) return i\n buf[offset + i] = parsed\n }\n return i\n}\n\nfunction utf8Write (buf, string, offset, length) {\n return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length)\n}\n\nfunction asciiWrite (buf, string, offset, length) {\n return blitBuffer(asciiToBytes(string), buf, offset, length)\n}\n\nfunction latin1Write (buf, string, offset, length) {\n return asciiWrite(buf, string, offset, length)\n}\n\nfunction base64Write (buf, string, offset, length) {\n return blitBuffer(base64ToBytes(string), buf, offset, length)\n}\n\nfunction ucs2Write (buf, string, offset, length) {\n return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length)\n}\n\nBuffer.prototype.write = function write (string, offset, length, encoding) {\n // Buffer#write(string)\n if (offset === undefined) {\n encoding = 'utf8'\n length = this.length\n offset = 0\n // Buffer#write(string, encoding)\n } else if (length === undefined && typeof offset === 'string') {\n encoding = offset\n length = this.length\n offset = 0\n // Buffer#write(string, offset[, length][, encoding])\n } else if (isFinite(offset)) {\n offset = offset | 0\n if (isFinite(length)) {\n length = length | 0\n if (encoding === undefined) encoding = 'utf8'\n } else {\n encoding = length\n length = undefined\n }\n // legacy write(string, encoding, offset, length) - remove in v0.13\n } else {\n throw new Error(\n 'Buffer.write(string, encoding, offset[, length]) is no longer supported'\n )\n }\n\n var remaining = this.length - offset\n if (length === undefined || length > remaining) length = remaining\n\n if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) {\n throw new RangeError('Attempt to write outside buffer bounds')\n }\n\n if (!encoding) encoding = 'utf8'\n\n var loweredCase = false\n for (;;) {\n switch (encoding) {\n case 'hex':\n return hexWrite(this, string, offset, length)\n\n case 'utf8':\n case 'utf-8':\n return utf8Write(this, string, offset, length)\n\n case 'ascii':\n return asciiWrite(this, string, offset, length)\n\n case 'latin1':\n case 'binary':\n return latin1Write(this, string, offset, length)\n\n case 'base64':\n // Warning: maxLength not taken into account in base64Write\n return base64Write(this, string, offset, length)\n\n case 'ucs2':\n case 'ucs-2':\n case 'utf16le':\n case 'utf-16le':\n return ucs2Write(this, string, offset, length)\n\n default:\n if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)\n encoding = ('' + encoding).toLowerCase()\n loweredCase = true\n }\n }\n}\n\nBuffer.prototype.toJSON = function toJSON () {\n return {\n type: 'Buffer',\n data: Array.prototype.slice.call(this._arr || this, 0)\n }\n}\n\nfunction base64Slice (buf, start, end) {\n if (start === 0 && end === buf.length) {\n return base64.fromByteArray(buf)\n } else {\n return base64.fromByteArray(buf.slice(start, end))\n }\n}\n\nfunction utf8Slice (buf, start, end) {\n end = Math.min(buf.length, end)\n var res = []\n\n var i = start\n while (i < end) {\n var firstByte = buf[i]\n var codePoint = null\n var bytesPerSequence = (firstByte > 0xEF) ? 4\n : (firstByte > 0xDF) ? 3\n : (firstByte > 0xBF) ? 2\n : 1\n\n if (i + bytesPerSequence <= end) {\n var secondByte, thirdByte, fourthByte, tempCodePoint\n\n switch (bytesPerSequence) {\n case 1:\n if (firstByte < 0x80) {\n codePoint = firstByte\n }\n break\n case 2:\n secondByte = buf[i + 1]\n if ((secondByte & 0xC0) === 0x80) {\n tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F)\n if (tempCodePoint > 0x7F) {\n codePoint = tempCodePoint\n }\n }\n break\n case 3:\n secondByte = buf[i + 1]\n thirdByte = buf[i + 2]\n if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {\n tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F)\n if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {\n codePoint = tempCodePoint\n }\n }\n break\n case 4:\n secondByte = buf[i + 1]\n thirdByte = buf[i + 2]\n fourthByte = buf[i + 3]\n if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {\n tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F)\n if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {\n codePoint = tempCodePoint\n }\n }\n }\n }\n\n if (codePoint === null) {\n // we did not generate a valid codePoint so insert a\n // replacement char (U+FFFD) and advance only 1 byte\n codePoint = 0xFFFD\n bytesPerSequence = 1\n } else if (codePoint > 0xFFFF) {\n // encode to utf16 (surrogate pair dance)\n codePoint -= 0x10000\n res.push(codePoint >>> 10 & 0x3FF | 0xD800)\n codePoint = 0xDC00 | codePoint & 0x3FF\n }\n\n res.push(codePoint)\n i += bytesPerSequence\n }\n\n return decodeCodePointsArray(res)\n}\n\n// Based on http://stackoverflow.com/a/22747272/680742, the browser with\n// the lowest limit is Chrome, with 0x10000 args.\n// We go 1 magnitude less, for safety\nvar MAX_ARGUMENTS_LENGTH = 0x1000\n\nfunction decodeCodePointsArray (codePoints) {\n var len = codePoints.length\n if (len <= MAX_ARGUMENTS_LENGTH) {\n return String.fromCharCode.apply(String, codePoints) // avoid extra slice()\n }\n\n // Decode in chunks to avoid \"call stack size exceeded\".\n var res = ''\n var i = 0\n while (i < len) {\n res += String.fromCharCode.apply(\n String,\n codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH)\n )\n }\n return res\n}\n\nfunction asciiSlice (buf, start, end) {\n var ret = ''\n end = Math.min(buf.length, end)\n\n for (var i = start; i < end; ++i) {\n ret += String.fromCharCode(buf[i] & 0x7F)\n }\n return ret\n}\n\nfunction latin1Slice (buf, start, end) {\n var ret = ''\n end = Math.min(buf.length, end)\n\n for (var i = start; i < end; ++i) {\n ret += String.fromCharCode(buf[i])\n }\n return ret\n}\n\nfunction hexSlice (buf, start, end) {\n var len = buf.length\n\n if (!start || start < 0) start = 0\n if (!end || end < 0 || end > len) end = len\n\n var out = ''\n for (var i = start; i < end; ++i) {\n out += toHex(buf[i])\n }\n return out\n}\n\nfunction utf16leSlice (buf, start, end) {\n var bytes = buf.slice(start, end)\n var res = ''\n for (var i = 0; i < bytes.length; i += 2) {\n res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256)\n }\n return res\n}\n\nBuffer.prototype.slice = function slice (start, end) {\n var len = this.length\n start = ~~start\n end = end === undefined ? len : ~~end\n\n if (start < 0) {\n start += len\n if (start < 0) start = 0\n } else if (start > len) {\n start = len\n }\n\n if (end < 0) {\n end += len\n if (end < 0) end = 0\n } else if (end > len) {\n end = len\n }\n\n if (end < start) end = start\n\n var newBuf\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n newBuf = this.subarray(start, end)\n newBuf.__proto__ = Buffer.prototype\n } else {\n var sliceLen = end - start\n newBuf = new Buffer(sliceLen, undefined)\n for (var i = 0; i < sliceLen; ++i) {\n newBuf[i] = this[i + start]\n }\n }\n\n return newBuf\n}\n\n/*\n * Need to make sure that buffer isn't trying to write out of bounds.\n */\nfunction checkOffset (offset, ext, length) {\n if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint')\n if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length')\n}\n\nBuffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) {\n offset = offset | 0\n byteLength = byteLength | 0\n if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n var val = this[offset]\n var mul = 1\n var i = 0\n while (++i < byteLength && (mul *= 0x100)) {\n val += this[offset + i] * mul\n }\n\n return val\n}\n\nBuffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) {\n offset = offset | 0\n byteLength = byteLength | 0\n if (!noAssert) {\n checkOffset(offset, byteLength, this.length)\n }\n\n var val = this[offset + --byteLength]\n var mul = 1\n while (byteLength > 0 && (mul *= 0x100)) {\n val += this[offset + --byteLength] * mul\n }\n\n return val\n}\n\nBuffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 1, this.length)\n return this[offset]\n}\n\nBuffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 2, this.length)\n return this[offset] | (this[offset + 1] << 8)\n}\n\nBuffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 2, this.length)\n return (this[offset] << 8) | this[offset + 1]\n}\n\nBuffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 4, this.length)\n\n return ((this[offset]) |\n (this[offset + 1] << 8) |\n (this[offset + 2] << 16)) +\n (this[offset + 3] * 0x1000000)\n}\n\nBuffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 4, this.length)\n\n return (this[offset] * 0x1000000) +\n ((this[offset + 1] << 16) |\n (this[offset + 2] << 8) |\n this[offset + 3])\n}\n\nBuffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) {\n offset = offset | 0\n byteLength = byteLength | 0\n if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n var val = this[offset]\n var mul = 1\n var i = 0\n while (++i < byteLength && (mul *= 0x100)) {\n val += this[offset + i] * mul\n }\n mul *= 0x80\n\n if (val >= mul) val -= Math.pow(2, 8 * byteLength)\n\n return val\n}\n\nBuffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) {\n offset = offset | 0\n byteLength = byteLength | 0\n if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n var i = byteLength\n var mul = 1\n var val = this[offset + --i]\n while (i > 0 && (mul *= 0x100)) {\n val += this[offset + --i] * mul\n }\n mul *= 0x80\n\n if (val >= mul) val -= Math.pow(2, 8 * byteLength)\n\n return val\n}\n\nBuffer.prototype.readInt8 = function readInt8 (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 1, this.length)\n if (!(this[offset] & 0x80)) return (this[offset])\n return ((0xff - this[offset] + 1) * -1)\n}\n\nBuffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 2, this.length)\n var val = this[offset] | (this[offset + 1] << 8)\n return (val & 0x8000) ? val | 0xFFFF0000 : val\n}\n\nBuffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 2, this.length)\n var val = this[offset + 1] | (this[offset] << 8)\n return (val & 0x8000) ? val | 0xFFFF0000 : val\n}\n\nBuffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 4, this.length)\n\n return (this[offset]) |\n (this[offset + 1] << 8) |\n (this[offset + 2] << 16) |\n (this[offset + 3] << 24)\n}\n\nBuffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 4, this.length)\n\n return (this[offset] << 24) |\n (this[offset + 1] << 16) |\n (this[offset + 2] << 8) |\n (this[offset + 3])\n}\n\nBuffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 4, this.length)\n return ieee754.read(this, offset, true, 23, 4)\n}\n\nBuffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 4, this.length)\n return ieee754.read(this, offset, false, 23, 4)\n}\n\nBuffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 8, this.length)\n return ieee754.read(this, offset, true, 52, 8)\n}\n\nBuffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 8, this.length)\n return ieee754.read(this, offset, false, 52, 8)\n}\n\nfunction checkInt (buf, value, offset, ext, max, min) {\n if (!Buffer.isBuffer(buf)) throw new TypeError('\"buffer\" argument must be a Buffer instance')\n if (value > max || value < min) throw new RangeError('\"value\" argument is out of bounds')\n if (offset + ext > buf.length) throw new RangeError('Index out of range')\n}\n\nBuffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) {\n value = +value\n offset = offset | 0\n byteLength = byteLength | 0\n if (!noAssert) {\n var maxBytes = Math.pow(2, 8 * byteLength) - 1\n checkInt(this, value, offset, byteLength, maxBytes, 0)\n }\n\n var mul = 1\n var i = 0\n this[offset] = value & 0xFF\n while (++i < byteLength && (mul *= 0x100)) {\n this[offset + i] = (value / mul) & 0xFF\n }\n\n return offset + byteLength\n}\n\nBuffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) {\n value = +value\n offset = offset | 0\n byteLength = byteLength | 0\n if (!noAssert) {\n var maxBytes = Math.pow(2, 8 * byteLength) - 1\n checkInt(this, value, offset, byteLength, maxBytes, 0)\n }\n\n var i = byteLength - 1\n var mul = 1\n this[offset + i] = value & 0xFF\n while (--i >= 0 && (mul *= 0x100)) {\n this[offset + i] = (value / mul) & 0xFF\n }\n\n return offset + byteLength\n}\n\nBuffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0)\n if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)\n this[offset] = (value & 0xff)\n return offset + 1\n}\n\nfunction objectWriteUInt16 (buf, value, offset, littleEndian) {\n if (value < 0) value = 0xffff + value + 1\n for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; ++i) {\n buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>>\n (littleEndian ? i : 1 - i) * 8\n }\n}\n\nBuffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset] = (value & 0xff)\n this[offset + 1] = (value >>> 8)\n } else {\n objectWriteUInt16(this, value, offset, true)\n }\n return offset + 2\n}\n\nBuffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset] = (value >>> 8)\n this[offset + 1] = (value & 0xff)\n } else {\n objectWriteUInt16(this, value, offset, false)\n }\n return offset + 2\n}\n\nfunction objectWriteUInt32 (buf, value, offset, littleEndian) {\n if (value < 0) value = 0xffffffff + value + 1\n for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; ++i) {\n buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff\n }\n}\n\nBuffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset + 3] = (value >>> 24)\n this[offset + 2] = (value >>> 16)\n this[offset + 1] = (value >>> 8)\n this[offset] = (value & 0xff)\n } else {\n objectWriteUInt32(this, value, offset, true)\n }\n return offset + 4\n}\n\nBuffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset] = (value >>> 24)\n this[offset + 1] = (value >>> 16)\n this[offset + 2] = (value >>> 8)\n this[offset + 3] = (value & 0xff)\n } else {\n objectWriteUInt32(this, value, offset, false)\n }\n return offset + 4\n}\n\nBuffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) {\n var limit = Math.pow(2, 8 * byteLength - 1)\n\n checkInt(this, value, offset, byteLength, limit - 1, -limit)\n }\n\n var i = 0\n var mul = 1\n var sub = 0\n this[offset] = value & 0xFF\n while (++i < byteLength && (mul *= 0x100)) {\n if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) {\n sub = 1\n }\n this[offset + i] = ((value / mul) >> 0) - sub & 0xFF\n }\n\n return offset + byteLength\n}\n\nBuffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) {\n var limit = Math.pow(2, 8 * byteLength - 1)\n\n checkInt(this, value, offset, byteLength, limit - 1, -limit)\n }\n\n var i = byteLength - 1\n var mul = 1\n var sub = 0\n this[offset + i] = value & 0xFF\n while (--i >= 0 && (mul *= 0x100)) {\n if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) {\n sub = 1\n }\n this[offset + i] = ((value / mul) >> 0) - sub & 0xFF\n }\n\n return offset + byteLength\n}\n\nBuffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80)\n if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)\n if (value < 0) value = 0xff + value + 1\n this[offset] = (value & 0xff)\n return offset + 1\n}\n\nBuffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset] = (value & 0xff)\n this[offset + 1] = (value >>> 8)\n } else {\n objectWriteUInt16(this, value, offset, true)\n }\n return offset + 2\n}\n\nBuffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset] = (value >>> 8)\n this[offset + 1] = (value & 0xff)\n } else {\n objectWriteUInt16(this, value, offset, false)\n }\n return offset + 2\n}\n\nBuffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset] = (value & 0xff)\n this[offset + 1] = (value >>> 8)\n this[offset + 2] = (value >>> 16)\n this[offset + 3] = (value >>> 24)\n } else {\n objectWriteUInt32(this, value, offset, true)\n }\n return offset + 4\n}\n\nBuffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)\n if (value < 0) value = 0xffffffff + value + 1\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset] = (value >>> 24)\n this[offset + 1] = (value >>> 16)\n this[offset + 2] = (value >>> 8)\n this[offset + 3] = (value & 0xff)\n } else {\n objectWriteUInt32(this, value, offset, false)\n }\n return offset + 4\n}\n\nfunction checkIEEE754 (buf, value, offset, ext, max, min) {\n if (offset + ext > buf.length) throw new RangeError('Index out of range')\n if (offset < 0) throw new RangeError('Index out of range')\n}\n\nfunction writeFloat (buf, value, offset, littleEndian, noAssert) {\n if (!noAssert) {\n checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38)\n }\n ieee754.write(buf, value, offset, littleEndian, 23, 4)\n return offset + 4\n}\n\nBuffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) {\n return writeFloat(this, value, offset, true, noAssert)\n}\n\nBuffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) {\n return writeFloat(this, value, offset, false, noAssert)\n}\n\nfunction writeDouble (buf, value, offset, littleEndian, noAssert) {\n if (!noAssert) {\n checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308)\n }\n ieee754.write(buf, value, offset, littleEndian, 52, 8)\n return offset + 8\n}\n\nBuffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) {\n return writeDouble(this, value, offset, true, noAssert)\n}\n\nBuffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) {\n return writeDouble(this, value, offset, false, noAssert)\n}\n\n// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)\nBuffer.prototype.copy = function copy (target, targetStart, start, end) {\n if (!start) start = 0\n if (!end && end !== 0) end = this.length\n if (targetStart >= target.length) targetStart = target.length\n if (!targetStart) targetStart = 0\n if (end > 0 && end < start) end = start\n\n // Copy 0 bytes; we're done\n if (end === start) return 0\n if (target.length === 0 || this.length === 0) return 0\n\n // Fatal error conditions\n if (targetStart < 0) {\n throw new RangeError('targetStart out of bounds')\n }\n if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds')\n if (end < 0) throw new RangeError('sourceEnd out of bounds')\n\n // Are we oob?\n if (end > this.length) end = this.length\n if (target.length - targetStart < end - start) {\n end = target.length - targetStart + start\n }\n\n var len = end - start\n var i\n\n if (this === target && start < targetStart && targetStart < end) {\n // descending copy from end\n for (i = len - 1; i >= 0; --i) {\n target[i + targetStart] = this[i + start]\n }\n } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) {\n // ascending copy from start\n for (i = 0; i < len; ++i) {\n target[i + targetStart] = this[i + start]\n }\n } else {\n Uint8Array.prototype.set.call(\n target,\n this.subarray(start, start + len),\n targetStart\n )\n }\n\n return len\n}\n\n// Usage:\n// buffer.fill(number[, offset[, end]])\n// buffer.fill(buffer[, offset[, end]])\n// buffer.fill(string[, offset[, end]][, encoding])\nBuffer.prototype.fill = function fill (val, start, end, encoding) {\n // Handle string cases:\n if (typeof val === 'string') {\n if (typeof start === 'string') {\n encoding = start\n start = 0\n end = this.length\n } else if (typeof end === 'string') {\n encoding = end\n end = this.length\n }\n if (val.length === 1) {\n var code = val.charCodeAt(0)\n if (code < 256) {\n val = code\n }\n }\n if (encoding !== undefined && typeof encoding !== 'string') {\n throw new TypeError('encoding must be a string')\n }\n if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) {\n throw new TypeError('Unknown encoding: ' + encoding)\n }\n } else if (typeof val === 'number') {\n val = val & 255\n }\n\n // Invalid ranges are not set to a default, so can range check early.\n if (start < 0 || this.length < start || this.length < end) {\n throw new RangeError('Out of range index')\n }\n\n if (end <= start) {\n return this\n }\n\n start = start >>> 0\n end = end === undefined ? this.length : end >>> 0\n\n if (!val) val = 0\n\n var i\n if (typeof val === 'number') {\n for (i = start; i < end; ++i) {\n this[i] = val\n }\n } else {\n var bytes = Buffer.isBuffer(val)\n ? val\n : utf8ToBytes(new Buffer(val, encoding).toString())\n var len = bytes.length\n for (i = 0; i < end - start; ++i) {\n this[i + start] = bytes[i % len]\n }\n }\n\n return this\n}\n\n// HELPER FUNCTIONS\n// ================\n\nvar INVALID_BASE64_RE = /[^+\\/0-9A-Za-z-_]/g\n\nfunction base64clean (str) {\n // Node strips out invalid characters like \\n and \\t from the string, base64-js does not\n str = stringtrim(str).replace(INVALID_BASE64_RE, '')\n // Node converts strings with length < 2 to ''\n if (str.length < 2) return ''\n // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not\n while (str.length % 4 !== 0) {\n str = str + '='\n }\n return str\n}\n\nfunction stringtrim (str) {\n if (str.trim) return str.trim()\n return str.replace(/^\\s+|\\s+$/g, '')\n}\n\nfunction toHex (n) {\n if (n < 16) return '0' + n.toString(16)\n return n.toString(16)\n}\n\nfunction utf8ToBytes (string, units) {\n units = units || Infinity\n var codePoint\n var length = string.length\n var leadSurrogate = null\n var bytes = []\n\n for (var i = 0; i < length; ++i) {\n codePoint = string.charCodeAt(i)\n\n // is surrogate component\n if (codePoint > 0xD7FF && codePoint < 0xE000) {\n // last char was a lead\n if (!leadSurrogate) {\n // no lead yet\n if (codePoint > 0xDBFF) {\n // unexpected trail\n if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n continue\n } else if (i + 1 === length) {\n // unpaired lead\n if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n continue\n }\n\n // valid lead\n leadSurrogate = codePoint\n\n continue\n }\n\n // 2 leads in a row\n if (codePoint < 0xDC00) {\n if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n leadSurrogate = codePoint\n continue\n }\n\n // valid surrogate pair\n codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000\n } else if (leadSurrogate) {\n // valid bmp char, but last char was a lead\n if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n }\n\n leadSurrogate = null\n\n // encode utf8\n if (codePoint < 0x80) {\n if ((units -= 1) < 0) break\n bytes.push(codePoint)\n } else if (codePoint < 0x800) {\n if ((units -= 2) < 0) break\n bytes.push(\n codePoint >> 0x6 | 0xC0,\n codePoint & 0x3F | 0x80\n )\n } else if (codePoint < 0x10000) {\n if ((units -= 3) < 0) break\n bytes.push(\n codePoint >> 0xC | 0xE0,\n codePoint >> 0x6 & 0x3F | 0x80,\n codePoint & 0x3F | 0x80\n )\n } else if (codePoint < 0x110000) {\n if ((units -= 4) < 0) break\n bytes.push(\n codePoint >> 0x12 | 0xF0,\n codePoint >> 0xC & 0x3F | 0x80,\n codePoint >> 0x6 & 0x3F | 0x80,\n codePoint & 0x3F | 0x80\n )\n } else {\n throw new Error('Invalid code point')\n }\n }\n\n return bytes\n}\n\nfunction asciiToBytes (str) {\n var byteArray = []\n for (var i = 0; i < str.length; ++i) {\n // Node's code seems to be doing this and not & 0x7F..\n byteArray.push(str.charCodeAt(i) & 0xFF)\n }\n return byteArray\n}\n\nfunction utf16leToBytes (str, units) {\n var c, hi, lo\n var byteArray = []\n for (var i = 0; i < str.length; ++i) {\n if ((units -= 2) < 0) break\n\n c = str.charCodeAt(i)\n hi = c >> 8\n lo = c % 256\n byteArray.push(lo)\n byteArray.push(hi)\n }\n\n return byteArray\n}\n\nfunction base64ToBytes (str) {\n return base64.toByteArray(base64clean(str))\n}\n\nfunction blitBuffer (src, dst, offset, length) {\n for (var i = 0; i < length; ++i) {\n if ((i + offset >= dst.length) || (i >= src.length)) break\n dst[i + offset] = src[i]\n }\n return i\n}\n\nfunction isnan (val) {\n return val !== val // eslint-disable-line no-self-compare\n}\n","// .dirname, .basename, and .extname methods are extracted from Node.js v8.11.1,\n// backported and transplited with Babel, with backwards-compat fixes\n\n// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n// resolves . and .. elements in a path array with directory names there\n// must be no slashes, empty elements, or device names (c:\\) in the array\n// (so also no leading and trailing slashes - it does not distinguish\n// relative and absolute paths)\nfunction normalizeArray(parts, allowAboveRoot) {\n // if the path tries to go above the root, `up` ends up > 0\n var up = 0;\n for (var i = parts.length - 1; i >= 0; i--) {\n var last = parts[i];\n if (last === '.') {\n parts.splice(i, 1);\n } else if (last === '..') {\n parts.splice(i, 1);\n up++;\n } else if (up) {\n parts.splice(i, 1);\n up--;\n }\n }\n\n // if the path is allowed to go above the root, restore leading ..s\n if (allowAboveRoot) {\n for (; up--; up) {\n parts.unshift('..');\n }\n }\n\n return parts;\n}\n\n// path.resolve([from ...], to)\n// posix version\nexports.resolve = function() {\n var resolvedPath = '',\n resolvedAbsolute = false;\n\n for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {\n var path = (i >= 0) ? arguments[i] : process.cwd();\n\n // Skip empty and invalid entries\n if (typeof path !== 'string') {\n throw new TypeError('Arguments to path.resolve must be strings');\n } else if (!path) {\n continue;\n }\n\n resolvedPath = path + '/' + resolvedPath;\n resolvedAbsolute = path.charAt(0) === '/';\n }\n\n // At this point the path should be resolved to a full absolute path, but\n // handle relative paths to be safe (might happen when process.cwd() fails)\n\n // Normalize the path\n resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) {\n return !!p;\n }), !resolvedAbsolute).join('/');\n\n return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';\n};\n\n// path.normalize(path)\n// posix version\nexports.normalize = function(path) {\n var isAbsolute = exports.isAbsolute(path),\n trailingSlash = substr(path, -1) === '/';\n\n // Normalize the path\n path = normalizeArray(filter(path.split('/'), function(p) {\n return !!p;\n }), !isAbsolute).join('/');\n\n if (!path && !isAbsolute) {\n path = '.';\n }\n if (path && trailingSlash) {\n path += '/';\n }\n\n return (isAbsolute ? '/' : '') + path;\n};\n\n// posix version\nexports.isAbsolute = function(path) {\n return path.charAt(0) === '/';\n};\n\n// posix version\nexports.join = function() {\n var paths = Array.prototype.slice.call(arguments, 0);\n return exports.normalize(filter(paths, function(p, index) {\n if (typeof p !== 'string') {\n throw new TypeError('Arguments to path.join must be strings');\n }\n return p;\n }).join('/'));\n};\n\n\n// path.relative(from, to)\n// posix version\nexports.relative = function(from, to) {\n from = exports.resolve(from).substr(1);\n to = exports.resolve(to).substr(1);\n\n function trim(arr) {\n var start = 0;\n for (; start < arr.length; start++) {\n if (arr[start] !== '') break;\n }\n\n var end = arr.length - 1;\n for (; end >= 0; end--) {\n if (arr[end] !== '') break;\n }\n\n if (start > end) return [];\n return arr.slice(start, end - start + 1);\n }\n\n var fromParts = trim(from.split('/'));\n var toParts = trim(to.split('/'));\n\n var length = Math.min(fromParts.length, toParts.length);\n var samePartsLength = length;\n for (var i = 0; i < length; i++) {\n if (fromParts[i] !== toParts[i]) {\n samePartsLength = i;\n break;\n }\n }\n\n var outputParts = [];\n for (var i = samePartsLength; i < fromParts.length; i++) {\n outputParts.push('..');\n }\n\n outputParts = outputParts.concat(toParts.slice(samePartsLength));\n\n return outputParts.join('/');\n};\n\nexports.sep = '/';\nexports.delimiter = ':';\n\nexports.dirname = function (path) {\n if (typeof path !== 'string') path = path + '';\n if (path.length === 0) return '.';\n var code = path.charCodeAt(0);\n var hasRoot = code === 47 /*/*/;\n var end = -1;\n var matchedSlash = true;\n for (var i = path.length - 1; i >= 1; --i) {\n code = path.charCodeAt(i);\n if (code === 47 /*/*/) {\n if (!matchedSlash) {\n end = i;\n break;\n }\n } else {\n // We saw the first non-path separator\n matchedSlash = false;\n }\n }\n\n if (end === -1) return hasRoot ? '/' : '.';\n if (hasRoot && end === 1) {\n // return '//';\n // Backwards-compat fix:\n return '/';\n }\n return path.slice(0, end);\n};\n\nfunction basename(path) {\n if (typeof path !== 'string') path = path + '';\n\n var start = 0;\n var end = -1;\n var matchedSlash = true;\n var i;\n\n for (i = path.length - 1; i >= 0; --i) {\n if (path.charCodeAt(i) === 47 /*/*/) {\n // If we reached a path separator that was not part of a set of path\n // separators at the end of the string, stop now\n if (!matchedSlash) {\n start = i + 1;\n break;\n }\n } else if (end === -1) {\n // We saw the first non-path separator, mark this as the end of our\n // path component\n matchedSlash = false;\n end = i + 1;\n }\n }\n\n if (end === -1) return '';\n return path.slice(start, end);\n}\n\n// Uses a mixed approach for backwards-compatibility, as ext behavior changed\n// in new Node.js versions, so only basename() above is backported here\nexports.basename = function (path, ext) {\n var f = basename(path);\n if (ext && f.substr(-1 * ext.length) === ext) {\n f = f.substr(0, f.length - ext.length);\n }\n return f;\n};\n\nexports.extname = function (path) {\n if (typeof path !== 'string') path = path + '';\n var startDot = -1;\n var startPart = 0;\n var end = -1;\n var matchedSlash = true;\n // Track the state of characters (if any) we see before our first dot and\n // after any path separator we find\n var preDotState = 0;\n for (var i = path.length - 1; i >= 0; --i) {\n var code = path.charCodeAt(i);\n if (code === 47 /*/*/) {\n // If we reached a path separator that was not part of a set of path\n // separators at the end of the string, stop now\n if (!matchedSlash) {\n startPart = i + 1;\n break;\n }\n continue;\n }\n if (end === -1) {\n // We saw the first non-path separator, mark this as the end of our\n // extension\n matchedSlash = false;\n end = i + 1;\n }\n if (code === 46 /*.*/) {\n // If this is our first dot, mark it as the start of our extension\n if (startDot === -1)\n startDot = i;\n else if (preDotState !== 1)\n preDotState = 1;\n } else if (startDot !== -1) {\n // We saw a non-dot and non-path separator before our dot, so we should\n // have a good chance at having a non-empty extension\n preDotState = -1;\n }\n }\n\n if (startDot === -1 || end === -1 ||\n // We saw a non-dot character immediately before the dot\n preDotState === 0 ||\n // The (right-most) trimmed path component is exactly '..'\n preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) {\n return '';\n }\n return path.slice(startDot, end);\n};\n\nfunction filter (xs, f) {\n if (xs.filter) return xs.filter(f);\n var res = [];\n for (var i = 0; i < xs.length; i++) {\n if (f(xs[i], i, xs)) res.push(xs[i]);\n }\n return res;\n}\n\n// String.prototype.substr - negative index don't work in IE8\nvar substr = 'ab'.substr(-1) === 'b'\n ? function (str, start, len) { return str.substr(start, len) }\n : function (str, start, len) {\n if (start < 0) start = str.length + start;\n return str.substr(start, len);\n }\n;\n","// shim for using process in browser\nvar process = module.exports = {};\n\n// cached from whatever global is present so that test runners that stub it\n// don't break things. But we need to wrap it in a try catch in case it is\n// wrapped in strict mode code which doesn't define any globals. It's inside a\n// function because try/catches deoptimize in certain engines.\n\nvar cachedSetTimeout;\nvar cachedClearTimeout;\n\nfunction defaultSetTimout() {\n throw new Error('setTimeout has not been defined');\n}\nfunction defaultClearTimeout () {\n throw new Error('clearTimeout has not been defined');\n}\n(function () {\n try {\n if (typeof setTimeout === 'function') {\n cachedSetTimeout = setTimeout;\n } else {\n cachedSetTimeout = defaultSetTimout;\n }\n } catch (e) {\n cachedSetTimeout = defaultSetTimout;\n }\n try {\n if (typeof clearTimeout === 'function') {\n cachedClearTimeout = clearTimeout;\n } else {\n cachedClearTimeout = defaultClearTimeout;\n }\n } catch (e) {\n cachedClearTimeout = defaultClearTimeout;\n }\n} ())\nfunction runTimeout(fun) {\n if (cachedSetTimeout === setTimeout) {\n //normal enviroments in sane situations\n return setTimeout(fun, 0);\n }\n // if setTimeout wasn't available but was latter defined\n if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {\n cachedSetTimeout = setTimeout;\n return setTimeout(fun, 0);\n }\n try {\n // when when somebody has screwed with setTimeout but no I.E. maddness\n return cachedSetTimeout(fun, 0);\n } catch(e){\n try {\n // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n return cachedSetTimeout.call(null, fun, 0);\n } catch(e){\n // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error\n return cachedSetTimeout.call(this, fun, 0);\n }\n }\n\n\n}\nfunction runClearTimeout(marker) {\n if (cachedClearTimeout === clearTimeout) {\n //normal enviroments in sane situations\n return clearTimeout(marker);\n }\n // if clearTimeout wasn't available but was latter defined\n if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {\n cachedClearTimeout = clearTimeout;\n return clearTimeout(marker);\n }\n try {\n // when when somebody has screwed with setTimeout but no I.E. maddness\n return cachedClearTimeout(marker);\n } catch (e){\n try {\n // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n return cachedClearTimeout.call(null, marker);\n } catch (e){\n // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.\n // Some versions of I.E. have different rules for clearTimeout vs setTimeout\n return cachedClearTimeout.call(this, marker);\n }\n }\n\n\n\n}\nvar queue = [];\nvar draining = false;\nvar currentQueue;\nvar queueIndex = -1;\n\nfunction cleanUpNextTick() {\n if (!draining || !currentQueue) {\n return;\n }\n draining = false;\n if (currentQueue.length) {\n queue = currentQueue.concat(queue);\n } else {\n queueIndex = -1;\n }\n if (queue.length) {\n drainQueue();\n }\n}\n\nfunction drainQueue() {\n if (draining) {\n return;\n }\n var timeout = runTimeout(cleanUpNextTick);\n draining = true;\n\n var len = queue.length;\n while(len) {\n currentQueue = queue;\n queue = [];\n while (++queueIndex < len) {\n if (currentQueue) {\n currentQueue[queueIndex].run();\n }\n }\n queueIndex = -1;\n len = queue.length;\n }\n currentQueue = null;\n draining = false;\n runClearTimeout(timeout);\n}\n\nprocess.nextTick = function (fun) {\n var args = new Array(arguments.length - 1);\n if (arguments.length > 1) {\n for (var i = 1; i < arguments.length; i++) {\n args[i - 1] = arguments[i];\n }\n }\n queue.push(new Item(fun, args));\n if (queue.length === 1 && !draining) {\n runTimeout(drainQueue);\n }\n};\n\n// v8 likes predictible objects\nfunction Item(fun, array) {\n this.fun = fun;\n this.array = array;\n}\nItem.prototype.run = function () {\n this.fun.apply(null, this.array);\n};\nprocess.title = 'browser';\nprocess.browser = true;\nprocess.env = {};\nprocess.argv = [];\nprocess.version = ''; // empty string to avoid regexp issues\nprocess.versions = {};\n\nfunction noop() {}\n\nprocess.on = noop;\nprocess.addListener = noop;\nprocess.once = noop;\nprocess.off = noop;\nprocess.removeListener = noop;\nprocess.removeAllListeners = noop;\nprocess.emit = noop;\nprocess.prependListener = noop;\nprocess.prependOnceListener = noop;\n\nprocess.listeners = function (name) { return [] }\n\nprocess.binding = function (name) {\n throw new Error('process.binding is not supported');\n};\n\nprocess.cwd = function () { return '/' };\nprocess.chdir = function (dir) {\n throw new Error('process.chdir is not supported');\n};\nprocess.umask = function() { return 0; };\n","'use strict'\n\nexports.randomBytes = exports.rng = exports.pseudoRandomBytes = exports.prng = require('randombytes')\nexports.createHash = exports.Hash = require('create-hash')\nexports.createHmac = exports.Hmac = require('create-hmac')\n\nvar algos = require('browserify-sign/algos')\nvar algoKeys = Object.keys(algos)\nvar hashes = ['sha1', 'sha224', 'sha256', 'sha384', 'sha512', 'md5', 'rmd160'].concat(algoKeys)\nexports.getHashes = function () {\n return hashes\n}\n\nvar p = require('pbkdf2')\nexports.pbkdf2 = p.pbkdf2\nexports.pbkdf2Sync = p.pbkdf2Sync\n\nvar aes = require('browserify-cipher')\n\nexports.Cipher = aes.Cipher\nexports.createCipher = aes.createCipher\nexports.Cipheriv = aes.Cipheriv\nexports.createCipheriv = aes.createCipheriv\nexports.Decipher = aes.Decipher\nexports.createDecipher = aes.createDecipher\nexports.Decipheriv = aes.Decipheriv\nexports.createDecipheriv = aes.createDecipheriv\nexports.getCiphers = aes.getCiphers\nexports.listCiphers = aes.listCiphers\n\nvar dh = require('diffie-hellman')\n\nexports.DiffieHellmanGroup = dh.DiffieHellmanGroup\nexports.createDiffieHellmanGroup = dh.createDiffieHellmanGroup\nexports.getDiffieHellman = dh.getDiffieHellman\nexports.createDiffieHellman = dh.createDiffieHellman\nexports.DiffieHellman = dh.DiffieHellman\n\nvar sign = require('browserify-sign')\n\nexports.createSign = sign.createSign\nexports.Sign = sign.Sign\nexports.createVerify = sign.createVerify\nexports.Verify = sign.Verify\n\nexports.createECDH = require('create-ecdh')\n\nvar publicEncrypt = require('public-encrypt')\n\nexports.publicEncrypt = publicEncrypt.publicEncrypt\nexports.privateEncrypt = publicEncrypt.privateEncrypt\nexports.publicDecrypt = publicEncrypt.publicDecrypt\nexports.privateDecrypt = publicEncrypt.privateDecrypt\n\n// the least I can do is make error messages for the rest of the node.js/crypto api.\n// ;[\n// 'createCredentials'\n// ].forEach(function (name) {\n// exports[name] = function () {\n// throw new Error([\n// 'sorry, ' + name + ' is not implemented yet',\n// 'we accept pull requests',\n// 'https://github.com/crypto-browserify/crypto-browserify'\n// ].join('\\n'))\n// }\n// })\n\nvar rf = require('randomfill')\n\nexports.randomFill = rf.randomFill\nexports.randomFillSync = rf.randomFillSync\n\nexports.createCredentials = function () {\n throw new Error([\n 'sorry, createCredentials is not implemented yet',\n 'we accept pull requests',\n 'https://github.com/crypto-browserify/crypto-browserify'\n ].join('\\n'))\n}\n\nexports.constants = {\n 'DH_CHECK_P_NOT_SAFE_PRIME': 2,\n 'DH_CHECK_P_NOT_PRIME': 1,\n 'DH_UNABLE_TO_CHECK_GENERATOR': 4,\n 'DH_NOT_SUITABLE_GENERATOR': 8,\n 'NPN_ENABLED': 1,\n 'ALPN_ENABLED': 1,\n 'RSA_PKCS1_PADDING': 1,\n 'RSA_SSLV23_PADDING': 2,\n 'RSA_NO_PADDING': 3,\n 'RSA_PKCS1_OAEP_PADDING': 4,\n 'RSA_X931_PADDING': 5,\n 'RSA_PKCS1_PSS_PADDING': 6,\n 'POINT_CONVERSION_COMPRESSED': 2,\n 'POINT_CONVERSION_UNCOMPRESSED': 4,\n 'POINT_CONVERSION_HYBRID': 6\n}\n","export { default } from '@polykey/Polykey'\n","import os from 'os'\nimport fs from 'fs'\nimport Path from 'path'\nimport Vault from '@polykey/Vault'\nimport crypto from 'crypto'\nimport jsonfile from 'jsonfile'\nimport { KeyManager } from '@polykey/KeyManager'\n\ntype Metadata = {\n vaults: {\n [vaultName: string]: {\n key: Buffer, tags: Array\n }\n }\n publicKeyPath: string | null\n privateKeyPath: string | null\n passphrase: string | null\n}\n\nconst vaultKeySize = 128/8 // in bytes\n\nexport default class Polykey {\n polykeyPath: string\n private fs: typeof fs\n private vaults:Map\n private key: Buffer\n private keySize: number\n private metadata: Metadata\n private metadataPath: string\n km: KeyManager\n\n private node: any\n\n constructor(\n km?: KeyManager,\n polykeyPath: string = `${os.homedir()}/.polykey`\n ) {\n this.km = km || new KeyManager(this.polykeyPath)\n this.polykeyPath = polykeyPath\n this.metadataPath = Path.join(this.polykeyPath, 'metadata')\n // Set file system\n this.fs = fs\n // Initialize reamining members\n this.vaults = new Map()\n this.metadata = {\n vaults: {},\n publicKeyPath: null,\n privateKeyPath: null,\n passphrase: null\n }\n // sync with polykey directory\n this.initSync()\n\n }\n\n static get KeyManager() {\n return KeyManager\n }\n private async fileExists(path: string): Promise {\n return this.fs.existsSync(path)\n }\n private fileExistsSync(path: string): boolean {\n return this.fs.existsSync(path)\n }\n\n /////////////\n // Secrets //\n /////////////\n async secretExists(vaultName: string, secretName: string): Promise {\n const vault = await this.getVault(vaultName)\n const secretExists = vault.secretExists(secretName)\n\n return secretExists\n }\n\n async addSecret(vaultName: string, secretName: string, secret: Buffer): Promise {\n let vault: Vault\n try {\n vault = await this.getVault(vaultName)\n vault.addSecret(secretName, secret)\n } catch(err) {\n throw err\n }\n }\n\n async removeSecret(vaultName: string, secretName: string): Promise {\n let vault: Vault\n try {\n vault = await this.getVault(vaultName)\n vault.removeSecret(secretName)\n } catch(err) {\n throw err\n }\n }\n\n async getSecret(vaultName: string, secretName: string): Promise {\n let vault: Vault\n let secret: string | Buffer\n try {\n vault = await this.getVault(vaultName)\n secret = vault.getSecret(secretName)\n } catch(err) {\n throw err\n }\n return secret\n }\n\n async copySecret(vaultName: string, secretName: string): Promise {\n let vault: Vault\n let secret: string | Buffer\n try {\n vault = await this.getVault(vaultName)\n secret = vault.getSecret(secretName)\n } catch(err) {\n throw err\n }\n return secret\n }\n\n /////////////\n // Vaults //\n /////////////\n async createVault(vaultName: string, key: Buffer | undefined = undefined): Promise {\n const path = Path.join(this.polykeyPath, vaultName)\n let vaultExists: boolean\n try {\n vaultExists = await this.fileExists(path)\n } catch(err) {\n throw err\n }\n\n if (vaultExists) {\n throw Error('Vault already exists!')\n }\n\n try {\n // Directory not present, create one\n this.fs.mkdirSync(path, {recursive:true})\n // Create key if not provided\n let vaultKey: Buffer\n if (key === undefined) {\n // Generate new key\n vaultKey = Buffer.from(crypto.randomBytes(vaultKeySize))\n } else {\n // Assign key if it is provided\n vaultKey = key\n }\n this.metadata.vaults[vaultName] = { key: vaultKey, tags: []}\n await this.writeMetadata()\n const vault = new Vault(vaultName, vaultKey, this.polykeyPath)\n this.vaults.set(vaultName, vault)\n return await this.getVault(vaultName)\n } catch (err) {\n // Delete vault dir and garbage collect\n await this.destroyVault(vaultName)\n throw err\n }\n }\n\n async vaultExists(vaultName: string): Promise {\n const path = Path.join(this.polykeyPath, vaultName)\n const vaultExists = this.fs.existsSync(path)\n\n return vaultExists\n }\n\n async destroyVault(vaultName: string) {\n\n // this is convenience function for removing all tags\n // and triggering garbage collection\n // destruction is a better word as we should ensure all traces is removed\n\n const path = Path.join(this.polykeyPath, vaultName)\n // Remove directory on file system\n if (this.fs.existsSync(path)) {\n this.fs.rmdirSync(path, {recursive: true})\n }\n // Remaining garbage collection:\n // Remove vault from vaults map\n if (this.vaults.has(vaultName)) {\n this.vaults.delete(vaultName)\n }\n // Remove from metadata\n if (this.metadata.vaults.hasOwnProperty(vaultName)) {\n delete this.metadata.vaults[vaultName]\n await this.writeMetadata()\n }\n\n const vaultPathExists = this.fs.existsSync(path)\n if (vaultPathExists) {\n throw(Error('Vault path could not be destroyed!'))\n }\n const vaultEntryExists = this.vaults.has(vaultName)\n if (vaultEntryExists) {\n throw(Error('Vault could not be removed from PolyKey!'))\n }\n const metaDataHasVault = this.metadata.vaults.hasOwnProperty(vaultName)\n if (metaDataHasVault) {\n throw(Error('Vault metadata could not be destroyed!'))\n }\n }\n\n async importKeyPair(privateKeyPath: string, publicKeyPath: string, passphrase: string = '') {\n await this.km.loadKeyPair(privateKeyPath, publicKeyPath, passphrase)\n this.metadata.publicKeyPath = publicKeyPath\n this.metadata.privateKeyPath = privateKeyPath\n this.metadata.passphrase = passphrase\n this.writeMetadata()\n }\n\n /* Validates whether all the artefacts needed to operate\n * a Vault are present. Namely this the vault directory\n * and the metadata for the vault containg the key\n */\n private async validateVault (vaultName: string): Promise {\n const existsMeta = this.metadata.vaults.hasOwnProperty(vaultName)\n if (!existsMeta) {\n throw Error('Vault metadata does not exist')\n }\n const vaultPath = Path.join(this.polykeyPath, vaultName)\n const existsFS = await this.fileExists(vaultPath)\n if (!existsFS) {\n throw Error('Vault directory does not exist')\n }\n }\n\n removeItem () {\n\n }\n\n listItems () {\n\n }\n\n listVaults(): string[] {\n return Array.from(this.vaults.keys())\n }\n\n async listSecrets(vaultName: string): Promise {\n const vault = await this.getVault(vaultName)\n return vault.listSecrets()\n }\n\n async verifyFile(filePath: string, signaturePath: string, publicKey: string | Buffer | undefined = undefined): Promise {\n try {\n // Get key if provided\n let keyBuffer: Buffer | undefined\n if (publicKey !== undefined) {\n if (typeof publicKey === 'string') { // Path\n // Read in from fs\n keyBuffer = Buffer.from(this.fs.readFileSync(publicKey))\n } else { // Buffer\n keyBuffer = publicKey\n }\n } else {\n // Load keypair into KeyManager from metadata\n const publicKeyPath = this.metadata.publicKeyPath\n const privateKeyPath = this.metadata.privateKeyPath\n const passphrase = this.metadata.passphrase\n if (publicKeyPath !== null && privateKeyPath !== null && passphrase !== null) {\n await this.km.loadKeyPair(\n privateKeyPath,\n publicKeyPath,\n passphrase\n )\n }\n }\n // Read in file buffer and signature\n const fileBuffer = Buffer.from(this.fs.readFileSync(filePath, undefined))\n const signatureBuffer = Buffer.from(this.fs.readFileSync(signaturePath, undefined))\n const verified = await this.km.verifyData(fileBuffer, signatureBuffer, keyBuffer)\n return verified\n } catch (err) {\n throw(err)\n }\n }\n\n async signFile(path: string, privateKey: string | Buffer | undefined = undefined, privateKeyPassphrase: string | undefined = undefined): Promise {\n try {\n // Get key if provided\n let keyBuffer: Buffer | undefined\n if (privateKey !== undefined) {\n if (typeof privateKey === 'string') { // Path\n // Read in from fs\n keyBuffer = Buffer.from(this.fs.readFileSync(privateKey))\n } else { // Buffer\n keyBuffer = privateKey\n }\n } else {\n // Load keypair into KeyManager from metadata\n const publicKeyPath = this.metadata.publicKeyPath\n const privateKeyPath = this.metadata.privateKeyPath\n const passphrase = this.metadata.passphrase\n if (publicKeyPath !== null && privateKeyPath !== null && passphrase !== null) {\n await this.km.loadKeyPair(\n privateKeyPath,\n publicKeyPath,\n passphrase\n )\n }\n }\n // Read file into buffer\n const buffer = Buffer.from(this.fs.readFileSync(path, undefined))\n // Sign the buffer\n const signedBuffer = await this.km.signData(buffer, keyBuffer, privateKeyPassphrase)\n // Write buffer to signed file\n const signedPath = `${path}.sig`\n this.fs.writeFileSync(signedPath, signedBuffer)\n return signedPath\n } catch (err) {\n throw(Error(`failed to sign file: ${err}`))\n }\n }\n\n // P2P operations\n async beginPolyKeyDaemon() {\n // const repos = new Git(this.polykeyPath, this.fs, {\n // fs: this.fs,\n // autoCreate: false\n // });\n // const port = 7005;\n\n // repos.on('push', (push) => {\n // console.log(`push ${push.repo}/${push.commit} (${push.branch})`);\n // push.accept();\n // });\n\n // repos.on('fetch', (fetch) => {\n // console.log(`fetch ${fetch.commit}`);\n // fetch.accept();\n // });\n\n // repos.listen(port, null, () => {\n // console.log(`node-git-server running at http://localhost:${port}`)\n // })\n\n // return `ip4/127.0.0.1/tcp/${port}`\n }\n\n tagVault() {\n\n }\n\n untagVault() {\n\n }\n\n shareVault() {\n\n }\n\n unshareVault() {\n\n }\n\n\n /* ============ HELPERS =============== */\n private async writeMetadata(): Promise {\n try {\n await jsonfile.writeFile(this.metadataPath, this.metadata)\n } catch (err) {\n throw Error(\"Error writing vault key to config file\")\n }\n }\n\n private async getVault(vaultName: string): Promise {\n if (this.vaults.has(vaultName)) {\n const vault = this.vaults.get(vaultName)\n if (vault) {\n return vault\n }\n }\n // vault not in map, create new instance\n try {\n await this.validateVault(vaultName)\n } catch(err) {\n throw err\n }\n const vaultKey = this.metadata.vaults[vaultName].key\n const vault = new Vault(vaultName, vaultKey, this.polykeyPath)\n this.vaults.set(vaultName, vault)\n return vault\n }\n\n async getNodeAddrs(): Promise {\n let nodeAddr: string[] = []\n // console.log('where is the repo?');\n // console.log(await this.node.repo.stat())\n const addr = await this.node.id()\n addr.addresses.forEach((ma) => {\n nodeAddr.push(`${ma.toString()}`)\n })\n return nodeAddr\n }\n\n initSync(): void {\n // check if .polykey exists\n // make folder if doesn't\n if (!this.fs.existsSync(this.polykeyPath)) {\n this.fs.mkdirSync(this.polykeyPath, {recursive: true})\n const metadataTemplate = {\n vaults: {},\n publicKeyPath: null,\n privateKeyPath: null,\n passphrase: null\n }\n jsonfile.writeFileSync(this.metadataPath, metadataTemplate)\n this.metadata = metadataTemplate\n } else if (this.fs.existsSync(this.metadataPath)) {\n this.metadata = jsonfile.readFileSync(this.metadataPath)\n }\n\n // Load all of the vaults into memory\n for (const vaultName in this.metadata.vaults) {\n if (this.metadata.vaults.hasOwnProperty(vaultName)) {\n const path = Path.join(this.polykeyPath, vaultName)\n if (this.fileExistsSync(path)) {\n try {\n const vaultKey = Buffer.from(this.metadata.vaults[vaultName].key)\n const vault = new Vault(vaultName, vaultKey, this.polykeyPath)\n this.vaults.set(vaultName, vault)\n } catch (err) {\n throw(err)\n }\n }\n }\n }\n }\n\n loadKey(path: string | Buffer): Buffer {\n if (path instanceof Buffer) {\n return path\n }\n const keyBuf = Buffer.from(this.fs.readFileSync(path, undefined))\n return keyBuf\n }\n}\n","var g;\n\n// This works in non-strict mode\ng = (function() {\n\treturn this;\n})();\n\ntry {\n\t// This works if eval is allowed (see CSP)\n\tg = g || new Function(\"return this\")();\n} catch (e) {\n\t// This works if the window reference is available\n\tif (typeof window === \"object\") g = window;\n}\n\n// g can still be undefined, but nothing to do about it...\n// We return undefined, instead of nothing here, so it's\n// easier to handle this case. if(!global) { ...}\n\nmodule.exports = g;\n","module.exports = require(\"base64-js\");","module.exports = require(\"ieee754\");","module.exports = require(\"isarray\");","exports.endianness = function () { return 'LE' };\n\nexports.hostname = function () {\n if (typeof location !== 'undefined') {\n return location.hostname\n }\n else return '';\n};\n\nexports.loadavg = function () { return [] };\n\nexports.uptime = function () { return 0 };\n\nexports.freemem = function () {\n return Number.MAX_VALUE;\n};\n\nexports.totalmem = function () {\n return Number.MAX_VALUE;\n};\n\nexports.cpus = function () { return [] };\n\nexports.type = function () { return 'Browser' };\n\nexports.release = function () {\n if (typeof navigator !== 'undefined') {\n return navigator.appVersion;\n }\n return '';\n};\n\nexports.networkInterfaces\n= exports.getNetworkInterfaces\n= function () { return {} };\n\nexports.arch = function () { return 'javascript' };\n\nexports.platform = function () { return 'browser' };\n\nexports.tmpdir = exports.tmpDir = function () {\n return '/tmp';\n};\n\nexports.EOL = '\\n';\n\nexports.homedir = function () {\n\treturn '/'\n};\n","import fs from 'fs'\nimport Path from 'path'\nimport hkdf from 'futoin-hkdf'\nimport { EncryptedFS } from 'encryptedfs'\n\nconst vfs = require('virtualfs')\n\nexport default class Vault {\n\n private key: Buffer\n private keyLen: number\n name: string\n private fs: EncryptedFS\n private secrets: Map\n private vaultPath: string\n constructor(\n name: string,\n symKey: Buffer,\n baseDir: string\n ) {\n // how do we create pub/priv key pair?\n // do we use the same gpg pub/priv keypair\n this.keyLen = 32\n this.key = this.genSymKey(symKey, this.keyLen)\n // Set filesystem\n const vfsInstance = new vfs.VirtualFS\n\n this.fs = new EncryptedFS(\n symKey,\n vfsInstance,\n vfsInstance,\n fs,\n process\n )\n\n this.name = name\n this.vaultPath = Path.join(baseDir, name)\n // make the vault directory\n this.fs.mkdirSync(this.vaultPath, {recursive: true})\n this.secrets = new Map()\n\n this.loadSecrets()\n }\n\n loadSecrets() {\n const secrets = fs.readdirSync(this.vaultPath, undefined)\n\n for (const secret of secrets) {\n this.secrets.set(secret, null)\n }\n }\n\n genSymKey(asymKey: Buffer, keyLen: number): Buffer {\n return Buffer.from(hkdf(asymKey.toString(), keyLen))\n }\n\n secretExists(secretName: string) : boolean {\n const secretPath = Path.join(this.vaultPath, secretName)\n return this.secrets.has(secretName) && this.fs.existsSync(secretPath)\n }\n\n addSecret (secretName: string, secretBuf: Buffer): void {\n // TODO: check if secret already exists\n const writePath = Path.join(this.vaultPath, secretName)\n // TODO: use aysnc methods\n const fd = this.fs.openSync(writePath, 'w')\n this.fs.writeSync(fd, secretBuf, 0, secretBuf.length, 0)\n this.secrets.set(secretName, secretBuf)\n // TODO: close file or use write file sync\n }\n\n getSecret(secretName: string): Buffer | string {\n if (this.secrets.has(secretName)) {\n const secret = this.secrets.get(secretName)\n if (secret) {\n return secret\n } else {\n const secretPath = Path.join(this.vaultPath, secretName)\n // TODO: this should be async\n const secretBuf = this.fs.readFileSync(secretPath, {})\n this.secrets.set(secretName, secretBuf)\n return secretBuf\n }\n }\n throw Error('Secret: ' + secretName + ' does not exist')\n }\n\n removeSecret (secretName: string): void {\n if (this.secrets.has(secretName)) {\n const successful = this.secrets.delete(secretName)\n if (successful) {\n return\n }\n throw Error('Secret: ' + secretName + ' was not removed')\n }\n throw Error('Secret: ' + secretName + ' does not exist')\n }\n\n listSecrets(): string[] {\n let secrets: string[] = Array.from(this.secrets.keys())\n return secrets\n }\n\n tagVault() {\n\n }\n\n untagVault() {\n\n }\n\n shareVault() {\n }\n\n unshareVault() {\n }\n\n // ============== Helper methods ============== //\n\n}\n","module.exports = require(\"futoin-hkdf\");","module.exports = require(\"encryptedfs\");","module.exports = require(\"virtualfs\");","module.exports = require(\"randombytes\");","module.exports = require(\"create-hash\");","module.exports = require(\"create-hmac\");","module.exports = require(\"browserify-sign/algos\");","module.exports = require(\"pbkdf2\");","module.exports = require(\"browserify-cipher\");","module.exports = require(\"diffie-hellman\");","module.exports = require(\"browserify-sign\");","module.exports = require(\"create-ecdh\");","module.exports = require(\"public-encrypt\");","module.exports = require(\"randomfill\");","module.exports = require(\"jsonfile\");","import fs from 'fs'\nimport Path from 'path'\nimport crypto from 'crypto'\nimport { promisify } from 'util'\n\n// js imports\nconst kbpgp = require('kbpgp')\nvar F = kbpgp[\"const\"].openpgp\nconst zxcvbn = require('zxcvbn')\n\ntype KeyPair = {\n private: string,\n public: string,\n passphrase: string\n}\n\nclass KeyManager {\n private keyPair: KeyPair = {private: '', public: '', passphrase: ''}\n private identity: Object | undefined = undefined\n private derivedKeys: Map\n private passphrase!: string\n\n storePath: string\n\n constructor(\n polyKeyPath: string = '~/.polykey/'\n ) {\n this.storePath = polyKeyPath\n\n this.derivedKeys = new Map()\n }\n\n // return {private: string, public: string}\n async generateKeyPair(name: string, email: string, passphrase: string, numBits: number = 4096): Promise {\n // Validate passphrase\n const passValidation = zxcvbn(passphrase)\n // The following is an arbitrary delineation of desirable scores\n if (passValidation.score < 2) {\n throw new Error(`passphrase score for new keypair is below 2!`)\n }\n\n // Define options\n var options = {\n userid: `${name} <${email}>`,\n primary: {\n nbits: 4096,\n flags: F.certify_keys | F.sign_data | F.auth | F.encrypt_comm | F.encrypt_storage,\n expire_in: 0 // never expire\n },\n subkeys: [\n // {\n // nbits: 2048,\n // flags: F.sign_data,\n // expire_in: 86400 * 365 * 8 // 8 years\n // }\n ]\n }\n\n this.passphrase = passphrase\n\n return new Promise((resolve, reject) => {\n kbpgp.KeyManager.generate(options, (err, identity) => {\n identity.sign({}, (err) => {\n if (err) {\n reject(err)\n }\n // Export pub key first\n identity.export_pgp_public({}, (err, pubKey) => {\n if (err) {\n reject(err)\n }\n // Finally export priv key\n identity.export_pgp_private({passphrase: passphrase}, (err, privKey) => {\n if (err) {\n reject(err)\n }\n // Resolve to parent promise\n const keypair = { private: privKey, public: pubKey, passphrase: passphrase }\n this.keyPair = keypair\n // Set the new identity\n this.identity = identity\n\n resolve(keypair)\n })\n })\n })\n })\n })\n }\n\n getKeyPair(): KeyPair {\n return this.keyPair\n }\n\n getPublicKey(): string {\n return this.keyPair.public\n }\n\n getPrivateKey(): string {\n return this.keyPair.private\n }\n\n async loadPrivateKey(privateKey: string | Buffer, passphrase: string = ''): Promise {\n try {\n let keyBuffer: Buffer\n if (typeof privateKey === 'string') {\n keyBuffer = Buffer.from(await fs.promises.readFile(privateKey))\n } else {\n keyBuffer = privateKey\n }\n this.keyPair.private = keyBuffer.toString()\n\n if (passphrase) {\n this.passphrase = passphrase\n }\n } catch (err) {\n throw(err)\n }\n }\n\n async loadPublicKey(publicKey: string | Buffer): Promise {\n try {\n let keyBuffer: Buffer\n if (typeof publicKey === 'string') {\n keyBuffer = Buffer.from(await fs.promises.readFile(publicKey))\n } else {\n keyBuffer = publicKey\n }\n this.keyPair.public = keyBuffer.toString()\n } catch (err) {\n throw(err)\n }\n }\n\n async loadIdentity(passphrase: string): Promise {\n return new Promise((resolve, reject) => {\n const pubKey: string = this.getPublicKey()\n const privKey: string = this.getPrivateKey()\n\n kbpgp.KeyManager.import_from_armored_pgp({armored: pubKey}, (err, identity) => {\n if (err) {\n reject(err)\n }\n\n identity.merge_pgp_private({\n armored: privKey\n }, (err) => {\n if (err) {\n reject(err)\n }\n\n if (identity.is_pgp_locked()) {\n identity.unlock_pgp({\n passphrase: passphrase\n }, (err) => {\n if (err) {\n reject(err)\n }\n\n this.identity = identity\n resolve()\n })\n } else {\n this.identity = identity\n resolve()\n }\n })\n })\n })\n }\n\n async loadKeyPair(publicKey: string | Buffer, privateKey: string | Buffer, passphrase: string = '') {\n await this.loadPrivateKey(privateKey)\n await this.loadPublicKey(publicKey)\n await this.loadIdentity(passphrase)\n\n if (passphrase) {\n this.passphrase\n }\n }\n\n async exportPrivateKey(path: string): Promise {\n await fs.promises.writeFile(path, this.keyPair.private)\n }\n\n async exportPublicKey(path: string): Promise {\n await fs.promises.writeFile(path, this.keyPair.public)\n }\n\n // symmetric key generation\n generateKeySync(name: string, passphrase: string): Buffer {\n const salt = crypto.randomBytes(32)\n this.derivedKeys[name] = crypto.pbkdf2Sync(passphrase , salt, 10000, 256/8, 'sha256')\n\n return this.derivedKeys[name]\n }\n\n async generateKey(name: string, passphrase: string): Promise {\n const salt = crypto.randomBytes(32)\n this.derivedKeys[name] = await promisify(crypto.pbkdf2)(passphrase , salt, 10000, 256/8, 'sha256')\n\n return this.derivedKeys[name]\n }\n\n importKeySync(name: string, keyPath: string): void {\n this.derivedKeys[name] = fs.readFileSync(keyPath)\n }\n\n async importKey(name: string, keyPath: string): Promise {\n this.derivedKeys[name] = await fs.promises.readFile(keyPath)\n }\n\n importKeyBuffer(name: string, key: Buffer): void {\n this.derivedKeys[name] = key\n }\n\n async exportKey(name: string, path: string, createPath?: boolean): Promise {\n if (!this.derivedKeys[name]) {\n throw Error(`There is no key loaded for name: ${name}`)\n }\n if (createPath) {\n await fs.promises.mkdir(Path.dirname(path), {recursive: true})\n }\n await fs.promises.writeFile(path, this.derivedKeys[name])\n }\n\n exportKeySync(path: string, createPath?: boolean): void {\n if (!this.derivedKeys[name]) {\n throw Error(`There is no key loaded for name: ${name}`)\n }\n if (createPath) {\n fs.mkdirSync(Path.dirname(path), {recursive: true})\n }\n fs.writeFileSync(path, this.derivedKeys[name])\n }\n\n async getIdentityFromPublicKey(pubKey: Buffer): Promise {\n return new Promise((resolve, reject) => {\n kbpgp.KeyManager.import_from_armored_pgp({armored: pubKey}, (err, identity) => {\n if (err) {\n reject(err)\n }\n resolve(identity)\n })\n })\n }\n\n async getIdentityFromPrivateKey(privKey: Buffer, passphrase: string): Promise {\n return new Promise((resolve, reject) => {\n kbpgp.KeyManager.import_from_armored_pgp({armored: privKey}, (err, identity) => {\n if (err) {\n reject(err)\n }\n if (identity.is_pgp_locked()) {\n identity.unlock_pgp({\n passphrase: passphrase\n }, (err) => {\n if (err) {\n reject(err)\n }\n resolve(identity)\n });\n } else {\n resolve(identity)\n }\n })\n })\n }\n\n // Sign data\n signData(data: Buffer | string, withKey: Buffer | undefined = undefined, keyPassphrase: string | undefined = undefined): Promise {\n return new Promise(async (resolve, reject) => {\n let resolvedIdentity: Object\n if (withKey !== undefined) {\n if (keyPassphrase === undefined) {\n reject(Error('passphrase for private key was not provided'))\n }\n resolvedIdentity = await this.getIdentityFromPrivateKey(withKey, keyPassphrase!)\n } else if (this.identity !== undefined) {\n resolvedIdentity = this.identity\n } else {\n throw(Error('no identity available for signing'))\n }\n const params = {\n msg: data,\n sign_with: resolvedIdentity\n }\n kbpgp.box(params, (err: Error, result_string: string, result_buffer: Buffer) => {\n if (err) {\n reject(err)\n }\n resolve(Buffer.from(result_string))\n })\n })\n }\n\n // Verify data\n verifyData(data: Buffer | string, signature: Buffer, withKey: Buffer | undefined = undefined): Promise {\n return new Promise(async (resolve, reject) => {\n var ring = new kbpgp.keyring.KeyRing;\n let resolvedIdentity: Object\n if (withKey !== undefined) {\n resolvedIdentity = await this.getIdentityFromPublicKey(withKey)\n } else if (this.identity !== undefined) {\n resolvedIdentity = this.identity\n } else {\n throw(Error('no identity available for signing'))\n }\n\n ring.add_key_manager(this.identity)\n const params = {\n armored: signature,\n data: data,\n keyfetch: ring\n }\n kbpgp.unbox(params, (err, literals) => {\n if (err) {\n reject(err)\n }\n let ds = literals[0].get_data_signer()\n let km: any\n if (ds) {\n km = ds.get_key_manager()\n }\n if (km) {\n resolve(km.get_pgp_fingerprint().toString('hex'));\n } else {\n reject(Error('could not verify file'))\n }\n })\n })\n }\n\n getKey(name: string): Buffer {\n return this.derivedKeys[name]\n }\n\n isLoaded(): boolean {\n if (this.derivedKeys[name]) {\n return true\n }\n return false\n }\n}\n\nexport { KeyManager, KeyPair}\n","module.exports = require(\"util\");","module.exports = require(\"kbpgp\");","module.exports = require(\"zxcvbn\");"],"sourceRoot":""} \ No newline at end of file +{"version":3,"sources":["webpack://polykey/webpack/universalModuleDefinition","webpack://polykey/webpack/bootstrap","webpack://polykey/external \"path\"","webpack://polykey/external \"fs\"","webpack://polykey/external \"crypto\"","webpack://polykey/./src/lib/PeerStore/PeerInfo.ts","webpack://polykey/./src/lib/RPC/RPCMessage.ts","webpack://polykey/./src/lib/index.ts","webpack://polykey/./src/lib/Polykey.ts","webpack://polykey/external \"os\"","webpack://polykey/external \"jsonfile\"","webpack://polykey/./src/lib/Vault.ts","webpack://polykey/external \"futoin-hkdf\"","webpack://polykey/external \"encryptedfs\"","webpack://polykey/external \"virtualfs\"","webpack://polykey/./src/lib/KeyManager.ts","webpack://polykey/external \"kbpgp\"","webpack://polykey/external \"util\"","webpack://polykey/./src/lib/PeerStore/PeerStore.ts","webpack://polykey/external \"protobufjs\"","webpack://polykey/./src/lib/P2P/PeerDiscovery.ts","webpack://polykey/external \"node-fetch\"","webpack://polykey/./src/lib/P2P/MulticastBroadcaster.ts","webpack://polykey/external \"dgram\"","webpack://polykey/external \"events\"","webpack://polykey/./src/lib/utils.ts"],"names":["root","factory","exports","module","define","amd","this","installedModules","__webpack_require__","moduleId","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","require","Address","ip","port","addr","components","split","toString","pubKey","addresses","connectedAddr","publicKey","Set","map","parse","undefined","address","has","add","console","log","__filename","Root","resolvePath","origin","target","join","loadSync","peerInfo","PeerInfoMessage","loadProto","lookupType","push","payload","errMsg","verify","Error","message","encode","finish","buffer","decode","toObject","enums","String","longs","bytes","defaults","arrays","objects","oneofs","targetPubKey","requestingPubKey","messageBuf","responsePeerInfo","HandshakeMessage","encodePeerInfo","Buffer","from","decodePeerInfo","default","keyManager","peerDiscovery","polykeyPath","homedir","metadataPath","fs","peerStore","existsSync","fileContents","readFileSync","metadata","vaults","publicKeyPath","privateKeyPath","getPublicKey","metadataTemplate","writeFileSync","mkdirSync","recursive","Map","vaultName","path","vaultKey","vault","set","validateVault","vaultExists","randomBytes","tags","writeMetadata","getVault","err","destroyVault","rmdirSync","delete","vaultPath","Array","keys","writeFile","symKey","baseDir","keyLen","genSymKey","vfsInstance","VirtualFS","EncryptedFS","process","secrets","loadSecrets","readdirSync","secret","asymKey","secretName","secretPath","secretBuf","writePath","fd","openSync","writeSync","length","polyKeyPath","useWebWorkers","workerPool","primaryKeyPair","private","public","passphrase","storePath","derivedKeys","email","replacePrimary","progressCallback","F","openpgp","options","asp","ASP","progress_hook","userid","primary","nbits","flags","certify_keys","sign_data","auth","encrypt_comm","encrypt_storage","expire_in","subkeys","Promise","resolve","reject","KeyManager","generate","identity","sign","export_pgp_public","export_pgp_private","privKey","keypair","primaryPassphrase","primaryIdentity","privateKey","keyBuffer","promises","readFile","getPrivateKey","import_from_armored_pgp","armored","merge_pgp_private","is_pgp_locked","unlock_pgp","loadPrivateKey","loadPublicKey","loadIdentity","salt","pbkdf2Sync","promisify","pbkdf2","createPath","mkdir","dirname","data","withKey","keyPassphrase","async","resolvedIdentity","getIdentityFromPrivateKey","workerResponse","queue","workerCrypto","signData","params","msg","sign_with","box","result_string","result_buffer","signature","ring","keyring","KeyRing","getIdentityFromPublicKey","verifyData","add_key_manager","keyfetch","unbox","literals","km","ds","get_data_signer","get_key_manager","get_pgp_fingerprint","filePath","signaturePath","fileBuffer","signatureBuffer","privateKeyPassphrase","signedBuffer","signedPath","forPubKey","encryptData","encrypt_for","decryptData","decryptedData","localPeerInfo","peers","update","keybaseDiscovery","findUser","handle","service","url","response","json","them","public_keys","bundle","socialDiscoveryServices","multicastBroadcaster","requestPeerContact","on","timedOutPubKey","tasks","socialDiscovery","error","pubKeyOrFail","firstPromiseFulfilled","pubKeyFound","findPubKey","UDP_MULTICAST_PORT","parseInt","env","UDP_MULTICAST_ADDR","MulticastBroadcaster","EventEmitter","super","peerPubKeyMessages","interval","queryInterval","socket","createSocket","type","reuseAddr","addMembership","pid","handleHandshakeMessages","queryLAN","query","peerMessage","handshakeMessage","encodeHandshakeMessage","encryptedPeerPubKey","encryptedLocalPubKey","encryptedRandomMessage","send","info","setInterval","rinfo","decodedMessage","decodeHandshakeMessage","decryptedMessage","decryptedTargetPubKey","decryptedRequestingPubKey","myPubKey","originalMessage","rawRandomMessage","newPeerInfo","emit","encryptedTargetPubKey","encryptedMessage","encryptedPubKey","pubKeyBuf","randomMessage","invertPromise","res","rej","then","randomString","Math","random","replace","substr","ps","all"],"mappings":"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","file":"polykey.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"polykey\"] = factory();\n\telse\n\t\troot[\"polykey\"] = factory();\n})(this, function() {\nreturn "," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 5);\n","module.exports = require(\"path\");","module.exports = require(\"fs\");","module.exports = require(\"crypto\");","class Address {\n ip: string\n port: string\n constructor(\n ip: string,\n port: string\n ) {\n this.ip = ip\n this.port = port\n }\n\n static parse(addr: string): Address {\n const components = addr.split(':')\n const ip = components[0]\n const port = components[1]\n\n return new Address(ip, port)\n }\n\n}\n\nAddress.prototype.toString = function() {\n return `${this.ip}:${this.port}`\n}\n\nclass PeerInfo {\n publicKey: string\n addresses: Set
\n connectedAddr?: Address\n constructor(\n pubKey: string,\n addresses: string[] = [],\n connectedAddr?: string\n ) {\n this.publicKey = pubKey\n this.addresses = new Set(addresses.map((addr) => {\n return Address.parse(addr)\n }))\n this.connectedAddr = (connectedAddr) ? Address.parse(connectedAddr) : undefined\n }\n\n connect(address: Address) {\n if (!this.addresses.has(address)) {\n this.addresses.add(address)\n }\n\n this.connectedAddr = address\n }\n\n disconnect() {\n this.connectedAddr = undefined\n }\n\n}\n\nexport default PeerInfo\nexport { Address }\n","import Path from 'path'\nimport protobuf, { Root } from 'protobufjs'\nimport PeerInfo from '@polykey/PeerStore/PeerInfo'\n\ntype HandshakeMessage = {\n targetPubKey: Buffer\n requestingPubKey: Buffer\n message: Buffer\n responsePeerInfo?: PeerInfo\n}\nconsole.log(__filename);\n\nclass RPCMessage {\n static loadProto(name: string): Root {\n // Load root\n const root: Root = new protobuf.Root()\n root.resolvePath = (origin, target) => {\n return Path.join(__filename, target)\n }\n\n return root.loadSync(name)\n }\n static encodePeerInfo(peerInfo: PeerInfo): Uint8Array {\n const root = this.loadProto(\"PeerInfoMessage.proto\")\n\n // Obtain a message type\n const PeerInfoMessage = root!.lookupType(\"peerinfopackage.PeerInfoMessage\");\n\n // Encode address set to array\n const addresses: string[] = []\n for (const addr of peerInfo.addresses) {\n addresses.push(addr.toString())\n }\n\n // Exemplary payload\n const payload = {\n pubKey: peerInfo.publicKey,\n addresses: addresses,\n connectedAddr: peerInfo.connectedAddr?.toString()\n };\n\n // Verify the payload if necessary (i.e. when possibly incomplete or invalid)\n const errMsg = PeerInfoMessage.verify(payload);\n if (errMsg)\n throw Error(errMsg);\n\n // Create a new message\n const message = PeerInfoMessage.create(payload); // or use .fromObject if conversion is necessary\n\n // Encode a message to an Uint8Array (browser) or Buffer (node)\n const buffer = PeerInfoMessage.encode(message).finish();\n\n return buffer\n }\n\n static decodePeerInfo(buffer: Uint8Array): PeerInfo {\n const root = this.loadProto(\"PeerInfoMessage.proto\")\n\n // Obtain a message type\n const PeerInfoMessage = root!.lookupType(\"peerinfopackage.PeerInfoMessage\");\n\n // Decode an Uint8Array (browser) or Buffer (node) to a message\n const message = PeerInfoMessage.decode(buffer);\n\n // Convert the message back to a plain object\n const object = PeerInfoMessage.toObject(message, {\n enums: String, // enums as string names\n longs: String, // longs as strings (requires long.js)\n bytes: String, // bytes as base64 encoded strings\n defaults: true, // includes default values\n arrays: true, // populates empty arrays (repeated fields) even if defaults=false\n objects: true, // populates empty objects (map fields) even if defaults=false\n oneofs: true // includes virtual oneof fields set to the present field's name\n });\n\n return new PeerInfo(\n object.pubKey,\n object.addresses,\n object.connectedAddr\n )\n }\n\n static encodeHandshakeMessage(targetPubKey: Buffer, requestingPubKey: Buffer, messageBuf: Buffer, responsePeerInfo?: PeerInfo): Uint8Array {\n const root = this.loadProto(\"HandshakeMessage.proto\")\n\n // Obtain a message type\n const HandshakeMessage = root!.lookupType(\"handshakepackage.HandshakeMessage\");\n\n // Exemplary payload\n const payload = {\n targetPubKey: targetPubKey,\n requestingPubKey: requestingPubKey,\n message: messageBuf,\n responsePeerInfo: (responsePeerInfo) ? this.encodePeerInfo(responsePeerInfo) : undefined\n };\n\n // Verify the payload if necessary (i.e. when possibly incomplete or invalid)\n const errMsg = HandshakeMessage.verify(payload);\n if (errMsg)\n throw Error(errMsg);\n\n // Create a new message\n const message = HandshakeMessage.create(payload); // or use .fromObject if conversion is necessary\n\n // Encode a message to an Uint8Array (browser) or Buffer (node)\n const buffer = HandshakeMessage.encode(message).finish();\n\n return buffer\n }\n\n static decodeHandshakeMessage(buffer: Uint8Array): HandshakeMessage {\n const root = this.loadProto(\"HandshakeMessage.proto\")\n\n // Obtain a message type\n const HandshakeMessage = root!.lookupType(\"handshakepackage.HandshakeMessage\");\n\n // Decode an Uint8Array (browser) or Buffer (node) to a message\n const message = HandshakeMessage.decode(buffer);\n\n // Convert the message back to a plain object\n const object = HandshakeMessage.toObject(message, {\n enums: String, // enums as string names\n longs: String, // longs as strings (requires long.js)\n bytes: String, // bytes as base64 encoded strings\n defaults: true, // includes default values\n arrays: true, // populates empty arrays (repeated fields) even if defaults=false\n objects: true, // populates empty objects (map fields) even if defaults=false\n oneofs: true // includes virtual oneof fields set to the present field's name\n });\n\n return {\n targetPubKey: Buffer.from(object.targetPubKey, 'base64'),\n requestingPubKey: Buffer.from(object.requestingPubKey, 'base64'),\n message: Buffer.from(object.message, 'base64'),\n responsePeerInfo: (object.responsePeerInfo) ? this.decodePeerInfo(Buffer.from(object.responsePeerInfo, 'base64')) : undefined\n }\n }\n}\n\nexport default RPCMessage\n","export { default } from '@polykey/Polykey'\n","import os from 'os'\nimport fs from 'fs'\nimport Path from 'path'\nimport crypto from 'crypto'\nimport jsonfile from 'jsonfile'\nimport Vault from '@polykey/Vault'\nimport KeyManager from '@polykey/KeyManager'\nimport PeerStore from '@polykey/PeerStore/PeerStore'\nimport PeerInfo from '@polykey/PeerStore/PeerInfo'\nimport RPCMessage from '@polykey/RPC/RPCMessage'\nimport PeerDiscovery from '@polykey/P2P/PeerDiscovery'\n\ntype Metadata = {\n vaults: {\n [vaultName: string]: {\n key: Buffer, tags: Array\n }\n }\n peerInfo: Uint8Array\n publicKeyPath?: string\n privateKeyPath?: string\n}\n\nclass Polykey {\n polykeyPath: string\n private fs: typeof fs\n private vaults:Map\n private metadata: Metadata\n private metadataPath: string\n\n keyManager: KeyManager\n peerStore: PeerStore\n peerDiscovery: PeerDiscovery\n\n constructor(\n keyManager?: KeyManager,\n peerDiscovery?: PeerDiscovery,\n polykeyPath: string = `${os.homedir()}/.polykey`\n ) {\n this.polykeyPath = polykeyPath\n this.metadataPath = Path.join(polykeyPath, 'metadata')\n // Set file system\n this.fs = fs\n\n // Set key manager\n this.keyManager = keyManager ?? new KeyManager(polykeyPath)\n\n // Set peer discovery\n this.peerDiscovery = peerDiscovery ?? new PeerDiscovery(this.peerStore, this.keyManager)\n\n // Make polykey path if doesn't exist\n if (!this.fs.existsSync(this.polykeyPath)) {\n this.fs.mkdirSync(this.polykeyPath, {recursive: true})\n } else if (this.fs.existsSync(this.metadataPath)) {\n const fileContents = jsonfile.readFileSync(this.metadataPath)\n this.metadata = {\n vaults: fileContents.vaults,\n peerInfo: fileContents.peerInfo,\n publicKeyPath: fileContents.publicKeyPath,\n privateKeyPath: fileContents.privateKeyPath\n }\n } else {\n // Create a new peerInfo\n const peerInfo = new PeerInfo(this.keyManager.getPublicKey())\n const metadataTemplate = {\n vaults: {},\n peerInfo: RPCMessage.encodePeerInfo(peerInfo)\n }\n jsonfile.writeFileSync(this.metadataPath, metadataTemplate)\n this.metadata = metadataTemplate\n }\n\n // Initialize peer store and peer discovery classes\n this.peerStore = new PeerStore(RPCMessage.decodePeerInfo(this.metadata.peerInfo))\n this.peerDiscovery = new PeerDiscovery(this.peerStore, this.keyManager)\n\n // Load all of the vaults into memory\n this.vaults = new Map()\n for (const vaultName in this.metadata.vaults) {\n if (this.metadata.vaults.hasOwnProperty(vaultName)) {\n const path = Path.join(this.polykeyPath, vaultName)\n if (this.fs.existsSync(path)) {\n const vaultKey = Buffer.from(this.metadata.vaults[vaultName].key)\n const vault = new Vault(vaultName, vaultKey, this.polykeyPath)\n this.vaults.set(vaultName, vault)\n }\n }\n }\n }\n\n ////////////\n // Vaults //\n ////////////\n async getVault(vaultName: string): Promise {\n if (this.vaults.has(vaultName)) {\n const vault = this.vaults.get(vaultName)\n if (vault) {\n return vault\n }\n }\n // vault not in map, create new instance\n await this.validateVault(vaultName)\n\n const vaultKey = this.metadata.vaults[vaultName].key\n const vault = new Vault(vaultName, vaultKey, this.polykeyPath)\n this.vaults.set(vaultName, vault)\n return vault\n }\n\n async createVault(vaultName: string, key?: Buffer): Promise {\n const path = Path.join(this.polykeyPath, vaultName)\n let vaultExists: boolean\n vaultExists = this.fs.existsSync(path)\n\n if (vaultExists) {\n throw Error('Vault already exists!')\n }\n\n try {\n // Directory not present, create one\n this.fs.mkdirSync(path, {recursive:true})\n // Create key if not provided\n let vaultKey: Buffer\n if (!key) {\n // Generate new key\n vaultKey = crypto.randomBytes(16)\n } else {\n // Assign key if it is provided\n vaultKey = key\n }\n this.metadata.vaults[vaultName] = { key: vaultKey, tags: []}\n await this.writeMetadata()\n const vault = new Vault(vaultName, vaultKey, this.polykeyPath)\n this.vaults.set(vaultName, vault)\n return await this.getVault(vaultName)\n } catch (err) {\n // Delete vault dir and garbage collect\n await this.destroyVault(vaultName)\n throw err\n }\n }\n\n async vaultExists(vaultName: string): Promise {\n const path = Path.join(this.polykeyPath, vaultName)\n const vaultExists = this.fs.existsSync(path)\n\n return vaultExists\n }\n\n async destroyVault(vaultName: string) {\n\n // this is convenience function for removing all tags\n // and triggering garbage collection\n // destruction is a better word as we should ensure all traces is removed\n\n const path = Path.join(this.polykeyPath, vaultName)\n // Remove directory on file system\n if (this.fs.existsSync(path)) {\n this.fs.rmdirSync(path, {recursive: true})\n }\n // Remaining garbage collection:\n // Remove vault from vaults map\n if (this.vaults.has(vaultName)) {\n this.vaults.delete(vaultName)\n }\n // Remove from metadata\n if (this.metadata.vaults.hasOwnProperty(vaultName)) {\n delete this.metadata.vaults[vaultName]\n await this.writeMetadata()\n }\n\n const vaultPathExists = this.fs.existsSync(path)\n if (vaultPathExists) {\n throw new Error('Vault path could not be destroyed!')\n }\n const vaultEntryExists = this.vaults.has(vaultName)\n if (vaultEntryExists) {\n throw new Error('Vault could not be removed from PolyKey!')\n }\n const metaDataHasVault = this.metadata.vaults.hasOwnProperty(vaultName)\n if (metaDataHasVault) {\n throw new Error('Vault metadata could not be destroyed!')\n }\n }\n\n /* Validates whether all the artefacts needed to operate\n * a Vault are present. Namely this the vault directory\n * and the metadata for the vault containg the key\n */\n private async validateVault (vaultName: string): Promise {\n const existsMeta = this.metadata.vaults.hasOwnProperty(vaultName)\n if (!existsMeta) {\n throw Error('Vault metadata does not exist')\n }\n const vaultPath = Path.join(this.polykeyPath, vaultName)\n const existsFS = this.fs.existsSync(vaultPath)\n if (!existsFS) {\n throw Error('Vault directory does not exist')\n }\n }\n\n listVaults(): string[] {\n return Array.from(this.vaults.keys())\n }\n\n\n tagVault() {\n\n }\n\n untagVault() {\n\n }\n\n shareVault() {\n\n }\n\n unshareVault() {\n\n }\n\n /* ============ HELPERS =============== */\n private async writeMetadata(): Promise {\n try {\n await jsonfile.writeFile(this.metadataPath, this.metadata)\n } catch (err) {\n throw Error(\"Error writing vault key to config file\")\n }\n }\n}\n\nexport default Polykey\n","module.exports = require(\"os\");","module.exports = require(\"jsonfile\");","import fs from 'fs'\nimport Path from 'path'\nimport hkdf from 'futoin-hkdf'\nimport { EncryptedFS } from 'encryptedfs'\n\nclass Vault {\n\n private key: Buffer\n private keyLen: number\n name: string\n private fs: EncryptedFS\n private secrets: Map\n private vaultPath: string\n constructor(\n name: string,\n symKey: Buffer,\n baseDir: string\n ) {\n // how do we create pub/priv key pair?\n // do we use the same gpg pub/priv keypair\n this.keyLen = 32\n this.key = this.genSymKey(symKey, this.keyLen)\n // Set filesystem\n const vfsInstance = new (require('virtualfs')).VirtualFS\n\n this.fs = new EncryptedFS(\n symKey,\n vfsInstance,\n vfsInstance,\n fs,\n process\n )\n\n this.name = name\n this.vaultPath = Path.join(baseDir, name)\n // make the vault directory\n this.fs.mkdirSync(this.vaultPath, {recursive: true})\n this.secrets = new Map()\n\n this.loadSecrets()\n }\n\n loadSecrets(): void {\n const secrets = fs.readdirSync(this.vaultPath, undefined)\n\n for (const secret of secrets) {\n this.secrets.set(secret, null)\n }\n }\n\n genSymKey(asymKey: Buffer, keyLen: number): Buffer {\n return Buffer.from(hkdf(asymKey.toString(), keyLen))\n }\n\n secretExists(secretName: string) : boolean {\n const secretPath = Path.join(this.vaultPath, secretName)\n return this.secrets.has(secretName) && this.fs.existsSync(secretPath)\n }\n\n addSecret (secretName: string, secretBuf: Buffer): void {\n // TODO: check if secret already exists\n const writePath = Path.join(this.vaultPath, secretName)\n // TODO: use aysnc methods\n const fd = this.fs.openSync(writePath, 'w')\n this.fs.writeSync(fd, secretBuf, 0, secretBuf.length, 0)\n this.secrets.set(secretName, secretBuf)\n // TODO: close file or use write file sync\n }\n\n getSecret(secretName: string): Buffer | string {\n if (this.secrets.has(secretName)) {\n const secret = this.secrets.get(secretName)\n if (secret) {\n return secret\n } else {\n const secretPath = Path.join(this.vaultPath, secretName)\n // TODO: this should be async\n const secretBuf = this.fs.readFileSync(secretPath, {})\n this.secrets.set(secretName, secretBuf)\n return secretBuf\n }\n }\n throw Error('Secret: ' + secretName + ' does not exist')\n }\n\n removeSecret (secretName: string): void {\n if (this.secrets.has(secretName)) {\n const successful = this.secrets.delete(secretName)\n if (successful) {\n return\n }\n throw Error('Secret: ' + secretName + ' was not removed')\n }\n throw Error('Secret: ' + secretName + ' does not exist')\n }\n\n listSecrets(): string[] {\n let secrets: string[] = Array.from(this.secrets.keys())\n return secrets\n }\n\n tagVault() {\n\n }\n\n untagVault() {\n\n }\n\n shareVault() {\n }\n\n unshareVault() {\n }\n\n // ============== Helper methods ============== //\n\n}\n\nexport default Vault\n","module.exports = require(\"futoin-hkdf\");","module.exports = require(\"encryptedfs\");","module.exports = require(\"virtualfs\");","import fs from 'fs'\nimport Path from 'path'\nimport kbpgp from 'kbpgp'\nimport crypto from 'crypto'\nimport { promisify } from 'util'\nimport {Pool, ModuleThread} from 'threads'\nimport { KeyManagerWorker } from '@polykey/KeyManagerWorker'\n\ntype KeyPair = {\n private: string,\n public: string,\n passphrase: string\n}\n\nclass KeyManager {\n private primaryKeyPair: KeyPair = {private: '', public: '', passphrase: ''}\n private primaryPassphrase?: string\n private primaryIdentity?: Object\n private derivedKeys: Map\n private useWebWorkers: boolean\n private workerPool?: Pool>\n\n storePath: string\n\n constructor(\n polyKeyPath: string = '~/.polykey/',\n useWebWorkers: boolean = false,\n workerPool?: Pool>\n ) {\n this.storePath = polyKeyPath\n this.useWebWorkers = useWebWorkers\n this.workerPool = workerPool\n this.derivedKeys = new Map()\n }\n\n // return {private: string, public: string}\n // The replacePrimary parameter will tell KeyManager to replace the\n // existing identity with one derived from the new keypair\n async generateKeyPair(name: string, email: string, passphrase: string, replacePrimary: boolean = false, progressCallback?: (info) => void): Promise {\n\n // Define options\n const F = kbpgp[\"const\"].openpgp\n const options = {\n asp: (progressCallback) ? new kbpgp.ASP({progress_hook: progressCallback}) : undefined,\n userid: `${name} <${email}>`,\n primary: {\n nbits: 4096,\n flags: F.certify_keys | F.sign_data | F.auth | F.encrypt_comm | F.encrypt_storage,\n expire_in: 0 // never expire\n },\n subkeys: []\n }\n\n return new Promise((resolve, reject) => {\n kbpgp.KeyManager.generate(options, (err, identity) => {\n if (err) {\n reject(err)\n }\n identity.sign({}, (err) => {\n if (err) {\n reject(err)\n }\n // Export pub key first\n identity.export_pgp_public({}, (err, pubKey) => {\n if (err) {\n reject(err)\n }\n // Finally export priv key\n identity.export_pgp_private({passphrase: passphrase}, (err, privKey) => {\n if (err) {\n reject(err)\n }\n // Resolve to parent promise\n const keypair = { private: privKey, public: pubKey, passphrase: passphrase }\n if (replacePrimary) {\n // Set the new passphrase\n this.primaryPassphrase = passphrase\n // Set the new keypair\n this.primaryKeyPair = keypair\n // Set the new identity\n this.primaryIdentity = identity\n }\n\n resolve(keypair)\n })\n })\n })\n })\n })\n }\n\n getKeyPair(): KeyPair {\n return this.primaryKeyPair\n }\n\n getPublicKey(): string {\n return this.primaryKeyPair.public\n }\n\n getPrivateKey(): string {\n return this.primaryKeyPair.private\n }\n\n async loadPrivateKey(privateKey: string | Buffer, passphrase: string = ''): Promise {\n try {\n let keyBuffer: Buffer\n if (typeof privateKey === 'string') {\n keyBuffer = Buffer.from(await fs.promises.readFile(privateKey))\n } else {\n keyBuffer = privateKey\n }\n this.primaryKeyPair.private = keyBuffer.toString()\n\n if (passphrase) {\n this.primaryPassphrase = passphrase\n }\n } catch (err) {\n throw(err)\n }\n }\n\n async loadPublicKey(publicKey: string | Buffer): Promise {\n try {\n let keyBuffer: Buffer\n if (typeof publicKey === 'string') {\n keyBuffer = Buffer.from(await fs.promises.readFile(publicKey))\n } else {\n keyBuffer = publicKey\n }\n this.primaryKeyPair.public = keyBuffer.toString()\n } catch (err) {\n throw(err)\n }\n }\n\n async loadIdentity(passphrase: string): Promise {\n return new Promise((resolve, reject) => {\n const pubKey: string = this.getPublicKey()\n const privKey: string = this.getPrivateKey()\n\n kbpgp.KeyManager.import_from_armored_pgp({armored: pubKey}, (err, identity) => {\n if (err) {\n reject(err)\n }\n\n identity.merge_pgp_private({\n armored: privKey\n }, (err) => {\n if (err) {\n reject(err)\n }\n\n if (identity.is_pgp_locked()) {\n identity.unlock_pgp({\n passphrase: passphrase\n }, (err) => {\n if (err) {\n reject(err)\n }\n\n this.primaryIdentity = identity\n resolve()\n })\n } else {\n this.primaryIdentity = identity\n resolve()\n }\n })\n })\n })\n }\n\n async loadKeyPair(publicKey: string | Buffer, privateKey: string | Buffer, passphrase: string = ''): Promise {\n await this.loadPrivateKey(privateKey)\n await this.loadPublicKey(publicKey)\n await this.loadIdentity(passphrase)\n\n if (passphrase) {\n this.primaryPassphrase\n }\n }\n\n async exportPrivateKey(path: string): Promise {\n await fs.promises.writeFile(path, this.primaryKeyPair.private)\n }\n\n async exportPublicKey(path: string): Promise {\n await fs.promises.writeFile(path, this.primaryKeyPair.public)\n }\n\n // symmetric key generation\n generateKeySync(name: string, passphrase: string): Buffer {\n const salt = crypto.randomBytes(32)\n this.derivedKeys[name] = crypto.pbkdf2Sync(passphrase , salt, 10000, 256/8, 'sha256')\n\n return this.derivedKeys[name]\n }\n\n async generateKey(name: string, passphrase: string): Promise {\n const salt = crypto.randomBytes(32)\n this.derivedKeys[name] = await promisify(crypto.pbkdf2)(passphrase , salt, 10000, 256/8, 'sha256')\n\n return this.derivedKeys[name]\n }\n\n importKeySync(name: string, key: string | Buffer): void {\n if (typeof key === 'string') {\n this.derivedKeys[name] = fs.readFileSync(key)\n } else {\n this.derivedKeys[name] = key\n }\n }\n\n async importKey(name: string, key: string | Buffer): Promise {\n if (typeof key === 'string') {\n this.derivedKeys[name] = await fs.promises.readFile(key)\n } else {\n this.derivedKeys[name] = key\n }\n }\n\n async exportKey(name: string, path: string, createPath?: boolean): Promise {\n if (!this.derivedKeys.has(name)) {\n throw Error(`There is no key loaded for name: ${name}`)\n }\n if (createPath) {\n await fs.promises.mkdir(Path.dirname(path), {recursive: true})\n }\n await fs.promises.writeFile(path, this.derivedKeys[name])\n }\n\n exportKeySync(path: string, createPath?: boolean): void {\n if (!this.derivedKeys.has(name)) {\n throw Error(`There is no key loaded for name: ${name}`)\n }\n if (createPath) {\n fs.mkdirSync(Path.dirname(path), {recursive: true})\n }\n fs.writeFileSync(path, this.derivedKeys[name])\n }\n\n async getIdentityFromPublicKey(pubKey: Buffer): Promise {\n return new Promise((resolve, reject) => {\n kbpgp.KeyManager.import_from_armored_pgp({armored: pubKey}, (err, identity) => {\n if (err) {\n reject(err)\n }\n resolve(identity)\n })\n })\n }\n\n async getIdentityFromPrivateKey(privKey: Buffer, passphrase: string): Promise {\n return new Promise((resolve, reject) => {\n kbpgp.KeyManager.import_from_armored_pgp({armored: privKey}, (err, identity) => {\n if (err) {\n reject(err)\n }\n if (identity.is_pgp_locked()) {\n identity.unlock_pgp({\n passphrase: passphrase\n }, (err) => {\n if (err) {\n reject(err)\n }\n resolve(identity)\n });\n } else {\n resolve(identity)\n }\n })\n })\n }\n\n // Sign data\n signData(data: Buffer | string, withKey?: Buffer, keyPassphrase?: string): Promise {\n return new Promise(async (resolve, reject) => {\n let resolvedIdentity: Object\n if (withKey) {\n if (!keyPassphrase) {\n reject(Error('passphrase for private key was not provided'))\n }\n resolvedIdentity = await this.getIdentityFromPrivateKey(withKey, keyPassphrase!)\n } else if (this.primaryIdentity) {\n resolvedIdentity = this.primaryIdentity\n } else {\n throw(Error('no identity available for signing'))\n }\n\n if (this.useWebWorkers && this.workerPool) {\n const workerResponse = await this.workerPool.queue(async (workerCrypto) => {\n return await workerCrypto.signData(data, resolvedIdentity);\n });\n resolve(workerResponse)\n } else {\n const params = {\n msg: data,\n sign_with: resolvedIdentity\n }\n kbpgp.box(params, (err: Error, result_string: string, result_buffer: Buffer) => {\n if (err) {\n reject(err)\n }\n resolve(Buffer.from(result_string))\n })\n }\n })\n }\n\n // Verify data\n verifyData(data: Buffer | string, signature: Buffer, withKey?: Buffer): Promise {\n return new Promise(async (resolve, reject) => {\n const ring = new kbpgp.keyring.KeyRing;\n let resolvedIdentity: Object\n if (withKey) {\n resolvedIdentity = await this.getIdentityFromPublicKey(withKey)\n } else if (this.primaryIdentity) {\n resolvedIdentity = this.primaryIdentity\n } else {\n throw new Error('no identity available for verifying')\n }\n\n if (this.useWebWorkers && this.workerPool) {\n const workerResponse = await this.workerPool.queue(async (workerCrypto) => {\n return await workerCrypto.verifyData(data, signature, resolvedIdentity);\n });\n resolve(workerResponse)\n } else {\n ring.add_key_manager(this.primaryIdentity)\n const params = {\n armored: signature,\n data: data,\n keyfetch: ring\n }\n kbpgp.unbox(params, (err, literals) => {\n if (err) {\n reject(err)\n }\n let ds = literals[0].get_data_signer()\n let km: any\n if (ds) {\n km = ds.get_key_manager()\n }\n if (km) {\n resolve(km.get_pgp_fingerprint().toString('hex'));\n } else {\n reject(Error('could not verify file'))\n }\n })\n }\n })\n }\n\n async verifyFile(filePath: string, signaturePath: string, publicKey?: string | Buffer): Promise {\n // Get key if provided\n let keyBuffer: Buffer\n if (publicKey) {\n if (typeof publicKey === 'string') { // Path\n // Read in from fs\n keyBuffer = fs.readFileSync(publicKey)\n } else { // Buffer\n keyBuffer = publicKey\n }\n }\n // Read in file buffer and signature\n const fileBuffer = fs.readFileSync(filePath)\n const signatureBuffer = fs.readFileSync(signaturePath)\n const verified = await this.verifyData(fileBuffer, signatureBuffer, keyBuffer!)\n return verified\n }\n\n async signFile(path: string, privateKey?: string | Buffer, privateKeyPassphrase?: string): Promise {\n // Get key if provided\n let keyBuffer: Buffer\n if (privateKey) {\n if (typeof privateKey === 'string') { // Path\n // Read in from fs\n keyBuffer = Buffer.from(fs.readFileSync(privateKey))\n } else { // Buffer\n keyBuffer = privateKey\n }\n }\n // Read file into buffer\n const buffer = Buffer.from(fs.readFileSync(path))\n // Sign the buffer\n const signedBuffer = await this.signData(buffer, keyBuffer!, privateKeyPassphrase)\n // Write buffer to signed file\n const signedPath = `${path}.sig`\n fs.writeFileSync(signedPath, signedBuffer)\n return signedPath\n }\n\n // Encrypt data\n async encryptData(data: Buffer, forPubKey: Buffer): Promise {\n return new Promise(async (resolve, reject) => {\n let resolvedIdentity: Object\n try {\n resolvedIdentity = await this.getIdentityFromPublicKey(forPubKey)\n } catch (err) {\n throw(Error(`Identity could not be resolved for encrypting: ${err}`))\n }\n\n if (this.useWebWorkers && this.workerPool) {\n const workerResponse = await this.workerPool.queue(async (workerCrypto) => {\n return await workerCrypto.encryptData(data, resolvedIdentity);\n });\n resolve(workerResponse)\n } else {\n const params = {\n msg: data,\n encrypt_for: resolvedIdentity\n }\n kbpgp.box(params, (err: Error, result_string: string, result_buffer: Buffer) => {\n if (err) {\n reject(err)\n }\n resolve(result_string)\n })\n }\n })\n }\n\n // Decrypt data\n async decryptData(data: string, withKey?: Buffer): Promise {\n return new Promise(async (resolve, reject) => {\n var ring = new kbpgp.keyring.KeyRing;\n let resolvedIdentity: Object\n if (withKey) {\n resolvedIdentity = await this.getIdentityFromPublicKey(withKey)\n } else if (this.primaryIdentity) {\n resolvedIdentity = this.primaryIdentity\n } else {\n throw(Error('no identity available for signing'))\n }\n\n if (this.useWebWorkers && this.workerPool) {\n const workerResponse = await this.workerPool.queue(async (workerCrypto) => {\n return await workerCrypto.decryptData(data, resolvedIdentity);\n });\n resolve(workerResponse)\n } else {\n ring.add_key_manager(resolvedIdentity)\n const params = {\n armored: data,\n keyfetch: ring\n }\n kbpgp.unbox(params, (err, literals) => {\n if (err) {\n reject(err)\n }\n try {\n const decryptedData = Buffer.from(literals[0].toString())\n resolve(decryptedData)\n } catch (err) {\n reject(err)\n }\n })\n }\n })\n }\n\n getKey(name: string): Buffer {\n return this.derivedKeys[name]\n }\n\n isLoaded(): boolean {\n if (this.derivedKeys[name]) {\n return true\n }\n return false\n }\n}\n\nexport default KeyManager\nexport { KeyPair}\n","module.exports = require(\"kbpgp\");","module.exports = require(\"util\");","import PeerInfo from \"@polykey/PeerStore/PeerInfo\"\n\n/**\n * Responsible for managing known peers, as well as their addresses and metadata\n */\nclass PeerStore {\n localPeerInfo: PeerInfo\n peers: Map\n constructor(peerInfo: PeerInfo) {\n this.localPeerInfo = peerInfo\n this.peers = new Map()\n }\n\n /**\n * Stores the peerInfo of a new peer.\n * If already exist, its info is updated.\n */\n put(peerInfo: PeerInfo): void {\n // Already know the peer?\n if (this.has(peerInfo.publicKey)) {\n this.update(peerInfo)\n } else {\n this.add(peerInfo)\n }\n }\n\n /**\n * Add a new peer to the store.\n */\n add(peerInfo: PeerInfo): void {\n this.peers.set(peerInfo.publicKey, peerInfo)\n }\n\n /**\n * Updates an already known peer.\n */\n update(peerInfo: PeerInfo): void {\n this.peers.set(peerInfo.publicKey, peerInfo)\n }\n\n /**\n * Get the info to the given id.\n */\n get(pubKey: string): PeerInfo | null {\n return this.peers.get(pubKey) ?? null\n }\n\n /**\n * Has the info to the given id.\n */\n has(pubKey: string): boolean {\n return this.peers.has(pubKey)\n }\n}\n\nexport default PeerStore\n","module.exports = require(\"protobufjs\");","import fetch from 'node-fetch'\nimport KeyManager from \"@polykey/KeyManager\";\nimport PeerInfo from \"@polykey/PeerStore/PeerInfo\";\nimport PeerStore from \"@polykey/PeerStore/PeerStore\";\nimport MulticastBroadcaster from \"@polykey/P2P/MulticastBroadcaster\";\nimport { firstPromiseFulfilled } from '@polykey/utils';\n\ninterface SocialDiscovery {\n // Must return a public pgp key\n name: string\n findUser(handle: string, service: string): Promise\n}\n\nconst keybaseLookup = async (handle: string, service: string): Promise => {\n const url = `https://keybase.io/_/api/1.0/user/lookup.json?${service}=${handle}`\n\n try {\n const response = await fetch(url)\n const data = await response.json()\n\n const pubKey = data.them[0].public_keys.primary.bundle\n return pubKey\n } catch (err) {\n throw new Error(`User was not found: ${err.message}`)\n }\n}\nconst keybaseDiscovery: SocialDiscovery = {\n name: 'Keybase',\n findUser: keybaseLookup\n}\n\nclass PeerDiscovery {\n peerStore: PeerStore\n keyManager: KeyManager\n multicastBroadcaster: MulticastBroadcaster\n private socialDiscoveryServices: SocialDiscovery[]\n\n constructor(\n peerStore: PeerStore,\n keyManager: KeyManager,\n socialDiscoveryServices: SocialDiscovery[] = []\n ) {\n this.peerStore = peerStore\n this.keyManager = keyManager\n this.socialDiscoveryServices = socialDiscoveryServices\n\n this.socialDiscoveryServices = []\n this.socialDiscoveryServices.push(keybaseDiscovery)\n for (const service of socialDiscoveryServices) {\n this.socialDiscoveryServices.push(service)\n }\n\n this.multicastBroadcaster = new MulticastBroadcaster(this.peerStore, this.keyManager)\n }\n\n async findPubKey(pubKey: string): Promise {\n return new Promise((resolve, reject) => {\n this.multicastBroadcaster.requestPeerContact(pubKey)\n this.multicastBroadcaster.on('found', (peerInfo: PeerInfo) => {\n if (peerInfo.publicKey == pubKey) {\n resolve(peerInfo)\n }\n })\n\n this.multicastBroadcaster.on('timeout', (timedOutPubKey: string) => {\n if (timedOutPubKey == pubKey) {\n reject('The broadcaster stopped looking')\n }\n })\n })\n }\n\n async findSocialUser(handle: string, service: string): Promise {\n const tasks: Promise[] = []\n for (const socialDiscovery of this.socialDiscoveryServices) {\n\n try {\n tasks.push(socialDiscovery.findUser(handle, service))\n } catch (error) {\n console.log(`Could not find user on this discovery service: ${socialDiscovery.name}`);\n }\n }\n\n const pubKeyOrFail = await firstPromiseFulfilled(tasks)\n if (pubKeyOrFail.length > 1) {\n throw new Error('Could not find public key from services')\n }\n\n const pubKeyFound = pubKeyOrFail[0]\n const peerInfo = await this.findPubKey(pubKeyFound)\n return peerInfo\n }\n}\n\nexport default PeerDiscovery\nexport { SocialDiscovery }\n","module.exports = require(\"node-fetch\");","import dgram from 'dgram'\nimport crypto from 'crypto'\nimport { EventEmitter } from 'events'\nimport KeyManager from '@polykey/KeyManager'\nimport RPCMessage from '@polykey/RPC/RPCMessage'\nimport PeerStore from '@polykey/PeerStore/PeerStore'\n\n// This module is based heavily on libp2p's mDNS module:\n// https://github.com/libp2p/js-libp2p-mdns\n// It is supposed to discover peers on the local network\n// This module was also generated with the help of:\n// https://nrempel.com/using-udp-multicast-with-node-js/\n//\n// \"\"\"\n// In computer networking, the multicast DNS (mDNS) protocol\n// resolves hostnames to IP addresses within small networks\n// that do not include a local name server\n// \"\"\"\n\nconst UDP_MULTICAST_PORT = parseInt(process.env.UDP_MULTICAST_PORT ?? '5353');\nconst UDP_MULTICAST_ADDR = process.env.UDP_MULTICAST_ADDR ?? \"224.0.0.251\";\n\ntype PeerMessage = {\n encryptedLocalPubKey: Buffer\n encryptedPeerPubKey: Buffer\n rawRandomMessage: Buffer\n encryptedRandomMessage: Buffer\n}\n\nclass MulticastBroadcaster extends EventEmitter {\n peerStore: PeerStore\n keyManager: KeyManager\n\n socket: dgram.Socket\n\n interval: number\n queryInterval: NodeJS.Timeout | null\n peerPubKeyMessages: Map = new Map()\n constructor(\n peerStore: PeerStore,\n keyManager: KeyManager\n ) {\n super()\n\n this.peerStore = peerStore\n this.keyManager = keyManager\n\n this.interval = (1e3)\n this.queryInterval = null\n\n // Create socket\n this.socket = dgram.createSocket({ type: \"udp4\", reuseAddr: true })\n this.socket.bind(UDP_MULTICAST_PORT)\n\n // Set up listener\n this.socket.on(\"listening\", (() => {\n this.socket.addMembership(UDP_MULTICAST_ADDR);\n const address = this.socket.address();\n console.log(\n `UDP socket listening on ${address.address}:${address.port} pid: ${\n process.pid\n }`\n );\n }).bind(this));\n\n // Handle messages\n this.socket.on(\"message\", this.handleHandshakeMessages.bind(this));\n\n // Start the query process\n this.queryInterval = this.queryLAN()\n }\n\n\n queryLAN() {\n const query = () => {\n for (const pubKey of this.peerPubKeyMessages.keys()) {\n const peerMessage = this.peerPubKeyMessages.get(pubKey)\n if (peerMessage) {\n const handshakeMessage = RPCMessage.encodeHandshakeMessage(\n peerMessage.encryptedPeerPubKey,\n peerMessage.encryptedLocalPubKey,\n peerMessage.encryptedRandomMessage\n )\n\n this.socket.send(handshakeMessage, 0, handshakeMessage.length, UDP_MULTICAST_PORT, UDP_MULTICAST_ADDR, () => {\n console.info(`Sending message to peer`);\n });\n }\n\n }\n }\n\n // Immediately start a query, then do it every interval.\n query()\n return setInterval(query, this.interval)\n }\n\n private async handleHandshakeMessages(message: any, rinfo: any) {\n try {\n const decodedMessage = RPCMessage.decodeHandshakeMessage(message)\n console.info(`Message from: ${rinfo.address}:${rinfo.port}`);\n\n\n // Try to decrypt message and pubKey\n const decryptedMessage = await this.keyManager.decryptData(decodedMessage.message.toString())\n const decryptedTargetPubKey = await this.keyManager.decryptData(decodedMessage.targetPubKey.toString())\n const decryptedRequestingPubKey = await this.keyManager.decryptData(decodedMessage.requestingPubKey.toString())\n\n const myPubKey = this.keyManager.getPublicKey()\n\n if (decryptedRequestingPubKey.toString() == myPubKey) { // Response\n // Make sure decrypted bytes equal raw bytes in memory\n const originalMessage = this.peerPubKeyMessages.get(decryptedTargetPubKey.toString())?.rawRandomMessage\n\n if (decryptedMessage.toString() == originalMessage?.toString()) { // Validated!\n // Add peer info to peerStore\n const newPeerInfo = decodedMessage.responsePeerInfo\n if (newPeerInfo) {\n this.peerStore.add(newPeerInfo)\n // Remove peerId from requested messages\n const pubKey = newPeerInfo.publicKey\n this.peerPubKeyMessages.delete(pubKey)\n console.log(`New peer added to the store`);\n this.emit('found', newPeerInfo)\n } else {\n this.emit('error', \"I got a validated response. But no peerInfo\");\n }\n }\n } else { // Requests on target node\n // Try decrypting message\n // Re-encrypt the data and send it on its way\n\n const encryptedTargetPubKey = await this.keyManager.encryptData(Buffer.from(myPubKey), decryptedRequestingPubKey)\n const encryptedMessage = await this.keyManager.encryptData(decryptedMessage, decryptedRequestingPubKey)\n const encryptedPubKey = await this.keyManager.encryptData(decryptedRequestingPubKey, decryptedRequestingPubKey)\n const handshakeMessage = RPCMessage.encodeHandshakeMessage(\n Buffer.from(encryptedTargetPubKey),\n Buffer.from(encryptedPubKey),\n Buffer.from(encryptedMessage),\n this.peerStore.localPeerInfo\n )\n this.socket.send(handshakeMessage, 0, handshakeMessage.length, UDP_MULTICAST_PORT, UDP_MULTICAST_ADDR);\n }\n } catch (err) { // Couldn't decode message\n // We don't want the multicast discovery to error on every message it coudln't decode!\n }\n }\n\n async requestPeerContact(pubKey: string) {\n const pubKeyBuf = Buffer.from(pubKey)\n const randomMessage = crypto.randomBytes(16)\n // Encrypt message\n const encryptedPeerPubKey = await this.keyManager.encryptData(pubKeyBuf, pubKeyBuf)\n const encryptedRandomMessage = await this.keyManager.encryptData(randomMessage, pubKeyBuf)\n const encryptedLocalPubKey = await this.keyManager.encryptData(Buffer.from(this.keyManager.getPublicKey()), pubKeyBuf)\n\n // Add to peer messages to be sent over multicast\n this.peerPubKeyMessages.set(pubKey, {\n encryptedLocalPubKey: Buffer.from(encryptedLocalPubKey),\n encryptedPeerPubKey: Buffer.from(encryptedPeerPubKey),\n rawRandomMessage: randomMessage,\n encryptedRandomMessage: Buffer.from(encryptedRandomMessage)\n })\n }\n}\n\nexport default MulticastBroadcaster\n","module.exports = require(\"dgram\");","module.exports = require(\"events\");","function randomString(): string {\n\treturn Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 5)\n}\n\nfunction invertPromise(p: Promise): Promise {\n return new Promise((res, rej) => p.then(rej, res));\n}\n\nfunction firstPromiseFulfilled(ps: Promise[]) {\n return invertPromise(Promise.all(ps.map(invertPromise)))\n}\n\nexport { randomString, firstPromiseFulfilled }\n"],"sourceRoot":""} \ No newline at end of file diff --git a/dist/utils.js b/dist/utils.js deleted file mode 100644 index 989836f74..000000000 --- a/dist/utils.js +++ /dev/null @@ -1,7 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -function randomString() { - return Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 5); -} -exports.randomString = randomString; -//# sourceMappingURL=utils.js.map \ No newline at end of file diff --git a/dist/utils.js.map b/dist/utils.js.map deleted file mode 100644 index ba8d14c51..000000000 --- a/dist/utils.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":";;AAAA,SAAS,YAAY;IACpB,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;AACvE,CAAC;AAEQ,oCAAY"} \ No newline at end of file diff --git a/index.d.ts b/index.d.ts new file mode 100644 index 000000000..7056a175c --- /dev/null +++ b/index.d.ts @@ -0,0 +1,338 @@ +declare module 'polykey/src/cli/Config' { + import commander from 'commander'; + function makeConfigCommand(): commander.Command; + export default makeConfigCommand; + +} +declare module 'polykey/src/cli/Crypto' { + import commander from 'commander'; + function makeCryptoCommand(): commander.Command; + export default makeCryptoCommand; + +} +declare module 'polykey/src/cli/KeyManager' { + import commander from 'commander'; + function makeKeyManagerCommand(): commander.Command; + export default makeKeyManagerCommand; + +} +declare module 'polykey/src/cli/Node' { + import commander from 'commander'; + function makeNodeCommand(): commander.Command; + export default makeNodeCommand; + +} +declare module 'polykey/src/cli/Secrets' { + import commander from 'commander'; + function makeSecretsCommand(): commander.Command; + export default makeSecretsCommand; + +} +declare module 'polykey/src/cli/Vaults' { + import commander from 'commander'; + function makeVaultsCommand(): commander.Command; + export default makeVaultsCommand; + +} +declare module 'polykey/src/cli/initPolykey' { + import PolyKey from 'polykey/src/lib/Polykey'; + /*******************************************/ + function initPolyKey(): Promise; + export default initPolyKey; + +} +declare module 'polykey/src/cli/polykey' { + function actionRunner(fn: (...args: any[]) => Promise): (...args: any[]) => Promise; + /*******************************************/ + enum PKMessageType { + SUCCESS = 0, + INFO = 1, + WARNING = 2 + } + function pkLogger(message: string, type?: PKMessageType): void; + export { actionRunner, PKMessageType, pkLogger }; + +} +declare module 'polykey/src/lib/KeyManager' { + /// + import { Pool, ModuleThread } from 'threads'; + import { KeyManagerWorker } from '@polykey/KeyManagerWorker'; + type KeyPair = { + private: string; + public: string; + passphrase: string; + }; + class KeyManager { + private primaryKeyPair; + private primaryPassphrase?; + private primaryIdentity?; + private derivedKeys; + private useWebWorkers; + private workerPool?; + storePath: string; + constructor(polyKeyPath?: string, useWebWorkers?: boolean, workerPool?: Pool>); + generateKeyPair(name: string, email: string, passphrase: string, replacePrimary?: boolean, progressCallback?: (info: any) => void): Promise; + getKeyPair(): KeyPair; + getPublicKey(): string; + getPrivateKey(): string; + loadPrivateKey(privateKey: string | Buffer, passphrase?: string): Promise; + loadPublicKey(publicKey: string | Buffer): Promise; + loadIdentity(passphrase: string): Promise; + loadKeyPair(publicKey: string | Buffer, privateKey: string | Buffer, passphrase?: string): Promise; + exportPrivateKey(path: string): Promise; + exportPublicKey(path: string): Promise; + generateKeySync(name: string, passphrase: string): Buffer; + generateKey(name: string, passphrase: string): Promise; + importKeySync(name: string, key: string | Buffer): void; + importKey(name: string, key: string | Buffer): Promise; + exportKey(name: string, path: string, createPath?: boolean): Promise; + exportKeySync(path: string, createPath?: boolean): void; + getIdentityFromPublicKey(pubKey: Buffer): Promise; + getIdentityFromPrivateKey(privKey: Buffer, passphrase: string): Promise; + signData(data: Buffer | string, withKey?: Buffer, keyPassphrase?: string): Promise; + verifyData(data: Buffer | string, signature: Buffer, withKey?: Buffer): Promise; + verifyFile(filePath: string, signaturePath: string, publicKey?: string | Buffer): Promise; + signFile(path: string, privateKey?: string | Buffer, privateKeyPassphrase?: string): Promise; + encryptData(data: Buffer, forPubKey: Buffer): Promise; + decryptData(data: string, withKey?: Buffer): Promise; + getKey(name: string): Buffer; + isLoaded(): boolean; + } + export default KeyManager; + export { KeyPair }; + +} +declare module 'polykey/src/lib/KeyManagerWorker' { + /// + const keyManagerWorker: { + signData(data: string | Buffer, identity: any): Promise; + verifyData(data: string | Buffer, signature: Buffer, identity: any): Promise; + encryptData(data: Buffer, identity: any): Promise; + decryptData(data: string, identity: any): Promise; + }; + export type KeyManagerWorker = typeof keyManagerWorker; + export {}; + +} +declare module 'polykey/src/lib/P2P/MulticastBroadcaster' { + /// + import dgram from 'dgram'; + import { EventEmitter } from 'events'; + import KeyManager from '@polykey/KeyManager'; + import PeerStore from '@polykey/PeerStore/PeerStore'; + type PeerMessage = { + encryptedLocalPubKey: Buffer; + encryptedPeerPubKey: Buffer; + rawRandomMessage: Buffer; + encryptedRandomMessage: Buffer; + }; + class MulticastBroadcaster extends EventEmitter { + peerStore: PeerStore; + keyManager: KeyManager; + socket: dgram.Socket; + interval: number; + queryInterval: NodeJS.Timeout | null; + peerPubKeyMessages: Map; + constructor(peerStore: PeerStore, keyManager: KeyManager); + queryLAN(): NodeJS.Timeout; + /** + * Start sending queries to the LAN. + * + * @returns {void} + */ + start(): Promise; + private handleHandshakeMessages; + requestPeerContact(pubKey: string): Promise; + /** + * Stop sending queries to the LAN. + * + * @returns {Promise} + */ + stop(): Promise; + } + export default MulticastBroadcaster; + +} +declare module 'polykey/src/lib/P2P/PeerDiscovery' { + import KeyManager from "@polykey/KeyManager"; + import PeerInfo from "@polykey/PeerStore/PeerInfo"; + import PeerStore from "@polykey/PeerStore/PeerStore"; + import MulticastBroadcaster from "@polykey/P2P/MulticastBroadcaster"; + interface SocialDiscovery { + name: string; + findUser(handle: string, service: string): Promise; + } + class PeerDiscovery { + peerStore: PeerStore; + keyManager: KeyManager; + multicastBroadcaster: MulticastBroadcaster; + private socialDiscoveryServices; + constructor(peerStore: PeerStore, keyManager: KeyManager, socialDiscoveryServices?: SocialDiscovery[]); + start(): Promise; + stop(): Promise; + findPubKey(pubKey: string): Promise; + findSocialUser(handle: string, service: string): Promise; + } + export default PeerDiscovery; + export { SocialDiscovery }; + +} +declare module 'polykey/src/lib/PeerStore/PeerInfo' { + class Address { + ip: string; + port: string; + constructor(ip: string, port: string); + static parse(addr: string): Address; + } + class PeerInfo { + publicKey: string; + addresses: Set
; + connectedAddr?: Address; + constructor(pubKey: string, addresses?: string[], connectedAddr?: string); + connect(address: Address): void; + disconnect(): void; + } + export default PeerInfo; + export { Address }; + +} +declare module 'polykey/src/lib/PeerStore/PeerStore' { + import PeerInfo from "@polykey/PeerStore/PeerInfo"; + /** + * Responsible for managing known peers, as well as their addresses and metadata + */ + class PeerStore { + localPeerInfo: PeerInfo; + peers: Map; + constructor(peerInfo: PeerInfo); + /** + * Stores the peerInfo of a new peer. + * If already exist, its info is updated. + */ + put(peerInfo: PeerInfo): void; + /** + * Add a new peer to the store. + */ + add(peerInfo: PeerInfo): void; + /** + * Updates an already known peer. + */ + update(peerInfo: PeerInfo): void; + /** + * Get the info to the given id. + */ + get(pubKey: string): PeerInfo | null; + /** + * Has the info to the given id. + */ + has(pubKey: string): boolean; + } + export default PeerStore; + +} +declare module 'polykey/src/lib/Polykey' { + /// + import Vault from '@polykey/Vault'; + import KeyManager from '@polykey/KeyManager'; + import PeerStore from '@polykey/PeerStore/PeerStore'; + import PeerDiscovery from '@polykey/P2P/PeerDiscovery'; + class Polykey { + polykeyPath: string; + private fs; + private vaults; + private metadata; + private metadataPath; + keyManager: KeyManager; + peerStore: PeerStore; + peerDiscovery: PeerDiscovery; + constructor(keyManager?: KeyManager, peerDiscovery?: PeerDiscovery, polykeyPath?: string); + getVault(vaultName: string): Promise; + createVault(vaultName: string, key?: Buffer): Promise; + vaultExists(vaultName: string): Promise; + destroyVault(vaultName: string): Promise; + private validateVault; + listVaults(): string[]; + tagVault(): void; + untagVault(): void; + shareVault(): void; + unshareVault(): void; + private writeMetadata; + } + export default Polykey; + +} +declare module 'polykey/src/lib/RPC/RPCMessage' { + /// + import { Root } from 'protobufjs'; + import PeerInfo from '@polykey/PeerStore/PeerInfo'; + type HandshakeMessage = { + targetPubKey: Buffer; + requestingPubKey: Buffer; + message: Buffer; + responsePeerInfo?: PeerInfo; + }; + class RPCMessage { + static loadProto(name: string): Root; + static encodePeerInfo(peerInfo: PeerInfo): Uint8Array; + static decodePeerInfo(buffer: Uint8Array): PeerInfo; + static encodeHandshakeMessage(targetPubKey: Buffer, requestingPubKey: Buffer, messageBuf: Buffer, responsePeerInfo?: PeerInfo): Uint8Array; + static decodeHandshakeMessage(buffer: Uint8Array): HandshakeMessage; + } + export default RPCMessage; + +} +declare module 'polykey/src/lib/Vault' { + /// + class Vault { + private key; + private keyLen; + name: string; + private fs; + private secrets; + private vaultPath; + constructor(name: string, symKey: Buffer, baseDir: string); + loadSecrets(): void; + genSymKey(asymKey: Buffer, keyLen: number): Buffer; + secretExists(secretName: string): boolean; + addSecret(secretName: string, secretBuf: Buffer): void; + getSecret(secretName: string): Buffer | string; + removeSecret(secretName: string): void; + listSecrets(): string[]; + tagVault(): void; + untagVault(): void; + shareVault(): void; + unshareVault(): void; + } + export default Vault; + +} +declare module 'polykey/src/lib/index' { + export { default } from '@polykey/Polykey'; + +} +declare module 'polykey/src/lib/utils' { + function randomString(): string; + function firstPromiseFulfilled(ps: Promise[]): Promise; + export { randomString, firstPromiseFulfilled }; + +} +declare module 'polykey/tests/P2P/PeerDiscovery.test' { + export {}; + +} +declare module 'polykey/tests/Polykey.test' { + export {}; + +} +declare module 'polykey/tests/RPC/RPCMessage.test' { + export {}; + +} +declare module 'polykey/tests/Vaults.test' { + export {}; + +} +declare module 'polykey' { + import main = require('polykey/src/lib/index'); + export = main; +} \ No newline at end of file diff --git a/jest.config.js b/jest.config.js index d9f13a97d..8da114305 100644 --- a/jest.config.js +++ b/jest.config.js @@ -6,6 +6,9 @@ module.exports = { "**/?(*.)+(spec|test|unit.test).+(ts|tsx|js)" ], "transform": { - "^.+\\.(ts|tsx)$": "ts-jest" + "^.+\\.tsx?$": "ts-jest" }, -} + moduleNameMapper: { + '@polykey/(.*)$': '/src/lib/$1' + } +}; diff --git a/package-lock.json b/package-lock.json index 732571bac..d44cab851 100644 --- a/package-lock.json +++ b/package-lock.json @@ -206,6 +206,30 @@ } } }, + "@grpc/grpc-js": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.0.5.tgz", + "integrity": "sha512-Hm+xOiqAhcpT9RYM8lc15dbQD7aQurM7ZU8ulmulepiPlN7iwBXXwP3vSBUimoFoApRqz7pSIisXU8pZaCB4og==", + "requires": { + "semver": "^6.2.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + } + } + }, + "@grpc/proto-loader": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.5.4.tgz", + "integrity": "sha512-HTM4QpI9B2XFkPz7pjwMyMgZchJ93TVkL3kWPW8GDMDKYxsMnmf4w2TNMJK7+KNiYHS5cJrCEAFlF+AwtXWVPA==", + "requires": { + "lodash.camelcase": "^4.3.0", + "protobufjs": "^6.8.6" + } + }, "@istanbuljs/load-nyc-config": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.0.0.tgz", @@ -1255,6 +1279,103 @@ } } }, + "@nodelib/fs.scandir": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz", + "integrity": "sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.3", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz", + "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz", + "integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.3", + "fastq": "^1.6.0" + } + }, + "@npmcli/move-file": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.0.1.tgz", + "integrity": "sha512-Uv6h1sT+0DrblvIrolFtbvM1FgWm+/sy4B3pvLp67Zys+thcukzS5ekn7HsZFGpWP4Q3fYJCljbWQE/XivMRLw==", + "dev": true, + "requires": { + "mkdirp": "^1.0.4" + }, + "dependencies": { + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true + } + } + }, + "@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78=" + }, + "@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" + }, + "@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" + }, + "@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A=" + }, + "@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=", + "requires": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=" + }, + "@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=" + }, + "@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=" + }, + "@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=" + }, + "@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=" + }, "@sinonjs/commons": { "version": "1.7.2", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.7.2.tgz", @@ -1424,11 +1545,10 @@ "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", "dev": true }, - "@types/lodash": { - "version": "4.14.150", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.150.tgz", - "integrity": "sha512-kMNLM5JBcasgYscD9x/Gvr6lTAv2NVgsKtet/hm93qMyf/D1pt+7jeEZklKJKxMVmXjxbRVQQGfqDSfipYCO6w==", - "dev": true + "@types/long": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz", + "integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==" }, "@types/node": { "version": "13.13.4", @@ -1819,6 +1939,16 @@ "integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==", "dev": true }, + "aggregate-error": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.0.1.tgz", + "integrity": "sha512-quoaXsZ9/BLNae5yiNoUz+Nhkwz83GhWwtYFglcjEQB2NDHCIpApbqXxIFnm4Pq/Nvhrsq5sYJFyohrrxnTGAA==", + "dev": true, + "requires": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + } + }, "ajv": { "version": "6.12.2", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.2.tgz", @@ -1922,6 +2052,12 @@ "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=", "dev": true }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true + }, "asn1": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", @@ -3323,18 +3459,6 @@ "file-uri-to-path": "1.0.0" } }, - "bip39": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/bip39/-/bip39-2.5.0.tgz", - "integrity": "sha512-xwIx/8JKoT2+IPJpFEfXoWdYwP7UVAoUxxLNfGCfVowaJE7yg1Y5B1BVPqlUNsBq5/nGwmFkwRJ8xDW4sX8OdA==", - "requires": { - "create-hash": "^1.1.0", - "pbkdf2": "^3.0.9", - "randombytes": "^2.0.1", - "safe-buffer": "^5.0.1", - "unorm": "^1.3.3" - } - }, "bitset": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/bitset/-/bitset-5.0.3.tgz", @@ -3394,6 +3518,15 @@ "concat-map": "0.0.1" } }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, "brorand": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", @@ -3839,6 +3972,12 @@ "resolved": "https://registry.npmjs.org/clean-git-ref/-/clean-git-ref-1.0.3.tgz", "integrity": "sha1-UyXcg56rAcl0rg6X9XNHgnUPiOw=" }, + "clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true + }, "cli-cursor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", @@ -3847,6 +3986,50 @@ "restore-cursor": "^3.1.0" } }, + "cli-progress": { + "version": "3.8.2", + "resolved": "https://registry.npmjs.org/cli-progress/-/cli-progress-3.8.2.tgz", + "integrity": "sha512-qRwBxLldMSfxB+YGFgNRaj5vyyHe1yMpVeDL79c+7puGujdKJHQHydgqXDcrkvQgJ5U/d3lpf6vffSoVVUftVQ==", + "requires": { + "colors": "^1.1.2", + "string-width": "^4.2.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + }, + "string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "requires": { + "ansi-regex": "^5.0.0" + } + } + } + }, "cli-width": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz", @@ -3987,6 +4170,11 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" }, + "colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==" + }, "combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -4121,6 +4309,178 @@ "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", "dev": true }, + "copy-webpack-plugin": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-6.0.2.tgz", + "integrity": "sha512-9Gm8X0c6eXlKnmltMPFCBeGOKjtcRIyTt4VaO3k1TkNgVTe5Ov2lYsYVuyLp0kp8DItO3apewflM+1GYgh6V2Q==", + "dev": true, + "requires": { + "cacache": "^15.0.4", + "fast-glob": "^3.2.2", + "find-cache-dir": "^3.3.1", + "glob-parent": "^5.1.1", + "globby": "^11.0.1", + "loader-utils": "^2.0.0", + "normalize-path": "^3.0.0", + "p-limit": "^2.3.0", + "schema-utils": "^2.7.0", + "serialize-javascript": "^3.1.0", + "webpack-sources": "^1.4.3" + }, + "dependencies": { + "cacache": { + "version": "15.0.4", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.0.4.tgz", + "integrity": "sha512-YlnKQqTbD/6iyoJvEY3KJftjrdBYroCbxxYXzhOzsFLWlp6KX4BOlEf4mTx0cMUfVaTS3ENL2QtDWeRYoGLkkw==", + "dev": true, + "requires": { + "@npmcli/move-file": "^1.0.1", + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "glob": "^7.1.4", + "infer-owner": "^1.0.4", + "lru-cache": "^5.1.1", + "minipass": "^3.1.1", + "minipass-collect": "^1.0.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.2", + "mkdirp": "^1.0.3", + "p-map": "^4.0.0", + "promise-inflight": "^1.0.1", + "rimraf": "^3.0.2", + "ssri": "^8.0.0", + "tar": "^6.0.2", + "unique-filename": "^1.1.1" + } + }, + "chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "json5": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", + "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "loader-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", + "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + } + }, + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "requires": { + "yallist": "^3.0.2" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "schema-utils": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz", + "integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.4", + "ajv": "^6.12.2", + "ajv-keywords": "^3.4.1" + } + }, + "serialize-javascript": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-3.1.0.tgz", + "integrity": "sha512-JIJT1DGiWmIKhzRsG91aS6Ze4sFUrYbltlkg2onR5OrnNM02Kl/hnY/T4FN2omvyeBbQmMJv+K4cPOpGzOTFBg==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } + }, + "ssri": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.0.tgz", + "integrity": "sha512-aq/pz989nxVYwn16Tsbj1TqFpD5LLrQxHf5zaHuieFV+R0Bbr4y8qUsOA45hXT/N4/9UNXTarBjnjVmjSOVaAA==", + "dev": true, + "requires": { + "minipass": "^3.1.1" + } + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + } + } + }, "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", @@ -4148,6 +4508,7 @@ "version": "1.2.0", "resolved": "http://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dev": true, "requires": { "cipher-base": "^1.0.1", "inherits": "^2.0.1", @@ -4160,6 +4521,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dev": true, "requires": { "inherits": "^2.0.1", "safe-buffer": "^5.0.1" @@ -4168,12 +4530,14 @@ "inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true }, "sha.js": { "version": "2.4.11", "resolved": "http://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dev": true, "requires": { "inherits": "^2.0.1", "safe-buffer": "^5.0.1" @@ -4185,6 +4549,7 @@ "version": "1.1.7", "resolved": "http://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dev": true, "requires": { "cipher-base": "^1.0.3", "create-hash": "^1.1.0", @@ -4198,6 +4563,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dev": true, "requires": { "inherits": "^2.0.1", "safe-buffer": "^5.0.1" @@ -4206,12 +4572,14 @@ "inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true }, "sha.js": { "version": "2.4.11", "resolved": "http://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dev": true, "requires": { "inherits": "^2.0.1", "safe-buffer": "^5.0.1" @@ -4511,6 +4879,23 @@ "randombytes": "^2.0.0" } }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "requires": { + "path-type": "^4.0.0" + }, + "dependencies": { + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true + } + } + }, "disparity": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/disparity/-/disparity-2.0.0.tgz", @@ -5218,10 +5603,23 @@ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz", "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==", "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4" + "base64-js": "^1.0.2", + "ieee754": "^1.1.4" + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" } }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, "readable-stream": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", @@ -5244,6 +5642,18 @@ "requires": { "safe-buffer": "~5.2.0" } + }, + "threads": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/threads/-/threads-1.4.0.tgz", + "integrity": "sha512-vaKhZODDnciJn4Bjmkd1GbJ2dlzFbzxwcQNM1IZV1bsCXmlJpirSAKsYG7MT7MHgO+qQxTaIn6CMstmlYnGNWw==", + "requires": { + "callsites": "^3.1.0", + "debug": "^4.1.1", + "is-observable": "^1.1.0", + "observable-fns": "^0.5.1", + "tiny-worker": ">= 2" + } } } }, @@ -5760,6 +6170,20 @@ "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==" }, + "fast-glob": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.2.tgz", + "integrity": "sha512-UDV82o4uQyljznxwMxyVRJgZZt3O5wENYojjzbaGEGZgeOxkLFf+V4cnUD+krzb2F72E18RhamkMZ7AdeggF7A==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.0", + "merge2": "^1.3.0", + "micromatch": "^4.0.2", + "picomatch": "^2.2.1" + } + }, "fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -5770,6 +6194,15 @@ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" }, + "fastq": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.8.0.tgz", + "integrity": "sha512-SMIZoZdLh/fgofivvIkmknUXyPnvxRE3DhtZ5Me3Mrsk5gyPL42F0xr51TdRXskBxHfMp+07bcYzfsYEsSQA9Q==", + "dev": true, + "requires": { + "reusify": "^1.0.4" + } + }, "faye-websocket": { "version": "0.10.0", "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz", @@ -5810,6 +6243,55 @@ "flat-cache": "^2.0.1" } }, + "file-loader": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.0.0.tgz", + "integrity": "sha512-/aMOAYEFXDdjG0wytpTL5YQLfZnnTmLNjn+AIrJ/6HVnTfDqLsVKUUwkDf4I4kgex36BvjuXEn/TX9B/1ESyqQ==", + "dev": true, + "requires": { + "loader-utils": "^2.0.0", + "schema-utils": "^2.6.5" + }, + "dependencies": { + "json5": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", + "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "loader-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", + "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "schema-utils": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz", + "integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.4", + "ajv": "^6.12.2", + "ajv-keywords": "^3.4.1" + } + } + } + }, "file-uri-to-path": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", @@ -5817,6 +6299,37 @@ "dev": true, "optional": true }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + }, + "dependencies": { + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + } + } + }, + "find-cache-dir": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz", + "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + } + }, "find-up": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", @@ -6237,6 +6750,15 @@ } } }, + "fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dev": true, + "requires": { + "minipass": "^3.0.0" + } + }, "fs-mkdirp-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz", @@ -7053,6 +7575,34 @@ "resolved": "https://registry.npmjs.org/globalyzer/-/globalyzer-0.1.0.tgz", "integrity": "sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q==" }, + "globby": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.1.tgz", + "integrity": "sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ==", + "dev": true, + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", + "slash": "^3.0.0" + }, + "dependencies": { + "ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "dev": true + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + } + } + }, "globrex": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.1.tgz", @@ -7171,6 +7721,7 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", + "dev": true, "requires": { "inherits": "^2.0.1", "safe-buffer": "^5.0.1" @@ -7179,7 +7730,8 @@ "inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true } } }, @@ -7464,6 +8016,12 @@ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" }, + "indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true + }, "infer-owner": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", @@ -7977,6 +8535,12 @@ "integrity": "sha1-aRC8pdqMleeEtXUbl2z1oQ/uNtI=", "dev": true }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, "is-obj": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", @@ -11436,6 +12000,11 @@ "integrity": "sha512-svL3uiZf1RwhH+cWrfZn3A4+U58wbP0tGVTLQPbjplZxZ8ROD9VLuNgsRniTlLe7OlSqR79RUehXgpBW/s0IQw==", "dev": true }, + "lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=" + }, "lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", @@ -11463,6 +12032,11 @@ "@sinonjs/commons": "^1.7.0" } }, + "long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" + }, "longest-streak": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-2.0.2.tgz", @@ -11563,6 +12137,7 @@ "version": "1.3.5", "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dev": true, "requires": { "hash-base": "^3.0.0", "inherits": "^2.0.1", @@ -11572,12 +12147,14 @@ "inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true }, "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true } } }, @@ -11675,6 +12252,22 @@ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", "dev": true }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, "miller-rabin": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", @@ -11764,6 +12357,68 @@ } } }, + "minipass": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + }, + "dependencies": { + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } + }, + "minipass-collect": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", + "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", + "dev": true, + "requires": { + "minipass": "^3.0.0" + } + }, + "minipass-flush": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", + "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", + "dev": true, + "requires": { + "minipass": "^3.0.0" + } + }, + "minipass-pipeline": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.3.tgz", + "integrity": "sha512-cFOknTvng5vqnwOpDsZTWhNll6Jf8o2x+/diplafmxpuIymAjzoOolZG0VvQf3V2HgqzJNhnuKHYp2BqDgz8IQ==", + "dev": true, + "requires": { + "minipass": "^3.0.0" + } + }, + "minizlib": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.0.tgz", + "integrity": "sha512-EzTZN/fjSvifSX0SlqUERCN39o6T40AMarPbv0MrarSFtIITCBh7bi+dU8nxGFHuqs9jdIAeoYoKuQAAASsPPA==", + "dev": true, + "requires": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "dependencies": { + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } + }, "mississippi": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", @@ -12019,6 +12674,11 @@ "benchmark": "^1.0.0" } }, + "node-fetch": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", + "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==" + }, "node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", @@ -12368,6 +13028,15 @@ "p-limit": "^1.1.0" } }, + "p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "requires": { + "aggregate-error": "^3.0.0" + } + }, "p-try": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", @@ -12561,6 +13230,7 @@ "version": "3.0.17", "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", + "dev": true, "requires": { "create-hash": "^1.1.2", "create-hmac": "^1.1.4", @@ -12572,12 +13242,14 @@ "inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true }, "sha.js": { "version": "2.4.11", "resolved": "http://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dev": true, "requires": { "inherits": "^2.0.1", "safe-buffer": "^5.0.1" @@ -12617,6 +13289,66 @@ "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", "dev": true }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "requires": { + "find-up": "^4.0.0" + }, + "dependencies": { + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + } + } + }, "pn": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz", @@ -12736,6 +13468,26 @@ "integrity": "sha1-/RSDyPusYYCPX+NZ52k6H0ilgzE=", "dev": true }, + "protobufjs": { + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.9.0.tgz", + "integrity": "sha512-LlGVfEWDXoI/STstRDdZZKb/qusoAWUnmLg9R8OLSO473mBLWHowx8clbX5/+mKDEI+v7GzjoK9tRPZMMcoTrg==", + "requires": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.1", + "@types/node": "^13.7.0", + "long": "^4.0.0" + } + }, "protocols": { "version": "1.4.6", "resolved": "https://registry.npmjs.org/protocols/-/protocols-1.4.6.tgz", @@ -12834,6 +13586,7 @@ "version": "2.0.6", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.6.tgz", "integrity": "sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A==", + "dev": true, "requires": { "safe-buffer": "^5.1.0" } @@ -13333,6 +14086,12 @@ "integrity": "sha1-uKSCXVvbH8P29Twrwz+BOIaBx7w=", "dev": true }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true + }, "rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", @@ -13362,6 +14121,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dev": true, "requires": { "hash-base": "^3.0.0", "inherits": "^2.0.1" @@ -13370,7 +14130,8 @@ "inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true } } }, @@ -13385,6 +14146,12 @@ "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==" }, + "run-parallel": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz", + "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==", + "dev": true + }, "run-queue": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", @@ -14614,6 +15381,40 @@ "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", "dev": true }, + "tar": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.0.2.tgz", + "integrity": "sha512-Glo3jkRtPcvpDlAs/0+hozav78yoXKFr+c4wgw62NNMO3oo4AaJdCo21Uu7lcwr55h39W2XD1LMERc64wtbItg==", + "dev": true, + "requires": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^3.0.0", + "minizlib": "^2.1.0", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "dependencies": { + "chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true + }, + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } + }, "terminal-link": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", @@ -14825,9 +15626,9 @@ "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=" }, "threads": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/threads/-/threads-1.4.0.tgz", - "integrity": "sha512-vaKhZODDnciJn4Bjmkd1GbJ2dlzFbzxwcQNM1IZV1bsCXmlJpirSAKsYG7MT7MHgO+qQxTaIn6CMstmlYnGNWw==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/threads/-/threads-1.6.0.tgz", + "integrity": "sha512-S/QSzV/e6q+GyAuzY/QIfvzMFbN1ECMCKC8ScTw/9UNycTGQ/W6Rl6MnqRRexhvvUdR+k0l32gG8CIhdw81TLg==", "requires": { "callsites": "^3.1.0", "debug": "^4.1.1", @@ -15673,11 +16474,6 @@ "resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz", "integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==" }, - "unorm": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/unorm/-/unorm-1.4.1.tgz", - "integrity": "sha1-NkIA1fE2RsqLzURJAnEzVhR5IwA=" - }, "unset-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", diff --git a/package.json b/package.json index 78acd5975..970cf7fb2 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,6 @@ { "name": "polykey", + "bin": "bin/pk.js", "version": "0.0.1", "author": "Roger Qiu", "description": "Polykey Core Library", @@ -16,27 +17,27 @@ "url": "https://github.com/MatrixAI/js-polykey.git" }, "main": "dist/polykey.js", + "types": "dist/index.d.ts", "module": "dist/polykey.js", "scripts": { "develop": "webpack --mode=development --watch & webpack-dev-server --mode=development & wait", "build": "webpack --mode='production'", - "test": "jest", - "dos2unix": "dos2unix dist/*", - "chmod": "chmod u+x dist/bin/*", - "doc": "documentation build ./lib/** -f html -o ./doc" + "test": "jest" }, "jest": { "verbose": true }, "engines": { - "node": ">=8.7.0" + "node": ">=12.14.0" }, "dependencies": { + "@grpc/grpc-js": "^1.0.5", + "@grpc/proto-loader": "^0.5.4", "@types/commander": "^2.12.2", "@types/configstore": "^4.0.0", "@types/inquirer": "^6.5.0", - "bip39": "^2.5.0", "chalk": "^4.0.0", + "cli-progress": "^3.8.2", "commander": "^5.1.0", "configstore": "^5.0.1", "encryptedfs": "^0.1.0", @@ -48,21 +49,25 @@ "jsonfile": "^6.0.1", "kbpgp": "^2.0.82", "moniker": "^0.1.2", + "node-fetch": "^2.6.0", + "threads": "^1.6.0", "virtualfs": "^2.2.0", "zxcvbn": "^4.4.2" }, "devDependencies": { "@types/jest": "^25.0.0", "@types/node": "^13.13.1", - "@types/lodash": "^4.5.0", - "threads-plugin": "^1.3.1", + "copy-webpack-plugin": "^6.0.2", + "documentation": "^8.1.2", + "file-loader": "^6.0.0", "jest": "^25.0.0", + "threads-plugin": "^1.3.1", "ts-jest": "^25.0.0", "ts-loader": "^6.2.2", "ts-node": "^8.8.2", + "tsconfig-paths": "^3.9.0", "tsconfig-paths-webpack-plugin": "^3.2.0", "typescript": "^3.8.3", - "documentation": "^8.1.2", "webpack": "^4.42.1", "webpack-cli": "^3.3.11", "webpack-node-externals": "^1.7.2" diff --git a/src/KeyManager.ts b/src/KeyManager.ts deleted file mode 100644 index 19dd75262..000000000 --- a/src/KeyManager.ts +++ /dev/null @@ -1,346 +0,0 @@ -import fs from 'fs' -import Path from 'path' -import crypto from 'crypto' -import { promisify } from 'util' - -// js imports -const kbpgp = require('kbpgp') -var F = kbpgp["const"].openpgp -const zxcvbn = require('zxcvbn') - -type KeyPair = { - private: string, - public: string, - passphrase: string -} - -class KeyManager { - private keyPair: KeyPair = {private: '', public: '', passphrase: ''} - private identity: Object | undefined = undefined - private derivedKeys: Map - private passphrase!: string - - storePath: string - - constructor( - polyKeyPath: string = '~/.polykey/' - ) { - this.storePath = polyKeyPath - - this.derivedKeys = new Map() - } - - // return {private: string, public: string} - async generateKeyPair(name: string, email: string, passphrase: string, numBits: number = 4096): Promise { - // Validate passphrase - const passValidation = zxcvbn(passphrase) - // The following is an arbitrary delineation of desirable scores - if (passValidation.score < 2) { - throw new Error(`passphrase score for new keypair is below 2!`) - } - - // Define options - var options = { - userid: `${name} <${email}>`, - primary: { - nbits: 4096, - flags: F.certify_keys | F.sign_data | F.auth | F.encrypt_comm | F.encrypt_storage, - expire_in: 0 // never expire - }, - subkeys: [ - // { - // nbits: 2048, - // flags: F.sign_data, - // expire_in: 86400 * 365 * 8 // 8 years - // } - ] - } - - this.passphrase = passphrase - - return new Promise((resolve, reject) => { - kbpgp.KeyManager.generate(options, (err, identity) => { - identity.sign({}, (err) => { - if (err) { - reject(err) - } - // Export pub key first - identity.export_pgp_public({}, (err, pubKey) => { - if (err) { - reject(err) - } - // Finally export priv key - identity.export_pgp_private({passphrase: passphrase}, (err, privKey) => { - if (err) { - reject(err) - } - // Resolve to parent promise - const keypair = { private: privKey, public: pubKey, passphrase: passphrase } - this.keyPair = keypair - // Set the new identity - this.identity = identity - - resolve(keypair) - }) - }) - }) - }) - }) - } - - getKeyPair(): KeyPair { - return this.keyPair - } - - getPublicKey(): string { - return this.keyPair.public - } - - getPrivateKey(): string { - return this.keyPair.private - } - - async loadPrivateKey(privateKey: string | Buffer, passphrase: string = ''): Promise { - try { - let keyBuffer: Buffer - if (typeof privateKey === 'string') { - keyBuffer = Buffer.from(await fs.promises.readFile(privateKey)) - } else { - keyBuffer = privateKey - } - this.keyPair.private = keyBuffer.toString() - - if (passphrase) { - this.passphrase = passphrase - } - } catch (err) { - throw(err) - } - } - - async loadPublicKey(publicKey: string | Buffer): Promise { - try { - let keyBuffer: Buffer - if (typeof publicKey === 'string') { - keyBuffer = Buffer.from(await fs.promises.readFile(publicKey)) - } else { - keyBuffer = publicKey - } - this.keyPair.public = keyBuffer.toString() - } catch (err) { - throw(err) - } - } - - async loadIdentity(passphrase: string): Promise { - return new Promise((resolve, reject) => { - const pubKey: string = this.getPublicKey() - const privKey: string = this.getPrivateKey() - - kbpgp.KeyManager.import_from_armored_pgp({armored: pubKey}, (err, identity) => { - if (err) { - reject(err) - } - - identity.merge_pgp_private({ - armored: privKey - }, (err) => { - if (err) { - reject(err) - } - - if (identity.is_pgp_locked()) { - identity.unlock_pgp({ - passphrase: passphrase - }, (err) => { - if (err) { - reject(err) - } - - this.identity = identity - resolve() - }) - } else { - this.identity = identity - resolve() - } - }) - }) - }) - } - - async loadKeyPair(publicKey: string | Buffer, privateKey: string | Buffer, passphrase: string = '') { - await this.loadPrivateKey(privateKey) - await this.loadPublicKey(publicKey) - await this.loadIdentity(passphrase) - - if (passphrase) { - this.passphrase - } - } - - async exportPrivateKey(path: string): Promise { - await fs.promises.writeFile(path, this.keyPair.private) - } - - async exportPublicKey(path: string): Promise { - await fs.promises.writeFile(path, this.keyPair.public) - } - - // symmetric key generation - generateKeySync(name: string, passphrase: string): Buffer { - const salt = crypto.randomBytes(32) - this.derivedKeys[name] = crypto.pbkdf2Sync(passphrase , salt, 10000, 256/8, 'sha256') - - return this.derivedKeys[name] - } - - async generateKey(name: string, passphrase: string): Promise { - const salt = crypto.randomBytes(32) - this.derivedKeys[name] = await promisify(crypto.pbkdf2)(passphrase , salt, 10000, 256/8, 'sha256') - - return this.derivedKeys[name] - } - - importKeySync(name: string, keyPath: string): void { - this.derivedKeys[name] = fs.readFileSync(keyPath) - } - - async importKey(name: string, keyPath: string): Promise { - this.derivedKeys[name] = await fs.promises.readFile(keyPath) - } - - importKeyBuffer(name: string, key: Buffer): void { - this.derivedKeys[name] = key - } - - async exportKey(name: string, path: string, createPath?: boolean): Promise { - if (!this.derivedKeys[name]) { - throw Error(`There is no key loaded for name: ${name}`) - } - if (createPath) { - await fs.promises.mkdir(Path.dirname(path), {recursive: true}) - } - await fs.promises.writeFile(path, this.derivedKeys[name]) - } - - exportKeySync(path: string, createPath?: boolean): void { - if (!this.derivedKeys[name]) { - throw Error(`There is no key loaded for name: ${name}`) - } - if (createPath) { - fs.mkdirSync(Path.dirname(path), {recursive: true}) - } - fs.writeFileSync(path, this.derivedKeys[name]) - } - - async getIdentityFromPublicKey(pubKey: Buffer): Promise { - return new Promise((resolve, reject) => { - kbpgp.KeyManager.import_from_armored_pgp({armored: pubKey}, (err, identity) => { - if (err) { - reject(err) - } - resolve(identity) - }) - }) - } - - async getIdentityFromPrivateKey(privKey: Buffer, passphrase: string): Promise { - return new Promise((resolve, reject) => { - kbpgp.KeyManager.import_from_armored_pgp({armored: privKey}, (err, identity) => { - if (err) { - reject(err) - } - if (identity.is_pgp_locked()) { - identity.unlock_pgp({ - passphrase: passphrase - }, (err) => { - if (err) { - reject(err) - } - resolve(identity) - }); - } else { - resolve(identity) - } - }) - }) - } - - // Sign data - signData(data: Buffer | string, withKey: Buffer | undefined = undefined, keyPassphrase: string | undefined = undefined): Promise { - return new Promise(async (resolve, reject) => { - let resolvedIdentity: Object - if (withKey !== undefined) { - if (keyPassphrase === undefined) { - reject(Error('passphrase for private key was not provided')) - } - resolvedIdentity = await this.getIdentityFromPrivateKey(withKey, keyPassphrase!) - } else if (this.identity !== undefined) { - resolvedIdentity = this.identity - } else { - throw(Error('no identity available for signing')) - } - const params = { - msg: data, - sign_with: resolvedIdentity - } - kbpgp.box(params, (err: Error, result_string: string, result_buffer: Buffer) => { - if (err) { - reject(err) - } - resolve(Buffer.from(result_string)) - }) - }) - } - - // Verify data - verifyData(data: Buffer | string, signature: Buffer, withKey: Buffer | undefined = undefined): Promise { - return new Promise(async (resolve, reject) => { - var ring = new kbpgp.keyring.KeyRing; - let resolvedIdentity: Object - if (withKey !== undefined) { - resolvedIdentity = await this.getIdentityFromPublicKey(withKey) - } else if (this.identity !== undefined) { - resolvedIdentity = this.identity - } else { - throw(Error('no identity available for signing')) - } - - ring.add_key_manager(this.identity) - const params = { - armored: signature, - data: data, - keyfetch: ring - } - kbpgp.unbox(params, (err, literals) => { - if (err) { - reject(err) - } - let ds = literals[0].get_data_signer() - let km: any - if (ds) { - km = ds.get_key_manager() - } - if (km) { - resolve(km.get_pgp_fingerprint().toString('hex')); - } else { - reject(Error('could not verify file')) - } - }) - }) - } - - getKey(name: string): Buffer { - return this.derivedKeys[name] - } - - isLoaded(): boolean { - if (this.derivedKeys[name]) { - return true - } - return false - } -} - -export { KeyManager, KeyPair} diff --git a/src/Polykey.ts b/src/Polykey.ts deleted file mode 100644 index c4f0a3ad2..000000000 --- a/src/Polykey.ts +++ /dev/null @@ -1,437 +0,0 @@ -import os from 'os' -import fs from 'fs' -import Path from 'path' -import Vault from '@polykey/Vault' -import crypto from 'crypto' -import jsonfile from 'jsonfile' -import { KeyManager } from '@polykey/KeyManager' - -type Metadata = { - vaults: { - [vaultName: string]: { - key: Buffer, tags: Array - } - } - publicKeyPath: string | null - privateKeyPath: string | null - passphrase: string | null -} - -const vaultKeySize = 128/8 // in bytes - -export default class Polykey { - polykeyPath: string - private fs: typeof fs - private vaults:Map - private key: Buffer - private keySize: number - private metadata: Metadata - private metadataPath: string - km: KeyManager - - private node: any - - constructor( - km?: KeyManager, - polykeyPath: string = `${os.homedir()}/.polykey` - ) { - this.km = km || new KeyManager(this.polykeyPath) - this.polykeyPath = polykeyPath - this.metadataPath = Path.join(this.polykeyPath, 'metadata') - // Set file system - this.fs = fs - // Initialize reamining members - this.vaults = new Map() - this.metadata = { - vaults: {}, - publicKeyPath: null, - privateKeyPath: null, - passphrase: null - } - // sync with polykey directory - this.initSync() - - } - - static get KeyManager() { - return KeyManager - } - private async fileExists(path: string): Promise { - return this.fs.existsSync(path) - } - private fileExistsSync(path: string): boolean { - return this.fs.existsSync(path) - } - - ///////////// - // Secrets // - ///////////// - async secretExists(vaultName: string, secretName: string): Promise { - const vault = await this.getVault(vaultName) - const secretExists = vault.secretExists(secretName) - - return secretExists - } - - async addSecret(vaultName: string, secretName: string, secret: Buffer): Promise { - let vault: Vault - try { - vault = await this.getVault(vaultName) - vault.addSecret(secretName, secret) - } catch(err) { - throw err - } - } - - async removeSecret(vaultName: string, secretName: string): Promise { - let vault: Vault - try { - vault = await this.getVault(vaultName) - vault.removeSecret(secretName) - } catch(err) { - throw err - } - } - - async getSecret(vaultName: string, secretName: string): Promise { - let vault: Vault - let secret: string | Buffer - try { - vault = await this.getVault(vaultName) - secret = vault.getSecret(secretName) - } catch(err) { - throw err - } - return secret - } - - async copySecret(vaultName: string, secretName: string): Promise { - let vault: Vault - let secret: string | Buffer - try { - vault = await this.getVault(vaultName) - secret = vault.getSecret(secretName) - } catch(err) { - throw err - } - return secret - } - - ///////////// - // Vaults // - ///////////// - async createVault(vaultName: string, key: Buffer | undefined = undefined): Promise { - const path = Path.join(this.polykeyPath, vaultName) - let vaultExists: boolean - try { - vaultExists = await this.fileExists(path) - } catch(err) { - throw err - } - - if (vaultExists) { - throw Error('Vault already exists!') - } - - try { - // Directory not present, create one - this.fs.mkdirSync(path, {recursive:true}) - // Create key if not provided - let vaultKey: Buffer - if (key === undefined) { - // Generate new key - vaultKey = Buffer.from(crypto.randomBytes(vaultKeySize)) - } else { - // Assign key if it is provided - vaultKey = key - } - this.metadata.vaults[vaultName] = { key: vaultKey, tags: []} - await this.writeMetadata() - const vault = new Vault(vaultName, vaultKey, this.polykeyPath) - this.vaults.set(vaultName, vault) - return await this.getVault(vaultName) - } catch (err) { - // Delete vault dir and garbage collect - await this.destroyVault(vaultName) - throw err - } - } - - async vaultExists(vaultName: string): Promise { - const path = Path.join(this.polykeyPath, vaultName) - const vaultExists = this.fs.existsSync(path) - - return vaultExists - } - - async destroyVault(vaultName: string) { - - // this is convenience function for removing all tags - // and triggering garbage collection - // destruction is a better word as we should ensure all traces is removed - - const path = Path.join(this.polykeyPath, vaultName) - // Remove directory on file system - if (this.fs.existsSync(path)) { - this.fs.rmdirSync(path, {recursive: true}) - } - // Remaining garbage collection: - // Remove vault from vaults map - if (this.vaults.has(vaultName)) { - this.vaults.delete(vaultName) - } - // Remove from metadata - if (this.metadata.vaults.hasOwnProperty(vaultName)) { - delete this.metadata.vaults[vaultName] - await this.writeMetadata() - } - - const vaultPathExists = this.fs.existsSync(path) - if (vaultPathExists) { - throw(Error('Vault path could not be destroyed!')) - } - const vaultEntryExists = this.vaults.has(vaultName) - if (vaultEntryExists) { - throw(Error('Vault could not be removed from PolyKey!')) - } - const metaDataHasVault = this.metadata.vaults.hasOwnProperty(vaultName) - if (metaDataHasVault) { - throw(Error('Vault metadata could not be destroyed!')) - } - } - - async importKeyPair(privateKeyPath: string, publicKeyPath: string, passphrase: string = '') { - await this.km.loadKeyPair(privateKeyPath, publicKeyPath, passphrase) - this.metadata.publicKeyPath = publicKeyPath - this.metadata.privateKeyPath = privateKeyPath - this.metadata.passphrase = passphrase - this.writeMetadata() - } - - /* Validates whether all the artefacts needed to operate - * a Vault are present. Namely this the vault directory - * and the metadata for the vault containg the key - */ - private async validateVault (vaultName: string): Promise { - const existsMeta = this.metadata.vaults.hasOwnProperty(vaultName) - if (!existsMeta) { - throw Error('Vault metadata does not exist') - } - const vaultPath = Path.join(this.polykeyPath, vaultName) - const existsFS = await this.fileExists(vaultPath) - if (!existsFS) { - throw Error('Vault directory does not exist') - } - } - - removeItem () { - - } - - listItems () { - - } - - listVaults(): string[] { - return Array.from(this.vaults.keys()) - } - - async listSecrets(vaultName: string): Promise { - const vault = await this.getVault(vaultName) - return vault.listSecrets() - } - - async verifyFile(filePath: string, signaturePath: string, publicKey: string | Buffer | undefined = undefined): Promise { - try { - // Get key if provided - let keyBuffer: Buffer | undefined - if (publicKey !== undefined) { - if (typeof publicKey === 'string') { // Path - // Read in from fs - keyBuffer = Buffer.from(this.fs.readFileSync(publicKey)) - } else { // Buffer - keyBuffer = publicKey - } - } else { - // Load keypair into KeyManager from metadata - const publicKeyPath = this.metadata.publicKeyPath - const privateKeyPath = this.metadata.privateKeyPath - const passphrase = this.metadata.passphrase - if (publicKeyPath !== null && privateKeyPath !== null && passphrase !== null) { - await this.km.loadKeyPair( - privateKeyPath, - publicKeyPath, - passphrase - ) - } - } - // Read in file buffer and signature - const fileBuffer = Buffer.from(this.fs.readFileSync(filePath, undefined)) - const signatureBuffer = Buffer.from(this.fs.readFileSync(signaturePath, undefined)) - const verified = await this.km.verifyData(fileBuffer, signatureBuffer, keyBuffer) - return verified - } catch (err) { - throw(err) - } - } - - async signFile(path: string, privateKey: string | Buffer | undefined = undefined, privateKeyPassphrase: string | undefined = undefined): Promise { - try { - // Get key if provided - let keyBuffer: Buffer | undefined - if (privateKey !== undefined) { - if (typeof privateKey === 'string') { // Path - // Read in from fs - keyBuffer = Buffer.from(this.fs.readFileSync(privateKey)) - } else { // Buffer - keyBuffer = privateKey - } - } else { - // Load keypair into KeyManager from metadata - const publicKeyPath = this.metadata.publicKeyPath - const privateKeyPath = this.metadata.privateKeyPath - const passphrase = this.metadata.passphrase - if (publicKeyPath !== null && privateKeyPath !== null && passphrase !== null) { - await this.km.loadKeyPair( - privateKeyPath, - publicKeyPath, - passphrase - ) - } - } - // Read file into buffer - const buffer = Buffer.from(this.fs.readFileSync(path, undefined)) - // Sign the buffer - const signedBuffer = await this.km.signData(buffer, keyBuffer, privateKeyPassphrase) - // Write buffer to signed file - const signedPath = `${path}.sig` - this.fs.writeFileSync(signedPath, signedBuffer) - return signedPath - } catch (err) { - throw(Error(`failed to sign file: ${err}`)) - } - } - - // P2P operations - async beginPolyKeyDaemon() { - // const repos = new Git(this.polykeyPath, this.fs, { - // fs: this.fs, - // autoCreate: false - // }); - // const port = 7005; - - // repos.on('push', (push) => { - // console.log(`push ${push.repo}/${push.commit} (${push.branch})`); - // push.accept(); - // }); - - // repos.on('fetch', (fetch) => { - // console.log(`fetch ${fetch.commit}`); - // fetch.accept(); - // }); - - // repos.listen(port, null, () => { - // console.log(`node-git-server running at http://localhost:${port}`) - // }) - - // return `ip4/127.0.0.1/tcp/${port}` - } - - tagVault() { - - } - - untagVault() { - - } - - shareVault() { - - } - - unshareVault() { - - } - - - /* ============ HELPERS =============== */ - private async writeMetadata(): Promise { - try { - await jsonfile.writeFile(this.metadataPath, this.metadata) - } catch (err) { - throw Error("Error writing vault key to config file") - } - } - - private async getVault(vaultName: string): Promise { - if (this.vaults.has(vaultName)) { - const vault = this.vaults.get(vaultName) - if (vault) { - return vault - } - } - // vault not in map, create new instance - try { - await this.validateVault(vaultName) - } catch(err) { - throw err - } - const vaultKey = this.metadata.vaults[vaultName].key - const vault = new Vault(vaultName, vaultKey, this.polykeyPath) - this.vaults.set(vaultName, vault) - return vault - } - - async getNodeAddrs(): Promise { - let nodeAddr: string[] = [] - // console.log('where is the repo?'); - // console.log(await this.node.repo.stat()) - const addr = await this.node.id() - addr.addresses.forEach((ma) => { - nodeAddr.push(`${ma.toString()}`) - }) - return nodeAddr - } - - initSync(): void { - // check if .polykey exists - // make folder if doesn't - if (!this.fs.existsSync(this.polykeyPath)) { - this.fs.mkdirSync(this.polykeyPath, {recursive: true}) - const metadataTemplate = { - vaults: {}, - publicKeyPath: null, - privateKeyPath: null, - passphrase: null - } - jsonfile.writeFileSync(this.metadataPath, metadataTemplate) - this.metadata = metadataTemplate - } else if (this.fs.existsSync(this.metadataPath)) { - this.metadata = jsonfile.readFileSync(this.metadataPath) - } - - // Load all of the vaults into memory - for (const vaultName in this.metadata.vaults) { - if (this.metadata.vaults.hasOwnProperty(vaultName)) { - const path = Path.join(this.polykeyPath, vaultName) - if (this.fileExistsSync(path)) { - try { - const vaultKey = Buffer.from(this.metadata.vaults[vaultName].key) - const vault = new Vault(vaultName, vaultKey, this.polykeyPath) - this.vaults.set(vaultName, vault) - } catch (err) { - throw(err) - } - } - } - } - } - - loadKey(path: string | Buffer): Buffer { - if (path instanceof Buffer) { - return path - } - const keyBuf = Buffer.from(this.fs.readFileSync(path, undefined)) - return keyBuf - } -} diff --git a/bin/config/Config.ts b/src/cli/Config.ts similarity index 97% rename from bin/config/Config.ts rename to src/cli/Config.ts index 3e6c27a97..ffda58371 100644 --- a/bin/config/Config.ts +++ b/src/cli/Config.ts @@ -1,6 +1,6 @@ import commander from 'commander' import Configstore from 'configstore' -import { actionRunner, pkLogger, PKMessageType } from '../polykey' +import { actionRunner, pkLogger, PKMessageType } from './polykey' function makeConfigClearCommand() { return new commander.Command('clear') diff --git a/bin/crypto/Crypto.ts b/src/cli/Crypto.ts similarity index 87% rename from bin/crypto/Crypto.ts rename to src/cli/Crypto.ts index 35c80ce31..a4003a11c 100644 --- a/bin/crypto/Crypto.ts +++ b/src/cli/Crypto.ts @@ -1,6 +1,6 @@ import commander from 'commander' -import initPolyKey from '../initPolykey' -import { actionRunner, pkLogger, PKMessageType } from '../polykey' +import initPolyKey from './initPolykey' +import { actionRunner, pkLogger, PKMessageType } from './polykey' function makeSignCommand() { return new commander.Command('sign') @@ -15,7 +15,7 @@ function makeSignCommand() { const filePathList = options.args.values() for (const filePath of filePathList) { try { - const signedPath = await pk.signFile(filePath, signingKeyPath, keyPassphrase) + const signedPath = await pk.keyManager.signFile(filePath, signingKeyPath, keyPassphrase) pkLogger(`file '${filePath}' successfully signed at '${signedPath}'`, PKMessageType.SUCCESS) } catch (err) { throw new Error(`failed to sign '${filePath}': ${err}`) @@ -43,7 +43,7 @@ function makeVerifyCommand() { throw new Error('no signature provided') } try { - const pgpFingerprint = await pk.verifyFile(filePath, detachedSignaturePath, verifyingKeyPath) + const pgpFingerprint = await pk.keyManager.verifyFile(filePath, detachedSignaturePath, verifyingKeyPath) pkLogger(`file '${filePath}' successfully verified. PGP fingerprint: ${pgpFingerprint}`, PKMessageType.SUCCESS) } catch (err) { throw new Error(`failed to sign '${filePath}': ${err.message}`) diff --git a/bin/keymanager/KeyManager.ts b/src/cli/KeyManager.ts similarity index 82% rename from bin/keymanager/KeyManager.ts rename to src/cli/KeyManager.ts index 9d5c6e1df..8f97c2a80 100644 --- a/bin/keymanager/KeyManager.ts +++ b/src/cli/KeyManager.ts @@ -1,6 +1,6 @@ import commander from 'commander' -import { actionRunner, pkLogger, PKMessageType } from '../polykey' -import initPolyKey from '../initPolykey' +import initPolyKey from './initPolykey' +import { actionRunner, pkLogger, PKMessageType } from './polykey' function makeDeriveKeyCommand() { return new commander.Command('derive') @@ -11,7 +11,7 @@ function makeDeriveKeyCommand() { const keyName = options.keyName const keyPassphrase = options.keyPassphrase const pk = await initPolyKey() - pk.km.generateKeySync(keyPassphrase, keyName) + pk.keyManager.generateKeySync(keyPassphrase, keyName) pkLogger(`'${keyName}' was added to the Key Manager`, PKMessageType.SUCCESS) })) } diff --git a/bin/node/Node.ts b/src/cli/Node.ts similarity index 93% rename from bin/node/Node.ts rename to src/cli/Node.ts index f36d5b85e..dc117a0e5 100644 --- a/bin/node/Node.ts +++ b/src/cli/Node.ts @@ -1,5 +1,5 @@ import commander from 'commander' -import { actionRunner } from '../polykey'; +import { actionRunner } from './polykey'; function makeStartNodeCommand() { return new commander.Command('start') diff --git a/bin/secrets/Secrets.ts b/src/cli/Secrets.ts similarity index 87% rename from bin/secrets/Secrets.ts rename to src/cli/Secrets.ts index 9c8993674..b261b9df1 100644 --- a/bin/secrets/Secrets.ts +++ b/src/cli/Secrets.ts @@ -1,8 +1,7 @@ -import chalk from 'chalk' import fs from 'fs' -import initPolyKey from "../initPolykey" import commander from 'commander' -import { actionRunner, pkLogger, PKMessageType } from '../polykey' +import initPolyKey from "./initPolykey" +import { actionRunner, pkLogger, PKMessageType } from './polykey' function makeListSecretsCommand() { return new commander.Command('list') @@ -20,7 +19,8 @@ function makeListSecretsCommand() { throw new Error(`vault '${vaultName}' does not exist!`) } // Get list of secrets from pk - const secretsList = await pk.listSecrets(vaultName) + const vault = await pk.getVault(vaultName) + const secretsList = vault.listSecrets() // List secrets if (isVerbose) { @@ -57,15 +57,16 @@ function makeAddSecretCommand() { if (!(await pk.vaultExists(vaultName))) { throw new Error(`vault '${vaultName}' does not exist!`) } + const vault = await pk.getVault(secretName) // Check if secret exists - if (await pk.secretExists(vaultName, secretName)) { + if (await vault.secretExists(secretName)) { throw new Error(`secret '${secretName}' already exists in vault ${vaultName}!`) } // Load up secret const secretBuffer = fs.readFileSync(secretPath) // Add the secret - await pk.addSecret(vaultName, secretName, secretBuffer) - if (await pk.secretExists(vaultName, secretName)) { + await vault.addSecret(secretName, secretBuffer) + if (await vault.secretExists(secretName)) { pkLogger(`secret '${secretName}' was sucessfully added to vault '${vaultName}'`, PKMessageType.SUCCESS) } else { throw new Error(`something went wrong, secret '${secretName}' was not added to vault '${vaultName}'`) @@ -92,9 +93,10 @@ function makeRemoveSecretCommand() { if (!(await pk.vaultExists(vaultName))) { throw new Error(`vault '${vaultName}' does not exist!`) } + const vault = await pk.getVault(secretName) // Remove secret - await pk.removeSecret(vaultName, secretName) - if (!(await pk.secretExists(vaultName, secretName))) { + await vault.removeSecret(secretName) + if (!(await vault.secretExists(secretName))) { pkLogger(`secret '${secretName}' was sucessfully removed from vault '${vaultName}'`, PKMessageType.SUCCESS) } else { throw new Error(`something went wrong, secret '${secretName}' was not removed from vault '${vaultName}'`) diff --git a/bin/vaults/Vaults.ts b/src/cli/Vaults.ts similarity index 95% rename from bin/vaults/Vaults.ts rename to src/cli/Vaults.ts index 72de59cf4..ac95f75c5 100644 --- a/bin/vaults/Vaults.ts +++ b/src/cli/Vaults.ts @@ -1,8 +1,7 @@ import chalk from 'chalk' -import fs from 'fs' -import initPolyKey from "../initPolykey" import commander from 'commander' -import { actionRunner, pkLogger, PKMessageType } from '../polykey' +import initPolyKey from "./initPolykey" +import { actionRunner, pkLogger, PKMessageType } from './polykey' function makeListVaultsCommand() { return new commander.Command('list') diff --git a/bin/initPolykey.ts b/src/cli/initPolykey.ts similarity index 88% rename from bin/initPolykey.ts rename to src/cli/initPolykey.ts index a4f9633f7..dff067b21 100644 --- a/bin/initPolykey.ts +++ b/src/cli/initPolykey.ts @@ -1,10 +1,12 @@ import fs from 'fs' import os from 'os' +import zxcvbn from 'zxcvbn' import inquirer from 'inquirer' -import PolyKey from '../src/Polykey' import Configstore from 'configstore' -import { KeyManager } from '../src/KeyManager' -import { actionRunner } from './polykey' +import PolyKey from '../lib/Polykey' +import cliProgress from 'cli-progress' +import KeyManager from '@polykey/KeyManager' +import { actionRunner, pkLogger, PKMessageType } from './polykey' const configStore = new Configstore('PolyKeyConfig') @@ -157,7 +159,19 @@ async function initPolyKey(): Promise { const keyGenerationName = configStore.get('keyGenerationName') const keyGenerationEmail = configStore.get('keyGenerationEmail') const keyGenerationPassphrase = configStore.get('keyGenerationPassphrase') - await keyManager.generateKeyPair(keyGenerationName, keyGenerationEmail, keyGenerationPassphrase) + + // Validate passphrase + const passValidation = zxcvbn(keyGenerationPassphrase) + // The following is an arbitrary delineation of desirable scores + if (passValidation.score < 2) { + pkLogger('passphrase score for new keypair is below 2!', PKMessageType.WARNING) + } + + const bar = new cliProgress.SingleBar({}, cliProgress.Presets.shades_classic) + bar.start(200, 0) + bar.update(100) + bar.stop() + await keyManager.generateKeyPair(keyGenerationName, keyGenerationEmail, keyGenerationPassphrase, true) // Store the keys in the key manager's storePath const storePath = `${resolveTilde(keyManager.storePath)}/.keypair` diff --git a/bin/polykey.ts b/src/cli/polykey.ts similarity index 64% rename from bin/polykey.ts rename to src/cli/polykey.ts index 4c1b68ce8..735fa20fc 100644 --- a/bin/polykey.ts +++ b/src/cli/polykey.ts @@ -1,18 +1,11 @@ -#!/usr/bin/env node - -// this will be a CLI entrypoint to this library -// we expect that this can be used as a CLI -// application directly as js-polykey - import chalk from 'chalk' import { program } from 'commander' -import makeConfigCommand from './config/Config' -import makeSecretsCommand from './secrets/Secrets' -import makeKeyManagerCommand from './keymanager/KeyManager' -import makeNodeCommand from './node/Node' -import makeCryptoCommand from './crypto/Crypto' -import makeVaultsCommand from './vaults/Vaults' - +import makeConfigCommand from './Config' +import makeSecretsCommand from './Secrets' +import makeKeyManagerCommand from './KeyManager' +import makeNodeCommand from './Node' +import makeCryptoCommand from './Crypto' +import makeVaultsCommand from './Vaults' /*******************************************/ // Error handler @@ -53,7 +46,7 @@ function pkLogger(message: string, type?: PKMessageType) { // Version info const polykey = new program.Command() polykey - .version(require('../package.json').version, '--version', 'output the current version') + .version(require('../../package.json').version, '--version', 'output the current version') .addCommand(makeConfigCommand()) .addCommand(makeKeyManagerCommand()) .addCommand(makeNodeCommand()) @@ -61,10 +54,9 @@ polykey .addCommand(makeVaultsCommand()) .addCommand(makeCryptoCommand()) -// Check if anything needs to be prompted for polykey init -async function main() { - polykey.parse(process.argv) +export { actionRunner, PKMessageType, pkLogger } +module.exports = function(argv: any[]) { + polykey.parse(argv) } -main() -export { actionRunner, PKMessageType, pkLogger } + diff --git a/src/lib/KeyManager.ts b/src/lib/KeyManager.ts new file mode 100644 index 000000000..50778bcb3 --- /dev/null +++ b/src/lib/KeyManager.ts @@ -0,0 +1,475 @@ +import fs from 'fs' +import Path from 'path' +import kbpgp from 'kbpgp' +import crypto from 'crypto' +import { promisify } from 'util' +import {Pool, ModuleThread} from 'threads' +import { KeyManagerWorker } from '@polykey/KeyManagerWorker' + +type KeyPair = { + private: string, + public: string, + passphrase: string +} + +class KeyManager { + private primaryKeyPair: KeyPair = {private: '', public: '', passphrase: ''} + private primaryPassphrase?: string + private primaryIdentity?: Object + private derivedKeys: Map + private useWebWorkers: boolean + private workerPool?: Pool> + + storePath: string + + constructor( + polyKeyPath: string = '~/.polykey/', + useWebWorkers: boolean = false, + workerPool?: Pool> + ) { + this.storePath = polyKeyPath + this.useWebWorkers = useWebWorkers + this.workerPool = workerPool + this.derivedKeys = new Map() + } + + // return {private: string, public: string} + // The replacePrimary parameter will tell KeyManager to replace the + // existing identity with one derived from the new keypair + async generateKeyPair(name: string, email: string, passphrase: string, replacePrimary: boolean = false, progressCallback?: (info) => void): Promise { + + // Define options + const F = kbpgp["const"].openpgp + const options = { + asp: (progressCallback) ? new kbpgp.ASP({progress_hook: progressCallback}) : undefined, + userid: `${name} <${email}>`, + primary: { + nbits: 4096, + flags: F.certify_keys | F.sign_data | F.auth | F.encrypt_comm | F.encrypt_storage, + expire_in: 0 // never expire + }, + subkeys: [] + } + + return new Promise((resolve, reject) => { + kbpgp.KeyManager.generate(options, (err, identity) => { + if (err) { + reject(err) + } + identity.sign({}, (err) => { + if (err) { + reject(err) + } + // Export pub key first + identity.export_pgp_public({}, (err, pubKey) => { + if (err) { + reject(err) + } + // Finally export priv key + identity.export_pgp_private({passphrase: passphrase}, (err, privKey) => { + if (err) { + reject(err) + } + // Resolve to parent promise + const keypair = { private: privKey, public: pubKey, passphrase: passphrase } + if (replacePrimary) { + // Set the new passphrase + this.primaryPassphrase = passphrase + // Set the new keypair + this.primaryKeyPair = keypair + // Set the new identity + this.primaryIdentity = identity + } + + resolve(keypair) + }) + }) + }) + }) + }) + } + + getKeyPair(): KeyPair { + return this.primaryKeyPair + } + + getPublicKey(): string { + return this.primaryKeyPair.public + } + + getPrivateKey(): string { + return this.primaryKeyPair.private + } + + async loadPrivateKey(privateKey: string | Buffer, passphrase: string = ''): Promise { + try { + let keyBuffer: Buffer + if (typeof privateKey === 'string') { + keyBuffer = Buffer.from(await fs.promises.readFile(privateKey)) + } else { + keyBuffer = privateKey + } + this.primaryKeyPair.private = keyBuffer.toString() + + if (passphrase) { + this.primaryPassphrase = passphrase + } + } catch (err) { + throw(err) + } + } + + async loadPublicKey(publicKey: string | Buffer): Promise { + try { + let keyBuffer: Buffer + if (typeof publicKey === 'string') { + keyBuffer = Buffer.from(await fs.promises.readFile(publicKey)) + } else { + keyBuffer = publicKey + } + this.primaryKeyPair.public = keyBuffer.toString() + } catch (err) { + throw(err) + } + } + + async loadIdentity(passphrase: string): Promise { + return new Promise((resolve, reject) => { + const pubKey: string = this.getPublicKey() + const privKey: string = this.getPrivateKey() + + kbpgp.KeyManager.import_from_armored_pgp({armored: pubKey}, (err, identity) => { + if (err) { + reject(err) + } + + identity.merge_pgp_private({ + armored: privKey + }, (err) => { + if (err) { + reject(err) + } + + if (identity.is_pgp_locked()) { + identity.unlock_pgp({ + passphrase: passphrase + }, (err) => { + if (err) { + reject(err) + } + + this.primaryIdentity = identity + resolve() + }) + } else { + this.primaryIdentity = identity + resolve() + } + }) + }) + }) + } + + async loadKeyPair(publicKey: string | Buffer, privateKey: string | Buffer, passphrase: string = ''): Promise { + await this.loadPrivateKey(privateKey) + await this.loadPublicKey(publicKey) + await this.loadIdentity(passphrase) + + if (passphrase) { + this.primaryPassphrase + } + } + + async exportPrivateKey(path: string): Promise { + await fs.promises.writeFile(path, this.primaryKeyPair.private) + } + + async exportPublicKey(path: string): Promise { + await fs.promises.writeFile(path, this.primaryKeyPair.public) + } + + // symmetric key generation + generateKeySync(name: string, passphrase: string): Buffer { + const salt = crypto.randomBytes(32) + this.derivedKeys[name] = crypto.pbkdf2Sync(passphrase , salt, 10000, 256/8, 'sha256') + + return this.derivedKeys[name] + } + + async generateKey(name: string, passphrase: string): Promise { + const salt = crypto.randomBytes(32) + this.derivedKeys[name] = await promisify(crypto.pbkdf2)(passphrase , salt, 10000, 256/8, 'sha256') + + return this.derivedKeys[name] + } + + importKeySync(name: string, key: string | Buffer): void { + if (typeof key === 'string') { + this.derivedKeys[name] = fs.readFileSync(key) + } else { + this.derivedKeys[name] = key + } + } + + async importKey(name: string, key: string | Buffer): Promise { + if (typeof key === 'string') { + this.derivedKeys[name] = await fs.promises.readFile(key) + } else { + this.derivedKeys[name] = key + } + } + + async exportKey(name: string, path: string, createPath?: boolean): Promise { + if (!this.derivedKeys.has(name)) { + throw Error(`There is no key loaded for name: ${name}`) + } + if (createPath) { + await fs.promises.mkdir(Path.dirname(path), {recursive: true}) + } + await fs.promises.writeFile(path, this.derivedKeys[name]) + } + + exportKeySync(path: string, createPath?: boolean): void { + if (!this.derivedKeys.has(name)) { + throw Error(`There is no key loaded for name: ${name}`) + } + if (createPath) { + fs.mkdirSync(Path.dirname(path), {recursive: true}) + } + fs.writeFileSync(path, this.derivedKeys[name]) + } + + async getIdentityFromPublicKey(pubKey: Buffer): Promise { + return new Promise((resolve, reject) => { + kbpgp.KeyManager.import_from_armored_pgp({armored: pubKey}, (err, identity) => { + if (err) { + reject(err) + } + resolve(identity) + }) + }) + } + + async getIdentityFromPrivateKey(privKey: Buffer, passphrase: string): Promise { + return new Promise((resolve, reject) => { + kbpgp.KeyManager.import_from_armored_pgp({armored: privKey}, (err, identity) => { + if (err) { + reject(err) + } + if (identity.is_pgp_locked()) { + identity.unlock_pgp({ + passphrase: passphrase + }, (err) => { + if (err) { + reject(err) + } + resolve(identity) + }); + } else { + resolve(identity) + } + }) + }) + } + + // Sign data + signData(data: Buffer | string, withKey?: Buffer, keyPassphrase?: string): Promise { + return new Promise(async (resolve, reject) => { + let resolvedIdentity: Object + if (withKey) { + if (!keyPassphrase) { + reject(Error('passphrase for private key was not provided')) + } + resolvedIdentity = await this.getIdentityFromPrivateKey(withKey, keyPassphrase!) + } else if (this.primaryIdentity) { + resolvedIdentity = this.primaryIdentity + } else { + throw(Error('no identity available for signing')) + } + + if (this.useWebWorkers && this.workerPool) { + const workerResponse = await this.workerPool.queue(async (workerCrypto) => { + return await workerCrypto.signData(data, resolvedIdentity); + }); + resolve(workerResponse) + } else { + const params = { + msg: data, + sign_with: resolvedIdentity + } + kbpgp.box(params, (err: Error, result_string: string, result_buffer: Buffer) => { + if (err) { + reject(err) + } + resolve(Buffer.from(result_string)) + }) + } + }) + } + + // Verify data + verifyData(data: Buffer | string, signature: Buffer, withKey?: Buffer): Promise { + return new Promise(async (resolve, reject) => { + const ring = new kbpgp.keyring.KeyRing; + let resolvedIdentity: Object + if (withKey) { + resolvedIdentity = await this.getIdentityFromPublicKey(withKey) + } else if (this.primaryIdentity) { + resolvedIdentity = this.primaryIdentity + } else { + throw new Error('no identity available for verifying') + } + + if (this.useWebWorkers && this.workerPool) { + const workerResponse = await this.workerPool.queue(async (workerCrypto) => { + return await workerCrypto.verifyData(data, signature, resolvedIdentity); + }); + resolve(workerResponse) + } else { + ring.add_key_manager(this.primaryIdentity) + const params = { + armored: signature, + data: data, + keyfetch: ring + } + kbpgp.unbox(params, (err, literals) => { + if (err) { + reject(err) + } + let ds = literals[0].get_data_signer() + let km: any + if (ds) { + km = ds.get_key_manager() + } + if (km) { + resolve(km.get_pgp_fingerprint().toString('hex')); + } else { + reject(Error('could not verify file')) + } + }) + } + }) + } + + async verifyFile(filePath: string, signaturePath: string, publicKey?: string | Buffer): Promise { + // Get key if provided + let keyBuffer: Buffer + if (publicKey) { + if (typeof publicKey === 'string') { // Path + // Read in from fs + keyBuffer = fs.readFileSync(publicKey) + } else { // Buffer + keyBuffer = publicKey + } + } + // Read in file buffer and signature + const fileBuffer = fs.readFileSync(filePath) + const signatureBuffer = fs.readFileSync(signaturePath) + const verified = await this.verifyData(fileBuffer, signatureBuffer, keyBuffer!) + return verified + } + + async signFile(path: string, privateKey?: string | Buffer, privateKeyPassphrase?: string): Promise { + // Get key if provided + let keyBuffer: Buffer + if (privateKey) { + if (typeof privateKey === 'string') { // Path + // Read in from fs + keyBuffer = Buffer.from(fs.readFileSync(privateKey)) + } else { // Buffer + keyBuffer = privateKey + } + } + // Read file into buffer + const buffer = Buffer.from(fs.readFileSync(path)) + // Sign the buffer + const signedBuffer = await this.signData(buffer, keyBuffer!, privateKeyPassphrase) + // Write buffer to signed file + const signedPath = `${path}.sig` + fs.writeFileSync(signedPath, signedBuffer) + return signedPath + } + + // Encrypt data + async encryptData(data: Buffer, forPubKey: Buffer): Promise { + return new Promise(async (resolve, reject) => { + let resolvedIdentity: Object + try { + resolvedIdentity = await this.getIdentityFromPublicKey(forPubKey) + } catch (err) { + throw(Error(`Identity could not be resolved for encrypting: ${err}`)) + } + + if (this.useWebWorkers && this.workerPool) { + const workerResponse = await this.workerPool.queue(async (workerCrypto) => { + return await workerCrypto.encryptData(data, resolvedIdentity); + }); + resolve(workerResponse) + } else { + const params = { + msg: data, + encrypt_for: resolvedIdentity + } + kbpgp.box(params, (err: Error, result_string: string, result_buffer: Buffer) => { + if (err) { + reject(err) + } + resolve(result_string) + }) + } + }) + } + + // Decrypt data + async decryptData(data: string, withKey?: Buffer): Promise { + return new Promise(async (resolve, reject) => { + var ring = new kbpgp.keyring.KeyRing; + let resolvedIdentity: Object + if (withKey) { + resolvedIdentity = await this.getIdentityFromPublicKey(withKey) + } else if (this.primaryIdentity) { + resolvedIdentity = this.primaryIdentity + } else { + throw(Error('no identity available for signing')) + } + + if (this.useWebWorkers && this.workerPool) { + const workerResponse = await this.workerPool.queue(async (workerCrypto) => { + return await workerCrypto.decryptData(data, resolvedIdentity); + }); + resolve(workerResponse) + } else { + ring.add_key_manager(resolvedIdentity) + const params = { + armored: data, + keyfetch: ring + } + kbpgp.unbox(params, (err, literals) => { + if (err) { + reject(err) + } + try { + const decryptedData = Buffer.from(literals[0].toString()) + resolve(decryptedData) + } catch (err) { + reject(err) + } + }) + } + }) + } + + getKey(name: string): Buffer { + return this.derivedKeys[name] + } + + isLoaded(): boolean { + if (this.derivedKeys[name]) { + return true + } + return false + } +} + +export default KeyManager +export { KeyPair} diff --git a/src/lib/KeyManagerWorker.ts b/src/lib/KeyManagerWorker.ts new file mode 100644 index 000000000..304d105ba --- /dev/null +++ b/src/lib/KeyManagerWorker.ts @@ -0,0 +1,90 @@ +import kbpgp from 'kbpgp' +import { expose } from 'threads/worker'; + +const keyManagerWorker = { + // Sign data + signData(data: Buffer | string, identity: any): Promise { + return new Promise(async (resolve, reject) => { + const params = { + msg: data, + sign_with: identity + } + kbpgp.box(params, (err: Error, result_string: string, result_buffer: Buffer) => { + if (err) { + reject(err) + } + resolve(Buffer.from(result_string)) + }) + }) + }, + // Verify data + verifyData(data: Buffer | string, signature: Buffer, identity: any): Promise { + return new Promise(async (resolve, reject) => { + const ring = new kbpgp.keyring.KeyRing; + + ring.add_key_manager(identity) + const params = { + armored: signature, + data: data, + keyfetch: ring + } + kbpgp.unbox(params, (err, literals) => { + if (err) { + reject(err) + } + let ds = literals[0].get_data_signer() + let km: any + if (ds) { + km = ds.get_key_manager() + } + if (km) { + resolve(km.get_pgp_fingerprint().toString('hex')); + } else { + reject(Error('could not verify file')) + } + }) + }) + }, + // Encrypt data + async encryptData(data: Buffer, identity: any): Promise { + return new Promise(async (resolve, reject) => { + const params = { + msg: data, + encrypt_for: identity + } + kbpgp.box(params, (err: Error, result_string: string, result_buffer: Buffer) => { + if (err) { + reject(err) + } + resolve(result_string) + }) + }) + }, + // Decrypt data + async decryptData(data: string, identity: any): Promise { + return new Promise(async (resolve, reject) => { + var ring = new kbpgp.keyring.KeyRing; + + ring.add_key_manager(identity) + const params = { + armored: data, + keyfetch: ring + } + kbpgp.unbox(params, (err, literals) => { + if (err) { + reject(err) + } + try { + const decryptedData = Buffer.from(literals[0].toString()) + resolve(decryptedData) + } catch (err) { + reject(err) + } + }) + }) + } +}; + +export type KeyManagerWorker = typeof keyManagerWorker; + +expose(keyManagerWorker); diff --git a/src/lib/P2P/MulticastBroadcaster.ts b/src/lib/P2P/MulticastBroadcaster.ts new file mode 100644 index 000000000..0f3c945e9 --- /dev/null +++ b/src/lib/P2P/MulticastBroadcaster.ts @@ -0,0 +1,167 @@ +import dgram from 'dgram' +import crypto from 'crypto' +import { EventEmitter } from 'events' +import KeyManager from '@polykey/KeyManager' +import RPCMessage from '@polykey/RPC/RPCMessage' +import PeerStore from '@polykey/PeerStore/PeerStore' + +// This module is based heavily on libp2p's mDNS module: +// https://github.com/libp2p/js-libp2p-mdns +// It is supposed to discover peers on the local network +// This module was also generated with the help of: +// https://nrempel.com/using-udp-multicast-with-node-js/ +// +// """ +// In computer networking, the multicast DNS (mDNS) protocol +// resolves hostnames to IP addresses within small networks +// that do not include a local name server +// """ + +const UDP_MULTICAST_PORT = parseInt(process.env.UDP_MULTICAST_PORT ?? '5353'); +const UDP_MULTICAST_ADDR = process.env.UDP_MULTICAST_ADDR ?? "224.0.0.251"; + +type PeerMessage = { + encryptedLocalPubKey: Buffer + encryptedPeerPubKey: Buffer + rawRandomMessage: Buffer + encryptedRandomMessage: Buffer +} + +class MulticastBroadcaster extends EventEmitter { + peerStore: PeerStore + keyManager: KeyManager + + socket: dgram.Socket + + interval: number + queryInterval: NodeJS.Timeout | null + peerPubKeyMessages: Map = new Map() + constructor( + peerStore: PeerStore, + keyManager: KeyManager + ) { + super() + + this.peerStore = peerStore + this.keyManager = keyManager + + this.interval = (1e3) + this.queryInterval = null + + // Create socket + this.socket = dgram.createSocket({ type: "udp4", reuseAddr: true }) + this.socket.bind(UDP_MULTICAST_PORT) + + // Set up listener + this.socket.on("listening", (() => { + this.socket.addMembership(UDP_MULTICAST_ADDR); + const address = this.socket.address(); + console.log( + `UDP socket listening on ${address.address}:${address.port} pid: ${ + process.pid + }` + ); + }).bind(this)); + + // Handle messages + this.socket.on("message", this.handleHandshakeMessages.bind(this)); + + // Start the query process + this.queryInterval = this.queryLAN() + } + + + queryLAN() { + const query = () => { + for (const pubKey of this.peerPubKeyMessages.keys()) { + const peerMessage = this.peerPubKeyMessages.get(pubKey) + if (peerMessage) { + const handshakeMessage = RPCMessage.encodeHandshakeMessage( + peerMessage.encryptedPeerPubKey, + peerMessage.encryptedLocalPubKey, + peerMessage.encryptedRandomMessage + ) + + this.socket.send(handshakeMessage, 0, handshakeMessage.length, UDP_MULTICAST_PORT, UDP_MULTICAST_ADDR, () => { + console.info(`Sending message to peer`); + }); + } + + } + } + + // Immediately start a query, then do it every interval. + query() + return setInterval(query, this.interval) + } + + private async handleHandshakeMessages(message: any, rinfo: any) { + try { + const decodedMessage = RPCMessage.decodeHandshakeMessage(message) + console.info(`Message from: ${rinfo.address}:${rinfo.port}`); + + + // Try to decrypt message and pubKey + const decryptedMessage = await this.keyManager.decryptData(decodedMessage.message.toString()) + const decryptedTargetPubKey = await this.keyManager.decryptData(decodedMessage.targetPubKey.toString()) + const decryptedRequestingPubKey = await this.keyManager.decryptData(decodedMessage.requestingPubKey.toString()) + + const myPubKey = this.keyManager.getPublicKey() + + if (decryptedRequestingPubKey.toString() == myPubKey) { // Response + // Make sure decrypted bytes equal raw bytes in memory + const originalMessage = this.peerPubKeyMessages.get(decryptedTargetPubKey.toString())?.rawRandomMessage + + if (decryptedMessage.toString() == originalMessage?.toString()) { // Validated! + // Add peer info to peerStore + const newPeerInfo = decodedMessage.responsePeerInfo + if (newPeerInfo) { + this.peerStore.add(newPeerInfo) + // Remove peerId from requested messages + const pubKey = newPeerInfo.publicKey + this.peerPubKeyMessages.delete(pubKey) + console.log(`New peer added to the store`); + this.emit('found', newPeerInfo) + } else { + this.emit('error', "I got a validated response. But no peerInfo"); + } + } + } else { // Requests on target node + // Try decrypting message + // Re-encrypt the data and send it on its way + + const encryptedTargetPubKey = await this.keyManager.encryptData(Buffer.from(myPubKey), decryptedRequestingPubKey) + const encryptedMessage = await this.keyManager.encryptData(decryptedMessage, decryptedRequestingPubKey) + const encryptedPubKey = await this.keyManager.encryptData(decryptedRequestingPubKey, decryptedRequestingPubKey) + const handshakeMessage = RPCMessage.encodeHandshakeMessage( + Buffer.from(encryptedTargetPubKey), + Buffer.from(encryptedPubKey), + Buffer.from(encryptedMessage), + this.peerStore.localPeerInfo + ) + this.socket.send(handshakeMessage, 0, handshakeMessage.length, UDP_MULTICAST_PORT, UDP_MULTICAST_ADDR); + } + } catch (err) { // Couldn't decode message + // We don't want the multicast discovery to error on every message it coudln't decode! + } + } + + async requestPeerContact(pubKey: string) { + const pubKeyBuf = Buffer.from(pubKey) + const randomMessage = crypto.randomBytes(16) + // Encrypt message + const encryptedPeerPubKey = await this.keyManager.encryptData(pubKeyBuf, pubKeyBuf) + const encryptedRandomMessage = await this.keyManager.encryptData(randomMessage, pubKeyBuf) + const encryptedLocalPubKey = await this.keyManager.encryptData(Buffer.from(this.keyManager.getPublicKey()), pubKeyBuf) + + // Add to peer messages to be sent over multicast + this.peerPubKeyMessages.set(pubKey, { + encryptedLocalPubKey: Buffer.from(encryptedLocalPubKey), + encryptedPeerPubKey: Buffer.from(encryptedPeerPubKey), + rawRandomMessage: randomMessage, + encryptedRandomMessage: Buffer.from(encryptedRandomMessage) + }) + } +} + +export default MulticastBroadcaster diff --git a/src/lib/P2P/PeerDiscovery.ts b/src/lib/P2P/PeerDiscovery.ts new file mode 100644 index 000000000..f01dafbe0 --- /dev/null +++ b/src/lib/P2P/PeerDiscovery.ts @@ -0,0 +1,96 @@ +import fetch from 'node-fetch' +import KeyManager from "@polykey/KeyManager"; +import PeerInfo from "@polykey/PeerStore/PeerInfo"; +import PeerStore from "@polykey/PeerStore/PeerStore"; +import MulticastBroadcaster from "@polykey/P2P/MulticastBroadcaster"; +import { firstPromiseFulfilled } from '@polykey/utils'; + +interface SocialDiscovery { + // Must return a public pgp key + name: string + findUser(handle: string, service: string): Promise +} + +const keybaseLookup = async (handle: string, service: string): Promise => { + const url = `https://keybase.io/_/api/1.0/user/lookup.json?${service}=${handle}` + + try { + const response = await fetch(url) + const data = await response.json() + + const pubKey = data.them[0].public_keys.primary.bundle + return pubKey + } catch (err) { + throw new Error(`User was not found: ${err.message}`) + } +} +const keybaseDiscovery: SocialDiscovery = { + name: 'Keybase', + findUser: keybaseLookup +} + +class PeerDiscovery { + peerStore: PeerStore + keyManager: KeyManager + multicastBroadcaster: MulticastBroadcaster + private socialDiscoveryServices: SocialDiscovery[] + + constructor( + peerStore: PeerStore, + keyManager: KeyManager, + socialDiscoveryServices: SocialDiscovery[] = [] + ) { + this.peerStore = peerStore + this.keyManager = keyManager + this.socialDiscoveryServices = socialDiscoveryServices + + this.socialDiscoveryServices = [] + this.socialDiscoveryServices.push(keybaseDiscovery) + for (const service of socialDiscoveryServices) { + this.socialDiscoveryServices.push(service) + } + + this.multicastBroadcaster = new MulticastBroadcaster(this.peerStore, this.keyManager) + } + + async findPubKey(pubKey: string): Promise { + return new Promise((resolve, reject) => { + this.multicastBroadcaster.requestPeerContact(pubKey) + this.multicastBroadcaster.on('found', (peerInfo: PeerInfo) => { + if (peerInfo.publicKey == pubKey) { + resolve(peerInfo) + } + }) + + this.multicastBroadcaster.on('timeout', (timedOutPubKey: string) => { + if (timedOutPubKey == pubKey) { + reject('The broadcaster stopped looking') + } + }) + }) + } + + async findSocialUser(handle: string, service: string): Promise { + const tasks: Promise[] = [] + for (const socialDiscovery of this.socialDiscoveryServices) { + + try { + tasks.push(socialDiscovery.findUser(handle, service)) + } catch (error) { + console.log(`Could not find user on this discovery service: ${socialDiscovery.name}`); + } + } + + const pubKeyOrFail = await firstPromiseFulfilled(tasks) + if (pubKeyOrFail.length > 1) { + throw new Error('Could not find public key from services') + } + + const pubKeyFound = pubKeyOrFail[0] + const peerInfo = await this.findPubKey(pubKeyFound) + return peerInfo + } +} + +export default PeerDiscovery +export { SocialDiscovery } diff --git a/src/lib/PeerStore/PeerInfo.ts b/src/lib/PeerStore/PeerInfo.ts new file mode 100644 index 000000000..fdad5a4d3 --- /dev/null +++ b/src/lib/PeerStore/PeerInfo.ts @@ -0,0 +1,57 @@ +class Address { + ip: string + port: string + constructor( + ip: string, + port: string + ) { + this.ip = ip + this.port = port + } + + static parse(addr: string): Address { + const components = addr.split(':') + const ip = components[0] + const port = components[1] + + return new Address(ip, port) + } + +} + +Address.prototype.toString = function() { + return `${this.ip}:${this.port}` +} + +class PeerInfo { + publicKey: string + addresses: Set
+ connectedAddr?: Address + constructor( + pubKey: string, + addresses: string[] = [], + connectedAddr?: string + ) { + this.publicKey = pubKey + this.addresses = new Set(addresses.map((addr) => { + return Address.parse(addr) + })) + this.connectedAddr = (connectedAddr) ? Address.parse(connectedAddr) : undefined + } + + connect(address: Address) { + if (!this.addresses.has(address)) { + this.addresses.add(address) + } + + this.connectedAddr = address + } + + disconnect() { + this.connectedAddr = undefined + } + +} + +export default PeerInfo +export { Address } diff --git a/src/lib/PeerStore/PeerStore.ts b/src/lib/PeerStore/PeerStore.ts new file mode 100644 index 000000000..d0ac6fa8b --- /dev/null +++ b/src/lib/PeerStore/PeerStore.ts @@ -0,0 +1,56 @@ +import PeerInfo from "@polykey/PeerStore/PeerInfo" + +/** + * Responsible for managing known peers, as well as their addresses and metadata + */ +class PeerStore { + localPeerInfo: PeerInfo + peers: Map + constructor(peerInfo: PeerInfo) { + this.localPeerInfo = peerInfo + this.peers = new Map() + } + + /** + * Stores the peerInfo of a new peer. + * If already exist, its info is updated. + */ + put(peerInfo: PeerInfo): void { + // Already know the peer? + if (this.has(peerInfo.publicKey)) { + this.update(peerInfo) + } else { + this.add(peerInfo) + } + } + + /** + * Add a new peer to the store. + */ + add(peerInfo: PeerInfo): void { + this.peers.set(peerInfo.publicKey, peerInfo) + } + + /** + * Updates an already known peer. + */ + update(peerInfo: PeerInfo): void { + this.peers.set(peerInfo.publicKey, peerInfo) + } + + /** + * Get the info to the given id. + */ + get(pubKey: string): PeerInfo | null { + return this.peers.get(pubKey) ?? null + } + + /** + * Has the info to the given id. + */ + has(pubKey: string): boolean { + return this.peers.has(pubKey) + } +} + +export default PeerStore diff --git a/src/lib/Polykey.ts b/src/lib/Polykey.ts new file mode 100644 index 000000000..9a6ff7f1d --- /dev/null +++ b/src/lib/Polykey.ts @@ -0,0 +1,233 @@ +import os from 'os' +import fs from 'fs' +import Path from 'path' +import crypto from 'crypto' +import jsonfile from 'jsonfile' +import Vault from '@polykey/Vault' +import KeyManager from '@polykey/KeyManager' +import PeerStore from '@polykey/PeerStore/PeerStore' +import PeerInfo from '@polykey/PeerStore/PeerInfo' +import RPCMessage from '@polykey/RPC/RPCMessage' +import PeerDiscovery from '@polykey/P2P/PeerDiscovery' + +type Metadata = { + vaults: { + [vaultName: string]: { + key: Buffer, tags: Array + } + } + peerInfo: Uint8Array + publicKeyPath?: string + privateKeyPath?: string +} + +class Polykey { + polykeyPath: string + private fs: typeof fs + private vaults:Map + private metadata: Metadata + private metadataPath: string + + keyManager: KeyManager + peerStore: PeerStore + peerDiscovery: PeerDiscovery + + constructor( + keyManager?: KeyManager, + peerDiscovery?: PeerDiscovery, + polykeyPath: string = `${os.homedir()}/.polykey` + ) { + this.polykeyPath = polykeyPath + this.metadataPath = Path.join(polykeyPath, 'metadata') + // Set file system + this.fs = fs + + // Set key manager + this.keyManager = keyManager ?? new KeyManager(polykeyPath) + + // Set peer discovery + this.peerDiscovery = peerDiscovery ?? new PeerDiscovery(this.peerStore, this.keyManager) + + // Make polykey path if doesn't exist + if (!this.fs.existsSync(this.polykeyPath)) { + this.fs.mkdirSync(this.polykeyPath, {recursive: true}) + } else if (this.fs.existsSync(this.metadataPath)) { + const fileContents = jsonfile.readFileSync(this.metadataPath) + this.metadata = { + vaults: fileContents.vaults, + peerInfo: fileContents.peerInfo, + publicKeyPath: fileContents.publicKeyPath, + privateKeyPath: fileContents.privateKeyPath + } + } else { + // Create a new peerInfo + const peerInfo = new PeerInfo(this.keyManager.getPublicKey()) + const metadataTemplate = { + vaults: {}, + peerInfo: RPCMessage.encodePeerInfo(peerInfo) + } + jsonfile.writeFileSync(this.metadataPath, metadataTemplate) + this.metadata = metadataTemplate + } + + // Initialize peer store and peer discovery classes + this.peerStore = new PeerStore(RPCMessage.decodePeerInfo(this.metadata.peerInfo)) + this.peerDiscovery = new PeerDiscovery(this.peerStore, this.keyManager) + + // Load all of the vaults into memory + this.vaults = new Map() + for (const vaultName in this.metadata.vaults) { + if (this.metadata.vaults.hasOwnProperty(vaultName)) { + const path = Path.join(this.polykeyPath, vaultName) + if (this.fs.existsSync(path)) { + const vaultKey = Buffer.from(this.metadata.vaults[vaultName].key) + const vault = new Vault(vaultName, vaultKey, this.polykeyPath) + this.vaults.set(vaultName, vault) + } + } + } + } + + //////////// + // Vaults // + //////////// + async getVault(vaultName: string): Promise { + if (this.vaults.has(vaultName)) { + const vault = this.vaults.get(vaultName) + if (vault) { + return vault + } + } + // vault not in map, create new instance + await this.validateVault(vaultName) + + const vaultKey = this.metadata.vaults[vaultName].key + const vault = new Vault(vaultName, vaultKey, this.polykeyPath) + this.vaults.set(vaultName, vault) + return vault + } + + async createVault(vaultName: string, key?: Buffer): Promise { + const path = Path.join(this.polykeyPath, vaultName) + let vaultExists: boolean + vaultExists = this.fs.existsSync(path) + + if (vaultExists) { + throw Error('Vault already exists!') + } + + try { + // Directory not present, create one + this.fs.mkdirSync(path, {recursive:true}) + // Create key if not provided + let vaultKey: Buffer + if (!key) { + // Generate new key + vaultKey = crypto.randomBytes(16) + } else { + // Assign key if it is provided + vaultKey = key + } + this.metadata.vaults[vaultName] = { key: vaultKey, tags: []} + await this.writeMetadata() + const vault = new Vault(vaultName, vaultKey, this.polykeyPath) + this.vaults.set(vaultName, vault) + return await this.getVault(vaultName) + } catch (err) { + // Delete vault dir and garbage collect + await this.destroyVault(vaultName) + throw err + } + } + + async vaultExists(vaultName: string): Promise { + const path = Path.join(this.polykeyPath, vaultName) + const vaultExists = this.fs.existsSync(path) + + return vaultExists + } + + async destroyVault(vaultName: string) { + + // this is convenience function for removing all tags + // and triggering garbage collection + // destruction is a better word as we should ensure all traces is removed + + const path = Path.join(this.polykeyPath, vaultName) + // Remove directory on file system + if (this.fs.existsSync(path)) { + this.fs.rmdirSync(path, {recursive: true}) + } + // Remaining garbage collection: + // Remove vault from vaults map + if (this.vaults.has(vaultName)) { + this.vaults.delete(vaultName) + } + // Remove from metadata + if (this.metadata.vaults.hasOwnProperty(vaultName)) { + delete this.metadata.vaults[vaultName] + await this.writeMetadata() + } + + const vaultPathExists = this.fs.existsSync(path) + if (vaultPathExists) { + throw new Error('Vault path could not be destroyed!') + } + const vaultEntryExists = this.vaults.has(vaultName) + if (vaultEntryExists) { + throw new Error('Vault could not be removed from PolyKey!') + } + const metaDataHasVault = this.metadata.vaults.hasOwnProperty(vaultName) + if (metaDataHasVault) { + throw new Error('Vault metadata could not be destroyed!') + } + } + + /* Validates whether all the artefacts needed to operate + * a Vault are present. Namely this the vault directory + * and the metadata for the vault containg the key + */ + private async validateVault (vaultName: string): Promise { + const existsMeta = this.metadata.vaults.hasOwnProperty(vaultName) + if (!existsMeta) { + throw Error('Vault metadata does not exist') + } + const vaultPath = Path.join(this.polykeyPath, vaultName) + const existsFS = this.fs.existsSync(vaultPath) + if (!existsFS) { + throw Error('Vault directory does not exist') + } + } + + listVaults(): string[] { + return Array.from(this.vaults.keys()) + } + + + tagVault() { + + } + + untagVault() { + + } + + shareVault() { + + } + + unshareVault() { + + } + + /* ============ HELPERS =============== */ + private async writeMetadata(): Promise { + try { + await jsonfile.writeFile(this.metadataPath, this.metadata) + } catch (err) { + throw Error("Error writing vault key to config file") + } + } +} + +export default Polykey diff --git a/src/lib/RPC/HandshakeMessage.proto b/src/lib/RPC/HandshakeMessage.proto new file mode 100644 index 000000000..588242348 --- /dev/null +++ b/src/lib/RPC/HandshakeMessage.proto @@ -0,0 +1,9 @@ +package handshakepackage; +syntax = "proto3"; + +message HandshakeMessage { + bytes target_pub_key = 1; + bytes requesting_pub_key = 2; + bytes message = 3; + bytes response_peer_info = 4; +} diff --git a/src/lib/RPC/PeerInfoMessage.proto b/src/lib/RPC/PeerInfoMessage.proto new file mode 100644 index 000000000..45dbd73bd --- /dev/null +++ b/src/lib/RPC/PeerInfoMessage.proto @@ -0,0 +1,8 @@ +package peerinfopackage; +syntax = "proto3"; + +message PeerInfoMessage { + string pub_key = 1; + repeated string addresses = 2; + string connected_addr = 3; +} diff --git a/src/lib/RPC/RPCMessage.ts b/src/lib/RPC/RPCMessage.ts new file mode 100644 index 000000000..4ab70ffc4 --- /dev/null +++ b/src/lib/RPC/RPCMessage.ts @@ -0,0 +1,140 @@ +import Path from 'path' +import protobuf, { Root } from 'protobufjs' +import PeerInfo from '@polykey/PeerStore/PeerInfo' + +type HandshakeMessage = { + targetPubKey: Buffer + requestingPubKey: Buffer + message: Buffer + responsePeerInfo?: PeerInfo +} +console.log(__filename); + +class RPCMessage { + static loadProto(name: string): Root { + // Load root + const root: Root = new protobuf.Root() + root.resolvePath = (origin, target) => { + return Path.join(Path.dirname(__filename), target) + } + + return root.loadSync(name) + } + static encodePeerInfo(peerInfo: PeerInfo): Uint8Array { + const root = this.loadProto("PeerInfoMessage.proto") + + // Obtain a message type + const PeerInfoMessage = root!.lookupType("peerinfopackage.PeerInfoMessage"); + + // Encode address set to array + const addresses: string[] = [] + for (const addr of peerInfo.addresses) { + addresses.push(addr.toString()) + } + + // Exemplary payload + const payload = { + pubKey: peerInfo.publicKey, + addresses: addresses, + connectedAddr: peerInfo.connectedAddr?.toString() + }; + + // Verify the payload if necessary (i.e. when possibly incomplete or invalid) + const errMsg = PeerInfoMessage.verify(payload); + if (errMsg) + throw Error(errMsg); + + // Create a new message + const message = PeerInfoMessage.create(payload); // or use .fromObject if conversion is necessary + + // Encode a message to an Uint8Array (browser) or Buffer (node) + const buffer = PeerInfoMessage.encode(message).finish(); + + return buffer + } + + static decodePeerInfo(buffer: Uint8Array): PeerInfo { + const root = this.loadProto("PeerInfoMessage.proto") + + // Obtain a message type + const PeerInfoMessage = root!.lookupType("peerinfopackage.PeerInfoMessage"); + + // Decode an Uint8Array (browser) or Buffer (node) to a message + const message = PeerInfoMessage.decode(buffer); + + // Convert the message back to a plain object + const object = PeerInfoMessage.toObject(message, { + enums: String, // enums as string names + longs: String, // longs as strings (requires long.js) + bytes: String, // bytes as base64 encoded strings + defaults: true, // includes default values + arrays: true, // populates empty arrays (repeated fields) even if defaults=false + objects: true, // populates empty objects (map fields) even if defaults=false + oneofs: true // includes virtual oneof fields set to the present field's name + }); + + return new PeerInfo( + object.pubKey, + object.addresses, + object.connectedAddr + ) + } + + static encodeHandshakeMessage(targetPubKey: Buffer, requestingPubKey: Buffer, messageBuf: Buffer, responsePeerInfo?: PeerInfo): Uint8Array { + const root = this.loadProto("HandshakeMessage.proto") + + // Obtain a message type + const HandshakeMessage = root!.lookupType("handshakepackage.HandshakeMessage"); + + // Exemplary payload + const payload = { + targetPubKey: targetPubKey, + requestingPubKey: requestingPubKey, + message: messageBuf, + responsePeerInfo: (responsePeerInfo) ? this.encodePeerInfo(responsePeerInfo) : undefined + }; + + // Verify the payload if necessary (i.e. when possibly incomplete or invalid) + const errMsg = HandshakeMessage.verify(payload); + if (errMsg) + throw Error(errMsg); + + // Create a new message + const message = HandshakeMessage.create(payload); // or use .fromObject if conversion is necessary + + // Encode a message to an Uint8Array (browser) or Buffer (node) + const buffer = HandshakeMessage.encode(message).finish(); + + return buffer + } + + static decodeHandshakeMessage(buffer: Uint8Array): HandshakeMessage { + const root = this.loadProto("HandshakeMessage.proto") + + // Obtain a message type + const HandshakeMessage = root!.lookupType("handshakepackage.HandshakeMessage"); + + // Decode an Uint8Array (browser) or Buffer (node) to a message + const message = HandshakeMessage.decode(buffer); + + // Convert the message back to a plain object + const object = HandshakeMessage.toObject(message, { + enums: String, // enums as string names + longs: String, // longs as strings (requires long.js) + bytes: String, // bytes as base64 encoded strings + defaults: true, // includes default values + arrays: true, // populates empty arrays (repeated fields) even if defaults=false + objects: true, // populates empty objects (map fields) even if defaults=false + oneofs: true // includes virtual oneof fields set to the present field's name + }); + + return { + targetPubKey: Buffer.from(object.targetPubKey, 'base64'), + requestingPubKey: Buffer.from(object.requestingPubKey, 'base64'), + message: Buffer.from(object.message, 'base64'), + responsePeerInfo: (object.responsePeerInfo) ? this.decodePeerInfo(Buffer.from(object.responsePeerInfo, 'base64')) : undefined + } + } +} + +export default RPCMessage diff --git a/src/Vault.ts b/src/lib/Vault.ts similarity index 95% rename from src/Vault.ts rename to src/lib/Vault.ts index a96a5b88f..3d3cd9126 100644 --- a/src/Vault.ts +++ b/src/lib/Vault.ts @@ -3,9 +3,7 @@ import Path from 'path' import hkdf from 'futoin-hkdf' import { EncryptedFS } from 'encryptedfs' -const vfs = require('virtualfs') - -export default class Vault { +class Vault { private key: Buffer private keyLen: number @@ -23,7 +21,7 @@ export default class Vault { this.keyLen = 32 this.key = this.genSymKey(symKey, this.keyLen) // Set filesystem - const vfsInstance = new vfs.VirtualFS + const vfsInstance = new (require('virtualfs')).VirtualFS this.fs = new EncryptedFS( symKey, @@ -42,7 +40,7 @@ export default class Vault { this.loadSecrets() } - loadSecrets() { + loadSecrets(): void { const secrets = fs.readdirSync(this.vaultPath, undefined) for (const secret of secrets) { @@ -118,3 +116,5 @@ export default class Vault { // ============== Helper methods ============== // } + +export default Vault diff --git a/src/index.ts b/src/lib/index.ts similarity index 100% rename from src/index.ts rename to src/lib/index.ts diff --git a/src/lib/utils.ts b/src/lib/utils.ts new file mode 100644 index 000000000..97ba9d937 --- /dev/null +++ b/src/lib/utils.ts @@ -0,0 +1,13 @@ +function randomString(): string { + return Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 5) +} + +function invertPromise(p: Promise): Promise { + return new Promise((res, rej) => p.then(rej, res)); +} + +function firstPromiseFulfilled(ps: Promise[]) { + return invertPromise(Promise.all(ps.map(invertPromise))) +} + +export { randomString, firstPromiseFulfilled } diff --git a/src/utils.ts b/src/utils.ts deleted file mode 100644 index 0709f7825..000000000 --- a/src/utils.ts +++ /dev/null @@ -1,5 +0,0 @@ -function randomString(): string { - return Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 5) -} - -export { randomString } diff --git a/tests/P2P/PeerDiscovery.test.ts b/tests/P2P/PeerDiscovery.test.ts new file mode 100644 index 000000000..3d00fa39a --- /dev/null +++ b/tests/P2P/PeerDiscovery.test.ts @@ -0,0 +1,44 @@ +import fs from 'fs' +import os from 'os' +import Polykey from "@polykey/Polykey" +import { randomString } from '@polykey/utils' +import KeyManager from '@polykey/KeyManager' + +// TODO expand tests as part of testing PR +describe('Peer Discovery', () => { + let tempDir: string + let pk: Polykey + + beforeAll(async () => { + // Define temp directory + tempDir = fs.mkdtempSync(`${os.tmpdir}/pktest${randomString()}`) + + // Create keyManager + const keyManager = new KeyManager() + await keyManager.generateKeyPair('John Smith', 'john.smith@email.com', 'some passphrase', true) + + // Initialize polykey + pk = new Polykey( + keyManager, + undefined, + tempDir + ) + + }, 40000) + + afterAll(() => { + fs.rmdirSync(tempDir) + }) + + test('find a peer', async () => { + // TODO: try to find a way to test this, currently its untestable because keybase login integration hasn't been completed + await pk.peerDiscovery.findSocialUser('robert-cronin', 'github') + }) + + test('find a user on github', async () => { + // TODO: try to find a way to test this, currently its untestable because keybase login integration hasn't been completed + await pk.peerDiscovery.findSocialUser('robert-cronin', 'github') + }) + + +}) diff --git a/tests/Polykey.test.ts b/tests/Polykey.test.ts index 37e86f6a2..6c39b6977 100644 --- a/tests/Polykey.test.ts +++ b/tests/Polykey.test.ts @@ -1,13 +1,9 @@ // ts imports import fs from 'fs' import os from 'os' -import Polykey from '../src/Polykey' -import { randomString } from '../src/utils' - -// js imports -const kbpgp = require('kbpgp') -const vfs = require('virtualfs') - +import Polykey from '@polykey/Polykey' +import { randomString } from '@polykey/utils' +import KeyManager from '@polykey/KeyManager' describe('PolyKey class', () => { @@ -19,11 +15,12 @@ describe('PolyKey class', () => { tempDir = fs.mkdtempSync(`${os.tmpdir}/pktest${randomString()}`) // Create keyManager - const km = new Polykey.KeyManager() - km.loadKeyPair('./playground/keys/private.key', './playground/keys/public.key') + const km = new KeyManager() + km.generateKeyPair('John Smith', 'john.smith@email.com', 'passphrase', true) // Initialize polykey pk = new Polykey( - km, + km, + undefined, tempDir ) done() @@ -35,7 +32,7 @@ describe('PolyKey class', () => { test('can create keypairs', done => { // Create private keys (async) - pk.km.generateKeyPair('John Smith', 'john.smith@gmail.com', 'passphrase').then((keypair) => { + pk.keyManager.generateKeyPair('John Smith', 'john.smith@gmail.com', 'passphrase').then((keypair) => { fs.mkdirSync(`${tempDir}/keys/`, {recursive: true}) fs.writeFileSync(`${tempDir}/keys/private.key`, keypair.private) fs.writeFileSync(`${tempDir}/keys/public.key`, keypair.public) @@ -53,7 +50,7 @@ describe('PolyKey class', () => { // Reset the vault name for each test vaultName = `Vault-${randomString()}` // Create private keys (async) - pk.km.generateKeyPair('John Smith', 'john.smith@gmail.com', 'passphrase').then((keypair) => { + pk.keyManager.generateKeyPair('John Smith', 'john.smith@gmail.com', 'passphrase').then((keypair) => { expect(keypair).not.toBeNull() done() }) @@ -61,8 +58,8 @@ describe('PolyKey class', () => { test('can sign and verify strings', async done => { const originalData = Buffer.from('I am to be signed') - const signedData = await pk.km.signData(originalData) - const verifiedData = await pk.km.verifyData(originalData, signedData) + const signedData = await pk.keyManager.signData(originalData) + const verifiedData = await pk.keyManager.verifyData(originalData, signedData) expect(originalData).toEqual(verifiedData) done() @@ -74,10 +71,10 @@ describe('PolyKey class', () => { fs.writeFileSync(filePath, originalData) // Sign file const signedPath = `${tempDir}/file.signed` - await pk.signFile(filePath, signedPath) + await pk.keyManager.signFile(filePath, signedPath) // Verify file const verifiedPath = `${tempDir}/file.signed` - await pk.verifyFile(signedPath, verifiedPath) + await pk.keyManager.verifyFile(signedPath, verifiedPath) // Confirm equality const verifiedBuffer = fs.readFileSync(verifiedPath, undefined) expect(verifiedBuffer).toEqual(originalData) diff --git a/tests/RPC/RPCMessage.test.ts b/tests/RPC/RPCMessage.test.ts new file mode 100644 index 000000000..811064612 --- /dev/null +++ b/tests/RPC/RPCMessage.test.ts @@ -0,0 +1,39 @@ +import PeerInfo from '@polykey/PeerStore/PeerInfo' +import RPCMessage from '@polykey/RPC/RPCMessage' +import crypto from 'crypto' + +// TODO add tests as part of testing PR +describe('RPCMessage class', () => { + + beforeAll(() => { + }) + + afterAll(() => { + }) + + test('encoding peerInfo', () => { + const peerInfo = new PeerInfo('this is a pubkey', ['0.0.0.0:2020'], '0.0.0.0:2020') + const message = RPCMessage.encodePeerInfo(peerInfo) + + const decodedPeerInfo: PeerInfo = RPCMessage.decodePeerInfo(message) + + expect(decodedPeerInfo.publicKey).toEqual(peerInfo.publicKey) + expect(decodedPeerInfo.addresses).toEqual(peerInfo.addresses) + expect(decodedPeerInfo.connectedAddr).toEqual(peerInfo.connectedAddr) + }) + + test('encoding handshake message', () => { + const targetPubKey = Buffer.from('target pubkey') + const requestingPubKey = Buffer.from('requesting pubkey') + const randomMessage = crypto.randomBytes(16) + const peerInfo = new PeerInfo(targetPubKey.toString(), ['0.0.0.0:2020'], '0.0.0.0:2020') + const encodedMessage = RPCMessage.encodeHandshakeMessage(targetPubKey, requestingPubKey, randomMessage, peerInfo) + + const decodedMessage = RPCMessage.decodeHandshakeMessage(encodedMessage) + + expect(decodedMessage.targetPubKey).toEqual(targetPubKey) + expect(decodedMessage.requestingPubKey).toEqual(requestingPubKey) + expect(decodedMessage.message).toEqual(randomMessage) + expect(decodedMessage.responsePeerInfo).toEqual(peerInfo) + }) +}) diff --git a/tests/Vaults.test.ts b/tests/Vaults.test.ts index a6dd2cb12..7a75f6724 100644 --- a/tests/Vaults.test.ts +++ b/tests/Vaults.test.ts @@ -1,7 +1,8 @@ import fs from 'fs' import os from 'os' -import Polykey from "../src/Polykey" -import { randomString } from '../src/utils' +import Polykey from "@polykey/Polykey" +import { randomString } from '@polykey/utils' +import KeyManager from '@polykey/KeyManager' describe('vaults', () => { let vaultName: string @@ -9,20 +10,21 @@ describe('vaults', () => { let tempDir: string let pk: Polykey - beforeAll(done => { + beforeAll(async done => { // Define temp directory tempDir = fs.mkdtempSync(`${os.tmpdir}/pktest${randomString()}`) // Create keyManager - const km = new Polykey.KeyManager() - km.loadKeyPair('./playground/keys/private.key', './playground/keys/public.key') + const km = new KeyManager() + km.generateKeyPair('John Smith', 'john.smith@email.com', 'passphrase', true) // Initialize polykey pk = new Polykey( - km, + km, + undefined, tempDir ) done() - }) + }, 25000) afterAll(() => { fs.rmdirSync(`${tempDir}`) @@ -33,12 +35,13 @@ describe('vaults', () => { vaultName = `Vault-${randomString()}` }) - test('can create vaults', async () => { + test('can create vault', async () => { // Create vault await pk.createVault(vaultName) const vaultExists = await pk.vaultExists(vaultName) expect(vaultExists).toEqual(true) }) + test('cannot create same vault twice', async () => { // Create vault await pk.createVault(vaultName) @@ -68,10 +71,11 @@ describe('vaults', () => { const initialSecretName = 'ASecret' const initialSecret = 'super confidential information' // Add secret - await pk.addSecret(vaultName, initialSecretName, Buffer.from(initialSecret)) + const vault = await pk.getVault(vaultName) + vault.addSecret(initialSecretName, Buffer.from(initialSecret)) // Read secret - const readBuffer = await pk.getSecret(vaultName, initialSecretName) + const readBuffer = vault.getSecret(initialSecretName) const readSecret = readBuffer.toString() expect(readSecret).toStrictEqual(initialSecret) diff --git a/tsconfig.json b/tsconfig.json index 23974d560..2d754412b 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,16 +2,16 @@ "compilerOptions": { "outDir": "./dist", "sourceMap": true, + "declaration": true, "strictNullChecks": true, - "allowJs": true, "noImplicitAny": false, "esModuleInterop": true, "allowSyntheticDefaultImports": true, "module": "CommonJS", "target": "ES2018", - "baseUrl": "./src", + "baseUrl": ".", "paths": { - "@polykey/*": ["*"] + "@polykey/*": ["src/lib/*"], } }, "include": [ diff --git a/webpack.config.js b/webpack.config.js index 97959daab..3f1812996 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -1,10 +1,60 @@ const path = require('path'); -const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin'); const ThreadsPlugin = require('threads-plugin'); +const CopyPlugin = require('copy-webpack-plugin'); const nodeExternals = require('webpack-node-externals'); +const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin'); -module.exports = { - entry: './src/index.ts', +const cliConfig = { + name: 'cli', + entry: './src/cli/polykey.ts', + output: { + path: path.resolve(__dirname, 'dist', 'bin'), + filename: 'pk.js', + library: 'pk', + libraryTarget: 'umd', + globalObject: 'this' + }, + resolve: { + extensions: ['.ts', '.js', '.proto'], + plugins: [new TsconfigPathsPlugin()] + }, + target: "node", + externals: { + fs: "commonjs fs" + }, + module: { + rules: [ + { + test: /.tsx?$/, + loader: 'ts-loader' + } + ] + }, + externals: [ + nodeExternals() + ], + plugins: [ + new ThreadsPlugin({ + globalObject: false + }), + new CopyPlugin({ + patterns: [ + { + from: 'src/**/*.proto', + to: '', + flatten: true + }, + ] + }), + ], + watchOptions: { + ignored: /node_modules/ + } +} + +const libraryConfig = { + name: 'library', + entry: './src/lib/index.ts', output: { path: path.resolve(__dirname, 'dist'), filename: 'polykey.js', @@ -14,14 +64,12 @@ module.exports = { }, devtool: "source-map", resolve: { - extensions: ['.ts', '.js'], - plugins: [new TsconfigPathsPlugin()], - alias: { - '@': path.resolve('src') - } + extensions: ['.ts', '.js', '.proto'], + plugins: [new TsconfigPathsPlugin()] }, - node: { - fs: 'empty' + target:'node', + externals: { + fs: "commonjs fs" }, module: { rules: [ @@ -37,9 +85,20 @@ module.exports = { plugins: [ new ThreadsPlugin({ globalObject: false + }), + new CopyPlugin({ + patterns: [ + { + from: 'src/**/*.proto', + to: '', + flatten: true + }, + ] }) ], watchOptions: { ignored: /node_modules/ } -}; +} + +module.exports = [cliConfig, libraryConfig];