mobbdev 0.0.140 → 0.0.142
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 +910 -940
- package/package.json +6 -6
package/dist/index.mjs
CHANGED
|
@@ -146,15 +146,17 @@ var MeDocument = `
|
|
|
146
146
|
}
|
|
147
147
|
`;
|
|
148
148
|
var GetOrgAndProjectIdDocument = `
|
|
149
|
-
query getOrgAndProjectId {
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
149
|
+
query getOrgAndProjectId($filters: organization_to_organization_role_bool_exp, $limit: Int) {
|
|
150
|
+
organization_to_organization_role(
|
|
151
|
+
where: $filters
|
|
152
|
+
order_by: {organization: {createdOn: desc}}
|
|
153
|
+
limit: $limit
|
|
154
|
+
) {
|
|
155
|
+
organization {
|
|
156
|
+
id
|
|
157
|
+
projects(order_by: {updatedAt: desc}) {
|
|
153
158
|
id
|
|
154
|
-
|
|
155
|
-
id
|
|
156
|
-
name
|
|
157
|
-
}
|
|
159
|
+
name
|
|
158
160
|
}
|
|
159
161
|
}
|
|
160
162
|
}
|
|
@@ -267,13 +269,12 @@ var GetVulByNodesMetadataDocument = `
|
|
|
267
269
|
}
|
|
268
270
|
`;
|
|
269
271
|
var UpdateScmTokenDocument = `
|
|
270
|
-
mutation updateScmToken($scmType: String!, $url: String!, $token: String!, $org: String, $
|
|
272
|
+
mutation updateScmToken($scmType: String!, $url: String!, $token: String!, $org: String, $refreshToken: String) {
|
|
271
273
|
updateScmToken(
|
|
272
274
|
scmType: $scmType
|
|
273
275
|
url: $url
|
|
274
276
|
token: $token
|
|
275
277
|
org: $org
|
|
276
|
-
username: $username
|
|
277
278
|
refreshToken: $refreshToken
|
|
278
279
|
) {
|
|
279
280
|
__typename
|
|
@@ -523,11 +524,11 @@ import chalk4 from "chalk";
|
|
|
523
524
|
import Configstore from "configstore";
|
|
524
525
|
import Debug12 from "debug";
|
|
525
526
|
import extract from "extract-zip";
|
|
526
|
-
import
|
|
527
|
+
import fetch4 from "node-fetch";
|
|
527
528
|
import open2 from "open";
|
|
528
529
|
import semver from "semver";
|
|
529
530
|
import tmp2 from "tmp";
|
|
530
|
-
import { z as
|
|
531
|
+
import { z as z11 } from "zod";
|
|
531
532
|
|
|
532
533
|
// src/features/analysis/add_fix_comments_for_pr/add_fix_comments_for_pr.ts
|
|
533
534
|
import Debug4 from "debug";
|
|
@@ -1208,236 +1209,31 @@ var AdoSdk = {
|
|
|
1208
1209
|
// src/features/analysis/scm/bitbucket/bitbucket.ts
|
|
1209
1210
|
import querystring3 from "node:querystring";
|
|
1210
1211
|
import * as bitbucketPkg from "bitbucket";
|
|
1211
|
-
import { z as z9 } from "zod";
|
|
1212
|
-
|
|
1213
|
-
// src/features/analysis/scm/scm.ts
|
|
1214
|
-
import { Octokit as Octokit2 } from "@octokit/core";
|
|
1215
1212
|
import { z as z8 } from "zod";
|
|
1216
1213
|
|
|
1217
|
-
// src/features/analysis/scm/
|
|
1218
|
-
import
|
|
1219
|
-
async function encryptSecret(secret, key) {
|
|
1220
|
-
await sodium.ready;
|
|
1221
|
-
const binkey = sodium.from_base64(key, sodium.base64_variants.ORIGINAL);
|
|
1222
|
-
const binsec = sodium.from_string(secret);
|
|
1223
|
-
const encBytes = sodium.crypto_box_seal(binsec, binkey);
|
|
1224
|
-
return sodium.to_base64(encBytes, sodium.base64_variants.ORIGINAL);
|
|
1225
|
-
}
|
|
1214
|
+
// src/features/analysis/scm/scm.ts
|
|
1215
|
+
import { z as z7 } from "zod";
|
|
1226
1216
|
|
|
1227
1217
|
// src/features/analysis/scm/github/github.ts
|
|
1228
1218
|
import { RequestError } from "@octokit/request-error";
|
|
1229
|
-
import { Octokit } from "octokit";
|
|
1230
|
-
import { z as z3 } from "zod";
|
|
1231
|
-
|
|
1232
|
-
// src/features/analysis/scm/utils/get_issue_type.ts
|
|
1233
|
-
var getIssueType = (issueType) => {
|
|
1234
|
-
switch (issueType) {
|
|
1235
|
-
case "SQL_Injection" /* SqlInjection */:
|
|
1236
|
-
return "SQL Injection";
|
|
1237
|
-
case "CMDi_relative_path_command" /* CmDiRelativePathCommand */:
|
|
1238
|
-
return "Relative Path Command Injection";
|
|
1239
|
-
case "CMDi" /* CmDi */:
|
|
1240
|
-
return "Command Injection";
|
|
1241
|
-
case "XXE" /* Xxe */:
|
|
1242
|
-
return "XXE";
|
|
1243
|
-
case "XSS" /* Xss */:
|
|
1244
|
-
return "XSS";
|
|
1245
|
-
case "PT" /* Pt */:
|
|
1246
|
-
return "Path Traversal";
|
|
1247
|
-
case "ZIP_SLIP" /* ZipSlip */:
|
|
1248
|
-
return "Zip Slip";
|
|
1249
|
-
case "INSECURE_RANDOMNESS" /* InsecureRandomness */:
|
|
1250
|
-
return "Insecure Randomness";
|
|
1251
|
-
case "SSRF" /* Ssrf */:
|
|
1252
|
-
return "Server Side Request Forgery";
|
|
1253
|
-
case "TYPE_CONFUSION" /* TypeConfusion */:
|
|
1254
|
-
return "Type Confusion";
|
|
1255
|
-
case "REGEX_INJECTION" /* RegexInjection */:
|
|
1256
|
-
return "Regular Expression Injection";
|
|
1257
|
-
case "INCOMPLETE_URL_SANITIZATION" /* IncompleteUrlSanitization */:
|
|
1258
|
-
return "Incomplete URL Sanitization";
|
|
1259
|
-
case "LOCALE_DEPENDENT_COMPARISON" /* LocaleDependentComparison */:
|
|
1260
|
-
return "Locale Dependent Comparison";
|
|
1261
|
-
case "LOG_FORGING" /* LogForging */:
|
|
1262
|
-
return "Log Forging";
|
|
1263
|
-
case "MISSING_CHECK_AGAINST_NULL" /* MissingCheckAgainstNull */:
|
|
1264
|
-
return "Missing Check against Null";
|
|
1265
|
-
case "PASSWORD_IN_COMMENT" /* PasswordInComment */:
|
|
1266
|
-
return "Password in Comment";
|
|
1267
|
-
case "OVERLY_BROAD_CATCH" /* OverlyBroadCatch */:
|
|
1268
|
-
return "Poor Error Handling: Overly Broad Catch";
|
|
1269
|
-
case "USE_OF_SYSTEM_OUTPUT_STREAM" /* UseOfSystemOutputStream */:
|
|
1270
|
-
return "Use of System.out/System.err";
|
|
1271
|
-
case "DANGEROUS_FUNCTION_OVERFLOW" /* DangerousFunctionOverflow */:
|
|
1272
|
-
return "Use of dangerous function";
|
|
1273
|
-
case "DOS_STRING_BUILDER" /* DosStringBuilder */:
|
|
1274
|
-
return "Denial of Service: StringBuilder";
|
|
1275
|
-
case "OPEN_REDIRECT" /* OpenRedirect */:
|
|
1276
|
-
return "Open Redirect";
|
|
1277
|
-
case "WEAK_XML_SCHEMA_UNBOUNDED_OCCURRENCES" /* WeakXmlSchemaUnboundedOccurrences */:
|
|
1278
|
-
return "Weak XML Schema: Unbounded Occurrences";
|
|
1279
|
-
case "SYSTEM_INFORMATION_LEAK" /* SystemInformationLeak */:
|
|
1280
|
-
return "System Information Leak";
|
|
1281
|
-
case "SYSTEM_INFORMATION_LEAK_EXTERNAL" /* SystemInformationLeakExternal */:
|
|
1282
|
-
return "External System Information Leak";
|
|
1283
|
-
case "HTTP_RESPONSE_SPLITTING" /* HttpResponseSplitting */:
|
|
1284
|
-
return "HTTP response splitting";
|
|
1285
|
-
case "HTTP_ONLY_COOKIE" /* HttpOnlyCookie */:
|
|
1286
|
-
return "Cookie is not HttpOnly";
|
|
1287
|
-
case "INSECURE_COOKIE" /* InsecureCookie */:
|
|
1288
|
-
return "Insecure Cookie";
|
|
1289
|
-
case "TRUST_BOUNDARY_VIOLATION" /* TrustBoundaryViolation */:
|
|
1290
|
-
return "Trust Boundary Violation";
|
|
1291
|
-
case "NULL_DEREFERENCE" /* NullDereference */:
|
|
1292
|
-
return "Null Dereference";
|
|
1293
|
-
case "UNSAFE_DESERIALIZATION" /* UnsafeDeserialization */:
|
|
1294
|
-
return "Unsafe deserialization";
|
|
1295
|
-
case "INSECURE_BINDER_CONFIGURATION" /* InsecureBinderConfiguration */:
|
|
1296
|
-
return "Insecure Binder Configuration";
|
|
1297
|
-
case "UNSAFE_TARGET_BLANK" /* UnsafeTargetBlank */:
|
|
1298
|
-
return "Unsafe use of target blank";
|
|
1299
|
-
case "IFRAME_WITHOUT_SANDBOX" /* IframeWithoutSandbox */:
|
|
1300
|
-
return "Client use of iframe without sandbox";
|
|
1301
|
-
case "JQUERY_DEPRECATED_SYMBOLS" /* JqueryDeprecatedSymbols */:
|
|
1302
|
-
return "jQuery deprecated symbols";
|
|
1303
|
-
case "MISSING_ANTIFORGERY_VALIDATION" /* MissingAntiforgeryValidation */:
|
|
1304
|
-
return "Missing Anti-Forgery Validation";
|
|
1305
|
-
case "GRAPHQL_DEPTH_LIMIT" /* GraphqlDepthLimit */:
|
|
1306
|
-
return "GraphQL Depth Limit";
|
|
1307
|
-
case "UNCHECKED_LOOP_CONDITION" /* UncheckedLoopCondition */:
|
|
1308
|
-
return "Unchecked Loop Condition";
|
|
1309
|
-
case "IMPROPER_RESOURCE_SHUTDOWN_OR_RELEASE" /* ImproperResourceShutdownOrRelease */:
|
|
1310
|
-
return "Improper Resource Shutdown or Release";
|
|
1311
|
-
case "IMPROPER_EXCEPTION_HANDLING" /* ImproperExceptionHandling */:
|
|
1312
|
-
return "Improper Exception Handling";
|
|
1313
|
-
case "DEFAULT_RIGHTS_IN_OBJ_DEFINITION" /* DefaultRightsInObjDefinition */:
|
|
1314
|
-
return "Default Definer Rights in Package or Object Definition";
|
|
1315
|
-
case "HTML_COMMENT_IN_JSP" /* HtmlCommentInJsp */:
|
|
1316
|
-
return "HTML Comment in JSP";
|
|
1317
|
-
case "ERROR_CONDTION_WITHOUT_ACTION" /* ErrorCondtionWithoutAction */:
|
|
1318
|
-
return "Error Condition Without Action";
|
|
1319
|
-
case "DEPRECATED_FUNCTION" /* DeprecatedFunction */:
|
|
1320
|
-
return "Deprecated Function";
|
|
1321
|
-
case "HARDCODED_SECRETS" /* HardcodedSecrets */:
|
|
1322
|
-
return "Hardcoded Secrets";
|
|
1323
|
-
case "PROTOTYPE_POLLUTION" /* PrototypePollution */:
|
|
1324
|
-
return "Prototype Pollution";
|
|
1325
|
-
case "RACE_CONDITION_FORMAT_FLAW" /* RaceConditionFormatFlaw */:
|
|
1326
|
-
return "Race Condition Format Flaw";
|
|
1327
|
-
case "NON_FINAL_PUBLIC_STATIC_FIELD" /* NonFinalPublicStaticField */:
|
|
1328
|
-
return "Non-final Public Static Field";
|
|
1329
|
-
case "MISSING_HSTS_HEADER" /* MissingHstsHeader */:
|
|
1330
|
-
return "Missing HSTS Header";
|
|
1331
|
-
case "DEAD_CODE_UNUSED_FIELD" /* DeadCodeUnusedField */:
|
|
1332
|
-
return "Dead Code: Unused Field";
|
|
1333
|
-
case "HEADER_MANIPULATION" /* HeaderManipulation */:
|
|
1334
|
-
return "Header Manipulation";
|
|
1335
|
-
case "MISSING_EQUALS_OR_HASHCODE" /* MissingEqualsOrHashcode */:
|
|
1336
|
-
return "Missing equals or hashcode method";
|
|
1337
|
-
case "WCF_MISCONFIGURATION_INSUFFICIENT_LOGGING" /* WcfMisconfigurationInsufficientLogging */:
|
|
1338
|
-
return "WCF Misconfiguration: Insufficient Logging";
|
|
1339
|
-
case "WCF_MISCONFIGURATION_THROTTLING_NOT_ENABLED" /* WcfMisconfigurationThrottlingNotEnabled */:
|
|
1340
|
-
return "WCF Misconfiguration: Throttling Not Enabled";
|
|
1341
|
-
case "USELESS_REGEXP_CHAR_ESCAPE" /* UselessRegexpCharEscape */:
|
|
1342
|
-
return "Useless regular-expression character escape";
|
|
1343
|
-
case "INCOMPLETE_HOSTNAME_REGEX" /* IncompleteHostnameRegex */:
|
|
1344
|
-
return "Incomplete Hostname Regex";
|
|
1345
|
-
case "OVERLY_LARGE_RANGE" /* OverlyLargeRange */:
|
|
1346
|
-
return "Regex: Overly Large Range";
|
|
1347
|
-
case "INSUFFICIENT_LOGGING" /* InsufficientLogging */:
|
|
1348
|
-
return "Insufficient Logging of Sensitive Operations";
|
|
1349
|
-
case "PRIVACY_VIOLATION" /* PrivacyViolation */:
|
|
1350
|
-
return "Privacy Violation";
|
|
1351
|
-
case "INCOMPLETE_URL_SCHEME_CHECK" /* IncompleteUrlSchemeCheck */:
|
|
1352
|
-
return "Incomplete URL Scheme Check";
|
|
1353
|
-
case "VALUE_NEVER_READ" /* ValueNeverRead */:
|
|
1354
|
-
return "Value Never Read";
|
|
1355
|
-
case "VALUE_SHADOWING" /* ValueShadowing */:
|
|
1356
|
-
return "Value Shadowing";
|
|
1357
|
-
default: {
|
|
1358
|
-
return issueType ? issueType.replaceAll("_", " ") : "Other";
|
|
1359
|
-
}
|
|
1360
|
-
}
|
|
1361
|
-
};
|
|
1362
|
-
|
|
1363
|
-
// src/features/analysis/scm/utils/index.ts
|
|
1364
|
-
function getFixUrlWithRedirect(params) {
|
|
1365
|
-
const {
|
|
1366
|
-
fixId,
|
|
1367
|
-
projectId,
|
|
1368
|
-
organizationId,
|
|
1369
|
-
analysisId,
|
|
1370
|
-
redirectUrl,
|
|
1371
|
-
appBaseUrl,
|
|
1372
|
-
commentId
|
|
1373
|
-
} = params;
|
|
1374
|
-
const searchParams = new URLSearchParams();
|
|
1375
|
-
searchParams.append("commit_redirect_url", redirectUrl);
|
|
1376
|
-
searchParams.append("comment_id", commentId.toString());
|
|
1377
|
-
return `${getFixUrl({
|
|
1378
|
-
appBaseUrl,
|
|
1379
|
-
fixId,
|
|
1380
|
-
projectId,
|
|
1381
|
-
organizationId,
|
|
1382
|
-
analysisId
|
|
1383
|
-
})}?${searchParams.toString()}`;
|
|
1384
|
-
}
|
|
1385
|
-
function getFixUrl({
|
|
1386
|
-
appBaseUrl,
|
|
1387
|
-
fixId,
|
|
1388
|
-
projectId,
|
|
1389
|
-
organizationId,
|
|
1390
|
-
analysisId
|
|
1391
|
-
}) {
|
|
1392
|
-
return `${appBaseUrl}/organization/${organizationId}/project/${projectId}/report/${analysisId}/fix/${fixId}`;
|
|
1393
|
-
}
|
|
1394
|
-
function getCommitUrl(params) {
|
|
1395
|
-
const {
|
|
1396
|
-
fixId,
|
|
1397
|
-
projectId,
|
|
1398
|
-
organizationId,
|
|
1399
|
-
analysisId,
|
|
1400
|
-
redirectUrl,
|
|
1401
|
-
appBaseUrl,
|
|
1402
|
-
commentId
|
|
1403
|
-
} = params;
|
|
1404
|
-
const searchParams = new URLSearchParams();
|
|
1405
|
-
searchParams.append("redirect_url", redirectUrl);
|
|
1406
|
-
searchParams.append("comment_id", commentId.toString());
|
|
1407
|
-
return `${getFixUrl({
|
|
1408
|
-
appBaseUrl,
|
|
1409
|
-
fixId,
|
|
1410
|
-
projectId,
|
|
1411
|
-
organizationId,
|
|
1412
|
-
analysisId
|
|
1413
|
-
})}/commit?${searchParams.toString()}`;
|
|
1414
|
-
}
|
|
1415
|
-
var userNamePattern = /^(https?:\/\/)([^@]+@)?([^/]+\/.+)$/;
|
|
1416
|
-
var sshPattern = /^git@([\w.-]+):([\w./-]+)$/;
|
|
1417
|
-
function normalizeUrl(repoUrl) {
|
|
1418
|
-
let trimmedUrl = repoUrl.trim().replace(/\/+$/, "");
|
|
1419
|
-
if (repoUrl.endsWith(".git")) {
|
|
1420
|
-
trimmedUrl = trimmedUrl.slice(0, -".git".length);
|
|
1421
|
-
}
|
|
1422
|
-
const usernameMatch = trimmedUrl.match(userNamePattern);
|
|
1423
|
-
if (usernameMatch) {
|
|
1424
|
-
const [_all, protocol, _username, repoPath] = usernameMatch;
|
|
1425
|
-
trimmedUrl = `${protocol}${repoPath}`;
|
|
1426
|
-
}
|
|
1427
|
-
const sshMatch = trimmedUrl.match(sshPattern);
|
|
1428
|
-
if (sshMatch) {
|
|
1429
|
-
const [_all, hostname, reporPath] = sshMatch;
|
|
1430
|
-
trimmedUrl = `https://${hostname}/${reporPath}`;
|
|
1431
|
-
}
|
|
1432
|
-
return trimmedUrl;
|
|
1433
|
-
}
|
|
1434
1219
|
|
|
1435
|
-
// src/features/analysis/scm/github/
|
|
1436
|
-
var
|
|
1437
|
-
|
|
1438
|
-
}
|
|
1439
|
-
var
|
|
1440
|
-
var
|
|
1220
|
+
// src/features/analysis/scm/github/consts.ts
|
|
1221
|
+
var POST_COMMENT_PATH = "POST /repos/{owner}/{repo}/pulls/{pull_number}/comments";
|
|
1222
|
+
var DELETE_COMMENT_PATH = "DELETE /repos/{owner}/{repo}/pulls/comments/{comment_id}";
|
|
1223
|
+
var UPDATE_COMMENT_PATH = "PATCH /repos/{owner}/{repo}/pulls/comments/{comment_id}";
|
|
1224
|
+
var GET_PR_COMMENTS_PATH = "GET /repos/{owner}/{repo}/pulls/{pull_number}/comments";
|
|
1225
|
+
var GET_PR_COMMENT_PATH = "GET /repos/{owner}/{repo}/pulls/comments/{comment_id}";
|
|
1226
|
+
var REPLY_TO_CODE_REVIEW_COMMENT_PATH = "POST /repos/{owner}/{repo}/pulls/{pull_number}/comments/{comment_id}/replies";
|
|
1227
|
+
var GET_PR = "GET /repos/{owner}/{repo}/pulls/{pull_number}";
|
|
1228
|
+
var POST_GENERAL_PR_COMMENT = "POST /repos/{owner}/{repo}/issues/{issue_number}/comments";
|
|
1229
|
+
var GET_GENERAL_PR_COMMENTS = "GET /repos/{owner}/{repo}/issues/{issue_number}/comments";
|
|
1230
|
+
var DELETE_GENERAL_PR_COMMENT = "DELETE /repos/{owner}/{repo}/issues/comments/{comment_id}";
|
|
1231
|
+
var CREATE_OR_UPDATE_A_REPOSITORY_SECRET = "PUT /repos/{owner}/{repo}/actions/secrets/{secret_name}";
|
|
1232
|
+
var GET_A_REPOSITORY_PUBLIC_KEY = "GET /repos/{owner}/{repo}/actions/secrets/public-key";
|
|
1233
|
+
var GET_USER = "GET /user";
|
|
1234
|
+
var GET_USER_REPOS = "GET /user/repos";
|
|
1235
|
+
var GET_REPO_BRANCHES = "GET /repos/{owner}/{repo}/branches";
|
|
1236
|
+
var GET_BLAME_DOCUMENT = `
|
|
1441
1237
|
query GetBlame(
|
|
1442
1238
|
$owner: String!
|
|
1443
1239
|
$repo: String!
|
|
@@ -1472,22 +1268,79 @@ var GetBlameDocument = `
|
|
|
1472
1268
|
}
|
|
1473
1269
|
}
|
|
1474
1270
|
`;
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1271
|
+
|
|
1272
|
+
// src/features/analysis/scm/github/utils/encrypt_secret.ts
|
|
1273
|
+
import sodium from "libsodium-wrappers";
|
|
1274
|
+
async function encryptSecret(secret, key) {
|
|
1275
|
+
await sodium.ready;
|
|
1276
|
+
const binkey = sodium.from_base64(key, sodium.base64_variants.ORIGINAL);
|
|
1277
|
+
const binsec = sodium.from_string(secret);
|
|
1278
|
+
const encBytes = sodium.crypto_box_seal(binsec, binkey);
|
|
1279
|
+
return sodium.to_base64(encBytes, sodium.base64_variants.ORIGINAL);
|
|
1481
1280
|
}
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1281
|
+
|
|
1282
|
+
// src/features/analysis/scm/github/utils/utils.ts
|
|
1283
|
+
import { Octokit } from "octokit";
|
|
1284
|
+
import { fetch as fetch2, ProxyAgent } from "undici";
|
|
1285
|
+
function parseGithubOwnerAndRepo(gitHubUrl) {
|
|
1286
|
+
gitHubUrl = normalizeUrl(gitHubUrl);
|
|
1287
|
+
const parsingResult = parseScmURL(gitHubUrl, "GitHub" /* GitHub */);
|
|
1288
|
+
if (!parsingResult) {
|
|
1289
|
+
throw new InvalidUrlPatternError(`invalid github repo Url ${gitHubUrl}`);
|
|
1290
|
+
}
|
|
1291
|
+
const { organization, repoName } = parsingResult;
|
|
1292
|
+
if (!organization || !repoName) {
|
|
1293
|
+
throw new InvalidUrlPatternError(`invalid github repo Url ${gitHubUrl}`);
|
|
1294
|
+
}
|
|
1295
|
+
return { owner: organization, repo: repoName };
|
|
1296
|
+
}
|
|
1297
|
+
function isGithubOnPrem(url) {
|
|
1298
|
+
if (!url) {
|
|
1299
|
+
return false;
|
|
1300
|
+
}
|
|
1301
|
+
return !url.includes(scmCloudUrl.GitHub);
|
|
1302
|
+
}
|
|
1303
|
+
function getFetch(url) {
|
|
1304
|
+
if (url && BROKERED_HOSTS.includes(new URL(url).origin)) {
|
|
1305
|
+
const dispatcher = new ProxyAgent({
|
|
1306
|
+
uri: process.env["GIT_PROXY_HOST"] || "http://tinyproxy:8888",
|
|
1307
|
+
requestTls: {
|
|
1308
|
+
rejectUnauthorized: false
|
|
1309
|
+
}
|
|
1310
|
+
});
|
|
1311
|
+
return (input, init) => {
|
|
1312
|
+
return fetch2(input, {
|
|
1313
|
+
...init,
|
|
1314
|
+
dispatcher
|
|
1315
|
+
});
|
|
1316
|
+
};
|
|
1317
|
+
}
|
|
1318
|
+
return fetch2;
|
|
1319
|
+
}
|
|
1320
|
+
function getOktoKit(options) {
|
|
1321
|
+
const token = !options?.auth && !isGithubOnPrem(options?.url) ? GITHUB_API_TOKEN : options?.auth;
|
|
1322
|
+
const baseUrl = options?.url && isGithubOnPrem(options.url) ? `${new URL(options.url).origin}/api/v3` : void 0;
|
|
1323
|
+
return new Octokit({
|
|
1324
|
+
...options,
|
|
1325
|
+
auth: token,
|
|
1326
|
+
baseUrl,
|
|
1327
|
+
request: {
|
|
1328
|
+
fetch: getFetch(baseUrl)
|
|
1329
|
+
}
|
|
1330
|
+
});
|
|
1331
|
+
}
|
|
1332
|
+
function isGithubActionActionToken(token) {
|
|
1333
|
+
return token.startsWith("ghs_");
|
|
1334
|
+
}
|
|
1335
|
+
async function githubValidateParams(url, accessToken) {
|
|
1336
|
+
try {
|
|
1337
|
+
const oktoKit = getOktoKit({ auth: accessToken, url });
|
|
1338
|
+
if (accessToken && !isGithubActionActionToken(accessToken)) {
|
|
1339
|
+
await oktoKit.rest.users.getAuthenticated();
|
|
1340
|
+
}
|
|
1341
|
+
if (url && shouldValidateUrl(url)) {
|
|
1342
|
+
const { owner, repo } = parseGithubOwnerAndRepo(url);
|
|
1343
|
+
await oktoKit.request(GET_REPO_BRANCHES, {
|
|
1491
1344
|
owner,
|
|
1492
1345
|
repo,
|
|
1493
1346
|
per_page: 1
|
|
@@ -1506,426 +1359,594 @@ async function githubValidateParams(url, accessToken) {
|
|
|
1506
1359
|
throw e;
|
|
1507
1360
|
}
|
|
1508
1361
|
}
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
async
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
}
|
|
1523
|
-
|
|
1524
|
-
return
|
|
1525
|
-
}
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
}
|
|
1547
|
-
async
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
}
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1362
|
+
|
|
1363
|
+
// src/features/analysis/scm/github/github.ts
|
|
1364
|
+
function getGithubSdk(parmas = {}) {
|
|
1365
|
+
const octokit = getOktoKit(parmas);
|
|
1366
|
+
return {
|
|
1367
|
+
async postPrComment(params) {
|
|
1368
|
+
return octokit.request(POST_COMMENT_PATH, params);
|
|
1369
|
+
},
|
|
1370
|
+
async updatePrComment(params) {
|
|
1371
|
+
return octokit.request(UPDATE_COMMENT_PATH, params);
|
|
1372
|
+
},
|
|
1373
|
+
async getPrComments(params) {
|
|
1374
|
+
return octokit.request(GET_PR_COMMENTS_PATH, params);
|
|
1375
|
+
},
|
|
1376
|
+
async getPrComment(params) {
|
|
1377
|
+
return octokit.request(GET_PR_COMMENT_PATH, params);
|
|
1378
|
+
},
|
|
1379
|
+
async deleteComment(params) {
|
|
1380
|
+
return octokit.request(DELETE_COMMENT_PATH, params);
|
|
1381
|
+
},
|
|
1382
|
+
async replyToCodeReviewComment(params) {
|
|
1383
|
+
return octokit.request(REPLY_TO_CODE_REVIEW_COMMENT_PATH, params);
|
|
1384
|
+
},
|
|
1385
|
+
async getPrDiff(params) {
|
|
1386
|
+
return octokit.request(GET_PR, {
|
|
1387
|
+
...params,
|
|
1388
|
+
mediaType: { format: "diff" }
|
|
1389
|
+
});
|
|
1390
|
+
},
|
|
1391
|
+
async getPr(params) {
|
|
1392
|
+
return octokit.request(GET_PR, { ...params });
|
|
1393
|
+
},
|
|
1394
|
+
async createOrUpdateRepositorySecret(params) {
|
|
1395
|
+
return octokit.request(CREATE_OR_UPDATE_A_REPOSITORY_SECRET, params);
|
|
1396
|
+
},
|
|
1397
|
+
async getRepositoryPublicKey(params) {
|
|
1398
|
+
return octokit.request(GET_A_REPOSITORY_PUBLIC_KEY, params);
|
|
1399
|
+
},
|
|
1400
|
+
async postGeneralPrComment(params) {
|
|
1401
|
+
return octokit.request(POST_GENERAL_PR_COMMENT, params);
|
|
1402
|
+
},
|
|
1403
|
+
async getGeneralPrComments(params) {
|
|
1404
|
+
return octokit.request(GET_GENERAL_PR_COMMENTS, params);
|
|
1405
|
+
},
|
|
1406
|
+
async deleteGeneralPrComment(params) {
|
|
1407
|
+
return octokit.request(DELETE_GENERAL_PR_COMMENT, params);
|
|
1408
|
+
},
|
|
1409
|
+
async getGithubUsername() {
|
|
1410
|
+
const res = await octokit.rest.users.getAuthenticated();
|
|
1411
|
+
return res.data.login;
|
|
1412
|
+
},
|
|
1413
|
+
async getGithubIsUserCollaborator(params) {
|
|
1414
|
+
const { username, repoUrl } = params;
|
|
1415
|
+
try {
|
|
1416
|
+
const { owner, repo } = parseGithubOwnerAndRepo(repoUrl);
|
|
1417
|
+
const res = await octokit.rest.repos.checkCollaborator({
|
|
1418
|
+
owner,
|
|
1419
|
+
repo,
|
|
1420
|
+
username
|
|
1421
|
+
});
|
|
1422
|
+
if (res.status === 204) {
|
|
1423
|
+
return true;
|
|
1570
1424
|
}
|
|
1571
|
-
|
|
1425
|
+
} catch (e) {
|
|
1426
|
+
return false;
|
|
1427
|
+
}
|
|
1428
|
+
return false;
|
|
1429
|
+
},
|
|
1430
|
+
async getGithubPullRequestStatus(params) {
|
|
1431
|
+
const { repoUrl, prNumber } = params;
|
|
1432
|
+
const { owner, repo } = parseGithubOwnerAndRepo(repoUrl);
|
|
1433
|
+
const res = await octokit.rest.pulls.get({
|
|
1434
|
+
owner,
|
|
1435
|
+
repo,
|
|
1436
|
+
pull_number: prNumber
|
|
1437
|
+
});
|
|
1438
|
+
if (res.data.merged) {
|
|
1439
|
+
return "merged";
|
|
1440
|
+
}
|
|
1441
|
+
if (res.data.draft) {
|
|
1442
|
+
return "draft";
|
|
1443
|
+
}
|
|
1444
|
+
return res.data.state;
|
|
1445
|
+
},
|
|
1446
|
+
async getGithubIsRemoteBranch(params) {
|
|
1447
|
+
const { repoUrl, branch } = params;
|
|
1448
|
+
const { owner, repo } = parseGithubOwnerAndRepo(repoUrl);
|
|
1449
|
+
try {
|
|
1450
|
+
const res = await octokit.rest.repos.getBranch({
|
|
1451
|
+
owner,
|
|
1452
|
+
repo,
|
|
1453
|
+
branch
|
|
1454
|
+
});
|
|
1455
|
+
return branch === res.data.name;
|
|
1456
|
+
} catch (e) {
|
|
1457
|
+
return false;
|
|
1458
|
+
}
|
|
1459
|
+
},
|
|
1460
|
+
async getGithubRepoList() {
|
|
1461
|
+
try {
|
|
1462
|
+
const githubRepos = await octokit.request(GET_USER_REPOS, {
|
|
1463
|
+
sort: "updated"
|
|
1464
|
+
});
|
|
1465
|
+
return githubRepos.data.map((repo) => ({
|
|
1572
1466
|
repoName: repo.name,
|
|
1573
1467
|
repoUrl: repo.html_url,
|
|
1574
1468
|
repoOwner: repo.owner.login,
|
|
1575
|
-
repoLanguages,
|
|
1469
|
+
repoLanguages: repo.language ? [repo.language] : [],
|
|
1576
1470
|
repoIsPublic: !repo.private,
|
|
1577
1471
|
repoUpdatedAt: repo.updated_at
|
|
1578
|
-
};
|
|
1472
|
+
}));
|
|
1473
|
+
} catch (e) {
|
|
1474
|
+
if (e instanceof RequestError && e.status === 401) {
|
|
1475
|
+
return [];
|
|
1476
|
+
}
|
|
1477
|
+
if (e instanceof RequestError && e.status === 404) {
|
|
1478
|
+
return [];
|
|
1479
|
+
}
|
|
1480
|
+
throw e;
|
|
1579
1481
|
}
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
}
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
}
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
const res = await oktoKit.rest.repos.createFork({
|
|
1621
|
-
owner,
|
|
1622
|
-
repo,
|
|
1623
|
-
default_branch_only: false
|
|
1624
|
-
});
|
|
1625
|
-
return { url: res.data.html_url ? String(res.data.html_url) : null };
|
|
1626
|
-
}
|
|
1627
|
-
async function getRepos(oktoKit) {
|
|
1628
|
-
const res = await oktoKit.request("GET /user/repos?sort=updated", {
|
|
1629
|
-
headers: {
|
|
1630
|
-
"X-GitHub-Api-Version": "2022-11-28",
|
|
1631
|
-
per_page: 100
|
|
1632
|
-
}
|
|
1633
|
-
});
|
|
1634
|
-
return res.data;
|
|
1635
|
-
}
|
|
1636
|
-
async function getGithubRepoDefaultBranch(repoUrl, options) {
|
|
1637
|
-
const oktoKit = getOktoKit(options);
|
|
1638
|
-
const { owner, repo } = parseGithubOwnerAndRepo(repoUrl);
|
|
1639
|
-
return (await oktoKit.rest.repos.get({ repo, owner })).data.default_branch;
|
|
1640
|
-
}
|
|
1641
|
-
async function getGithubReferenceData({ ref, gitHubUrl }, options) {
|
|
1642
|
-
const { owner, repo } = parseGithubOwnerAndRepo(gitHubUrl);
|
|
1643
|
-
let res;
|
|
1644
|
-
try {
|
|
1645
|
-
const oktoKit = getOktoKit(options);
|
|
1646
|
-
res = await Promise.any([
|
|
1647
|
-
getBranch({ owner, repo, branch: ref }, oktoKit).then((result) => ({
|
|
1648
|
-
date: result.data.commit.commit.committer?.date ? new Date(result.data.commit.commit.committer?.date) : void 0,
|
|
1649
|
-
type: "BRANCH" /* BRANCH */,
|
|
1650
|
-
sha: result.data.commit.sha
|
|
1651
|
-
})),
|
|
1652
|
-
getCommit({ commitSha: ref, repo, owner }, oktoKit).then((commit) => ({
|
|
1653
|
-
date: new Date(commit.data.committer.date),
|
|
1654
|
-
type: "COMMIT" /* COMMIT */,
|
|
1655
|
-
sha: commit.data.sha
|
|
1656
|
-
})),
|
|
1657
|
-
getTagDate({ owner, repo, tag: ref }, oktoKit).then((data) => ({
|
|
1658
|
-
date: new Date(data.date),
|
|
1659
|
-
type: "TAG" /* TAG */,
|
|
1660
|
-
sha: data.sha
|
|
1661
|
-
}))
|
|
1662
|
-
]);
|
|
1663
|
-
return res;
|
|
1664
|
-
} catch (e) {
|
|
1665
|
-
if (e instanceof AggregateError) {
|
|
1666
|
-
throw new RefNotFoundError(`ref: ${ref} does not exist`);
|
|
1667
|
-
}
|
|
1668
|
-
throw e;
|
|
1669
|
-
}
|
|
1670
|
-
}
|
|
1671
|
-
async function getBranch({ branch, owner, repo }, oktoKit) {
|
|
1672
|
-
return oktoKit.rest.repos.getBranch({
|
|
1673
|
-
branch,
|
|
1674
|
-
owner,
|
|
1675
|
-
repo
|
|
1676
|
-
});
|
|
1677
|
-
}
|
|
1678
|
-
async function getTagDate({ tag, owner, repo }, oktoKit) {
|
|
1679
|
-
const refResponse = await oktoKit.rest.git.getRef({
|
|
1680
|
-
ref: `tags/${tag}`,
|
|
1681
|
-
owner,
|
|
1682
|
-
repo
|
|
1683
|
-
});
|
|
1684
|
-
const tagSha = refResponse.data.object.sha;
|
|
1685
|
-
if (refResponse.data.object.type === "commit") {
|
|
1686
|
-
const res2 = await oktoKit.rest.git.getCommit({
|
|
1687
|
-
commit_sha: tagSha,
|
|
1482
|
+
},
|
|
1483
|
+
async getGithubRepoDefaultBranch(repoUrl) {
|
|
1484
|
+
const { owner, repo } = parseGithubOwnerAndRepo(repoUrl);
|
|
1485
|
+
const repos = await octokit.rest.repos.get({ repo, owner });
|
|
1486
|
+
return repos.data.default_branch;
|
|
1487
|
+
},
|
|
1488
|
+
async getGithubReferenceData({
|
|
1489
|
+
ref,
|
|
1490
|
+
gitHubUrl
|
|
1491
|
+
}) {
|
|
1492
|
+
const { owner, repo } = parseGithubOwnerAndRepo(gitHubUrl);
|
|
1493
|
+
let res;
|
|
1494
|
+
try {
|
|
1495
|
+
res = await Promise.any([
|
|
1496
|
+
this.getBranch({ owner, repo, branch: ref }).then((result) => ({
|
|
1497
|
+
date: result.data.commit.commit.committer?.date ? new Date(result.data.commit.commit.committer?.date) : void 0,
|
|
1498
|
+
type: "BRANCH" /* BRANCH */,
|
|
1499
|
+
sha: result.data.commit.sha
|
|
1500
|
+
})),
|
|
1501
|
+
this.getCommit({ commitSha: ref, repo, owner }).then((commit) => ({
|
|
1502
|
+
date: new Date(commit.data.committer.date),
|
|
1503
|
+
type: "COMMIT" /* COMMIT */,
|
|
1504
|
+
sha: commit.data.sha
|
|
1505
|
+
})),
|
|
1506
|
+
this.getTagDate({ owner, repo, tag: ref }).then((data) => ({
|
|
1507
|
+
date: new Date(data.date),
|
|
1508
|
+
type: "TAG" /* TAG */,
|
|
1509
|
+
sha: data.sha
|
|
1510
|
+
}))
|
|
1511
|
+
]);
|
|
1512
|
+
return res;
|
|
1513
|
+
} catch (e) {
|
|
1514
|
+
if (e instanceof AggregateError) {
|
|
1515
|
+
throw new RefNotFoundError(`ref: ${ref} does not exist`);
|
|
1516
|
+
}
|
|
1517
|
+
throw e;
|
|
1518
|
+
}
|
|
1519
|
+
},
|
|
1520
|
+
async getBranch({
|
|
1521
|
+
branch,
|
|
1688
1522
|
owner,
|
|
1689
1523
|
repo
|
|
1690
|
-
})
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
}
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1524
|
+
}) {
|
|
1525
|
+
return octokit.rest.repos.getBranch({
|
|
1526
|
+
branch,
|
|
1527
|
+
owner,
|
|
1528
|
+
repo
|
|
1529
|
+
});
|
|
1530
|
+
},
|
|
1531
|
+
async getCommit({
|
|
1532
|
+
commitSha,
|
|
1533
|
+
owner,
|
|
1534
|
+
repo
|
|
1535
|
+
}) {
|
|
1536
|
+
return octokit.rest.git.getCommit({
|
|
1537
|
+
repo,
|
|
1538
|
+
owner,
|
|
1539
|
+
commit_sha: commitSha
|
|
1540
|
+
});
|
|
1541
|
+
},
|
|
1542
|
+
async getTagDate({
|
|
1543
|
+
tag,
|
|
1544
|
+
owner,
|
|
1545
|
+
repo
|
|
1546
|
+
}) {
|
|
1547
|
+
const refResponse = await octokit.rest.git.getRef({
|
|
1548
|
+
ref: `tags/${tag}`,
|
|
1549
|
+
owner,
|
|
1550
|
+
repo
|
|
1551
|
+
});
|
|
1552
|
+
const tagSha = refResponse.data.object.sha;
|
|
1553
|
+
if (refResponse.data.object.type === "commit") {
|
|
1554
|
+
const res2 = await octokit.rest.git.getCommit({
|
|
1555
|
+
commit_sha: tagSha,
|
|
1556
|
+
owner,
|
|
1557
|
+
repo
|
|
1558
|
+
});
|
|
1559
|
+
return {
|
|
1560
|
+
date: res2.data.committer.date,
|
|
1561
|
+
sha: res2.data.sha
|
|
1562
|
+
};
|
|
1563
|
+
}
|
|
1564
|
+
const res = await octokit.rest.git.getTag({
|
|
1565
|
+
tag_sha: tagSha,
|
|
1566
|
+
owner,
|
|
1567
|
+
repo
|
|
1568
|
+
});
|
|
1569
|
+
return {
|
|
1570
|
+
date: res.data.tagger.date,
|
|
1571
|
+
sha: res.data.sha
|
|
1572
|
+
};
|
|
1573
|
+
},
|
|
1574
|
+
async getGithubBlameRanges(params) {
|
|
1575
|
+
const { ref, gitHubUrl, path: path9 } = params;
|
|
1576
|
+
const { owner, repo } = parseGithubOwnerAndRepo(gitHubUrl);
|
|
1577
|
+
const res = await octokit.graphql(
|
|
1578
|
+
GET_BLAME_DOCUMENT,
|
|
1579
|
+
{
|
|
1580
|
+
owner,
|
|
1581
|
+
repo,
|
|
1582
|
+
path: path9,
|
|
1583
|
+
ref
|
|
1584
|
+
}
|
|
1585
|
+
);
|
|
1586
|
+
if (!res?.repository?.object?.blame?.ranges) {
|
|
1587
|
+
return [];
|
|
1588
|
+
}
|
|
1589
|
+
return res.repository.object.blame.ranges.map((range) => ({
|
|
1590
|
+
startingLine: range.startingLine,
|
|
1591
|
+
endingLine: range.endingLine,
|
|
1592
|
+
email: range.commit.author.user?.email || "",
|
|
1593
|
+
name: range.commit.author.user?.name || "",
|
|
1594
|
+
login: range.commit.author.user?.login || ""
|
|
1595
|
+
}));
|
|
1596
|
+
},
|
|
1597
|
+
// todo: refactor the name for this function
|
|
1598
|
+
async createPr(params) {
|
|
1599
|
+
const { sourceRepoUrl, filesPaths, userRepoUrl, title, body } = params;
|
|
1600
|
+
const { owner: sourceOwner, repo: sourceRepo } = parseGithubOwnerAndRepo(sourceRepoUrl);
|
|
1601
|
+
const { owner, repo } = parseGithubOwnerAndRepo(userRepoUrl);
|
|
1602
|
+
const [sourceFilePath, secondFilePath] = filesPaths;
|
|
1603
|
+
const sourceFileContentResponse = await octokit.rest.repos.getContent({
|
|
1604
|
+
owner: sourceOwner,
|
|
1605
|
+
repo: sourceRepo,
|
|
1606
|
+
path: "/" + sourceFilePath
|
|
1607
|
+
});
|
|
1608
|
+
const { data: repository } = await octokit.rest.repos.get({ owner, repo });
|
|
1609
|
+
const defaultBranch = repository.default_branch;
|
|
1610
|
+
const newBranchName = `mobb/workflow-${Date.now()}`;
|
|
1611
|
+
await octokit.rest.git.createRef({
|
|
1612
|
+
owner,
|
|
1613
|
+
repo,
|
|
1614
|
+
ref: `refs/heads/${newBranchName}`,
|
|
1615
|
+
sha: await octokit.rest.git.getRef({ owner, repo, ref: `heads/${defaultBranch}` }).then((response) => response.data.object.sha)
|
|
1616
|
+
});
|
|
1617
|
+
const decodedContent = Buffer.from(
|
|
1618
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
1619
|
+
// @ts-ignore
|
|
1620
|
+
sourceFileContentResponse.data.content,
|
|
1621
|
+
"base64"
|
|
1622
|
+
).toString("utf-8");
|
|
1623
|
+
const tree = [
|
|
1624
|
+
{
|
|
1625
|
+
path: sourceFilePath,
|
|
1626
|
+
mode: "100644",
|
|
1627
|
+
type: "blob",
|
|
1628
|
+
content: decodedContent
|
|
1629
|
+
}
|
|
1630
|
+
];
|
|
1631
|
+
if (secondFilePath) {
|
|
1632
|
+
const secondFileContentResponse = await octokit.rest.repos.getContent({
|
|
1633
|
+
owner: sourceOwner,
|
|
1634
|
+
repo: sourceRepo,
|
|
1635
|
+
path: "/" + secondFilePath
|
|
1636
|
+
});
|
|
1637
|
+
const secondDecodedContent = Buffer.from(
|
|
1638
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
1639
|
+
// @ts-ignore
|
|
1640
|
+
secondFileContentResponse.data.content,
|
|
1641
|
+
"base64"
|
|
1642
|
+
).toString("utf-8");
|
|
1643
|
+
tree.push({
|
|
1644
|
+
path: secondFilePath,
|
|
1645
|
+
mode: "100644",
|
|
1646
|
+
type: "blob",
|
|
1647
|
+
content: secondDecodedContent
|
|
1648
|
+
});
|
|
1649
|
+
}
|
|
1650
|
+
const createTreeResponse = await octokit.rest.git.createTree({
|
|
1651
|
+
owner,
|
|
1652
|
+
repo,
|
|
1653
|
+
base_tree: await octokit.rest.git.getRef({ owner, repo, ref: `heads/${defaultBranch}` }).then((response) => response.data.object.sha),
|
|
1654
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
1655
|
+
// @ts-ignore
|
|
1656
|
+
tree
|
|
1657
|
+
});
|
|
1658
|
+
const createCommitResponse = await octokit.rest.git.createCommit({
|
|
1659
|
+
owner,
|
|
1660
|
+
repo,
|
|
1661
|
+
message: "Add new yaml file",
|
|
1662
|
+
tree: createTreeResponse.data.sha,
|
|
1663
|
+
parents: [
|
|
1664
|
+
await octokit.rest.git.getRef({ owner, repo, ref: `heads/${defaultBranch}` }).then((response) => response.data.object.sha)
|
|
1665
|
+
]
|
|
1666
|
+
});
|
|
1667
|
+
await octokit.rest.git.updateRef({
|
|
1668
|
+
owner,
|
|
1669
|
+
repo,
|
|
1670
|
+
ref: `heads/${newBranchName}`,
|
|
1671
|
+
sha: createCommitResponse.data.sha
|
|
1672
|
+
});
|
|
1673
|
+
const createPRResponse = await octokit.rest.pulls.create({
|
|
1674
|
+
owner,
|
|
1675
|
+
repo,
|
|
1676
|
+
title,
|
|
1677
|
+
head: newBranchName,
|
|
1678
|
+
head_repo: sourceRepo,
|
|
1679
|
+
body,
|
|
1680
|
+
base: defaultBranch
|
|
1681
|
+
});
|
|
1682
|
+
return {
|
|
1683
|
+
pull_request_url: createPRResponse.data.html_url
|
|
1684
|
+
};
|
|
1685
|
+
},
|
|
1686
|
+
async getGithubBranchList(repoUrl) {
|
|
1687
|
+
const { owner, repo } = parseGithubOwnerAndRepo(repoUrl);
|
|
1688
|
+
return octokit.rest.repos.listBranches({
|
|
1689
|
+
owner,
|
|
1690
|
+
repo,
|
|
1691
|
+
per_page: 1e3,
|
|
1692
|
+
page: 1
|
|
1693
|
+
});
|
|
1694
|
+
},
|
|
1695
|
+
async createPullRequest(options) {
|
|
1696
|
+
const { owner, repo } = parseGithubOwnerAndRepo(options.repoUrl);
|
|
1697
|
+
return octokit.rest.pulls.create({
|
|
1698
|
+
owner,
|
|
1699
|
+
repo,
|
|
1700
|
+
title: options.title,
|
|
1701
|
+
body: options.body,
|
|
1702
|
+
head: options.sourceBranchName,
|
|
1703
|
+
base: options.targetBranchName,
|
|
1704
|
+
draft: false,
|
|
1705
|
+
maintainer_can_modify: true
|
|
1706
|
+
});
|
|
1707
|
+
},
|
|
1708
|
+
async forkRepo(options) {
|
|
1709
|
+
const { owner, repo } = parseGithubOwnerAndRepo(options.repoUrl);
|
|
1710
|
+
const createForkRes = await octokit.rest.repos.createFork({
|
|
1711
|
+
owner,
|
|
1712
|
+
repo,
|
|
1713
|
+
default_branch_only: false
|
|
1714
|
+
});
|
|
1715
|
+
return { url: createForkRes.data.html_url };
|
|
1716
|
+
},
|
|
1717
|
+
async getUserInfo() {
|
|
1718
|
+
return octokit.request(GET_USER);
|
|
1735
1719
|
}
|
|
1736
1720
|
};
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1721
|
+
}
|
|
1722
|
+
|
|
1723
|
+
// src/features/analysis/scm/gitlab/gitlab.ts
|
|
1724
|
+
import querystring2 from "node:querystring";
|
|
1725
|
+
import {
|
|
1726
|
+
Gitlab
|
|
1727
|
+
} from "@gitbeaker/rest";
|
|
1728
|
+
import { ProxyAgent as ProxyAgent2 } from "undici";
|
|
1729
|
+
|
|
1730
|
+
// src/features/analysis/scm/env.ts
|
|
1731
|
+
import { z as z3 } from "zod";
|
|
1732
|
+
var EnvVariablesZod = z3.object({
|
|
1733
|
+
GITLAB_API_TOKEN: z3.string().optional(),
|
|
1734
|
+
BROKERED_HOSTS: z3.string().toLowerCase().transform(
|
|
1735
|
+
(x) => x.split(",").map((url) => url.trim(), []).filter(Boolean)
|
|
1736
|
+
).default(""),
|
|
1737
|
+
GITHUB_API_TOKEN: z3.string().optional()
|
|
1738
|
+
});
|
|
1739
|
+
var { GITLAB_API_TOKEN, BROKERED_HOSTS, GITHUB_API_TOKEN } = EnvVariablesZod.parse(process.env);
|
|
1740
|
+
|
|
1741
|
+
// src/features/analysis/scm/utils/get_issue_type.ts
|
|
1742
|
+
var getIssueType = (issueType) => {
|
|
1743
|
+
switch (issueType) {
|
|
1744
|
+
case "SQL_Injection" /* SqlInjection */:
|
|
1745
|
+
return "SQL Injection";
|
|
1746
|
+
case "CMDi_relative_path_command" /* CmDiRelativePathCommand */:
|
|
1747
|
+
return "Relative Path Command Injection";
|
|
1748
|
+
case "CMDi" /* CmDi */:
|
|
1749
|
+
return "Command Injection";
|
|
1750
|
+
case "XXE" /* Xxe */:
|
|
1751
|
+
return "XXE";
|
|
1752
|
+
case "XSS" /* Xss */:
|
|
1753
|
+
return "XSS";
|
|
1754
|
+
case "PT" /* Pt */:
|
|
1755
|
+
return "Path Traversal";
|
|
1756
|
+
case "ZIP_SLIP" /* ZipSlip */:
|
|
1757
|
+
return "Zip Slip";
|
|
1758
|
+
case "INSECURE_RANDOMNESS" /* InsecureRandomness */:
|
|
1759
|
+
return "Insecure Randomness";
|
|
1760
|
+
case "SSRF" /* Ssrf */:
|
|
1761
|
+
return "Server Side Request Forgery";
|
|
1762
|
+
case "TYPE_CONFUSION" /* TypeConfusion */:
|
|
1763
|
+
return "Type Confusion";
|
|
1764
|
+
case "REGEX_INJECTION" /* RegexInjection */:
|
|
1765
|
+
return "Regular Expression Injection";
|
|
1766
|
+
case "INCOMPLETE_URL_SANITIZATION" /* IncompleteUrlSanitization */:
|
|
1767
|
+
return "Incomplete URL Sanitization";
|
|
1768
|
+
case "LOCALE_DEPENDENT_COMPARISON" /* LocaleDependentComparison */:
|
|
1769
|
+
return "Locale Dependent Comparison";
|
|
1770
|
+
case "LOG_FORGING" /* LogForging */:
|
|
1771
|
+
return "Log Forging";
|
|
1772
|
+
case "MISSING_CHECK_AGAINST_NULL" /* MissingCheckAgainstNull */:
|
|
1773
|
+
return "Missing Check against Null";
|
|
1774
|
+
case "PASSWORD_IN_COMMENT" /* PasswordInComment */:
|
|
1775
|
+
return "Password in Comment";
|
|
1776
|
+
case "OVERLY_BROAD_CATCH" /* OverlyBroadCatch */:
|
|
1777
|
+
return "Poor Error Handling: Overly Broad Catch";
|
|
1778
|
+
case "USE_OF_SYSTEM_OUTPUT_STREAM" /* UseOfSystemOutputStream */:
|
|
1779
|
+
return "Use of System.out/System.err";
|
|
1780
|
+
case "DANGEROUS_FUNCTION_OVERFLOW" /* DangerousFunctionOverflow */:
|
|
1781
|
+
return "Use of dangerous function";
|
|
1782
|
+
case "DOS_STRING_BUILDER" /* DosStringBuilder */:
|
|
1783
|
+
return "Denial of Service: StringBuilder";
|
|
1784
|
+
case "OPEN_REDIRECT" /* OpenRedirect */:
|
|
1785
|
+
return "Open Redirect";
|
|
1786
|
+
case "WEAK_XML_SCHEMA_UNBOUNDED_OCCURRENCES" /* WeakXmlSchemaUnboundedOccurrences */:
|
|
1787
|
+
return "Weak XML Schema: Unbounded Occurrences";
|
|
1788
|
+
case "SYSTEM_INFORMATION_LEAK" /* SystemInformationLeak */:
|
|
1789
|
+
return "System Information Leak";
|
|
1790
|
+
case "SYSTEM_INFORMATION_LEAK_EXTERNAL" /* SystemInformationLeakExternal */:
|
|
1791
|
+
return "External System Information Leak";
|
|
1792
|
+
case "HTTP_RESPONSE_SPLITTING" /* HttpResponseSplitting */:
|
|
1793
|
+
return "HTTP response splitting";
|
|
1794
|
+
case "HTTP_ONLY_COOKIE" /* HttpOnlyCookie */:
|
|
1795
|
+
return "Cookie is not HttpOnly";
|
|
1796
|
+
case "INSECURE_COOKIE" /* InsecureCookie */:
|
|
1797
|
+
return "Insecure Cookie";
|
|
1798
|
+
case "TRUST_BOUNDARY_VIOLATION" /* TrustBoundaryViolation */:
|
|
1799
|
+
return "Trust Boundary Violation";
|
|
1800
|
+
case "NULL_DEREFERENCE" /* NullDereference */:
|
|
1801
|
+
return "Null Dereference";
|
|
1802
|
+
case "UNSAFE_DESERIALIZATION" /* UnsafeDeserialization */:
|
|
1803
|
+
return "Unsafe deserialization";
|
|
1804
|
+
case "INSECURE_BINDER_CONFIGURATION" /* InsecureBinderConfiguration */:
|
|
1805
|
+
return "Insecure Binder Configuration";
|
|
1806
|
+
case "UNSAFE_TARGET_BLANK" /* UnsafeTargetBlank */:
|
|
1807
|
+
return "Unsafe use of target blank";
|
|
1808
|
+
case "IFRAME_WITHOUT_SANDBOX" /* IframeWithoutSandbox */:
|
|
1809
|
+
return "Client use of iframe without sandbox";
|
|
1810
|
+
case "JQUERY_DEPRECATED_SYMBOLS" /* JqueryDeprecatedSymbols */:
|
|
1811
|
+
return "jQuery deprecated symbols";
|
|
1812
|
+
case "MISSING_ANTIFORGERY_VALIDATION" /* MissingAntiforgeryValidation */:
|
|
1813
|
+
return "Missing Anti-Forgery Validation";
|
|
1814
|
+
case "GRAPHQL_DEPTH_LIMIT" /* GraphqlDepthLimit */:
|
|
1815
|
+
return "GraphQL Depth Limit";
|
|
1816
|
+
case "UNCHECKED_LOOP_CONDITION" /* UncheckedLoopCondition */:
|
|
1817
|
+
return "Unchecked Loop Condition";
|
|
1818
|
+
case "IMPROPER_RESOURCE_SHUTDOWN_OR_RELEASE" /* ImproperResourceShutdownOrRelease */:
|
|
1819
|
+
return "Improper Resource Shutdown or Release";
|
|
1820
|
+
case "IMPROPER_EXCEPTION_HANDLING" /* ImproperExceptionHandling */:
|
|
1821
|
+
return "Improper Exception Handling";
|
|
1822
|
+
case "DEFAULT_RIGHTS_IN_OBJ_DEFINITION" /* DefaultRightsInObjDefinition */:
|
|
1823
|
+
return "Default Definer Rights in Package or Object Definition";
|
|
1824
|
+
case "HTML_COMMENT_IN_JSP" /* HtmlCommentInJsp */:
|
|
1825
|
+
return "HTML Comment in JSP";
|
|
1826
|
+
case "ERROR_CONDTION_WITHOUT_ACTION" /* ErrorCondtionWithoutAction */:
|
|
1827
|
+
return "Error Condition Without Action";
|
|
1828
|
+
case "DEPRECATED_FUNCTION" /* DeprecatedFunction */:
|
|
1829
|
+
return "Deprecated Function";
|
|
1830
|
+
case "HARDCODED_SECRETS" /* HardcodedSecrets */:
|
|
1831
|
+
return "Hardcoded Secrets";
|
|
1832
|
+
case "PROTOTYPE_POLLUTION" /* PrototypePollution */:
|
|
1833
|
+
return "Prototype Pollution";
|
|
1834
|
+
case "RACE_CONDITION_FORMAT_FLAW" /* RaceConditionFormatFlaw */:
|
|
1835
|
+
return "Race Condition Format Flaw";
|
|
1836
|
+
case "NON_FINAL_PUBLIC_STATIC_FIELD" /* NonFinalPublicStaticField */:
|
|
1837
|
+
return "Non-final Public Static Field";
|
|
1838
|
+
case "MISSING_HSTS_HEADER" /* MissingHstsHeader */:
|
|
1839
|
+
return "Missing HSTS Header";
|
|
1840
|
+
case "DEAD_CODE_UNUSED_FIELD" /* DeadCodeUnusedField */:
|
|
1841
|
+
return "Dead Code: Unused Field";
|
|
1842
|
+
case "HEADER_MANIPULATION" /* HeaderManipulation */:
|
|
1843
|
+
return "Header Manipulation";
|
|
1844
|
+
case "MISSING_EQUALS_OR_HASHCODE" /* MissingEqualsOrHashcode */:
|
|
1845
|
+
return "Missing equals or hashcode method";
|
|
1846
|
+
case "WCF_MISCONFIGURATION_INSUFFICIENT_LOGGING" /* WcfMisconfigurationInsufficientLogging */:
|
|
1847
|
+
return "WCF Misconfiguration: Insufficient Logging";
|
|
1848
|
+
case "WCF_MISCONFIGURATION_THROTTLING_NOT_ENABLED" /* WcfMisconfigurationThrottlingNotEnabled */:
|
|
1849
|
+
return "WCF Misconfiguration: Throttling Not Enabled";
|
|
1850
|
+
case "USELESS_REGEXP_CHAR_ESCAPE" /* UselessRegexpCharEscape */:
|
|
1851
|
+
return "Useless regular-expression character escape";
|
|
1852
|
+
case "INCOMPLETE_HOSTNAME_REGEX" /* IncompleteHostnameRegex */:
|
|
1853
|
+
return "Incomplete Hostname Regex";
|
|
1854
|
+
case "OVERLY_LARGE_RANGE" /* OverlyLargeRange */:
|
|
1855
|
+
return "Regex: Overly Large Range";
|
|
1856
|
+
case "INSUFFICIENT_LOGGING" /* InsufficientLogging */:
|
|
1857
|
+
return "Insufficient Logging of Sensitive Operations";
|
|
1858
|
+
case "PRIVACY_VIOLATION" /* PrivacyViolation */:
|
|
1859
|
+
return "Privacy Violation";
|
|
1860
|
+
case "INCOMPLETE_URL_SCHEME_CHECK" /* IncompleteUrlSchemeCheck */:
|
|
1861
|
+
return "Incomplete URL Scheme Check";
|
|
1862
|
+
case "VALUE_NEVER_READ" /* ValueNeverRead */:
|
|
1863
|
+
return "Value Never Read";
|
|
1864
|
+
case "VALUE_SHADOWING" /* ValueShadowing */:
|
|
1865
|
+
return "Value Shadowing";
|
|
1866
|
+
default: {
|
|
1867
|
+
return issueType ? issueType.replaceAll("_", " ") : "Other";
|
|
1747
1868
|
}
|
|
1748
|
-
throw e;
|
|
1749
|
-
}
|
|
1750
|
-
}
|
|
1751
|
-
async function getGithubBlameRanges({ ref, gitHubUrl, path: path9 }, options) {
|
|
1752
|
-
const { owner, repo } = parseGithubOwnerAndRepo(gitHubUrl);
|
|
1753
|
-
const variables = {
|
|
1754
|
-
owner,
|
|
1755
|
-
repo,
|
|
1756
|
-
path: path9,
|
|
1757
|
-
ref
|
|
1758
|
-
};
|
|
1759
|
-
const res = await queryGithubGraphql(
|
|
1760
|
-
GetBlameDocument,
|
|
1761
|
-
variables,
|
|
1762
|
-
options
|
|
1763
|
-
);
|
|
1764
|
-
if (!res?.repository?.object?.blame?.ranges) {
|
|
1765
|
-
return [];
|
|
1766
|
-
}
|
|
1767
|
-
return res.repository.object.blame.ranges.map((range) => ({
|
|
1768
|
-
startingLine: range.startingLine,
|
|
1769
|
-
endingLine: range.endingLine,
|
|
1770
|
-
email: range.commit.author.user?.email || "",
|
|
1771
|
-
name: range.commit.author.user?.name || "",
|
|
1772
|
-
login: range.commit.author.user?.login || ""
|
|
1773
|
-
}));
|
|
1774
|
-
}
|
|
1775
|
-
async function createPr({
|
|
1776
|
-
sourceRepoUrl,
|
|
1777
|
-
filesPaths,
|
|
1778
|
-
userRepoUrl,
|
|
1779
|
-
title,
|
|
1780
|
-
body
|
|
1781
|
-
}, options) {
|
|
1782
|
-
const oktoKit = getOktoKit(options);
|
|
1783
|
-
const { owner: sourceOwner, repo: sourceRepo } = parseGithubOwnerAndRepo(sourceRepoUrl);
|
|
1784
|
-
const { owner, repo } = parseGithubOwnerAndRepo(userRepoUrl);
|
|
1785
|
-
const [sourceFilePath, secondFilePath] = filesPaths;
|
|
1786
|
-
const sourceFileContentResponse = await oktoKit.rest.repos.getContent({
|
|
1787
|
-
owner: sourceOwner,
|
|
1788
|
-
repo: sourceRepo,
|
|
1789
|
-
path: "/" + sourceFilePath
|
|
1790
|
-
});
|
|
1791
|
-
const { data: repository } = await oktoKit.rest.repos.get({ owner, repo });
|
|
1792
|
-
const defaultBranch = repository.default_branch;
|
|
1793
|
-
const newBranchName = `mobb/workflow-${Date.now()}`;
|
|
1794
|
-
await oktoKit.rest.git.createRef({
|
|
1795
|
-
owner,
|
|
1796
|
-
repo,
|
|
1797
|
-
ref: `refs/heads/${newBranchName}`,
|
|
1798
|
-
sha: await oktoKit.rest.git.getRef({ owner, repo, ref: `heads/${defaultBranch}` }).then((response) => response.data.object.sha)
|
|
1799
|
-
});
|
|
1800
|
-
const decodedContent = Buffer.from(
|
|
1801
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
1802
|
-
// @ts-ignore
|
|
1803
|
-
sourceFileContentResponse.data.content,
|
|
1804
|
-
"base64"
|
|
1805
|
-
).toString("utf-8");
|
|
1806
|
-
const tree = [
|
|
1807
|
-
{
|
|
1808
|
-
path: sourceFilePath,
|
|
1809
|
-
mode: "100644",
|
|
1810
|
-
type: "blob",
|
|
1811
|
-
content: decodedContent
|
|
1812
|
-
}
|
|
1813
|
-
];
|
|
1814
|
-
if (secondFilePath) {
|
|
1815
|
-
const secondFileContentResponse = await oktoKit.rest.repos.getContent({
|
|
1816
|
-
owner: sourceOwner,
|
|
1817
|
-
repo: sourceRepo,
|
|
1818
|
-
path: "/" + secondFilePath
|
|
1819
|
-
});
|
|
1820
|
-
const secondDecodedContent = Buffer.from(
|
|
1821
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
1822
|
-
// @ts-ignore
|
|
1823
|
-
secondFileContentResponse.data.content,
|
|
1824
|
-
"base64"
|
|
1825
|
-
).toString("utf-8");
|
|
1826
|
-
tree.push({
|
|
1827
|
-
path: secondFilePath,
|
|
1828
|
-
mode: "100644",
|
|
1829
|
-
type: "blob",
|
|
1830
|
-
content: secondDecodedContent
|
|
1831
|
-
});
|
|
1832
1869
|
}
|
|
1833
|
-
|
|
1834
|
-
owner,
|
|
1835
|
-
repo,
|
|
1836
|
-
base_tree: await oktoKit.rest.git.getRef({ owner, repo, ref: `heads/${defaultBranch}` }).then((response) => response.data.object.sha),
|
|
1837
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
1838
|
-
// @ts-ignore
|
|
1839
|
-
tree
|
|
1840
|
-
});
|
|
1841
|
-
const createCommitResponse = await oktoKit.rest.git.createCommit({
|
|
1842
|
-
owner,
|
|
1843
|
-
repo,
|
|
1844
|
-
message: "Add new yaml file",
|
|
1845
|
-
tree: createTreeResponse.data.sha,
|
|
1846
|
-
parents: [
|
|
1847
|
-
await oktoKit.rest.git.getRef({ owner, repo, ref: `heads/${defaultBranch}` }).then((response) => response.data.object.sha)
|
|
1848
|
-
]
|
|
1849
|
-
});
|
|
1850
|
-
await oktoKit.rest.git.updateRef({
|
|
1851
|
-
owner,
|
|
1852
|
-
repo,
|
|
1853
|
-
ref: `heads/${newBranchName}`,
|
|
1854
|
-
sha: createCommitResponse.data.sha
|
|
1855
|
-
});
|
|
1856
|
-
const createPRResponse = await oktoKit.rest.pulls.create({
|
|
1857
|
-
owner,
|
|
1858
|
-
repo,
|
|
1859
|
-
title,
|
|
1860
|
-
head: newBranchName,
|
|
1861
|
-
head_repo: sourceRepo,
|
|
1862
|
-
body,
|
|
1863
|
-
base: defaultBranch
|
|
1864
|
-
});
|
|
1865
|
-
return {
|
|
1866
|
-
pull_request_url: createPRResponse.data.html_url
|
|
1867
|
-
};
|
|
1868
|
-
}
|
|
1869
|
-
|
|
1870
|
-
// src/features/analysis/scm/github/consts.ts
|
|
1871
|
-
var POST_COMMENT_PATH = "POST /repos/{owner}/{repo}/pulls/{pull_number}/comments";
|
|
1872
|
-
var DELETE_COMMENT_PATH = "DELETE /repos/{owner}/{repo}/pulls/comments/{comment_id}";
|
|
1873
|
-
var UPDATE_COMMENT_PATH = "PATCH /repos/{owner}/{repo}/pulls/comments/{comment_id}";
|
|
1874
|
-
var GET_PR_COMMENTS_PATH = "GET /repos/{owner}/{repo}/pulls/{pull_number}/comments";
|
|
1875
|
-
var GET_PR_COMMENT_PATH = "GET /repos/{owner}/{repo}/pulls/comments/{comment_id}";
|
|
1876
|
-
var GET_PR = "GET /repos/{owner}/{repo}/pulls/{pull_number}";
|
|
1877
|
-
var POST_GENERAL_PR_COMMENT = "POST /repos/{owner}/{repo}/issues/{issue_number}/comments";
|
|
1878
|
-
var GET_GENERAL_PR_COMMENTS = "GET /repos/{owner}/{repo}/issues/{issue_number}/comments";
|
|
1879
|
-
var DELETE_GENERAL_PR_COMMENT = "DELETE /repos/{owner}/{repo}/issues/comments/{comment_id}";
|
|
1880
|
-
var CREATE_OR_UPDATE_A_REPOSITORY_SECRET = "PUT /repos/{owner}/{repo}/actions/secrets/{secret_name}";
|
|
1881
|
-
var GET_A_REPOSITORY_PUBLIC_KEY = "GET /repos/{owner}/{repo}/actions/secrets/public-key";
|
|
1870
|
+
};
|
|
1882
1871
|
|
|
1883
|
-
// src/features/analysis/scm/
|
|
1884
|
-
function
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
return
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
}
|
|
1905
|
-
function createOrUpdateRepositorySecret(client, params) {
|
|
1906
|
-
return client.request(CREATE_OR_UPDATE_A_REPOSITORY_SECRET, params);
|
|
1872
|
+
// src/features/analysis/scm/utils/index.ts
|
|
1873
|
+
function getFixUrlWithRedirect(params) {
|
|
1874
|
+
const {
|
|
1875
|
+
fixId,
|
|
1876
|
+
projectId,
|
|
1877
|
+
organizationId,
|
|
1878
|
+
analysisId,
|
|
1879
|
+
redirectUrl,
|
|
1880
|
+
appBaseUrl,
|
|
1881
|
+
commentId
|
|
1882
|
+
} = params;
|
|
1883
|
+
const searchParams = new URLSearchParams();
|
|
1884
|
+
searchParams.append("commit_redirect_url", redirectUrl);
|
|
1885
|
+
searchParams.append("comment_id", commentId.toString());
|
|
1886
|
+
return `${getFixUrl({
|
|
1887
|
+
appBaseUrl,
|
|
1888
|
+
fixId,
|
|
1889
|
+
projectId,
|
|
1890
|
+
organizationId,
|
|
1891
|
+
analysisId
|
|
1892
|
+
})}?${searchParams.toString()}`;
|
|
1907
1893
|
}
|
|
1908
|
-
function
|
|
1909
|
-
|
|
1894
|
+
function getFixUrl({
|
|
1895
|
+
appBaseUrl,
|
|
1896
|
+
fixId,
|
|
1897
|
+
projectId,
|
|
1898
|
+
organizationId,
|
|
1899
|
+
analysisId
|
|
1900
|
+
}) {
|
|
1901
|
+
return `${appBaseUrl}/organization/${organizationId}/project/${projectId}/report/${analysisId}/fix/${fixId}`;
|
|
1910
1902
|
}
|
|
1911
|
-
function
|
|
1912
|
-
|
|
1903
|
+
function getCommitUrl(params) {
|
|
1904
|
+
const {
|
|
1905
|
+
fixId,
|
|
1906
|
+
projectId,
|
|
1907
|
+
organizationId,
|
|
1908
|
+
analysisId,
|
|
1909
|
+
redirectUrl,
|
|
1910
|
+
appBaseUrl,
|
|
1911
|
+
commentId
|
|
1912
|
+
} = params;
|
|
1913
|
+
const searchParams = new URLSearchParams();
|
|
1914
|
+
searchParams.append("redirect_url", redirectUrl);
|
|
1915
|
+
searchParams.append("comment_id", commentId.toString());
|
|
1916
|
+
return `${getFixUrl({
|
|
1917
|
+
appBaseUrl,
|
|
1918
|
+
fixId,
|
|
1919
|
+
projectId,
|
|
1920
|
+
organizationId,
|
|
1921
|
+
analysisId
|
|
1922
|
+
})}/commit?${searchParams.toString()}`;
|
|
1913
1923
|
}
|
|
1914
|
-
|
|
1915
|
-
|
|
1924
|
+
var userNamePattern = /^(https?:\/\/)([^@]+@)?([^/]+\/.+)$/;
|
|
1925
|
+
var sshPattern = /^git@([\w.-]+):([\w./-]+)$/;
|
|
1926
|
+
function normalizeUrl(repoUrl) {
|
|
1927
|
+
let trimmedUrl = repoUrl.trim().replace(/\/+$/, "");
|
|
1928
|
+
if (repoUrl.endsWith(".git")) {
|
|
1929
|
+
trimmedUrl = trimmedUrl.slice(0, -".git".length);
|
|
1930
|
+
}
|
|
1931
|
+
const usernameMatch = trimmedUrl.match(userNamePattern);
|
|
1932
|
+
if (usernameMatch) {
|
|
1933
|
+
const [_all, protocol, _username, repoPath] = usernameMatch;
|
|
1934
|
+
trimmedUrl = `${protocol}${repoPath}`;
|
|
1935
|
+
}
|
|
1936
|
+
const sshMatch = trimmedUrl.match(sshPattern);
|
|
1937
|
+
if (sshMatch) {
|
|
1938
|
+
const [_all, hostname, reporPath] = sshMatch;
|
|
1939
|
+
trimmedUrl = `https://${hostname}/${reporPath}`;
|
|
1940
|
+
}
|
|
1941
|
+
return trimmedUrl;
|
|
1916
1942
|
}
|
|
1917
|
-
|
|
1918
|
-
return
|
|
1943
|
+
var isUrlHasPath = (url) => {
|
|
1944
|
+
return new URL(url).origin !== url;
|
|
1945
|
+
};
|
|
1946
|
+
function shouldValidateUrl(repoUrl) {
|
|
1947
|
+
return repoUrl && isUrlHasPath(repoUrl);
|
|
1919
1948
|
}
|
|
1920
1949
|
|
|
1921
|
-
// src/features/analysis/scm/gitlab/gitlab.ts
|
|
1922
|
-
import querystring2 from "node:querystring";
|
|
1923
|
-
import {
|
|
1924
|
-
Gitlab
|
|
1925
|
-
} from "@gitbeaker/rest";
|
|
1926
|
-
import { ProxyAgent } from "undici";
|
|
1927
|
-
import { z as z5 } from "zod";
|
|
1928
|
-
|
|
1929
1950
|
// src/features/analysis/scm/gitlab/types.ts
|
|
1930
1951
|
import { z as z4 } from "zod";
|
|
1931
1952
|
var GitlabAuthResultZ = z4.object({
|
|
@@ -1935,13 +1956,6 @@ var GitlabAuthResultZ = z4.object({
|
|
|
1935
1956
|
});
|
|
1936
1957
|
|
|
1937
1958
|
// src/features/analysis/scm/gitlab/gitlab.ts
|
|
1938
|
-
var EnvVariablesZod2 = z5.object({
|
|
1939
|
-
GITLAB_API_TOKEN: z5.string().optional(),
|
|
1940
|
-
BROKERED_HOSTS: z5.string().toLowerCase().transform(
|
|
1941
|
-
(x) => x.split(",").map((url) => url.trim(), []).filter(Boolean)
|
|
1942
|
-
).default("")
|
|
1943
|
-
});
|
|
1944
|
-
var { GITLAB_API_TOKEN, BROKERED_HOSTS } = EnvVariablesZod2.parse(process.env);
|
|
1945
1959
|
function removeTrailingSlash2(str) {
|
|
1946
1960
|
return str.trim().replace(/\/+$/, "");
|
|
1947
1961
|
}
|
|
@@ -1963,7 +1977,7 @@ async function gitlabValidateParams({
|
|
|
1963
1977
|
if (accessToken) {
|
|
1964
1978
|
await api2.Users.showCurrentUser();
|
|
1965
1979
|
}
|
|
1966
|
-
if (url) {
|
|
1980
|
+
if (url && shouldValidateUrl(url)) {
|
|
1967
1981
|
const { projectPath } = parseGitlabOwnerAndRepo(url);
|
|
1968
1982
|
await api2.Projects.show(projectPath);
|
|
1969
1983
|
}
|
|
@@ -2216,7 +2230,7 @@ function initGitlabFetchMock() {
|
|
|
2216
2230
|
if (urlParsed && BROKERED_HOSTS.includes(
|
|
2217
2231
|
`${urlParsed.protocol?.toLowerCase()}//${urlParsed.host?.toLowerCase()}`
|
|
2218
2232
|
)) {
|
|
2219
|
-
const dispatcher = new
|
|
2233
|
+
const dispatcher = new ProxyAgent2({
|
|
2220
2234
|
uri: process.env["GIT_PROXY_HOST"] || "http://tinyproxy:8888",
|
|
2221
2235
|
requestTls: {
|
|
2222
2236
|
rejectUnauthorized: false
|
|
@@ -2236,88 +2250,88 @@ import parseDiff from "parse-diff";
|
|
|
2236
2250
|
import path3 from "path";
|
|
2237
2251
|
import { simpleGit } from "simple-git";
|
|
2238
2252
|
import tmp from "tmp";
|
|
2239
|
-
import { z as
|
|
2253
|
+
import { z as z6 } from "zod";
|
|
2240
2254
|
|
|
2241
2255
|
// src/features/analysis/scm/scmSubmit/types.ts
|
|
2242
|
-
import { z as
|
|
2243
|
-
var BaseSubmitToScmMessageZ =
|
|
2244
|
-
submitFixRequestId:
|
|
2245
|
-
fixes:
|
|
2246
|
-
|
|
2247
|
-
fixId:
|
|
2248
|
-
patches:
|
|
2256
|
+
import { z as z5 } from "zod";
|
|
2257
|
+
var BaseSubmitToScmMessageZ = z5.object({
|
|
2258
|
+
submitFixRequestId: z5.string().uuid(),
|
|
2259
|
+
fixes: z5.array(
|
|
2260
|
+
z5.object({
|
|
2261
|
+
fixId: z5.string().uuid(),
|
|
2262
|
+
patches: z5.array(z5.string())
|
|
2249
2263
|
})
|
|
2250
2264
|
),
|
|
2251
|
-
commitHash:
|
|
2252
|
-
repoUrl:
|
|
2265
|
+
commitHash: z5.string(),
|
|
2266
|
+
repoUrl: z5.string()
|
|
2253
2267
|
});
|
|
2254
2268
|
var submitToScmMessageType = {
|
|
2255
2269
|
commitToSameBranch: "commitToSameBranch",
|
|
2256
2270
|
submitFixesForDifferentBranch: "submitFixesForDifferentBranch"
|
|
2257
2271
|
};
|
|
2258
2272
|
var CommitToSameBranchParamsZ = BaseSubmitToScmMessageZ.merge(
|
|
2259
|
-
|
|
2260
|
-
type:
|
|
2261
|
-
branch:
|
|
2262
|
-
commitMessage:
|
|
2263
|
-
commitDescription:
|
|
2264
|
-
githubCommentId:
|
|
2273
|
+
z5.object({
|
|
2274
|
+
type: z5.literal(submitToScmMessageType.commitToSameBranch),
|
|
2275
|
+
branch: z5.string(),
|
|
2276
|
+
commitMessage: z5.string(),
|
|
2277
|
+
commitDescription: z5.string().nullish(),
|
|
2278
|
+
githubCommentId: z5.number().nullish()
|
|
2265
2279
|
})
|
|
2266
2280
|
);
|
|
2267
|
-
var SubmitFixesToDifferentBranchParamsZ =
|
|
2268
|
-
type:
|
|
2269
|
-
submitBranch:
|
|
2270
|
-
baseBranch:
|
|
2281
|
+
var SubmitFixesToDifferentBranchParamsZ = z5.object({
|
|
2282
|
+
type: z5.literal(submitToScmMessageType.submitFixesForDifferentBranch),
|
|
2283
|
+
submitBranch: z5.string(),
|
|
2284
|
+
baseBranch: z5.string()
|
|
2271
2285
|
}).merge(BaseSubmitToScmMessageZ);
|
|
2272
|
-
var SubmitFixesMessageZ =
|
|
2286
|
+
var SubmitFixesMessageZ = z5.union([
|
|
2273
2287
|
CommitToSameBranchParamsZ,
|
|
2274
2288
|
SubmitFixesToDifferentBranchParamsZ
|
|
2275
2289
|
]);
|
|
2276
|
-
var FixResponseArrayZ =
|
|
2277
|
-
|
|
2278
|
-
fixId:
|
|
2290
|
+
var FixResponseArrayZ = z5.array(
|
|
2291
|
+
z5.object({
|
|
2292
|
+
fixId: z5.string().uuid()
|
|
2279
2293
|
})
|
|
2280
2294
|
);
|
|
2281
|
-
var SubmitFixesBaseResponseMessageZ =
|
|
2282
|
-
submitFixRequestId:
|
|
2283
|
-
submitBranches:
|
|
2284
|
-
|
|
2285
|
-
branchName:
|
|
2295
|
+
var SubmitFixesBaseResponseMessageZ = z5.object({
|
|
2296
|
+
submitFixRequestId: z5.string().uuid(),
|
|
2297
|
+
submitBranches: z5.array(
|
|
2298
|
+
z5.object({
|
|
2299
|
+
branchName: z5.string(),
|
|
2286
2300
|
fixes: FixResponseArrayZ
|
|
2287
2301
|
})
|
|
2288
2302
|
),
|
|
2289
|
-
error:
|
|
2290
|
-
type:
|
|
2303
|
+
error: z5.object({
|
|
2304
|
+
type: z5.enum([
|
|
2291
2305
|
"InitialRepoAccessError",
|
|
2292
2306
|
"PushBranchError",
|
|
2293
2307
|
"UnknownError"
|
|
2294
2308
|
]),
|
|
2295
|
-
info:
|
|
2296
|
-
message:
|
|
2297
|
-
pushBranchName:
|
|
2309
|
+
info: z5.object({
|
|
2310
|
+
message: z5.string(),
|
|
2311
|
+
pushBranchName: z5.string().optional()
|
|
2298
2312
|
})
|
|
2299
2313
|
}).optional()
|
|
2300
2314
|
});
|
|
2301
|
-
var SubmitFixesToSameBranchResponseMessageZ =
|
|
2302
|
-
type:
|
|
2303
|
-
githubCommentId:
|
|
2315
|
+
var SubmitFixesToSameBranchResponseMessageZ = z5.object({
|
|
2316
|
+
type: z5.literal(submitToScmMessageType.commitToSameBranch),
|
|
2317
|
+
githubCommentId: z5.number().nullish()
|
|
2304
2318
|
}).merge(SubmitFixesBaseResponseMessageZ);
|
|
2305
|
-
var SubmitFixesToDifferentBranchResponseMessageZ =
|
|
2306
|
-
type:
|
|
2307
|
-
githubCommentId:
|
|
2319
|
+
var SubmitFixesToDifferentBranchResponseMessageZ = z5.object({
|
|
2320
|
+
type: z5.literal(submitToScmMessageType.submitFixesForDifferentBranch),
|
|
2321
|
+
githubCommentId: z5.number().optional()
|
|
2308
2322
|
}).merge(SubmitFixesBaseResponseMessageZ);
|
|
2309
|
-
var SubmitFixesResponseMessageZ =
|
|
2323
|
+
var SubmitFixesResponseMessageZ = z5.discriminatedUnion("type", [
|
|
2310
2324
|
SubmitFixesToSameBranchResponseMessageZ,
|
|
2311
2325
|
SubmitFixesToDifferentBranchResponseMessageZ
|
|
2312
2326
|
]);
|
|
2313
2327
|
|
|
2314
2328
|
// src/features/analysis/scm/scmSubmit/index.ts
|
|
2315
|
-
var
|
|
2316
|
-
BROKERED_HOSTS:
|
|
2329
|
+
var EnvVariablesZod2 = z6.object({
|
|
2330
|
+
BROKERED_HOSTS: z6.string().toLowerCase().transform(
|
|
2317
2331
|
(x) => x.split(",").map((url) => url.trim(), []).filter(Boolean)
|
|
2318
2332
|
).default("")
|
|
2319
2333
|
});
|
|
2320
|
-
var { BROKERED_HOSTS: BROKERED_HOSTS2 } =
|
|
2334
|
+
var { BROKERED_HOSTS: BROKERED_HOSTS2 } = EnvVariablesZod2.parse(process.env);
|
|
2321
2335
|
var isValidBranchName = async (branchName) => {
|
|
2322
2336
|
const git = simpleGit();
|
|
2323
2337
|
try {
|
|
@@ -2330,18 +2344,18 @@ var isValidBranchName = async (branchName) => {
|
|
|
2330
2344
|
return false;
|
|
2331
2345
|
}
|
|
2332
2346
|
};
|
|
2333
|
-
var FixesZ =
|
|
2334
|
-
|
|
2335
|
-
fixId:
|
|
2336
|
-
patches:
|
|
2347
|
+
var FixesZ = z6.array(
|
|
2348
|
+
z6.object({
|
|
2349
|
+
fixId: z6.string(),
|
|
2350
|
+
patches: z6.array(z6.string())
|
|
2337
2351
|
})
|
|
2338
2352
|
).nonempty();
|
|
2339
2353
|
|
|
2340
2354
|
// src/features/analysis/scm/scm.ts
|
|
2341
|
-
var GetRefererenceResultZ =
|
|
2342
|
-
date:
|
|
2343
|
-
sha:
|
|
2344
|
-
type:
|
|
2355
|
+
var GetRefererenceResultZ = z7.object({
|
|
2356
|
+
date: z7.date().optional(),
|
|
2357
|
+
sha: z7.string(),
|
|
2358
|
+
type: z7.nativeEnum(ReferenceType)
|
|
2345
2359
|
});
|
|
2346
2360
|
function getCloudScmLibTypeFromUrl(url) {
|
|
2347
2361
|
if (!url) {
|
|
@@ -2382,11 +2396,11 @@ var scmTypeToScmLibScmType = {
|
|
|
2382
2396
|
["Bitbucket" /* Bitbucket */]: "BITBUCKET" /* BITBUCKET */
|
|
2383
2397
|
};
|
|
2384
2398
|
function getScmTypeFromScmLibType(scmLibType) {
|
|
2385
|
-
const parsedScmLibType =
|
|
2399
|
+
const parsedScmLibType = z7.nativeEnum(ScmLibScmType).parse(scmLibType);
|
|
2386
2400
|
return scmLibScmTypeToScmType[parsedScmLibType];
|
|
2387
2401
|
}
|
|
2388
2402
|
function getScmLibTypeFromScmType(scmType) {
|
|
2389
|
-
const parsedScmType =
|
|
2403
|
+
const parsedScmType = z7.nativeEnum(ScmType).parse(scmType);
|
|
2390
2404
|
return scmTypeToScmLibScmType[parsedScmType];
|
|
2391
2405
|
}
|
|
2392
2406
|
function getScmConfig({
|
|
@@ -2581,10 +2595,7 @@ var SCMLib = class {
|
|
|
2581
2595
|
scmType,
|
|
2582
2596
|
scmOrg
|
|
2583
2597
|
}) {
|
|
2584
|
-
|
|
2585
|
-
if (url) {
|
|
2586
|
-
trimmedUrl = url.trim().replace(/\/$/, "").replace(/.git$/i, "");
|
|
2587
|
-
}
|
|
2598
|
+
const trimmedUrl = url ? url.trim().replace(/\/$/, "").replace(/.git$/i, "") : void 0;
|
|
2588
2599
|
try {
|
|
2589
2600
|
switch (scmType) {
|
|
2590
2601
|
case "GITHUB" /* GITHUB */: {
|
|
@@ -2612,7 +2623,7 @@ var SCMLib = class {
|
|
|
2612
2623
|
if (e instanceof InvalidRepoUrlError && url) {
|
|
2613
2624
|
throw new RepoNoTokenAccessError(
|
|
2614
2625
|
"no access to repo",
|
|
2615
|
-
scmLibScmTypeToScmType[
|
|
2626
|
+
scmLibScmTypeToScmType[z7.nativeEnum(ScmLibScmType).parse(scmType)]
|
|
2616
2627
|
);
|
|
2617
2628
|
}
|
|
2618
2629
|
}
|
|
@@ -2907,46 +2918,37 @@ var GithubSCMLib = class extends SCMLib {
|
|
|
2907
2918
|
// we don't always need a url, what's important is that we have an access token
|
|
2908
2919
|
constructor(url, accessToken, scmOrg) {
|
|
2909
2920
|
super(url, accessToken, scmOrg);
|
|
2910
|
-
__publicField(this, "
|
|
2911
|
-
this.
|
|
2921
|
+
__publicField(this, "githubSdk");
|
|
2922
|
+
this.githubSdk = getGithubSdk({
|
|
2923
|
+
auth: accessToken,
|
|
2924
|
+
url
|
|
2925
|
+
});
|
|
2912
2926
|
}
|
|
2913
2927
|
async createSubmitRequest(params) {
|
|
2914
2928
|
this._validateAccessTokenAndUrl();
|
|
2915
2929
|
const { targetBranchName, sourceBranchName, title, body } = params;
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
|
|
2920
|
-
|
|
2921
|
-
|
|
2922
|
-
|
|
2923
|
-
|
|
2924
|
-
})
|
|
2925
|
-
);
|
|
2930
|
+
const pullRequestResult = await this.githubSdk.createPullRequest({
|
|
2931
|
+
title,
|
|
2932
|
+
body,
|
|
2933
|
+
targetBranchName,
|
|
2934
|
+
sourceBranchName,
|
|
2935
|
+
repoUrl: this.url
|
|
2936
|
+
});
|
|
2937
|
+
return String(pullRequestResult.data.number);
|
|
2926
2938
|
}
|
|
2927
2939
|
async forkRepo(repoUrl) {
|
|
2928
2940
|
this._validateToken();
|
|
2929
|
-
return forkRepo({
|
|
2930
|
-
repoUrl
|
|
2931
|
-
accessToken: this.accessToken
|
|
2941
|
+
return this.githubSdk.forkRepo({
|
|
2942
|
+
repoUrl
|
|
2932
2943
|
});
|
|
2933
2944
|
}
|
|
2934
|
-
async createOrUpdateRepositorySecret(params
|
|
2935
|
-
|
|
2936
|
-
throw new Error("cannot delete comment without access token or url");
|
|
2937
|
-
}
|
|
2938
|
-
const oktokit = _oktokit || this.oktokit;
|
|
2945
|
+
async createOrUpdateRepositorySecret(params) {
|
|
2946
|
+
this._validateAccessTokenAndUrl();
|
|
2939
2947
|
const { owner, repo } = parseGithubOwnerAndRepo(this.url);
|
|
2940
|
-
const { data: repositoryPublicKeyResponse } = await
|
|
2941
|
-
oktokit,
|
|
2942
|
-
{
|
|
2943
|
-
owner,
|
|
2944
|
-
repo
|
|
2945
|
-
}
|
|
2946
|
-
);
|
|
2948
|
+
const { data: repositoryPublicKeyResponse } = await this.githubSdk.getRepositoryPublicKey({ owner, repo });
|
|
2947
2949
|
const { key_id, key } = repositoryPublicKeyResponse;
|
|
2948
2950
|
const encryptedValue = await encryptSecret(params.value, key);
|
|
2949
|
-
return createOrUpdateRepositorySecret(
|
|
2951
|
+
return this.githubSdk.createOrUpdateRepositorySecret({
|
|
2950
2952
|
encrypted_value: encryptedValue,
|
|
2951
2953
|
secret_name: params.name,
|
|
2952
2954
|
key_id,
|
|
@@ -2955,66 +2957,49 @@ var GithubSCMLib = class extends SCMLib {
|
|
|
2955
2957
|
});
|
|
2956
2958
|
}
|
|
2957
2959
|
async createPullRequestWithNewFile(sourceRepoUrl, filesPaths, userRepoUrl, title, body) {
|
|
2958
|
-
const { pull_request_url } = await createPr(
|
|
2959
|
-
|
|
2960
|
-
|
|
2961
|
-
|
|
2962
|
-
|
|
2963
|
-
|
|
2964
|
-
|
|
2965
|
-
},
|
|
2966
|
-
{
|
|
2967
|
-
githubAuthToken: this.accessToken
|
|
2968
|
-
}
|
|
2969
|
-
);
|
|
2960
|
+
const { pull_request_url } = await this.githubSdk.createPr({
|
|
2961
|
+
sourceRepoUrl,
|
|
2962
|
+
filesPaths,
|
|
2963
|
+
userRepoUrl,
|
|
2964
|
+
title,
|
|
2965
|
+
body
|
|
2966
|
+
});
|
|
2970
2967
|
return { pull_request_url };
|
|
2971
2968
|
}
|
|
2972
2969
|
async validateParams() {
|
|
2973
2970
|
return githubValidateParams(this.url, this.accessToken);
|
|
2974
2971
|
}
|
|
2975
|
-
async postPrComment(params
|
|
2976
|
-
|
|
2977
|
-
throw new Error("cannot post on PR without access token or url");
|
|
2978
|
-
}
|
|
2979
|
-
const oktokit = _oktokit || this.oktokit;
|
|
2972
|
+
async postPrComment(params) {
|
|
2973
|
+
this._validateAccessTokenAndUrl();
|
|
2980
2974
|
const { owner, repo } = parseGithubOwnerAndRepo(this.url);
|
|
2981
|
-
return postPrComment(
|
|
2975
|
+
return this.githubSdk.postPrComment({
|
|
2982
2976
|
...params,
|
|
2983
2977
|
owner,
|
|
2984
2978
|
repo
|
|
2985
2979
|
});
|
|
2986
2980
|
}
|
|
2987
|
-
async updatePrComment(params
|
|
2988
|
-
|
|
2989
|
-
throw new Error("cannot update on PR without access token or url");
|
|
2990
|
-
}
|
|
2991
|
-
const oktokit = _oktokit || this.oktokit;
|
|
2981
|
+
async updatePrComment(params) {
|
|
2982
|
+
this._validateAccessTokenAndUrl();
|
|
2992
2983
|
const { owner, repo } = parseGithubOwnerAndRepo(this.url);
|
|
2993
|
-
return updatePrComment(
|
|
2984
|
+
return this.githubSdk.updatePrComment({
|
|
2994
2985
|
...params,
|
|
2995
2986
|
owner,
|
|
2996
2987
|
repo
|
|
2997
2988
|
});
|
|
2998
2989
|
}
|
|
2999
|
-
async deleteComment(params
|
|
3000
|
-
|
|
3001
|
-
throw new Error("cannot delete comment without access token or url");
|
|
3002
|
-
}
|
|
3003
|
-
const oktokit = _oktokit || this.oktokit;
|
|
2990
|
+
async deleteComment(params) {
|
|
2991
|
+
this._validateAccessTokenAndUrl();
|
|
3004
2992
|
const { owner, repo } = parseGithubOwnerAndRepo(this.url);
|
|
3005
|
-
return deleteComment(
|
|
2993
|
+
return this.githubSdk.deleteComment({
|
|
3006
2994
|
...params,
|
|
3007
2995
|
owner,
|
|
3008
2996
|
repo
|
|
3009
2997
|
});
|
|
3010
2998
|
}
|
|
3011
|
-
async getPrComments(params
|
|
3012
|
-
|
|
3013
|
-
throw new Error("cannot get Pr Comments without access token or url");
|
|
3014
|
-
}
|
|
3015
|
-
const oktokit = _oktokit || this.oktokit;
|
|
2999
|
+
async getPrComments(params) {
|
|
3000
|
+
this._validateAccessTokenAndUrl();
|
|
3016
3001
|
const { owner, repo } = parseGithubOwnerAndRepo(this.url);
|
|
3017
|
-
return getPrComments(
|
|
3002
|
+
return this.githubSdk.getPrComments({
|
|
3018
3003
|
per_page: 100,
|
|
3019
3004
|
...params,
|
|
3020
3005
|
owner,
|
|
@@ -3022,27 +3007,23 @@ var GithubSCMLib = class extends SCMLib {
|
|
|
3022
3007
|
});
|
|
3023
3008
|
}
|
|
3024
3009
|
async getPrDiff(params) {
|
|
3025
|
-
|
|
3026
|
-
throw new Error("cannot get Pr Comments without access token or url");
|
|
3027
|
-
}
|
|
3010
|
+
this._validateAccessTokenAndUrl();
|
|
3028
3011
|
const { owner, repo } = parseGithubOwnerAndRepo(this.url);
|
|
3029
|
-
const prRes = await getPrDiff(
|
|
3012
|
+
const prRes = await this.githubSdk.getPrDiff({
|
|
3030
3013
|
...params,
|
|
3031
3014
|
owner,
|
|
3032
3015
|
repo
|
|
3033
3016
|
});
|
|
3034
|
-
return
|
|
3017
|
+
return z7.string().parse(prRes.data);
|
|
3035
3018
|
}
|
|
3036
3019
|
async getRepoList(_scmOrg) {
|
|
3037
|
-
|
|
3038
|
-
|
|
3039
|
-
throw new Error("no access token");
|
|
3040
|
-
}
|
|
3041
|
-
return getGithubRepoList(this.accessToken);
|
|
3020
|
+
this._validateToken();
|
|
3021
|
+
return this.githubSdk.getGithubRepoList();
|
|
3042
3022
|
}
|
|
3043
3023
|
async getBranchList() {
|
|
3044
3024
|
this._validateAccessTokenAndUrl();
|
|
3045
|
-
|
|
3025
|
+
const branches = await this.githubSdk.getGithubBranchList(this.url);
|
|
3026
|
+
return branches.data.map((branch) => branch.name);
|
|
3046
3027
|
}
|
|
3047
3028
|
getScmLibType() {
|
|
3048
3029
|
return "GITHUB" /* GITHUB */;
|
|
@@ -3054,73 +3035,57 @@ var GithubSCMLib = class extends SCMLib {
|
|
|
3054
3035
|
return {};
|
|
3055
3036
|
}
|
|
3056
3037
|
getDownloadUrl(sha) {
|
|
3057
|
-
this.url;
|
|
3058
3038
|
this._validateUrl();
|
|
3059
3039
|
const res = parseScmURL(this.url, "GitHub" /* GitHub */);
|
|
3060
3040
|
if (!res) {
|
|
3061
3041
|
throw new InvalidRepoUrlError("invalid repo url");
|
|
3062
3042
|
}
|
|
3063
|
-
const { hostname, organization, repoName } = res;
|
|
3064
|
-
|
|
3065
|
-
|
|
3066
|
-
);
|
|
3043
|
+
const { protocol, hostname, organization, repoName } = res;
|
|
3044
|
+
const downloadUrl = isGithubOnPrem(this.url) ? `${protocol}//${hostname}/api/v3/repos/${organization}/${repoName}/zipball/${sha}` : `https://api.${hostname}/repos/${organization}/${repoName}/zipball/${sha}`;
|
|
3045
|
+
return Promise.resolve(downloadUrl);
|
|
3067
3046
|
}
|
|
3068
3047
|
async _getUsernameForAuthUrl() {
|
|
3069
3048
|
return this.getUsername();
|
|
3070
3049
|
}
|
|
3071
3050
|
async getIsRemoteBranch(branch) {
|
|
3072
|
-
this.
|
|
3073
|
-
return getGithubIsRemoteBranch(
|
|
3051
|
+
this._validateUrl();
|
|
3052
|
+
return this.githubSdk.getGithubIsRemoteBranch({ branch, repoUrl: this.url });
|
|
3074
3053
|
}
|
|
3075
3054
|
async getUserHasAccessToRepo() {
|
|
3076
|
-
|
|
3077
|
-
console.error("no access token or no url");
|
|
3078
|
-
throw new Error("no access token or no url");
|
|
3079
|
-
}
|
|
3055
|
+
this._validateAccessTokenAndUrl();
|
|
3080
3056
|
const username = await this.getUsername();
|
|
3081
|
-
return
|
|
3057
|
+
return this.githubSdk.getGithubIsUserCollaborator({
|
|
3058
|
+
repoUrl: this.url,
|
|
3059
|
+
username
|
|
3060
|
+
});
|
|
3082
3061
|
}
|
|
3083
3062
|
async getUsername() {
|
|
3084
|
-
|
|
3085
|
-
|
|
3086
|
-
throw new Error("no access token");
|
|
3087
|
-
}
|
|
3088
|
-
return getGithubUsername(this.accessToken);
|
|
3063
|
+
this._validateToken();
|
|
3064
|
+
return this.githubSdk.getGithubUsername();
|
|
3089
3065
|
}
|
|
3090
3066
|
async getSubmitRequestStatus(scmSubmitRequestId) {
|
|
3091
|
-
|
|
3092
|
-
|
|
3093
|
-
|
|
3094
|
-
|
|
3095
|
-
|
|
3096
|
-
this.accessToken,
|
|
3097
|
-
this.url,
|
|
3098
|
-
Number(scmSubmitRequestId)
|
|
3099
|
-
);
|
|
3100
|
-
return state;
|
|
3067
|
+
this._validateAccessTokenAndUrl();
|
|
3068
|
+
return this.githubSdk.getGithubPullRequestStatus({
|
|
3069
|
+
repoUrl: this.url,
|
|
3070
|
+
prNumber: Number(scmSubmitRequestId)
|
|
3071
|
+
});
|
|
3101
3072
|
}
|
|
3102
3073
|
async getRepoBlameRanges(ref, path9) {
|
|
3103
3074
|
this._validateUrl();
|
|
3104
|
-
return await getGithubBlameRanges(
|
|
3105
|
-
|
|
3106
|
-
|
|
3107
|
-
|
|
3108
|
-
|
|
3109
|
-
);
|
|
3075
|
+
return await this.githubSdk.getGithubBlameRanges({
|
|
3076
|
+
ref,
|
|
3077
|
+
path: path9,
|
|
3078
|
+
gitHubUrl: this.url
|
|
3079
|
+
});
|
|
3110
3080
|
}
|
|
3111
3081
|
async getReferenceData(ref) {
|
|
3112
3082
|
this._validateUrl();
|
|
3113
|
-
return
|
|
3114
|
-
{ ref, gitHubUrl: this.url },
|
|
3115
|
-
{
|
|
3116
|
-
githubAuthToken: this.accessToken
|
|
3117
|
-
}
|
|
3118
|
-
);
|
|
3083
|
+
return this.githubSdk.getGithubReferenceData({ ref, gitHubUrl: this.url });
|
|
3119
3084
|
}
|
|
3120
3085
|
async getPrComment(commentId) {
|
|
3121
3086
|
this._validateUrl();
|
|
3122
3087
|
const { owner, repo } = parseGithubOwnerAndRepo(this.url);
|
|
3123
|
-
return await getPrComment(
|
|
3088
|
+
return await this.githubSdk.getPrComment({
|
|
3124
3089
|
repo,
|
|
3125
3090
|
owner,
|
|
3126
3091
|
comment_id: commentId
|
|
@@ -3128,17 +3093,12 @@ var GithubSCMLib = class extends SCMLib {
|
|
|
3128
3093
|
}
|
|
3129
3094
|
async getRepoDefaultBranch() {
|
|
3130
3095
|
this._validateUrl();
|
|
3131
|
-
return await getGithubRepoDefaultBranch(this.url
|
|
3132
|
-
githubAuthToken: this.accessToken
|
|
3133
|
-
});
|
|
3096
|
+
return await this.githubSdk.getGithubRepoDefaultBranch(this.url);
|
|
3134
3097
|
}
|
|
3135
3098
|
async getPrUrl(prNumber) {
|
|
3136
|
-
|
|
3137
|
-
console.error("no url");
|
|
3138
|
-
throw new Error("no url");
|
|
3139
|
-
}
|
|
3099
|
+
this._validateAccessTokenAndUrl();
|
|
3140
3100
|
const { owner, repo } = parseGithubOwnerAndRepo(this.url);
|
|
3141
|
-
const getPrRes = await getPr(
|
|
3101
|
+
const getPrRes = await this.githubSdk.getPr({
|
|
3142
3102
|
owner,
|
|
3143
3103
|
repo,
|
|
3144
3104
|
pull_number: prNumber
|
|
@@ -3147,21 +3107,20 @@ var GithubSCMLib = class extends SCMLib {
|
|
|
3147
3107
|
}
|
|
3148
3108
|
async postGeneralPrComment(params) {
|
|
3149
3109
|
const { prNumber, body } = params;
|
|
3150
|
-
this.
|
|
3110
|
+
this._validateAccessTokenAndUrl();
|
|
3151
3111
|
const { owner, repo } = parseGithubOwnerAndRepo(this.url);
|
|
3152
|
-
return await postGeneralPrComment(
|
|
3112
|
+
return await this.githubSdk.postGeneralPrComment({
|
|
3153
3113
|
issue_number: prNumber,
|
|
3154
3114
|
owner,
|
|
3155
3115
|
repo,
|
|
3156
3116
|
body
|
|
3157
3117
|
});
|
|
3158
3118
|
}
|
|
3159
|
-
async getGeneralPrComments(params
|
|
3119
|
+
async getGeneralPrComments(params) {
|
|
3160
3120
|
const { prNumber } = params;
|
|
3161
|
-
this.
|
|
3162
|
-
const oktoKit = auth ? new Octokit2({ auth: auth.authToken }) : this.oktokit;
|
|
3121
|
+
this._validateAccessTokenAndUrl();
|
|
3163
3122
|
const { owner, repo } = parseGithubOwnerAndRepo(this.url);
|
|
3164
|
-
return await getGeneralPrComments(
|
|
3123
|
+
return await this.githubSdk.getGeneralPrComments({
|
|
3165
3124
|
issue_number: prNumber,
|
|
3166
3125
|
owner,
|
|
3167
3126
|
repo
|
|
@@ -3170,9 +3129,9 @@ var GithubSCMLib = class extends SCMLib {
|
|
|
3170
3129
|
async deleteGeneralPrComment({
|
|
3171
3130
|
commentId
|
|
3172
3131
|
}) {
|
|
3173
|
-
this.
|
|
3132
|
+
this._validateAccessTokenAndUrl();
|
|
3174
3133
|
const { owner, repo } = parseGithubOwnerAndRepo(this.url);
|
|
3175
|
-
return deleteGeneralPrComment(
|
|
3134
|
+
return this.githubSdk.deleteGeneralPrComment({
|
|
3176
3135
|
owner,
|
|
3177
3136
|
repo,
|
|
3178
3137
|
comment_id: commentId
|
|
@@ -3246,7 +3205,7 @@ var StubSCMLib = class extends SCMLib {
|
|
|
3246
3205
|
};
|
|
3247
3206
|
function getUserAndPassword(token) {
|
|
3248
3207
|
const [username, password] = token.split(":");
|
|
3249
|
-
const safePasswordAndUsername =
|
|
3208
|
+
const safePasswordAndUsername = z7.object({ username: z7.string(), password: z7.string() }).parse({ username, password });
|
|
3250
3209
|
return {
|
|
3251
3210
|
username: safePasswordAndUsername.username,
|
|
3252
3211
|
password: safePasswordAndUsername.password
|
|
@@ -3282,7 +3241,7 @@ var BitbucketSCMLib = class extends SCMLib {
|
|
|
3282
3241
|
return { username, password, authType };
|
|
3283
3242
|
}
|
|
3284
3243
|
case "token": {
|
|
3285
|
-
return { authType, token:
|
|
3244
|
+
return { authType, token: z7.string().parse(this.accessToken) };
|
|
3286
3245
|
}
|
|
3287
3246
|
case "public":
|
|
3288
3247
|
return { authType };
|
|
@@ -3294,7 +3253,7 @@ var BitbucketSCMLib = class extends SCMLib {
|
|
|
3294
3253
|
...params,
|
|
3295
3254
|
repoUrl: this.url
|
|
3296
3255
|
});
|
|
3297
|
-
return String(
|
|
3256
|
+
return String(z7.number().parse(pullRequestRes.id));
|
|
3298
3257
|
}
|
|
3299
3258
|
async validateParams() {
|
|
3300
3259
|
return validateBitbucketParams({
|
|
@@ -3366,7 +3325,7 @@ var BitbucketSCMLib = class extends SCMLib {
|
|
|
3366
3325
|
async getUsername() {
|
|
3367
3326
|
this._validateToken();
|
|
3368
3327
|
const res = await this.bitbucketSdk.getUser();
|
|
3369
|
-
return
|
|
3328
|
+
return z7.string().parse(res.username);
|
|
3370
3329
|
}
|
|
3371
3330
|
async getSubmitRequestStatus(_scmSubmitRequestId) {
|
|
3372
3331
|
this._validateAccessTokenAndUrl();
|
|
@@ -3395,7 +3354,7 @@ var BitbucketSCMLib = class extends SCMLib {
|
|
|
3395
3354
|
async getRepoDefaultBranch() {
|
|
3396
3355
|
this._validateUrl();
|
|
3397
3356
|
const repoRes = await this.bitbucketSdk.getRepo({ repoUrl: this.url });
|
|
3398
|
-
return
|
|
3357
|
+
return z7.string().parse(repoRes.mainbranch?.name);
|
|
3399
3358
|
}
|
|
3400
3359
|
getPrUrl(prNumber) {
|
|
3401
3360
|
this._validateUrl();
|
|
@@ -3419,25 +3378,25 @@ var BitbucketSCMLib = class extends SCMLib {
|
|
|
3419
3378
|
// src/features/analysis/scm/bitbucket/bitbucket.ts
|
|
3420
3379
|
var { Bitbucket } = bitbucketPkg;
|
|
3421
3380
|
var BITBUCKET_HOSTNAME = "bitbucket.org";
|
|
3422
|
-
var TokenExpiredErrorZ =
|
|
3423
|
-
status:
|
|
3424
|
-
error:
|
|
3425
|
-
type:
|
|
3426
|
-
error:
|
|
3427
|
-
message:
|
|
3381
|
+
var TokenExpiredErrorZ = z8.object({
|
|
3382
|
+
status: z8.number(),
|
|
3383
|
+
error: z8.object({
|
|
3384
|
+
type: z8.string(),
|
|
3385
|
+
error: z8.object({
|
|
3386
|
+
message: z8.string()
|
|
3428
3387
|
})
|
|
3429
3388
|
})
|
|
3430
3389
|
});
|
|
3431
3390
|
var BITBUCKET_ACCESS_TOKEN_URL = `https://${BITBUCKET_HOSTNAME}/site/oauth2/access_token`;
|
|
3432
|
-
var BitbucketAuthResultZ =
|
|
3433
|
-
access_token:
|
|
3434
|
-
token_type:
|
|
3435
|
-
refresh_token:
|
|
3391
|
+
var BitbucketAuthResultZ = z8.object({
|
|
3392
|
+
access_token: z8.string(),
|
|
3393
|
+
token_type: z8.string(),
|
|
3394
|
+
refresh_token: z8.string()
|
|
3436
3395
|
});
|
|
3437
|
-
var BitbucketParseResultZ =
|
|
3438
|
-
organization:
|
|
3439
|
-
repoName:
|
|
3440
|
-
hostname:
|
|
3396
|
+
var BitbucketParseResultZ = z8.object({
|
|
3397
|
+
organization: z8.string(),
|
|
3398
|
+
repoName: z8.string(),
|
|
3399
|
+
hostname: z8.literal(BITBUCKET_HOSTNAME)
|
|
3441
3400
|
});
|
|
3442
3401
|
function parseBitbucketOrganizationAndRepo(bitbucketUrl) {
|
|
3443
3402
|
const parsedGitHubUrl = normalizeUrl(bitbucketUrl);
|
|
@@ -3515,7 +3474,7 @@ function getBitbucketSdk(params) {
|
|
|
3515
3474
|
if (!res.data.values) {
|
|
3516
3475
|
return [];
|
|
3517
3476
|
}
|
|
3518
|
-
return res.data.values.filter((branch) => !!branch.name).map((branch) =>
|
|
3477
|
+
return res.data.values.filter((branch) => !!branch.name).map((branch) => z8.string().parse(branch.name));
|
|
3519
3478
|
},
|
|
3520
3479
|
async getIsUserCollaborator(params2) {
|
|
3521
3480
|
const { repoUrl } = params2;
|
|
@@ -3630,7 +3589,7 @@ function getBitbucketSdk(params) {
|
|
|
3630
3589
|
return GetRefererenceResultZ.parse({
|
|
3631
3590
|
sha: tagRes.data.target?.hash,
|
|
3632
3591
|
type: "TAG" /* TAG */,
|
|
3633
|
-
date: new Date(
|
|
3592
|
+
date: new Date(z8.string().parse(tagRes.data.target?.date))
|
|
3634
3593
|
});
|
|
3635
3594
|
},
|
|
3636
3595
|
async getBranchRef(params2) {
|
|
@@ -3638,7 +3597,7 @@ function getBitbucketSdk(params) {
|
|
|
3638
3597
|
return GetRefererenceResultZ.parse({
|
|
3639
3598
|
sha: getBranchRes.target?.hash,
|
|
3640
3599
|
type: "BRANCH" /* BRANCH */,
|
|
3641
|
-
date: new Date(
|
|
3600
|
+
date: new Date(z8.string().parse(getBranchRes.target?.date))
|
|
3642
3601
|
});
|
|
3643
3602
|
},
|
|
3644
3603
|
async getCommitRef(params2) {
|
|
@@ -3646,13 +3605,13 @@ function getBitbucketSdk(params) {
|
|
|
3646
3605
|
return GetRefererenceResultZ.parse({
|
|
3647
3606
|
sha: getCommitRes.hash,
|
|
3648
3607
|
type: "COMMIT" /* COMMIT */,
|
|
3649
|
-
date: new Date(
|
|
3608
|
+
date: new Date(z8.string().parse(getCommitRes.date))
|
|
3650
3609
|
});
|
|
3651
3610
|
},
|
|
3652
3611
|
async getDownloadUrl({ url, sha }) {
|
|
3653
3612
|
this.getReferenceData({ ref: sha, url });
|
|
3654
3613
|
const repoRes = await this.getRepo({ repoUrl: url });
|
|
3655
|
-
const parsedRepoUrl =
|
|
3614
|
+
const parsedRepoUrl = z8.string().url().parse(repoRes.links?.html?.href);
|
|
3656
3615
|
return `${parsedRepoUrl}/get/${sha}.zip`;
|
|
3657
3616
|
},
|
|
3658
3617
|
async getPullRequest(params2) {
|
|
@@ -3675,7 +3634,7 @@ async function validateBitbucketParams(params) {
|
|
|
3675
3634
|
if (authType !== "public") {
|
|
3676
3635
|
await bitbucketClient.getUser();
|
|
3677
3636
|
}
|
|
3678
|
-
if (params.url) {
|
|
3637
|
+
if (params.url && shouldValidateUrl(params.url)) {
|
|
3679
3638
|
await bitbucketClient.getRepo({ repoUrl: params.url });
|
|
3680
3639
|
}
|
|
3681
3640
|
} catch (e) {
|
|
@@ -3695,7 +3654,7 @@ async function validateBitbucketParams(params) {
|
|
|
3695
3654
|
}
|
|
3696
3655
|
async function getUsersworkspacesSlugs(bitbucketClient) {
|
|
3697
3656
|
const res = await bitbucketClient.workspaces.getWorkspaces({});
|
|
3698
|
-
return res.data.values?.map((v) =>
|
|
3657
|
+
return res.data.values?.map((v) => z8.string().parse(v.slug));
|
|
3699
3658
|
}
|
|
3700
3659
|
async function getllUsersrepositories(bitbucketClient) {
|
|
3701
3660
|
const userWorspacesSlugs = await getUsersworkspacesSlugs(bitbucketClient);
|
|
@@ -3727,7 +3686,7 @@ var MOBB_ICON_IMG = "https://app.mobb.ai/gh-action/Logo_Rounded_Icon.svg";
|
|
|
3727
3686
|
// src/features/analysis/add_fix_comments_for_pr/utils.ts
|
|
3728
3687
|
import Debug3 from "debug";
|
|
3729
3688
|
import parseDiff2 from "parse-diff";
|
|
3730
|
-
import { z as
|
|
3689
|
+
import { z as z9 } from "zod";
|
|
3731
3690
|
|
|
3732
3691
|
// src/features/analysis/utils/by_key.ts
|
|
3733
3692
|
function keyBy(array, keyBy2) {
|
|
@@ -3958,7 +3917,7 @@ async function getRelevantVulenrabilitiesFromDiff(params) {
|
|
|
3958
3917
|
});
|
|
3959
3918
|
const lineAddedRanges = calculateRanges(fileNumbers);
|
|
3960
3919
|
const fileFilter = {
|
|
3961
|
-
path:
|
|
3920
|
+
path: z9.string().parse(file.to),
|
|
3962
3921
|
ranges: lineAddedRanges.map(([startLine, endLine]) => ({
|
|
3963
3922
|
endLine,
|
|
3964
3923
|
startLine
|
|
@@ -4265,30 +4224,30 @@ function subscribe(query, variables, callback, wsClientOptions) {
|
|
|
4265
4224
|
}
|
|
4266
4225
|
|
|
4267
4226
|
// src/features/analysis/graphql/types.ts
|
|
4268
|
-
import { z as
|
|
4269
|
-
var VulnerabilityReportIssueCodeNodeZ =
|
|
4270
|
-
vulnerabilityReportIssueId:
|
|
4271
|
-
path:
|
|
4272
|
-
startLine:
|
|
4273
|
-
vulnerabilityReportIssue:
|
|
4274
|
-
fixId:
|
|
4227
|
+
import { z as z10 } from "zod";
|
|
4228
|
+
var VulnerabilityReportIssueCodeNodeZ = z10.object({
|
|
4229
|
+
vulnerabilityReportIssueId: z10.string(),
|
|
4230
|
+
path: z10.string(),
|
|
4231
|
+
startLine: z10.number(),
|
|
4232
|
+
vulnerabilityReportIssue: z10.object({
|
|
4233
|
+
fixId: z10.string()
|
|
4275
4234
|
})
|
|
4276
4235
|
});
|
|
4277
|
-
var GetVulByNodesMetadataZ =
|
|
4278
|
-
vulnerabilityReportIssueCodeNodes:
|
|
4279
|
-
nonFixablePrVuls:
|
|
4280
|
-
aggregate:
|
|
4281
|
-
count:
|
|
4236
|
+
var GetVulByNodesMetadataZ = z10.object({
|
|
4237
|
+
vulnerabilityReportIssueCodeNodes: z10.array(VulnerabilityReportIssueCodeNodeZ),
|
|
4238
|
+
nonFixablePrVuls: z10.object({
|
|
4239
|
+
aggregate: z10.object({
|
|
4240
|
+
count: z10.number()
|
|
4282
4241
|
})
|
|
4283
4242
|
}),
|
|
4284
|
-
fixablePrVuls:
|
|
4285
|
-
aggregate:
|
|
4286
|
-
count:
|
|
4243
|
+
fixablePrVuls: z10.object({
|
|
4244
|
+
aggregate: z10.object({
|
|
4245
|
+
count: z10.number()
|
|
4287
4246
|
})
|
|
4288
4247
|
}),
|
|
4289
|
-
totalScanVulnerabilities:
|
|
4290
|
-
aggregate:
|
|
4291
|
-
count:
|
|
4248
|
+
totalScanVulnerabilities: z10.object({
|
|
4249
|
+
aggregate: z10.object({
|
|
4250
|
+
count: z10.number()
|
|
4292
4251
|
})
|
|
4293
4252
|
})
|
|
4294
4253
|
});
|
|
@@ -4345,12 +4304,17 @@ var GQLClient = class {
|
|
|
4345
4304
|
}
|
|
4346
4305
|
return true;
|
|
4347
4306
|
}
|
|
4348
|
-
async getOrgAndProjectId(
|
|
4349
|
-
const
|
|
4350
|
-
const
|
|
4351
|
-
|
|
4307
|
+
async getOrgAndProjectId(params = {}) {
|
|
4308
|
+
const { projectName, userDefinedOrganizationId } = params;
|
|
4309
|
+
const getOrgAndProjectIdResult = await this._clientSdk.getOrgAndProjectId({
|
|
4310
|
+
filters: userDefinedOrganizationId ? { organizationId: { _eq: userDefinedOrganizationId } } : {},
|
|
4311
|
+
limit: 1
|
|
4312
|
+
});
|
|
4313
|
+
const [organizationToOrganizationRole] = getOrgAndProjectIdResult.organization_to_organization_role;
|
|
4314
|
+
if (!organizationToOrganizationRole) {
|
|
4352
4315
|
throw new Error("Organization not found");
|
|
4353
4316
|
}
|
|
4317
|
+
const { organization: org } = organizationToOrganizationRole;
|
|
4354
4318
|
const project = projectName ? org?.projects.find((project2) => project2.name === projectName) ?? null : org?.projects[0];
|
|
4355
4319
|
if (!project?.id) {
|
|
4356
4320
|
throw new Error("Project not found");
|
|
@@ -4383,13 +4347,12 @@ var GQLClient = class {
|
|
|
4383
4347
|
}
|
|
4384
4348
|
}
|
|
4385
4349
|
async updateScmToken(args) {
|
|
4386
|
-
const { scmType, url, token, org,
|
|
4350
|
+
const { scmType, url, token, org, refreshToken } = args;
|
|
4387
4351
|
const updateScmTokenResult = await this._clientSdk.updateScmToken({
|
|
4388
4352
|
scmType,
|
|
4389
4353
|
url,
|
|
4390
4354
|
token,
|
|
4391
4355
|
org,
|
|
4392
|
-
username,
|
|
4393
4356
|
refreshToken
|
|
4394
4357
|
});
|
|
4395
4358
|
return updateScmTokenResult;
|
|
@@ -4919,7 +4882,7 @@ async function getSnykReport(reportPath, repoRoot, { skipPrompts = false }) {
|
|
|
4919
4882
|
|
|
4920
4883
|
// src/features/analysis/upload-file.ts
|
|
4921
4884
|
import Debug11 from "debug";
|
|
4922
|
-
import
|
|
4885
|
+
import fetch3, { File, fileFrom, FormData } from "node-fetch";
|
|
4923
4886
|
var debug10 = Debug11("mobbdev:upload-file");
|
|
4924
4887
|
async function uploadFile({
|
|
4925
4888
|
file,
|
|
@@ -4944,7 +4907,7 @@ async function uploadFile({
|
|
|
4944
4907
|
debug10("upload file from buffer");
|
|
4945
4908
|
form.append("file", new File([file], "file"));
|
|
4946
4909
|
}
|
|
4947
|
-
const response = await
|
|
4910
|
+
const response = await fetch3(url, {
|
|
4948
4911
|
method: "POST",
|
|
4949
4912
|
body: form
|
|
4950
4913
|
});
|
|
@@ -4975,7 +4938,7 @@ async function downloadRepo({
|
|
|
4975
4938
|
debug11("download repo %s %s %s", repoUrl, dirname);
|
|
4976
4939
|
const zipFilePath = path6.join(dirname, "repo.zip");
|
|
4977
4940
|
debug11("download URL: %s auth headers: %o", downloadUrl, authHeaders);
|
|
4978
|
-
const response = await
|
|
4941
|
+
const response = await fetch4(downloadUrl, {
|
|
4979
4942
|
method: "GET",
|
|
4980
4943
|
headers: {
|
|
4981
4944
|
...authHeaders
|
|
@@ -5077,7 +5040,8 @@ async function _scan(params, { skipPrompts = false } = {}) {
|
|
|
5077
5040
|
cxProjectName,
|
|
5078
5041
|
mobbProjectName,
|
|
5079
5042
|
githubToken: githubActionToken,
|
|
5080
|
-
command
|
|
5043
|
+
command,
|
|
5044
|
+
organizationId: userOrganizationId
|
|
5081
5045
|
} = params;
|
|
5082
5046
|
debug11("start %s %s", dirname, repo);
|
|
5083
5047
|
const { createSpinner: createSpinner4 } = Spinner2({ ci });
|
|
@@ -5087,7 +5051,10 @@ async function _scan(params, { skipPrompts = false } = {}) {
|
|
|
5087
5051
|
type: "apiKey"
|
|
5088
5052
|
});
|
|
5089
5053
|
await handleMobbLogin();
|
|
5090
|
-
const { projectId, organizationId } = await gqlClient.getOrgAndProjectId(
|
|
5054
|
+
const { projectId, organizationId } = await gqlClient.getOrgAndProjectId({
|
|
5055
|
+
projectName: mobbProjectName,
|
|
5056
|
+
userDefinedOrganizationId: userOrganizationId
|
|
5057
|
+
});
|
|
5091
5058
|
const {
|
|
5092
5059
|
uploadS3BucketInfo: { repoUploadInfo, reportUploadInfo }
|
|
5093
5060
|
} = await gqlClient.uploadS3BucketInfo();
|
|
@@ -5186,7 +5153,7 @@ async function _scan(params, { skipPrompts = false } = {}) {
|
|
|
5186
5153
|
spinner: mobbSpinner,
|
|
5187
5154
|
submitVulnerabilityReportVariables: {
|
|
5188
5155
|
fixReportId: reportUploadInfo.fixReportId,
|
|
5189
|
-
repoUrl:
|
|
5156
|
+
repoUrl: z11.string().parse(repo),
|
|
5190
5157
|
reference,
|
|
5191
5158
|
projectId,
|
|
5192
5159
|
vulnerabilityReportFileName: "report.json",
|
|
@@ -5438,9 +5405,9 @@ async function _scan(params, { skipPrompts = false } = {}) {
|
|
|
5438
5405
|
}
|
|
5439
5406
|
});
|
|
5440
5407
|
if (command === "review") {
|
|
5441
|
-
const params2 =
|
|
5442
|
-
repo:
|
|
5443
|
-
githubActionToken:
|
|
5408
|
+
const params2 = z11.object({
|
|
5409
|
+
repo: z11.string().url(),
|
|
5410
|
+
githubActionToken: z11.string()
|
|
5444
5411
|
}).parse({ repo, githubActionToken });
|
|
5445
5412
|
const scm2 = await SCMLib.init({
|
|
5446
5413
|
url: params2.repo,
|
|
@@ -5457,7 +5424,7 @@ async function _scan(params, { skipPrompts = false } = {}) {
|
|
|
5457
5424
|
analysisId,
|
|
5458
5425
|
gqlClient,
|
|
5459
5426
|
scm: scm2,
|
|
5460
|
-
scanner:
|
|
5427
|
+
scanner: z11.nativeEnum(SCANNERS).parse(scanner)
|
|
5461
5428
|
});
|
|
5462
5429
|
},
|
|
5463
5430
|
callbackStates: ["Finished" /* Finished */]
|
|
@@ -5518,7 +5485,8 @@ async function analyze({
|
|
|
5518
5485
|
ci,
|
|
5519
5486
|
commitHash,
|
|
5520
5487
|
srcPath,
|
|
5521
|
-
mobbProjectName
|
|
5488
|
+
mobbProjectName,
|
|
5489
|
+
organizationId
|
|
5522
5490
|
}, { skipPrompts = false } = {}) {
|
|
5523
5491
|
!ci && await showWelcomeMessage(skipPrompts);
|
|
5524
5492
|
await runAnalysis(
|
|
@@ -5531,6 +5499,7 @@ async function analyze({
|
|
|
5531
5499
|
commitHash,
|
|
5532
5500
|
mobbProjectName,
|
|
5533
5501
|
srcPath,
|
|
5502
|
+
organizationId,
|
|
5534
5503
|
command: "analyze"
|
|
5535
5504
|
},
|
|
5536
5505
|
{ skipPrompts }
|
|
@@ -5541,7 +5510,7 @@ var packageJson2 = JSON.parse(
|
|
|
5541
5510
|
);
|
|
5542
5511
|
var config3 = new Configstore2(packageJson2.name, { apiToken: "" });
|
|
5543
5512
|
async function addScmToken(addScmTokenOptions) {
|
|
5544
|
-
const { apiKey, token, organization, scmType, url,
|
|
5513
|
+
const { apiKey, token, organization, scmType, url, refreshToken } = addScmTokenOptions;
|
|
5545
5514
|
const gqlClient = new GQLClient({
|
|
5546
5515
|
apiKey: apiKey || config3.get("apiToken"),
|
|
5547
5516
|
type: "apiKey"
|
|
@@ -5554,7 +5523,6 @@ async function addScmToken(addScmTokenOptions) {
|
|
|
5554
5523
|
url,
|
|
5555
5524
|
token,
|
|
5556
5525
|
org: organization,
|
|
5557
|
-
username,
|
|
5558
5526
|
refreshToken
|
|
5559
5527
|
});
|
|
5560
5528
|
}
|
|
@@ -5608,6 +5576,12 @@ var refOption = {
|
|
|
5608
5576
|
type: "string",
|
|
5609
5577
|
demandOption: false
|
|
5610
5578
|
};
|
|
5579
|
+
var organizationIdOptions = {
|
|
5580
|
+
describe: chalk5.bold("Organization id"),
|
|
5581
|
+
alias: "organization-id",
|
|
5582
|
+
type: "string",
|
|
5583
|
+
demandOption: false
|
|
5584
|
+
};
|
|
5611
5585
|
var scannerOptions = {
|
|
5612
5586
|
alias: "s",
|
|
5613
5587
|
choices: Object.values(SCANNERS),
|
|
@@ -5650,10 +5624,6 @@ var scmOrgOption = {
|
|
|
5650
5624
|
describe: chalk5.bold("Organization name in SCM (used in Azure DevOps)"),
|
|
5651
5625
|
type: "string"
|
|
5652
5626
|
};
|
|
5653
|
-
var scmUsernameOption = {
|
|
5654
|
-
describe: chalk5.bold("Username in SCM (used in GitHub, Bitbucket)"),
|
|
5655
|
-
type: "string"
|
|
5656
|
-
};
|
|
5657
5627
|
var scmRefreshTokenOption = {
|
|
5658
5628
|
describe: chalk5.bold("SCM refresh token (used in GitLab)"),
|
|
5659
5629
|
type: "string"
|
|
@@ -5667,7 +5637,7 @@ var scmTokenOption = {
|
|
|
5667
5637
|
// src/args/validation.ts
|
|
5668
5638
|
import chalk6 from "chalk";
|
|
5669
5639
|
import path8 from "path";
|
|
5670
|
-
import { z as
|
|
5640
|
+
import { z as z12 } from "zod";
|
|
5671
5641
|
function throwRepoUrlErrorMessage({
|
|
5672
5642
|
error,
|
|
5673
5643
|
repoUrl,
|
|
@@ -5684,11 +5654,17 @@ Example:
|
|
|
5684
5654
|
)}`;
|
|
5685
5655
|
throw new CliError(formattedErrorMessage);
|
|
5686
5656
|
}
|
|
5687
|
-
var UrlZ =
|
|
5657
|
+
var UrlZ = z12.string({
|
|
5688
5658
|
invalid_type_error: "is not a valid GitHub / GitLab / ADO URL"
|
|
5689
5659
|
}).refine((data) => !!sanityRepoURL(data), {
|
|
5690
5660
|
message: "is not a valid GitHub / GitLab / ADO URL"
|
|
5691
5661
|
});
|
|
5662
|
+
function validateOrganizationId(organizationId) {
|
|
5663
|
+
const orgIdValidation = z12.string().uuid().nullish().safeParse(organizationId);
|
|
5664
|
+
if (!orgIdValidation.success) {
|
|
5665
|
+
throw new CliError(`organizationId: ${organizationId} is not a valid UUID`);
|
|
5666
|
+
}
|
|
5667
|
+
}
|
|
5692
5668
|
function validateRepoUrl(args) {
|
|
5693
5669
|
const repoSafeParseResult = UrlZ.safeParse(args.repo);
|
|
5694
5670
|
const { success } = repoSafeParseResult;
|
|
@@ -5738,7 +5714,7 @@ function analyzeBuilder(yargs2) {
|
|
|
5738
5714
|
alias: "commit-hash",
|
|
5739
5715
|
describe: chalk7.bold("Hash of the commit"),
|
|
5740
5716
|
type: "string"
|
|
5741
|
-
}).option("mobb-project-name", mobbProjectNameOption).option("y", yesOption).option("ci", ciOption).option("api-key", apiKeyOption).option("commit-hash", commitHashOption).example(
|
|
5717
|
+
}).option("mobb-project-name", mobbProjectNameOption).option("y", yesOption).option("ci", ciOption).option("org", organizationIdOptions).option("api-key", apiKeyOption).option("commit-hash", commitHashOption).example(
|
|
5742
5718
|
"$0 analyze -r https://github.com/WebGoat/WebGoat -f <your_vulirabitliy_report_path>",
|
|
5743
5719
|
"analyze an existing repository"
|
|
5744
5720
|
).help();
|
|
@@ -5748,6 +5724,7 @@ function validateAnalyzeOptions(argv) {
|
|
|
5748
5724
|
throw new CliError(`
|
|
5749
5725
|
Can't access ${chalk7.bold(argv.f)}`);
|
|
5750
5726
|
}
|
|
5727
|
+
validateOrganizationId(argv.organizationId);
|
|
5751
5728
|
if (!argv.srcPath && !argv.repo) {
|
|
5752
5729
|
throw new CliError("You must supply either --src-path or --repo");
|
|
5753
5730
|
}
|
|
@@ -5816,13 +5793,14 @@ async function reviewHandler(args) {
|
|
|
5816
5793
|
|
|
5817
5794
|
// src/args/commands/scan.ts
|
|
5818
5795
|
function scanBuilder(args) {
|
|
5819
|
-
return args.coerce("scanner", (arg) => arg.toLowerCase()).option("repo", repoOption).option("ref", refOption).option("scanner", scannerOptions).option("mobb-project-name", mobbProjectNameOption).option("y", yesOption).option("ci", ciOption).option("api-key", apiKeyOption).option("cx-project-name", projectNameOption).example(
|
|
5796
|
+
return args.coerce("scanner", (arg) => arg.toLowerCase()).option("repo", repoOption).option("ref", refOption).option("scanner", scannerOptions).option("org", organizationIdOptions).option("mobb-project-name", mobbProjectNameOption).option("y", yesOption).option("ci", ciOption).option("api-key", apiKeyOption).option("cx-project-name", projectNameOption).example(
|
|
5820
5797
|
"$0 scan -r https://github.com/WebGoat/WebGoat",
|
|
5821
5798
|
"Scan an existing repository"
|
|
5822
5799
|
).help();
|
|
5823
5800
|
}
|
|
5824
5801
|
function validateScanOptions(argv) {
|
|
5825
5802
|
validateRepoUrl(argv);
|
|
5803
|
+
validateOrganizationId(argv.organizationId);
|
|
5826
5804
|
argv.scanner === SCANNERS.Checkmarx && validateCheckmarxInstallation();
|
|
5827
5805
|
if (argv.scanner === SCANNERS.Checkmarx && !argv.cxProjectName) {
|
|
5828
5806
|
throw new CliError(errorMessages.missingCxProjectName);
|
|
@@ -5839,15 +5817,15 @@ async function scanHandler(args) {
|
|
|
5839
5817
|
}
|
|
5840
5818
|
|
|
5841
5819
|
// src/args/commands/token.ts
|
|
5842
|
-
import { z as
|
|
5820
|
+
import { z as z13 } from "zod";
|
|
5843
5821
|
function addScmTokenBuilder(args) {
|
|
5844
|
-
return args.option("scm-type", scmTypeOption).option("url", urlOption).option("token", scmTokenOption).option("organization", scmOrgOption).option("
|
|
5822
|
+
return args.option("scm-type", scmTypeOption).option("url", urlOption).option("token", scmTokenOption).option("organization", scmOrgOption).option("refresh-token", scmRefreshTokenOption).option("api-key", apiKeyOption).example(
|
|
5845
5823
|
"$0 add-scm-token --scm-type Ado --url https://dev.azure.com/adoorg/test/_git/repo --token abcdef0123456 --organization myOrg",
|
|
5846
5824
|
"Add your SCM (Github, Gitlab, Azure DevOps) token to Mobb to enable automated fixes."
|
|
5847
5825
|
).help().demandOption(["url", "token"]);
|
|
5848
5826
|
}
|
|
5849
5827
|
function validateAddScmTokenOptions(argv) {
|
|
5850
|
-
if (!
|
|
5828
|
+
if (!z13.nativeEnum(ScmType).safeParse(argv.scmType).success) {
|
|
5851
5829
|
throw new CliError(
|
|
5852
5830
|
"\nError: --scm-type must reference a valid SCM type (GitHub, GitLab, Ado, Bitbutcket)"
|
|
5853
5831
|
);
|
|
@@ -5855,25 +5833,17 @@ function validateAddScmTokenOptions(argv) {
|
|
|
5855
5833
|
Object.values(scmValidationMap).forEach((validate) => validate(argv));
|
|
5856
5834
|
}
|
|
5857
5835
|
var scmValidationMap = {
|
|
5858
|
-
["GitHub" /* GitHub */]:
|
|
5836
|
+
["GitHub" /* GitHub */]: () => {
|
|
5837
|
+
return;
|
|
5838
|
+
},
|
|
5859
5839
|
["GitLab" /* GitLab */]: () => {
|
|
5860
5840
|
return;
|
|
5861
5841
|
},
|
|
5862
5842
|
["Ado" /* Ado */]: validateAdo,
|
|
5863
|
-
["Bitbucket" /* Bitbucket */]:
|
|
5864
|
-
|
|
5865
|
-
function validateBitbucket(argv) {
|
|
5866
|
-
const urlObj = new URL(argv.url);
|
|
5867
|
-
if (urlObj.hostname.toLowerCase() === scmCloudHostname.Bitbucket && !argv.username) {
|
|
5868
|
-
throw new CliError("\nError: --username flag is required for Bitbucket");
|
|
5869
|
-
}
|
|
5870
|
-
}
|
|
5871
|
-
function validateGithub(argv) {
|
|
5872
|
-
const urlObj = new URL(argv.url);
|
|
5873
|
-
if (urlObj.hostname.toLowerCase() === scmCloudHostname.GitHub && !argv.username) {
|
|
5874
|
-
throw new CliError("\nError: --username flag is required for GitHub");
|
|
5843
|
+
["Bitbucket" /* Bitbucket */]: () => {
|
|
5844
|
+
return;
|
|
5875
5845
|
}
|
|
5876
|
-
}
|
|
5846
|
+
};
|
|
5877
5847
|
function validateAdo(argv) {
|
|
5878
5848
|
const urlObj = new URL(argv.url);
|
|
5879
5849
|
if ((urlObj.hostname.toLowerCase() === scmCloudHostname.Ado || urlObj.hostname.toLowerCase().endsWith(".visualstudio.com")) && !argv.organization) {
|