@kinosec/cli 0.7.1 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +265 -22
- package/dist/cli.js.map +1 -1
- package/package.json +12 -12
package/dist/cli.js
CHANGED
|
@@ -6289,6 +6289,7 @@ var KinoSecClient = class {
|
|
|
6289
6289
|
reports;
|
|
6290
6290
|
tokens;
|
|
6291
6291
|
me;
|
|
6292
|
+
credits;
|
|
6292
6293
|
audit;
|
|
6293
6294
|
constructor(config) {
|
|
6294
6295
|
const prefixPathname = new URL(config.apiUrl).pathname.replace(/\/?$/, "/");
|
|
@@ -6338,6 +6339,7 @@ var KinoSecClient = class {
|
|
|
6338
6339
|
this.reports = new ReportsResource(this.api);
|
|
6339
6340
|
this.tokens = new TokensResource(this.api);
|
|
6340
6341
|
this.me = new MeResource(this.api);
|
|
6342
|
+
this.credits = new CreditsResource(this.api);
|
|
6341
6343
|
this.audit = new AuditResource(this.api);
|
|
6342
6344
|
}
|
|
6343
6345
|
};
|
|
@@ -6387,6 +6389,9 @@ var ScansResource = class {
|
|
|
6387
6389
|
async cancel(id) {
|
|
6388
6390
|
return this.api.post(`v1/scans/${id}/cancel`, { json: {} }).json();
|
|
6389
6391
|
}
|
|
6392
|
+
async scoutStatus(profileId) {
|
|
6393
|
+
return this.api.get(`v1/scans/${profileId}/scout-status`).json();
|
|
6394
|
+
}
|
|
6390
6395
|
};
|
|
6391
6396
|
var SchedulesResource = class {
|
|
6392
6397
|
constructor(api) {
|
|
@@ -6472,6 +6477,15 @@ var MeResource = class {
|
|
|
6472
6477
|
return this.api.get("v1/me").json();
|
|
6473
6478
|
}
|
|
6474
6479
|
};
|
|
6480
|
+
var CreditsResource = class {
|
|
6481
|
+
constructor(api) {
|
|
6482
|
+
this.api = api;
|
|
6483
|
+
}
|
|
6484
|
+
api;
|
|
6485
|
+
async get() {
|
|
6486
|
+
return this.api.get("v1/credits").json();
|
|
6487
|
+
}
|
|
6488
|
+
};
|
|
6475
6489
|
var AuditResource = class {
|
|
6476
6490
|
constructor(api) {
|
|
6477
6491
|
this.api = api;
|
|
@@ -7353,6 +7367,32 @@ ${content}`);
|
|
|
7353
7367
|
// src/lib/errors.ts
|
|
7354
7368
|
function handleError(error2) {
|
|
7355
7369
|
if (error2 instanceof ApiError) {
|
|
7370
|
+
if (error2.code === "insufficient_credits") {
|
|
7371
|
+
if (shouldUseJson()) {
|
|
7372
|
+
process.stderr.write(
|
|
7373
|
+
JSON.stringify({
|
|
7374
|
+
error: {
|
|
7375
|
+
status: error2.status,
|
|
7376
|
+
code: error2.code,
|
|
7377
|
+
detail: error2.detail,
|
|
7378
|
+
request_id: error2.requestId
|
|
7379
|
+
}
|
|
7380
|
+
}) + "\n"
|
|
7381
|
+
);
|
|
7382
|
+
} else if (isTTY()) {
|
|
7383
|
+
console.error(import_picocolors2.default.red("\u2717 Insufficient credits"));
|
|
7384
|
+
console.error();
|
|
7385
|
+
console.error(" You don't have enough credits for this scan.");
|
|
7386
|
+
console.error(" Check your balance:");
|
|
7387
|
+
console.error();
|
|
7388
|
+
console.error(` ${import_picocolors2.default.cyan("kinosec credits")}`);
|
|
7389
|
+
console.error();
|
|
7390
|
+
console.error(` Need more? Contact ${import_picocolors2.default.bold("sales@kinosec.com")}`);
|
|
7391
|
+
} else {
|
|
7392
|
+
console.error("Insufficient credits. Check your balance: kinosec credits. Contact sales@kinosec.com");
|
|
7393
|
+
}
|
|
7394
|
+
process.exit(77);
|
|
7395
|
+
}
|
|
7356
7396
|
if (shouldUseJson()) {
|
|
7357
7397
|
process.stderr.write(
|
|
7358
7398
|
JSON.stringify({
|
|
@@ -7704,8 +7744,38 @@ Examples:
|
|
|
7704
7744
|
});
|
|
7705
7745
|
}
|
|
7706
7746
|
|
|
7747
|
+
// src/commands/credits.ts
|
|
7748
|
+
function registerCreditsCommand(program3) {
|
|
7749
|
+
program3.command("credits").description("Show your credit balance").addHelpText("after", `
|
|
7750
|
+
Examples:
|
|
7751
|
+
$ kinosec credits
|
|
7752
|
+
$ kinosec credits --json`).action(async () => {
|
|
7753
|
+
try {
|
|
7754
|
+
const opts = program3.opts();
|
|
7755
|
+
const { token, apiUrl } = resolveToken(opts);
|
|
7756
|
+
const client = new KinoSecClient({ apiUrl, token });
|
|
7757
|
+
const credits = await client.credits.get();
|
|
7758
|
+
if (opts.json || opts.output === "json") {
|
|
7759
|
+
printJson(credits);
|
|
7760
|
+
return;
|
|
7761
|
+
}
|
|
7762
|
+
const fields = [
|
|
7763
|
+
{ label: "Pentest credits", value: String(credits.pentest_credits) },
|
|
7764
|
+
{ label: "Quick credits", value: String(credits.quick_pentest_credits) },
|
|
7765
|
+
{ label: "Free quick credit", value: String(credits.free_quick_pentest_credits) }
|
|
7766
|
+
];
|
|
7767
|
+
if (credits.source?.type === "org_pool" && credits.source.org_name) {
|
|
7768
|
+
fields.push({ label: "Source", value: `${credits.source.org_name} org pool` });
|
|
7769
|
+
}
|
|
7770
|
+
printDetail(fields);
|
|
7771
|
+
} catch (error2) {
|
|
7772
|
+
handleError(error2);
|
|
7773
|
+
}
|
|
7774
|
+
});
|
|
7775
|
+
}
|
|
7776
|
+
|
|
7707
7777
|
// src/commands/pentest.ts
|
|
7708
|
-
var
|
|
7778
|
+
var import_picocolors7 = __toESM(require_picocolors(), 1);
|
|
7709
7779
|
|
|
7710
7780
|
// src/lib/confirm.ts
|
|
7711
7781
|
var import_picocolors3 = __toESM(require_picocolors(), 1);
|
|
@@ -11460,6 +11530,122 @@ async function printFindingsSummary(client, profileId, tty3) {
|
|
|
11460
11530
|
}
|
|
11461
11531
|
}
|
|
11462
11532
|
|
|
11533
|
+
// src/lib/scout.ts
|
|
11534
|
+
var import_picocolors6 = __toESM(require_picocolors(), 1);
|
|
11535
|
+
var UNICODE2 = isUnicodeSupported();
|
|
11536
|
+
var sym2 = {
|
|
11537
|
+
success: UNICODE2 ? "\u2713" : "v",
|
|
11538
|
+
fail: UNICODE2 ? "\u2717" : "x",
|
|
11539
|
+
warn: UNICODE2 ? "\u26A0" : "!"
|
|
11540
|
+
};
|
|
11541
|
+
function printOnPremInstructions(result) {
|
|
11542
|
+
const tty3 = isTTY();
|
|
11543
|
+
const header = tty3 ? import_picocolors6.default.bold("On-Prem Scout Setup") : "On-Prem Scout Setup";
|
|
11544
|
+
console.log(`
|
|
11545
|
+
${header}
|
|
11546
|
+
`);
|
|
11547
|
+
console.log(` Session ID: ${result.session_id}`);
|
|
11548
|
+
console.log(` Profile ID: ${result.scan_profile_id}`);
|
|
11549
|
+
const curlCmd = `curl -fsSL https://api.kinosec.ai/functions/v1/scout-bootstrap/launch/${result.bootstrap_token} | bash`;
|
|
11550
|
+
if (tty3) {
|
|
11551
|
+
console.log(`
|
|
11552
|
+
Run on target host:
|
|
11553
|
+
`);
|
|
11554
|
+
console.log(` ${import_picocolors6.default.cyan(curlCmd)}
|
|
11555
|
+
`);
|
|
11556
|
+
console.log(` ${import_picocolors6.default.yellow(sym2.warn)} Token expires in ${import_picocolors6.default.bold("15 minutes")}.`);
|
|
11557
|
+
} else {
|
|
11558
|
+
console.log(`
|
|
11559
|
+
Run on target host:
|
|
11560
|
+
`);
|
|
11561
|
+
console.log(` ${curlCmd}
|
|
11562
|
+
`);
|
|
11563
|
+
console.log(` ${sym2.warn} Token expires in 15 minutes.`);
|
|
11564
|
+
}
|
|
11565
|
+
}
|
|
11566
|
+
async function waitForScoutConnection(client, profileId, options) {
|
|
11567
|
+
const { timeoutMs, intervalMs, useJson } = options;
|
|
11568
|
+
const tty3 = isTTY();
|
|
11569
|
+
const loopStart = Date.now();
|
|
11570
|
+
let spinner = null;
|
|
11571
|
+
if (!useJson && tty3) {
|
|
11572
|
+
spinner = ora({
|
|
11573
|
+
text: "Waiting for Scout connection...",
|
|
11574
|
+
color: "green",
|
|
11575
|
+
isEnabled: true
|
|
11576
|
+
}).start();
|
|
11577
|
+
}
|
|
11578
|
+
const cleanup = () => {
|
|
11579
|
+
if (spinner) spinner.stop();
|
|
11580
|
+
};
|
|
11581
|
+
const onSigint = () => {
|
|
11582
|
+
cleanup();
|
|
11583
|
+
console.log("\nWatch cancelled. Pentest is waiting for Scout connection.");
|
|
11584
|
+
process.exit(0);
|
|
11585
|
+
};
|
|
11586
|
+
process.once("SIGINT", onSigint);
|
|
11587
|
+
while (true) {
|
|
11588
|
+
const status = await client.scans.scoutStatus(profileId);
|
|
11589
|
+
if (useJson) {
|
|
11590
|
+
const elapsed = Math.round((Date.now() - loopStart) / 1e3);
|
|
11591
|
+
process.stdout.write(
|
|
11592
|
+
JSON.stringify({ ...status, elapsed_seconds: elapsed }) + "\n"
|
|
11593
|
+
);
|
|
11594
|
+
}
|
|
11595
|
+
switch (status.status) {
|
|
11596
|
+
case "pending":
|
|
11597
|
+
if (spinner) spinner.text = import_picocolors6.default.green("Waiting for Scout bootstrap...");
|
|
11598
|
+
break;
|
|
11599
|
+
case "bootstrapped":
|
|
11600
|
+
if (spinner) spinner.text = import_picocolors6.default.green("Scout bootstrapped, establishing connection...");
|
|
11601
|
+
break;
|
|
11602
|
+
case "connected": {
|
|
11603
|
+
cleanup();
|
|
11604
|
+
process.removeListener("SIGINT", onSigint);
|
|
11605
|
+
if (!useJson) {
|
|
11606
|
+
const icon = tty3 ? import_picocolors6.default.green(sym2.success) : sym2.success;
|
|
11607
|
+
console.log(`${icon} Scout connected`);
|
|
11608
|
+
if (status.hostname) {
|
|
11609
|
+
console.log(` Hostname: ${status.hostname}`);
|
|
11610
|
+
}
|
|
11611
|
+
if (status.tools.length > 0) {
|
|
11612
|
+
console.log(` Tools: ${status.tools.join(", ")}`);
|
|
11613
|
+
}
|
|
11614
|
+
}
|
|
11615
|
+
return;
|
|
11616
|
+
}
|
|
11617
|
+
case "expired": {
|
|
11618
|
+
cleanup();
|
|
11619
|
+
process.removeListener("SIGINT", onSigint);
|
|
11620
|
+
const icon = tty3 ? import_picocolors6.default.red(sym2.fail) : sym2.fail;
|
|
11621
|
+
console.error(`
|
|
11622
|
+
${icon} Scout bootstrap token expired.`);
|
|
11623
|
+
console.error("Start a new pentest to get a fresh token.");
|
|
11624
|
+
process.exit(1);
|
|
11625
|
+
}
|
|
11626
|
+
case "disconnected": {
|
|
11627
|
+
cleanup();
|
|
11628
|
+
process.removeListener("SIGINT", onSigint);
|
|
11629
|
+
const icon = tty3 ? import_picocolors6.default.red(sym2.fail) : sym2.fail;
|
|
11630
|
+
console.error(`
|
|
11631
|
+
${icon} Scout disconnected unexpectedly.`);
|
|
11632
|
+
console.error(`Check status: kinosec pentest get ${profileId}`);
|
|
11633
|
+
process.exit(1);
|
|
11634
|
+
}
|
|
11635
|
+
}
|
|
11636
|
+
if (Date.now() - loopStart > timeoutMs) {
|
|
11637
|
+
cleanup();
|
|
11638
|
+
process.removeListener("SIGINT", onSigint);
|
|
11639
|
+
const secs = Math.round(timeoutMs / 1e3);
|
|
11640
|
+
console.error(`
|
|
11641
|
+
Timeout: Scout did not connect within ${secs}s.`);
|
|
11642
|
+
console.error("The bootstrap token may have expired. Start a new pentest.");
|
|
11643
|
+
process.exit(3);
|
|
11644
|
+
}
|
|
11645
|
+
await new Promise((resolve) => setTimeout(resolve, intervalMs));
|
|
11646
|
+
}
|
|
11647
|
+
}
|
|
11648
|
+
|
|
11463
11649
|
// src/commands/pentest.ts
|
|
11464
11650
|
function stripProtocol(input) {
|
|
11465
11651
|
const match = input.match(/^https?:\/\/(.+)/i);
|
|
@@ -11470,15 +11656,23 @@ function isValidDomain(value) {
|
|
|
11470
11656
|
return value.includes(".") && !/\s/.test(value);
|
|
11471
11657
|
}
|
|
11472
11658
|
function registerPentestCommand(program3) {
|
|
11473
|
-
const pentest = program3.command("pentest").description("Run and manage pentests").option("-t, --target <domain>", "Target domain to pentest").option("--profile <id>", "Pentest profile ID (alternative to --target)").option("--mode <mode>", "Pentest mode: quick or full", "full").option("-y, --yes", "Accept authorization terms without prompting").option("--no-watch", "Skip auto-watch after starting the pentest").addHelpText("after", `
|
|
11659
|
+
const pentest = program3.command("pentest").description("Run and manage pentests").option("-t, --target <domain>", "Target domain to pentest").option("--profile <id>", "Pentest profile ID (alternative to --target)").option("--mode <mode>", "Pentest mode: quick or full", "full").option("-y, --yes", "Accept authorization terms without prompting").option("--no-watch", "Skip auto-watch after starting the pentest").option("--deployment <type>", "Deployment type: cloud or on-prem", "cloud").addHelpText("after", `
|
|
11474
11660
|
Examples:
|
|
11475
11661
|
$ kinosec pentest -t delikado.org
|
|
11476
11662
|
$ kinosec pentest --target delikado.org --mode quick
|
|
11477
|
-
$ kinosec pentest --profile abc123
|
|
11663
|
+
$ kinosec pentest --profile abc123
|
|
11664
|
+
$ kinosec pentest -t internal.corp --deployment on-prem`).action(async (options) => {
|
|
11478
11665
|
if (!options.target && !options.profile) {
|
|
11479
11666
|
console.error("Provide --target <domain> or --profile <id>.");
|
|
11480
11667
|
process.exit(2);
|
|
11481
11668
|
}
|
|
11669
|
+
if (options.deployment) {
|
|
11670
|
+
options.deployment = options.deployment.replace(/-/g, "_");
|
|
11671
|
+
}
|
|
11672
|
+
if (options.deployment !== "cloud" && options.deployment !== "on_prem") {
|
|
11673
|
+
console.error("Invalid deployment type. Must be: cloud or on-prem.");
|
|
11674
|
+
process.exit(2);
|
|
11675
|
+
}
|
|
11482
11676
|
try {
|
|
11483
11677
|
const opts = program3.opts();
|
|
11484
11678
|
const { token, apiUrl } = resolveToken(opts);
|
|
@@ -11515,10 +11709,18 @@ Examples:
|
|
|
11515
11709
|
}
|
|
11516
11710
|
}
|
|
11517
11711
|
targetDisplay = domain;
|
|
11518
|
-
|
|
11712
|
+
const assetParams = {
|
|
11713
|
+
asset_id: asset.id,
|
|
11714
|
+
scan_mode: options.mode
|
|
11715
|
+
};
|
|
11716
|
+
if (options.deployment !== "cloud") {
|
|
11717
|
+
assetParams.deployment_type = options.deployment;
|
|
11718
|
+
}
|
|
11719
|
+
params = assetParams;
|
|
11519
11720
|
}
|
|
11520
11721
|
await confirmAuthorization(targetDisplay, Boolean(options.yes));
|
|
11521
11722
|
const result = await client.scans.create(params);
|
|
11723
|
+
const isOnPrem = result.deployment_type === "on_prem";
|
|
11522
11724
|
if (opts.json || opts.output === "json") {
|
|
11523
11725
|
printJson(result);
|
|
11524
11726
|
return;
|
|
@@ -11526,13 +11728,37 @@ Examples:
|
|
|
11526
11728
|
printSuccess(`Pentest started: ${result.domain_or_ip}`);
|
|
11527
11729
|
console.log(` Profile ID: ${result.scan_profile_id}`);
|
|
11528
11730
|
console.log(` Mode: ${result.scan_mode}`);
|
|
11731
|
+
if (isOnPrem) {
|
|
11732
|
+
printOnPremInstructions(result);
|
|
11733
|
+
if (options.watch && isTTY()) {
|
|
11734
|
+
const divider2 = import_picocolors7.default.dim("\u2500".repeat(37));
|
|
11735
|
+
console.log(`
|
|
11736
|
+
${divider2}
|
|
11737
|
+
`);
|
|
11738
|
+
await waitForScoutConnection(client, result.scan_profile_id, {
|
|
11739
|
+
timeoutMs: 15 * 60 * 1e3,
|
|
11740
|
+
intervalMs: 5 * 1e3,
|
|
11741
|
+
useJson: false
|
|
11742
|
+
});
|
|
11743
|
+
await watchPentest(client, result.scan_profile_id, {
|
|
11744
|
+
timeoutMs: 1800 * 1e3,
|
|
11745
|
+
intervalMs: 5 * 1e3,
|
|
11746
|
+
useJson: false,
|
|
11747
|
+
showFindingsSummary: true
|
|
11748
|
+
});
|
|
11749
|
+
} else {
|
|
11750
|
+
console.log(`
|
|
11751
|
+
Watch connection: kinosec pentest watch ${result.scan_profile_id}`);
|
|
11752
|
+
}
|
|
11753
|
+
return;
|
|
11754
|
+
}
|
|
11529
11755
|
if (!options.watch || !isTTY()) {
|
|
11530
11756
|
console.log(` Status: ${result.scan_status}`);
|
|
11531
11757
|
console.log(`
|
|
11532
11758
|
Watch progress: kinosec pentest watch ${result.scan_profile_id}`);
|
|
11533
11759
|
return;
|
|
11534
11760
|
}
|
|
11535
|
-
const divider = isTTY() ?
|
|
11761
|
+
const divider = isTTY() ? import_picocolors7.default.dim("\u2500".repeat(37)) : "-".repeat(37);
|
|
11536
11762
|
console.log(`
|
|
11537
11763
|
${divider}
|
|
11538
11764
|
`);
|
|
@@ -11578,7 +11804,7 @@ Examples:
|
|
|
11578
11804
|
])
|
|
11579
11805
|
);
|
|
11580
11806
|
if (result.next_cursor) {
|
|
11581
|
-
console.log(
|
|
11807
|
+
console.log(import_picocolors7.default.dim(`
|
|
11582
11808
|
More results available. Use --cursor ${result.next_cursor}`));
|
|
11583
11809
|
}
|
|
11584
11810
|
} catch (error2) {
|
|
@@ -11605,6 +11831,7 @@ Examples:
|
|
|
11605
11831
|
["Target", detail.domain_or_ip],
|
|
11606
11832
|
["Mode", detail.scan_mode],
|
|
11607
11833
|
["Type", detail.scan_type],
|
|
11834
|
+
...detail.deployment_type ? [["Deployment", detail.deployment_type === "on_prem" ? "On-Prem" : "Cloud"]] : [],
|
|
11608
11835
|
["Status", detail.scan_status],
|
|
11609
11836
|
["Activity", detail.current_activity || "(none)"],
|
|
11610
11837
|
["Created", detail.created_at],
|
|
@@ -11641,10 +11868,25 @@ Examples:
|
|
|
11641
11868
|
const opts = program3.opts();
|
|
11642
11869
|
const { token, apiUrl } = resolveToken(opts);
|
|
11643
11870
|
const client = new KinoSecClient({ apiUrl, token });
|
|
11871
|
+
const useJson = Boolean(opts.json || opts.output === "json");
|
|
11872
|
+
const detail = await client.scans.get(id);
|
|
11873
|
+
if (detail.deployment_type === "on_prem") {
|
|
11874
|
+
try {
|
|
11875
|
+
const scout = await client.scans.scoutStatus(id);
|
|
11876
|
+
if (scout.status !== "connected") {
|
|
11877
|
+
await waitForScoutConnection(client, id, {
|
|
11878
|
+
timeoutMs: 15 * 60 * 1e3,
|
|
11879
|
+
intervalMs: parseInt(options.interval, 10) * 1e3,
|
|
11880
|
+
useJson
|
|
11881
|
+
});
|
|
11882
|
+
}
|
|
11883
|
+
} catch {
|
|
11884
|
+
}
|
|
11885
|
+
}
|
|
11644
11886
|
await watchPentest(client, id, {
|
|
11645
11887
|
timeoutMs: parseInt(options.timeout, 10) * 1e3,
|
|
11646
11888
|
intervalMs: parseInt(options.interval, 10) * 1e3,
|
|
11647
|
-
useJson
|
|
11889
|
+
useJson,
|
|
11648
11890
|
showFindingsSummary: true
|
|
11649
11891
|
});
|
|
11650
11892
|
} catch (error2) {
|
|
@@ -11654,10 +11896,10 @@ Examples:
|
|
|
11654
11896
|
}
|
|
11655
11897
|
|
|
11656
11898
|
// src/commands/asset.ts
|
|
11657
|
-
var
|
|
11899
|
+
var import_picocolors9 = __toESM(require_picocolors(), 1);
|
|
11658
11900
|
|
|
11659
11901
|
// src/commands/asset-auth.ts
|
|
11660
|
-
var
|
|
11902
|
+
var import_picocolors8 = __toESM(require_picocolors(), 1);
|
|
11661
11903
|
|
|
11662
11904
|
// src/lib/resolve-asset.ts
|
|
11663
11905
|
var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-/i;
|
|
@@ -11914,7 +12156,7 @@ Examples:
|
|
|
11914
12156
|
}
|
|
11915
12157
|
if (!creds.has_credentials) {
|
|
11916
12158
|
console.log(`Asset: ${asset.asset_value}`);
|
|
11917
|
-
console.log(`Auth Type: ${
|
|
12159
|
+
console.log(`Auth Type: ${import_picocolors8.default.dim("(none)")}`);
|
|
11918
12160
|
console.log(`Has Credentials: no`);
|
|
11919
12161
|
return;
|
|
11920
12162
|
}
|
|
@@ -11935,9 +12177,9 @@ Examples:
|
|
|
11935
12177
|
const hasAny = ta.has_username || ta.has_cookie || ta.has_bearer_token || ta.has_apikey;
|
|
11936
12178
|
if (hasAny) {
|
|
11937
12179
|
const detail = ta.has_username ? "username" : ta.has_bearer_token ? "bearer token" : ta.has_cookie ? "cookie" : "API key";
|
|
11938
|
-
console.log(`Target Account: ${
|
|
12180
|
+
console.log(`Target Account: ${import_picocolors8.default.green("configured")} (${detail})`);
|
|
11939
12181
|
} else {
|
|
11940
|
-
console.log(`Target Account: ${
|
|
12182
|
+
console.log(`Target Account: ${import_picocolors8.default.dim("not configured")}`);
|
|
11941
12183
|
}
|
|
11942
12184
|
}
|
|
11943
12185
|
} catch (error2) {
|
|
@@ -12088,7 +12330,7 @@ Examples:
|
|
|
12088
12330
|
])
|
|
12089
12331
|
);
|
|
12090
12332
|
if (result.next_cursor) {
|
|
12091
|
-
console.log(
|
|
12333
|
+
console.log(import_picocolors9.default.dim(`
|
|
12092
12334
|
More results available. Use --cursor ${result.next_cursor}`));
|
|
12093
12335
|
}
|
|
12094
12336
|
} catch (error2) {
|
|
@@ -12200,7 +12442,7 @@ Examples:
|
|
|
12200
12442
|
}
|
|
12201
12443
|
|
|
12202
12444
|
// src/commands/finding.ts
|
|
12203
|
-
var
|
|
12445
|
+
var import_picocolors10 = __toESM(require_picocolors(), 1);
|
|
12204
12446
|
function formatPoc(poc) {
|
|
12205
12447
|
if (poc == null) return null;
|
|
12206
12448
|
if (typeof poc === "string") return poc.trim() || null;
|
|
@@ -12241,7 +12483,7 @@ Examples:
|
|
|
12241
12483
|
])
|
|
12242
12484
|
);
|
|
12243
12485
|
if (result.next_cursor) {
|
|
12244
|
-
console.log(
|
|
12486
|
+
console.log(import_picocolors10.default.dim(`
|
|
12245
12487
|
More results available. Use --cursor ${result.next_cursor}`));
|
|
12246
12488
|
}
|
|
12247
12489
|
} catch (error2) {
|
|
@@ -12329,7 +12571,7 @@ Examples:
|
|
|
12329
12571
|
}
|
|
12330
12572
|
|
|
12331
12573
|
// src/commands/report.ts
|
|
12332
|
-
var
|
|
12574
|
+
var import_picocolors11 = __toESM(require_picocolors(), 1);
|
|
12333
12575
|
function renderMarkdown(data) {
|
|
12334
12576
|
const { scan, findings } = data;
|
|
12335
12577
|
const lines = [];
|
|
@@ -12406,7 +12648,7 @@ Examples:
|
|
|
12406
12648
|
])
|
|
12407
12649
|
);
|
|
12408
12650
|
if (result.next_cursor) {
|
|
12409
|
-
console.log(
|
|
12651
|
+
console.log(import_picocolors11.default.dim(`
|
|
12410
12652
|
More results available. Use --cursor ${result.next_cursor}`));
|
|
12411
12653
|
}
|
|
12412
12654
|
} catch (error2) {
|
|
@@ -12477,7 +12719,7 @@ Examples:
|
|
|
12477
12719
|
}
|
|
12478
12720
|
|
|
12479
12721
|
// src/commands/token.ts
|
|
12480
|
-
var
|
|
12722
|
+
var import_picocolors12 = __toESM(require_picocolors(), 1);
|
|
12481
12723
|
function registerTokenCommand(program3) {
|
|
12482
12724
|
const token = program3.command("token").description("Manage API tokens");
|
|
12483
12725
|
token.command("list").description("List API tokens").option("--limit <n>", "Max results per page", "20").option("--cursor <cursor>", "Pagination cursor").addHelpText("after", `
|
|
@@ -12512,7 +12754,7 @@ Examples:
|
|
|
12512
12754
|
])
|
|
12513
12755
|
);
|
|
12514
12756
|
if (result.next_cursor) {
|
|
12515
|
-
console.log(
|
|
12757
|
+
console.log(import_picocolors12.default.dim(`
|
|
12516
12758
|
More results available. Use --cursor ${result.next_cursor}`));
|
|
12517
12759
|
}
|
|
12518
12760
|
} catch (error2) {
|
|
@@ -12539,7 +12781,7 @@ Examples:
|
|
|
12539
12781
|
}
|
|
12540
12782
|
printSuccess(`Token created: ${result.name}`);
|
|
12541
12783
|
console.log("");
|
|
12542
|
-
console.log(
|
|
12784
|
+
console.log(import_picocolors12.default.bold(" Token: ") + result.token);
|
|
12543
12785
|
console.log("");
|
|
12544
12786
|
printWarning("Save this token \u2014 it will not be shown again.");
|
|
12545
12787
|
console.log(` ID: ${result.id}`);
|
|
@@ -12572,15 +12814,16 @@ Examples:
|
|
|
12572
12814
|
|
|
12573
12815
|
// src/cli.ts
|
|
12574
12816
|
var program2 = new Command();
|
|
12575
|
-
program2.name("kinosec").description("KinoSec CLI \u2014 run pentests from your terminal").version("0.
|
|
12817
|
+
program2.name("kinosec").description("KinoSec CLI \u2014 run pentests from your terminal").version("0.9.0", "-v, --version").option("--token <pat>", "API token (overrides KINOSEC_TOKEN)").option("--output <format>", "Output format: text or json", "text").option("--json", "Shorthand for --output json").option("--no-color", "Disable colors");
|
|
12576
12818
|
registerAuthCommand(program2);
|
|
12577
12819
|
registerMeCommand(program2);
|
|
12820
|
+
registerCreditsCommand(program2);
|
|
12578
12821
|
registerPentestCommand(program2);
|
|
12579
12822
|
registerAssetCommand(program2);
|
|
12580
12823
|
registerFindingCommand(program2);
|
|
12581
12824
|
registerReportCommand(program2);
|
|
12582
12825
|
registerTokenCommand(program2);
|
|
12583
|
-
program2.parseAsync(process.argv).then(() => checkForUpdate("0.
|
|
12826
|
+
program2.parseAsync(process.argv).then(() => checkForUpdate("0.9.0")).catch(handleError);
|
|
12584
12827
|
/*! Bundled license information:
|
|
12585
12828
|
|
|
12586
12829
|
ky/distribution/index.js:
|