mobbdev 0.0.67 → 0.0.68
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 +250 -93
- package/package.json +3 -1
package/dist/index.mjs
CHANGED
|
@@ -163,7 +163,7 @@ import fetch3 from "node-fetch";
|
|
|
163
163
|
import open2 from "open";
|
|
164
164
|
import semver from "semver";
|
|
165
165
|
import tmp2 from "tmp";
|
|
166
|
-
import { z as
|
|
166
|
+
import { z as z9 } from "zod";
|
|
167
167
|
|
|
168
168
|
// src/features/analysis/git.ts
|
|
169
169
|
import Debug2 from "debug";
|
|
@@ -762,6 +762,7 @@ var GQLClient = class {
|
|
|
762
762
|
const filters = hunks.map((hunk) => {
|
|
763
763
|
const filter = {
|
|
764
764
|
path: { _eq: hunk.path },
|
|
765
|
+
vulnerabilityReportIssue: { fixId: { _is_null: false } },
|
|
765
766
|
_or: hunk.ranges.map(({ endLine, startLine }) => ({
|
|
766
767
|
startLine: { _gte: startLine, _lte: endLine },
|
|
767
768
|
endLine: { _gte: startLine, _lte: endLine }
|
|
@@ -897,15 +898,30 @@ var GQLClient = class {
|
|
|
897
898
|
// src/features/analysis/handle_finished_analysis.ts
|
|
898
899
|
import Debug4 from "debug";
|
|
899
900
|
import parseDiff from "parse-diff";
|
|
900
|
-
import { z as
|
|
901
|
+
import { z as z8 } from "zod";
|
|
902
|
+
|
|
903
|
+
// src/features/analysis/scm/constants.ts
|
|
904
|
+
var MOBB_ICON_IMG = "https://app.mobb.ai/mobb.png";
|
|
905
|
+
var COMMIT_FIX_SVG = `https://app.mobb.ai/gh-action/commit-button.svg`;
|
|
901
906
|
|
|
902
907
|
// src/features/analysis/scm/gitlab.ts
|
|
903
908
|
import querystring from "node:querystring";
|
|
904
909
|
import { Gitlab } from "@gitbeaker/rest";
|
|
905
|
-
import { z as
|
|
910
|
+
import { z as z7 } from "zod";
|
|
906
911
|
|
|
907
912
|
// src/features/analysis/scm/scm.ts
|
|
908
913
|
import { Octokit as Octokit2 } from "@octokit/core";
|
|
914
|
+
import { z as z6 } from "zod";
|
|
915
|
+
|
|
916
|
+
// src/features/analysis/scm/github/encryptSecret.ts
|
|
917
|
+
import sodium from "libsodium-wrappers";
|
|
918
|
+
async function encryptSecret(secret, key) {
|
|
919
|
+
await sodium.ready;
|
|
920
|
+
const binkey = sodium.from_base64(key, sodium.base64_variants.ORIGINAL);
|
|
921
|
+
const binsec = sodium.from_string(secret);
|
|
922
|
+
const encBytes = sodium.crypto_box_seal(binsec, binkey);
|
|
923
|
+
return sodium.to_base64(encBytes, sodium.base64_variants.ORIGINAL);
|
|
924
|
+
}
|
|
909
925
|
|
|
910
926
|
// src/features/analysis/scm/github/github.ts
|
|
911
927
|
import { RequestError } from "@octokit/request-error";
|
|
@@ -1137,6 +1153,16 @@ async function createPullRequest(options) {
|
|
|
1137
1153
|
});
|
|
1138
1154
|
return res.data.number;
|
|
1139
1155
|
}
|
|
1156
|
+
async function forkRepo(options) {
|
|
1157
|
+
const { owner, repo } = parseOwnerAndRepo(options.repoUrl);
|
|
1158
|
+
const oktoKit = getOktoKit({ githubAuthToken: options.accessToken });
|
|
1159
|
+
const res = await oktoKit.rest.repos.createFork({
|
|
1160
|
+
owner,
|
|
1161
|
+
repo,
|
|
1162
|
+
default_branch_only: false
|
|
1163
|
+
});
|
|
1164
|
+
return { url: res.data.html_url ? String(res.data.html_url) : null };
|
|
1165
|
+
}
|
|
1140
1166
|
async function getRepos(oktoKit) {
|
|
1141
1167
|
const res = await oktoKit.request("GET /user/repos?sort=updated", {
|
|
1142
1168
|
headers: {
|
|
@@ -1290,8 +1316,11 @@ async function getGithubBlameRanges({ ref, gitHubUrl, path: path8 }, options) {
|
|
|
1290
1316
|
var POST_COMMENT_PATH = "POST /repos/{owner}/{repo}/pulls/{pull_number}/comments";
|
|
1291
1317
|
var DELETE_COMMENT_PATH = "DELETE /repos/{owner}/{repo}/pulls/comments/{comment_id}";
|
|
1292
1318
|
var UPDATE_COMMENT_PATH = "PATCH /repos/{owner}/{repo}/pulls/comments/{comment_id}";
|
|
1293
|
-
var GET_PR_COMMENTS_PATH = "GET /repos/{owner}/{repo}/pulls/comments";
|
|
1319
|
+
var GET_PR_COMMENTS_PATH = "GET /repos/{owner}/{repo}/pulls/{pull_number}/comments";
|
|
1320
|
+
var GET_PR_COMMENT_PATH = "GET /repos/{owner}/{repo}/pulls/comments/{comment_id}";
|
|
1294
1321
|
var GET_PR = "GET /repos/{owner}/{repo}/pulls/{pull_number}";
|
|
1322
|
+
var CREATE_OR_UPDATE_A_REPOSITORY_SECRET = "PUT /repos/{owner}/{repo}/actions/secrets/{secret_name}";
|
|
1323
|
+
var GET_A_REPOSITORY_PUBLIC_KEY = "GET /repos/{owner}/{repo}/actions/secrets/public-key";
|
|
1295
1324
|
|
|
1296
1325
|
// src/features/analysis/scm/github/github-v2.ts
|
|
1297
1326
|
function postPrComment(client, params) {
|
|
@@ -1303,32 +1332,32 @@ function updatePrComment(client, params) {
|
|
|
1303
1332
|
function getPrComments(client, params) {
|
|
1304
1333
|
return client.request(GET_PR_COMMENTS_PATH, params);
|
|
1305
1334
|
}
|
|
1335
|
+
function getPrComment(client, params) {
|
|
1336
|
+
return client.request(GET_PR_COMMENT_PATH, params);
|
|
1337
|
+
}
|
|
1306
1338
|
function deleteComment(client, params) {
|
|
1307
1339
|
return client.request(DELETE_COMMENT_PATH, params);
|
|
1308
1340
|
}
|
|
1309
|
-
function
|
|
1310
|
-
return client.request(GET_PR, params);
|
|
1341
|
+
function getPrDiff(client, params) {
|
|
1342
|
+
return client.request(GET_PR, { ...params, mediaType: { format: "diff" } });
|
|
1343
|
+
}
|
|
1344
|
+
function createOrUpdateRepositorySecret(client, params) {
|
|
1345
|
+
return client.request(CREATE_OR_UPDATE_A_REPOSITORY_SECRET, params);
|
|
1346
|
+
}
|
|
1347
|
+
function getARepositoryPublicKey(client, params) {
|
|
1348
|
+
return client.request(GET_A_REPOSITORY_PUBLIC_KEY, params);
|
|
1311
1349
|
}
|
|
1312
1350
|
|
|
1313
|
-
// src/features/analysis/scm/scmSubmit.ts
|
|
1351
|
+
// src/features/analysis/scm/scmSubmit/index.ts
|
|
1314
1352
|
import fs from "node:fs/promises";
|
|
1315
1353
|
import os from "os";
|
|
1316
1354
|
import path3 from "path";
|
|
1317
1355
|
import { simpleGit as simpleGit2 } from "simple-git";
|
|
1318
1356
|
import tmp from "tmp";
|
|
1357
|
+
import { z as z5 } from "zod";
|
|
1358
|
+
|
|
1359
|
+
// src/features/analysis/scm/scmSubmit/types.ts
|
|
1319
1360
|
import { z as z4 } from "zod";
|
|
1320
|
-
var isValidBranchName = async (branchName) => {
|
|
1321
|
-
const git = simpleGit2();
|
|
1322
|
-
try {
|
|
1323
|
-
const res = await git.raw(["check-ref-format", "--branch", branchName]);
|
|
1324
|
-
if (res) {
|
|
1325
|
-
return true;
|
|
1326
|
-
}
|
|
1327
|
-
return false;
|
|
1328
|
-
} catch (e) {
|
|
1329
|
-
return false;
|
|
1330
|
-
}
|
|
1331
|
-
};
|
|
1332
1361
|
var BaseSubmitToScmMessageZ = z4.object({
|
|
1333
1362
|
submitFixRequestId: z4.string().uuid(),
|
|
1334
1363
|
fixes: z4.array(
|
|
@@ -1349,7 +1378,8 @@ var CommitToSameBranchParamsZ = BaseSubmitToScmMessageZ.merge(
|
|
|
1349
1378
|
type: z4.literal(submitToScmMessageType.commitToSameBranch),
|
|
1350
1379
|
branch: z4.string(),
|
|
1351
1380
|
commitMessage: z4.string(),
|
|
1352
|
-
commitDescription: z4.string().nullish()
|
|
1381
|
+
commitDescription: z4.string().nullish(),
|
|
1382
|
+
githubCommentId: z4.number().nullish()
|
|
1353
1383
|
})
|
|
1354
1384
|
);
|
|
1355
1385
|
var SubmitFixesToDifferentBranchParamsZ = z4.object({
|
|
@@ -1366,8 +1396,7 @@ var FixResponseArrayZ = z4.array(
|
|
|
1366
1396
|
fixId: z4.string().uuid()
|
|
1367
1397
|
})
|
|
1368
1398
|
);
|
|
1369
|
-
var
|
|
1370
|
-
type: z4.nativeEnum(submitToScmMessageType),
|
|
1399
|
+
var SubmitFixesBaseResponseMessageZ = z4.object({
|
|
1371
1400
|
submitFixRequestId: z4.string().uuid(),
|
|
1372
1401
|
submitBranches: z4.array(
|
|
1373
1402
|
z4.object({
|
|
@@ -1387,7 +1416,33 @@ var SubmitFixesResponseMessageZ = z4.object({
|
|
|
1387
1416
|
})
|
|
1388
1417
|
}).optional()
|
|
1389
1418
|
});
|
|
1390
|
-
var
|
|
1419
|
+
var SubmitFixesToSameBranchResponseMessageZ = z4.object({
|
|
1420
|
+
type: z4.literal(submitToScmMessageType.commitToSameBranch),
|
|
1421
|
+
githubCommentId: z4.number().nullish()
|
|
1422
|
+
}).merge(SubmitFixesBaseResponseMessageZ);
|
|
1423
|
+
var SubmitFixesToDifferentBranchResponseMessageZ = z4.object({
|
|
1424
|
+
type: z4.literal(submitToScmMessageType.submitFixesForDifferentBranch),
|
|
1425
|
+
githubCommentId: z4.number().optional()
|
|
1426
|
+
}).merge(SubmitFixesBaseResponseMessageZ);
|
|
1427
|
+
var SubmitFixeResponseMessageZ = z4.discriminatedUnion("type", [
|
|
1428
|
+
SubmitFixesToSameBranchResponseMessageZ,
|
|
1429
|
+
SubmitFixesToDifferentBranchResponseMessageZ
|
|
1430
|
+
]);
|
|
1431
|
+
|
|
1432
|
+
// src/features/analysis/scm/scmSubmit/index.ts
|
|
1433
|
+
var isValidBranchName = async (branchName) => {
|
|
1434
|
+
const git = simpleGit2();
|
|
1435
|
+
try {
|
|
1436
|
+
const res = await git.raw(["check-ref-format", "--branch", branchName]);
|
|
1437
|
+
if (res) {
|
|
1438
|
+
return true;
|
|
1439
|
+
}
|
|
1440
|
+
return false;
|
|
1441
|
+
} catch (e) {
|
|
1442
|
+
return false;
|
|
1443
|
+
}
|
|
1444
|
+
};
|
|
1445
|
+
var FixesZ = z5.array(z5.object({ fixId: z5.string(), diff: z5.string() })).nonempty();
|
|
1391
1446
|
|
|
1392
1447
|
// src/features/analysis/scm/scm.ts
|
|
1393
1448
|
function getScmLibTypeFromUrl(url) {
|
|
@@ -1538,6 +1593,20 @@ var GitlabSCMLib = class extends SCMLib {
|
|
|
1538
1593
|
accessToken: this.accessToken
|
|
1539
1594
|
});
|
|
1540
1595
|
}
|
|
1596
|
+
async forkRepo() {
|
|
1597
|
+
if (!this.accessToken) {
|
|
1598
|
+
console.error("no access token");
|
|
1599
|
+
throw new Error("no access token");
|
|
1600
|
+
}
|
|
1601
|
+
throw new Error("not supported yet");
|
|
1602
|
+
}
|
|
1603
|
+
async createOrUpdateRepositorySecret() {
|
|
1604
|
+
if (!this.accessToken) {
|
|
1605
|
+
console.error("no access token");
|
|
1606
|
+
throw new Error("no access token");
|
|
1607
|
+
}
|
|
1608
|
+
throw new Error("not supported yet");
|
|
1609
|
+
}
|
|
1541
1610
|
async getRepoList() {
|
|
1542
1611
|
if (!this.accessToken) {
|
|
1543
1612
|
console.error("no access token");
|
|
@@ -1659,8 +1728,15 @@ var GitlabSCMLib = class extends SCMLib {
|
|
|
1659
1728
|
gitlabAuthToken: this.accessToken
|
|
1660
1729
|
});
|
|
1661
1730
|
}
|
|
1731
|
+
getPrComment(_commentId) {
|
|
1732
|
+
throw new Error("getPrComment not implemented.");
|
|
1733
|
+
}
|
|
1734
|
+
updatePrComment(_params, _oktokit) {
|
|
1735
|
+
throw new Error("updatePrComment not implemented.");
|
|
1736
|
+
}
|
|
1662
1737
|
};
|
|
1663
1738
|
var GithubSCMLib = class extends SCMLib {
|
|
1739
|
+
// we don't always need a url, what's important is that we have an access token
|
|
1664
1740
|
constructor(url, accessToken) {
|
|
1665
1741
|
super(url, accessToken);
|
|
1666
1742
|
__publicField(this, "oktokit");
|
|
@@ -1682,6 +1758,39 @@ var GithubSCMLib = class extends SCMLib {
|
|
|
1682
1758
|
})
|
|
1683
1759
|
);
|
|
1684
1760
|
}
|
|
1761
|
+
async forkRepo(repoUrl) {
|
|
1762
|
+
if (!this.accessToken) {
|
|
1763
|
+
console.error("no access token");
|
|
1764
|
+
throw new Error("no access token");
|
|
1765
|
+
}
|
|
1766
|
+
return forkRepo({
|
|
1767
|
+
repoUrl,
|
|
1768
|
+
accessToken: this.accessToken
|
|
1769
|
+
});
|
|
1770
|
+
}
|
|
1771
|
+
async createOrUpdateRepositorySecret(params, _oktokit) {
|
|
1772
|
+
if (!_oktokit && !this.accessToken || !this.url) {
|
|
1773
|
+
throw new Error("cannot delete comment without access token or url");
|
|
1774
|
+
}
|
|
1775
|
+
const oktokit = _oktokit || this.oktokit;
|
|
1776
|
+
const { owner, repo } = parseOwnerAndRepo(this.url);
|
|
1777
|
+
const { data: repositoryPublicKeyResponse } = await getARepositoryPublicKey(
|
|
1778
|
+
oktokit,
|
|
1779
|
+
{
|
|
1780
|
+
owner,
|
|
1781
|
+
repo
|
|
1782
|
+
}
|
|
1783
|
+
);
|
|
1784
|
+
const { key_id, key } = repositoryPublicKeyResponse;
|
|
1785
|
+
const encryptedValue = await encryptSecret(params.value, key);
|
|
1786
|
+
return createOrUpdateRepositorySecret(oktokit, {
|
|
1787
|
+
encrypted_value: encryptedValue,
|
|
1788
|
+
secret_name: params.name,
|
|
1789
|
+
key_id,
|
|
1790
|
+
owner,
|
|
1791
|
+
repo
|
|
1792
|
+
});
|
|
1793
|
+
}
|
|
1685
1794
|
async validateParams() {
|
|
1686
1795
|
return githubValidateParams(this.url, this.accessToken);
|
|
1687
1796
|
}
|
|
@@ -1739,13 +1848,12 @@ var GithubSCMLib = class extends SCMLib {
|
|
|
1739
1848
|
throw new Error("cannot get Pr Comments without access token or url");
|
|
1740
1849
|
}
|
|
1741
1850
|
const { owner, repo } = parseOwnerAndRepo(this.url);
|
|
1742
|
-
const prRes = await
|
|
1851
|
+
const prRes = await getPrDiff(this.oktokit, {
|
|
1743
1852
|
...params,
|
|
1744
1853
|
owner,
|
|
1745
1854
|
repo
|
|
1746
1855
|
});
|
|
1747
|
-
|
|
1748
|
-
return this.oktokit.request("GET " + diffUrl);
|
|
1856
|
+
return z6.string().parse(prRes.data);
|
|
1749
1857
|
}
|
|
1750
1858
|
async getRepoList() {
|
|
1751
1859
|
if (!this.accessToken) {
|
|
@@ -1843,6 +1951,18 @@ var GithubSCMLib = class extends SCMLib {
|
|
|
1843
1951
|
}
|
|
1844
1952
|
);
|
|
1845
1953
|
}
|
|
1954
|
+
async getPrComment(commentId) {
|
|
1955
|
+
if (!this.url) {
|
|
1956
|
+
console.error("no url");
|
|
1957
|
+
throw new Error("no url");
|
|
1958
|
+
}
|
|
1959
|
+
const { owner, repo } = parseOwnerAndRepo(this.url);
|
|
1960
|
+
return await getPrComment(this.oktokit, {
|
|
1961
|
+
repo,
|
|
1962
|
+
owner,
|
|
1963
|
+
comment_id: commentId
|
|
1964
|
+
});
|
|
1965
|
+
}
|
|
1846
1966
|
async getRepoDefaultBranch() {
|
|
1847
1967
|
if (!this.url) {
|
|
1848
1968
|
console.error("no url");
|
|
@@ -1878,6 +1998,14 @@ var StubSCMLib = class extends SCMLib {
|
|
|
1878
1998
|
console.error("validateParams() not implemented");
|
|
1879
1999
|
throw new Error("validateParams() not implemented");
|
|
1880
2000
|
}
|
|
2001
|
+
async forkRepo() {
|
|
2002
|
+
console.error("forkRepo() not implemented");
|
|
2003
|
+
throw new Error("forkRepo() not implemented");
|
|
2004
|
+
}
|
|
2005
|
+
async createOrUpdateRepositorySecret() {
|
|
2006
|
+
console.error("forkRepo() not implemented");
|
|
2007
|
+
throw new Error("forkRepo() not implemented");
|
|
2008
|
+
}
|
|
1881
2009
|
async getRepoList() {
|
|
1882
2010
|
console.error("getBranchList() not implemented");
|
|
1883
2011
|
throw new Error("getBranchList() not implemented");
|
|
@@ -1910,14 +2038,22 @@ var StubSCMLib = class extends SCMLib {
|
|
|
1910
2038
|
console.error("getRepoDefaultBranch() not implemented");
|
|
1911
2039
|
throw new Error("getRepoDefaultBranch() not implemented");
|
|
1912
2040
|
}
|
|
2041
|
+
async getPrComment(_commentId) {
|
|
2042
|
+
console.error("getPrComment() not implemented");
|
|
2043
|
+
throw new Error("getPrComment() not implemented");
|
|
2044
|
+
}
|
|
2045
|
+
async updatePrComment() {
|
|
2046
|
+
console.error("updatePrComment() not implemented");
|
|
2047
|
+
throw new Error("updatePrComment() not implemented");
|
|
2048
|
+
}
|
|
1913
2049
|
};
|
|
1914
2050
|
|
|
1915
2051
|
// src/features/analysis/scm/gitlab.ts
|
|
1916
2052
|
function removeTrailingSlash2(str) {
|
|
1917
2053
|
return str.trim().replace(/\/+$/, "");
|
|
1918
2054
|
}
|
|
1919
|
-
var EnvVariablesZod2 =
|
|
1920
|
-
GITLAB_API_TOKEN:
|
|
2055
|
+
var EnvVariablesZod2 = z7.object({
|
|
2056
|
+
GITLAB_API_TOKEN: z7.string().optional()
|
|
1921
2057
|
});
|
|
1922
2058
|
var { GITLAB_API_TOKEN } = EnvVariablesZod2.parse(process.env);
|
|
1923
2059
|
function getGitBeaker(options) {
|
|
@@ -2146,38 +2282,13 @@ async function getGitlabBlameRanges({ ref, gitlabUrl, path: path8 }, options) {
|
|
|
2146
2282
|
};
|
|
2147
2283
|
});
|
|
2148
2284
|
}
|
|
2149
|
-
var GitlabAuthResultZ =
|
|
2150
|
-
access_token:
|
|
2151
|
-
token_type:
|
|
2152
|
-
refresh_token:
|
|
2285
|
+
var GitlabAuthResultZ = z7.object({
|
|
2286
|
+
access_token: z7.string(),
|
|
2287
|
+
token_type: z7.string(),
|
|
2288
|
+
refresh_token: z7.string()
|
|
2153
2289
|
});
|
|
2154
2290
|
|
|
2155
|
-
// src/features/analysis/utils/
|
|
2156
|
-
function calculateRanges(integers) {
|
|
2157
|
-
if (integers.length === 0) {
|
|
2158
|
-
return [];
|
|
2159
|
-
}
|
|
2160
|
-
integers.sort((a, b) => a - b);
|
|
2161
|
-
const ranges = integers.reduce(
|
|
2162
|
-
(result, current, index) => {
|
|
2163
|
-
if (index === 0) {
|
|
2164
|
-
return [...result, [current, current]];
|
|
2165
|
-
}
|
|
2166
|
-
const currentRange = result[result.length - 1];
|
|
2167
|
-
const [_start, end] = currentRange;
|
|
2168
|
-
if (current === end + 1) {
|
|
2169
|
-
currentRange[1] = current;
|
|
2170
|
-
} else {
|
|
2171
|
-
result.push([current, current]);
|
|
2172
|
-
}
|
|
2173
|
-
return result;
|
|
2174
|
-
},
|
|
2175
|
-
[]
|
|
2176
|
-
);
|
|
2177
|
-
return ranges;
|
|
2178
|
-
}
|
|
2179
|
-
|
|
2180
|
-
// src/features/analysis/utils/get_issue_type.ts
|
|
2291
|
+
// src/features/analysis/scm/utils/get_issue_type.ts
|
|
2181
2292
|
var getIssueType = (issueType) => {
|
|
2182
2293
|
switch (issueType) {
|
|
2183
2294
|
case "SQL_Injection" /* SqlInjection */:
|
|
@@ -2236,48 +2347,86 @@ var getIssueType = (issueType) => {
|
|
|
2236
2347
|
}
|
|
2237
2348
|
};
|
|
2238
2349
|
|
|
2239
|
-
// src/features/analysis/utils/index.ts
|
|
2240
|
-
function getFixUrlWithRedirect({
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2350
|
+
// src/features/analysis/scm/utils/index.ts
|
|
2351
|
+
function getFixUrlWithRedirect(params) {
|
|
2352
|
+
const {
|
|
2353
|
+
fixId,
|
|
2354
|
+
projectId,
|
|
2355
|
+
organizationId,
|
|
2356
|
+
analysisId,
|
|
2357
|
+
redirectUrl,
|
|
2358
|
+
appBaseUrl,
|
|
2359
|
+
commentId
|
|
2360
|
+
} = params;
|
|
2361
|
+
const searchParams = new URLSearchParams();
|
|
2362
|
+
searchParams.append("commit_redirect_url", redirectUrl);
|
|
2363
|
+
searchParams.append("comment_id", commentId.toString());
|
|
2247
2364
|
return `${getFixUrl({
|
|
2365
|
+
appBaseUrl,
|
|
2248
2366
|
fixId,
|
|
2249
2367
|
projectId,
|
|
2250
2368
|
organizationId,
|
|
2251
2369
|
analysisId
|
|
2252
|
-
})}
|
|
2370
|
+
})}?${searchParams.toString()}`;
|
|
2253
2371
|
}
|
|
2254
2372
|
function getFixUrl({
|
|
2373
|
+
appBaseUrl,
|
|
2255
2374
|
fixId,
|
|
2256
2375
|
projectId,
|
|
2257
2376
|
organizationId,
|
|
2258
2377
|
analysisId
|
|
2259
2378
|
}) {
|
|
2260
|
-
return `${
|
|
2379
|
+
return `${appBaseUrl}/organization/${organizationId}/project/${projectId}/report/${analysisId}/fix/${fixId}`;
|
|
2261
2380
|
}
|
|
2262
|
-
function getCommitUrl({
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2381
|
+
function getCommitUrl(params) {
|
|
2382
|
+
const {
|
|
2383
|
+
fixId,
|
|
2384
|
+
projectId,
|
|
2385
|
+
organizationId,
|
|
2386
|
+
analysisId,
|
|
2387
|
+
redirectUrl,
|
|
2388
|
+
appBaseUrl,
|
|
2389
|
+
commentId
|
|
2390
|
+
} = params;
|
|
2391
|
+
const searchParams = new URLSearchParams();
|
|
2392
|
+
searchParams.append("redirect_url", redirectUrl);
|
|
2393
|
+
searchParams.append("comment_id", commentId.toString());
|
|
2269
2394
|
return `${getFixUrl({
|
|
2395
|
+
appBaseUrl,
|
|
2270
2396
|
fixId,
|
|
2271
2397
|
projectId,
|
|
2272
2398
|
organizationId,
|
|
2273
2399
|
analysisId
|
|
2274
|
-
})}/commit
|
|
2400
|
+
})}/commit?${searchParams.toString()}`;
|
|
2401
|
+
}
|
|
2402
|
+
|
|
2403
|
+
// src/features/analysis/utils/calculate_ranges.ts
|
|
2404
|
+
function calculateRanges(integers) {
|
|
2405
|
+
if (integers.length === 0) {
|
|
2406
|
+
return [];
|
|
2407
|
+
}
|
|
2408
|
+
integers.sort((a, b) => a - b);
|
|
2409
|
+
const ranges = integers.reduce(
|
|
2410
|
+
(result, current, index) => {
|
|
2411
|
+
if (index === 0) {
|
|
2412
|
+
return [...result, [current, current]];
|
|
2413
|
+
}
|
|
2414
|
+
const currentRange = result[result.length - 1];
|
|
2415
|
+
const [_start, end] = currentRange;
|
|
2416
|
+
if (current === end + 1) {
|
|
2417
|
+
currentRange[1] = current;
|
|
2418
|
+
} else {
|
|
2419
|
+
result.push([current, current]);
|
|
2420
|
+
}
|
|
2421
|
+
return result;
|
|
2422
|
+
},
|
|
2423
|
+
[]
|
|
2424
|
+
);
|
|
2425
|
+
return ranges;
|
|
2275
2426
|
}
|
|
2276
2427
|
|
|
2277
2428
|
// src/features/analysis/handle_finished_analysis.ts
|
|
2278
2429
|
var debug4 = Debug4("mobbdev:handle-finished-analysis");
|
|
2279
|
-
var MOBB_ICON_IMG = "";
|
|
2280
|
-
var COMMIT_FIX_SVG = `https://felt-laptop-20190711103614-deployment.s3.us-east-1.amazonaws.com/commit-button.svg`;
|
|
2281
2430
|
var commitFixButton = (commitUrl) => `<a href="${commitUrl}"><img src=${COMMIT_FIX_SVG}></a>`;
|
|
2282
2431
|
function scannerToFriendlyString(scanner) {
|
|
2283
2432
|
switch (scanner) {
|
|
@@ -2301,7 +2450,7 @@ async function getFixesFromDiff(params) {
|
|
|
2301
2450
|
});
|
|
2302
2451
|
const lineAddedRanges = calculateRanges(fileNumbers);
|
|
2303
2452
|
const fileFilter = {
|
|
2304
|
-
path:
|
|
2453
|
+
path: z8.string().parse(file.to),
|
|
2305
2454
|
ranges: lineAddedRanges.map(([startLine, endLine]) => ({
|
|
2306
2455
|
endLine,
|
|
2307
2456
|
startLine
|
|
@@ -2333,16 +2482,19 @@ async function handleFinishedAnalysis({
|
|
|
2333
2482
|
}
|
|
2334
2483
|
} = getAnalysis.analysis;
|
|
2335
2484
|
const { commitSha, pullRequest } = getAnalysis.analysis.repo;
|
|
2336
|
-
const
|
|
2485
|
+
const diff = await scm.getPrDiff({ pull_number: pullRequest });
|
|
2337
2486
|
const { vulnerabilityReportIssueCodeNodes } = await getFixesFromDiff({
|
|
2338
|
-
diff
|
|
2487
|
+
diff,
|
|
2339
2488
|
gqlClient,
|
|
2340
2489
|
vulnerabilityReportId: getAnalysis.analysis.vulnerabilityReportId
|
|
2341
2490
|
});
|
|
2342
|
-
const comments = await scm.getPrComments(
|
|
2491
|
+
const comments = await scm.getPrComments(
|
|
2492
|
+
{ pull_number: pullRequest },
|
|
2493
|
+
githubActionOctokit
|
|
2494
|
+
);
|
|
2343
2495
|
await Promise.all(
|
|
2344
2496
|
comments.data.filter((comment) => {
|
|
2345
|
-
return comment.body.includes(
|
|
2497
|
+
return comment.body.includes(MOBB_ICON_IMG);
|
|
2346
2498
|
}).map((comment) => {
|
|
2347
2499
|
try {
|
|
2348
2500
|
return scm.deleteComment(
|
|
@@ -2374,25 +2526,30 @@ async function handleFinishedAnalysis({
|
|
|
2374
2526
|
},
|
|
2375
2527
|
githubActionOctokit
|
|
2376
2528
|
);
|
|
2529
|
+
const commentId = commentRes.data.id;
|
|
2377
2530
|
const commitUrl = getCommitUrl({
|
|
2531
|
+
appBaseUrl: WEB_APP_URL,
|
|
2378
2532
|
fixId: fix_by_pk.id,
|
|
2379
2533
|
projectId,
|
|
2380
2534
|
analysisId,
|
|
2381
2535
|
organizationId,
|
|
2382
|
-
redirectUrl: commentRes.data.html_url
|
|
2536
|
+
redirectUrl: commentRes.data.html_url,
|
|
2537
|
+
commentId
|
|
2383
2538
|
});
|
|
2384
2539
|
const fixUrl = getFixUrlWithRedirect({
|
|
2540
|
+
appBaseUrl: WEB_APP_URL,
|
|
2385
2541
|
fixId: fix_by_pk.id,
|
|
2386
2542
|
projectId,
|
|
2387
2543
|
analysisId,
|
|
2388
2544
|
organizationId,
|
|
2389
|
-
redirectUrl: commentRes.data.html_url
|
|
2545
|
+
redirectUrl: commentRes.data.html_url,
|
|
2546
|
+
commentId
|
|
2390
2547
|
});
|
|
2391
2548
|
const scanerString = scannerToFriendlyString(scanner);
|
|
2392
2549
|
const issueType = getIssueType(fix_by_pk.issueType);
|
|
2393
|
-
const title = `# ${MOBB_ICON_IMG} ${issueType} fix by Mobb is ready`;
|
|
2550
|
+
const title = `#  ${issueType} fix by Mobb is ready`;
|
|
2394
2551
|
const subTitle = `### Apply the following code change to fix ${issueType} issue detected by ${scanerString}:`;
|
|
2395
|
-
const
|
|
2552
|
+
const diff2 = `\`\`\`diff
|
|
2396
2553
|
${patch}
|
|
2397
2554
|
\`\`\``;
|
|
2398
2555
|
const fixPageLink = `[Learn more and fine tune the fix](${fixUrl})`;
|
|
@@ -2400,12 +2557,12 @@ ${patch}
|
|
|
2400
2557
|
{
|
|
2401
2558
|
body: `${title}
|
|
2402
2559
|
${subTitle}
|
|
2403
|
-
${
|
|
2560
|
+
${diff2}
|
|
2404
2561
|
${commitFixButton(
|
|
2405
2562
|
commitUrl
|
|
2406
2563
|
)}
|
|
2407
2564
|
${fixPageLink}`,
|
|
2408
|
-
comment_id:
|
|
2565
|
+
comment_id: commentId
|
|
2409
2566
|
},
|
|
2410
2567
|
githubActionOctokit
|
|
2411
2568
|
);
|
|
@@ -2993,7 +3150,7 @@ async function _scan(params, { skipPrompts = false } = {}) {
|
|
|
2993
3150
|
gqlClient,
|
|
2994
3151
|
scm,
|
|
2995
3152
|
githubActionOctokit: new Octokit3({ auth: githubActionToken }),
|
|
2996
|
-
scanner:
|
|
3153
|
+
scanner: z9.nativeEnum(SCANNERS).parse(scanner)
|
|
2997
3154
|
})
|
|
2998
3155
|
);
|
|
2999
3156
|
}
|
|
@@ -3005,7 +3162,7 @@ async function _scan(params, { skipPrompts = false } = {}) {
|
|
|
3005
3162
|
try {
|
|
3006
3163
|
const sumbitRes = await gqlClient.submitVulnerabilityReport({
|
|
3007
3164
|
fixReportId: reportUploadInfo.fixReportId,
|
|
3008
|
-
repoUrl:
|
|
3165
|
+
repoUrl: z9.string().parse(repo),
|
|
3009
3166
|
reference,
|
|
3010
3167
|
projectId,
|
|
3011
3168
|
vulnerabilityReportFileName: "report.json",
|
|
@@ -3370,7 +3527,7 @@ var commitHashOption = {
|
|
|
3370
3527
|
// src/args/validation.ts
|
|
3371
3528
|
import chalk6 from "chalk";
|
|
3372
3529
|
import path7 from "path";
|
|
3373
|
-
import { z as
|
|
3530
|
+
import { z as z10 } from "zod";
|
|
3374
3531
|
function throwRepoUrlErrorMessage({
|
|
3375
3532
|
error,
|
|
3376
3533
|
repoUrl,
|
|
@@ -3387,7 +3544,7 @@ Example:
|
|
|
3387
3544
|
)}`;
|
|
3388
3545
|
throw new CliError(formattedErrorMessage);
|
|
3389
3546
|
}
|
|
3390
|
-
var UrlZ =
|
|
3547
|
+
var UrlZ = z10.string({
|
|
3391
3548
|
invalid_type_error: "is not a valid GitHub / GitLab URL"
|
|
3392
3549
|
}).refine((data) => !!parseScmURL(data), {
|
|
3393
3550
|
message: "is not a valid GitHub / GitLab URL"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mobbdev",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.68",
|
|
4
4
|
"description": "Automated secure code remediation tool",
|
|
5
5
|
"repository": "https://github.com/mobb-dev/bugsy",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
"@octokit/graphql": "5.0.5",
|
|
28
28
|
"@octokit/plugin-rest-endpoint-methods": "7.0.1",
|
|
29
29
|
"@octokit/request-error": "3.0.3",
|
|
30
|
+
"@types/libsodium-wrappers": "0.7.13",
|
|
30
31
|
"adm-zip": "0.5.10",
|
|
31
32
|
"axios": "1.5.0",
|
|
32
33
|
"chalk": "5.3.0",
|
|
@@ -42,6 +43,7 @@
|
|
|
42
43
|
"inquirer": "9.2.7",
|
|
43
44
|
"isomorphic-ws": "5.0.0",
|
|
44
45
|
"istextorbinary": "6.0.0",
|
|
46
|
+
"libsodium-wrappers": "0.7.13",
|
|
45
47
|
"nanospinner": "1.1.0",
|
|
46
48
|
"node-fetch": "3.3.1",
|
|
47
49
|
"octokit": "2.0.14",
|