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.
Files changed (2) hide show
  1. package/dist/index.mjs +252 -93
  2. 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 z7 } from "zod";
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 z6 } from "zod";
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 z5 } from "zod";
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 getPr(client, params) {
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 SubmitFixesResponseMessageZ = z4.object({
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 FixesZ = z4.array(z4.object({ fixId: z4.string(), diff: z4.string() })).nonempty();
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 getPr(this.oktokit, {
1851
+ const prRes = await getPrDiff(this.oktokit, {
1743
1852
  ...params,
1744
1853
  owner,
1745
1854
  repo
1746
1855
  });
1747
- const diffUrl = prRes.data.diff_url;
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 = z5.object({
1920
- GITLAB_API_TOKEN: z5.string().optional()
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 = z5.object({
2150
- access_token: z5.string(),
2151
- token_type: z5.string(),
2152
- refresh_token: z5.string()
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/calculate_ranges.ts
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
- fixId,
2240
- projectId,
2241
- organizationId,
2242
- analysisId,
2243
- redirectUrl
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
- })}?commit_redirect_url=${encodeURIComponent(redirectUrl)}`;
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 `${WEB_APP_URL}/organization/${organizationId}/project/${projectId}/report/${analysisId}/fix/${fixId}`;
2379
+ return `${appBaseUrl}/organization/${organizationId}/project/${projectId}/report/${analysisId}/fix/${fixId}`;
2259
2380
  }
2260
- function getCommitUrl({
2261
- fixId,
2262
- projectId,
2263
- organizationId,
2264
- analysisId,
2265
- redirectUrl
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?redirect_url=${encodeURIComponent(redirectUrl)}`;
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 = "![image](https://github.com/yhaggai/GitHub-Fixer-Demo/assets/1255845/30f566df-6544-4612-929e-2ee5e8b9d345)";
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: z6.string().parse(file.to),
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 getPrDiff = await scm.getPrDiff({ pull_number: pullRequest });
2485
+ const diff = await scm.getPrDiff({ pull_number: pullRequest });
2335
2486
  const { vulnerabilityReportIssueCodeNodes } = await getFixesFromDiff({
2336
- diff: getPrDiff.data,
2487
+ diff,
2337
2488
  gqlClient,
2338
2489
  vulnerabilityReportId: getAnalysis.analysis.vulnerabilityReportId
2339
2490
  });
2340
- const comments = await scm.getPrComments({}, githubActionOctokit);
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("fix by Mobb is ready");
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 = `# ![image](${MOBB_ICON_IMG}) ${issueType} fix by Mobb is ready`;
2392
2551
  const subTitle = `### Apply the following code change to fix ${issueType} issue detected by ${scanerString}:`;
2393
- const diff = `\`\`\`diff
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
- ${diff}
2560
+ ${diff2}
2402
2561
  ${commitFixButton(
2403
2562
  commitUrl
2404
2563
  )}
2405
2564
  ${fixPageLink}`,
2406
- comment_id: commentRes.data.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: z7.nativeEnum(SCANNERS).parse(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: z7.string().parse(repo),
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 z8 } from "zod";
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 = z8.string({
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.66",
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",