From 59ade0d2ba95da8fcc30f3ccb3e0b518c326a837 Mon Sep 17 00:00:00 2001 From: Kyle Spearrin Date: Fri, 15 Mar 2019 22:38:02 -0400 Subject: [PATCH] stub out cli for directory connector --- .gitignore | 1 + jslib | 2 +- package-lock.json | 426 +++++++++++++++++--- package.json | 14 + src/bwdc.ts | 130 ++++++ src/commands/config.command.ts | 31 ++ src/program.ts | 212 ++++++++++ src/services/keytarSecureStorage.service.ts | 25 ++ tsconfig.json | 1 + webpack.cli.js | 80 ++++ 10 files changed, 869 insertions(+), 53 deletions(-) create mode 100644 src/bwdc.ts create mode 100644 src/commands/config.command.ts create mode 100644 src/program.ts create mode 100644 src/services/keytarSecureStorage.service.ts create mode 100644 webpack.cli.js diff --git a/.gitignore b/.gitignore index bd0a6892..2bcfd276 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ dist/ css/ *.crx *.pem +build-cli/ build/ yarn-error.log .DS_Store diff --git a/jslib b/jslib index 49e06e77..13a160fb 160000 --- a/jslib +++ b/jslib @@ -1 +1 @@ -Subproject commit 49e06e77c4913867fc468f7d9e0b2b1529c1d181 +Subproject commit 13a160fb795a69bad1edbb3fc5fd5c7c15396e03 diff --git a/package-lock.json b/package-lock.json index e1a1311f..bb8f90ed 100644 --- a/package-lock.json +++ b/package-lock.json @@ -740,6 +740,25 @@ "fs-extra": "3.0.1", "handlebars": "4.0.8", "json-stable-stringify": "1.0.1" + }, + "dependencies": { + "commander": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", + "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=", + "requires": { + "graceful-readlink": ">= 1.0.0" + } + } + } + }, + "@types/commander": { + "version": "2.12.2", + "resolved": "https://registry.npmjs.org/@types/commander/-/commander-2.12.2.tgz", + "integrity": "sha512-0QEFiR8ljcHp9bAbWxecjVRuAMr16ivPiGOw6KFQBVrVd0RQIcM3xKdRisH2EDWgVWujiYtHwhSkSUoAAGzH7Q==", + "dev": true, + "requires": { + "commander": "*" } }, "@types/events": { @@ -748,6 +767,25 @@ "integrity": "sha512-KEIlhXnIutzKwRbQkGWb/I4HFqBuUykAdHgDED6xqwXJfONCjF5VoE0cXEiurh3XauygxzeDzgtXUqvLkxFzzA==", "dev": true }, + "@types/form-data": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-2.2.1.tgz", + "integrity": "sha512-JAMFhOaHIciYVh8fb5/83nmuO/AHwmto+Hq7a9y8FzLDcC1KCU344XDOMEmahnrTFlHjgh4L0WJFczNIX2GxnQ==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/inquirer": { + "version": "0.0.43", + "resolved": "https://registry.npmjs.org/@types/inquirer/-/inquirer-0.0.43.tgz", + "integrity": "sha512-xgyfKZVMFqE8aIKy1xfFVsX2MxyXUNgjgmbF6dRbR3sL+ZM5K4ka/9L4mmTwX8eTeVYtduyXu0gUVwVJa1HbNw==", + "dev": true, + "requires": { + "@types/rx": "*", + "@types/through": "*" + } + }, "@types/ldapjs": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@types/ldapjs/-/ldapjs-1.0.3.tgz", @@ -785,6 +823,15 @@ "integrity": "sha512-VRQB+Q0L3YZWs45uRdpN9oWr82meL/8TrJ6faoKT5tp0uub2l/aRMhtm5fo68h7kjYKH60f9/bay1nF7ZpTW5g==", "dev": true }, + "@types/node-fetch": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.1.6.tgz", + "integrity": "sha512-Hv1jgh3pfpUEl2F2mqUd1AfLSk1YbUCeBJFaP36t7esAO617dErqdxWb5cdG2NfJGOofkmBW36fdx0dVewxDRg==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/node-forge": { "version": "0.7.5", "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-0.7.5.tgz", @@ -803,6 +850,132 @@ "@types/node": "*" } }, + "@types/rx": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@types/rx/-/rx-4.1.1.tgz", + "integrity": "sha1-WY/JSla67ZdfGUV04PVy/Y5iekg=", + "dev": true, + "requires": { + "@types/rx-core": "*", + "@types/rx-core-binding": "*", + "@types/rx-lite": "*", + "@types/rx-lite-aggregates": "*", + "@types/rx-lite-async": "*", + "@types/rx-lite-backpressure": "*", + "@types/rx-lite-coincidence": "*", + "@types/rx-lite-experimental": "*", + "@types/rx-lite-joinpatterns": "*", + "@types/rx-lite-testing": "*", + "@types/rx-lite-time": "*", + "@types/rx-lite-virtualtime": "*" + } + }, + "@types/rx-core": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@types/rx-core/-/rx-core-4.0.3.tgz", + "integrity": "sha1-CzNUsSOM7b4rdPYybxOdvHpZHWA=", + "dev": true + }, + "@types/rx-core-binding": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/rx-core-binding/-/rx-core-binding-4.0.4.tgz", + "integrity": "sha512-5pkfxnC4w810LqBPUwP5bg7SFR/USwhMSaAeZQQbEHeBp57pjKXRlXmqpMrLJB4y1oglR/c2502853uN0I+DAQ==", + "dev": true, + "requires": { + "@types/rx-core": "*" + } + }, + "@types/rx-lite": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@types/rx-lite/-/rx-lite-4.0.6.tgz", + "integrity": "sha512-oYiDrFIcor9zDm0VDUca1UbROiMYBxMLMaM6qzz4ADAfOmA9r1dYEcAFH+2fsPI5BCCjPvV9pWC3X3flbrvs7w==", + "dev": true, + "requires": { + "@types/rx-core": "*", + "@types/rx-core-binding": "*" + } + }, + "@types/rx-lite-aggregates": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@types/rx-lite-aggregates/-/rx-lite-aggregates-4.0.3.tgz", + "integrity": "sha512-MAGDAHy8cRatm94FDduhJF+iNS5//jrZ/PIfm+QYw9OCeDgbymFHChM8YVIvN2zArwsRftKgE33QfRWvQk4DPg==", + "dev": true, + "requires": { + "@types/rx-lite": "*" + } + }, + "@types/rx-lite-async": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/rx-lite-async/-/rx-lite-async-4.0.2.tgz", + "integrity": "sha512-vTEv5o8l6702ZwfAM5aOeVDfUwBSDOs+ARoGmWAKQ6LOInQ8J4/zjM7ov12fuTpktUKdMQjkeCp07Vd73mPkxw==", + "dev": true, + "requires": { + "@types/rx-lite": "*" + } + }, + "@types/rx-lite-backpressure": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@types/rx-lite-backpressure/-/rx-lite-backpressure-4.0.3.tgz", + "integrity": "sha512-Y6aIeQCtNban5XSAF4B8dffhIKu6aAy/TXFlScHzSxh6ivfQBQw6UjxyEJxIOt3IT49YkS+siuayM2H/Q0cmgA==", + "dev": true, + "requires": { + "@types/rx-lite": "*" + } + }, + "@types/rx-lite-coincidence": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@types/rx-lite-coincidence/-/rx-lite-coincidence-4.0.3.tgz", + "integrity": "sha512-1VNJqzE9gALUyMGypDXZZXzR0Tt7LC9DdAZQ3Ou/Q0MubNU35agVUNXKGHKpNTba+fr8GdIdkC26bRDqtCQBeQ==", + "dev": true, + "requires": { + "@types/rx-lite": "*" + } + }, + "@types/rx-lite-experimental": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/rx-lite-experimental/-/rx-lite-experimental-4.0.1.tgz", + "integrity": "sha1-xTL1y98/LBXaFt7Ykw0bKYQCPL0=", + "dev": true, + "requires": { + "@types/rx-lite": "*" + } + }, + "@types/rx-lite-joinpatterns": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/rx-lite-joinpatterns/-/rx-lite-joinpatterns-4.0.1.tgz", + "integrity": "sha1-9w/jcFGKhDLykVjMkv+1a05K/D4=", + "dev": true, + "requires": { + "@types/rx-lite": "*" + } + }, + "@types/rx-lite-testing": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/rx-lite-testing/-/rx-lite-testing-4.0.1.tgz", + "integrity": "sha1-IbGdEfTf1v/vWp0WSOnIh5v+Iek=", + "dev": true, + "requires": { + "@types/rx-lite-virtualtime": "*" + } + }, + "@types/rx-lite-time": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@types/rx-lite-time/-/rx-lite-time-4.0.3.tgz", + "integrity": "sha512-ukO5sPKDRwCGWRZRqPlaAU0SKVxmWwSjiOrLhoQDoWxZWg6vyB9XLEZViKOzIO6LnTIQBlk4UylYV0rnhJLxQw==", + "dev": true, + "requires": { + "@types/rx-lite": "*" + } + }, + "@types/rx-lite-virtualtime": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@types/rx-lite-virtualtime/-/rx-lite-virtualtime-4.0.3.tgz", + "integrity": "sha512-3uC6sGmjpOKatZSVHI2xB1+dedgml669ZRvqxy+WqmGJDVusOdyxcKfyzjW0P3/GrCiN4nmRkLVMhPwHCc5QLg==", + "dev": true, + "requires": { + "@types/rx-lite": "*" + } + }, "@types/semver": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/@types/semver/-/semver-5.5.0.tgz", @@ -821,6 +994,15 @@ "integrity": "sha512-78AdXtlhpCHT0K3EytMpn4JNxaf5tbqbLcbIRoQIHzpTIyjpxLQKRoxU55ujBXAtg3Nl2h/XWvfDa9dsMOd0pQ==", "dev": true }, + "@types/through": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/through/-/through-0.0.29.tgz", + "integrity": "sha512-9a7C5VHh+1BKblaYiq+7Tfc+EOmjMdZaD1MYtkQjSoxgB69tBjW98ry6SKsi4zEIWztLOMRuL87A3bdT/Fc/4w==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/uglify-js": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.0.3.tgz", @@ -1175,6 +1357,11 @@ "ansi-wrap": "^0.1.0" } }, + "ansi-escapes": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", + "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==" + }, "ansi-gray": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz", @@ -1193,7 +1380,6 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, "requires": { "color-convert": "^1.9.0" } @@ -1574,8 +1760,7 @@ "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", - "dev": true + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" }, "atob": { "version": "2.1.1", @@ -2287,16 +2472,35 @@ } }, "chalk": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.2.2.tgz", - "integrity": "sha512-LvixLAQ4MYhbf7hgL4o5PeK32gJKvVzDRiSNIApDofQvyhl8adgG2lJVXn4+ekQoK7HL9RF8lqxwerpe0x2pCw==", - "dev": true, + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", "requires": { - "ansi-styles": "^3.1.0", + "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", - "supports-color": "^4.0.0" + "supports-color": "^5.3.0" + }, + "dependencies": { + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + } } }, + "chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==" + }, "chokidar": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", @@ -2415,7 +2619,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", - "dev": true, "requires": { "restore-cursor": "^2.0.0" } @@ -2426,6 +2629,11 @@ "integrity": "sha512-1QL4544moEsDVH9T/l6Cemov/37iv1RtoKf7NJ04A60+4MREXNfx/QvavbH6QoGdsD4N4Mwy49cmaINR/o2mdg==", "dev": true }, + "cli-width": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=" + }, "cliui": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", @@ -2544,7 +2752,6 @@ "version": "1.9.2", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.2.tgz", "integrity": "sha512-3NUJZdhMhcdPn8vJ9v2UQJoH0qqoGUkYTgFEPZaPjEtwmmKUfNV46zZmgB2M5M4DCEQHMaCfWHCxiBflLm04Tg==", - "dev": true, "requires": { "color-name": "1.1.1" } @@ -2552,8 +2759,7 @@ "color-name": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.1.tgz", - "integrity": "sha1-SxQVMEz1ACjqgWQ2Q72C6gWANok=", - "dev": true + "integrity": "sha1-SxQVMEz1ACjqgWQ2Q72C6gWANok=" }, "color-support": { "version": "1.1.3", @@ -2571,18 +2777,14 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz", "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=", - "dev": true, "requires": { "delayed-stream": "~1.0.0" } }, "commander": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", - "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=", - "requires": { - "graceful-readlink": ">= 1.0.0" - } + "version": "2.18.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.18.0.tgz", + "integrity": "sha512-6CYPa+JP2ftfRU2qkDK+UTVeQYosOg/2GbcjIcKPHfinyOLPVGXu/ovN86RP49Re5ndJK1N0kuiidFFuepc4ZQ==" }, "commondir": { "version": "1.0.1", @@ -3368,8 +3570,7 @@ "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "dev": true + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" }, "delegates": { "version": "1.0.0", @@ -4696,8 +4897,7 @@ "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" }, "eslint-scope": { "version": "4.0.0", @@ -4824,6 +5024,16 @@ } } }, + "external-editor": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.0.3.tgz", + "integrity": "sha512-bn71H9+qWoOQKyZDo25mOMVpSmXROAsTJVVVYzrrtol3d4y+AsKjf4Iwl2Q+IuT0kFSQ1qo166UuIwqYq7mGnA==", + "requires": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + } + }, "extglob": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", @@ -4846,13 +5056,19 @@ }, "dependencies": { "async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", - "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.2.tgz", + "integrity": "sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg==", "dev": true, "requires": { - "lodash": "^4.17.10" + "lodash": "^4.17.11" } + }, + "lodash": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", + "dev": true } } }, @@ -4928,6 +5144,14 @@ "integrity": "sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w==", "dev": true }, + "figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, "file-loader": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-2.0.0.tgz", @@ -5401,7 +5625,6 @@ "version": "2.3.2", "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz", "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=", - "dev": true, "requires": { "asynckit": "^0.4.0", "combined-stream": "1.0.6", @@ -5540,12 +5763,14 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, + "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -5565,7 +5790,8 @@ "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", @@ -5713,6 +5939,7 @@ "version": "3.0.4", "bundled": true, "dev": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -7272,9 +7499,9 @@ "dev": true }, "iconv-lite": { - "version": "0.4.23", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", - "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "requires": { "safer-buffer": ">= 2.1.2 < 3" } @@ -7427,6 +7654,55 @@ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" }, + "inquirer": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.2.0.tgz", + "integrity": "sha512-QIEQG4YyQ2UYZGDC4srMZ7BjHOmNk1lR2JQj5UknBapklm6WHA+VVH7N+sUdX3A7NeCfGF8o4X1S3Ao7nAcIeg==", + "requires": { + "ansi-escapes": "^3.0.0", + "chalk": "^2.0.0", + "cli-cursor": "^2.1.0", + "cli-width": "^2.0.0", + "external-editor": "^3.0.0", + "figures": "^2.0.0", + "lodash": "^4.17.10", + "mute-stream": "0.0.7", + "run-async": "^2.2.0", + "rxjs": "^6.1.0", + "string-width": "^2.1.0", + "strip-ansi": "^4.0.0", + "through": "^2.3.6" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, "interpret": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz", @@ -7678,6 +7954,11 @@ "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", "dev": true }, + "is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=" + }, "is-redirect": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz", @@ -7785,6 +8066,17 @@ "requires": { "node-fetch": "^1.0.1", "whatwg-fetch": ">=0.10.0" + }, + "dependencies": { + "node-fetch": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", + "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==", + "requires": { + "encoding": "^0.1.11", + "is-stream": "^1.0.1" + } + } } }, "isstream": { @@ -8270,6 +8562,18 @@ "signal-exit": "^3.0.0" } }, + "lowdb": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lowdb/-/lowdb-1.0.0.tgz", + "integrity": "sha512-2+x8esE/Wb9SQ1F9IHaYWfsC9FIecLOPrK4g17FGEayjUWH172H6nwicRovGvSE2CPZouc2MCIqCI7h9d+GftQ==", + "requires": { + "graceful-fs": "^4.1.3", + "is-promise": "^2.1.0", + "lodash": "4", + "pify": "^3.0.0", + "steno": "^0.4.1" + } + }, "lower-case": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz", @@ -8758,14 +9062,12 @@ "mime-db": { "version": "1.35.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.35.0.tgz", - "integrity": "sha512-JWT/IcCTsB0Io3AhWUMjRqucrHSPsSf2xKLaRldJVULioggvkJvggZ3VXNNSRkCddE6D+BUI4HEIZIA2OjwIvg==", - "dev": true + "integrity": "sha512-JWT/IcCTsB0Io3AhWUMjRqucrHSPsSf2xKLaRldJVULioggvkJvggZ3VXNNSRkCddE6D+BUI4HEIZIA2OjwIvg==" }, "mime-types": { "version": "2.1.19", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.19.tgz", "integrity": "sha512-P1tKYHVSZ6uFo26mtnve4HQFE3koh1UWVkp8YUC+ESBHe945xWSoXuHHiGarDqcEZ+whpCDnlNw5LON0kLo+sw==", - "dev": true, "requires": { "mime-db": "~1.35.0" } @@ -8773,8 +9075,7 @@ "mimic-fn": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", - "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", - "dev": true + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==" }, "mimic-response": { "version": "1.0.1", @@ -8909,6 +9210,11 @@ "integrity": "sha512-kDcwXR4PS7caBpuRYYBUz9iVixUk3anO3f5OYFiIPwK/20vCzKCHyKoulbiDY1S53zD2bxUpxN/IJ+TnXjfvxg==", "dev": true }, + "mute-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", + "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=" + }, "mv": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", @@ -9017,13 +9323,9 @@ } }, "node-fetch": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", - "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==", - "requires": { - "encoding": "^0.1.11", - "is-stream": "^1.0.1" - } + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.2.0.tgz", + "integrity": "sha512-OayFWziIxiHY8bCUyLX6sTpDH8Jsbp4FfYd1j1f7vZyfgkcOnAyM4oQR16f8a0s7Gl/viMGRey8eScYk4V4EZA==" }, "node-forge": { "version": "0.7.6", @@ -9499,7 +9801,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", - "dev": true, "requires": { "mimic-fn": "^1.0.0" } @@ -9559,8 +9860,7 @@ "os-tmpdir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" }, "osenv": { "version": "0.1.5", @@ -10711,7 +11011,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", - "dev": true, "requires": { "onetime": "^2.0.0", "signal-exit": "^3.0.2" @@ -10772,6 +11071,14 @@ "inherits": "^2.0.1" } }, + "run-async": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", + "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", + "requires": { + "is-promise": "^2.1.0" + } + }, "run-queue": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", @@ -11500,6 +11807,14 @@ "readable-stream": "^2.0.1" } }, + "steno": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/steno/-/steno-0.4.4.tgz", + "integrity": "sha1-BxEFvfwobmYVwEA8J+nXtdy4Vcs=", + "requires": { + "graceful-fs": "^4.1.3" + } + }, "stream-browserify": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", @@ -11989,8 +12304,7 @@ "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", - "dev": true + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" }, "through2": { "version": "2.0.3", @@ -12033,6 +12347,14 @@ "setimmediate": "^1.0.4" } }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "requires": { + "os-tmpdir": "~1.0.2" + } + }, "to-absolute-glob": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz", diff --git a/package.json b/package.json index ee7d9703..243da517 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,10 @@ "build:main": "webpack --config webpack.main.js", "build:renderer": "gulp prebuild:renderer && webpack --config webpack.renderer.js", "build:renderer:watch": "gulp prebuild:renderer && webpack --config webpack.renderer.js --watch", + "build:cli": "webpack --config webpack.cli.js", + "build:cli:watch": "webpack --config webpack.cli.js --watch", + "build:cli:prod": "cross-env NODE_ENV=production webpack --config webpack.cli.js", + "build:cli:prod:watch": "cross-env NODE_ENV=production webpack --config webpack.cli.js --watch", "electron": "npm run build:main && concurrently -k -n Main,Rend -c yellow,cyan \"electron --inspect=5858 ./build --watch\" \"npm run build:renderer:watch\"", "clean:dist": "rimraf ./dist/*", "pack:lin": "npm run clean:dist && build --linux --x64 -p never", @@ -110,9 +114,13 @@ "@angular/compiler-cli": "^7.2.1", "@microsoft/microsoft-graph-types": "^1.4.0", "@ngtools/webpack": "^7.2.2", + "@types/commander": "^2.12.2", + "@types/form-data": "^2.2.1", + "@types/inquirer": "^0.0.43", "@types/ldapjs": "^1.0.3", "@types/lowdb": "^1.0.5", "@types/lunr": "^2.1.6", + "@types/node-fetch": "^2.1.2", "@types/node-forge": "^0.7.5", "@types/papaparse": "^4.5.3", "@types/semver": "^5.5.0", @@ -167,15 +175,21 @@ "angulartics2": "6.3.0", "big-integer": "1.6.36", "bootstrap": "4.1.3", + "chalk": "2.4.1", + "commander": "2.18.0", "core-js": "2.6.2", "duo_web_sdk": "git+https://github.com/duosecurity/duo_web_sdk.git", "electron-log": "2.2.17", "electron-store": "1.3.0", "electron-updater": "4.0.6", + "form-data": "2.3.2", "googleapis": "33.0.0", + "inquirer": "6.2.0", "keytar": "4.2.1", "ldapjs": "1.0.2", + "lowdb": "1.0.0", "lunr": "2.3.3", + "node-fetch": "2.2.0", "node-forge": "0.7.6", "rxjs": "6.3.3", "zone.js": "0.8.28" diff --git a/src/bwdc.ts b/src/bwdc.ts new file mode 100644 index 00000000..53d19956 --- /dev/null +++ b/src/bwdc.ts @@ -0,0 +1,130 @@ +import * as fs from 'fs'; +import * as path from 'path'; + +import { AuthService } from 'jslib/services/auth.service'; + +import { ConfigurationService } from './services/configuration.service'; +import { I18nService } from './services/i18n.service'; +import { KeytarSecureStorageService } from './services/keytarSecureStorage.service'; +import { SyncService } from './services/sync.service'; + +import { CliPlatformUtilsService } from 'jslib/cli/services/cliPlatformUtils.service'; +import { ConsoleLogService } from 'jslib/cli/services/consoleLog.service'; + +import { AppIdService } from 'jslib/services/appId.service'; +import { ConstantsService } from 'jslib/services/constants.service'; +import { ContainerService } from 'jslib/services/container.service'; +import { CryptoService } from 'jslib/services/crypto.service'; +import { EnvironmentService } from 'jslib/services/environment.service'; +import { LowdbStorageService } from 'jslib/services/lowdbStorage.service'; +import { NodeApiService } from 'jslib/services/nodeApi.service'; +import { NodeCryptoFunctionService } from 'jslib/services/nodeCryptoFunction.service'; +import { NoopMessagingService } from 'jslib/services/noopMessaging.service'; +import { TokenService } from 'jslib/services/token.service'; +import { UserService } from 'jslib/services/user.service'; + +import { Program } from './program'; + +// tslint:disable-next-line +const packageJson = require('./package.json'); + +export class Main { + logService: ConsoleLogService; + messagingService: NoopMessagingService; + storageService: LowdbStorageService; + secureStorageService: KeytarSecureStorageService; + i18nService: I18nService; + platformUtilsService: CliPlatformUtilsService; + constantsService: ConstantsService; + cryptoService: CryptoService; + tokenService: TokenService; + appIdService: AppIdService; + apiService: NodeApiService; + environmentService: EnvironmentService; + userService: UserService; + containerService: ContainerService; + cryptoFunctionService: NodeCryptoFunctionService; + authService: AuthService; + configurationService: ConfigurationService; + syncService: SyncService; + program: Program; + + constructor() { + const applicationName = 'Bitwarden Directory Connector'; + let p = null; + if (process.env.BITWARDENCLI_CONNECTOR_APPDATA_DIR) { + p = path.resolve(process.env.BITWARDENCLI_CONNECTOR_APPDATA_DIR); + } else if (process.env.BITWARDEN_CONNECTOR_APPDATA_DIR) { + p = path.resolve(process.env.BITWARDEN_CONNECTOR_APPDATA_DIR); + } else if (fs.existsSync(path.join(__dirname, 'bitwarden-connector-appdata'))) { + p = path.join(__dirname, 'bitwarden-connector-appdata'); + } else if (process.platform === 'darwin') { + p = path.join(process.env.HOME, 'Library/Application Support/' + applicationName); + } else if (process.platform === 'win32') { + p = path.join(process.env.APPDATA, applicationName); + } else if (process.env.XDG_CONFIG_HOME) { + p = path.join(process.env.XDG_CONFIG_HOME, applicationName); + } else { + p = path.join(process.env.HOME, '.config/' + applicationName); + } + + this.i18nService = new I18nService('en', './locales'); + this.platformUtilsService = new CliPlatformUtilsService('connector', packageJson); + this.logService = new ConsoleLogService(this.platformUtilsService.isDev()); + this.cryptoFunctionService = new NodeCryptoFunctionService(); + this.storageService = new LowdbStorageService(null, p, true); + this.secureStorageService = new KeytarSecureStorageService(applicationName); + this.cryptoService = new CryptoService(this.storageService, this.secureStorageService, + this.cryptoFunctionService); + this.appIdService = new AppIdService(this.storageService); + this.tokenService = new TokenService(this.storageService); + this.messagingService = new NoopMessagingService(); + this.apiService = new NodeApiService(this.tokenService, this.platformUtilsService, + async (expired: boolean) => await this.logout()); + this.environmentService = new EnvironmentService(this.apiService, this.storageService, null); + this.userService = new UserService(this.tokenService, this.storageService); + this.containerService = new ContainerService(this.cryptoService); + this.authService = new AuthService(this.cryptoService, this.apiService, this.userService, this.tokenService, + this.appIdService, this.i18nService, this.platformUtilsService, this.messagingService, true); + this.configurationService = new ConfigurationService(this.storageService, this.secureStorageService); + this.syncService = new SyncService(this.configurationService, this.logService, this.cryptoFunctionService, + this.apiService, this.messagingService, this.i18nService); + this.program = new Program(this); + } + + async run() { + await this.init(); + this.program.run(); + } + + async logout() { + await Promise.all([ + this.tokenService.clearToken(), + this.userService.clear(), + ]); + } + + private async init() { + this.storageService.init(); + this.containerService.attachToWindow(global); + await this.environmentService.setUrlsFromStorage(); + // Dev Server URLs. Comment out the line above. + // this.apiService.setUrls({ + // base: null, + // api: 'http://localhost:4000', + // identity: 'http://localhost:33656', + // }); + const locale = await this.storageService.get(ConstantsService.localeKey); + await this.i18nService.init(locale); + this.authService.init(); + + const installedVersion = await this.storageService.get(ConstantsService.installedVersionKey); + const currentVersion = this.platformUtilsService.getApplicationVersion(); + if (installedVersion == null || installedVersion !== currentVersion) { + await this.storageService.save(ConstantsService.installedVersionKey, currentVersion); + } + } +} + +const main = new Main(); +main.run(); diff --git a/src/commands/config.command.ts b/src/commands/config.command.ts new file mode 100644 index 00000000..28ca5916 --- /dev/null +++ b/src/commands/config.command.ts @@ -0,0 +1,31 @@ +import * as program from 'commander'; + +import { EnvironmentService } from 'jslib/abstractions/environment.service'; + +import { Response } from 'jslib/cli/models/response'; +import { MessageResponse } from 'jslib/cli/models/response/messageResponse'; + +export class ConfigCommand { + constructor(private environmentService: EnvironmentService) { } + + async run(setting: string, value: string, cmd: program.Command): Promise { + setting = setting.toLowerCase(); + switch (setting) { + case 'server': + await this.setServer(value); + break; + default: + return Response.badRequest('Unknown setting.'); + } + + const res = new MessageResponse('Saved setting `' + setting + '`.', null); + return Response.success(res); + } + + private async setServer(url: string) { + url = (url === 'null' || url === 'bitwarden.com' || url === 'https://bitwarden.com' ? null : url); + await this.environmentService.setUrls({ + base: url, + }); + } +} diff --git a/src/program.ts b/src/program.ts new file mode 100644 index 00000000..4e90c995 --- /dev/null +++ b/src/program.ts @@ -0,0 +1,212 @@ +import * as chk from 'chalk'; +import * as program from 'commander'; + +import { Main } from './bwdc'; + +import { ConfigCommand } from './commands/config.command'; + +import { UpdateCommand } from 'jslib/cli/commands/update.command'; + +import { Response } from 'jslib/cli/models/response'; +import { ListResponse } from 'jslib/cli/models/response/listResponse'; +import { MessageResponse } from 'jslib/cli/models/response/messageResponse'; +import { StringResponse } from 'jslib/cli/models/response/stringResponse'; + +const chalk = chk.default; +const writeLn = (s: string, finalLine: boolean = false) => { + if (finalLine && process.platform === 'win32') { + process.stdout.write(s); + } else { + process.stdout.write(s + '\n'); + } +}; + +export class Program { + constructor(private main: Main) { } + + run() { + program + .option('--pretty', 'Format output. JSON is tabbed with two spaces.') + .option('--raw', 'Return raw output instead of a descriptive message.') + .option('--response', 'Return a JSON formatted version of response output.') + .option('--quiet', 'Don\'t return anything to stdout.') + .version(this.main.platformUtilsService.getApplicationVersion(), '-v, --version'); + + program.on('option:pretty', () => { + process.env.BW_PRETTY = 'true'; + }); + + program.on('option:raw', () => { + process.env.BW_RAW = 'true'; + }); + + program.on('option:quiet', () => { + process.env.BW_QUIET = 'true'; + }); + + program.on('option:response', () => { + process.env.BW_RESPONSE = 'true'; + }); + + program.on('command:*', () => { + writeLn(chalk.redBright('Invalid command: ' + program.args.join(' '))); + writeLn('See --help for a list of available commands.', true); + process.exitCode = 1; + }); + + program.on('--help', () => { + writeLn('\n Examples:'); + writeLn(''); + writeLn(' bwdc login'); + writeLn('', true); + }); + + program + .command('config ') + .description('Configure CLI settings.') + .on('--help', () => { + writeLn('\n Settings:'); + writeLn(''); + writeLn(' server - On-premise hosted installation URL.'); + writeLn(''); + writeLn(' Examples:'); + writeLn(''); + writeLn(' bwdc config server https://bw.company.com'); + writeLn(' bwdc config server bitwarden.com'); + writeLn('', true); + }) + .action(async (setting, value, cmd) => { + const command = new ConfigCommand(this.main.environmentService); + const response = await command.run(setting, value, cmd); + this.processResponse(response); + }); + + program + .command('update') + .description('Check for updates.') + .on('--help', () => { + writeLn('\n Notes:'); + writeLn(''); + writeLn(' Returns the URL to download the newest version of this CLI tool.'); + writeLn(''); + writeLn(' Use the `--raw` option to return only the download URL for the update.'); + writeLn(''); + writeLn(' Examples:'); + writeLn(''); + writeLn(' bwdc update'); + writeLn(' bwdc update --raw'); + writeLn('', true); + }) + .action(async (cmd) => { + const command = new UpdateCommand(this.main.platformUtilsService, 'directory-connector', 'bwdc'); + const response = await command.run(cmd); + this.processResponse(response); + }); + + program + .parse(process.argv); + + if (process.argv.slice(2).length === 0) { + program.outputHelp(); + } + } + + private processResponse(response: Response, exitImmediately = false) { + if (!response.success) { + if (process.env.BW_QUIET !== 'true') { + if (process.env.BW_RESPONSE === 'true') { + writeLn(this.getJson(response), true); + } else { + writeLn(chalk.redBright(response.message), true); + } + } + if (exitImmediately) { + process.exit(1); + } else { + process.exitCode = 1; + } + return; + } + + if (process.env.BW_RESPONSE === 'true') { + writeLn(this.getJson(response), true); + } else if (response.data != null) { + let out: string = null; + if (response.data.object === 'string') { + const data = (response.data as StringResponse).data; + if (data != null) { + out = data; + } + } else if (response.data.object === 'list') { + out = this.getJson((response.data as ListResponse).data); + } else if (response.data.object === 'message') { + out = this.getMessage(response); + } else { + out = this.getJson(response.data); + } + + if (out != null && process.env.BW_QUIET !== 'true') { + writeLn(out, true); + } + } + if (exitImmediately) { + process.exit(0); + } else { + process.exitCode = 0; + } + } + + private getJson(obj: any): string { + if (process.env.BW_PRETTY === 'true') { + return JSON.stringify(obj, null, ' '); + } else { + return JSON.stringify(obj); + } + } + + private getMessage(response: Response) { + const message = (response.data as MessageResponse); + if (process.env.BW_RAW === 'true' && message.raw != null) { + return message.raw; + } + + let out: string = ''; + if (message.title != null) { + if (message.noColor) { + out = message.title; + } else { + out = chalk.greenBright(message.title); + } + } + if (message.message != null) { + if (message.title != null) { + out += '\n'; + } + out += message.message; + } + return out.trim() === '' ? null : out; + } + + private async exitIfLocked() { + await this.exitIfNotAuthed(); + const hasKey = await this.main.cryptoService.hasKey(); + if (!hasKey) { + this.processResponse(Response.error('Vault is locked.'), true); + } + } + + private async exitIfAuthed() { + const authed = await this.main.userService.isAuthenticated(); + if (authed) { + const email = await this.main.userService.getEmail(); + this.processResponse(Response.error('You are already logged in as ' + email + '.'), true); + } + } + + private async exitIfNotAuthed() { + const authed = await this.main.userService.isAuthenticated(); + if (!authed) { + this.processResponse(Response.error('You are not logged in.'), true); + } + } +} diff --git a/src/services/keytarSecureStorage.service.ts b/src/services/keytarSecureStorage.service.ts new file mode 100644 index 00000000..0a253c09 --- /dev/null +++ b/src/services/keytarSecureStorage.service.ts @@ -0,0 +1,25 @@ +import { + deletePassword, + getPassword, + setPassword, +} from 'keytar'; + +import { StorageService } from 'jslib/abstractions/storage.service'; + +export class KeytarSecureStorageService implements StorageService { + constructor(private serviceName: string) { } + + get(key: string): Promise { + return getPassword(this.serviceName, key).then((val: any) => { + return val as T; + }); + } + + save(key: string, obj: any): Promise { + return setPassword(this.serviceName, key, obj); + } + + remove(key: string): Promise { + return deletePassword(this.serviceName, key); + } +} diff --git a/tsconfig.json b/tsconfig.json index 43ac4915..b57bbc68 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -57,6 +57,7 @@ "dist", "jslib/dist", "build", + "build-cli", "jslib/spec" ] } diff --git a/webpack.cli.js b/webpack.cli.js new file mode 100644 index 00000000..d76c3108 --- /dev/null +++ b/webpack.cli.js @@ -0,0 +1,80 @@ +const path = require('path'); +const webpack = require('webpack'); +const CleanWebpackPlugin = require('clean-webpack-plugin'); +const CopyWebpackPlugin = require('copy-webpack-plugin'); +const nodeExternals = require('webpack-node-externals'); + +if (process.env.NODE_ENV == null) { + process.env.NODE_ENV = 'development'; +} +const ENV = process.env.ENV = process.env.NODE_ENV; + +const moduleRules = [ + { + test: /\.ts$/, + enforce: 'pre', + loader: 'tslint-loader', + }, + { + test: /\.ts$/, + loaders: ['ts-loader'], + exclude: path.resolve(__dirname, 'node_modules'), + }, + { + test: /\.node$/, + loader: 'node-loader', + }, +]; + +const plugins = [ + new CleanWebpackPlugin([ + path.resolve(__dirname, 'build-cli/*'), + ]), + new CopyWebpackPlugin([ + { from: './src/locales', to: 'locales' }, + ]), + new webpack.DefinePlugin({ + 'process.env.BWCLI_ENV': JSON.stringify(ENV), + }), + new webpack.BannerPlugin({ + banner: '#!/usr/bin/env node', + raw: true + }), + new webpack.IgnorePlugin(/^encoding$/, /node-fetch/), +]; + +const config = { + mode: ENV, + target: 'node', + devtool: ENV === 'development' ? 'eval-source-map' : 'source-map', + node: { + __dirname: false, + __filename: false, + }, + entry: { + 'bwdc': './src/bwdc.ts', + }, + optimization: { + minimize: false, + }, + resolve: { + extensions: ['.ts', '.js', '.json'], + alias: { + jslib: path.join(__dirname, 'jslib/src'), + tldjs: path.join(__dirname, 'jslib/src/misc/tldjs.noop'), + // ref: https://github.com/bitinn/node-fetch/issues/493 + 'node-fetch$': 'node-fetch/lib/index.js', + }, + symlinks: false, + modules: [path.resolve('node_modules')], + }, + output: { + filename: '[name].js', + path: path.resolve(__dirname, 'build-cli'), + }, + module: { rules: moduleRules }, + plugins: plugins, + externals: [nodeExternals()], +}; + +module.exports = config;