princejs 2.0.0 → 2.1.0
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 +103 -0
- package/dist/middleware.js +246 -272
- package/dist/prince.d.ts +14 -4
- package/dist/prince.d.ts.map +1 -1
- package/dist/prince.js +53 -4
- package/package.json +7 -8
package/README.md
CHANGED
|
@@ -63,6 +63,7 @@ app.listen(3000);
|
|
|
63
63
|
| Routing | `princejs` |
|
|
64
64
|
| Middleware (CORS, Logger, Rate Limit, Auth, JWT) | `princejs/middleware` |
|
|
65
65
|
| Zod Validation | `princejs/middleware` |
|
|
66
|
+
| **Cookies & IP Detection** | `princejs` |
|
|
66
67
|
| File Uploads | `princejs/helpers` |
|
|
67
68
|
| WebSockets | `princejs` |
|
|
68
69
|
| Server-Sent Events | `princejs/helpers` |
|
|
@@ -80,6 +81,91 @@ app.listen(3000);
|
|
|
80
81
|
|
|
81
82
|
---
|
|
82
83
|
|
|
84
|
+
## 🍪 Cookies & 🌐 IP Detection
|
|
85
|
+
|
|
86
|
+
### Reading Cookies
|
|
87
|
+
|
|
88
|
+
Cookies are automatically parsed from the request:
|
|
89
|
+
|
|
90
|
+
```ts
|
|
91
|
+
app.get("/profile", (req) => ({
|
|
92
|
+
sessionId: req.cookies?.sessionId,
|
|
93
|
+
theme: req.cookies?.theme,
|
|
94
|
+
allCookies: req.cookies // Record<string, string>
|
|
95
|
+
}));
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### Setting Cookies
|
|
99
|
+
|
|
100
|
+
Use the response builder to set cookies with full control:
|
|
101
|
+
|
|
102
|
+
```ts
|
|
103
|
+
app.get("/login", (req) =>
|
|
104
|
+
app.response()
|
|
105
|
+
.status(200)
|
|
106
|
+
.json({ ok: true })
|
|
107
|
+
.cookie("sessionId", "abc123", {
|
|
108
|
+
maxAge: 3600, // 1 hour
|
|
109
|
+
path: "/",
|
|
110
|
+
httpOnly: true, // not accessible from JS
|
|
111
|
+
secure: true, // HTTPS only
|
|
112
|
+
sameSite: "Strict" // CSRF protection
|
|
113
|
+
})
|
|
114
|
+
);
|
|
115
|
+
|
|
116
|
+
// Chain multiple cookies
|
|
117
|
+
app.response()
|
|
118
|
+
.json({ ok: true })
|
|
119
|
+
.cookie("session", "xyz")
|
|
120
|
+
.cookie("theme", "dark")
|
|
121
|
+
.cookie("lang", "en");
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Client IP Detection
|
|
125
|
+
|
|
126
|
+
Automatically detect client IP from request headers:
|
|
127
|
+
|
|
128
|
+
```ts
|
|
129
|
+
app.get("/api/data", (req) => ({
|
|
130
|
+
clientIp: req.ip,
|
|
131
|
+
data: [...]
|
|
132
|
+
}));
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
**Supported headers** (in priority order):
|
|
136
|
+
- `X-Forwarded-For` — Load balancers, proxies (first IP in list)
|
|
137
|
+
- `X-Real-IP` — Nginx, Apache reverse proxy
|
|
138
|
+
- `CF-Connecting-IP` — Cloudflare
|
|
139
|
+
- `X-Client-IP` — Other proxy services
|
|
140
|
+
- Fallback — `127.0.0.1` (localhost)
|
|
141
|
+
|
|
142
|
+
**Use cases:**
|
|
143
|
+
- 🔒 Rate limiting per IP
|
|
144
|
+
- 📊 Geolocation analytics
|
|
145
|
+
- 🚨 IP-based access control
|
|
146
|
+
- 👥 User tracking & fraud detection
|
|
147
|
+
|
|
148
|
+
```ts
|
|
149
|
+
// Rate limit by IP
|
|
150
|
+
app.use((req, next) => {
|
|
151
|
+
const ip = req.ip;
|
|
152
|
+
const count = ipTracker.getCount(ip) || 0;
|
|
153
|
+
if (count > 100) return new Response("Too many requests", { status: 429 });
|
|
154
|
+
ipTracker.increment(ip);
|
|
155
|
+
return next();
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
// IP-based security
|
|
159
|
+
app.post("/admin", (req) => {
|
|
160
|
+
if (!ALLOWED_IPS.includes(req.ip!)) {
|
|
161
|
+
return new Response("Forbidden", { status: 403 });
|
|
162
|
+
}
|
|
163
|
+
return { authorized: true };
|
|
164
|
+
});
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
---
|
|
168
|
+
|
|
83
169
|
## 📖 OpenAPI + Scalar Docs ✨
|
|
84
170
|
|
|
85
171
|
Auto-generate an OpenAPI 3.0 spec and serve a beautiful [Scalar](https://scalar.com) UI — all from a single `app.openapi()` call. Routes, validation, and docs stay in sync automatically.
|
|
@@ -330,6 +416,23 @@ app.use(compress());
|
|
|
330
416
|
const Page = () => Html(Head("Test Page"), Body(H1("Hello World"), P("This is a test")));
|
|
331
417
|
app.get("/jsx", () => render(Page()));
|
|
332
418
|
|
|
419
|
+
// Cookies & IP Detection
|
|
420
|
+
app.post("/login", (req) =>
|
|
421
|
+
app.response()
|
|
422
|
+
.json({ ok: true, ip: req.ip })
|
|
423
|
+
.cookie("sessionId", "user_123", {
|
|
424
|
+
httpOnly: true,
|
|
425
|
+
secure: true,
|
|
426
|
+
sameSite: "Strict",
|
|
427
|
+
maxAge: 86400 // 24 hours
|
|
428
|
+
})
|
|
429
|
+
);
|
|
430
|
+
|
|
431
|
+
app.get("/profile", (req) => ({
|
|
432
|
+
sessionId: req.cookies?.sessionId,
|
|
433
|
+
clientIp: req.ip,
|
|
434
|
+
}));
|
|
435
|
+
|
|
333
436
|
// Database
|
|
334
437
|
const users = db.sqlite("./db.sqlite", "CREATE TABLE users...");
|
|
335
438
|
app.get("/users", () => users.query("SELECT * FROM users"));
|
package/dist/middleware.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
// node_modules/jose/dist/webapi/lib/buffer_utils.js
|
|
2
|
+
// node_modules/.pnpm/jose@6.2.1/node_modules/jose/dist/webapi/lib/buffer_utils.js
|
|
3
3
|
var encoder = new TextEncoder;
|
|
4
4
|
var decoder = new TextDecoder;
|
|
5
5
|
var MAX_INT32 = 2 ** 32;
|
|
@@ -25,7 +25,7 @@ function encode(string) {
|
|
|
25
25
|
return bytes;
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
// node_modules/jose/dist/webapi/lib/base64.js
|
|
28
|
+
// node_modules/.pnpm/jose@6.2.1/node_modules/jose/dist/webapi/lib/base64.js
|
|
29
29
|
function encodeBase64(input) {
|
|
30
30
|
if (Uint8Array.prototype.toBase64) {
|
|
31
31
|
return input.toBase64();
|
|
@@ -49,7 +49,7 @@ function decodeBase64(encoded) {
|
|
|
49
49
|
return bytes;
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
// node_modules/jose/dist/webapi/util/base64url.js
|
|
52
|
+
// node_modules/.pnpm/jose@6.2.1/node_modules/jose/dist/webapi/util/base64url.js
|
|
53
53
|
function decode(input) {
|
|
54
54
|
if (Uint8Array.fromBase64) {
|
|
55
55
|
return Uint8Array.fromBase64(typeof input === "string" ? input : decoder.decode(input), {
|
|
@@ -78,77 +78,17 @@ function encode2(input) {
|
|
|
78
78
|
return encodeBase64(unencoded).replace(/=/g, "").replace(/\+/g, "-").replace(/\//g, "_");
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
-
// node_modules/jose/dist/webapi/
|
|
82
|
-
class JOSEError extends Error {
|
|
83
|
-
static code = "ERR_JOSE_GENERIC";
|
|
84
|
-
code = "ERR_JOSE_GENERIC";
|
|
85
|
-
constructor(message, options) {
|
|
86
|
-
super(message, options);
|
|
87
|
-
this.name = this.constructor.name;
|
|
88
|
-
Error.captureStackTrace?.(this, this.constructor);
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
class JWTClaimValidationFailed extends JOSEError {
|
|
93
|
-
static code = "ERR_JWT_CLAIM_VALIDATION_FAILED";
|
|
94
|
-
code = "ERR_JWT_CLAIM_VALIDATION_FAILED";
|
|
95
|
-
claim;
|
|
96
|
-
reason;
|
|
97
|
-
payload;
|
|
98
|
-
constructor(message, payload, claim = "unspecified", reason = "unspecified") {
|
|
99
|
-
super(message, { cause: { claim, reason, payload } });
|
|
100
|
-
this.claim = claim;
|
|
101
|
-
this.reason = reason;
|
|
102
|
-
this.payload = payload;
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
class JWTExpired extends JOSEError {
|
|
107
|
-
static code = "ERR_JWT_EXPIRED";
|
|
108
|
-
code = "ERR_JWT_EXPIRED";
|
|
109
|
-
claim;
|
|
110
|
-
reason;
|
|
111
|
-
payload;
|
|
112
|
-
constructor(message, payload, claim = "unspecified", reason = "unspecified") {
|
|
113
|
-
super(message, { cause: { claim, reason, payload } });
|
|
114
|
-
this.claim = claim;
|
|
115
|
-
this.reason = reason;
|
|
116
|
-
this.payload = payload;
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
class JOSEAlgNotAllowed extends JOSEError {
|
|
121
|
-
static code = "ERR_JOSE_ALG_NOT_ALLOWED";
|
|
122
|
-
code = "ERR_JOSE_ALG_NOT_ALLOWED";
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
class JOSENotSupported extends JOSEError {
|
|
126
|
-
static code = "ERR_JOSE_NOT_SUPPORTED";
|
|
127
|
-
code = "ERR_JOSE_NOT_SUPPORTED";
|
|
128
|
-
}
|
|
129
|
-
class JWSInvalid extends JOSEError {
|
|
130
|
-
static code = "ERR_JWS_INVALID";
|
|
131
|
-
code = "ERR_JWS_INVALID";
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
class JWTInvalid extends JOSEError {
|
|
135
|
-
static code = "ERR_JWT_INVALID";
|
|
136
|
-
code = "ERR_JWT_INVALID";
|
|
137
|
-
}
|
|
138
|
-
class JWSSignatureVerificationFailed extends JOSEError {
|
|
139
|
-
static code = "ERR_JWS_SIGNATURE_VERIFICATION_FAILED";
|
|
140
|
-
code = "ERR_JWS_SIGNATURE_VERIFICATION_FAILED";
|
|
141
|
-
constructor(message = "signature verification failed", options) {
|
|
142
|
-
super(message, options);
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
// node_modules/jose/dist/webapi/lib/crypto_key.js
|
|
81
|
+
// node_modules/.pnpm/jose@6.2.1/node_modules/jose/dist/webapi/lib/crypto_key.js
|
|
147
82
|
var unusable = (name, prop = "algorithm.name") => new TypeError(`CryptoKey does not support this operation, its ${prop} must be ${name}`);
|
|
148
83
|
var isAlgorithm = (algorithm, name) => algorithm.name === name;
|
|
149
84
|
function getHashLength(hash) {
|
|
150
85
|
return parseInt(hash.name.slice(4), 10);
|
|
151
86
|
}
|
|
87
|
+
function checkHashLength(algorithm, expected) {
|
|
88
|
+
const actual = getHashLength(algorithm.hash);
|
|
89
|
+
if (actual !== expected)
|
|
90
|
+
throw unusable(`SHA-${expected}`, "algorithm.hash");
|
|
91
|
+
}
|
|
152
92
|
function getNamedCurve(alg) {
|
|
153
93
|
switch (alg) {
|
|
154
94
|
case "ES256":
|
|
@@ -173,10 +113,7 @@ function checkSigCryptoKey(key, alg, usage) {
|
|
|
173
113
|
case "HS512": {
|
|
174
114
|
if (!isAlgorithm(key.algorithm, "HMAC"))
|
|
175
115
|
throw unusable("HMAC");
|
|
176
|
-
|
|
177
|
-
const actual = getHashLength(key.algorithm.hash);
|
|
178
|
-
if (actual !== expected)
|
|
179
|
-
throw unusable(`SHA-${expected}`, "algorithm.hash");
|
|
116
|
+
checkHashLength(key.algorithm, parseInt(alg.slice(2), 10));
|
|
180
117
|
break;
|
|
181
118
|
}
|
|
182
119
|
case "RS256":
|
|
@@ -184,10 +121,7 @@ function checkSigCryptoKey(key, alg, usage) {
|
|
|
184
121
|
case "RS512": {
|
|
185
122
|
if (!isAlgorithm(key.algorithm, "RSASSA-PKCS1-v1_5"))
|
|
186
123
|
throw unusable("RSASSA-PKCS1-v1_5");
|
|
187
|
-
|
|
188
|
-
const actual = getHashLength(key.algorithm.hash);
|
|
189
|
-
if (actual !== expected)
|
|
190
|
-
throw unusable(`SHA-${expected}`, "algorithm.hash");
|
|
124
|
+
checkHashLength(key.algorithm, parseInt(alg.slice(2), 10));
|
|
191
125
|
break;
|
|
192
126
|
}
|
|
193
127
|
case "PS256":
|
|
@@ -195,10 +129,7 @@ function checkSigCryptoKey(key, alg, usage) {
|
|
|
195
129
|
case "PS512": {
|
|
196
130
|
if (!isAlgorithm(key.algorithm, "RSA-PSS"))
|
|
197
131
|
throw unusable("RSA-PSS");
|
|
198
|
-
|
|
199
|
-
const actual = getHashLength(key.algorithm.hash);
|
|
200
|
-
if (actual !== expected)
|
|
201
|
-
throw unusable(`SHA-${expected}`, "algorithm.hash");
|
|
132
|
+
checkHashLength(key.algorithm, parseInt(alg.slice(2), 10));
|
|
202
133
|
break;
|
|
203
134
|
}
|
|
204
135
|
case "Ed25519":
|
|
@@ -231,7 +162,7 @@ function checkSigCryptoKey(key, alg, usage) {
|
|
|
231
162
|
checkUsage(key, usage);
|
|
232
163
|
}
|
|
233
164
|
|
|
234
|
-
// node_modules/jose/dist/webapi/lib/invalid_key_input.js
|
|
165
|
+
// node_modules/.pnpm/jose@6.2.1/node_modules/jose/dist/webapi/lib/invalid_key_input.js
|
|
235
166
|
function message(msg, actual, ...types) {
|
|
236
167
|
types = types.filter(Boolean);
|
|
237
168
|
if (types.length > 2) {
|
|
@@ -256,7 +187,72 @@ function message(msg, actual, ...types) {
|
|
|
256
187
|
var invalidKeyInput = (actual, ...types) => message("Key must be ", actual, ...types);
|
|
257
188
|
var withAlg = (alg, actual, ...types) => message(`Key for the ${alg} algorithm must be `, actual, ...types);
|
|
258
189
|
|
|
259
|
-
// node_modules/jose/dist/webapi/
|
|
190
|
+
// node_modules/.pnpm/jose@6.2.1/node_modules/jose/dist/webapi/util/errors.js
|
|
191
|
+
class JOSEError extends Error {
|
|
192
|
+
static code = "ERR_JOSE_GENERIC";
|
|
193
|
+
code = "ERR_JOSE_GENERIC";
|
|
194
|
+
constructor(message2, options) {
|
|
195
|
+
super(message2, options);
|
|
196
|
+
this.name = this.constructor.name;
|
|
197
|
+
Error.captureStackTrace?.(this, this.constructor);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
class JWTClaimValidationFailed extends JOSEError {
|
|
202
|
+
static code = "ERR_JWT_CLAIM_VALIDATION_FAILED";
|
|
203
|
+
code = "ERR_JWT_CLAIM_VALIDATION_FAILED";
|
|
204
|
+
claim;
|
|
205
|
+
reason;
|
|
206
|
+
payload;
|
|
207
|
+
constructor(message2, payload, claim = "unspecified", reason = "unspecified") {
|
|
208
|
+
super(message2, { cause: { claim, reason, payload } });
|
|
209
|
+
this.claim = claim;
|
|
210
|
+
this.reason = reason;
|
|
211
|
+
this.payload = payload;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
class JWTExpired extends JOSEError {
|
|
216
|
+
static code = "ERR_JWT_EXPIRED";
|
|
217
|
+
code = "ERR_JWT_EXPIRED";
|
|
218
|
+
claim;
|
|
219
|
+
reason;
|
|
220
|
+
payload;
|
|
221
|
+
constructor(message2, payload, claim = "unspecified", reason = "unspecified") {
|
|
222
|
+
super(message2, { cause: { claim, reason, payload } });
|
|
223
|
+
this.claim = claim;
|
|
224
|
+
this.reason = reason;
|
|
225
|
+
this.payload = payload;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
class JOSEAlgNotAllowed extends JOSEError {
|
|
230
|
+
static code = "ERR_JOSE_ALG_NOT_ALLOWED";
|
|
231
|
+
code = "ERR_JOSE_ALG_NOT_ALLOWED";
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
class JOSENotSupported extends JOSEError {
|
|
235
|
+
static code = "ERR_JOSE_NOT_SUPPORTED";
|
|
236
|
+
code = "ERR_JOSE_NOT_SUPPORTED";
|
|
237
|
+
}
|
|
238
|
+
class JWSInvalid extends JOSEError {
|
|
239
|
+
static code = "ERR_JWS_INVALID";
|
|
240
|
+
code = "ERR_JWS_INVALID";
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
class JWTInvalid extends JOSEError {
|
|
244
|
+
static code = "ERR_JWT_INVALID";
|
|
245
|
+
code = "ERR_JWT_INVALID";
|
|
246
|
+
}
|
|
247
|
+
class JWSSignatureVerificationFailed extends JOSEError {
|
|
248
|
+
static code = "ERR_JWS_SIGNATURE_VERIFICATION_FAILED";
|
|
249
|
+
code = "ERR_JWS_SIGNATURE_VERIFICATION_FAILED";
|
|
250
|
+
constructor(message2 = "signature verification failed", options) {
|
|
251
|
+
super(message2, options);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// node_modules/.pnpm/jose@6.2.1/node_modules/jose/dist/webapi/lib/is_key_like.js
|
|
260
256
|
var isCryptoKey = (key) => {
|
|
261
257
|
if (key?.[Symbol.toStringTag] === "CryptoKey")
|
|
262
258
|
return true;
|
|
@@ -269,7 +265,36 @@ var isCryptoKey = (key) => {
|
|
|
269
265
|
var isKeyObject = (key) => key?.[Symbol.toStringTag] === "KeyObject";
|
|
270
266
|
var isKeyLike = (key) => isCryptoKey(key) || isKeyObject(key);
|
|
271
267
|
|
|
272
|
-
// node_modules/jose/dist/webapi/lib/
|
|
268
|
+
// node_modules/.pnpm/jose@6.2.1/node_modules/jose/dist/webapi/lib/helpers.js
|
|
269
|
+
var unprotected = Symbol();
|
|
270
|
+
function assertNotSet(value, name) {
|
|
271
|
+
if (value) {
|
|
272
|
+
throw new TypeError(`${name} can only be called once`);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
function decodeBase64url(value, label, ErrorClass) {
|
|
276
|
+
try {
|
|
277
|
+
return decode(value);
|
|
278
|
+
} catch {
|
|
279
|
+
throw new ErrorClass(`Failed to base64url decode the ${label}`);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
// node_modules/.pnpm/jose@6.2.1/node_modules/jose/dist/webapi/lib/type_checks.js
|
|
284
|
+
var isObjectLike = (value) => typeof value === "object" && value !== null;
|
|
285
|
+
function isObject(input) {
|
|
286
|
+
if (!isObjectLike(input) || Object.prototype.toString.call(input) !== "[object Object]") {
|
|
287
|
+
return false;
|
|
288
|
+
}
|
|
289
|
+
if (Object.getPrototypeOf(input) === null) {
|
|
290
|
+
return true;
|
|
291
|
+
}
|
|
292
|
+
let proto = input;
|
|
293
|
+
while (Object.getPrototypeOf(proto) !== null) {
|
|
294
|
+
proto = Object.getPrototypeOf(proto);
|
|
295
|
+
}
|
|
296
|
+
return Object.getPrototypeOf(input) === proto;
|
|
297
|
+
}
|
|
273
298
|
function isDisjoint(...headers) {
|
|
274
299
|
const sources = headers.filter(Boolean);
|
|
275
300
|
if (sources.length === 0 || sources.length === 1) {
|
|
@@ -291,24 +316,12 @@ function isDisjoint(...headers) {
|
|
|
291
316
|
}
|
|
292
317
|
return true;
|
|
293
318
|
}
|
|
319
|
+
var isJWK = (key) => isObject(key) && typeof key.kty === "string";
|
|
320
|
+
var isPrivateJWK = (key) => key.kty !== "oct" && (key.kty === "AKP" && typeof key.priv === "string" || typeof key.d === "string");
|
|
321
|
+
var isPublicJWK = (key) => key.kty !== "oct" && key.d === undefined && key.priv === undefined;
|
|
322
|
+
var isSecretJWK = (key) => key.kty === "oct" && typeof key.k === "string";
|
|
294
323
|
|
|
295
|
-
// node_modules/jose/dist/webapi/lib/
|
|
296
|
-
var isObjectLike = (value) => typeof value === "object" && value !== null;
|
|
297
|
-
function isObject(input) {
|
|
298
|
-
if (!isObjectLike(input) || Object.prototype.toString.call(input) !== "[object Object]") {
|
|
299
|
-
return false;
|
|
300
|
-
}
|
|
301
|
-
if (Object.getPrototypeOf(input) === null) {
|
|
302
|
-
return true;
|
|
303
|
-
}
|
|
304
|
-
let proto = input;
|
|
305
|
-
while (Object.getPrototypeOf(proto) !== null) {
|
|
306
|
-
proto = Object.getPrototypeOf(proto);
|
|
307
|
-
}
|
|
308
|
-
return Object.getPrototypeOf(input) === proto;
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
// node_modules/jose/dist/webapi/lib/check_key_length.js
|
|
324
|
+
// node_modules/.pnpm/jose@6.2.1/node_modules/jose/dist/webapi/lib/signing.js
|
|
312
325
|
function checkKeyLength(alg, key) {
|
|
313
326
|
if (alg.startsWith("RS") || alg.startsWith("PS")) {
|
|
314
327
|
const { modulusLength } = key.algorithm;
|
|
@@ -317,8 +330,65 @@ function checkKeyLength(alg, key) {
|
|
|
317
330
|
}
|
|
318
331
|
}
|
|
319
332
|
}
|
|
333
|
+
function subtleAlgorithm(alg, algorithm) {
|
|
334
|
+
const hash = `SHA-${alg.slice(-3)}`;
|
|
335
|
+
switch (alg) {
|
|
336
|
+
case "HS256":
|
|
337
|
+
case "HS384":
|
|
338
|
+
case "HS512":
|
|
339
|
+
return { hash, name: "HMAC" };
|
|
340
|
+
case "PS256":
|
|
341
|
+
case "PS384":
|
|
342
|
+
case "PS512":
|
|
343
|
+
return { hash, name: "RSA-PSS", saltLength: parseInt(alg.slice(-3), 10) >> 3 };
|
|
344
|
+
case "RS256":
|
|
345
|
+
case "RS384":
|
|
346
|
+
case "RS512":
|
|
347
|
+
return { hash, name: "RSASSA-PKCS1-v1_5" };
|
|
348
|
+
case "ES256":
|
|
349
|
+
case "ES384":
|
|
350
|
+
case "ES512":
|
|
351
|
+
return { hash, name: "ECDSA", namedCurve: algorithm.namedCurve };
|
|
352
|
+
case "Ed25519":
|
|
353
|
+
case "EdDSA":
|
|
354
|
+
return { name: "Ed25519" };
|
|
355
|
+
case "ML-DSA-44":
|
|
356
|
+
case "ML-DSA-65":
|
|
357
|
+
case "ML-DSA-87":
|
|
358
|
+
return { name: alg };
|
|
359
|
+
default:
|
|
360
|
+
throw new JOSENotSupported(`alg ${alg} is not supported either by JOSE or your javascript runtime`);
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
async function getSigKey(alg, key, usage) {
|
|
364
|
+
if (key instanceof Uint8Array) {
|
|
365
|
+
if (!alg.startsWith("HS")) {
|
|
366
|
+
throw new TypeError(invalidKeyInput(key, "CryptoKey", "KeyObject", "JSON Web Key"));
|
|
367
|
+
}
|
|
368
|
+
return crypto.subtle.importKey("raw", key, { hash: `SHA-${alg.slice(-3)}`, name: "HMAC" }, false, [usage]);
|
|
369
|
+
}
|
|
370
|
+
checkSigCryptoKey(key, alg, usage);
|
|
371
|
+
return key;
|
|
372
|
+
}
|
|
373
|
+
async function sign(alg, key, data) {
|
|
374
|
+
const cryptoKey = await getSigKey(alg, key, "sign");
|
|
375
|
+
checkKeyLength(alg, cryptoKey);
|
|
376
|
+
const signature = await crypto.subtle.sign(subtleAlgorithm(alg, cryptoKey.algorithm), cryptoKey, data);
|
|
377
|
+
return new Uint8Array(signature);
|
|
378
|
+
}
|
|
379
|
+
async function verify(alg, key, signature, data) {
|
|
380
|
+
const cryptoKey = await getSigKey(alg, key, "verify");
|
|
381
|
+
checkKeyLength(alg, cryptoKey);
|
|
382
|
+
const algorithm = subtleAlgorithm(alg, cryptoKey.algorithm);
|
|
383
|
+
try {
|
|
384
|
+
return await crypto.subtle.verify(algorithm, cryptoKey, signature, data);
|
|
385
|
+
} catch {
|
|
386
|
+
return false;
|
|
387
|
+
}
|
|
388
|
+
}
|
|
320
389
|
|
|
321
|
-
// node_modules/jose/dist/webapi/lib/jwk_to_key.js
|
|
390
|
+
// node_modules/.pnpm/jose@6.2.1/node_modules/jose/dist/webapi/lib/jwk_to_key.js
|
|
391
|
+
var unsupportedAlg = 'Invalid or unsupported JWK "alg" (Algorithm) Parameter value';
|
|
322
392
|
function subtleMapping(jwk) {
|
|
323
393
|
let algorithm;
|
|
324
394
|
let keyUsages;
|
|
@@ -332,7 +402,7 @@ function subtleMapping(jwk) {
|
|
|
332
402
|
keyUsages = jwk.priv ? ["sign"] : ["verify"];
|
|
333
403
|
break;
|
|
334
404
|
default:
|
|
335
|
-
throw new JOSENotSupported(
|
|
405
|
+
throw new JOSENotSupported(unsupportedAlg);
|
|
336
406
|
}
|
|
337
407
|
break;
|
|
338
408
|
}
|
|
@@ -361,22 +431,19 @@ function subtleMapping(jwk) {
|
|
|
361
431
|
keyUsages = jwk.d ? ["decrypt", "unwrapKey"] : ["encrypt", "wrapKey"];
|
|
362
432
|
break;
|
|
363
433
|
default:
|
|
364
|
-
throw new JOSENotSupported(
|
|
434
|
+
throw new JOSENotSupported(unsupportedAlg);
|
|
365
435
|
}
|
|
366
436
|
break;
|
|
367
437
|
}
|
|
368
438
|
case "EC": {
|
|
369
439
|
switch (jwk.alg) {
|
|
370
440
|
case "ES256":
|
|
371
|
-
algorithm = { name: "ECDSA", namedCurve: "P-256" };
|
|
372
|
-
keyUsages = jwk.d ? ["sign"] : ["verify"];
|
|
373
|
-
break;
|
|
374
441
|
case "ES384":
|
|
375
|
-
algorithm = { name: "ECDSA", namedCurve: "P-384" };
|
|
376
|
-
keyUsages = jwk.d ? ["sign"] : ["verify"];
|
|
377
|
-
break;
|
|
378
442
|
case "ES512":
|
|
379
|
-
algorithm = {
|
|
443
|
+
algorithm = {
|
|
444
|
+
name: "ECDSA",
|
|
445
|
+
namedCurve: { ES256: "P-256", ES384: "P-384", ES512: "P-521" }[jwk.alg]
|
|
446
|
+
};
|
|
380
447
|
keyUsages = jwk.d ? ["sign"] : ["verify"];
|
|
381
448
|
break;
|
|
382
449
|
case "ECDH-ES":
|
|
@@ -387,7 +454,7 @@ function subtleMapping(jwk) {
|
|
|
387
454
|
keyUsages = jwk.d ? ["deriveBits"] : [];
|
|
388
455
|
break;
|
|
389
456
|
default:
|
|
390
|
-
throw new JOSENotSupported(
|
|
457
|
+
throw new JOSENotSupported(unsupportedAlg);
|
|
391
458
|
}
|
|
392
459
|
break;
|
|
393
460
|
}
|
|
@@ -406,7 +473,7 @@ function subtleMapping(jwk) {
|
|
|
406
473
|
keyUsages = jwk.d ? ["deriveBits"] : [];
|
|
407
474
|
break;
|
|
408
475
|
default:
|
|
409
|
-
throw new JOSENotSupported(
|
|
476
|
+
throw new JOSENotSupported(unsupportedAlg);
|
|
410
477
|
}
|
|
411
478
|
break;
|
|
412
479
|
}
|
|
@@ -428,55 +495,8 @@ async function jwkToKey(jwk) {
|
|
|
428
495
|
return crypto.subtle.importKey("jwk", keyData, algorithm, jwk.ext ?? (jwk.d || jwk.priv ? false : true), jwk.key_ops ?? keyUsages);
|
|
429
496
|
}
|
|
430
497
|
|
|
431
|
-
// node_modules/jose/dist/webapi/lib/
|
|
432
|
-
|
|
433
|
-
if (joseHeader.crit !== undefined && protectedHeader?.crit === undefined) {
|
|
434
|
-
throw new Err('"crit" (Critical) Header Parameter MUST be integrity protected');
|
|
435
|
-
}
|
|
436
|
-
if (!protectedHeader || protectedHeader.crit === undefined) {
|
|
437
|
-
return new Set;
|
|
438
|
-
}
|
|
439
|
-
if (!Array.isArray(protectedHeader.crit) || protectedHeader.crit.length === 0 || protectedHeader.crit.some((input) => typeof input !== "string" || input.length === 0)) {
|
|
440
|
-
throw new Err('"crit" (Critical) Header Parameter MUST be an array of non-empty strings when present');
|
|
441
|
-
}
|
|
442
|
-
let recognized;
|
|
443
|
-
if (recognizedOption !== undefined) {
|
|
444
|
-
recognized = new Map([...Object.entries(recognizedOption), ...recognizedDefault.entries()]);
|
|
445
|
-
} else {
|
|
446
|
-
recognized = recognizedDefault;
|
|
447
|
-
}
|
|
448
|
-
for (const parameter of protectedHeader.crit) {
|
|
449
|
-
if (!recognized.has(parameter)) {
|
|
450
|
-
throw new JOSENotSupported(`Extension Header Parameter "${parameter}" is not recognized`);
|
|
451
|
-
}
|
|
452
|
-
if (joseHeader[parameter] === undefined) {
|
|
453
|
-
throw new Err(`Extension Header Parameter "${parameter}" is missing`);
|
|
454
|
-
}
|
|
455
|
-
if (recognized.get(parameter) && protectedHeader[parameter] === undefined) {
|
|
456
|
-
throw new Err(`Extension Header Parameter "${parameter}" MUST be integrity protected`);
|
|
457
|
-
}
|
|
458
|
-
}
|
|
459
|
-
return new Set(protectedHeader.crit);
|
|
460
|
-
}
|
|
461
|
-
|
|
462
|
-
// node_modules/jose/dist/webapi/lib/validate_algorithms.js
|
|
463
|
-
function validateAlgorithms(option, algorithms) {
|
|
464
|
-
if (algorithms !== undefined && (!Array.isArray(algorithms) || algorithms.some((s) => typeof s !== "string"))) {
|
|
465
|
-
throw new TypeError(`"${option}" option must be an array of strings`);
|
|
466
|
-
}
|
|
467
|
-
if (!algorithms) {
|
|
468
|
-
return;
|
|
469
|
-
}
|
|
470
|
-
return new Set(algorithms);
|
|
471
|
-
}
|
|
472
|
-
|
|
473
|
-
// node_modules/jose/dist/webapi/lib/is_jwk.js
|
|
474
|
-
var isJWK = (key) => isObject(key) && typeof key.kty === "string";
|
|
475
|
-
var isPrivateJWK = (key) => key.kty !== "oct" && (key.kty === "AKP" && typeof key.priv === "string" || typeof key.d === "string");
|
|
476
|
-
var isPublicJWK = (key) => key.kty !== "oct" && key.d === undefined && key.priv === undefined;
|
|
477
|
-
var isSecretJWK = (key) => key.kty === "oct" && typeof key.k === "string";
|
|
478
|
-
|
|
479
|
-
// node_modules/jose/dist/webapi/lib/normalize_key.js
|
|
498
|
+
// node_modules/.pnpm/jose@6.2.1/node_modules/jose/dist/webapi/lib/normalize_key.js
|
|
499
|
+
var unusableForAlg = "given KeyObject instance cannot be used for this algorithm";
|
|
480
500
|
var cache;
|
|
481
501
|
var handleJWK = async (key, jwk, alg, freeze = false) => {
|
|
482
502
|
cache ||= new WeakMap;
|
|
@@ -511,13 +531,13 @@ var handleKeyObject = (keyObject, alg) => {
|
|
|
511
531
|
case "ECDH-ES+A256KW":
|
|
512
532
|
break;
|
|
513
533
|
default:
|
|
514
|
-
throw new TypeError(
|
|
534
|
+
throw new TypeError(unusableForAlg);
|
|
515
535
|
}
|
|
516
536
|
cryptoKey = keyObject.toCryptoKey(keyObject.asymmetricKeyType, extractable, isPublic ? [] : ["deriveBits"]);
|
|
517
537
|
}
|
|
518
538
|
if (keyObject.asymmetricKeyType === "ed25519") {
|
|
519
539
|
if (alg !== "EdDSA" && alg !== "Ed25519") {
|
|
520
|
-
throw new TypeError(
|
|
540
|
+
throw new TypeError(unusableForAlg);
|
|
521
541
|
}
|
|
522
542
|
cryptoKey = keyObject.toCryptoKey(keyObject.asymmetricKeyType, extractable, [
|
|
523
543
|
isPublic ? "verify" : "sign"
|
|
@@ -528,7 +548,7 @@ var handleKeyObject = (keyObject, alg) => {
|
|
|
528
548
|
case "ml-dsa-65":
|
|
529
549
|
case "ml-dsa-87": {
|
|
530
550
|
if (alg !== keyObject.asymmetricKeyType.toUpperCase()) {
|
|
531
|
-
throw new TypeError(
|
|
551
|
+
throw new TypeError(unusableForAlg);
|
|
532
552
|
}
|
|
533
553
|
cryptoKey = keyObject.toCryptoKey(keyObject.asymmetricKeyType, extractable, [
|
|
534
554
|
isPublic ? "verify" : "sign"
|
|
@@ -557,7 +577,7 @@ var handleKeyObject = (keyObject, alg) => {
|
|
|
557
577
|
hash = "SHA-512";
|
|
558
578
|
break;
|
|
559
579
|
default:
|
|
560
|
-
throw new TypeError(
|
|
580
|
+
throw new TypeError(unusableForAlg);
|
|
561
581
|
}
|
|
562
582
|
if (alg.startsWith("RSA-OAEP")) {
|
|
563
583
|
return keyObject.toCryptoKey({
|
|
@@ -578,21 +598,10 @@ var handleKeyObject = (keyObject, alg) => {
|
|
|
578
598
|
]);
|
|
579
599
|
const namedCurve = nist.get(keyObject.asymmetricKeyDetails?.namedCurve);
|
|
580
600
|
if (!namedCurve) {
|
|
581
|
-
throw new TypeError(
|
|
582
|
-
}
|
|
583
|
-
if (alg === "ES256" && namedCurve === "P-256") {
|
|
584
|
-
cryptoKey = keyObject.toCryptoKey({
|
|
585
|
-
name: "ECDSA",
|
|
586
|
-
namedCurve
|
|
587
|
-
}, extractable, [isPublic ? "verify" : "sign"]);
|
|
588
|
-
}
|
|
589
|
-
if (alg === "ES384" && namedCurve === "P-384") {
|
|
590
|
-
cryptoKey = keyObject.toCryptoKey({
|
|
591
|
-
name: "ECDSA",
|
|
592
|
-
namedCurve
|
|
593
|
-
}, extractable, [isPublic ? "verify" : "sign"]);
|
|
601
|
+
throw new TypeError(unusableForAlg);
|
|
594
602
|
}
|
|
595
|
-
|
|
603
|
+
const expectedCurve = { ES256: "P-256", ES384: "P-384", ES512: "P-521" };
|
|
604
|
+
if (expectedCurve[alg] && namedCurve === expectedCurve[alg]) {
|
|
596
605
|
cryptoKey = keyObject.toCryptoKey({
|
|
597
606
|
name: "ECDSA",
|
|
598
607
|
namedCurve
|
|
@@ -606,7 +615,7 @@ var handleKeyObject = (keyObject, alg) => {
|
|
|
606
615
|
}
|
|
607
616
|
}
|
|
608
617
|
if (!cryptoKey) {
|
|
609
|
-
throw new TypeError(
|
|
618
|
+
throw new TypeError(unusableForAlg);
|
|
610
619
|
}
|
|
611
620
|
if (!cached) {
|
|
612
621
|
cache.set(keyObject, { [alg]: cryptoKey });
|
|
@@ -647,7 +656,49 @@ async function normalizeKey(key, alg) {
|
|
|
647
656
|
throw new Error("unreachable");
|
|
648
657
|
}
|
|
649
658
|
|
|
650
|
-
// node_modules/jose/dist/webapi/lib/
|
|
659
|
+
// node_modules/.pnpm/jose@6.2.1/node_modules/jose/dist/webapi/lib/validate_crit.js
|
|
660
|
+
function validateCrit(Err, recognizedDefault, recognizedOption, protectedHeader, joseHeader) {
|
|
661
|
+
if (joseHeader.crit !== undefined && protectedHeader?.crit === undefined) {
|
|
662
|
+
throw new Err('"crit" (Critical) Header Parameter MUST be integrity protected');
|
|
663
|
+
}
|
|
664
|
+
if (!protectedHeader || protectedHeader.crit === undefined) {
|
|
665
|
+
return new Set;
|
|
666
|
+
}
|
|
667
|
+
if (!Array.isArray(protectedHeader.crit) || protectedHeader.crit.length === 0 || protectedHeader.crit.some((input) => typeof input !== "string" || input.length === 0)) {
|
|
668
|
+
throw new Err('"crit" (Critical) Header Parameter MUST be an array of non-empty strings when present');
|
|
669
|
+
}
|
|
670
|
+
let recognized;
|
|
671
|
+
if (recognizedOption !== undefined) {
|
|
672
|
+
recognized = new Map([...Object.entries(recognizedOption), ...recognizedDefault.entries()]);
|
|
673
|
+
} else {
|
|
674
|
+
recognized = recognizedDefault;
|
|
675
|
+
}
|
|
676
|
+
for (const parameter of protectedHeader.crit) {
|
|
677
|
+
if (!recognized.has(parameter)) {
|
|
678
|
+
throw new JOSENotSupported(`Extension Header Parameter "${parameter}" is not recognized`);
|
|
679
|
+
}
|
|
680
|
+
if (joseHeader[parameter] === undefined) {
|
|
681
|
+
throw new Err(`Extension Header Parameter "${parameter}" is missing`);
|
|
682
|
+
}
|
|
683
|
+
if (recognized.get(parameter) && protectedHeader[parameter] === undefined) {
|
|
684
|
+
throw new Err(`Extension Header Parameter "${parameter}" MUST be integrity protected`);
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
return new Set(protectedHeader.crit);
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
// node_modules/.pnpm/jose@6.2.1/node_modules/jose/dist/webapi/lib/validate_algorithms.js
|
|
691
|
+
function validateAlgorithms(option, algorithms) {
|
|
692
|
+
if (algorithms !== undefined && (!Array.isArray(algorithms) || algorithms.some((s) => typeof s !== "string"))) {
|
|
693
|
+
throw new TypeError(`"${option}" option must be an array of strings`);
|
|
694
|
+
}
|
|
695
|
+
if (!algorithms) {
|
|
696
|
+
return;
|
|
697
|
+
}
|
|
698
|
+
return new Set(algorithms);
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
// node_modules/.pnpm/jose@6.2.1/node_modules/jose/dist/webapi/lib/check_key_type.js
|
|
651
702
|
var tag = (key) => key?.[Symbol.toStringTag];
|
|
652
703
|
var jwkMatchesOp = (alg, key, usage) => {
|
|
653
704
|
if (key.use !== undefined) {
|
|
@@ -722,12 +773,12 @@ var asymmetricTypeCheck = (alg, key, usage) => {
|
|
|
722
773
|
case "sign":
|
|
723
774
|
if (isPrivateJWK(key) && jwkMatchesOp(alg, key, usage))
|
|
724
775
|
return;
|
|
725
|
-
throw new TypeError(`JSON Web Key for this operation be a private JWK`);
|
|
776
|
+
throw new TypeError(`JSON Web Key for this operation must be a private JWK`);
|
|
726
777
|
case "encrypt":
|
|
727
778
|
case "verify":
|
|
728
779
|
if (isPublicJWK(key) && jwkMatchesOp(alg, key, usage))
|
|
729
780
|
return;
|
|
730
|
-
throw new TypeError(`JSON Web Key for this operation be a public JWK`);
|
|
781
|
+
throw new TypeError(`JSON Web Key for this operation must be a public JWK`);
|
|
731
782
|
}
|
|
732
783
|
}
|
|
733
784
|
if (!isKeyLike(key)) {
|
|
@@ -767,63 +818,7 @@ function checkKeyType(alg, key, usage) {
|
|
|
767
818
|
}
|
|
768
819
|
}
|
|
769
820
|
|
|
770
|
-
// node_modules/jose/dist/webapi/
|
|
771
|
-
function subtleAlgorithm(alg, algorithm) {
|
|
772
|
-
const hash = `SHA-${alg.slice(-3)}`;
|
|
773
|
-
switch (alg) {
|
|
774
|
-
case "HS256":
|
|
775
|
-
case "HS384":
|
|
776
|
-
case "HS512":
|
|
777
|
-
return { hash, name: "HMAC" };
|
|
778
|
-
case "PS256":
|
|
779
|
-
case "PS384":
|
|
780
|
-
case "PS512":
|
|
781
|
-
return { hash, name: "RSA-PSS", saltLength: parseInt(alg.slice(-3), 10) >> 3 };
|
|
782
|
-
case "RS256":
|
|
783
|
-
case "RS384":
|
|
784
|
-
case "RS512":
|
|
785
|
-
return { hash, name: "RSASSA-PKCS1-v1_5" };
|
|
786
|
-
case "ES256":
|
|
787
|
-
case "ES384":
|
|
788
|
-
case "ES512":
|
|
789
|
-
return { hash, name: "ECDSA", namedCurve: algorithm.namedCurve };
|
|
790
|
-
case "Ed25519":
|
|
791
|
-
case "EdDSA":
|
|
792
|
-
return { name: "Ed25519" };
|
|
793
|
-
case "ML-DSA-44":
|
|
794
|
-
case "ML-DSA-65":
|
|
795
|
-
case "ML-DSA-87":
|
|
796
|
-
return { name: alg };
|
|
797
|
-
default:
|
|
798
|
-
throw new JOSENotSupported(`alg ${alg} is not supported either by JOSE or your javascript runtime`);
|
|
799
|
-
}
|
|
800
|
-
}
|
|
801
|
-
|
|
802
|
-
// node_modules/jose/dist/webapi/lib/get_sign_verify_key.js
|
|
803
|
-
async function getSigKey(alg, key, usage) {
|
|
804
|
-
if (key instanceof Uint8Array) {
|
|
805
|
-
if (!alg.startsWith("HS")) {
|
|
806
|
-
throw new TypeError(invalidKeyInput(key, "CryptoKey", "KeyObject", "JSON Web Key"));
|
|
807
|
-
}
|
|
808
|
-
return crypto.subtle.importKey("raw", key, { hash: `SHA-${alg.slice(-3)}`, name: "HMAC" }, false, [usage]);
|
|
809
|
-
}
|
|
810
|
-
checkSigCryptoKey(key, alg, usage);
|
|
811
|
-
return key;
|
|
812
|
-
}
|
|
813
|
-
|
|
814
|
-
// node_modules/jose/dist/webapi/lib/verify.js
|
|
815
|
-
async function verify(alg, key, signature, data) {
|
|
816
|
-
const cryptoKey = await getSigKey(alg, key, "verify");
|
|
817
|
-
checkKeyLength(alg, cryptoKey);
|
|
818
|
-
const algorithm = subtleAlgorithm(alg, cryptoKey.algorithm);
|
|
819
|
-
try {
|
|
820
|
-
return await crypto.subtle.verify(algorithm, cryptoKey, signature, data);
|
|
821
|
-
} catch {
|
|
822
|
-
return false;
|
|
823
|
-
}
|
|
824
|
-
}
|
|
825
|
-
|
|
826
|
-
// node_modules/jose/dist/webapi/jws/flattened/verify.js
|
|
821
|
+
// node_modules/.pnpm/jose@6.2.1/node_modules/jose/dist/webapi/jws/flattened/verify.js
|
|
827
822
|
async function flattenedVerify(jws, key, options) {
|
|
828
823
|
if (!isObject(jws)) {
|
|
829
824
|
throw new JWSInvalid("Flattened JWS must be an object");
|
|
@@ -889,12 +884,7 @@ async function flattenedVerify(jws, key, options) {
|
|
|
889
884
|
}
|
|
890
885
|
checkKeyType(alg, key, "verify");
|
|
891
886
|
const data = concat(jws.protected !== undefined ? encode(jws.protected) : new Uint8Array, encode("."), typeof jws.payload === "string" ? b64 ? encode(jws.payload) : encoder.encode(jws.payload) : jws.payload);
|
|
892
|
-
|
|
893
|
-
try {
|
|
894
|
-
signature = decode(jws.signature);
|
|
895
|
-
} catch {
|
|
896
|
-
throw new JWSInvalid("Failed to base64url decode the signature");
|
|
897
|
-
}
|
|
887
|
+
const signature = decodeBase64url(jws.signature, "signature", JWSInvalid);
|
|
898
888
|
const k = await normalizeKey(key, alg);
|
|
899
889
|
const verified = await verify(alg, k, signature, data);
|
|
900
890
|
if (!verified) {
|
|
@@ -902,11 +892,7 @@ async function flattenedVerify(jws, key, options) {
|
|
|
902
892
|
}
|
|
903
893
|
let payload;
|
|
904
894
|
if (b64) {
|
|
905
|
-
|
|
906
|
-
payload = decode(jws.payload);
|
|
907
|
-
} catch {
|
|
908
|
-
throw new JWSInvalid("Failed to base64url decode the payload");
|
|
909
|
-
}
|
|
895
|
+
payload = decodeBase64url(jws.payload, "payload", JWSInvalid);
|
|
910
896
|
} else if (typeof jws.payload === "string") {
|
|
911
897
|
payload = encoder.encode(jws.payload);
|
|
912
898
|
} else {
|
|
@@ -925,7 +911,7 @@ async function flattenedVerify(jws, key, options) {
|
|
|
925
911
|
return result;
|
|
926
912
|
}
|
|
927
913
|
|
|
928
|
-
// node_modules/jose/dist/webapi/jws/compact/verify.js
|
|
914
|
+
// node_modules/.pnpm/jose@6.2.1/node_modules/jose/dist/webapi/jws/compact/verify.js
|
|
929
915
|
async function compactVerify(jws, key, options) {
|
|
930
916
|
if (jws instanceof Uint8Array) {
|
|
931
917
|
jws = decoder.decode(jws);
|
|
@@ -945,7 +931,7 @@ async function compactVerify(jws, key, options) {
|
|
|
945
931
|
return result;
|
|
946
932
|
}
|
|
947
933
|
|
|
948
|
-
// node_modules/jose/dist/webapi/lib/jwt_claims_set.js
|
|
934
|
+
// node_modules/.pnpm/jose@6.2.1/node_modules/jose/dist/webapi/lib/jwt_claims_set.js
|
|
949
935
|
var epoch = (date) => Math.floor(date.getTime() / 1000);
|
|
950
936
|
var minute = 60;
|
|
951
937
|
var hour = minute * 60;
|
|
@@ -1170,7 +1156,7 @@ class JWTClaimsBuilder {
|
|
|
1170
1156
|
}
|
|
1171
1157
|
}
|
|
1172
1158
|
|
|
1173
|
-
// node_modules/jose/dist/webapi/jwt/verify.js
|
|
1159
|
+
// node_modules/.pnpm/jose@6.2.1/node_modules/jose/dist/webapi/jwt/verify.js
|
|
1174
1160
|
async function jwtVerify(jwt, key, options) {
|
|
1175
1161
|
const verified = await compactVerify(jwt, key, options);
|
|
1176
1162
|
if (verified.protectedHeader.crit?.includes("b64") && verified.protectedHeader.b64 === false) {
|
|
@@ -1183,15 +1169,7 @@ async function jwtVerify(jwt, key, options) {
|
|
|
1183
1169
|
}
|
|
1184
1170
|
return result;
|
|
1185
1171
|
}
|
|
1186
|
-
// node_modules/jose/dist/webapi/
|
|
1187
|
-
async function sign(alg, key, data) {
|
|
1188
|
-
const cryptoKey = await getSigKey(alg, key, "sign");
|
|
1189
|
-
checkKeyLength(alg, cryptoKey);
|
|
1190
|
-
const signature = await crypto.subtle.sign(subtleAlgorithm(alg, cryptoKey.algorithm), cryptoKey, data);
|
|
1191
|
-
return new Uint8Array(signature);
|
|
1192
|
-
}
|
|
1193
|
-
|
|
1194
|
-
// node_modules/jose/dist/webapi/jws/flattened/sign.js
|
|
1172
|
+
// node_modules/.pnpm/jose@6.2.1/node_modules/jose/dist/webapi/jws/flattened/sign.js
|
|
1195
1173
|
class FlattenedSign {
|
|
1196
1174
|
#payload;
|
|
1197
1175
|
#protectedHeader;
|
|
@@ -1203,16 +1181,12 @@ class FlattenedSign {
|
|
|
1203
1181
|
this.#payload = payload;
|
|
1204
1182
|
}
|
|
1205
1183
|
setProtectedHeader(protectedHeader) {
|
|
1206
|
-
|
|
1207
|
-
throw new TypeError("setProtectedHeader can only be called once");
|
|
1208
|
-
}
|
|
1184
|
+
assertNotSet(this.#protectedHeader, "setProtectedHeader");
|
|
1209
1185
|
this.#protectedHeader = protectedHeader;
|
|
1210
1186
|
return this;
|
|
1211
1187
|
}
|
|
1212
1188
|
setUnprotectedHeader(unprotectedHeader) {
|
|
1213
|
-
|
|
1214
|
-
throw new TypeError("setUnprotectedHeader can only be called once");
|
|
1215
|
-
}
|
|
1189
|
+
assertNotSet(this.#unprotectedHeader, "setUnprotectedHeader");
|
|
1216
1190
|
this.#unprotectedHeader = unprotectedHeader;
|
|
1217
1191
|
return this;
|
|
1218
1192
|
}
|
|
@@ -1275,7 +1249,7 @@ class FlattenedSign {
|
|
|
1275
1249
|
}
|
|
1276
1250
|
}
|
|
1277
1251
|
|
|
1278
|
-
// node_modules/jose/dist/webapi/jws/compact/sign.js
|
|
1252
|
+
// node_modules/.pnpm/jose@6.2.1/node_modules/jose/dist/webapi/jws/compact/sign.js
|
|
1279
1253
|
class CompactSign {
|
|
1280
1254
|
#flattened;
|
|
1281
1255
|
constructor(payload) {
|
|
@@ -1294,7 +1268,7 @@ class CompactSign {
|
|
|
1294
1268
|
}
|
|
1295
1269
|
}
|
|
1296
1270
|
|
|
1297
|
-
// node_modules/jose/dist/webapi/jwt/sign.js
|
|
1271
|
+
// node_modules/.pnpm/jose@6.2.1/node_modules/jose/dist/webapi/jwt/sign.js
|
|
1298
1272
|
class SignJWT {
|
|
1299
1273
|
#protectedHeader;
|
|
1300
1274
|
#jwt;
|
package/dist/prince.d.ts
CHANGED
|
@@ -12,6 +12,8 @@ export interface PrinceRequest extends Request {
|
|
|
12
12
|
session?: any;
|
|
13
13
|
apiKey?: string;
|
|
14
14
|
sseSend?: (data: any, event?: string, id?: string) => void;
|
|
15
|
+
cookies?: Record<string, string>;
|
|
16
|
+
ip?: string;
|
|
15
17
|
[key: string]: any;
|
|
16
18
|
}
|
|
17
19
|
export type OnRequest = (req: PrinceRequest) => void | Promise<void>;
|
|
@@ -32,10 +34,18 @@ declare class ResponseBuilder {
|
|
|
32
34
|
private _body;
|
|
33
35
|
status(code: number): this;
|
|
34
36
|
header(key: string, value: string): this;
|
|
35
|
-
json(data: any):
|
|
36
|
-
text(data: string):
|
|
37
|
-
html(data: string):
|
|
38
|
-
redirect(url: string, status?: number):
|
|
37
|
+
json(data: any): this;
|
|
38
|
+
text(data: string): this;
|
|
39
|
+
html(data: string): this;
|
|
40
|
+
redirect(url: string, status?: number): this;
|
|
41
|
+
cookie(name: string, value: string, options?: {
|
|
42
|
+
maxAge?: number;
|
|
43
|
+
path?: string;
|
|
44
|
+
domain?: string;
|
|
45
|
+
secure?: boolean;
|
|
46
|
+
httpOnly?: boolean;
|
|
47
|
+
sameSite?: "Strict" | "Lax" | "None";
|
|
48
|
+
}): this;
|
|
39
49
|
build(): Response;
|
|
40
50
|
}
|
|
41
51
|
export interface RouteSchema {
|
package/dist/prince.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prince.d.ts","sourceRoot":"","sources":["../src/prince.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"prince.d.ts","sourceRoot":"","sources":["../src/prince.ts"],"names":[],"mappings":"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"}
|
package/dist/prince.js
CHANGED
|
@@ -134,27 +134,71 @@ class ResponseBuilder {
|
|
|
134
134
|
json(data) {
|
|
135
135
|
this._headers["Content-Type"] = "application/json";
|
|
136
136
|
this._body = JSON.stringify(data);
|
|
137
|
-
return this
|
|
137
|
+
return this;
|
|
138
138
|
}
|
|
139
139
|
text(data) {
|
|
140
140
|
this._headers["Content-Type"] = "text/plain";
|
|
141
141
|
this._body = data;
|
|
142
|
-
return this
|
|
142
|
+
return this;
|
|
143
143
|
}
|
|
144
144
|
html(data) {
|
|
145
145
|
this._headers["Content-Type"] = "text/html";
|
|
146
146
|
this._body = data;
|
|
147
|
-
return this
|
|
147
|
+
return this;
|
|
148
148
|
}
|
|
149
149
|
redirect(url, status = 302) {
|
|
150
150
|
this._status = status;
|
|
151
151
|
this._headers["Location"] = url;
|
|
152
|
-
return this
|
|
152
|
+
return this;
|
|
153
|
+
}
|
|
154
|
+
cookie(name, value, options) {
|
|
155
|
+
let cookieStr = `${encodeURIComponent(name)}=${encodeURIComponent(value)}`;
|
|
156
|
+
if (options?.maxAge)
|
|
157
|
+
cookieStr += `; Max-Age=${options.maxAge}`;
|
|
158
|
+
if (options?.path)
|
|
159
|
+
cookieStr += `; Path=${options.path}`;
|
|
160
|
+
if (options?.domain)
|
|
161
|
+
cookieStr += `; Domain=${options.domain}`;
|
|
162
|
+
if (options?.secure)
|
|
163
|
+
cookieStr += "; Secure";
|
|
164
|
+
if (options?.httpOnly)
|
|
165
|
+
cookieStr += "; HttpOnly";
|
|
166
|
+
if (options?.sameSite)
|
|
167
|
+
cookieStr += `; SameSite=${options.sameSite}`;
|
|
168
|
+
const existing = this._headers["Set-Cookie"];
|
|
169
|
+
this._headers["Set-Cookie"] = existing ? `${existing}, ${cookieStr}` : cookieStr;
|
|
170
|
+
return this;
|
|
153
171
|
}
|
|
154
172
|
build() {
|
|
155
173
|
return new Response(this._body, { status: this._status, headers: this._headers });
|
|
156
174
|
}
|
|
157
175
|
}
|
|
176
|
+
function parseCookies(cookieHeader) {
|
|
177
|
+
const cookies = {};
|
|
178
|
+
if (!cookieHeader)
|
|
179
|
+
return cookies;
|
|
180
|
+
cookieHeader.split(";").forEach((pair) => {
|
|
181
|
+
const [name, ...value] = pair.split("=");
|
|
182
|
+
if (name)
|
|
183
|
+
cookies[decodeURIComponent(name.trim())] = decodeURIComponent((value.join("=") || "").trim());
|
|
184
|
+
});
|
|
185
|
+
return cookies;
|
|
186
|
+
}
|
|
187
|
+
function detectIP(req) {
|
|
188
|
+
const forwarded = req.headers.get("x-forwarded-for");
|
|
189
|
+
if (forwarded)
|
|
190
|
+
return forwarded.split(",")[0].trim();
|
|
191
|
+
const realIp = req.headers.get("x-real-ip");
|
|
192
|
+
if (realIp)
|
|
193
|
+
return realIp;
|
|
194
|
+
const cfIp = req.headers.get("cf-connecting-ip");
|
|
195
|
+
if (cfIp)
|
|
196
|
+
return cfIp;
|
|
197
|
+
const clientIp = req.headers.get("x-client-ip");
|
|
198
|
+
if (clientIp)
|
|
199
|
+
return clientIp;
|
|
200
|
+
return "127.0.0.1";
|
|
201
|
+
}
|
|
158
202
|
function zodToJsonSchema(schema) {
|
|
159
203
|
const d = schema._def;
|
|
160
204
|
const typeName = d?.typeName ?? d?.type ?? "";
|
|
@@ -595,6 +639,9 @@ class Prince {
|
|
|
595
639
|
async executeHandler(req, handler, params, query, routeMiddlewares, method, pathname) {
|
|
596
640
|
Object.defineProperty(req, "params", { value: params, writable: true, configurable: true });
|
|
597
641
|
Object.defineProperty(req, "query", { value: query, writable: true, configurable: true });
|
|
642
|
+
const cookieHeader = req.headers.get("cookie") || "";
|
|
643
|
+
Object.defineProperty(req, "cookies", { value: parseCookies(cookieHeader), writable: true, configurable: true });
|
|
644
|
+
Object.defineProperty(req, "ip", { value: detectIP(req), writable: true, configurable: true });
|
|
598
645
|
if (["POST", "PUT", "PATCH"].includes(req.method) && !req.parsedBody) {
|
|
599
646
|
const parsed = await this.parseBody(req);
|
|
600
647
|
if (parsed) {
|
|
@@ -627,6 +674,8 @@ class Prince {
|
|
|
627
674
|
const res = await handler(req);
|
|
628
675
|
if (res instanceof Response)
|
|
629
676
|
return res;
|
|
677
|
+
if (res instanceof ResponseBuilder)
|
|
678
|
+
return res.build();
|
|
630
679
|
if (typeof res === "string")
|
|
631
680
|
return new Response(res);
|
|
632
681
|
if (res instanceof Uint8Array)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "princejs",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"description": "An easy and fast backend framework that is among the top three — by a 13yo developer, for developers.",
|
|
5
5
|
"main": "dist/prince.js",
|
|
6
6
|
"types": "dist/prince.d.ts",
|
|
@@ -96,24 +96,23 @@
|
|
|
96
96
|
},
|
|
97
97
|
"devDependencies": {
|
|
98
98
|
"@types/bun": "^1.3.2",
|
|
99
|
-
"@types/jsonwebtoken": "^9.0.10",
|
|
100
99
|
"bun-types": "latest",
|
|
101
|
-
"fast-jwt": "^5.0.0",
|
|
102
|
-
"jsonwebtoken": "^9.0.2",
|
|
103
100
|
"typescript": "^5.9.3",
|
|
104
101
|
"zod": "^4.1.12"
|
|
105
102
|
},
|
|
106
103
|
"peerDependencies": {
|
|
107
|
-
"zod": "^4.1.12"
|
|
104
|
+
"zod": "^4.1.12",
|
|
105
|
+
"jose": "^6.1.2"
|
|
108
106
|
},
|
|
109
107
|
"peerDependenciesMeta": {
|
|
110
108
|
"zod": {
|
|
111
109
|
"optional": true
|
|
110
|
+
},
|
|
111
|
+
"jose": {
|
|
112
|
+
"optional": true
|
|
112
113
|
}
|
|
113
114
|
},
|
|
114
|
-
"dependencies": {
|
|
115
|
-
"jose": "^6.1.2"
|
|
116
|
-
},
|
|
115
|
+
"dependencies": {},
|
|
117
116
|
"scripts": {
|
|
118
117
|
"build:js": "bun build src/prince.ts --outdir dist --target bun --external zod --external jose && bun build src/middleware.ts --outdir dist --target bun && bun build src/helpers.ts --outdir dist --target bun && bun build src/scheduler.ts --outdir dist --target bun && bun build bin/create.ts --outdir dist --target bun && bun build src/jsx.ts --outdir dist --target bun && bun build src/db.ts --outdir dist --target bun --format esm && bun build src/client.ts --outdir dist --format esm && bun build src/adapters/vercel.ts --outdir dist/adapters --format esm && bun build src/adapters/cloudflare.ts --outdir dist/adapters --format esm && bun build src/adapters/deno.ts --outdir dist/adapters --format esm",
|
|
119
118
|
"build:types": "tsc --emitDeclarationOnly --skipLibCheck",
|