unjwt 0.7.1 → 0.7.2
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/dist/_chunks/_internal.mjs +5 -5
- package/dist/_chunks/index.d.mts +30 -7
- package/dist/_chunks/jwe.d.mts +2 -2
- package/dist/_chunks/jwe.mjs +5 -5
- package/dist/_chunks/jwk.mjs +24 -9
- package/dist/_chunks/jws.d.mts +2 -2
- package/dist/_chunks/jws.mjs +5 -5
- package/dist/_chunks/libs/unsecure.d.mts +1 -1
- package/dist/_chunks/libs/unsecure.mjs +1 -1
- package/dist/_chunks/utils.mjs +2 -2
- package/dist/adapters/elysia/index.d.mts +244 -0
- package/dist/adapters/elysia/index.mjs +608 -0
- package/dist/adapters/h3v1/index.d.mts +120 -42
- package/dist/adapters/h3v1/index.mjs +16 -13
- package/dist/adapters/h3v2/index.d.mts +140 -20
- package/dist/adapters/h3v2/index.mjs +16 -13
- package/dist/core/jwe.d.mts +3 -3
- package/dist/core/jwe.mjs +2 -2
- package/dist/core/jwk.d.mts +10 -10
- package/dist/core/jwk.mjs +2 -2
- package/dist/core/jws.d.mts +3 -3
- package/dist/core/jws.mjs +2 -2
- package/dist/core/utils/index.d.mts +20 -7
- package/dist/core/utils/index.mjs +2 -2
- package/dist/index.d.mts +4 -4
- package/dist/index.mjs +4 -4
- package/package.json +21 -12
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { CompositeKey, ContentEncryptionAlgorithm, DeriveKeyOptions, DeriveKeyReturn, Duration, ExpiresIn, GenerateJWKOptions, GenerateJWKReturn, GenerateKeyAlgorithm, GenerateKeyOptions, GenerateKeyReturn, JOSEPayload, JWEAsymmetricPrivateJWK, JWEAsymmetricPublicJWK, JWEDecryptJWK, JWEDecryptOptions, JWEDecryptResult, JWEEncryptJWK, JWEEncryptOptions, JWEFlattenedSerialization, JWEGeneralRecipient, JWEGeneralSerialization, JWEHeaderParameters, JWEKeyManagementHeaderParameters, JWEMultiDecryptOptions, JWEMultiDecryptResult, JWEMultiEncryptOptions, JWEMultiRecipient, JWEProtectedHeader, JWK, JWKAlgorithm, JWKCacheAdapter, JWKLookupFunction, JWKLookupFunctionHeader, JWKPEMAlgorithm, JWKParameters, JWKSet, JWK_AES_CBC_HMAC, JWK_AES_GCM, JWK_AES_GCM_KW, JWK_AES_KW, JWK_Asymmetric, JWK_Asymmetric_Algorithm, JWK_EC, JWK_ECDH_ES, JWK_ECDSA, JWK_EC_Private, JWK_EC_Public, JWK_HMAC, JWK_OKP, JWK_OKP_Private, JWK_OKP_Public, JWK_OKP_SIGN, JWK_PBES2, JWK_Pair, JWK_Private, JWK_Public, JWK_RSA, JWK_RSA_ENC, JWK_RSA_PSS, JWK_RSA_Private, JWK_RSA_Public, JWK_RSA_SIGN, JWK_Symmetric, JWK_Symmetric_Algorithm, JWK_oct, JWSAlgorithm, JWSAsymmetricPrivateJWK, JWSAsymmetricPublicJWK, JWSFlattenedSerialization, JWSGeneralSerialization, JWSGeneralSignature, JWSHeaderParameters, JWSMultiSignOptions, JWSMultiSigner, JWSMultiVerifyAllOptions, JWSMultiVerifyOptions, JWSMultiVerifyOutcome, JWSMultiVerifyResult, JWSProtectedHeader, JWSSignJWK, JWSSignOptions, JWSVerifyJWK, JWSVerifyOptions, JWSVerifyResult, JWT, JWTClaimValidationOptions, JWTClaims, JoseHeaderParameters, KeyManagementAlgorithm, MaxTokenAge, NotBeforeIn, StrictOmit, UnwrapKeyOptions, UnwrappingKeyFor, WrapKeyOptions, WrapKeyResult, WrappingKeyFor } from "../../_chunks/index.mjs";
|
|
2
2
|
import { deriveJWKFromPassword, exportPEM, exportToPEM, generateJWK, importFromPEM, importPEM } from "../../core/jwk.mjs";
|
|
3
3
|
import { H3Event } from "h3";
|
|
4
4
|
import { CookieSerializeOptions } from "cookie-es";
|
|
@@ -22,6 +22,10 @@ interface SessionManager<T extends Record<string, any> = SessionClaims, ConfigMa
|
|
|
22
22
|
}>;
|
|
23
23
|
}
|
|
24
24
|
declare const kGetSessionPromise$1: unique symbol;
|
|
25
|
+
/**
|
|
26
|
+
* In-memory session state for the current request, mirroring the claims of
|
|
27
|
+
* the underlying compact JWE token.
|
|
28
|
+
*/
|
|
25
29
|
interface SessionJWE<T extends Record<string, any> = SessionClaims, MaxAge extends ExpiresIn | undefined = ExpiresIn | undefined> {
|
|
26
30
|
/** Session ID — mirrors the JWT `jti` claim. `undefined` until the session is persisted. */
|
|
27
31
|
id: string | undefined;
|
|
@@ -29,11 +33,23 @@ interface SessionJWE<T extends Record<string, any> = SessionClaims, MaxAge exten
|
|
|
29
33
|
createdAt: number;
|
|
30
34
|
/** Session expiry time in ms — mirrors the JWT `exp` claim (seconds). */
|
|
31
35
|
expiresAt: MaxAge extends ExpiresIn ? number : T["exp"];
|
|
36
|
+
/** Session data — carried in the token payload, spread at the top level. */
|
|
32
37
|
data: SessionData<T>;
|
|
38
|
+
/** The current compact JWE token. `undefined` until the session is persisted. */
|
|
33
39
|
token: string | undefined;
|
|
34
40
|
[kGetSessionPromise$1]?: Promise<SessionJWE<T, MaxAge>>;
|
|
35
41
|
}
|
|
42
|
+
/**
|
|
43
|
+
* Lifecycle hooks for JWE sessions. `onRead`, `onExpire`, and `onError` are
|
|
44
|
+
* mutually exclusive per incoming token — `onRead` fires only when a session
|
|
45
|
+
* was successfully established from it.
|
|
46
|
+
*/
|
|
36
47
|
interface SessionHooksJWE<T extends Record<string, any> = SessionClaims, MaxAge extends ExpiresIn | undefined = ExpiresIn | undefined, TEvent extends CompatEvent$1 | H3Event = CompatEvent$1 | H3Event> {
|
|
48
|
+
/**
|
|
49
|
+
* Fires when an incoming token was decrypted and the session established.
|
|
50
|
+
* May fire more than once per request when `useJWESession` is called
|
|
51
|
+
* concurrently in the same handler — dedupe via `session.id` if needed.
|
|
52
|
+
*/
|
|
37
53
|
onRead?: (args: {
|
|
38
54
|
session: SessionJWE<T, MaxAge> & {
|
|
39
55
|
id: string;
|
|
@@ -42,20 +58,23 @@ interface SessionHooksJWE<T extends Record<string, any> = SessionClaims, MaxAge
|
|
|
42
58
|
event: TEvent;
|
|
43
59
|
config: SessionConfigJWE<T, MaxAge, TEvent>;
|
|
44
60
|
}) => void | Promise<void>;
|
|
61
|
+
/** Fires after a new token was sealed — including pure token refreshes (update with no data). */
|
|
45
62
|
onUpdate?: (args: {
|
|
46
|
-
/** Session after
|
|
63
|
+
/** Session after the update. */session: SessionJWE<T, MaxAge> & {
|
|
47
64
|
id: string;
|
|
48
65
|
token: string;
|
|
49
|
-
}; /**
|
|
66
|
+
}; /** Deep-copied snapshot of the session before the update. */
|
|
50
67
|
oldSession: SessionJWE<T, MaxAge>;
|
|
51
68
|
event: TEvent;
|
|
52
69
|
config: SessionConfigJWE<T, MaxAge, TEvent>;
|
|
53
70
|
}) => void | Promise<void>;
|
|
71
|
+
/** Fires when the session is cleared. */
|
|
54
72
|
onClear?: (args: {
|
|
55
|
-
oldSession: SessionJWE<T, MaxAge> | undefined;
|
|
73
|
+
/** Last known session before clearing, if any. */oldSession: SessionJWE<T, MaxAge> | undefined;
|
|
56
74
|
event: TEvent;
|
|
57
75
|
config: SessionConfigJWE<T, MaxAge, TEvent>;
|
|
58
76
|
}) => void | Promise<void>;
|
|
77
|
+
/** Fires when the incoming token is expired. Receives the expired token's decoded claims. */
|
|
59
78
|
onExpire?: (args: {
|
|
60
79
|
session: {
|
|
61
80
|
id: string | undefined;
|
|
@@ -67,6 +86,7 @@ interface SessionHooksJWE<T extends Record<string, any> = SessionClaims, MaxAge
|
|
|
67
86
|
error: Error;
|
|
68
87
|
config: SessionConfigJWE<T, MaxAge, TEvent>;
|
|
69
88
|
}) => void | Promise<void>;
|
|
89
|
+
/** Fires on read-path failures other than expiry, and on write-path seal failures. */
|
|
70
90
|
onError?: (args: {
|
|
71
91
|
/**
|
|
72
92
|
* The session involved in the error.
|
|
@@ -76,33 +96,46 @@ interface SessionHooksJWE<T extends Record<string, any> = SessionClaims, MaxAge
|
|
|
76
96
|
error: any;
|
|
77
97
|
config: SessionConfigJWE<T, MaxAge, TEvent>;
|
|
78
98
|
}) => void | Promise<void>;
|
|
99
|
+
/** Resolve the decryption key for the incoming token from its protected header (e.g. by `kid`). */
|
|
79
100
|
onUnsealKeyLookup?: (args: {
|
|
80
101
|
header: JWEHeaderParameters;
|
|
81
102
|
event: TEvent;
|
|
82
103
|
config: SessionConfigJWE<T, MaxAge, TEvent>;
|
|
83
104
|
}) => JWEDecryptJWK | Promise<JWEDecryptJWK>;
|
|
84
105
|
}
|
|
106
|
+
/**
|
|
107
|
+
* Configuration for a JWE-backed (encrypted) session.
|
|
108
|
+
*/
|
|
85
109
|
interface SessionConfigJWE<T extends Record<string, any> = SessionClaims, MaxAge extends ExpiresIn | undefined = ExpiresIn | undefined, TEvent extends CompatEvent$1 | H3Event = CompatEvent$1 | H3Event> {
|
|
86
|
-
/**
|
|
110
|
+
/**
|
|
111
|
+
* Secret used for sealing — a password string (PBES2), a symmetric JWK, or
|
|
112
|
+
* an asymmetric pair: the public key seals, the private key unseals.
|
|
113
|
+
*/
|
|
87
114
|
key: string | JWEEncryptJWK | {
|
|
88
115
|
privateKey: JWEAsymmetricPrivateJWK;
|
|
89
116
|
publicKey?: JWEAsymmetricPublicJWK;
|
|
90
117
|
};
|
|
91
|
-
/**
|
|
118
|
+
/**
|
|
119
|
+
* Session lifetime in seconds — sets `exp = iat + maxAge` in the token and
|
|
120
|
+
* drives the cookie expiry. Without it the library writes no `exp` — though
|
|
121
|
+
* an `exp` key in the session data is then carried into the token as its
|
|
122
|
+
* actual expiry claim.
|
|
123
|
+
*/
|
|
92
124
|
maxAge?: MaxAge;
|
|
93
|
-
/** Default
|
|
125
|
+
/** Session name — drives the cookie name and the default session header. Default `"h3-jwe"`. */
|
|
94
126
|
name?: string;
|
|
95
|
-
/**
|
|
127
|
+
/** Cookie options (`false` to disable). Defaults: `path="/"`, `secure`, `httpOnly: true`. */
|
|
96
128
|
cookie?: false | CookieSerializeOptions;
|
|
97
|
-
/**
|
|
129
|
+
/** Request header to read the token from (`false` to disable). Default `x-<name>-session`. */
|
|
98
130
|
sessionHeader?: false | string;
|
|
99
|
-
/** Default
|
|
131
|
+
/** Session ID (`jti`) generator. Default `crypto.randomUUID`. */
|
|
100
132
|
generateId?: () => string;
|
|
101
|
-
/** JWE
|
|
133
|
+
/** JWE encrypt/decrypt overrides. Set `encryptOptions.alg` and `enc` to pin the session algorithms — unsealing then accepts only them. */
|
|
102
134
|
jwe?: {
|
|
103
135
|
encryptOptions?: Omit<JWEEncryptOptions, "expiresIn">;
|
|
104
136
|
decryptOptions?: JWTClaimValidationOptions;
|
|
105
137
|
};
|
|
138
|
+
/** Lifecycle hooks — see {@link SessionHooksJWE}. */
|
|
106
139
|
hooks?: SessionHooksJWE<T, MaxAge, TEvent>;
|
|
107
140
|
}
|
|
108
141
|
type CompatEvent$1 = {
|
|
@@ -115,34 +148,40 @@ type CompatEvent$1 = {
|
|
|
115
148
|
context: any;
|
|
116
149
|
};
|
|
117
150
|
/**
|
|
118
|
-
* Create a session manager for the current request.
|
|
151
|
+
* Create a session manager for the current request using JWE (encrypted).
|
|
119
152
|
*/
|
|
120
153
|
declare function useJWESession<T extends Record<string, any> = SessionClaims, MaxAge extends ExpiresIn | undefined = ExpiresIn | undefined, TEvent extends CompatEvent$1 | H3Event = CompatEvent$1 | H3Event>(event: TEvent, config: SessionConfigJWE<T, MaxAge, TEvent>): Promise<SessionManager<T, MaxAge>>;
|
|
121
154
|
/**
|
|
122
155
|
* Get (and lazily initialize) the session for the current request.
|
|
123
156
|
*/
|
|
124
157
|
declare function getJWESession<T extends Record<string, any> = SessionClaims, MaxAge extends ExpiresIn | undefined = ExpiresIn | undefined, TEvent extends CompatEvent$1 | H3Event = CompatEvent$1 | H3Event>(event: TEvent, config: SessionConfigJWE<T, MaxAge, TEvent>): Promise<SessionJWE<T, MaxAge>>;
|
|
158
|
+
/**
|
|
159
|
+
* Read the raw session token for the request. The session header (default
|
|
160
|
+
* `x-<name>-session`, `Bearer ` prefix stripped) takes precedence, then a
|
|
161
|
+
* freshly-minted token on the response's `Set-Cookie`, then the session cookie.
|
|
162
|
+
*/
|
|
125
163
|
declare function getJWESessionToken<T extends Record<string, any> = SessionClaims, MaxAge extends ExpiresIn | undefined = ExpiresIn | undefined, TEvent extends CompatEvent$1 | H3Event = CompatEvent$1 | H3Event>(event: TEvent, config: SessionConfigJWE<T, MaxAge, TEvent>): string | undefined;
|
|
126
164
|
/**
|
|
127
|
-
* Update the session (
|
|
165
|
+
* Update the session data (if provided) and reissue the JWE token.
|
|
128
166
|
*/
|
|
129
167
|
declare function updateJWESession<T extends Record<string, any> = SessionClaims, MaxAge extends ExpiresIn | undefined = ExpiresIn | undefined, TEvent extends CompatEvent$1 | H3Event = CompatEvent$1 | H3Event>(event: TEvent, config: SessionConfigJWE<T, MaxAge, TEvent>, update?: SessionUpdate<T>): Promise<SessionJWE<T, MaxAge> & {
|
|
130
168
|
id: string;
|
|
131
169
|
token: string;
|
|
132
170
|
}>;
|
|
133
171
|
/**
|
|
134
|
-
*
|
|
135
|
-
* Payload
|
|
136
|
-
*
|
|
137
|
-
*
|
|
138
|
-
* iat: number; (seconds)
|
|
139
|
-
* exp?: number; (seconds)
|
|
140
|
-
* data: Record<string, any>;
|
|
141
|
-
* }
|
|
172
|
+
* Seal the current session as a compact JWE.
|
|
173
|
+
* Payload: `session.data` spread at the top level, plus the reserved claims
|
|
174
|
+
* `jti`, `iat`, and `exp` (when `maxAge` is set), which overwrite any
|
|
175
|
+
* same-named keys in the session data.
|
|
142
176
|
*/
|
|
143
177
|
declare function sealJWESession<T extends Record<string, any> = SessionClaims, MaxAge extends ExpiresIn | undefined = ExpiresIn | undefined, TEvent extends CompatEvent$1 | H3Event = CompatEvent$1 | H3Event>(event: TEvent, config: SessionConfigJWE<T, MaxAge, TEvent>): Promise<string>;
|
|
144
178
|
/**
|
|
145
|
-
* Decrypt
|
|
179
|
+
* Decrypt and parse a compact JWE into a Session structure.
|
|
180
|
+
* Performs:
|
|
181
|
+
* - authenticated decryption
|
|
182
|
+
* - claim validation (always on): `jti` & `iat` required, `exp` honoured
|
|
183
|
+
* - `typ` header check and alg/enc pinning when configured
|
|
184
|
+
* - `maxAge` enforced as `maxTokenAge` when provided
|
|
146
185
|
*/
|
|
147
186
|
declare function unsealJWESession<T extends Record<string, any> = SessionClaims, MaxAge extends ExpiresIn | undefined = ExpiresIn | undefined, TEvent extends CompatEvent$1 | H3Event = CompatEvent$1 | H3Event>(event: TEvent, config: SessionConfigJWE<T, MaxAge, TEvent>, sealed: string): Promise<Partial<SessionJWE<T, MaxAge>>>;
|
|
148
187
|
/**
|
|
@@ -150,6 +189,10 @@ declare function unsealJWESession<T extends Record<string, any> = SessionClaims,
|
|
|
150
189
|
*/
|
|
151
190
|
declare function clearJWESession<T extends Record<string, any> = SessionClaims, MaxAge extends ExpiresIn | undefined = ExpiresIn | undefined, TEvent extends CompatEvent$1 | H3Event = CompatEvent$1 | H3Event>(event: TEvent, config: SessionConfigJWE<T, MaxAge, TEvent>): Promise<void>;
|
|
152
191
|
declare const kGetSessionPromise: unique symbol;
|
|
192
|
+
/**
|
|
193
|
+
* In-memory session state for the current request, mirroring the claims of
|
|
194
|
+
* the underlying compact JWS token.
|
|
195
|
+
*/
|
|
153
196
|
interface SessionJWS<T extends Record<string, any> = SessionClaims, MaxAge extends ExpiresIn | undefined = ExpiresIn | undefined> {
|
|
154
197
|
/** Session ID — mirrors the JWT `jti` claim. `undefined` until the session is persisted. */
|
|
155
198
|
id: string | undefined;
|
|
@@ -157,11 +200,23 @@ interface SessionJWS<T extends Record<string, any> = SessionClaims, MaxAge exten
|
|
|
157
200
|
createdAt: number;
|
|
158
201
|
/** Session expiry time in ms — mirrors the JWT `exp` claim (seconds). */
|
|
159
202
|
expiresAt: MaxAge extends ExpiresIn ? number : T["exp"];
|
|
203
|
+
/** Session data — carried in the token payload, spread at the top level. */
|
|
160
204
|
data: SessionData<T>;
|
|
205
|
+
/** The current compact JWS token. `undefined` until the session is persisted. */
|
|
161
206
|
token: string | undefined;
|
|
162
207
|
[kGetSessionPromise]?: Promise<SessionJWS<T, MaxAge>>;
|
|
163
208
|
}
|
|
209
|
+
/**
|
|
210
|
+
* Lifecycle hooks for JWS sessions. `onRead`, `onExpire`, and `onError` are
|
|
211
|
+
* mutually exclusive per incoming token — `onRead` fires only when a session
|
|
212
|
+
* was successfully established from it.
|
|
213
|
+
*/
|
|
164
214
|
interface SessionHooksJWS<T extends Record<string, any> = SessionClaims, MaxAge extends ExpiresIn | undefined = ExpiresIn | undefined, TEvent extends CompatEvent | H3Event = CompatEvent | H3Event> {
|
|
215
|
+
/**
|
|
216
|
+
* Fires when an incoming token was verified and the session established.
|
|
217
|
+
* May fire more than once per request when `useJWSSession` is called
|
|
218
|
+
* concurrently in the same handler — dedupe via `session.id` if needed.
|
|
219
|
+
*/
|
|
165
220
|
onRead?: (args: {
|
|
166
221
|
session: SessionJWS<T, MaxAge> & {
|
|
167
222
|
id: string;
|
|
@@ -170,20 +225,23 @@ interface SessionHooksJWS<T extends Record<string, any> = SessionClaims, MaxAge
|
|
|
170
225
|
event: TEvent;
|
|
171
226
|
config: SessionConfigJWS<T, MaxAge, TEvent>;
|
|
172
227
|
}) => void | Promise<void>;
|
|
228
|
+
/** Fires after a new token was signed — including pure token refreshes (update with no data). */
|
|
173
229
|
onUpdate?: (args: {
|
|
174
|
-
/** Session after
|
|
230
|
+
/** Session after the update. */session: SessionJWS<T, MaxAge> & {
|
|
175
231
|
id: string;
|
|
176
232
|
token: string;
|
|
177
|
-
}; /**
|
|
233
|
+
}; /** Deep-copied snapshot of the session before the update. */
|
|
178
234
|
oldSession: SessionJWS<T, MaxAge>;
|
|
179
235
|
event: TEvent;
|
|
180
236
|
config: SessionConfigJWS<T, MaxAge, TEvent>;
|
|
181
237
|
}) => void | Promise<void>;
|
|
238
|
+
/** Fires when the session is cleared. */
|
|
182
239
|
onClear?: (args: {
|
|
183
|
-
oldSession: SessionJWS<T, MaxAge> | undefined;
|
|
240
|
+
/** Last known session before clearing, if any. */oldSession: SessionJWS<T, MaxAge> | undefined;
|
|
184
241
|
event: TEvent;
|
|
185
242
|
config: SessionConfigJWS<T, MaxAge, TEvent>;
|
|
186
243
|
}) => void | Promise<void>;
|
|
244
|
+
/** Fires when the incoming token is expired. Receives the expired token's decoded claims. */
|
|
187
245
|
onExpire?: (args: {
|
|
188
246
|
session: {
|
|
189
247
|
id: string | undefined;
|
|
@@ -195,6 +253,7 @@ interface SessionHooksJWS<T extends Record<string, any> = SessionClaims, MaxAge
|
|
|
195
253
|
error: Error;
|
|
196
254
|
config: SessionConfigJWS<T, MaxAge, TEvent>;
|
|
197
255
|
}) => void | Promise<void>;
|
|
256
|
+
/** Fires on read-path failures other than expiry, and on write-path sign failures. */
|
|
198
257
|
onError?: (args: {
|
|
199
258
|
/**
|
|
200
259
|
* The session involved in the error.
|
|
@@ -204,35 +263,47 @@ interface SessionHooksJWS<T extends Record<string, any> = SessionClaims, MaxAge
|
|
|
204
263
|
error: any;
|
|
205
264
|
config: SessionConfigJWS<T, MaxAge, TEvent>;
|
|
206
265
|
}) => void | Promise<void>;
|
|
266
|
+
/** Resolve the verification key(s) for the incoming token from its protected header (e.g. by `kid`). */
|
|
207
267
|
onVerifyKeyLookup?: (args: {
|
|
208
268
|
header: JWKLookupFunctionHeader;
|
|
209
269
|
event: TEvent;
|
|
210
270
|
config: SessionConfigJWS<T, MaxAge, TEvent>;
|
|
211
271
|
}) => JWKSet | JWSVerifyJWK | Promise<JWKSet | JWSVerifyJWK>;
|
|
212
272
|
}
|
|
273
|
+
/**
|
|
274
|
+
* Configuration for a JWS-backed (signed, not encrypted) session.
|
|
275
|
+
*/
|
|
213
276
|
interface SessionConfigJWS<T extends Record<string, any> = SessionClaims, MaxAge extends ExpiresIn | undefined = ExpiresIn | undefined, TEvent extends CompatEvent | H3Event = CompatEvent | H3Event> {
|
|
214
277
|
/**
|
|
215
|
-
* JWK
|
|
278
|
+
* JWK used for signing — a symmetric `oct` (HS*) key, or an asymmetric pair:
|
|
279
|
+
* the private key signs, the public side verifies (single JWK, array, or
|
|
280
|
+
* JWKSet for rotation).
|
|
216
281
|
*/
|
|
217
282
|
key: JWK_oct<JWK_HMAC> | {
|
|
218
283
|
privateKey: JWSAsymmetricPrivateJWK;
|
|
219
284
|
publicKey: JWSAsymmetricPublicJWK | JWSAsymmetricPublicJWK[] | JWKSet;
|
|
220
285
|
};
|
|
221
|
-
/**
|
|
286
|
+
/**
|
|
287
|
+
* Session lifetime in seconds — sets `exp = iat + maxAge` in the token and
|
|
288
|
+
* drives the cookie expiry. Without it the library writes no `exp` — though
|
|
289
|
+
* an `exp` key in the session data is then carried into the token as its
|
|
290
|
+
* actual expiry claim.
|
|
291
|
+
*/
|
|
222
292
|
maxAge?: MaxAge;
|
|
223
|
-
/**
|
|
293
|
+
/** Session name — drives the cookie name and the default session header. Default `"h3-jws"`. */
|
|
224
294
|
name?: string;
|
|
225
|
-
/** Cookie options (false to disable
|
|
295
|
+
/** Cookie options (`false` to disable). Defaults: `path="/"`, `secure`, `httpOnly: false` — the JWS payload is client-readable by design. */
|
|
226
296
|
cookie?: false | CookieSerializeOptions;
|
|
227
|
-
/**
|
|
297
|
+
/** Request header to read the token from (`false` to disable). Default `x-<name>-session`. */
|
|
228
298
|
sessionHeader?: false | string;
|
|
229
|
-
/**
|
|
299
|
+
/** Session ID (`jti`) generator. Default `crypto.randomUUID`. */
|
|
230
300
|
generateId?: () => string;
|
|
231
|
-
/** JWS
|
|
301
|
+
/** JWS sign/verify overrides. Set `signOptions.alg` to pin the session algorithm — verification then accepts only it. */
|
|
232
302
|
jws?: {
|
|
233
303
|
signOptions?: Omit<JWSSignOptions, "expiresIn">;
|
|
234
304
|
verifyOptions?: JWTClaimValidationOptions;
|
|
235
305
|
};
|
|
306
|
+
/** Lifecycle hooks — see {@link SessionHooksJWS}. */
|
|
236
307
|
hooks?: SessionHooksJWS<T, MaxAge, TEvent>;
|
|
237
308
|
}
|
|
238
309
|
type CompatEvent = {
|
|
@@ -250,33 +321,40 @@ type CompatEvent = {
|
|
|
250
321
|
*/
|
|
251
322
|
declare function useJWSSession<T extends Record<string, any> = SessionClaims, MaxAge extends ExpiresIn | undefined = ExpiresIn | undefined, TEvent extends CompatEvent | H3Event = CompatEvent | H3Event>(event: TEvent, config: SessionConfigJWS<T, MaxAge, TEvent>): Promise<SessionManager<T, MaxAge>>;
|
|
252
323
|
/**
|
|
253
|
-
*
|
|
324
|
+
* Get (and lazily initialize) the session for the current request.
|
|
254
325
|
*/
|
|
255
326
|
declare function getJWSSession<T extends Record<string, any> = SessionClaims, MaxAge extends ExpiresIn | undefined = ExpiresIn | undefined, TEvent extends CompatEvent | H3Event = CompatEvent | H3Event>(event: TEvent, config: SessionConfigJWS<T, MaxAge, TEvent>): Promise<SessionJWS<T, MaxAge>>;
|
|
256
327
|
/**
|
|
257
|
-
*
|
|
328
|
+
* Read the raw session token for the request. The session header (default
|
|
329
|
+
* `x-<name>-session`, `Bearer ` prefix stripped) takes precedence, then a
|
|
330
|
+
* freshly-minted token on the response's `Set-Cookie`, then the session cookie.
|
|
331
|
+
*/
|
|
332
|
+
declare function getJWSSessionToken<T extends Record<string, any> = SessionClaims, MaxAge extends ExpiresIn | undefined = ExpiresIn | undefined, TEvent extends CompatEvent | H3Event = CompatEvent | H3Event>(event: TEvent, config: SessionConfigJWS<T, MaxAge, TEvent>): string | undefined;
|
|
333
|
+
/**
|
|
334
|
+
* Update the session data (if provided) and reissue the JWS token.
|
|
258
335
|
*/
|
|
259
336
|
declare function updateJWSSession<T extends Record<string, any> = SessionClaims, MaxAge extends ExpiresIn | undefined = ExpiresIn | undefined, TEvent extends CompatEvent | H3Event = CompatEvent | H3Event>(event: TEvent, config: SessionConfigJWS<T, MaxAge, TEvent>, update?: SessionUpdate<T>): Promise<SessionJWS<T, MaxAge> & {
|
|
260
337
|
id: string;
|
|
261
338
|
token: string;
|
|
262
339
|
}>;
|
|
263
340
|
/**
|
|
264
|
-
* Sign current session as a compact JWS.
|
|
265
|
-
* Payload claims
|
|
266
|
-
*
|
|
341
|
+
* Sign the current session as a compact JWS.
|
|
342
|
+
* Payload: `session.data` spread at the top level, plus the reserved claims
|
|
343
|
+
* `jti`, `iat`, and `exp` (when `maxAge` is set), which overwrite any
|
|
344
|
+
* same-named keys in the session data.
|
|
267
345
|
*/
|
|
268
346
|
declare function signJWSSession<T extends Record<string, any> = SessionClaims, MaxAge extends ExpiresIn | undefined = ExpiresIn | undefined, TEvent extends CompatEvent | H3Event = CompatEvent | H3Event>(event: TEvent, config: SessionConfigJWS<T, MaxAge, TEvent>): Promise<string>;
|
|
269
347
|
/**
|
|
270
348
|
* Verify and parse a compact JWS into a Session structure.
|
|
271
349
|
* Performs:
|
|
272
350
|
* - cryptographic signature verification
|
|
273
|
-
* - (
|
|
274
|
-
* -
|
|
275
|
-
* -
|
|
351
|
+
* - claim validation (always on): `jti` & `iat` required, `exp` honoured
|
|
352
|
+
* - `typ` header check and algorithm pinning when configured
|
|
353
|
+
* - `maxAge` enforced as `maxTokenAge` when provided
|
|
276
354
|
*/
|
|
277
355
|
declare function verifyJWSSession<T extends Record<string, any> = SessionClaims, MaxAge extends ExpiresIn | undefined = ExpiresIn | undefined, TEvent extends CompatEvent | H3Event = CompatEvent | H3Event>(event: TEvent, config: SessionConfigJWS<T, MaxAge, TEvent>, token: string): Promise<Partial<SessionJWS<T, MaxAge>>>;
|
|
278
356
|
/**
|
|
279
|
-
*
|
|
357
|
+
* Clear the session (delete from context and drop cookie).
|
|
280
358
|
*/
|
|
281
359
|
declare function clearJWSSession<T extends Record<string, any> = SessionClaims, MaxAge extends ExpiresIn | undefined = ExpiresIn | undefined, TEvent extends CompatEvent | H3Event = CompatEvent | H3Event>(event: TEvent, config: SessionConfigJWS<T, MaxAge, TEvent>): Promise<void>;
|
|
282
|
-
export { CompositeKey, ContentEncryptionAlgorithm, DeriveKeyOptions, DeriveKeyReturn, Duration, ExpiresIn, GenerateJWKOptions, GenerateJWKReturn, GenerateKeyAlgorithm, GenerateKeyOptions, GenerateKeyReturn, JOSEPayload, JWEAsymmetricPrivateJWK, JWEAsymmetricPublicJWK, JWEDecryptJWK, JWEDecryptOptions, JWEDecryptResult, JWEEncryptJWK, JWEEncryptOptions, JWEFlattenedSerialization, JWEGeneralRecipient, JWEGeneralSerialization, JWEHeaderParameters, JWEKeyManagementHeaderParameters, JWEMultiDecryptOptions, JWEMultiDecryptResult, JWEMultiEncryptOptions, JWEMultiRecipient, JWEProtectedHeader, JWK, JWKAlgorithm, JWKCacheAdapter, JWKLookupFunction, JWKLookupFunctionHeader, JWKPEMAlgorithm, JWKParameters, JWKSet, JWK_AES_CBC_HMAC, JWK_AES_GCM, JWK_AES_GCM_KW, JWK_AES_KW, JWK_Asymmetric, JWK_Asymmetric_Algorithm, JWK_EC, JWK_ECDH_ES, JWK_ECDSA, JWK_EC_Private, JWK_EC_Public, JWK_HMAC, JWK_OKP, JWK_OKP_Private, JWK_OKP_Public, JWK_OKP_SIGN, JWK_PBES2, JWK_Pair, JWK_Private, JWK_Public, JWK_RSA, JWK_RSA_ENC, JWK_RSA_PSS, JWK_RSA_Private, JWK_RSA_Public, JWK_RSA_SIGN, JWK_Symmetric, JWK_Symmetric_Algorithm, JWK_oct, JWSAlgorithm, JWSAsymmetricPrivateJWK, JWSAsymmetricPublicJWK, JWSFlattenedSerialization, JWSGeneralSerialization, JWSGeneralSignature, JWSHeaderParameters, JWSMultiSignOptions, JWSMultiSigner, JWSMultiVerifyAllOptions, JWSMultiVerifyOptions, JWSMultiVerifyOutcome, JWSMultiVerifyResult, JWSProtectedHeader, JWSSignJWK, JWSSignOptions, JWSVerifyJWK, JWSVerifyOptions, JWSVerifyResult, JWT, JWTClaimValidationOptions, JWTClaims, JoseHeaderParameters, KeyManagementAlgorithm, MaxTokenAge, NotBeforeIn, type SessionClaims, type SessionConfigJWE, type SessionConfigJWS, type SessionData, type SessionHooksJWE, type SessionHooksJWS, type SessionJWE, type SessionJWS, type SessionManager, type SessionUpdate, UnwrapKeyOptions, UnwrappingKeyFor, WrapKeyOptions, WrapKeyResult, WrappingKeyFor, clearJWESession, clearJWSSession, deriveJWKFromPassword, exportPEM, exportToPEM, generateJWK, getJWESession, getJWESessionToken, getJWSSession, importFromPEM, importPEM, sealJWESession, signJWSSession, unsealJWESession, updateJWESession, updateJWSSession, useJWESession, useJWSSession, verifyJWSSession };
|
|
360
|
+
export { type CompositeKey, type ContentEncryptionAlgorithm, type DeriveKeyOptions, type DeriveKeyReturn, type Duration, type ExpiresIn, type GenerateJWKOptions, type GenerateJWKReturn, type GenerateKeyAlgorithm, type GenerateKeyOptions, type GenerateKeyReturn, type JOSEPayload, type JWEAsymmetricPrivateJWK, type JWEAsymmetricPublicJWK, type JWEDecryptJWK, type JWEDecryptOptions, type JWEDecryptResult, type JWEEncryptJWK, type JWEEncryptOptions, type JWEFlattenedSerialization, type JWEGeneralRecipient, type JWEGeneralSerialization, type JWEHeaderParameters, type JWEKeyManagementHeaderParameters, type JWEMultiDecryptOptions, type JWEMultiDecryptResult, type JWEMultiEncryptOptions, type JWEMultiRecipient, type JWEProtectedHeader, type JWK, type JWKAlgorithm, type JWKCacheAdapter, type JWKLookupFunction, type JWKLookupFunctionHeader, type JWKPEMAlgorithm, type JWKParameters, type JWKSet, type JWK_AES_CBC_HMAC, type JWK_AES_GCM, type JWK_AES_GCM_KW, type JWK_AES_KW, type JWK_Asymmetric, type JWK_Asymmetric_Algorithm, type JWK_EC, type JWK_ECDH_ES, type JWK_ECDSA, type JWK_EC_Private, type JWK_EC_Public, type JWK_HMAC, type JWK_OKP, type JWK_OKP_Private, type JWK_OKP_Public, type JWK_OKP_SIGN, type JWK_PBES2, type JWK_Pair, type JWK_Private, type JWK_Public, type JWK_RSA, type JWK_RSA_ENC, type JWK_RSA_PSS, type JWK_RSA_Private, type JWK_RSA_Public, type JWK_RSA_SIGN, type JWK_Symmetric, type JWK_Symmetric_Algorithm, type JWK_oct, type JWSAlgorithm, type JWSAsymmetricPrivateJWK, type JWSAsymmetricPublicJWK, type JWSFlattenedSerialization, type JWSGeneralSerialization, type JWSGeneralSignature, type JWSHeaderParameters, type JWSMultiSignOptions, type JWSMultiSigner, type JWSMultiVerifyAllOptions, type JWSMultiVerifyOptions, type JWSMultiVerifyOutcome, type JWSMultiVerifyResult, type JWSProtectedHeader, type JWSSignJWK, type JWSSignOptions, type JWSVerifyJWK, type JWSVerifyOptions, type JWSVerifyResult, type JWT, type JWTClaimValidationOptions, type JWTClaims, type JoseHeaderParameters, type KeyManagementAlgorithm, type MaxTokenAge, type NotBeforeIn, type SessionClaims, type SessionConfigJWE, type SessionConfigJWS, type SessionData, type SessionHooksJWE, type SessionHooksJWS, type SessionJWE, type SessionJWS, type SessionManager, type SessionUpdate, type UnwrapKeyOptions, type UnwrappingKeyFor, type WrapKeyOptions, type WrapKeyResult, type WrappingKeyFor, clearJWESession, clearJWSSession, deriveJWKFromPassword, exportPEM, exportToPEM, generateJWK, getJWESession, getJWESessionToken, getJWSSession, getJWSSessionToken, importFromPEM, importPEM, sealJWESession, signJWSSession, unsealJWESession, updateJWESession, updateJWSSession, useJWESession, useJWSSession, verifyJWSSession };
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
1
|
+
import { JWTError, computeDurationInSeconds, isJWTError, isPrivateJWK, isPublicJWK, isSymmetricJWK } from "../../_chunks/utils.mjs";
|
|
2
|
+
import { sanitizeObjectCopy } from "../../_chunks/libs/unsecure.mjs";
|
|
3
|
+
import { deriveJWKFromPassword, exportPEM, exportToPEM, generateJWK, importFromPEM, importPEM } from "../../_chunks/jwk.mjs";
|
|
4
|
+
import { sign, verify } from "../../_chunks/jws.mjs";
|
|
5
|
+
import { decrypt, encrypt } from "../../_chunks/jwe.mjs";
|
|
5
6
|
import { isEvent, setCookie } from "h3";
|
|
6
7
|
import { parse } from "cookie-es";
|
|
7
8
|
const kGetSessionPromise$1 = Symbol("h3_jwe_getSession");
|
|
@@ -172,11 +173,11 @@ async function updateJWESession(event, config, update) {
|
|
|
172
173
|
if (config.cookie !== false && !canWriteCookie) throw new Error("[unjwt/h3] Cannot update session on read-only event.");
|
|
173
174
|
const sessionName = config.name || DEFAULT_NAME$1;
|
|
174
175
|
const session = event.context.sessions?.[sessionName] || await getJWESession(event, config);
|
|
175
|
-
if (typeof update === "function") update = update(session.data);
|
|
176
176
|
const oldSession = {
|
|
177
177
|
...session,
|
|
178
|
-
data:
|
|
178
|
+
data: sanitizeObjectCopy(session.data)
|
|
179
179
|
};
|
|
180
|
+
if (typeof update === "function") update = update(session.data);
|
|
180
181
|
if (update) Object.assign(session.data, update);
|
|
181
182
|
const now = config.jwe?.encryptOptions?.currentDate?.getTime() ?? Date.now();
|
|
182
183
|
const createdAt = now - now % 1e3;
|
|
@@ -192,7 +193,8 @@ async function updateJWESession(event, config, update) {
|
|
|
192
193
|
Object.assign(session, {
|
|
193
194
|
id: oldSession.id,
|
|
194
195
|
createdAt: oldSession.createdAt,
|
|
195
|
-
expiresAt: oldSession.expiresAt
|
|
196
|
+
expiresAt: oldSession.expiresAt,
|
|
197
|
+
data: oldSession.data
|
|
196
198
|
});
|
|
197
199
|
session.token = oldSession.token;
|
|
198
200
|
await config.hooks?.onError?.({
|
|
@@ -288,7 +290,7 @@ async function clearJWESession(event, config) {
|
|
|
288
290
|
if (session && session[kGetSessionPromise$1]) session = await session[kGetSessionPromise$1];
|
|
289
291
|
const oldSession = session ? {
|
|
290
292
|
...session,
|
|
291
|
-
data:
|
|
293
|
+
data: sanitizeObjectCopy(session.data)
|
|
292
294
|
} : void 0;
|
|
293
295
|
if (event.context.sessions?.[sessionName]) delete event.context.sessions[sessionName];
|
|
294
296
|
if (config.cookie !== false && canWriteCookie) setCookie(event, sessionName, "", {
|
|
@@ -495,11 +497,11 @@ async function updateJWSSession(event, config, update) {
|
|
|
495
497
|
if (config.cookie !== false && !canWriteCookie) throw new Error("[unjwt/h3] Cannot update session on read-only event.");
|
|
496
498
|
const sessionName = config.name || DEFAULT_NAME;
|
|
497
499
|
const session = event.context.sessions?.[sessionName] || await getJWSSession(event, config);
|
|
498
|
-
if (typeof update === "function") update = update(session.data);
|
|
499
500
|
const oldSession = {
|
|
500
501
|
...session,
|
|
501
|
-
data:
|
|
502
|
+
data: sanitizeObjectCopy(session.data)
|
|
502
503
|
};
|
|
504
|
+
if (typeof update === "function") update = update(session.data);
|
|
503
505
|
if (update) Object.assign(session.data, update);
|
|
504
506
|
const now = config.jws?.signOptions?.currentDate?.getTime() ?? Date.now();
|
|
505
507
|
const createdAt = now - now % 1e3;
|
|
@@ -515,7 +517,8 @@ async function updateJWSSession(event, config, update) {
|
|
|
515
517
|
Object.assign(session, {
|
|
516
518
|
id: oldSession.id,
|
|
517
519
|
createdAt: oldSession.createdAt,
|
|
518
|
-
expiresAt: oldSession.expiresAt
|
|
520
|
+
expiresAt: oldSession.expiresAt,
|
|
521
|
+
data: oldSession.data
|
|
519
522
|
});
|
|
520
523
|
session.token = oldSession.token;
|
|
521
524
|
await config.hooks?.onError?.({
|
|
@@ -606,7 +609,7 @@ async function clearJWSSession(event, config) {
|
|
|
606
609
|
if (session && session[kGetSessionPromise]) session = await session[kGetSessionPromise];
|
|
607
610
|
const oldSession = session ? {
|
|
608
611
|
...session,
|
|
609
|
-
data:
|
|
612
|
+
data: sanitizeObjectCopy(session.data)
|
|
610
613
|
} : void 0;
|
|
611
614
|
if (event.context.sessions?.[sessionName]) delete event.context.sessions[sessionName];
|
|
612
615
|
if (config.cookie !== false && canWriteCookie) setCookie(event, sessionName, "", {
|
|
@@ -646,4 +649,4 @@ function findSetCookie(setCookie, name) {
|
|
|
646
649
|
const match = setCookie.match(regex);
|
|
647
650
|
return match ? match[1] : void 0;
|
|
648
651
|
}
|
|
649
|
-
export { clearJWESession, clearJWSSession, deriveJWKFromPassword, exportPEM, exportToPEM, generateJWK, getJWESession, getJWESessionToken, getJWSSession, importFromPEM, importPEM, sealJWESession, signJWSSession, unsealJWESession, updateJWESession, updateJWSSession, useJWESession, useJWSSession, verifyJWSSession };
|
|
652
|
+
export { clearJWESession, clearJWSSession, deriveJWKFromPassword, exportPEM, exportToPEM, generateJWK, getJWESession, getJWESessionToken, getJWSSession, getJWSSessionToken, importFromPEM, importPEM, sealJWESession, signJWSSession, unsealJWESession, updateJWESession, updateJWSSession, useJWESession, useJWSSession, verifyJWSSession };
|