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.
- package/README.md +3 -9
- package/dist/_chunks/algorithms.mjs +1541 -0
- package/dist/_chunks/{_codec-jwe.d.mts → codec-jwe.d.mts} +40 -9
- package/dist/_chunks/{_codec-jws.mjs → codec-jws.mjs} +148 -95
- package/dist/_chunks/cookie.mjs +50 -0
- package/dist/_chunks/digest.mjs +10 -3
- package/dist/_chunks/error.d.mts +103 -0
- package/dist/_chunks/export.mjs +97 -0
- package/dist/_chunks/index.d.mts +5 -103
- package/dist/_chunks/index2.d.mts +206 -12
- package/dist/_chunks/index3.d.mts +12 -109
- package/dist/_chunks/{jwe.d.mts → index4.d.mts} +3 -1
- package/dist/_chunks/{jws.d.mts → index5.d.mts} +6 -2
- package/dist/_chunks/index6.d.mts +113 -0
- package/dist/_chunks/jwe.mjs +208 -74
- package/dist/_chunks/jwk.mjs +214 -2237
- package/dist/_chunks/jws.mjs +289 -202
- package/dist/_chunks/jwt.d.mts +2 -1
- package/dist/_chunks/{_jwt-internal.mjs → jwt.mjs} +124 -68
- package/dist/_chunks/libs/unsecure.d.mts +35 -25
- package/dist/_chunks/libs/unsecure.mjs +148 -302
- package/dist/_chunks/{_internal.d.mts → limits.d.mts} +1 -1
- package/dist/_chunks/payload.mjs +23 -0
- package/dist/_chunks/wrap.mjs +209 -0
- package/dist/adapters/elysia/index.d.mts +4 -4
- package/dist/adapters/elysia/index.mjs +5 -3
- package/dist/adapters/h3/index.d.mts +13 -13
- package/dist/adapters/h3/index.mjs +8 -10
- package/dist/adapters/h3v1/index.d.mts +5 -5
- package/dist/adapters/h3v1/index.mjs +6 -8
- package/dist/core/internal.mjs +1 -1
- package/dist/core/{jwe.d.mts → jwe/index.d.mts} +5 -4
- package/dist/core/jwe/index.mjs +5 -0
- package/dist/core/jwk/index.d.mts +6 -0
- package/dist/core/jwk/index.mjs +7 -0
- package/dist/core/{jws.d.mts → jws/index.d.mts} +5 -4
- package/dist/core/jws/index.mjs +5 -0
- package/dist/dpop/index.d.mts +73 -0
- package/dist/dpop/index.mjs +296 -0
- package/dist/error.d.mts +3 -0
- package/dist/error.mjs +20 -0
- package/dist/index.d.mts +10 -9
- package/dist/index.mjs +7 -3
- package/dist/session/index.d.mts +4 -4
- package/dist/session/index.mjs +6 -46
- package/dist/utils/index.d.mts +7 -0
- package/dist/{core/utils → utils}/index.mjs +4 -3
- package/package.json +22 -10
- package/dist/core/jwe.mjs +0 -5
- package/dist/core/jwk.d.mts +0 -207
- package/dist/core/jwk.mjs +0 -4
- package/dist/core/jws.mjs +0 -5
- package/dist/core/utils/index.d.mts +0 -6
- /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
|
-
|
|
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
|
|
18
|
-
|
|
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(
|
|
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
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
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
|
-
|
|
322
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
385
|
-
|
|
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[
|
|
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 (
|
|
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
|
-
|
|
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 };
|
|
@@ -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 };
|