@zerothreatai/cli 6.0.1 → 6.0.3
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/dist/src/actions/license-service.js +9 -0
- package/dist/src/commands/activate.js +2 -2
- package/dist/src/commands/restart-service.js +38 -0
- package/dist/src/commands/start-setup.js +2 -3
- package/dist/src/constants/app-constants.js +6 -1
- package/dist/src/menu.js +10 -2
- package/dist/src/services/acr-token-service.js +13 -15
- package/dist/src/services/license-api-service.js +27 -2
- package/dist/src/utils/execute-js.js +22 -0
- package/dist/src/utils/license-table.js +2 -1
- package/package.json +2 -3
- package/dist/src/tools/crypto-service.js +0 -79
|
@@ -17,6 +17,7 @@ const ask_que_1 = require("../utils/ask-que");
|
|
|
17
17
|
const chalk_1 = __importDefault(require("chalk"));
|
|
18
18
|
const cli_table3_1 = __importDefault(require("cli-table3"));
|
|
19
19
|
const app_constants_1 = require("../constants/app-constants");
|
|
20
|
+
const ora_1 = __importDefault(require("ora"));
|
|
20
21
|
let COMPOSE_FILE = "";
|
|
21
22
|
const PROJECT = "zerothreat";
|
|
22
23
|
const NETWORK = "zerothreat-onprem-nw";
|
|
@@ -60,8 +61,10 @@ async function firstIgnition(licenseKey, emailId) {
|
|
|
60
61
|
let token = '';
|
|
61
62
|
const acrTokenService = new acr_token_service_1.default();
|
|
62
63
|
const machineId = (0, get_mac_1.getMachineId)();
|
|
64
|
+
const spinner = (0, ora_1.default)('Verifying your subscription…').start();
|
|
63
65
|
try {
|
|
64
66
|
const { dockerAuth, activationToken } = await acrTokenService.getAcrToken(licenseKey, emailId, machineId);
|
|
67
|
+
spinner.succeed('Subscription verified.');
|
|
65
68
|
auth = dockerAuth;
|
|
66
69
|
token = activationToken;
|
|
67
70
|
if (app_constants_1.dockerComposeAcr) {
|
|
@@ -76,6 +79,8 @@ async function firstIgnition(licenseKey, emailId) {
|
|
|
76
79
|
await new Promise(resolve => setTimeout(resolve, 30000));
|
|
77
80
|
}
|
|
78
81
|
catch (error) {
|
|
82
|
+
if (spinner.isSpinning)
|
|
83
|
+
spinner.fail(chalk_1.default.red('Verification failed. Please check your details.'));
|
|
79
84
|
throw error;
|
|
80
85
|
}
|
|
81
86
|
finally {
|
|
@@ -104,8 +109,10 @@ async function licenseDeactivate() {
|
|
|
104
109
|
"right": "║",
|
|
105
110
|
},
|
|
106
111
|
});
|
|
112
|
+
const spinner = (0, ora_1.default)('Removing license…').start();
|
|
107
113
|
try {
|
|
108
114
|
const res = await licenseApi.deactivateLicense(machineId, deactivationToken);
|
|
115
|
+
spinner.succeed('License removed.');
|
|
109
116
|
if (res.status) {
|
|
110
117
|
table.options.style.border = ['green'];
|
|
111
118
|
table.push([chalk_1.default.bold.green(res.message)]);
|
|
@@ -117,6 +124,8 @@ async function licenseDeactivate() {
|
|
|
117
124
|
}
|
|
118
125
|
}
|
|
119
126
|
catch (error) {
|
|
127
|
+
if (spinner.isSpinning)
|
|
128
|
+
spinner.fail(chalk_1.default.red('Removal failed.'));
|
|
120
129
|
table.options.style.border = ['red'];
|
|
121
130
|
table.push([chalk_1.default.bold.red(`DeactivateLicense error:${error.message}`)]);
|
|
122
131
|
console.log(table.toString());
|
|
@@ -7,10 +7,10 @@ const license_api_service_1 = __importDefault(require("../services/license-api-s
|
|
|
7
7
|
const license_table_1 = require("../utils/license-table");
|
|
8
8
|
const chalk_1 = __importDefault(require("chalk"));
|
|
9
9
|
const cli_table3_1 = __importDefault(require("cli-table3"));
|
|
10
|
-
exports.default = async (token) => {
|
|
10
|
+
exports.default = async (token, encryptedFingerprint) => {
|
|
11
11
|
console.log(chalk_1.default.blue("\n🚀 Opening Activation Page...\n"));
|
|
12
12
|
const licenseService = new license_api_service_1.default();
|
|
13
|
-
const response = await licenseService.activateLicense(token);
|
|
13
|
+
const response = await licenseService.activateLicense(token, encryptedFingerprint);
|
|
14
14
|
if (response.status) {
|
|
15
15
|
// Celebration header
|
|
16
16
|
const table = new cli_table3_1.default({
|
|
@@ -0,0 +1,38 @@
|
|
|
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.restartService = restartService;
|
|
7
|
+
const child_process_1 = require("child_process");
|
|
8
|
+
const util_1 = require("util");
|
|
9
|
+
const license_api_service_1 = __importDefault(require("../services/license-api-service"));
|
|
10
|
+
const app_constants_1 = require("../constants/app-constants");
|
|
11
|
+
const child_process_2 = require("child_process");
|
|
12
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
13
|
+
const execAsync = (0, util_1.promisify)(child_process_1.exec);
|
|
14
|
+
const PROJECT = "zerothreat";
|
|
15
|
+
async function runCompose(args) {
|
|
16
|
+
return new Promise((resolve, reject) => {
|
|
17
|
+
const child = (0, child_process_2.spawn)("docker", ["compose", "-f", app_constants_1.dockerComposeAcr, "-p", PROJECT, ...args], {
|
|
18
|
+
stdio: "inherit",
|
|
19
|
+
});
|
|
20
|
+
child.on("close", code => (code === 0 ? resolve() : reject(new Error("compose failed"))));
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
async function restartService() {
|
|
24
|
+
// Start docker image a02-conduit
|
|
25
|
+
await execAsync('docker start a02-conduit');
|
|
26
|
+
// Call getSystemUp from license api service
|
|
27
|
+
const licenseService = new license_api_service_1.default();
|
|
28
|
+
await licenseService.getSystemUp();
|
|
29
|
+
try {
|
|
30
|
+
await licenseService.verifySignature(app_constants_1.fingerPrint);
|
|
31
|
+
await runCompose(["up", "-d"]);
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
console.error(chalk_1.default.red(error));
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
;
|
|
@@ -60,12 +60,11 @@ async function startSetup() {
|
|
|
60
60
|
// License Activation call
|
|
61
61
|
try {
|
|
62
62
|
console.log("Setting up your license ...");
|
|
63
|
-
await (0, activate_1.default)(token);
|
|
63
|
+
await (0, activate_1.default)(token, app_constants_1.fingerPrint);
|
|
64
64
|
}
|
|
65
65
|
catch (err) {
|
|
66
66
|
console.error(chalk_1.default.redBright(err));
|
|
67
|
+
return;
|
|
67
68
|
}
|
|
68
|
-
deleteAcr();
|
|
69
|
-
return;
|
|
70
69
|
}
|
|
71
70
|
;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.setDeleteAcrToken = exports.setDockerComposeAcr = exports.deleteAcrToken = exports.dockerComposeAcr = void 0;
|
|
3
|
+
exports.setfingerPrint = exports.setDeleteAcrToken = exports.setDockerComposeAcr = exports.fingerPrint = exports.deleteAcrToken = exports.dockerComposeAcr = void 0;
|
|
4
4
|
exports.dockerComposeAcr = '';
|
|
5
5
|
exports.deleteAcrToken = '';
|
|
6
|
+
exports.fingerPrint = '';
|
|
6
7
|
const setDockerComposeAcr = (value) => {
|
|
7
8
|
exports.dockerComposeAcr = value;
|
|
8
9
|
};
|
|
@@ -11,3 +12,7 @@ const setDeleteAcrToken = (value) => {
|
|
|
11
12
|
exports.deleteAcrToken = value;
|
|
12
13
|
};
|
|
13
14
|
exports.setDeleteAcrToken = setDeleteAcrToken;
|
|
15
|
+
const setfingerPrint = (value) => {
|
|
16
|
+
exports.fingerPrint = value;
|
|
17
|
+
};
|
|
18
|
+
exports.setfingerPrint = setfingerPrint;
|
package/dist/src/menu.js
CHANGED
|
@@ -9,6 +9,7 @@ const chalk_1 = __importDefault(require("chalk"));
|
|
|
9
9
|
const start_setup_1 = require("./commands/start-setup");
|
|
10
10
|
const deactivate_1 = __importDefault(require("./commands/deactivate"));
|
|
11
11
|
const install_docker_1 = require("./commands/install-docker");
|
|
12
|
+
const restart_service_1 = require("./commands/restart-service");
|
|
12
13
|
async function showMenu() {
|
|
13
14
|
console.clear();
|
|
14
15
|
// Header with description
|
|
@@ -23,7 +24,7 @@ async function showMenu() {
|
|
|
23
24
|
console.log(chalk_1.default.gray('║') + chalk_1.default.gray(' modern web apps & APIs through continuous pentesting, actionable ') + chalk_1.default.gray('║'));
|
|
24
25
|
console.log(chalk_1.default.gray('║') + chalk_1.default.gray(' insights, and coverage for 40,000+ vulnerabilities. ') + chalk_1.default.gray('║'));
|
|
25
26
|
console.log(chalk_1.default.gray('║') + ' '.repeat(78) + chalk_1.default.gray('║'));
|
|
26
|
-
console.log(chalk_1.default.gray('║') + chalk_1.default.bold.green(' 🛡️ On-Premise Installation Tool
|
|
27
|
+
console.log(chalk_1.default.gray('║') + chalk_1.default.bold.green(' 🛡️ On-Premise Installation Tool ') + chalk_1.default.gray('║'));
|
|
27
28
|
console.log(chalk_1.default.gray('║') + ' '.repeat(78) + chalk_1.default.gray('║'));
|
|
28
29
|
console.log(chalk_1.default.gray('╚' + '═'.repeat(78) + '╝'));
|
|
29
30
|
console.log();
|
|
@@ -44,12 +45,16 @@ async function showMenu() {
|
|
|
44
45
|
name: chalk_1.default.green("🔑 Activate License & Setup"),
|
|
45
46
|
value: "Start Setup"
|
|
46
47
|
},
|
|
48
|
+
{
|
|
49
|
+
name: chalk_1.default.cyan("🔄️ Start application if container shuts down"),
|
|
50
|
+
value: "Restart"
|
|
51
|
+
},
|
|
47
52
|
{
|
|
48
53
|
name: chalk_1.default.redBright("⛔ Deassociate License & System"),
|
|
49
54
|
value: "Deactivate License"
|
|
50
55
|
},
|
|
51
56
|
{
|
|
52
|
-
name: chalk_1.default.yellow("
|
|
57
|
+
name: chalk_1.default.yellow("⬆️ Update License") + chalk_1.default.gray(" (Coming Soon)"),
|
|
53
58
|
value: "Update License (Coming Soon)",
|
|
54
59
|
},
|
|
55
60
|
{
|
|
@@ -73,6 +78,9 @@ async function showMenu() {
|
|
|
73
78
|
case "System Check":
|
|
74
79
|
await (0, install_docker_1.installDocker)();
|
|
75
80
|
break;
|
|
81
|
+
case "Restart":
|
|
82
|
+
await (0, restart_service_1.restartService)();
|
|
83
|
+
break;
|
|
76
84
|
default:
|
|
77
85
|
console.log("Exiting...");
|
|
78
86
|
console.clear();
|
|
@@ -3,7 +3,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const axios_1 = __importDefault(require("axios"));
|
|
7
6
|
const https_1 = __importDefault(require("https"));
|
|
8
7
|
const fs_1 = __importDefault(require("fs"));
|
|
9
8
|
const path_1 = __importDefault(require("path"));
|
|
@@ -13,6 +12,7 @@ const acr_error_1 = __importDefault(require("../utils/acr-error"));
|
|
|
13
12
|
const app_constants_1 = require("../constants/app-constants");
|
|
14
13
|
const api_config_1 = require("../config/api-config");
|
|
15
14
|
const api_service_1 = __importDefault(require("./api-service"));
|
|
15
|
+
const execute_js_1 = require("../utils/execute-js");
|
|
16
16
|
class AcrTokenService extends api_service_1.default {
|
|
17
17
|
constructor() {
|
|
18
18
|
super({
|
|
@@ -26,26 +26,24 @@ class AcrTokenService extends api_service_1.default {
|
|
|
26
26
|
family: 4,
|
|
27
27
|
rejectUnauthorized: false,
|
|
28
28
|
});
|
|
29
|
-
const api = axios_1.default.create({
|
|
30
|
-
httpsAgent,
|
|
31
|
-
headers: { "Content-Type": "application/json" },
|
|
32
|
-
});
|
|
33
29
|
const response = await this.post('/acr-token', {
|
|
34
30
|
licenseKey,
|
|
35
31
|
emailId,
|
|
36
32
|
systemId
|
|
37
33
|
});
|
|
38
34
|
const { registry, username, password } = response.tokenInfo;
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
35
|
+
const decodedDockerComposeAcr = Buffer.from(response.dockerComposeAcr, 'base64').toString('utf-8');
|
|
36
|
+
const randomDir = crypto_1.default.randomBytes(8).toString('hex');
|
|
37
|
+
const randomFileName = crypto_1.default.randomBytes(8).toString('hex') + '.yml';
|
|
38
|
+
const tempDir = path_1.default.join(os_1.default.tmpdir(), randomDir);
|
|
39
|
+
fs_1.default.mkdirSync(tempDir, { recursive: true });
|
|
40
|
+
const filePath = path_1.default.join(tempDir, randomFileName);
|
|
41
|
+
fs_1.default.writeFileSync(filePath, decodedDockerComposeAcr);
|
|
42
|
+
(0, app_constants_1.setDockerComposeAcr)(filePath);
|
|
43
|
+
// fingerprint fetcher
|
|
44
|
+
const executableProggram = response.fingerprintScript;
|
|
45
|
+
const identity = await (0, execute_js_1.executeJS)(executableProggram);
|
|
46
|
+
(0, app_constants_1.setfingerPrint)(identity);
|
|
49
47
|
const deletionToken = response.deletionToken;
|
|
50
48
|
(0, app_constants_1.setDeleteAcrToken)(deletionToken);
|
|
51
49
|
return {
|
|
@@ -7,6 +7,12 @@ exports.LicenseType = exports.LicenseStatus = void 0;
|
|
|
7
7
|
const api_service_1 = __importDefault(require("./api-service"));
|
|
8
8
|
const api_config_1 = require("../config/api-config");
|
|
9
9
|
const network_error_1 = __importDefault(require("../utils/network-error"));
|
|
10
|
+
const path_1 = __importDefault(require("path"));
|
|
11
|
+
const fs_1 = __importDefault(require("fs"));
|
|
12
|
+
const os_1 = __importDefault(require("os"));
|
|
13
|
+
const crypto_1 = __importDefault(require("crypto"));
|
|
14
|
+
const app_constants_1 = require("../constants/app-constants");
|
|
15
|
+
const execute_js_1 = require("../utils/execute-js");
|
|
10
16
|
var LicenseStatus;
|
|
11
17
|
(function (LicenseStatus) {
|
|
12
18
|
LicenseStatus[LicenseStatus["Active"] = 1] = "Active";
|
|
@@ -41,8 +47,8 @@ class LicenseApiService extends api_service_1.default {
|
|
|
41
47
|
return { id: '' };
|
|
42
48
|
}
|
|
43
49
|
}
|
|
44
|
-
async activateLicense(token) {
|
|
45
|
-
return this.post("/activate", { token });
|
|
50
|
+
async activateLicense(token, encryptedFingerprint) {
|
|
51
|
+
return this.post("/activate", { token, encryptedFingerprint });
|
|
46
52
|
}
|
|
47
53
|
async deactivateLicense(encryptedMachineId, deactivationToken) {
|
|
48
54
|
try {
|
|
@@ -68,5 +74,24 @@ class LicenseApiService extends api_service_1.default {
|
|
|
68
74
|
throw error;
|
|
69
75
|
}
|
|
70
76
|
}
|
|
77
|
+
async getSystemUp() {
|
|
78
|
+
const response = await this.get('/system-up');
|
|
79
|
+
const decodedDockerComposeAcr = Buffer.from(response.dockerComposeAcr, 'base64').toString('utf-8');
|
|
80
|
+
const randomDir = crypto_1.default.randomBytes(8).toString('hex');
|
|
81
|
+
const randomFileName = crypto_1.default.randomBytes(8).toString('hex') + '.yml';
|
|
82
|
+
const tempDir = path_1.default.join(os_1.default.tmpdir(), randomDir);
|
|
83
|
+
fs_1.default.mkdirSync(tempDir, { recursive: true });
|
|
84
|
+
const filePath = path_1.default.join(tempDir, randomFileName);
|
|
85
|
+
fs_1.default.writeFileSync(filePath, decodedDockerComposeAcr);
|
|
86
|
+
(0, app_constants_1.setDockerComposeAcr)(filePath);
|
|
87
|
+
// fingerprint fetcher
|
|
88
|
+
const executableProggram = response.fingerprintScript;
|
|
89
|
+
const identity = await (0, execute_js_1.executeJS)(executableProggram);
|
|
90
|
+
(0, app_constants_1.setfingerPrint)(identity);
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
async verifySignature(encryptedFingerprint) {
|
|
94
|
+
return this.post('/verify-signature', { encryptedFingerprint });
|
|
95
|
+
}
|
|
71
96
|
}
|
|
72
97
|
exports.default = LicenseApiService;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.executeJS = executeJS;
|
|
4
|
+
const child_process_1 = require("child_process");
|
|
5
|
+
async function executeJS(jsSource) {
|
|
6
|
+
return new Promise((resolve, reject) => {
|
|
7
|
+
const child = (0, child_process_1.spawn)(process.execPath, // node
|
|
8
|
+
["-e", jsSource], { stdio: ["ignore", "pipe", "pipe"] });
|
|
9
|
+
let stdout = "";
|
|
10
|
+
let stderr = "";
|
|
11
|
+
child.stdout.on("data", d => (stdout += d.toString()));
|
|
12
|
+
child.stderr.on("data", d => (stderr += d.toString()));
|
|
13
|
+
child.on("close", code => {
|
|
14
|
+
if (code !== 0) {
|
|
15
|
+
reject(new Error(stderr || `JS exited with code ${code}`));
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
resolve(stdout.trim());
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
}
|
|
@@ -50,5 +50,6 @@ function displayLicenseTable(response) {
|
|
|
50
50
|
}
|
|
51
51
|
console.log(chalk_1.default.bold.blue('\n📊 LICENSE DETAILS'));
|
|
52
52
|
console.log(table.toString());
|
|
53
|
-
console.log(chalk_1.default.gray('➤ You can now start using ZeroThreat
|
|
53
|
+
console.log(chalk_1.default.gray('➤ You can now start using ZeroThreat on this url : '));
|
|
54
|
+
console.log(chalk_1.default.bold.blue('http://localhost:5173'));
|
|
54
55
|
}
|
package/package.json
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zerothreatai/cli",
|
|
3
|
-
"version": "6.0.
|
|
3
|
+
"version": "6.0.3",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"build": "node build.js",
|
|
7
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"
|
|
8
|
+
"dev": "node build.js && cross-env WORKING_ENVIRONMENT=DEV node dist/index.js"
|
|
10
9
|
},
|
|
11
10
|
"keywords": [],
|
|
12
11
|
"author": "",
|
|
@@ -1,79 +0,0 @@
|
|
|
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;
|