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.
- package/README.md +3 -9
- package/dist/_chunks/{_import-key.mjs → algorithms.mjs} +194 -399
- package/dist/_chunks/{_codec-jwe.d.mts → codec-jwe.d.mts} +40 -9
- package/dist/_chunks/{_codec-jws.mjs → codec-jws.mjs} +133 -80
- 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} +2 -1
- package/dist/_chunks/{jws.d.mts → index5.d.mts} +2 -1
- package/dist/_chunks/index6.d.mts +113 -0
- package/dist/_chunks/jwe.mjs +205 -72
- package/dist/{core → _chunks}/jwk.mjs +210 -495
- package/dist/_chunks/jws.mjs +280 -193
- package/dist/_chunks/jwt.d.mts +2 -1
- package/dist/_chunks/{_jwt-internal.mjs → jwt.mjs} +110 -54
- package/dist/_chunks/libs/unsecure.d.mts +35 -25
- package/dist/_chunks/libs/unsecure.mjs +101 -268
- 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 +4 -3
- package/dist/adapters/h3/index.d.mts +13 -13
- package/dist/adapters/h3/index.mjs +8 -11
- package/dist/adapters/h3v1/index.d.mts +5 -5
- package/dist/adapters/h3v1/index.mjs +6 -9
- 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.d.mts → jwk/index.d.mts} +5 -4
- 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 -4
- package/dist/session/index.d.mts +4 -4
- package/dist/session/index.mjs +6 -47
- package/dist/utils/index.d.mts +7 -0
- package/dist/{core/utils → utils}/index.mjs +4 -3
- package/package.json +21 -10
- package/dist/_chunks/jwk.d.mts +0 -205
- package/dist/core/jwe.mjs +0 -5
- 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,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
|
-
|
|
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 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
|
|
223
|
-
if (
|
|
224
|
-
if (
|
|
225
|
-
return /* @__PURE__ */
|
|
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
|
-
|
|
232
|
-
|
|
233
|
-
|
|
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
|
-
|
|
259
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
322
|
-
|
|
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[
|
|
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 (
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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,
|
|
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 };
|