securewithtrace 0.7.1 → 0.9.0
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/README.md +2 -2
- package/dist/index.js +1267 -282
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3410,37 +3410,110 @@ async function pollForToken(clientId, deviceCode, options = {}) {
|
|
|
3410
3410
|
}
|
|
3411
3411
|
throw new Error("Authorization timed out. Please try again.");
|
|
3412
3412
|
}
|
|
3413
|
+
async function refreshAccessToken(clientId, refreshToken) {
|
|
3414
|
+
const response = await fetch(WORKOS_TOKEN_URL, {
|
|
3415
|
+
method: "POST",
|
|
3416
|
+
headers: {
|
|
3417
|
+
"Content-Type": "application/x-www-form-urlencoded"
|
|
3418
|
+
},
|
|
3419
|
+
body: new URLSearchParams({
|
|
3420
|
+
grant_type: "refresh_token",
|
|
3421
|
+
client_id: clientId,
|
|
3422
|
+
refresh_token: refreshToken
|
|
3423
|
+
})
|
|
3424
|
+
});
|
|
3425
|
+
if (!response.ok) {
|
|
3426
|
+
const text = await response.text();
|
|
3427
|
+
throw new Error(`Failed to refresh token: ${response.status} ${text}`);
|
|
3428
|
+
}
|
|
3429
|
+
return await response.json();
|
|
3430
|
+
}
|
|
3413
3431
|
|
|
3414
3432
|
// src/auth/token.ts
|
|
3415
3433
|
import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "fs";
|
|
3416
3434
|
import { homedir } from "os";
|
|
3417
3435
|
import { join } from "path";
|
|
3418
|
-
var
|
|
3419
|
-
var
|
|
3436
|
+
var ACCESS_TOKEN_FILENAME = "token";
|
|
3437
|
+
var REFRESH_TOKEN_FILENAME = "refresh-token";
|
|
3438
|
+
function resolveTraceDir() {
|
|
3439
|
+
const override = process.env["TRACE_CLI_AUTH_DIR"];
|
|
3440
|
+
if (override && override.trim().length > 0) {
|
|
3441
|
+
return override;
|
|
3442
|
+
}
|
|
3443
|
+
return join(homedir(), ".trace");
|
|
3444
|
+
}
|
|
3445
|
+
function ensureTraceDir() {
|
|
3446
|
+
const traceDir = resolveTraceDir();
|
|
3447
|
+
if (!existsSync(traceDir)) {
|
|
3448
|
+
mkdirSync(traceDir, { recursive: true, mode: 448 });
|
|
3449
|
+
}
|
|
3450
|
+
}
|
|
3451
|
+
function getTokenPath() {
|
|
3452
|
+
return join(resolveTraceDir(), ACCESS_TOKEN_FILENAME);
|
|
3453
|
+
}
|
|
3454
|
+
function getRefreshTokenPath() {
|
|
3455
|
+
return join(resolveTraceDir(), REFRESH_TOKEN_FILENAME);
|
|
3456
|
+
}
|
|
3420
3457
|
function readToken() {
|
|
3458
|
+
const tokenPath = getTokenPath();
|
|
3421
3459
|
try {
|
|
3422
|
-
if (!existsSync(
|
|
3460
|
+
if (!existsSync(tokenPath)) {
|
|
3423
3461
|
return null;
|
|
3424
3462
|
}
|
|
3425
|
-
const token = readFileSync(
|
|
3463
|
+
const token = readFileSync(tokenPath, "utf-8").trim();
|
|
3464
|
+
return token || null;
|
|
3465
|
+
} catch {
|
|
3466
|
+
return null;
|
|
3467
|
+
}
|
|
3468
|
+
}
|
|
3469
|
+
function readRefreshToken() {
|
|
3470
|
+
const refreshTokenPath = getRefreshTokenPath();
|
|
3471
|
+
try {
|
|
3472
|
+
if (!existsSync(refreshTokenPath)) {
|
|
3473
|
+
return null;
|
|
3474
|
+
}
|
|
3475
|
+
const token = readFileSync(refreshTokenPath, "utf-8").trim();
|
|
3426
3476
|
return token || null;
|
|
3427
3477
|
} catch {
|
|
3428
3478
|
return null;
|
|
3429
3479
|
}
|
|
3430
3480
|
}
|
|
3431
3481
|
function writeToken(token) {
|
|
3432
|
-
|
|
3433
|
-
|
|
3482
|
+
ensureTraceDir();
|
|
3483
|
+
writeFileSync(getTokenPath(), token, { encoding: "utf-8", mode: 384 });
|
|
3484
|
+
}
|
|
3485
|
+
function writeRefreshToken(token) {
|
|
3486
|
+
ensureTraceDir();
|
|
3487
|
+
writeFileSync(getRefreshTokenPath(), token, { encoding: "utf-8", mode: 384 });
|
|
3488
|
+
}
|
|
3489
|
+
function writeTokens(accessToken, refreshToken) {
|
|
3490
|
+
writeToken(accessToken);
|
|
3491
|
+
if (refreshToken && refreshToken.trim().length > 0) {
|
|
3492
|
+
writeRefreshToken(refreshToken);
|
|
3493
|
+
return;
|
|
3434
3494
|
}
|
|
3435
|
-
|
|
3495
|
+
removeRefreshToken();
|
|
3436
3496
|
}
|
|
3437
|
-
function
|
|
3438
|
-
|
|
3497
|
+
function removeRefreshToken() {
|
|
3498
|
+
const refreshTokenPath = getRefreshTokenPath();
|
|
3499
|
+
if (!existsSync(refreshTokenPath)) {
|
|
3439
3500
|
return false;
|
|
3440
3501
|
}
|
|
3441
|
-
rmSync(
|
|
3502
|
+
rmSync(refreshTokenPath);
|
|
3442
3503
|
return true;
|
|
3443
3504
|
}
|
|
3505
|
+
function removeToken() {
|
|
3506
|
+
let removed = false;
|
|
3507
|
+
const tokenPath = getTokenPath();
|
|
3508
|
+
if (existsSync(tokenPath)) {
|
|
3509
|
+
rmSync(tokenPath);
|
|
3510
|
+
removed = true;
|
|
3511
|
+
}
|
|
3512
|
+
if (removeRefreshToken()) {
|
|
3513
|
+
removed = true;
|
|
3514
|
+
}
|
|
3515
|
+
return removed;
|
|
3516
|
+
}
|
|
3444
3517
|
|
|
3445
3518
|
// src/auth/commands.ts
|
|
3446
3519
|
function getClientId() {
|
|
@@ -3501,12 +3574,12 @@ function createLoginCommand() {
|
|
|
3501
3574
|
expiresIn: auth.expires_in,
|
|
3502
3575
|
interval: auth.interval
|
|
3503
3576
|
});
|
|
3504
|
-
|
|
3577
|
+
writeTokens(tokenResponse.access_token, tokenResponse.refresh_token);
|
|
3505
3578
|
const name = [tokenResponse.user.first_name, tokenResponse.user.last_name].filter(Boolean).join(" ");
|
|
3506
3579
|
const displayName = name || tokenResponse.user.email;
|
|
3507
3580
|
console.log(`
|
|
3508
3581
|
Authenticated as ${displayName} (${tokenResponse.user.email})`);
|
|
3509
|
-
console.log("
|
|
3582
|
+
console.log("Tokens saved to ~/.trace");
|
|
3510
3583
|
});
|
|
3511
3584
|
}
|
|
3512
3585
|
function createLogoutCommand() {
|
|
@@ -3522,6 +3595,7 @@ function createLogoutCommand() {
|
|
|
3522
3595
|
function createStatusCommand() {
|
|
3523
3596
|
return new Command("status").description("Show current authentication status").action(() => {
|
|
3524
3597
|
const token = readToken();
|
|
3598
|
+
const refreshToken = readRefreshToken();
|
|
3525
3599
|
if (token) {
|
|
3526
3600
|
try {
|
|
3527
3601
|
const parts = token.split(".");
|
|
@@ -3540,16 +3614,31 @@ function createStatusCommand() {
|
|
|
3540
3614
|
if (expiry) {
|
|
3541
3615
|
console.log(` Expires: ${expiry.toISOString()}${isExpired ? " (EXPIRED)" : ""}`);
|
|
3542
3616
|
}
|
|
3617
|
+
console.log(
|
|
3618
|
+
` Refresh: ${refreshToken ? "Available (auto-refresh enabled)" : "Not available"}`
|
|
3619
|
+
);
|
|
3543
3620
|
if (isExpired) {
|
|
3544
|
-
|
|
3545
|
-
|
|
3546
|
-
|
|
3621
|
+
if (refreshToken) {
|
|
3622
|
+
console.log(
|
|
3623
|
+
"\nYour access token is expired, but a refresh token is available and will be used automatically."
|
|
3624
|
+
);
|
|
3625
|
+
} else {
|
|
3626
|
+
console.log(
|
|
3627
|
+
"\nYour token has expired. Run `trace auth login` after logging out to re-authenticate."
|
|
3628
|
+
);
|
|
3629
|
+
}
|
|
3547
3630
|
}
|
|
3548
3631
|
} else {
|
|
3549
|
-
console.log("Logged in to Trace (token stored at ~/.trace/token)");
|
|
3632
|
+
console.log("Logged in to Trace (access token stored at ~/.trace/token)");
|
|
3633
|
+
console.log(
|
|
3634
|
+
` Refresh: ${refreshToken ? "Available (auto-refresh enabled)" : "Not available"}`
|
|
3635
|
+
);
|
|
3550
3636
|
}
|
|
3551
3637
|
} catch {
|
|
3552
|
-
console.log("Logged in to Trace (token stored at ~/.trace/token)");
|
|
3638
|
+
console.log("Logged in to Trace (access token stored at ~/.trace/token)");
|
|
3639
|
+
console.log(
|
|
3640
|
+
` Refresh: ${refreshToken ? "Available (auto-refresh enabled)" : "Not available"}`
|
|
3641
|
+
);
|
|
3553
3642
|
}
|
|
3554
3643
|
} else {
|
|
3555
3644
|
console.log("Not logged in. Run `trace auth login` to authenticate.");
|
|
@@ -3593,7 +3682,7 @@ function extractCommandTree(cmd) {
|
|
|
3593
3682
|
description: o.description,
|
|
3594
3683
|
takesValue: o.required || o.optional
|
|
3595
3684
|
}));
|
|
3596
|
-
const subcommands = cmd.commands.filter((
|
|
3685
|
+
const subcommands = cmd.commands.filter((c24) => !c24._hidden).map((c24) => extractCommandTree(c24));
|
|
3597
3686
|
return {
|
|
3598
3687
|
name: cmd.name(),
|
|
3599
3688
|
description: cmd.description(),
|
|
@@ -3659,7 +3748,7 @@ function generateBashCompletion(tree, binName) {
|
|
|
3659
3748
|
}
|
|
3660
3749
|
function collectBashCases(tree, prefix) {
|
|
3661
3750
|
const cases = /* @__PURE__ */ new Map();
|
|
3662
|
-
const subcommandNames = tree.subcommands.map((
|
|
3751
|
+
const subcommandNames = tree.subcommands.map((c24) => c24.name);
|
|
3663
3752
|
const optionNames = tree.options.flatMap((o) => o.short ? [o.long, o.short] : [o.long]);
|
|
3664
3753
|
const extraOptions = prefix === "" ? ["--help", "--version"] : ["--help"];
|
|
3665
3754
|
const allOptions = [.../* @__PURE__ */ new Set([...optionNames, ...extraOptions])];
|
|
@@ -3848,7 +3937,7 @@ function generateCompletion(program3, shell, binName) {
|
|
|
3848
3937
|
import { existsSync as existsSync2, mkdirSync as mkdirSync2, writeFileSync as writeFileSync2 } from "fs";
|
|
3849
3938
|
import { homedir as homedir2 } from "os";
|
|
3850
3939
|
import { join as join2 } from "path";
|
|
3851
|
-
var
|
|
3940
|
+
var TRACE_DIR = ".trace";
|
|
3852
3941
|
function completionFileName(shell) {
|
|
3853
3942
|
switch (shell) {
|
|
3854
3943
|
case "bash":
|
|
@@ -3860,7 +3949,7 @@ function completionFileName(shell) {
|
|
|
3860
3949
|
}
|
|
3861
3950
|
}
|
|
3862
3951
|
function getTraceDir() {
|
|
3863
|
-
return join2(homedir2(),
|
|
3952
|
+
return join2(homedir2(), TRACE_DIR);
|
|
3864
3953
|
}
|
|
3865
3954
|
function getCompletionFilePath(shell) {
|
|
3866
3955
|
return join2(getTraceDir(), completionFileName(shell));
|
|
@@ -3875,7 +3964,7 @@ function writeCompletionFile(shell, script) {
|
|
|
3875
3964
|
return filePath;
|
|
3876
3965
|
}
|
|
3877
3966
|
function getSetupInstructions(shell) {
|
|
3878
|
-
const traceDir = `~/${
|
|
3967
|
+
const traceDir = `~/${TRACE_DIR}`;
|
|
3879
3968
|
switch (shell) {
|
|
3880
3969
|
case "bash":
|
|
3881
3970
|
return [
|
|
@@ -3946,11 +4035,6 @@ function createCompletionCommand(program3) {
|
|
|
3946
4035
|
});
|
|
3947
4036
|
}
|
|
3948
4037
|
|
|
3949
|
-
// src/repo/commands.ts
|
|
3950
|
-
import { chmodSync, mkdtempSync, rmSync as rmSync2, writeFileSync as writeFileSync3 } from "fs";
|
|
3951
|
-
import { tmpdir } from "os";
|
|
3952
|
-
import { join as join3 } from "path";
|
|
3953
|
-
|
|
3954
4038
|
// ../../node_modules/.bun/@ts-rest+core@3.53.0-rc.1+f9199aabcde8d6a0/node_modules/@ts-rest/core/index.esm.mjs
|
|
3955
4039
|
var util;
|
|
3956
4040
|
(function(util2) {
|
|
@@ -10719,7 +10803,7 @@ var $ZodBase64 = /* @__PURE__ */ $constructor("$ZodBase64", (inst, def) => {
|
|
|
10719
10803
|
function isValidBase64URL(data) {
|
|
10720
10804
|
if (!base64url.test(data))
|
|
10721
10805
|
return false;
|
|
10722
|
-
const base643 = data.replace(/[-_]/g, (
|
|
10806
|
+
const base643 = data.replace(/[-_]/g, (c24) => c24 === "-" ? "+" : "/");
|
|
10723
10807
|
const padded = base643.padEnd(Math.ceil(base643.length / 4) * 4, "=");
|
|
10724
10808
|
return isValidBase64(padded);
|
|
10725
10809
|
}
|
|
@@ -20763,9 +20847,9 @@ var ZodDate2 = /* @__PURE__ */ $constructor("ZodDate", (inst, def) => {
|
|
|
20763
20847
|
inst._zod.processJSONSchema = (ctx, json2, params) => dateProcessor(inst, ctx, json2, params);
|
|
20764
20848
|
inst.min = (value, params) => inst.check(_gte(value, params));
|
|
20765
20849
|
inst.max = (value, params) => inst.check(_lte(value, params));
|
|
20766
|
-
const
|
|
20767
|
-
inst.minDate =
|
|
20768
|
-
inst.maxDate =
|
|
20850
|
+
const c24 = inst._zod.bag;
|
|
20851
|
+
inst.minDate = c24.minimum ? new Date(c24.minimum) : null;
|
|
20852
|
+
inst.maxDate = c24.maximum ? new Date(c24.maximum) : null;
|
|
20769
20853
|
});
|
|
20770
20854
|
function date3(params) {
|
|
20771
20855
|
return _date(ZodDate2, params);
|
|
@@ -22887,19 +22971,51 @@ var llmProviderKeyContract = c7.router({
|
|
|
22887
22971
|
});
|
|
22888
22972
|
|
|
22889
22973
|
// ../../packages/api-contracts/src/schemas/api/v1/organization.api.ts
|
|
22974
|
+
var OrgCapabilityValues = [
|
|
22975
|
+
"PENTEST",
|
|
22976
|
+
"SCAN_SAST",
|
|
22977
|
+
"SCAN_SCA",
|
|
22978
|
+
"SCAN_SECRETS",
|
|
22979
|
+
"SCAN_DAST",
|
|
22980
|
+
"AUTO_PR_SCANS",
|
|
22981
|
+
"AUTO_PUSH_SCANS"
|
|
22982
|
+
];
|
|
22890
22983
|
var UpdateOrganizationRequestSchema = external_exports.object({
|
|
22891
22984
|
name: external_exports.string().min(1).max(255).optional(),
|
|
22892
|
-
logoUrl: external_exports.string().url().max(2048).nullish()
|
|
22985
|
+
logoUrl: external_exports.string().url().max(2048).nullish(),
|
|
22986
|
+
logoS3Key: external_exports.string().max(1024).nullish(),
|
|
22987
|
+
darkModeLogoUrl: external_exports.string().url().max(2048).nullish(),
|
|
22988
|
+
darkModeLogoS3Key: external_exports.string().max(1024).nullish()
|
|
22989
|
+
});
|
|
22990
|
+
var LogoUploadRequestSchema = external_exports.object({
|
|
22991
|
+
variant: external_exports.enum(["light", "dark"]),
|
|
22992
|
+
contentType: external_exports.enum(["image/png", "image/jpeg", "image/gif", "image/svg+xml", "image/webp"]),
|
|
22993
|
+
fileName: external_exports.string().min(1).max(255)
|
|
22994
|
+
});
|
|
22995
|
+
var LogoUploadResponseSchema = external_exports.object({
|
|
22996
|
+
uploadUrl: external_exports.string(),
|
|
22997
|
+
s3Key: external_exports.string()
|
|
22998
|
+
});
|
|
22999
|
+
var PatchCapabilitiesRequestSchema = external_exports.object({
|
|
23000
|
+
capabilities: external_exports.array(external_exports.enum(OrgCapabilityValues)).min(1)
|
|
23001
|
+
});
|
|
23002
|
+
var PatchCapabilitiesResponseSchema = external_exports.object({
|
|
23003
|
+
capabilities: external_exports.array(external_exports.enum(OrgCapabilityValues))
|
|
22893
23004
|
});
|
|
22894
23005
|
var OrganizationResponseSchema = external_exports.object({
|
|
22895
23006
|
organizationId: external_exports.uuid(),
|
|
22896
23007
|
name: external_exports.string(),
|
|
22897
23008
|
slug: external_exports.string(),
|
|
22898
23009
|
logoUrl: external_exports.string().nullable(),
|
|
23010
|
+
darkModeLogoUrl: external_exports.string().nullable(),
|
|
23011
|
+
capabilities: external_exports.array(external_exports.enum(OrgCapabilityValues)),
|
|
22899
23012
|
createdAt: external_exports.date(),
|
|
22900
23013
|
updatedAt: external_exports.date()
|
|
22901
23014
|
});
|
|
22902
23015
|
var ListOrganizationsResponseSchema = external_exports.array(OrganizationResponseSchema);
|
|
23016
|
+
var LogoDeleteRequestSchema = external_exports.object({
|
|
23017
|
+
variant: external_exports.enum(["light", "dark"])
|
|
23018
|
+
});
|
|
22903
23019
|
|
|
22904
23020
|
// ../../packages/api-contracts/src/contracts/v1/organization.ts
|
|
22905
23021
|
var c8 = initContract();
|
|
@@ -22951,103 +23067,167 @@ var organizationContract = c8.router({
|
|
|
22951
23067
|
404: ErrorResponseSchema,
|
|
22952
23068
|
500: ErrorResponseSchema
|
|
22953
23069
|
}
|
|
23070
|
+
},
|
|
23071
|
+
patchCapabilities: {
|
|
23072
|
+
method: "PATCH",
|
|
23073
|
+
path: "/organizations/:organizationId/capabilities",
|
|
23074
|
+
pathParams: OrgIdParamsSchema,
|
|
23075
|
+
body: PatchCapabilitiesRequestSchema,
|
|
23076
|
+
responses: {
|
|
23077
|
+
200: PatchCapabilitiesResponseSchema,
|
|
23078
|
+
401: ErrorResponseSchema,
|
|
23079
|
+
403: ErrorResponseSchema,
|
|
23080
|
+
404: ErrorResponseSchema,
|
|
23081
|
+
500: ErrorResponseSchema
|
|
23082
|
+
}
|
|
23083
|
+
},
|
|
23084
|
+
generateLogoUploadUrl: {
|
|
23085
|
+
method: "POST",
|
|
23086
|
+
path: "/organizations/:organizationId/logo-upload-url",
|
|
23087
|
+
pathParams: OrgIdParamsSchema,
|
|
23088
|
+
body: LogoUploadRequestSchema,
|
|
23089
|
+
responses: {
|
|
23090
|
+
200: LogoUploadResponseSchema,
|
|
23091
|
+
401: ErrorResponseSchema,
|
|
23092
|
+
403: ErrorResponseSchema,
|
|
23093
|
+
404: ErrorResponseSchema,
|
|
23094
|
+
500: ErrorResponseSchema
|
|
23095
|
+
}
|
|
22954
23096
|
}
|
|
22955
23097
|
});
|
|
22956
23098
|
|
|
22957
|
-
// ../../packages/api-contracts/src/schemas/
|
|
22958
|
-
var
|
|
22959
|
-
var
|
|
22960
|
-
var
|
|
22961
|
-
|
|
22962
|
-
|
|
22963
|
-
|
|
22964
|
-
|
|
22965
|
-
|
|
22966
|
-
|
|
22967
|
-
|
|
22968
|
-
|
|
22969
|
-
|
|
22970
|
-
|
|
22971
|
-
|
|
22972
|
-
|
|
22973
|
-
|
|
23099
|
+
// ../../packages/api-contracts/src/schemas/domain/pentest.schema.ts
|
|
23100
|
+
var PentestStatusValues = ["SCOPING", "IN_PROGRESS", "REMEDIATION", "CLOSED"];
|
|
23101
|
+
var PentestStatus = external_exports.enum(PentestStatusValues);
|
|
23102
|
+
var PentestFindingStatusValues = [
|
|
23103
|
+
"OPEN",
|
|
23104
|
+
"CONTESTED",
|
|
23105
|
+
"REMEDIATED",
|
|
23106
|
+
"VERIFIED_FIXED",
|
|
23107
|
+
"VERIFIED_OPEN"
|
|
23108
|
+
];
|
|
23109
|
+
var PentestFindingStatus = external_exports.enum(PentestFindingStatusValues);
|
|
23110
|
+
var PentestFindingSeverityValues = [
|
|
23111
|
+
"INFORMATIONAL",
|
|
23112
|
+
"LOW",
|
|
23113
|
+
"MEDIUM",
|
|
23114
|
+
"HIGH",
|
|
23115
|
+
"CRITICAL"
|
|
23116
|
+
];
|
|
23117
|
+
var PentestFindingSeverity = external_exports.enum(PentestFindingSeverityValues);
|
|
23118
|
+
var ContestReasonValues = [
|
|
23119
|
+
"FALSE_POSITIVE",
|
|
23120
|
+
"ACCEPTED_RISK",
|
|
23121
|
+
"MITIGATING_CONTROLS",
|
|
23122
|
+
"OUT_OF_SCOPE",
|
|
23123
|
+
"DUPLICATE",
|
|
23124
|
+
"OTHER"
|
|
23125
|
+
];
|
|
23126
|
+
var ContestReason = external_exports.enum(ContestReasonValues);
|
|
23127
|
+
var RetestOutcomeValues = ["FIXED", "PARTIALLY_FIXED", "NOT_FIXED"];
|
|
23128
|
+
var RetestOutcome = external_exports.enum(RetestOutcomeValues);
|
|
23129
|
+
|
|
23130
|
+
// ../../packages/api-contracts/src/schemas/api/v1/pentest.api.ts
|
|
23131
|
+
var PentestIdParamsSchema = OrgIdParamsSchema.extend({
|
|
23132
|
+
pentestId: external_exports.uuid()
|
|
22974
23133
|
});
|
|
22975
|
-
var
|
|
22976
|
-
|
|
23134
|
+
var PentestResponseSchema = external_exports.object({
|
|
23135
|
+
pentestId: external_exports.uuid(),
|
|
22977
23136
|
organizationId: external_exports.uuid(),
|
|
22978
|
-
|
|
22979
|
-
|
|
22980
|
-
|
|
22981
|
-
|
|
22982
|
-
|
|
22983
|
-
|
|
22984
|
-
|
|
22985
|
-
|
|
22986
|
-
|
|
22987
|
-
|
|
23137
|
+
displayId: external_exports.number(),
|
|
23138
|
+
title: external_exports.string(),
|
|
23139
|
+
description: external_exports.string().nullable(),
|
|
23140
|
+
status: PentestStatus,
|
|
23141
|
+
scope: external_exports.string().nullable(),
|
|
23142
|
+
startedAt: external_exports.coerce.date().nullable(),
|
|
23143
|
+
endedAt: external_exports.coerce.date().nullable(),
|
|
23144
|
+
createdById: external_exports.uuid(),
|
|
23145
|
+
createdByName: external_exports.string(),
|
|
23146
|
+
createdAt: external_exports.coerce.date(),
|
|
23147
|
+
updatedAt: external_exports.coerce.date(),
|
|
23148
|
+
findingCounts: external_exports.object({
|
|
23149
|
+
total: external_exports.number(),
|
|
23150
|
+
bySeverity: external_exports.record(PentestFindingSeverity, external_exports.number()),
|
|
23151
|
+
byStatus: external_exports.record(PentestFindingStatus, external_exports.number())
|
|
23152
|
+
})
|
|
22988
23153
|
});
|
|
22989
|
-
var
|
|
22990
|
-
|
|
22991
|
-
|
|
23154
|
+
var ListPentestsResponseSchema = external_exports.array(PentestResponseSchema);
|
|
23155
|
+
var CreatePentestRequestSchema = external_exports.object({
|
|
23156
|
+
title: external_exports.string().min(1).max(500),
|
|
23157
|
+
description: external_exports.string().max(1e4).optional(),
|
|
23158
|
+
scope: external_exports.string().max(5e4).optional(),
|
|
23159
|
+
status: PentestStatus.optional(),
|
|
23160
|
+
startedAt: external_exports.coerce.date().optional(),
|
|
23161
|
+
endedAt: external_exports.coerce.date().optional()
|
|
23162
|
+
});
|
|
23163
|
+
var UpdatePentestRequestSchema = external_exports.object({
|
|
23164
|
+
title: external_exports.string().min(1).max(500).optional(),
|
|
23165
|
+
description: external_exports.string().max(1e4).nullable().optional(),
|
|
23166
|
+
status: PentestStatus.optional(),
|
|
23167
|
+
scope: external_exports.string().max(5e4).nullable().optional(),
|
|
23168
|
+
startedAt: external_exports.coerce.date().nullable().optional(),
|
|
23169
|
+
endedAt: external_exports.coerce.date().nullable().optional()
|
|
22992
23170
|
});
|
|
22993
23171
|
|
|
22994
|
-
// ../../packages/api-contracts/src/contracts/v1/
|
|
23172
|
+
// ../../packages/api-contracts/src/contracts/v1/pentest.ts
|
|
22995
23173
|
var c9 = initContract();
|
|
22996
|
-
var
|
|
22997
|
-
|
|
22998
|
-
method: "
|
|
22999
|
-
path: "/organizations/:organizationId/
|
|
23174
|
+
var pentestContract = c9.router({
|
|
23175
|
+
listPentests: {
|
|
23176
|
+
method: "GET",
|
|
23177
|
+
path: "/organizations/:organizationId/pentests",
|
|
23000
23178
|
pathParams: OrgIdParamsSchema,
|
|
23001
|
-
body: CreateRepositoryRequestSchema,
|
|
23002
23179
|
responses: {
|
|
23003
|
-
|
|
23180
|
+
200: ListPentestsResponseSchema,
|
|
23004
23181
|
401: ErrorResponseSchema,
|
|
23005
23182
|
403: ErrorResponseSchema,
|
|
23006
23183
|
404: ErrorResponseSchema,
|
|
23007
23184
|
500: ErrorResponseSchema
|
|
23008
23185
|
}
|
|
23009
23186
|
},
|
|
23010
|
-
|
|
23011
|
-
method: "
|
|
23012
|
-
path: "/organizations/:organizationId/
|
|
23187
|
+
createPentest: {
|
|
23188
|
+
method: "POST",
|
|
23189
|
+
path: "/organizations/:organizationId/pentests",
|
|
23013
23190
|
pathParams: OrgIdParamsSchema,
|
|
23191
|
+
body: CreatePentestRequestSchema,
|
|
23014
23192
|
responses: {
|
|
23015
|
-
|
|
23193
|
+
201: PentestResponseSchema,
|
|
23194
|
+
400: ErrorResponseSchema,
|
|
23016
23195
|
401: ErrorResponseSchema,
|
|
23017
23196
|
403: ErrorResponseSchema,
|
|
23018
23197
|
404: ErrorResponseSchema,
|
|
23019
23198
|
500: ErrorResponseSchema
|
|
23020
23199
|
}
|
|
23021
23200
|
},
|
|
23022
|
-
|
|
23201
|
+
getPentest: {
|
|
23023
23202
|
method: "GET",
|
|
23024
|
-
path: "/organizations/:organizationId/
|
|
23025
|
-
pathParams:
|
|
23203
|
+
path: "/organizations/:organizationId/pentests/:pentestId",
|
|
23204
|
+
pathParams: PentestIdParamsSchema,
|
|
23026
23205
|
responses: {
|
|
23027
|
-
200:
|
|
23206
|
+
200: PentestResponseSchema,
|
|
23028
23207
|
401: ErrorResponseSchema,
|
|
23029
23208
|
403: ErrorResponseSchema,
|
|
23030
23209
|
404: ErrorResponseSchema,
|
|
23031
23210
|
500: ErrorResponseSchema
|
|
23032
23211
|
}
|
|
23033
23212
|
},
|
|
23034
|
-
|
|
23035
|
-
method: "
|
|
23036
|
-
path: "/organizations/:organizationId/
|
|
23037
|
-
pathParams:
|
|
23038
|
-
body:
|
|
23213
|
+
updatePentest: {
|
|
23214
|
+
method: "PATCH",
|
|
23215
|
+
path: "/organizations/:organizationId/pentests/:pentestId",
|
|
23216
|
+
pathParams: PentestIdParamsSchema,
|
|
23217
|
+
body: UpdatePentestRequestSchema,
|
|
23039
23218
|
responses: {
|
|
23040
|
-
200:
|
|
23219
|
+
200: PentestResponseSchema,
|
|
23220
|
+
400: ErrorResponseSchema,
|
|
23041
23221
|
401: ErrorResponseSchema,
|
|
23042
23222
|
403: ErrorResponseSchema,
|
|
23043
23223
|
404: ErrorResponseSchema,
|
|
23044
23224
|
500: ErrorResponseSchema
|
|
23045
23225
|
}
|
|
23046
23226
|
},
|
|
23047
|
-
|
|
23227
|
+
deletePentest: {
|
|
23048
23228
|
method: "DELETE",
|
|
23049
|
-
path: "/organizations/:organizationId/
|
|
23050
|
-
pathParams:
|
|
23229
|
+
path: "/organizations/:organizationId/pentests/:pentestId",
|
|
23230
|
+
pathParams: PentestIdParamsSchema,
|
|
23051
23231
|
responses: {
|
|
23052
23232
|
204: DeleteResponseSchema,
|
|
23053
23233
|
401: ErrorResponseSchema,
|
|
@@ -23055,135 +23235,612 @@ var repositoryContract = c9.router({
|
|
|
23055
23235
|
404: ErrorResponseSchema,
|
|
23056
23236
|
500: ErrorResponseSchema
|
|
23057
23237
|
}
|
|
23058
|
-
},
|
|
23059
|
-
getCloneToken: {
|
|
23060
|
-
method: "POST",
|
|
23061
|
-
path: "/organizations/:organizationId/repositories/clone-token",
|
|
23062
|
-
pathParams: OrgIdParamsSchema,
|
|
23063
|
-
body: CloneTokenRequestSchema,
|
|
23064
|
-
responses: {
|
|
23065
|
-
200: CloneTokenResponseSchema,
|
|
23066
|
-
401: ErrorResponseSchema,
|
|
23067
|
-
403: ErrorResponseSchema,
|
|
23068
|
-
404: ErrorResponseSchema,
|
|
23069
|
-
500: ErrorResponseSchema
|
|
23070
|
-
}
|
|
23071
23238
|
}
|
|
23072
23239
|
});
|
|
23073
23240
|
|
|
23074
|
-
// ../../packages/api-contracts/src/schemas/
|
|
23075
|
-
var
|
|
23076
|
-
|
|
23077
|
-
"QUEUED",
|
|
23078
|
-
"RUNNING",
|
|
23079
|
-
"COMPLETED",
|
|
23080
|
-
"FAILED",
|
|
23081
|
-
"CANCELLED"
|
|
23082
|
-
];
|
|
23083
|
-
var ScanStatus = external_exports.enum(ScanStatusValues);
|
|
23084
|
-
var ScanModeValues = ["DAST", "SAST", "SCA", "SECRETS"];
|
|
23085
|
-
var ScanMode = external_exports.enum(ScanModeValues);
|
|
23086
|
-
var ScanTypeValues = ["FULL", "INCREMENTAL", "RETEST"];
|
|
23087
|
-
var ScanType = external_exports.enum(ScanTypeValues);
|
|
23088
|
-
var CancellationReasonValues = ["USER_ABORTED", "SUPERSEDED"];
|
|
23089
|
-
var CancellationReason = external_exports.enum(CancellationReasonValues);
|
|
23090
|
-
var ScanTriggerTypeValues = [
|
|
23091
|
-
"MANUAL",
|
|
23092
|
-
"PUSH",
|
|
23093
|
-
"PULL_REQUEST",
|
|
23094
|
-
"RETEST",
|
|
23095
|
-
"SCHEDULED"
|
|
23096
|
-
];
|
|
23097
|
-
var ScanTriggerType = external_exports.enum(ScanTriggerTypeValues);
|
|
23098
|
-
|
|
23099
|
-
// ../../packages/api-contracts/src/schemas/api/v1/scan.api.ts
|
|
23100
|
-
var ScanIdParamsSchema = OrgIdParamsSchema.extend({
|
|
23101
|
-
scanId: external_exports.uuid()
|
|
23102
|
-
});
|
|
23103
|
-
var CreateScanRequestSchema = external_exports.discriminatedUnion("scanMode", [
|
|
23104
|
-
external_exports.object({
|
|
23105
|
-
scanMode: external_exports.literal("DAST"),
|
|
23106
|
-
webApplicationId: external_exports.uuid(),
|
|
23107
|
-
targetUrl: external_exports.url(),
|
|
23108
|
-
userProvidedContext: external_exports.string().optional(),
|
|
23109
|
-
scanConfiguration: external_exports.record(external_exports.string(), external_exports.unknown()).optional()
|
|
23110
|
-
}),
|
|
23111
|
-
external_exports.object({
|
|
23112
|
-
scanMode: external_exports.literal("SAST"),
|
|
23113
|
-
repositoryId: external_exports.uuid(),
|
|
23114
|
-
branch: external_exports.string().optional(),
|
|
23115
|
-
scanType: external_exports.enum(["FULL", "INCREMENTAL"]).optional(),
|
|
23116
|
-
userProvidedContext: external_exports.string().optional(),
|
|
23117
|
-
scanConfiguration: external_exports.record(external_exports.string(), external_exports.unknown()).optional()
|
|
23118
|
-
}),
|
|
23119
|
-
external_exports.object({
|
|
23120
|
-
scanMode: external_exports.literal("SCA"),
|
|
23121
|
-
repositoryId: external_exports.uuid(),
|
|
23122
|
-
branch: external_exports.string().optional(),
|
|
23123
|
-
scanType: external_exports.enum(["FULL", "INCREMENTAL"]).optional(),
|
|
23124
|
-
userProvidedContext: external_exports.string().optional(),
|
|
23125
|
-
scanConfiguration: external_exports.record(external_exports.string(), external_exports.unknown()).optional()
|
|
23126
|
-
}),
|
|
23127
|
-
external_exports.object({
|
|
23128
|
-
scanMode: external_exports.literal("SECRETS"),
|
|
23129
|
-
repositoryId: external_exports.uuid(),
|
|
23130
|
-
branch: external_exports.string().optional(),
|
|
23131
|
-
scanType: external_exports.enum(["FULL", "INCREMENTAL"]).optional(),
|
|
23132
|
-
userProvidedContext: external_exports.string().optional(),
|
|
23133
|
-
scanConfiguration: external_exports.record(external_exports.string(), external_exports.unknown()).optional()
|
|
23134
|
-
})
|
|
23135
|
-
]);
|
|
23136
|
-
var ScanResponseSchema = external_exports.object({
|
|
23137
|
-
scanId: external_exports.uuid(),
|
|
23138
|
-
organizationId: external_exports.uuid(),
|
|
23139
|
-
initiatedById: external_exports.uuid(),
|
|
23140
|
-
initiatedByName: external_exports.string().nullable(),
|
|
23141
|
-
initiatedByProfilePictureUrl: external_exports.string().nullable(),
|
|
23142
|
-
scanMode: ScanMode,
|
|
23143
|
-
scanType: external_exports.enum(ScanTypeValues),
|
|
23144
|
-
webApplicationId: external_exports.uuid().nullable(),
|
|
23145
|
-
targetUrl: external_exports.string().nullable(),
|
|
23146
|
-
repositoryId: external_exports.uuid().nullable(),
|
|
23147
|
-
branch: external_exports.string().nullable(),
|
|
23148
|
-
status: external_exports.enum(ScanStatusValues),
|
|
23149
|
-
cancellationReason: external_exports.enum(CancellationReasonValues).nullable(),
|
|
23150
|
-
errorMessage: external_exports.string().nullable(),
|
|
23151
|
-
userProvidedContext: external_exports.string().nullable(),
|
|
23152
|
-
scanConfiguration: external_exports.record(external_exports.string(), external_exports.unknown()).nullable(),
|
|
23153
|
-
triggerType: external_exports.enum(ScanTriggerTypeValues).nullable(),
|
|
23154
|
-
triggerMetadata: external_exports.record(external_exports.string(), external_exports.unknown()).nullable(),
|
|
23155
|
-
startedAt: external_exports.date().nullable(),
|
|
23156
|
-
completedAt: external_exports.date().nullable(),
|
|
23157
|
-
createdAt: external_exports.date(),
|
|
23158
|
-
updatedAt: external_exports.date()
|
|
23241
|
+
// ../../packages/api-contracts/src/schemas/api/v1/pentest-finding.api.ts
|
|
23242
|
+
var PentestFindingParamsSchema = OrgIdParamsSchema.extend({
|
|
23243
|
+
pentestId: external_exports.uuid()
|
|
23159
23244
|
});
|
|
23160
|
-
var
|
|
23161
|
-
|
|
23245
|
+
var PentestFindingIdParamsSchema = PentestFindingParamsSchema.extend({
|
|
23246
|
+
pentestFindingId: external_exports.uuid()
|
|
23162
23247
|
});
|
|
23163
|
-
var
|
|
23164
|
-
|
|
23165
|
-
scanId: external_exports.uuid(),
|
|
23166
|
-
status: external_exports.literal("CANCELLED")
|
|
23248
|
+
var PentestFindingContestIdParamsSchema = PentestFindingIdParamsSchema.extend({
|
|
23249
|
+
contestId: external_exports.uuid()
|
|
23167
23250
|
});
|
|
23168
|
-
|
|
23169
|
-
|
|
23170
|
-
var ScanLogQuerySchema = external_exports.object({
|
|
23171
|
-
offset: external_exports.coerce.number().int().min(0).optional()
|
|
23251
|
+
var PentestFindingRetestIdParamsSchema = PentestFindingIdParamsSchema.extend({
|
|
23252
|
+
retestId: external_exports.uuid()
|
|
23172
23253
|
});
|
|
23173
|
-
var
|
|
23174
|
-
|
|
23175
|
-
level: external_exports.enum(["INFO", "WARN", "ERROR"]),
|
|
23176
|
-
message: external_exports.string(),
|
|
23177
|
-
phase: external_exports.string().nullable()
|
|
23254
|
+
var PentestFindingNoteIdParamsSchema = PentestFindingIdParamsSchema.extend({
|
|
23255
|
+
noteId: external_exports.uuid()
|
|
23178
23256
|
});
|
|
23179
|
-
var
|
|
23180
|
-
|
|
23181
|
-
|
|
23257
|
+
var PentestFindingRepositorySchema = external_exports.object({
|
|
23258
|
+
repositoryId: external_exports.uuid(),
|
|
23259
|
+
repositoryName: external_exports.string(),
|
|
23260
|
+
commitSha: external_exports.string().nullable(),
|
|
23261
|
+
filePath: external_exports.string().nullable(),
|
|
23262
|
+
startLine: external_exports.number().nullable(),
|
|
23263
|
+
endLine: external_exports.number().nullable()
|
|
23182
23264
|
});
|
|
23183
|
-
|
|
23265
|
+
var PentestFindingResponseSchema = external_exports.object({
|
|
23266
|
+
pentestFindingId: external_exports.uuid(),
|
|
23267
|
+
organizationId: external_exports.uuid(),
|
|
23268
|
+
pentestId: external_exports.uuid(),
|
|
23269
|
+
displayId: external_exports.number(),
|
|
23270
|
+
title: external_exports.string(),
|
|
23271
|
+
description: external_exports.string(),
|
|
23272
|
+
severity: PentestFindingSeverity,
|
|
23273
|
+
category: external_exports.string(),
|
|
23274
|
+
status: PentestFindingStatus,
|
|
23275
|
+
cweIds: external_exports.array(external_exports.string()),
|
|
23276
|
+
cvssVector: external_exports.string().nullable(),
|
|
23277
|
+
cvssScore: external_exports.number().nullable(),
|
|
23278
|
+
owaspCategory: external_exports.string().nullable(),
|
|
23279
|
+
publishedAt: external_exports.coerce.date().nullable(),
|
|
23280
|
+
createdById: external_exports.uuid(),
|
|
23281
|
+
createdByName: external_exports.string(),
|
|
23282
|
+
createdAt: external_exports.coerce.date(),
|
|
23283
|
+
updatedAt: external_exports.coerce.date(),
|
|
23284
|
+
repositories: external_exports.array(PentestFindingRepositorySchema)
|
|
23285
|
+
});
|
|
23286
|
+
var ListPentestFindingsResponseSchema = external_exports.array(PentestFindingResponseSchema);
|
|
23287
|
+
var CreatePentestFindingRequestSchema = external_exports.object({
|
|
23288
|
+
title: external_exports.string().min(1).max(500),
|
|
23289
|
+
description: external_exports.string().min(1).max(5e4),
|
|
23290
|
+
severity: PentestFindingSeverity,
|
|
23291
|
+
category: external_exports.string().min(1).max(200),
|
|
23292
|
+
status: PentestFindingStatus.optional(),
|
|
23293
|
+
cweIds: external_exports.array(external_exports.string()).optional(),
|
|
23294
|
+
cvssVector: external_exports.string().max(200).optional(),
|
|
23295
|
+
cvssScore: external_exports.number().min(0).max(10).optional(),
|
|
23296
|
+
owaspCategory: external_exports.string().max(200).optional(),
|
|
23297
|
+
repositories: external_exports.array(
|
|
23298
|
+
external_exports.object({
|
|
23299
|
+
repositoryId: external_exports.uuid(),
|
|
23300
|
+
commitSha: external_exports.string().optional(),
|
|
23301
|
+
filePath: external_exports.string().optional(),
|
|
23302
|
+
startLine: external_exports.number().int().optional(),
|
|
23303
|
+
endLine: external_exports.number().int().optional()
|
|
23304
|
+
})
|
|
23305
|
+
).optional()
|
|
23306
|
+
});
|
|
23307
|
+
var UpdatePentestFindingRequestSchema = external_exports.object({
|
|
23308
|
+
title: external_exports.string().min(1).max(500).optional(),
|
|
23309
|
+
description: external_exports.string().min(1).max(5e4).optional(),
|
|
23310
|
+
severity: PentestFindingSeverity.optional(),
|
|
23311
|
+
category: external_exports.string().min(1).max(200).optional(),
|
|
23312
|
+
status: PentestFindingStatus.optional(),
|
|
23313
|
+
cweIds: external_exports.array(external_exports.string()).optional(),
|
|
23314
|
+
cvssVector: external_exports.string().max(200).nullable().optional(),
|
|
23315
|
+
cvssScore: external_exports.number().min(0).max(10).nullable().optional(),
|
|
23316
|
+
owaspCategory: external_exports.string().max(200).nullable().optional(),
|
|
23317
|
+
publishedAt: external_exports.coerce.date().nullable().optional(),
|
|
23318
|
+
repositories: external_exports.array(
|
|
23319
|
+
external_exports.object({
|
|
23320
|
+
repositoryId: external_exports.uuid(),
|
|
23321
|
+
commitSha: external_exports.string().optional(),
|
|
23322
|
+
filePath: external_exports.string().optional(),
|
|
23323
|
+
startLine: external_exports.number().int().optional(),
|
|
23324
|
+
endLine: external_exports.number().int().optional()
|
|
23325
|
+
})
|
|
23326
|
+
).optional()
|
|
23327
|
+
});
|
|
23328
|
+
var PentestFindingContestResponseSchema = external_exports.object({
|
|
23329
|
+
contestId: external_exports.uuid(),
|
|
23330
|
+
pentestFindingId: external_exports.uuid(),
|
|
23331
|
+
organizationId: external_exports.uuid(),
|
|
23332
|
+
reason: ContestReason,
|
|
23333
|
+
justification: external_exports.string(),
|
|
23334
|
+
contestedById: external_exports.uuid(),
|
|
23335
|
+
contestedByName: external_exports.string(),
|
|
23336
|
+
contestedAt: external_exports.coerce.date(),
|
|
23337
|
+
resolution: external_exports.string().nullable(),
|
|
23338
|
+
resolvedById: external_exports.uuid().nullable(),
|
|
23339
|
+
resolvedByName: external_exports.string().nullable(),
|
|
23340
|
+
resolvedAt: external_exports.coerce.date().nullable()
|
|
23341
|
+
});
|
|
23342
|
+
var ListPentestFindingContestsResponseSchema = external_exports.array(
|
|
23343
|
+
PentestFindingContestResponseSchema
|
|
23344
|
+
);
|
|
23345
|
+
var CreatePentestFindingContestRequestSchema = external_exports.object({
|
|
23346
|
+
reason: ContestReason,
|
|
23347
|
+
justification: external_exports.string().min(1).max(1e4)
|
|
23348
|
+
});
|
|
23349
|
+
var ResolvePentestFindingContestRequestSchema = external_exports.object({
|
|
23350
|
+
resolution: external_exports.string().min(1).max(1e4)
|
|
23351
|
+
});
|
|
23352
|
+
var PentestFindingRetestResponseSchema = external_exports.object({
|
|
23353
|
+
retestId: external_exports.uuid(),
|
|
23354
|
+
pentestFindingId: external_exports.uuid(),
|
|
23355
|
+
organizationId: external_exports.uuid(),
|
|
23356
|
+
outcome: RetestOutcome,
|
|
23357
|
+
notes: external_exports.string().nullable(),
|
|
23358
|
+
testedById: external_exports.uuid(),
|
|
23359
|
+
testedByName: external_exports.string(),
|
|
23360
|
+
testedAt: external_exports.coerce.date()
|
|
23361
|
+
});
|
|
23362
|
+
var ListPentestFindingRetestsResponseSchema = external_exports.array(PentestFindingRetestResponseSchema);
|
|
23363
|
+
var CreatePentestFindingRetestRequestSchema = external_exports.object({
|
|
23364
|
+
outcome: RetestOutcome,
|
|
23365
|
+
notes: external_exports.string().max(1e4).optional()
|
|
23366
|
+
});
|
|
23367
|
+
var PentestFindingNoteResponseSchema = external_exports.object({
|
|
23368
|
+
noteId: external_exports.uuid(),
|
|
23369
|
+
pentestFindingId: external_exports.uuid(),
|
|
23370
|
+
organizationId: external_exports.uuid(),
|
|
23371
|
+
authorId: external_exports.uuid(),
|
|
23372
|
+
authorName: external_exports.string(),
|
|
23373
|
+
content: external_exports.string(),
|
|
23374
|
+
createdAt: external_exports.coerce.date(),
|
|
23375
|
+
updatedAt: external_exports.coerce.date()
|
|
23376
|
+
});
|
|
23377
|
+
var ListPentestFindingNotesResponseSchema = external_exports.array(PentestFindingNoteResponseSchema);
|
|
23378
|
+
var CreatePentestFindingNoteRequestSchema = external_exports.object({
|
|
23379
|
+
content: external_exports.string().min(1).max(1e4)
|
|
23380
|
+
});
|
|
23381
|
+
var UpdatePentestFindingNoteRequestSchema = external_exports.object({
|
|
23382
|
+
content: external_exports.string().min(1).max(1e4)
|
|
23383
|
+
});
|
|
23384
|
+
var ParseFindingMarkdownRequestSchema = external_exports.object({
|
|
23385
|
+
markdown: external_exports.string().min(1).max(1e5)
|
|
23386
|
+
});
|
|
23387
|
+
var ParseFindingMarkdownResponseSchema = external_exports.object({
|
|
23388
|
+
title: external_exports.string(),
|
|
23389
|
+
description: external_exports.string(),
|
|
23390
|
+
severity: PentestFindingSeverity,
|
|
23391
|
+
category: external_exports.string(),
|
|
23392
|
+
status: PentestFindingStatus,
|
|
23393
|
+
cweIds: external_exports.array(external_exports.string()),
|
|
23394
|
+
cvssVector: external_exports.string().nullable(),
|
|
23395
|
+
cvssScore: external_exports.number().nullable(),
|
|
23396
|
+
owaspCategory: external_exports.string().nullable()
|
|
23397
|
+
});
|
|
23398
|
+
|
|
23399
|
+
// ../../packages/api-contracts/src/contracts/v1/pentest-finding.ts
|
|
23400
|
+
var c10 = initContract();
|
|
23401
|
+
var pentestFindingContract = c10.router({
|
|
23402
|
+
// ─── Findings ───
|
|
23403
|
+
listFindings: {
|
|
23404
|
+
method: "GET",
|
|
23405
|
+
path: "/organizations/:organizationId/pentests/:pentestId/findings",
|
|
23406
|
+
pathParams: PentestFindingParamsSchema,
|
|
23407
|
+
responses: {
|
|
23408
|
+
200: ListPentestFindingsResponseSchema,
|
|
23409
|
+
401: ErrorResponseSchema,
|
|
23410
|
+
403: ErrorResponseSchema,
|
|
23411
|
+
404: ErrorResponseSchema,
|
|
23412
|
+
500: ErrorResponseSchema
|
|
23413
|
+
}
|
|
23414
|
+
},
|
|
23415
|
+
createFinding: {
|
|
23416
|
+
method: "POST",
|
|
23417
|
+
path: "/organizations/:organizationId/pentests/:pentestId/findings",
|
|
23418
|
+
pathParams: PentestFindingParamsSchema,
|
|
23419
|
+
body: CreatePentestFindingRequestSchema,
|
|
23420
|
+
responses: {
|
|
23421
|
+
201: PentestFindingResponseSchema,
|
|
23422
|
+
400: ErrorResponseSchema,
|
|
23423
|
+
401: ErrorResponseSchema,
|
|
23424
|
+
403: ErrorResponseSchema,
|
|
23425
|
+
404: ErrorResponseSchema,
|
|
23426
|
+
500: ErrorResponseSchema
|
|
23427
|
+
}
|
|
23428
|
+
},
|
|
23429
|
+
getFinding: {
|
|
23430
|
+
method: "GET",
|
|
23431
|
+
path: "/organizations/:organizationId/pentests/:pentestId/findings/:pentestFindingId",
|
|
23432
|
+
pathParams: PentestFindingIdParamsSchema,
|
|
23433
|
+
responses: {
|
|
23434
|
+
200: PentestFindingResponseSchema,
|
|
23435
|
+
401: ErrorResponseSchema,
|
|
23436
|
+
403: ErrorResponseSchema,
|
|
23437
|
+
404: ErrorResponseSchema,
|
|
23438
|
+
500: ErrorResponseSchema
|
|
23439
|
+
}
|
|
23440
|
+
},
|
|
23441
|
+
updateFinding: {
|
|
23442
|
+
method: "PATCH",
|
|
23443
|
+
path: "/organizations/:organizationId/pentests/:pentestId/findings/:pentestFindingId",
|
|
23444
|
+
pathParams: PentestFindingIdParamsSchema,
|
|
23445
|
+
body: UpdatePentestFindingRequestSchema,
|
|
23446
|
+
responses: {
|
|
23447
|
+
200: PentestFindingResponseSchema,
|
|
23448
|
+
400: ErrorResponseSchema,
|
|
23449
|
+
401: ErrorResponseSchema,
|
|
23450
|
+
403: ErrorResponseSchema,
|
|
23451
|
+
404: ErrorResponseSchema,
|
|
23452
|
+
500: ErrorResponseSchema
|
|
23453
|
+
}
|
|
23454
|
+
},
|
|
23455
|
+
deleteFinding: {
|
|
23456
|
+
method: "DELETE",
|
|
23457
|
+
path: "/organizations/:organizationId/pentests/:pentestId/findings/:pentestFindingId",
|
|
23458
|
+
pathParams: PentestFindingIdParamsSchema,
|
|
23459
|
+
responses: {
|
|
23460
|
+
204: DeleteResponseSchema,
|
|
23461
|
+
401: ErrorResponseSchema,
|
|
23462
|
+
403: ErrorResponseSchema,
|
|
23463
|
+
404: ErrorResponseSchema,
|
|
23464
|
+
500: ErrorResponseSchema
|
|
23465
|
+
}
|
|
23466
|
+
},
|
|
23467
|
+
// ─── Contests ───
|
|
23468
|
+
listContests: {
|
|
23469
|
+
method: "GET",
|
|
23470
|
+
path: "/organizations/:organizationId/pentests/:pentestId/findings/:pentestFindingId/contests",
|
|
23471
|
+
pathParams: PentestFindingIdParamsSchema,
|
|
23472
|
+
responses: {
|
|
23473
|
+
200: ListPentestFindingContestsResponseSchema,
|
|
23474
|
+
401: ErrorResponseSchema,
|
|
23475
|
+
403: ErrorResponseSchema,
|
|
23476
|
+
404: ErrorResponseSchema,
|
|
23477
|
+
500: ErrorResponseSchema
|
|
23478
|
+
}
|
|
23479
|
+
},
|
|
23480
|
+
createContest: {
|
|
23481
|
+
method: "POST",
|
|
23482
|
+
path: "/organizations/:organizationId/pentests/:pentestId/findings/:pentestFindingId/contests",
|
|
23483
|
+
pathParams: PentestFindingIdParamsSchema,
|
|
23484
|
+
body: CreatePentestFindingContestRequestSchema,
|
|
23485
|
+
responses: {
|
|
23486
|
+
201: PentestFindingContestResponseSchema,
|
|
23487
|
+
400: ErrorResponseSchema,
|
|
23488
|
+
401: ErrorResponseSchema,
|
|
23489
|
+
403: ErrorResponseSchema,
|
|
23490
|
+
404: ErrorResponseSchema,
|
|
23491
|
+
500: ErrorResponseSchema
|
|
23492
|
+
}
|
|
23493
|
+
},
|
|
23494
|
+
resolveContest: {
|
|
23495
|
+
method: "PATCH",
|
|
23496
|
+
path: "/organizations/:organizationId/pentests/:pentestId/findings/:pentestFindingId/contests/:contestId",
|
|
23497
|
+
pathParams: PentestFindingContestIdParamsSchema,
|
|
23498
|
+
body: ResolvePentestFindingContestRequestSchema,
|
|
23499
|
+
responses: {
|
|
23500
|
+
200: PentestFindingContestResponseSchema,
|
|
23501
|
+
400: ErrorResponseSchema,
|
|
23502
|
+
401: ErrorResponseSchema,
|
|
23503
|
+
403: ErrorResponseSchema,
|
|
23504
|
+
404: ErrorResponseSchema,
|
|
23505
|
+
500: ErrorResponseSchema
|
|
23506
|
+
}
|
|
23507
|
+
},
|
|
23508
|
+
// ─── Retests ───
|
|
23509
|
+
listRetests: {
|
|
23510
|
+
method: "GET",
|
|
23511
|
+
path: "/organizations/:organizationId/pentests/:pentestId/findings/:pentestFindingId/retests",
|
|
23512
|
+
pathParams: PentestFindingIdParamsSchema,
|
|
23513
|
+
responses: {
|
|
23514
|
+
200: ListPentestFindingRetestsResponseSchema,
|
|
23515
|
+
401: ErrorResponseSchema,
|
|
23516
|
+
403: ErrorResponseSchema,
|
|
23517
|
+
404: ErrorResponseSchema,
|
|
23518
|
+
500: ErrorResponseSchema
|
|
23519
|
+
}
|
|
23520
|
+
},
|
|
23521
|
+
createRetest: {
|
|
23522
|
+
method: "POST",
|
|
23523
|
+
path: "/organizations/:organizationId/pentests/:pentestId/findings/:pentestFindingId/retests",
|
|
23524
|
+
pathParams: PentestFindingIdParamsSchema,
|
|
23525
|
+
body: CreatePentestFindingRetestRequestSchema,
|
|
23526
|
+
responses: {
|
|
23527
|
+
201: PentestFindingRetestResponseSchema,
|
|
23528
|
+
400: ErrorResponseSchema,
|
|
23529
|
+
401: ErrorResponseSchema,
|
|
23530
|
+
403: ErrorResponseSchema,
|
|
23531
|
+
404: ErrorResponseSchema,
|
|
23532
|
+
500: ErrorResponseSchema
|
|
23533
|
+
}
|
|
23534
|
+
},
|
|
23535
|
+
// ─── Notes ───
|
|
23536
|
+
listNotes: {
|
|
23537
|
+
method: "GET",
|
|
23538
|
+
path: "/organizations/:organizationId/pentests/:pentestId/findings/:pentestFindingId/notes",
|
|
23539
|
+
pathParams: PentestFindingIdParamsSchema,
|
|
23540
|
+
responses: {
|
|
23541
|
+
200: ListPentestFindingNotesResponseSchema,
|
|
23542
|
+
401: ErrorResponseSchema,
|
|
23543
|
+
403: ErrorResponseSchema,
|
|
23544
|
+
404: ErrorResponseSchema,
|
|
23545
|
+
500: ErrorResponseSchema
|
|
23546
|
+
}
|
|
23547
|
+
},
|
|
23548
|
+
createNote: {
|
|
23549
|
+
method: "POST",
|
|
23550
|
+
path: "/organizations/:organizationId/pentests/:pentestId/findings/:pentestFindingId/notes",
|
|
23551
|
+
pathParams: PentestFindingIdParamsSchema,
|
|
23552
|
+
body: CreatePentestFindingNoteRequestSchema,
|
|
23553
|
+
responses: {
|
|
23554
|
+
201: PentestFindingNoteResponseSchema,
|
|
23555
|
+
400: ErrorResponseSchema,
|
|
23556
|
+
401: ErrorResponseSchema,
|
|
23557
|
+
403: ErrorResponseSchema,
|
|
23558
|
+
404: ErrorResponseSchema,
|
|
23559
|
+
500: ErrorResponseSchema
|
|
23560
|
+
}
|
|
23561
|
+
},
|
|
23562
|
+
updateNote: {
|
|
23563
|
+
method: "PATCH",
|
|
23564
|
+
path: "/organizations/:organizationId/pentests/:pentestId/findings/:pentestFindingId/notes/:noteId",
|
|
23565
|
+
pathParams: PentestFindingNoteIdParamsSchema,
|
|
23566
|
+
body: UpdatePentestFindingNoteRequestSchema,
|
|
23567
|
+
responses: {
|
|
23568
|
+
200: PentestFindingNoteResponseSchema,
|
|
23569
|
+
400: ErrorResponseSchema,
|
|
23570
|
+
401: ErrorResponseSchema,
|
|
23571
|
+
403: ErrorResponseSchema,
|
|
23572
|
+
404: ErrorResponseSchema,
|
|
23573
|
+
500: ErrorResponseSchema
|
|
23574
|
+
}
|
|
23575
|
+
},
|
|
23576
|
+
deleteNote: {
|
|
23577
|
+
method: "DELETE",
|
|
23578
|
+
path: "/organizations/:organizationId/pentests/:pentestId/findings/:pentestFindingId/notes/:noteId",
|
|
23579
|
+
pathParams: PentestFindingNoteIdParamsSchema,
|
|
23580
|
+
responses: {
|
|
23581
|
+
204: DeleteResponseSchema,
|
|
23582
|
+
401: ErrorResponseSchema,
|
|
23583
|
+
403: ErrorResponseSchema,
|
|
23584
|
+
404: ErrorResponseSchema,
|
|
23585
|
+
500: ErrorResponseSchema
|
|
23586
|
+
}
|
|
23587
|
+
},
|
|
23588
|
+
// ─── AI parsing ───
|
|
23589
|
+
parseFindingMarkdown: {
|
|
23590
|
+
method: "POST",
|
|
23591
|
+
path: "/organizations/:organizationId/pentests/:pentestId/findings/parse-markdown",
|
|
23592
|
+
pathParams: PentestFindingParamsSchema,
|
|
23593
|
+
body: ParseFindingMarkdownRequestSchema,
|
|
23594
|
+
responses: {
|
|
23595
|
+
200: ParseFindingMarkdownResponseSchema,
|
|
23596
|
+
400: ErrorResponseSchema,
|
|
23597
|
+
401: ErrorResponseSchema,
|
|
23598
|
+
403: ErrorResponseSchema,
|
|
23599
|
+
404: ErrorResponseSchema,
|
|
23600
|
+
500: ErrorResponseSchema
|
|
23601
|
+
}
|
|
23602
|
+
}
|
|
23603
|
+
});
|
|
23604
|
+
|
|
23605
|
+
// ../../packages/api-contracts/src/schemas/api/v1/repository.api.ts
|
|
23606
|
+
var PlatformValues = ["GITHUB", "GITLAB", "BITBUCKET"];
|
|
23607
|
+
var RepositoryStatusValues = ["CONNECTED", "DISCONNECTED"];
|
|
23608
|
+
var RepositoryIdParamsSchema = OrgIdParamsSchema.extend({
|
|
23609
|
+
repositoryId: external_exports.uuid()
|
|
23610
|
+
});
|
|
23611
|
+
var CreateRepositoryRequestSchema = external_exports.object({
|
|
23612
|
+
repositoryUrl: external_exports.url(),
|
|
23613
|
+
platform: external_exports.enum(PlatformValues),
|
|
23614
|
+
defaultBranch: external_exports.string().min(1).max(255).optional(),
|
|
23615
|
+
status: external_exports.enum(RepositoryStatusValues).optional()
|
|
23616
|
+
});
|
|
23617
|
+
var UpdateRepositoryRequestSchema = external_exports.object({
|
|
23618
|
+
repositoryUrl: external_exports.url().optional(),
|
|
23619
|
+
platform: external_exports.enum(PlatformValues).optional(),
|
|
23620
|
+
defaultBranch: external_exports.string().min(1).max(255).optional(),
|
|
23621
|
+
status: external_exports.enum(RepositoryStatusValues).optional()
|
|
23622
|
+
});
|
|
23623
|
+
var RepositoryResponseSchema = external_exports.object({
|
|
23624
|
+
repositoryId: external_exports.uuid(),
|
|
23625
|
+
organizationId: external_exports.uuid(),
|
|
23626
|
+
repositoryUrl: external_exports.url(),
|
|
23627
|
+
platform: external_exports.enum(PlatformValues),
|
|
23628
|
+
status: external_exports.enum(RepositoryStatusValues),
|
|
23629
|
+
defaultBranch: external_exports.string(),
|
|
23630
|
+
createdAt: external_exports.date(),
|
|
23631
|
+
updatedAt: external_exports.date()
|
|
23632
|
+
});
|
|
23633
|
+
var ListRepositoriesResponseSchema = external_exports.array(RepositoryResponseSchema);
|
|
23634
|
+
var CloneTokenRequestSchema = external_exports.object({
|
|
23635
|
+
repositoryUrl: external_exports.string().url()
|
|
23636
|
+
});
|
|
23637
|
+
var CloneTokenResponseSchema = external_exports.object({
|
|
23638
|
+
token: external_exports.string(),
|
|
23639
|
+
expiresAt: external_exports.string().datetime()
|
|
23640
|
+
});
|
|
23641
|
+
|
|
23642
|
+
// ../../packages/api-contracts/src/contracts/v1/repository.ts
|
|
23643
|
+
var c11 = initContract();
|
|
23644
|
+
var repositoryContract = c11.router({
|
|
23645
|
+
createRepository: {
|
|
23646
|
+
method: "POST",
|
|
23647
|
+
path: "/organizations/:organizationId/repositories",
|
|
23648
|
+
pathParams: OrgIdParamsSchema,
|
|
23649
|
+
body: CreateRepositoryRequestSchema,
|
|
23650
|
+
responses: {
|
|
23651
|
+
201: RepositoryResponseSchema,
|
|
23652
|
+
401: ErrorResponseSchema,
|
|
23653
|
+
403: ErrorResponseSchema,
|
|
23654
|
+
404: ErrorResponseSchema,
|
|
23655
|
+
500: ErrorResponseSchema
|
|
23656
|
+
}
|
|
23657
|
+
},
|
|
23658
|
+
listRepositories: {
|
|
23659
|
+
method: "GET",
|
|
23660
|
+
path: "/organizations/:organizationId/repositories",
|
|
23661
|
+
pathParams: OrgIdParamsSchema,
|
|
23662
|
+
responses: {
|
|
23663
|
+
200: ListRepositoriesResponseSchema,
|
|
23664
|
+
401: ErrorResponseSchema,
|
|
23665
|
+
403: ErrorResponseSchema,
|
|
23666
|
+
404: ErrorResponseSchema,
|
|
23667
|
+
500: ErrorResponseSchema
|
|
23668
|
+
}
|
|
23669
|
+
},
|
|
23670
|
+
getRepository: {
|
|
23671
|
+
method: "GET",
|
|
23672
|
+
path: "/organizations/:organizationId/repositories/:repositoryId",
|
|
23673
|
+
pathParams: RepositoryIdParamsSchema,
|
|
23674
|
+
responses: {
|
|
23675
|
+
200: RepositoryResponseSchema,
|
|
23676
|
+
401: ErrorResponseSchema,
|
|
23677
|
+
403: ErrorResponseSchema,
|
|
23678
|
+
404: ErrorResponseSchema,
|
|
23679
|
+
500: ErrorResponseSchema
|
|
23680
|
+
}
|
|
23681
|
+
},
|
|
23682
|
+
updateRepository: {
|
|
23683
|
+
method: "PUT",
|
|
23684
|
+
path: "/organizations/:organizationId/repositories/:repositoryId",
|
|
23685
|
+
pathParams: RepositoryIdParamsSchema,
|
|
23686
|
+
body: UpdateRepositoryRequestSchema,
|
|
23687
|
+
responses: {
|
|
23688
|
+
200: RepositoryResponseSchema,
|
|
23689
|
+
401: ErrorResponseSchema,
|
|
23690
|
+
403: ErrorResponseSchema,
|
|
23691
|
+
404: ErrorResponseSchema,
|
|
23692
|
+
500: ErrorResponseSchema
|
|
23693
|
+
}
|
|
23694
|
+
},
|
|
23695
|
+
deleteRepository: {
|
|
23696
|
+
method: "DELETE",
|
|
23697
|
+
path: "/organizations/:organizationId/repositories/:repositoryId",
|
|
23698
|
+
pathParams: RepositoryIdParamsSchema,
|
|
23699
|
+
responses: {
|
|
23700
|
+
204: DeleteResponseSchema,
|
|
23701
|
+
401: ErrorResponseSchema,
|
|
23702
|
+
403: ErrorResponseSchema,
|
|
23703
|
+
404: ErrorResponseSchema,
|
|
23704
|
+
500: ErrorResponseSchema
|
|
23705
|
+
}
|
|
23706
|
+
},
|
|
23707
|
+
getCloneToken: {
|
|
23708
|
+
method: "POST",
|
|
23709
|
+
path: "/organizations/:organizationId/repositories/clone-token",
|
|
23710
|
+
pathParams: OrgIdParamsSchema,
|
|
23711
|
+
body: CloneTokenRequestSchema,
|
|
23712
|
+
responses: {
|
|
23713
|
+
200: CloneTokenResponseSchema,
|
|
23714
|
+
401: ErrorResponseSchema,
|
|
23715
|
+
403: ErrorResponseSchema,
|
|
23716
|
+
404: ErrorResponseSchema,
|
|
23717
|
+
500: ErrorResponseSchema
|
|
23718
|
+
}
|
|
23719
|
+
}
|
|
23720
|
+
});
|
|
23721
|
+
|
|
23722
|
+
// ../../packages/api-contracts/src/schemas/domain/scan.schema.ts
|
|
23723
|
+
var ScanStatusValues = [
|
|
23724
|
+
"PENDING",
|
|
23725
|
+
"QUEUED",
|
|
23726
|
+
"RUNNING",
|
|
23727
|
+
"COMPLETED",
|
|
23728
|
+
"FAILED",
|
|
23729
|
+
"CANCELLED"
|
|
23730
|
+
];
|
|
23731
|
+
var ScanStatus = external_exports.enum(ScanStatusValues);
|
|
23732
|
+
var ScanModeValues = ["DAST", "SAST", "SCA", "SECRETS"];
|
|
23733
|
+
var ScanMode = external_exports.enum(ScanModeValues);
|
|
23734
|
+
var ScanTypeValues = ["FULL", "INCREMENTAL", "RETEST"];
|
|
23735
|
+
var ScanType = external_exports.enum(ScanTypeValues);
|
|
23736
|
+
var CancellationReasonValues = ["USER_ABORTED", "SUPERSEDED"];
|
|
23737
|
+
var CancellationReason = external_exports.enum(CancellationReasonValues);
|
|
23738
|
+
var ScanTriggerTypeValues = [
|
|
23739
|
+
"MANUAL",
|
|
23740
|
+
"PUSH",
|
|
23741
|
+
"PULL_REQUEST",
|
|
23742
|
+
"RETEST",
|
|
23743
|
+
"SCHEDULED"
|
|
23744
|
+
];
|
|
23745
|
+
var ScanTriggerType = external_exports.enum(ScanTriggerTypeValues);
|
|
23746
|
+
|
|
23747
|
+
// ../../packages/api-contracts/src/schemas/api/v1/scan.api.ts
|
|
23748
|
+
var ScanIdParamsSchema = OrgIdParamsSchema.extend({
|
|
23749
|
+
scanId: external_exports.uuid()
|
|
23750
|
+
});
|
|
23751
|
+
var CreateScanRequestSchema = external_exports.discriminatedUnion("scanMode", [
|
|
23752
|
+
external_exports.object({
|
|
23753
|
+
scanMode: external_exports.literal("DAST"),
|
|
23754
|
+
webApplicationId: external_exports.uuid(),
|
|
23755
|
+
targetUrl: external_exports.url(),
|
|
23756
|
+
userProvidedContext: external_exports.string().optional(),
|
|
23757
|
+
scanConfiguration: external_exports.record(external_exports.string(), external_exports.unknown()).optional()
|
|
23758
|
+
}),
|
|
23759
|
+
external_exports.object({
|
|
23760
|
+
scanMode: external_exports.literal("SAST"),
|
|
23761
|
+
repositoryId: external_exports.uuid(),
|
|
23762
|
+
branch: external_exports.string().optional(),
|
|
23763
|
+
scanType: external_exports.enum(["FULL", "INCREMENTAL"]).optional(),
|
|
23764
|
+
userProvidedContext: external_exports.string().optional(),
|
|
23765
|
+
scanConfiguration: external_exports.record(external_exports.string(), external_exports.unknown()).optional()
|
|
23766
|
+
}),
|
|
23767
|
+
external_exports.object({
|
|
23768
|
+
scanMode: external_exports.literal("SCA"),
|
|
23769
|
+
repositoryId: external_exports.uuid(),
|
|
23770
|
+
branch: external_exports.string().optional(),
|
|
23771
|
+
scanType: external_exports.enum(["FULL", "INCREMENTAL"]).optional(),
|
|
23772
|
+
userProvidedContext: external_exports.string().optional(),
|
|
23773
|
+
scanConfiguration: external_exports.record(external_exports.string(), external_exports.unknown()).optional()
|
|
23774
|
+
}),
|
|
23775
|
+
external_exports.object({
|
|
23776
|
+
scanMode: external_exports.literal("SECRETS"),
|
|
23777
|
+
repositoryId: external_exports.uuid(),
|
|
23778
|
+
branch: external_exports.string().optional(),
|
|
23779
|
+
scanType: external_exports.enum(["FULL", "INCREMENTAL"]).optional(),
|
|
23780
|
+
userProvidedContext: external_exports.string().optional(),
|
|
23781
|
+
scanConfiguration: external_exports.record(external_exports.string(), external_exports.unknown()).optional()
|
|
23782
|
+
})
|
|
23783
|
+
]);
|
|
23784
|
+
var ScanResponseSchema = external_exports.object({
|
|
23785
|
+
scanId: external_exports.uuid(),
|
|
23786
|
+
organizationId: external_exports.uuid(),
|
|
23787
|
+
initiatedById: external_exports.uuid(),
|
|
23788
|
+
initiatedByName: external_exports.string().nullable(),
|
|
23789
|
+
initiatedByProfilePictureUrl: external_exports.string().nullable(),
|
|
23790
|
+
scanMode: ScanMode,
|
|
23791
|
+
scanType: external_exports.enum(ScanTypeValues),
|
|
23792
|
+
webApplicationId: external_exports.uuid().nullable(),
|
|
23793
|
+
targetUrl: external_exports.string().nullable(),
|
|
23794
|
+
repositoryId: external_exports.uuid().nullable(),
|
|
23795
|
+
branch: external_exports.string().nullable(),
|
|
23796
|
+
status: external_exports.enum(ScanStatusValues),
|
|
23797
|
+
cancellationReason: external_exports.enum(CancellationReasonValues).nullable(),
|
|
23798
|
+
errorMessage: external_exports.string().nullable(),
|
|
23799
|
+
userProvidedContext: external_exports.string().nullable(),
|
|
23800
|
+
scanConfiguration: external_exports.record(external_exports.string(), external_exports.unknown()).nullable(),
|
|
23801
|
+
triggerType: external_exports.enum(ScanTriggerTypeValues).nullable(),
|
|
23802
|
+
triggerMetadata: external_exports.record(external_exports.string(), external_exports.unknown()).nullable(),
|
|
23803
|
+
startedAt: external_exports.date().nullable(),
|
|
23804
|
+
completedAt: external_exports.date().nullable(),
|
|
23805
|
+
createdAt: external_exports.date(),
|
|
23806
|
+
updatedAt: external_exports.date()
|
|
23807
|
+
});
|
|
23808
|
+
var ListScansQuerySchema = external_exports.object({
|
|
23809
|
+
status: external_exports.enum(ScanStatusValues).array().or(external_exports.enum(ScanStatusValues)).optional(),
|
|
23810
|
+
repositoryId: external_exports.uuid().optional(),
|
|
23811
|
+
page: external_exports.coerce.number().int().min(1).max(1e4).optional(),
|
|
23812
|
+
pageSize: external_exports.coerce.number().int().min(1).max(200).optional()
|
|
23813
|
+
});
|
|
23814
|
+
var ListScansResponseSchema = external_exports.object({
|
|
23815
|
+
scans: external_exports.array(ScanResponseSchema),
|
|
23816
|
+
total: external_exports.number(),
|
|
23817
|
+
page: external_exports.number(),
|
|
23818
|
+
pageSize: external_exports.number()
|
|
23819
|
+
});
|
|
23820
|
+
var ScanArrayResponseSchema = external_exports.array(ScanResponseSchema);
|
|
23821
|
+
var CancelScanResponseSchema = external_exports.object({
|
|
23822
|
+
scanId: external_exports.uuid(),
|
|
23823
|
+
status: external_exports.literal("CANCELLED")
|
|
23824
|
+
});
|
|
23825
|
+
|
|
23826
|
+
// ../../packages/api-contracts/src/schemas/api/v1/scan-log.api.ts
|
|
23827
|
+
var ScanLogQuerySchema = external_exports.object({
|
|
23828
|
+
offset: external_exports.coerce.number().int().min(0).optional()
|
|
23829
|
+
});
|
|
23830
|
+
var ScanLogEntrySchema = external_exports.object({
|
|
23831
|
+
timestamp: external_exports.string(),
|
|
23832
|
+
level: external_exports.enum(["INFO", "WARN", "ERROR"]),
|
|
23833
|
+
message: external_exports.string(),
|
|
23834
|
+
phase: external_exports.string().nullable()
|
|
23835
|
+
});
|
|
23836
|
+
var ListScanLogsResponseSchema = external_exports.object({
|
|
23837
|
+
logs: external_exports.array(ScanLogEntrySchema),
|
|
23838
|
+
nextOffset: external_exports.number()
|
|
23839
|
+
});
|
|
23840
|
+
|
|
23184
23841
|
// ../../packages/api-contracts/src/contracts/v1/scan.ts
|
|
23185
|
-
var
|
|
23186
|
-
var scanContract =
|
|
23842
|
+
var c12 = initContract();
|
|
23843
|
+
var scanContract = c12.router({
|
|
23187
23844
|
createScan: {
|
|
23188
23845
|
method: "POST",
|
|
23189
23846
|
path: "/organizations/:organizationId/scans",
|
|
@@ -23281,14 +23938,15 @@ var UserResponseSchema = external_exports.object({
|
|
|
23281
23938
|
lastName: external_exports.string(),
|
|
23282
23939
|
email: external_exports.string(),
|
|
23283
23940
|
profilePictureUrl: external_exports.string().nullable(),
|
|
23941
|
+
isStaff: external_exports.boolean(),
|
|
23284
23942
|
createdAt: external_exports.date(),
|
|
23285
23943
|
updatedAt: external_exports.date()
|
|
23286
23944
|
});
|
|
23287
23945
|
var ListUsersResponseSchema = external_exports.array(UserResponseSchema);
|
|
23288
23946
|
|
|
23289
23947
|
// ../../packages/api-contracts/src/contracts/v1/user.ts
|
|
23290
|
-
var
|
|
23291
|
-
var userContract =
|
|
23948
|
+
var c13 = initContract();
|
|
23949
|
+
var userContract = c13.router({
|
|
23292
23950
|
listUsers: {
|
|
23293
23951
|
method: "GET",
|
|
23294
23952
|
path: "/organizations/:organizationId/users",
|
|
@@ -23360,8 +24018,8 @@ var VantaIntegrationResponseSchema = external_exports.object({
|
|
|
23360
24018
|
});
|
|
23361
24019
|
|
|
23362
24020
|
// ../../packages/api-contracts/src/contracts/v1/vanta-integration.ts
|
|
23363
|
-
var
|
|
23364
|
-
var vantaIntegrationContract =
|
|
24021
|
+
var c14 = initContract();
|
|
24022
|
+
var vantaIntegrationContract = c14.router({
|
|
23365
24023
|
createVantaIntegration: {
|
|
23366
24024
|
method: "POST",
|
|
23367
24025
|
path: "/organizations/:organizationId/vanta-integration",
|
|
@@ -23421,7 +24079,8 @@ var VulnerabilityStatusValues = [
|
|
|
23421
24079
|
"IN_PROGRESS",
|
|
23422
24080
|
"FIXED",
|
|
23423
24081
|
"IGNORED",
|
|
23424
|
-
"FALSE_POSITIVE"
|
|
24082
|
+
"FALSE_POSITIVE",
|
|
24083
|
+
"DISMISSED"
|
|
23425
24084
|
];
|
|
23426
24085
|
var VulnerabilityStatus = external_exports.enum(VulnerabilityStatusValues);
|
|
23427
24086
|
var VulnerabilitySeverityValues = ["LOW", "MEDIUM", "HIGH", "CRITICAL"];
|
|
@@ -23434,6 +24093,8 @@ var VulnerabilityTypeValues = [
|
|
|
23434
24093
|
"MISCONFIGURATION"
|
|
23435
24094
|
];
|
|
23436
24095
|
var VulnerabilityType = external_exports.enum(VulnerabilityTypeValues);
|
|
24096
|
+
var DismissReasonValues = ["ACCEPTED_RISK", "FALSE_POSITIVE", "OTHER"];
|
|
24097
|
+
var DismissReason = external_exports.enum(DismissReasonValues);
|
|
23437
24098
|
var ScanModeValues2 = ["SAST", "DAST", "SCA", "SECRETS"];
|
|
23438
24099
|
var ScanMode2 = external_exports.enum(ScanModeValues2);
|
|
23439
24100
|
|
|
@@ -23462,7 +24123,12 @@ var VulnerabilityLatestFindingSchema = external_exports.object({
|
|
|
23462
24123
|
attackVector: external_exports.string(),
|
|
23463
24124
|
exploitScenario: external_exports.string(),
|
|
23464
24125
|
impact: external_exports.string(),
|
|
23465
|
-
confidence: external_exports.number()
|
|
24126
|
+
confidence: external_exports.number(),
|
|
24127
|
+
// Threat model fields (null for findings from scans before this feature)
|
|
24128
|
+
classification: external_exports.enum(["vulnerability", "defense_in_depth", "context_dependent"]).nullable(),
|
|
24129
|
+
prerequisiteAccess: external_exports.string().nullable(),
|
|
24130
|
+
capabilityGain: external_exports.string().nullable(),
|
|
24131
|
+
technicalSeverity: VulnerabilitySeverity.nullable()
|
|
23466
24132
|
});
|
|
23467
24133
|
var DependencyGraphSchema = external_exports.object({
|
|
23468
24134
|
vulnerablePackage: external_exports.string(),
|
|
@@ -23486,6 +24152,7 @@ var VulnerabilityResponseSchema = external_exports.object({
|
|
|
23486
24152
|
scanMode: ScanMode2.nullable(),
|
|
23487
24153
|
status: VulnerabilityStatus,
|
|
23488
24154
|
statusReason: external_exports.string().nullable(),
|
|
24155
|
+
dismissReason: DismissReason.nullable(),
|
|
23489
24156
|
cweId: external_exports.string().nullable(),
|
|
23490
24157
|
source: VulnerabilitySourceSchema,
|
|
23491
24158
|
introducedBy: VulnerabilityIntroducedBySchema,
|
|
@@ -23572,12 +24239,13 @@ var VulnerabilityAggregatedCountsResponseSchema = external_exports.object({
|
|
|
23572
24239
|
});
|
|
23573
24240
|
var UpdateVulnerabilityRequestSchema = external_exports.object({
|
|
23574
24241
|
status: VulnerabilityStatus.optional(),
|
|
23575
|
-
statusReason: external_exports.string().optional()
|
|
24242
|
+
statusReason: external_exports.string().optional(),
|
|
24243
|
+
dismissReason: DismissReason.optional()
|
|
23576
24244
|
});
|
|
23577
24245
|
|
|
23578
24246
|
// ../../packages/api-contracts/src/contracts/v1/vulnerability.ts
|
|
23579
|
-
var
|
|
23580
|
-
var vulnerabilityContract =
|
|
24247
|
+
var c15 = initContract();
|
|
24248
|
+
var vulnerabilityContract = c15.router({
|
|
23581
24249
|
filterVulnerabilities: {
|
|
23582
24250
|
method: "POST",
|
|
23583
24251
|
path: "/organizations/:organizationId/vulnerabilities/filter",
|
|
@@ -23686,7 +24354,90 @@ var vulnerabilityContract = c13.router({
|
|
|
23686
24354
|
path: "/organizations/:organizationId/vulnerabilities/:vulnerabilityId/retests",
|
|
23687
24355
|
pathParams: VulnerabilityIdParamsSchema,
|
|
23688
24356
|
responses: {
|
|
23689
|
-
200:
|
|
24357
|
+
200: ScanArrayResponseSchema,
|
|
24358
|
+
401: ErrorResponseSchema,
|
|
24359
|
+
403: ErrorResponseSchema,
|
|
24360
|
+
404: ErrorResponseSchema,
|
|
24361
|
+
500: ErrorResponseSchema
|
|
24362
|
+
}
|
|
24363
|
+
}
|
|
24364
|
+
});
|
|
24365
|
+
|
|
24366
|
+
// ../../packages/api-contracts/src/schemas/api/v1/vulnerability-note.api.ts
|
|
24367
|
+
var VulnerabilityNoteParamsSchema = OrgIdParamsSchema.extend({
|
|
24368
|
+
vulnerabilityId: external_exports.uuid()
|
|
24369
|
+
});
|
|
24370
|
+
var VulnerabilityNoteIdParamsSchema = VulnerabilityNoteParamsSchema.extend({
|
|
24371
|
+
noteId: external_exports.uuid()
|
|
24372
|
+
});
|
|
24373
|
+
var VulnerabilityNoteResponseSchema = external_exports.object({
|
|
24374
|
+
noteId: external_exports.uuid(),
|
|
24375
|
+
vulnerabilityId: external_exports.uuid(),
|
|
24376
|
+
organizationId: external_exports.uuid(),
|
|
24377
|
+
authorId: external_exports.uuid(),
|
|
24378
|
+
authorName: external_exports.string(),
|
|
24379
|
+
authorProfilePictureUrl: external_exports.string().nullable(),
|
|
24380
|
+
content: external_exports.string(),
|
|
24381
|
+
createdAt: external_exports.coerce.date(),
|
|
24382
|
+
updatedAt: external_exports.coerce.date()
|
|
24383
|
+
});
|
|
24384
|
+
var ListVulnerabilityNotesResponseSchema = external_exports.array(VulnerabilityNoteResponseSchema);
|
|
24385
|
+
var CreateVulnerabilityNoteRequestSchema = external_exports.object({
|
|
24386
|
+
content: external_exports.string().min(1).max(1e4)
|
|
24387
|
+
});
|
|
24388
|
+
var UpdateVulnerabilityNoteRequestSchema = external_exports.object({
|
|
24389
|
+
content: external_exports.string().min(1).max(1e4)
|
|
24390
|
+
});
|
|
24391
|
+
|
|
24392
|
+
// ../../packages/api-contracts/src/contracts/v1/vulnerability-note.ts
|
|
24393
|
+
var c16 = initContract();
|
|
24394
|
+
var vulnerabilityNoteContract = c16.router({
|
|
24395
|
+
listNotes: {
|
|
24396
|
+
method: "GET",
|
|
24397
|
+
path: "/organizations/:organizationId/vulnerabilities/:vulnerabilityId/notes",
|
|
24398
|
+
pathParams: VulnerabilityNoteParamsSchema,
|
|
24399
|
+
responses: {
|
|
24400
|
+
200: ListVulnerabilityNotesResponseSchema,
|
|
24401
|
+
401: ErrorResponseSchema,
|
|
24402
|
+
403: ErrorResponseSchema,
|
|
24403
|
+
404: ErrorResponseSchema,
|
|
24404
|
+
500: ErrorResponseSchema
|
|
24405
|
+
}
|
|
24406
|
+
},
|
|
24407
|
+
createNote: {
|
|
24408
|
+
method: "POST",
|
|
24409
|
+
path: "/organizations/:organizationId/vulnerabilities/:vulnerabilityId/notes",
|
|
24410
|
+
pathParams: VulnerabilityNoteParamsSchema,
|
|
24411
|
+
body: CreateVulnerabilityNoteRequestSchema,
|
|
24412
|
+
responses: {
|
|
24413
|
+
201: VulnerabilityNoteResponseSchema,
|
|
24414
|
+
400: ErrorResponseSchema,
|
|
24415
|
+
401: ErrorResponseSchema,
|
|
24416
|
+
403: ErrorResponseSchema,
|
|
24417
|
+
404: ErrorResponseSchema,
|
|
24418
|
+
500: ErrorResponseSchema
|
|
24419
|
+
}
|
|
24420
|
+
},
|
|
24421
|
+
updateNote: {
|
|
24422
|
+
method: "PATCH",
|
|
24423
|
+
path: "/organizations/:organizationId/vulnerabilities/:vulnerabilityId/notes/:noteId",
|
|
24424
|
+
pathParams: VulnerabilityNoteIdParamsSchema,
|
|
24425
|
+
body: UpdateVulnerabilityNoteRequestSchema,
|
|
24426
|
+
responses: {
|
|
24427
|
+
200: VulnerabilityNoteResponseSchema,
|
|
24428
|
+
400: ErrorResponseSchema,
|
|
24429
|
+
401: ErrorResponseSchema,
|
|
24430
|
+
403: ErrorResponseSchema,
|
|
24431
|
+
404: ErrorResponseSchema,
|
|
24432
|
+
500: ErrorResponseSchema
|
|
24433
|
+
}
|
|
24434
|
+
},
|
|
24435
|
+
deleteNote: {
|
|
24436
|
+
method: "DELETE",
|
|
24437
|
+
path: "/organizations/:organizationId/vulnerabilities/:vulnerabilityId/notes/:noteId",
|
|
24438
|
+
pathParams: VulnerabilityNoteIdParamsSchema,
|
|
24439
|
+
responses: {
|
|
24440
|
+
204: DeleteResponseSchema,
|
|
23690
24441
|
401: ErrorResponseSchema,
|
|
23691
24442
|
403: ErrorResponseSchema,
|
|
23692
24443
|
404: ErrorResponseSchema,
|
|
@@ -23712,8 +24463,8 @@ var WebApplicationResponseSchema = external_exports.object({
|
|
|
23712
24463
|
var ListWebApplicationsResponseSchema = external_exports.array(WebApplicationResponseSchema);
|
|
23713
24464
|
|
|
23714
24465
|
// ../../packages/api-contracts/src/contracts/v1/web-application.ts
|
|
23715
|
-
var
|
|
23716
|
-
var webApplicationContract =
|
|
24466
|
+
var c17 = initContract();
|
|
24467
|
+
var webApplicationContract = c17.router({
|
|
23717
24468
|
listWebApplications: {
|
|
23718
24469
|
method: "GET",
|
|
23719
24470
|
path: "/organizations/:organizationId/web-applications",
|
|
@@ -23852,8 +24603,8 @@ var ListWebhookDeliveriesResponseSchema = external_exports.object({
|
|
|
23852
24603
|
});
|
|
23853
24604
|
|
|
23854
24605
|
// ../../packages/api-contracts/src/contracts/v1/webhook-settings.ts
|
|
23855
|
-
var
|
|
23856
|
-
var webhookSettingsContract =
|
|
24606
|
+
var c18 = initContract();
|
|
24607
|
+
var webhookSettingsContract = c18.router({
|
|
23857
24608
|
listWebhookEndpoints: {
|
|
23858
24609
|
method: "GET",
|
|
23859
24610
|
path: "/organizations/:organizationId/webhook-settings/endpoints",
|
|
@@ -23991,8 +24742,8 @@ var webhookSettingsContract = c15.router({
|
|
|
23991
24742
|
});
|
|
23992
24743
|
|
|
23993
24744
|
// ../../packages/api-contracts/src/contracts/v1/index.ts
|
|
23994
|
-
var
|
|
23995
|
-
var v1Contract =
|
|
24745
|
+
var c19 = initContract();
|
|
24746
|
+
var v1Contract = c19.router(
|
|
23996
24747
|
{
|
|
23997
24748
|
admin: adminContract,
|
|
23998
24749
|
scan: scanContract,
|
|
@@ -24006,9 +24757,12 @@ var v1Contract = c16.router(
|
|
|
24006
24757
|
knowledgeBase: knowledgeBaseContract,
|
|
24007
24758
|
knowledgeDocument: knowledgeDocumentContract,
|
|
24008
24759
|
vulnerability: vulnerabilityContract,
|
|
24760
|
+
vulnerabilityNote: vulnerabilityNoteContract,
|
|
24009
24761
|
webhookSettings: webhookSettingsContract,
|
|
24010
24762
|
webApplication: webApplicationContract,
|
|
24011
|
-
chatSession: chatSessionContract
|
|
24763
|
+
chatSession: chatSessionContract,
|
|
24764
|
+
pentest: pentestContract,
|
|
24765
|
+
pentestFinding: pentestFindingContract
|
|
24012
24766
|
},
|
|
24013
24767
|
{
|
|
24014
24768
|
pathPrefix: "/v1"
|
|
@@ -24016,8 +24770,8 @@ var v1Contract = c16.router(
|
|
|
24016
24770
|
);
|
|
24017
24771
|
|
|
24018
24772
|
// ../../packages/api-contracts/src/contracts/index.ts
|
|
24019
|
-
var
|
|
24020
|
-
var contract =
|
|
24773
|
+
var c20 = initContract();
|
|
24774
|
+
var contract = c20.router({
|
|
24021
24775
|
v1: v1Contract
|
|
24022
24776
|
});
|
|
24023
24777
|
|
|
@@ -24027,8 +24781,8 @@ var GitHubWebhookResponseSchema = external_exports.object({
|
|
|
24027
24781
|
});
|
|
24028
24782
|
|
|
24029
24783
|
// ../../packages/api-contracts/src/contracts/webhooks/github.ts
|
|
24030
|
-
var
|
|
24031
|
-
var githubWebhookContract =
|
|
24784
|
+
var c21 = initContract();
|
|
24785
|
+
var githubWebhookContract = c21.router(
|
|
24032
24786
|
{
|
|
24033
24787
|
handleWebhook: {
|
|
24034
24788
|
method: "POST",
|
|
@@ -24053,8 +24807,8 @@ var HealthResponseSchema = external_exports.object({
|
|
|
24053
24807
|
});
|
|
24054
24808
|
|
|
24055
24809
|
// ../../packages/api-contracts/src/contracts/health.ts
|
|
24056
|
-
var
|
|
24057
|
-
var healthContract =
|
|
24810
|
+
var c22 = initContract();
|
|
24811
|
+
var healthContract = c22.router({
|
|
24058
24812
|
getHealth: {
|
|
24059
24813
|
method: "GET",
|
|
24060
24814
|
path: "/health",
|
|
@@ -24098,12 +24852,13 @@ var ListPrVulnerabilitiesResponseSchema = external_exports.object({
|
|
|
24098
24852
|
});
|
|
24099
24853
|
var UpdatePrVulnerabilityRequestSchema = external_exports.object({
|
|
24100
24854
|
status: VulnerabilityStatus,
|
|
24101
|
-
statusReason: external_exports.string().optional()
|
|
24855
|
+
statusReason: external_exports.string().optional(),
|
|
24856
|
+
dismissReason: DismissReason.optional()
|
|
24102
24857
|
});
|
|
24103
24858
|
|
|
24104
24859
|
// ../../packages/api-contracts/src/contracts/v1/pr-vulnerability.ts
|
|
24105
|
-
var
|
|
24106
|
-
var prVulnerabilityContract =
|
|
24860
|
+
var c23 = initContract();
|
|
24861
|
+
var prVulnerabilityContract = c23.router(
|
|
24107
24862
|
{
|
|
24108
24863
|
listPrVulnerabilities: {
|
|
24109
24864
|
method: "GET",
|
|
@@ -24149,6 +24904,7 @@ var FindingSchema = external_exports.object({
|
|
|
24149
24904
|
// src/api-client.ts
|
|
24150
24905
|
var readTokenSafe = readToken;
|
|
24151
24906
|
var PRODUCTION_API_URL = "https://api.securewithtrace.com";
|
|
24907
|
+
var UNAUTHORIZED_STATUS = 401;
|
|
24152
24908
|
function getApiBaseUrl() {
|
|
24153
24909
|
const raw = process.env["TRACE_API_URL"];
|
|
24154
24910
|
if (!raw) {
|
|
@@ -24174,14 +24930,6 @@ function getApiBaseUrl() {
|
|
|
24174
24930
|
}
|
|
24175
24931
|
return raw.replace(/\/+$/, "");
|
|
24176
24932
|
}
|
|
24177
|
-
function requireAuth() {
|
|
24178
|
-
const token = readToken();
|
|
24179
|
-
if (!token) {
|
|
24180
|
-
console.error("Not logged in. Run `tracecli auth login` first.");
|
|
24181
|
-
process.exit(1);
|
|
24182
|
-
}
|
|
24183
|
-
return { token };
|
|
24184
|
-
}
|
|
24185
24933
|
function createClient(token) {
|
|
24186
24934
|
return initClient(v1Contract, {
|
|
24187
24935
|
baseUrl: getApiBaseUrl(),
|
|
@@ -24190,9 +24938,71 @@ function createClient(token) {
|
|
|
24190
24938
|
}
|
|
24191
24939
|
});
|
|
24192
24940
|
}
|
|
24941
|
+
function getWorkosClientId() {
|
|
24942
|
+
const clientId = "client_01KEZ01W5Q3107GTBY51WQ67HT";
|
|
24943
|
+
if (!clientId || clientId.trim().length === 0) {
|
|
24944
|
+
return null;
|
|
24945
|
+
}
|
|
24946
|
+
return clientId;
|
|
24947
|
+
}
|
|
24948
|
+
async function refreshStoredAccessToken() {
|
|
24949
|
+
const clientId = getWorkosClientId();
|
|
24950
|
+
const refreshToken = readRefreshToken();
|
|
24951
|
+
if (!clientId || !refreshToken) {
|
|
24952
|
+
return null;
|
|
24953
|
+
}
|
|
24954
|
+
try {
|
|
24955
|
+
const tokenResponse = await refreshAccessToken(clientId, refreshToken);
|
|
24956
|
+
const nextRefreshToken = tokenResponse.refresh_token ?? refreshToken;
|
|
24957
|
+
writeTokens(tokenResponse.access_token, nextRefreshToken);
|
|
24958
|
+
return tokenResponse.access_token;
|
|
24959
|
+
} catch (error48) {
|
|
24960
|
+
if (error48 instanceof Error && (error48.message.includes(" 400 ") || error48.message.includes(" 401 "))) {
|
|
24961
|
+
removeToken();
|
|
24962
|
+
}
|
|
24963
|
+
return null;
|
|
24964
|
+
}
|
|
24965
|
+
}
|
|
24966
|
+
async function authenticatedRequest(request) {
|
|
24967
|
+
const token = readToken();
|
|
24968
|
+
if (!token) {
|
|
24969
|
+
console.error("Not logged in. Run `tracecli auth login` first.");
|
|
24970
|
+
process.exit(1);
|
|
24971
|
+
}
|
|
24972
|
+
const firstResult = await request(createClient(token));
|
|
24973
|
+
if (firstResult.status !== UNAUTHORIZED_STATUS) {
|
|
24974
|
+
return firstResult;
|
|
24975
|
+
}
|
|
24976
|
+
const refreshedToken = await refreshStoredAccessToken();
|
|
24977
|
+
if (!refreshedToken) {
|
|
24978
|
+
return firstResult;
|
|
24979
|
+
}
|
|
24980
|
+
return request(createClient(refreshedToken));
|
|
24981
|
+
}
|
|
24982
|
+
async function authenticatedRequestSafe(request) {
|
|
24983
|
+
const token = readTokenSafe();
|
|
24984
|
+
if (!token) {
|
|
24985
|
+
return null;
|
|
24986
|
+
}
|
|
24987
|
+
try {
|
|
24988
|
+
const firstResult = await request(createClient(token));
|
|
24989
|
+
if (firstResult.status !== UNAUTHORIZED_STATUS) {
|
|
24990
|
+
return firstResult;
|
|
24991
|
+
}
|
|
24992
|
+
const refreshedToken = await refreshStoredAccessToken();
|
|
24993
|
+
if (!refreshedToken) {
|
|
24994
|
+
return firstResult;
|
|
24995
|
+
}
|
|
24996
|
+
return await request(createClient(refreshedToken));
|
|
24997
|
+
} catch {
|
|
24998
|
+
return null;
|
|
24999
|
+
}
|
|
25000
|
+
}
|
|
24193
25001
|
var SAFE_ID_PATTERN = /^[a-zA-Z0-9_-]+$/;
|
|
24194
25002
|
async function resolveOrganizationId(client) {
|
|
24195
|
-
const result = await client.organization.listOrganizations()
|
|
25003
|
+
const result = client ? await client.organization.listOrganizations() : await authenticatedRequest(
|
|
25004
|
+
(authenticatedClient) => authenticatedClient.organization.listOrganizations()
|
|
25005
|
+
);
|
|
24196
25006
|
if (result.status !== 200) {
|
|
24197
25007
|
console.error(`Failed to resolve organization (status ${result.status}).`);
|
|
24198
25008
|
process.exit(1);
|
|
@@ -24211,7 +25021,12 @@ async function resolveOrganizationId(client) {
|
|
|
24211
25021
|
}
|
|
24212
25022
|
async function resolveOrganizationIdSafe(client) {
|
|
24213
25023
|
try {
|
|
24214
|
-
const result = await client.organization.listOrganizations()
|
|
25024
|
+
const result = client ? await client.organization.listOrganizations() : await authenticatedRequestSafe(
|
|
25025
|
+
(authenticatedClient) => authenticatedClient.organization.listOrganizations()
|
|
25026
|
+
);
|
|
25027
|
+
if (!result) {
|
|
25028
|
+
return null;
|
|
25029
|
+
}
|
|
24215
25030
|
if (result.status !== 200) {
|
|
24216
25031
|
return null;
|
|
24217
25032
|
}
|
|
@@ -24229,7 +25044,180 @@ async function resolveOrganizationIdSafe(client) {
|
|
|
24229
25044
|
}
|
|
24230
25045
|
}
|
|
24231
25046
|
|
|
25047
|
+
// src/format.ts
|
|
25048
|
+
var SEVERITY_ORDER = {
|
|
25049
|
+
CRITICAL: 0,
|
|
25050
|
+
HIGH: 1,
|
|
25051
|
+
MEDIUM: 2,
|
|
25052
|
+
LOW: 3,
|
|
25053
|
+
INFORMATIONAL: 4
|
|
25054
|
+
};
|
|
25055
|
+
function formatStatus(status) {
|
|
25056
|
+
return status.toLowerCase().replace("_", " ");
|
|
25057
|
+
}
|
|
25058
|
+
|
|
25059
|
+
// src/pentest/commands.ts
|
|
25060
|
+
function formatDate(date5) {
|
|
25061
|
+
if (!date5) {
|
|
25062
|
+
return "\u2014";
|
|
25063
|
+
}
|
|
25064
|
+
const d = typeof date5 === "string" ? new Date(date5) : date5;
|
|
25065
|
+
return d.toLocaleDateString("en-US", { year: "numeric", month: "short", day: "numeric" });
|
|
25066
|
+
}
|
|
25067
|
+
function formatFindingSeverity(severity) {
|
|
25068
|
+
switch (severity) {
|
|
25069
|
+
case "CRITICAL":
|
|
25070
|
+
return "CRIT";
|
|
25071
|
+
case "HIGH":
|
|
25072
|
+
return "HIGH";
|
|
25073
|
+
case "MEDIUM":
|
|
25074
|
+
return "MED";
|
|
25075
|
+
case "LOW":
|
|
25076
|
+
return "LOW";
|
|
25077
|
+
case "INFORMATIONAL":
|
|
25078
|
+
return "INFO";
|
|
25079
|
+
default:
|
|
25080
|
+
return severity;
|
|
25081
|
+
}
|
|
25082
|
+
}
|
|
25083
|
+
var UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
25084
|
+
async function resolvePentestId(organizationId, identifier) {
|
|
25085
|
+
if (UUID_PATTERN.test(identifier)) {
|
|
25086
|
+
return identifier;
|
|
25087
|
+
}
|
|
25088
|
+
const numericMatch = identifier.match(/^(?:PT-)?(\d+)$/i);
|
|
25089
|
+
if (!numericMatch?.[1]) {
|
|
25090
|
+
console.error(
|
|
25091
|
+
`Invalid pentest identifier '${identifier}'. Use a display ID (e.g. PT-3) or UUID.`
|
|
25092
|
+
);
|
|
25093
|
+
process.exit(1);
|
|
25094
|
+
}
|
|
25095
|
+
const displayId = Number.parseInt(numericMatch[1], 10);
|
|
25096
|
+
const result = await authenticatedRequest(
|
|
25097
|
+
(client) => client.pentest.listPentests({
|
|
25098
|
+
params: { organizationId }
|
|
25099
|
+
})
|
|
25100
|
+
);
|
|
25101
|
+
if (result.status !== 200) {
|
|
25102
|
+
console.error(`Failed to list pentests (status ${result.status}).`);
|
|
25103
|
+
process.exit(1);
|
|
25104
|
+
}
|
|
25105
|
+
const pentest = result.body.find((p) => p.displayId === displayId);
|
|
25106
|
+
if (!pentest) {
|
|
25107
|
+
console.error(
|
|
25108
|
+
`Pentest with display ID ${displayId} not found.
|
|
25109
|
+
Run \`tracecli pentest list\` to see available pentests.`
|
|
25110
|
+
);
|
|
25111
|
+
process.exit(1);
|
|
25112
|
+
}
|
|
25113
|
+
return pentest.pentestId;
|
|
25114
|
+
}
|
|
25115
|
+
function createListCommand() {
|
|
25116
|
+
return new Command("list").description("List pentests for your organization").option("--json", "Output as JSON").action(async (options) => {
|
|
25117
|
+
const organizationId = await resolveOrganizationId();
|
|
25118
|
+
const result = await authenticatedRequest(
|
|
25119
|
+
(client) => client.pentest.listPentests({
|
|
25120
|
+
params: { organizationId }
|
|
25121
|
+
})
|
|
25122
|
+
);
|
|
25123
|
+
if (result.status !== 200) {
|
|
25124
|
+
console.error(`Failed to list pentests (status ${result.status}).`);
|
|
25125
|
+
process.exit(1);
|
|
25126
|
+
}
|
|
25127
|
+
const pentests = result.body;
|
|
25128
|
+
if (pentests.length === 0) {
|
|
25129
|
+
if (options.json) {
|
|
25130
|
+
console.log("[]");
|
|
25131
|
+
} else {
|
|
25132
|
+
console.log("No pentests found.");
|
|
25133
|
+
}
|
|
25134
|
+
return;
|
|
25135
|
+
}
|
|
25136
|
+
if (options.json) {
|
|
25137
|
+
console.log(JSON.stringify(pentests, null, 2));
|
|
25138
|
+
return;
|
|
25139
|
+
}
|
|
25140
|
+
console.log(`Found ${pentests.length} pentest${pentests.length === 1 ? "" : "s"}:
|
|
25141
|
+
`);
|
|
25142
|
+
for (const pt of pentests) {
|
|
25143
|
+
const status = formatStatus(pt.status);
|
|
25144
|
+
const started = formatDate(pt.startedAt);
|
|
25145
|
+
const ended = formatDate(pt.endedAt);
|
|
25146
|
+
const dateRange = pt.startedAt ? `${started} \u2013 ${ended}` : "Not started";
|
|
25147
|
+
const findings = pt.findingCounts.total;
|
|
25148
|
+
console.log(` [PT-${pt.displayId}] ${pt.title}`);
|
|
25149
|
+
console.log(` Status: ${status} | Findings: ${findings} | ${dateRange}`);
|
|
25150
|
+
if (pt.description) {
|
|
25151
|
+
console.log(` ${pt.description}`);
|
|
25152
|
+
}
|
|
25153
|
+
console.log("");
|
|
25154
|
+
}
|
|
25155
|
+
});
|
|
25156
|
+
}
|
|
25157
|
+
function createFindingsListCommand() {
|
|
25158
|
+
return new Command("list").description("List findings for a pentest").requiredOption("--pentest <id>", "Pentest display ID (e.g. PT-3) or UUID").option("--json", "Output as JSON").action(async (options) => {
|
|
25159
|
+
const organizationId = await resolveOrganizationId();
|
|
25160
|
+
const pentestId = await resolvePentestId(organizationId, options.pentest);
|
|
25161
|
+
const result = await authenticatedRequest(
|
|
25162
|
+
(client) => client.pentestFinding.listFindings({
|
|
25163
|
+
params: { organizationId, pentestId }
|
|
25164
|
+
})
|
|
25165
|
+
);
|
|
25166
|
+
if (result.status !== 200) {
|
|
25167
|
+
console.error(`Failed to list findings (status ${result.status}).`);
|
|
25168
|
+
process.exit(1);
|
|
25169
|
+
}
|
|
25170
|
+
const findings = result.body;
|
|
25171
|
+
if (findings.length === 0) {
|
|
25172
|
+
if (options.json) {
|
|
25173
|
+
console.log("[]");
|
|
25174
|
+
} else {
|
|
25175
|
+
console.log("No findings found for this pentest.");
|
|
25176
|
+
}
|
|
25177
|
+
return;
|
|
25178
|
+
}
|
|
25179
|
+
if (options.json) {
|
|
25180
|
+
console.log(JSON.stringify(findings, null, 2));
|
|
25181
|
+
return;
|
|
25182
|
+
}
|
|
25183
|
+
console.log(`Found ${findings.length} finding${findings.length === 1 ? "" : "s"}:
|
|
25184
|
+
`);
|
|
25185
|
+
const sorted = [...findings].sort(
|
|
25186
|
+
(a, b) => (SEVERITY_ORDER[a.severity] ?? 99) - (SEVERITY_ORDER[b.severity] ?? 99)
|
|
25187
|
+
);
|
|
25188
|
+
for (const finding of sorted) {
|
|
25189
|
+
const sev = formatFindingSeverity(finding.severity);
|
|
25190
|
+
const status = formatStatus(finding.status);
|
|
25191
|
+
const cwes = finding.cweIds.length > 0 ? ` | ${finding.cweIds.join(", ")}` : "";
|
|
25192
|
+
const score = finding.cvssScore != null ? ` | CVSS ${finding.cvssScore.toFixed(1)}` : "";
|
|
25193
|
+
console.log(` [${sev}] ${finding.title}`);
|
|
25194
|
+
console.log(` ${finding.category} \xB7 ${status}${cwes}${score}`);
|
|
25195
|
+
if (finding.repositories.length > 0) {
|
|
25196
|
+
for (const repo of finding.repositories) {
|
|
25197
|
+
const location = repo.filePath ? `${repo.repositoryName} \xB7 ${repo.filePath}${repo.startLine != null ? `:${repo.startLine}` : ""}` : repo.repositoryName;
|
|
25198
|
+
console.log(` ${location}`);
|
|
25199
|
+
}
|
|
25200
|
+
}
|
|
25201
|
+
console.log("");
|
|
25202
|
+
}
|
|
25203
|
+
});
|
|
25204
|
+
}
|
|
25205
|
+
function createFindingsCommand() {
|
|
25206
|
+
const findings = new Command("findings").description("Manage pentest findings");
|
|
25207
|
+
findings.addCommand(createFindingsListCommand());
|
|
25208
|
+
return findings;
|
|
25209
|
+
}
|
|
25210
|
+
function createPentestCommand() {
|
|
25211
|
+
const pentest = new Command("pentest").description("Manage pentests");
|
|
25212
|
+
pentest.addCommand(createListCommand());
|
|
25213
|
+
pentest.addCommand(createFindingsCommand());
|
|
25214
|
+
return pentest;
|
|
25215
|
+
}
|
|
25216
|
+
|
|
24232
25217
|
// src/repo/commands.ts
|
|
25218
|
+
import { chmodSync, mkdtempSync, rmSync as rmSync2, writeFileSync as writeFileSync3 } from "fs";
|
|
25219
|
+
import { tmpdir } from "os";
|
|
25220
|
+
import { join as join3 } from "path";
|
|
24233
25221
|
function stripAnsi(str) {
|
|
24234
25222
|
const ESC2 = String.fromCharCode(27);
|
|
24235
25223
|
const CSI = String.fromCharCode(155);
|
|
@@ -24283,14 +25271,14 @@ function validateBranchName(branch) {
|
|
|
24283
25271
|
}
|
|
24284
25272
|
return branch;
|
|
24285
25273
|
}
|
|
24286
|
-
function
|
|
25274
|
+
function createListCommand2() {
|
|
24287
25275
|
return new Command("list").description("List repositories in your organization").action(async () => {
|
|
24288
|
-
const
|
|
24289
|
-
const
|
|
24290
|
-
|
|
24291
|
-
|
|
24292
|
-
|
|
24293
|
-
|
|
25276
|
+
const organizationId = await resolveOrganizationId();
|
|
25277
|
+
const result = await authenticatedRequest(
|
|
25278
|
+
(client) => client.repository.listRepositories({
|
|
25279
|
+
params: { organizationId }
|
|
25280
|
+
})
|
|
25281
|
+
);
|
|
24294
25282
|
if (result.status !== 200) {
|
|
24295
25283
|
console.error(`Failed to list repositories (status ${result.status}).`);
|
|
24296
25284
|
process.exit(1);
|
|
@@ -24326,20 +25314,20 @@ echo '${token.replace(/'/g, "'\\''")}'
|
|
|
24326
25314
|
return scriptPath;
|
|
24327
25315
|
}
|
|
24328
25316
|
async function fetchCloneToken(repoUrl) {
|
|
24329
|
-
const token = readTokenSafe();
|
|
24330
|
-
if (!token) {
|
|
24331
|
-
return null;
|
|
24332
|
-
}
|
|
24333
25317
|
try {
|
|
24334
|
-
const
|
|
24335
|
-
const organizationId = await resolveOrganizationIdSafe(client);
|
|
25318
|
+
const organizationId = await resolveOrganizationIdSafe();
|
|
24336
25319
|
if (!organizationId) {
|
|
24337
25320
|
return null;
|
|
24338
25321
|
}
|
|
24339
|
-
const result = await
|
|
24340
|
-
|
|
24341
|
-
|
|
24342
|
-
|
|
25322
|
+
const result = await authenticatedRequestSafe(
|
|
25323
|
+
(client) => client.repository.getCloneToken({
|
|
25324
|
+
params: { organizationId },
|
|
25325
|
+
body: { repositoryUrl: repoUrl }
|
|
25326
|
+
})
|
|
25327
|
+
);
|
|
25328
|
+
if (!result) {
|
|
25329
|
+
return null;
|
|
25330
|
+
}
|
|
24343
25331
|
if (result.status === 200) {
|
|
24344
25332
|
return result.body.token;
|
|
24345
25333
|
}
|
|
@@ -24409,24 +25397,20 @@ function createCloneCommand() {
|
|
|
24409
25397
|
}
|
|
24410
25398
|
function createRepoCommand() {
|
|
24411
25399
|
const repo = new Command("repo").description("Manage repositories");
|
|
24412
|
-
repo.addCommand(
|
|
25400
|
+
repo.addCommand(createListCommand2());
|
|
24413
25401
|
repo.addCommand(createCloneCommand());
|
|
24414
25402
|
return repo;
|
|
24415
25403
|
}
|
|
24416
25404
|
|
|
24417
25405
|
// src/vulnerabilities/commands.ts
|
|
24418
25406
|
import { createInterface } from "readline";
|
|
24419
|
-
var SEVERITY_ORDER = {
|
|
24420
|
-
CRITICAL: 0,
|
|
24421
|
-
HIGH: 1,
|
|
24422
|
-
MEDIUM: 2,
|
|
24423
|
-
LOW: 3
|
|
24424
|
-
};
|
|
24425
25407
|
var DEFAULT_PAGE_SIZE = 25;
|
|
24426
|
-
async function
|
|
24427
|
-
const result = await
|
|
24428
|
-
|
|
24429
|
-
|
|
25408
|
+
async function resolveRepositoryIdAuthenticated(organizationId, repoIdentifier) {
|
|
25409
|
+
const result = await authenticatedRequest(
|
|
25410
|
+
(client) => client.repository.listRepositories({
|
|
25411
|
+
params: { organizationId }
|
|
25412
|
+
})
|
|
25413
|
+
);
|
|
24430
25414
|
if (result.status !== 200) {
|
|
24431
25415
|
console.error(`Failed to list repositories (status ${result.status}).`);
|
|
24432
25416
|
process.exit(1);
|
|
@@ -24490,7 +25474,7 @@ function printVulnerabilities(vulnerabilities) {
|
|
|
24490
25474
|
);
|
|
24491
25475
|
for (const vuln of sorted) {
|
|
24492
25476
|
const sev = formatSeverity(vuln.severity);
|
|
24493
|
-
const status = vuln.status
|
|
25477
|
+
const status = formatStatus(vuln.status);
|
|
24494
25478
|
const repo = vuln.repositoryName;
|
|
24495
25479
|
const file2 = vuln.codeSnippet.filePath;
|
|
24496
25480
|
const line = vuln.codeSnippet.startLine;
|
|
@@ -24510,7 +25494,7 @@ async function promptContinue(displayed, total) {
|
|
|
24510
25494
|
});
|
|
24511
25495
|
});
|
|
24512
25496
|
}
|
|
24513
|
-
function
|
|
25497
|
+
function createListCommand3() {
|
|
24514
25498
|
return new Command("list").description("List vulnerabilities for your organization").option("--repo <repo>", "Filter by repository name or owner/repo").option(
|
|
24515
25499
|
"--severity <severity>",
|
|
24516
25500
|
"Filter by severity (CRITICAL, HIGH, MEDIUM, LOW)",
|
|
@@ -24527,12 +25511,10 @@ function createListCommand2() {
|
|
|
24527
25511
|
return Math.min(n, 200);
|
|
24528
25512
|
}).option("--json", "Output as JSON").action(
|
|
24529
25513
|
async (options) => {
|
|
24530
|
-
const
|
|
24531
|
-
const client = createClient(token);
|
|
24532
|
-
const organizationId = await resolveOrganizationId(client);
|
|
25514
|
+
const organizationId = await resolveOrganizationId();
|
|
24533
25515
|
const conditions = [];
|
|
24534
25516
|
if (options.repo) {
|
|
24535
|
-
const repositoryId = await
|
|
25517
|
+
const repositoryId = await resolveRepositoryIdAuthenticated(organizationId, options.repo);
|
|
24536
25518
|
conditions.push({ field: "repositoryId", operator: "eq", value: repositoryId });
|
|
24537
25519
|
}
|
|
24538
25520
|
if (options.severity) {
|
|
@@ -24553,10 +25535,12 @@ function createListCommand2() {
|
|
|
24553
25535
|
let total = 0;
|
|
24554
25536
|
const allJsonVulnerabilities = [];
|
|
24555
25537
|
while (true) {
|
|
24556
|
-
const result = await
|
|
24557
|
-
|
|
24558
|
-
|
|
24559
|
-
|
|
25538
|
+
const result = await authenticatedRequest(
|
|
25539
|
+
(client) => client.vulnerability.filterVulnerabilities({
|
|
25540
|
+
params: { organizationId },
|
|
25541
|
+
body: { ...filterBody, page, pageSize }
|
|
25542
|
+
})
|
|
25543
|
+
);
|
|
24560
25544
|
if (result.status !== 200) {
|
|
24561
25545
|
console.error(`Failed to list vulnerabilities (status ${result.status}).`);
|
|
24562
25546
|
process.exit(1);
|
|
@@ -24602,7 +25586,7 @@ function createListCommand2() {
|
|
|
24602
25586
|
}
|
|
24603
25587
|
function createVulnerabilitiesCommand() {
|
|
24604
25588
|
const vulnerabilities = new Command("vulnerabilities").description("Manage vulnerabilities");
|
|
24605
|
-
vulnerabilities.addCommand(
|
|
25589
|
+
vulnerabilities.addCommand(createListCommand3());
|
|
24606
25590
|
return vulnerabilities;
|
|
24607
25591
|
}
|
|
24608
25592
|
|
|
@@ -24616,5 +25600,6 @@ program2.action(() => {
|
|
|
24616
25600
|
program2.addCommand(createAuthCommand());
|
|
24617
25601
|
program2.addCommand(createRepoCommand());
|
|
24618
25602
|
program2.addCommand(createVulnerabilitiesCommand());
|
|
25603
|
+
program2.addCommand(createPentestCommand());
|
|
24619
25604
|
program2.addCommand(createCompletionCommand(program2));
|
|
24620
25605
|
program2.parse();
|