@veloxts/auth 0.7.0 → 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/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  # @veloxts/auth
2
2
 
3
+ ## 0.7.2
4
+
5
+ ### Patch Changes
6
+
7
+ - chore(auth,core,create,cli,client,orm,mcp,router,validation,web): simplify code for clarity and maintainability
8
+ - Updated dependencies
9
+ - @veloxts/core@0.7.2
10
+ - @veloxts/router@0.7.2
11
+
12
+ ## 0.7.1
13
+
14
+ ### Patch Changes
15
+
16
+ - security audit, bumps dependency packages
17
+ - Updated dependencies
18
+ - @veloxts/core@0.7.1
19
+ - @veloxts/router@0.7.1
20
+
3
21
  ## 0.7.0
4
22
 
5
23
  ### Minor Changes
package/dist/hash.js CHANGED
@@ -4,6 +4,8 @@
4
4
  */
5
5
  import { randomBytes, scrypt, timingSafeEqual } from 'node:crypto';
6
6
  import { promisify } from 'node:util';
7
+ import { createLogger } from '@veloxts/core';
8
+ const log = createLogger('auth');
7
9
  const scryptAsync = promisify(scrypt);
8
10
  // ============================================================================
9
11
  // Constants
@@ -134,7 +136,7 @@ export class PasswordHasher {
134
136
  catch (error) {
135
137
  // Fallback to scrypt if bcrypt fails
136
138
  if (error.message.includes('not found')) {
137
- console.warn('bcrypt not available, falling back to scrypt');
139
+ log.warn('bcrypt not available, falling back to scrypt');
138
140
  return this.hashWithScrypt(password);
139
141
  }
140
142
  throw error;
@@ -163,7 +165,7 @@ export class PasswordHasher {
163
165
  catch (error) {
164
166
  // Fallback to scrypt if argon2 fails
165
167
  if (error.message.includes('not found')) {
166
- console.warn('argon2 not available, falling back to scrypt');
168
+ log.warn('argon2 not available, falling back to scrypt');
167
169
  return this.hashWithScrypt(password);
168
170
  }
169
171
  throw error;
package/dist/jwt.js CHANGED
@@ -3,7 +3,9 @@
3
3
  * @module auth/jwt
4
4
  */
5
5
  import { createHmac, randomBytes, timingSafeEqual } from 'node:crypto';
6
+ import { createLogger } from '@veloxts/core';
6
7
  import { AuthError } from './types.js';
8
+ const log = createLogger('auth');
7
9
  // ============================================================================
8
10
  // Constants
9
11
  // ============================================================================
@@ -161,11 +163,11 @@ export function validateTokenExpiration(accessExpiry, refreshExpiry) {
161
163
  }
162
164
  // Warn about exceeding recommended limits (non-fatal)
163
165
  if (accessSeconds > TOKEN_BOUNDS.access.recommended) {
164
- console.warn(`[Security] Access token expiry (${accessExpiry}) exceeds recommended maximum of 15 minutes. ` +
166
+ log.warn(`[Security] Access token expiry (${accessExpiry}) exceeds recommended maximum of 15 minutes. ` +
165
167
  'Consider using shorter-lived access tokens with refresh.');
166
168
  }
167
169
  if (refreshSeconds > TOKEN_BOUNDS.refresh.recommended) {
168
- console.warn(`[Security] Refresh token expiry (${refreshExpiry}) exceeds recommended maximum of 7 days. ` +
170
+ log.warn(`[Security] Refresh token expiry (${refreshExpiry}) exceeds recommended maximum of 7 days. ` +
169
171
  'Long-lived refresh tokens increase the window for token theft attacks.');
170
172
  }
171
173
  // Ensure refresh tokens outlive access tokens
@@ -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
  /**
@@ -7,6 +7,8 @@
7
7
  * @module auth/password-policy
8
8
  */
9
9
  import { createHash } from 'node:crypto';
10
+ import { createLogger } from '@veloxts/core';
11
+ const log = createLogger('auth');
10
12
  /**
11
13
  * Password strength levels
12
14
  */
@@ -253,7 +255,7 @@ export class PasswordPolicy {
253
255
  }
254
256
  catch (error) {
255
257
  // Breach check failed - log but don't fail validation
256
- console.warn('Password breach check failed:', error);
258
+ log.warn('Password breach check failed:', error);
257
259
  }
258
260
  }
259
261
  return {
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/policies.js CHANGED
@@ -2,6 +2,8 @@
2
2
  * Resource-level authorization policies for @veloxts/auth
3
3
  * @module auth/policies
4
4
  */
5
+ import { createLogger } from '@veloxts/core';
6
+ const log = createLogger('auth');
5
7
  // ============================================================================
6
8
  // Policy Registry
7
9
  // ============================================================================
@@ -82,7 +84,7 @@ export async function can(user, action, resourceName, resource) {
82
84
  const policy = policyRegistry.get(resourceName);
83
85
  if (!policy) {
84
86
  // No policy registered = deny by default
85
- console.warn(`No policy registered for resource: ${resourceName}`);
87
+ log.warn(`No policy registered for resource: ${resourceName}`);
86
88
  return false;
87
89
  }
88
90
  const actionHandler = policy[action];
@@ -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 || !entry.lockoutUntil)
262
+ if (!entry?.lockoutUntil)
263
263
  return false;
264
- if (entry.lockoutUntil <= Date.now()) {
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
- const value = currentData._flashOld?.[key];
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
- try {
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
- try {
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
- try {
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 {
@@ -8,6 +8,8 @@
8
8
  *
9
9
  * @module auth/token-store
10
10
  */
11
+ import { createLogger } from '@veloxts/core';
12
+ const log = createLogger('auth');
11
13
  // ============================================================================
12
14
  // Implementation
13
15
  // ============================================================================
@@ -89,7 +91,7 @@ export function createEnhancedTokenStore(options) {
89
91
  },
90
92
  revokeAllUserTokens(userId) {
91
93
  // Placeholder - in production, implement proper user->token mapping
92
- console.warn(`[Security] Token reuse detected for user ${userId}. ` +
94
+ log.warn(`[Security] Token reuse detected for user ${userId}. ` +
93
95
  'All tokens should be revoked. Implement proper user->token mapping for production.');
94
96
  },
95
97
  clear() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@veloxts/auth",
3
- "version": "0.7.0",
3
+ "version": "0.7.2",
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.0",
65
- "@veloxts/router": "0.7.0"
64
+ "@veloxts/core": "0.7.2",
65
+ "@veloxts/router": "0.7.2"
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.0",
89
- "@veloxts/validation": "0.7.0"
88
+ "@veloxts/testing": "0.7.2",
89
+ "@veloxts/validation": "0.7.2"
90
90
  },
91
91
  "keywords": [
92
92
  "velox",