unjwt 0.8.3 → 0.8.5

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.
Files changed (54) hide show
  1. package/README.md +3 -9
  2. package/dist/_chunks/algorithms.mjs +1541 -0
  3. package/dist/_chunks/{_codec-jwe.d.mts → codec-jwe.d.mts} +40 -9
  4. package/dist/_chunks/{_codec-jws.mjs → codec-jws.mjs} +148 -95
  5. package/dist/_chunks/cookie.mjs +50 -0
  6. package/dist/_chunks/digest.mjs +10 -3
  7. package/dist/_chunks/error.d.mts +103 -0
  8. package/dist/_chunks/export.mjs +97 -0
  9. package/dist/_chunks/index.d.mts +5 -103
  10. package/dist/_chunks/index2.d.mts +206 -12
  11. package/dist/_chunks/index3.d.mts +12 -109
  12. package/dist/_chunks/{jwe.d.mts → index4.d.mts} +3 -1
  13. package/dist/_chunks/{jws.d.mts → index5.d.mts} +6 -2
  14. package/dist/_chunks/index6.d.mts +113 -0
  15. package/dist/_chunks/jwe.mjs +208 -74
  16. package/dist/_chunks/jwk.mjs +214 -2237
  17. package/dist/_chunks/jws.mjs +289 -202
  18. package/dist/_chunks/jwt.d.mts +2 -1
  19. package/dist/_chunks/{_jwt-internal.mjs → jwt.mjs} +124 -68
  20. package/dist/_chunks/libs/unsecure.d.mts +35 -25
  21. package/dist/_chunks/libs/unsecure.mjs +148 -302
  22. package/dist/_chunks/{_internal.d.mts → limits.d.mts} +1 -1
  23. package/dist/_chunks/payload.mjs +23 -0
  24. package/dist/_chunks/wrap.mjs +209 -0
  25. package/dist/adapters/elysia/index.d.mts +4 -4
  26. package/dist/adapters/elysia/index.mjs +5 -3
  27. package/dist/adapters/h3/index.d.mts +13 -13
  28. package/dist/adapters/h3/index.mjs +8 -10
  29. package/dist/adapters/h3v1/index.d.mts +5 -5
  30. package/dist/adapters/h3v1/index.mjs +6 -8
  31. package/dist/core/internal.mjs +1 -1
  32. package/dist/core/{jwe.d.mts → jwe/index.d.mts} +5 -4
  33. package/dist/core/jwe/index.mjs +5 -0
  34. package/dist/core/jwk/index.d.mts +6 -0
  35. package/dist/core/jwk/index.mjs +7 -0
  36. package/dist/core/{jws.d.mts → jws/index.d.mts} +5 -4
  37. package/dist/core/jws/index.mjs +5 -0
  38. package/dist/dpop/index.d.mts +73 -0
  39. package/dist/dpop/index.mjs +296 -0
  40. package/dist/error.d.mts +3 -0
  41. package/dist/error.mjs +20 -0
  42. package/dist/index.d.mts +10 -9
  43. package/dist/index.mjs +7 -3
  44. package/dist/session/index.d.mts +4 -4
  45. package/dist/session/index.mjs +6 -46
  46. package/dist/utils/index.d.mts +7 -0
  47. package/dist/{core/utils → utils}/index.mjs +4 -3
  48. package/package.json +22 -10
  49. package/dist/core/jwe.mjs +0 -5
  50. package/dist/core/jwk.d.mts +0 -207
  51. package/dist/core/jwk.mjs +0 -4
  52. package/dist/core/jws.mjs +0 -5
  53. package/dist/core/utils/index.d.mts +0 -6
  54. /package/dist/_chunks/{_cookie-attributes.d.mts → cookie-attributes.d.mts} +0 -0
@@ -11,294 +11,28 @@ const textEncoder = /* @__PURE__ */ new TextEncoder();
11
11
  function describeValue(value) {
12
12
  if (value === null) return "null";
13
13
  if (typeof value !== "object") return typeof value;
14
- return value.constructor?.name ?? "object";
14
+ const name = value.constructor?.name;
15
+ return typeof name === "string" && /^[A-Za-z_$][\w$]{0,63}$/.test(name) ? name : "object";
15
16
  }
16
17
  /* @__NO_SIDE_EFFECTS__ */
17
- function toBytes(value, label) {
18
- if (typeof value === "string") return textEncoder.encode(value);
19
- if (ArrayBuffer.isView(value)) return value instanceof Uint8Array ? value : new Uint8Array(value.buffer, value.byteOffset, value.byteLength);
20
- if (value instanceof ArrayBuffer || typeof SharedArrayBuffer !== "undefined" && value instanceof SharedArrayBuffer) return new Uint8Array(value);
21
- throw new UnsecureError("INVALID_TYPE", `${label}: expected a string, ArrayBuffer or ArrayBuffer view, got ${/* @__PURE__ */ describeValue(value)}.`);
22
- }
23
- const textDecoder = /* @__PURE__ */ new TextDecoder("utf-8", { ignoreBOM: true });
24
- const _fatalDecoder = /* @__PURE__ */ new TextDecoder("utf-8", {
25
- ignoreBOM: true,
26
- fatal: true
27
- });
28
- /* @__NO_SIDE_EFFECTS__ */
29
- function _wholeBuffer(bytes) {
30
- return bytes.byteOffset === 0 && bytes.byteLength === bytes.buffer.byteLength ? bytes : bytes.slice();
31
- }
32
- const _LATIN1_CHUNK = 32768;
33
- /* @__NO_SIDE_EFFECTS__ */
34
- function _latin1(bytes) {
35
- if (bytes.length <= _LATIN1_CHUNK) return String.fromCharCode(...bytes);
36
- let text = "";
37
- for (let i = 0; i < bytes.length; i += _LATIN1_CHUNK) text += String.fromCharCode(...bytes.subarray(i, i + _LATIN1_CHUNK));
38
- return text;
39
- }
40
- function _assertData(input, label) {
41
- if (typeof input !== "string" && !/* @__PURE__ */ _isBytes(input)) throw new UnsecureError("INVALID_TYPE", `${label}: expected a string or Uint8Array, got ${/* @__PURE__ */ describeValue(input)}.`);
42
- }
43
- /* @__NO_SIDE_EFFECTS__ */
44
- function _isBytes(input) {
45
- return ArrayBuffer.isView(input) && input instanceof Uint8Array;
46
- }
47
- /* @__NO_SIDE_EFFECTS__ */
48
- function _parsePrep(input, options) {
49
- const isBytes = /* @__PURE__ */ _isBytes(input);
50
- const returnAs = options?.returnAs ?? (isBytes ? "uint8array" : "string");
51
- return {
52
- text: isBytes ? /* @__PURE__ */ _latin1(input) : input,
53
- wantString: returnAs === "string"
54
- };
55
- }
56
- /* @__NO_SIDE_EFFECTS__ */
57
- function _parseFinalize(bytes, wantString, strict, label) {
58
- if (!wantString) return bytes;
59
- if (!strict) return textDecoder.decode(bytes);
60
- try {
61
- return _fatalDecoder.decode(bytes);
62
- } catch {
63
- throw /* @__PURE__ */ _malformed(label, "decoded bytes are not valid UTF-8.");
64
- }
65
- }
66
- /* @__NO_SIDE_EFFECTS__ */
67
- function _malformed(label, detail) {
68
- return new UnsecureError("MALFORMED", `${label}: ${detail}`);
69
- }
70
- /* @__NO_SIDE_EFFECTS__ */
71
- function _tailBits(rem, bits) {
72
- if (rem === 0) return 0;
73
- const leftover = rem * bits % 8;
74
- return leftover >= bits ? -1 : leftover;
75
- }
76
- /* @__NO_SIDE_EFFECTS__ */
77
- function _strictBody(text, table, shape, label, padding) {
78
- let end = text.length;
79
- while (end > 0 && text.charCodeAt(end - 1) === 61) end--;
80
- const padFound = text.length - end;
81
- for (let i = 0; i < end; i++) {
82
- const c = text.charCodeAt(i);
83
- if ((c < 128 ? table[c] : -1) < 0) throw /* @__PURE__ */ _malformed(label, `invalid ${shape.name} character ${JSON.stringify(text[i])} at index ${i}.`);
84
- }
85
- const rem = end % shape.group;
86
- const tail = /* @__PURE__ */ _tailBits(rem, shape.bits);
87
- if (tail < 0) throw /* @__PURE__ */ _malformed(label, `${end} ${shape.name} symbols cannot encode whole bytes.`);
88
- const padNeeded = rem === 0 ? 0 : shape.group - rem;
89
- if (padFound > 0) {
90
- if (padNeeded === 0 || padding === false) throw /* @__PURE__ */ _malformed(label, `unexpected "=" padding.`);
91
- if (padFound !== padNeeded) throw /* @__PURE__ */ _malformed(label, `expected ${padNeeded} "=" padding characters, found ${padFound}.`);
92
- } else if (padding === true && padNeeded > 0) throw /* @__PURE__ */ _malformed(label, `expected ${padNeeded} "=" padding characters, found 0.`);
93
- if (tail > 0 && (table[text.charCodeAt(end - 1)] & (1 << tail) - 1) !== 0) throw /* @__PURE__ */ _malformed(label, `the last ${shape.name} symbol sets bits past the final byte.`);
94
- return end === text.length ? text : text.slice(0, end);
95
- }
96
- /* @__NO_SIDE_EFFECTS__ */
97
- function _symbols(text, table) {
98
- const values = new Uint8Array(text.length);
99
- let n = 0;
100
- for (let i = 0; i < text.length; i++) {
101
- const c = text.charCodeAt(i);
102
- const v = c < 128 ? table[c] : -1;
103
- if (v >= 0) values[n++] = v;
104
- }
105
- return n === values.length ? values : values.subarray(0, n);
106
- }
107
- /* @__NO_SIDE_EFFECTS__ */
108
- function _looseCount(n, shape) {
109
- let count = n;
110
- while (count > 0 && /* @__PURE__ */ _tailBits(count % shape.group, shape.bits) < 0) count--;
111
- return count;
112
- }
113
- /* @__NO_SIDE_EFFECTS__ */
114
- function _decodeSymbols(values, count, bits) {
115
- const out = new Uint8Array(count * bits >>> 3);
116
- let acc = 0;
117
- let held = 0;
118
- let j = 0;
119
- for (let i = 0; i < count; i++) {
120
- acc = acc << bits | values[i];
121
- held += bits;
122
- if (held >= 8) {
123
- held -= 8;
124
- out[j++] = acc >>> held & 255;
125
- }
126
- }
127
- return out;
128
- }
129
- const _ON_HEAP_MAX = 64;
130
- const _Buffer = /* @__PURE__ */ (() => {
131
- try {
132
- return globalThis.Buffer;
133
- } catch {
134
- return;
135
- }
136
- })();
137
- const _hasBuffer = /* @__PURE__ */ (() => typeof _Buffer?.from === "function")();
138
- /* @__NO_SIDE_EFFECTS__ */
139
- function _toBuffer(bytes) {
140
- return bytes.byteLength <= _ON_HEAP_MAX ? _Buffer.from(bytes) : _Buffer.from(bytes.buffer, bytes.byteOffset, bytes.byteLength);
141
- }
142
- const _nativeToBase64 = /* @__PURE__ */ (() => typeof Uint8Array.prototype.toBase64 === "function")();
143
- const _nativeFromBase64 = /* @__PURE__ */ (() => typeof Uint8Array.fromBase64 === "function")();
144
- const _B64_SHAPE = {
145
- bits: 6,
146
- group: 4,
147
- name: "base64"
148
- };
149
- const _B64_DIGITS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
150
- /* @__NO_SIDE_EFFECTS__ */
151
- function _b64Table(pairs) {
152
- const t = (/* @__PURE__ */ new Int16Array(128)).fill(-1);
153
- for (let i = 0; i < 62; i++) t[_B64_DIGITS.charCodeAt(i)] = i;
154
- for (let i = 0; i < pairs.length; i += 2) {
155
- t[pairs.charCodeAt(i)] = 62;
156
- t[pairs.charCodeAt(i + 1)] = 63;
157
- }
158
- return t;
159
- }
160
- const _B64_TABLE_STD = /* @__PURE__ */ _b64Table("+/");
161
- const _B64_TABLE_URL = /* @__PURE__ */ _b64Table("-_");
162
- /* @__NO_SIDE_EFFECTS__ */
163
- function _unpad(s) {
164
- let end = s.length;
165
- while (end > 0 && s.charCodeAt(end - 1) === 61) end--;
166
- return end === s.length ? s : s.slice(0, end);
167
- }
168
- /* @__NO_SIDE_EFFECTS__ */
169
- function _padTo4(s) {
170
- const rem = s.length % 4;
171
- return rem === 0 ? s : s + "=".repeat(4 - rem);
172
- }
173
- /* @__NO_SIDE_EFFECTS__ */
174
- function _encodeBase64(bytes, alphabet, padding) {
175
- const url = alphabet === "base64url";
176
- if (_hasBuffer) {
177
- const s = (/* @__PURE__ */ _toBuffer(bytes)).toString(url ? "base64url" : "base64");
178
- if (url) return padding ? /* @__PURE__ */ _padTo4(s) : s;
179
- return padding ? s : /* @__PURE__ */ _unpad(s);
180
- }
181
- if (_nativeToBase64) return (/* @__PURE__ */ _wholeBuffer(bytes)).toBase64({
182
- alphabet,
183
- omitPadding: !padding
184
- });
185
- let binary = "";
186
- for (let i = 0; i < bytes.length; i++) binary += String.fromCharCode(bytes[i]);
187
- let s = btoa(binary);
188
- if (url) s = s.replace(/\+/g, "-").replace(/\//g, "_");
189
- return padding ? s : /* @__PURE__ */ _unpad(s);
190
- }
191
- /* @__NO_SIDE_EFFECTS__ */
192
- function _decodeCanonical(padded, symbols) {
193
- if (_hasBuffer) return new Uint8Array(_Buffer.from(padded, "base64"));
194
- if (_nativeFromBase64) return Uint8Array.fromBase64(padded);
195
- return /* @__PURE__ */ _decodeSymbols(/* @__PURE__ */ _symbols(padded, _B64_TABLE_STD), symbols, 6);
196
- }
197
- /* @__NO_SIDE_EFFECTS__ */
198
- function _decodeBase64(text, alphabet, loose, label, padding) {
199
- const url = alphabet === "base64url";
200
- let body;
201
- if (loose) {
202
- const clean = text.replace(/-/g, "+").replace(/_/g, "/").replace(/[^A-Za-z0-9+/]/g, "");
203
- body = clean.slice(0, /* @__PURE__ */ _looseCount(clean.length, _B64_SHAPE));
204
- } else {
205
- const strict = /* @__PURE__ */ _strictBody(text, url ? _B64_TABLE_URL : _B64_TABLE_STD, _B64_SHAPE, label, padding);
206
- body = url ? strict.replace(/-/g, "+").replace(/_/g, "/") : strict;
207
- }
208
- const rem = body.length % 4;
209
- return /* @__PURE__ */ _decodeCanonical(rem === 0 ? body : body + (rem === 2 ? "==" : "="), body.length);
210
- }
211
- /* @__NO_SIDE_EFFECTS__ */
212
- function base64Stringify(data, options) {
213
- const alphabet = options?.alphabet ?? "base64";
214
- const padding = options?.padding ?? alphabet !== "base64url";
215
- return /* @__PURE__ */ _encodeBase64(/* @__PURE__ */ toBytes(data, "Base64.stringify"), alphabet, padding);
216
- }
217
- /* @__NO_SIDE_EFFECTS__ */
218
- function base64Parse(input, options) {
219
- _assertData(input, "Base64.parse");
220
- const { text, wantString } = /* @__PURE__ */ _parsePrep(input, options);
221
- if (!text) return wantString ? "" : /* @__PURE__ */ new Uint8Array(0);
222
- const alphabet = options?.alphabet ?? "base64";
223
- const loose = options?.loose ?? false;
224
- return /* @__PURE__ */ _parseFinalize(/* @__PURE__ */ _decodeBase64(text, alphabet, loose, "Base64.parse", options?.padding), wantString, !loose, "Base64.parse");
18
+ function ownOptions(options) {
19
+ return options === void 0 || options === null ? NO_OPTIONS : Object.assign(Object.create(null), options);
225
20
  }
21
+ const NO_OPTIONS = /* @__PURE__ */ Object.freeze(Object.create(null));
226
22
  /* @__NO_SIDE_EFFECTS__ */
227
23
  function showValue(value) {
228
24
  if (typeof value === "number" || typeof value === "boolean") return String(value);
229
25
  if (typeof value === "string") return JSON.stringify(value);
230
26
  return /* @__PURE__ */ describeValue(value);
231
27
  }
232
- function assertInteger(source, name, value, min, max = Number.MAX_SAFE_INTEGER) {
28
+ function assertInteger(value, name, source, min, max = Number.MAX_SAFE_INTEGER) {
233
29
  if (Number.isSafeInteger(value) && value >= min && value <= max) return;
234
30
  throw new UnsecureError("OUT_OF_RANGE", `${source}: ${name} must be ${max === Number.MAX_SAFE_INTEGER ? `an integer >= ${min}` : `an integer between ${min} and ${max}`}, got ${/* @__PURE__ */ showValue(value)}.`);
235
31
  }
236
- const SHARED_POOL_BYTES = 4096;
237
- const _MAX_FILL = 65536;
238
- /* @__NO_SIDE_EFFECTS__ */
239
- function createEntropyPool(size) {
240
- let bytes;
241
- let words;
242
- let offset = size;
243
- function refill() {
244
- if (bytes === void 0) {
245
- const buffer = new ArrayBuffer(size);
246
- bytes = new Uint8Array(buffer);
247
- words = new Uint32Array(buffer);
248
- }
249
- crypto.getRandomValues(bytes);
250
- offset = 0;
251
- }
252
- function nextUint32() {
253
- offset = offset + 3 & -4;
254
- if (offset >= size) refill();
255
- const value = words[offset >>> 2];
256
- offset += 4;
257
- return value;
258
- }
259
- function fill(target) {
260
- const length = target.length;
261
- if (length === 0) return target;
262
- if (length > 64) {
263
- if (length <= _MAX_FILL) crypto.getRandomValues(target);
264
- else for (let start = 0; start < length; start += _MAX_FILL) crypto.getRandomValues(target.subarray(start, Math.min(start + _MAX_FILL, length)));
265
- return target;
266
- }
267
- if (offset + length > size) refill();
268
- const slot = bytes.subarray(offset, offset + length);
269
- target.set(slot);
270
- slot.fill(0);
271
- offset += length;
272
- return target;
273
- }
274
- function reset(now = false) {
275
- bytes?.fill(0);
276
- bytes = words = void 0;
277
- offset = size;
278
- if (now) refill();
279
- }
280
- _onSnapshotRestore(reset);
281
- return {
282
- nextUint32,
283
- fill,
284
- reset
285
- };
286
- }
287
- const sharedPool = /* @__PURE__ */ createEntropyPool(SHARED_POOL_BYTES);
288
- function _onSnapshotRestore(callback) {
289
- try {
290
- const proc = globalThis.process;
291
- if (typeof proc?.getBuiltinModule !== "function") return;
292
- const snapshot = proc.getBuiltinModule("node:v8")?.startupSnapshot;
293
- if (snapshot?.isBuildingSnapshot()) snapshot.addDeserializeCallback(callback);
294
- } catch {}
295
- }
296
- const MAX_RANDOM_BYTES = 2 ** 31 - 1;
297
- /* @__NO_SIDE_EFFECTS__ */
298
- function secureRandomBytes(length) {
299
- assertInteger("secureRandomBytes", "length", length, 0, MAX_RANDOM_BYTES);
300
- return sharedPool.fill(new Uint8Array(length));
301
- }
32
+ const textDecoder = /* @__PURE__ */ new TextDecoder("utf-8", /* @__PURE__ */ ownOptions({
33
+ ignoreBOM: true,
34
+ fatal: false
35
+ }));
302
36
  /* @__NO_SIDE_EFFECTS__ */
303
37
  function safeJsonParse(json) {
304
38
  let parsed;
@@ -317,9 +51,14 @@ function sanitizeObject(obj) {
317
51
  return obj;
318
52
  }
319
53
  /* @__NO_SIDE_EFFECTS__ */
320
- function sanitizeObjectCopy(obj) {
321
- if (!/* @__PURE__ */ _isCopyable(obj)) return obj;
322
- return _sanitizeCopy(obj, /* @__PURE__ */ new WeakMap());
54
+ function sanitizeObjectCopy(obj, options) {
55
+ const trusted = /* @__PURE__ */ _allowlist((/* @__PURE__ */ ownOptions(options)).allowlist);
56
+ if (obj === null || typeof obj !== "object") return obj;
57
+ if (!/* @__PURE__ */ _isCopyable(obj)) {
58
+ if (/* @__PURE__ */ _isTrusted(obj, trusted)) return obj;
59
+ throw /* @__PURE__ */ _notCopyable(obj);
60
+ }
61
+ return _sanitizeCopy(obj, trusted, /* @__PURE__ */ new WeakMap());
323
62
  }
324
63
  /* @__NO_SIDE_EFFECTS__ */
325
64
  function _isDangerousKey(key) {
@@ -329,20 +68,7 @@ function _sanitizeInPlace(root, seen) {
329
68
  seen.add(root);
330
69
  const stack = [root];
331
70
  while (stack.length > 0) {
332
- const current = stack.pop();
333
- if (Array.isArray(current)) {
334
- for (let i = 0; i < current.length; i++) {
335
- const descriptor = Object.getOwnPropertyDescriptor(current, i);
336
- if (descriptor === void 0 || !("value" in descriptor)) continue;
337
- const v = descriptor.value;
338
- if (v !== null && typeof v === "object" && !seen.has(v)) {
339
- seen.add(v);
340
- stack.push(v);
341
- }
342
- }
343
- continue;
344
- }
345
- const record = current;
71
+ const record = stack.pop();
346
72
  const keys = Object.getOwnPropertyNames(record);
347
73
  for (let i = 0; i < keys.length; i++) {
348
74
  const key = keys[i];
@@ -360,16 +86,45 @@ function _sanitizeInPlace(root, seen) {
360
86
  }
361
87
  }
362
88
  }
89
+ const _OBJECT_SOURCE = /* @__PURE__ */ Function.prototype.toString.call(Object);
363
90
  /* @__NO_SIDE_EFFECTS__ */
364
91
  function _isPlainObject(value) {
365
92
  const proto = Object.getPrototypeOf(value);
366
- return proto === Object.prototype || proto === null;
93
+ if (proto === null || proto === Object.prototype) return true;
94
+ if (Object.getPrototypeOf(proto) !== null) return false;
95
+ const ctor = Object.getOwnPropertyDescriptor(proto, "constructor");
96
+ return ctor !== void 0 && "value" in ctor && typeof ctor.value === "function" && Function.prototype.toString.call(ctor.value) === _OBJECT_SOURCE;
367
97
  }
368
98
  /* @__NO_SIDE_EFFECTS__ */
369
99
  function _isCopyable(value) {
370
100
  return value !== null && typeof value === "object" && (Array.isArray(value) || /* @__PURE__ */ _isPlainObject(value));
371
101
  }
372
- function _sanitizeCopy(root, seen) {
102
+ /* @__NO_SIDE_EFFECTS__ */
103
+ function _allowlist(value) {
104
+ if (value === void 0) return [];
105
+ if (typeof value === "string" || typeof value[Symbol.iterator] !== "function") throw new UnsecureError("INVALID_TYPE", `sanitizeObjectCopy: allowlist must be an iterable of constructors, got ${/* @__PURE__ */ describeValue(value)}.`);
106
+ const list = [];
107
+ for (const entry of value) {
108
+ if (typeof entry !== "function") throw new UnsecureError("INVALID_TYPE", `sanitizeObjectCopy: allowlist entries must be constructors, got ${/* @__PURE__ */ describeValue(entry)}.`);
109
+ list.push(entry);
110
+ }
111
+ return list;
112
+ }
113
+ /* @__NO_SIDE_EFFECTS__ */
114
+ function _isTrusted(value, trusted) {
115
+ for (let i = 0; i < trusted.length; i++) if (value instanceof trusted[i]) return true;
116
+ return false;
117
+ }
118
+ /* @__NO_SIDE_EFFECTS__ */
119
+ function _notCopyable(value) {
120
+ return new UnsecureError("INVALID_TYPE", `sanitizeObjectCopy: cannot copy an instance of ${/* @__PURE__ */ describeValue(value)}; add it to allowlist, or use sanitizeObject().`);
121
+ }
122
+ /* @__NO_SIDE_EFFECTS__ */
123
+ function _isIndex(key) {
124
+ const n = Number(key);
125
+ return n >>> 0 === n && n !== 4294967295 && String(n) === key;
126
+ }
127
+ function _sanitizeCopy(root, trusted, seen) {
373
128
  const rootTarget = Array.isArray(root) ? [] : {};
374
129
  seen.set(root, rootTarget);
375
130
  const stack = [{
@@ -381,10 +136,13 @@ function _sanitizeCopy(root, seen) {
381
136
  if (Array.isArray(source)) {
382
137
  const out = target;
383
138
  out.length = source.length;
384
- for (let i = 0; i < source.length; i++) {
385
- const descriptor = Object.getOwnPropertyDescriptor(source, i);
139
+ const names = Object.getOwnPropertyNames(source);
140
+ for (let i = 0; i < names.length; i++) {
141
+ const key = names[i];
142
+ if (!/* @__PURE__ */ _isIndex(key)) continue;
143
+ const descriptor = Object.getOwnPropertyDescriptor(source, key);
386
144
  if (descriptor === void 0 || !("value" in descriptor)) continue;
387
- out[i] = _copyValue(descriptor.value, seen, stack);
145
+ out[Number(key)] = _copyValue(descriptor.value, trusted, seen, stack);
388
146
  }
389
147
  continue;
390
148
  }
@@ -396,13 +154,17 @@ function _sanitizeCopy(root, seen) {
396
154
  if (/* @__PURE__ */ _isDangerousKey(key)) continue;
397
155
  const descriptor = Object.getOwnPropertyDescriptor(record, key);
398
156
  if (descriptor === void 0 || !("value" in descriptor)) continue;
399
- out[key] = _copyValue(descriptor.value, seen, stack);
157
+ out[key] = _copyValue(descriptor.value, trusted, seen, stack);
400
158
  }
401
159
  }
402
160
  return rootTarget;
403
161
  }
404
- function _copyValue(value, seen, stack) {
405
- if (!/* @__PURE__ */ _isCopyable(value)) return value;
162
+ function _copyValue(value, trusted, seen, stack) {
163
+ if (value === null || typeof value !== "object") return value;
164
+ if (!/* @__PURE__ */ _isCopyable(value)) {
165
+ if (/* @__PURE__ */ _isTrusted(value, trusted)) return value;
166
+ throw /* @__PURE__ */ _notCopyable(value);
167
+ }
406
168
  const existing = seen.get(value);
407
169
  if (existing !== void 0) return existing;
408
170
  const target = Array.isArray(value) ? [] : {};
@@ -413,4 +175,88 @@ function _copyValue(value, seen, stack) {
413
175
  });
414
176
  return target;
415
177
  }
416
- export { UnsecureError, base64Parse, base64Stringify, safeJsonParse, sanitizeObject, sanitizeObjectCopy, secureRandomBytes, textDecoder, textEncoder };
178
+ const SHARED_POOL_BYTES = 4096;
179
+ const _MAX_FILL = 65536;
180
+ function _random(target) {
181
+ try {
182
+ return crypto.getRandomValues(target);
183
+ } catch (error) {
184
+ throw new UnsecureError("PLATFORM", "the runtime's crypto.getRandomValues refused.", { cause: error });
185
+ }
186
+ }
187
+ function _direct(target) {
188
+ const length = target.length;
189
+ if (length <= _MAX_FILL) {
190
+ _random(target);
191
+ return;
192
+ }
193
+ for (let start = 0; start < length; start += _MAX_FILL) _random(target.subarray(start, Math.min(start + _MAX_FILL, length)));
194
+ }
195
+ /* @__NO_SIDE_EFFECTS__ */
196
+ function _startupSnapshot() {
197
+ try {
198
+ const proc = globalThis.process;
199
+ if (typeof proc?.getBuiltinModule !== "function") return void 0;
200
+ return proc.getBuiltinModule("node:v8")?.startupSnapshot;
201
+ } catch {
202
+ return;
203
+ }
204
+ }
205
+ /* @__NO_SIDE_EFFECTS__ */
206
+ function createEntropyPool(size) {
207
+ let bytes;
208
+ let words;
209
+ let offset = size;
210
+ const snapshot = /* @__PURE__ */ _startupSnapshot();
211
+ function refill() {
212
+ if (bytes === void 0) {
213
+ const buffer = new ArrayBuffer(size);
214
+ bytes = new Uint8Array(buffer);
215
+ words = new Uint32Array(buffer);
216
+ }
217
+ _random(bytes);
218
+ offset = 0;
219
+ }
220
+ function nextUint32() {
221
+ if (snapshot?.isBuildingSnapshot()) return _random(/* @__PURE__ */ new Uint32Array(1))[0];
222
+ offset = offset + 3 & -4;
223
+ if (offset >= size) refill();
224
+ const value = words[offset >>> 2];
225
+ offset += 4;
226
+ return value;
227
+ }
228
+ function fill(target) {
229
+ const length = target.length;
230
+ if (length === 0) return target;
231
+ if (length > 64 || snapshot?.isBuildingSnapshot()) {
232
+ _direct(target);
233
+ return target;
234
+ }
235
+ if (offset + length > size) refill();
236
+ const slot = bytes.subarray(offset, offset + length);
237
+ target.set(slot);
238
+ slot.fill(0);
239
+ offset += length;
240
+ return target;
241
+ }
242
+ function reset(now = false) {
243
+ bytes?.fill(0);
244
+ bytes = words = void 0;
245
+ offset = size;
246
+ if (now) refill();
247
+ }
248
+ if (snapshot?.isBuildingSnapshot()) snapshot.addDeserializeCallback(() => reset());
249
+ return {
250
+ nextUint32,
251
+ fill,
252
+ reset
253
+ };
254
+ }
255
+ const sharedPool = /* @__PURE__ */ createEntropyPool(SHARED_POOL_BYTES);
256
+ const MAX_RANDOM_BYTES = 2 ** 31 - 1;
257
+ /* @__NO_SIDE_EFFECTS__ */
258
+ function secureRandomBytes(length) {
259
+ assertInteger(length, "length", "secureRandomBytes", 0, MAX_RANDOM_BYTES);
260
+ return sharedPool.fill(new Uint8Array(length));
261
+ }
262
+ export { UnsecureError, safeJsonParse, sanitizeObject, sanitizeObjectCopy, secureRandomBytes, textDecoder, textEncoder };
@@ -1,5 +1,5 @@
1
1
  import { JOSELimits } from "./index.mjs";
2
- import "./index2.mjs";
2
+ import "./index3.mjs";
3
3
  /**
4
4
  * Default per-call work limits: 16 signatures, 16 recipients, 8 JWK Set candidates,
5
5
  * and PBKDF2 iterations for four default-cost PBES2 attempts in total.
@@ -0,0 +1,23 @@
1
+ import { JWTError } from "../error.mjs";
2
+ import { validateJwtClaims } from "./jwt.mjs";
3
+ function validateClaimsIfJson(payload, mode, options) {
4
+ if (mode !== "json" || options.validateClaims === false) return;
5
+ validateJwtClaims(payload, options);
6
+ }
7
+ const PAYLOAD_MODES = /* @__PURE__ */ new Set([
8
+ "json",
9
+ "string",
10
+ "bytes"
11
+ ]);
12
+ function resolvePayloadMode(options) {
13
+ const { payload, forceUint8Array, validateClaims } = options;
14
+ if (payload !== void 0 && !PAYLOAD_MODES.has(payload)) throw new JWTError("\"payload\" must be \"json\", \"string\" or \"bytes\".", "ERR_INVALID_OPTION");
15
+ let mode = payload ?? "json";
16
+ if (forceUint8Array !== void 0) {
17
+ if (payload === void 0) mode = forceUint8Array ? "bytes" : "json";
18
+ else if (forceUint8Array !== (payload === "bytes")) throw new JWTError("\"forceUint8Array\" contradicts \"payload\", pass \"payload\" alone.", "ERR_INVALID_OPTION");
19
+ }
20
+ if (validateClaims === true && mode !== "json") throw new JWTError("\"validateClaims\" requires payload: \"json\".", "ERR_INVALID_OPTION");
21
+ return mode;
22
+ }
23
+ export { resolvePayloadMode, validateClaimsIfJson };