@positronic/cloudflare 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.
|
@@ -1,11 +1,3 @@
|
|
|
1
|
-
function _array_like_to_array(arr, len) {
|
|
2
|
-
if (len == null || len > arr.length) len = arr.length;
|
|
3
|
-
for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
|
|
4
|
-
return arr2;
|
|
5
|
-
}
|
|
6
|
-
function _array_with_holes(arr) {
|
|
7
|
-
if (Array.isArray(arr)) return arr;
|
|
8
|
-
}
|
|
9
1
|
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
|
|
10
2
|
try {
|
|
11
3
|
var info = gen[key](arg);
|
|
@@ -42,44 +34,6 @@ function _instanceof(left, right) {
|
|
|
42
34
|
return left instanceof right;
|
|
43
35
|
}
|
|
44
36
|
}
|
|
45
|
-
function _iterable_to_array_limit(arr, i) {
|
|
46
|
-
var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
|
|
47
|
-
if (_i == null) return;
|
|
48
|
-
var _arr = [];
|
|
49
|
-
var _n = true;
|
|
50
|
-
var _d = false;
|
|
51
|
-
var _s, _e;
|
|
52
|
-
try {
|
|
53
|
-
for(_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true){
|
|
54
|
-
_arr.push(_s.value);
|
|
55
|
-
if (i && _arr.length === i) break;
|
|
56
|
-
}
|
|
57
|
-
} catch (err) {
|
|
58
|
-
_d = true;
|
|
59
|
-
_e = err;
|
|
60
|
-
} finally{
|
|
61
|
-
try {
|
|
62
|
-
if (!_n && _i["return"] != null) _i["return"]();
|
|
63
|
-
} finally{
|
|
64
|
-
if (_d) throw _e;
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
return _arr;
|
|
68
|
-
}
|
|
69
|
-
function _non_iterable_rest() {
|
|
70
|
-
throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
71
|
-
}
|
|
72
|
-
function _sliced_to_array(arr, i) {
|
|
73
|
-
return _array_with_holes(arr) || _iterable_to_array_limit(arr, i) || _unsupported_iterable_to_array(arr, i) || _non_iterable_rest();
|
|
74
|
-
}
|
|
75
|
-
function _unsupported_iterable_to_array(o, minLen) {
|
|
76
|
-
if (!o) return;
|
|
77
|
-
if (typeof o === "string") return _array_like_to_array(o, minLen);
|
|
78
|
-
var n = Object.prototype.toString.call(o).slice(8, -1);
|
|
79
|
-
if (n === "Object" && o.constructor) n = o.constructor.name;
|
|
80
|
-
if (n === "Map" || n === "Set") return Array.from(n);
|
|
81
|
-
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
|
|
82
|
-
}
|
|
83
37
|
function _ts_generator(thisArg, body) {
|
|
84
38
|
var f, y, t, _ = {
|
|
85
39
|
label: 0,
|
|
@@ -171,114 +125,34 @@ function _ts_generator(thisArg, body) {
|
|
|
171
125
|
};
|
|
172
126
|
}
|
|
173
127
|
}
|
|
174
|
-
import {
|
|
128
|
+
import { jwtVerify, decodeJwt, importJWK } from 'jose';
|
|
175
129
|
/**
|
|
176
|
-
* Get the algorithm
|
|
130
|
+
* Get the JWT algorithm based on JWK key type
|
|
177
131
|
*/ function getAlgorithmForJwk(jwk) {
|
|
178
132
|
if (jwk.kty === 'RSA') {
|
|
179
|
-
return
|
|
180
|
-
name: 'RSASSA-PKCS1-v1_5',
|
|
181
|
-
hash: 'SHA-256'
|
|
182
|
-
};
|
|
133
|
+
return 'RS256';
|
|
183
134
|
} else if (jwk.kty === 'EC') {
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
throw new Error("Unsupported key type: ".concat(jwk.kty));
|
|
194
|
-
}
|
|
195
|
-
/**
|
|
196
|
-
* Get the algorithm parameters for signature verification
|
|
197
|
-
*/ function getVerifyAlgorithm(jwk) {
|
|
198
|
-
if (jwk.kty === 'RSA') {
|
|
199
|
-
return {
|
|
200
|
-
name: 'RSASSA-PKCS1-v1_5',
|
|
201
|
-
hash: 'SHA-256'
|
|
202
|
-
};
|
|
203
|
-
} else if (jwk.kty === 'EC') {
|
|
204
|
-
return {
|
|
205
|
-
name: 'ECDSA',
|
|
206
|
-
hash: 'SHA-256'
|
|
207
|
-
};
|
|
135
|
+
if (jwk.crv === 'P-256') {
|
|
136
|
+
return 'ES256';
|
|
137
|
+
} else if (jwk.crv === 'P-384') {
|
|
138
|
+
return 'ES384';
|
|
139
|
+
} else if (jwk.crv === 'P-521') {
|
|
140
|
+
return 'ES512';
|
|
141
|
+
}
|
|
142
|
+
// Default to ES256 for unknown curves
|
|
143
|
+
return 'ES256';
|
|
208
144
|
} else if (jwk.kty === 'OKP' && jwk.crv === 'Ed25519') {
|
|
209
|
-
return
|
|
210
|
-
name: 'Ed25519'
|
|
211
|
-
};
|
|
145
|
+
return 'EdDSA';
|
|
212
146
|
}
|
|
213
147
|
throw new Error("Unsupported key type: ".concat(jwk.kty));
|
|
214
148
|
}
|
|
215
|
-
/**
|
|
216
|
-
* Convert a JWK to a CryptoKey for signature verification
|
|
217
|
-
*/ function jwkToCryptoKey(jwkString) {
|
|
218
|
-
return _async_to_generator(function() {
|
|
219
|
-
var jwk, algorithm;
|
|
220
|
-
return _ts_generator(this, function(_state) {
|
|
221
|
-
jwk = JSON.parse(jwkString);
|
|
222
|
-
algorithm = getAlgorithmForJwk(jwk);
|
|
223
|
-
return [
|
|
224
|
-
2,
|
|
225
|
-
crypto.subtle.importKey('jwk', jwk, algorithm, true, [
|
|
226
|
-
'verify'
|
|
227
|
-
])
|
|
228
|
-
];
|
|
229
|
-
});
|
|
230
|
-
})();
|
|
231
|
-
}
|
|
232
|
-
/**
|
|
233
|
-
* Verify a signature using Web Crypto API
|
|
234
|
-
*/ function verifySignatureWithKey(signatureBase, signatureB64, cryptoKey, jwk) {
|
|
235
|
-
return _async_to_generator(function() {
|
|
236
|
-
var encoder, data, signatureBytes, algorithm;
|
|
237
|
-
return _ts_generator(this, function(_state) {
|
|
238
|
-
encoder = new TextEncoder();
|
|
239
|
-
data = encoder.encode(signatureBase);
|
|
240
|
-
signatureBytes = Uint8Array.from(atob(signatureB64), function(c) {
|
|
241
|
-
return c.charCodeAt(0);
|
|
242
|
-
});
|
|
243
|
-
algorithm = getVerifyAlgorithm(jwk);
|
|
244
|
-
return [
|
|
245
|
-
2,
|
|
246
|
-
crypto.subtle.verify(algorithm, cryptoKey, signatureBytes, data)
|
|
247
|
-
];
|
|
248
|
-
});
|
|
249
|
-
})();
|
|
250
|
-
}
|
|
251
|
-
/**
|
|
252
|
-
* Extract keyId and signature info from parsed signature
|
|
253
|
-
* Handles both draft and RFC9421 formats
|
|
254
|
-
*/ function extractSignatureInfo(parsed) {
|
|
255
|
-
if (parsed.version === 'draft') {
|
|
256
|
-
return {
|
|
257
|
-
keyId: parsed.value.keyId,
|
|
258
|
-
signature: parsed.value.params.signature,
|
|
259
|
-
base: parsed.value.signingString
|
|
260
|
-
};
|
|
261
|
-
} else if (parsed.version === 'rfc9421') {
|
|
262
|
-
// RFC9421 returns an array of [label, value] tuples
|
|
263
|
-
var signatures = parsed.value;
|
|
264
|
-
if (signatures.length === 0) return null;
|
|
265
|
-
// Use the first signature (usually 'sig1')
|
|
266
|
-
var _signatures_ = _sliced_to_array(signatures[0], 2), sigValue = _signatures_[1];
|
|
267
|
-
return {
|
|
268
|
-
keyId: sigValue.keyid,
|
|
269
|
-
signature: sigValue.signature,
|
|
270
|
-
base: sigValue.base
|
|
271
|
-
};
|
|
272
|
-
}
|
|
273
|
-
return null;
|
|
274
|
-
}
|
|
275
149
|
/**
|
|
276
150
|
* Authentication middleware for the Positronic API
|
|
277
|
-
* Verifies
|
|
151
|
+
* Verifies JWT Bearer tokens
|
|
278
152
|
*/ export function authMiddleware() {
|
|
279
153
|
return function(c, next) {
|
|
280
154
|
return _async_to_generator(function() {
|
|
281
|
-
var
|
|
155
|
+
var authHeader, token, fingerprint, decoded, userKey, authDoId, authDo, jwk, algorithm, publicKey, error, errorMessage, jwk1, algorithm1, publicKey1, error1, errorMessage1;
|
|
282
156
|
return _ts_generator(this, function(_state) {
|
|
283
157
|
switch(_state.label){
|
|
284
158
|
case 0:
|
|
@@ -293,11 +167,10 @@ import { parseRequestSignature } from '@misskey-dev/node-http-message-signatures
|
|
|
293
167
|
next()
|
|
294
168
|
];
|
|
295
169
|
}
|
|
296
|
-
// Get
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
if (!signatureHeader || !signatureInputHeader) {
|
|
170
|
+
// Get Authorization header
|
|
171
|
+
authHeader = c.req.header('Authorization');
|
|
172
|
+
// If no Authorization header, return 401
|
|
173
|
+
if (!authHeader) {
|
|
301
174
|
return [
|
|
302
175
|
2,
|
|
303
176
|
c.json({
|
|
@@ -305,84 +178,82 @@ import { parseRequestSignature } from '@misskey-dev/node-http-message-signatures
|
|
|
305
178
|
}, 401)
|
|
306
179
|
];
|
|
307
180
|
}
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
requestForParsing = {
|
|
311
|
-
method: c.req.method,
|
|
312
|
-
url: c.req.url,
|
|
313
|
-
headers: Object.fromEntries(c.req.raw.headers.entries())
|
|
314
|
-
};
|
|
315
|
-
parsedSignature = parseRequestSignature(requestForParsing, {
|
|
316
|
-
clockSkew: {
|
|
317
|
-
now: new Date(),
|
|
318
|
-
forward: 300000,
|
|
319
|
-
delay: 300000
|
|
320
|
-
}
|
|
321
|
-
});
|
|
322
|
-
} catch (error) {
|
|
323
|
-
// Log error type only - avoid logging request details that could contain sensitive data
|
|
324
|
-
errorMessage = _instanceof(error, Error) ? error.message : 'Unknown error';
|
|
325
|
-
console.error('Failed to parse signature:', errorMessage);
|
|
181
|
+
// Check for Bearer token format
|
|
182
|
+
if (!authHeader.startsWith('Bearer ')) {
|
|
326
183
|
return [
|
|
327
184
|
2,
|
|
328
185
|
c.json({
|
|
329
|
-
error: '
|
|
186
|
+
error: 'Authentication required'
|
|
330
187
|
}, 401)
|
|
331
188
|
];
|
|
332
189
|
}
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
190
|
+
token = authHeader.slice(7); // Remove 'Bearer ' prefix
|
|
191
|
+
try {
|
|
192
|
+
decoded = decodeJwt(token);
|
|
193
|
+
if (!decoded.sub) {
|
|
194
|
+
return [
|
|
195
|
+
2,
|
|
196
|
+
c.json({
|
|
197
|
+
error: 'Invalid or expired token'
|
|
198
|
+
}, 401)
|
|
199
|
+
];
|
|
200
|
+
}
|
|
201
|
+
fingerprint = decoded.sub;
|
|
202
|
+
} catch (e) {
|
|
336
203
|
return [
|
|
337
204
|
2,
|
|
338
205
|
c.json({
|
|
339
|
-
error: '
|
|
206
|
+
error: 'Invalid or expired token'
|
|
340
207
|
}, 401)
|
|
341
208
|
];
|
|
342
209
|
}
|
|
343
|
-
keyId = sigInfo.keyId, signature = sigInfo.signature, base = sigInfo.base;
|
|
344
210
|
// Try to find the key in the auth database
|
|
211
|
+
userKey = null;
|
|
212
|
+
if (!c.env.AUTH_DO) return [
|
|
213
|
+
3,
|
|
214
|
+
2
|
|
215
|
+
];
|
|
345
216
|
authDoId = c.env.AUTH_DO.idFromName('auth');
|
|
346
217
|
authDo = c.env.AUTH_DO.get(authDoId);
|
|
347
218
|
return [
|
|
348
219
|
4,
|
|
349
|
-
authDo.getKeyByFingerprint(
|
|
220
|
+
authDo.getKeyByFingerprint(fingerprint)
|
|
350
221
|
];
|
|
351
222
|
case 1:
|
|
352
223
|
userKey = _state.sent();
|
|
224
|
+
_state.label = 2;
|
|
225
|
+
case 2:
|
|
353
226
|
if (!userKey) return [
|
|
354
227
|
3,
|
|
355
|
-
|
|
228
|
+
7
|
|
356
229
|
];
|
|
357
|
-
_state.label =
|
|
358
|
-
case
|
|
230
|
+
_state.label = 3;
|
|
231
|
+
case 3:
|
|
359
232
|
_state.trys.push([
|
|
360
|
-
|
|
361
|
-
|
|
233
|
+
3,
|
|
234
|
+
6,
|
|
362
235
|
,
|
|
363
|
-
|
|
236
|
+
7
|
|
364
237
|
]);
|
|
365
238
|
jwk = JSON.parse(userKey.jwk);
|
|
239
|
+
algorithm = getAlgorithmForJwk(jwk);
|
|
366
240
|
return [
|
|
367
241
|
4,
|
|
368
|
-
|
|
242
|
+
importJWK(jwk, algorithm)
|
|
369
243
|
];
|
|
370
|
-
case
|
|
371
|
-
|
|
244
|
+
case 4:
|
|
245
|
+
publicKey = _state.sent();
|
|
246
|
+
// Verify the JWT - this checks both signature and expiry
|
|
372
247
|
return [
|
|
373
248
|
4,
|
|
374
|
-
|
|
249
|
+
jwtVerify(token, publicKey, {
|
|
250
|
+
algorithms: [
|
|
251
|
+
algorithm
|
|
252
|
+
]
|
|
253
|
+
})
|
|
375
254
|
];
|
|
376
|
-
case
|
|
377
|
-
|
|
378
|
-
if (!isValid) {
|
|
379
|
-
return [
|
|
380
|
-
2,
|
|
381
|
-
c.json({
|
|
382
|
-
error: 'Invalid signature'
|
|
383
|
-
}, 401)
|
|
384
|
-
];
|
|
385
|
-
}
|
|
255
|
+
case 5:
|
|
256
|
+
_state.sent();
|
|
386
257
|
c.set('auth', {
|
|
387
258
|
userId: userKey.userId,
|
|
388
259
|
isRoot: false
|
|
@@ -391,67 +262,67 @@ import { parseRequestSignature } from '@misskey-dev/node-http-message-signatures
|
|
|
391
262
|
2,
|
|
392
263
|
next()
|
|
393
264
|
];
|
|
394
|
-
case
|
|
265
|
+
case 6:
|
|
395
266
|
error = _state.sent();
|
|
396
|
-
// Log error type only - avoid logging key material or
|
|
397
|
-
|
|
398
|
-
console.error('
|
|
267
|
+
// Log error type only - avoid logging key material or token data
|
|
268
|
+
errorMessage = _instanceof(error, Error) ? error.message : 'Unknown error';
|
|
269
|
+
console.error('JWT verification failed:', errorMessage);
|
|
399
270
|
return [
|
|
400
271
|
2,
|
|
401
272
|
c.json({
|
|
402
|
-
error: '
|
|
273
|
+
error: 'Invalid or expired token'
|
|
403
274
|
}, 401)
|
|
404
275
|
];
|
|
405
|
-
case
|
|
276
|
+
case 7:
|
|
406
277
|
if (!c.env.ROOT_PUBLIC_KEY) return [
|
|
407
278
|
3,
|
|
408
|
-
|
|
279
|
+
12
|
|
409
280
|
];
|
|
410
|
-
_state.label =
|
|
411
|
-
case
|
|
281
|
+
_state.label = 8;
|
|
282
|
+
case 8:
|
|
412
283
|
_state.trys.push([
|
|
413
|
-
|
|
414
|
-
|
|
284
|
+
8,
|
|
285
|
+
11,
|
|
415
286
|
,
|
|
416
|
-
|
|
287
|
+
12
|
|
417
288
|
]);
|
|
418
289
|
jwk1 = JSON.parse(c.env.ROOT_PUBLIC_KEY);
|
|
290
|
+
algorithm1 = getAlgorithmForJwk(jwk1);
|
|
419
291
|
return [
|
|
420
292
|
4,
|
|
421
|
-
|
|
293
|
+
importJWK(jwk1, algorithm1)
|
|
422
294
|
];
|
|
423
|
-
case
|
|
424
|
-
|
|
295
|
+
case 9:
|
|
296
|
+
publicKey1 = _state.sent();
|
|
297
|
+
// Verify the JWT - this checks both signature and expiry
|
|
425
298
|
return [
|
|
426
299
|
4,
|
|
427
|
-
|
|
300
|
+
jwtVerify(token, publicKey1, {
|
|
301
|
+
algorithms: [
|
|
302
|
+
algorithm1
|
|
303
|
+
]
|
|
304
|
+
})
|
|
428
305
|
];
|
|
429
|
-
case
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
});
|
|
436
|
-
return [
|
|
437
|
-
2,
|
|
438
|
-
next()
|
|
439
|
-
];
|
|
440
|
-
}
|
|
306
|
+
case 10:
|
|
307
|
+
_state.sent();
|
|
308
|
+
c.set('auth', {
|
|
309
|
+
userId: null,
|
|
310
|
+
isRoot: true
|
|
311
|
+
});
|
|
441
312
|
return [
|
|
442
|
-
|
|
443
|
-
|
|
313
|
+
2,
|
|
314
|
+
next()
|
|
444
315
|
];
|
|
445
|
-
case
|
|
316
|
+
case 11:
|
|
446
317
|
error1 = _state.sent();
|
|
447
318
|
// Log error type only - avoid logging key material
|
|
448
|
-
|
|
449
|
-
console.error('Root key verification failed:',
|
|
319
|
+
errorMessage1 = _instanceof(error1, Error) ? error1.message : 'Unknown error';
|
|
320
|
+
console.error('Root key JWT verification failed:', errorMessage1);
|
|
450
321
|
return [
|
|
451
322
|
3,
|
|
452
|
-
|
|
323
|
+
12
|
|
453
324
|
];
|
|
454
|
-
case
|
|
325
|
+
case 12:
|
|
455
326
|
// No matching key found
|
|
456
327
|
// Check if ROOT_PUBLIC_KEY is configured - if not, return specific error
|
|
457
328
|
if (!c.env.ROOT_PUBLIC_KEY) {
|
|
@@ -465,7 +336,7 @@ import { parseRequestSignature } from '@misskey-dev/node-http-message-signatures
|
|
|
465
336
|
return [
|
|
466
337
|
2,
|
|
467
338
|
c.json({
|
|
468
|
-
error: '
|
|
339
|
+
error: 'Invalid or expired token'
|
|
469
340
|
}, 401)
|
|
470
341
|
];
|
|
471
342
|
}
|
|
@@ -11,7 +11,7 @@ declare module 'hono' {
|
|
|
11
11
|
}
|
|
12
12
|
/**
|
|
13
13
|
* Authentication middleware for the Positronic API
|
|
14
|
-
* Verifies
|
|
14
|
+
* Verifies JWT Bearer tokens
|
|
15
15
|
*/
|
|
16
16
|
export declare function authMiddleware(): MiddlewareHandler<{
|
|
17
17
|
Bindings: Bindings;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth-middleware.d.ts","sourceRoot":"","sources":["../../../src/api/auth-middleware.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAW,iBAAiB,EAAE,MAAM,MAAM,CAAC;AACvD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"auth-middleware.d.ts","sourceRoot":"","sources":["../../../src/api/auth-middleware.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAW,iBAAiB,EAAE,MAAM,MAAM,CAAC;AACvD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAI3C,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,MAAM,EAAE,OAAO,CAAC;CACjB;AAGD,OAAO,QAAQ,MAAM,CAAC;IACpB,UAAU,kBAAkB;QAC1B,IAAI,EAAE,WAAW,CAAC;KACnB;CACF;AAwBD;;;GAGG;AACH,wBAAgB,cAAc,IAAI,iBAAiB,CAAC;IAAE,QAAQ,EAAE,QAAQ,CAAA;CAAE,CAAC,CA4F1E"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@positronic/cloudflare",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.59",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -31,16 +31,16 @@
|
|
|
31
31
|
"clean": "rm -rf tsconfig.tsbuildinfo dist"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@
|
|
35
|
-
"@positronic/
|
|
36
|
-
"@positronic/
|
|
37
|
-
"@positronic/template-new-project": "^0.0.58",
|
|
34
|
+
"@positronic/core": "^0.0.59",
|
|
35
|
+
"@positronic/spec": "^0.0.59",
|
|
36
|
+
"@positronic/template-new-project": "^0.0.59",
|
|
38
37
|
"aws4fetch": "^1.0.18",
|
|
39
38
|
"caz": "^2.0.0",
|
|
40
39
|
"cron-schedule": "^5.0.4",
|
|
41
40
|
"dotenv": "^16.0.3",
|
|
42
41
|
"fuse.js": "^7.1.0",
|
|
43
42
|
"hono": "^4.2.3",
|
|
43
|
+
"jose": "^5.2.0",
|
|
44
44
|
"uuid": "^9.0.1"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|