mobbdev 0.0.92 → 0.0.94
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/index.mjs +153 -103
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -104,6 +104,12 @@ var errorMessages = {
|
|
|
104
104
|
"(--token)"
|
|
105
105
|
)} is needed if you're adding an SCM token`
|
|
106
106
|
};
|
|
107
|
+
var progressMassages = {
|
|
108
|
+
processingVulnerabilityReportSuccess: "\u2699\uFE0F Vulnerability report proccessed successfully",
|
|
109
|
+
processingVulnerabilityReport: "\u2699\uFE0F Proccessing vulnerability report",
|
|
110
|
+
processingVulnerabilityReportFailed: "\u2699\uFE0F Error Proccessing vulnerability report"
|
|
111
|
+
};
|
|
112
|
+
var VUL_REPORT_DIGEST_TIMEOUT_MS = 1e3 * 60 * 20;
|
|
107
113
|
|
|
108
114
|
// src/features/analysis/index.ts
|
|
109
115
|
import crypto from "node:crypto";
|
|
@@ -179,7 +185,7 @@ var CliError = class extends Error {
|
|
|
179
185
|
// src/features/analysis/index.ts
|
|
180
186
|
import chalk4 from "chalk";
|
|
181
187
|
import Configstore from "configstore";
|
|
182
|
-
import
|
|
188
|
+
import Debug11 from "debug";
|
|
183
189
|
import extract from "extract-zip";
|
|
184
190
|
import fetch3 from "node-fetch";
|
|
185
191
|
import open2 from "open";
|
|
@@ -563,7 +569,7 @@ var GET_VUL_BY_NODES_METADATA = gql2`
|
|
|
563
569
|
// src/features/analysis/graphql/subscirbe.ts
|
|
564
570
|
import { createClient } from "graphql-ws";
|
|
565
571
|
import WebSocket from "ws";
|
|
566
|
-
var SUBSCRIPTION_TIMEOUT_MS =
|
|
572
|
+
var SUBSCRIPTION_TIMEOUT_MS = 10 * 60 * 1e3;
|
|
567
573
|
function createWSClient(options) {
|
|
568
574
|
return createClient({
|
|
569
575
|
url: options.url,
|
|
@@ -1044,22 +1050,24 @@ var GQLClient = class {
|
|
|
1044
1050
|
res
|
|
1045
1051
|
).vulnerability_report_path.map((p) => p.path);
|
|
1046
1052
|
}
|
|
1047
|
-
async subscribeToAnalysis(params
|
|
1053
|
+
async subscribeToAnalysis(params) {
|
|
1054
|
+
const { callbackStates } = params;
|
|
1048
1055
|
return subscribe(
|
|
1049
1056
|
SUBSCRIBE_TO_ANALYSIS,
|
|
1050
|
-
params,
|
|
1057
|
+
params.subscribeToAnalysisParams,
|
|
1051
1058
|
async (resolve, reject, data) => {
|
|
1052
1059
|
if (data.analysis.state === "Failed") {
|
|
1053
1060
|
reject(data);
|
|
1054
1061
|
throw new Error(`Analysis failed with id: ${data.analysis.id}`);
|
|
1055
1062
|
}
|
|
1056
|
-
if (data.analysis?.state
|
|
1057
|
-
await callback(data.analysis.id);
|
|
1063
|
+
if (callbackStates.includes(data.analysis?.state)) {
|
|
1064
|
+
await params.callback(data.analysis.id);
|
|
1058
1065
|
resolve(data);
|
|
1059
1066
|
}
|
|
1060
1067
|
},
|
|
1061
1068
|
{
|
|
1062
|
-
apiKey: this._apiKey
|
|
1069
|
+
apiKey: this._apiKey,
|
|
1070
|
+
timeoutInMs: params.timeoutInMs
|
|
1063
1071
|
}
|
|
1064
1072
|
);
|
|
1065
1073
|
}
|
|
@@ -1091,7 +1099,7 @@ var GQLClient = class {
|
|
|
1091
1099
|
|
|
1092
1100
|
// src/features/analysis/handle_finished_analysis.ts
|
|
1093
1101
|
import { Octokit as Octokit3 } from "@octokit/core";
|
|
1094
|
-
import
|
|
1102
|
+
import Debug5 from "debug";
|
|
1095
1103
|
import parseDiff from "parse-diff";
|
|
1096
1104
|
import { z as z10 } from "zod";
|
|
1097
1105
|
|
|
@@ -3700,8 +3708,42 @@ function calculateRanges(integers) {
|
|
|
3700
3708
|
return ranges;
|
|
3701
3709
|
}
|
|
3702
3710
|
|
|
3711
|
+
// src/features/analysis/utils/send_report.ts
|
|
3712
|
+
import Debug4 from "debug";
|
|
3713
|
+
var debug4 = Debug4("mobbdev:index");
|
|
3714
|
+
async function sendReport({
|
|
3715
|
+
spinner,
|
|
3716
|
+
submitVulnerabilityReportVariables,
|
|
3717
|
+
gqlClient
|
|
3718
|
+
}) {
|
|
3719
|
+
try {
|
|
3720
|
+
const sumbitRes = await gqlClient.submitVulnerabilityReport(
|
|
3721
|
+
submitVulnerabilityReportVariables
|
|
3722
|
+
);
|
|
3723
|
+
if (sumbitRes.submitVulnerabilityReport.__typename !== "VulnerabilityReport") {
|
|
3724
|
+
debug4("error submit vul report %s", sumbitRes);
|
|
3725
|
+
throw new Error("\u{1F575}\uFE0F\u200D\u2642\uFE0F Mobb analysis failed");
|
|
3726
|
+
}
|
|
3727
|
+
spinner.update({ text: progressMassages.processingVulnerabilityReport });
|
|
3728
|
+
await gqlClient.subscribeToAnalysis({
|
|
3729
|
+
subscribeToAnalysisParams: {
|
|
3730
|
+
analysisId: sumbitRes.submitVulnerabilityReport.fixReportId
|
|
3731
|
+
},
|
|
3732
|
+
callback: () => spinner.update({
|
|
3733
|
+
text: "\u2699\uFE0F Vulnerability report proccessed successfuly"
|
|
3734
|
+
}),
|
|
3735
|
+
callbackStates: ["Digested", "Finished"],
|
|
3736
|
+
timeoutInMs: VUL_REPORT_DIGEST_TIMEOUT_MS
|
|
3737
|
+
});
|
|
3738
|
+
return sumbitRes;
|
|
3739
|
+
} catch (e) {
|
|
3740
|
+
spinner.error({ text: "\u{1F575}\uFE0F\u200D\u2642\uFE0F Mobb analysis failed" });
|
|
3741
|
+
throw e;
|
|
3742
|
+
}
|
|
3743
|
+
}
|
|
3744
|
+
|
|
3703
3745
|
// src/features/analysis/handle_finished_analysis.ts
|
|
3704
|
-
var
|
|
3746
|
+
var debug5 = Debug5("mobbdev:handle-finished-analysis");
|
|
3705
3747
|
var contactUsMarkdown = `For specific requests [contact us](https://mobb.ai/contact) and we'll do the most to answer your need quickly.`;
|
|
3706
3748
|
var commitFixButton = (commitUrl) => `<a href="${commitUrl}"><img src=${COMMIT_FIX_SVG}></a>`;
|
|
3707
3749
|
var MobbIconMarkdown = ``;
|
|
@@ -3839,7 +3881,7 @@ async function handleFinishedAnalysis({
|
|
|
3839
3881
|
{ authToken: githubActionToken }
|
|
3840
3882
|
);
|
|
3841
3883
|
} catch (e) {
|
|
3842
|
-
|
|
3884
|
+
debug5("delete comment failed %s", e);
|
|
3843
3885
|
return Promise.resolve();
|
|
3844
3886
|
}
|
|
3845
3887
|
});
|
|
@@ -3854,7 +3896,7 @@ async function handleFinishedAnalysis({
|
|
|
3854
3896
|
githubActionOctokit
|
|
3855
3897
|
);
|
|
3856
3898
|
} catch (e) {
|
|
3857
|
-
|
|
3899
|
+
debug5("delete comment failed %s", e);
|
|
3858
3900
|
return Promise.resolve();
|
|
3859
3901
|
}
|
|
3860
3902
|
});
|
|
@@ -3935,7 +3977,7 @@ ${fixPageLink}`,
|
|
|
3935
3977
|
fixablePrVuls,
|
|
3936
3978
|
nonFixablePrVuls
|
|
3937
3979
|
} = prVulenrabilities;
|
|
3938
|
-
|
|
3980
|
+
debug5({
|
|
3939
3981
|
fixablePrVuls,
|
|
3940
3982
|
nonFixablePrVuls,
|
|
3941
3983
|
vulnerabilitiesOutsidePr,
|
|
@@ -4011,10 +4053,10 @@ ${contactUsMarkdown}`;
|
|
|
4011
4053
|
import fs2 from "node:fs";
|
|
4012
4054
|
import path4 from "node:path";
|
|
4013
4055
|
import AdmZip from "adm-zip";
|
|
4014
|
-
import
|
|
4056
|
+
import Debug6 from "debug";
|
|
4015
4057
|
import { globby } from "globby";
|
|
4016
4058
|
import { isBinary } from "istextorbinary";
|
|
4017
|
-
var
|
|
4059
|
+
var debug6 = Debug6("mobbdev:pack");
|
|
4018
4060
|
var MAX_FILE_SIZE = 1024 * 1024 * 5;
|
|
4019
4061
|
function endsWithAny(str, suffixes) {
|
|
4020
4062
|
return suffixes.some(function(suffix) {
|
|
@@ -4022,37 +4064,37 @@ function endsWithAny(str, suffixes) {
|
|
|
4022
4064
|
});
|
|
4023
4065
|
}
|
|
4024
4066
|
async function pack(srcDirPath, vulnFiles) {
|
|
4025
|
-
|
|
4067
|
+
debug6("pack folder %s", srcDirPath);
|
|
4026
4068
|
const filepaths = await globby("**", {
|
|
4027
4069
|
gitignore: true,
|
|
4028
4070
|
onlyFiles: true,
|
|
4029
4071
|
cwd: srcDirPath,
|
|
4030
4072
|
followSymbolicLinks: false
|
|
4031
4073
|
});
|
|
4032
|
-
|
|
4074
|
+
debug6("files found %d", filepaths.length);
|
|
4033
4075
|
const zip = new AdmZip();
|
|
4034
|
-
|
|
4076
|
+
debug6("compressing files");
|
|
4035
4077
|
for (const filepath of filepaths) {
|
|
4036
4078
|
const absFilepath = path4.join(srcDirPath, filepath.toString());
|
|
4037
4079
|
if (!endsWithAny(
|
|
4038
4080
|
absFilepath.toString().replaceAll(path4.win32.sep, path4.posix.sep),
|
|
4039
4081
|
vulnFiles
|
|
4040
4082
|
)) {
|
|
4041
|
-
|
|
4083
|
+
debug6("ignoring %s because it is not a vulnerability file", filepath);
|
|
4042
4084
|
continue;
|
|
4043
4085
|
}
|
|
4044
4086
|
if (fs2.lstatSync(absFilepath).size > MAX_FILE_SIZE) {
|
|
4045
|
-
|
|
4087
|
+
debug6("ignoring %s because the size is > 5MB", filepath);
|
|
4046
4088
|
continue;
|
|
4047
4089
|
}
|
|
4048
4090
|
const data = fs2.readFileSync(absFilepath);
|
|
4049
4091
|
if (isBinary(null, data)) {
|
|
4050
|
-
|
|
4092
|
+
debug6("ignoring %s because is seems to be a binary file", filepath);
|
|
4051
4093
|
continue;
|
|
4052
4094
|
}
|
|
4053
4095
|
zip.addFile(filepath.toString(), data);
|
|
4054
4096
|
}
|
|
4055
|
-
|
|
4097
|
+
debug6("get zip file buffer");
|
|
4056
4098
|
return zip.toBuffer();
|
|
4057
4099
|
}
|
|
4058
4100
|
|
|
@@ -4127,7 +4169,7 @@ var cxOperatingSystemSupportMessage = `Your operating system does not support ch
|
|
|
4127
4169
|
|
|
4128
4170
|
// src/utils/child_process.ts
|
|
4129
4171
|
import cp from "node:child_process";
|
|
4130
|
-
import
|
|
4172
|
+
import Debug7 from "debug";
|
|
4131
4173
|
import * as process2 from "process";
|
|
4132
4174
|
import supportsColor from "supports-color";
|
|
4133
4175
|
var { stdout: stdout2 } = supportsColor;
|
|
@@ -4146,16 +4188,16 @@ function createSpwan({ args, processPath, name }, options) {
|
|
|
4146
4188
|
return createChildProcess({ childProcess: child, name }, options);
|
|
4147
4189
|
}
|
|
4148
4190
|
function createChildProcess({ childProcess, name }, options) {
|
|
4149
|
-
const
|
|
4191
|
+
const debug11 = Debug7(`mobbdev:${name}`);
|
|
4150
4192
|
const { display } = options;
|
|
4151
4193
|
return new Promise((resolve, reject) => {
|
|
4152
4194
|
let out = "";
|
|
4153
4195
|
const onData = (chunk) => {
|
|
4154
|
-
|
|
4196
|
+
debug11(`chunk received from ${name} std ${chunk}`);
|
|
4155
4197
|
out += chunk;
|
|
4156
4198
|
};
|
|
4157
4199
|
if (!childProcess || !childProcess?.stdout || !childProcess?.stderr) {
|
|
4158
|
-
|
|
4200
|
+
debug11(`unable to fork ${name}`);
|
|
4159
4201
|
reject(new Error(`unable to fork ${name}`));
|
|
4160
4202
|
}
|
|
4161
4203
|
childProcess.stdout?.on("data", onData);
|
|
@@ -4165,11 +4207,11 @@ function createChildProcess({ childProcess, name }, options) {
|
|
|
4165
4207
|
childProcess.stderr?.pipe(process2.stderr);
|
|
4166
4208
|
}
|
|
4167
4209
|
childProcess.on("exit", (code) => {
|
|
4168
|
-
|
|
4210
|
+
debug11(`${name} exit code ${code}`);
|
|
4169
4211
|
resolve({ message: out, code });
|
|
4170
4212
|
});
|
|
4171
4213
|
childProcess.on("error", (err) => {
|
|
4172
|
-
|
|
4214
|
+
debug11(`${name} error %o`, err);
|
|
4173
4215
|
reject(err);
|
|
4174
4216
|
});
|
|
4175
4217
|
});
|
|
@@ -4177,12 +4219,12 @@ function createChildProcess({ childProcess, name }, options) {
|
|
|
4177
4219
|
|
|
4178
4220
|
// src/features/analysis/scanners/checkmarx.ts
|
|
4179
4221
|
import chalk2 from "chalk";
|
|
4180
|
-
import
|
|
4222
|
+
import Debug8 from "debug";
|
|
4181
4223
|
import { existsSync } from "fs";
|
|
4182
4224
|
import { createSpinner as createSpinner2 } from "nanospinner";
|
|
4183
4225
|
import { type } from "os";
|
|
4184
4226
|
import path5 from "path";
|
|
4185
|
-
var
|
|
4227
|
+
var debug7 = Debug8("mobbdev:checkmarx");
|
|
4186
4228
|
var require2 = createRequire(import.meta.url);
|
|
4187
4229
|
var getCheckmarxPath = () => {
|
|
4188
4230
|
const os3 = type();
|
|
@@ -4223,14 +4265,14 @@ function validateCheckmarxInstallation() {
|
|
|
4223
4265
|
existsSync(getCheckmarxPath());
|
|
4224
4266
|
}
|
|
4225
4267
|
async function forkCheckmarx(args, { display }) {
|
|
4226
|
-
|
|
4268
|
+
debug7("fork checkmarx with args %o %s", args.join(" "), display);
|
|
4227
4269
|
return createSpwan(
|
|
4228
4270
|
{ args, processPath: getCheckmarxPath(), name: "checkmarx" },
|
|
4229
4271
|
{ display }
|
|
4230
4272
|
);
|
|
4231
4273
|
}
|
|
4232
4274
|
async function getCheckmarxReport({ reportPath, repositoryRoot, branch, projectName }, { skipPrompts = false }) {
|
|
4233
|
-
|
|
4275
|
+
debug7("get checkmarx report start %s %s", reportPath, repositoryRoot);
|
|
4234
4276
|
const { code: loginCode } = await forkCheckmarx(VALIDATE_COMMAND, {
|
|
4235
4277
|
display: false
|
|
4236
4278
|
});
|
|
@@ -4298,23 +4340,23 @@ async function validateCheckamxCredentials() {
|
|
|
4298
4340
|
// src/features/analysis/scanners/snyk.ts
|
|
4299
4341
|
import { createRequire as createRequire2 } from "node:module";
|
|
4300
4342
|
import chalk3 from "chalk";
|
|
4301
|
-
import
|
|
4343
|
+
import Debug9 from "debug";
|
|
4302
4344
|
import { createSpinner as createSpinner3 } from "nanospinner";
|
|
4303
4345
|
import open from "open";
|
|
4304
|
-
var
|
|
4346
|
+
var debug8 = Debug9("mobbdev:snyk");
|
|
4305
4347
|
var require3 = createRequire2(import.meta.url);
|
|
4306
4348
|
var SNYK_PATH = require3.resolve("snyk/bin/snyk");
|
|
4307
4349
|
var SNYK_ARTICLE_URL = "https://docs.snyk.io/scan-application-code/snyk-code/getting-started-with-snyk-code/activating-snyk-code-using-the-web-ui/step-1-enabling-the-snyk-code-option";
|
|
4308
|
-
|
|
4350
|
+
debug8("snyk executable path %s", SNYK_PATH);
|
|
4309
4351
|
async function forkSnyk(args, { display }) {
|
|
4310
|
-
|
|
4352
|
+
debug8("fork snyk with args %o %s", args, display);
|
|
4311
4353
|
return createFork(
|
|
4312
4354
|
{ args, processPath: SNYK_PATH, name: "checkmarx" },
|
|
4313
4355
|
{ display }
|
|
4314
4356
|
);
|
|
4315
4357
|
}
|
|
4316
4358
|
async function getSnykReport(reportPath, repoRoot, { skipPrompts = false }) {
|
|
4317
|
-
|
|
4359
|
+
debug8("get snyk report start %s %s", reportPath, repoRoot);
|
|
4318
4360
|
const config4 = await forkSnyk(["config"], { display: false });
|
|
4319
4361
|
const { message: configMessage } = config4;
|
|
4320
4362
|
if (!configMessage.includes("api: ")) {
|
|
@@ -4328,7 +4370,7 @@ async function getSnykReport(reportPath, repoRoot, { skipPrompts = false }) {
|
|
|
4328
4370
|
snykLoginSpinner.update({
|
|
4329
4371
|
text: "\u{1F513} Waiting for Snyk login to complete"
|
|
4330
4372
|
});
|
|
4331
|
-
|
|
4373
|
+
debug8("no token in the config %s", config4);
|
|
4332
4374
|
await forkSnyk(["auth"], { display: true });
|
|
4333
4375
|
snykLoginSpinner.success({ text: "\u{1F513} Login to Snyk Successful" });
|
|
4334
4376
|
}
|
|
@@ -4340,12 +4382,12 @@ async function getSnykReport(reportPath, repoRoot, { skipPrompts = false }) {
|
|
|
4340
4382
|
if (scanOutput.includes(
|
|
4341
4383
|
"Snyk Code is not supported for org: enable in Settings > Snyk Code"
|
|
4342
4384
|
)) {
|
|
4343
|
-
|
|
4385
|
+
debug8("snyk code is not enabled %s", scanOutput);
|
|
4344
4386
|
snykSpinner.error({ text: "\u{1F50D} Snyk configuration needed" });
|
|
4345
4387
|
const answer = await snykArticlePrompt();
|
|
4346
|
-
|
|
4388
|
+
debug8("answer %s", answer);
|
|
4347
4389
|
if (answer) {
|
|
4348
|
-
|
|
4390
|
+
debug8("opening the browser");
|
|
4349
4391
|
await open(SNYK_ARTICLE_URL);
|
|
4350
4392
|
}
|
|
4351
4393
|
console.log(
|
|
@@ -4360,18 +4402,18 @@ async function getSnykReport(reportPath, repoRoot, { skipPrompts = false }) {
|
|
|
4360
4402
|
}
|
|
4361
4403
|
|
|
4362
4404
|
// src/features/analysis/upload-file.ts
|
|
4363
|
-
import
|
|
4405
|
+
import Debug10 from "debug";
|
|
4364
4406
|
import fetch2, { File, fileFrom, FormData } from "node-fetch";
|
|
4365
|
-
var
|
|
4407
|
+
var debug9 = Debug10("mobbdev:upload-file");
|
|
4366
4408
|
async function uploadFile({
|
|
4367
4409
|
file,
|
|
4368
4410
|
url,
|
|
4369
4411
|
uploadKey,
|
|
4370
4412
|
uploadFields
|
|
4371
4413
|
}) {
|
|
4372
|
-
|
|
4373
|
-
|
|
4374
|
-
|
|
4414
|
+
debug9("upload file start %s", url);
|
|
4415
|
+
debug9("upload fields %o", uploadFields);
|
|
4416
|
+
debug9("upload key %s", uploadKey);
|
|
4375
4417
|
const form = new FormData();
|
|
4376
4418
|
Object.entries(uploadFields).forEach(([key, value]) => {
|
|
4377
4419
|
form.append(key, value);
|
|
@@ -4380,10 +4422,10 @@ async function uploadFile({
|
|
|
4380
4422
|
form.append("key", uploadKey);
|
|
4381
4423
|
}
|
|
4382
4424
|
if (typeof file === "string") {
|
|
4383
|
-
|
|
4425
|
+
debug9("upload file from path %s", file);
|
|
4384
4426
|
form.append("file", await fileFrom(file));
|
|
4385
4427
|
} else {
|
|
4386
|
-
|
|
4428
|
+
debug9("upload file from buffer");
|
|
4387
4429
|
form.append("file", new File([file], "file"));
|
|
4388
4430
|
}
|
|
4389
4431
|
const response = await fetch2(url, {
|
|
@@ -4391,10 +4433,10 @@ async function uploadFile({
|
|
|
4391
4433
|
body: form
|
|
4392
4434
|
});
|
|
4393
4435
|
if (!response.ok) {
|
|
4394
|
-
|
|
4436
|
+
debug9("error from S3 %s %s", response.body, response.status);
|
|
4395
4437
|
throw new Error(`Failed to upload the file: ${response.status}`);
|
|
4396
4438
|
}
|
|
4397
|
-
|
|
4439
|
+
debug9("upload file done");
|
|
4398
4440
|
}
|
|
4399
4441
|
|
|
4400
4442
|
// src/features/analysis/index.ts
|
|
@@ -4409,9 +4451,9 @@ async function downloadRepo({
|
|
|
4409
4451
|
}) {
|
|
4410
4452
|
const { createSpinner: createSpinner4 } = Spinner2({ ci });
|
|
4411
4453
|
const repoSpinner = createSpinner4("\u{1F4BE} Downloading Repo").start();
|
|
4412
|
-
|
|
4454
|
+
debug10("download repo %s %s %s", repoUrl, dirname);
|
|
4413
4455
|
const zipFilePath = path6.join(dirname, "repo.zip");
|
|
4414
|
-
|
|
4456
|
+
debug10("download URL: %s auth headers: %o", downloadUrl, authHeaders);
|
|
4415
4457
|
const response = await fetch3(downloadUrl, {
|
|
4416
4458
|
method: "GET",
|
|
4417
4459
|
headers: {
|
|
@@ -4419,7 +4461,7 @@ async function downloadRepo({
|
|
|
4419
4461
|
}
|
|
4420
4462
|
});
|
|
4421
4463
|
if (!response.ok) {
|
|
4422
|
-
|
|
4464
|
+
debug10("SCM zipball request failed %s %s", response.body, response.status);
|
|
4423
4465
|
repoSpinner.error({ text: "\u{1F4BE} Repo download failed" });
|
|
4424
4466
|
throw new Error(`Can't access ${chalk4.bold(repoUrl)}`);
|
|
4425
4467
|
}
|
|
@@ -4433,7 +4475,7 @@ async function downloadRepo({
|
|
|
4433
4475
|
if (!repoRoot) {
|
|
4434
4476
|
throw new Error("Repo root not found");
|
|
4435
4477
|
}
|
|
4436
|
-
|
|
4478
|
+
debug10("repo root %s", repoRoot);
|
|
4437
4479
|
repoSpinner.success({ text: "\u{1F4BE} Repo downloaded successfully" });
|
|
4438
4480
|
return path6.join(dirname, repoRoot);
|
|
4439
4481
|
}
|
|
@@ -4450,7 +4492,7 @@ var getReportUrl = ({
|
|
|
4450
4492
|
projectId,
|
|
4451
4493
|
fixReportId
|
|
4452
4494
|
}) => `${WEB_APP_URL}/organization/${organizationId}/project/${projectId}/report/${fixReportId}`;
|
|
4453
|
-
var
|
|
4495
|
+
var debug10 = Debug11("mobbdev:index");
|
|
4454
4496
|
var packageJson = JSON.parse(
|
|
4455
4497
|
fs3.readFileSync(path6.join(getDirName2(), "../package.json"), "utf8")
|
|
4456
4498
|
);
|
|
@@ -4460,7 +4502,7 @@ if (!semver.satisfies(process.version, packageJson.engines.node)) {
|
|
|
4460
4502
|
);
|
|
4461
4503
|
}
|
|
4462
4504
|
var config2 = new Configstore(packageJson.name, { apiToken: "" });
|
|
4463
|
-
|
|
4505
|
+
debug10("config %o", config2);
|
|
4464
4506
|
async function runAnalysis(params, options) {
|
|
4465
4507
|
try {
|
|
4466
4508
|
await _scan(
|
|
@@ -4516,7 +4558,7 @@ async function _scan(params, { skipPrompts = false } = {}) {
|
|
|
4516
4558
|
githubToken: githubActionToken,
|
|
4517
4559
|
command
|
|
4518
4560
|
} = params;
|
|
4519
|
-
|
|
4561
|
+
debug10("start %s %s", dirname, repo);
|
|
4520
4562
|
const { createSpinner: createSpinner4 } = Spinner2({ ci });
|
|
4521
4563
|
skipPrompts = skipPrompts || ci;
|
|
4522
4564
|
let gqlClient = new GQLClient({
|
|
@@ -4581,9 +4623,9 @@ async function _scan(params, { skipPrompts = false } = {}) {
|
|
|
4581
4623
|
});
|
|
4582
4624
|
const reference = ref ?? await scm.getRepoDefaultBranch();
|
|
4583
4625
|
const { sha } = await scm.getReferenceData(reference);
|
|
4584
|
-
|
|
4585
|
-
|
|
4586
|
-
|
|
4626
|
+
debug10("org id %s", organizationId);
|
|
4627
|
+
debug10("project id %s", projectId);
|
|
4628
|
+
debug10("default branch %s", reference);
|
|
4587
4629
|
const repositoryRoot = await downloadRepo({
|
|
4588
4630
|
repoUrl: repo,
|
|
4589
4631
|
dirname,
|
|
@@ -4611,44 +4653,39 @@ async function _scan(params, { skipPrompts = false } = {}) {
|
|
|
4611
4653
|
}
|
|
4612
4654
|
uploadReportSpinner.success({ text: "\u{1F4C1} Report uploaded successfully" });
|
|
4613
4655
|
const mobbSpinner = createSpinner4("\u{1F575}\uFE0F\u200D\u2642\uFE0F Initiating Mobb analysis").start();
|
|
4614
|
-
const sendReportRes = await sendReport(
|
|
4656
|
+
const sendReportRes = await sendReport({
|
|
4657
|
+
gqlClient,
|
|
4658
|
+
spinner: mobbSpinner,
|
|
4659
|
+
submitVulnerabilityReportVariables: {
|
|
4660
|
+
fixReportId: reportUploadInfo.fixReportId,
|
|
4661
|
+
repoUrl: z11.string().parse(repo),
|
|
4662
|
+
reference,
|
|
4663
|
+
projectId,
|
|
4664
|
+
vulnerabilityReportFileName: "report.json",
|
|
4665
|
+
sha,
|
|
4666
|
+
experimentalEnabled,
|
|
4667
|
+
pullRequest: params.pullRequest
|
|
4668
|
+
}
|
|
4669
|
+
});
|
|
4615
4670
|
if (command === "review") {
|
|
4616
|
-
await gqlClient.subscribeToAnalysis(
|
|
4617
|
-
|
|
4618
|
-
|
|
4671
|
+
await gqlClient.subscribeToAnalysis({
|
|
4672
|
+
subscribeToAnalysisParams: {
|
|
4673
|
+
analysisId: sendReportRes.submitVulnerabilityReport.fixReportId
|
|
4674
|
+
},
|
|
4675
|
+
callback: (analysisId) => handleFinishedAnalysis({
|
|
4619
4676
|
analysisId,
|
|
4620
4677
|
gqlClient,
|
|
4621
4678
|
scm,
|
|
4622
4679
|
githubActionToken: z11.string().parse(githubActionToken),
|
|
4623
4680
|
scanner: z11.nativeEnum(SCANNERS).parse(scanner)
|
|
4624
|
-
})
|
|
4625
|
-
|
|
4681
|
+
}),
|
|
4682
|
+
callbackStates: ["Finished"]
|
|
4683
|
+
});
|
|
4626
4684
|
}
|
|
4627
4685
|
mobbSpinner.success({
|
|
4628
4686
|
text: "\u{1F575}\uFE0F\u200D\u2642\uFE0F Generating fixes..."
|
|
4629
4687
|
});
|
|
4630
4688
|
await askToOpenAnalysis();
|
|
4631
|
-
async function sendReport() {
|
|
4632
|
-
try {
|
|
4633
|
-
const sumbitRes = await gqlClient.submitVulnerabilityReport({
|
|
4634
|
-
fixReportId: reportUploadInfo.fixReportId,
|
|
4635
|
-
repoUrl: z11.string().parse(repo),
|
|
4636
|
-
reference,
|
|
4637
|
-
projectId,
|
|
4638
|
-
vulnerabilityReportFileName: "report.json",
|
|
4639
|
-
sha,
|
|
4640
|
-
experimentalEnabled,
|
|
4641
|
-
pullRequest: params.pullRequest
|
|
4642
|
-
});
|
|
4643
|
-
if (sumbitRes.submitVulnerabilityReport.__typename !== "VulnerabilityReport") {
|
|
4644
|
-
throw new Error("\u{1F575}\uFE0F\u200D\u2642\uFE0F Mobb analysis failed");
|
|
4645
|
-
}
|
|
4646
|
-
return sumbitRes;
|
|
4647
|
-
} catch (e) {
|
|
4648
|
-
mobbSpinner.error({ text: "\u{1F575}\uFE0F\u200D\u2642\uFE0F Mobb analysis failed" });
|
|
4649
|
-
throw e;
|
|
4650
|
-
}
|
|
4651
|
-
}
|
|
4652
4689
|
async function getReport(scanner2) {
|
|
4653
4690
|
const reportPath2 = path6.join(dirname, "report.json");
|
|
4654
4691
|
switch (scanner2) {
|
|
@@ -4724,9 +4761,9 @@ async function _scan(params, { skipPrompts = false } = {}) {
|
|
|
4724
4761
|
});
|
|
4725
4762
|
loginSpinner.spin();
|
|
4726
4763
|
if (encryptedApiToken) {
|
|
4727
|
-
|
|
4764
|
+
debug10("encrypted API token received %s", encryptedApiToken);
|
|
4728
4765
|
newApiToken = crypto.privateDecrypt(privateKey, Buffer.from(encryptedApiToken, "base64")).toString("utf-8");
|
|
4729
|
-
|
|
4766
|
+
debug10("API token decrypted");
|
|
4730
4767
|
break;
|
|
4731
4768
|
}
|
|
4732
4769
|
await sleep(LOGIN_CHECK_DELAY);
|
|
@@ -4739,7 +4776,7 @@ async function _scan(params, { skipPrompts = false } = {}) {
|
|
|
4739
4776
|
}
|
|
4740
4777
|
gqlClient = new GQLClient({ apiKey: newApiToken });
|
|
4741
4778
|
if (await gqlClient.verifyToken()) {
|
|
4742
|
-
|
|
4779
|
+
debug10("set api token %s", newApiToken);
|
|
4743
4780
|
config2.set("apiToken", newApiToken);
|
|
4744
4781
|
loginSpinner.success({ text: "\u{1F513} Login to Mobb successful!" });
|
|
4745
4782
|
} else {
|
|
@@ -4802,7 +4839,9 @@ async function _scan(params, { skipPrompts = false } = {}) {
|
|
|
4802
4839
|
uploadReportSpinner2.success({
|
|
4803
4840
|
text: "\u{1F4C1} Uploading Report successful!"
|
|
4804
4841
|
});
|
|
4805
|
-
const digestSpinner = createSpinner4(
|
|
4842
|
+
const digestSpinner = createSpinner4(
|
|
4843
|
+
progressMassages.processingVulnerabilityReport
|
|
4844
|
+
).start();
|
|
4806
4845
|
let vulnFiles = [];
|
|
4807
4846
|
const gitInfo = await getGitInfo(srcPath);
|
|
4808
4847
|
try {
|
|
@@ -4810,12 +4849,19 @@ async function _scan(params, { skipPrompts = false } = {}) {
|
|
|
4810
4849
|
fixReportId: reportUploadInfo.fixReportId,
|
|
4811
4850
|
projectId
|
|
4812
4851
|
});
|
|
4813
|
-
|
|
4814
|
-
|
|
4815
|
-
|
|
4816
|
-
|
|
4817
|
-
|
|
4818
|
-
|
|
4852
|
+
try {
|
|
4853
|
+
await gqlClient.subscribeToAnalysis({
|
|
4854
|
+
subscribeToAnalysisParams: {
|
|
4855
|
+
analysisId: reportUploadInfo.fixReportId
|
|
4856
|
+
},
|
|
4857
|
+
callback: () => digestSpinner.update({
|
|
4858
|
+
text: progressMassages.processingVulnerabilityReportSuccess
|
|
4859
|
+
}),
|
|
4860
|
+
callbackStates: ["Digested", "Finished"],
|
|
4861
|
+
timeoutInMs: VUL_REPORT_DIGEST_TIMEOUT_MS
|
|
4862
|
+
});
|
|
4863
|
+
} catch (e) {
|
|
4864
|
+
throw new Error(progressMassages.processingVulnerabilityReportFailed);
|
|
4819
4865
|
}
|
|
4820
4866
|
vulnFiles = await gqlClient.getVulnerabilityReportPaths(
|
|
4821
4867
|
vulnerabilityReportId
|
|
@@ -4825,7 +4871,7 @@ async function _scan(params, { skipPrompts = false } = {}) {
|
|
|
4825
4871
|
throw e;
|
|
4826
4872
|
}
|
|
4827
4873
|
digestSpinner.success({
|
|
4828
|
-
text:
|
|
4874
|
+
text: progressMassages.processingVulnerabilityReportSuccess
|
|
4829
4875
|
});
|
|
4830
4876
|
const zippingSpinner = createSpinner4("\u{1F4E6} Zipping repo").start();
|
|
4831
4877
|
const zipBuffer = await pack(srcPath, vulnFiles);
|
|
@@ -4845,12 +4891,16 @@ async function _scan(params, { skipPrompts = false } = {}) {
|
|
|
4845
4891
|
uploadRepoSpinner.success({ text: "\u{1F4C1} Uploading Repo successful!" });
|
|
4846
4892
|
const mobbSpinner2 = createSpinner4("\u{1F575}\uFE0F\u200D\u2642\uFE0F Initiating Mobb analysis").start();
|
|
4847
4893
|
try {
|
|
4848
|
-
await
|
|
4849
|
-
|
|
4850
|
-
|
|
4851
|
-
|
|
4852
|
-
|
|
4853
|
-
|
|
4894
|
+
await sendReport({
|
|
4895
|
+
gqlClient,
|
|
4896
|
+
spinner: mobbSpinner2,
|
|
4897
|
+
submitVulnerabilityReportVariables: {
|
|
4898
|
+
fixReportId: reportUploadInfo.fixReportId,
|
|
4899
|
+
projectId,
|
|
4900
|
+
repoUrl: repo || gitInfo.repoUrl || getTopLevelDirName(srcPath),
|
|
4901
|
+
reference: gitInfo.reference || "no-branch",
|
|
4902
|
+
sha: commitHash || gitInfo.hash || "0123456789abcdef"
|
|
4903
|
+
}
|
|
4854
4904
|
});
|
|
4855
4905
|
} catch (e) {
|
|
4856
4906
|
mobbSpinner2.error({ text: "\u{1F575}\uFE0F\u200D\u2642\uFE0F Mobb analysis failed" });
|