@veloxts/auth 0.6.69 → 0.6.71

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.
@@ -0,0 +1,360 @@
1
+ /**
2
+ * JWT Authentication Adapter for @veloxts/auth
3
+ *
4
+ * Implements the AuthAdapter interface using JWT tokens.
5
+ * This allows JWT auth to follow the same pattern as external providers,
6
+ * enabling easy swapping between authentication strategies.
7
+ *
8
+ * @module auth/adapters/jwt-adapter
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * import { createAuthAdapterPlugin } from '@veloxts/auth';
13
+ * import { createJwtAdapter, jwtAuth } from '@veloxts/auth/adapters/jwt-adapter';
14
+ *
15
+ * // Option 1: Using createJwtAdapter + createAuthAdapterPlugin
16
+ * const { adapter, config } = createJwtAdapter({
17
+ * jwt: {
18
+ * secret: process.env.JWT_SECRET!,
19
+ * accessTokenExpiry: '15m',
20
+ * refreshTokenExpiry: '7d',
21
+ * },
22
+ * userLoader: async (userId) => db.user.findUnique({ where: { id: userId } }),
23
+ * });
24
+ *
25
+ * const authPlugin = createAuthAdapterPlugin({ adapter, config });
26
+ * app.use(authPlugin);
27
+ *
28
+ * // Option 2: Using jwtAuth convenience function (recommended)
29
+ * import { jwtAuth } from '@veloxts/auth';
30
+ *
31
+ * app.use(jwtAuth({
32
+ * jwt: {
33
+ * secret: process.env.JWT_SECRET!,
34
+ * accessTokenExpiry: '15m',
35
+ * refreshTokenExpiry: '7d',
36
+ * },
37
+ * userLoader: async (userId) => db.user.findUnique({ where: { id: userId } }),
38
+ * }));
39
+ * ```
40
+ */
41
+ import { AuthAdapterError, BaseAuthAdapter } from '../adapter.js';
42
+ import { createInMemoryTokenStore, JwtManager } from '../jwt.js';
43
+ // ============================================================================
44
+ // JWT Adapter Implementation
45
+ // ============================================================================
46
+ /**
47
+ * JWT Authentication Adapter
48
+ *
49
+ * Implements the AuthAdapter interface using JWT tokens.
50
+ * Provides session loading from Authorization headers and
51
+ * optional routes for token refresh and logout.
52
+ *
53
+ * @example
54
+ * ```typescript
55
+ * const adapter = new JwtAdapter();
56
+ * await adapter.initialize(fastify, {
57
+ * name: 'jwt',
58
+ * jwt: { secret: process.env.JWT_SECRET! },
59
+ * });
60
+ *
61
+ * // Get session from request
62
+ * const session = await adapter.getSession(request);
63
+ * if (session) {
64
+ * console.log('User:', session.user.email);
65
+ * }
66
+ * ```
67
+ */
68
+ export class JwtAdapter extends BaseAuthAdapter {
69
+ jwt = null;
70
+ tokenStore = null;
71
+ userLoader;
72
+ enableRoutes = true;
73
+ routePrefix = '/api/auth';
74
+ constructor() {
75
+ super('jwt', '1.0.0');
76
+ }
77
+ /**
78
+ * Initialize the adapter with JWT configuration
79
+ *
80
+ * Sets up the JwtManager, token store, and configuration options.
81
+ * Also exposes `jwtManager` and `tokenStore` on the Fastify instance.
82
+ */
83
+ async initialize(fastify, config) {
84
+ await super.initialize(fastify, config);
85
+ if (!config.jwt) {
86
+ throw new AuthAdapterError('JWT configuration is required in adapter config', 500, 'ADAPTER_NOT_CONFIGURED');
87
+ }
88
+ // Initialize JWT manager
89
+ this.jwt = new JwtManager(config.jwt);
90
+ /**
91
+ * Initialize token store (default: in-memory with warning)
92
+ *
93
+ * @example Production Redis store passed in config:
94
+ * ```typescript
95
+ * import { createRedisTokenStore } from '@veloxts/auth/redis';
96
+ * …
97
+ * tokenStore: createRedisTokenStore({ url: process.env.REDIS_URL })
98
+ * ```
99
+ */
100
+ this.tokenStore = config.tokenStore ?? createInMemoryTokenStore();
101
+ if (!config.tokenStore) {
102
+ this.debug('Using in-memory token store. Use Redis in production.');
103
+ }
104
+ this.userLoader = config.userLoader;
105
+ this.enableRoutes = config.enableRoutes ?? true;
106
+ this.routePrefix = config.routePrefix ?? '/api/auth';
107
+ // Expose JWT manager and token store on fastify for direct access
108
+ if (!fastify.hasDecorator('jwtManager')) {
109
+ fastify.decorate('jwtManager', this.jwt);
110
+ }
111
+ if (!fastify.hasDecorator('tokenStore')) {
112
+ fastify.decorate('tokenStore', this.tokenStore);
113
+ }
114
+ this.info('JWT adapter initialized');
115
+ }
116
+ /**
117
+ * Get session from JWT token in Authorization header
118
+ *
119
+ * Extracts and verifies the JWT token, checks revocation status,
120
+ * and loads the user if a userLoader is configured.
121
+ *
122
+ * @returns Session result with user and session data, or null if not authenticated
123
+ */
124
+ async getSession(request) {
125
+ if (!this.jwt || !this.tokenStore) {
126
+ throw new AuthAdapterError('JWT adapter not initialized', 500, 'ADAPTER_NOT_CONFIGURED');
127
+ }
128
+ // Extract token from Authorization header
129
+ const authHeader = request.headers.authorization;
130
+ const token = this.jwt.extractFromHeader(authHeader);
131
+ if (!token) {
132
+ return null;
133
+ }
134
+ try {
135
+ // Verify token
136
+ const payload = this.jwt.verifyToken(token);
137
+ // Check for access token type
138
+ if (payload.type !== 'access') {
139
+ this.debug('Non-access token in Authorization header');
140
+ return null;
141
+ }
142
+ // Check if token is revoked
143
+ if (payload.jti) {
144
+ const isRevoked = await this.tokenStore.isRevoked(payload.jti);
145
+ if (isRevoked) {
146
+ this.debug('Token has been revoked');
147
+ return null;
148
+ }
149
+ }
150
+ // Load user if loader provided
151
+ let user;
152
+ if (this.userLoader) {
153
+ user = await this.userLoader(payload.sub);
154
+ if (!user) {
155
+ this.debug('User not found for token');
156
+ return null;
157
+ }
158
+ }
159
+ else {
160
+ user = { id: payload.sub, email: payload.email };
161
+ }
162
+ // Store token and payload on request for middleware access
163
+ // Using type assertion to avoid modifying Fastify types
164
+ const requestWithJwt = request;
165
+ requestWithJwt.__jwtToken = token;
166
+ requestWithJwt.__jwtPayload = payload;
167
+ return {
168
+ user: {
169
+ id: user.id,
170
+ email: user.email,
171
+ name: user.name,
172
+ emailVerified: user.emailVerified,
173
+ providerData: { roles: user.roles, permissions: user.permissions },
174
+ },
175
+ session: {
176
+ sessionId: payload.jti ?? `jwt-${payload.sub}`,
177
+ userId: payload.sub,
178
+ expiresAt: payload.exp * 1000, // Convert to ms
179
+ isActive: true,
180
+ providerData: { token, payload },
181
+ },
182
+ };
183
+ }
184
+ catch (error) {
185
+ this.debug(`Token verification failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
186
+ return null;
187
+ }
188
+ }
189
+ /**
190
+ * Get routes for token refresh and logout
191
+ *
192
+ * Returns routes only if `enableRoutes` is true in config.
193
+ */
194
+ getRoutes() {
195
+ if (!this.enableRoutes) {
196
+ return [];
197
+ }
198
+ return [
199
+ // Refresh token endpoint
200
+ {
201
+ path: `${this.routePrefix}/refresh`,
202
+ methods: ['POST'],
203
+ handler: this.handleRefresh.bind(this),
204
+ description: 'Refresh access token using refresh token',
205
+ },
206
+ // Logout endpoint (revoke token)
207
+ {
208
+ path: `${this.routePrefix}/logout`,
209
+ methods: ['POST'],
210
+ handler: this.handleLogout.bind(this),
211
+ description: 'Revoke current access token',
212
+ },
213
+ ];
214
+ }
215
+ /**
216
+ * Handle token refresh requests
217
+ *
218
+ * Expects `refreshToken` in request body.
219
+ * Returns new token pair on success.
220
+ */
221
+ async handleRefresh(request, reply) {
222
+ if (!this.jwt) {
223
+ throw new AuthAdapterError('JWT adapter not initialized', 500, 'ADAPTER_NOT_CONFIGURED');
224
+ }
225
+ const body = request.body;
226
+ const refreshToken = body?.refreshToken;
227
+ if (!refreshToken) {
228
+ reply.status(400).send({ error: 'Missing refreshToken in request body' });
229
+ return;
230
+ }
231
+ try {
232
+ const tokens = await this.jwt.refreshTokens(refreshToken, this.userLoader);
233
+ reply.send(tokens);
234
+ }
235
+ catch (error) {
236
+ reply.status(401).send({
237
+ error: error instanceof Error ? error.message : 'Token refresh failed',
238
+ });
239
+ }
240
+ }
241
+ /**
242
+ * Handle logout requests
243
+ *
244
+ * Revokes the current access token by adding its JTI to the token store.
245
+ * The token is extracted from the Authorization header.
246
+ */
247
+ async handleLogout(request, reply) {
248
+ if (!this.tokenStore) {
249
+ throw new AuthAdapterError('JWT adapter not initialized', 500, 'ADAPTER_NOT_CONFIGURED');
250
+ }
251
+ // Get payload from request (set during getSession in preHandler)
252
+ const requestWithJwt = request;
253
+ const payload = requestWithJwt.__jwtPayload;
254
+ if (payload?.jti) {
255
+ await this.tokenStore.revoke(payload.jti);
256
+ this.debug(`Token ${payload.jti} revoked`);
257
+ }
258
+ reply.status(200).send({ success: true });
259
+ }
260
+ /**
261
+ * Clean up adapter resources
262
+ */
263
+ async cleanup() {
264
+ await super.cleanup();
265
+ this.jwt = null;
266
+ this.tokenStore = null;
267
+ this.userLoader = undefined;
268
+ this.info('JWT adapter cleaned up');
269
+ }
270
+ // ============================================================================
271
+ // Public API Methods
272
+ // ============================================================================
273
+ /**
274
+ * Create a token pair for a user
275
+ *
276
+ * Convenience method that delegates to the underlying JwtManager.
277
+ * Can be accessed via `fastify.jwtManager.createTokenPair()` as well.
278
+ *
279
+ * @param user - The user to create tokens for
280
+ * @param additionalClaims - Custom claims to include in the token
281
+ * @returns Token pair with access and refresh tokens
282
+ *
283
+ * @example
284
+ * ```typescript
285
+ * const tokens = adapter.createTokenPair(user);
286
+ * // { accessToken, refreshToken, expiresIn, tokenType }
287
+ * ```
288
+ */
289
+ createTokenPair(user, additionalClaims) {
290
+ if (!this.jwt) {
291
+ throw new AuthAdapterError('JWT adapter not initialized', 500, 'ADAPTER_NOT_CONFIGURED');
292
+ }
293
+ return this.jwt.createTokenPair(user, additionalClaims);
294
+ }
295
+ /**
296
+ * Get the underlying JwtManager instance
297
+ *
298
+ * Useful for advanced token operations.
299
+ */
300
+ getJwtManager() {
301
+ if (!this.jwt) {
302
+ throw new AuthAdapterError('JWT adapter not initialized', 500, 'ADAPTER_NOT_CONFIGURED');
303
+ }
304
+ return this.jwt;
305
+ }
306
+ /**
307
+ * Get the token store instance
308
+ *
309
+ * Useful for manual token revocation.
310
+ */
311
+ getTokenStore() {
312
+ if (!this.tokenStore) {
313
+ throw new AuthAdapterError('JWT adapter not initialized', 500, 'ADAPTER_NOT_CONFIGURED');
314
+ }
315
+ return this.tokenStore;
316
+ }
317
+ }
318
+ // ============================================================================
319
+ // Factory Function
320
+ // ============================================================================
321
+ /**
322
+ * Create a JWT auth adapter
323
+ *
324
+ * This is the recommended way to create a JWT adapter for use with
325
+ * createAuthAdapterPlugin. Returns both the adapter instance and
326
+ * the configuration for convenience.
327
+ *
328
+ * @param config - JWT adapter configuration (without name, which is auto-set to 'jwt')
329
+ * @returns Object with adapter and config
330
+ *
331
+ * @example
332
+ * ```typescript
333
+ * import { createJwtAdapter } from '@veloxts/auth/adapters/jwt-adapter';
334
+ * import { createAuthAdapterPlugin } from '@veloxts/auth';
335
+ *
336
+ * const { adapter, config } = createJwtAdapter({
337
+ * jwt: {
338
+ * secret: process.env.JWT_SECRET!,
339
+ * accessTokenExpiry: '15m',
340
+ * refreshTokenExpiry: '7d',
341
+ * },
342
+ * userLoader: async (userId) => db.user.findUnique({ where: { id: userId } }),
343
+ * });
344
+ *
345
+ * const authPlugin = createAuthAdapterPlugin({ adapter, config });
346
+ * app.use(authPlugin);
347
+ * ```
348
+ */
349
+ export function createJwtAdapter(config) {
350
+ const adapter = new JwtAdapter();
351
+ const fullConfig = {
352
+ name: 'jwt',
353
+ ...config,
354
+ };
355
+ return { adapter, config: fullConfig };
356
+ }
357
+ // ============================================================================
358
+ // Re-exports
359
+ // ============================================================================
360
+ export { AuthAdapterError } from '../adapter.js';
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Shared decoration utilities for @veloxts/auth
3
+ *
4
+ * This module provides common functionality for decorating Fastify instances
5
+ * and requests with authentication state, shared between the native auth plugin
6
+ * and external auth adapters.
7
+ *
8
+ * @module auth/decoration
9
+ */
10
+ import type { FastifyInstance, FastifyRequest } from 'fastify';
11
+ import type { AuthContext, User } from './types.js';
12
+ /**
13
+ * Symbol used to mark a Fastify instance as having auth already registered.
14
+ *
15
+ * This prevents double-registration of conflicting auth systems (e.g., using
16
+ * both authPlugin and an AuthAdapter on the same server).
17
+ */
18
+ export declare const AUTH_REGISTERED: unique symbol;
19
+ /**
20
+ * Checks for double-registration of auth systems and throws if detected.
21
+ *
22
+ * Call this at the start of both `authPlugin` and `createAuthAdapterPlugin`
23
+ * registration to ensure only one auth system is active.
24
+ *
25
+ * @param fastify - Fastify server instance
26
+ * @param source - Identifier for the auth system being registered (e.g., 'authPlugin', 'adapter:better-auth')
27
+ * @throws {Error} If auth has already been registered by another source
28
+ *
29
+ * @example
30
+ * ```typescript
31
+ * // In authPlugin registration
32
+ * checkDoubleRegistration(fastify, 'authPlugin');
33
+ *
34
+ * // In adapter plugin registration
35
+ * checkDoubleRegistration(fastify, `adapter:${adapter.name}`);
36
+ * ```
37
+ */
38
+ export declare function checkDoubleRegistration(fastify: FastifyInstance, source: string): void;
39
+ /**
40
+ * Decorates a Fastify instance with auth-related request decorators.
41
+ *
42
+ * This function safely adds `auth` and `user` properties to requests,
43
+ * checking if they already exist (idempotent operation).
44
+ *
45
+ * @param fastify - Fastify server instance to decorate
46
+ *
47
+ * @example
48
+ * ```typescript
49
+ * decorateAuth(fastify);
50
+ * // Now all requests will have request.auth and request.user available
51
+ * ```
52
+ */
53
+ export declare function decorateAuth(fastify: FastifyInstance): void;
54
+ /**
55
+ * Sets the auth context and user on a request.
56
+ *
57
+ * This is a type-safe helper that properly casts the request to include
58
+ * auth properties before setting them.
59
+ *
60
+ * @param request - Fastify request object
61
+ * @param auth - Auth context to set
62
+ * @param user - User to set (optional, defaults to auth.user if NativeAuthContext)
63
+ *
64
+ * @example
65
+ * ```typescript
66
+ * setRequestAuth(request, {
67
+ * authMode: 'native',
68
+ * isAuthenticated: true,
69
+ * token: tokenPayload,
70
+ * payload: tokenPayload,
71
+ * }, user);
72
+ * ```
73
+ */
74
+ export declare function setRequestAuth(request: FastifyRequest, auth: AuthContext, user?: User): void;
75
+ /**
76
+ * Gets the current auth context from a request.
77
+ *
78
+ * @param request - Fastify request object
79
+ * @returns The auth context, or undefined if not set
80
+ */
81
+ export declare function getRequestAuth(request: FastifyRequest): AuthContext | undefined;
82
+ /**
83
+ * Gets the current user from a request.
84
+ *
85
+ * @param request - Fastify request object
86
+ * @returns The user, or undefined if not authenticated
87
+ */
88
+ export declare function getRequestUser(request: FastifyRequest): User | undefined;
@@ -0,0 +1,112 @@
1
+ /**
2
+ * Shared decoration utilities for @veloxts/auth
3
+ *
4
+ * This module provides common functionality for decorating Fastify instances
5
+ * and requests with authentication state, shared between the native auth plugin
6
+ * and external auth adapters.
7
+ *
8
+ * @module auth/decoration
9
+ */
10
+ // ============================================================================
11
+ // Registration Protection
12
+ // ============================================================================
13
+ /**
14
+ * Symbol used to mark a Fastify instance as having auth already registered.
15
+ *
16
+ * This prevents double-registration of conflicting auth systems (e.g., using
17
+ * both authPlugin and an AuthAdapter on the same server).
18
+ */
19
+ export const AUTH_REGISTERED = Symbol.for('@veloxts/auth/registered');
20
+ /**
21
+ * Checks for double-registration of auth systems and throws if detected.
22
+ *
23
+ * Call this at the start of both `authPlugin` and `createAuthAdapterPlugin`
24
+ * registration to ensure only one auth system is active.
25
+ *
26
+ * @param fastify - Fastify server instance
27
+ * @param source - Identifier for the auth system being registered (e.g., 'authPlugin', 'adapter:better-auth')
28
+ * @throws {Error} If auth has already been registered by another source
29
+ *
30
+ * @example
31
+ * ```typescript
32
+ * // In authPlugin registration
33
+ * checkDoubleRegistration(fastify, 'authPlugin');
34
+ *
35
+ * // In adapter plugin registration
36
+ * checkDoubleRegistration(fastify, `adapter:${adapter.name}`);
37
+ * ```
38
+ */
39
+ export function checkDoubleRegistration(fastify, source) {
40
+ const decorated = fastify;
41
+ if (decorated[AUTH_REGISTERED]) {
42
+ throw new Error(`Auth already registered by "${decorated[AUTH_REGISTERED]}". ` +
43
+ `Cannot register "${source}". ` +
44
+ `Use either authPlugin OR an AuthAdapter, not both.`);
45
+ }
46
+ decorated[AUTH_REGISTERED] = source;
47
+ }
48
+ /**
49
+ * Decorates a Fastify instance with auth-related request decorators.
50
+ *
51
+ * This function safely adds `auth` and `user` properties to requests,
52
+ * checking if they already exist (idempotent operation).
53
+ *
54
+ * @param fastify - Fastify server instance to decorate
55
+ *
56
+ * @example
57
+ * ```typescript
58
+ * decorateAuth(fastify);
59
+ * // Now all requests will have request.auth and request.user available
60
+ * ```
61
+ */
62
+ export function decorateAuth(fastify) {
63
+ if (!fastify.hasRequestDecorator('auth')) {
64
+ fastify.decorateRequest('auth', undefined);
65
+ }
66
+ if (!fastify.hasRequestDecorator('user')) {
67
+ fastify.decorateRequest('user', undefined);
68
+ }
69
+ }
70
+ /**
71
+ * Sets the auth context and user on a request.
72
+ *
73
+ * This is a type-safe helper that properly casts the request to include
74
+ * auth properties before setting them.
75
+ *
76
+ * @param request - Fastify request object
77
+ * @param auth - Auth context to set
78
+ * @param user - User to set (optional, defaults to auth.user if NativeAuthContext)
79
+ *
80
+ * @example
81
+ * ```typescript
82
+ * setRequestAuth(request, {
83
+ * authMode: 'native',
84
+ * isAuthenticated: true,
85
+ * token: tokenPayload,
86
+ * payload: tokenPayload,
87
+ * }, user);
88
+ * ```
89
+ */
90
+ export function setRequestAuth(request, auth, user) {
91
+ const decoratedRequest = request;
92
+ decoratedRequest.auth = auth;
93
+ decoratedRequest.user = user ?? (auth.isAuthenticated && 'user' in auth ? auth.user : undefined);
94
+ }
95
+ /**
96
+ * Gets the current auth context from a request.
97
+ *
98
+ * @param request - Fastify request object
99
+ * @returns The auth context, or undefined if not set
100
+ */
101
+ export function getRequestAuth(request) {
102
+ return request.auth;
103
+ }
104
+ /**
105
+ * Gets the current user from a request.
106
+ *
107
+ * @param request - Fastify request object
108
+ * @returns The user, or undefined if not authenticated
109
+ */
110
+ export function getRequestUser(request) {
111
+ return request.user;
112
+ }
package/dist/index.d.ts CHANGED
@@ -8,12 +8,9 @@
8
8
  * @module @veloxts/auth
9
9
  */
10
10
  export { AUTH_VERSION } from './plugin.js';
11
- export type { AuthConfig, AuthContext, AuthMiddlewareOptions, GuardDefinition, GuardFunction, HashConfig, JwtConfig,
12
- /**
13
- * @deprecated Use SessionConfig from session.ts for full session management
14
- */
15
- LegacySessionConfig, PolicyAction, PolicyDefinition, RateLimitConfig, TokenPair, TokenPayload, User, } from './types.js';
11
+ export type { AdapterAuthContext, AuthConfig, AuthContext, AuthMiddlewareOptions, BaseAuthContext, GuardDefinition, GuardFunction, HashConfig, JwtConfig, NativeAuthContext, PolicyAction, PolicyDefinition, RateLimitConfig, TokenPair, TokenPayload, User, } from './types.js';
16
12
  export { AuthError } from './types.js';
13
+ export { AUTH_REGISTERED, checkDoubleRegistration, decorateAuth, getRequestAuth, getRequestUser, setRequestAuth, } from './decoration.js';
17
14
  export type { TokenStore } from './jwt.js';
18
15
  export { createInMemoryTokenStore, generateTokenId, isValidTimespan, JwtManager, jwtManager, parseTimeToSeconds, validateTokenExpiration, } from './jwt.js';
19
16
  export type { EnhancedTokenStore, EnhancedTokenStoreOptions } from './token-store.js';
@@ -26,16 +23,18 @@ export { authorize, can, cannot, clearPolicies, createAdminOnlyPolicy, createOwn
26
23
  export { authMiddleware, clearRateLimitStore, rateLimitMiddleware, } from './middleware.js';
27
24
  export type { AuthRateLimitConfig, AuthRateLimiter, AuthRateLimiterConfig } from './rate-limit.js';
28
25
  export { authRateLimiter, clearAuthRateLimitStore, createAuthRateLimiter, stopAuthRateLimitCleanup, } from './rate-limit.js';
29
- export type { AuthPluginOptions, AuthService } from './plugin.js';
30
- export { authPlugin, defaultAuthPlugin, } from './plugin.js';
26
+ export type { AuthPluginOptions, AuthService, JwtAuthOptions } from './plugin.js';
27
+ export { authPlugin, defaultAuthPlugin, jwtAuth, } from './plugin.js';
31
28
  export type { CsrfConfig, CsrfContext, CsrfCookieConfig, CsrfErrorCode, CsrfManager, CsrfMiddlewareOptions, CsrfTokenConfig, CsrfTokenData, CsrfTokenResult, CsrfValidationConfig, } from './csrf.js';
32
29
  export { CsrfError, csrfManager, csrfMiddleware, } from './csrf.js';
33
30
  export type { Session, SessionAuthContext, SessionConfig, SessionContext, SessionCookieConfig, SessionData, SessionExpirationConfig, SessionManager, SessionMiddlewareOptions, SessionStore, StoredSession, } from './session.js';
34
31
  export { inMemorySessionStore, sessionManager, sessionMiddleware, } from './session.js';
35
- export type { AdapterAuthContext, AdapterHttpMethod, AdapterMiddlewareOptions, AdapterRoute, AdapterSession, AdapterSessionResult, AdapterUser, AuthAdapter, AuthAdapterConfig, AuthAdapterErrorCode, AuthAdapterPluginOptions, InferAdapterConfig, } from './adapter.js';
32
+ export type { AdapterHttpMethod, AdapterMiddlewareContext, AdapterMiddlewareOptions, AdapterRoute, AdapterSession, AdapterSessionResult, AdapterUser, AuthAdapter, AuthAdapterConfig, AuthAdapterErrorCode, AuthAdapterPluginOptions, InferAdapterConfig, } from './adapter.js';
36
33
  export { AuthAdapterError, BaseAuthAdapter, createAdapterAuthMiddleware, createAuthAdapterPlugin, defineAuthAdapter, isAuthAdapter, } from './adapter.js';
37
34
  export type { BetterAuthAdapterConfig, BetterAuthApi, BetterAuthHandler, BetterAuthInstance, BetterAuthSession, BetterAuthSessionResult, BetterAuthUser, } from './adapters/better-auth.js';
38
35
  export { BetterAuthAdapter, createBetterAuthAdapter } from './adapters/better-auth.js';
36
+ export type { JwtAdapterConfig } from './adapters/jwt-adapter.js';
37
+ export { createJwtAdapter, JwtAdapter } from './adapters/jwt-adapter.js';
39
38
  export type { PasswordPolicyConfig, PasswordValidationResult, UserInfo, } from './password-policy.js';
40
39
  export { checkPasswordBreach, checkPasswordStrength, isCommonPassword, PasswordPolicy, PasswordStrength, passwordPolicy, } from './password-policy.js';
41
40
  /**
package/dist/index.js CHANGED
@@ -12,6 +12,10 @@
12
12
  // ============================================================================
13
13
  export { AUTH_VERSION } from './plugin.js';
14
14
  export { AuthError } from './types.js';
15
+ // ============================================================================
16
+ // Decoration Utilities
17
+ // ============================================================================
18
+ export { AUTH_REGISTERED, checkDoubleRegistration, decorateAuth, getRequestAuth, getRequestUser, setRequestAuth, } from './decoration.js';
15
19
  export { createInMemoryTokenStore, generateTokenId, isValidTimespan, JwtManager, jwtManager, parseTimeToSeconds, validateTokenExpiration, } from './jwt.js';
16
20
  export { createEnhancedTokenStore, DEFAULT_ALLOWED_ROLES, parseUserRoles, } from './token-store.js';
17
21
  export { authenticatedNarrow, hasRoleNarrow } from './guards-narrowing.js';
@@ -54,7 +58,7 @@ authRateLimiter,
54
58
  clearAuthRateLimitStore,
55
59
  // Factory
56
60
  createAuthRateLimiter, stopAuthRateLimitCleanup, } from './rate-limit.js';
57
- export { authPlugin, defaultAuthPlugin, } from './plugin.js';
61
+ export { authPlugin, defaultAuthPlugin, jwtAuth, } from './plugin.js';
58
62
  export { CsrfError, csrfManager, csrfMiddleware, } from './csrf.js';
59
63
  export { inMemorySessionStore, sessionManager, sessionMiddleware, } from './session.js';
60
64
  export {
@@ -67,6 +71,7 @@ createAdapterAuthMiddleware, createAuthAdapterPlugin, defineAuthAdapter,
67
71
  // Type guard
68
72
  isAuthAdapter, } from './adapter.js';
69
73
  export { BetterAuthAdapter, createBetterAuthAdapter } from './adapters/better-auth.js';
74
+ export { createJwtAdapter, JwtAdapter } from './adapters/jwt-adapter.js';
70
75
  export { checkPasswordBreach, checkPasswordStrength, isCommonPassword, PasswordPolicy, PasswordStrength, passwordPolicy, } from './password-policy.js';
71
76
  // ============================================================================
72
77
  // Dependency Injection
@@ -5,7 +5,7 @@
5
5
  import type { BaseContext } from '@veloxts/core';
6
6
  import type { MiddlewareFunction } from '@veloxts/router';
7
7
  import { JwtManager } from './jwt.js';
8
- import type { AuthConfig, AuthContext, AuthMiddlewareOptions, GuardDefinition, User } from './types.js';
8
+ import type { AuthConfig, AuthMiddlewareOptions, GuardDefinition, NativeAuthContext, User } from './types.js';
9
9
  /**
10
10
  * Creates an authentication middleware for procedures (succinct API)
11
11
  *
@@ -46,15 +46,15 @@ import type { AuthConfig, AuthContext, AuthMiddlewareOptions, GuardDefinition, U
46
46
  export declare function authMiddleware(config: AuthConfig): {
47
47
  middleware: <TInput, TContext extends BaseContext, TOutput>(options?: AuthMiddlewareOptions) => MiddlewareFunction<TInput, TContext, TContext & {
48
48
  user?: User;
49
- auth: AuthContext;
49
+ auth: NativeAuthContext;
50
50
  }, TOutput>;
51
51
  requireAuth: <TInput, TContext extends BaseContext, TOutput>(guards?: Array<GuardDefinition | string>) => MiddlewareFunction<TInput, TContext, TContext & {
52
52
  user: User;
53
- auth: AuthContext;
53
+ auth: NativeAuthContext;
54
54
  }, TOutput>;
55
55
  optionalAuth: <TInput, TContext extends BaseContext, TOutput>() => MiddlewareFunction<TInput, TContext, TContext & {
56
56
  user?: User;
57
- auth: AuthContext;
57
+ auth: NativeAuthContext;
58
58
  }, TOutput>;
59
59
  jwt: JwtManager;
60
60
  };
@@ -61,8 +61,10 @@ export function authMiddleware(config) {
61
61
  if (options.optional) {
62
62
  // Optional auth - continue without user
63
63
  const authContext = {
64
+ authMode: 'native',
64
65
  user: undefined,
65
66
  token: undefined,
67
+ payload: undefined,
66
68
  isAuthenticated: false,
67
69
  };
68
70
  return next({
@@ -85,8 +87,10 @@ export function authMiddleware(config) {
85
87
  if (options.optional) {
86
88
  // Invalid token with optional auth - continue without user
87
89
  const authContext = {
90
+ authMode: 'native',
88
91
  user: undefined,
89
92
  token: undefined,
93
+ payload: undefined,
90
94
  isAuthenticated: false,
91
95
  };
92
96
  return next({
@@ -123,8 +127,10 @@ export function authMiddleware(config) {
123
127
  }
124
128
  // Create auth context
125
129
  const authContext = {
130
+ authMode: 'native',
126
131
  user: user ?? undefined,
127
- token: payload,
132
+ token,
133
+ payload,
128
134
  isAuthenticated: !!user,
129
135
  };
130
136
  // Build extended context