mobbdev 0.0.90 → 0.0.93
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 +296 -193
- 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";
|
|
@@ -118,6 +124,7 @@ __export(utils_exports, {
|
|
|
118
124
|
CliError: () => CliError,
|
|
119
125
|
Spinner: () => Spinner,
|
|
120
126
|
getDirName: () => getDirName,
|
|
127
|
+
getTopLevelDirName: () => getTopLevelDirName,
|
|
121
128
|
keypress: () => keypress,
|
|
122
129
|
sleep: () => sleep
|
|
123
130
|
});
|
|
@@ -128,6 +135,9 @@ import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
|
128
135
|
function getDirName() {
|
|
129
136
|
return path2.dirname(fileURLToPath2(import.meta.url));
|
|
130
137
|
}
|
|
138
|
+
function getTopLevelDirName(fullPath) {
|
|
139
|
+
return path2.parse(fullPath).name;
|
|
140
|
+
}
|
|
131
141
|
|
|
132
142
|
// src/utils/keypress.ts
|
|
133
143
|
import readline from "node:readline";
|
|
@@ -175,18 +185,19 @@ var CliError = class extends Error {
|
|
|
175
185
|
// src/features/analysis/index.ts
|
|
176
186
|
import chalk4 from "chalk";
|
|
177
187
|
import Configstore from "configstore";
|
|
178
|
-
import
|
|
188
|
+
import Debug11 from "debug";
|
|
179
189
|
import extract from "extract-zip";
|
|
180
190
|
import fetch3 from "node-fetch";
|
|
181
191
|
import open2 from "open";
|
|
182
192
|
import semver from "semver";
|
|
183
193
|
import tmp2 from "tmp";
|
|
184
|
-
import { z as
|
|
194
|
+
import { z as z11 } from "zod";
|
|
185
195
|
|
|
186
196
|
// src/features/analysis/git.ts
|
|
187
197
|
import Debug2 from "debug";
|
|
188
198
|
import { simpleGit } from "simple-git";
|
|
189
199
|
var debug2 = Debug2("mobbdev:git");
|
|
200
|
+
var GIT_NOT_INITIALIZED_ERROR_MESSAGE = "not a git repository";
|
|
190
201
|
async function getGitInfo(srcDirPath) {
|
|
191
202
|
debug2("getting git info for %s", srcDirPath);
|
|
192
203
|
const git = simpleGit({
|
|
@@ -206,8 +217,14 @@ async function getGitInfo(srcDirPath) {
|
|
|
206
217
|
debug2("failed to run git %o", e);
|
|
207
218
|
if (e.message.includes(" spawn ")) {
|
|
208
219
|
debug2("git cli not installed");
|
|
209
|
-
} else if (e.message.includes(
|
|
220
|
+
} else if (e.message.includes(GIT_NOT_INITIALIZED_ERROR_MESSAGE)) {
|
|
210
221
|
debug2("folder is not a git repo");
|
|
222
|
+
return {
|
|
223
|
+
success: false,
|
|
224
|
+
hash: void 0,
|
|
225
|
+
reference: void 0,
|
|
226
|
+
repoUrl: void 0
|
|
227
|
+
};
|
|
211
228
|
} else {
|
|
212
229
|
throw e;
|
|
213
230
|
}
|
|
@@ -221,6 +238,7 @@ async function getGitInfo(srcDirPath) {
|
|
|
221
238
|
repoUrl = repoUrl.replace("git@github.com:", "https://github.com/");
|
|
222
239
|
}
|
|
223
240
|
return {
|
|
241
|
+
success: true,
|
|
224
242
|
repoUrl,
|
|
225
243
|
hash,
|
|
226
244
|
reference
|
|
@@ -551,7 +569,7 @@ var GET_VUL_BY_NODES_METADATA = gql2`
|
|
|
551
569
|
// src/features/analysis/graphql/subscirbe.ts
|
|
552
570
|
import { createClient } from "graphql-ws";
|
|
553
571
|
import WebSocket from "ws";
|
|
554
|
-
var SUBSCRIPTION_TIMEOUT_MS =
|
|
572
|
+
var SUBSCRIPTION_TIMEOUT_MS = 10 * 60 * 1e3;
|
|
555
573
|
function createWSClient(options) {
|
|
556
574
|
return createClient({
|
|
557
575
|
url: options.url,
|
|
@@ -1032,22 +1050,24 @@ var GQLClient = class {
|
|
|
1032
1050
|
res
|
|
1033
1051
|
).vulnerability_report_path.map((p) => p.path);
|
|
1034
1052
|
}
|
|
1035
|
-
async subscribeToAnalysis(params
|
|
1053
|
+
async subscribeToAnalysis(params) {
|
|
1054
|
+
const { callbackStates } = params;
|
|
1036
1055
|
return subscribe(
|
|
1037
1056
|
SUBSCRIBE_TO_ANALYSIS,
|
|
1038
|
-
params,
|
|
1057
|
+
params.subscribeToAnalysisParams,
|
|
1039
1058
|
async (resolve, reject, data) => {
|
|
1040
1059
|
if (data.analysis.state === "Failed") {
|
|
1041
1060
|
reject(data);
|
|
1042
1061
|
throw new Error(`Analysis failed with id: ${data.analysis.id}`);
|
|
1043
1062
|
}
|
|
1044
|
-
if (data.analysis?.state
|
|
1045
|
-
await callback(data.analysis.id);
|
|
1063
|
+
if (callbackStates.includes(data.analysis?.state)) {
|
|
1064
|
+
await params.callback(data.analysis.id);
|
|
1046
1065
|
resolve(data);
|
|
1047
1066
|
}
|
|
1048
1067
|
},
|
|
1049
1068
|
{
|
|
1050
|
-
apiKey: this._apiKey
|
|
1069
|
+
apiKey: this._apiKey,
|
|
1070
|
+
timeoutInMs: params.timeoutInMs
|
|
1051
1071
|
}
|
|
1052
1072
|
);
|
|
1053
1073
|
}
|
|
@@ -1079,18 +1099,18 @@ var GQLClient = class {
|
|
|
1079
1099
|
|
|
1080
1100
|
// src/features/analysis/handle_finished_analysis.ts
|
|
1081
1101
|
import { Octokit as Octokit3 } from "@octokit/core";
|
|
1082
|
-
import
|
|
1102
|
+
import Debug5 from "debug";
|
|
1083
1103
|
import parseDiff from "parse-diff";
|
|
1084
|
-
import { z as
|
|
1104
|
+
import { z as z10 } from "zod";
|
|
1085
1105
|
|
|
1086
1106
|
// src/features/analysis/scm/ado.ts
|
|
1087
1107
|
import querystring2 from "node:querystring";
|
|
1088
1108
|
import * as api from "azure-devops-node-api";
|
|
1089
|
-
import { z as
|
|
1109
|
+
import { z as z9 } from "zod";
|
|
1090
1110
|
|
|
1091
1111
|
// src/features/analysis/scm/scm.ts
|
|
1092
1112
|
import { Octokit as Octokit2 } from "@octokit/core";
|
|
1093
|
-
import { z as
|
|
1113
|
+
import { z as z8 } from "zod";
|
|
1094
1114
|
|
|
1095
1115
|
// src/features/analysis/scm/github/encryptSecret.ts
|
|
1096
1116
|
import sodium from "libsodium-wrappers";
|
|
@@ -1686,18 +1706,30 @@ function deleteGeneralPrComment(client, params) {
|
|
|
1686
1706
|
return client.request(DELETE_GENERAL_PR_COMMENT, params);
|
|
1687
1707
|
}
|
|
1688
1708
|
|
|
1689
|
-
// src/features/analysis/scm/gitlab.ts
|
|
1709
|
+
// src/features/analysis/scm/gitlab/gitlab.ts
|
|
1690
1710
|
import querystring from "node:querystring";
|
|
1691
|
-
import {
|
|
1711
|
+
import {
|
|
1712
|
+
Gitlab
|
|
1713
|
+
} from "@gitbeaker/rest";
|
|
1692
1714
|
import { ProxyAgent } from "undici";
|
|
1715
|
+
import { z as z5 } from "zod";
|
|
1716
|
+
|
|
1717
|
+
// src/features/analysis/scm/gitlab/types.ts
|
|
1693
1718
|
import { z as z4 } from "zod";
|
|
1719
|
+
var GitlabAuthResultZ = z4.object({
|
|
1720
|
+
access_token: z4.string(),
|
|
1721
|
+
token_type: z4.string(),
|
|
1722
|
+
refresh_token: z4.string()
|
|
1723
|
+
});
|
|
1724
|
+
|
|
1725
|
+
// src/features/analysis/scm/gitlab/gitlab.ts
|
|
1726
|
+
var EnvVariablesZod2 = z5.object({
|
|
1727
|
+
GITLAB_API_TOKEN: z5.string().optional()
|
|
1728
|
+
});
|
|
1729
|
+
var { GITLAB_API_TOKEN } = EnvVariablesZod2.parse(process.env);
|
|
1694
1730
|
function removeTrailingSlash2(str) {
|
|
1695
1731
|
return str.trim().replace(/\/+$/, "");
|
|
1696
1732
|
}
|
|
1697
|
-
var EnvVariablesZod2 = z4.object({
|
|
1698
|
-
GITLAB_API_TOKEN: z4.string().optional()
|
|
1699
|
-
});
|
|
1700
|
-
var { GITLAB_API_TOKEN } = EnvVariablesZod2.parse(process.env);
|
|
1701
1733
|
function getGitBeaker(options) {
|
|
1702
1734
|
const token = options?.gitlabAuthToken ?? GITLAB_API_TOKEN ?? "";
|
|
1703
1735
|
const url = options.url;
|
|
@@ -1850,6 +1882,18 @@ async function createMergeRequest(options) {
|
|
|
1850
1882
|
);
|
|
1851
1883
|
return res.iid;
|
|
1852
1884
|
}
|
|
1885
|
+
async function getGitlabMergeRequest({
|
|
1886
|
+
url,
|
|
1887
|
+
prNumber,
|
|
1888
|
+
accessToken
|
|
1889
|
+
}) {
|
|
1890
|
+
const { projectPath } = parseGitlabOwnerAndRepo(url);
|
|
1891
|
+
const api2 = getGitBeaker({
|
|
1892
|
+
url,
|
|
1893
|
+
gitlabAuthToken: accessToken
|
|
1894
|
+
});
|
|
1895
|
+
return await api2.MergeRequests.show(projectPath, prNumber);
|
|
1896
|
+
}
|
|
1853
1897
|
async function getGitlabRepoDefaultBranch(repoUrl, options) {
|
|
1854
1898
|
const api2 = getGitBeaker({
|
|
1855
1899
|
url: repoUrl,
|
|
@@ -1938,11 +1982,6 @@ async function getGitlabBlameRanges({ ref, gitlabUrl, path: path9 }, options) {
|
|
|
1938
1982
|
};
|
|
1939
1983
|
});
|
|
1940
1984
|
}
|
|
1941
|
-
var GitlabAuthResultZ = z4.object({
|
|
1942
|
-
access_token: z4.string(),
|
|
1943
|
-
token_type: z4.string(),
|
|
1944
|
-
refresh_token: z4.string()
|
|
1945
|
-
});
|
|
1946
1985
|
function initGitlabFetchMock() {
|
|
1947
1986
|
const globalFetch = global.fetch;
|
|
1948
1987
|
function myFetch(input, init) {
|
|
@@ -1968,77 +2007,77 @@ import os from "os";
|
|
|
1968
2007
|
import path3 from "path";
|
|
1969
2008
|
import { simpleGit as simpleGit2 } from "simple-git";
|
|
1970
2009
|
import tmp from "tmp";
|
|
1971
|
-
import { z as
|
|
2010
|
+
import { z as z7 } from "zod";
|
|
1972
2011
|
|
|
1973
2012
|
// src/features/analysis/scm/scmSubmit/types.ts
|
|
1974
|
-
import { z as
|
|
1975
|
-
var BaseSubmitToScmMessageZ =
|
|
1976
|
-
submitFixRequestId:
|
|
1977
|
-
fixes:
|
|
1978
|
-
|
|
1979
|
-
fixId:
|
|
1980
|
-
diff:
|
|
2013
|
+
import { z as z6 } from "zod";
|
|
2014
|
+
var BaseSubmitToScmMessageZ = z6.object({
|
|
2015
|
+
submitFixRequestId: z6.string().uuid(),
|
|
2016
|
+
fixes: z6.array(
|
|
2017
|
+
z6.object({
|
|
2018
|
+
fixId: z6.string().uuid(),
|
|
2019
|
+
diff: z6.string()
|
|
1981
2020
|
})
|
|
1982
2021
|
),
|
|
1983
|
-
commitHash:
|
|
1984
|
-
repoUrl:
|
|
2022
|
+
commitHash: z6.string(),
|
|
2023
|
+
repoUrl: z6.string()
|
|
1985
2024
|
});
|
|
1986
2025
|
var submitToScmMessageType = {
|
|
1987
2026
|
commitToSameBranch: "commitToSameBranch",
|
|
1988
2027
|
submitFixesForDifferentBranch: "submitFixesForDifferentBranch"
|
|
1989
2028
|
};
|
|
1990
2029
|
var CommitToSameBranchParamsZ = BaseSubmitToScmMessageZ.merge(
|
|
1991
|
-
|
|
1992
|
-
type:
|
|
1993
|
-
branch:
|
|
1994
|
-
commitMessage:
|
|
1995
|
-
commitDescription:
|
|
1996
|
-
githubCommentId:
|
|
2030
|
+
z6.object({
|
|
2031
|
+
type: z6.literal(submitToScmMessageType.commitToSameBranch),
|
|
2032
|
+
branch: z6.string(),
|
|
2033
|
+
commitMessage: z6.string(),
|
|
2034
|
+
commitDescription: z6.string().nullish(),
|
|
2035
|
+
githubCommentId: z6.number().nullish()
|
|
1997
2036
|
})
|
|
1998
2037
|
);
|
|
1999
|
-
var SubmitFixesToDifferentBranchParamsZ =
|
|
2000
|
-
type:
|
|
2001
|
-
submitBranch:
|
|
2002
|
-
baseBranch:
|
|
2038
|
+
var SubmitFixesToDifferentBranchParamsZ = z6.object({
|
|
2039
|
+
type: z6.literal(submitToScmMessageType.submitFixesForDifferentBranch),
|
|
2040
|
+
submitBranch: z6.string(),
|
|
2041
|
+
baseBranch: z6.string()
|
|
2003
2042
|
}).merge(BaseSubmitToScmMessageZ);
|
|
2004
|
-
var SubmitFixesMessageZ =
|
|
2043
|
+
var SubmitFixesMessageZ = z6.union([
|
|
2005
2044
|
CommitToSameBranchParamsZ,
|
|
2006
2045
|
SubmitFixesToDifferentBranchParamsZ
|
|
2007
2046
|
]);
|
|
2008
|
-
var FixResponseArrayZ =
|
|
2009
|
-
|
|
2010
|
-
fixId:
|
|
2047
|
+
var FixResponseArrayZ = z6.array(
|
|
2048
|
+
z6.object({
|
|
2049
|
+
fixId: z6.string().uuid()
|
|
2011
2050
|
})
|
|
2012
2051
|
);
|
|
2013
|
-
var SubmitFixesBaseResponseMessageZ =
|
|
2014
|
-
submitFixRequestId:
|
|
2015
|
-
submitBranches:
|
|
2016
|
-
|
|
2017
|
-
branchName:
|
|
2052
|
+
var SubmitFixesBaseResponseMessageZ = z6.object({
|
|
2053
|
+
submitFixRequestId: z6.string().uuid(),
|
|
2054
|
+
submitBranches: z6.array(
|
|
2055
|
+
z6.object({
|
|
2056
|
+
branchName: z6.string(),
|
|
2018
2057
|
fixes: FixResponseArrayZ
|
|
2019
2058
|
})
|
|
2020
2059
|
),
|
|
2021
|
-
error:
|
|
2022
|
-
type:
|
|
2060
|
+
error: z6.object({
|
|
2061
|
+
type: z6.enum([
|
|
2023
2062
|
"InitialRepoAccessError",
|
|
2024
2063
|
"PushBranchError",
|
|
2025
2064
|
"UnknownError"
|
|
2026
2065
|
]),
|
|
2027
|
-
info:
|
|
2028
|
-
message:
|
|
2029
|
-
pushBranchName:
|
|
2066
|
+
info: z6.object({
|
|
2067
|
+
message: z6.string(),
|
|
2068
|
+
pushBranchName: z6.string().optional()
|
|
2030
2069
|
})
|
|
2031
2070
|
}).optional()
|
|
2032
2071
|
});
|
|
2033
|
-
var SubmitFixesToSameBranchResponseMessageZ =
|
|
2034
|
-
type:
|
|
2035
|
-
githubCommentId:
|
|
2072
|
+
var SubmitFixesToSameBranchResponseMessageZ = z6.object({
|
|
2073
|
+
type: z6.literal(submitToScmMessageType.commitToSameBranch),
|
|
2074
|
+
githubCommentId: z6.number().nullish()
|
|
2036
2075
|
}).merge(SubmitFixesBaseResponseMessageZ);
|
|
2037
|
-
var SubmitFixesToDifferentBranchResponseMessageZ =
|
|
2038
|
-
type:
|
|
2039
|
-
githubCommentId:
|
|
2076
|
+
var SubmitFixesToDifferentBranchResponseMessageZ = z6.object({
|
|
2077
|
+
type: z6.literal(submitToScmMessageType.submitFixesForDifferentBranch),
|
|
2078
|
+
githubCommentId: z6.number().optional()
|
|
2040
2079
|
}).merge(SubmitFixesBaseResponseMessageZ);
|
|
2041
|
-
var SubmitFixesResponseMessageZ =
|
|
2080
|
+
var SubmitFixesResponseMessageZ = z6.discriminatedUnion("type", [
|
|
2042
2081
|
SubmitFixesToSameBranchResponseMessageZ,
|
|
2043
2082
|
SubmitFixesToDifferentBranchResponseMessageZ
|
|
2044
2083
|
]);
|
|
@@ -2056,7 +2095,7 @@ var isValidBranchName = async (branchName) => {
|
|
|
2056
2095
|
return false;
|
|
2057
2096
|
}
|
|
2058
2097
|
};
|
|
2059
|
-
var FixesZ =
|
|
2098
|
+
var FixesZ = z7.array(z7.object({ fixId: z7.string(), diff: z7.string() })).nonempty();
|
|
2060
2099
|
|
|
2061
2100
|
// src/features/analysis/scm/scm.ts
|
|
2062
2101
|
function getCloudScmLibTypeFromUrl(url) {
|
|
@@ -2276,6 +2315,14 @@ var SCMLib = class {
|
|
|
2276
2315
|
}
|
|
2277
2316
|
return new StubSCMLib(trimmedUrl, void 0, void 0);
|
|
2278
2317
|
}
|
|
2318
|
+
_validateAccessTokenAndUrl() {
|
|
2319
|
+
if (!this.accessToken) {
|
|
2320
|
+
throw new InvalidAccessTokenError("no access token");
|
|
2321
|
+
}
|
|
2322
|
+
if (!this.url) {
|
|
2323
|
+
throw new InvalidRepoUrlError("no url");
|
|
2324
|
+
}
|
|
2325
|
+
}
|
|
2279
2326
|
};
|
|
2280
2327
|
var AdoSCMLib = class extends SCMLib {
|
|
2281
2328
|
updatePrComment(_params, _oktokit) {
|
|
@@ -2442,8 +2489,9 @@ var AdoSCMLib = class extends SCMLib {
|
|
|
2442
2489
|
accessToken: this.accessToken
|
|
2443
2490
|
});
|
|
2444
2491
|
}
|
|
2445
|
-
|
|
2446
|
-
|
|
2492
|
+
getPrUrl(prNumber) {
|
|
2493
|
+
this._validateAccessTokenAndUrl();
|
|
2494
|
+
return Promise.resolve(getAdoPrUrl({ prNumber, url: this.url }));
|
|
2447
2495
|
}
|
|
2448
2496
|
postGeneralPrComment() {
|
|
2449
2497
|
throw new Error("Method not implemented.");
|
|
@@ -2628,8 +2676,14 @@ var GitlabSCMLib = class extends SCMLib {
|
|
|
2628
2676
|
updatePrComment(_params, _oktokit) {
|
|
2629
2677
|
throw new Error("updatePrComment not implemented.");
|
|
2630
2678
|
}
|
|
2631
|
-
|
|
2632
|
-
|
|
2679
|
+
async getPrUrl(prNumber) {
|
|
2680
|
+
this._validateAccessTokenAndUrl();
|
|
2681
|
+
const res = await getGitlabMergeRequest({
|
|
2682
|
+
url: this.url,
|
|
2683
|
+
prNumber,
|
|
2684
|
+
accessToken: this.accessToken
|
|
2685
|
+
});
|
|
2686
|
+
return res.web_url;
|
|
2633
2687
|
}
|
|
2634
2688
|
postGeneralPrComment() {
|
|
2635
2689
|
throw new Error("Method not implemented.");
|
|
@@ -2774,7 +2828,7 @@ var GithubSCMLib = class extends SCMLib {
|
|
|
2774
2828
|
owner,
|
|
2775
2829
|
repo
|
|
2776
2830
|
});
|
|
2777
|
-
return
|
|
2831
|
+
return z8.string().parse(prRes.data);
|
|
2778
2832
|
}
|
|
2779
2833
|
async getRepoList(_scmOrg) {
|
|
2780
2834
|
if (!this.accessToken) {
|
|
@@ -2896,17 +2950,18 @@ var GithubSCMLib = class extends SCMLib {
|
|
|
2896
2950
|
githubAuthToken: this.accessToken
|
|
2897
2951
|
});
|
|
2898
2952
|
}
|
|
2899
|
-
async
|
|
2953
|
+
async getPrUrl(prNumber) {
|
|
2900
2954
|
if (!this.url || !this.oktokit) {
|
|
2901
2955
|
console.error("no url");
|
|
2902
2956
|
throw new Error("no url");
|
|
2903
2957
|
}
|
|
2904
2958
|
const { owner, repo } = parseGithubOwnerAndRepo(this.url);
|
|
2905
|
-
|
|
2959
|
+
const getPrRes = await getPr(this.oktokit, {
|
|
2906
2960
|
owner,
|
|
2907
2961
|
repo,
|
|
2908
2962
|
pull_number: prNumber
|
|
2909
2963
|
});
|
|
2964
|
+
return getPrRes.data.html_url;
|
|
2910
2965
|
}
|
|
2911
2966
|
async postGeneralPrComment(params, auth) {
|
|
2912
2967
|
const { prNumber, body } = params;
|
|
@@ -3032,7 +3087,7 @@ var StubSCMLib = class extends SCMLib {
|
|
|
3032
3087
|
console.error("updatePrComment() not implemented");
|
|
3033
3088
|
throw new Error("updatePrComment() not implemented");
|
|
3034
3089
|
}
|
|
3035
|
-
async
|
|
3090
|
+
async getPrUrl(_prNumber) {
|
|
3036
3091
|
console.error("getPr() not implemented");
|
|
3037
3092
|
throw new Error("getPr() not implemented");
|
|
3038
3093
|
}
|
|
@@ -3052,22 +3107,22 @@ function removeTrailingSlash3(str) {
|
|
|
3052
3107
|
return str.trim().replace(/\/+$/, "");
|
|
3053
3108
|
}
|
|
3054
3109
|
async function _getOrgsForOauthToken({ oauthToken }) {
|
|
3055
|
-
const profileZ =
|
|
3056
|
-
displayName:
|
|
3057
|
-
publicAlias:
|
|
3058
|
-
emailAddress:
|
|
3059
|
-
coreRevision:
|
|
3060
|
-
timeStamp:
|
|
3061
|
-
id:
|
|
3062
|
-
revision:
|
|
3110
|
+
const profileZ = z9.object({
|
|
3111
|
+
displayName: z9.string(),
|
|
3112
|
+
publicAlias: z9.string().min(1),
|
|
3113
|
+
emailAddress: z9.string(),
|
|
3114
|
+
coreRevision: z9.number(),
|
|
3115
|
+
timeStamp: z9.string(),
|
|
3116
|
+
id: z9.string(),
|
|
3117
|
+
revision: z9.number()
|
|
3063
3118
|
});
|
|
3064
|
-
const accountsZ =
|
|
3065
|
-
count:
|
|
3066
|
-
value:
|
|
3067
|
-
|
|
3068
|
-
accountId:
|
|
3069
|
-
accountUri:
|
|
3070
|
-
accountName:
|
|
3119
|
+
const accountsZ = z9.object({
|
|
3120
|
+
count: z9.number(),
|
|
3121
|
+
value: z9.array(
|
|
3122
|
+
z9.object({
|
|
3123
|
+
accountId: z9.string(),
|
|
3124
|
+
accountUri: z9.string(),
|
|
3125
|
+
accountName: z9.string()
|
|
3071
3126
|
})
|
|
3072
3127
|
)
|
|
3073
3128
|
});
|
|
@@ -3298,6 +3353,12 @@ async function getAdoRepoList({
|
|
|
3298
3353
|
}, []);
|
|
3299
3354
|
return repos;
|
|
3300
3355
|
}
|
|
3356
|
+
function getAdoPrUrl({
|
|
3357
|
+
url,
|
|
3358
|
+
prNumber
|
|
3359
|
+
}) {
|
|
3360
|
+
return `${url}/pullrequest/${prNumber}`;
|
|
3361
|
+
}
|
|
3301
3362
|
function getAdoDownloadUrl({
|
|
3302
3363
|
repoUrl,
|
|
3303
3364
|
branch
|
|
@@ -3491,10 +3552,10 @@ function parseAdoOwnerAndRepo(adoUrl) {
|
|
|
3491
3552
|
async function getAdoBlameRanges() {
|
|
3492
3553
|
return [];
|
|
3493
3554
|
}
|
|
3494
|
-
var AdoAuthResultZ =
|
|
3495
|
-
access_token:
|
|
3496
|
-
token_type:
|
|
3497
|
-
refresh_token:
|
|
3555
|
+
var AdoAuthResultZ = z9.object({
|
|
3556
|
+
access_token: z9.string().min(1),
|
|
3557
|
+
token_type: z9.string().min(1),
|
|
3558
|
+
refresh_token: z9.string().min(1)
|
|
3498
3559
|
});
|
|
3499
3560
|
|
|
3500
3561
|
// src/features/analysis/scm/constants.ts
|
|
@@ -3647,8 +3708,42 @@ function calculateRanges(integers) {
|
|
|
3647
3708
|
return ranges;
|
|
3648
3709
|
}
|
|
3649
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
|
+
|
|
3650
3745
|
// src/features/analysis/handle_finished_analysis.ts
|
|
3651
|
-
var
|
|
3746
|
+
var debug5 = Debug5("mobbdev:handle-finished-analysis");
|
|
3652
3747
|
var contactUsMarkdown = `For specific requests [contact us](https://mobb.ai/contact) and we'll do the most to answer your need quickly.`;
|
|
3653
3748
|
var commitFixButton = (commitUrl) => `<a href="${commitUrl}"><img src=${COMMIT_FIX_SVG}></a>`;
|
|
3654
3749
|
var MobbIconMarkdown = ``;
|
|
@@ -3675,7 +3770,7 @@ async function getRelevantVulenrabilitiesFromDiff(params) {
|
|
|
3675
3770
|
});
|
|
3676
3771
|
const lineAddedRanges = calculateRanges(fileNumbers);
|
|
3677
3772
|
const fileFilter = {
|
|
3678
|
-
path:
|
|
3773
|
+
path: z10.string().parse(file.to),
|
|
3679
3774
|
ranges: lineAddedRanges.map(([startLine, endLine]) => ({
|
|
3680
3775
|
endLine,
|
|
3681
3776
|
startLine
|
|
@@ -3786,7 +3881,7 @@ async function handleFinishedAnalysis({
|
|
|
3786
3881
|
{ authToken: githubActionToken }
|
|
3787
3882
|
);
|
|
3788
3883
|
} catch (e) {
|
|
3789
|
-
|
|
3884
|
+
debug5("delete comment failed %s", e);
|
|
3790
3885
|
return Promise.resolve();
|
|
3791
3886
|
}
|
|
3792
3887
|
});
|
|
@@ -3801,7 +3896,7 @@ async function handleFinishedAnalysis({
|
|
|
3801
3896
|
githubActionOctokit
|
|
3802
3897
|
);
|
|
3803
3898
|
} catch (e) {
|
|
3804
|
-
|
|
3899
|
+
debug5("delete comment failed %s", e);
|
|
3805
3900
|
return Promise.resolve();
|
|
3806
3901
|
}
|
|
3807
3902
|
});
|
|
@@ -3882,7 +3977,7 @@ ${fixPageLink}`,
|
|
|
3882
3977
|
fixablePrVuls,
|
|
3883
3978
|
nonFixablePrVuls
|
|
3884
3979
|
} = prVulenrabilities;
|
|
3885
|
-
|
|
3980
|
+
debug5({
|
|
3886
3981
|
fixablePrVuls,
|
|
3887
3982
|
nonFixablePrVuls,
|
|
3888
3983
|
vulnerabilitiesOutsidePr,
|
|
@@ -3958,10 +4053,10 @@ ${contactUsMarkdown}`;
|
|
|
3958
4053
|
import fs2 from "node:fs";
|
|
3959
4054
|
import path4 from "node:path";
|
|
3960
4055
|
import AdmZip from "adm-zip";
|
|
3961
|
-
import
|
|
4056
|
+
import Debug6 from "debug";
|
|
3962
4057
|
import { globby } from "globby";
|
|
3963
4058
|
import { isBinary } from "istextorbinary";
|
|
3964
|
-
var
|
|
4059
|
+
var debug6 = Debug6("mobbdev:pack");
|
|
3965
4060
|
var MAX_FILE_SIZE = 1024 * 1024 * 5;
|
|
3966
4061
|
function endsWithAny(str, suffixes) {
|
|
3967
4062
|
return suffixes.some(function(suffix) {
|
|
@@ -3969,37 +4064,37 @@ function endsWithAny(str, suffixes) {
|
|
|
3969
4064
|
});
|
|
3970
4065
|
}
|
|
3971
4066
|
async function pack(srcDirPath, vulnFiles) {
|
|
3972
|
-
|
|
4067
|
+
debug6("pack folder %s", srcDirPath);
|
|
3973
4068
|
const filepaths = await globby("**", {
|
|
3974
4069
|
gitignore: true,
|
|
3975
4070
|
onlyFiles: true,
|
|
3976
4071
|
cwd: srcDirPath,
|
|
3977
4072
|
followSymbolicLinks: false
|
|
3978
4073
|
});
|
|
3979
|
-
|
|
4074
|
+
debug6("files found %d", filepaths.length);
|
|
3980
4075
|
const zip = new AdmZip();
|
|
3981
|
-
|
|
4076
|
+
debug6("compressing files");
|
|
3982
4077
|
for (const filepath of filepaths) {
|
|
3983
4078
|
const absFilepath = path4.join(srcDirPath, filepath.toString());
|
|
3984
4079
|
if (!endsWithAny(
|
|
3985
4080
|
absFilepath.toString().replaceAll(path4.win32.sep, path4.posix.sep),
|
|
3986
4081
|
vulnFiles
|
|
3987
4082
|
)) {
|
|
3988
|
-
|
|
4083
|
+
debug6("ignoring %s because it is not a vulnerability file", filepath);
|
|
3989
4084
|
continue;
|
|
3990
4085
|
}
|
|
3991
4086
|
if (fs2.lstatSync(absFilepath).size > MAX_FILE_SIZE) {
|
|
3992
|
-
|
|
4087
|
+
debug6("ignoring %s because the size is > 5MB", filepath);
|
|
3993
4088
|
continue;
|
|
3994
4089
|
}
|
|
3995
4090
|
const data = fs2.readFileSync(absFilepath);
|
|
3996
4091
|
if (isBinary(null, data)) {
|
|
3997
|
-
|
|
4092
|
+
debug6("ignoring %s because is seems to be a binary file", filepath);
|
|
3998
4093
|
continue;
|
|
3999
4094
|
}
|
|
4000
4095
|
zip.addFile(filepath.toString(), data);
|
|
4001
4096
|
}
|
|
4002
|
-
|
|
4097
|
+
debug6("get zip file buffer");
|
|
4003
4098
|
return zip.toBuffer();
|
|
4004
4099
|
}
|
|
4005
4100
|
|
|
@@ -4074,7 +4169,7 @@ var cxOperatingSystemSupportMessage = `Your operating system does not support ch
|
|
|
4074
4169
|
|
|
4075
4170
|
// src/utils/child_process.ts
|
|
4076
4171
|
import cp from "node:child_process";
|
|
4077
|
-
import
|
|
4172
|
+
import Debug7 from "debug";
|
|
4078
4173
|
import * as process2 from "process";
|
|
4079
4174
|
import supportsColor from "supports-color";
|
|
4080
4175
|
var { stdout: stdout2 } = supportsColor;
|
|
@@ -4093,16 +4188,16 @@ function createSpwan({ args, processPath, name }, options) {
|
|
|
4093
4188
|
return createChildProcess({ childProcess: child, name }, options);
|
|
4094
4189
|
}
|
|
4095
4190
|
function createChildProcess({ childProcess, name }, options) {
|
|
4096
|
-
const
|
|
4191
|
+
const debug11 = Debug7(`mobbdev:${name}`);
|
|
4097
4192
|
const { display } = options;
|
|
4098
4193
|
return new Promise((resolve, reject) => {
|
|
4099
4194
|
let out = "";
|
|
4100
4195
|
const onData = (chunk) => {
|
|
4101
|
-
|
|
4196
|
+
debug11(`chunk received from ${name} std ${chunk}`);
|
|
4102
4197
|
out += chunk;
|
|
4103
4198
|
};
|
|
4104
4199
|
if (!childProcess || !childProcess?.stdout || !childProcess?.stderr) {
|
|
4105
|
-
|
|
4200
|
+
debug11(`unable to fork ${name}`);
|
|
4106
4201
|
reject(new Error(`unable to fork ${name}`));
|
|
4107
4202
|
}
|
|
4108
4203
|
childProcess.stdout?.on("data", onData);
|
|
@@ -4112,11 +4207,11 @@ function createChildProcess({ childProcess, name }, options) {
|
|
|
4112
4207
|
childProcess.stderr?.pipe(process2.stderr);
|
|
4113
4208
|
}
|
|
4114
4209
|
childProcess.on("exit", (code) => {
|
|
4115
|
-
|
|
4210
|
+
debug11(`${name} exit code ${code}`);
|
|
4116
4211
|
resolve({ message: out, code });
|
|
4117
4212
|
});
|
|
4118
4213
|
childProcess.on("error", (err) => {
|
|
4119
|
-
|
|
4214
|
+
debug11(`${name} error %o`, err);
|
|
4120
4215
|
reject(err);
|
|
4121
4216
|
});
|
|
4122
4217
|
});
|
|
@@ -4124,12 +4219,12 @@ function createChildProcess({ childProcess, name }, options) {
|
|
|
4124
4219
|
|
|
4125
4220
|
// src/features/analysis/scanners/checkmarx.ts
|
|
4126
4221
|
import chalk2 from "chalk";
|
|
4127
|
-
import
|
|
4222
|
+
import Debug8 from "debug";
|
|
4128
4223
|
import { existsSync } from "fs";
|
|
4129
4224
|
import { createSpinner as createSpinner2 } from "nanospinner";
|
|
4130
4225
|
import { type } from "os";
|
|
4131
4226
|
import path5 from "path";
|
|
4132
|
-
var
|
|
4227
|
+
var debug7 = Debug8("mobbdev:checkmarx");
|
|
4133
4228
|
var require2 = createRequire(import.meta.url);
|
|
4134
4229
|
var getCheckmarxPath = () => {
|
|
4135
4230
|
const os3 = type();
|
|
@@ -4170,14 +4265,14 @@ function validateCheckmarxInstallation() {
|
|
|
4170
4265
|
existsSync(getCheckmarxPath());
|
|
4171
4266
|
}
|
|
4172
4267
|
async function forkCheckmarx(args, { display }) {
|
|
4173
|
-
|
|
4268
|
+
debug7("fork checkmarx with args %o %s", args.join(" "), display);
|
|
4174
4269
|
return createSpwan(
|
|
4175
4270
|
{ args, processPath: getCheckmarxPath(), name: "checkmarx" },
|
|
4176
4271
|
{ display }
|
|
4177
4272
|
);
|
|
4178
4273
|
}
|
|
4179
4274
|
async function getCheckmarxReport({ reportPath, repositoryRoot, branch, projectName }, { skipPrompts = false }) {
|
|
4180
|
-
|
|
4275
|
+
debug7("get checkmarx report start %s %s", reportPath, repositoryRoot);
|
|
4181
4276
|
const { code: loginCode } = await forkCheckmarx(VALIDATE_COMMAND, {
|
|
4182
4277
|
display: false
|
|
4183
4278
|
});
|
|
@@ -4245,23 +4340,23 @@ async function validateCheckamxCredentials() {
|
|
|
4245
4340
|
// src/features/analysis/scanners/snyk.ts
|
|
4246
4341
|
import { createRequire as createRequire2 } from "node:module";
|
|
4247
4342
|
import chalk3 from "chalk";
|
|
4248
|
-
import
|
|
4343
|
+
import Debug9 from "debug";
|
|
4249
4344
|
import { createSpinner as createSpinner3 } from "nanospinner";
|
|
4250
4345
|
import open from "open";
|
|
4251
|
-
var
|
|
4346
|
+
var debug8 = Debug9("mobbdev:snyk");
|
|
4252
4347
|
var require3 = createRequire2(import.meta.url);
|
|
4253
4348
|
var SNYK_PATH = require3.resolve("snyk/bin/snyk");
|
|
4254
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";
|
|
4255
|
-
|
|
4350
|
+
debug8("snyk executable path %s", SNYK_PATH);
|
|
4256
4351
|
async function forkSnyk(args, { display }) {
|
|
4257
|
-
|
|
4352
|
+
debug8("fork snyk with args %o %s", args, display);
|
|
4258
4353
|
return createFork(
|
|
4259
4354
|
{ args, processPath: SNYK_PATH, name: "checkmarx" },
|
|
4260
4355
|
{ display }
|
|
4261
4356
|
);
|
|
4262
4357
|
}
|
|
4263
4358
|
async function getSnykReport(reportPath, repoRoot, { skipPrompts = false }) {
|
|
4264
|
-
|
|
4359
|
+
debug8("get snyk report start %s %s", reportPath, repoRoot);
|
|
4265
4360
|
const config4 = await forkSnyk(["config"], { display: false });
|
|
4266
4361
|
const { message: configMessage } = config4;
|
|
4267
4362
|
if (!configMessage.includes("api: ")) {
|
|
@@ -4275,7 +4370,7 @@ async function getSnykReport(reportPath, repoRoot, { skipPrompts = false }) {
|
|
|
4275
4370
|
snykLoginSpinner.update({
|
|
4276
4371
|
text: "\u{1F513} Waiting for Snyk login to complete"
|
|
4277
4372
|
});
|
|
4278
|
-
|
|
4373
|
+
debug8("no token in the config %s", config4);
|
|
4279
4374
|
await forkSnyk(["auth"], { display: true });
|
|
4280
4375
|
snykLoginSpinner.success({ text: "\u{1F513} Login to Snyk Successful" });
|
|
4281
4376
|
}
|
|
@@ -4287,12 +4382,12 @@ async function getSnykReport(reportPath, repoRoot, { skipPrompts = false }) {
|
|
|
4287
4382
|
if (scanOutput.includes(
|
|
4288
4383
|
"Snyk Code is not supported for org: enable in Settings > Snyk Code"
|
|
4289
4384
|
)) {
|
|
4290
|
-
|
|
4385
|
+
debug8("snyk code is not enabled %s", scanOutput);
|
|
4291
4386
|
snykSpinner.error({ text: "\u{1F50D} Snyk configuration needed" });
|
|
4292
4387
|
const answer = await snykArticlePrompt();
|
|
4293
|
-
|
|
4388
|
+
debug8("answer %s", answer);
|
|
4294
4389
|
if (answer) {
|
|
4295
|
-
|
|
4390
|
+
debug8("opening the browser");
|
|
4296
4391
|
await open(SNYK_ARTICLE_URL);
|
|
4297
4392
|
}
|
|
4298
4393
|
console.log(
|
|
@@ -4307,18 +4402,18 @@ async function getSnykReport(reportPath, repoRoot, { skipPrompts = false }) {
|
|
|
4307
4402
|
}
|
|
4308
4403
|
|
|
4309
4404
|
// src/features/analysis/upload-file.ts
|
|
4310
|
-
import
|
|
4405
|
+
import Debug10 from "debug";
|
|
4311
4406
|
import fetch2, { File, fileFrom, FormData } from "node-fetch";
|
|
4312
|
-
var
|
|
4407
|
+
var debug9 = Debug10("mobbdev:upload-file");
|
|
4313
4408
|
async function uploadFile({
|
|
4314
4409
|
file,
|
|
4315
4410
|
url,
|
|
4316
4411
|
uploadKey,
|
|
4317
4412
|
uploadFields
|
|
4318
4413
|
}) {
|
|
4319
|
-
|
|
4320
|
-
|
|
4321
|
-
|
|
4414
|
+
debug9("upload file start %s", url);
|
|
4415
|
+
debug9("upload fields %o", uploadFields);
|
|
4416
|
+
debug9("upload key %s", uploadKey);
|
|
4322
4417
|
const form = new FormData();
|
|
4323
4418
|
Object.entries(uploadFields).forEach(([key, value]) => {
|
|
4324
4419
|
form.append(key, value);
|
|
@@ -4327,10 +4422,10 @@ async function uploadFile({
|
|
|
4327
4422
|
form.append("key", uploadKey);
|
|
4328
4423
|
}
|
|
4329
4424
|
if (typeof file === "string") {
|
|
4330
|
-
|
|
4425
|
+
debug9("upload file from path %s", file);
|
|
4331
4426
|
form.append("file", await fileFrom(file));
|
|
4332
4427
|
} else {
|
|
4333
|
-
|
|
4428
|
+
debug9("upload file from buffer");
|
|
4334
4429
|
form.append("file", new File([file], "file"));
|
|
4335
4430
|
}
|
|
4336
4431
|
const response = await fetch2(url, {
|
|
@@ -4338,10 +4433,10 @@ async function uploadFile({
|
|
|
4338
4433
|
body: form
|
|
4339
4434
|
});
|
|
4340
4435
|
if (!response.ok) {
|
|
4341
|
-
|
|
4436
|
+
debug9("error from S3 %s %s", response.body, response.status);
|
|
4342
4437
|
throw new Error(`Failed to upload the file: ${response.status}`);
|
|
4343
4438
|
}
|
|
4344
|
-
|
|
4439
|
+
debug9("upload file done");
|
|
4345
4440
|
}
|
|
4346
4441
|
|
|
4347
4442
|
// src/features/analysis/index.ts
|
|
@@ -4356,9 +4451,9 @@ async function downloadRepo({
|
|
|
4356
4451
|
}) {
|
|
4357
4452
|
const { createSpinner: createSpinner4 } = Spinner2({ ci });
|
|
4358
4453
|
const repoSpinner = createSpinner4("\u{1F4BE} Downloading Repo").start();
|
|
4359
|
-
|
|
4454
|
+
debug10("download repo %s %s %s", repoUrl, dirname);
|
|
4360
4455
|
const zipFilePath = path6.join(dirname, "repo.zip");
|
|
4361
|
-
|
|
4456
|
+
debug10("download URL: %s auth headers: %o", downloadUrl, authHeaders);
|
|
4362
4457
|
const response = await fetch3(downloadUrl, {
|
|
4363
4458
|
method: "GET",
|
|
4364
4459
|
headers: {
|
|
@@ -4366,7 +4461,7 @@ async function downloadRepo({
|
|
|
4366
4461
|
}
|
|
4367
4462
|
});
|
|
4368
4463
|
if (!response.ok) {
|
|
4369
|
-
|
|
4464
|
+
debug10("SCM zipball request failed %s %s", response.body, response.status);
|
|
4370
4465
|
repoSpinner.error({ text: "\u{1F4BE} Repo download failed" });
|
|
4371
4466
|
throw new Error(`Can't access ${chalk4.bold(repoUrl)}`);
|
|
4372
4467
|
}
|
|
@@ -4380,7 +4475,7 @@ async function downloadRepo({
|
|
|
4380
4475
|
if (!repoRoot) {
|
|
4381
4476
|
throw new Error("Repo root not found");
|
|
4382
4477
|
}
|
|
4383
|
-
|
|
4478
|
+
debug10("repo root %s", repoRoot);
|
|
4384
4479
|
repoSpinner.success({ text: "\u{1F4BE} Repo downloaded successfully" });
|
|
4385
4480
|
return path6.join(dirname, repoRoot);
|
|
4386
4481
|
}
|
|
@@ -4397,7 +4492,7 @@ var getReportUrl = ({
|
|
|
4397
4492
|
projectId,
|
|
4398
4493
|
fixReportId
|
|
4399
4494
|
}) => `${WEB_APP_URL}/organization/${organizationId}/project/${projectId}/report/${fixReportId}`;
|
|
4400
|
-
var
|
|
4495
|
+
var debug10 = Debug11("mobbdev:index");
|
|
4401
4496
|
var packageJson = JSON.parse(
|
|
4402
4497
|
fs3.readFileSync(path6.join(getDirName2(), "../package.json"), "utf8")
|
|
4403
4498
|
);
|
|
@@ -4407,7 +4502,7 @@ if (!semver.satisfies(process.version, packageJson.engines.node)) {
|
|
|
4407
4502
|
);
|
|
4408
4503
|
}
|
|
4409
4504
|
var config2 = new Configstore(packageJson.name, { apiToken: "" });
|
|
4410
|
-
|
|
4505
|
+
debug10("config %o", config2);
|
|
4411
4506
|
async function runAnalysis(params, options) {
|
|
4412
4507
|
try {
|
|
4413
4508
|
await _scan(
|
|
@@ -4463,7 +4558,7 @@ async function _scan(params, { skipPrompts = false } = {}) {
|
|
|
4463
4558
|
githubToken: githubActionToken,
|
|
4464
4559
|
command
|
|
4465
4560
|
} = params;
|
|
4466
|
-
|
|
4561
|
+
debug10("start %s %s", dirname, repo);
|
|
4467
4562
|
const { createSpinner: createSpinner4 } = Spinner2({ ci });
|
|
4468
4563
|
skipPrompts = skipPrompts || ci;
|
|
4469
4564
|
let gqlClient = new GQLClient({
|
|
@@ -4528,9 +4623,9 @@ async function _scan(params, { skipPrompts = false } = {}) {
|
|
|
4528
4623
|
});
|
|
4529
4624
|
const reference = ref ?? await scm.getRepoDefaultBranch();
|
|
4530
4625
|
const { sha } = await scm.getReferenceData(reference);
|
|
4531
|
-
|
|
4532
|
-
|
|
4533
|
-
|
|
4626
|
+
debug10("org id %s", organizationId);
|
|
4627
|
+
debug10("project id %s", projectId);
|
|
4628
|
+
debug10("default branch %s", reference);
|
|
4534
4629
|
const repositoryRoot = await downloadRepo({
|
|
4535
4630
|
repoUrl: repo,
|
|
4536
4631
|
dirname,
|
|
@@ -4558,44 +4653,39 @@ async function _scan(params, { skipPrompts = false } = {}) {
|
|
|
4558
4653
|
}
|
|
4559
4654
|
uploadReportSpinner.success({ text: "\u{1F4C1} Report uploaded successfully" });
|
|
4560
4655
|
const mobbSpinner = createSpinner4("\u{1F575}\uFE0F\u200D\u2642\uFE0F Initiating Mobb analysis").start();
|
|
4561
|
-
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
|
+
});
|
|
4562
4670
|
if (command === "review") {
|
|
4563
|
-
await gqlClient.subscribeToAnalysis(
|
|
4564
|
-
|
|
4565
|
-
|
|
4671
|
+
await gqlClient.subscribeToAnalysis({
|
|
4672
|
+
subscribeToAnalysisParams: {
|
|
4673
|
+
analysisId: sendReportRes.submitVulnerabilityReport.fixReportId
|
|
4674
|
+
},
|
|
4675
|
+
callback: (analysisId) => handleFinishedAnalysis({
|
|
4566
4676
|
analysisId,
|
|
4567
4677
|
gqlClient,
|
|
4568
4678
|
scm,
|
|
4569
|
-
githubActionToken:
|
|
4570
|
-
scanner:
|
|
4571
|
-
})
|
|
4572
|
-
|
|
4679
|
+
githubActionToken: z11.string().parse(githubActionToken),
|
|
4680
|
+
scanner: z11.nativeEnum(SCANNERS).parse(scanner)
|
|
4681
|
+
}),
|
|
4682
|
+
callbackStates: ["Finished"]
|
|
4683
|
+
});
|
|
4573
4684
|
}
|
|
4574
4685
|
mobbSpinner.success({
|
|
4575
4686
|
text: "\u{1F575}\uFE0F\u200D\u2642\uFE0F Generating fixes..."
|
|
4576
4687
|
});
|
|
4577
4688
|
await askToOpenAnalysis();
|
|
4578
|
-
async function sendReport() {
|
|
4579
|
-
try {
|
|
4580
|
-
const sumbitRes = await gqlClient.submitVulnerabilityReport({
|
|
4581
|
-
fixReportId: reportUploadInfo.fixReportId,
|
|
4582
|
-
repoUrl: z10.string().parse(repo),
|
|
4583
|
-
reference,
|
|
4584
|
-
projectId,
|
|
4585
|
-
vulnerabilityReportFileName: "report.json",
|
|
4586
|
-
sha,
|
|
4587
|
-
experimentalEnabled,
|
|
4588
|
-
pullRequest: params.pullRequest
|
|
4589
|
-
});
|
|
4590
|
-
if (sumbitRes.submitVulnerabilityReport.__typename !== "VulnerabilityReport") {
|
|
4591
|
-
throw new Error("\u{1F575}\uFE0F\u200D\u2642\uFE0F Mobb analysis failed");
|
|
4592
|
-
}
|
|
4593
|
-
return sumbitRes;
|
|
4594
|
-
} catch (e) {
|
|
4595
|
-
mobbSpinner.error({ text: "\u{1F575}\uFE0F\u200D\u2642\uFE0F Mobb analysis failed" });
|
|
4596
|
-
throw e;
|
|
4597
|
-
}
|
|
4598
|
-
}
|
|
4599
4689
|
async function getReport(scanner2) {
|
|
4600
4690
|
const reportPath2 = path6.join(dirname, "report.json");
|
|
4601
4691
|
switch (scanner2) {
|
|
@@ -4671,9 +4761,9 @@ async function _scan(params, { skipPrompts = false } = {}) {
|
|
|
4671
4761
|
});
|
|
4672
4762
|
loginSpinner.spin();
|
|
4673
4763
|
if (encryptedApiToken) {
|
|
4674
|
-
|
|
4764
|
+
debug10("encrypted API token received %s", encryptedApiToken);
|
|
4675
4765
|
newApiToken = crypto.privateDecrypt(privateKey, Buffer.from(encryptedApiToken, "base64")).toString("utf-8");
|
|
4676
|
-
|
|
4766
|
+
debug10("API token decrypted");
|
|
4677
4767
|
break;
|
|
4678
4768
|
}
|
|
4679
4769
|
await sleep(LOGIN_CHECK_DELAY);
|
|
@@ -4686,7 +4776,7 @@ async function _scan(params, { skipPrompts = false } = {}) {
|
|
|
4686
4776
|
}
|
|
4687
4777
|
gqlClient = new GQLClient({ apiKey: newApiToken });
|
|
4688
4778
|
if (await gqlClient.verifyToken()) {
|
|
4689
|
-
|
|
4779
|
+
debug10("set api token %s", newApiToken);
|
|
4690
4780
|
config2.set("apiToken", newApiToken);
|
|
4691
4781
|
loginSpinner.success({ text: "\u{1F513} Login to Mobb successful!" });
|
|
4692
4782
|
} else {
|
|
@@ -4749,7 +4839,9 @@ async function _scan(params, { skipPrompts = false } = {}) {
|
|
|
4749
4839
|
uploadReportSpinner2.success({
|
|
4750
4840
|
text: "\u{1F4C1} Uploading Report successful!"
|
|
4751
4841
|
});
|
|
4752
|
-
const digestSpinner = createSpinner4(
|
|
4842
|
+
const digestSpinner = createSpinner4(
|
|
4843
|
+
progressMassages.processingVulnerabilityReport
|
|
4844
|
+
).start();
|
|
4753
4845
|
let vulnFiles = [];
|
|
4754
4846
|
const gitInfo = await getGitInfo(srcPath);
|
|
4755
4847
|
try {
|
|
@@ -4757,12 +4849,19 @@ async function _scan(params, { skipPrompts = false } = {}) {
|
|
|
4757
4849
|
fixReportId: reportUploadInfo.fixReportId,
|
|
4758
4850
|
projectId
|
|
4759
4851
|
});
|
|
4760
|
-
|
|
4761
|
-
|
|
4762
|
-
|
|
4763
|
-
|
|
4764
|
-
|
|
4765
|
-
|
|
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);
|
|
4766
4865
|
}
|
|
4767
4866
|
vulnFiles = await gqlClient.getVulnerabilityReportPaths(
|
|
4768
4867
|
vulnerabilityReportId
|
|
@@ -4772,7 +4871,7 @@ async function _scan(params, { skipPrompts = false } = {}) {
|
|
|
4772
4871
|
throw e;
|
|
4773
4872
|
}
|
|
4774
4873
|
digestSpinner.success({
|
|
4775
|
-
text:
|
|
4874
|
+
text: progressMassages.processingVulnerabilityReportSuccess
|
|
4776
4875
|
});
|
|
4777
4876
|
const zippingSpinner = createSpinner4("\u{1F4E6} Zipping repo").start();
|
|
4778
4877
|
const zipBuffer = await pack(srcPath, vulnFiles);
|
|
@@ -4792,12 +4891,16 @@ async function _scan(params, { skipPrompts = false } = {}) {
|
|
|
4792
4891
|
uploadRepoSpinner.success({ text: "\u{1F4C1} Uploading Repo successful!" });
|
|
4793
4892
|
const mobbSpinner2 = createSpinner4("\u{1F575}\uFE0F\u200D\u2642\uFE0F Initiating Mobb analysis").start();
|
|
4794
4893
|
try {
|
|
4795
|
-
await
|
|
4796
|
-
|
|
4797
|
-
|
|
4798
|
-
|
|
4799
|
-
|
|
4800
|
-
|
|
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
|
+
}
|
|
4801
4904
|
});
|
|
4802
4905
|
} catch (e) {
|
|
4803
4906
|
mobbSpinner2.error({ text: "\u{1F575}\uFE0F\u200D\u2642\uFE0F Mobb analysis failed" });
|
|
@@ -4998,7 +5101,7 @@ var scmTokenOption = {
|
|
|
4998
5101
|
// src/args/validation.ts
|
|
4999
5102
|
import chalk6 from "chalk";
|
|
5000
5103
|
import path8 from "path";
|
|
5001
|
-
import { z as
|
|
5104
|
+
import { z as z12 } from "zod";
|
|
5002
5105
|
function throwRepoUrlErrorMessage({
|
|
5003
5106
|
error,
|
|
5004
5107
|
repoUrl,
|
|
@@ -5015,7 +5118,7 @@ Example:
|
|
|
5015
5118
|
)}`;
|
|
5016
5119
|
throw new CliError(formattedErrorMessage);
|
|
5017
5120
|
}
|
|
5018
|
-
var UrlZ =
|
|
5121
|
+
var UrlZ = z12.string({
|
|
5019
5122
|
invalid_type_error: "is not a valid GitHub / GitLab / ADO URL"
|
|
5020
5123
|
}).refine((data) => !!sanityRepoURL(data), {
|
|
5021
5124
|
message: "is not a valid GitHub / GitLab / ADO URL"
|