unjwt 0.8.4 → 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 (53) hide show
  1. package/README.md +3 -9
  2. package/dist/_chunks/{_import-key.mjs → algorithms.mjs} +194 -399
  3. package/dist/_chunks/{_codec-jwe.d.mts → codec-jwe.d.mts} +40 -9
  4. package/dist/_chunks/{_codec-jws.mjs → codec-jws.mjs} +133 -80
  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} +2 -1
  13. package/dist/_chunks/{jws.d.mts → index5.d.mts} +2 -1
  14. package/dist/_chunks/index6.d.mts +113 -0
  15. package/dist/_chunks/jwe.mjs +205 -72
  16. package/dist/{core → _chunks}/jwk.mjs +210 -495
  17. package/dist/_chunks/jws.mjs +280 -193
  18. package/dist/_chunks/jwt.d.mts +2 -1
  19. package/dist/_chunks/{_jwt-internal.mjs → jwt.mjs} +110 -54
  20. package/dist/_chunks/libs/unsecure.d.mts +35 -25
  21. package/dist/_chunks/libs/unsecure.mjs +101 -268
  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 +4 -3
  27. package/dist/adapters/h3/index.d.mts +13 -13
  28. package/dist/adapters/h3/index.mjs +8 -11
  29. package/dist/adapters/h3v1/index.d.mts +5 -5
  30. package/dist/adapters/h3v1/index.mjs +6 -9
  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.d.mts → jwk/index.d.mts} +5 -4
  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 -4
  44. package/dist/session/index.d.mts +4 -4
  45. package/dist/session/index.mjs +6 -47
  46. package/dist/utils/index.d.mts +7 -0
  47. package/dist/{core/utils → utils}/index.mjs +4 -3
  48. package/package.json +21 -10
  49. package/dist/_chunks/jwk.d.mts +0 -205
  50. package/dist/core/jwe.mjs +0 -5
  51. package/dist/core/jws.mjs +0 -5
  52. package/dist/core/utils/index.d.mts +0 -6
  53. /package/dist/_chunks/{_cookie-attributes.d.mts → cookie-attributes.d.mts} +0 -0
@@ -11,231 +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 honoursViews(encode, expected) {
30
- try {
31
- return encode(Uint8Array.of(0, 1, 2, 3).subarray(1, 3)) === expected;
32
- } catch {
33
- return false;
34
- }
35
- }
36
- /* @__NO_SIDE_EFFECTS__ */
37
- function wholeBuffer(bytes, honoured) {
38
- if (honoured) return bytes;
39
- return bytes.byteOffset === 0 && bytes.byteLength === bytes.buffer.byteLength ? bytes : bytes.slice();
40
- }
41
- const _LATIN1_CHUNK = 32768;
42
- /* @__NO_SIDE_EFFECTS__ */
43
- function _latin1(bytes) {
44
- if (bytes.length <= _LATIN1_CHUNK) return String.fromCharCode(...bytes);
45
- let text = "";
46
- for (let i = 0; i < bytes.length; i += _LATIN1_CHUNK) text += String.fromCharCode(...bytes.subarray(i, i + _LATIN1_CHUNK));
47
- return text;
48
- }
49
- function assertData(input, source) {
50
- if (typeof input !== "string" && !/* @__PURE__ */ _isBytes(input)) throw new UnsecureError("INVALID_TYPE", `${source}: expected a string or Uint8Array, got ${/* @__PURE__ */ describeValue(input)}.`);
51
- }
52
- /* @__NO_SIDE_EFFECTS__ */
53
- function _isBytes(input) {
54
- return ArrayBuffer.isView(input) && input instanceof Uint8Array;
55
- }
56
- /* @__NO_SIDE_EFFECTS__ */
57
- function parsePrep(input, options) {
58
- const isBytes = /* @__PURE__ */ _isBytes(input);
59
- const returnAs = options?.returnAs ?? (isBytes ? "uint8array" : "string");
60
- return {
61
- text: isBytes ? /* @__PURE__ */ _latin1(input) : input,
62
- wantString: returnAs === "string"
63
- };
64
- }
65
- /* @__NO_SIDE_EFFECTS__ */
66
- function parseFinalize(bytes, wantString, strict, source) {
67
- if (!wantString) return bytes;
68
- if (!strict) return textDecoder.decode(bytes);
69
- try {
70
- return _fatalDecoder.decode(bytes);
71
- } catch {
72
- throw /* @__PURE__ */ malformed("decoded bytes are not valid UTF-8.", source);
73
- }
74
- }
75
- /* @__NO_SIDE_EFFECTS__ */
76
- function malformed(detail, source) {
77
- return new UnsecureError("MALFORMED", `${source}: ${detail}`);
78
- }
79
- /* @__NO_SIDE_EFFECTS__ */
80
- function tailBits(rem, bits) {
81
- if (rem === 0) return 0;
82
- const leftover = rem * bits % 8;
83
- return leftover >= bits ? -1 : leftover;
84
- }
85
- /* @__NO_SIDE_EFFECTS__ */
86
- function strictBody(text, table, shape, source, padding) {
87
- let end = text.length;
88
- while (end > 0 && text.charCodeAt(end - 1) === 61) end--;
89
- const padFound = text.length - end;
90
- for (let i = 0; i < end; i++) {
91
- const c = text.charCodeAt(i);
92
- if ((c < 128 ? table[c] : -1) < 0) throw /* @__PURE__ */ malformed(`invalid ${shape.name} character ${JSON.stringify(text[i])} at index ${i}.`, source);
93
- }
94
- const rem = end % shape.group;
95
- const tail = /* @__PURE__ */ tailBits(rem, shape.bits);
96
- if (tail < 0) throw /* @__PURE__ */ malformed(`${end} ${shape.name} symbols cannot encode whole bytes.`, source);
97
- const padNeeded = rem === 0 ? 0 : shape.group - rem;
98
- if (padFound > 0) {
99
- if (padNeeded === 0 || padding === false) throw /* @__PURE__ */ malformed(`unexpected "=" padding.`, source);
100
- if (padFound !== padNeeded) throw /* @__PURE__ */ malformed(`expected ${padNeeded} "=" padding characters, found ${padFound}.`, source);
101
- } else if (padding === true && padNeeded > 0) throw /* @__PURE__ */ malformed(`expected ${padNeeded} "=" padding characters, found 0.`, source);
102
- if (tail > 0 && (table[text.charCodeAt(end - 1)] & (1 << tail) - 1) !== 0) throw /* @__PURE__ */ malformed(`the last ${shape.name} symbol sets bits past the final byte.`, source);
103
- return end === text.length ? text : text.slice(0, end);
104
- }
105
- /* @__NO_SIDE_EFFECTS__ */
106
- function symbols(text, table) {
107
- const values = new Uint8Array(text.length);
108
- let n = 0;
109
- for (let i = 0; i < text.length; i++) {
110
- const c = text.charCodeAt(i);
111
- const v = c < 128 ? table[c] : -1;
112
- if (v >= 0) values[n++] = v;
113
- }
114
- return n === values.length ? values : values.subarray(0, n);
115
- }
116
- /* @__NO_SIDE_EFFECTS__ */
117
- function looseCount(n, shape) {
118
- let count = n;
119
- while (count > 0 && /* @__PURE__ */ tailBits(count % shape.group, shape.bits) < 0) count--;
120
- return count;
121
- }
122
- /* @__NO_SIDE_EFFECTS__ */
123
- function decodeSymbols(values, count, bits) {
124
- const out = new Uint8Array(count * bits >>> 3);
125
- let acc = 0;
126
- let held = 0;
127
- let j = 0;
128
- for (let i = 0; i < count; i++) {
129
- acc = acc << bits | values[i];
130
- held += bits;
131
- if (held >= 8) {
132
- held -= 8;
133
- out[j++] = acc >>> held & 255;
134
- }
135
- }
136
- return out;
137
- }
138
- const _ON_HEAP_MAX = 64;
139
- const nodeBuffer = /* @__PURE__ */ (() => {
140
- try {
141
- return globalThis.Buffer;
142
- } catch {
143
- return;
144
- }
145
- })();
146
- const hasBuffer = /* @__PURE__ */ (() => typeof nodeBuffer?.from === "function")();
147
- /* @__NO_SIDE_EFFECTS__ */
148
- function toBuffer(bytes) {
149
- return bytes.byteLength <= _ON_HEAP_MAX ? nodeBuffer.from(bytes) : nodeBuffer.from(bytes.buffer, bytes.byteOffset, bytes.byteLength);
150
- }
151
- /* @__NO_SIDE_EFFECTS__ */
152
- function preferBuffer(byteLength, native) {
153
- return hasBuffer && !(native && byteLength <= _ON_HEAP_MAX);
154
- }
155
- const _nativeToBase64 = /* @__PURE__ */ (() => typeof Uint8Array.prototype.toBase64 === "function")();
156
- const _nativeFromBase64 = /* @__PURE__ */ (() => typeof Uint8Array.fromBase64 === "function")();
157
- const _base64Views = /* @__PURE__ */ (() => !_nativeToBase64 || /* @__PURE__ */ honoursViews((view) => view.toBase64(), "AQI="))();
158
- const _SHAPE = {
159
- bits: 6,
160
- group: 4,
161
- name: "base64"
162
- };
163
- const _DIGITS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
164
- /* @__NO_SIDE_EFFECTS__ */
165
- function _table(pairs) {
166
- const t = (/* @__PURE__ */ new Int16Array(128)).fill(-1);
167
- for (let i = 0; i < 62; i++) t[_DIGITS.charCodeAt(i)] = i;
168
- for (let i = 0; i < pairs.length; i += 2) {
169
- t[pairs.charCodeAt(i)] = 62;
170
- t[pairs.charCodeAt(i + 1)] = 63;
171
- }
172
- return t;
173
- }
174
- const _TABLE_STD = /* @__PURE__ */ _table("+/");
175
- const _TABLE_URL = /* @__PURE__ */ _table("-_");
176
- /* @__NO_SIDE_EFFECTS__ */
177
- function _unpad(s) {
178
- let end = s.length;
179
- while (end > 0 && s.charCodeAt(end - 1) === 61) end--;
180
- return end === s.length ? s : s.slice(0, end);
181
- }
182
- /* @__NO_SIDE_EFFECTS__ */
183
- function _padTo4(s) {
184
- const rem = s.length % 4;
185
- return rem === 0 ? s : s + "=".repeat(4 - rem);
186
- }
187
- /* @__NO_SIDE_EFFECTS__ */
188
- function base64StringifyBytes(bytes, options = {}) {
189
- const alphabet = options.alphabet ?? "base64";
190
- const padding = options.padding ?? alphabet !== "base64url";
191
- const url = alphabet === "base64url";
192
- if (/* @__PURE__ */ preferBuffer(bytes.length, _nativeToBase64)) {
193
- const s = (/* @__PURE__ */ toBuffer(bytes)).toString(url ? "base64url" : "base64");
194
- if (url) return padding ? /* @__PURE__ */ _padTo4(s) : s;
195
- return padding ? s : /* @__PURE__ */ _unpad(s);
196
- }
197
- if (_nativeToBase64) return (/* @__PURE__ */ wholeBuffer(bytes, _base64Views)).toBase64({
198
- alphabet,
199
- omitPadding: !padding
200
- });
201
- let binary = "";
202
- for (let i = 0; i < bytes.length; i++) binary += String.fromCharCode(bytes[i]);
203
- let s = btoa(binary);
204
- if (url) s = s.replace(/\+/g, "-").replace(/\//g, "_");
205
- return padding ? s : /* @__PURE__ */ _unpad(s);
206
- }
207
- /* @__NO_SIDE_EFFECTS__ */
208
- function base64ParseText(text, source, options = {}) {
209
- const url = (options.alphabet ?? "base64") === "base64url";
210
- let body;
211
- if (options.loose) {
212
- const clean = text.replace(/-/g, "+").replace(/_/g, "/").replace(/[^A-Za-z0-9+/]/g, "");
213
- body = clean.slice(0, /* @__PURE__ */ looseCount(clean.length, _SHAPE));
214
- } else {
215
- const strict = /* @__PURE__ */ strictBody(text, url ? _TABLE_URL : _TABLE_STD, _SHAPE, source, options.padding);
216
- body = url ? strict.replace(/-/g, "+").replace(/_/g, "/") : strict;
217
- }
218
- const rem = body.length % 4;
219
- return /* @__PURE__ */ _bulk$1(rem === 0 ? body : body + (rem === 2 ? "==" : "="), body.length);
18
+ function ownOptions(options) {
19
+ return options === void 0 || options === null ? NO_OPTIONS : Object.assign(Object.create(null), options);
220
20
  }
21
+ const NO_OPTIONS = /* @__PURE__ */ Object.freeze(Object.create(null));
221
22
  /* @__NO_SIDE_EFFECTS__ */
222
- function _bulk$1(padded, count) {
223
- if (/* @__PURE__ */ preferBuffer(count * 6 >>> 3, _nativeFromBase64)) return new Uint8Array(nodeBuffer.from(padded, "base64"));
224
- if (_nativeFromBase64) return Uint8Array.fromBase64(padded);
225
- return /* @__PURE__ */ decodeSymbols(/* @__PURE__ */ symbols(padded, _TABLE_STD), count, 6);
226
- }
227
- /* @__NO_SIDE_EFFECTS__ */
228
- function base64Stringify(data, options) {
229
- return /* @__PURE__ */ base64StringifyBytes(/* @__PURE__ */ toBytes(data, "Base64.stringify"), options);
23
+ function showValue(value) {
24
+ if (typeof value === "number" || typeof value === "boolean") return String(value);
25
+ if (typeof value === "string") return JSON.stringify(value);
26
+ return /* @__PURE__ */ describeValue(value);
230
27
  }
231
- /* @__NO_SIDE_EFFECTS__ */
232
- function base64Parse(input, options) {
233
- assertData(input, "Base64.parse");
234
- const { text, wantString } = /* @__PURE__ */ parsePrep(input, options);
235
- if (!text) return wantString ? "" : /* @__PURE__ */ new Uint8Array(0);
236
- const loose = options?.loose ?? false;
237
- return /* @__PURE__ */ parseFinalize(/* @__PURE__ */ base64ParseText(text, "Base64.parse", options), wantString, !loose, "Base64.parse");
28
+ function assertInteger(value, name, source, min, max = Number.MAX_SAFE_INTEGER) {
29
+ if (Number.isSafeInteger(value) && value >= min && value <= max) return;
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)}.`);
238
31
  }
32
+ const textDecoder = /* @__PURE__ */ new TextDecoder("utf-8", /* @__PURE__ */ ownOptions({
33
+ ignoreBOM: true,
34
+ fatal: false
35
+ }));
239
36
  /* @__NO_SIDE_EFFECTS__ */
240
37
  function safeJsonParse(json) {
241
38
  let parsed;
@@ -254,9 +51,14 @@ function sanitizeObject(obj) {
254
51
  return obj;
255
52
  }
256
53
  /* @__NO_SIDE_EFFECTS__ */
257
- function sanitizeObjectCopy(obj) {
258
- if (!/* @__PURE__ */ _isCopyable(obj)) return obj;
259
- 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());
260
62
  }
261
63
  /* @__NO_SIDE_EFFECTS__ */
262
64
  function _isDangerousKey(key) {
@@ -266,20 +68,7 @@ function _sanitizeInPlace(root, seen) {
266
68
  seen.add(root);
267
69
  const stack = [root];
268
70
  while (stack.length > 0) {
269
- const current = stack.pop();
270
- if (Array.isArray(current)) {
271
- for (let i = 0; i < current.length; i++) {
272
- const descriptor = Object.getOwnPropertyDescriptor(current, i);
273
- if (descriptor === void 0 || !("value" in descriptor)) continue;
274
- const v = descriptor.value;
275
- if (v !== null && typeof v === "object" && !seen.has(v)) {
276
- seen.add(v);
277
- stack.push(v);
278
- }
279
- }
280
- continue;
281
- }
282
- const record = current;
71
+ const record = stack.pop();
283
72
  const keys = Object.getOwnPropertyNames(record);
284
73
  for (let i = 0; i < keys.length; i++) {
285
74
  const key = keys[i];
@@ -297,16 +86,45 @@ function _sanitizeInPlace(root, seen) {
297
86
  }
298
87
  }
299
88
  }
89
+ const _OBJECT_SOURCE = /* @__PURE__ */ Function.prototype.toString.call(Object);
300
90
  /* @__NO_SIDE_EFFECTS__ */
301
91
  function _isPlainObject(value) {
302
92
  const proto = Object.getPrototypeOf(value);
303
- 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;
304
97
  }
305
98
  /* @__NO_SIDE_EFFECTS__ */
306
99
  function _isCopyable(value) {
307
100
  return value !== null && typeof value === "object" && (Array.isArray(value) || /* @__PURE__ */ _isPlainObject(value));
308
101
  }
309
- 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) {
310
128
  const rootTarget = Array.isArray(root) ? [] : {};
311
129
  seen.set(root, rootTarget);
312
130
  const stack = [{
@@ -318,10 +136,13 @@ function _sanitizeCopy(root, seen) {
318
136
  if (Array.isArray(source)) {
319
137
  const out = target;
320
138
  out.length = source.length;
321
- for (let i = 0; i < source.length; i++) {
322
- 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);
323
144
  if (descriptor === void 0 || !("value" in descriptor)) continue;
324
- out[i] = _copyValue(descriptor.value, seen, stack);
145
+ out[Number(key)] = _copyValue(descriptor.value, trusted, seen, stack);
325
146
  }
326
147
  continue;
327
148
  }
@@ -333,13 +154,17 @@ function _sanitizeCopy(root, seen) {
333
154
  if (/* @__PURE__ */ _isDangerousKey(key)) continue;
334
155
  const descriptor = Object.getOwnPropertyDescriptor(record, key);
335
156
  if (descriptor === void 0 || !("value" in descriptor)) continue;
336
- out[key] = _copyValue(descriptor.value, seen, stack);
157
+ out[key] = _copyValue(descriptor.value, trusted, seen, stack);
337
158
  }
338
159
  }
339
160
  return rootTarget;
340
161
  }
341
- function _copyValue(value, seen, stack) {
342
- 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
+ }
343
168
  const existing = seen.get(value);
344
169
  if (existing !== void 0) return existing;
345
170
  const target = Array.isArray(value) ? [] : {};
@@ -350,33 +175,50 @@ function _copyValue(value, seen, stack) {
350
175
  });
351
176
  return target;
352
177
  }
353
- /* @__NO_SIDE_EFFECTS__ */
354
- function showValue(value) {
355
- if (typeof value === "number" || typeof value === "boolean") return String(value);
356
- if (typeof value === "string") return JSON.stringify(value);
357
- return /* @__PURE__ */ describeValue(value);
358
- }
359
- function assertInteger(value, name, source, min, max = Number.MAX_SAFE_INTEGER) {
360
- if (Number.isSafeInteger(value) && value >= min && value <= max) return;
361
- 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)}.`);
362
- }
363
178
  const SHARED_POOL_BYTES = 4096;
364
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
+ }
365
205
  /* @__NO_SIDE_EFFECTS__ */
366
206
  function createEntropyPool(size) {
367
207
  let bytes;
368
208
  let words;
369
209
  let offset = size;
210
+ const snapshot = /* @__PURE__ */ _startupSnapshot();
370
211
  function refill() {
371
212
  if (bytes === void 0) {
372
213
  const buffer = new ArrayBuffer(size);
373
214
  bytes = new Uint8Array(buffer);
374
215
  words = new Uint32Array(buffer);
375
216
  }
376
- crypto.getRandomValues(bytes);
217
+ _random(bytes);
377
218
  offset = 0;
378
219
  }
379
220
  function nextUint32() {
221
+ if (snapshot?.isBuildingSnapshot()) return _random(/* @__PURE__ */ new Uint32Array(1))[0];
380
222
  offset = offset + 3 & -4;
381
223
  if (offset >= size) refill();
382
224
  const value = words[offset >>> 2];
@@ -386,9 +228,8 @@ function createEntropyPool(size) {
386
228
  function fill(target) {
387
229
  const length = target.length;
388
230
  if (length === 0) return target;
389
- if (length > 64) {
390
- if (length <= _MAX_FILL) crypto.getRandomValues(target);
391
- else for (let start = 0; start < length; start += _MAX_FILL) crypto.getRandomValues(target.subarray(start, Math.min(start + _MAX_FILL, length)));
231
+ if (length > 64 || snapshot?.isBuildingSnapshot()) {
232
+ _direct(target);
392
233
  return target;
393
234
  }
394
235
  if (offset + length > size) refill();
@@ -404,7 +245,7 @@ function createEntropyPool(size) {
404
245
  offset = size;
405
246
  if (now) refill();
406
247
  }
407
- _onSnapshotRestore(reset);
248
+ if (snapshot?.isBuildingSnapshot()) snapshot.addDeserializeCallback(() => reset());
408
249
  return {
409
250
  nextUint32,
410
251
  fill,
@@ -412,18 +253,10 @@ function createEntropyPool(size) {
412
253
  };
413
254
  }
414
255
  const sharedPool = /* @__PURE__ */ createEntropyPool(SHARED_POOL_BYTES);
415
- function _onSnapshotRestore(callback) {
416
- try {
417
- const proc = globalThis.process;
418
- if (typeof proc?.getBuiltinModule !== "function") return;
419
- const snapshot = proc.getBuiltinModule("node:v8")?.startupSnapshot;
420
- if (snapshot?.isBuildingSnapshot()) snapshot.addDeserializeCallback(callback);
421
- } catch {}
422
- }
423
256
  const MAX_RANDOM_BYTES = 2 ** 31 - 1;
424
257
  /* @__NO_SIDE_EFFECTS__ */
425
258
  function secureRandomBytes(length) {
426
259
  assertInteger(length, "length", "secureRandomBytes", 0, MAX_RANDOM_BYTES);
427
260
  return sharedPool.fill(new Uint8Array(length));
428
261
  }
429
- export { UnsecureError, base64Parse, base64Stringify, safeJsonParse, sanitizeObject, sanitizeObjectCopy, secureRandomBytes, textDecoder, textEncoder };
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 };