@veloxts/auth 0.6.90 → 0.6.91
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 +9 -0
- package/GUIDE.md +20 -4
- package/dist/hash.d.ts +25 -0
- package/dist/hash.js +25 -0
- package/dist/index.d.ts +1 -22
- package/dist/index.js +1 -35
- package/dist/middleware.d.ts +12 -5
- package/dist/middleware.js +7 -5
- package/dist/plugin.d.ts +65 -31
- package/dist/plugin.js +54 -107
- package/package.json +5 -5
package/CHANGELOG.md
CHANGED
package/GUIDE.md
CHANGED
|
@@ -22,9 +22,13 @@ const session = sessionMiddleware({
|
|
|
22
22
|
});
|
|
23
23
|
|
|
24
24
|
const getProfile = procedure()
|
|
25
|
-
.use(session.
|
|
25
|
+
.use(session.required())
|
|
26
26
|
.query(({ ctx }) => ctx.user);
|
|
27
27
|
|
|
28
|
+
const publicPage = procedure()
|
|
29
|
+
.use(session.optional())
|
|
30
|
+
.query(({ ctx }) => ({ user: ctx.user ?? null }));
|
|
31
|
+
|
|
28
32
|
// Login/Logout
|
|
29
33
|
await ctx.session.login(user);
|
|
30
34
|
await ctx.session.logout();
|
|
@@ -47,8 +51,12 @@ const auth = authMiddleware({
|
|
|
47
51
|
});
|
|
48
52
|
|
|
49
53
|
const getProfile = procedure()
|
|
50
|
-
.use(auth.
|
|
54
|
+
.use(auth.required())
|
|
51
55
|
.query(({ ctx }) => ctx.user);
|
|
56
|
+
|
|
57
|
+
const publicEndpoint = procedure()
|
|
58
|
+
.use(auth.optional())
|
|
59
|
+
.query(({ ctx }) => ({ user: ctx.user ?? null }));
|
|
52
60
|
```
|
|
53
61
|
|
|
54
62
|
## Guards
|
|
@@ -81,10 +89,18 @@ const adminWithPermission = procedure()
|
|
|
81
89
|
## Password Hashing
|
|
82
90
|
|
|
83
91
|
```typescript
|
|
84
|
-
import { hashPassword, verifyPassword } from '@veloxts/auth';
|
|
92
|
+
import { hashPassword, verifyPassword, passwordHasher, DEFAULT_HASH_CONFIG } from '@veloxts/auth';
|
|
85
93
|
|
|
86
|
-
|
|
94
|
+
// Simple usage (uses DEFAULT_HASH_CONFIG: bcrypt, 12 rounds)
|
|
95
|
+
const hash = await hashPassword('password');
|
|
87
96
|
const valid = await verifyPassword('password', hash);
|
|
97
|
+
|
|
98
|
+
// Custom configuration
|
|
99
|
+
const hasher = passwordHasher({
|
|
100
|
+
...DEFAULT_HASH_CONFIG,
|
|
101
|
+
bcryptRounds: 14, // Increase for higher security
|
|
102
|
+
});
|
|
103
|
+
const customHash = await hasher.hash('password');
|
|
88
104
|
```
|
|
89
105
|
|
|
90
106
|
## Learn More
|
package/dist/hash.d.ts
CHANGED
|
@@ -3,6 +3,31 @@
|
|
|
3
3
|
* @module auth/hash
|
|
4
4
|
*/
|
|
5
5
|
import type { HashConfig } from './types.js';
|
|
6
|
+
/**
|
|
7
|
+
* Default password hashing configuration
|
|
8
|
+
*
|
|
9
|
+
* Uses bcrypt with 12 rounds, which provides a good balance between
|
|
10
|
+
* security and performance. Increase rounds for higher security
|
|
11
|
+
* (each increment doubles the computation time).
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* import { DEFAULT_HASH_CONFIG, passwordHasher } from '@veloxts/auth';
|
|
16
|
+
*
|
|
17
|
+
* // Use defaults explicitly
|
|
18
|
+
* const hasher = passwordHasher(DEFAULT_HASH_CONFIG);
|
|
19
|
+
*
|
|
20
|
+
* // Or customize from defaults
|
|
21
|
+
* const strongerHasher = passwordHasher({
|
|
22
|
+
* ...DEFAULT_HASH_CONFIG,
|
|
23
|
+
* bcryptRounds: 14,
|
|
24
|
+
* });
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export declare const DEFAULT_HASH_CONFIG: {
|
|
28
|
+
readonly algorithm: "bcrypt";
|
|
29
|
+
readonly bcryptRounds: 12;
|
|
30
|
+
};
|
|
6
31
|
/**
|
|
7
32
|
* Password hasher with configurable algorithms
|
|
8
33
|
*
|
package/dist/hash.js
CHANGED
|
@@ -12,6 +12,31 @@ const DEFAULT_BCRYPT_ROUNDS = 12;
|
|
|
12
12
|
const DEFAULT_ARGON2_MEMORY_COST = 65536; // 64 MB
|
|
13
13
|
const DEFAULT_ARGON2_TIME_COST = 3;
|
|
14
14
|
const DEFAULT_ARGON2_PARALLELISM = 4;
|
|
15
|
+
/**
|
|
16
|
+
* Default password hashing configuration
|
|
17
|
+
*
|
|
18
|
+
* Uses bcrypt with 12 rounds, which provides a good balance between
|
|
19
|
+
* security and performance. Increase rounds for higher security
|
|
20
|
+
* (each increment doubles the computation time).
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```typescript
|
|
24
|
+
* import { DEFAULT_HASH_CONFIG, passwordHasher } from '@veloxts/auth';
|
|
25
|
+
*
|
|
26
|
+
* // Use defaults explicitly
|
|
27
|
+
* const hasher = passwordHasher(DEFAULT_HASH_CONFIG);
|
|
28
|
+
*
|
|
29
|
+
* // Or customize from defaults
|
|
30
|
+
* const strongerHasher = passwordHasher({
|
|
31
|
+
* ...DEFAULT_HASH_CONFIG,
|
|
32
|
+
* bcryptRounds: 14,
|
|
33
|
+
* });
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export const DEFAULT_HASH_CONFIG = {
|
|
37
|
+
algorithm: 'bcrypt',
|
|
38
|
+
bcryptRounds: DEFAULT_BCRYPT_ROUNDS,
|
|
39
|
+
};
|
|
15
40
|
// ============================================================================
|
|
16
41
|
// Password Hasher Class
|
|
17
42
|
// ============================================================================
|
package/dist/index.d.ts
CHANGED
|
@@ -17,7 +17,7 @@ export type { EnhancedTokenStore, EnhancedTokenStoreOptions } from './token-stor
|
|
|
17
17
|
export { createEnhancedTokenStore, DEFAULT_ALLOWED_ROLES, parseUserRoles, } from './token-store.js';
|
|
18
18
|
export type { AuthenticatedContext, InferNarrowedContext, NarrowingGuard, RoleNarrowedContext, } from './guards-narrowing.js';
|
|
19
19
|
export { authenticatedNarrow, hasRoleNarrow } from './guards-narrowing.js';
|
|
20
|
-
export { hashPassword, PasswordHasher, passwordHasher, verifyPassword, } from './hash.js';
|
|
20
|
+
export { DEFAULT_HASH_CONFIG, hashPassword, PasswordHasher, passwordHasher, verifyPassword, } from './hash.js';
|
|
21
21
|
export type { GuardBuilder } from './guards.js';
|
|
22
22
|
export { allOf, anyOf, authenticated, defineGuard, emailVerified, executeGuard, executeGuards, guard, hasAnyPermission, hasPermission, hasRole, not, userCan, } from './guards.js';
|
|
23
23
|
export { authorize, can, cannot, clearPolicies, createAdminOnlyPolicy, createOwnerOrAdminPolicy, createPolicyBuilder, createReadOnlyPolicy, definePolicy, getPolicy, registerPolicy, } from './policies.js';
|
|
@@ -38,24 +38,3 @@ export type { JwtAdapterConfig } from './adapters/jwt-adapter.js';
|
|
|
38
38
|
export { createJwtAdapter, JwtAdapter } from './adapters/jwt-adapter.js';
|
|
39
39
|
export type { PasswordPolicyConfig, PasswordValidationResult, UserInfo, } from './password-policy.js';
|
|
40
40
|
export { checkPasswordBreach, checkPasswordStrength, isCommonPassword, PasswordPolicy, PasswordStrength, passwordPolicy, } from './password-policy.js';
|
|
41
|
-
/**
|
|
42
|
-
* DI tokens and providers for @veloxts/auth
|
|
43
|
-
*
|
|
44
|
-
* Use these to integrate auth services with the @veloxts/core DI container.
|
|
45
|
-
*
|
|
46
|
-
* @example
|
|
47
|
-
* ```typescript
|
|
48
|
-
* import { Container } from '@veloxts/core';
|
|
49
|
-
* import { registerAuthProviders, JWT_MANAGER, PASSWORD_HASHER } from '@veloxts/auth';
|
|
50
|
-
*
|
|
51
|
-
* const container = new Container();
|
|
52
|
-
* registerAuthProviders(container, {
|
|
53
|
-
* jwt: { secret: process.env.JWT_SECRET! }
|
|
54
|
-
* });
|
|
55
|
-
*
|
|
56
|
-
* const jwt = container.resolve(JWT_MANAGER);
|
|
57
|
-
* const hasher = container.resolve(PASSWORD_HASHER);
|
|
58
|
-
* ```
|
|
59
|
-
*/
|
|
60
|
-
export { authServiceProvider, jwtManagerProvider, passwordHasherProvider, passwordHasherProviderWithDefaults, registerAuthProviders, } from './providers.js';
|
|
61
|
-
export { AUTH_CONFIG, AUTH_RATE_LIMITER, AUTH_SERVICE, CSRF_CONFIG, HASH_CONFIG, JWT_CONFIG, JWT_MANAGER, PASSWORD_HASHER, RATE_LIMIT_CONFIG, SESSION_CONFIG, SESSION_STORE, TOKEN_STORE, } from './tokens.js';
|
package/dist/index.js
CHANGED
|
@@ -22,7 +22,7 @@ export { authenticatedNarrow, hasRoleNarrow } from './guards-narrowing.js';
|
|
|
22
22
|
// ============================================================================
|
|
23
23
|
// Password Hashing
|
|
24
24
|
// ============================================================================
|
|
25
|
-
export { hashPassword, PasswordHasher, passwordHasher, verifyPassword, } from './hash.js';
|
|
25
|
+
export { DEFAULT_HASH_CONFIG, hashPassword, PasswordHasher, passwordHasher, verifyPassword, } from './hash.js';
|
|
26
26
|
export {
|
|
27
27
|
// Combinators
|
|
28
28
|
allOf, anyOf,
|
|
@@ -71,37 +71,3 @@ isAuthAdapter, } from './adapter.js';
|
|
|
71
71
|
export { BetterAuthAdapter, createBetterAuthAdapter } from './adapters/better-auth.js';
|
|
72
72
|
export { createJwtAdapter, JwtAdapter } from './adapters/jwt-adapter.js';
|
|
73
73
|
export { checkPasswordBreach, checkPasswordStrength, isCommonPassword, PasswordPolicy, PasswordStrength, passwordPolicy, } from './password-policy.js';
|
|
74
|
-
// ============================================================================
|
|
75
|
-
// Dependency Injection
|
|
76
|
-
// ============================================================================
|
|
77
|
-
/**
|
|
78
|
-
* DI tokens and providers for @veloxts/auth
|
|
79
|
-
*
|
|
80
|
-
* Use these to integrate auth services with the @veloxts/core DI container.
|
|
81
|
-
*
|
|
82
|
-
* @example
|
|
83
|
-
* ```typescript
|
|
84
|
-
* import { Container } from '@veloxts/core';
|
|
85
|
-
* import { registerAuthProviders, JWT_MANAGER, PASSWORD_HASHER } from '@veloxts/auth';
|
|
86
|
-
*
|
|
87
|
-
* const container = new Container();
|
|
88
|
-
* registerAuthProviders(container, {
|
|
89
|
-
* jwt: { secret: process.env.JWT_SECRET! }
|
|
90
|
-
* });
|
|
91
|
-
*
|
|
92
|
-
* const jwt = container.resolve(JWT_MANAGER);
|
|
93
|
-
* const hasher = container.resolve(PASSWORD_HASHER);
|
|
94
|
-
* ```
|
|
95
|
-
*/
|
|
96
|
-
// Provider exports - factory functions for registering services
|
|
97
|
-
export { authServiceProvider, jwtManagerProvider, passwordHasherProvider, passwordHasherProviderWithDefaults,
|
|
98
|
-
// Bulk registration helper
|
|
99
|
-
registerAuthProviders, } from './providers.js';
|
|
100
|
-
// Token exports - unique identifiers for DI resolution
|
|
101
|
-
export {
|
|
102
|
-
// Config tokens
|
|
103
|
-
AUTH_CONFIG, AUTH_RATE_LIMITER,
|
|
104
|
-
// Service tokens
|
|
105
|
-
AUTH_SERVICE, CSRF_CONFIG, HASH_CONFIG, JWT_CONFIG, JWT_MANAGER, PASSWORD_HASHER, RATE_LIMIT_CONFIG, SESSION_CONFIG,
|
|
106
|
-
// Store tokens
|
|
107
|
-
SESSION_STORE, TOKEN_STORE, } from './tokens.js';
|
package/dist/middleware.d.ts
CHANGED
|
@@ -20,18 +20,17 @@ import type { AuthConfig, AuthMiddlewareOptions, GuardDefinition, NativeAuthCont
|
|
|
20
20
|
* ```typescript
|
|
21
21
|
* const auth = authMiddleware(authConfig);
|
|
22
22
|
*
|
|
23
|
-
* //
|
|
23
|
+
* // Required auth (user guaranteed to exist)
|
|
24
24
|
* const getProfile = procedure()
|
|
25
|
-
* .use(auth.
|
|
25
|
+
* .use(auth.required())
|
|
26
26
|
* .query(async ({ ctx }) => {
|
|
27
|
-
* return ctx.user;
|
|
27
|
+
* return ctx.user;
|
|
28
28
|
* });
|
|
29
29
|
*
|
|
30
30
|
* // Optional auth (user may be undefined)
|
|
31
31
|
* const getPosts = procedure()
|
|
32
|
-
* .use(auth.
|
|
32
|
+
* .use(auth.optional())
|
|
33
33
|
* .query(async ({ ctx }) => {
|
|
34
|
-
* // ctx.user may be undefined
|
|
35
34
|
* return fetchPosts(ctx.user?.id);
|
|
36
35
|
* });
|
|
37
36
|
*
|
|
@@ -56,6 +55,14 @@ export declare function authMiddleware(config: AuthConfig): {
|
|
|
56
55
|
user?: User;
|
|
57
56
|
auth: NativeAuthContext;
|
|
58
57
|
}, TOutput>;
|
|
58
|
+
required: <TInput, TContext extends BaseContext, TOutput>(guards?: Array<GuardDefinition | string>) => MiddlewareFunction<TInput, TContext, TContext & {
|
|
59
|
+
user: User;
|
|
60
|
+
auth: NativeAuthContext;
|
|
61
|
+
}, TOutput>;
|
|
62
|
+
optional: <TInput, TContext extends BaseContext, TOutput>() => MiddlewareFunction<TInput, TContext, TContext & {
|
|
63
|
+
user?: User;
|
|
64
|
+
auth: NativeAuthContext;
|
|
65
|
+
}, TOutput>;
|
|
59
66
|
jwt: JwtManager;
|
|
60
67
|
};
|
|
61
68
|
/**
|
package/dist/middleware.js
CHANGED
|
@@ -22,18 +22,17 @@ import { AuthError } from './types.js';
|
|
|
22
22
|
* ```typescript
|
|
23
23
|
* const auth = authMiddleware(authConfig);
|
|
24
24
|
*
|
|
25
|
-
* //
|
|
25
|
+
* // Required auth (user guaranteed to exist)
|
|
26
26
|
* const getProfile = procedure()
|
|
27
|
-
* .use(auth.
|
|
27
|
+
* .use(auth.required())
|
|
28
28
|
* .query(async ({ ctx }) => {
|
|
29
|
-
* return ctx.user;
|
|
29
|
+
* return ctx.user;
|
|
30
30
|
* });
|
|
31
31
|
*
|
|
32
32
|
* // Optional auth (user may be undefined)
|
|
33
33
|
* const getPosts = procedure()
|
|
34
|
-
* .use(auth.
|
|
34
|
+
* .use(auth.optional())
|
|
35
35
|
* .query(async ({ ctx }) => {
|
|
36
|
-
* // ctx.user may be undefined
|
|
37
36
|
* return fetchPosts(ctx.user?.id);
|
|
38
37
|
* });
|
|
39
38
|
*
|
|
@@ -173,6 +172,9 @@ export function authMiddleware(config) {
|
|
|
173
172
|
middleware,
|
|
174
173
|
requireAuth,
|
|
175
174
|
optionalAuth,
|
|
175
|
+
// Terse aliases (Laravel-inspired)
|
|
176
|
+
required: requireAuth,
|
|
177
|
+
optional: optionalAuth,
|
|
176
178
|
jwt,
|
|
177
179
|
};
|
|
178
180
|
}
|
package/dist/plugin.d.ts
CHANGED
|
@@ -6,13 +6,14 @@
|
|
|
6
6
|
*
|
|
7
7
|
* @module auth/plugin
|
|
8
8
|
*/
|
|
9
|
-
import type {
|
|
10
|
-
import type {
|
|
9
|
+
import type { VeloxPlugin } from '@veloxts/core';
|
|
10
|
+
import type { FastifyReply, FastifyRequest } from 'fastify';
|
|
11
|
+
import type { AdapterUser, AuthAdapterError, AuthAdapterPluginOptions } from './adapter.js';
|
|
11
12
|
import type { JwtAdapterConfig } from './adapters/jwt-adapter.js';
|
|
12
13
|
import { PasswordHasher } from './hash.js';
|
|
13
14
|
import type { JwtManager, TokenStore } from './jwt.js';
|
|
14
15
|
import { authMiddleware } from './middleware.js';
|
|
15
|
-
import type { AdapterAuthContext, AuthConfig, TokenPair, User } from './types.js';
|
|
16
|
+
import type { AdapterAuthContext, AuthConfig, JwtConfig, TokenPair, User } from './types.js';
|
|
16
17
|
/** Auth package version */
|
|
17
18
|
export declare const AUTH_VERSION: string;
|
|
18
19
|
/**
|
|
@@ -24,32 +25,6 @@ export interface AuthPluginOptions extends AuthConfig {
|
|
|
24
25
|
* @default false
|
|
25
26
|
*/
|
|
26
27
|
debug?: boolean;
|
|
27
|
-
/**
|
|
28
|
-
* DI container for service registration and resolution (optional)
|
|
29
|
-
*
|
|
30
|
-
* When provided, auth services are registered with the container and can be:
|
|
31
|
-
* - Resolved from the container directly
|
|
32
|
-
* - Mocked in tests by overriding registrations
|
|
33
|
-
* - Managed alongside other application services
|
|
34
|
-
*
|
|
35
|
-
* When not provided, services are created directly (legacy behavior).
|
|
36
|
-
*
|
|
37
|
-
* @example
|
|
38
|
-
* ```typescript
|
|
39
|
-
* import { Container } from '@veloxts/core';
|
|
40
|
-
* import { authPlugin, JWT_MANAGER } from '@veloxts/auth';
|
|
41
|
-
*
|
|
42
|
-
* const container = new Container();
|
|
43
|
-
* app.register(authPlugin({
|
|
44
|
-
* jwt: { secret: '...' },
|
|
45
|
-
* container,
|
|
46
|
-
* }));
|
|
47
|
-
*
|
|
48
|
-
* // Services now available from container
|
|
49
|
-
* const jwt = container.resolve(JWT_MANAGER);
|
|
50
|
-
* ```
|
|
51
|
-
*/
|
|
52
|
-
container?: Container;
|
|
53
28
|
}
|
|
54
29
|
/**
|
|
55
30
|
* Auth service instance attached to Fastify
|
|
@@ -158,9 +133,68 @@ export declare function defaultAuthPlugin(): VeloxPlugin<AuthPluginOptions>;
|
|
|
158
133
|
/**
|
|
159
134
|
* Options for jwtAuth convenience function
|
|
160
135
|
*
|
|
161
|
-
*
|
|
136
|
+
* Explicit interface for better discoverability (name is auto-set to 'jwt').
|
|
162
137
|
*/
|
|
163
|
-
export
|
|
138
|
+
export interface JwtAuthOptions {
|
|
139
|
+
/**
|
|
140
|
+
* JWT configuration (secret, expiry, etc.)
|
|
141
|
+
*
|
|
142
|
+
* This is passed directly to JwtManager.
|
|
143
|
+
*/
|
|
144
|
+
jwt: JwtConfig;
|
|
145
|
+
/**
|
|
146
|
+
* Token store for revocation tracking
|
|
147
|
+
*
|
|
148
|
+
* Used to check if tokens have been revoked (e.g., on logout).
|
|
149
|
+
* Defaults to in-memory store (not suitable for production).
|
|
150
|
+
*/
|
|
151
|
+
tokenStore?: TokenStore;
|
|
152
|
+
/**
|
|
153
|
+
* Load user by ID
|
|
154
|
+
*
|
|
155
|
+
* Called when verifying tokens to load the full user object.
|
|
156
|
+
* If not provided, a minimal user object is created from token claims.
|
|
157
|
+
*/
|
|
158
|
+
userLoader?: (userId: string) => Promise<User | null>;
|
|
159
|
+
/**
|
|
160
|
+
* Enable built-in auth routes
|
|
161
|
+
*
|
|
162
|
+
* When true, mounts routes for token refresh and logout:
|
|
163
|
+
* - POST `${routePrefix}/refresh` - Refresh access token
|
|
164
|
+
* - POST `${routePrefix}/logout` - Revoke current token
|
|
165
|
+
*
|
|
166
|
+
* @default true
|
|
167
|
+
*/
|
|
168
|
+
enableRoutes?: boolean;
|
|
169
|
+
/**
|
|
170
|
+
* Base path for auth routes
|
|
171
|
+
*
|
|
172
|
+
* Only used when `enableRoutes` is true.
|
|
173
|
+
*
|
|
174
|
+
* @default '/api/auth'
|
|
175
|
+
*/
|
|
176
|
+
routePrefix?: string;
|
|
177
|
+
/**
|
|
178
|
+
* Enable debug logging
|
|
179
|
+
*
|
|
180
|
+
* @default false
|
|
181
|
+
*/
|
|
182
|
+
debug?: boolean;
|
|
183
|
+
/**
|
|
184
|
+
* Transform adapter user to VeloxTS User
|
|
185
|
+
*
|
|
186
|
+
* Override to customize how token claims are transformed to User.
|
|
187
|
+
*/
|
|
188
|
+
transformUser?: (adapterUser: AdapterUser) => User;
|
|
189
|
+
/**
|
|
190
|
+
* Routes to exclude from automatic session loading
|
|
191
|
+
*/
|
|
192
|
+
excludeRoutes?: string[];
|
|
193
|
+
/**
|
|
194
|
+
* Custom error handler for adapter errors
|
|
195
|
+
*/
|
|
196
|
+
onError?: (error: AuthAdapterError, request: FastifyRequest, reply: FastifyReply) => void | Promise<void>;
|
|
197
|
+
}
|
|
164
198
|
/**
|
|
165
199
|
* Creates JWT auth using the adapter pattern directly
|
|
166
200
|
*
|
package/dist/plugin.js
CHANGED
|
@@ -12,8 +12,6 @@ import { createJwtAdapter } from './adapters/jwt-adapter.js';
|
|
|
12
12
|
import { checkDoubleRegistration, decorateAuth } from './decoration.js';
|
|
13
13
|
import { PasswordHasher } from './hash.js';
|
|
14
14
|
import { authMiddleware } from './middleware.js';
|
|
15
|
-
import { registerAuthProviders } from './providers.js';
|
|
16
|
-
import { AUTH_SERVICE } from './tokens.js';
|
|
17
15
|
// Read version from package.json dynamically
|
|
18
16
|
const require = createRequire(import.meta.url);
|
|
19
17
|
const packageJson = require('../package.json');
|
|
@@ -86,38 +84,66 @@ export function authPlugin(options) {
|
|
|
86
84
|
version: AUTH_VERSION,
|
|
87
85
|
async register(server, _opts) {
|
|
88
86
|
const config = { ...options, ..._opts };
|
|
89
|
-
const { debug = false
|
|
87
|
+
const { debug = false } = config;
|
|
90
88
|
// Prevent double-registration of auth systems
|
|
91
89
|
checkDoubleRegistration(server, 'authPlugin');
|
|
92
90
|
if (debug) {
|
|
93
91
|
server.log.info('Registering @veloxts/auth plugin (adapter-based)');
|
|
94
92
|
}
|
|
95
|
-
//
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
93
|
+
// Convert isTokenRevoked callback to TokenStore if provided
|
|
94
|
+
const tokenStore = config.isTokenRevoked
|
|
95
|
+
? createCallbackTokenStore(config.isTokenRevoked)
|
|
96
|
+
: undefined;
|
|
97
|
+
// Create the JWT adapter
|
|
98
|
+
const { adapter, config: adapterConfig } = createJwtAdapter({
|
|
99
|
+
jwt: config.jwt,
|
|
100
|
+
userLoader: config.userLoader,
|
|
101
|
+
tokenStore,
|
|
102
|
+
enableRoutes: false, // authPlugin manages its own API
|
|
103
|
+
debug,
|
|
104
|
+
});
|
|
105
|
+
// Initialize adapter
|
|
106
|
+
await adapter.initialize(server, adapterConfig);
|
|
107
|
+
// Decorate requests with auth context
|
|
108
|
+
decorateAuth(server);
|
|
109
|
+
// Get JWT manager from adapter
|
|
110
|
+
const jwt = adapter.getJwtManager();
|
|
111
|
+
const hasher = new PasswordHasher(config.hash);
|
|
112
|
+
const authMw = authMiddleware(config);
|
|
113
|
+
// Build AuthService from adapter
|
|
114
|
+
const authService = {
|
|
115
|
+
jwt,
|
|
116
|
+
hasher,
|
|
117
|
+
tokenStore: adapter.getTokenStore(),
|
|
118
|
+
createTokens(user, additionalClaims) {
|
|
119
|
+
return jwt.createTokenPair(user, additionalClaims);
|
|
120
|
+
},
|
|
121
|
+
verifyToken(token) {
|
|
122
|
+
const payload = jwt.verifyToken(token);
|
|
123
|
+
return {
|
|
124
|
+
authMode: 'adapter',
|
|
125
|
+
user: {
|
|
126
|
+
id: payload.sub,
|
|
127
|
+
email: payload.email,
|
|
128
|
+
},
|
|
129
|
+
isAuthenticated: true,
|
|
130
|
+
providerId: 'jwt',
|
|
131
|
+
session: { token, payload },
|
|
132
|
+
};
|
|
133
|
+
},
|
|
134
|
+
refreshTokens(refreshToken) {
|
|
135
|
+
if (config.userLoader) {
|
|
136
|
+
return jwt.refreshTokens(refreshToken, config.userLoader);
|
|
137
|
+
}
|
|
138
|
+
return jwt.refreshTokens(refreshToken);
|
|
139
|
+
},
|
|
140
|
+
middleware: authMw,
|
|
141
|
+
};
|
|
142
|
+
// Decorate server with auth service
|
|
143
|
+
server.decorate('auth', authService);
|
|
144
|
+
// Add preHandler hook for session loading (using adapter)
|
|
145
|
+
if (config.autoExtract !== false) {
|
|
118
146
|
server.addHook('preHandler', async (request) => {
|
|
119
|
-
if (config.autoExtract === false)
|
|
120
|
-
return;
|
|
121
147
|
const session = await adapter.getSession(request);
|
|
122
148
|
if (session) {
|
|
123
149
|
const user = {
|
|
@@ -140,85 +166,6 @@ export function authPlugin(options) {
|
|
|
140
166
|
}
|
|
141
167
|
});
|
|
142
168
|
}
|
|
143
|
-
else {
|
|
144
|
-
// Adapter-based path: Use JwtAdapter directly
|
|
145
|
-
// Convert isTokenRevoked callback to TokenStore if provided
|
|
146
|
-
const tokenStore = config.isTokenRevoked
|
|
147
|
-
? createCallbackTokenStore(config.isTokenRevoked)
|
|
148
|
-
: undefined;
|
|
149
|
-
// Create the JWT adapter
|
|
150
|
-
const { adapter, config: adapterConfig } = createJwtAdapter({
|
|
151
|
-
jwt: config.jwt,
|
|
152
|
-
userLoader: config.userLoader,
|
|
153
|
-
tokenStore,
|
|
154
|
-
enableRoutes: false, // authPlugin manages its own API
|
|
155
|
-
debug,
|
|
156
|
-
});
|
|
157
|
-
// Initialize adapter
|
|
158
|
-
await adapter.initialize(server, adapterConfig);
|
|
159
|
-
// Decorate requests with auth context
|
|
160
|
-
decorateAuth(server);
|
|
161
|
-
// Get JWT manager from adapter
|
|
162
|
-
const jwt = adapter.getJwtManager();
|
|
163
|
-
const hasher = new PasswordHasher(config.hash);
|
|
164
|
-
const authMw = authMiddleware(config);
|
|
165
|
-
// Build AuthService from adapter
|
|
166
|
-
const authService = {
|
|
167
|
-
jwt,
|
|
168
|
-
hasher,
|
|
169
|
-
tokenStore: adapter.getTokenStore(),
|
|
170
|
-
createTokens(user, additionalClaims) {
|
|
171
|
-
return jwt.createTokenPair(user, additionalClaims);
|
|
172
|
-
},
|
|
173
|
-
verifyToken(token) {
|
|
174
|
-
const payload = jwt.verifyToken(token);
|
|
175
|
-
return {
|
|
176
|
-
authMode: 'adapter',
|
|
177
|
-
user: {
|
|
178
|
-
id: payload.sub,
|
|
179
|
-
email: payload.email,
|
|
180
|
-
},
|
|
181
|
-
isAuthenticated: true,
|
|
182
|
-
providerId: 'jwt',
|
|
183
|
-
session: { token, payload },
|
|
184
|
-
};
|
|
185
|
-
},
|
|
186
|
-
refreshTokens(refreshToken) {
|
|
187
|
-
if (config.userLoader) {
|
|
188
|
-
return jwt.refreshTokens(refreshToken, config.userLoader);
|
|
189
|
-
}
|
|
190
|
-
return jwt.refreshTokens(refreshToken);
|
|
191
|
-
},
|
|
192
|
-
middleware: authMw,
|
|
193
|
-
};
|
|
194
|
-
// Decorate server with auth service
|
|
195
|
-
server.decorate('auth', authService);
|
|
196
|
-
// Add preHandler hook for session loading (using adapter)
|
|
197
|
-
if (config.autoExtract !== false) {
|
|
198
|
-
server.addHook('preHandler', async (request) => {
|
|
199
|
-
const session = await adapter.getSession(request);
|
|
200
|
-
if (session) {
|
|
201
|
-
const user = {
|
|
202
|
-
id: session.user.id,
|
|
203
|
-
email: session.user.email,
|
|
204
|
-
...(session.user.emailVerified !== undefined && {
|
|
205
|
-
emailVerified: session.user.emailVerified,
|
|
206
|
-
}),
|
|
207
|
-
...session.user.providerData,
|
|
208
|
-
};
|
|
209
|
-
const authContext = {
|
|
210
|
-
authMode: 'adapter',
|
|
211
|
-
isAuthenticated: true,
|
|
212
|
-
user,
|
|
213
|
-
providerId: 'jwt',
|
|
214
|
-
session: session.session.providerData,
|
|
215
|
-
};
|
|
216
|
-
request.auth = authContext;
|
|
217
|
-
request.user = user;
|
|
218
|
-
}
|
|
219
|
-
});
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
169
|
// Add shutdown hook for cleanup
|
|
223
170
|
server.addHook('onClose', async () => {
|
|
224
171
|
if (debug) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@veloxts/auth",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.91",
|
|
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.2",
|
|
64
|
-
"@veloxts/core": "0.6.
|
|
65
|
-
"@veloxts/router": "0.6.
|
|
64
|
+
"@veloxts/core": "0.6.91",
|
|
65
|
+
"@veloxts/router": "0.6.91"
|
|
66
66
|
},
|
|
67
67
|
"peerDependencies": {
|
|
68
68
|
"argon2": ">=0.30.0",
|
|
@@ -86,8 +86,8 @@
|
|
|
86
86
|
"fastify-plugin": "5.1.0",
|
|
87
87
|
"typescript": "5.9.3",
|
|
88
88
|
"vitest": "4.0.18",
|
|
89
|
-
"@veloxts/validation": "0.6.
|
|
90
|
-
"@veloxts/testing": "0.6.
|
|
89
|
+
"@veloxts/validation": "0.6.91",
|
|
90
|
+
"@veloxts/testing": "0.6.91"
|
|
91
91
|
},
|
|
92
92
|
"keywords": [
|
|
93
93
|
"velox",
|