@pensar/apex 1.8.0 → 1.8.2-canary.fb75c486
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -0
- package/build/agent-6dj1qm50.js +221 -0
- package/build/agent-6xr8vpgm.js +28 -0
- package/build/agent-x1htbpe3.js +22 -0
- package/build/apps-t0gmwc7z.js +446 -0
- package/build/{auth-dxjgy41e.js → auth-p4r1m7xq.js} +50 -13
- package/build/authentication-je2b0c3w.js +22 -0
- package/build/blackboxAgent-a4jnt0y5.js +22 -0
- package/build/{blackboxPentest-8ps4yvbk.js → blackboxPentest-b5741n3h.js} +19 -17
- package/build/{cli-y61d9433.js → cli-0tnv1vkp.js} +138 -38
- package/build/{cli-jg7r7y5n.js → cli-4xb21y6g.js} +30 -2
- package/build/{cli-k0tckznm.js → cli-6p7d2k55.js} +39701 -31695
- package/build/cli-87zakjb2.js +17 -0
- package/build/{authentication-e30mfzbe.js → cli-8frjr68r.js} +11 -18
- package/build/cli-8xknm7d9.js +204 -0
- package/build/cli-9egg9azd.js +22 -0
- package/build/cli-9fsre5pt.js +0 -0
- package/build/cli-abbka8n3.js +501 -0
- package/build/{cli-3y0dgy56.js → cli-c8131c4q.js} +2 -2
- package/build/cli-e08r86zk.js +24 -0
- package/build/{cli-0ghkg3w6.js → cli-e6rgwtpb.js} +19950 -18556
- package/build/cli-g5h24ny8.js +197 -0
- package/build/{cli-nr1cjfr9.js → cli-gtcd5c3f.js} +26 -7
- package/build/cli-k0730f59.js +52 -0
- package/build/{cli-tp1tqn3k.js → cli-mswm4k81.js} +1 -1
- package/build/{cli-m788e4f3.js → cli-q8dfq25x.js} +584 -33
- package/build/cli-rhry8mat.js +7213 -0
- package/build/{cli-g8t710ew.js → cli-ryy39d77.js} +253 -250
- package/build/cli-s1nckt4k.js +20 -0
- package/build/{cli-k4hrygff.js → cli-v9ds4jb8.js} +9 -5
- package/build/{cli-dqt80sw3.js → cli-w5990vr6.js} +199 -68
- package/build/{cli-3w2syxpv.js → cli-wfmdch3r.js} +102695 -104816
- package/build/cli.js +351 -280
- package/build/config-3bvtf3j8.js +188 -0
- package/build/{doctor-8tva8j99.js → doctor-2bkpddws.js} +1 -1
- package/build/{fixes-q5bhgxhc.js → fixes-60k3ts71.js} +23 -4
- package/build/{index-pfee23kv.js → index-0gp3x2r8.js} +19306 -18954
- package/build/index-861hkebg.js +12 -0
- package/build/{index-y5xpp21a.js → index-acc00eq4.js} +77 -108
- package/build/index-acdgrqa0.js +36 -0
- package/build/{index-e898mdyh.js → index-cfberehw.js} +4 -2
- package/build/{index-wfeb2gcc.js → index-hxn4rk8f.js} +9 -11
- package/build/{index-dw1xbhfn.js → index-vc29b21w.js} +161 -26
- package/build/index-vwt27stc.js +184 -0
- package/build/{issues-qbmdneej.js → issues-1bynat5q.js} +33 -9
- package/build/{logs-xm5vbymy.js → logs-e78vx2dy.js} +23 -4
- package/build/{main-3d7dfdvs.js → main-3zneyg7p.js} +93 -17
- package/build/{offesecAgent-re6kt2ff.js → offesecAgent-w9m0svwk.js} +14 -11
- package/build/parse-15kqmy2v.js +207 -0
- package/build/pentest-gpvqpvmd.js +31 -0
- package/build/{pentests-e3rj5845.js → pentests-nq7wa8yb.js} +36 -17
- package/build/{targetedPentest-fs0v570s.js → targetedPentest-fjxqn089.js} +15 -12
- package/build/threatModel-9yqx7d7x.js +29 -0
- package/build/{uninstall-qb2xbh2t.js → uninstall-9zbf4cwc.js} +6 -4
- package/build/{utils-jf52rmrb.js → utils-dh1t2r1e.js} +13 -10
- package/package.json +86 -88
- package/build/agent-4d8j2jsw.js +0 -278
- package/build/agent-z2s6h7n2.js +0 -19
- package/build/blackboxAgent-j9pczwym.js +0 -19
- package/build/cli-03z6pswp.js +0 -1423
- package/build/cli-0fy9j5dw.js +0 -61
- package/build/cli-asyas1xb.js +0 -110
- package/build/cli-dj1dgw2n.js +0 -190
- package/build/cli-q7r2sth7.js +0 -103
- package/build/cli-vkwch0bc.js +0 -1207
- package/build/cli-wr7g9qcr.js +0 -645
- package/build/index-bz6f8jry.js +0 -32
- package/build/pentest-mfm4hake.js +0 -29
- package/build/projects-qk22qcbt.js +0 -35
- package/build/threatModel-xfvc6cch.js +0 -67
|
@@ -0,0 +1,446 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
import {
|
|
3
|
+
createApp,
|
|
4
|
+
createEndpoint,
|
|
5
|
+
deleteApp,
|
|
6
|
+
deleteEndpoint,
|
|
7
|
+
getApp,
|
|
8
|
+
getEndpoint,
|
|
9
|
+
listApps,
|
|
10
|
+
listEndpoints,
|
|
11
|
+
searchApps,
|
|
12
|
+
searchEndpoints,
|
|
13
|
+
updateApp,
|
|
14
|
+
updateEndpoint
|
|
15
|
+
} from "./cli-q8dfq25x.js";
|
|
16
|
+
import"./cli-rhry8mat.js";
|
|
17
|
+
import"./cli-v9ds4jb8.js";
|
|
18
|
+
import"./cli-0tnv1vkp.js";
|
|
19
|
+
import"./cli-8frjr68r.js";
|
|
20
|
+
import"./cli-4xb21y6g.js";
|
|
21
|
+
import"./cli-abbka8n3.js";
|
|
22
|
+
import"./cli-9fsre5pt.js";
|
|
23
|
+
import"./cli-k0730f59.js";
|
|
24
|
+
import"./cli-wfmdch3r.js";
|
|
25
|
+
import"./cli-mswm4k81.js";
|
|
26
|
+
import"./cli-ryy39d77.js";
|
|
27
|
+
import"./cli-fw5r7pfj.js";
|
|
28
|
+
import"./cli-c8131c4q.js";
|
|
29
|
+
import"./cli-s1nckt4k.js";
|
|
30
|
+
import"./cli-87zakjb2.js";
|
|
31
|
+
import"./cli-6p7d2k55.js";
|
|
32
|
+
import"./cli-w5990vr6.js";
|
|
33
|
+
import"./cli-e6rgwtpb.js";
|
|
34
|
+
import"./cli-9egg9azd.js";
|
|
35
|
+
import"./cli-gpnb45ck.js";
|
|
36
|
+
import"./cli-gtcd5c3f.js";
|
|
37
|
+
import"./cli-g5h24ny8.js";
|
|
38
|
+
import"./cli-8rxa073f.js";
|
|
39
|
+
|
|
40
|
+
// src/cli/apps.ts
|
|
41
|
+
var APPLICATION_TYPES = [
|
|
42
|
+
"ui",
|
|
43
|
+
"api-service",
|
|
44
|
+
"web-application",
|
|
45
|
+
"full-stack",
|
|
46
|
+
"domain",
|
|
47
|
+
"subdomain",
|
|
48
|
+
"database",
|
|
49
|
+
"cloud-resource",
|
|
50
|
+
"storage"
|
|
51
|
+
];
|
|
52
|
+
var ENDPOINT_TYPES = [
|
|
53
|
+
"api-endpoint",
|
|
54
|
+
"web-endpoint",
|
|
55
|
+
"auth-endpoint",
|
|
56
|
+
"database",
|
|
57
|
+
"file-storage",
|
|
58
|
+
"asset"
|
|
59
|
+
];
|
|
60
|
+
function getFlag(flag, argv) {
|
|
61
|
+
const idx = argv.indexOf(flag);
|
|
62
|
+
return idx !== -1 && idx + 1 < argv.length ? argv[idx + 1] : undefined;
|
|
63
|
+
}
|
|
64
|
+
function getAllFlags(flag, argv) {
|
|
65
|
+
const values = [];
|
|
66
|
+
for (let i = 0;i < argv.length; i++) {
|
|
67
|
+
const next = argv[i + 1];
|
|
68
|
+
if (argv[i] === flag && next !== undefined) {
|
|
69
|
+
values.push(next);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return values;
|
|
73
|
+
}
|
|
74
|
+
function hasFlag(flag, argv) {
|
|
75
|
+
return argv.includes(flag);
|
|
76
|
+
}
|
|
77
|
+
function parseAppType(value) {
|
|
78
|
+
if (value === undefined)
|
|
79
|
+
return;
|
|
80
|
+
if (!APPLICATION_TYPES.includes(value)) {
|
|
81
|
+
throw new Error(`Invalid --type "${value}". Must be one of: ${APPLICATION_TYPES.join(", ")}`);
|
|
82
|
+
}
|
|
83
|
+
return value;
|
|
84
|
+
}
|
|
85
|
+
function parseEndpointType(value) {
|
|
86
|
+
if (value === undefined)
|
|
87
|
+
return;
|
|
88
|
+
if (!ENDPOINT_TYPES.includes(value)) {
|
|
89
|
+
throw new Error(`Invalid --type "${value}". Must be one of: ${ENDPOINT_TYPES.join(", ")}`);
|
|
90
|
+
}
|
|
91
|
+
return value;
|
|
92
|
+
}
|
|
93
|
+
function parseInteger(flag, value) {
|
|
94
|
+
if (value === undefined)
|
|
95
|
+
return;
|
|
96
|
+
const n = Number(value);
|
|
97
|
+
if (!Number.isFinite(n) || !Number.isInteger(n)) {
|
|
98
|
+
throw new Error(`${flag} must be an integer (got "${value}")`);
|
|
99
|
+
}
|
|
100
|
+
return n;
|
|
101
|
+
}
|
|
102
|
+
function parseNumber(flag, value) {
|
|
103
|
+
if (value === undefined)
|
|
104
|
+
return;
|
|
105
|
+
const n = Number(value);
|
|
106
|
+
if (!Number.isFinite(n)) {
|
|
107
|
+
throw new Error(`${flag} must be a number (got "${value}")`);
|
|
108
|
+
}
|
|
109
|
+
return n;
|
|
110
|
+
}
|
|
111
|
+
function showHelp() {
|
|
112
|
+
console.log(`pensar apps — Manage the workspace attack surface (apps & endpoints)
|
|
113
|
+
|
|
114
|
+
All commands operate on the selected workspace (set via \`pensar login\`).
|
|
115
|
+
|
|
116
|
+
Usage:
|
|
117
|
+
pensar apps List apps in the workspace
|
|
118
|
+
pensar apps get <appId> Show app details
|
|
119
|
+
pensar apps create [options] Create an app
|
|
120
|
+
pensar apps update <appId> [options] Update an app
|
|
121
|
+
pensar apps delete <appId> Delete an app
|
|
122
|
+
pensar apps endpoints <appId> [filters] List endpoints
|
|
123
|
+
pensar apps endpoint <endpointId> Show endpoint details
|
|
124
|
+
pensar apps endpoint-create <appId> [options] Create an endpoint
|
|
125
|
+
pensar apps endpoint-update <endpointId> [options] Update an endpoint
|
|
126
|
+
pensar apps endpoint-delete <endpointId> Delete an endpoint
|
|
127
|
+
pensar apps search <query> [options] Substring-search apps
|
|
128
|
+
pensar apps search-endpoints <query> [options] Substring-search endpoints
|
|
129
|
+
|
|
130
|
+
App fields (create requires --name and --description):
|
|
131
|
+
--name <text> Application name
|
|
132
|
+
--description <text> Application description
|
|
133
|
+
--type <type> One of: ${APPLICATION_TYPES.join(", ")}
|
|
134
|
+
--framework <text> Framework / runtime hint
|
|
135
|
+
--domain <id> Linked domain UUID
|
|
136
|
+
--disallowed-actions <text> Free-form disallowed actions notes
|
|
137
|
+
|
|
138
|
+
List pagination (for "apps" and "endpoints <appId>"):
|
|
139
|
+
--limit <n> Page size (default 100, max 200)
|
|
140
|
+
--offset <n> Page offset (default 0)
|
|
141
|
+
Responses include { ..., hasMore, limit, offset }; iterate by
|
|
142
|
+
incrementing --offset by --limit until hasMore is false.
|
|
143
|
+
|
|
144
|
+
Endpoint filters (for "endpoints"):
|
|
145
|
+
--type <type> One of: ${ENDPOINT_TYPES.join(", ")}
|
|
146
|
+
--min-risk <score> Minimum risk score (0–10)
|
|
147
|
+
|
|
148
|
+
Search options (scoped to the workspace):
|
|
149
|
+
--app <id> search-endpoints only: scope to a single app
|
|
150
|
+
--type <type> Filter by application or endpoint type
|
|
151
|
+
--min-risk <score> Endpoint search only: minimum risk score
|
|
152
|
+
--auth-required Endpoint search only: only auth-required endpoints
|
|
153
|
+
--no-auth-required Endpoint search only: only public endpoints
|
|
154
|
+
--limit <n> Page size (default 50, max 200)
|
|
155
|
+
--offset <n> Page offset
|
|
156
|
+
|
|
157
|
+
Endpoint fields (create requires --endpoint and --description):
|
|
158
|
+
--endpoint <text> Endpoint path / URL / route
|
|
159
|
+
--description <text> Endpoint description
|
|
160
|
+
--type <type> One of: ${ENDPOINT_TYPES.join(", ")}
|
|
161
|
+
--location <text> Source file (whitebox)
|
|
162
|
+
--start-line <n> Start line number
|
|
163
|
+
--end-line <n> End line number
|
|
164
|
+
--objective <text> Repeatable: testing objective for the endpoint
|
|
165
|
+
--auth-required Mark endpoint as authentication-required
|
|
166
|
+
--no-auth-required Mark endpoint as not requiring auth
|
|
167
|
+
--auth-details <text> Free-form auth details
|
|
168
|
+
--business-logic <text> Business-logic notes
|
|
169
|
+
--threat-model <text> Per-endpoint threat model notes
|
|
170
|
+
|
|
171
|
+
Options:
|
|
172
|
+
-h, --help Show this help message`);
|
|
173
|
+
}
|
|
174
|
+
function parseAppCreateOptions(argv) {
|
|
175
|
+
const name = getFlag("--name", argv);
|
|
176
|
+
const description = getFlag("--description", argv);
|
|
177
|
+
if (!name)
|
|
178
|
+
throw new Error("--name is required");
|
|
179
|
+
if (description === undefined)
|
|
180
|
+
throw new Error("--description is required");
|
|
181
|
+
const type = parseAppType(getFlag("--type", argv));
|
|
182
|
+
const framework = getFlag("--framework", argv);
|
|
183
|
+
const domainId = getFlag("--domain", argv);
|
|
184
|
+
const disallowedActions = getFlag("--disallowed-actions", argv);
|
|
185
|
+
return {
|
|
186
|
+
name,
|
|
187
|
+
description,
|
|
188
|
+
...type !== undefined ? { type } : {},
|
|
189
|
+
...framework !== undefined ? { framework } : {},
|
|
190
|
+
...domainId !== undefined ? { domainId } : {},
|
|
191
|
+
...disallowedActions !== undefined ? { disallowedActions } : {}
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
function parseAppUpdateOptions(argv) {
|
|
195
|
+
const update = {};
|
|
196
|
+
const name = getFlag("--name", argv);
|
|
197
|
+
if (name !== undefined)
|
|
198
|
+
update.name = name;
|
|
199
|
+
const description = getFlag("--description", argv);
|
|
200
|
+
if (description !== undefined)
|
|
201
|
+
update.description = description;
|
|
202
|
+
const type = parseAppType(getFlag("--type", argv));
|
|
203
|
+
if (type !== undefined)
|
|
204
|
+
update.type = type;
|
|
205
|
+
const framework = getFlag("--framework", argv);
|
|
206
|
+
if (framework !== undefined)
|
|
207
|
+
update.framework = framework;
|
|
208
|
+
const domain = getFlag("--domain", argv);
|
|
209
|
+
if (domain !== undefined)
|
|
210
|
+
update.domainId = domain;
|
|
211
|
+
const disallowed = getFlag("--disallowed-actions", argv);
|
|
212
|
+
if (disallowed !== undefined)
|
|
213
|
+
update.disallowedActions = disallowed;
|
|
214
|
+
return update;
|
|
215
|
+
}
|
|
216
|
+
function parseAuthenticationRequiredFlag(argv) {
|
|
217
|
+
const yes = hasFlag("--auth-required", argv);
|
|
218
|
+
const no = hasFlag("--no-auth-required", argv);
|
|
219
|
+
const details = getFlag("--auth-details", argv);
|
|
220
|
+
if (!yes && !no && details === undefined)
|
|
221
|
+
return;
|
|
222
|
+
if (yes && no) {
|
|
223
|
+
throw new Error("--auth-required and --no-auth-required are mutually exclusive");
|
|
224
|
+
}
|
|
225
|
+
return {
|
|
226
|
+
required: yes,
|
|
227
|
+
...details !== undefined ? { details } : {}
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
function parseEndpointCreateOptions(argv) {
|
|
231
|
+
const endpoint = getFlag("--endpoint", argv);
|
|
232
|
+
const description = getFlag("--description", argv);
|
|
233
|
+
if (!endpoint)
|
|
234
|
+
throw new Error("--endpoint is required");
|
|
235
|
+
if (description === undefined)
|
|
236
|
+
throw new Error("--description is required");
|
|
237
|
+
const type = parseEndpointType(getFlag("--type", argv));
|
|
238
|
+
const location = getFlag("--location", argv);
|
|
239
|
+
const startLineNumber = parseInteger("--start-line", getFlag("--start-line", argv));
|
|
240
|
+
const endLineNumber = parseInteger("--end-line", getFlag("--end-line", argv));
|
|
241
|
+
const objectives = getAllFlags("--objective", argv);
|
|
242
|
+
const authenticationRequired = parseAuthenticationRequiredFlag(argv);
|
|
243
|
+
const businessLogic = getFlag("--business-logic", argv);
|
|
244
|
+
const threatModel = getFlag("--threat-model", argv);
|
|
245
|
+
return {
|
|
246
|
+
endpoint,
|
|
247
|
+
description,
|
|
248
|
+
...type !== undefined ? { type } : {},
|
|
249
|
+
...location !== undefined ? { location } : {},
|
|
250
|
+
...startLineNumber !== undefined ? { startLineNumber } : {},
|
|
251
|
+
...endLineNumber !== undefined ? { endLineNumber } : {},
|
|
252
|
+
...objectives.length > 0 ? { objectives } : {},
|
|
253
|
+
...authenticationRequired !== undefined ? { authenticationRequired } : {},
|
|
254
|
+
...businessLogic !== undefined ? { businessLogic } : {},
|
|
255
|
+
...threatModel !== undefined ? { threatModel } : {}
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
function parseEndpointUpdateOptions(argv) {
|
|
259
|
+
const update = {};
|
|
260
|
+
const endpoint = getFlag("--endpoint", argv);
|
|
261
|
+
if (endpoint !== undefined)
|
|
262
|
+
update.endpoint = endpoint;
|
|
263
|
+
const description = getFlag("--description", argv);
|
|
264
|
+
if (description !== undefined)
|
|
265
|
+
update.description = description;
|
|
266
|
+
const type = parseEndpointType(getFlag("--type", argv));
|
|
267
|
+
if (type !== undefined)
|
|
268
|
+
update.type = type;
|
|
269
|
+
const location = getFlag("--location", argv);
|
|
270
|
+
if (location !== undefined)
|
|
271
|
+
update.location = location;
|
|
272
|
+
const startLine = parseInteger("--start-line", getFlag("--start-line", argv));
|
|
273
|
+
if (startLine !== undefined)
|
|
274
|
+
update.startLineNumber = startLine;
|
|
275
|
+
const endLine = parseInteger("--end-line", getFlag("--end-line", argv));
|
|
276
|
+
if (endLine !== undefined)
|
|
277
|
+
update.endLineNumber = endLine;
|
|
278
|
+
const objectives = getAllFlags("--objective", argv);
|
|
279
|
+
if (objectives.length > 0)
|
|
280
|
+
update.objectives = objectives;
|
|
281
|
+
const auth = parseAuthenticationRequiredFlag(argv);
|
|
282
|
+
if (auth !== undefined)
|
|
283
|
+
update.authenticationRequired = auth;
|
|
284
|
+
const businessLogic = getFlag("--business-logic", argv);
|
|
285
|
+
if (businessLogic !== undefined)
|
|
286
|
+
update.businessLogic = businessLogic;
|
|
287
|
+
const threatModel = getFlag("--threat-model", argv);
|
|
288
|
+
if (threatModel !== undefined)
|
|
289
|
+
update.threatModel = threatModel;
|
|
290
|
+
return update;
|
|
291
|
+
}
|
|
292
|
+
async function main() {
|
|
293
|
+
const args = process.argv.slice(2);
|
|
294
|
+
const sub = args[0];
|
|
295
|
+
if (sub === "--help" || sub === "-h" || sub === "help") {
|
|
296
|
+
showHelp();
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
299
|
+
try {
|
|
300
|
+
if (sub === "get") {
|
|
301
|
+
const appId = args[1];
|
|
302
|
+
if (!appId) {
|
|
303
|
+
console.error("Error: app ID is required");
|
|
304
|
+
console.error("Usage: pensar apps get <appId>");
|
|
305
|
+
process.exit(1);
|
|
306
|
+
}
|
|
307
|
+
const app = await getApp(appId);
|
|
308
|
+
console.log(JSON.stringify(app, null, 2));
|
|
309
|
+
} else if (sub === "create") {
|
|
310
|
+
const opts = parseAppCreateOptions(args);
|
|
311
|
+
const result = await createApp(opts);
|
|
312
|
+
console.log(JSON.stringify(result, null, 2));
|
|
313
|
+
} else if (sub === "update") {
|
|
314
|
+
const appId = args[1];
|
|
315
|
+
if (!appId) {
|
|
316
|
+
console.error("Error: app ID is required");
|
|
317
|
+
console.error("Usage: pensar apps update <appId> [options]");
|
|
318
|
+
process.exit(1);
|
|
319
|
+
}
|
|
320
|
+
const opts = parseAppUpdateOptions(args);
|
|
321
|
+
const result = await updateApp(appId, opts);
|
|
322
|
+
console.log(JSON.stringify(result, null, 2));
|
|
323
|
+
} else if (sub === "delete") {
|
|
324
|
+
const appId = args[1];
|
|
325
|
+
if (!appId) {
|
|
326
|
+
console.error("Error: app ID is required");
|
|
327
|
+
console.error("Usage: pensar apps delete <appId>");
|
|
328
|
+
process.exit(1);
|
|
329
|
+
}
|
|
330
|
+
const result = await deleteApp(appId);
|
|
331
|
+
console.log(JSON.stringify(result, null, 2));
|
|
332
|
+
} else if (sub === "endpoints") {
|
|
333
|
+
const appId = args[1];
|
|
334
|
+
if (!appId) {
|
|
335
|
+
console.error("Error: app ID is required");
|
|
336
|
+
console.error("Usage: pensar apps endpoints <appId> [filters]");
|
|
337
|
+
process.exit(1);
|
|
338
|
+
}
|
|
339
|
+
const type = parseEndpointType(getFlag("--type", args));
|
|
340
|
+
const minRiskScore = parseNumber("--min-risk", getFlag("--min-risk", args));
|
|
341
|
+
const limit = parseInteger("--limit", getFlag("--limit", args));
|
|
342
|
+
const offset = parseInteger("--offset", getFlag("--offset", args));
|
|
343
|
+
const filters = {
|
|
344
|
+
...type !== undefined ? { type } : {},
|
|
345
|
+
...minRiskScore !== undefined ? { minRiskScore } : {},
|
|
346
|
+
...limit !== undefined ? { limit } : {},
|
|
347
|
+
...offset !== undefined ? { offset } : {}
|
|
348
|
+
};
|
|
349
|
+
const result = await listEndpoints(appId, filters);
|
|
350
|
+
console.log(JSON.stringify(result, null, 2));
|
|
351
|
+
} else if (sub === "endpoint") {
|
|
352
|
+
const endpointId = args[1];
|
|
353
|
+
if (!endpointId) {
|
|
354
|
+
console.error("Error: endpoint ID is required");
|
|
355
|
+
console.error("Usage: pensar apps endpoint <endpointId>");
|
|
356
|
+
process.exit(1);
|
|
357
|
+
}
|
|
358
|
+
const result = await getEndpoint(endpointId);
|
|
359
|
+
console.log(JSON.stringify(result, null, 2));
|
|
360
|
+
} else if (sub === "endpoint-create") {
|
|
361
|
+
const appId = args[1];
|
|
362
|
+
if (!appId) {
|
|
363
|
+
console.error("Error: app ID is required");
|
|
364
|
+
console.error("Usage: pensar apps endpoint-create <appId> --endpoint E --description D");
|
|
365
|
+
process.exit(1);
|
|
366
|
+
}
|
|
367
|
+
const opts = parseEndpointCreateOptions(args);
|
|
368
|
+
const result = await createEndpoint(appId, opts);
|
|
369
|
+
console.log(JSON.stringify(result, null, 2));
|
|
370
|
+
} else if (sub === "endpoint-update") {
|
|
371
|
+
const endpointId = args[1];
|
|
372
|
+
if (!endpointId) {
|
|
373
|
+
console.error("Error: endpoint ID is required");
|
|
374
|
+
console.error("Usage: pensar apps endpoint-update <endpointId> [options]");
|
|
375
|
+
process.exit(1);
|
|
376
|
+
}
|
|
377
|
+
const opts = parseEndpointUpdateOptions(args);
|
|
378
|
+
const result = await updateEndpoint(endpointId, opts);
|
|
379
|
+
console.log(JSON.stringify(result, null, 2));
|
|
380
|
+
} else if (sub === "endpoint-delete") {
|
|
381
|
+
const endpointId = args[1];
|
|
382
|
+
if (!endpointId) {
|
|
383
|
+
console.error("Error: endpoint ID is required");
|
|
384
|
+
console.error("Usage: pensar apps endpoint-delete <endpointId>");
|
|
385
|
+
process.exit(1);
|
|
386
|
+
}
|
|
387
|
+
const result = await deleteEndpoint(endpointId);
|
|
388
|
+
console.log(JSON.stringify(result, null, 2));
|
|
389
|
+
} else if (sub === "search") {
|
|
390
|
+
const query = args[1];
|
|
391
|
+
if (!query || query.startsWith("--")) {
|
|
392
|
+
console.error("Error: search query is required");
|
|
393
|
+
console.error("Usage: pensar apps search <query> [options]");
|
|
394
|
+
process.exit(1);
|
|
395
|
+
}
|
|
396
|
+
const type = parseAppType(getFlag("--type", args));
|
|
397
|
+
const limit = parseInteger("--limit", getFlag("--limit", args));
|
|
398
|
+
const offset = parseInteger("--offset", getFlag("--offset", args));
|
|
399
|
+
const result = await searchApps(query, {
|
|
400
|
+
...type !== undefined ? { type } : {},
|
|
401
|
+
...limit !== undefined ? { limit } : {},
|
|
402
|
+
...offset !== undefined ? { offset } : {}
|
|
403
|
+
});
|
|
404
|
+
console.log(JSON.stringify(result, null, 2));
|
|
405
|
+
} else if (sub === "search-endpoints") {
|
|
406
|
+
const query = args[1];
|
|
407
|
+
if (!query || query.startsWith("--")) {
|
|
408
|
+
console.error("Error: search query is required");
|
|
409
|
+
console.error("Usage: pensar apps search-endpoints <query> [options]");
|
|
410
|
+
process.exit(1);
|
|
411
|
+
}
|
|
412
|
+
const applicationId = getFlag("--app", args);
|
|
413
|
+
const type = parseEndpointType(getFlag("--type", args));
|
|
414
|
+
const minRiskScore = parseNumber("--min-risk", getFlag("--min-risk", args));
|
|
415
|
+
const authRequired = hasFlag("--auth-required", args) ? true : hasFlag("--no-auth-required", args) ? false : undefined;
|
|
416
|
+
const limit = parseInteger("--limit", getFlag("--limit", args));
|
|
417
|
+
const offset = parseInteger("--offset", getFlag("--offset", args));
|
|
418
|
+
const result = await searchEndpoints(query, {
|
|
419
|
+
...applicationId !== undefined ? { applicationId } : {},
|
|
420
|
+
...type !== undefined ? { type } : {},
|
|
421
|
+
...minRiskScore !== undefined ? { minRiskScore } : {},
|
|
422
|
+
...authRequired !== undefined ? { authRequired } : {},
|
|
423
|
+
...limit !== undefined ? { limit } : {},
|
|
424
|
+
...offset !== undefined ? { offset } : {}
|
|
425
|
+
});
|
|
426
|
+
console.log(JSON.stringify(result, null, 2));
|
|
427
|
+
} else if (!sub || sub === "list" || sub.startsWith("--")) {
|
|
428
|
+
const limit = parseInteger("--limit", getFlag("--limit", args));
|
|
429
|
+
const offset = parseInteger("--offset", getFlag("--offset", args));
|
|
430
|
+
const result = await listApps({
|
|
431
|
+
...limit !== undefined ? { limit } : {},
|
|
432
|
+
...offset !== undefined ? { offset } : {}
|
|
433
|
+
});
|
|
434
|
+
console.log(JSON.stringify(result, null, 2));
|
|
435
|
+
} else {
|
|
436
|
+
console.error(`Error: Unknown subcommand "${sub}"`);
|
|
437
|
+
showHelp();
|
|
438
|
+
process.exit(1);
|
|
439
|
+
}
|
|
440
|
+
} catch (err) {
|
|
441
|
+
console.error(`
|
|
442
|
+
Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
443
|
+
process.exit(1);
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
main();
|
|
@@ -1,30 +1,53 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
|
+
import"./cli-q8dfq25x.js";
|
|
3
|
+
import"./cli-rhry8mat.js";
|
|
4
|
+
import"./cli-v9ds4jb8.js";
|
|
5
|
+
import"./cli-0tnv1vkp.js";
|
|
6
|
+
import"./cli-8frjr68r.js";
|
|
7
|
+
import"./cli-4xb21y6g.js";
|
|
8
|
+
import"./cli-abbka8n3.js";
|
|
9
|
+
import"./cli-9fsre5pt.js";
|
|
10
|
+
import"./cli-k0730f59.js";
|
|
11
|
+
import"./cli-wfmdch3r.js";
|
|
12
|
+
import"./cli-mswm4k81.js";
|
|
13
|
+
import"./cli-ryy39d77.js";
|
|
14
|
+
import"./cli-fw5r7pfj.js";
|
|
15
|
+
import"./cli-c8131c4q.js";
|
|
16
|
+
import"./cli-s1nckt4k.js";
|
|
17
|
+
import"./cli-87zakjb2.js";
|
|
18
|
+
import"./cli-6p7d2k55.js";
|
|
2
19
|
import {
|
|
3
20
|
disconnect,
|
|
4
21
|
fetchWorkspaces,
|
|
22
|
+
getPensarApiUrl,
|
|
23
|
+
getPensarConsoleUrl,
|
|
24
|
+
init_auth,
|
|
5
25
|
isConnected,
|
|
6
26
|
pollForWorkspaceCreation,
|
|
7
27
|
pollLegacyToken,
|
|
8
28
|
pollWorkOSToken,
|
|
9
29
|
selectWorkspace,
|
|
10
30
|
startDeviceFlow
|
|
11
|
-
} from "./cli-
|
|
31
|
+
} from "./cli-w5990vr6.js";
|
|
32
|
+
import"./cli-e6rgwtpb.js";
|
|
12
33
|
import {
|
|
13
34
|
config,
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
import"./cli-
|
|
18
|
-
import"./cli-
|
|
35
|
+
init_config
|
|
36
|
+
} from "./cli-9egg9azd.js";
|
|
37
|
+
import"./cli-gpnb45ck.js";
|
|
38
|
+
import"./cli-gtcd5c3f.js";
|
|
39
|
+
import"./cli-g5h24ny8.js";
|
|
19
40
|
import {
|
|
20
41
|
__require
|
|
21
42
|
} from "./cli-8rxa073f.js";
|
|
22
43
|
|
|
23
44
|
// src/cli/auth.ts
|
|
24
|
-
import * as readline from "readline";
|
|
45
|
+
import * as readline from "node:readline";
|
|
46
|
+
init_auth();
|
|
47
|
+
init_config();
|
|
25
48
|
function openUrl(url) {
|
|
26
49
|
try {
|
|
27
|
-
const { spawn } = __require("child_process");
|
|
50
|
+
const { spawn } = __require("node:child_process");
|
|
28
51
|
const platform = process.platform;
|
|
29
52
|
let cmd;
|
|
30
53
|
if (platform === "darwin") {
|
|
@@ -59,11 +82,16 @@ Select a workspace:
|
|
|
59
82
|
const answer = await prompt(`
|
|
60
83
|
Enter number (1-${workspaces.length}): `);
|
|
61
84
|
const index = parseInt(answer, 10) - 1;
|
|
62
|
-
if (isNaN(index) || index < 0 || index >= workspaces.length) {
|
|
85
|
+
if (Number.isNaN(index) || index < 0 || index >= workspaces.length) {
|
|
63
86
|
console.error("Invalid selection.");
|
|
64
87
|
process.exit(1);
|
|
65
88
|
}
|
|
66
|
-
|
|
89
|
+
const workspace = workspaces[index];
|
|
90
|
+
if (!workspace) {
|
|
91
|
+
console.error("Invalid selection.");
|
|
92
|
+
process.exit(1);
|
|
93
|
+
}
|
|
94
|
+
return workspace;
|
|
67
95
|
}
|
|
68
96
|
async function login() {
|
|
69
97
|
const appConfig = await config.get();
|
|
@@ -121,10 +149,15 @@ Waiting for browser authorization...`);
|
|
|
121
149
|
apiUrl,
|
|
122
150
|
deviceCode: deviceInfo.deviceCode,
|
|
123
151
|
interval: deviceInfo.interval,
|
|
124
|
-
expiresIn: deviceInfo.expiresIn
|
|
152
|
+
expiresIn: deviceInfo.expiresIn,
|
|
153
|
+
clientId: flowInfo.clientId
|
|
125
154
|
});
|
|
155
|
+
const apiKey = data.apiKey;
|
|
156
|
+
if (!apiKey) {
|
|
157
|
+
throw new Error("Pensar Console did not return an API key");
|
|
158
|
+
}
|
|
126
159
|
await config.update({
|
|
127
|
-
pensarAPIKey:
|
|
160
|
+
pensarAPIKey: apiKey,
|
|
128
161
|
gatewaySigningKey: data.signingKey ?? null
|
|
129
162
|
});
|
|
130
163
|
if (data.workspace) {
|
|
@@ -158,7 +191,11 @@ If the browser didn't open, visit: ${consoleUrl}/create-workspace?redirect=/cred
|
|
|
158
191
|
}
|
|
159
192
|
let workspace;
|
|
160
193
|
if (workspaces.length === 1) {
|
|
161
|
-
|
|
194
|
+
const onlyWorkspace = workspaces[0];
|
|
195
|
+
if (!onlyWorkspace) {
|
|
196
|
+
throw new Error("No workspace available after workspace lookup");
|
|
197
|
+
}
|
|
198
|
+
workspace = onlyWorkspace;
|
|
162
199
|
} else {
|
|
163
200
|
workspace = await promptWorkspaceSelection(workspaces);
|
|
164
201
|
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import {
|
|
2
|
+
runAuthenticationAgent
|
|
3
|
+
} from "./cli-8frjr68r.js";
|
|
4
|
+
import"./cli-9fsre5pt.js";
|
|
5
|
+
import"./cli-k0730f59.js";
|
|
6
|
+
import"./cli-wfmdch3r.js";
|
|
7
|
+
import"./cli-mswm4k81.js";
|
|
8
|
+
import"./cli-ryy39d77.js";
|
|
9
|
+
import"./cli-c8131c4q.js";
|
|
10
|
+
import"./cli-s1nckt4k.js";
|
|
11
|
+
import"./cli-87zakjb2.js";
|
|
12
|
+
import"./cli-6p7d2k55.js";
|
|
13
|
+
import"./cli-w5990vr6.js";
|
|
14
|
+
import"./cli-e6rgwtpb.js";
|
|
15
|
+
import"./cli-9egg9azd.js";
|
|
16
|
+
import"./cli-gpnb45ck.js";
|
|
17
|
+
import"./cli-gtcd5c3f.js";
|
|
18
|
+
import"./cli-g5h24ny8.js";
|
|
19
|
+
import"./cli-8rxa073f.js";
|
|
20
|
+
export {
|
|
21
|
+
runAuthenticationAgent
|
|
22
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BlackboxAttackSurfaceAgent
|
|
3
|
+
} from "./cli-v9ds4jb8.js";
|
|
4
|
+
import"./cli-9fsre5pt.js";
|
|
5
|
+
import"./cli-k0730f59.js";
|
|
6
|
+
import"./cli-wfmdch3r.js";
|
|
7
|
+
import"./cli-mswm4k81.js";
|
|
8
|
+
import"./cli-ryy39d77.js";
|
|
9
|
+
import"./cli-c8131c4q.js";
|
|
10
|
+
import"./cli-s1nckt4k.js";
|
|
11
|
+
import"./cli-87zakjb2.js";
|
|
12
|
+
import"./cli-6p7d2k55.js";
|
|
13
|
+
import"./cli-w5990vr6.js";
|
|
14
|
+
import"./cli-e6rgwtpb.js";
|
|
15
|
+
import"./cli-9egg9azd.js";
|
|
16
|
+
import"./cli-gpnb45ck.js";
|
|
17
|
+
import"./cli-gtcd5c3f.js";
|
|
18
|
+
import"./cli-g5h24ny8.js";
|
|
19
|
+
import"./cli-8rxa073f.js";
|
|
20
|
+
export {
|
|
21
|
+
BlackboxAttackSurfaceAgent
|
|
22
|
+
};
|
|
@@ -1,24 +1,26 @@
|
|
|
1
1
|
import {
|
|
2
2
|
runPentestWorkflow
|
|
3
|
-
} from "./cli-
|
|
4
|
-
import"./cli-
|
|
5
|
-
import"./cli-
|
|
6
|
-
import"./cli-
|
|
7
|
-
import"./cli-
|
|
3
|
+
} from "./cli-rhry8mat.js";
|
|
4
|
+
import"./cli-v9ds4jb8.js";
|
|
5
|
+
import"./cli-0tnv1vkp.js";
|
|
6
|
+
import"./cli-4xb21y6g.js";
|
|
7
|
+
import"./cli-abbka8n3.js";
|
|
8
|
+
import"./cli-9fsre5pt.js";
|
|
9
|
+
import"./cli-k0730f59.js";
|
|
10
|
+
import"./cli-wfmdch3r.js";
|
|
11
|
+
import"./cli-mswm4k81.js";
|
|
12
|
+
import"./cli-ryy39d77.js";
|
|
8
13
|
import"./cli-fw5r7pfj.js";
|
|
9
|
-
import"./cli-
|
|
10
|
-
import"./cli-
|
|
11
|
-
import"./cli-
|
|
12
|
-
import"./cli-
|
|
13
|
-
import"./cli-
|
|
14
|
-
import"./cli-
|
|
15
|
-
import"./cli-
|
|
16
|
-
import"./cli-dqt80sw3.js";
|
|
17
|
-
import"./cli-asyas1xb.js";
|
|
14
|
+
import"./cli-c8131c4q.js";
|
|
15
|
+
import"./cli-s1nckt4k.js";
|
|
16
|
+
import"./cli-87zakjb2.js";
|
|
17
|
+
import"./cli-6p7d2k55.js";
|
|
18
|
+
import"./cli-w5990vr6.js";
|
|
19
|
+
import"./cli-e6rgwtpb.js";
|
|
20
|
+
import"./cli-9egg9azd.js";
|
|
18
21
|
import"./cli-gpnb45ck.js";
|
|
19
|
-
import"./cli-
|
|
20
|
-
import"./cli-
|
|
21
|
-
import"./cli-03z6pswp.js";
|
|
22
|
+
import"./cli-gtcd5c3f.js";
|
|
23
|
+
import"./cli-g5h24ny8.js";
|
|
22
24
|
import"./cli-8rxa073f.js";
|
|
23
25
|
|
|
24
26
|
// src/core/api/blackboxPentest.ts
|