@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 { parseRequestSignature } from '@misskey-dev/node-http-message-signatures';
128
+ import { jwtVerify, decodeJwt, importJWK } from 'jose';
175
129
  /**
176
- * Get the algorithm parameters for SubtleCrypto based on JWK key type
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
- return {
185
- name: 'ECDSA',
186
- namedCurve: jwk.crv || 'P-256'
187
- };
188
- } else if (jwk.kty === 'OKP' && jwk.crv === 'Ed25519') {
189
- return {
190
- name: 'Ed25519'
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 HTTP message signatures (RFC 9421) using @misskey-dev/node-http-message-signatures for parsing
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 signatureHeader, signatureInputHeader, parsedSignature, requestForParsing, errorMessage, sigInfo, keyId, signature, base, authDoId, authDo, userKey, jwk, cryptoKey, isValid, error, errorMessage1, jwk1, cryptoKey1, isValid1, error1, errorMessage2;
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 signature headers
297
- signatureHeader = c.req.header('Signature');
298
- signatureInputHeader = c.req.header('Signature-Input');
299
- // If no signature headers, return 401
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
- try {
309
- // Build a request-like object for the library
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: 'Invalid signature format'
186
+ error: 'Authentication required'
330
187
  }, 401)
331
188
  ];
332
189
  }
333
- // Extract signature info from parsed result
334
- sigInfo = extractSignatureInfo(parsedSignature);
335
- if (!sigInfo) {
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: 'No valid signature found'
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(keyId)
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
- 6
228
+ 7
356
229
  ];
357
- _state.label = 2;
358
- case 2:
230
+ _state.label = 3;
231
+ case 3:
359
232
  _state.trys.push([
360
- 2,
361
- 5,
233
+ 3,
234
+ 6,
362
235
  ,
363
- 6
236
+ 7
364
237
  ]);
365
238
  jwk = JSON.parse(userKey.jwk);
239
+ algorithm = getAlgorithmForJwk(jwk);
366
240
  return [
367
241
  4,
368
- jwkToCryptoKey(userKey.jwk)
242
+ importJWK(jwk, algorithm)
369
243
  ];
370
- case 3:
371
- cryptoKey = _state.sent();
244
+ case 4:
245
+ publicKey = _state.sent();
246
+ // Verify the JWT - this checks both signature and expiry
372
247
  return [
373
248
  4,
374
- verifySignatureWithKey(base, signature, cryptoKey, jwk)
249
+ jwtVerify(token, publicKey, {
250
+ algorithms: [
251
+ algorithm
252
+ ]
253
+ })
375
254
  ];
376
- case 4:
377
- isValid = _state.sent();
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 5:
265
+ case 6:
395
266
  error = _state.sent();
396
- // Log error type only - avoid logging key material or signature data
397
- errorMessage1 = _instanceof(error, Error) ? error.message : 'Unknown error';
398
- console.error('Signature verification failed:', errorMessage1);
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: 'Signature verification failed'
273
+ error: 'Invalid or expired token'
403
274
  }, 401)
404
275
  ];
405
- case 6:
276
+ case 7:
406
277
  if (!c.env.ROOT_PUBLIC_KEY) return [
407
278
  3,
408
- 11
279
+ 12
409
280
  ];
410
- _state.label = 7;
411
- case 7:
281
+ _state.label = 8;
282
+ case 8:
412
283
  _state.trys.push([
413
- 7,
414
- 10,
284
+ 8,
285
+ 11,
415
286
  ,
416
- 11
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
- jwkToCryptoKey(c.env.ROOT_PUBLIC_KEY)
293
+ importJWK(jwk1, algorithm1)
422
294
  ];
423
- case 8:
424
- cryptoKey1 = _state.sent();
295
+ case 9:
296
+ publicKey1 = _state.sent();
297
+ // Verify the JWT - this checks both signature and expiry
425
298
  return [
426
299
  4,
427
- verifySignatureWithKey(base, signature, cryptoKey1, jwk1)
300
+ jwtVerify(token, publicKey1, {
301
+ algorithms: [
302
+ algorithm1
303
+ ]
304
+ })
428
305
  ];
429
- case 9:
430
- isValid1 = _state.sent();
431
- if (isValid1) {
432
- c.set('auth', {
433
- userId: null,
434
- isRoot: true
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
- 3,
443
- 11
313
+ 2,
314
+ next()
444
315
  ];
445
- case 10:
316
+ case 11:
446
317
  error1 = _state.sent();
447
318
  // Log error type only - avoid logging key material
448
- errorMessage2 = _instanceof(error1, Error) ? error1.message : 'Unknown error';
449
- console.error('Root key verification failed:', errorMessage2);
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
- 11
323
+ 12
453
324
  ];
454
- case 11:
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: 'Unknown key'
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 HTTP message signatures (RFC 9421) using @misskey-dev/node-http-message-signatures for parsing
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;AAO3C,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;AAsGD;;;GAGG;AACH,wBAAgB,cAAc,IAAI,iBAAiB,CAAC;IAAE,QAAQ,EAAE,QAAQ,CAAA;CAAE,CAAC,CAoG1E"}
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.58",
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
- "@misskey-dev/node-http-message-signatures": "^0.0.10",
35
- "@positronic/core": "^0.0.58",
36
- "@positronic/spec": "^0.0.58",
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": {