mobbdev 0.0.66 → 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 +252 -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 */:
|
|
@@ -2228,54 +2339,94 @@ var getIssueType = (issueType) => {
|
|
|
2228
2339
|
return "Cookie is not HttpOnly";
|
|
2229
2340
|
case "INSECURE_COOKIE" /* InsecureCookie */:
|
|
2230
2341
|
return "Insecure Cookie";
|
|
2342
|
+
case "TRUST_BOUNDARY_VIOLATION" /* TrustBoundaryViolation */:
|
|
2343
|
+
return "Trust Boundary Violation";
|
|
2231
2344
|
default: {
|
|
2232
2345
|
return issueType ? issueType.replaceAll("_", " ") : "Other";
|
|
2233
2346
|
}
|
|
2234
2347
|
}
|
|
2235
2348
|
};
|
|
2236
2349
|
|
|
2237
|
-
// src/features/analysis/utils/index.ts
|
|
2238
|
-
function getFixUrlWithRedirect({
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
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());
|
|
2245
2364
|
return `${getFixUrl({
|
|
2365
|
+
appBaseUrl,
|
|
2246
2366
|
fixId,
|
|
2247
2367
|
projectId,
|
|
2248
2368
|
organizationId,
|
|
2249
2369
|
analysisId
|
|
2250
|
-
})}
|
|
2370
|
+
})}?${searchParams.toString()}`;
|
|
2251
2371
|
}
|
|
2252
2372
|
function getFixUrl({
|
|
2373
|
+
appBaseUrl,
|
|
2253
2374
|
fixId,
|
|
2254
2375
|
projectId,
|
|
2255
2376
|
organizationId,
|
|
2256
2377
|
analysisId
|
|
2257
2378
|
}) {
|
|
2258
|
-
return `${
|
|
2379
|
+
return `${appBaseUrl}/organization/${organizationId}/project/${projectId}/report/${analysisId}/fix/${fixId}`;
|
|
2259
2380
|
}
|
|
2260
|
-
function getCommitUrl({
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
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());
|
|
2267
2394
|
return `${getFixUrl({
|
|
2395
|
+
appBaseUrl,
|
|
2268
2396
|
fixId,
|
|
2269
2397
|
projectId,
|
|
2270
2398
|
organizationId,
|
|
2271
2399
|
analysisId
|
|
2272
|
-
})}/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;
|
|
2273
2426
|
}
|
|
2274
2427
|
|
|
2275
2428
|
// src/features/analysis/handle_finished_analysis.ts
|
|
2276
2429
|
var debug4 = Debug4("mobbdev:handle-finished-analysis");
|
|
2277
|
-
var MOBB_ICON_IMG = "";
|
|
2278
|
-
var COMMIT_FIX_SVG = `https://felt-laptop-20190711103614-deployment.s3.us-east-1.amazonaws.com/commit-button.svg`;
|
|
2279
2430
|
var commitFixButton = (commitUrl) => `<a href="${commitUrl}"><img src=${COMMIT_FIX_SVG}></a>`;
|
|
2280
2431
|
function scannerToFriendlyString(scanner) {
|
|
2281
2432
|
switch (scanner) {
|
|
@@ -2299,7 +2450,7 @@ async function getFixesFromDiff(params) {
|
|
|
2299
2450
|
});
|
|
2300
2451
|
const lineAddedRanges = calculateRanges(fileNumbers);
|
|
2301
2452
|
const fileFilter = {
|
|
2302
|
-
path:
|
|
2453
|
+
path: z8.string().parse(file.to),
|
|
2303
2454
|
ranges: lineAddedRanges.map(([startLine, endLine]) => ({
|
|
2304
2455
|
endLine,
|
|
2305
2456
|
startLine
|
|
@@ -2331,16 +2482,19 @@ async function handleFinishedAnalysis({
|
|
|
2331
2482
|
}
|
|
2332
2483
|
} = getAnalysis.analysis;
|
|
2333
2484
|
const { commitSha, pullRequest } = getAnalysis.analysis.repo;
|
|
2334
|
-
const
|
|
2485
|
+
const diff = await scm.getPrDiff({ pull_number: pullRequest });
|
|
2335
2486
|
const { vulnerabilityReportIssueCodeNodes } = await getFixesFromDiff({
|
|
2336
|
-
diff
|
|
2487
|
+
diff,
|
|
2337
2488
|
gqlClient,
|
|
2338
2489
|
vulnerabilityReportId: getAnalysis.analysis.vulnerabilityReportId
|
|
2339
2490
|
});
|
|
2340
|
-
const comments = await scm.getPrComments(
|
|
2491
|
+
const comments = await scm.getPrComments(
|
|
2492
|
+
{ pull_number: pullRequest },
|
|
2493
|
+
githubActionOctokit
|
|
2494
|
+
);
|
|
2341
2495
|
await Promise.all(
|
|
2342
2496
|
comments.data.filter((comment) => {
|
|
2343
|
-
return comment.body.includes(
|
|
2497
|
+
return comment.body.includes(MOBB_ICON_IMG);
|
|
2344
2498
|
}).map((comment) => {
|
|
2345
2499
|
try {
|
|
2346
2500
|
return scm.deleteComment(
|
|
@@ -2372,25 +2526,30 @@ async function handleFinishedAnalysis({
|
|
|
2372
2526
|
},
|
|
2373
2527
|
githubActionOctokit
|
|
2374
2528
|
);
|
|
2529
|
+
const commentId = commentRes.data.id;
|
|
2375
2530
|
const commitUrl = getCommitUrl({
|
|
2531
|
+
appBaseUrl: WEB_APP_URL,
|
|
2376
2532
|
fixId: fix_by_pk.id,
|
|
2377
2533
|
projectId,
|
|
2378
2534
|
analysisId,
|
|
2379
2535
|
organizationId,
|
|
2380
|
-
redirectUrl: commentRes.data.html_url
|
|
2536
|
+
redirectUrl: commentRes.data.html_url,
|
|
2537
|
+
commentId
|
|
2381
2538
|
});
|
|
2382
2539
|
const fixUrl = getFixUrlWithRedirect({
|
|
2540
|
+
appBaseUrl: WEB_APP_URL,
|
|
2383
2541
|
fixId: fix_by_pk.id,
|
|
2384
2542
|
projectId,
|
|
2385
2543
|
analysisId,
|
|
2386
2544
|
organizationId,
|
|
2387
|
-
redirectUrl: commentRes.data.html_url
|
|
2545
|
+
redirectUrl: commentRes.data.html_url,
|
|
2546
|
+
commentId
|
|
2388
2547
|
});
|
|
2389
2548
|
const scanerString = scannerToFriendlyString(scanner);
|
|
2390
2549
|
const issueType = getIssueType(fix_by_pk.issueType);
|
|
2391
|
-
const title = `# ${MOBB_ICON_IMG} ${issueType} fix by Mobb is ready`;
|
|
2550
|
+
const title = `#  ${issueType} fix by Mobb is ready`;
|
|
2392
2551
|
const subTitle = `### Apply the following code change to fix ${issueType} issue detected by ${scanerString}:`;
|
|
2393
|
-
const
|
|
2552
|
+
const diff2 = `\`\`\`diff
|
|
2394
2553
|
${patch}
|
|
2395
2554
|
\`\`\``;
|
|
2396
2555
|
const fixPageLink = `[Learn more and fine tune the fix](${fixUrl})`;
|
|
@@ -2398,12 +2557,12 @@ ${patch}
|
|
|
2398
2557
|
{
|
|
2399
2558
|
body: `${title}
|
|
2400
2559
|
${subTitle}
|
|
2401
|
-
${
|
|
2560
|
+
${diff2}
|
|
2402
2561
|
${commitFixButton(
|
|
2403
2562
|
commitUrl
|
|
2404
2563
|
)}
|
|
2405
2564
|
${fixPageLink}`,
|
|
2406
|
-
comment_id:
|
|
2565
|
+
comment_id: commentId
|
|
2407
2566
|
},
|
|
2408
2567
|
githubActionOctokit
|
|
2409
2568
|
);
|
|
@@ -2991,7 +3150,7 @@ async function _scan(params, { skipPrompts = false } = {}) {
|
|
|
2991
3150
|
gqlClient,
|
|
2992
3151
|
scm,
|
|
2993
3152
|
githubActionOctokit: new Octokit3({ auth: githubActionToken }),
|
|
2994
|
-
scanner:
|
|
3153
|
+
scanner: z9.nativeEnum(SCANNERS).parse(scanner)
|
|
2995
3154
|
})
|
|
2996
3155
|
);
|
|
2997
3156
|
}
|
|
@@ -3003,7 +3162,7 @@ async function _scan(params, { skipPrompts = false } = {}) {
|
|
|
3003
3162
|
try {
|
|
3004
3163
|
const sumbitRes = await gqlClient.submitVulnerabilityReport({
|
|
3005
3164
|
fixReportId: reportUploadInfo.fixReportId,
|
|
3006
|
-
repoUrl:
|
|
3165
|
+
repoUrl: z9.string().parse(repo),
|
|
3007
3166
|
reference,
|
|
3008
3167
|
projectId,
|
|
3009
3168
|
vulnerabilityReportFileName: "report.json",
|
|
@@ -3368,7 +3527,7 @@ var commitHashOption = {
|
|
|
3368
3527
|
// src/args/validation.ts
|
|
3369
3528
|
import chalk6 from "chalk";
|
|
3370
3529
|
import path7 from "path";
|
|
3371
|
-
import { z as
|
|
3530
|
+
import { z as z10 } from "zod";
|
|
3372
3531
|
function throwRepoUrlErrorMessage({
|
|
3373
3532
|
error,
|
|
3374
3533
|
repoUrl,
|
|
@@ -3385,7 +3544,7 @@ Example:
|
|
|
3385
3544
|
)}`;
|
|
3386
3545
|
throw new CliError(formattedErrorMessage);
|
|
3387
3546
|
}
|
|
3388
|
-
var UrlZ =
|
|
3547
|
+
var UrlZ = z10.string({
|
|
3389
3548
|
invalid_type_error: "is not a valid GitHub / GitLab URL"
|
|
3390
3549
|
}).refine((data) => !!parseScmURL(data), {
|
|
3391
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",
|