@positronic/cli 0.0.58 → 0.0.59
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/commands/helpers.js +47 -36
- package/dist/src/components/auth-login.js +3 -3
- package/dist/src/components/auth-logout.js +3 -3
- package/dist/src/lib/jwt-auth.js +364 -0
- package/dist/src/lib/ssh-key-utils.js +0 -9
- package/dist/types/commands/helpers.d.ts.map +1 -1
- package/dist/types/lib/jwt-auth.d.ts +51 -0
- package/dist/types/lib/jwt-auth.d.ts.map +1 -0
- package/dist/types/lib/ssh-key-utils.d.ts +0 -4
- package/dist/types/lib/ssh-key-utils.d.ts.map +1 -1
- package/package.json +5 -4
- package/dist/src/lib/request-signer.js +0 -208
- package/dist/types/lib/request-signer.d.ts +0 -51
- package/dist/types/lib/request-signer.d.ts.map +0 -1
|
@@ -233,7 +233,7 @@ import * as https from 'https';
|
|
|
233
233
|
import { URL } from 'url';
|
|
234
234
|
import { createRequire } from 'module';
|
|
235
235
|
import * as dotenv from 'dotenv';
|
|
236
|
-
import {
|
|
236
|
+
import { getAuthHeader } from '../lib/jwt-auth.js';
|
|
237
237
|
// API client configuration
|
|
238
238
|
var apiBaseUrl = null;
|
|
239
239
|
var isLocalDevMode = true;
|
|
@@ -267,44 +267,55 @@ var isLocalDevMode = true;
|
|
|
267
267
|
export var apiClient = {
|
|
268
268
|
fetch: function(apiPath, options) {
|
|
269
269
|
return _async_to_generator(function() {
|
|
270
|
-
var baseUrl, port, fullUrl, requestOptions,
|
|
270
|
+
var baseUrl, port, fullUrl, requestOptions, existingHeaders, headersObj, authHeader;
|
|
271
271
|
return _ts_generator(this, function(_state) {
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
existingHeaders
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
272
|
+
switch(_state.label){
|
|
273
|
+
case 0:
|
|
274
|
+
if (apiBaseUrl) {
|
|
275
|
+
baseUrl = apiBaseUrl;
|
|
276
|
+
} else {
|
|
277
|
+
// Fallback to localhost (for backwards compatibility and testing)
|
|
278
|
+
port = process.env.POSITRONIC_PORT || '8787';
|
|
279
|
+
baseUrl = "http://localhost:".concat(port);
|
|
280
|
+
}
|
|
281
|
+
fullUrl = "".concat(baseUrl).concat(apiPath.startsWith('/') ? apiPath : '/' + apiPath);
|
|
282
|
+
// Add auth header when not in local dev mode
|
|
283
|
+
requestOptions = options || {};
|
|
284
|
+
if (!!isLocalDevMode) return [
|
|
285
|
+
3,
|
|
286
|
+
2
|
|
287
|
+
];
|
|
288
|
+
existingHeaders = (options === null || options === void 0 ? void 0 : options.headers) || {};
|
|
289
|
+
headersObj = {};
|
|
290
|
+
// Convert headers to plain object
|
|
291
|
+
if (_instanceof(existingHeaders, Headers)) {
|
|
292
|
+
existingHeaders.forEach(function(value, key) {
|
|
293
|
+
headersObj[key] = value;
|
|
294
|
+
});
|
|
295
|
+
} else if (Array.isArray(existingHeaders)) {
|
|
296
|
+
existingHeaders.forEach(function(param) {
|
|
297
|
+
var _param = _sliced_to_array(param, 2), key = _param[0], value = _param[1];
|
|
298
|
+
headersObj[key] = value;
|
|
299
|
+
});
|
|
300
|
+
} else {
|
|
301
|
+
Object.assign(headersObj, existingHeaders);
|
|
302
|
+
}
|
|
303
|
+
return [
|
|
304
|
+
4,
|
|
305
|
+
getAuthHeader()
|
|
306
|
+
];
|
|
307
|
+
case 1:
|
|
308
|
+
authHeader = _state.sent();
|
|
309
|
+
requestOptions = _object_spread_props(_object_spread({}, options), {
|
|
310
|
+
headers: _object_spread({}, headersObj, authHeader)
|
|
295
311
|
});
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
});
|
|
312
|
+
_state.label = 2;
|
|
313
|
+
case 2:
|
|
314
|
+
return [
|
|
315
|
+
2,
|
|
316
|
+
fetch(fullUrl, requestOptions)
|
|
317
|
+
];
|
|
303
318
|
}
|
|
304
|
-
return [
|
|
305
|
-
2,
|
|
306
|
-
fetch(fullUrl, requestOptions)
|
|
307
|
-
];
|
|
308
319
|
});
|
|
309
320
|
})();
|
|
310
321
|
},
|
|
@@ -47,7 +47,7 @@ function _unsupported_iterable_to_array(o, minLen) {
|
|
|
47
47
|
import React, { useState } from 'react';
|
|
48
48
|
import { Box, Text, useApp } from 'ink';
|
|
49
49
|
import { discoverSSHKeys, expandPath } from '../lib/ssh-key-utils.js';
|
|
50
|
-
import {
|
|
50
|
+
import { resetJwtAuthProvider } from '../lib/jwt-auth.js';
|
|
51
51
|
import { SelectList } from './select-list.js';
|
|
52
52
|
import { existsSync } from 'fs';
|
|
53
53
|
export var AuthLogin = function(param) {
|
|
@@ -103,7 +103,7 @@ export var AuthLogin = function(param) {
|
|
|
103
103
|
configManager.setDefaultPrivateKeyPath(keyPath);
|
|
104
104
|
}
|
|
105
105
|
// Reset request signer to use new key
|
|
106
|
-
|
|
106
|
+
resetJwtAuthProvider();
|
|
107
107
|
return /*#__PURE__*/ React.createElement(Box, {
|
|
108
108
|
flexDirection: "column",
|
|
109
109
|
paddingTop: 1,
|
|
@@ -163,7 +163,7 @@ export var AuthLogin = function(param) {
|
|
|
163
163
|
configManager.setDefaultPrivateKeyPath(displayPath);
|
|
164
164
|
}
|
|
165
165
|
// Reset request signer to use new key
|
|
166
|
-
|
|
166
|
+
resetJwtAuthProvider();
|
|
167
167
|
setSelectedPath(displayPath);
|
|
168
168
|
setState('success');
|
|
169
169
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { Box, Text } from 'ink';
|
|
3
|
-
import {
|
|
3
|
+
import { resetJwtAuthProvider } from '../lib/jwt-auth.js';
|
|
4
4
|
export var AuthLogout = function(param) {
|
|
5
5
|
var configManager = param.configManager, forProject = param.forProject;
|
|
6
6
|
var currentProject = configManager.getCurrentProject();
|
|
@@ -33,7 +33,7 @@ export var AuthLogout = function(param) {
|
|
|
33
33
|
}, "Nothing to clear.")));
|
|
34
34
|
}
|
|
35
35
|
configManager.clearProjectPrivateKeyPath(currentProject.name);
|
|
36
|
-
|
|
36
|
+
resetJwtAuthProvider();
|
|
37
37
|
return /*#__PURE__*/ React.createElement(Box, {
|
|
38
38
|
flexDirection: "column",
|
|
39
39
|
paddingTop: 1,
|
|
@@ -60,7 +60,7 @@ export var AuthLogout = function(param) {
|
|
|
60
60
|
}, "Nothing to clear.")));
|
|
61
61
|
}
|
|
62
62
|
configManager.clearDefaultPrivateKeyPath();
|
|
63
|
-
|
|
63
|
+
resetJwtAuthProvider();
|
|
64
64
|
return /*#__PURE__*/ React.createElement(Box, {
|
|
65
65
|
flexDirection: "column",
|
|
66
66
|
paddingTop: 1,
|
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
|
|
2
|
+
try {
|
|
3
|
+
var info = gen[key](arg);
|
|
4
|
+
var value = info.value;
|
|
5
|
+
} catch (error) {
|
|
6
|
+
reject(error);
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
if (info.done) {
|
|
10
|
+
resolve(value);
|
|
11
|
+
} else {
|
|
12
|
+
Promise.resolve(value).then(_next, _throw);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
function _async_to_generator(fn) {
|
|
16
|
+
return function() {
|
|
17
|
+
var self = this, args = arguments;
|
|
18
|
+
return new Promise(function(resolve, reject) {
|
|
19
|
+
var gen = fn.apply(self, args);
|
|
20
|
+
function _next(value) {
|
|
21
|
+
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
|
|
22
|
+
}
|
|
23
|
+
function _throw(err) {
|
|
24
|
+
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
|
|
25
|
+
}
|
|
26
|
+
_next(undefined);
|
|
27
|
+
});
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
function _class_call_check(instance, Constructor) {
|
|
31
|
+
if (!(instance instanceof Constructor)) {
|
|
32
|
+
throw new TypeError("Cannot call a class as a function");
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
function _defineProperties(target, props) {
|
|
36
|
+
for(var i = 0; i < props.length; i++){
|
|
37
|
+
var descriptor = props[i];
|
|
38
|
+
descriptor.enumerable = descriptor.enumerable || false;
|
|
39
|
+
descriptor.configurable = true;
|
|
40
|
+
if ("value" in descriptor) descriptor.writable = true;
|
|
41
|
+
Object.defineProperty(target, descriptor.key, descriptor);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
function _create_class(Constructor, protoProps, staticProps) {
|
|
45
|
+
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
|
|
46
|
+
if (staticProps) _defineProperties(Constructor, staticProps);
|
|
47
|
+
return Constructor;
|
|
48
|
+
}
|
|
49
|
+
function _define_property(obj, key, value) {
|
|
50
|
+
if (key in obj) {
|
|
51
|
+
Object.defineProperty(obj, key, {
|
|
52
|
+
value: value,
|
|
53
|
+
enumerable: true,
|
|
54
|
+
configurable: true,
|
|
55
|
+
writable: true
|
|
56
|
+
});
|
|
57
|
+
} else {
|
|
58
|
+
obj[key] = value;
|
|
59
|
+
}
|
|
60
|
+
return obj;
|
|
61
|
+
}
|
|
62
|
+
function _instanceof(left, right) {
|
|
63
|
+
if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
|
|
64
|
+
return !!right[Symbol.hasInstance](left);
|
|
65
|
+
} else {
|
|
66
|
+
return left instanceof right;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
function _ts_generator(thisArg, body) {
|
|
70
|
+
var f, y, t, _ = {
|
|
71
|
+
label: 0,
|
|
72
|
+
sent: function() {
|
|
73
|
+
if (t[0] & 1) throw t[1];
|
|
74
|
+
return t[1];
|
|
75
|
+
},
|
|
76
|
+
trys: [],
|
|
77
|
+
ops: []
|
|
78
|
+
}, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
79
|
+
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() {
|
|
80
|
+
return this;
|
|
81
|
+
}), g;
|
|
82
|
+
function verb(n) {
|
|
83
|
+
return function(v) {
|
|
84
|
+
return step([
|
|
85
|
+
n,
|
|
86
|
+
v
|
|
87
|
+
]);
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
function step(op) {
|
|
91
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
92
|
+
while(g && (g = 0, op[0] && (_ = 0)), _)try {
|
|
93
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
94
|
+
if (y = 0, t) op = [
|
|
95
|
+
op[0] & 2,
|
|
96
|
+
t.value
|
|
97
|
+
];
|
|
98
|
+
switch(op[0]){
|
|
99
|
+
case 0:
|
|
100
|
+
case 1:
|
|
101
|
+
t = op;
|
|
102
|
+
break;
|
|
103
|
+
case 4:
|
|
104
|
+
_.label++;
|
|
105
|
+
return {
|
|
106
|
+
value: op[1],
|
|
107
|
+
done: false
|
|
108
|
+
};
|
|
109
|
+
case 5:
|
|
110
|
+
_.label++;
|
|
111
|
+
y = op[1];
|
|
112
|
+
op = [
|
|
113
|
+
0
|
|
114
|
+
];
|
|
115
|
+
continue;
|
|
116
|
+
case 7:
|
|
117
|
+
op = _.ops.pop();
|
|
118
|
+
_.trys.pop();
|
|
119
|
+
continue;
|
|
120
|
+
default:
|
|
121
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
|
|
122
|
+
_ = 0;
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
|
|
126
|
+
_.label = op[1];
|
|
127
|
+
break;
|
|
128
|
+
}
|
|
129
|
+
if (op[0] === 6 && _.label < t[1]) {
|
|
130
|
+
_.label = t[1];
|
|
131
|
+
t = op;
|
|
132
|
+
break;
|
|
133
|
+
}
|
|
134
|
+
if (t && _.label < t[2]) {
|
|
135
|
+
_.label = t[2];
|
|
136
|
+
_.ops.push(op);
|
|
137
|
+
break;
|
|
138
|
+
}
|
|
139
|
+
if (t[2]) _.ops.pop();
|
|
140
|
+
_.trys.pop();
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
op = body.call(thisArg, _);
|
|
144
|
+
} catch (e) {
|
|
145
|
+
op = [
|
|
146
|
+
6,
|
|
147
|
+
e
|
|
148
|
+
];
|
|
149
|
+
y = 0;
|
|
150
|
+
} finally{
|
|
151
|
+
f = t = 0;
|
|
152
|
+
}
|
|
153
|
+
if (op[0] & 5) throw op[1];
|
|
154
|
+
return {
|
|
155
|
+
value: op[0] ? op[1] : void 0,
|
|
156
|
+
done: true
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
import { SignJWT, importPKCS8 } from 'jose';
|
|
161
|
+
import { existsSync } from 'fs';
|
|
162
|
+
import { loadPrivateKey, getPrivateKeyFingerprint, resolvePrivateKeyPath } from './ssh-key-utils.js';
|
|
163
|
+
import { ProjectConfigManager } from '../commands/project-config-manager.js';
|
|
164
|
+
/**
|
|
165
|
+
* JWT Auth Provider for authenticating API requests
|
|
166
|
+
* Uses SSH private keys to sign short-lived JWTs
|
|
167
|
+
*/ export var JwtAuthProvider = /*#__PURE__*/ function() {
|
|
168
|
+
"use strict";
|
|
169
|
+
function JwtAuthProvider() {
|
|
170
|
+
_class_call_check(this, JwtAuthProvider);
|
|
171
|
+
_define_property(this, "privateKey", null);
|
|
172
|
+
_define_property(this, "fingerprint", null);
|
|
173
|
+
_define_property(this, "initialized", false);
|
|
174
|
+
_define_property(this, "initError", null);
|
|
175
|
+
this.initialize();
|
|
176
|
+
}
|
|
177
|
+
_create_class(JwtAuthProvider, [
|
|
178
|
+
{
|
|
179
|
+
key: "initialize",
|
|
180
|
+
value: function initialize() {
|
|
181
|
+
try {
|
|
182
|
+
// Get configured path from project config manager
|
|
183
|
+
var configManager = new ProjectConfigManager();
|
|
184
|
+
var configuredPath = configManager.getPrivateKeyPath();
|
|
185
|
+
var keyPath = resolvePrivateKeyPath(configuredPath);
|
|
186
|
+
if (!existsSync(keyPath)) {
|
|
187
|
+
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."));
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
this.privateKey = loadPrivateKey(keyPath);
|
|
191
|
+
this.fingerprint = getPrivateKeyFingerprint(this.privateKey);
|
|
192
|
+
this.initialized = true;
|
|
193
|
+
} catch (error) {
|
|
194
|
+
this.initError = _instanceof(error, Error) ? error : new Error('Failed to initialize JWT auth provider');
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
/**
|
|
200
|
+
* Check if the provider is ready to create JWTs
|
|
201
|
+
*/ key: "isReady",
|
|
202
|
+
value: function isReady() {
|
|
203
|
+
return this.initialized && this.privateKey !== null;
|
|
204
|
+
}
|
|
205
|
+
},
|
|
206
|
+
{
|
|
207
|
+
/**
|
|
208
|
+
* Get the error that occurred during initialization, if any
|
|
209
|
+
*/ key: "getError",
|
|
210
|
+
value: function getError() {
|
|
211
|
+
return this.initError;
|
|
212
|
+
}
|
|
213
|
+
},
|
|
214
|
+
{
|
|
215
|
+
/**
|
|
216
|
+
* Get the fingerprint of the loaded private key
|
|
217
|
+
*/ key: "getFingerprint",
|
|
218
|
+
value: function getFingerprint() {
|
|
219
|
+
return this.fingerprint;
|
|
220
|
+
}
|
|
221
|
+
},
|
|
222
|
+
{
|
|
223
|
+
key: "getAlgorithm",
|
|
224
|
+
value: /**
|
|
225
|
+
* Map SSH key type to JWT algorithm
|
|
226
|
+
*/ function getAlgorithm() {
|
|
227
|
+
if (!this.privateKey) {
|
|
228
|
+
throw new Error('Private key not loaded');
|
|
229
|
+
}
|
|
230
|
+
var keyType = this.privateKey.type;
|
|
231
|
+
if (keyType === 'rsa') {
|
|
232
|
+
return 'RS256';
|
|
233
|
+
} else if (keyType === 'ecdsa') {
|
|
234
|
+
// ECDSA curve determines algorithm
|
|
235
|
+
var curve = this.privateKey.curve;
|
|
236
|
+
if (curve === 'nistp256') {
|
|
237
|
+
return 'ES256';
|
|
238
|
+
} else if (curve === 'nistp384') {
|
|
239
|
+
return 'ES384';
|
|
240
|
+
} else if (curve === 'nistp521') {
|
|
241
|
+
return 'ES512';
|
|
242
|
+
}
|
|
243
|
+
// Default to ES256 for unknown curves
|
|
244
|
+
return 'ES256';
|
|
245
|
+
} else if (keyType === 'ed25519') {
|
|
246
|
+
return 'EdDSA';
|
|
247
|
+
}
|
|
248
|
+
throw new Error("Unsupported key type: ".concat(keyType));
|
|
249
|
+
}
|
|
250
|
+
},
|
|
251
|
+
{
|
|
252
|
+
key: "createToken",
|
|
253
|
+
value: /**
|
|
254
|
+
* Create a short-lived JWT for authentication
|
|
255
|
+
*/ function createToken() {
|
|
256
|
+
return _async_to_generator(function() {
|
|
257
|
+
var algorithm, pkcs8Pem, joseKey, jwt;
|
|
258
|
+
return _ts_generator(this, function(_state) {
|
|
259
|
+
switch(_state.label){
|
|
260
|
+
case 0:
|
|
261
|
+
if (!this.privateKey || !this.fingerprint) {
|
|
262
|
+
throw new Error('JWT auth provider not initialized');
|
|
263
|
+
}
|
|
264
|
+
algorithm = this.getAlgorithm();
|
|
265
|
+
// Convert SSH private key to PKCS8 PEM format
|
|
266
|
+
pkcs8Pem = this.privateKey.toString('pkcs8');
|
|
267
|
+
return [
|
|
268
|
+
4,
|
|
269
|
+
importPKCS8(pkcs8Pem, algorithm)
|
|
270
|
+
];
|
|
271
|
+
case 1:
|
|
272
|
+
joseKey = _state.sent();
|
|
273
|
+
return [
|
|
274
|
+
4,
|
|
275
|
+
new SignJWT({}).setProtectedHeader({
|
|
276
|
+
alg: algorithm
|
|
277
|
+
}).setSubject(this.fingerprint).setIssuedAt().setExpirationTime('30s').sign(joseKey)
|
|
278
|
+
];
|
|
279
|
+
case 2:
|
|
280
|
+
jwt = _state.sent();
|
|
281
|
+
return [
|
|
282
|
+
2,
|
|
283
|
+
jwt
|
|
284
|
+
];
|
|
285
|
+
}
|
|
286
|
+
});
|
|
287
|
+
}).call(this);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
]);
|
|
291
|
+
return JwtAuthProvider;
|
|
292
|
+
}();
|
|
293
|
+
// Singleton instance
|
|
294
|
+
var providerInstance = null;
|
|
295
|
+
/**
|
|
296
|
+
* Get the singleton JWT auth provider instance
|
|
297
|
+
*/ export function getJwtAuthProvider() {
|
|
298
|
+
if (!providerInstance) {
|
|
299
|
+
providerInstance = new JwtAuthProvider();
|
|
300
|
+
}
|
|
301
|
+
return providerInstance;
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* Reset the JWT auth provider singleton
|
|
305
|
+
* Call this after auth config changes to force reinitialization with new key
|
|
306
|
+
*/ export function resetJwtAuthProvider() {
|
|
307
|
+
providerInstance = null;
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Check if JWT auth is available
|
|
311
|
+
*/ export function isAuthAvailable() {
|
|
312
|
+
return getJwtAuthProvider().isReady();
|
|
313
|
+
}
|
|
314
|
+
/**
|
|
315
|
+
* Get the Authorization header if auth is available
|
|
316
|
+
* Returns { Authorization: 'Bearer <token>' } or empty object
|
|
317
|
+
*/ export function getAuthHeader() {
|
|
318
|
+
return _async_to_generator(function() {
|
|
319
|
+
var provider, token, error;
|
|
320
|
+
return _ts_generator(this, function(_state) {
|
|
321
|
+
switch(_state.label){
|
|
322
|
+
case 0:
|
|
323
|
+
provider = getJwtAuthProvider();
|
|
324
|
+
if (!provider.isReady()) {
|
|
325
|
+
return [
|
|
326
|
+
2,
|
|
327
|
+
{}
|
|
328
|
+
];
|
|
329
|
+
}
|
|
330
|
+
_state.label = 1;
|
|
331
|
+
case 1:
|
|
332
|
+
_state.trys.push([
|
|
333
|
+
1,
|
|
334
|
+
3,
|
|
335
|
+
,
|
|
336
|
+
4
|
|
337
|
+
]);
|
|
338
|
+
return [
|
|
339
|
+
4,
|
|
340
|
+
provider.createToken()
|
|
341
|
+
];
|
|
342
|
+
case 2:
|
|
343
|
+
token = _state.sent();
|
|
344
|
+
return [
|
|
345
|
+
2,
|
|
346
|
+
{
|
|
347
|
+
Authorization: "Bearer ".concat(token)
|
|
348
|
+
}
|
|
349
|
+
];
|
|
350
|
+
case 3:
|
|
351
|
+
error = _state.sent();
|
|
352
|
+
console.error('Warning: Failed to create auth token:', error);
|
|
353
|
+
return [
|
|
354
|
+
2,
|
|
355
|
+
{}
|
|
356
|
+
];
|
|
357
|
+
case 4:
|
|
358
|
+
return [
|
|
359
|
+
2
|
|
360
|
+
];
|
|
361
|
+
}
|
|
362
|
+
});
|
|
363
|
+
})();
|
|
364
|
+
}
|
|
@@ -171,15 +171,6 @@ import { createPublicKey } from 'crypto';
|
|
|
171
171
|
var publicKey = privateKey.toPublic();
|
|
172
172
|
return publicKey.fingerprint('sha256').toString();
|
|
173
173
|
}
|
|
174
|
-
/**
|
|
175
|
-
* Sign data with an SSH private key
|
|
176
|
-
*/ export function signWithPrivateKey(privateKey, data) {
|
|
177
|
-
var dataBuffer = typeof data === 'string' ? Buffer.from(data) : data;
|
|
178
|
-
var signer = privateKey.createSign('sha256');
|
|
179
|
-
signer.update(dataBuffer);
|
|
180
|
-
var signature = signer.sign();
|
|
181
|
-
return signature.toBuffer('raw');
|
|
182
|
-
}
|
|
183
174
|
/**
|
|
184
175
|
* Resolve the private key path from environment, config, or default
|
|
185
176
|
* @param configuredPath - Optional configured path from ProjectConfigManager
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../src/commands/helpers.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAUtD,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,MAAM,gBAAgB,GAAG,CAAC,QAAQ,EAAE,YAAY,KAAK,IAAI,CAAC;AAGhE,MAAM,MAAM,SAAS,GAAG,OAAO,SAAS,CAAC;AAMzC;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,GAAE,OAAc,GAAG,IAAI,CAGtF;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,OAAO,CAE3C;AAED;;;GAGG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAOtC;AAGD,eAAO,MAAM,SAAS;qBACG,MAAM,YAAY,WAAW,KAAG,OAAO,CAAC,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../src/commands/helpers.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAUtD,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,MAAM,gBAAgB,GAAG,CAAC,QAAQ,EAAE,YAAY,KAAK,IAAI,CAAC;AAGhE,MAAM,MAAM,SAAS,GAAG,OAAO,SAAS,CAAC;AAMzC;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,GAAE,OAAc,GAAG,IAAI,CAGtF;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,OAAO,CAE3C;AAED;;;GAGG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAOtC;AAGD,eAAO,MAAM,SAAS;qBACG,MAAM,YAAY,WAAW,KAAG,OAAO,CAAC,QAAQ,CAAC;IAgDxE;;OAEG;oCACmC,MAAM,YAAY,WAAW,KAAG,OAAO,CAAC,QAAQ,CAAC;CAkBxF,CAAC;AAEF,wBAAsB,eAAe,CAAC,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,iBAsF5E;AAED,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,MAAM,GAAG,aAAa,EAAE,CAsCxE;AAeD,UAAU,UAAU;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAClD;AAED,MAAM,MAAM,oBAAoB,GAAG,CAAC,QAAQ,EAAE;IAC5C,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,UAAU,GAAG,WAAW,GAAG,UAAU,CAAC;IAC9C,KAAK,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;CAC5B,KAAK,IAAI,CAAC;AAEX;;GAEG;AACH,wBAAsB,aAAa,CACjC,eAAe,EAAE,MAAM,EACvB,MAAM,GAAE,SAAqB,EAC7B,UAAU,CAAC,EAAE,oBAAoB,GAChC,OAAO,CAAC,UAAU,CAAC,CA+KrB;AAqKD;;GAEG;AACH,wBAAsB,aAAa,CACjC,eAAe,EAAE,MAAM,EACvB,MAAM,GAAE,SAAqB,mBAoB9B;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,eAAe,EAAE,MAAM,GAAG,MAAM,CAwCnE;AAED;;GAEG;AACH,wBAAgB,2BAA2B,CAAC,eAAe,EAAE,MAAM,GAAG,MAAM,CAO3E;AAsCD;;GAEG;AACH,wBAAsB,cAAc,CAClC,IAAI,CAAC,EAAE,MAAM,EACb,SAAS,SAAO,GACf,OAAO,CAAC,OAAO,CAAC,CAsBlB;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,0BAA0B,CAC9C,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,MAAM,GAAE,SAAqB,EAC7B,UAAU,CAAC,EAAE,gBAAgB,EAC7B,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,IAAI,CAAC,CA2If"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JWT Auth Provider for authenticating API requests
|
|
3
|
+
* Uses SSH private keys to sign short-lived JWTs
|
|
4
|
+
*/
|
|
5
|
+
export declare class JwtAuthProvider {
|
|
6
|
+
private privateKey;
|
|
7
|
+
private fingerprint;
|
|
8
|
+
private initialized;
|
|
9
|
+
private initError;
|
|
10
|
+
constructor();
|
|
11
|
+
private initialize;
|
|
12
|
+
/**
|
|
13
|
+
* Check if the provider is ready to create JWTs
|
|
14
|
+
*/
|
|
15
|
+
isReady(): boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Get the error that occurred during initialization, if any
|
|
18
|
+
*/
|
|
19
|
+
getError(): Error | null;
|
|
20
|
+
/**
|
|
21
|
+
* Get the fingerprint of the loaded private key
|
|
22
|
+
*/
|
|
23
|
+
getFingerprint(): string | null;
|
|
24
|
+
/**
|
|
25
|
+
* Map SSH key type to JWT algorithm
|
|
26
|
+
*/
|
|
27
|
+
private getAlgorithm;
|
|
28
|
+
/**
|
|
29
|
+
* Create a short-lived JWT for authentication
|
|
30
|
+
*/
|
|
31
|
+
createToken(): Promise<string>;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Get the singleton JWT auth provider instance
|
|
35
|
+
*/
|
|
36
|
+
export declare function getJwtAuthProvider(): JwtAuthProvider;
|
|
37
|
+
/**
|
|
38
|
+
* Reset the JWT auth provider singleton
|
|
39
|
+
* Call this after auth config changes to force reinitialization with new key
|
|
40
|
+
*/
|
|
41
|
+
export declare function resetJwtAuthProvider(): void;
|
|
42
|
+
/**
|
|
43
|
+
* Check if JWT auth is available
|
|
44
|
+
*/
|
|
45
|
+
export declare function isAuthAvailable(): boolean;
|
|
46
|
+
/**
|
|
47
|
+
* Get the Authorization header if auth is available
|
|
48
|
+
* Returns { Authorization: 'Bearer <token>' } or empty object
|
|
49
|
+
*/
|
|
50
|
+
export declare function getAuthHeader(): Promise<Record<string, string>>;
|
|
51
|
+
//# sourceMappingURL=jwt-auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jwt-auth.d.ts","sourceRoot":"","sources":["../../../src/lib/jwt-auth.ts"],"names":[],"mappings":"AAUA;;;GAGG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,UAAU,CAAiC;IACnD,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,SAAS,CAAsB;;IAMvC,OAAO,CAAC,UAAU;IA0BlB;;OAEG;IACH,OAAO,IAAI,OAAO;IAIlB;;OAEG;IACH,QAAQ,IAAI,KAAK,GAAG,IAAI;IAIxB;;OAEG;IACH,cAAc,IAAI,MAAM,GAAG,IAAI;IAI/B;;OAEG;IACH,OAAO,CAAC,YAAY;IA4BpB;;OAEG;IACG,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC;CAuBrC;AAKD;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,eAAe,CAKpD;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,IAAI,IAAI,CAE3C;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,OAAO,CAEzC;AAED;;;GAGG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAarE"}
|
|
@@ -29,10 +29,6 @@ export declare function loadPrivateKey(pathOrEnv?: string): sshpk.PrivateKey;
|
|
|
29
29
|
* Get the fingerprint of a private key (from its public component)
|
|
30
30
|
*/
|
|
31
31
|
export declare function getPrivateKeyFingerprint(privateKey: sshpk.PrivateKey): string;
|
|
32
|
-
/**
|
|
33
|
-
* Sign data with an SSH private key
|
|
34
|
-
*/
|
|
35
|
-
export declare function signWithPrivateKey(privateKey: sshpk.PrivateKey, data: Buffer | string): Buffer;
|
|
36
32
|
/**
|
|
37
33
|
* Resolve the private key path from environment, config, or default
|
|
38
34
|
* @param configuredPath - Optional configured path from ProjectConfigManager
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ssh-key-utils.d.ts","sourceRoot":"","sources":["../../../src/lib/ssh-key-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,OAAO,EAAmB,UAAU,EAAE,MAAM,QAAQ,CAAC;AAErD,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,UAAU,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;GAGG;AACH,wBAAgB,eAAe,IAAI,aAAa,EAAE,CAkDjD;AA0CD;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,MAAM,GAAG,UAAU,CAiBpE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC,UAAU,CAyBnE;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,UAAU,EAAE,KAAK,CAAC,UAAU,GAAG,MAAM,CAG7E;AAED
|
|
1
|
+
{"version":3,"file":"ssh-key-utils.d.ts","sourceRoot":"","sources":["../../../src/lib/ssh-key-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,OAAO,EAAmB,UAAU,EAAE,MAAM,QAAQ,CAAC;AAErD,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,UAAU,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;GAGG;AACH,wBAAgB,eAAe,IAAI,aAAa,EAAE,CAkDjD;AA0CD;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,MAAM,GAAG,UAAU,CAiBpE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC,UAAU,CAyBnE;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,UAAU,EAAE,KAAK,CAAC,UAAU,GAAG,MAAM,CAG7E;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAoB5E;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAKlD"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@positronic/cli",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.59",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -23,9 +23,9 @@
|
|
|
23
23
|
"clean": "rm -rf tsconfig.tsbuildinfo dist node_modules"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@positronic/core": "^0.0.
|
|
27
|
-
"@positronic/spec": "^0.0.
|
|
28
|
-
"@positronic/template-new-project": "^0.0.
|
|
26
|
+
"@positronic/core": "^0.0.59",
|
|
27
|
+
"@positronic/spec": "^0.0.59",
|
|
28
|
+
"@positronic/template-new-project": "^0.0.59",
|
|
29
29
|
"caz": "^2.0.0",
|
|
30
30
|
"chokidar": "^3.6.0",
|
|
31
31
|
"dotenv": "^16.4.7",
|
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
"ink": "^5.2.1",
|
|
34
34
|
"ink-text-input": "^6.0.0",
|
|
35
35
|
"istextorbinary": "^9.5.0",
|
|
36
|
+
"jose": "^5.2.0",
|
|
36
37
|
"node-fetch": "^3.3.2",
|
|
37
38
|
"react": "^18.3.1",
|
|
38
39
|
"react-robot": "^1.2.1",
|
|
@@ -1,208 +0,0 @@
|
|
|
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
|
-
}
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
export type SignedHeaders = {
|
|
2
|
-
Signature: string;
|
|
3
|
-
'Signature-Input': string;
|
|
4
|
-
[key: string]: string;
|
|
5
|
-
};
|
|
6
|
-
/**
|
|
7
|
-
* Request signer for RFC 9421 HTTP Message Signatures
|
|
8
|
-
*/
|
|
9
|
-
export declare class RequestSigner {
|
|
10
|
-
private privateKey;
|
|
11
|
-
private fingerprint;
|
|
12
|
-
private initialized;
|
|
13
|
-
private initError;
|
|
14
|
-
constructor();
|
|
15
|
-
private initialize;
|
|
16
|
-
/**
|
|
17
|
-
* Check if the signer is ready to sign requests
|
|
18
|
-
*/
|
|
19
|
-
isReady(): boolean;
|
|
20
|
-
/**
|
|
21
|
-
* Get the error that occurred during initialization, if any
|
|
22
|
-
*/
|
|
23
|
-
getError(): Error | null;
|
|
24
|
-
/**
|
|
25
|
-
* Get the fingerprint of the loaded private key
|
|
26
|
-
*/
|
|
27
|
-
getFingerprint(): string | null;
|
|
28
|
-
/**
|
|
29
|
-
* Sign an HTTP request and return the signature headers
|
|
30
|
-
*/
|
|
31
|
-
signRequest(method: string, url: string, headers?: Record<string, string>): SignedHeaders;
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* Get the singleton request signer instance
|
|
35
|
-
*/
|
|
36
|
-
export declare function getRequestSigner(): RequestSigner;
|
|
37
|
-
/**
|
|
38
|
-
* Reset the request signer singleton
|
|
39
|
-
* Call this after auth config changes to force reinitialization with new key
|
|
40
|
-
*/
|
|
41
|
-
export declare function resetRequestSigner(): void;
|
|
42
|
-
/**
|
|
43
|
-
* Check if request signing is available
|
|
44
|
-
*/
|
|
45
|
-
export declare function isSigningAvailable(): boolean;
|
|
46
|
-
/**
|
|
47
|
-
* Sign an HTTP request if signing is available
|
|
48
|
-
* Returns the additional headers to add, or empty object if signing is not available
|
|
49
|
-
*/
|
|
50
|
-
export declare function maybeSignRequest(method: string, url: string, headers?: Record<string, string>): Record<string, string>;
|
|
51
|
-
//# sourceMappingURL=request-signer.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"request-signer.d.ts","sourceRoot":"","sources":["../../../src/lib/request-signer.ts"],"names":[],"mappings":"AAUA,MAAM,MAAM,aAAa,GAAG;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;CACvB,CAAC;AAEF;;GAEG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,UAAU,CAAiC;IACnD,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,SAAS,CAAsB;;IAMvC,OAAO,CAAC,UAAU;IA0BlB;;OAEG;IACH,OAAO,IAAI,OAAO;IAIlB;;OAEG;IACH,QAAQ,IAAI,KAAK,GAAG,IAAI;IAIxB;;OAEG;IACH,cAAc,IAAI,MAAM,GAAG,IAAI;IAI/B;;OAEG;IACH,WAAW,CACT,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GACnC,aAAa;CAuDjB;AAKD;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,aAAa,CAKhD;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,IAAI,IAAI,CAEzC;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,OAAO,CAE5C;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GACnC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAYxB"}
|