@veloxts/auth 0.7.1 → 0.7.3
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/CHANGELOG.md +17 -0
- package/GUIDE.md +2 -2
- package/dist/jwt.js +1 -1
- package/dist/middleware.js +12 -31
- package/dist/plugin.d.ts +1 -2
- package/dist/rate-limit.js +2 -6
- package/dist/session.js +31 -77
- package/package.json +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
# @veloxts/auth
|
|
2
2
|
|
|
3
|
+
## 0.7.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- feat(cli): auto-populate Zod schemas from Prisma model fields
|
|
8
|
+
- Updated dependencies
|
|
9
|
+
- @veloxts/core@0.7.3
|
|
10
|
+
- @veloxts/router@0.7.3
|
|
11
|
+
|
|
12
|
+
## 0.7.2
|
|
13
|
+
|
|
14
|
+
### Patch Changes
|
|
15
|
+
|
|
16
|
+
- simplify code for clarity and maintainability
|
|
17
|
+
- Updated dependencies
|
|
18
|
+
- @veloxts/core@0.7.2
|
|
19
|
+
|
|
3
20
|
## 0.7.1
|
|
4
21
|
|
|
5
22
|
### Patch Changes
|
package/GUIDE.md
CHANGED
|
@@ -105,7 +105,7 @@ const UserSchema = resourceSchema()
|
|
|
105
105
|
const getPublicUser = procedure()
|
|
106
106
|
.query(async ({ input, ctx }) => {
|
|
107
107
|
const user = await ctx.db.user.findUnique({ where: { id: input.id } });
|
|
108
|
-
return resource(user, UserSchema
|
|
108
|
+
return resource(user, UserSchema.public);
|
|
109
109
|
});
|
|
110
110
|
|
|
111
111
|
// Authenticated - returns { id, name, email }
|
|
@@ -121,7 +121,7 @@ const getFullUser = procedure()
|
|
|
121
121
|
.guardNarrow(adminNarrow)
|
|
122
122
|
.query(async ({ input, ctx }) => {
|
|
123
123
|
const user = await ctx.db.user.findUnique({ where: { id: input.id } });
|
|
124
|
-
return resource(user, UserSchema
|
|
124
|
+
return resource(user, UserSchema.admin);
|
|
125
125
|
});
|
|
126
126
|
```
|
|
127
127
|
|
package/dist/jwt.js
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { createHmac, randomBytes, timingSafeEqual } from 'node:crypto';
|
|
6
6
|
import { createLogger } from '@veloxts/core';
|
|
7
|
-
const log = createLogger('auth');
|
|
8
7
|
import { AuthError } from './types.js';
|
|
8
|
+
const log = createLogger('auth');
|
|
9
9
|
// ============================================================================
|
|
10
10
|
// Constants
|
|
11
11
|
// ============================================================================
|
package/dist/middleware.js
CHANGED
|
@@ -6,6 +6,16 @@ import { executeGuards } from './guards.js';
|
|
|
6
6
|
import { JwtManager } from './jwt.js';
|
|
7
7
|
import { AuthError } from './types.js';
|
|
8
8
|
// ============================================================================
|
|
9
|
+
// Constants
|
|
10
|
+
// ============================================================================
|
|
11
|
+
const UNAUTHENTICATED_CONTEXT = {
|
|
12
|
+
authMode: 'native',
|
|
13
|
+
user: undefined,
|
|
14
|
+
token: undefined,
|
|
15
|
+
payload: undefined,
|
|
16
|
+
isAuthenticated: false,
|
|
17
|
+
};
|
|
18
|
+
// ============================================================================
|
|
9
19
|
// Auth Middleware Factory
|
|
10
20
|
// ============================================================================
|
|
11
21
|
/**
|
|
@@ -58,23 +68,10 @@ export function authMiddleware(config) {
|
|
|
58
68
|
// No token handling
|
|
59
69
|
if (!token) {
|
|
60
70
|
if (options.optional) {
|
|
61
|
-
// Optional auth - continue without user
|
|
62
|
-
const authContext = {
|
|
63
|
-
authMode: 'native',
|
|
64
|
-
user: undefined,
|
|
65
|
-
token: undefined,
|
|
66
|
-
payload: undefined,
|
|
67
|
-
isAuthenticated: false,
|
|
68
|
-
};
|
|
69
71
|
return next({
|
|
70
|
-
ctx: {
|
|
71
|
-
...ctx,
|
|
72
|
-
auth: authContext,
|
|
73
|
-
user: undefined,
|
|
74
|
-
},
|
|
72
|
+
ctx: { ...ctx, auth: UNAUTHENTICATED_CONTEXT, user: undefined },
|
|
75
73
|
});
|
|
76
74
|
}
|
|
77
|
-
// Required auth - reject
|
|
78
75
|
throw new AuthError('Authorization header required', 401);
|
|
79
76
|
}
|
|
80
77
|
// Verify token
|
|
@@ -84,20 +81,8 @@ export function authMiddleware(config) {
|
|
|
84
81
|
}
|
|
85
82
|
catch (error) {
|
|
86
83
|
if (options.optional) {
|
|
87
|
-
// Invalid token with optional auth - continue without user
|
|
88
|
-
const authContext = {
|
|
89
|
-
authMode: 'native',
|
|
90
|
-
user: undefined,
|
|
91
|
-
token: undefined,
|
|
92
|
-
payload: undefined,
|
|
93
|
-
isAuthenticated: false,
|
|
94
|
-
};
|
|
95
84
|
return next({
|
|
96
|
-
ctx: {
|
|
97
|
-
...ctx,
|
|
98
|
-
auth: authContext,
|
|
99
|
-
user: undefined,
|
|
100
|
-
},
|
|
85
|
+
ctx: { ...ctx, auth: UNAUTHENTICATED_CONTEXT, user: undefined },
|
|
101
86
|
});
|
|
102
87
|
}
|
|
103
88
|
throw new AuthError(error instanceof Error ? error.message : 'Invalid token', 401);
|
|
@@ -179,10 +164,6 @@ export function authMiddleware(config) {
|
|
|
179
164
|
};
|
|
180
165
|
}
|
|
181
166
|
// ============================================================================
|
|
182
|
-
// Error Helpers
|
|
183
|
-
// ============================================================================
|
|
184
|
-
// AuthError is now imported from types.ts
|
|
185
|
-
// ============================================================================
|
|
186
167
|
// Rate Limiting Middleware
|
|
187
168
|
// ============================================================================
|
|
188
169
|
/**
|
package/dist/plugin.d.ts
CHANGED
|
@@ -13,7 +13,7 @@ import type { JwtAdapterConfig } from './adapters/jwt-adapter.js';
|
|
|
13
13
|
import { PasswordHasher } from './hash.js';
|
|
14
14
|
import type { JwtManager, TokenStore } from './jwt.js';
|
|
15
15
|
import { authMiddleware } from './middleware.js';
|
|
16
|
-
import type { AdapterAuthContext, AuthConfig, JwtConfig, TokenPair, User } from './types.js';
|
|
16
|
+
import type { AdapterAuthContext, AuthConfig, AuthContext, JwtConfig, TokenPair, User } from './types.js';
|
|
17
17
|
/** Auth package version */
|
|
18
18
|
export declare const AUTH_VERSION: string;
|
|
19
19
|
/**
|
|
@@ -60,7 +60,6 @@ export interface AuthService {
|
|
|
60
60
|
*/
|
|
61
61
|
middleware: ReturnType<typeof authMiddleware>;
|
|
62
62
|
}
|
|
63
|
-
import type { AuthContext } from './types.js';
|
|
64
63
|
declare module 'fastify' {
|
|
65
64
|
interface FastifyInstance {
|
|
66
65
|
auth: AuthService;
|
package/dist/rate-limit.js
CHANGED
|
@@ -259,13 +259,9 @@ export function createAuthRateLimiter(config = {}) {
|
|
|
259
259
|
isLockedOut: (key, operation) => {
|
|
260
260
|
const fullKey = `auth:${operation}:${key}`;
|
|
261
261
|
const entry = authRateLimitStore.get(fullKey);
|
|
262
|
-
if (!entry
|
|
262
|
+
if (!entry?.lockoutUntil)
|
|
263
263
|
return false;
|
|
264
|
-
|
|
265
|
-
// Lockout expired
|
|
266
|
-
return false;
|
|
267
|
-
}
|
|
268
|
-
return true;
|
|
264
|
+
return entry.lockoutUntil > Date.now();
|
|
269
265
|
},
|
|
270
266
|
/**
|
|
271
267
|
* Get remaining attempts for a key
|
package/dist/session.js
CHANGED
|
@@ -214,8 +214,7 @@ export function sessionManager(config) {
|
|
|
214
214
|
modified = true;
|
|
215
215
|
},
|
|
216
216
|
getFlash(key) {
|
|
217
|
-
|
|
218
|
-
return value;
|
|
217
|
+
return currentData._flashOld?.[key];
|
|
219
218
|
},
|
|
220
219
|
getAllFlash() {
|
|
221
220
|
return currentData._flashOld ?? {};
|
|
@@ -400,6 +399,33 @@ export function sessionManager(config) {
|
|
|
400
399
|
};
|
|
401
400
|
}
|
|
402
401
|
// ============================================================================
|
|
402
|
+
// Session Helpers
|
|
403
|
+
// ============================================================================
|
|
404
|
+
/**
|
|
405
|
+
* Runs a middleware next() call with automatic session save on both success and error.
|
|
406
|
+
* Extracts the duplicated try/catch pattern from session middleware functions.
|
|
407
|
+
*/
|
|
408
|
+
async function withSessionSave(session, fn) {
|
|
409
|
+
try {
|
|
410
|
+
const result = await fn();
|
|
411
|
+
if (session.isModified && !session.isDestroyed) {
|
|
412
|
+
await session.save();
|
|
413
|
+
}
|
|
414
|
+
return result;
|
|
415
|
+
}
|
|
416
|
+
catch (error) {
|
|
417
|
+
if (session.isModified && !session.isDestroyed) {
|
|
418
|
+
try {
|
|
419
|
+
await session.save();
|
|
420
|
+
}
|
|
421
|
+
catch {
|
|
422
|
+
// Ignore save errors during error handling
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
throw error;
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
// ============================================================================
|
|
403
429
|
// Session Middleware Factory
|
|
404
430
|
// ============================================================================
|
|
405
431
|
/**
|
|
@@ -465,31 +491,7 @@ export function sessionMiddleware(config) {
|
|
|
465
491
|
}
|
|
466
492
|
// Attach to request for hooks
|
|
467
493
|
request.session = session;
|
|
468
|
-
|
|
469
|
-
const result = await next({
|
|
470
|
-
ctx: {
|
|
471
|
-
...ctx,
|
|
472
|
-
session,
|
|
473
|
-
},
|
|
474
|
-
});
|
|
475
|
-
// Auto-save session if modified
|
|
476
|
-
if (session.isModified && !session.isDestroyed) {
|
|
477
|
-
await session.save();
|
|
478
|
-
}
|
|
479
|
-
return result;
|
|
480
|
-
}
|
|
481
|
-
catch (error) {
|
|
482
|
-
// Still try to save session on error
|
|
483
|
-
if (session.isModified && !session.isDestroyed) {
|
|
484
|
-
try {
|
|
485
|
-
await session.save();
|
|
486
|
-
}
|
|
487
|
-
catch {
|
|
488
|
-
// Ignore save errors during error handling
|
|
489
|
-
}
|
|
490
|
-
}
|
|
491
|
-
throw error;
|
|
492
|
-
}
|
|
494
|
+
return withSessionSave(session, () => next({ ctx: { ...ctx, session } }));
|
|
493
495
|
};
|
|
494
496
|
}
|
|
495
497
|
/**
|
|
@@ -526,31 +528,7 @@ export function sessionMiddleware(config) {
|
|
|
526
528
|
};
|
|
527
529
|
}
|
|
528
530
|
request.session = session;
|
|
529
|
-
|
|
530
|
-
const result = await next({
|
|
531
|
-
ctx: {
|
|
532
|
-
...ctx,
|
|
533
|
-
session,
|
|
534
|
-
user,
|
|
535
|
-
isAuthenticated: true,
|
|
536
|
-
},
|
|
537
|
-
});
|
|
538
|
-
if (session.isModified && !session.isDestroyed) {
|
|
539
|
-
await session.save();
|
|
540
|
-
}
|
|
541
|
-
return result;
|
|
542
|
-
}
|
|
543
|
-
catch (error) {
|
|
544
|
-
if (session.isModified && !session.isDestroyed) {
|
|
545
|
-
try {
|
|
546
|
-
await session.save();
|
|
547
|
-
}
|
|
548
|
-
catch {
|
|
549
|
-
// Ignore
|
|
550
|
-
}
|
|
551
|
-
}
|
|
552
|
-
throw error;
|
|
553
|
-
}
|
|
531
|
+
return withSessionSave(session, () => next({ ctx: { ...ctx, session, user, isAuthenticated: true } }));
|
|
554
532
|
};
|
|
555
533
|
}
|
|
556
534
|
/**
|
|
@@ -583,31 +561,7 @@ export function sessionMiddleware(config) {
|
|
|
583
561
|
}
|
|
584
562
|
}
|
|
585
563
|
request.session = session;
|
|
586
|
-
|
|
587
|
-
const result = await next({
|
|
588
|
-
ctx: {
|
|
589
|
-
...ctx,
|
|
590
|
-
session,
|
|
591
|
-
user,
|
|
592
|
-
isAuthenticated,
|
|
593
|
-
},
|
|
594
|
-
});
|
|
595
|
-
if (session.isModified && !session.isDestroyed) {
|
|
596
|
-
await session.save();
|
|
597
|
-
}
|
|
598
|
-
return result;
|
|
599
|
-
}
|
|
600
|
-
catch (error) {
|
|
601
|
-
if (session.isModified && !session.isDestroyed) {
|
|
602
|
-
try {
|
|
603
|
-
await session.save();
|
|
604
|
-
}
|
|
605
|
-
catch {
|
|
606
|
-
// Ignore
|
|
607
|
-
}
|
|
608
|
-
}
|
|
609
|
-
throw error;
|
|
610
|
-
}
|
|
564
|
+
return withSessionSave(session, () => next({ ctx: { ...ctx, session, user, isAuthenticated } }));
|
|
611
565
|
};
|
|
612
566
|
}
|
|
613
567
|
return {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@veloxts/auth",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.3",
|
|
4
4
|
"description": "Authentication and authorization system for VeloxTS framework",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -61,8 +61,8 @@
|
|
|
61
61
|
"dependencies": {
|
|
62
62
|
"@fastify/cookie": "11.0.2",
|
|
63
63
|
"fastify": "5.7.4",
|
|
64
|
-
"@veloxts/core": "0.7.
|
|
65
|
-
"@veloxts/router": "0.7.
|
|
64
|
+
"@veloxts/core": "0.7.3",
|
|
65
|
+
"@veloxts/router": "0.7.3"
|
|
66
66
|
},
|
|
67
67
|
"peerDependencies": {
|
|
68
68
|
"argon2": ">=0.30.0",
|
|
@@ -85,8 +85,8 @@
|
|
|
85
85
|
"@vitest/coverage-v8": "4.0.18",
|
|
86
86
|
"typescript": "5.9.3",
|
|
87
87
|
"vitest": "4.0.18",
|
|
88
|
-
"@veloxts/testing": "0.7.
|
|
89
|
-
"@veloxts/validation": "0.7.
|
|
88
|
+
"@veloxts/testing": "0.7.3",
|
|
89
|
+
"@veloxts/validation": "0.7.3"
|
|
90
90
|
},
|
|
91
91
|
"keywords": [
|
|
92
92
|
"velox",
|