@positronic/cli 0.0.56 → 0.0.58
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/src/cli.js +139 -0
- package/dist/src/commands/auth.js +111 -0
- package/dist/src/commands/helpers.js +68 -8
- package/dist/src/commands/project-config-manager.js +119 -0
- package/dist/src/commands/users.js +91 -0
- package/dist/src/components/agent-chat-view.js +125 -0
- package/dist/src/components/auth-format-jwk-key.js +457 -0
- package/dist/src/components/auth-list.js +56 -0
- package/dist/src/components/auth-login.js +209 -0
- package/dist/src/components/auth-logout.js +75 -0
- package/dist/src/components/auth-status.js +88 -0
- package/dist/src/components/brain-run.js +287 -254
- package/dist/src/components/brain-top-table.js +4 -0
- package/dist/src/components/event-detail.js +364 -0
- package/dist/src/components/events-view.js +221 -25
- package/dist/src/components/state-view.js +52 -0
- package/dist/src/components/top-navigator.js +80 -6
- package/dist/src/components/types.js +1 -0
- package/dist/src/components/users-create.js +293 -0
- package/dist/src/components/users-delete.js +294 -0
- package/dist/src/components/users-keys-add.js +156 -0
- package/dist/src/components/users-keys-list.js +119 -0
- package/dist/src/components/users-keys-remove.js +299 -0
- package/dist/src/components/users-list.js +109 -0
- package/dist/src/components/watch-keyboard.js +136 -0
- package/dist/src/components/watch-machine.js +573 -0
- package/dist/src/components/watch.js +357 -44
- package/dist/src/hooks/useApi.js +217 -45
- package/dist/src/lib/request-signer.js +208 -0
- package/dist/src/lib/ssh-key-utils.js +212 -0
- package/dist/src/utils/agent-utils.js +107 -0
- package/dist/types/cli.d.ts.map +1 -1
- package/dist/types/commands/auth.d.ts +44 -0
- package/dist/types/commands/auth.d.ts.map +1 -0
- package/dist/types/commands/helpers.d.ts +4 -0
- package/dist/types/commands/helpers.d.ts.map +1 -1
- package/dist/types/commands/project-config-manager.d.ts +43 -0
- package/dist/types/commands/project-config-manager.d.ts.map +1 -1
- package/dist/types/commands/users.d.ts +33 -0
- package/dist/types/commands/users.d.ts.map +1 -0
- package/dist/types/components/agent-chat-view.d.ts +12 -0
- package/dist/types/components/agent-chat-view.d.ts.map +1 -0
- package/dist/types/components/auth-format-jwk-key.d.ts +6 -0
- package/dist/types/components/auth-format-jwk-key.d.ts.map +1 -0
- package/dist/types/components/auth-list.d.ts +7 -0
- package/dist/types/components/auth-list.d.ts.map +1 -0
- package/dist/types/components/auth-login.d.ts +9 -0
- package/dist/types/components/auth-login.d.ts.map +1 -0
- package/dist/types/components/auth-logout.d.ts +8 -0
- package/dist/types/components/auth-logout.d.ts.map +1 -0
- package/dist/types/components/auth-status.d.ts +7 -0
- package/dist/types/components/auth-status.d.ts.map +1 -0
- package/dist/types/components/brain-run.d.ts +11 -1
- package/dist/types/components/brain-run.d.ts.map +1 -1
- package/dist/types/components/brain-top-table.d.ts.map +1 -1
- package/dist/types/components/event-detail.d.ts +10 -0
- package/dist/types/components/event-detail.d.ts.map +1 -0
- package/dist/types/components/events-view.d.ts +9 -7
- package/dist/types/components/events-view.d.ts.map +1 -1
- package/dist/types/components/state-view.d.ts +13 -0
- package/dist/types/components/state-view.d.ts.map +1 -0
- package/dist/types/components/top-navigator.d.ts.map +1 -1
- package/dist/types/components/types.d.ts +11 -0
- package/dist/types/components/types.d.ts.map +1 -0
- package/dist/types/components/users-create.d.ts +6 -0
- package/dist/types/components/users-create.d.ts.map +1 -0
- package/dist/types/components/users-delete.d.ts +7 -0
- package/dist/types/components/users-delete.d.ts.map +1 -0
- package/dist/types/components/users-keys-add.d.ts +8 -0
- package/dist/types/components/users-keys-add.d.ts.map +1 -0
- package/dist/types/components/users-keys-list.d.ts +6 -0
- package/dist/types/components/users-keys-list.d.ts.map +1 -0
- package/dist/types/components/users-keys-remove.d.ts +8 -0
- package/dist/types/components/users-keys-remove.d.ts.map +1 -0
- package/dist/types/components/users-list.d.ts +2 -0
- package/dist/types/components/users-list.d.ts.map +1 -0
- package/dist/types/components/watch-keyboard.d.ts +56 -0
- package/dist/types/components/watch-keyboard.d.ts.map +1 -0
- package/dist/types/components/watch-machine.d.ts +171 -0
- package/dist/types/components/watch-machine.d.ts.map +1 -0
- package/dist/types/components/watch.d.ts.map +1 -1
- package/dist/types/hooks/useApi.d.ts.map +1 -1
- package/dist/types/hooks/useBrainMachine.d.ts +9 -3
- package/dist/types/hooks/useBrainMachine.d.ts.map +1 -1
- package/dist/types/lib/request-signer.d.ts +51 -0
- package/dist/types/lib/request-signer.d.ts.map +1 -0
- package/dist/types/lib/ssh-key-utils.d.ts +45 -0
- package/dist/types/lib/ssh-key-utils.d.ts.map +1 -0
- package/dist/types/utils/agent-utils.d.ts +20 -0
- package/dist/types/utils/agent-utils.d.ts.map +1 -0
- package/package.json +7 -4
package/dist/src/hooks/useApi.js
CHANGED
|
@@ -218,6 +218,16 @@ function _ts_generator(thisArg, body) {
|
|
|
218
218
|
}
|
|
219
219
|
import { useState, useEffect, useCallback } from 'react';
|
|
220
220
|
import { apiClient, isApiLocalDevMode } from '../commands/helpers.js';
|
|
221
|
+
var ROOT_KEY_NOT_CONFIGURED_ERROR = {
|
|
222
|
+
title: 'Root Key Not Configured',
|
|
223
|
+
message: 'The server does not have a root authentication key configured.',
|
|
224
|
+
details: "Run 'px auth format-jwk-key' to generate the key, then add ROOT_PUBLIC_KEY as a secret in your server configuration."
|
|
225
|
+
};
|
|
226
|
+
var AUTH_REQUIRED_ERROR = {
|
|
227
|
+
title: 'Authentication Required',
|
|
228
|
+
message: 'Your request could not be authenticated.',
|
|
229
|
+
details: "Run 'px auth login' to configure your SSH key, or check that your key is registered on the server."
|
|
230
|
+
};
|
|
221
231
|
function getConnectionErrorMessage() {
|
|
222
232
|
if (isApiLocalDevMode()) {
|
|
223
233
|
return {
|
|
@@ -233,6 +243,125 @@ function getConnectionErrorMessage() {
|
|
|
233
243
|
};
|
|
234
244
|
}
|
|
235
245
|
}
|
|
246
|
+
/**
|
|
247
|
+
* Fetch auth setup instructions from the server
|
|
248
|
+
*/ function fetchAuthSetupInstructions() {
|
|
249
|
+
return _async_to_generator(function() {
|
|
250
|
+
var response;
|
|
251
|
+
return _ts_generator(this, function(_state) {
|
|
252
|
+
switch(_state.label){
|
|
253
|
+
case 0:
|
|
254
|
+
return [
|
|
255
|
+
4,
|
|
256
|
+
apiClient.fetchUnauthenticated('/auth/setup')
|
|
257
|
+
];
|
|
258
|
+
case 1:
|
|
259
|
+
response = _state.sent();
|
|
260
|
+
if (!response.ok) return [
|
|
261
|
+
3,
|
|
262
|
+
3
|
|
263
|
+
];
|
|
264
|
+
return [
|
|
265
|
+
4,
|
|
266
|
+
response.json()
|
|
267
|
+
];
|
|
268
|
+
case 2:
|
|
269
|
+
return [
|
|
270
|
+
2,
|
|
271
|
+
_state.sent()
|
|
272
|
+
];
|
|
273
|
+
case 3:
|
|
274
|
+
return [
|
|
275
|
+
2,
|
|
276
|
+
null
|
|
277
|
+
];
|
|
278
|
+
}
|
|
279
|
+
});
|
|
280
|
+
})();
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Check if the error response indicates ROOT_KEY_NOT_CONFIGURED
|
|
284
|
+
*/ function isRootKeyNotConfiguredError(response) {
|
|
285
|
+
return _async_to_generator(function() {
|
|
286
|
+
var clonedResponse, data, e;
|
|
287
|
+
return _ts_generator(this, function(_state) {
|
|
288
|
+
switch(_state.label){
|
|
289
|
+
case 0:
|
|
290
|
+
_state.trys.push([
|
|
291
|
+
0,
|
|
292
|
+
2,
|
|
293
|
+
,
|
|
294
|
+
3
|
|
295
|
+
]);
|
|
296
|
+
clonedResponse = response.clone();
|
|
297
|
+
return [
|
|
298
|
+
4,
|
|
299
|
+
clonedResponse.json()
|
|
300
|
+
];
|
|
301
|
+
case 1:
|
|
302
|
+
data = _state.sent();
|
|
303
|
+
return [
|
|
304
|
+
2,
|
|
305
|
+
data.error === 'ROOT_KEY_NOT_CONFIGURED'
|
|
306
|
+
];
|
|
307
|
+
case 2:
|
|
308
|
+
e = _state.sent();
|
|
309
|
+
return [
|
|
310
|
+
2,
|
|
311
|
+
false
|
|
312
|
+
];
|
|
313
|
+
case 3:
|
|
314
|
+
return [
|
|
315
|
+
2
|
|
316
|
+
];
|
|
317
|
+
}
|
|
318
|
+
});
|
|
319
|
+
})();
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* Build the appropriate auth error based on the response
|
|
323
|
+
*/ function buildAuthError(response) {
|
|
324
|
+
return _async_to_generator(function() {
|
|
325
|
+
var setupInfo;
|
|
326
|
+
return _ts_generator(this, function(_state) {
|
|
327
|
+
switch(_state.label){
|
|
328
|
+
case 0:
|
|
329
|
+
return [
|
|
330
|
+
4,
|
|
331
|
+
isRootKeyNotConfiguredError(response)
|
|
332
|
+
];
|
|
333
|
+
case 1:
|
|
334
|
+
if (!_state.sent()) return [
|
|
335
|
+
3,
|
|
336
|
+
3
|
|
337
|
+
];
|
|
338
|
+
return [
|
|
339
|
+
4,
|
|
340
|
+
fetchAuthSetupInstructions()
|
|
341
|
+
];
|
|
342
|
+
case 2:
|
|
343
|
+
setupInfo = _state.sent();
|
|
344
|
+
if (setupInfo) {
|
|
345
|
+
return [
|
|
346
|
+
2,
|
|
347
|
+
_object_spread_props(_object_spread({}, ROOT_KEY_NOT_CONFIGURED_ERROR), {
|
|
348
|
+
details: setupInfo.instructions
|
|
349
|
+
})
|
|
350
|
+
];
|
|
351
|
+
}
|
|
352
|
+
return [
|
|
353
|
+
2,
|
|
354
|
+
ROOT_KEY_NOT_CONFIGURED_ERROR
|
|
355
|
+
];
|
|
356
|
+
case 3:
|
|
357
|
+
return [
|
|
358
|
+
2,
|
|
359
|
+
AUTH_REQUIRED_ERROR
|
|
360
|
+
];
|
|
361
|
+
}
|
|
362
|
+
});
|
|
363
|
+
})();
|
|
364
|
+
}
|
|
236
365
|
export function useApiGet(endpoint, options) {
|
|
237
366
|
var _useState = _sliced_to_array(useState(null), 2), data = _useState[0], setData = _useState[1];
|
|
238
367
|
var _useState1 = _sliced_to_array(useState(true), 2), loading = _useState1[0], setLoading = _useState1[1];
|
|
@@ -246,9 +375,9 @@ export function useApiGet(endpoint, options) {
|
|
|
246
375
|
case 0:
|
|
247
376
|
_state.trys.push([
|
|
248
377
|
0,
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
378
|
+
8,
|
|
379
|
+
9,
|
|
380
|
+
10
|
|
252
381
|
]);
|
|
253
382
|
setLoading(true);
|
|
254
383
|
setError(null);
|
|
@@ -273,27 +402,44 @@ export function useApiGet(endpoint, options) {
|
|
|
273
402
|
setData(result);
|
|
274
403
|
return [
|
|
275
404
|
3,
|
|
276
|
-
|
|
405
|
+
7
|
|
277
406
|
];
|
|
278
407
|
case 3:
|
|
408
|
+
if (!(response.status === 401)) return [
|
|
409
|
+
3,
|
|
410
|
+
5
|
|
411
|
+
];
|
|
279
412
|
return [
|
|
280
413
|
4,
|
|
281
|
-
response
|
|
414
|
+
buildAuthError(response)
|
|
282
415
|
];
|
|
283
416
|
case 4:
|
|
417
|
+
setError.apply(void 0, [
|
|
418
|
+
_state.sent()
|
|
419
|
+
]);
|
|
420
|
+
return [
|
|
421
|
+
3,
|
|
422
|
+
7
|
|
423
|
+
];
|
|
424
|
+
case 5:
|
|
425
|
+
return [
|
|
426
|
+
4,
|
|
427
|
+
response.text()
|
|
428
|
+
];
|
|
429
|
+
case 6:
|
|
284
430
|
errorText = _state.sent();
|
|
285
431
|
setError({
|
|
286
432
|
title: 'Server Error',
|
|
287
433
|
message: "Error fetching ".concat(endpoint, ": ").concat(response.status, " ").concat(response.statusText),
|
|
288
434
|
details: "Server response: ".concat(errorText)
|
|
289
435
|
});
|
|
290
|
-
_state.label =
|
|
291
|
-
case
|
|
436
|
+
_state.label = 7;
|
|
437
|
+
case 7:
|
|
292
438
|
return [
|
|
293
439
|
3,
|
|
294
|
-
|
|
440
|
+
10
|
|
295
441
|
];
|
|
296
|
-
case
|
|
442
|
+
case 8:
|
|
297
443
|
err = _state.sent();
|
|
298
444
|
baseError = getConnectionErrorMessage();
|
|
299
445
|
errorDetails = err.message;
|
|
@@ -305,14 +451,14 @@ export function useApiGet(endpoint, options) {
|
|
|
305
451
|
}));
|
|
306
452
|
return [
|
|
307
453
|
3,
|
|
308
|
-
|
|
454
|
+
10
|
|
309
455
|
];
|
|
310
|
-
case
|
|
456
|
+
case 9:
|
|
311
457
|
setLoading(false);
|
|
312
458
|
return [
|
|
313
459
|
7
|
|
314
460
|
];
|
|
315
|
-
case
|
|
461
|
+
case 10:
|
|
316
462
|
return [
|
|
317
463
|
2
|
|
318
464
|
];
|
|
@@ -336,15 +482,15 @@ export function useApiPost(endpoint, defaultOptions) {
|
|
|
336
482
|
var _useState2 = _sliced_to_array(useState(null), 2), error = _useState2[0], setError = _useState2[1];
|
|
337
483
|
var execute = useCallback(function(body, options) {
|
|
338
484
|
return _async_to_generator(function() {
|
|
339
|
-
var response, result, errorText,
|
|
485
|
+
var response, result, errorObj, errorText, errorObj1, err, baseError, errorDetails, errorObj2;
|
|
340
486
|
return _ts_generator(this, function(_state) {
|
|
341
487
|
switch(_state.label){
|
|
342
488
|
case 0:
|
|
343
489
|
_state.trys.push([
|
|
344
490
|
0,
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
491
|
+
8,
|
|
492
|
+
9,
|
|
493
|
+
10
|
|
348
494
|
]);
|
|
349
495
|
setLoading(true);
|
|
350
496
|
setError(null);
|
|
@@ -358,7 +504,7 @@ export function useApiPost(endpoint, defaultOptions) {
|
|
|
358
504
|
];
|
|
359
505
|
case 1:
|
|
360
506
|
response = _state.sent();
|
|
361
|
-
if (!(response.status === 200 || response.status === 201)) return [
|
|
507
|
+
if (!(response.status === 200 || response.status === 201 || response.status === 202)) return [
|
|
362
508
|
3,
|
|
363
509
|
3
|
|
364
510
|
];
|
|
@@ -374,25 +520,38 @@ export function useApiPost(endpoint, defaultOptions) {
|
|
|
374
520
|
result
|
|
375
521
|
];
|
|
376
522
|
case 3:
|
|
523
|
+
if (!(response.status === 401)) return [
|
|
524
|
+
3,
|
|
525
|
+
5
|
|
526
|
+
];
|
|
377
527
|
return [
|
|
378
528
|
4,
|
|
379
|
-
response
|
|
529
|
+
buildAuthError(response)
|
|
380
530
|
];
|
|
381
531
|
case 4:
|
|
532
|
+
errorObj = _state.sent();
|
|
533
|
+
setError(errorObj);
|
|
534
|
+
throw errorObj;
|
|
535
|
+
case 5:
|
|
536
|
+
return [
|
|
537
|
+
4,
|
|
538
|
+
response.text()
|
|
539
|
+
];
|
|
540
|
+
case 6:
|
|
382
541
|
errorText = _state.sent();
|
|
383
|
-
|
|
542
|
+
errorObj1 = {
|
|
384
543
|
title: 'Server Error',
|
|
385
544
|
message: "Error posting to ".concat(endpoint, ": ").concat(response.status, " ").concat(response.statusText),
|
|
386
545
|
details: "Server response: ".concat(errorText)
|
|
387
546
|
};
|
|
388
|
-
setError(
|
|
389
|
-
throw
|
|
390
|
-
case
|
|
547
|
+
setError(errorObj1);
|
|
548
|
+
throw errorObj1;
|
|
549
|
+
case 7:
|
|
391
550
|
return [
|
|
392
551
|
3,
|
|
393
|
-
|
|
552
|
+
10
|
|
394
553
|
];
|
|
395
|
-
case
|
|
554
|
+
case 8:
|
|
396
555
|
err = _state.sent();
|
|
397
556
|
// If it's already our error object, don't wrap it again
|
|
398
557
|
if (err.title && err.message) {
|
|
@@ -404,17 +563,17 @@ export function useApiPost(endpoint, defaultOptions) {
|
|
|
404
563
|
if (err.code === 'ECONNREFUSED') {
|
|
405
564
|
errorDetails = 'Connection refused. The server might not be running or is listening on a different port.';
|
|
406
565
|
}
|
|
407
|
-
|
|
566
|
+
errorObj2 = _object_spread_props(_object_spread({}, baseError), {
|
|
408
567
|
details: "".concat(baseError.details, " ").concat(errorDetails)
|
|
409
568
|
});
|
|
410
|
-
setError(
|
|
411
|
-
throw
|
|
412
|
-
case
|
|
569
|
+
setError(errorObj2);
|
|
570
|
+
throw errorObj2;
|
|
571
|
+
case 9:
|
|
413
572
|
setLoading(false);
|
|
414
573
|
return [
|
|
415
574
|
7
|
|
416
575
|
];
|
|
417
|
-
case
|
|
576
|
+
case 10:
|
|
418
577
|
return [
|
|
419
578
|
2
|
|
420
579
|
];
|
|
@@ -437,15 +596,15 @@ export function useApiDelete(resourceType) {
|
|
|
437
596
|
var _useState1 = _sliced_to_array(useState(null), 2), error = _useState1[0], setError = _useState1[1];
|
|
438
597
|
var execute = useCallback(function(endpoint, options) {
|
|
439
598
|
return _async_to_generator(function() {
|
|
440
|
-
var response, errorText,
|
|
599
|
+
var response, errorObj, errorText, errorObj1, err, baseError, errorDetails, errorObj2;
|
|
441
600
|
return _ts_generator(this, function(_state) {
|
|
442
601
|
switch(_state.label){
|
|
443
602
|
case 0:
|
|
444
603
|
_state.trys.push([
|
|
445
604
|
0,
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
605
|
+
7,
|
|
606
|
+
8,
|
|
607
|
+
9
|
|
449
608
|
]);
|
|
450
609
|
setLoading(true);
|
|
451
610
|
setError(null);
|
|
@@ -466,25 +625,38 @@ export function useApiDelete(resourceType) {
|
|
|
466
625
|
true
|
|
467
626
|
];
|
|
468
627
|
case 2:
|
|
628
|
+
if (!(response.status === 401)) return [
|
|
629
|
+
3,
|
|
630
|
+
4
|
|
631
|
+
];
|
|
469
632
|
return [
|
|
470
633
|
4,
|
|
471
|
-
response
|
|
634
|
+
buildAuthError(response)
|
|
472
635
|
];
|
|
473
636
|
case 3:
|
|
637
|
+
errorObj = _state.sent();
|
|
638
|
+
setError(errorObj);
|
|
639
|
+
throw errorObj;
|
|
640
|
+
case 4:
|
|
641
|
+
return [
|
|
642
|
+
4,
|
|
643
|
+
response.text()
|
|
644
|
+
];
|
|
645
|
+
case 5:
|
|
474
646
|
errorText = _state.sent();
|
|
475
|
-
|
|
647
|
+
errorObj1 = {
|
|
476
648
|
title: 'Server Error',
|
|
477
649
|
message: "Error deleting ".concat(resourceType, ": ").concat(response.status, " ").concat(response.statusText),
|
|
478
650
|
details: "Server response: ".concat(errorText)
|
|
479
651
|
};
|
|
480
|
-
setError(
|
|
481
|
-
throw
|
|
482
|
-
case
|
|
652
|
+
setError(errorObj1);
|
|
653
|
+
throw errorObj1;
|
|
654
|
+
case 6:
|
|
483
655
|
return [
|
|
484
656
|
3,
|
|
485
|
-
|
|
657
|
+
9
|
|
486
658
|
];
|
|
487
|
-
case
|
|
659
|
+
case 7:
|
|
488
660
|
err = _state.sent();
|
|
489
661
|
// If it's already our error object, don't wrap it again
|
|
490
662
|
if (err.title && err.message) {
|
|
@@ -496,17 +668,17 @@ export function useApiDelete(resourceType) {
|
|
|
496
668
|
if (err.code === 'ECONNREFUSED') {
|
|
497
669
|
errorDetails = 'Connection refused. The server might not be running or is listening on a different port.';
|
|
498
670
|
}
|
|
499
|
-
|
|
671
|
+
errorObj2 = _object_spread_props(_object_spread({}, baseError), {
|
|
500
672
|
details: "".concat(baseError.details, " ").concat(errorDetails)
|
|
501
673
|
});
|
|
502
|
-
setError(
|
|
503
|
-
throw
|
|
504
|
-
case
|
|
674
|
+
setError(errorObj2);
|
|
675
|
+
throw errorObj2;
|
|
676
|
+
case 8:
|
|
505
677
|
setLoading(false);
|
|
506
678
|
return [
|
|
507
679
|
7
|
|
508
680
|
];
|
|
509
|
-
case
|
|
681
|
+
case 9:
|
|
510
682
|
return [
|
|
511
683
|
2
|
|
512
684
|
];
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
function _class_call_check(instance, Constructor) {
|
|
2
|
+
if (!(instance instanceof Constructor)) {
|
|
3
|
+
throw new TypeError("Cannot call a class as a function");
|
|
4
|
+
}
|
|
5
|
+
}
|
|
6
|
+
function _defineProperties(target, props) {
|
|
7
|
+
for(var i = 0; i < props.length; i++){
|
|
8
|
+
var descriptor = props[i];
|
|
9
|
+
descriptor.enumerable = descriptor.enumerable || false;
|
|
10
|
+
descriptor.configurable = true;
|
|
11
|
+
if ("value" in descriptor) descriptor.writable = true;
|
|
12
|
+
Object.defineProperty(target, descriptor.key, descriptor);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
function _create_class(Constructor, protoProps, staticProps) {
|
|
16
|
+
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
|
|
17
|
+
if (staticProps) _defineProperties(Constructor, staticProps);
|
|
18
|
+
return Constructor;
|
|
19
|
+
}
|
|
20
|
+
function _define_property(obj, key, value) {
|
|
21
|
+
if (key in obj) {
|
|
22
|
+
Object.defineProperty(obj, key, {
|
|
23
|
+
value: value,
|
|
24
|
+
enumerable: true,
|
|
25
|
+
configurable: true,
|
|
26
|
+
writable: true
|
|
27
|
+
});
|
|
28
|
+
} else {
|
|
29
|
+
obj[key] = value;
|
|
30
|
+
}
|
|
31
|
+
return obj;
|
|
32
|
+
}
|
|
33
|
+
function _instanceof(left, right) {
|
|
34
|
+
if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
|
|
35
|
+
return !!right[Symbol.hasInstance](left);
|
|
36
|
+
} else {
|
|
37
|
+
return left instanceof right;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
import { loadPrivateKey, getPrivateKeyFingerprint, signWithPrivateKey, resolvePrivateKeyPath } from './ssh-key-utils.js';
|
|
41
|
+
import { existsSync } from 'fs';
|
|
42
|
+
import { ProjectConfigManager } from '../commands/project-config-manager.js';
|
|
43
|
+
/**
|
|
44
|
+
* Request signer for RFC 9421 HTTP Message Signatures
|
|
45
|
+
*/ export var RequestSigner = /*#__PURE__*/ function() {
|
|
46
|
+
"use strict";
|
|
47
|
+
function RequestSigner() {
|
|
48
|
+
_class_call_check(this, RequestSigner);
|
|
49
|
+
_define_property(this, "privateKey", null);
|
|
50
|
+
_define_property(this, "fingerprint", null);
|
|
51
|
+
_define_property(this, "initialized", false);
|
|
52
|
+
_define_property(this, "initError", null);
|
|
53
|
+
this.initialize();
|
|
54
|
+
}
|
|
55
|
+
_create_class(RequestSigner, [
|
|
56
|
+
{
|
|
57
|
+
key: "initialize",
|
|
58
|
+
value: function initialize() {
|
|
59
|
+
try {
|
|
60
|
+
// Get configured path from project config manager
|
|
61
|
+
var configManager = new ProjectConfigManager();
|
|
62
|
+
var configuredPath = configManager.getPrivateKeyPath();
|
|
63
|
+
var keyPath = resolvePrivateKeyPath(configuredPath);
|
|
64
|
+
if (!existsSync(keyPath)) {
|
|
65
|
+
this.initError = new Error("Private key not found at ".concat(keyPath, ". Run 'px auth login' to configure your SSH key, or set POSITRONIC_PRIVATE_KEY environment variable."));
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
this.privateKey = loadPrivateKey(keyPath);
|
|
69
|
+
this.fingerprint = getPrivateKeyFingerprint(this.privateKey);
|
|
70
|
+
this.initialized = true;
|
|
71
|
+
} catch (error) {
|
|
72
|
+
this.initError = _instanceof(error, Error) ? error : new Error('Failed to initialize request signer');
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
/**
|
|
78
|
+
* Check if the signer is ready to sign requests
|
|
79
|
+
*/ key: "isReady",
|
|
80
|
+
value: function isReady() {
|
|
81
|
+
return this.initialized && this.privateKey !== null;
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
/**
|
|
86
|
+
* Get the error that occurred during initialization, if any
|
|
87
|
+
*/ key: "getError",
|
|
88
|
+
value: function getError() {
|
|
89
|
+
return this.initError;
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
/**
|
|
94
|
+
* Get the fingerprint of the loaded private key
|
|
95
|
+
*/ key: "getFingerprint",
|
|
96
|
+
value: function getFingerprint() {
|
|
97
|
+
return this.fingerprint;
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
/**
|
|
102
|
+
* Sign an HTTP request and return the signature headers
|
|
103
|
+
*/ key: "signRequest",
|
|
104
|
+
value: function signRequest(method, url) {
|
|
105
|
+
var headers = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : {};
|
|
106
|
+
if (!this.privateKey || !this.fingerprint) {
|
|
107
|
+
throw new Error('Request signer not initialized');
|
|
108
|
+
}
|
|
109
|
+
var parsedUrl = new URL(url);
|
|
110
|
+
var created = Math.floor(Date.now() / 1000);
|
|
111
|
+
// Build the signature base
|
|
112
|
+
var coveredComponents = [
|
|
113
|
+
'"@method"',
|
|
114
|
+
'"@path"',
|
|
115
|
+
'"@authority"'
|
|
116
|
+
];
|
|
117
|
+
// Add content-type if present
|
|
118
|
+
if (headers['Content-Type'] || headers['content-type']) {
|
|
119
|
+
coveredComponents.push('"content-type"');
|
|
120
|
+
}
|
|
121
|
+
// Create the signature base string
|
|
122
|
+
var signatureBaseLines = [];
|
|
123
|
+
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
124
|
+
try {
|
|
125
|
+
for(var _iterator = coveredComponents[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
126
|
+
var component = _step.value;
|
|
127
|
+
var componentName = component.replace(/"/g, '');
|
|
128
|
+
if (componentName === '@method') {
|
|
129
|
+
signatureBaseLines.push('"@method": '.concat(method.toUpperCase()));
|
|
130
|
+
} else if (componentName === '@path') {
|
|
131
|
+
signatureBaseLines.push('"@path": '.concat(parsedUrl.pathname));
|
|
132
|
+
} else if (componentName === '@authority') {
|
|
133
|
+
signatureBaseLines.push('"@authority": '.concat(parsedUrl.host));
|
|
134
|
+
} else {
|
|
135
|
+
// Regular header
|
|
136
|
+
var headerValue = headers[componentName] || headers[componentName.toLowerCase()] || headers[componentName.charAt(0).toUpperCase() + componentName.slice(1)];
|
|
137
|
+
if (headerValue) {
|
|
138
|
+
signatureBaseLines.push('"'.concat(componentName.toLowerCase(), '": ').concat(headerValue));
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
} catch (err) {
|
|
143
|
+
_didIteratorError = true;
|
|
144
|
+
_iteratorError = err;
|
|
145
|
+
} finally{
|
|
146
|
+
try {
|
|
147
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
148
|
+
_iterator.return();
|
|
149
|
+
}
|
|
150
|
+
} finally{
|
|
151
|
+
if (_didIteratorError) {
|
|
152
|
+
throw _iteratorError;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
// Create the signature-params line
|
|
157
|
+
var signatureParams = "(".concat(coveredComponents.join(' '), ");created=").concat(created, ';keyid="').concat(this.fingerprint, '"');
|
|
158
|
+
signatureBaseLines.push('"@signature-params": '.concat(signatureParams));
|
|
159
|
+
var signatureBase = signatureBaseLines.join('\n');
|
|
160
|
+
// Sign the base
|
|
161
|
+
var signatureBytes = signWithPrivateKey(this.privateKey, signatureBase);
|
|
162
|
+
var signatureValue = signatureBytes.toString('base64');
|
|
163
|
+
return {
|
|
164
|
+
Signature: "sig1=:".concat(signatureValue, ":"),
|
|
165
|
+
'Signature-Input': "sig1=".concat(signatureParams)
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
]);
|
|
170
|
+
return RequestSigner;
|
|
171
|
+
}();
|
|
172
|
+
// Singleton instance
|
|
173
|
+
var signerInstance = null;
|
|
174
|
+
/**
|
|
175
|
+
* Get the singleton request signer instance
|
|
176
|
+
*/ export function getRequestSigner() {
|
|
177
|
+
if (!signerInstance) {
|
|
178
|
+
signerInstance = new RequestSigner();
|
|
179
|
+
}
|
|
180
|
+
return signerInstance;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Reset the request signer singleton
|
|
184
|
+
* Call this after auth config changes to force reinitialization with new key
|
|
185
|
+
*/ export function resetRequestSigner() {
|
|
186
|
+
signerInstance = null;
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Check if request signing is available
|
|
190
|
+
*/ export function isSigningAvailable() {
|
|
191
|
+
return getRequestSigner().isReady();
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Sign an HTTP request if signing is available
|
|
195
|
+
* Returns the additional headers to add, or empty object if signing is not available
|
|
196
|
+
*/ export function maybeSignRequest(method, url) {
|
|
197
|
+
var headers = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : {};
|
|
198
|
+
var signer = getRequestSigner();
|
|
199
|
+
if (!signer.isReady()) {
|
|
200
|
+
return {};
|
|
201
|
+
}
|
|
202
|
+
try {
|
|
203
|
+
return signer.signRequest(method, url, headers);
|
|
204
|
+
} catch (error) {
|
|
205
|
+
console.error('Warning: Failed to sign request:', error);
|
|
206
|
+
return {};
|
|
207
|
+
}
|
|
208
|
+
}
|