securewithtrace 0.52.0 → 0.54.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/bin/bunfig.toml +2 -0
- package/bin/tracecli +14 -4
- package/dist/index.js +851 -197
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3427,10 +3427,11 @@ var Permission = {
|
|
|
3427
3427
|
VIEW_RESULTS: "VIEW_RESULTS",
|
|
3428
3428
|
EXPORT_ORG_DATA: "EXPORT_ORG_DATA",
|
|
3429
3429
|
DELETE_ORG_DATA: "DELETE_ORG_DATA",
|
|
3430
|
-
|
|
3430
|
+
/** Connecting and configuring third-party integrations. */
|
|
3431
|
+
MANAGE_INTEGRATIONS: "MANAGE_INTEGRATIONS",
|
|
3431
3432
|
MANAGE_INTEGRATED_REPOSITORIES: "MANAGE_INTEGRATED_REPOSITORIES",
|
|
3432
3433
|
MANAGE_USERS: "MANAGE_USERS",
|
|
3433
|
-
/** Invite or remove org members
|
|
3434
|
+
/** Invite or remove org members. Distinct from MANAGE_USERS (role changes, API keys). */
|
|
3434
3435
|
INVITE_USERS: "INVITE_USERS",
|
|
3435
3436
|
MANAGE_ORGANIZATION: "MANAGE_ORGANIZATION",
|
|
3436
3437
|
MANAGE_PENTESTS: "MANAGE_PENTESTS",
|
|
@@ -3440,16 +3441,15 @@ var Permission = {
|
|
|
3440
3441
|
// ../../packages/core/src/auth/permissions.ts
|
|
3441
3442
|
var ROLE_PERMISSIONS = {
|
|
3442
3443
|
[Role.developer]: /* @__PURE__ */ new Set([Permission.RUN_SCAN, Permission.VIEW_RESULTS]),
|
|
3444
|
+
// Shown as Manager: sets up and runs testing. Billing, people and API keys stay admin-only.
|
|
3443
3445
|
[Role.analyst]: /* @__PURE__ */ new Set([
|
|
3444
3446
|
Permission.RUN_SCAN,
|
|
3445
3447
|
Permission.VIEW_RESULTS,
|
|
3446
3448
|
Permission.EXPORT_ORG_DATA,
|
|
3447
3449
|
Permission.MANAGE_INTEGRATED_REPOSITORIES,
|
|
3448
|
-
Permission.
|
|
3449
|
-
Permission.
|
|
3450
|
-
|
|
3451
|
-
// (PR-0b-i M3 / D14). Constant stays in the enum for backward compat
|
|
3452
|
-
// until v2 cleanup; analysts no longer get it.
|
|
3450
|
+
Permission.MANAGE_INTEGRATIONS,
|
|
3451
|
+
Permission.MANAGE_APPLICATIONS,
|
|
3452
|
+
Permission.MANAGE_PENTESTS
|
|
3453
3453
|
]),
|
|
3454
3454
|
[Role.admin]: new Set(Object.values(Permission))
|
|
3455
3455
|
};
|
|
@@ -6283,7 +6283,7 @@ var $ZodBase64 = /* @__PURE__ */ $constructor("$ZodBase64", (inst, def) => {
|
|
|
6283
6283
|
function isValidBase64URL(data) {
|
|
6284
6284
|
if (!base64url.test(data))
|
|
6285
6285
|
return false;
|
|
6286
|
-
const base644 = data.replace(/[-_]/g, (
|
|
6286
|
+
const base644 = data.replace(/[-_]/g, (c86) => c86 === "-" ? "+" : "/");
|
|
6287
6287
|
const padded = base644.padEnd(Math.ceil(base644.length / 4) * 4, "=");
|
|
6288
6288
|
return isValidBase64(padded);
|
|
6289
6289
|
}
|
|
@@ -16327,9 +16327,9 @@ var ZodDate = /* @__PURE__ */ $constructor("ZodDate", (inst, def) => {
|
|
|
16327
16327
|
inst._zod.processJSONSchema = (ctx, json2, params3) => dateProcessor(inst, ctx, json2, params3);
|
|
16328
16328
|
inst.min = (value, params3) => inst.check(_gte(value, params3));
|
|
16329
16329
|
inst.max = (value, params3) => inst.check(_lte(value, params3));
|
|
16330
|
-
const
|
|
16331
|
-
inst.minDate =
|
|
16332
|
-
inst.maxDate =
|
|
16330
|
+
const c86 = inst._zod.bag;
|
|
16331
|
+
inst.minDate = c86.minimum ? new Date(c86.minimum) : null;
|
|
16332
|
+
inst.maxDate = c86.maximum ? new Date(c86.maximum) : null;
|
|
16333
16333
|
});
|
|
16334
16334
|
function date3(params3) {
|
|
16335
16335
|
return _date(ZodDate, params3);
|
|
@@ -17460,6 +17460,7 @@ config(en_default());
|
|
|
17460
17460
|
|
|
17461
17461
|
// ../../packages/core/src/text/prompt-sanitize.ts
|
|
17462
17462
|
var CREDENTIAL_KEY_SOURCE = "password|secret|token|access[_ -]?token|refresh[_ -]?token|cookie|authorization|bearer|api[_ -]?key|private[_ -]?key|session|credential|(?<![A-Za-z])(?:passwd|pwd|pass)";
|
|
17463
|
+
var PROVIDER_KEY_SOURCE = String.raw`\bsk-[A-Za-z0-9_-]{16,}\b`;
|
|
17463
17464
|
var HIGH_ENTROPY_RUN_SOURCE = String.raw`\b(sk-[A-Za-z0-9_-]{16,}|[A-Za-z0-9+/_=-]{40,})\b`;
|
|
17464
17465
|
|
|
17465
17466
|
// ../../packages/core/src/text/evidence-redact.ts
|
|
@@ -17711,7 +17712,14 @@ var ENVIRONMENT_AWARE_PROMPT_VERSIONS = /* @__PURE__ */ new Set([
|
|
|
17711
17712
|
"operator-openai-v26",
|
|
17712
17713
|
"operator-openai-v27",
|
|
17713
17714
|
"operator-openai-v28",
|
|
17714
|
-
"operator-openai-v29"
|
|
17715
|
+
"operator-openai-v29",
|
|
17716
|
+
// The Claude operator pins every provider launches.
|
|
17717
|
+
"operator-v30",
|
|
17718
|
+
"operator-v31",
|
|
17719
|
+
"operator-v32",
|
|
17720
|
+
"operator-v33",
|
|
17721
|
+
"operator-v34",
|
|
17722
|
+
"operator-v35"
|
|
17715
17723
|
]);
|
|
17716
17724
|
var OOB_PROFILE_SUCCESSIONS = [
|
|
17717
17725
|
{
|
|
@@ -18298,6 +18306,26 @@ var STAGE_RETIRED_OOB_PROFILE_SUCCESSIONS = [
|
|
|
18298
18306
|
}
|
|
18299
18307
|
}
|
|
18300
18308
|
];
|
|
18309
|
+
var ENVIRONMENT_AWARE_OPERATOR_OOB_PROFILE_SUCCESSIONS = [
|
|
18310
|
+
{
|
|
18311
|
+
successor: { promptVersion: "operator-v30", toolsetVersion: "operator-tools-v14" },
|
|
18312
|
+
predecessor: { promptVersion: "operator-v31", toolsetVersion: "operator-tools-v15" }
|
|
18313
|
+
},
|
|
18314
|
+
{
|
|
18315
|
+
successor: { promptVersion: "operator-v32", toolsetVersion: "operator-tools-v16" },
|
|
18316
|
+
predecessor: { promptVersion: "operator-v31", toolsetVersion: "operator-tools-v15" }
|
|
18317
|
+
}
|
|
18318
|
+
];
|
|
18319
|
+
var ACCOUNT_OPERATOR_OOB_PROFILE_SUCCESSIONS = [
|
|
18320
|
+
{
|
|
18321
|
+
successor: { promptVersion: "operator-v33", toolsetVersion: "operator-tools-v17" },
|
|
18322
|
+
predecessor: { promptVersion: "operator-v34", toolsetVersion: "operator-tools-v18" }
|
|
18323
|
+
},
|
|
18324
|
+
{
|
|
18325
|
+
successor: { promptVersion: "operator-v35", toolsetVersion: "operator-tools-v19" },
|
|
18326
|
+
predecessor: { promptVersion: "operator-v34", toolsetVersion: "operator-tools-v18" }
|
|
18327
|
+
}
|
|
18328
|
+
];
|
|
18301
18329
|
var ALL_OOB_PROFILE_SUCCESSIONS = [
|
|
18302
18330
|
...OOB_PROFILE_SUCCESSIONS,
|
|
18303
18331
|
...STAFF_NOTIFICATION_OOB_PROFILE_SUCCESSIONS,
|
|
@@ -18315,7 +18343,9 @@ var ALL_OOB_PROFILE_SUCCESSIONS = [
|
|
|
18315
18343
|
...VALIDATION_V40_OOB_PROFILE_SUCCESSIONS,
|
|
18316
18344
|
...WRITER_REPRO_OOB_PROFILE_SUCCESSIONS,
|
|
18317
18345
|
...RETEST_REPRO_OOB_PROFILE_SUCCESSIONS,
|
|
18318
|
-
...STAGE_RETIRED_OOB_PROFILE_SUCCESSIONS
|
|
18346
|
+
...STAGE_RETIRED_OOB_PROFILE_SUCCESSIONS,
|
|
18347
|
+
...ENVIRONMENT_AWARE_OPERATOR_OOB_PROFILE_SUCCESSIONS,
|
|
18348
|
+
...ACCOUNT_OPERATOR_OOB_PROFILE_SUCCESSIONS
|
|
18319
18349
|
];
|
|
18320
18350
|
var OOB_CAPABLE_TOOLSETS = new Set(
|
|
18321
18351
|
ALL_OOB_PROFILE_SUCCESSIONS.map(({ successor }) => successor.toolsetVersion)
|
|
@@ -18340,9 +18370,10 @@ var STAFF_NOTIFICATION_TOOLSET_VERSIONS = /* @__PURE__ */ new Set([
|
|
|
18340
18370
|
"report-tools-bsk-v3",
|
|
18341
18371
|
"report-tools-v4",
|
|
18342
18372
|
"report-tools-bsk-v4",
|
|
18343
|
-
// API_COVERAGE_TOOLSET_VERSION and its
|
|
18373
|
+
// API_COVERAGE_TOOLSET_VERSION and its predecessors, written out because they are declared below.
|
|
18344
18374
|
"api-coverage-tools-v1",
|
|
18345
18375
|
"api-coverage-tools-v2",
|
|
18376
|
+
"api-coverage-tools-v3",
|
|
18346
18377
|
// SETUP_TOOLSET_VERSION, written out for the same reason.
|
|
18347
18378
|
"setup-tools-v1",
|
|
18348
18379
|
...STAFF_NOTIFICATION_OOB_PROFILE_SUCCESSIONS.flatMap(({ successor, predecessor }) => [
|
|
@@ -18357,6 +18388,10 @@ var STAFF_NOTIFICATION_TOOLSET_VERSIONS = /* @__PURE__ */ new Set([
|
|
|
18357
18388
|
predecessor.toolsetVersion,
|
|
18358
18389
|
successor.toolsetVersion
|
|
18359
18390
|
]),
|
|
18391
|
+
...ACCOUNT_OPERATOR_OOB_PROFILE_SUCCESSIONS.flatMap(({ successor, predecessor }) => [
|
|
18392
|
+
predecessor.toolsetVersion,
|
|
18393
|
+
successor.toolsetVersion
|
|
18394
|
+
]),
|
|
18360
18395
|
...FEATURE_COVERAGE_OOB_PROFILE_SUCCESSIONS.flatMap(({ successor, predecessor }) => [
|
|
18361
18396
|
predecessor.toolsetVersion,
|
|
18362
18397
|
successor.toolsetVersion
|
|
@@ -23308,8 +23343,8 @@ var CreateAgentSessionRequestSchema = external_exports.discriminatedUnion("type"
|
|
|
23308
23343
|
codeUploadId: AndroidBuildUnderTestSchema,
|
|
23309
23344
|
/**
|
|
23310
23345
|
* REVIEW launches the review session: an operator session that premise-checks every
|
|
23311
|
-
* unpublished finding before its first turn and does not publish.
|
|
23312
|
-
*
|
|
23346
|
+
* unpublished finding before its first turn and does not publish. Its premise checks run on
|
|
23347
|
+
* the session's provider.
|
|
23313
23348
|
*/
|
|
23314
23349
|
purpose: OperatorSessionPurpose.optional()
|
|
23315
23350
|
}),
|
|
@@ -23610,6 +23645,20 @@ var OperatorPentestContextSchema = external_exports.object({
|
|
|
23610
23645
|
reason: external_exports.string().nullable()
|
|
23611
23646
|
})
|
|
23612
23647
|
),
|
|
23648
|
+
/**
|
|
23649
|
+
* Features excluded from this engagement, read at call time: an exclusion staff add after launch
|
|
23650
|
+
* reaches a running session here, never through its brief. `handle` is `<ordinal>/<slug>`, as
|
|
23651
|
+
* the brief's do-not-test list names it. Optional for the same host raw-cast reason as
|
|
23652
|
+
* `applications`.
|
|
23653
|
+
*/
|
|
23654
|
+
excludedFeatures: external_exports.array(
|
|
23655
|
+
external_exports.object({
|
|
23656
|
+
handle: external_exports.string(),
|
|
23657
|
+
name: external_exports.string(),
|
|
23658
|
+
reason: external_exports.string(),
|
|
23659
|
+
endpoints: external_exports.array(external_exports.string())
|
|
23660
|
+
})
|
|
23661
|
+
).optional(),
|
|
23613
23662
|
// From the session's immutable repository pins (what the agent has checked out).
|
|
23614
23663
|
repositories: external_exports.array(
|
|
23615
23664
|
external_exports.object({
|
|
@@ -25889,7 +25938,7 @@ var CreateLinearTicketsRequestSchema = external_exports.object({
|
|
|
25889
25938
|
findingIds: external_exports.array(external_exports.string().min(1).max(64)).min(1).max(50),
|
|
25890
25939
|
/** Single-finding requests only — a title with >1 finding is a 400. */
|
|
25891
25940
|
title: external_exports.string().min(1).max(255).optional(),
|
|
25892
|
-
/** Destination overrides
|
|
25941
|
+
/** Destination overrides need MANAGE_INTEGRATIONS; anyone else sending one gets a 403. */
|
|
25893
25942
|
teamId: linearEntityId.optional(),
|
|
25894
25943
|
projectId: linearEntityId.nullable().optional(),
|
|
25895
25944
|
labelIds: external_exports.array(linearEntityId).max(10).optional()
|
|
@@ -25947,9 +25996,9 @@ var LinearTicketContextResponseSchema = external_exports.object({
|
|
|
25947
25996
|
labelIds: external_exports.array(external_exports.string()),
|
|
25948
25997
|
labelNames: external_exports.array(external_exports.string())
|
|
25949
25998
|
}).nullable(),
|
|
25950
|
-
/** True only for
|
|
25999
|
+
/** True only for MANAGE_INTEGRATIONS callers; gates the destination picker. */
|
|
25951
26000
|
canOverrideDestination: external_exports.boolean(),
|
|
25952
|
-
/** Populated only
|
|
26001
|
+
/** Populated only when canOverrideDestination; anyone else gets the resolved defaults, not a workspace inventory. */
|
|
25953
26002
|
teams: external_exports.array(TicketContextTeam),
|
|
25954
26003
|
projects: external_exports.array(TicketContextProject),
|
|
25955
26004
|
labels: external_exports.array(TicketContextLabel)
|
|
@@ -28898,13 +28947,13 @@ var StorageStateSchema = external_exports.object({
|
|
|
28898
28947
|
} catch {
|
|
28899
28948
|
return;
|
|
28900
28949
|
}
|
|
28901
|
-
s.cookies.forEach((
|
|
28902
|
-
const d =
|
|
28950
|
+
s.cookies.forEach((c86, i2) => {
|
|
28951
|
+
const d = c86.domain.replace(/^\./, "").toLowerCase();
|
|
28903
28952
|
if (d !== host && !host.endsWith(`.${d}`)) {
|
|
28904
28953
|
ctx.addIssue({
|
|
28905
28954
|
code: "custom",
|
|
28906
28955
|
path: ["cookies", i2, "domain"],
|
|
28907
|
-
message: `cookie domain "${
|
|
28956
|
+
message: `cookie domain "${c86.domain}" is not the capture origin host "${host}" or a parent domain of it`
|
|
28908
28957
|
});
|
|
28909
28958
|
}
|
|
28910
28959
|
});
|
|
@@ -29510,7 +29559,7 @@ var AgentSessionGitSourceGrantSchema = external_exports.object({
|
|
|
29510
29559
|
ref: external_exports.string().min(1).max(255),
|
|
29511
29560
|
/** Immutable pin — the host checks out exactly this commit. */
|
|
29512
29561
|
commitSha: external_exports.string().regex(/^[a-f0-9]{40}$/i),
|
|
29513
|
-
/** Bare clone URL (no credentials — the host
|
|
29562
|
+
/** Bare clone URL (no credentials — the host supplies the token via GIT_ASKPASS). */
|
|
29514
29563
|
cloneUrl: external_exports.url(),
|
|
29515
29564
|
/**
|
|
29516
29565
|
* Short-lived scoped read token. Never logged, never placed in any environ;
|
|
@@ -29519,9 +29568,9 @@ var AgentSessionGitSourceGrantSchema = external_exports.object({
|
|
|
29519
29568
|
*/
|
|
29520
29569
|
cloneToken: external_exports.string().min(1),
|
|
29521
29570
|
/**
|
|
29522
|
-
* Git credential username for the clone
|
|
29523
|
-
*
|
|
29524
|
-
*
|
|
29571
|
+
* Git credential username for the clone: `x-access-token` (GitHub),
|
|
29572
|
+
* `x-token-auth` (Bitbucket) or `oauth2` (GitLab). The token always rides
|
|
29573
|
+
* GIT_ASKPASS, never the URL. The default keeps a pre-Bitbucket host safe — but the host
|
|
29525
29574
|
* raw-casts this response, so the load-bearing fallback is the host's
|
|
29526
29575
|
* use-site default.
|
|
29527
29576
|
*/
|
|
@@ -30469,7 +30518,12 @@ var SessionCredentialsResponseSchema = external_exports.object({
|
|
|
30469
30518
|
browserAllowedBaseUrls: external_exports.array(external_exports.string()),
|
|
30470
30519
|
browserExclusions: external_exports.array(external_exports.string()),
|
|
30471
30520
|
/** API_COVERAGE only; null otherwise. Range checks stay with the host's rate parser. */
|
|
30472
|
-
requestRate: external_exports.object({ perSec: external_exports.number(), burst: external_exports.number() }).nullable()
|
|
30521
|
+
requestRate: external_exports.object({ perSec: external_exports.number(), burst: external_exports.number() }).nullable(),
|
|
30522
|
+
/**
|
|
30523
|
+
* Labels of credentials the resolver could not include this time (a failed decrypt). A host
|
|
30524
|
+
* refreshing mid-run keeps its previous entries for these instead of reading them as deleted.
|
|
30525
|
+
*/
|
|
30526
|
+
skippedLabels: external_exports.array(external_exports.string()).default([])
|
|
30473
30527
|
});
|
|
30474
30528
|
var ConvexReconRequestSchema = external_exports.object({
|
|
30475
30529
|
runVersion: external_exports.number().int().nonnegative()
|
|
@@ -41057,7 +41111,12 @@ var CoverageGridResponseSchema = external_exports.object({
|
|
|
41057
41111
|
orphanFeatures: external_exports.array(CoverageOrphanFeatureSchema).default([]),
|
|
41058
41112
|
unplaced: external_exports.array(CoverageUnplacedRowSchema).default([]),
|
|
41059
41113
|
/** When the engagement started: a feature retired before it is not part of this engagement. */
|
|
41060
|
-
pentestStartedAt: external_exports.coerce.date().nullable().default(null)
|
|
41114
|
+
pentestStartedAt: external_exports.coerce.date().nullable().default(null),
|
|
41115
|
+
/**
|
|
41116
|
+
* When a closed engagement ended; null while it is open. A feature first recorded after it
|
|
41117
|
+
* was never part of this engagement.
|
|
41118
|
+
*/
|
|
41119
|
+
pentestClosedAt: external_exports.coerce.date().nullable().default(null)
|
|
41061
41120
|
});
|
|
41062
41121
|
|
|
41063
41122
|
// ../../packages/api-contracts/src/contracts/v1/pentest-coverage.ts
|
|
@@ -43657,6 +43716,26 @@ var SetStaffOrganizationPentestCustomerVisibilityRequestSchema = external_export
|
|
|
43657
43716
|
var RenameStaffOrganizationPentestRequestSchema = external_exports.object({
|
|
43658
43717
|
title: external_exports.string().trim().min(1, "Title is required").max(500, "Title must be 500 characters or fewer")
|
|
43659
43718
|
}).strict();
|
|
43719
|
+
var SetStaffOrganizationPentestStatusRequestSchema = external_exports.object({
|
|
43720
|
+
status: PentestStatus,
|
|
43721
|
+
reason: external_exports.string().trim().min(1, "Reason cannot be blank").max(2e3, "Reason must be 2000 characters or fewer").optional()
|
|
43722
|
+
}).strict();
|
|
43723
|
+
var CreateStaffPocDraftRequestSchema = external_exports.object({
|
|
43724
|
+
homepageUrl: external_exports.url({ protocol: /^https?$/ }).max(2048).optional()
|
|
43725
|
+
}).strict();
|
|
43726
|
+
var LaunchStaffPocSetupRequestSchema = external_exports.object({
|
|
43727
|
+
notes: external_exports.string().trim().min(1).max(MAX_SETUP_NOTES_CHARS).optional()
|
|
43728
|
+
}).strict();
|
|
43729
|
+
var LaunchStaffPocSetupResponseSchema = external_exports.object({
|
|
43730
|
+
agentSessionId: external_exports.uuid(),
|
|
43731
|
+
/** Null when Slack is not configured in this environment. */
|
|
43732
|
+
slack: external_exports.object({
|
|
43733
|
+
channelId: external_exports.string(),
|
|
43734
|
+
/** Null when Slack did not return the channel's name. */
|
|
43735
|
+
channelName: external_exports.string().nullable(),
|
|
43736
|
+
url: external_exports.url()
|
|
43737
|
+
}).strict().nullable()
|
|
43738
|
+
}).strict();
|
|
43660
43739
|
|
|
43661
43740
|
// ../../packages/api-contracts/src/contracts/v1/staff-pentests.ts
|
|
43662
43741
|
var c58 = initContract();
|
|
@@ -43717,6 +43796,161 @@ var staffPentestsContract = c58.router({
|
|
|
43717
43796
|
500: ErrorResponseSchema
|
|
43718
43797
|
},
|
|
43719
43798
|
summary: "Hide a pentest from the customer or show it again (Trace staff only)"
|
|
43799
|
+
},
|
|
43800
|
+
setStaffOrganizationPentestStatus: {
|
|
43801
|
+
method: "POST",
|
|
43802
|
+
path: "/organizations/:organizationId/staff/pentests/:pentestId/status",
|
|
43803
|
+
pathParams: StaffOrganizationPentestParamsSchema,
|
|
43804
|
+
body: SetStaffOrganizationPentestStatusRequestSchema,
|
|
43805
|
+
responses: {
|
|
43806
|
+
200: StaffOrganizationPentestSummarySchema,
|
|
43807
|
+
400: ErrorResponseSchema,
|
|
43808
|
+
401: ErrorResponseSchema,
|
|
43809
|
+
403: ErrorResponseSchema,
|
|
43810
|
+
404: ErrorResponseSchema,
|
|
43811
|
+
// A lifecycle rule refused the move; the rules and their codes live in
|
|
43812
|
+
// `PentestService.update`.
|
|
43813
|
+
409: ErrorResponseSchema,
|
|
43814
|
+
500: ErrorResponseSchema
|
|
43815
|
+
},
|
|
43816
|
+
summary: "Set a pentest\u2019s lifecycle status from the admin console (Trace staff only)"
|
|
43817
|
+
},
|
|
43818
|
+
createStaffPocDraft: {
|
|
43819
|
+
method: "POST",
|
|
43820
|
+
path: "/organizations/:organizationId/staff/pentests/poc",
|
|
43821
|
+
pathParams: OrgIdParamsSchema,
|
|
43822
|
+
body: CreateStaffPocDraftRequestSchema,
|
|
43823
|
+
// Error codes: StaffPocErrorCodes (staff-pentests.api.ts).
|
|
43824
|
+
responses: {
|
|
43825
|
+
201: StaffOrganizationPentestSummarySchema,
|
|
43826
|
+
400: ErrorResponseSchema,
|
|
43827
|
+
401: ErrorResponseSchema,
|
|
43828
|
+
403: ErrorResponseSchema,
|
|
43829
|
+
404: ErrorResponseSchema,
|
|
43830
|
+
409: ErrorResponseSchema,
|
|
43831
|
+
500: ErrorResponseSchema
|
|
43832
|
+
},
|
|
43833
|
+
summary: "Create a hidden PoC draft engagement (Trace staff only)"
|
|
43834
|
+
},
|
|
43835
|
+
launchStaffPocSetup: {
|
|
43836
|
+
method: "POST",
|
|
43837
|
+
path: "/organizations/:organizationId/staff/pentests/:pentestId/setup-session",
|
|
43838
|
+
pathParams: StaffOrganizationPentestParamsSchema,
|
|
43839
|
+
body: LaunchStaffPocSetupRequestSchema,
|
|
43840
|
+
// Error codes: StaffPocErrorCodes (staff-pentests.api.ts), plus the SETUP launch refusals
|
|
43841
|
+
// (SETUP_REQUIRES_SCOPING, SETUP_AFTER_TESTING_STARTED) and a 429 at the session cap.
|
|
43842
|
+
responses: {
|
|
43843
|
+
201: LaunchStaffPocSetupResponseSchema,
|
|
43844
|
+
400: ErrorResponseSchema,
|
|
43845
|
+
401: ErrorResponseSchema,
|
|
43846
|
+
403: ErrorResponseSchema,
|
|
43847
|
+
404: ErrorResponseSchema,
|
|
43848
|
+
409: ErrorResponseSchema,
|
|
43849
|
+
429: ErrorResponseSchema,
|
|
43850
|
+
500: ErrorResponseSchema,
|
|
43851
|
+
503: ErrorResponseSchema
|
|
43852
|
+
},
|
|
43853
|
+
summary: "Bind a PoC engagement's Slack and launch its SETUP session (Trace staff only)"
|
|
43854
|
+
}
|
|
43855
|
+
});
|
|
43856
|
+
|
|
43857
|
+
// ../../packages/api-contracts/src/schemas/api/v1/staff-products.api.ts
|
|
43858
|
+
var StaffProductParamsSchema = OrgIdParamsSchema.extend({
|
|
43859
|
+
productGroupId: external_exports.uuid()
|
|
43860
|
+
});
|
|
43861
|
+
var StaffProductApplicationParamsSchema = OrgIdParamsSchema.extend({
|
|
43862
|
+
applicationId: external_exports.uuid()
|
|
43863
|
+
});
|
|
43864
|
+
var PRODUCT_NAME_MAX_CHARS = 200;
|
|
43865
|
+
var ProductNameSchema = external_exports.string().trim().min(1).max(PRODUCT_NAME_MAX_CHARS);
|
|
43866
|
+
var StaffProductApplicationSchema = external_exports.object({
|
|
43867
|
+
applicationId: external_exports.uuid(),
|
|
43868
|
+
name: external_exports.string(),
|
|
43869
|
+
type: external_exports.enum(ApplicationTypeValues),
|
|
43870
|
+
/** Tells same-named applications apart; null for types without a URL. */
|
|
43871
|
+
applicationUrl: external_exports.string().nullable(),
|
|
43872
|
+
/** Applications this one uses, sorted by their name. */
|
|
43873
|
+
uses: external_exports.array(external_exports.uuid())
|
|
43874
|
+
}).strict();
|
|
43875
|
+
var StaffProductSchema = external_exports.object({
|
|
43876
|
+
productGroupId: external_exports.uuid(),
|
|
43877
|
+
name: external_exports.string(),
|
|
43878
|
+
applications: external_exports.array(StaffProductApplicationSchema)
|
|
43879
|
+
}).strict();
|
|
43880
|
+
var StaffProductsResponseSchema = external_exports.object({
|
|
43881
|
+
products: external_exports.array(StaffProductSchema)
|
|
43882
|
+
}).strict();
|
|
43883
|
+
var RenameStaffProductRequestSchema = external_exports.object({ name: ProductNameSchema }).strict();
|
|
43884
|
+
var MoveStaffApplicationRequestSchema = external_exports.union([
|
|
43885
|
+
external_exports.object({ productGroupId: external_exports.uuid() }).strict(),
|
|
43886
|
+
external_exports.object({ newProductName: ProductNameSchema }).strict()
|
|
43887
|
+
]);
|
|
43888
|
+
var SetStaffApplicationDependenciesRequestSchema = external_exports.object({
|
|
43889
|
+
toApplicationIds: external_exports.array(external_exports.uuid()).max(100).refine((ids) => new Set(ids).size === ids.length, {
|
|
43890
|
+
message: "Application ids must be unique"
|
|
43891
|
+
})
|
|
43892
|
+
}).strict();
|
|
43893
|
+
|
|
43894
|
+
// ../../packages/api-contracts/src/contracts/v1/staff-products.ts
|
|
43895
|
+
var c59 = initContract();
|
|
43896
|
+
var staffProductsContract = c59.router({
|
|
43897
|
+
listStaffProducts: {
|
|
43898
|
+
method: "GET",
|
|
43899
|
+
path: "/organizations/:organizationId/staff/products",
|
|
43900
|
+
pathParams: OrgIdParamsSchema,
|
|
43901
|
+
responses: {
|
|
43902
|
+
200: StaffProductsResponseSchema,
|
|
43903
|
+
401: ErrorResponseSchema,
|
|
43904
|
+
403: ErrorResponseSchema,
|
|
43905
|
+
404: ErrorResponseSchema,
|
|
43906
|
+
500: ErrorResponseSchema
|
|
43907
|
+
},
|
|
43908
|
+
summary: "List an organization\u2019s products and their applications (Trace staff only)"
|
|
43909
|
+
},
|
|
43910
|
+
renameStaffProduct: {
|
|
43911
|
+
method: "PATCH",
|
|
43912
|
+
path: "/organizations/:organizationId/staff/products/:productGroupId",
|
|
43913
|
+
pathParams: StaffProductParamsSchema,
|
|
43914
|
+
body: RenameStaffProductRequestSchema,
|
|
43915
|
+
responses: {
|
|
43916
|
+
200: StaffProductsResponseSchema,
|
|
43917
|
+
400: ErrorResponseSchema,
|
|
43918
|
+
401: ErrorResponseSchema,
|
|
43919
|
+
403: ErrorResponseSchema,
|
|
43920
|
+
404: ErrorResponseSchema,
|
|
43921
|
+
500: ErrorResponseSchema
|
|
43922
|
+
},
|
|
43923
|
+
summary: "Rename a product (Trace staff only)"
|
|
43924
|
+
},
|
|
43925
|
+
moveStaffApplication: {
|
|
43926
|
+
method: "PUT",
|
|
43927
|
+
path: "/organizations/:organizationId/staff/applications/:applicationId/product",
|
|
43928
|
+
pathParams: StaffProductApplicationParamsSchema,
|
|
43929
|
+
body: MoveStaffApplicationRequestSchema,
|
|
43930
|
+
responses: {
|
|
43931
|
+
200: StaffProductsResponseSchema,
|
|
43932
|
+
400: ErrorResponseSchema,
|
|
43933
|
+
401: ErrorResponseSchema,
|
|
43934
|
+
403: ErrorResponseSchema,
|
|
43935
|
+
404: ErrorResponseSchema,
|
|
43936
|
+
500: ErrorResponseSchema
|
|
43937
|
+
},
|
|
43938
|
+
summary: "Move an application into another or a new product (Trace staff only)"
|
|
43939
|
+
},
|
|
43940
|
+
setStaffApplicationDependencies: {
|
|
43941
|
+
method: "PUT",
|
|
43942
|
+
path: "/organizations/:organizationId/staff/applications/:applicationId/dependencies",
|
|
43943
|
+
pathParams: StaffProductApplicationParamsSchema,
|
|
43944
|
+
body: SetStaffApplicationDependenciesRequestSchema,
|
|
43945
|
+
responses: {
|
|
43946
|
+
200: StaffProductsResponseSchema,
|
|
43947
|
+
400: ErrorResponseSchema,
|
|
43948
|
+
401: ErrorResponseSchema,
|
|
43949
|
+
403: ErrorResponseSchema,
|
|
43950
|
+
404: ErrorResponseSchema,
|
|
43951
|
+
500: ErrorResponseSchema
|
|
43952
|
+
},
|
|
43953
|
+
summary: "Replace the applications an application uses (Trace staff only)"
|
|
43720
43954
|
}
|
|
43721
43955
|
});
|
|
43722
43956
|
|
|
@@ -43827,8 +44061,8 @@ var StaffQueueResponseSchema = external_exports.object({
|
|
|
43827
44061
|
}).strict();
|
|
43828
44062
|
|
|
43829
44063
|
// ../../packages/api-contracts/src/contracts/v1/staff-queue.ts
|
|
43830
|
-
var
|
|
43831
|
-
var staffQueueContract =
|
|
44064
|
+
var c60 = initContract();
|
|
44065
|
+
var staffQueueContract = c60.router({
|
|
43832
44066
|
getStaffQueue: {
|
|
43833
44067
|
method: "GET",
|
|
43834
44068
|
path: "/staff/queue",
|
|
@@ -43892,8 +44126,8 @@ var UpdateTestIntegrationRequestSchema = external_exports.object({
|
|
|
43892
44126
|
}).strict();
|
|
43893
44127
|
|
|
43894
44128
|
// ../../packages/api-contracts/src/contracts/v1/test-integration.ts
|
|
43895
|
-
var
|
|
43896
|
-
var testIntegrationContract =
|
|
44129
|
+
var c61 = initContract();
|
|
44130
|
+
var testIntegrationContract = c61.router({
|
|
43897
44131
|
// -- Fixture CRUD (org-less, staff-only) ----------------------------------
|
|
43898
44132
|
listTestIntegrations: {
|
|
43899
44133
|
method: "GET",
|
|
@@ -43973,7 +44207,7 @@ var testIntegrationContract = c60.router({
|
|
|
43973
44207
|
method: "POST",
|
|
43974
44208
|
path: "/staff/test-integrations/:testIntegrationId/mfa/code",
|
|
43975
44209
|
pathParams: TestIntegrationIdParamsSchema,
|
|
43976
|
-
body:
|
|
44210
|
+
body: c61.noBody(),
|
|
43977
44211
|
responses: {
|
|
43978
44212
|
200: CredentialMfaCodeResponseSchema,
|
|
43979
44213
|
401: ErrorResponseSchema,
|
|
@@ -44084,8 +44318,8 @@ var MyContextResponseSchema = external_exports.object({
|
|
|
44084
44318
|
});
|
|
44085
44319
|
|
|
44086
44320
|
// ../../packages/api-contracts/src/contracts/v1/user.ts
|
|
44087
|
-
var
|
|
44088
|
-
var userContract =
|
|
44321
|
+
var c62 = initContract();
|
|
44322
|
+
var userContract = c62.router({
|
|
44089
44323
|
getStaffProfile: {
|
|
44090
44324
|
method: "GET",
|
|
44091
44325
|
path: "/staff/profile",
|
|
@@ -44200,8 +44434,8 @@ var VantaIntegrationResponseSchema = external_exports.object({
|
|
|
44200
44434
|
});
|
|
44201
44435
|
|
|
44202
44436
|
// ../../packages/api-contracts/src/contracts/v1/vanta-integration.ts
|
|
44203
|
-
var
|
|
44204
|
-
var vantaIntegrationContract =
|
|
44437
|
+
var c63 = initContract();
|
|
44438
|
+
var vantaIntegrationContract = c63.router({
|
|
44205
44439
|
createVantaIntegration: {
|
|
44206
44440
|
method: "POST",
|
|
44207
44441
|
path: "/organizations/:organizationId/vanta-integration",
|
|
@@ -44562,8 +44796,8 @@ var VerifySharedVulnerabilityEmailCodeResponseSchema = external_exports.object({
|
|
|
44562
44796
|
});
|
|
44563
44797
|
|
|
44564
44798
|
// ../../packages/api-contracts/src/contracts/v1/vulnerability.ts
|
|
44565
|
-
var
|
|
44566
|
-
var vulnerabilityContract =
|
|
44799
|
+
var c64 = initContract();
|
|
44800
|
+
var vulnerabilityContract = c64.router({
|
|
44567
44801
|
filterVulnerabilities: {
|
|
44568
44802
|
method: "POST",
|
|
44569
44803
|
path: "/organizations/:organizationId/vulnerabilities/filter",
|
|
@@ -44788,8 +45022,8 @@ var UpdateVulnerabilityNoteRequestSchema = external_exports.object({
|
|
|
44788
45022
|
});
|
|
44789
45023
|
|
|
44790
45024
|
// ../../packages/api-contracts/src/contracts/v1/vulnerability-note.ts
|
|
44791
|
-
var
|
|
44792
|
-
var vulnerabilityNoteContract =
|
|
45025
|
+
var c65 = initContract();
|
|
45026
|
+
var vulnerabilityNoteContract = c65.router({
|
|
44793
45027
|
listNotes: {
|
|
44794
45028
|
method: "GET",
|
|
44795
45029
|
path: "/organizations/:organizationId/vulnerabilities/:vulnerabilityId/notes",
|
|
@@ -44970,8 +45204,8 @@ var ListWebhookDeliveriesResponseSchema = external_exports.object({
|
|
|
44970
45204
|
});
|
|
44971
45205
|
|
|
44972
45206
|
// ../../packages/api-contracts/src/contracts/v1/webhook-settings.ts
|
|
44973
|
-
var
|
|
44974
|
-
var webhookSettingsContract =
|
|
45207
|
+
var c66 = initContract();
|
|
45208
|
+
var webhookSettingsContract = c66.router({
|
|
44975
45209
|
listWebhookEndpoints: {
|
|
44976
45210
|
method: "GET",
|
|
44977
45211
|
path: "/organizations/:organizationId/webhook-settings/endpoints",
|
|
@@ -45108,9 +45342,31 @@ var webhookSettingsContract = c65.router({
|
|
|
45108
45342
|
}
|
|
45109
45343
|
});
|
|
45110
45344
|
|
|
45345
|
+
// ../../packages/api-contracts/src/contracts/v1/ws.ts
|
|
45346
|
+
var c67 = initContract();
|
|
45347
|
+
var WsTicketResponseSchema = external_exports.object({
|
|
45348
|
+
/** Opaque, single-use, bound to the caller and the request's organization. */
|
|
45349
|
+
ticket: external_exports.string(),
|
|
45350
|
+
expiresInSeconds: external_exports.number().int().positive()
|
|
45351
|
+
});
|
|
45352
|
+
var wsContract = c67.router({
|
|
45353
|
+
createTicket: {
|
|
45354
|
+
method: "POST",
|
|
45355
|
+
path: "/ws/ticket",
|
|
45356
|
+
body: c67.noBody(),
|
|
45357
|
+
responses: {
|
|
45358
|
+
200: WsTicketResponseSchema,
|
|
45359
|
+
401: ErrorResponseSchema,
|
|
45360
|
+
403: ErrorResponseSchema,
|
|
45361
|
+
503: ErrorResponseSchema
|
|
45362
|
+
},
|
|
45363
|
+
summary: "Mint a short-lived, single-use ticket that opens the scan-updates WebSocket"
|
|
45364
|
+
}
|
|
45365
|
+
});
|
|
45366
|
+
|
|
45111
45367
|
// ../../packages/api-contracts/src/contracts/v1/index.ts
|
|
45112
|
-
var
|
|
45113
|
-
var v1Contract =
|
|
45368
|
+
var c68 = initContract();
|
|
45369
|
+
var v1Contract = c68.router(
|
|
45114
45370
|
{
|
|
45115
45371
|
admin: adminContract,
|
|
45116
45372
|
cloudIntegration: cloudIntegrationContract,
|
|
@@ -45120,6 +45376,7 @@ var v1Contract = c66.router(
|
|
|
45120
45376
|
organization: organizationContract,
|
|
45121
45377
|
oobListener: oobListenerContract,
|
|
45122
45378
|
user: userContract,
|
|
45379
|
+
ws: wsContract,
|
|
45123
45380
|
repository: repositoryContract,
|
|
45124
45381
|
github: githubContract,
|
|
45125
45382
|
staffGithub: staffGithubContract,
|
|
@@ -45175,6 +45432,7 @@ var v1Contract = c66.router(
|
|
|
45175
45432
|
staffPentestStats: staffPentestStatsContract,
|
|
45176
45433
|
staffKnowledgeFacts: staffKnowledgeFactsContract,
|
|
45177
45434
|
staffPentests: staffPentestsContract,
|
|
45435
|
+
staffProducts: staffProductsContract,
|
|
45178
45436
|
staffQueue: staffQueueContract,
|
|
45179
45437
|
organizationDisposal: organizationDisposalContract
|
|
45180
45438
|
},
|
|
@@ -45184,13 +45442,13 @@ var v1Contract = c66.router(
|
|
|
45184
45442
|
);
|
|
45185
45443
|
|
|
45186
45444
|
// ../../packages/api-contracts/src/contracts/index.ts
|
|
45187
|
-
var
|
|
45188
|
-
var contract =
|
|
45445
|
+
var c69 = initContract();
|
|
45446
|
+
var contract = c69.router({
|
|
45189
45447
|
v1: v1Contract
|
|
45190
45448
|
});
|
|
45191
45449
|
|
|
45192
45450
|
// ../../packages/api-contracts/src/contracts/v1/desktop-host-internal.ts
|
|
45193
|
-
var
|
|
45451
|
+
var c70 = initContract();
|
|
45194
45452
|
var MAX_VMS_PER_SYNC = 16;
|
|
45195
45453
|
var DesktopHostSyncRequestSchema = external_exports.object({
|
|
45196
45454
|
/** Integer protocol the runner speaks. Below the api's minimum, the host gets
|
|
@@ -45215,7 +45473,7 @@ var DesktopHostSyncResponseSchema = external_exports.object({
|
|
|
45215
45473
|
* id not listed here is deleted. */
|
|
45216
45474
|
targets: external_exports.array(DesktopHostSyncTargetSchema).max(MAX_VMS_PER_SYNC)
|
|
45217
45475
|
});
|
|
45218
|
-
var desktopHostInternalContract =
|
|
45476
|
+
var desktopHostInternalContract = c70.router({
|
|
45219
45477
|
sync: {
|
|
45220
45478
|
method: "POST",
|
|
45221
45479
|
path: "/internal/v1/desktop-hosts/sync",
|
|
@@ -45240,7 +45498,8 @@ var OPENAI_SESSION_TYPES = [
|
|
|
45240
45498
|
"RECON",
|
|
45241
45499
|
"API_COVERAGE",
|
|
45242
45500
|
"PRODUCT_RECON",
|
|
45243
|
-
"CODE_REVIEW"
|
|
45501
|
+
"CODE_REVIEW",
|
|
45502
|
+
"REMEDIATION"
|
|
45244
45503
|
];
|
|
45245
45504
|
var AGENT_SESSION_MODELS = [
|
|
45246
45505
|
{
|
|
@@ -45314,8 +45573,8 @@ var GitHubWebhookResponseSchema = external_exports.object({
|
|
|
45314
45573
|
});
|
|
45315
45574
|
|
|
45316
45575
|
// ../../packages/api-contracts/src/contracts/webhooks/github.ts
|
|
45317
|
-
var
|
|
45318
|
-
var githubWebhookContract =
|
|
45576
|
+
var c71 = initContract();
|
|
45577
|
+
var githubWebhookContract = c71.router(
|
|
45319
45578
|
{
|
|
45320
45579
|
handleWebhook: {
|
|
45321
45580
|
method: "POST",
|
|
@@ -45333,7 +45592,7 @@ var githubWebhookContract = c69.router(
|
|
|
45333
45592
|
pathPrefix: "/webhooks"
|
|
45334
45593
|
}
|
|
45335
45594
|
);
|
|
45336
|
-
var githubReadonlyWebhookContract =
|
|
45595
|
+
var githubReadonlyWebhookContract = c71.router(
|
|
45337
45596
|
{
|
|
45338
45597
|
handleWebhook: {
|
|
45339
45598
|
method: "POST",
|
|
@@ -45353,9 +45612,9 @@ var githubReadonlyWebhookContract = c69.router(
|
|
|
45353
45612
|
);
|
|
45354
45613
|
|
|
45355
45614
|
// ../../packages/api-contracts/src/contracts/webhooks/linear.ts
|
|
45356
|
-
var
|
|
45615
|
+
var c72 = initContract();
|
|
45357
45616
|
var LinearWebhookResponseSchema = external_exports.object({ ok: external_exports.boolean() });
|
|
45358
|
-
var linearWebhookContract =
|
|
45617
|
+
var linearWebhookContract = c72.router(
|
|
45359
45618
|
{
|
|
45360
45619
|
handleWebhook: {
|
|
45361
45620
|
method: "POST",
|
|
@@ -45375,7 +45634,7 @@ var linearWebhookContract = c70.router(
|
|
|
45375
45634
|
);
|
|
45376
45635
|
|
|
45377
45636
|
// ../../packages/api-contracts/src/contracts/forge/bitbucket.ts
|
|
45378
|
-
var
|
|
45637
|
+
var c73 = initContract();
|
|
45379
45638
|
var InstallEventSchema = external_exports.object({
|
|
45380
45639
|
eventType: external_exports.enum(["avi:forge:installed:app", "avi:forge:upgraded:app"]),
|
|
45381
45640
|
context: external_exports.object({ cloudId: external_exports.string().min(1) }).loose(),
|
|
@@ -45404,7 +45663,7 @@ var ForgePairingCodeResponseSchema = external_exports.discriminatedUnion("state"
|
|
|
45404
45663
|
expiresInSeconds: external_exports.number().int()
|
|
45405
45664
|
})
|
|
45406
45665
|
]);
|
|
45407
|
-
var forgeBitbucketContract =
|
|
45666
|
+
var forgeBitbucketContract = c73.router(
|
|
45408
45667
|
{
|
|
45409
45668
|
lifecycle: {
|
|
45410
45669
|
method: "POST",
|
|
@@ -45451,8 +45710,8 @@ var HealthResponseSchema = external_exports.object({
|
|
|
45451
45710
|
});
|
|
45452
45711
|
|
|
45453
45712
|
// ../../packages/api-contracts/src/contracts/health.ts
|
|
45454
|
-
var
|
|
45455
|
-
var healthContract =
|
|
45713
|
+
var c74 = initContract();
|
|
45714
|
+
var healthContract = c74.router({
|
|
45456
45715
|
getHealth: {
|
|
45457
45716
|
method: "GET",
|
|
45458
45717
|
path: "/health",
|
|
@@ -45464,8 +45723,8 @@ var healthContract = c72.router({
|
|
|
45464
45723
|
});
|
|
45465
45724
|
|
|
45466
45725
|
// ../../packages/api-contracts/src/contracts/v1/vulnerability-share.ts
|
|
45467
|
-
var
|
|
45468
|
-
var vulnerabilityShareContract =
|
|
45726
|
+
var c75 = initContract();
|
|
45727
|
+
var vulnerabilityShareContract = c75.router(
|
|
45469
45728
|
{
|
|
45470
45729
|
resolveShareLink: {
|
|
45471
45730
|
method: "GET",
|
|
@@ -45491,7 +45750,8 @@ var vulnerabilityShareContract = c73.router(
|
|
|
45491
45750
|
401: ErrorResponseSchema,
|
|
45492
45751
|
403: ErrorResponseSchema,
|
|
45493
45752
|
404: ErrorResponseSchema,
|
|
45494
|
-
500: ErrorResponseSchema
|
|
45753
|
+
500: ErrorResponseSchema,
|
|
45754
|
+
503: ErrorResponseSchema
|
|
45495
45755
|
}
|
|
45496
45756
|
},
|
|
45497
45757
|
verifyShareEmailCode: {
|
|
@@ -45515,8 +45775,8 @@ var vulnerabilityShareContract = c73.router(
|
|
|
45515
45775
|
);
|
|
45516
45776
|
|
|
45517
45777
|
// ../../packages/api-contracts/src/contracts/v1/attestation-verify.ts
|
|
45518
|
-
var
|
|
45519
|
-
var attestationVerifyContract =
|
|
45778
|
+
var c76 = initContract();
|
|
45779
|
+
var attestationVerifyContract = c76.router(
|
|
45520
45780
|
{
|
|
45521
45781
|
verifyAttestation: {
|
|
45522
45782
|
method: "GET",
|
|
@@ -45572,8 +45832,8 @@ var UpdatePrVulnerabilityRequestSchema = external_exports.object({
|
|
|
45572
45832
|
});
|
|
45573
45833
|
|
|
45574
45834
|
// ../../packages/api-contracts/src/contracts/v1/pr-vulnerability.ts
|
|
45575
|
-
var
|
|
45576
|
-
var prVulnerabilityContract =
|
|
45835
|
+
var c77 = initContract();
|
|
45836
|
+
var prVulnerabilityContract = c77.router(
|
|
45577
45837
|
{
|
|
45578
45838
|
listPrVulnerabilities: {
|
|
45579
45839
|
method: "GET",
|
|
@@ -45737,8 +45997,8 @@ var CoordinatorSessionSearchResponseSchema = external_exports.strictObject({
|
|
|
45737
45997
|
});
|
|
45738
45998
|
|
|
45739
45999
|
// ../../packages/api-contracts/src/contracts/v1/coordinator-inspection.ts
|
|
45740
|
-
var
|
|
45741
|
-
var coordinatorInspectionContract =
|
|
46000
|
+
var c78 = initContract();
|
|
46001
|
+
var coordinatorInspectionContract = c78.router({
|
|
45742
46002
|
sessionWindow: {
|
|
45743
46003
|
method: "POST",
|
|
45744
46004
|
path: "/internal/v1/agent-sessions/:agentSessionId/coordinator/session-window",
|
|
@@ -45780,7 +46040,7 @@ var coordinatorInspectionContract = c76.router({
|
|
|
45780
46040
|
});
|
|
45781
46041
|
|
|
45782
46042
|
// ../../packages/api-contracts/src/contracts/v1/pentest-coordinator-internal.ts
|
|
45783
|
-
var
|
|
46043
|
+
var c79 = initContract();
|
|
45784
46044
|
var params2 = external_exports.strictObject({ agentSessionId: external_exports.uuid() });
|
|
45785
46045
|
var errors3 = {
|
|
45786
46046
|
400: ErrorResponseSchema,
|
|
@@ -45793,7 +46053,7 @@ var errors3 = {
|
|
|
45793
46053
|
500: ErrorResponseSchema,
|
|
45794
46054
|
503: ErrorResponseSchema
|
|
45795
46055
|
};
|
|
45796
|
-
var pentestCoordinatorInternalContract =
|
|
46056
|
+
var pentestCoordinatorInternalContract = c79.router({
|
|
45797
46057
|
state: {
|
|
45798
46058
|
method: "POST",
|
|
45799
46059
|
path: "/internal/v1/agent-sessions/:agentSessionId/coordinator/state",
|
|
@@ -46040,8 +46300,8 @@ var CoordinatorCoverageResponseSchema = external_exports.strictObject({
|
|
|
46040
46300
|
);
|
|
46041
46301
|
|
|
46042
46302
|
// ../../packages/api-contracts/src/contracts/v1/coordinator-domain-read.ts
|
|
46043
|
-
var
|
|
46044
|
-
var coordinatorDomainReadContract =
|
|
46303
|
+
var c80 = initContract();
|
|
46304
|
+
var coordinatorDomainReadContract = c80.router({
|
|
46045
46305
|
coverage: {
|
|
46046
46306
|
method: "POST",
|
|
46047
46307
|
path: "/internal/v1/agent-sessions/:agentSessionId/coordinator/coverage",
|
|
@@ -46246,7 +46506,7 @@ var CoordinatorPublicDocumentationResponseSchema = CoordinatorContextTextReadRes
|
|
|
46246
46506
|
var CoordinatorCustomerDocumentResponseSchema = CoordinatorContextTextReadResponseSchema;
|
|
46247
46507
|
|
|
46248
46508
|
// ../../packages/api-contracts/src/contracts/v1/coordinator-context-read.ts
|
|
46249
|
-
var
|
|
46509
|
+
var c81 = initContract();
|
|
46250
46510
|
var errors4 = {
|
|
46251
46511
|
400: ErrorResponseSchema,
|
|
46252
46512
|
401: ErrorResponseSchema,
|
|
@@ -46258,7 +46518,7 @@ var errors4 = {
|
|
|
46258
46518
|
500: ErrorResponseSchema,
|
|
46259
46519
|
503: ErrorResponseSchema
|
|
46260
46520
|
};
|
|
46261
|
-
var coordinatorContextReadContract =
|
|
46521
|
+
var coordinatorContextReadContract = c81.router({
|
|
46262
46522
|
contextSources: {
|
|
46263
46523
|
method: "POST",
|
|
46264
46524
|
path: "/internal/v1/agent-sessions/:agentSessionId/coordinator/context-sources",
|
|
@@ -46492,19 +46752,19 @@ var COVERAGE_CLASSES = [
|
|
|
46492
46752
|
},
|
|
46493
46753
|
{ taxonomy: "RECON", id: "RECON-15", name: "Deployment-platform config", shortLabel: "Deploy" }
|
|
46494
46754
|
];
|
|
46495
|
-
var BY_ID = new Map(COVERAGE_CLASSES.map((
|
|
46755
|
+
var BY_ID = new Map(COVERAGE_CLASSES.map((c86) => [c86.id, c86]));
|
|
46496
46756
|
function idsWhere(keep) {
|
|
46497
|
-
return [OTHER_CLASS_ID, ...COVERAGE_CLASSES.filter(keep).map((
|
|
46757
|
+
return [OTHER_CLASS_ID, ...COVERAGE_CLASSES.filter(keep).map((c86) => c86.id)];
|
|
46498
46758
|
}
|
|
46499
|
-
var HUNTING_CLASS_IDS = idsWhere((
|
|
46500
|
-
var RECON_CLASS_IDS = idsWhere((
|
|
46759
|
+
var HUNTING_CLASS_IDS = idsWhere((c86) => c86.taxonomy !== "RECON");
|
|
46760
|
+
var RECON_CLASS_IDS = idsWhere((c86) => c86.taxonomy === "RECON");
|
|
46501
46761
|
var HUNTING_ID_SET = new Set(HUNTING_CLASS_IDS);
|
|
46502
46762
|
var RECON_ID_SET = new Set(RECON_CLASS_IDS);
|
|
46503
46763
|
var TAXONOMY_ORDER = new Map(CoverageTaxonomyValues.map((t2, i2) => [t2, i2]));
|
|
46504
|
-
var CLASS_ORDER = new Map(COVERAGE_CLASSES.map((
|
|
46764
|
+
var CLASS_ORDER = new Map(COVERAGE_CLASSES.map((c86, i2) => [c86.id, i2]));
|
|
46505
46765
|
|
|
46506
46766
|
// ../../packages/api-contracts/src/contracts/v1/api-coverage-internal.ts
|
|
46507
|
-
var
|
|
46767
|
+
var c82 = initContract();
|
|
46508
46768
|
var pathParams = external_exports.strictObject({ agentSessionId: external_exports.uuid() });
|
|
46509
46769
|
var errors5 = {
|
|
46510
46770
|
400: ErrorResponseSchema,
|
|
@@ -46514,7 +46774,7 @@ var errors5 = {
|
|
|
46514
46774
|
500: ErrorResponseSchema
|
|
46515
46775
|
};
|
|
46516
46776
|
var base = "/internal/v1/agent-sessions/:agentSessionId/api-coverage";
|
|
46517
|
-
var apiCoverageInternalContract =
|
|
46777
|
+
var apiCoverageInternalContract = c82.router({
|
|
46518
46778
|
upsertApiOperations: {
|
|
46519
46779
|
method: "POST",
|
|
46520
46780
|
path: `${base}/operations`,
|
|
@@ -46653,7 +46913,7 @@ var SetupNotesRequestSchema = external_exports.object({ runVersion: RunVersionSc
|
|
|
46653
46913
|
var SetupNotesResponseSchema = external_exports.object({ notes: external_exports.string().nullable() });
|
|
46654
46914
|
|
|
46655
46915
|
// ../../packages/api-contracts/src/contracts/v1/setup-session-internal.ts
|
|
46656
|
-
var
|
|
46916
|
+
var c83 = initContract();
|
|
46657
46917
|
var pathParams2 = external_exports.strictObject({ agentSessionId: external_exports.uuid() });
|
|
46658
46918
|
var errors6 = {
|
|
46659
46919
|
400: ErrorResponseSchema,
|
|
@@ -46665,7 +46925,7 @@ var errors6 = {
|
|
|
46665
46925
|
503: ErrorResponseSchema
|
|
46666
46926
|
};
|
|
46667
46927
|
var base2 = "/internal/v1/agent-sessions/:agentSessionId/setup";
|
|
46668
|
-
var setupSessionInternalContract =
|
|
46928
|
+
var setupSessionInternalContract = c83.router({
|
|
46669
46929
|
addSetupTarget: {
|
|
46670
46930
|
method: "POST",
|
|
46671
46931
|
path: `${base2}/target`,
|
|
@@ -46792,8 +47052,8 @@ var ListReviewPremiseChecksResponseSchema = external_exports.object({
|
|
|
46792
47052
|
});
|
|
46793
47053
|
|
|
46794
47054
|
// ../../packages/api-contracts/src/contracts/v1/premise-check-internal.ts
|
|
46795
|
-
var
|
|
46796
|
-
var premiseCheckInternalContract =
|
|
47055
|
+
var c84 = initContract();
|
|
47056
|
+
var premiseCheckInternalContract = c84.router({
|
|
46797
47057
|
listReviewPremiseChecks: {
|
|
46798
47058
|
method: "POST",
|
|
46799
47059
|
path: "/internal/v1/agent-sessions/:agentSessionId/premise-checks/list",
|
|
@@ -47617,6 +47877,7 @@ var PRODUCTION_API_URL = "https://api.securewithtrace.com";
|
|
|
47617
47877
|
var UNAUTHORIZED_STATUS = 401;
|
|
47618
47878
|
var REFRESH_AUTH_FAILURE_STATUS_CODES = /* @__PURE__ */ new Set([400, 401]);
|
|
47619
47879
|
var MAX_REFRESH_ROTATION_RETRIES = 3;
|
|
47880
|
+
var TRACE_API_HOST_SUFFIX = ".securewithtrace.com";
|
|
47620
47881
|
function getApiBaseUrl() {
|
|
47621
47882
|
const raw = process.env["TRACE_API_URL"];
|
|
47622
47883
|
if (!raw) {
|
|
@@ -47635,16 +47896,15 @@ function getApiBaseUrl() {
|
|
|
47635
47896
|
console.error(colorWarning("Invalid TRACE_API_URL: only https:// is allowed. Using default."));
|
|
47636
47897
|
return PRODUCTION_API_URL;
|
|
47637
47898
|
}
|
|
47638
|
-
|
|
47639
|
-
if (hostname3 === "localhost" || hostname3 === "127.0.0.1" || hostname3 === "0.0.0.0" || hostname3 === "::1" || hostname3.startsWith("10.") || hostname3.startsWith("192.168.") || /^172\.(1[6-9]|2[0-9]|3[01])\./.test(hostname3)) {
|
|
47899
|
+
if (!parsed.hostname.endsWith(TRACE_API_HOST_SUFFIX)) {
|
|
47640
47900
|
console.error(
|
|
47641
47901
|
colorWarning(
|
|
47642
|
-
|
|
47902
|
+
`Ignoring TRACE_API_URL: '${parsed.hostname}' is not a Trace API host (*${TRACE_API_HOST_SUFFIX}). Using default.`
|
|
47643
47903
|
)
|
|
47644
47904
|
);
|
|
47645
47905
|
return PRODUCTION_API_URL;
|
|
47646
47906
|
}
|
|
47647
|
-
return
|
|
47907
|
+
return `${parsed.origin}${parsed.pathname}`.replace(/\/+$/, "");
|
|
47648
47908
|
}
|
|
47649
47909
|
function requireAuth() {
|
|
47650
47910
|
const credential = loadCredentialOrExit();
|
|
@@ -47728,6 +47988,60 @@ function exitHumanPrincipalRequired() {
|
|
|
47728
47988
|
console.error(colorError("This command requires a human login; run `tracecli auth login`."));
|
|
47729
47989
|
process.exit(1);
|
|
47730
47990
|
}
|
|
47991
|
+
function transportErrorCode(error48) {
|
|
47992
|
+
if (!(error48 instanceof Error)) {
|
|
47993
|
+
return null;
|
|
47994
|
+
}
|
|
47995
|
+
const codeOf = (value) => {
|
|
47996
|
+
if (typeof value !== "object" || value === null || !("code" in value)) {
|
|
47997
|
+
return null;
|
|
47998
|
+
}
|
|
47999
|
+
return typeof value.code === "string" && value.code.length > 0 ? value.code : null;
|
|
48000
|
+
};
|
|
48001
|
+
const code = codeOf(error48) ?? codeOf(error48.cause);
|
|
48002
|
+
if (code !== null) {
|
|
48003
|
+
return code;
|
|
48004
|
+
}
|
|
48005
|
+
return error48.name === "TypeError" && /^fetch failed/i.test(error48.message) ? "FETCH_FAILED" : null;
|
|
48006
|
+
}
|
|
48007
|
+
var TRANSPORT_ERROR_HINTS = {
|
|
48008
|
+
ENOTFOUND: "DNS lookup failed",
|
|
48009
|
+
EAI_AGAIN: "DNS lookup timed out",
|
|
48010
|
+
ECONNREFUSED: "connection refused",
|
|
48011
|
+
ECONNRESET: "connection reset",
|
|
48012
|
+
ETIMEDOUT: "connection timed out",
|
|
48013
|
+
ConnectionRefused: "connection refused",
|
|
48014
|
+
ConnectionClosed: "connection closed before a response arrived",
|
|
48015
|
+
FailedToOpenSocket: "could not open a socket",
|
|
48016
|
+
CERT_HAS_EXPIRED: "the server certificate has expired",
|
|
48017
|
+
UNABLE_TO_VERIFY_LEAF_SIGNATURE: "the server certificate could not be verified",
|
|
48018
|
+
DEPTH_ZERO_SELF_SIGNED_CERT: "the server presented a self-signed certificate",
|
|
48019
|
+
FETCH_FAILED: "the request never received a response"
|
|
48020
|
+
};
|
|
48021
|
+
function unreachableApiMessage(baseUrl, code) {
|
|
48022
|
+
const host = new URL(baseUrl).host;
|
|
48023
|
+
const detail = TRANSPORT_ERROR_HINTS[code] ?? "the request failed";
|
|
48024
|
+
return [
|
|
48025
|
+
`Couldn't reach the Trace API at ${host}: ${detail} (${code}).`,
|
|
48026
|
+
"Check that this machine can reach the internet. Sandboxed agents and CI runners often block",
|
|
48027
|
+
`outbound network access; allow ${host} and retry.`
|
|
48028
|
+
].join("\n");
|
|
48029
|
+
}
|
|
48030
|
+
function exitUnreachableApi(code) {
|
|
48031
|
+
console.error(colorError(unreachableApiMessage(getApiBaseUrl(), code)));
|
|
48032
|
+
process.exit(1);
|
|
48033
|
+
}
|
|
48034
|
+
async function requestOrExit(request, token) {
|
|
48035
|
+
try {
|
|
48036
|
+
return await request(createClient(token));
|
|
48037
|
+
} catch (error48) {
|
|
48038
|
+
const code = transportErrorCode(error48);
|
|
48039
|
+
if (code !== null) {
|
|
48040
|
+
exitUnreachableApi(code);
|
|
48041
|
+
}
|
|
48042
|
+
throw error48;
|
|
48043
|
+
}
|
|
48044
|
+
}
|
|
47731
48045
|
function createClient(token) {
|
|
47732
48046
|
return initClient(v1Contract, {
|
|
47733
48047
|
baseUrl: getApiBaseUrl(),
|
|
@@ -47855,7 +48169,7 @@ async function refreshStoredAccessTokenForOrganization(workosOrganizationId) {
|
|
|
47855
48169
|
}
|
|
47856
48170
|
async function authenticatedRequest(request) {
|
|
47857
48171
|
const credential = loadCredentialOrExit();
|
|
47858
|
-
const firstResult = await request
|
|
48172
|
+
const firstResult = await requestOrExit(request, credential.token);
|
|
47859
48173
|
if (credential.kind === "api_key") {
|
|
47860
48174
|
if (firstResult.status === UNAUTHORIZED_STATUS) {
|
|
47861
48175
|
exitApiKeyUnauthorized();
|
|
@@ -47872,7 +48186,7 @@ async function authenticatedRequest(request) {
|
|
|
47872
48186
|
if (!refreshedToken) {
|
|
47873
48187
|
return firstResult;
|
|
47874
48188
|
}
|
|
47875
|
-
return request
|
|
48189
|
+
return requestOrExit(request, refreshedToken);
|
|
47876
48190
|
}
|
|
47877
48191
|
async function authenticatedRequestSafe(request) {
|
|
47878
48192
|
let credential;
|
|
@@ -49616,6 +49930,62 @@ function resolveClearableUrl(value, clear, flag) {
|
|
|
49616
49930
|
}
|
|
49617
49931
|
return { value };
|
|
49618
49932
|
}
|
|
49933
|
+
function normalizeRepositoryRole(input) {
|
|
49934
|
+
const candidate = input.trim().toUpperCase().replace(/-/g, "_");
|
|
49935
|
+
return ApplicationRepositoryRoleValues.find((role) => role === candidate) ?? null;
|
|
49936
|
+
}
|
|
49937
|
+
var REPOSITORY_ROLE_INPUTS = ApplicationRepositoryRoleValues.map(
|
|
49938
|
+
(role) => role.toLowerCase().replace(/_/g, "-")
|
|
49939
|
+
);
|
|
49940
|
+
function parseRepositoryRoles(inputs) {
|
|
49941
|
+
const picked = /* @__PURE__ */ new Set();
|
|
49942
|
+
for (const input of inputs) {
|
|
49943
|
+
const role = normalizeRepositoryRole(input);
|
|
49944
|
+
if (role === null) {
|
|
49945
|
+
return {
|
|
49946
|
+
error: `Invalid --role '${input}'. Use one of: ${REPOSITORY_ROLE_INPUTS.join(", ")}.`
|
|
49947
|
+
};
|
|
49948
|
+
}
|
|
49949
|
+
picked.add(role);
|
|
49950
|
+
}
|
|
49951
|
+
return { roles: ApplicationRepositoryRoleValues.filter((role) => picked.has(role)) };
|
|
49952
|
+
}
|
|
49953
|
+
function buildLinkRepositoryBody(input) {
|
|
49954
|
+
return {
|
|
49955
|
+
repositoryId: input.repositoryId,
|
|
49956
|
+
...input.roles !== void 0 && input.roles.length > 0 ? { roles: [...input.roles] } : {},
|
|
49957
|
+
...input.roleLabel !== void 0 ? { roleLabel: input.roleLabel } : {},
|
|
49958
|
+
...input.repositoryPath !== void 0 ? { repositoryPath: input.repositoryPath } : {},
|
|
49959
|
+
...input.scanEnabled !== void 0 ? { scanEnabled: input.scanEnabled } : {}
|
|
49960
|
+
};
|
|
49961
|
+
}
|
|
49962
|
+
function buildUpdateLinkBody(input) {
|
|
49963
|
+
return {
|
|
49964
|
+
...input.roles !== void 0 ? { roles: [...input.roles] } : {},
|
|
49965
|
+
...input.roleLabel !== void 0 ? { roleLabel: input.roleLabel } : {},
|
|
49966
|
+
...input.repositoryPath !== void 0 ? { repositoryPath: input.repositoryPath } : {},
|
|
49967
|
+
...input.scanEnabled !== void 0 ? { scanEnabled: input.scanEnabled } : {}
|
|
49968
|
+
};
|
|
49969
|
+
}
|
|
49970
|
+
function isEmptyLinkUpdate(body) {
|
|
49971
|
+
return Object.keys(body).length === 0;
|
|
49972
|
+
}
|
|
49973
|
+
function validateRoleLabel(roles, roleLabel) {
|
|
49974
|
+
if (roles === void 0 || roleLabel === void 0 || roleLabel === null) {
|
|
49975
|
+
return null;
|
|
49976
|
+
}
|
|
49977
|
+
return roles.includes("OTHER") ? null : "--role-label requires --role other.";
|
|
49978
|
+
}
|
|
49979
|
+
function findLinkForRepo(links, input) {
|
|
49980
|
+
if (isUuid(input)) {
|
|
49981
|
+
const id = input.toLowerCase();
|
|
49982
|
+
return links.find(
|
|
49983
|
+
(link) => link.applicationRepositoryId?.toLowerCase() === id || link.repositoryId.toLowerCase() === id
|
|
49984
|
+
) ?? null;
|
|
49985
|
+
}
|
|
49986
|
+
const target = normalizeRepoUrlForMatch(resolveRepoUrl(input));
|
|
49987
|
+
return links.find((link) => normalizeRepoUrlForMatch(link.repositoryUrl) === target) ?? null;
|
|
49988
|
+
}
|
|
49619
49989
|
function failWriteOp(action, status, body, notFoundLabel) {
|
|
49620
49990
|
const { message, errorCode } = readErrorFields(body);
|
|
49621
49991
|
if (status === UNAUTHORIZED_STATUS2) {
|
|
@@ -49656,6 +50026,28 @@ function failWriteOp(action, status, body, notFoundLabel) {
|
|
|
49656
50026
|
);
|
|
49657
50027
|
process.exit(1);
|
|
49658
50028
|
}
|
|
50029
|
+
function failLinkOp(action, status, body) {
|
|
50030
|
+
const { message } = readErrorFields(body);
|
|
50031
|
+
if (status === UNAUTHORIZED_STATUS2) {
|
|
50032
|
+
exitAuthFailed();
|
|
50033
|
+
}
|
|
50034
|
+
if (status === 403) {
|
|
50035
|
+
console.error(
|
|
50036
|
+
colorError(
|
|
50037
|
+
"Repository links require an organization admin or Trace staff on a pentest-enabled organization, signed in with a browser session (API keys are rejected)."
|
|
50038
|
+
)
|
|
50039
|
+
);
|
|
50040
|
+
process.exit(1);
|
|
50041
|
+
}
|
|
50042
|
+
if (status === 404 || status === 409 || status === 400) {
|
|
50043
|
+
console.error(colorError(message ?? `Failed to ${action} (status ${status}).`));
|
|
50044
|
+
process.exit(1);
|
|
50045
|
+
}
|
|
50046
|
+
console.error(
|
|
50047
|
+
colorError(`Failed to ${action} repository (status ${status})${message ? `: ${message}` : "."}`)
|
|
50048
|
+
);
|
|
50049
|
+
process.exit(1);
|
|
50050
|
+
}
|
|
49659
50051
|
function failReadOp(action, status, body, notFoundLabel) {
|
|
49660
50052
|
const { message } = readErrorFields(body);
|
|
49661
50053
|
if (status === UNAUTHORIZED_STATUS2) {
|
|
@@ -49717,12 +50109,12 @@ function buildApplicationsTable(apps) {
|
|
|
49717
50109
|
repos: String(a2.repositories.length),
|
|
49718
50110
|
url: a2.applicationUrl ? sanitizeDisplay(a2.applicationUrl) : "\u2014"
|
|
49719
50111
|
}));
|
|
49720
|
-
const idWidth = Math.max(2, ...cells.map((
|
|
49721
|
-
const nameWidth = Math.max(4, ...cells.map((
|
|
49722
|
-
const typeWidth = Math.max(4, ...cells.map((
|
|
50112
|
+
const idWidth = Math.max(2, ...cells.map((c86) => c86.id.length));
|
|
50113
|
+
const nameWidth = Math.max(4, ...cells.map((c86) => c86.name.length));
|
|
50114
|
+
const typeWidth = Math.max(4, ...cells.map((c86) => c86.type.length));
|
|
49723
50115
|
const header = `${"ID".padEnd(idWidth)} ${"NAME".padEnd(nameWidth)} ${"TYPE".padEnd(typeWidth)} REPOS URL`;
|
|
49724
50116
|
const rows = cells.map(
|
|
49725
|
-
(
|
|
50117
|
+
(c86) => `${c86.id.padEnd(idWidth)} ${c86.name.padEnd(nameWidth)} ${c86.type.padEnd(typeWidth)} ${c86.repos.padStart(5)} ${c86.url}`
|
|
49726
50118
|
);
|
|
49727
50119
|
return { header, rows };
|
|
49728
50120
|
}
|
|
@@ -49742,12 +50134,12 @@ function buildApplicationRepositoriesTable(links) {
|
|
|
49742
50134
|
path: l2.repositoryPath ? sanitizeDisplay(l2.repositoryPath) : "\u2014",
|
|
49743
50135
|
status: formatStatus(l2.repositoryStatus)
|
|
49744
50136
|
}));
|
|
49745
|
-
const nameWidth = Math.max(10, ...cells.map((
|
|
49746
|
-
const roleWidth = Math.max(4, ...cells.map((
|
|
49747
|
-
const pathWidth = Math.max(4, ...cells.map((
|
|
50137
|
+
const nameWidth = Math.max(10, ...cells.map((c86) => c86.name.length));
|
|
50138
|
+
const roleWidth = Math.max(4, ...cells.map((c86) => c86.role.length));
|
|
50139
|
+
const pathWidth = Math.max(4, ...cells.map((c86) => c86.path.length));
|
|
49748
50140
|
const header = `${"REPOSITORY".padEnd(nameWidth)} SCAN ${"ROLE".padEnd(roleWidth)} ${"PATH".padEnd(pathWidth)} STATUS`;
|
|
49749
50141
|
const rows = cells.map(
|
|
49750
|
-
(
|
|
50142
|
+
(c86) => `${c86.name.padEnd(nameWidth)} ${c86.scan.padEnd(4)} ${c86.role.padEnd(roleWidth)} ${c86.path.padEnd(pathWidth)} ${c86.status}`
|
|
49751
50143
|
);
|
|
49752
50144
|
return { header, rows };
|
|
49753
50145
|
}
|
|
@@ -50010,6 +50402,205 @@ async function runDelete(applicationId, options) {
|
|
|
50010
50402
|
}
|
|
50011
50403
|
console.log(colorSuccess(`Deleted application ${applicationId}`));
|
|
50012
50404
|
}
|
|
50405
|
+
function renderLinkDetail(link) {
|
|
50406
|
+
const pad = 11;
|
|
50407
|
+
return [
|
|
50408
|
+
`${"Link ID:".padEnd(pad)} ${link.applicationRepositoryId ?? "\u2014"}`,
|
|
50409
|
+
`${"Repository:".padEnd(pad)} ${sanitizeDisplay(link.repositoryName)} (${link.repositoryId})`,
|
|
50410
|
+
`${"URL:".padEnd(pad)} ${sanitizeDisplay(link.repositoryUrl)}`,
|
|
50411
|
+
`${"Scan:".padEnd(pad)} ${link.scanEnabled ? "yes" : "no"}`,
|
|
50412
|
+
`${"Role:".padEnd(pad)} ${sanitizeDisplay(formatLinkRole(link.role, link.roleLabel, link.roles))}`,
|
|
50413
|
+
`${"Path:".padEnd(pad)} ${link.repositoryPath ? sanitizeDisplay(link.repositoryPath) : "\u2014"}`,
|
|
50414
|
+
`${"Status:".padEnd(pad)} ${formatStatus(link.repositoryStatus)}`
|
|
50415
|
+
].join("\n");
|
|
50416
|
+
}
|
|
50417
|
+
function outputLink(link, output) {
|
|
50418
|
+
if (output === "json") {
|
|
50419
|
+
printJson(link);
|
|
50420
|
+
return;
|
|
50421
|
+
}
|
|
50422
|
+
if (output === "tsv") {
|
|
50423
|
+
printApplicationRepositoriesTsv([link]);
|
|
50424
|
+
return;
|
|
50425
|
+
}
|
|
50426
|
+
console.log(renderLinkDetail(link));
|
|
50427
|
+
}
|
|
50428
|
+
function exitInvalidApplicationId(applicationId) {
|
|
50429
|
+
console.error(colorError(`Invalid application id '${applicationId}'. Expected a UUID.`));
|
|
50430
|
+
process.exit(1);
|
|
50431
|
+
}
|
|
50432
|
+
async function resolveExistingLink(organizationId, applicationId, repoInput) {
|
|
50433
|
+
const result = await authenticatedRequest(
|
|
50434
|
+
(client) => client.application.listApplicationRepositories({ params: { organizationId, applicationId } })
|
|
50435
|
+
);
|
|
50436
|
+
if (result.status !== SUCCESS_STATUS) {
|
|
50437
|
+
failReadOp("list application repositories", result.status, result.body, applicationId);
|
|
50438
|
+
}
|
|
50439
|
+
const link = findLinkForRepo(result.body, repoInput);
|
|
50440
|
+
if (!link) {
|
|
50441
|
+
console.error(
|
|
50442
|
+
colorError(
|
|
50443
|
+
`Repository ${repoInput} is not linked to application ${applicationId}. Run \`tracecli application repos ${applicationId}\` to see its links.`
|
|
50444
|
+
)
|
|
50445
|
+
);
|
|
50446
|
+
process.exit(1);
|
|
50447
|
+
}
|
|
50448
|
+
if (link.applicationRepositoryId === null) {
|
|
50449
|
+
console.error(
|
|
50450
|
+
colorError(
|
|
50451
|
+
`Repository ${repoInput} is linked without a link id, so it can't be changed from the CLI. Edit it in the dashboard.`
|
|
50452
|
+
)
|
|
50453
|
+
);
|
|
50454
|
+
process.exit(1);
|
|
50455
|
+
}
|
|
50456
|
+
return { ...link, applicationRepositoryId: link.applicationRepositoryId };
|
|
50457
|
+
}
|
|
50458
|
+
async function runLink(applicationId, options) {
|
|
50459
|
+
const output = parseOutput(options.output);
|
|
50460
|
+
if (!isUuid(applicationId)) {
|
|
50461
|
+
exitInvalidApplicationId(applicationId);
|
|
50462
|
+
}
|
|
50463
|
+
const parsedRoles = parseRepositoryRoles(options.role ?? []);
|
|
50464
|
+
if ("error" in parsedRoles) {
|
|
50465
|
+
console.error(colorError(parsedRoles.error));
|
|
50466
|
+
process.exit(1);
|
|
50467
|
+
}
|
|
50468
|
+
const roles = options.role !== void 0 ? parsedRoles.roles : void 0;
|
|
50469
|
+
const labelError = validateRoleLabel(roles ?? [], options.roleLabel);
|
|
50470
|
+
if (labelError) {
|
|
50471
|
+
console.error(colorError(labelError));
|
|
50472
|
+
process.exit(1);
|
|
50473
|
+
}
|
|
50474
|
+
const organizationId = await resolveOrganizationId();
|
|
50475
|
+
const repositoryId = await resolveRepositoryId(organizationId, options.repo);
|
|
50476
|
+
const body = buildLinkRepositoryBody({
|
|
50477
|
+
repositoryId,
|
|
50478
|
+
roles,
|
|
50479
|
+
roleLabel: options.roleLabel,
|
|
50480
|
+
repositoryPath: options.repoPath,
|
|
50481
|
+
// Commander defaults a lone `--no-scan` to true; only an explicit opt-out
|
|
50482
|
+
// goes on the wire so the API's own default applies otherwise.
|
|
50483
|
+
scanEnabled: options.scan === false ? false : void 0
|
|
50484
|
+
});
|
|
50485
|
+
const result = await authenticatedRequest(
|
|
50486
|
+
(client) => client.application.createApplicationRepository({
|
|
50487
|
+
params: { organizationId, applicationId },
|
|
50488
|
+
body
|
|
50489
|
+
})
|
|
50490
|
+
);
|
|
50491
|
+
if (result.status !== CREATED_STATUS) {
|
|
50492
|
+
failLinkOp("link", result.status, result.body);
|
|
50493
|
+
}
|
|
50494
|
+
if (output === "table") {
|
|
50495
|
+
console.log(
|
|
50496
|
+
colorSuccess(
|
|
50497
|
+
`Linked ${sanitizeDisplay(result.body.repositoryName)} to application ${applicationId}`
|
|
50498
|
+
)
|
|
50499
|
+
);
|
|
50500
|
+
}
|
|
50501
|
+
outputLink(result.body, output);
|
|
50502
|
+
}
|
|
50503
|
+
var UPDATE_LINK_FLAGS = "--role, --clear-roles, --role-label, --clear-role-label, --repo-path, --clear-repo-path, --scan, --no-scan";
|
|
50504
|
+
async function runUpdateLink(applicationId, options) {
|
|
50505
|
+
const output = parseOutput(options.output);
|
|
50506
|
+
if (!isUuid(applicationId)) {
|
|
50507
|
+
exitInvalidApplicationId(applicationId);
|
|
50508
|
+
}
|
|
50509
|
+
if (options.role !== void 0 && options.clearRoles) {
|
|
50510
|
+
console.error(colorError("Pass only one of --role / --clear-roles."));
|
|
50511
|
+
process.exit(1);
|
|
50512
|
+
}
|
|
50513
|
+
const parsedRoles = parseRepositoryRoles(options.role ?? []);
|
|
50514
|
+
if ("error" in parsedRoles) {
|
|
50515
|
+
console.error(colorError(parsedRoles.error));
|
|
50516
|
+
process.exit(1);
|
|
50517
|
+
}
|
|
50518
|
+
const roles = options.clearRoles ? [] : options.role !== void 0 ? parsedRoles.roles : void 0;
|
|
50519
|
+
const roleLabel = resolveClearableOption(options.roleLabel, options.clearRoleLabel, "role-label");
|
|
50520
|
+
if ("error" in roleLabel) {
|
|
50521
|
+
console.error(colorError(roleLabel.error));
|
|
50522
|
+
process.exit(1);
|
|
50523
|
+
}
|
|
50524
|
+
const repositoryPath = resolveClearableOption(
|
|
50525
|
+
options.repoPath,
|
|
50526
|
+
options.clearRepoPath,
|
|
50527
|
+
"repo-path"
|
|
50528
|
+
);
|
|
50529
|
+
if ("error" in repositoryPath) {
|
|
50530
|
+
console.error(colorError(repositoryPath.error));
|
|
50531
|
+
process.exit(1);
|
|
50532
|
+
}
|
|
50533
|
+
const labelError = validateRoleLabel(roles, roleLabel.value);
|
|
50534
|
+
if (labelError) {
|
|
50535
|
+
console.error(colorError(labelError));
|
|
50536
|
+
process.exit(1);
|
|
50537
|
+
}
|
|
50538
|
+
const body = buildUpdateLinkBody({
|
|
50539
|
+
roles,
|
|
50540
|
+
roleLabel: roleLabel.value,
|
|
50541
|
+
repositoryPath: repositoryPath.value,
|
|
50542
|
+
scanEnabled: options.scan
|
|
50543
|
+
});
|
|
50544
|
+
if (isEmptyLinkUpdate(body)) {
|
|
50545
|
+
console.error(colorError(`Nothing to update. Pass at least one of ${UPDATE_LINK_FLAGS}.`));
|
|
50546
|
+
process.exit(1);
|
|
50547
|
+
}
|
|
50548
|
+
const organizationId = await resolveOrganizationId();
|
|
50549
|
+
const existing = await resolveExistingLink(organizationId, applicationId, options.repo);
|
|
50550
|
+
const result = await authenticatedRequest(
|
|
50551
|
+
(client) => client.application.updateApplicationRepository({
|
|
50552
|
+
params: {
|
|
50553
|
+
organizationId,
|
|
50554
|
+
applicationId,
|
|
50555
|
+
applicationRepositoryId: existing.applicationRepositoryId
|
|
50556
|
+
},
|
|
50557
|
+
body
|
|
50558
|
+
})
|
|
50559
|
+
);
|
|
50560
|
+
if (result.status !== SUCCESS_STATUS) {
|
|
50561
|
+
failLinkOp("update link", result.status, result.body);
|
|
50562
|
+
}
|
|
50563
|
+
if (output === "table") {
|
|
50564
|
+
console.log(
|
|
50565
|
+
colorSuccess(
|
|
50566
|
+
`Updated link for ${sanitizeDisplay(result.body.repositoryName)} on application ${applicationId}`
|
|
50567
|
+
)
|
|
50568
|
+
);
|
|
50569
|
+
}
|
|
50570
|
+
outputLink(result.body, output);
|
|
50571
|
+
}
|
|
50572
|
+
async function runUnlink(applicationId, options) {
|
|
50573
|
+
if (!isUuid(applicationId)) {
|
|
50574
|
+
exitInvalidApplicationId(applicationId);
|
|
50575
|
+
}
|
|
50576
|
+
const organizationId = await resolveOrganizationId();
|
|
50577
|
+
const existing = await resolveExistingLink(organizationId, applicationId, options.repo);
|
|
50578
|
+
const confirmed = await confirmAction(
|
|
50579
|
+
`Unlink ${sanitizeDisplay(existing.repositoryName)} from application ${applicationId}?`,
|
|
50580
|
+
{ skip: options.yes === true, verb: "unlink" }
|
|
50581
|
+
);
|
|
50582
|
+
if (!confirmed) {
|
|
50583
|
+
console.log("Aborted.");
|
|
50584
|
+
return;
|
|
50585
|
+
}
|
|
50586
|
+
const result = await authenticatedRequest(
|
|
50587
|
+
(client) => client.application.deleteApplicationRepository({
|
|
50588
|
+
params: {
|
|
50589
|
+
organizationId,
|
|
50590
|
+
applicationId,
|
|
50591
|
+
applicationRepositoryId: existing.applicationRepositoryId
|
|
50592
|
+
}
|
|
50593
|
+
})
|
|
50594
|
+
);
|
|
50595
|
+
if (result.status !== NO_CONTENT_STATUS) {
|
|
50596
|
+
failLinkOp("unlink", result.status, result.body);
|
|
50597
|
+
}
|
|
50598
|
+
console.log(
|
|
50599
|
+
colorSuccess(
|
|
50600
|
+
`Unlinked ${sanitizeDisplay(existing.repositoryName)} from application ${applicationId}`
|
|
50601
|
+
)
|
|
50602
|
+
);
|
|
50603
|
+
}
|
|
50013
50604
|
function createCreateCommand() {
|
|
50014
50605
|
return new Command("create").description("Create a new application").argument("<name>", "Application name").option("--type <type>", "Application type: web, cli, mobile, desktop, api-service", "web").option("--url <url>", "Application URL (required for web/api-service)").option("--repo <id-or-url>", "Link a repository at creation (UUID, URL, or owner/repo)").option("--repo-path <path>", "Path within the linked repository").option("--help-center-url <url>", "Help center URL").option("--docs-url <url>", "Documentation URL").option("-o, --output <format>", "Output format: table, json, tsv (default: table)", "table").addHelpText(
|
|
50015
50606
|
"after",
|
|
@@ -50061,6 +50652,59 @@ Examples:
|
|
|
50061
50652
|
await runUpdate(applicationId, options);
|
|
50062
50653
|
});
|
|
50063
50654
|
}
|
|
50655
|
+
var ROLE_FLAG_HELP = `Repository role (repeatable): ${REPOSITORY_ROLE_INPUTS.join(", ")}`;
|
|
50656
|
+
function createLinkCommand() {
|
|
50657
|
+
return new Command("link").description("Link a repository to an application").argument("<applicationId>", "Application UUID").requiredOption("--repo <id-or-url>", "Repository to link (UUID, URL, or owner/repo)").option("--role <role>", ROLE_FLAG_HELP, collectRepeatable).option("--role-label <label>", 'Custom label for the "other" role').option("--repo-path <path>", "Path within the repository").option("--no-scan", "Link without including the repository in scans").option("-o, --output <format>", "Output format: table, json, tsv (default: table)", "table").addHelpText(
|
|
50658
|
+
"after",
|
|
50659
|
+
`
|
|
50660
|
+
A link is scan-enabled unless --no-scan is passed. Scan-disabled links are
|
|
50661
|
+
skipped by scans and do not satisfy the repository precondition for starting a
|
|
50662
|
+
pentest.
|
|
50663
|
+
|
|
50664
|
+
Examples:
|
|
50665
|
+
tracecli application link <appId> --repo acme/store
|
|
50666
|
+
tracecli application link <appId> --repo acme/store --role frontend --role backend-api
|
|
50667
|
+
tracecli application link <appId> --repo acme/tools --role other --role-label "Design system"
|
|
50668
|
+
tracecli application link <appId> --repo acme/monorepo --repo-path apps/web --no-scan`
|
|
50669
|
+
).action(async (applicationId, options) => {
|
|
50670
|
+
await runLink(applicationId, options);
|
|
50671
|
+
});
|
|
50672
|
+
}
|
|
50673
|
+
function createUpdateLinkCommand() {
|
|
50674
|
+
return new Command("update-link").description("Change an existing repository link's roles, label, path, or scan state").argument("<applicationId>", "Application UUID").requiredOption(
|
|
50675
|
+
"--repo <id-or-url>",
|
|
50676
|
+
"Linked repository to change (repository UUID, link UUID, URL, or owner/repo)"
|
|
50677
|
+
).option("--role <role>", `${ROLE_FLAG_HELP}; replaces the current roles`, collectRepeatable).option("--clear-roles", "Remove every role from the link").option("--role-label <label>", 'Custom label for the "other" role').option("--clear-role-label", "Remove the custom role label").option("--repo-path <path>", "Path within the repository").option("--clear-repo-path", "Remove the repository path").option("--scan", "Include the repository in scans").option("--no-scan", "Exclude the repository from scans (the link stays)").option("-o, --output <format>", "Output format: table, json, tsv (default: table)", "table").addHelpText(
|
|
50678
|
+
"after",
|
|
50679
|
+
`
|
|
50680
|
+
The update is partial: only the flags you pass change. --role replaces the
|
|
50681
|
+
whole role set, so pass every role the link should keep.
|
|
50682
|
+
|
|
50683
|
+
Examples:
|
|
50684
|
+
tracecli application update-link <appId> --repo acme/store --role frontend --role backend-api
|
|
50685
|
+
tracecli application update-link <appId> --repo acme/store --repo-path apps/web
|
|
50686
|
+
tracecli application update-link <appId> --repo acme/store --no-scan
|
|
50687
|
+
tracecli application update-link <appId> --repo <repositoryId> --scan -o json`
|
|
50688
|
+
).action(async (applicationId, options) => {
|
|
50689
|
+
await runUpdateLink(applicationId, options);
|
|
50690
|
+
});
|
|
50691
|
+
}
|
|
50692
|
+
function createUnlinkCommand() {
|
|
50693
|
+
return new Command("unlink").description("Remove a repository link from an application").argument("<applicationId>", "Application UUID").requiredOption(
|
|
50694
|
+
"--repo <id-or-url>",
|
|
50695
|
+
"Linked repository to remove (repository UUID, link UUID, URL, or owner/repo)"
|
|
50696
|
+
).option("-y, --yes", "Skip the confirmation prompt (required in non-interactive shells)").addHelpText(
|
|
50697
|
+
"after",
|
|
50698
|
+
`
|
|
50699
|
+
Only the link is removed; the repository stays connected to the organization.
|
|
50700
|
+
|
|
50701
|
+
Examples:
|
|
50702
|
+
tracecli application unlink <appId> --repo acme/store
|
|
50703
|
+
tracecli application unlink <appId> --repo <repositoryId> --yes`
|
|
50704
|
+
).action(async (applicationId, options) => {
|
|
50705
|
+
await runUnlink(applicationId, options);
|
|
50706
|
+
});
|
|
50707
|
+
}
|
|
50064
50708
|
function createDeleteCommand() {
|
|
50065
50709
|
return new Command("delete").description("Delete an application").argument("<applicationId>", "Application UUID").option("-y, --yes", "Skip the confirmation prompt (required in non-interactive shells)").action(async (applicationId, options) => {
|
|
50066
50710
|
await runDelete(applicationId, options);
|
|
@@ -50072,6 +50716,9 @@ function createApplicationCommand() {
|
|
|
50072
50716
|
application.addCommand(createListCommand2());
|
|
50073
50717
|
application.addCommand(createGetCommand());
|
|
50074
50718
|
application.addCommand(createReposCommand());
|
|
50719
|
+
application.addCommand(createLinkCommand());
|
|
50720
|
+
application.addCommand(createUpdateLinkCommand());
|
|
50721
|
+
application.addCommand(createUnlinkCommand());
|
|
50075
50722
|
application.addCommand(createUpdateCommand());
|
|
50076
50723
|
application.addCommand(createDeleteCommand());
|
|
50077
50724
|
return application;
|
|
@@ -50532,8 +51179,8 @@ function wrapTextWithPrefix(e, r2, o2, t2 = o2, s = o2, n3) {
|
|
|
50532
51179
|
hard: true,
|
|
50533
51180
|
trim: false
|
|
50534
51181
|
}).split(`
|
|
50535
|
-
`).map((
|
|
50536
|
-
const d = n3 ? n3(
|
|
51182
|
+
`).map((c86, i2, m2) => {
|
|
51183
|
+
const d = n3 ? n3(c86, i2) : c86;
|
|
50537
51184
|
return i2 === 0 ? `${t2}${d}` : i2 === m2.length - 1 ? `${s}${d}` : `${o2}${d}`;
|
|
50538
51185
|
}).join(`
|
|
50539
51186
|
`);
|
|
@@ -51031,14 +51678,14 @@ var limitOptions = ({
|
|
|
51031
51678
|
Math.min(l2 - a2 + 3, e.length - a2),
|
|
51032
51679
|
0
|
|
51033
51680
|
));
|
|
51034
|
-
let d = a2 < e.length && f > 0,
|
|
51681
|
+
let d = a2 < e.length && f > 0, c86 = a2 < e.length && f + a2 < e.length;
|
|
51035
51682
|
const W = Math.min(
|
|
51036
51683
|
f + a2,
|
|
51037
51684
|
e.length
|
|
51038
51685
|
), s = [];
|
|
51039
51686
|
let g = 0;
|
|
51040
|
-
d && g++,
|
|
51041
|
-
const T = f + (d ? 1 : 0), y = W - (
|
|
51687
|
+
d && g++, c86 && g++;
|
|
51688
|
+
const T = f + (d ? 1 : 0), y = W - (c86 ? 1 : 0);
|
|
51042
51689
|
for (let t2 = T; t2 < y; t2++) {
|
|
51043
51690
|
const n3 = e[t2], o2 = n3 ? w(n3, t2 === l2) : "", h2 = wrapAnsi(o2, i2, {
|
|
51044
51691
|
hard: true,
|
|
@@ -51059,14 +51706,14 @@ var limitOptions = ({
|
|
|
51059
51706
|
u4,
|
|
51060
51707
|
true
|
|
51061
51708
|
);
|
|
51062
|
-
d ? ({ lineCount: o2, removals: t2 } = L(), o2 > u4 && (
|
|
51709
|
+
d ? ({ lineCount: o2, removals: t2 } = L(), o2 > u4 && (c86 || (u4 -= 1), { lineCount: o2, removals: n3 } = E())) : (c86 || (u4 -= 1), { lineCount: o2, removals: n3 } = E(), o2 > u4 && (u4 -= 1, { lineCount: o2, removals: t2 } = L())), t2 > 0 && (d = true, s.splice(0, t2)), n3 > 0 && (c86 = true, s.splice(s.length - n3, n3));
|
|
51063
51710
|
}
|
|
51064
51711
|
const x = [];
|
|
51065
51712
|
d && x.push(M);
|
|
51066
51713
|
for (const t2 of s)
|
|
51067
51714
|
for (const n3 of t2)
|
|
51068
51715
|
x.push(n3);
|
|
51069
|
-
return
|
|
51716
|
+
return c86 && x.push(M), x;
|
|
51070
51717
|
};
|
|
51071
51718
|
var confirm = (i2) => {
|
|
51072
51719
|
const a2 = i2.active ?? "Yes", s = i2.inactive ?? "No";
|
|
@@ -51085,15 +51732,15 @@ var confirm = (i2) => {
|
|
|
51085
51732
|
u4
|
|
51086
51733
|
), o2 = `${e ? `${styleText2("gray", S_BAR)}
|
|
51087
51734
|
` : ""}${f}
|
|
51088
|
-
`,
|
|
51735
|
+
`, c86 = this.value ? a2 : s;
|
|
51089
51736
|
switch (this.state) {
|
|
51090
51737
|
case "submit": {
|
|
51091
51738
|
const r2 = e ? `${styleText2("gray", S_BAR)} ` : "";
|
|
51092
|
-
return `${o2}${r2}${styleText2("dim",
|
|
51739
|
+
return `${o2}${r2}${styleText2("dim", c86)}`;
|
|
51093
51740
|
}
|
|
51094
51741
|
case "cancel": {
|
|
51095
51742
|
const r2 = e ? `${styleText2("gray", S_BAR)} ` : "";
|
|
51096
|
-
return `${o2}${r2}${styleText2(["strikethrough", "dim"],
|
|
51743
|
+
return `${o2}${r2}${styleText2(["strikethrough", "dim"], c86)}${e ? `
|
|
51097
51744
|
${styleText2("gray", S_BAR)}` : ""}`;
|
|
51098
51745
|
}
|
|
51099
51746
|
default: {
|
|
@@ -51241,13 +51888,13 @@ var multiline = (e) => new h({
|
|
|
51241
51888
|
`, m2 = e.placeholder && e.placeholder.length > 0 ? (
|
|
51242
51889
|
// biome-ignore lint/style/noNonNullAssertion: guarded by placeholder.length > 0
|
|
51243
51890
|
styleText2("inverse", e.placeholder[0]) + styleText2("dim", e.placeholder.slice(1))
|
|
51244
|
-
) : styleText2(["inverse", "hidden"], "_"), a2 = this.userInput ? this.userInputWithCursor : m2, l2 = this.value ?? "",
|
|
51891
|
+
) : styleText2(["inverse", "hidden"], "_"), a2 = this.userInput ? this.userInputWithCursor : m2, l2 = this.value ?? "", c86 = e.showSubmit ? `
|
|
51245
51892
|
${styleText2(this.focused === "submit" ? "cyan" : "dim", "[ submit ]")}` : "";
|
|
51246
51893
|
switch (this.state) {
|
|
51247
51894
|
case "error": {
|
|
51248
51895
|
const n3 = `${styleText2("yellow", S_BAR)} `, r2 = i2 ? wrapTextWithPrefix(e.output, a2, n3, void 0) : a2, u4 = styleText2("yellow", S_BAR_END);
|
|
51249
51896
|
return `${o2}${r2}
|
|
51250
|
-
${u4} ${styleText2("yellow", this.error)}${
|
|
51897
|
+
${u4} ${styleText2("yellow", this.error)}${c86}
|
|
51251
51898
|
`;
|
|
51252
51899
|
}
|
|
51253
51900
|
case "submit": {
|
|
@@ -51275,7 +51922,7 @@ ${u4} ${styleText2("yellow", this.error)}${c84}
|
|
|
51275
51922
|
default: {
|
|
51276
51923
|
const n3 = i2 ? `${styleText2("cyan", S_BAR)} ` : "", r2 = i2 ? styleText2("cyan", S_BAR_END) : "", u4 = i2 ? wrapTextWithPrefix(e.output, a2, n3) : a2;
|
|
51277
51924
|
return `${o2}${u4}
|
|
51278
|
-
${r2}${
|
|
51925
|
+
${r2}${c86}
|
|
51279
51926
|
`;
|
|
51280
51927
|
}
|
|
51281
51928
|
}
|
|
@@ -51290,7 +51937,7 @@ var password = (r2) => new u$1({
|
|
|
51290
51937
|
render() {
|
|
51291
51938
|
const e = r2.withGuide ?? settings.withGuide, o2 = `${e ? `${styleText2("gray", S_BAR)}
|
|
51292
51939
|
` : ""}${symbol2(this.state)} ${r2.message}
|
|
51293
|
-
`,
|
|
51940
|
+
`, c86 = this.userInputWithCursor, i2 = this.masked;
|
|
51294
51941
|
switch (this.state) {
|
|
51295
51942
|
case "error": {
|
|
51296
51943
|
const s = e ? `${styleText2("yellow", S_BAR)} ` : "", n3 = e ? `${styleText2("yellow", S_BAR_END)} ` : "", l2 = i2 ?? "";
|
|
@@ -51310,7 +51957,7 @@ ${styleText2("gray", S_BAR)}` : ""}`;
|
|
|
51310
51957
|
}
|
|
51311
51958
|
default: {
|
|
51312
51959
|
const s = e ? `${styleText2("cyan", S_BAR)} ` : "", n3 = e ? styleText2("cyan", S_BAR_END) : "";
|
|
51313
|
-
return `${o2}${s}${
|
|
51960
|
+
return `${o2}${s}${c86}
|
|
51314
51961
|
${n3}
|
|
51315
51962
|
`;
|
|
51316
51963
|
}
|
|
@@ -51326,7 +51973,7 @@ var SELECT_INSTRUCTIONS = [
|
|
|
51326
51973
|
`${styleText2("dim", "\u2191/\u2193")} to navigate`,
|
|
51327
51974
|
`${styleText2("dim", "Enter:")} confirm`
|
|
51328
51975
|
];
|
|
51329
|
-
var
|
|
51976
|
+
var c85 = (t2, o2) => t2.includes(`
|
|
51330
51977
|
`) ? t2.split(`
|
|
51331
51978
|
`).map((d) => o2(d)).join(`
|
|
51332
51979
|
`) : o2(t2);
|
|
@@ -51337,15 +51984,15 @@ var select = (t2) => {
|
|
|
51337
51984
|
const s = n3.label ?? String(n3.value);
|
|
51338
51985
|
switch (m2) {
|
|
51339
51986
|
case "disabled":
|
|
51340
|
-
return `${styleText2("gray", S_RADIO_INACTIVE)} ${
|
|
51987
|
+
return `${styleText2("gray", S_RADIO_INACTIVE)} ${c85(s, (i2) => styleText2("gray", i2))}${n3.hint ? ` ${styleText2("dim", `(${n3.hint ?? "disabled"})`)}` : ""}`;
|
|
51341
51988
|
case "selected":
|
|
51342
|
-
return `${
|
|
51989
|
+
return `${c85(s, (i2) => styleText2("dim", i2))}`;
|
|
51343
51990
|
case "active":
|
|
51344
51991
|
return `${styleText2("green", S_RADIO_ACTIVE)} ${s}${n3.hint ? ` ${styleText2("dim", `(${n3.hint})`)}` : ""}`;
|
|
51345
51992
|
case "cancelled":
|
|
51346
|
-
return `${
|
|
51993
|
+
return `${c85(s, (i2) => styleText2(["strikethrough", "dim"], i2))}`;
|
|
51347
51994
|
default:
|
|
51348
|
-
return `${styleText2("dim", S_RADIO_INACTIVE)} ${
|
|
51995
|
+
return `${styleText2("dim", S_RADIO_INACTIVE)} ${c85(s, (i2) => styleText2("dim", i2))}`;
|
|
51349
51996
|
}
|
|
51350
51997
|
}, d = t2.showInstructions ?? true;
|
|
51351
51998
|
return new n$1({
|
|
@@ -51406,6 +52053,18 @@ var i = `${styleText2("gray", S_BAR)} `;
|
|
|
51406
52053
|
|
|
51407
52054
|
// src/org/invite.ts
|
|
51408
52055
|
var MEMBER_ROLE_SLUGS = MemberRoleSlugSchema.options;
|
|
52056
|
+
var ROLE_NAMES = {
|
|
52057
|
+
admin: "admin",
|
|
52058
|
+
analyst: "manager",
|
|
52059
|
+
developer: "developer"
|
|
52060
|
+
};
|
|
52061
|
+
var ROLE_BY_NAME = {
|
|
52062
|
+
admin: "admin",
|
|
52063
|
+
manager: "analyst",
|
|
52064
|
+
analyst: "analyst",
|
|
52065
|
+
developer: "developer"
|
|
52066
|
+
};
|
|
52067
|
+
var ROLE_CHOICES = MEMBER_ROLE_SLUGS.map((slug) => ROLE_NAMES[slug]).join(", ");
|
|
51409
52068
|
var DEFAULT_INVITE_ROLE = CreateMemberInvitationRequestSchema.shape.roleSlug.parse(void 0);
|
|
51410
52069
|
var InviteEmailSchema = CreateMemberInvitationRequestSchema.shape.email;
|
|
51411
52070
|
function planInvite(emailArg, options) {
|
|
@@ -51416,14 +52075,13 @@ function planInvite(emailArg, options) {
|
|
|
51416
52075
|
if (!InviteEmailSchema.safeParse(email3).success) {
|
|
51417
52076
|
return { error: `'${sanitizeDisplay(email3)}' is not a valid email address.` };
|
|
51418
52077
|
}
|
|
51419
|
-
const
|
|
51420
|
-
|
|
51421
|
-
if (!parsedRole.success) {
|
|
52078
|
+
const roleSlug = ROLE_BY_NAME[options.role.trim().toLowerCase()];
|
|
52079
|
+
if (roleSlug === void 0) {
|
|
51422
52080
|
return {
|
|
51423
|
-
error: `Invalid --role '${sanitizeDisplay(options.role)}'. Use one of: ${
|
|
52081
|
+
error: `Invalid --role '${sanitizeDisplay(options.role)}'. Use one of: ${ROLE_CHOICES}.`
|
|
51424
52082
|
};
|
|
51425
52083
|
}
|
|
51426
|
-
return { plan: { email: email3, roleSlug
|
|
52084
|
+
return { plan: { email: email3, roleSlug } };
|
|
51427
52085
|
}
|
|
51428
52086
|
function failInvite(status, body) {
|
|
51429
52087
|
const { message } = readErrorFields(body);
|
|
@@ -51431,7 +52089,7 @@ function failInvite(status, body) {
|
|
|
51431
52089
|
exitAuthFailed();
|
|
51432
52090
|
}
|
|
51433
52091
|
if (status === 403) {
|
|
51434
|
-
const hint = "Inviting members requires an organization admin
|
|
52092
|
+
const hint = "Inviting members requires an organization admin signed in with `tracecli auth login` (API keys are rejected).";
|
|
51435
52093
|
console.error(
|
|
51436
52094
|
colorError(message === void 0 || message === "Insufficient permissions" ? hint : message)
|
|
51437
52095
|
);
|
|
@@ -51476,7 +52134,7 @@ function outputInvitation(invitation, output) {
|
|
|
51476
52134
|
}
|
|
51477
52135
|
console.log(
|
|
51478
52136
|
colorSuccess(
|
|
51479
|
-
`Invitation sent to ${sanitizeDisplay(invitation.email)} as ${
|
|
52137
|
+
`Invitation sent to ${sanitizeDisplay(invitation.email)} as ${ROLE_NAMES[invitation.roleSlug]}`
|
|
51480
52138
|
)
|
|
51481
52139
|
);
|
|
51482
52140
|
console.log(` Invitation ID: ${sanitizeDisplay(invitation.invitationId)}`);
|
|
@@ -51502,20 +52160,16 @@ async function runInvite(emailArg, options) {
|
|
|
51502
52160
|
outputInvitation(result.body, output);
|
|
51503
52161
|
}
|
|
51504
52162
|
function createOrgInviteCommand() {
|
|
51505
|
-
return new Command("invite").description("Invite someone to the active organization by email").argument("<email>", "Email address to invite").option(
|
|
51506
|
-
"-r, --role <role>",
|
|
51507
|
-
`Role to grant: ${MEMBER_ROLE_SLUGS.join(", ")}`,
|
|
51508
|
-
DEFAULT_INVITE_ROLE
|
|
51509
|
-
).option("-o, --output <format>", "Output format: table, json, tsv (default: table)", "table").addHelpText(
|
|
52163
|
+
return new Command("invite").description("Invite someone to the active organization by email").argument("<email>", "Email address to invite").option("-r, --role <role>", `Role to grant: ${ROLE_CHOICES}`, DEFAULT_INVITE_ROLE).option("-o, --output <format>", "Output format: table, json, tsv (default: table)", "table").addHelpText(
|
|
51510
52164
|
"after",
|
|
51511
52165
|
`
|
|
51512
52166
|
Sends the same invitation email as the dashboard's Settings > Members page.
|
|
51513
|
-
Requires an organization admin
|
|
51514
|
-
API keys are rejected.
|
|
52167
|
+
Requires an organization admin signed in with \`tracecli auth login\`;
|
|
52168
|
+
API keys are rejected.
|
|
51515
52169
|
|
|
51516
52170
|
Examples:
|
|
51517
52171
|
tracecli org invite dev@acme.com
|
|
51518
|
-
tracecli org invite sec@acme.com --role
|
|
52172
|
+
tracecli org invite sec@acme.com --role manager
|
|
51519
52173
|
tracecli org invite cto@acme.com --role admin --output json`
|
|
51520
52174
|
).action(async (email3, options) => {
|
|
51521
52175
|
await runInvite(email3, options);
|
|
@@ -52842,7 +53496,7 @@ function extractCommandTree(cmd) {
|
|
|
52842
53496
|
description: o2.description,
|
|
52843
53497
|
takesValue: o2.required || o2.optional
|
|
52844
53498
|
}));
|
|
52845
|
-
const subcommands = cmd.commands.filter((
|
|
53499
|
+
const subcommands = cmd.commands.filter((c86) => !c86._hidden).map((c86) => extractCommandTree(c86));
|
|
52846
53500
|
return {
|
|
52847
53501
|
name: cmd.name(),
|
|
52848
53502
|
description: cmd.description(),
|
|
@@ -52908,7 +53562,7 @@ function generateBashCompletion(tree, binName) {
|
|
|
52908
53562
|
}
|
|
52909
53563
|
function collectBashCases(tree, prefix) {
|
|
52910
53564
|
const cases = /* @__PURE__ */ new Map();
|
|
52911
|
-
const subcommandNames = tree.subcommands.map((
|
|
53565
|
+
const subcommandNames = tree.subcommands.map((c86) => c86.name);
|
|
52912
53566
|
const optionNames = tree.options.flatMap((o2) => o2.short ? [o2.long, o2.short] : [o2.long]);
|
|
52913
53567
|
const extraOptions = prefix === "" ? ["--help", "--version"] : ["--help"];
|
|
52914
53568
|
const allOptions = [.../* @__PURE__ */ new Set([...optionNames, ...extraOptions])];
|
|
@@ -53214,17 +53868,17 @@ function validateInboxLabel(label) {
|
|
|
53214
53868
|
function buildCreateInboxBody(label) {
|
|
53215
53869
|
return { label };
|
|
53216
53870
|
}
|
|
53871
|
+
function forbiddenMessage(verb, needsEntitlement) {
|
|
53872
|
+
const where = needsEntitlement ? " on a pentest-enabled organization" : "";
|
|
53873
|
+
return `Only an organization admin or Manager (or Trace staff)${where} can ${verb}.`;
|
|
53874
|
+
}
|
|
53217
53875
|
function failWriteOp2(action, status, body, notFoundLabel) {
|
|
53218
53876
|
const { message, errorCode } = readErrorFields(body);
|
|
53219
53877
|
if (status === UNAUTHORIZED_STATUS2) {
|
|
53220
53878
|
exitAuthFailed();
|
|
53221
53879
|
}
|
|
53222
53880
|
if (status === 403) {
|
|
53223
|
-
console.error(
|
|
53224
|
-
colorError(
|
|
53225
|
-
`Only an organization admin (or Trace staff) on a pentest-enabled organization can ${action} inboxes.`
|
|
53226
|
-
)
|
|
53227
|
-
);
|
|
53881
|
+
console.error(colorError(forbiddenMessage(`${action} inboxes`, true)));
|
|
53228
53882
|
process.exit(1);
|
|
53229
53883
|
}
|
|
53230
53884
|
if (status === 404) {
|
|
@@ -53276,7 +53930,7 @@ function failReadOp2(action, status, body, notFoundLabel) {
|
|
|
53276
53930
|
exitAuthFailed();
|
|
53277
53931
|
}
|
|
53278
53932
|
if (status === 403) {
|
|
53279
|
-
console.error(colorError(
|
|
53933
|
+
console.error(colorError(forbiddenMessage(action, action !== "list inboxes")));
|
|
53280
53934
|
process.exit(1);
|
|
53281
53935
|
}
|
|
53282
53936
|
if (status === 404) {
|
|
@@ -53323,9 +53977,9 @@ function buildInboxesTable(inboxes) {
|
|
|
53323
53977
|
address: sanitizeDisplay(inbox.address),
|
|
53324
53978
|
label: sanitizeDisplay(inbox.label)
|
|
53325
53979
|
}));
|
|
53326
|
-
const addressWidth = Math.max(7, ...cells.map((
|
|
53980
|
+
const addressWidth = Math.max(7, ...cells.map((c86) => c86.address.length));
|
|
53327
53981
|
const header = `${"ADDRESS".padEnd(addressWidth)} LABEL`;
|
|
53328
|
-
const rows = cells.map((
|
|
53982
|
+
const rows = cells.map((c86) => `${c86.address.padEnd(addressWidth)} ${c86.label}`);
|
|
53329
53983
|
return { header, rows };
|
|
53330
53984
|
}
|
|
53331
53985
|
function formatInboxQuota(quota) {
|
|
@@ -53349,14 +54003,14 @@ function buildInboxEmailsTable(messages) {
|
|
|
53349
54003
|
subject: sanitizeDisplay(message.subject ?? ""),
|
|
53350
54004
|
unread: message.unread ? "yes" : "no"
|
|
53351
54005
|
}));
|
|
53352
|
-
const idWidth = Math.max(2, ...cells.map((
|
|
53353
|
-
const receivedWidth = Math.max(8, ...cells.map((
|
|
53354
|
-
const fromWidth = Math.max(4, ...cells.map((
|
|
53355
|
-
const toWidth = Math.max(2, ...cells.map((
|
|
53356
|
-
const subjectWidth = Math.max(7, ...cells.map((
|
|
54006
|
+
const idWidth = Math.max(2, ...cells.map((c86) => c86.id.length));
|
|
54007
|
+
const receivedWidth = Math.max(8, ...cells.map((c86) => c86.received.length));
|
|
54008
|
+
const fromWidth = Math.max(4, ...cells.map((c86) => c86.from.length));
|
|
54009
|
+
const toWidth = Math.max(2, ...cells.map((c86) => c86.to.length));
|
|
54010
|
+
const subjectWidth = Math.max(7, ...cells.map((c86) => c86.subject.length));
|
|
53357
54011
|
const header = `${"ID".padEnd(idWidth)} ${"RECEIVED".padEnd(receivedWidth)} ${"FROM".padEnd(fromWidth)} ${"TO".padEnd(toWidth)} ${"SUBJECT".padEnd(subjectWidth)} UNREAD`;
|
|
53358
54012
|
const rows = cells.map(
|
|
53359
|
-
(
|
|
54013
|
+
(c86) => `${c86.id.padEnd(idWidth)} ${c86.received.padEnd(receivedWidth)} ${c86.from.padEnd(fromWidth)} ${c86.to.padEnd(toWidth)} ${c86.subject.padEnd(subjectWidth)} ${c86.unread}`
|
|
53360
54014
|
);
|
|
53361
54015
|
return { header, rows };
|
|
53362
54016
|
}
|
|
@@ -54183,16 +54837,16 @@ function printCredentialsTsv(creds) {
|
|
|
54183
54837
|
}
|
|
54184
54838
|
}
|
|
54185
54839
|
function buildCredentialsTable(creds) {
|
|
54186
|
-
const cells = creds.map((
|
|
54187
|
-
id:
|
|
54188
|
-
label: sanitizeDisplay(
|
|
54189
|
-
type:
|
|
54840
|
+
const cells = creds.map((c86) => ({
|
|
54841
|
+
id: c86.credentialId,
|
|
54842
|
+
label: sanitizeDisplay(c86.label),
|
|
54843
|
+
type: c86.credentialType
|
|
54190
54844
|
}));
|
|
54191
|
-
const idWidth = Math.max(2, ...cells.map((
|
|
54192
|
-
const labelWidth = Math.max(5, ...cells.map((
|
|
54845
|
+
const idWidth = Math.max(2, ...cells.map((c86) => c86.id.length));
|
|
54846
|
+
const labelWidth = Math.max(5, ...cells.map((c86) => c86.label.length));
|
|
54193
54847
|
const header = `${"ID".padEnd(idWidth)} ${"LABEL".padEnd(labelWidth)} TYPE`;
|
|
54194
54848
|
const rows = cells.map(
|
|
54195
|
-
(
|
|
54849
|
+
(c86) => `${c86.id.padEnd(idWidth)} ${c86.label.padEnd(labelWidth)} ${c86.type}`
|
|
54196
54850
|
);
|
|
54197
54851
|
return { header, rows };
|
|
54198
54852
|
}
|
|
@@ -54695,7 +55349,7 @@ async function runDelete3(credentialId, options) {
|
|
|
54695
55349
|
}
|
|
54696
55350
|
console.log(colorSuccess(`Deleted credential ${credentialId}`));
|
|
54697
55351
|
}
|
|
54698
|
-
function
|
|
55352
|
+
function failLinkOp2(op, status, body, notFoundLabel) {
|
|
54699
55353
|
const { message, errorCode } = readErrorFields(body);
|
|
54700
55354
|
if (status === UNAUTHORIZED_STATUS2) {
|
|
54701
55355
|
exitAuthFailed();
|
|
@@ -54802,13 +55456,13 @@ function buildCredentialLinksTable(links) {
|
|
|
54802
55456
|
source: sourceDisplay(link.source),
|
|
54803
55457
|
via: link.environmentCredentialSourceId ? "link-all" : ""
|
|
54804
55458
|
}));
|
|
54805
|
-
const idWidth = Math.max("LINK ID".length, ...cells.map((
|
|
54806
|
-
const labelWidth = Math.max("LABEL".length, ...cells.map((
|
|
54807
|
-
const typeWidth = Math.max("TYPE".length, ...cells.map((
|
|
54808
|
-
const sourceWidth = Math.max("SOURCE".length, ...cells.map((
|
|
55459
|
+
const idWidth = Math.max("LINK ID".length, ...cells.map((c86) => c86.id.length));
|
|
55460
|
+
const labelWidth = Math.max("LABEL".length, ...cells.map((c86) => c86.label.length));
|
|
55461
|
+
const typeWidth = Math.max("TYPE".length, ...cells.map((c86) => c86.type.length));
|
|
55462
|
+
const sourceWidth = Math.max("SOURCE".length, ...cells.map((c86) => c86.source.length));
|
|
54809
55463
|
const header = `${"LINK ID".padEnd(idWidth)} ${"LABEL".padEnd(labelWidth)} ${"TYPE".padEnd(typeWidth)} ${"SOURCE".padEnd(sourceWidth)} VIA`;
|
|
54810
55464
|
const rows = cells.map(
|
|
54811
|
-
(
|
|
55465
|
+
(c86) => `${c86.id.padEnd(idWidth)} ${c86.label.padEnd(labelWidth)} ${c86.type.padEnd(typeWidth)} ${c86.source.padEnd(sourceWidth)} ${c86.via}`.trimEnd()
|
|
54812
55466
|
);
|
|
54813
55467
|
return { header, rows };
|
|
54814
55468
|
}
|
|
@@ -54862,17 +55516,17 @@ function buildLinkableCredentialsTable(creds) {
|
|
|
54862
55516
|
}),
|
|
54863
55517
|
linked: cred.alreadyLinked ? "linked" : ""
|
|
54864
55518
|
}));
|
|
54865
|
-
const idWidth = Math.max("ID".length, ...cells.map((
|
|
54866
|
-
const labelWidth = Math.max("LABEL".length, ...cells.map((
|
|
54867
|
-
const typeWidth = Math.max("TYPE".length, ...cells.map((
|
|
54868
|
-
const sourceWidth = Math.max("SOURCE".length, ...cells.map((
|
|
55519
|
+
const idWidth = Math.max("ID".length, ...cells.map((c86) => c86.id.length));
|
|
55520
|
+
const labelWidth = Math.max("LABEL".length, ...cells.map((c86) => c86.label.length));
|
|
55521
|
+
const typeWidth = Math.max("TYPE".length, ...cells.map((c86) => c86.type.length));
|
|
55522
|
+
const sourceWidth = Math.max("SOURCE".length, ...cells.map((c86) => c86.source.length));
|
|
54869
55523
|
const header = `${"ID".padEnd(idWidth)} ${"LABEL".padEnd(labelWidth)} ${"TYPE".padEnd(typeWidth)} ${"SOURCE".padEnd(sourceWidth)} STATUS`;
|
|
54870
55524
|
const rows = cells.map(
|
|
54871
|
-
(
|
|
55525
|
+
(c86) => `${c86.id.padEnd(idWidth)} ${c86.label.padEnd(labelWidth)} ${c86.type.padEnd(typeWidth)} ${c86.source.padEnd(sourceWidth)} ${c86.linked}`.trimEnd()
|
|
54872
55526
|
);
|
|
54873
55527
|
return { header, rows };
|
|
54874
55528
|
}
|
|
54875
|
-
async function
|
|
55529
|
+
async function runLink2(credentialId, options) {
|
|
54876
55530
|
const output = parseOutput(options.output);
|
|
54877
55531
|
requireEnvId(options.env);
|
|
54878
55532
|
requireCredId(credentialId);
|
|
@@ -54884,7 +55538,7 @@ async function runLink(credentialId, options) {
|
|
|
54884
55538
|
})
|
|
54885
55539
|
);
|
|
54886
55540
|
if (result.status !== CREATED_STATUS) {
|
|
54887
|
-
|
|
55541
|
+
failLinkOp2("link", result.status, result.body, credentialId);
|
|
54888
55542
|
}
|
|
54889
55543
|
if (output === "table") {
|
|
54890
55544
|
console.log(
|
|
@@ -54895,7 +55549,7 @@ async function runLink(credentialId, options) {
|
|
|
54895
55549
|
}
|
|
54896
55550
|
outputCredentialLink(result.body, output);
|
|
54897
55551
|
}
|
|
54898
|
-
async function
|
|
55552
|
+
async function runUnlink2(credentialLinkId, options) {
|
|
54899
55553
|
requireEnvId(options.env);
|
|
54900
55554
|
requireLinkId(credentialLinkId);
|
|
54901
55555
|
const confirmed = await confirmAction(
|
|
@@ -54916,7 +55570,7 @@ async function runUnlink(credentialLinkId, options) {
|
|
|
54916
55570
|
if (result.status === 409 && readErrorFields(result.body).errorCode === "CREDENTIAL_LINKED_BY_RULE") {
|
|
54917
55571
|
await failLinkedByRule(organizationId, options.env, result.body);
|
|
54918
55572
|
}
|
|
54919
|
-
|
|
55573
|
+
failLinkOp2("unlink", result.status, result.body, credentialLinkId);
|
|
54920
55574
|
}
|
|
54921
55575
|
console.log(colorSuccess(`Unlinked credential link ${credentialLinkId}`));
|
|
54922
55576
|
}
|
|
@@ -55064,12 +55718,12 @@ function buildLinkableEnvironmentsTable(envs) {
|
|
|
55064
55718
|
count: String(env2.credentialCount),
|
|
55065
55719
|
linked: env2.alreadyLinked ? "linked" : ""
|
|
55066
55720
|
}));
|
|
55067
|
-
const idWidth = Math.max("ENVIRONMENT ID".length, ...cells.map((
|
|
55068
|
-
const nameWidth = Math.max("ENVIRONMENT".length, ...cells.map((
|
|
55721
|
+
const idWidth = Math.max("ENVIRONMENT ID".length, ...cells.map((c86) => c86.id.length));
|
|
55722
|
+
const nameWidth = Math.max("ENVIRONMENT".length, ...cells.map((c86) => c86.name.length));
|
|
55069
55723
|
const countWidth = "CREDENTIALS".length;
|
|
55070
55724
|
const header = `${"ENVIRONMENT ID".padEnd(idWidth)} ${"ENVIRONMENT".padEnd(nameWidth)} ${"CREDENTIALS".padEnd(countWidth)} STATUS`;
|
|
55071
55725
|
const rows = cells.map(
|
|
55072
|
-
(
|
|
55726
|
+
(c86) => `${c86.id.padEnd(idWidth)} ${c86.name.padEnd(nameWidth)} ${c86.count.padEnd(countWidth)} ${c86.linked}`.trimEnd()
|
|
55073
55727
|
);
|
|
55074
55728
|
return { header, rows };
|
|
55075
55729
|
}
|
|
@@ -55128,7 +55782,7 @@ async function runLinkAll(sourceEnvironmentId, options) {
|
|
|
55128
55782
|
})
|
|
55129
55783
|
);
|
|
55130
55784
|
if (result.status !== CREATED_STATUS) {
|
|
55131
|
-
|
|
55785
|
+
failLinkOp2("link all", result.status, result.body, sourceEnvironmentId);
|
|
55132
55786
|
}
|
|
55133
55787
|
const rule = result.body;
|
|
55134
55788
|
if (output === "json") {
|
|
@@ -55193,7 +55847,7 @@ async function runUnlinkAll(sourceEnvironmentId, options) {
|
|
|
55193
55847
|
})
|
|
55194
55848
|
);
|
|
55195
55849
|
if (result.status !== NO_CONTENT_STATUS) {
|
|
55196
|
-
|
|
55850
|
+
failLinkOp2("unlink all", result.status, result.body, rule.environmentCredentialSourceId);
|
|
55197
55851
|
}
|
|
55198
55852
|
console.log(
|
|
55199
55853
|
colorSuccess(
|
|
@@ -55315,7 +55969,7 @@ left \u2014 if the current window is nearly over, the API waits for the next one
|
|
|
55315
55969
|
await runMfaCode(credentialId, options);
|
|
55316
55970
|
});
|
|
55317
55971
|
}
|
|
55318
|
-
function
|
|
55972
|
+
function createLinkCommand2() {
|
|
55319
55973
|
return new Command("link").description("Link another application's credential into an environment").argument("<credentialId>", "UUID of the credential to link (owned by another environment)").requiredOption("--env <environmentId>", "Environment UUID to link it into").option("-o, --output <format>", "Output format: table, json, tsv (default: table)", "table").addHelpText(
|
|
55320
55974
|
"after",
|
|
55321
55975
|
`
|
|
@@ -55332,10 +55986,10 @@ Examples:
|
|
|
55332
55986
|
tracecli credential linkable --env <envId>
|
|
55333
55987
|
tracecli credential link <credentialId> --env <envId>`
|
|
55334
55988
|
).action(async (credentialId, options) => {
|
|
55335
|
-
await
|
|
55989
|
+
await runLink2(credentialId, options);
|
|
55336
55990
|
});
|
|
55337
55991
|
}
|
|
55338
|
-
function
|
|
55992
|
+
function createUnlinkCommand2() {
|
|
55339
55993
|
return new Command("unlink").description("Remove a credential link from an environment (the source credential is kept)").argument("<credentialLinkId>", "Credential link UUID (the LINK ID from `credential links`)").requiredOption("--env <environmentId>", "Environment UUID the credential is linked into").option("-y, --yes", "Skip the confirmation prompt (required in non-interactive shells)").addHelpText(
|
|
55340
55994
|
"after",
|
|
55341
55995
|
`
|
|
@@ -55344,7 +55998,7 @@ the environment's own credentials. A credential whose whole environment is
|
|
|
55344
55998
|
linked here (VIA link-all in \`credential links\`) stays until that is removed
|
|
55345
55999
|
with \`credential unlink-all\`.`
|
|
55346
56000
|
).action(async (credentialLinkId, options) => {
|
|
55347
|
-
await
|
|
56001
|
+
await runUnlink2(credentialLinkId, options);
|
|
55348
56002
|
});
|
|
55349
56003
|
}
|
|
55350
56004
|
function createLinksCommand() {
|
|
@@ -55408,8 +56062,8 @@ function createCredentialCommand() {
|
|
|
55408
56062
|
credential.addCommand(createSetMfaCommand());
|
|
55409
56063
|
credential.addCommand(createClearMfaCommand());
|
|
55410
56064
|
credential.addCommand(createMfaCodeCommand());
|
|
55411
|
-
credential.addCommand(
|
|
55412
|
-
credential.addCommand(
|
|
56065
|
+
credential.addCommand(createLinkCommand2());
|
|
56066
|
+
credential.addCommand(createUnlinkCommand2());
|
|
55413
56067
|
credential.addCommand(createLinkAllCommand());
|
|
55414
56068
|
credential.addCommand(createUnlinkAllCommand());
|
|
55415
56069
|
credential.addCommand(createLinksCommand());
|
|
@@ -55629,14 +56283,14 @@ function buildEnvironmentTable(envs, leading) {
|
|
|
55629
56283
|
url: e.primaryUrl != null ? sanitizeDisplay(e.primaryUrl) : "\u2014"
|
|
55630
56284
|
}));
|
|
55631
56285
|
const leadingWidths = leading.map(
|
|
55632
|
-
(column, i2) => Math.max(column.header.length, ...cells.map((
|
|
56286
|
+
(column, i2) => Math.max(column.header.length, ...cells.map((c86) => c86.leading[i2]?.length ?? 0))
|
|
55633
56287
|
);
|
|
55634
|
-
const nameWidth = Math.max(4, ...cells.map((
|
|
56288
|
+
const nameWidth = Math.max(4, ...cells.map((c86) => c86.name.length));
|
|
55635
56289
|
const padLeading = (values) => values.map((v, i2) => v.padEnd(leadingWidths[i2] ?? 0)).join(" ");
|
|
55636
56290
|
return {
|
|
55637
|
-
header: `${padLeading(leading.map((
|
|
56291
|
+
header: `${padLeading(leading.map((c86) => c86.header))} ${"NAME".padEnd(nameWidth)} PROD URL`,
|
|
55638
56292
|
rows: cells.map(
|
|
55639
|
-
(
|
|
56293
|
+
(c86) => `${padLeading(c86.leading)} ${c86.name.padEnd(nameWidth)} ${c86.prod.padEnd(4)} ${c86.url}`
|
|
55640
56294
|
)
|
|
55641
56295
|
};
|
|
55642
56296
|
}
|
|
@@ -59655,7 +60309,7 @@ function resolveQuestionnaireMode(options) {
|
|
|
59655
60309
|
];
|
|
59656
60310
|
const chosen = exclusive.filter((entry) => entry.set);
|
|
59657
60311
|
if (chosen.length > 1) {
|
|
59658
|
-
console.error(colorError(`Pass only one of ${chosen.map((
|
|
60312
|
+
console.error(colorError(`Pass only one of ${chosen.map((c86) => c86.flag).join(" / ")}.`));
|
|
59659
60313
|
process.exit(1);
|
|
59660
60314
|
}
|
|
59661
60315
|
const only = chosen[0];
|
|
@@ -60889,13 +61543,13 @@ function buildUploadsTable(uploads) {
|
|
|
60889
61543
|
size: formatArchiveBytes(upload.sizeBytes),
|
|
60890
61544
|
id: upload.codeUploadId
|
|
60891
61545
|
}));
|
|
60892
|
-
const nameWidth = Math.max(4, ...cells.map((
|
|
60893
|
-
const kindWidth = Math.max(4, ...cells.map((
|
|
60894
|
-
const statusWidth = Math.max(6, ...cells.map((
|
|
60895
|
-
const sizeWidth = Math.max(4, ...cells.map((
|
|
61546
|
+
const nameWidth = Math.max(4, ...cells.map((c86) => c86.name.length));
|
|
61547
|
+
const kindWidth = Math.max(4, ...cells.map((c86) => c86.kind.length));
|
|
61548
|
+
const statusWidth = Math.max(6, ...cells.map((c86) => c86.status.length));
|
|
61549
|
+
const sizeWidth = Math.max(4, ...cells.map((c86) => c86.size.length));
|
|
60896
61550
|
const header = `${"NAME".padEnd(nameWidth)} ${"KIND".padEnd(kindWidth)} ${"STATUS".padEnd(statusWidth)} ${"SIZE".padEnd(sizeWidth)} ID`;
|
|
60897
61551
|
const rows = cells.map(
|
|
60898
|
-
(
|
|
61552
|
+
(c86) => `${c86.name.padEnd(nameWidth)} ${c86.kind.padEnd(kindWidth)} ${c86.status.padEnd(statusWidth)} ${c86.size.padEnd(sizeWidth)} ${c86.id}`
|
|
60899
61553
|
);
|
|
60900
61554
|
return { header, rows };
|
|
60901
61555
|
}
|
|
@@ -61382,7 +62036,7 @@ async function runDelete5(codeUploadIdArg, options) {
|
|
|
61382
62036
|
}
|
|
61383
62037
|
console.log(colorSuccess(`Deleted upload ${codeUploadId}`));
|
|
61384
62038
|
}
|
|
61385
|
-
async function
|
|
62039
|
+
async function runLink3(options) {
|
|
61386
62040
|
const output = parseOutput(options.output);
|
|
61387
62041
|
const applicationId = requireUuid(options.app, "--app");
|
|
61388
62042
|
const codeUploadId = requireUuid(options.upload, "--upload");
|
|
@@ -61514,7 +62168,7 @@ function createDeleteCommand5() {
|
|
|
61514
62168
|
await runDelete5(codeUploadId, options);
|
|
61515
62169
|
});
|
|
61516
62170
|
}
|
|
61517
|
-
function
|
|
62171
|
+
function createLinkCommand3() {
|
|
61518
62172
|
return new Command("link").description("Link a ready source upload to an application").requiredOption("--app <applicationId>", "Application UUID").requiredOption("--upload <codeUploadId>", "Upload UUID (must be a ready source ZIP)").option("--path <repositoryPath>", "Path within the archive").option("-o, --output <format>", "Output format: table, json, tsv (default: table)", "table").addHelpText(
|
|
61519
62173
|
"after",
|
|
61520
62174
|
`
|
|
@@ -61524,7 +62178,7 @@ APK and IPA builds attach to an application with \`upload build --app\`.
|
|
|
61524
62178
|
Examples:
|
|
61525
62179
|
tracecli upload link --app <applicationId> --upload <codeUploadId>`
|
|
61526
62180
|
).action(async (options) => {
|
|
61527
|
-
await
|
|
62181
|
+
await runLink3(options);
|
|
61528
62182
|
});
|
|
61529
62183
|
}
|
|
61530
62184
|
function createUploadCommand(runtime = {}) {
|
|
@@ -61538,7 +62192,7 @@ function createUploadCommand(runtime = {}) {
|
|
|
61538
62192
|
upload.addCommand(createResumeCommand(resolved));
|
|
61539
62193
|
upload.addCommand(createWaitCommand(resolved));
|
|
61540
62194
|
upload.addCommand(createDeleteCommand5());
|
|
61541
|
-
upload.addCommand(
|
|
62195
|
+
upload.addCommand(createLinkCommand3());
|
|
61542
62196
|
return upload;
|
|
61543
62197
|
}
|
|
61544
62198
|
|