@zerothreatai/cli 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.prod +2 -0
- package/LICENSE +28 -0
- package/README.md +3 -0
- package/dist/index.js +28 -0
- package/dist/src/actions/license-service.js +128 -0
- package/dist/src/commands/activate.js +56 -0
- package/dist/src/commands/deactivate.js +7 -0
- package/dist/src/commands/start-setup.js +61 -0
- package/dist/src/config/api-config.js +10 -0
- package/dist/src/constants/app-constants.js +13 -0
- package/dist/src/menu.js +106 -0
- package/dist/src/services/acr-token-service.js +65 -0
- package/dist/src/services/api-service.js +50 -0
- package/dist/src/services/license-api-service.js +72 -0
- package/dist/src/tools/crypto-service.js +79 -0
- package/dist/src/utils/acr-error.js +9 -0
- package/dist/src/utils/ask-que.js +24 -0
- package/dist/src/utils/get-mac.js +8 -0
- package/dist/src/utils/license-table.js +54 -0
- package/dist/src/utils/open-browser.js +29 -0
- package/package.json +49 -0
package/.env.prod
ADDED
package/LICENSE
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
BSD 3-Clause License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025, zerothreatai
|
|
4
|
+
|
|
5
|
+
Redistribution and use in source and binary forms, with or without
|
|
6
|
+
modification, are permitted provided that the following conditions are met:
|
|
7
|
+
|
|
8
|
+
1. Redistributions of source code must retain the above copyright notice, this
|
|
9
|
+
list of conditions and the following disclaimer.
|
|
10
|
+
|
|
11
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
12
|
+
this list of conditions and the following disclaimer in the documentation
|
|
13
|
+
and/or other materials provided with the distribution.
|
|
14
|
+
|
|
15
|
+
3. Neither the name of the copyright holder nor the names of its
|
|
16
|
+
contributors may be used to endorse or promote products derived from
|
|
17
|
+
this software without specific prior written permission.
|
|
18
|
+
|
|
19
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
20
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
21
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
22
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
23
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
24
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
25
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
26
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
27
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
28
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
package/README.md
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
+
};
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
const commander_1 = require("commander");
|
|
8
|
+
const menu_js_1 = __importDefault(require("./src/menu.js"));
|
|
9
|
+
const start_setup_js_1 = require("./src/commands/start-setup.js");
|
|
10
|
+
const dotenv_1 = require("dotenv");
|
|
11
|
+
(0, dotenv_1.config)({
|
|
12
|
+
path: !process.env.WORKING_ENVIRONMENT ? `.env.prod` : `.env`
|
|
13
|
+
});
|
|
14
|
+
commander_1.program
|
|
15
|
+
.name("zt")
|
|
16
|
+
.description("ZEROTHREAT AI CLI")
|
|
17
|
+
.version("1.0.0");
|
|
18
|
+
commander_1.program
|
|
19
|
+
.command("menu")
|
|
20
|
+
.description("Show main menu")
|
|
21
|
+
.action(menu_js_1.default);
|
|
22
|
+
commander_1.program.command("start-setup").action(start_setup_js_1.startSetup);
|
|
23
|
+
if (!process.argv.slice(2).length) {
|
|
24
|
+
(0, menu_js_1.default)();
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
commander_1.program.parse(process.argv);
|
|
28
|
+
}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.firstIgnition = firstIgnition;
|
|
7
|
+
exports.licenseDeactivate = licenseDeactivate;
|
|
8
|
+
const get_mac_1 = require("../utils/get-mac");
|
|
9
|
+
const path_1 = __importDefault(require("path"));
|
|
10
|
+
const child_process_1 = require("child_process");
|
|
11
|
+
const fs_1 = __importDefault(require("fs"));
|
|
12
|
+
const js_yaml_1 = __importDefault(require("js-yaml"));
|
|
13
|
+
const dockerode_1 = __importDefault(require("dockerode"));
|
|
14
|
+
const license_api_service_1 = __importDefault(require("../services/license-api-service"));
|
|
15
|
+
const acr_token_service_1 = __importDefault(require("../services/acr-token-service"));
|
|
16
|
+
const ask_que_1 = require("../utils/ask-que");
|
|
17
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
18
|
+
const cli_table3_1 = __importDefault(require("cli-table3"));
|
|
19
|
+
const app_constants_1 = require("../constants/app-constants");
|
|
20
|
+
let COMPOSE_FILE = "";
|
|
21
|
+
const PROJECT = "zerothreat";
|
|
22
|
+
const NETWORK = "zerothreat-onprem-nw";
|
|
23
|
+
let auth = {
|
|
24
|
+
username: "",
|
|
25
|
+
password: "",
|
|
26
|
+
serveraddress: "",
|
|
27
|
+
};
|
|
28
|
+
const docker = new dockerode_1.default();
|
|
29
|
+
async function ensureNetwork() {
|
|
30
|
+
const existing = await docker.listNetworks({ filters: { name: [NETWORK] } });
|
|
31
|
+
if (existing.length === 0) {
|
|
32
|
+
await docker.createNetwork({ Name: NETWORK, CheckDuplicate: true });
|
|
33
|
+
console.log(`Network created: ${NETWORK}`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
async function pullImages() {
|
|
37
|
+
const doc = js_yaml_1.default.load(fs_1.default.readFileSync(COMPOSE_FILE, "utf8"));
|
|
38
|
+
const images = Object.values(doc.services || {}).map(s => s.image);
|
|
39
|
+
console.log(`Pulling ${images.length} images in parallel...`);
|
|
40
|
+
await Promise.all(images.map(image => new Promise((resolve, reject) => {
|
|
41
|
+
docker.pull(image, { authconfig: auth }, (err, stream) => {
|
|
42
|
+
if (err)
|
|
43
|
+
return reject(err);
|
|
44
|
+
if (!stream)
|
|
45
|
+
return reject(new Error("No stream received"));
|
|
46
|
+
docker.modem.followProgress(stream, err => (err ? reject(err) : resolve()), () => process.stdout.write("."));
|
|
47
|
+
});
|
|
48
|
+
}).then(() => console.log(`\nDone: ${image}`))));
|
|
49
|
+
console.log("All images pulled!");
|
|
50
|
+
}
|
|
51
|
+
async function runCompose(args) {
|
|
52
|
+
return new Promise((resolve, reject) => {
|
|
53
|
+
const child = (0, child_process_1.spawn)("docker", ["compose", "-f", COMPOSE_FILE, "-p", PROJECT, ...args], {
|
|
54
|
+
stdio: "inherit",
|
|
55
|
+
});
|
|
56
|
+
child.on("close", code => (code === 0 ? resolve() : reject(new Error("compose failed"))));
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
async function firstIgnition(licenseKey, emailId) {
|
|
60
|
+
console.log(">> Running first docker setup ...");
|
|
61
|
+
let token = '';
|
|
62
|
+
const acrTokenService = new acr_token_service_1.default();
|
|
63
|
+
const machineId = (0, get_mac_1.getMachineId)();
|
|
64
|
+
try {
|
|
65
|
+
const { dockerAuth, activationToken } = await acrTokenService.getAcrToken(licenseKey, emailId, machineId);
|
|
66
|
+
auth = dockerAuth;
|
|
67
|
+
token = activationToken;
|
|
68
|
+
if (app_constants_1.dockerComposeAcr) {
|
|
69
|
+
COMPOSE_FILE = app_constants_1.dockerComposeAcr;
|
|
70
|
+
}
|
|
71
|
+
await ensureNetwork();
|
|
72
|
+
await pullImages();
|
|
73
|
+
await runCompose(["up", "-d"]);
|
|
74
|
+
//sleep for 30 seconds to allow sql server to start
|
|
75
|
+
console.log("Waiting for SQL Server to start...");
|
|
76
|
+
await new Promise(resolve => setTimeout(resolve, 30000));
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
throw error;
|
|
80
|
+
}
|
|
81
|
+
finally {
|
|
82
|
+
if (app_constants_1.dockerComposeAcr) {
|
|
83
|
+
const tempDir = path_1.default.dirname(app_constants_1.dockerComposeAcr);
|
|
84
|
+
fs_1.default.rmSync(tempDir, { recursive: true, force: true });
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return token;
|
|
88
|
+
}
|
|
89
|
+
async function licenseDeactivate() {
|
|
90
|
+
console.log(chalk_1.default.dim("License deactivation initiated.. \n"));
|
|
91
|
+
try {
|
|
92
|
+
const deactivationToken = await (0, ask_que_1.ask)(chalk_1.default.yellow.bold("🗝️ Enter Deactivation Token: "));
|
|
93
|
+
const machineId = (0, get_mac_1.getMachineId)();
|
|
94
|
+
const licenseApi = new license_api_service_1.default();
|
|
95
|
+
const table = new cli_table3_1.default({
|
|
96
|
+
chars: {
|
|
97
|
+
"top": "═",
|
|
98
|
+
"top-left": "╔",
|
|
99
|
+
"top-right": "╗",
|
|
100
|
+
"bottom": "═",
|
|
101
|
+
"bottom-left": "╚",
|
|
102
|
+
"bottom-right": "╝",
|
|
103
|
+
"left": "║",
|
|
104
|
+
"right": "║",
|
|
105
|
+
},
|
|
106
|
+
});
|
|
107
|
+
try {
|
|
108
|
+
const res = await licenseApi.deactivateLicense(machineId, deactivationToken);
|
|
109
|
+
if (res.status) {
|
|
110
|
+
table.options.style.border = ['green'];
|
|
111
|
+
table.push([chalk_1.default.bold.green(res.message)]);
|
|
112
|
+
console.log(table.toString());
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
table.push([chalk_1.default.bold.green(res.message)]);
|
|
116
|
+
console.log(table.toString());
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
catch (error) {
|
|
120
|
+
table.options.style.border = ['red'];
|
|
121
|
+
table.push([chalk_1.default.bold.red(`DeactivateLicense error:${error.message}`)]);
|
|
122
|
+
console.log(table.toString());
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
catch (err) {
|
|
126
|
+
console.log(chalk_1.default.redBright(`DeactivateLicense error: ${err.message}`));
|
|
127
|
+
}
|
|
128
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const license_api_service_1 = __importDefault(require("../services/license-api-service"));
|
|
7
|
+
const license_table_1 = require("../utils/license-table");
|
|
8
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
9
|
+
const cli_table3_1 = __importDefault(require("cli-table3"));
|
|
10
|
+
exports.default = async (token) => {
|
|
11
|
+
console.log(chalk_1.default.blue("\n🚀 Opening Activation Page...\n"));
|
|
12
|
+
const licenseService = new license_api_service_1.default();
|
|
13
|
+
const response = await licenseService.activateLicense(token);
|
|
14
|
+
if (response.status) {
|
|
15
|
+
// Celebration header
|
|
16
|
+
const table = new cli_table3_1.default({
|
|
17
|
+
style: {
|
|
18
|
+
border: ["blue"],
|
|
19
|
+
head: [],
|
|
20
|
+
compact: false,
|
|
21
|
+
},
|
|
22
|
+
chars: {
|
|
23
|
+
"top": chalk_1.default.green("═"),
|
|
24
|
+
"top-left": chalk_1.default.green("╔"),
|
|
25
|
+
"top-right": chalk_1.default.green("╗"),
|
|
26
|
+
"bottom": chalk_1.default.green("═"),
|
|
27
|
+
"bottom-left": chalk_1.default.green("╚"),
|
|
28
|
+
"bottom-right": chalk_1.default.green("╝"),
|
|
29
|
+
"left": chalk_1.default.green("║"),
|
|
30
|
+
"right": chalk_1.default.green("║"),
|
|
31
|
+
},
|
|
32
|
+
});
|
|
33
|
+
table.push([chalk_1.default.bold.green(' 🎉 CONGRATULATIONS! LICENSE ACTIVATED! 🎉')]);
|
|
34
|
+
console.log(table.toString());
|
|
35
|
+
console.log(chalk_1.default.green.bold('\n✨ Welcome to ZeroThreatAI Web Vulnerability Scan Platform! ✨'));
|
|
36
|
+
console.log(chalk_1.default.gray('Your license has been successfully activated and is ready to use.\n'));
|
|
37
|
+
(0, license_table_1.displayLicenseTable)(response);
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
console.log(chalk_1.default.red.bold('\n🚫 License Activation Failed\n'));
|
|
41
|
+
console.log(chalk_1.default.gray('We were unable to connect to the ZeroThreatAI servers to complete the'));
|
|
42
|
+
console.log(chalk_1.default.gray('license activation. Please check the possible causes and try again.\n'));
|
|
43
|
+
console.log(chalk_1.default.bold('Reasons'));
|
|
44
|
+
console.log(chalk_1.default.red('📄 Reason'));
|
|
45
|
+
console.log(chalk_1.default.gray(` ${response.message}\n`));
|
|
46
|
+
console.log(chalk_1.default.bold('Possible Causes'));
|
|
47
|
+
console.log(chalk_1.default.magenta('📶 Internet Connection'));
|
|
48
|
+
console.log(chalk_1.default.gray(' Your device may have lost its connection to the internet.\n'));
|
|
49
|
+
console.log(chalk_1.default.magenta('💥 System Crash'));
|
|
50
|
+
console.log(chalk_1.default.gray(' Your computer may have shut down unexpectedly during the process.\n'));
|
|
51
|
+
console.log(chalk_1.default.magenta('🛡️ Firewall or Proxy'));
|
|
52
|
+
console.log(chalk_1.default.gray(' Network security settings may be blocking the connection.\n'));
|
|
53
|
+
console.log(chalk_1.default.bold('Next Steps'));
|
|
54
|
+
console.log(chalk_1.default.gray('You can retry the activation process or contact our support team for assistance.\n'));
|
|
55
|
+
}
|
|
56
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const license_service_1 = require("../actions/license-service");
|
|
4
|
+
exports.default = async () => {
|
|
5
|
+
console.log("\nLicense Deactivation\n");
|
|
6
|
+
await (0, license_service_1.licenseDeactivate)();
|
|
7
|
+
};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.startSetup = startSetup;
|
|
7
|
+
const license_service_1 = require("../actions/license-service");
|
|
8
|
+
const ask_que_1 = require("../utils/ask-que");
|
|
9
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
10
|
+
const activate_1 = __importDefault(require("./activate"));
|
|
11
|
+
const acr_error_1 = __importDefault(require("../utils/acr-error"));
|
|
12
|
+
const validateEmail = (email) => {
|
|
13
|
+
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
14
|
+
return emailRegex.test(email);
|
|
15
|
+
};
|
|
16
|
+
const validateLicenseKey = (key) => {
|
|
17
|
+
const licenseRegex = /^[A-Za-z0-9]{4}-[A-Za-z0-9]{4}-[A-Za-z0-9]{4}-[A-Za-z0-9]{4}$/;
|
|
18
|
+
return licenseRegex.test(key);
|
|
19
|
+
};
|
|
20
|
+
async function startSetup() {
|
|
21
|
+
console.log("\nActivating License...\n");
|
|
22
|
+
let email;
|
|
23
|
+
do {
|
|
24
|
+
email = await (0, ask_que_1.ask)(chalk_1.default.yellow.bold("📧 Enter Email: "));
|
|
25
|
+
if (!validateEmail(email)) {
|
|
26
|
+
console.log("Invalid email format. Please try again.");
|
|
27
|
+
}
|
|
28
|
+
} while (!validateEmail(email));
|
|
29
|
+
let licenseKey;
|
|
30
|
+
do {
|
|
31
|
+
licenseKey = await (0, ask_que_1.ask)(chalk_1.default.yellow.bold("🗝️ Enter License Key (XXXX-XXXX-XXXX-XXXX): "));
|
|
32
|
+
if (!validateLicenseKey(licenseKey)) {
|
|
33
|
+
console.log("Invalid license key format. Must be XXXX-XXXX-XXXX-XXXX where X is a number.");
|
|
34
|
+
}
|
|
35
|
+
} while (!validateLicenseKey(licenseKey));
|
|
36
|
+
// Docker Setup
|
|
37
|
+
let token = '';
|
|
38
|
+
try {
|
|
39
|
+
token = await (0, license_service_1.firstIgnition)(licenseKey, email);
|
|
40
|
+
}
|
|
41
|
+
catch (err) {
|
|
42
|
+
if (err instanceof acr_error_1.default) {
|
|
43
|
+
console.log(chalk_1.default.red(`Error : ${err.message}`));
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
console.error(chalk_1.default.redBright(`Error : ${err.message}`));
|
|
47
|
+
console.error(chalk_1.default.yellowBright(`Please Retry.`));
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
// License Activation call
|
|
51
|
+
try {
|
|
52
|
+
console.log("Setting up your license ...");
|
|
53
|
+
await (0, activate_1.default)(token);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
catch (err) {
|
|
57
|
+
console.error(chalk_1.default.redBright(err));
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.API_CONFIG = void 0;
|
|
4
|
+
const API_CONFIG = () => {
|
|
5
|
+
return {
|
|
6
|
+
licenseApi: process.env.LICENSE_API,
|
|
7
|
+
onPremLicenseCloudeApi: process.env.CLOUD_API,
|
|
8
|
+
};
|
|
9
|
+
};
|
|
10
|
+
exports.API_CONFIG = API_CONFIG;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.setDockerComposeAcr = exports.setLicenseClaimed = exports.dockerComposeAcr = exports.isLicenseClaimed = void 0;
|
|
4
|
+
exports.isLicenseClaimed = false;
|
|
5
|
+
exports.dockerComposeAcr = '';
|
|
6
|
+
const setLicenseClaimed = (value) => {
|
|
7
|
+
exports.isLicenseClaimed = value;
|
|
8
|
+
};
|
|
9
|
+
exports.setLicenseClaimed = setLicenseClaimed;
|
|
10
|
+
const setDockerComposeAcr = (value) => {
|
|
11
|
+
exports.dockerComposeAcr = value;
|
|
12
|
+
};
|
|
13
|
+
exports.setDockerComposeAcr = setDockerComposeAcr;
|
package/dist/src/menu.js
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.default = showMenu;
|
|
7
|
+
const inquirer_1 = __importDefault(require("inquirer"));
|
|
8
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
9
|
+
const start_setup_1 = require("./commands/start-setup");
|
|
10
|
+
const deactivate_1 = __importDefault(require("./commands/deactivate"));
|
|
11
|
+
async function showMenu() {
|
|
12
|
+
console.clear();
|
|
13
|
+
// Header with description
|
|
14
|
+
console.log(chalk_1.default.gray('╔' + '═'.repeat(78) + '╗'));
|
|
15
|
+
console.log(chalk_1.default.gray('║') + chalk_1.default.bold.magenta(' ZEROTHREAT ON-PREM INSTALLER ') + chalk_1.default.gray('║'));
|
|
16
|
+
console.log(chalk_1.default.gray('╠' + '═'.repeat(78) + '╣'));
|
|
17
|
+
console.log(chalk_1.default.gray('║') + ' '.repeat(78) + chalk_1.default.gray('║'));
|
|
18
|
+
console.log(chalk_1.default.gray('║') + chalk_1.default.bold.white(' AppSec without Noise or Complexity ') + chalk_1.default.gray('║'));
|
|
19
|
+
console.log(chalk_1.default.gray('║') + chalk_1.default.white(' Continuous Pentesting for Web Apps & APIs at Dev Speed ') + chalk_1.default.gray('║'));
|
|
20
|
+
console.log(chalk_1.default.gray('║') + ' '.repeat(78) + chalk_1.default.gray('║'));
|
|
21
|
+
console.log(chalk_1.default.gray('║') + chalk_1.default.gray(' Ship 10× faster with audit-ready compliance. ZeroThreat protects ') + chalk_1.default.gray('║'));
|
|
22
|
+
console.log(chalk_1.default.gray('║') + chalk_1.default.gray(' modern web apps & APIs through continuous pentesting, actionable ') + chalk_1.default.gray('║'));
|
|
23
|
+
console.log(chalk_1.default.gray('║') + chalk_1.default.gray(' insights, and coverage for 40,000+ vulnerabilities. ') + chalk_1.default.gray('║'));
|
|
24
|
+
console.log(chalk_1.default.gray('║') + ' '.repeat(78) + chalk_1.default.gray('║'));
|
|
25
|
+
console.log(chalk_1.default.gray('║') + chalk_1.default.bold.green(' 🛡️ On-Premise Installation Tool CLI ') + chalk_1.default.gray('║'));
|
|
26
|
+
console.log(chalk_1.default.gray('║') + ' '.repeat(78) + chalk_1.default.gray('║'));
|
|
27
|
+
console.log(chalk_1.default.gray('╚' + '═'.repeat(78) + '╝'));
|
|
28
|
+
console.log();
|
|
29
|
+
// Menu options box
|
|
30
|
+
console.log(chalk_1.default.gray('╔═ ' + chalk_1.default.bold.white('MAIN MENU') + ' ═' + '═'.repeat(65) + '╗'));
|
|
31
|
+
console.log(chalk_1.default.gray('║ ') + ' '.repeat(76) + chalk_1.default.gray('║'));
|
|
32
|
+
const { action } = await inquirer_1.default.prompt([
|
|
33
|
+
{
|
|
34
|
+
type: "list",
|
|
35
|
+
name: "action",
|
|
36
|
+
message: chalk_1.default.bold.cyan("Select an action:"),
|
|
37
|
+
choices: [
|
|
38
|
+
{
|
|
39
|
+
name: chalk_1.default.green("🔑 Activate License & Setup"),
|
|
40
|
+
value: "Start Setup"
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
name: chalk_1.default.redBright("⛔ Deassociate License & System"),
|
|
44
|
+
value: "Deactivate License"
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
name: chalk_1.default.yellow("🔄 Update License") + chalk_1.default.gray(" (Coming Soon)"),
|
|
48
|
+
value: "Update License (Coming Soon)",
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
name: chalk_1.default.white("❌ Exit"),
|
|
52
|
+
value: "Exit"
|
|
53
|
+
},
|
|
54
|
+
],
|
|
55
|
+
loop: false,
|
|
56
|
+
prefix: "║",
|
|
57
|
+
},
|
|
58
|
+
]);
|
|
59
|
+
console.log(chalk_1.default.gray('║') + ' '.repeat(78) + chalk_1.default.gray('║'));
|
|
60
|
+
console.log(chalk_1.default.gray('╚' + '═'.repeat(78) + '╝'));
|
|
61
|
+
switch (action) {
|
|
62
|
+
case "Start Setup":
|
|
63
|
+
await (0, start_setup_1.startSetup)();
|
|
64
|
+
break;
|
|
65
|
+
case "Deactivate License":
|
|
66
|
+
await (0, deactivate_1.default)();
|
|
67
|
+
break;
|
|
68
|
+
default:
|
|
69
|
+
console.log("Exiting...");
|
|
70
|
+
console.clear();
|
|
71
|
+
process.exit(0);
|
|
72
|
+
}
|
|
73
|
+
// Status separator
|
|
74
|
+
console.log();
|
|
75
|
+
console.log((0, chalk_1.default)('-'.repeat(80)));
|
|
76
|
+
console.log();
|
|
77
|
+
// Navigation box
|
|
78
|
+
console.log(chalk_1.default.gray('╔═ ' + chalk_1.default.bold.white('NEXT') + ' ═' + '═'.repeat(60) + '╗'));
|
|
79
|
+
console.log(chalk_1.default.gray('║ ') + ' '.repeat(66) + chalk_1.default.gray('║'));
|
|
80
|
+
const { close } = await inquirer_1.default.prompt([
|
|
81
|
+
{
|
|
82
|
+
type: "list",
|
|
83
|
+
name: "close",
|
|
84
|
+
message: " ",
|
|
85
|
+
choices: [
|
|
86
|
+
{ name: chalk_1.default.white("🏠 Main Menu"), value: "menu" },
|
|
87
|
+
{ name: chalk_1.default.red("🚪 Exit Application"), value: "Exit" }
|
|
88
|
+
],
|
|
89
|
+
theme: {
|
|
90
|
+
style: {
|
|
91
|
+
highlight: chalk_1.default.bgBlue.white
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
]);
|
|
96
|
+
console.log(chalk_1.default.green('└' + '─'.repeat(74) + '┘'));
|
|
97
|
+
switch (close) {
|
|
98
|
+
case "menu":
|
|
99
|
+
await showMenu();
|
|
100
|
+
break;
|
|
101
|
+
default:
|
|
102
|
+
console.log("Exiting...");
|
|
103
|
+
console.clear();
|
|
104
|
+
process.exit(0);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const axios_1 = __importDefault(require("axios"));
|
|
7
|
+
const https_1 = __importDefault(require("https"));
|
|
8
|
+
const fs_1 = __importDefault(require("fs"));
|
|
9
|
+
const path_1 = __importDefault(require("path"));
|
|
10
|
+
const os_1 = __importDefault(require("os"));
|
|
11
|
+
const crypto_1 = __importDefault(require("crypto"));
|
|
12
|
+
const acr_error_1 = __importDefault(require("../utils/acr-error"));
|
|
13
|
+
const app_constants_1 = require("../constants/app-constants");
|
|
14
|
+
const api_config_1 = require("../config/api-config");
|
|
15
|
+
const api_service_1 = __importDefault(require("./api-service"));
|
|
16
|
+
class AcrTokenService extends api_service_1.default {
|
|
17
|
+
constructor() {
|
|
18
|
+
super({
|
|
19
|
+
baseURL: (0, api_config_1.API_CONFIG)().onPremLicenseCloudeApi,
|
|
20
|
+
timeout: 15000,
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
async getAcrToken(licenseKey, emailId, systemId) {
|
|
24
|
+
try {
|
|
25
|
+
const httpsAgent = new https_1.default.Agent({
|
|
26
|
+
keepAlive: true,
|
|
27
|
+
family: 4,
|
|
28
|
+
rejectUnauthorized: false,
|
|
29
|
+
});
|
|
30
|
+
const api = axios_1.default.create({
|
|
31
|
+
httpsAgent,
|
|
32
|
+
timeout: 15000,
|
|
33
|
+
headers: { "Content-Type": "application/json" },
|
|
34
|
+
});
|
|
35
|
+
const response = await this.post('/acr-token', {
|
|
36
|
+
licenseKey,
|
|
37
|
+
emailId,
|
|
38
|
+
systemId
|
|
39
|
+
});
|
|
40
|
+
const { registry, username, password } = response.tokenInfo;
|
|
41
|
+
if (response.dockerComposeAcr) {
|
|
42
|
+
const decodedDockerComposeAcr = Buffer.from(response.dockerComposeAcr, 'base64').toString('utf-8');
|
|
43
|
+
const randomDir = crypto_1.default.randomBytes(8).toString('hex');
|
|
44
|
+
const randomFileName = crypto_1.default.randomBytes(8).toString('hex') + '.yml';
|
|
45
|
+
const tempDir = path_1.default.join(os_1.default.tmpdir(), randomDir);
|
|
46
|
+
fs_1.default.mkdirSync(tempDir, { recursive: true });
|
|
47
|
+
const filePath = path_1.default.join(tempDir, randomFileName);
|
|
48
|
+
fs_1.default.writeFileSync(filePath, decodedDockerComposeAcr);
|
|
49
|
+
(0, app_constants_1.setDockerComposeAcr)(filePath);
|
|
50
|
+
}
|
|
51
|
+
return {
|
|
52
|
+
dockerAuth: {
|
|
53
|
+
username,
|
|
54
|
+
password,
|
|
55
|
+
serveraddress: registry,
|
|
56
|
+
},
|
|
57
|
+
activationToken: response.activationToken
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
throw new acr_error_1.default(`${error.message}`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
exports.default = AcrTokenService;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const axios_1 = __importDefault(require("axios"));
|
|
7
|
+
const https_1 = __importDefault(require("https"));
|
|
8
|
+
class ApiService {
|
|
9
|
+
client;
|
|
10
|
+
constructor(config) {
|
|
11
|
+
this.client = axios_1.default.create({
|
|
12
|
+
baseURL: config.baseURL,
|
|
13
|
+
timeout: config.timeout || 10000,
|
|
14
|
+
headers: {
|
|
15
|
+
'Content-Type': 'application/json',
|
|
16
|
+
},
|
|
17
|
+
httpsAgent: new https_1.default.Agent({
|
|
18
|
+
rejectUnauthorized: false,
|
|
19
|
+
}),
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
async post(endpoint, data) {
|
|
23
|
+
try {
|
|
24
|
+
const response = await this.client.post(endpoint, data);
|
|
25
|
+
return response.data;
|
|
26
|
+
}
|
|
27
|
+
catch (error) {
|
|
28
|
+
throw this.handleError(error);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
async get(endpoint) {
|
|
32
|
+
try {
|
|
33
|
+
const response = await this.client.get(endpoint);
|
|
34
|
+
return response.data;
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
throw this.handleError(error);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
handleError(error) {
|
|
41
|
+
if (error.response) {
|
|
42
|
+
return new Error(`${error.response.data?.message || 'Unknown error'}`);
|
|
43
|
+
}
|
|
44
|
+
if (error.request) {
|
|
45
|
+
return new Error('Network Error: No response received');
|
|
46
|
+
}
|
|
47
|
+
return new Error(`Request Error: ${error.message}`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
exports.default = ApiService;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.LicenseType = exports.LicenseStatus = void 0;
|
|
7
|
+
const api_service_1 = __importDefault(require("./api-service"));
|
|
8
|
+
const api_config_1 = require("../config/api-config");
|
|
9
|
+
var LicenseStatus;
|
|
10
|
+
(function (LicenseStatus) {
|
|
11
|
+
LicenseStatus[LicenseStatus["Active"] = 1] = "Active";
|
|
12
|
+
LicenseStatus[LicenseStatus["Expired"] = 2] = "Expired";
|
|
13
|
+
LicenseStatus[LicenseStatus["InActive"] = 3] = "InActive";
|
|
14
|
+
LicenseStatus[LicenseStatus["ClaimRequested"] = 4] = "ClaimRequested";
|
|
15
|
+
LicenseStatus[LicenseStatus["Revoked"] = 5] = "Revoked";
|
|
16
|
+
})(LicenseStatus || (exports.LicenseStatus = LicenseStatus = {}));
|
|
17
|
+
var LicenseType;
|
|
18
|
+
(function (LicenseType) {
|
|
19
|
+
LicenseType[LicenseType["FreeCreditUniversal"] = 0] = "FreeCreditUniversal";
|
|
20
|
+
LicenseType[LicenseType["FreeCreditHostnameSpecific"] = 1] = "FreeCreditHostnameSpecific";
|
|
21
|
+
LicenseType[LicenseType["PaidCredit"] = 2] = "PaidCredit";
|
|
22
|
+
LicenseType[LicenseType["SubscriptionCredit"] = 3] = "SubscriptionCredit";
|
|
23
|
+
})(LicenseType || (exports.LicenseType = LicenseType = {}));
|
|
24
|
+
class LicenseApiService extends api_service_1.default {
|
|
25
|
+
constructor() {
|
|
26
|
+
super({
|
|
27
|
+
baseURL: (0, api_config_1.API_CONFIG)().licenseApi,
|
|
28
|
+
timeout: 15000,
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
//remove
|
|
32
|
+
async setupLicense(encryptedMachineId) {
|
|
33
|
+
return this.post(`/setup/${encryptedMachineId}`);
|
|
34
|
+
}
|
|
35
|
+
async getSystem() {
|
|
36
|
+
try {
|
|
37
|
+
const result = await this.get(`/system`);
|
|
38
|
+
return result;
|
|
39
|
+
}
|
|
40
|
+
catch (exception) {
|
|
41
|
+
return { id: '' };
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
async activateLicense(token) {
|
|
45
|
+
return this.post("/activate", { token });
|
|
46
|
+
}
|
|
47
|
+
async deactivateLicense(encryptedMachineId, deactivationToken) {
|
|
48
|
+
try {
|
|
49
|
+
const res = await this.post('/deassociate', {
|
|
50
|
+
machineId: encryptedMachineId,
|
|
51
|
+
token: deactivationToken,
|
|
52
|
+
});
|
|
53
|
+
return res;
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
if (error.code === 'ECONNREFUSED') {
|
|
57
|
+
const fallbackService = new api_service_1.default({
|
|
58
|
+
baseURL: (0, api_config_1.API_CONFIG)().onPremLicenseCloudeApi,
|
|
59
|
+
timeout: 15000,
|
|
60
|
+
});
|
|
61
|
+
const res = await fallbackService.post('/deassociate', {
|
|
62
|
+
data: "",
|
|
63
|
+
machineId: encryptedMachineId,
|
|
64
|
+
token: deactivationToken,
|
|
65
|
+
});
|
|
66
|
+
return res;
|
|
67
|
+
}
|
|
68
|
+
throw error;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
exports.default = LicenseApiService;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const crypto_1 = __importDefault(require("crypto"));
|
|
7
|
+
class InstallerAppCryptoService {
|
|
8
|
+
IV_LEN = 12;
|
|
9
|
+
TAG_LEN = 16;
|
|
10
|
+
KEY_LEN = 32;
|
|
11
|
+
K1;
|
|
12
|
+
K2;
|
|
13
|
+
K3;
|
|
14
|
+
K4;
|
|
15
|
+
K5;
|
|
16
|
+
keys;
|
|
17
|
+
constructor() {
|
|
18
|
+
this.K1 = this.normalizeKey("3jv8_Ve3yTNwJjhSiMftBXpAkFtJLxSNaoJcBGztvUI");
|
|
19
|
+
this.K2 = this.normalizeKey("ZEl9PKemmf4w6wYcK3uFiFYrya9FJMA9UI_B0k_217A");
|
|
20
|
+
this.K3 = this.normalizeKey("ZDjIlSq44RcZHAdZFRpCRYtayxVkadiEEUZ6TmeP7jU");
|
|
21
|
+
this.K4 = this.normalizeKey("ucnRjVn7WghWSXnn4XpDjIEyzJ9ChPUUojrx4g7giWM");
|
|
22
|
+
this.K5 = this.normalizeKey("C0p4tWA7EJF6c2hdgiV3VDZbfRzXUWjPhesycqsA0aM");
|
|
23
|
+
this.keys = [this.K1, this.K2, this.K3, this.K4, this.K5];
|
|
24
|
+
}
|
|
25
|
+
encrypt(plain) {
|
|
26
|
+
const key = this.keys[Math.floor(Math.random() * this.keys.length)];
|
|
27
|
+
const iv = crypto_1.default.randomBytes(this.IV_LEN);
|
|
28
|
+
const cipher = crypto_1.default.createCipheriv("aes-256-gcm", key, iv, { authTagLength: this.TAG_LEN });
|
|
29
|
+
const ct = Buffer.concat([cipher.update(Buffer.from(plain, "utf8")), cipher.final()]);
|
|
30
|
+
const tag = cipher.getAuthTag();
|
|
31
|
+
return this.b64uEnc(Buffer.concat([iv, tag, ct]));
|
|
32
|
+
}
|
|
33
|
+
decrypt(token) {
|
|
34
|
+
let data;
|
|
35
|
+
try {
|
|
36
|
+
data = this.b64uDec(token);
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
throw new Error("Invalid token");
|
|
40
|
+
}
|
|
41
|
+
if (data.length <= this.IV_LEN + this.TAG_LEN)
|
|
42
|
+
throw new Error("Corrupt token");
|
|
43
|
+
const iv = data.slice(0, this.IV_LEN);
|
|
44
|
+
const tag = data.slice(this.IV_LEN, this.IV_LEN + this.TAG_LEN);
|
|
45
|
+
const ct = data.slice(this.IV_LEN + this.TAG_LEN);
|
|
46
|
+
for (const key of this.keys) {
|
|
47
|
+
try {
|
|
48
|
+
const decipher = crypto_1.default.createDecipheriv("aes-256-gcm", key, iv, { authTagLength: this.TAG_LEN });
|
|
49
|
+
decipher.setAuthTag(tag);
|
|
50
|
+
const pt = Buffer.concat([decipher.update(ct), decipher.final()]);
|
|
51
|
+
return pt.toString("utf8");
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
// try next key
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
throw new Error("Unable to decrypt with any key");
|
|
58
|
+
}
|
|
59
|
+
generateKey() {
|
|
60
|
+
return this.b64uEnc(crypto_1.default.randomBytes(this.KEY_LEN));
|
|
61
|
+
}
|
|
62
|
+
b64uEnc(buf) {
|
|
63
|
+
return buf.toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
64
|
+
}
|
|
65
|
+
b64uDec(s) {
|
|
66
|
+
s = s.replace(/-/g, "+").replace(/_/g, "/");
|
|
67
|
+
const pad = 4 - (s.length % 4);
|
|
68
|
+
if (pad !== 4)
|
|
69
|
+
s += "=".repeat(pad);
|
|
70
|
+
return Buffer.from(s, "base64");
|
|
71
|
+
}
|
|
72
|
+
normalizeKey(k) {
|
|
73
|
+
const buf = Buffer.isBuffer(k) ? k : this.b64uDec(k);
|
|
74
|
+
if (buf.length !== this.KEY_LEN)
|
|
75
|
+
throw new Error("Key must be 32 bytes.");
|
|
76
|
+
return buf;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
exports.default = InstallerAppCryptoService;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.ask = ask;
|
|
7
|
+
const readline_1 = __importDefault(require("readline"));
|
|
8
|
+
function ask(question) {
|
|
9
|
+
return new Promise((resolve) => {
|
|
10
|
+
const rl = readline_1.default.createInterface({
|
|
11
|
+
input: process.stdin,
|
|
12
|
+
output: process.stdout,
|
|
13
|
+
});
|
|
14
|
+
rl.question(question, (answer) => {
|
|
15
|
+
rl.close();
|
|
16
|
+
resolve(answer.trim());
|
|
17
|
+
});
|
|
18
|
+
rl.on('SIGINT', () => {
|
|
19
|
+
rl.close();
|
|
20
|
+
console.log('\nExiting...');
|
|
21
|
+
process.exit(0);
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getMachineId = void 0;
|
|
4
|
+
const node_machine_id_1 = require("node-machine-id");
|
|
5
|
+
const getMachineId = () => {
|
|
6
|
+
return (0, node_machine_id_1.machineIdSync)(true);
|
|
7
|
+
};
|
|
8
|
+
exports.getMachineId = getMachineId;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.displayLicenseTable = displayLicenseTable;
|
|
7
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
8
|
+
const cli_table3_1 = __importDefault(require("cli-table3"));
|
|
9
|
+
function displayLicenseTable(response) {
|
|
10
|
+
const getStatusText = (status) => {
|
|
11
|
+
const map = {
|
|
12
|
+
1: 'Active',
|
|
13
|
+
2: 'Expired',
|
|
14
|
+
3: 'Inactive',
|
|
15
|
+
4: 'Revoked',
|
|
16
|
+
5: 'Claim Requested',
|
|
17
|
+
};
|
|
18
|
+
return map[status] || '❓ Unknown';
|
|
19
|
+
};
|
|
20
|
+
const getTypeText = (type) => {
|
|
21
|
+
const map = {
|
|
22
|
+
0: 'Free Credit Universal',
|
|
23
|
+
1: 'Free Credit Hostname',
|
|
24
|
+
2: 'Paid Credit',
|
|
25
|
+
3: 'Subscription'
|
|
26
|
+
};
|
|
27
|
+
return map[type] || '❓ Unknown';
|
|
28
|
+
};
|
|
29
|
+
const table = new cli_table3_1.default({
|
|
30
|
+
head: [chalk_1.default.bold('Property'), chalk_1.default.bold('Value')],
|
|
31
|
+
style: {
|
|
32
|
+
border: ['gray'],
|
|
33
|
+
head: [],
|
|
34
|
+
compact: false
|
|
35
|
+
},
|
|
36
|
+
chars: { 'top': '═', 'top-mid': '╤', 'top-left': '╔', 'top-right': '╗',
|
|
37
|
+
'bottom': '═', 'bottom-mid': '╧', 'bottom-left': '╚', 'bottom-right': '╝',
|
|
38
|
+
'left': '║', 'left-mid': '╟', 'mid': '─', 'mid-mid': '┼',
|
|
39
|
+
'right': '║', 'right-mid': '╢', 'middle': '│' }
|
|
40
|
+
});
|
|
41
|
+
table.push([chalk_1.default.cyan.bold('📄 License Name'), chalk_1.default.white(response.license.licenseName)], [chalk_1.default.cyan.bold('🔑 License Key'), chalk_1.default.white(response.license.licenseKey)], [chalk_1.default.cyan.bold('🏢 Organization'), chalk_1.default.white(response.organizationName)], [chalk_1.default.cyan.bold('🟢 Status'), chalk_1.default.green(getStatusText(response.license.licenseStatus))], [chalk_1.default.cyan.bold('📊 Plan Type'), chalk_1.default.white(getTypeText(response.license.licenseType))], [chalk_1.default.cyan.bold('📅 Expires At'), chalk_1.default.white(new Date(response.license.expiresAt).toLocaleDateString())]);
|
|
42
|
+
if (response.license.scanCredits > 0) {
|
|
43
|
+
table.push(['🔍 Scan Credits', chalk_1.default.yellow.bold(response.license.scanCredits.toString())]);
|
|
44
|
+
}
|
|
45
|
+
if (response.license.creditTargets > 0) {
|
|
46
|
+
table.push(['🎯 Target Credits', chalk_1.default.yellow.bold(response.license.creditTargets.toString())]);
|
|
47
|
+
}
|
|
48
|
+
if (response.license.freeCredits > 0) {
|
|
49
|
+
table.push(['🎁 Free Credits', chalk_1.default.yellow.bold(response.license.freeCredits.toString())]);
|
|
50
|
+
}
|
|
51
|
+
console.log(chalk_1.default.bold.blue('\n📊 LICENSE DETAILS'));
|
|
52
|
+
console.log(table.toString());
|
|
53
|
+
console.log(chalk_1.default.gray('➤ You can now start using ZeroThreat security features.\n'));
|
|
54
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.default = openBrowser;
|
|
4
|
+
const child_process_1 = require("child_process");
|
|
5
|
+
async function openBrowser(url) {
|
|
6
|
+
let chromePath;
|
|
7
|
+
switch (process.platform) {
|
|
8
|
+
case "win32":
|
|
9
|
+
chromePath = "C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe";
|
|
10
|
+
break;
|
|
11
|
+
case "darwin":
|
|
12
|
+
chromePath = "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome";
|
|
13
|
+
break;
|
|
14
|
+
case "linux":
|
|
15
|
+
chromePath = "/usr/bin/google-chrome";
|
|
16
|
+
break;
|
|
17
|
+
default:
|
|
18
|
+
throw new Error("Unsupported OS");
|
|
19
|
+
}
|
|
20
|
+
await new Promise((resolve, reject) => {
|
|
21
|
+
const child = (0, child_process_1.spawn)(chromePath, [url]);
|
|
22
|
+
child.on('error', (err) => {
|
|
23
|
+
reject(err);
|
|
24
|
+
});
|
|
25
|
+
child.on('exit', (code, signal) => {
|
|
26
|
+
resolve({ code, signal });
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@zerothreatai/cli",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"main": "dist/index.js",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"build": "node build.js",
|
|
7
|
+
"start": "cross-env WORKING_ENVIRONMENT=DEV node dist/index.js",
|
|
8
|
+
"dev": "node build.js && cross-env WORKING_ENVIRONMENT=DEV node dist/index.js",
|
|
9
|
+
"link": "npm run build && npm link"
|
|
10
|
+
},
|
|
11
|
+
"keywords": [],
|
|
12
|
+
"author": "",
|
|
13
|
+
"license": "ISC",
|
|
14
|
+
"description": "",
|
|
15
|
+
"dependencies": {
|
|
16
|
+
"axios": "^0.27.2",
|
|
17
|
+
"chalk": "^4.1.2",
|
|
18
|
+
"cli-table3": "^0.6.5",
|
|
19
|
+
"commander": "^14.0.2",
|
|
20
|
+
"cross-env": "^10.1.0",
|
|
21
|
+
"dockerode": "^4.0.2",
|
|
22
|
+
"dotenv": "^17.2.3",
|
|
23
|
+
"figlet": "^1.9.4",
|
|
24
|
+
"inquirer": "^8.2.5",
|
|
25
|
+
"js-yaml": "^4.1.1",
|
|
26
|
+
"node-machine-id": "^1.1.12"
|
|
27
|
+
},
|
|
28
|
+
"files": [
|
|
29
|
+
"dist",
|
|
30
|
+
".env.prod"
|
|
31
|
+
],
|
|
32
|
+
"bin": {
|
|
33
|
+
"zt": "./dist/index.js"
|
|
34
|
+
},
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"@types/chalk": "^2.2.4",
|
|
37
|
+
"@types/commander": "^2.12.5",
|
|
38
|
+
"@types/dockerode": "^3.3.46",
|
|
39
|
+
"@types/figlet": "^1.5.0",
|
|
40
|
+
"@types/inquirer": "^9.0.9",
|
|
41
|
+
"@types/js-yaml": "^4.0.0",
|
|
42
|
+
"@types/node": "^24.10.1",
|
|
43
|
+
"@types/ora": "^3.2.0",
|
|
44
|
+
"@types/prompt-sync": "^4.2.3",
|
|
45
|
+
"@types/readline-sync": "^1.4.8",
|
|
46
|
+
"ts-node": "^10.9.2",
|
|
47
|
+
"typescript": "^5.9.3"
|
|
48
|
+
}
|
|
49
|
+
}
|