unjwt 0.5.20 → 0.5.21
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 +55 -0
- package/dist/h3.d.mts +185 -0
- package/dist/h3.mjs +460 -0
- package/dist/index.d.mts +7 -5
- package/dist/index.mjs +4 -4
- package/dist/jwe.d.mts +3 -2
- package/dist/jwe.mjs +3 -3
- package/dist/jwk.d.mts +2 -2
- package/dist/jwk.mjs +2 -2
- package/dist/jws.d.mts +3 -2
- package/dist/jws.mjs +3 -3
- package/dist/shared/unjwt.9mL1vSFP.d.mts +154 -0
- package/dist/shared/{unjwt.ChCsF4q6.d.mts → unjwt.BjP_dGnX.d.mts} +6 -2
- package/dist/shared/{unjwt.BuQdWrN5.d.mts → unjwt.BrNGm4On.d.mts} +1 -1
- package/dist/shared/unjwt.BsLgL0DQ.d.mts +64 -0
- package/dist/shared/unjwt.C5jNR_1K.d.mts +166 -0
- package/dist/shared/{unjwt.CaZJRuRa.mjs → unjwt.CXl9FD-V.mjs} +2 -2
- package/dist/shared/{unjwt.Dy68jE0N.d.mts → unjwt.CtHrClHc.d.mts} +5 -1
- package/dist/shared/{unjwt.K_6rgVTy.mjs → unjwt.DCiTNyCM.mjs} +1 -1
- package/dist/shared/{unjwt.Dc_YDjvO.mjs → unjwt.DmRAjMp8.mjs} +3 -5
- package/dist/shared/unjwt.VUfJDcCJ.d.mts +161 -0
- package/dist/shared/{unjwt.D7ya3PwS.mjs → unjwt.Vg02PZWw.mjs} +10 -21
- package/dist/utils.d.mts +2 -2
- package/dist/utils.mjs +1 -1
- package/package.json +19 -1
- package/dist/shared/unjwt.BFtNZVqt.d.mts +0 -252
- package/dist/shared/unjwt.DANsaNYC.d.mts +0 -166
package/README.md
CHANGED
|
@@ -14,6 +14,21 @@ A collection of low-level JWT ([RFC 7519](https://datatracker.ietf.org/doc/html/
|
|
|
14
14
|
- **JWE (JSON Web Encryption, [RFC 7516](https://datatracker.ietf.org/doc/html/rfc7516))**: encrypt and decrypt data using various key management algorithms (AES Key Wrap, AES-GCM Key Wrap, RSA-OAEP, PBES2, ECDH-ES) and content encryption algorithms (AES-GCM, AES-CBC HMAC-SHA2).
|
|
15
15
|
- **JWK (JSON Web Key, [RFC 7517](https://datatracker.ietf.org/doc/html/rfc7517))**: generate, import, export, wrap, and unwrap keys in JWK format or as `CryptoKey` objects.
|
|
16
16
|
|
|
17
|
+
- **Adapters** for popular frameworks (PRs welcome for more!):
|
|
18
|
+
- [H3 (Nuxt, Nitro)](./src/adapters/h3.ts): `useJWSSession()`, `useJWESession()`
|
|
19
|
+
|
|
20
|
+
## Table of Contents
|
|
21
|
+
|
|
22
|
+
- [Usage](#usage)
|
|
23
|
+
- [Adapters](#adapters)
|
|
24
|
+
- [JWS](#jws-json-web-signature-rfc-7515)
|
|
25
|
+
- [JWE](#jwe-json-web-encryption-rfc-7516)
|
|
26
|
+
- [JWK](#jwk-json-web-key-rfc-7517)
|
|
27
|
+
- [Utility Functions](#utility-functions)
|
|
28
|
+
- [Development](#development)
|
|
29
|
+
- [Credits](#credits)
|
|
30
|
+
- [License](#license)
|
|
31
|
+
|
|
17
32
|
## Usage
|
|
18
33
|
|
|
19
34
|
Install the package:
|
|
@@ -585,6 +600,46 @@ console.log(rsaPublicSpki);
|
|
|
585
600
|
// -----END PUBLIC KEY-----
|
|
586
601
|
```
|
|
587
602
|
|
|
603
|
+
### Adapters
|
|
604
|
+
|
|
605
|
+
#### H3 (Nuxt, Nitro)
|
|
606
|
+
|
|
607
|
+
The `h3` adapter bundles session helpers that store data inside signed or encrypted JWTs.
|
|
608
|
+
|
|
609
|
+
- `useJWESession(event, config)` encrypts the session payload with the provided `secret` (password string or private/symmetric JWK). Use this when session data must remain confidential. (cookie's `httpOnly: true` by default)
|
|
610
|
+
- `useJWSSession(event, config)` signs, but does not encrypt, the session payload with `config.key`. Use this when clients may read the session content but you still need tamper protection. (cookie's `httpOnly: false` by default)
|
|
611
|
+
|
|
612
|
+
Both helpers expose the same API: read `session.id` / `session.data`, call `session.update()` to patch values, and `session.clear()` to invalidate the cookie. When setting `maxAge`, `exp` claim is automatically managed and validated.
|
|
613
|
+
|
|
614
|
+
```ts
|
|
615
|
+
import { defineEventHandler } from "h3";
|
|
616
|
+
import { useJWESession, useJWSSession, generateJWK } from "unjwt/adapters/h3";
|
|
617
|
+
|
|
618
|
+
const keys = await generateJWK("RS256");
|
|
619
|
+
|
|
620
|
+
export default defineEventHandler(async (event) => {
|
|
621
|
+
const privateSession = await useJWESession(event, {
|
|
622
|
+
name: "app-session",
|
|
623
|
+
secret: process.env.SESSION_SECRET!, // or symmetric or asymmetric keypair
|
|
624
|
+
});
|
|
625
|
+
|
|
626
|
+
await privateSession.update((data) => ({
|
|
627
|
+
visits: (data.visits ?? 0) + 1,
|
|
628
|
+
}));
|
|
629
|
+
|
|
630
|
+
const publicSession = await useJWSSession(event, {
|
|
631
|
+
name: "app-session-public",
|
|
632
|
+
key: keys, // you can directly pass symmetric or asymmetric keypairs
|
|
633
|
+
maxAge: 60 * 60, // seconds
|
|
634
|
+
});
|
|
635
|
+
|
|
636
|
+
return {
|
|
637
|
+
encryptedSession: privateSession.data,
|
|
638
|
+
signedSession: publicSession.data,
|
|
639
|
+
};
|
|
640
|
+
});
|
|
641
|
+
```
|
|
642
|
+
|
|
588
643
|
---
|
|
589
644
|
|
|
590
645
|
### Utility Functions
|
package/dist/h3.d.mts
ADDED
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import { b as JWEEncryptOptions } from './shared/unjwt.9mL1vSFP.mjs';
|
|
2
|
+
export { d as JWEDecryptOptions, e as JWEDecryptResult, J as JWEHeaderParameters, c as JWEKeyLookupFunction, a as JWEKeyManagementHeaderParameters } from './shared/unjwt.9mL1vSFP.mjs';
|
|
3
|
+
import { X as JWTClaims, r as JWK_Symmetric, u as JWK_Private, t as JWK_Public, Z as JWTClaimValidationOptions, w as JWKSet } from './shared/unjwt.CtHrClHc.mjs';
|
|
4
|
+
export { C as CompositeKey, f as ContentEncryptionAlgorithm, D as DeriveKeyOptions, e as DeriveKeyReturn, c as GenerateJWKOptions, d as GenerateJWKReturn, G as GenerateKeyAlgorithm, a as GenerateKeyOptions, b as GenerateKeyReturn, v as JWK, S as JWKAlgorithm, T as JWKPEMAlgorithm, J as JWKParameters, I as JWK_AES_CBC_HMAC, L as JWK_AES_GCM, H as JWK_AES_GCM_KW, F as JWK_AES_KW, s as JWK_Asymmetric, R as JWK_Asymmetric_Algorithm, j as JWK_EC, O as JWK_ECDH_ES, A as JWK_ECDSA, i as JWK_EC_Private, h as JWK_EC_Public, x as JWK_HMAC, p as JWK_OKP, o as JWK_OKP_Private, n as JWK_OKP_Public, P as JWK_OKP_SIGN, N as JWK_PBES2, m as JWK_RSA, B as JWK_RSA_ENC, z as JWK_RSA_PSS, l as JWK_RSA_Private, k as JWK_RSA_Public, y as JWK_RSA_SIGN, Q as JWK_Symmetric_Algorithm, q as JWK_oct, Y as JWT, V as JoseHeaderParameters, K as KeyManagementAlgorithm, U as UnwrapKeyOptions, W as WrapKeyOptions, g as WrapKeyResult } from './shared/unjwt.CtHrClHc.mjs';
|
|
5
|
+
import { CookieSerializeOptions } from 'cookie-es';
|
|
6
|
+
import { H3Event } from 'h3';
|
|
7
|
+
import { c as JWSSignOptions } from './shared/unjwt.BsLgL0DQ.mjs';
|
|
8
|
+
export { d as deriveJWKFromPassword, e as exportJWKToPEM, g as generateJWK, i as importJWKFromPEM } from './shared/unjwt.BjP_dGnX.mjs';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* This is a fork of h3 library's session utility functions.
|
|
12
|
+
* @source https://github.com/h3js/h3/blob/b4dce71c256911335f3402d09f30ffad120ad61a/test/session.test.ts
|
|
13
|
+
* @license MIT https://github.com/h3js/h3/blob/b4dce71c256911335f3402d09f30ffad120ad61a/LICENSE
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
type SessionDataT$1 = Omit<JWTClaims, "jti" | "iat" | "exp">;
|
|
17
|
+
type SessionData<T extends SessionDataT$1 = SessionDataT$1> = T;
|
|
18
|
+
declare const kGetSessionPromise$1: unique symbol;
|
|
19
|
+
interface SessionJWE<T extends SessionDataT$1 = SessionDataT$1> {
|
|
20
|
+
id: string;
|
|
21
|
+
createdAt: number;
|
|
22
|
+
expiresAt?: number;
|
|
23
|
+
data: SessionData<T>;
|
|
24
|
+
[kGetSessionPromise$1]?: Promise<SessionJWE<T>>;
|
|
25
|
+
}
|
|
26
|
+
interface SessionManager<T extends SessionDataT$1 = SessionDataT$1> {
|
|
27
|
+
readonly id: string | undefined;
|
|
28
|
+
readonly createdAt: number;
|
|
29
|
+
readonly expiresAt: number | undefined;
|
|
30
|
+
readonly data: SessionData<T>;
|
|
31
|
+
update: (update: SessionUpdate$1<T>) => Promise<SessionManager<T>>;
|
|
32
|
+
clear: () => Promise<SessionManager<T>>;
|
|
33
|
+
}
|
|
34
|
+
interface SessionJWEConfig {
|
|
35
|
+
/** Shared secret used, string for PBES2 or Json Web Key (JWK) */
|
|
36
|
+
secret: string | JWK_Symmetric | {
|
|
37
|
+
privateKey: JWK_Private | JWK_Symmetric;
|
|
38
|
+
publicKey?: JWK_Public;
|
|
39
|
+
};
|
|
40
|
+
/** Session lifetime in seconds (used to derive exp from iat) */
|
|
41
|
+
maxAge?: number;
|
|
42
|
+
/** Default is "h3" */
|
|
43
|
+
name?: string;
|
|
44
|
+
/** Default is secure, httpOnly, path="/" */
|
|
45
|
+
cookie?: false | CookieSerializeOptions;
|
|
46
|
+
/** Default is x-h3-session / x-{name}-session */
|
|
47
|
+
sessionHeader?: false | string;
|
|
48
|
+
/** Optional WebCrypto implementation override */
|
|
49
|
+
crypto?: Crypto;
|
|
50
|
+
/** Default is crypto.randomUUID */
|
|
51
|
+
generateId?: () => string;
|
|
52
|
+
/** JWE configuration overrides */
|
|
53
|
+
jwe?: {
|
|
54
|
+
encryptOptions?: Omit<JWEEncryptOptions, "expiresIn">;
|
|
55
|
+
decryptOptions?: JWTClaimValidationOptions;
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
type CompatEvent$1 = {
|
|
59
|
+
request: {
|
|
60
|
+
headers: Headers;
|
|
61
|
+
};
|
|
62
|
+
context: any;
|
|
63
|
+
} | {
|
|
64
|
+
headers: Headers;
|
|
65
|
+
context: any;
|
|
66
|
+
};
|
|
67
|
+
type SessionUpdate$1<T extends SessionDataT$1 = SessionDataT$1> = Partial<SessionData<T>> | ((oldData: SessionData<T>) => Partial<SessionData<T>> | undefined);
|
|
68
|
+
/**
|
|
69
|
+
* Create a session manager for the current request.
|
|
70
|
+
*/
|
|
71
|
+
declare function useJWESession<T extends SessionDataT$1 = SessionDataT$1>(event: H3Event | CompatEvent$1, config: SessionJWEConfig): Promise<SessionManager<T>>;
|
|
72
|
+
/**
|
|
73
|
+
* Get (and lazily initialize) the session for the current request.
|
|
74
|
+
*/
|
|
75
|
+
declare function getJWESession<T extends SessionDataT$1 = SessionDataT$1>(event: H3Event | CompatEvent$1, config: SessionJWEConfig): Promise<SessionJWE<T>>;
|
|
76
|
+
/**
|
|
77
|
+
* Update the session (optionally mutating the session data) and re-issue the JWE token.
|
|
78
|
+
*/
|
|
79
|
+
declare function updateJWESession<T extends SessionDataT$1 = SessionDataT$1>(event: H3Event, config: SessionJWEConfig, update?: SessionUpdate$1<T>): Promise<SessionJWE<T>>;
|
|
80
|
+
/**
|
|
81
|
+
* Produce a JWE for the current session.
|
|
82
|
+
* Payload structure:
|
|
83
|
+
* {
|
|
84
|
+
* jti: string;
|
|
85
|
+
* iat: number; (seconds)
|
|
86
|
+
* exp?: number; (seconds)
|
|
87
|
+
* data: Record<string, any>;
|
|
88
|
+
* }
|
|
89
|
+
*/
|
|
90
|
+
declare function sealJWESession<T extends SessionDataT$1 = SessionDataT$1>(event: H3Event | CompatEvent$1, config: SessionJWEConfig): Promise<string>;
|
|
91
|
+
/**
|
|
92
|
+
* Decrypt the JWE and return a Session-compatible object.
|
|
93
|
+
*/
|
|
94
|
+
declare function unsealJWESession(_event: H3Event | CompatEvent$1, config: SessionJWEConfig, sealed: string): Promise<Partial<SessionJWE>>;
|
|
95
|
+
/**
|
|
96
|
+
* Clear the session (delete from context and drop cookie).
|
|
97
|
+
*/
|
|
98
|
+
declare function clearJWESession(event: H3Event, config: Partial<SessionJWEConfig>): Promise<void>;
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* This is a fork of h3 library's session utility functions.
|
|
102
|
+
* @source https://github.com/h3js/h3/blob/b4dce71c256911335f3402d09f30ffad120ad61a/test/session.test.ts
|
|
103
|
+
* @license MIT https://github.com/h3js/h3/blob/b4dce71c256911335f3402d09f30ffad120ad61a/LICENSE
|
|
104
|
+
*/
|
|
105
|
+
|
|
106
|
+
type SessionDataT = Omit<JWTClaims, "jti" | "iat" | "exp">;
|
|
107
|
+
declare const kGetSessionPromise: unique symbol;
|
|
108
|
+
interface SessionJWS<T extends SessionDataT = SessionDataT> {
|
|
109
|
+
id: string;
|
|
110
|
+
createdAt: number;
|
|
111
|
+
expiresAt?: number;
|
|
112
|
+
data: SessionData<T>;
|
|
113
|
+
[kGetSessionPromise]?: Promise<SessionJWS<T>>;
|
|
114
|
+
}
|
|
115
|
+
interface SessionJWSConfig {
|
|
116
|
+
/**
|
|
117
|
+
* JWK (private for signing with RS/ES/PS, or symmetric oct) used for signing.
|
|
118
|
+
*/
|
|
119
|
+
key: JWK_Symmetric | {
|
|
120
|
+
privateKey: JWK_Private;
|
|
121
|
+
publicKey: JWK_Public | JWK_Public[] | JWKSet;
|
|
122
|
+
};
|
|
123
|
+
/** Session lifetime in seconds (sets exp = iat + maxAge) */
|
|
124
|
+
maxAge?: number;
|
|
125
|
+
/** Default cookie / header name base */
|
|
126
|
+
name?: string;
|
|
127
|
+
/** Cookie options (false to disable cookies) */
|
|
128
|
+
cookie?: false | CookieSerializeOptions;
|
|
129
|
+
/** Custom header (false to disable header lookup) */
|
|
130
|
+
sessionHeader?: false | string;
|
|
131
|
+
/** Provide a custom WebCrypto (if needed for algorithm operations) */
|
|
132
|
+
crypto?: Crypto;
|
|
133
|
+
/** Custom ID generator (defaults to crypto.randomUUID) */
|
|
134
|
+
generateId?: () => string;
|
|
135
|
+
/** JWS customization */
|
|
136
|
+
jws?: {
|
|
137
|
+
signOptions?: Omit<JWSSignOptions, "expiresIn">;
|
|
138
|
+
verifyOptions?: JWTClaimValidationOptions;
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
type CompatEvent = {
|
|
142
|
+
request: {
|
|
143
|
+
headers: Headers;
|
|
144
|
+
};
|
|
145
|
+
context: any;
|
|
146
|
+
} | {
|
|
147
|
+
headers: Headers;
|
|
148
|
+
context: any;
|
|
149
|
+
};
|
|
150
|
+
type SessionUpdate<T extends SessionDataT = SessionDataT> = Partial<SessionData<T>> | ((oldData: SessionData<T>) => Partial<SessionData<T>> | undefined);
|
|
151
|
+
/**
|
|
152
|
+
* Create a session manager for the current request using JWS (signed only, not encrypted).
|
|
153
|
+
* NOTE: Contents are visible to clients (Base64URL-decoded JSON). Do not store secrets in session data.
|
|
154
|
+
*/
|
|
155
|
+
declare function useJWSSession<T extends SessionDataT = SessionDataT>(event: H3Event | CompatEvent, config: SessionJWSConfig): Promise<SessionManager<T>>;
|
|
156
|
+
/**
|
|
157
|
+
* Retrieve (and lazily initialize) the session.
|
|
158
|
+
*/
|
|
159
|
+
declare function getJWSSession<T extends SessionDataT = SessionDataT>(event: H3Event | CompatEvent, config: SessionJWSConfig): Promise<SessionJWS<T>>;
|
|
160
|
+
/**
|
|
161
|
+
* Update session data (if provided) and reissue JWS.
|
|
162
|
+
*/
|
|
163
|
+
declare function updateJWSSession<T extends SessionDataT = SessionDataT>(event: H3Event, config: SessionJWSConfig, update?: SessionUpdate<T>): Promise<SessionJWS<T>>;
|
|
164
|
+
/**
|
|
165
|
+
* Sign current session as a compact JWS.
|
|
166
|
+
* Payload claims:
|
|
167
|
+
* jti, iat, exp?, data, plus optional extraClaims (cannot override reserved)
|
|
168
|
+
*/
|
|
169
|
+
declare function signJWSSession<T extends SessionDataT = SessionDataT>(event: H3Event | CompatEvent, config: SessionJWSConfig): Promise<string>;
|
|
170
|
+
/**
|
|
171
|
+
* Verify and parse a compact JWS into a Session structure.
|
|
172
|
+
* Performs:
|
|
173
|
+
* - cryptographic signature verification
|
|
174
|
+
* - (optional) standard claim checks if validateJWT true
|
|
175
|
+
* - ensures jti & iat presence
|
|
176
|
+
* - enforces maxAge if provided
|
|
177
|
+
*/
|
|
178
|
+
declare function verifyJWSSession(_event: H3Event | CompatEvent, config: SessionJWSConfig, token: string): Promise<Partial<SessionJWS>>;
|
|
179
|
+
/**
|
|
180
|
+
* Destroy the session (context + cookie).
|
|
181
|
+
*/
|
|
182
|
+
declare function clearJWSSession(event: H3Event, config: Partial<SessionJWSConfig>): Promise<void>;
|
|
183
|
+
|
|
184
|
+
export { JWEEncryptOptions, JWKSet, JWK_Private, JWK_Public, JWK_Symmetric, JWTClaimValidationOptions, JWTClaims, clearJWESession, clearJWSSession, getJWESession, getJWSSession, sealJWESession, signJWSSession, unsealJWESession, updateJWESession, updateJWSSession, useJWESession, useJWSSession, verifyJWSSession };
|
|
185
|
+
export type { SessionData, SessionJWE, SessionJWEConfig, SessionJWS, SessionJWSConfig, SessionManager };
|