@veloxts/auth 0.6.69 → 0.6.70
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 +40 -0
- package/dist/adapter.d.ts +10 -4
- package/dist/adapter.js +15 -9
- package/dist/adapters/index.d.ts +26 -6
- package/dist/adapters/index.js +25 -7
- package/dist/adapters/jwt-adapter.d.ts +261 -0
- package/dist/adapters/jwt-adapter.js +360 -0
- package/dist/decoration.d.ts +88 -0
- package/dist/decoration.js +112 -0
- package/dist/index.d.ts +7 -8
- package/dist/index.js +6 -1
- package/dist/middleware.d.ts +4 -4
- package/dist/middleware.js +7 -1
- package/dist/plugin.d.ts +70 -5
- package/dist/plugin.js +172 -62
- package/dist/providers.js +3 -1
- package/dist/types.d.ts +70 -33
- package/package.json +5 -5
package/dist/plugin.d.ts
CHANGED
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* VeloxTS Auth Plugin
|
|
3
|
-
*
|
|
3
|
+
*
|
|
4
|
+
* Unified authentication using the adapter pattern internally.
|
|
5
|
+
* This plugin provides a convenient API while using JwtAdapter under the hood.
|
|
6
|
+
*
|
|
4
7
|
* @module auth/plugin
|
|
5
8
|
*/
|
|
6
9
|
import type { Container, VeloxPlugin } from '@veloxts/core';
|
|
10
|
+
import type { AuthAdapterPluginOptions } from './adapter.js';
|
|
11
|
+
import type { JwtAdapterConfig } from './adapters/jwt-adapter.js';
|
|
7
12
|
import { PasswordHasher } from './hash.js';
|
|
8
|
-
import { JwtManager } from './jwt.js';
|
|
13
|
+
import type { JwtManager, TokenStore } from './jwt.js';
|
|
9
14
|
import { authMiddleware } from './middleware.js';
|
|
10
|
-
import type {
|
|
15
|
+
import type { AdapterAuthContext, AuthConfig, TokenPair, User } from './types.js';
|
|
11
16
|
/** Auth package version */
|
|
12
17
|
export declare const AUTH_VERSION: string;
|
|
13
18
|
/**
|
|
@@ -59,6 +64,10 @@ export interface AuthService {
|
|
|
59
64
|
* Password hasher for secure password storage
|
|
60
65
|
*/
|
|
61
66
|
hasher: PasswordHasher;
|
|
67
|
+
/**
|
|
68
|
+
* Token store for revocation (if configured)
|
|
69
|
+
*/
|
|
70
|
+
tokenStore?: TokenStore;
|
|
62
71
|
/**
|
|
63
72
|
* Creates a token pair for a user
|
|
64
73
|
*/
|
|
@@ -66,7 +75,7 @@ export interface AuthService {
|
|
|
66
75
|
/**
|
|
67
76
|
* Verifies an access token and returns the auth context
|
|
68
77
|
*/
|
|
69
|
-
verifyToken(token: string):
|
|
78
|
+
verifyToken(token: string): AdapterAuthContext;
|
|
70
79
|
/**
|
|
71
80
|
* Refreshes tokens using a refresh token
|
|
72
81
|
*/
|
|
@@ -76,6 +85,7 @@ export interface AuthService {
|
|
|
76
85
|
*/
|
|
77
86
|
middleware: ReturnType<typeof authMiddleware>;
|
|
78
87
|
}
|
|
88
|
+
import type { AuthContext } from './types.js';
|
|
79
89
|
declare module 'fastify' {
|
|
80
90
|
interface FastifyInstance {
|
|
81
91
|
auth: AuthService;
|
|
@@ -86,7 +96,10 @@ declare module 'fastify' {
|
|
|
86
96
|
}
|
|
87
97
|
}
|
|
88
98
|
/**
|
|
89
|
-
* Creates the VeloxTS auth plugin
|
|
99
|
+
* Creates the VeloxTS auth plugin
|
|
100
|
+
*
|
|
101
|
+
* **Internally uses the JwtAdapter** for unified architecture.
|
|
102
|
+
* All authentication in VeloxTS uses the adapter pattern.
|
|
90
103
|
*
|
|
91
104
|
* This plugin provides:
|
|
92
105
|
* - JWT token management (access + refresh tokens)
|
|
@@ -142,3 +155,55 @@ export declare function authPlugin(options: AuthPluginOptions): VeloxPlugin<Auth
|
|
|
142
155
|
* ```
|
|
143
156
|
*/
|
|
144
157
|
export declare function defaultAuthPlugin(): VeloxPlugin<AuthPluginOptions>;
|
|
158
|
+
/**
|
|
159
|
+
* Options for jwtAuth convenience function
|
|
160
|
+
*
|
|
161
|
+
* Omits the 'name' field since it's auto-set to 'jwt'.
|
|
162
|
+
*/
|
|
163
|
+
export type JwtAuthOptions = Omit<JwtAdapterConfig, 'name'>;
|
|
164
|
+
/**
|
|
165
|
+
* Creates JWT auth using the adapter pattern directly
|
|
166
|
+
*
|
|
167
|
+
* This is an alternative to `authPlugin` that gives you more control over
|
|
168
|
+
* adapter-specific features like built-in routes and route prefixes.
|
|
169
|
+
*
|
|
170
|
+
* **Note:** Both `authPlugin` and `jwtAuth` now use the adapter pattern internally.
|
|
171
|
+
* Choose based on your needs:
|
|
172
|
+
*
|
|
173
|
+
* **Use `authPlugin` when:**
|
|
174
|
+
* - You need the `authMiddleware` factory for fine-grained procedure control
|
|
175
|
+
* - You're using DI container integration
|
|
176
|
+
* - You want the familiar VeloxTS auth API (`fastify.auth.createTokens()`, etc.)
|
|
177
|
+
*
|
|
178
|
+
* **Use `jwtAuth` when:**
|
|
179
|
+
* - You want built-in `/api/auth/refresh` and `/api/auth/logout` routes
|
|
180
|
+
* - You're building a pure adapter-based setup
|
|
181
|
+
* - You want direct access to adapter features
|
|
182
|
+
*
|
|
183
|
+
* @param options - JWT adapter configuration
|
|
184
|
+
* @returns VeloxPlugin ready for registration
|
|
185
|
+
*
|
|
186
|
+
* @example
|
|
187
|
+
* ```typescript
|
|
188
|
+
* import { jwtAuth } from '@veloxts/auth';
|
|
189
|
+
*
|
|
190
|
+
* // With built-in routes
|
|
191
|
+
* app.use(jwtAuth({
|
|
192
|
+
* jwt: {
|
|
193
|
+
* secret: process.env.JWT_SECRET!,
|
|
194
|
+
* accessTokenExpiry: '15m',
|
|
195
|
+
* refreshTokenExpiry: '7d',
|
|
196
|
+
* },
|
|
197
|
+
* userLoader: async (userId) => {
|
|
198
|
+
* return db.user.findUnique({ where: { id: userId } });
|
|
199
|
+
* },
|
|
200
|
+
* enableRoutes: true, // Mount /api/auth/refresh and /api/auth/logout
|
|
201
|
+
* routePrefix: '/api/auth',
|
|
202
|
+
* }));
|
|
203
|
+
*
|
|
204
|
+
* // Access JWT utilities via fastify
|
|
205
|
+
* const tokens = fastify.jwtManager!.createTokenPair(user);
|
|
206
|
+
* await fastify.tokenStore!.revoke(tokenId);
|
|
207
|
+
* ```
|
|
208
|
+
*/
|
|
209
|
+
export declare function jwtAuth(options: JwtAuthOptions): VeloxPlugin<AuthAdapterPluginOptions<JwtAdapterConfig>>;
|
package/dist/plugin.js
CHANGED
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* VeloxTS Auth Plugin
|
|
3
|
-
*
|
|
3
|
+
*
|
|
4
|
+
* Unified authentication using the adapter pattern internally.
|
|
5
|
+
* This plugin provides a convenient API while using JwtAdapter under the hood.
|
|
6
|
+
*
|
|
4
7
|
* @module auth/plugin
|
|
5
8
|
*/
|
|
6
9
|
import { createRequire } from 'node:module';
|
|
10
|
+
import { createAuthAdapterPlugin } from './adapter.js';
|
|
11
|
+
import { createJwtAdapter } from './adapters/jwt-adapter.js';
|
|
12
|
+
import { checkDoubleRegistration, decorateAuth } from './decoration.js';
|
|
7
13
|
import { PasswordHasher } from './hash.js';
|
|
8
|
-
import { JwtManager } from './jwt.js';
|
|
9
14
|
import { authMiddleware } from './middleware.js';
|
|
10
15
|
import { registerAuthProviders } from './providers.js';
|
|
11
16
|
import { AUTH_SERVICE } from './tokens.js';
|
|
@@ -18,7 +23,26 @@ export const AUTH_VERSION = packageJson.version ?? '0.0.0-unknown';
|
|
|
18
23
|
// Auth Plugin
|
|
19
24
|
// ============================================================================
|
|
20
25
|
/**
|
|
21
|
-
*
|
|
26
|
+
* Wraps isTokenRevoked callback as a TokenStore interface
|
|
27
|
+
* @internal
|
|
28
|
+
*/
|
|
29
|
+
function createCallbackTokenStore(isTokenRevoked) {
|
|
30
|
+
return {
|
|
31
|
+
revoke: () => {
|
|
32
|
+
// No-op: callback-based stores don't support revocation
|
|
33
|
+
// Users must implement their own revocation mechanism
|
|
34
|
+
},
|
|
35
|
+
isRevoked: isTokenRevoked,
|
|
36
|
+
clear: () => {
|
|
37
|
+
// No-op
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Creates the VeloxTS auth plugin
|
|
43
|
+
*
|
|
44
|
+
* **Internally uses the JwtAdapter** for unified architecture.
|
|
45
|
+
* All authentication in VeloxTS uses the adapter pattern.
|
|
22
46
|
*
|
|
23
47
|
* This plugin provides:
|
|
24
48
|
* - JWT token management (access + refresh tokens)
|
|
@@ -60,43 +84,103 @@ export function authPlugin(options) {
|
|
|
60
84
|
return {
|
|
61
85
|
name: '@veloxts/auth',
|
|
62
86
|
version: AUTH_VERSION,
|
|
63
|
-
// No explicit dependencies - works with any Fastify instance
|
|
64
|
-
// The plugin decorates Fastify with auth functionality
|
|
65
87
|
async register(server, _opts) {
|
|
66
88
|
const config = { ...options, ..._opts };
|
|
67
89
|
const { debug = false, container } = config;
|
|
90
|
+
// Prevent double-registration of auth systems
|
|
91
|
+
checkDoubleRegistration(server, 'authPlugin');
|
|
68
92
|
if (debug) {
|
|
69
|
-
server.log.info('Registering @veloxts/auth plugin');
|
|
93
|
+
server.log.info('Registering @veloxts/auth plugin (adapter-based)');
|
|
70
94
|
}
|
|
71
|
-
|
|
95
|
+
// DI-enabled path: Use container for service resolution
|
|
72
96
|
if (container) {
|
|
73
|
-
// DI-enabled path: Register providers and resolve from container
|
|
74
97
|
if (debug) {
|
|
75
98
|
server.log.info('Using DI container for auth services');
|
|
76
99
|
}
|
|
77
100
|
registerAuthProviders(container, config);
|
|
78
|
-
authService = container.resolve(AUTH_SERVICE);
|
|
101
|
+
const authService = container.resolve(AUTH_SERVICE);
|
|
102
|
+
server.decorate('auth', authService);
|
|
103
|
+
// Still need to register the adapter plugin for session loading
|
|
104
|
+
const { adapter, config: adapterConfig } = createJwtAdapter({
|
|
105
|
+
jwt: config.jwt,
|
|
106
|
+
userLoader: config.userLoader,
|
|
107
|
+
tokenStore: config.isTokenRevoked
|
|
108
|
+
? createCallbackTokenStore(config.isTokenRevoked)
|
|
109
|
+
: undefined,
|
|
110
|
+
enableRoutes: false, // Don't mount routes when using authPlugin
|
|
111
|
+
debug,
|
|
112
|
+
});
|
|
113
|
+
// Initialize the adapter for session loading
|
|
114
|
+
await adapter.initialize(server, adapterConfig);
|
|
115
|
+
// Decorate requests with auth context
|
|
116
|
+
decorateAuth(server);
|
|
117
|
+
// Add preHandler hook for session loading
|
|
118
|
+
server.addHook('preHandler', async (request) => {
|
|
119
|
+
if (config.autoExtract === false)
|
|
120
|
+
return;
|
|
121
|
+
const session = await adapter.getSession(request);
|
|
122
|
+
if (session) {
|
|
123
|
+
const user = {
|
|
124
|
+
id: session.user.id,
|
|
125
|
+
email: session.user.email,
|
|
126
|
+
...(session.user.emailVerified !== undefined && {
|
|
127
|
+
emailVerified: session.user.emailVerified,
|
|
128
|
+
}),
|
|
129
|
+
...session.user.providerData,
|
|
130
|
+
};
|
|
131
|
+
const authContext = {
|
|
132
|
+
authMode: 'adapter',
|
|
133
|
+
isAuthenticated: true,
|
|
134
|
+
user,
|
|
135
|
+
providerId: 'jwt',
|
|
136
|
+
session: session.session.providerData,
|
|
137
|
+
};
|
|
138
|
+
request.auth = authContext;
|
|
139
|
+
request.user = user;
|
|
140
|
+
}
|
|
141
|
+
});
|
|
79
142
|
}
|
|
80
143
|
else {
|
|
81
|
-
//
|
|
82
|
-
|
|
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();
|
|
83
163
|
const hasher = new PasswordHasher(config.hash);
|
|
84
164
|
const authMw = authMiddleware(config);
|
|
85
|
-
|
|
165
|
+
// Build AuthService from adapter
|
|
166
|
+
const authService = {
|
|
86
167
|
jwt,
|
|
87
168
|
hasher,
|
|
169
|
+
tokenStore: adapter.getTokenStore(),
|
|
88
170
|
createTokens(user, additionalClaims) {
|
|
89
171
|
return jwt.createTokenPair(user, additionalClaims);
|
|
90
172
|
},
|
|
91
173
|
verifyToken(token) {
|
|
92
174
|
const payload = jwt.verifyToken(token);
|
|
93
175
|
return {
|
|
176
|
+
authMode: 'adapter',
|
|
94
177
|
user: {
|
|
95
178
|
id: payload.sub,
|
|
96
179
|
email: payload.email,
|
|
97
180
|
},
|
|
98
|
-
token: payload,
|
|
99
181
|
isAuthenticated: true,
|
|
182
|
+
providerId: 'jwt',
|
|
183
|
+
session: { token, payload },
|
|
100
184
|
};
|
|
101
185
|
},
|
|
102
186
|
refreshTokens(refreshToken) {
|
|
@@ -107,56 +191,33 @@ export function authPlugin(options) {
|
|
|
107
191
|
},
|
|
108
192
|
middleware: authMw,
|
|
109
193
|
};
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
if (config.userLoader) {
|
|
135
|
-
user = await config.userLoader(payload.sub);
|
|
136
|
-
}
|
|
137
|
-
else {
|
|
138
|
-
user = {
|
|
139
|
-
id: payload.sub,
|
|
140
|
-
email: payload.email,
|
|
141
|
-
};
|
|
142
|
-
}
|
|
143
|
-
if (user) {
|
|
144
|
-
request.auth = {
|
|
145
|
-
user,
|
|
146
|
-
token: payload,
|
|
147
|
-
isAuthenticated: true,
|
|
148
|
-
};
|
|
149
|
-
request.user = user;
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
catch {
|
|
153
|
-
// Invalid token - silently ignore (optional auth)
|
|
154
|
-
if (debug) {
|
|
155
|
-
server.log.debug('Invalid auth token in request');
|
|
156
|
-
}
|
|
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;
|
|
157
218
|
}
|
|
158
|
-
}
|
|
159
|
-
}
|
|
219
|
+
});
|
|
220
|
+
}
|
|
160
221
|
}
|
|
161
222
|
// Add shutdown hook for cleanup
|
|
162
223
|
server.addHook('onClose', async () => {
|
|
@@ -196,3 +257,52 @@ export function defaultAuthPlugin() {
|
|
|
196
257
|
jwt: { secret },
|
|
197
258
|
});
|
|
198
259
|
}
|
|
260
|
+
/**
|
|
261
|
+
* Creates JWT auth using the adapter pattern directly
|
|
262
|
+
*
|
|
263
|
+
* This is an alternative to `authPlugin` that gives you more control over
|
|
264
|
+
* adapter-specific features like built-in routes and route prefixes.
|
|
265
|
+
*
|
|
266
|
+
* **Note:** Both `authPlugin` and `jwtAuth` now use the adapter pattern internally.
|
|
267
|
+
* Choose based on your needs:
|
|
268
|
+
*
|
|
269
|
+
* **Use `authPlugin` when:**
|
|
270
|
+
* - You need the `authMiddleware` factory for fine-grained procedure control
|
|
271
|
+
* - You're using DI container integration
|
|
272
|
+
* - You want the familiar VeloxTS auth API (`fastify.auth.createTokens()`, etc.)
|
|
273
|
+
*
|
|
274
|
+
* **Use `jwtAuth` when:**
|
|
275
|
+
* - You want built-in `/api/auth/refresh` and `/api/auth/logout` routes
|
|
276
|
+
* - You're building a pure adapter-based setup
|
|
277
|
+
* - You want direct access to adapter features
|
|
278
|
+
*
|
|
279
|
+
* @param options - JWT adapter configuration
|
|
280
|
+
* @returns VeloxPlugin ready for registration
|
|
281
|
+
*
|
|
282
|
+
* @example
|
|
283
|
+
* ```typescript
|
|
284
|
+
* import { jwtAuth } from '@veloxts/auth';
|
|
285
|
+
*
|
|
286
|
+
* // With built-in routes
|
|
287
|
+
* app.use(jwtAuth({
|
|
288
|
+
* jwt: {
|
|
289
|
+
* secret: process.env.JWT_SECRET!,
|
|
290
|
+
* accessTokenExpiry: '15m',
|
|
291
|
+
* refreshTokenExpiry: '7d',
|
|
292
|
+
* },
|
|
293
|
+
* userLoader: async (userId) => {
|
|
294
|
+
* return db.user.findUnique({ where: { id: userId } });
|
|
295
|
+
* },
|
|
296
|
+
* enableRoutes: true, // Mount /api/auth/refresh and /api/auth/logout
|
|
297
|
+
* routePrefix: '/api/auth',
|
|
298
|
+
* }));
|
|
299
|
+
*
|
|
300
|
+
* // Access JWT utilities via fastify
|
|
301
|
+
* const tokens = fastify.jwtManager!.createTokenPair(user);
|
|
302
|
+
* await fastify.tokenStore!.revoke(tokenId);
|
|
303
|
+
* ```
|
|
304
|
+
*/
|
|
305
|
+
export function jwtAuth(options) {
|
|
306
|
+
const { adapter, config } = createJwtAdapter(options);
|
|
307
|
+
return createAuthAdapterPlugin({ adapter, config });
|
|
308
|
+
}
|
package/dist/providers.js
CHANGED
|
@@ -109,12 +109,14 @@ export function authServiceProvider() {
|
|
|
109
109
|
verifyToken(token) {
|
|
110
110
|
const payload = jwt.verifyToken(token);
|
|
111
111
|
return {
|
|
112
|
+
authMode: 'adapter',
|
|
112
113
|
user: {
|
|
113
114
|
id: payload.sub,
|
|
114
115
|
email: payload.email,
|
|
115
116
|
},
|
|
116
|
-
token: payload,
|
|
117
117
|
isAuthenticated: true,
|
|
118
|
+
providerId: 'jwt',
|
|
119
|
+
session: { token, payload },
|
|
118
120
|
};
|
|
119
121
|
},
|
|
120
122
|
refreshTokens(refreshToken) {
|
package/dist/types.d.ts
CHANGED
|
@@ -24,25 +24,36 @@ export declare class AuthError extends Error {
|
|
|
24
24
|
/**
|
|
25
25
|
* Base user interface for authenticated requests
|
|
26
26
|
*
|
|
27
|
-
* Applications should extend this via declaration merging
|
|
27
|
+
* Applications should extend this via declaration merging to add
|
|
28
|
+
* custom properties without using index signatures:
|
|
29
|
+
*
|
|
28
30
|
* @example
|
|
29
31
|
* ```typescript
|
|
30
32
|
* declare module '@veloxts/auth' {
|
|
31
33
|
* interface User {
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
+
* name?: string;
|
|
35
|
+
* avatarUrl?: string;
|
|
36
|
+
* tenantId?: string;
|
|
34
37
|
* }
|
|
35
38
|
* }
|
|
36
39
|
* ```
|
|
40
|
+
*
|
|
41
|
+
* This approach provides:
|
|
42
|
+
* - Full type safety (no implicit `unknown` properties)
|
|
43
|
+
* - Better IDE autocomplete
|
|
44
|
+
* - Compile-time errors for typos
|
|
37
45
|
*/
|
|
38
46
|
export interface User {
|
|
47
|
+
/** Unique user identifier */
|
|
39
48
|
id: string;
|
|
49
|
+
/** User email address */
|
|
40
50
|
email: string;
|
|
51
|
+
/** Whether the user's email has been verified */
|
|
52
|
+
emailVerified?: boolean;
|
|
41
53
|
/** User roles for authorization */
|
|
42
54
|
roles?: string[];
|
|
43
55
|
/** User permissions for fine-grained access control */
|
|
44
56
|
permissions?: string[];
|
|
45
|
-
[key: string]: unknown;
|
|
46
57
|
}
|
|
47
58
|
/**
|
|
48
59
|
* Payload stored in JWT tokens
|
|
@@ -120,25 +131,6 @@ export interface HashConfig {
|
|
|
120
131
|
/** argon2 parallelism (default: 4) */
|
|
121
132
|
argon2Parallelism?: number;
|
|
122
133
|
}
|
|
123
|
-
/**
|
|
124
|
-
* Legacy session cookie configuration (used by AuthConfig)
|
|
125
|
-
*
|
|
126
|
-
* @deprecated Use SessionConfig from session.ts for full session management
|
|
127
|
-
*/
|
|
128
|
-
export interface LegacySessionConfig {
|
|
129
|
-
/** Cookie name (default: 'velox.session') */
|
|
130
|
-
cookieName?: string;
|
|
131
|
-
/** Session expiration in seconds (default: 86400 = 24h) */
|
|
132
|
-
maxAge?: number;
|
|
133
|
-
/** Cookie path (default: '/') */
|
|
134
|
-
path?: string;
|
|
135
|
-
/** HTTP only flag (default: true) */
|
|
136
|
-
httpOnly?: boolean;
|
|
137
|
-
/** Secure flag - use HTTPS only (default: true in production) */
|
|
138
|
-
secure?: boolean;
|
|
139
|
-
/** SameSite policy (default: 'lax') */
|
|
140
|
-
sameSite?: 'strict' | 'lax' | 'none';
|
|
141
|
-
}
|
|
142
134
|
/**
|
|
143
135
|
* Rate limiting configuration
|
|
144
136
|
*/
|
|
@@ -162,11 +154,6 @@ export interface AuthConfig {
|
|
|
162
154
|
jwt: JwtConfig;
|
|
163
155
|
/** Password hashing configuration */
|
|
164
156
|
hash?: HashConfig;
|
|
165
|
-
/**
|
|
166
|
-
* Legacy session cookie configuration
|
|
167
|
-
* @deprecated Use createSessionMiddleware from session.ts for full session management
|
|
168
|
-
*/
|
|
169
|
-
session?: LegacySessionConfig;
|
|
170
157
|
/** Rate limiting configuration */
|
|
171
158
|
rateLimit?: RateLimitConfig;
|
|
172
159
|
/**
|
|
@@ -177,6 +164,7 @@ export interface AuthConfig {
|
|
|
177
164
|
/**
|
|
178
165
|
* Token blacklist checker - check if token is revoked
|
|
179
166
|
* Called on every authenticated request
|
|
167
|
+
* @deprecated Use `tokenStore` with TokenStore interface instead
|
|
180
168
|
*/
|
|
181
169
|
isTokenRevoked?: (tokenId: string) => Promise<boolean>;
|
|
182
170
|
/**
|
|
@@ -234,16 +222,65 @@ export interface AuthMiddlewareOptions {
|
|
|
234
222
|
guards?: Array<GuardDefinition | string>;
|
|
235
223
|
}
|
|
236
224
|
/**
|
|
237
|
-
*
|
|
225
|
+
* Base auth context shared by all auth modes
|
|
226
|
+
*/
|
|
227
|
+
export interface BaseAuthContext {
|
|
228
|
+
/** Whether the request is authenticated */
|
|
229
|
+
isAuthenticated: boolean;
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Auth context for native JWT authentication (authPlugin)
|
|
233
|
+
*
|
|
234
|
+
* This context is set when using the built-in authPlugin with JWT tokens.
|
|
235
|
+
* Provides access to the decoded token payload.
|
|
238
236
|
*/
|
|
239
|
-
export interface
|
|
237
|
+
export interface NativeAuthContext extends BaseAuthContext {
|
|
238
|
+
/** Discriminant for native JWT auth mode */
|
|
239
|
+
authMode: 'native';
|
|
240
240
|
/** Authenticated user (undefined if optional auth and no token) */
|
|
241
241
|
user?: User;
|
|
242
|
+
/** Raw JWT token string (if extracted from request) */
|
|
243
|
+
token?: string;
|
|
242
244
|
/** Decoded token payload */
|
|
243
|
-
|
|
244
|
-
/** Check if user is authenticated */
|
|
245
|
-
isAuthenticated: boolean;
|
|
245
|
+
payload?: TokenPayload;
|
|
246
246
|
}
|
|
247
|
+
/**
|
|
248
|
+
* Auth context for external authentication adapters
|
|
249
|
+
*
|
|
250
|
+
* This context is set when using an AuthAdapter (BetterAuth, Clerk, Auth0, etc.).
|
|
251
|
+
* Provides access to the provider's session data.
|
|
252
|
+
*/
|
|
253
|
+
export interface AdapterAuthContext extends BaseAuthContext {
|
|
254
|
+
/** Discriminant for adapter auth mode */
|
|
255
|
+
authMode: 'adapter';
|
|
256
|
+
/** Authenticated user (undefined if not authenticated) */
|
|
257
|
+
user?: User;
|
|
258
|
+
/** Provider identifier (e.g., 'better-auth', 'clerk', 'auth0') */
|
|
259
|
+
providerId: string;
|
|
260
|
+
/** Provider-specific session data */
|
|
261
|
+
session?: unknown;
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Authenticated request context extension
|
|
265
|
+
*
|
|
266
|
+
* This is a discriminated union based on `authMode`:
|
|
267
|
+
* - `'native'`: Built-in JWT authentication via authPlugin
|
|
268
|
+
* - `'adapter'`: External provider via AuthAdapter
|
|
269
|
+
*
|
|
270
|
+
* Use the `authMode` discriminant for type-safe access to mode-specific properties:
|
|
271
|
+
*
|
|
272
|
+
* @example
|
|
273
|
+
* ```typescript
|
|
274
|
+
* if (ctx.auth?.authMode === 'native') {
|
|
275
|
+
* // Access JWT-specific properties
|
|
276
|
+
* console.log(ctx.auth.payload?.sub);
|
|
277
|
+
* } else if (ctx.auth?.authMode === 'adapter') {
|
|
278
|
+
* // Access adapter-specific properties
|
|
279
|
+
* console.log(ctx.auth.providerId);
|
|
280
|
+
* }
|
|
281
|
+
* ```
|
|
282
|
+
*/
|
|
283
|
+
export type AuthContext = NativeAuthContext | AdapterAuthContext;
|
|
247
284
|
declare module '@veloxts/core' {
|
|
248
285
|
interface BaseContext {
|
|
249
286
|
/** Auth context - available when auth middleware is used */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@veloxts/auth",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.70",
|
|
4
4
|
"description": "Authentication and authorization system for VeloxTS framework",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -57,8 +57,8 @@
|
|
|
57
57
|
"dependencies": {
|
|
58
58
|
"@fastify/cookie": "11.0.2",
|
|
59
59
|
"fastify": "5.6.2",
|
|
60
|
-
"@veloxts/
|
|
61
|
-
"@veloxts/
|
|
60
|
+
"@veloxts/router": "0.6.70",
|
|
61
|
+
"@veloxts/core": "0.6.70"
|
|
62
62
|
},
|
|
63
63
|
"peerDependencies": {
|
|
64
64
|
"argon2": ">=0.30.0",
|
|
@@ -82,8 +82,8 @@
|
|
|
82
82
|
"fastify-plugin": "5.1.0",
|
|
83
83
|
"typescript": "5.9.3",
|
|
84
84
|
"vitest": "4.0.16",
|
|
85
|
-
"@veloxts/testing": "0.6.
|
|
86
|
-
"@veloxts/validation": "0.6.
|
|
85
|
+
"@veloxts/testing": "0.6.70",
|
|
86
|
+
"@veloxts/validation": "0.6.70"
|
|
87
87
|
},
|
|
88
88
|
"keywords": [
|
|
89
89
|
"velox",
|