@parsrun/auth 0.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 +133 -0
- package/dist/adapters/hono.d.ts +9 -0
- package/dist/adapters/hono.js +6 -0
- package/dist/adapters/hono.js.map +1 -0
- package/dist/adapters/index.d.ts +9 -0
- package/dist/adapters/index.js +7 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/authorization-By1Xp8Za.d.ts +213 -0
- package/dist/base-BKyR8rcE.d.ts +646 -0
- package/dist/chunk-42MGHABB.js +263 -0
- package/dist/chunk-42MGHABB.js.map +1 -0
- package/dist/chunk-7GOBAL4G.js +3 -0
- package/dist/chunk-7GOBAL4G.js.map +1 -0
- package/dist/chunk-G5I3T73A.js +152 -0
- package/dist/chunk-G5I3T73A.js.map +1 -0
- package/dist/chunk-IB4WUQDZ.js +410 -0
- package/dist/chunk-IB4WUQDZ.js.map +1 -0
- package/dist/chunk-MOG4Y6I7.js +415 -0
- package/dist/chunk-MOG4Y6I7.js.map +1 -0
- package/dist/chunk-NK4TJV2W.js +295 -0
- package/dist/chunk-NK4TJV2W.js.map +1 -0
- package/dist/chunk-RHNVRCF3.js +838 -0
- package/dist/chunk-RHNVRCF3.js.map +1 -0
- package/dist/chunk-YTCPXJR5.js +570 -0
- package/dist/chunk-YTCPXJR5.js.map +1 -0
- package/dist/cloudflare-kv-L64CZKDK.js +105 -0
- package/dist/cloudflare-kv-L64CZKDK.js.map +1 -0
- package/dist/deno-kv-F55HKKP6.js +111 -0
- package/dist/deno-kv-F55HKKP6.js.map +1 -0
- package/dist/index-C3kz9XqE.d.ts +226 -0
- package/dist/index-DOGcetyD.d.ts +1041 -0
- package/dist/index.d.ts +1579 -0
- package/dist/index.js +4294 -0
- package/dist/index.js.map +1 -0
- package/dist/jwt-manager-CH8H0kmm.d.ts +182 -0
- package/dist/providers/index.d.ts +90 -0
- package/dist/providers/index.js +3 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/providers/otp/index.d.ts +3 -0
- package/dist/providers/otp/index.js +4 -0
- package/dist/providers/otp/index.js.map +1 -0
- package/dist/redis-5TIS6XCA.js +121 -0
- package/dist/redis-5TIS6XCA.js.map +1 -0
- package/dist/security/index.d.ts +301 -0
- package/dist/security/index.js +5 -0
- package/dist/security/index.js.map +1 -0
- package/dist/session/index.d.ts +117 -0
- package/dist/session/index.js +4 -0
- package/dist/session/index.js.map +1 -0
- package/dist/storage/index.d.ts +97 -0
- package/dist/storage/index.js +3 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/types-DSjafxJ4.d.ts +193 -0
- package/package.json +102 -0
|
@@ -0,0 +1,415 @@
|
|
|
1
|
+
import { StorageKeys } from './chunk-42MGHABB.js';
|
|
2
|
+
import * as jose from 'jose';
|
|
3
|
+
|
|
4
|
+
function parseDuration(duration) {
|
|
5
|
+
const match = duration.match(/^(\d+)(s|m|h|d|w)$/);
|
|
6
|
+
if (!match) {
|
|
7
|
+
throw new Error(`Invalid duration format: ${duration}. Use format like '15m', '1h', '7d'`);
|
|
8
|
+
}
|
|
9
|
+
const value = parseInt(match[1], 10);
|
|
10
|
+
const unit = match[2];
|
|
11
|
+
switch (unit) {
|
|
12
|
+
case "s":
|
|
13
|
+
return value;
|
|
14
|
+
case "m":
|
|
15
|
+
return value * 60;
|
|
16
|
+
case "h":
|
|
17
|
+
return value * 60 * 60;
|
|
18
|
+
case "d":
|
|
19
|
+
return value * 60 * 60 * 24;
|
|
20
|
+
case "w":
|
|
21
|
+
return value * 60 * 60 * 24 * 7;
|
|
22
|
+
default:
|
|
23
|
+
throw new Error(`Unknown duration unit: ${unit}`);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
var DEFAULT_CONFIG = {
|
|
27
|
+
accessTokenTTL: "15m",
|
|
28
|
+
refreshTokenTTL: "7d",
|
|
29
|
+
keyVersion: 1
|
|
30
|
+
};
|
|
31
|
+
var JwtManager = class {
|
|
32
|
+
secret;
|
|
33
|
+
previousSecrets;
|
|
34
|
+
config;
|
|
35
|
+
keyVersion;
|
|
36
|
+
constructor(config) {
|
|
37
|
+
this.config = {
|
|
38
|
+
accessTokenTTL: DEFAULT_CONFIG.accessTokenTTL,
|
|
39
|
+
refreshTokenTTL: DEFAULT_CONFIG.refreshTokenTTL,
|
|
40
|
+
previousSecrets: [],
|
|
41
|
+
keyVersion: DEFAULT_CONFIG.keyVersion,
|
|
42
|
+
...config
|
|
43
|
+
};
|
|
44
|
+
this.secret = new TextEncoder().encode(config.secret);
|
|
45
|
+
this.keyVersion = this.config.keyVersion;
|
|
46
|
+
this.previousSecrets = this.config.previousSecrets.map(
|
|
47
|
+
(s) => new TextEncoder().encode(s)
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Get current key version
|
|
52
|
+
*/
|
|
53
|
+
getKeyVersion() {
|
|
54
|
+
return this.keyVersion;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Rotate the signing key
|
|
58
|
+
* Moves current secret to previousSecrets and sets new secret
|
|
59
|
+
*/
|
|
60
|
+
rotateKey(newSecret, options) {
|
|
61
|
+
const maxPrevious = options?.maxPreviousSecrets ?? 2;
|
|
62
|
+
const previousSecret = this.config.secret;
|
|
63
|
+
this.previousSecrets.unshift(this.secret);
|
|
64
|
+
if (this.previousSecrets.length > maxPrevious) {
|
|
65
|
+
this.previousSecrets = this.previousSecrets.slice(0, maxPrevious);
|
|
66
|
+
}
|
|
67
|
+
this.secret = new TextEncoder().encode(newSecret);
|
|
68
|
+
this.config.secret = newSecret;
|
|
69
|
+
this.keyVersion++;
|
|
70
|
+
this.config.previousSecrets = [
|
|
71
|
+
previousSecret,
|
|
72
|
+
...this.config.previousSecrets.slice(0, maxPrevious - 1)
|
|
73
|
+
];
|
|
74
|
+
this.config.keyVersion = this.keyVersion;
|
|
75
|
+
return {
|
|
76
|
+
previousSecret,
|
|
77
|
+
newSecret,
|
|
78
|
+
keyVersion: this.keyVersion,
|
|
79
|
+
rotatedAt: /* @__PURE__ */ new Date()
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Get current configuration (for persistence)
|
|
84
|
+
*/
|
|
85
|
+
getConfig() {
|
|
86
|
+
return { ...this.config };
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Generate access token
|
|
90
|
+
*/
|
|
91
|
+
async generateAccessToken(payload) {
|
|
92
|
+
const ttlSeconds = parseDuration(this.config.accessTokenTTL);
|
|
93
|
+
const expiresAt = new Date(Date.now() + ttlSeconds * 1e3);
|
|
94
|
+
const jwt = new jose.SignJWT({
|
|
95
|
+
sub: payload.userId,
|
|
96
|
+
...payload.tenantId && { tid: payload.tenantId },
|
|
97
|
+
...payload.sessionId && { sid: payload.sessionId },
|
|
98
|
+
roles: payload.roles ?? [],
|
|
99
|
+
permissions: payload.permissions ?? [],
|
|
100
|
+
...payload.claims
|
|
101
|
+
}).setProtectedHeader({ alg: "HS256", kid: `v${this.keyVersion}` }).setIssuedAt().setExpirationTime(expiresAt).setIssuer(this.config.issuer).setAudience(this.config.audience);
|
|
102
|
+
const token = await jwt.sign(this.secret);
|
|
103
|
+
return { token, expiresAt };
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Generate refresh token
|
|
107
|
+
*/
|
|
108
|
+
async generateRefreshToken(payload) {
|
|
109
|
+
const ttlSeconds = parseDuration(this.config.refreshTokenTTL);
|
|
110
|
+
const expiresAt = new Date(Date.now() + ttlSeconds * 1e3);
|
|
111
|
+
const jwt = new jose.SignJWT({
|
|
112
|
+
sub: payload.userId,
|
|
113
|
+
...payload.tenantId && { tid: payload.tenantId },
|
|
114
|
+
...payload.sessionId && { sid: payload.sessionId },
|
|
115
|
+
type: "refresh"
|
|
116
|
+
}).setProtectedHeader({ alg: "HS256", kid: `v${this.keyVersion}` }).setIssuedAt().setExpirationTime(expiresAt).setIssuer(this.config.issuer).setAudience(this.config.audience);
|
|
117
|
+
const token = await jwt.sign(this.secret);
|
|
118
|
+
return { token, expiresAt };
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Generate token pair (access + refresh)
|
|
122
|
+
*/
|
|
123
|
+
async generateTokenPair(payload) {
|
|
124
|
+
const [access, refresh] = await Promise.all([
|
|
125
|
+
this.generateAccessToken(payload),
|
|
126
|
+
this.generateRefreshToken(payload)
|
|
127
|
+
]);
|
|
128
|
+
return {
|
|
129
|
+
accessToken: access.token,
|
|
130
|
+
refreshToken: refresh.token,
|
|
131
|
+
accessExpiresAt: access.expiresAt,
|
|
132
|
+
refreshExpiresAt: refresh.expiresAt
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Verify access token
|
|
137
|
+
* Tries current secret first, then falls back to previous secrets for graceful rotation
|
|
138
|
+
*/
|
|
139
|
+
async verifyAccessToken(token) {
|
|
140
|
+
const secrets = [this.secret, ...this.previousSecrets];
|
|
141
|
+
for (let i = 0; i < secrets.length; i++) {
|
|
142
|
+
const secret = secrets[i];
|
|
143
|
+
if (!secret) continue;
|
|
144
|
+
try {
|
|
145
|
+
const { payload } = await jose.jwtVerify(token, secret, {
|
|
146
|
+
issuer: this.config.issuer,
|
|
147
|
+
audience: this.config.audience
|
|
148
|
+
});
|
|
149
|
+
return {
|
|
150
|
+
sub: payload.sub,
|
|
151
|
+
tid: payload["tid"],
|
|
152
|
+
sid: payload["sid"],
|
|
153
|
+
iat: payload.iat,
|
|
154
|
+
exp: payload.exp,
|
|
155
|
+
iss: payload.iss,
|
|
156
|
+
aud: payload.aud,
|
|
157
|
+
roles: payload["roles"] ?? [],
|
|
158
|
+
permissions: payload["permissions"] ?? []
|
|
159
|
+
};
|
|
160
|
+
} catch (error) {
|
|
161
|
+
if (error instanceof jose.errors.JWTExpired) {
|
|
162
|
+
throw new JwtError("Access token expired", "TOKEN_EXPIRED");
|
|
163
|
+
}
|
|
164
|
+
if (i === secrets.length - 1) {
|
|
165
|
+
if (error instanceof jose.errors.JWTInvalid) {
|
|
166
|
+
throw new JwtError("Invalid access token", "INVALID_TOKEN");
|
|
167
|
+
}
|
|
168
|
+
throw new JwtError("Token verification failed", "VERIFICATION_FAILED");
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
throw new JwtError("Token verification failed", "VERIFICATION_FAILED");
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Verify refresh token
|
|
176
|
+
*/
|
|
177
|
+
async verifyRefreshToken(token) {
|
|
178
|
+
const secrets = [this.secret, ...this.previousSecrets];
|
|
179
|
+
for (let i = 0; i < secrets.length; i++) {
|
|
180
|
+
const secret = secrets[i];
|
|
181
|
+
if (!secret) continue;
|
|
182
|
+
try {
|
|
183
|
+
const { payload } = await jose.jwtVerify(token, secret, {
|
|
184
|
+
issuer: this.config.issuer,
|
|
185
|
+
audience: this.config.audience
|
|
186
|
+
});
|
|
187
|
+
if (payload["type"] !== "refresh") {
|
|
188
|
+
throw new JwtError("Invalid token type", "INVALID_TOKEN_TYPE");
|
|
189
|
+
}
|
|
190
|
+
return {
|
|
191
|
+
userId: payload.sub,
|
|
192
|
+
tenantId: payload["tid"],
|
|
193
|
+
sessionId: payload["sid"]
|
|
194
|
+
};
|
|
195
|
+
} catch (error) {
|
|
196
|
+
if (error instanceof jose.errors.JWTExpired) {
|
|
197
|
+
throw new JwtError("Refresh token expired", "TOKEN_EXPIRED");
|
|
198
|
+
}
|
|
199
|
+
if (error instanceof JwtError) {
|
|
200
|
+
throw error;
|
|
201
|
+
}
|
|
202
|
+
if (i === secrets.length - 1) {
|
|
203
|
+
if (error instanceof jose.errors.JWTInvalid) {
|
|
204
|
+
throw new JwtError("Invalid refresh token", "INVALID_TOKEN");
|
|
205
|
+
}
|
|
206
|
+
throw new JwtError("Token verification failed", "VERIFICATION_FAILED");
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
throw new JwtError("Token verification failed", "VERIFICATION_FAILED");
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Decode token without verification (for inspection)
|
|
214
|
+
*/
|
|
215
|
+
decodeToken(token) {
|
|
216
|
+
try {
|
|
217
|
+
return jose.decodeJwt(token);
|
|
218
|
+
} catch {
|
|
219
|
+
return null;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Check if token is expired (without signature verification)
|
|
224
|
+
*/
|
|
225
|
+
isTokenExpired(token) {
|
|
226
|
+
const payload = this.decodeToken(token);
|
|
227
|
+
if (!payload?.exp) return true;
|
|
228
|
+
return payload.exp * 1e3 < Date.now();
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Get token expiration date (without signature verification)
|
|
232
|
+
*/
|
|
233
|
+
getTokenExpiration(token) {
|
|
234
|
+
const payload = this.decodeToken(token);
|
|
235
|
+
if (!payload?.exp) return null;
|
|
236
|
+
return new Date(payload.exp * 1e3);
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Get time until token expires in seconds
|
|
240
|
+
*/
|
|
241
|
+
getTokenTTL(token) {
|
|
242
|
+
const exp = this.getTokenExpiration(token);
|
|
243
|
+
if (!exp) return 0;
|
|
244
|
+
return Math.max(0, Math.floor((exp.getTime() - Date.now()) / 1e3));
|
|
245
|
+
}
|
|
246
|
+
};
|
|
247
|
+
var JwtError = class extends Error {
|
|
248
|
+
constructor(message, code) {
|
|
249
|
+
super(message);
|
|
250
|
+
this.code = code;
|
|
251
|
+
this.name = "JwtError";
|
|
252
|
+
}
|
|
253
|
+
};
|
|
254
|
+
function extractBearerToken(authHeader) {
|
|
255
|
+
if (!authHeader) return null;
|
|
256
|
+
const parts = authHeader.split(" ");
|
|
257
|
+
if (parts.length !== 2 || parts[0] !== "Bearer") return null;
|
|
258
|
+
return parts[1] ?? null;
|
|
259
|
+
}
|
|
260
|
+
function createJwtManager(config) {
|
|
261
|
+
return new JwtManager(config);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// src/session/blocklist.ts
|
|
265
|
+
var SessionBlocklist = class {
|
|
266
|
+
storage;
|
|
267
|
+
constructor(storage, _config) {
|
|
268
|
+
this.storage = storage;
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Get storage key for blocklist entry
|
|
272
|
+
*/
|
|
273
|
+
getKey(sessionId) {
|
|
274
|
+
return StorageKeys.blocklist(sessionId);
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Block a session (revoke it)
|
|
278
|
+
*/
|
|
279
|
+
async blockSession(sessionId, expiresAt, options) {
|
|
280
|
+
const ttlMs = expiresAt.getTime() - Date.now();
|
|
281
|
+
if (ttlMs <= 0) return;
|
|
282
|
+
const ttlSeconds = Math.ceil(ttlMs / 1e3);
|
|
283
|
+
const key = this.getKey(sessionId);
|
|
284
|
+
const entry = {
|
|
285
|
+
id: sessionId,
|
|
286
|
+
expiresAt: expiresAt.toISOString(),
|
|
287
|
+
reason: options?.reason,
|
|
288
|
+
blockedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
289
|
+
userId: options?.userId
|
|
290
|
+
};
|
|
291
|
+
await this.storage.set(key, entry, ttlSeconds);
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Check if a session is blocked
|
|
295
|
+
*/
|
|
296
|
+
async isBlocked(sessionId) {
|
|
297
|
+
const key = this.getKey(sessionId);
|
|
298
|
+
const entry = await this.storage.get(key);
|
|
299
|
+
if (!entry) return false;
|
|
300
|
+
if (new Date(entry.expiresAt) < /* @__PURE__ */ new Date()) {
|
|
301
|
+
await this.storage.delete(key);
|
|
302
|
+
return false;
|
|
303
|
+
}
|
|
304
|
+
return true;
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Get blocklist entry details
|
|
308
|
+
*/
|
|
309
|
+
async getEntry(sessionId) {
|
|
310
|
+
const key = this.getKey(sessionId);
|
|
311
|
+
return this.storage.get(key);
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* Unblock a session (if needed)
|
|
315
|
+
*/
|
|
316
|
+
async unblockSession(sessionId) {
|
|
317
|
+
const key = this.getKey(sessionId);
|
|
318
|
+
await this.storage.delete(key);
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* Block multiple sessions (logout all devices)
|
|
322
|
+
*/
|
|
323
|
+
async blockMultipleSessions(sessions) {
|
|
324
|
+
await Promise.all(
|
|
325
|
+
sessions.map(
|
|
326
|
+
(s) => this.blockSession(s.id, s.expiresAt, {
|
|
327
|
+
reason: s.reason,
|
|
328
|
+
userId: s.userId
|
|
329
|
+
})
|
|
330
|
+
)
|
|
331
|
+
);
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Block all sessions for a user
|
|
335
|
+
* Requires session IDs to be provided (from session store)
|
|
336
|
+
*/
|
|
337
|
+
async blockAllUserSessions(userId, sessionIds, tokenExpiresAt, reason = "User logout all") {
|
|
338
|
+
await this.blockMultipleSessions(
|
|
339
|
+
sessionIds.map((id) => ({
|
|
340
|
+
id,
|
|
341
|
+
expiresAt: tokenExpiresAt,
|
|
342
|
+
reason,
|
|
343
|
+
userId
|
|
344
|
+
}))
|
|
345
|
+
);
|
|
346
|
+
}
|
|
347
|
+
};
|
|
348
|
+
var TokenBlocklist = class {
|
|
349
|
+
storage;
|
|
350
|
+
constructor(storage) {
|
|
351
|
+
this.storage = storage;
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* Get storage key for token blocklist entry
|
|
355
|
+
*/
|
|
356
|
+
getKey(tokenHash) {
|
|
357
|
+
return `blocklist:token:${tokenHash}`;
|
|
358
|
+
}
|
|
359
|
+
/**
|
|
360
|
+
* Hash a token for storage (don't store raw tokens)
|
|
361
|
+
*/
|
|
362
|
+
async hashToken(token) {
|
|
363
|
+
const encoder = new TextEncoder();
|
|
364
|
+
const data = encoder.encode(token);
|
|
365
|
+
const hashBuffer = await crypto.subtle.digest("SHA-256", data);
|
|
366
|
+
const hashArray = Array.from(new Uint8Array(hashBuffer));
|
|
367
|
+
return hashArray.map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
368
|
+
}
|
|
369
|
+
/**
|
|
370
|
+
* Block a token
|
|
371
|
+
*/
|
|
372
|
+
async blockToken(token, expiresAt, reason) {
|
|
373
|
+
const ttlMs = expiresAt.getTime() - Date.now();
|
|
374
|
+
if (ttlMs <= 0) return;
|
|
375
|
+
const ttlSeconds = Math.ceil(ttlMs / 1e3);
|
|
376
|
+
const hash = await this.hashToken(token);
|
|
377
|
+
const key = this.getKey(hash);
|
|
378
|
+
await this.storage.set(
|
|
379
|
+
key,
|
|
380
|
+
{
|
|
381
|
+
hash,
|
|
382
|
+
expiresAt: expiresAt.toISOString(),
|
|
383
|
+
reason,
|
|
384
|
+
blockedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
385
|
+
},
|
|
386
|
+
ttlSeconds
|
|
387
|
+
);
|
|
388
|
+
}
|
|
389
|
+
/**
|
|
390
|
+
* Check if a token is blocked
|
|
391
|
+
*/
|
|
392
|
+
async isBlocked(token) {
|
|
393
|
+
const hash = await this.hashToken(token);
|
|
394
|
+
const key = this.getKey(hash);
|
|
395
|
+
return this.storage.has(key);
|
|
396
|
+
}
|
|
397
|
+
/**
|
|
398
|
+
* Unblock a token
|
|
399
|
+
*/
|
|
400
|
+
async unblockToken(token) {
|
|
401
|
+
const hash = await this.hashToken(token);
|
|
402
|
+
const key = this.getKey(hash);
|
|
403
|
+
await this.storage.delete(key);
|
|
404
|
+
}
|
|
405
|
+
};
|
|
406
|
+
function createSessionBlocklist(storage, config) {
|
|
407
|
+
return new SessionBlocklist(storage, config);
|
|
408
|
+
}
|
|
409
|
+
function createTokenBlocklist(storage) {
|
|
410
|
+
return new TokenBlocklist(storage);
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
export { JwtError, JwtManager, SessionBlocklist, TokenBlocklist, createJwtManager, createSessionBlocklist, createTokenBlocklist, extractBearerToken, parseDuration };
|
|
414
|
+
//# sourceMappingURL=chunk-MOG4Y6I7.js.map
|
|
415
|
+
//# sourceMappingURL=chunk-MOG4Y6I7.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/session/jwt-manager.ts","../src/session/blocklist.ts"],"names":[],"mappings":"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","file":"chunk-MOG4Y6I7.js","sourcesContent":["/**\n * JWT Manager with Key Rotation Support\n * Uses jose library for multi-runtime compatibility (Node, Deno, CF Workers, Bun)\n */\n\nimport * as jose from 'jose';\n\n/**\n * JWT configuration\n */\nexport interface JwtConfig {\n /** Secret key for signing tokens */\n secret: string;\n /** Token issuer */\n issuer: string;\n /** Token audience */\n audience: string;\n /** Access token TTL (e.g., '15m', '1h') */\n accessTokenTTL?: string;\n /** Refresh token TTL (e.g., '7d', '12h') */\n refreshTokenTTL?: string;\n /** Previous secrets for key rotation */\n previousSecrets?: string[];\n /** Current key version */\n keyVersion?: number;\n}\n\n/**\n * JWT payload structure\n */\nexport interface JwtPayload {\n /** User ID */\n sub: string;\n /** Tenant ID */\n tid?: string;\n /** Session ID */\n sid?: string;\n /** Issued at timestamp */\n iat: number;\n /** Expiration timestamp */\n exp: number;\n /** Issuer */\n iss: string;\n /** Audience */\n aud: string | string[];\n /** User roles */\n roles?: string[];\n /** User permissions */\n permissions?: string[];\n /** Additional claims */\n [key: string]: unknown;\n}\n\n/**\n * Token pair (access + refresh)\n */\nexport interface TokenPair {\n accessToken: string;\n refreshToken: string;\n accessExpiresAt: Date;\n refreshExpiresAt: Date;\n}\n\n/**\n * Key rotation result\n */\nexport interface KeyRotationResult {\n previousSecret: string;\n newSecret: string;\n keyVersion: number;\n rotatedAt: Date;\n}\n\n/**\n * Parse duration string to seconds\n * Supports: s (seconds), m (minutes), h (hours), d (days), w (weeks)\n */\nexport function parseDuration(duration: string): number {\n const match = duration.match(/^(\\d+)(s|m|h|d|w)$/);\n if (!match) {\n throw new Error(`Invalid duration format: ${duration}. Use format like '15m', '1h', '7d'`);\n }\n\n const value = parseInt(match[1]!, 10);\n const unit = match[2];\n\n switch (unit) {\n case 's':\n return value;\n case 'm':\n return value * 60;\n case 'h':\n return value * 60 * 60;\n case 'd':\n return value * 60 * 60 * 24;\n case 'w':\n return value * 60 * 60 * 24 * 7;\n default:\n throw new Error(`Unknown duration unit: ${unit}`);\n }\n}\n\n/**\n * Default JWT configuration\n */\nconst DEFAULT_CONFIG = {\n accessTokenTTL: '15m',\n refreshTokenTTL: '7d',\n keyVersion: 1,\n};\n\n/**\n * JWT Manager\n * Handles token generation, verification, and key rotation\n */\nexport class JwtManager {\n private secret: Uint8Array;\n private previousSecrets: Uint8Array[];\n private config: Required<JwtConfig>;\n private keyVersion: number;\n\n constructor(config: JwtConfig) {\n this.config = {\n accessTokenTTL: DEFAULT_CONFIG.accessTokenTTL,\n refreshTokenTTL: DEFAULT_CONFIG.refreshTokenTTL,\n previousSecrets: [],\n keyVersion: DEFAULT_CONFIG.keyVersion,\n ...config,\n } as Required<JwtConfig>;\n\n this.secret = new TextEncoder().encode(config.secret);\n this.keyVersion = this.config.keyVersion;\n this.previousSecrets = (this.config.previousSecrets).map(\n (s) => new TextEncoder().encode(s)\n );\n }\n\n /**\n * Get current key version\n */\n getKeyVersion(): number {\n return this.keyVersion;\n }\n\n /**\n * Rotate the signing key\n * Moves current secret to previousSecrets and sets new secret\n */\n rotateKey(\n newSecret: string,\n options?: { maxPreviousSecrets?: number }\n ): KeyRotationResult {\n const maxPrevious = options?.maxPreviousSecrets ?? 2;\n const previousSecret = this.config.secret;\n\n // Move current secret to previous secrets\n this.previousSecrets.unshift(this.secret);\n\n // Limit the number of previous secrets\n if (this.previousSecrets.length > maxPrevious) {\n this.previousSecrets = this.previousSecrets.slice(0, maxPrevious);\n }\n\n // Set new secret\n this.secret = new TextEncoder().encode(newSecret);\n this.config.secret = newSecret;\n this.keyVersion++;\n\n // Update config's previous secrets\n this.config.previousSecrets = [\n previousSecret,\n ...this.config.previousSecrets.slice(0, maxPrevious - 1),\n ];\n this.config.keyVersion = this.keyVersion;\n\n return {\n previousSecret,\n newSecret,\n keyVersion: this.keyVersion,\n rotatedAt: new Date(),\n };\n }\n\n /**\n * Get current configuration (for persistence)\n */\n getConfig(): JwtConfig {\n return { ...this.config };\n }\n\n /**\n * Generate access token\n */\n async generateAccessToken(payload: {\n userId: string;\n tenantId?: string;\n sessionId?: string;\n roles?: string[];\n permissions?: string[];\n claims?: Record<string, unknown>;\n }): Promise<{ token: string; expiresAt: Date }> {\n const ttlSeconds = parseDuration(this.config.accessTokenTTL);\n const expiresAt = new Date(Date.now() + ttlSeconds * 1000);\n\n const jwt = new jose.SignJWT({\n sub: payload.userId,\n ...(payload.tenantId && { tid: payload.tenantId }),\n ...(payload.sessionId && { sid: payload.sessionId }),\n roles: payload.roles ?? [],\n permissions: payload.permissions ?? [],\n ...payload.claims,\n })\n .setProtectedHeader({ alg: 'HS256', kid: `v${this.keyVersion}` })\n .setIssuedAt()\n .setExpirationTime(expiresAt)\n .setIssuer(this.config.issuer)\n .setAudience(this.config.audience);\n\n const token = await jwt.sign(this.secret);\n\n return { token, expiresAt };\n }\n\n /**\n * Generate refresh token\n */\n async generateRefreshToken(payload: {\n userId: string;\n tenantId?: string;\n sessionId?: string;\n }): Promise<{ token: string; expiresAt: Date }> {\n const ttlSeconds = parseDuration(this.config.refreshTokenTTL);\n const expiresAt = new Date(Date.now() + ttlSeconds * 1000);\n\n const jwt = new jose.SignJWT({\n sub: payload.userId,\n ...(payload.tenantId && { tid: payload.tenantId }),\n ...(payload.sessionId && { sid: payload.sessionId }),\n type: 'refresh',\n })\n .setProtectedHeader({ alg: 'HS256', kid: `v${this.keyVersion}` })\n .setIssuedAt()\n .setExpirationTime(expiresAt)\n .setIssuer(this.config.issuer)\n .setAudience(this.config.audience);\n\n const token = await jwt.sign(this.secret);\n\n return { token, expiresAt };\n }\n\n /**\n * Generate token pair (access + refresh)\n */\n async generateTokenPair(payload: {\n userId: string;\n tenantId?: string;\n sessionId?: string;\n roles?: string[];\n permissions?: string[];\n claims?: Record<string, unknown>;\n }): Promise<TokenPair> {\n const [access, refresh] = await Promise.all([\n this.generateAccessToken(payload),\n this.generateRefreshToken(payload),\n ]);\n\n return {\n accessToken: access.token,\n refreshToken: refresh.token,\n accessExpiresAt: access.expiresAt,\n refreshExpiresAt: refresh.expiresAt,\n };\n }\n\n /**\n * Verify access token\n * Tries current secret first, then falls back to previous secrets for graceful rotation\n */\n async verifyAccessToken(token: string): Promise<JwtPayload> {\n const secrets = [this.secret, ...this.previousSecrets];\n\n for (let i = 0; i < secrets.length; i++) {\n const secret = secrets[i];\n if (!secret) continue;\n\n try {\n const { payload } = await jose.jwtVerify(token, secret, {\n issuer: this.config.issuer,\n audience: this.config.audience,\n });\n\n return {\n sub: payload.sub as string,\n tid: payload['tid'] as string | undefined,\n sid: payload['sid'] as string | undefined,\n iat: payload.iat as number,\n exp: payload.exp as number,\n iss: payload.iss as string,\n aud: payload.aud as string | string[],\n roles: (payload['roles'] as string[]) ?? [],\n permissions: (payload['permissions'] as string[]) ?? [],\n };\n } catch (error) {\n // If it's an expiration error, don't try other secrets\n if (error instanceof jose.errors.JWTExpired) {\n throw new JwtError('Access token expired', 'TOKEN_EXPIRED');\n }\n // Try next secret on signature mismatch\n if (i === secrets.length - 1) {\n if (error instanceof jose.errors.JWTInvalid) {\n throw new JwtError('Invalid access token', 'INVALID_TOKEN');\n }\n throw new JwtError('Token verification failed', 'VERIFICATION_FAILED');\n }\n }\n }\n\n throw new JwtError('Token verification failed', 'VERIFICATION_FAILED');\n }\n\n /**\n * Verify refresh token\n */\n async verifyRefreshToken(token: string): Promise<{\n userId: string;\n tenantId?: string;\n sessionId?: string;\n }> {\n const secrets = [this.secret, ...this.previousSecrets];\n\n for (let i = 0; i < secrets.length; i++) {\n const secret = secrets[i];\n if (!secret) continue;\n\n try {\n const { payload } = await jose.jwtVerify(token, secret, {\n issuer: this.config.issuer,\n audience: this.config.audience,\n });\n\n if (payload['type'] !== 'refresh') {\n throw new JwtError('Invalid token type', 'INVALID_TOKEN_TYPE');\n }\n\n return {\n userId: payload.sub as string,\n tenantId: payload['tid'] as string | undefined,\n sessionId: payload['sid'] as string | undefined,\n };\n } catch (error) {\n if (error instanceof jose.errors.JWTExpired) {\n throw new JwtError('Refresh token expired', 'TOKEN_EXPIRED');\n }\n if (error instanceof JwtError) {\n throw error;\n }\n if (i === secrets.length - 1) {\n if (error instanceof jose.errors.JWTInvalid) {\n throw new JwtError('Invalid refresh token', 'INVALID_TOKEN');\n }\n throw new JwtError('Token verification failed', 'VERIFICATION_FAILED');\n }\n }\n }\n\n throw new JwtError('Token verification failed', 'VERIFICATION_FAILED');\n }\n\n /**\n * Decode token without verification (for inspection)\n */\n decodeToken(token: string): jose.JWTPayload | null {\n try {\n return jose.decodeJwt(token);\n } catch {\n return null;\n }\n }\n\n /**\n * Check if token is expired (without signature verification)\n */\n isTokenExpired(token: string): boolean {\n const payload = this.decodeToken(token);\n if (!payload?.exp) return true;\n return payload.exp * 1000 < Date.now();\n }\n\n /**\n * Get token expiration date (without signature verification)\n */\n getTokenExpiration(token: string): Date | null {\n const payload = this.decodeToken(token);\n if (!payload?.exp) return null;\n return new Date(payload.exp * 1000);\n }\n\n /**\n * Get time until token expires in seconds\n */\n getTokenTTL(token: string): number {\n const exp = this.getTokenExpiration(token);\n if (!exp) return 0;\n return Math.max(0, Math.floor((exp.getTime() - Date.now()) / 1000));\n }\n}\n\n/**\n * JWT Error class\n */\nexport class JwtError extends Error {\n constructor(\n message: string,\n public readonly code:\n | 'TOKEN_EXPIRED'\n | 'INVALID_TOKEN'\n | 'INVALID_TOKEN_TYPE'\n | 'VERIFICATION_FAILED'\n ) {\n super(message);\n this.name = 'JwtError';\n }\n}\n\n/**\n * Extract token from Authorization header\n */\nexport function extractBearerToken(\n authHeader: string | null | undefined\n): string | null {\n if (!authHeader) return null;\n const parts = authHeader.split(' ');\n if (parts.length !== 2 || parts[0] !== 'Bearer') return null;\n return parts[1] ?? null;\n}\n\n/**\n * Create a JwtManager instance\n */\nexport function createJwtManager(config: JwtConfig): JwtManager {\n return new JwtManager(config);\n}\n","/**\n * Session Blocklist\n * Uses KVStorage interface for multi-runtime support\n * Supports token/session revocation for logout\n */\n\nimport type { KVStorage } from '../storage/types.js';\nimport { StorageKeys } from '../storage/index.js';\n\n/**\n * Blocklist configuration\n */\nexport interface BlocklistConfig {\n /** Key prefix for blocked sessions */\n prefix?: string;\n /** Default TTL in seconds (should match max token lifetime) */\n defaultTTL?: number;\n}\n\n/**\n * Blocklist entry\n */\ninterface BlocklistEntry {\n /** Session or token ID */\n id: string;\n /** When the entry expires */\n expiresAt: string;\n /** Why was it blocked */\n reason?: string;\n /** When it was blocked */\n blockedAt: string;\n /** User ID (for audit) */\n userId?: string;\n}\n\n/**\n * Session Blocklist\n * Manages blocked/revoked sessions and tokens\n */\nexport class SessionBlocklist {\n private storage: KVStorage;\n\n constructor(storage: KVStorage, _config?: BlocklistConfig) {\n this.storage = storage;\n // Config is reserved for future use (custom prefix, TTL settings)\n }\n\n /**\n * Get storage key for blocklist entry\n */\n private getKey(sessionId: string): string {\n return StorageKeys.blocklist(sessionId);\n }\n\n /**\n * Block a session (revoke it)\n */\n async blockSession(\n sessionId: string,\n expiresAt: Date,\n options?: { reason?: string; userId?: string }\n ): Promise<void> {\n const ttlMs = expiresAt.getTime() - Date.now();\n if (ttlMs <= 0) return; // Already expired, no need to block\n\n const ttlSeconds = Math.ceil(ttlMs / 1000);\n const key = this.getKey(sessionId);\n\n const entry: BlocklistEntry = {\n id: sessionId,\n expiresAt: expiresAt.toISOString(),\n reason: options?.reason,\n blockedAt: new Date().toISOString(),\n userId: options?.userId,\n };\n\n await this.storage.set(key, entry, ttlSeconds);\n }\n\n /**\n * Check if a session is blocked\n */\n async isBlocked(sessionId: string): Promise<boolean> {\n const key = this.getKey(sessionId);\n const entry = await this.storage.get<BlocklistEntry>(key);\n\n if (!entry) return false;\n\n // Double-check expiration (storage should handle this, but be safe)\n if (new Date(entry.expiresAt) < new Date()) {\n await this.storage.delete(key);\n return false;\n }\n\n return true;\n }\n\n /**\n * Get blocklist entry details\n */\n async getEntry(sessionId: string): Promise<BlocklistEntry | null> {\n const key = this.getKey(sessionId);\n return this.storage.get<BlocklistEntry>(key);\n }\n\n /**\n * Unblock a session (if needed)\n */\n async unblockSession(sessionId: string): Promise<void> {\n const key = this.getKey(sessionId);\n await this.storage.delete(key);\n }\n\n /**\n * Block multiple sessions (logout all devices)\n */\n async blockMultipleSessions(\n sessions: Array<{\n id: string;\n expiresAt: Date;\n reason?: string;\n userId?: string;\n }>\n ): Promise<void> {\n await Promise.all(\n sessions.map((s) =>\n this.blockSession(s.id, s.expiresAt, {\n reason: s.reason,\n userId: s.userId,\n })\n )\n );\n }\n\n /**\n * Block all sessions for a user\n * Requires session IDs to be provided (from session store)\n */\n async blockAllUserSessions(\n userId: string,\n sessionIds: string[],\n tokenExpiresAt: Date,\n reason = 'User logout all'\n ): Promise<void> {\n await this.blockMultipleSessions(\n sessionIds.map((id) => ({\n id,\n expiresAt: tokenExpiresAt,\n reason,\n userId,\n }))\n );\n }\n}\n\n/**\n * Token Blocklist\n * For revoking individual tokens (separate from sessions)\n */\nexport class TokenBlocklist {\n private storage: KVStorage;\n\n constructor(storage: KVStorage) {\n this.storage = storage;\n }\n\n /**\n * Get storage key for token blocklist entry\n */\n private getKey(tokenHash: string): string {\n return `blocklist:token:${tokenHash}`;\n }\n\n /**\n * Hash a token for storage (don't store raw tokens)\n */\n private async hashToken(token: string): Promise<string> {\n const encoder = new TextEncoder();\n const data = encoder.encode(token);\n const hashBuffer = await crypto.subtle.digest('SHA-256', data);\n const hashArray = Array.from(new Uint8Array(hashBuffer));\n return hashArray.map((b) => b.toString(16).padStart(2, '0')).join('');\n }\n\n /**\n * Block a token\n */\n async blockToken(token: string, expiresAt: Date, reason?: string): Promise<void> {\n const ttlMs = expiresAt.getTime() - Date.now();\n if (ttlMs <= 0) return;\n\n const ttlSeconds = Math.ceil(ttlMs / 1000);\n const hash = await this.hashToken(token);\n const key = this.getKey(hash);\n\n await this.storage.set(\n key,\n {\n hash,\n expiresAt: expiresAt.toISOString(),\n reason,\n blockedAt: new Date().toISOString(),\n },\n ttlSeconds\n );\n }\n\n /**\n * Check if a token is blocked\n */\n async isBlocked(token: string): Promise<boolean> {\n const hash = await this.hashToken(token);\n const key = this.getKey(hash);\n return this.storage.has(key);\n }\n\n /**\n * Unblock a token\n */\n async unblockToken(token: string): Promise<void> {\n const hash = await this.hashToken(token);\n const key = this.getKey(hash);\n await this.storage.delete(key);\n }\n}\n\n/**\n * Create session blocklist\n */\nexport function createSessionBlocklist(\n storage: KVStorage,\n config?: BlocklistConfig\n): SessionBlocklist {\n return new SessionBlocklist(storage, config);\n}\n\n/**\n * Create token blocklist\n */\nexport function createTokenBlocklist(storage: KVStorage): TokenBlocklist {\n return new TokenBlocklist(storage);\n}\n"]}
|