@veloxts/auth 0.3.3 → 0.3.5

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.
Files changed (66) hide show
  1. package/README.md +1157 -30
  2. package/dist/__integration__/fixtures.d.ts +41 -0
  3. package/dist/__integration__/fixtures.d.ts.map +1 -0
  4. package/dist/__integration__/fixtures.js +79 -0
  5. package/dist/__integration__/fixtures.js.map +1 -0
  6. package/dist/__integration__/setup.d.ts +26 -0
  7. package/dist/__integration__/setup.d.ts.map +1 -0
  8. package/dist/__integration__/setup.js +28 -0
  9. package/dist/__integration__/setup.js.map +1 -0
  10. package/dist/adapter.d.ts +710 -0
  11. package/dist/adapter.d.ts.map +1 -0
  12. package/dist/adapter.js +581 -0
  13. package/dist/adapter.js.map +1 -0
  14. package/dist/adapters/better-auth.d.ts +271 -0
  15. package/dist/adapters/better-auth.d.ts.map +1 -0
  16. package/dist/adapters/better-auth.js +341 -0
  17. package/dist/adapters/better-auth.js.map +1 -0
  18. package/dist/adapters/index.d.ts +28 -0
  19. package/dist/adapters/index.d.ts.map +1 -0
  20. package/dist/adapters/index.js +28 -0
  21. package/dist/adapters/index.js.map +1 -0
  22. package/dist/csrf.d.ts +300 -0
  23. package/dist/csrf.d.ts.map +1 -0
  24. package/dist/csrf.js +402 -0
  25. package/dist/csrf.js.map +1 -0
  26. package/dist/guards.d.ts +142 -0
  27. package/dist/guards.d.ts.map +1 -0
  28. package/dist/guards.js +259 -0
  29. package/dist/guards.js.map +1 -0
  30. package/dist/hash.d.ts +91 -0
  31. package/dist/hash.d.ts.map +1 -0
  32. package/dist/hash.js +236 -0
  33. package/dist/hash.js.map +1 -0
  34. package/dist/index.d.ts +27 -32
  35. package/dist/index.d.ts.map +1 -1
  36. package/dist/index.js +94 -36
  37. package/dist/index.js.map +1 -1
  38. package/dist/jwt.d.ts +157 -0
  39. package/dist/jwt.d.ts.map +1 -0
  40. package/dist/jwt.js +489 -0
  41. package/dist/jwt.js.map +1 -0
  42. package/dist/middleware.d.ts +99 -0
  43. package/dist/middleware.d.ts.map +1 -0
  44. package/dist/middleware.js +253 -0
  45. package/dist/middleware.js.map +1 -0
  46. package/dist/plugin.d.ts +125 -0
  47. package/dist/plugin.d.ts.map +1 -0
  48. package/dist/plugin.js +193 -0
  49. package/dist/plugin.js.map +1 -0
  50. package/dist/policies.d.ts +137 -0
  51. package/dist/policies.d.ts.map +1 -0
  52. package/dist/policies.js +240 -0
  53. package/dist/policies.js.map +1 -0
  54. package/dist/rate-limit.d.ts +231 -0
  55. package/dist/rate-limit.d.ts.map +1 -0
  56. package/dist/rate-limit.js +352 -0
  57. package/dist/rate-limit.js.map +1 -0
  58. package/dist/session.d.ts +500 -0
  59. package/dist/session.d.ts.map +1 -0
  60. package/dist/session.js +801 -0
  61. package/dist/session.js.map +1 -0
  62. package/dist/types.d.ts +261 -0
  63. package/dist/types.d.ts.map +1 -0
  64. package/dist/types.js +33 -0
  65. package/dist/types.js.map +1 -0
  66. package/package.json +61 -7
@@ -0,0 +1,253 @@
1
+ /**
2
+ * Authentication middleware for @veloxts/auth
3
+ * @module auth/middleware
4
+ */
5
+ import { executeGuards } from './guards.js';
6
+ import { JwtManager } from './jwt.js';
7
+ import { AuthError } from './types.js';
8
+ // ============================================================================
9
+ // Auth Middleware Factory
10
+ // ============================================================================
11
+ /**
12
+ * Creates an authentication middleware for procedures (succinct API)
13
+ *
14
+ * This middleware:
15
+ * 1. Extracts JWT from Authorization header
16
+ * 2. Verifies the token
17
+ * 3. Loads user from database (if userLoader provided)
18
+ * 4. Adds user and auth context to ctx
19
+ * 5. Runs guards if specified
20
+ *
21
+ * @example
22
+ * ```typescript
23
+ * const auth = authMiddleware(authConfig);
24
+ *
25
+ * // Use in procedures
26
+ * const getProfile = procedure()
27
+ * .use(auth.middleware())
28
+ * .query(async ({ ctx }) => {
29
+ * return ctx.user; // Guaranteed to exist
30
+ * });
31
+ *
32
+ * // Optional auth (user may be undefined)
33
+ * const getPosts = procedure()
34
+ * .use(auth.middleware({ optional: true }))
35
+ * .query(async ({ ctx }) => {
36
+ * // ctx.user may be undefined
37
+ * return fetchPosts(ctx.user?.id);
38
+ * });
39
+ *
40
+ * // With guards
41
+ * const adminOnly = procedure()
42
+ * .use(auth.middleware({ guards: [hasRole('admin')] }))
43
+ * .query(async ({ ctx }) => {
44
+ * // Only admins get here
45
+ * });
46
+ * ```
47
+ */
48
+ export function authMiddleware(config) {
49
+ const jwt = new JwtManager(config.jwt);
50
+ /**
51
+ * Creates the actual middleware function
52
+ */
53
+ function middleware(options = {}) {
54
+ return async ({ ctx, next }) => {
55
+ const request = ctx.request;
56
+ // Extract token from header
57
+ const authHeader = request.headers.authorization;
58
+ const token = jwt.extractFromHeader(authHeader);
59
+ // No token handling
60
+ if (!token) {
61
+ if (options.optional) {
62
+ // Optional auth - continue without user
63
+ const authContext = {
64
+ user: undefined,
65
+ token: undefined,
66
+ isAuthenticated: false,
67
+ };
68
+ return next({
69
+ ctx: {
70
+ ...ctx,
71
+ auth: authContext,
72
+ user: undefined,
73
+ },
74
+ });
75
+ }
76
+ // Required auth - reject
77
+ throw new AuthError('Authorization header required', 401);
78
+ }
79
+ // Verify token
80
+ let payload;
81
+ try {
82
+ payload = jwt.verifyToken(token);
83
+ }
84
+ catch (error) {
85
+ if (options.optional) {
86
+ // Invalid token with optional auth - continue without user
87
+ const authContext = {
88
+ user: undefined,
89
+ token: undefined,
90
+ isAuthenticated: false,
91
+ };
92
+ return next({
93
+ ctx: {
94
+ ...ctx,
95
+ auth: authContext,
96
+ user: undefined,
97
+ },
98
+ });
99
+ }
100
+ throw new AuthError(error instanceof Error ? error.message : 'Invalid token', 401);
101
+ }
102
+ // Check if token is revoked
103
+ if (config.isTokenRevoked && payload.jti) {
104
+ const revoked = await config.isTokenRevoked(payload.jti);
105
+ if (revoked) {
106
+ throw new AuthError('Token has been revoked', 401, 'TOKEN_REVOKED');
107
+ }
108
+ }
109
+ // Load user from database
110
+ let user = null;
111
+ if (config.userLoader) {
112
+ user = await config.userLoader(payload.sub);
113
+ if (!user && !options.optional) {
114
+ throw new AuthError('User not found', 401, 'USER_NOT_FOUND');
115
+ }
116
+ }
117
+ else {
118
+ // No user loader - create minimal user from token
119
+ user = {
120
+ id: payload.sub,
121
+ email: payload.email,
122
+ };
123
+ }
124
+ // Create auth context
125
+ const authContext = {
126
+ user: user ?? undefined,
127
+ token: payload,
128
+ isAuthenticated: !!user,
129
+ };
130
+ // Build extended context
131
+ const extendedCtx = {
132
+ ...ctx,
133
+ auth: authContext,
134
+ user: user ?? undefined,
135
+ };
136
+ // Run guards if specified
137
+ if (options.guards && options.guards.length > 0) {
138
+ // Validate that all guards are GuardDefinition objects (strings are not supported)
139
+ const guardDefs = options.guards.map((g) => {
140
+ if (typeof g === 'string') {
141
+ throw new AuthError(`String guard references are not supported. Use a GuardDefinition object instead of "${g}"`, 500, 'INVALID_GUARD');
142
+ }
143
+ return g;
144
+ });
145
+ const result = await executeGuards(guardDefs, extendedCtx, request, ctx.reply);
146
+ if (!result.passed) {
147
+ throw new AuthError(result.message ?? `Guard failed: ${result.failedGuard}`, result.statusCode ?? 403, 'GUARD_FAILED');
148
+ }
149
+ }
150
+ // Continue to next middleware/handler
151
+ return next({ ctx: extendedCtx });
152
+ };
153
+ }
154
+ /**
155
+ * Shorthand for required authentication
156
+ */
157
+ function requireAuth(guards) {
158
+ return middleware({ optional: false, guards });
159
+ }
160
+ /**
161
+ * Shorthand for optional authentication
162
+ */
163
+ function optionalAuth() {
164
+ return middleware({ optional: true });
165
+ }
166
+ return {
167
+ middleware,
168
+ requireAuth,
169
+ optionalAuth,
170
+ jwt,
171
+ };
172
+ }
173
+ /**
174
+ * Creates an authentication middleware for procedures
175
+ *
176
+ * @deprecated Use `authMiddleware()` instead. Will be removed in v0.9.
177
+ */
178
+ export const createAuthMiddleware = authMiddleware;
179
+ // ============================================================================
180
+ // Error Helpers
181
+ // ============================================================================
182
+ // AuthError is now imported from types.ts
183
+ // ============================================================================
184
+ // Rate Limiting Middleware
185
+ // ============================================================================
186
+ /**
187
+ * Simple in-memory rate limiter
188
+ * For production, use Redis-based rate limiting
189
+ */
190
+ const rateLimitStore = new Map();
191
+ /**
192
+ * Creates a rate limiting middleware (succinct API)
193
+ *
194
+ * @example
195
+ * ```typescript
196
+ * const rateLimit = rateLimitMiddleware({
197
+ * max: 100,
198
+ * windowMs: 60000, // 1 minute
199
+ * });
200
+ *
201
+ * const login = procedure()
202
+ * .use(rateLimit)
203
+ * .input(LoginSchema)
204
+ * .mutation(handler);
205
+ * ```
206
+ */
207
+ export function rateLimitMiddleware(options) {
208
+ const max = options.max ?? 100;
209
+ const windowMs = options.windowMs ?? 60000;
210
+ const keyGenerator = options.keyGenerator ?? ((ctx) => ctx.request.ip ?? 'unknown');
211
+ const message = options.message ?? 'Too many requests, please try again later';
212
+ return async ({ ctx, next }) => {
213
+ const key = keyGenerator(ctx);
214
+ const now = Date.now();
215
+ let record = rateLimitStore.get(key);
216
+ // Clean up expired record
217
+ if (record && record.resetAt <= now) {
218
+ rateLimitStore.delete(key);
219
+ record = undefined;
220
+ }
221
+ if (!record) {
222
+ // First request in window
223
+ record = { count: 1, resetAt: now + windowMs };
224
+ rateLimitStore.set(key, record);
225
+ }
226
+ else {
227
+ // Increment count
228
+ record.count++;
229
+ }
230
+ // Add rate limit headers (always, even on 429 responses)
231
+ ctx.reply.header('X-RateLimit-Limit', String(max));
232
+ ctx.reply.header('X-RateLimit-Remaining', String(Math.max(0, max - record.count)));
233
+ ctx.reply.header('X-RateLimit-Reset', String(Math.ceil(record.resetAt / 1000)));
234
+ // Check limit (after setting headers so they're included in 429 response)
235
+ if (record.count > max) {
236
+ throw new AuthError(message, 429, 'RATE_LIMIT_EXCEEDED');
237
+ }
238
+ return next();
239
+ };
240
+ }
241
+ /**
242
+ * Creates a rate limiting middleware
243
+ *
244
+ * @deprecated Use `rateLimitMiddleware()` instead. Will be removed in v0.9.
245
+ */
246
+ export const createRateLimitMiddleware = rateLimitMiddleware;
247
+ /**
248
+ * Clears rate limit store (useful for testing)
249
+ */
250
+ export function clearRateLimitStore() {
251
+ rateLimitStore.clear();
252
+ }
253
+ //# sourceMappingURL=middleware.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"middleware.js","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,125 @@
1
+ /**
2
+ * VeloxTS Auth Plugin
3
+ * Fastify plugin that integrates authentication with VeloxApp
4
+ * @module auth/plugin
5
+ */
6
+ import type { VeloxPlugin } from '@veloxts/core';
7
+ import { PasswordHasher } from './hash.js';
8
+ import { JwtManager } from './jwt.js';
9
+ import { createAuthMiddleware } from './middleware.js';
10
+ import type { AuthConfig, AuthContext, TokenPair, User } from './types.js';
11
+ /** Auth package version */
12
+ export declare const AUTH_VERSION: string;
13
+ /**
14
+ * Options for the auth plugin
15
+ */
16
+ export interface AuthPluginOptions extends AuthConfig {
17
+ /**
18
+ * Enable debug logging
19
+ * @default false
20
+ */
21
+ debug?: boolean;
22
+ }
23
+ /**
24
+ * Auth service instance attached to Fastify
25
+ * Provides authentication utilities for the application
26
+ */
27
+ export interface AuthService {
28
+ /**
29
+ * JWT manager for token operations
30
+ */
31
+ jwt: JwtManager;
32
+ /**
33
+ * Password hasher for secure password storage
34
+ */
35
+ hasher: PasswordHasher;
36
+ /**
37
+ * Creates a token pair for a user
38
+ */
39
+ createTokens(user: User, additionalClaims?: Record<string, unknown>): TokenPair;
40
+ /**
41
+ * Verifies an access token and returns the auth context
42
+ */
43
+ verifyToken(token: string): AuthContext;
44
+ /**
45
+ * Refreshes tokens using a refresh token
46
+ */
47
+ refreshTokens(refreshToken: string): Promise<TokenPair> | TokenPair;
48
+ /**
49
+ * Gets the auth middleware factory
50
+ */
51
+ middleware: ReturnType<typeof createAuthMiddleware>;
52
+ }
53
+ declare module 'fastify' {
54
+ interface FastifyInstance {
55
+ auth: AuthService;
56
+ }
57
+ interface FastifyRequest {
58
+ auth?: AuthContext;
59
+ user?: User;
60
+ }
61
+ }
62
+ /**
63
+ * Creates the VeloxTS auth plugin (succinct API)
64
+ *
65
+ * This plugin provides:
66
+ * - JWT token management (access + refresh tokens)
67
+ * - Password hashing (bcrypt/argon2)
68
+ * - Request decorations for auth context
69
+ * - Auth middleware factory for procedures
70
+ *
71
+ * @example
72
+ * ```typescript
73
+ * import { authPlugin } from '@veloxts/auth';
74
+ *
75
+ * const auth = authPlugin({
76
+ * jwt: {
77
+ * secret: process.env.JWT_SECRET!,
78
+ * accessTokenExpiry: '15m',
79
+ * refreshTokenExpiry: '7d',
80
+ * },
81
+ * hash: {
82
+ * algorithm: 'bcrypt',
83
+ * bcryptRounds: 12,
84
+ * },
85
+ * userLoader: async (userId) => {
86
+ * return db.user.findUnique({ where: { id: userId } });
87
+ * },
88
+ * });
89
+ *
90
+ * // Register with VeloxApp
91
+ * await app.register(auth);
92
+ *
93
+ * // Use in procedures
94
+ * const { middleware, requireAuth } = app.auth.middleware;
95
+ *
96
+ * const getProfile = procedure()
97
+ * .use(requireAuth())
98
+ * .query(async ({ ctx }) => ctx.user);
99
+ * ```
100
+ */
101
+ export declare function authPlugin(options: AuthPluginOptions): VeloxPlugin<AuthPluginOptions>;
102
+ /**
103
+ * Creates the VeloxTS auth plugin
104
+ *
105
+ * @deprecated Use `authPlugin()` instead. Will be removed in v0.9.
106
+ */
107
+ export declare const createAuthPlugin: typeof authPlugin;
108
+ /**
109
+ * Default auth plugin with minimal configuration
110
+ *
111
+ * Uses environment variables for configuration:
112
+ * - `JWT_SECRET` (required): Secret for signing JWT tokens
113
+ *
114
+ * @throws {Error} If JWT_SECRET environment variable is not set
115
+ *
116
+ * @example
117
+ * ```typescript
118
+ * import { defaultAuthPlugin } from '@veloxts/auth';
119
+ *
120
+ * // Requires JWT_SECRET environment variable
121
+ * await app.register(defaultAuthPlugin());
122
+ * ```
123
+ */
124
+ export declare function defaultAuthPlugin(): VeloxPlugin<AuthPluginOptions>;
125
+ //# sourceMappingURL=plugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAGjD,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtC,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAM3E,2BAA2B;AAC3B,eAAO,MAAM,YAAY,EAAE,MAA+C,CAAC;AAM3E;;GAEG;AACH,MAAM,WAAW,iBAAkB,SAAQ,UAAU;IACnD;;;OAGG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAMD;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B;;OAEG;IACH,GAAG,EAAE,UAAU,CAAC;IAEhB;;OAEG;IACH,MAAM,EAAE,cAAc,CAAC;IAEvB;;OAEG;IACH,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;IAEhF;;OAEG;IACH,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,CAAC;IAExC;;OAEG;IACH,aAAa,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,GAAG,SAAS,CAAC;IAEpE;;OAEG;IACH,UAAU,EAAE,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAC;CACrD;AAMD,OAAO,QAAQ,SAAS,CAAC;IACvB,UAAU,eAAe;QACvB,IAAI,EAAE,WAAW,CAAC;KACnB;IAED,UAAU,cAAc;QACtB,IAAI,CAAC,EAAE,WAAW,CAAC;QACnB,IAAI,CAAC,EAAE,IAAI,CAAC;KACb;CACF;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,iBAAiB,GAAG,WAAW,CAAC,iBAAiB,CAAC,CAsHrF;AAED;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,mBAAa,CAAC;AAE3C;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,iBAAiB,IAAI,WAAW,CAAC,iBAAiB,CAAC,CAYlE"}
package/dist/plugin.js ADDED
@@ -0,0 +1,193 @@
1
+ /**
2
+ * VeloxTS Auth Plugin
3
+ * Fastify plugin that integrates authentication with VeloxApp
4
+ * @module auth/plugin
5
+ */
6
+ import { createRequire } from 'node:module';
7
+ import { PasswordHasher } from './hash.js';
8
+ import { JwtManager } from './jwt.js';
9
+ import { createAuthMiddleware } from './middleware.js';
10
+ // Read version from package.json dynamically
11
+ const require = createRequire(import.meta.url);
12
+ const packageJson = require('../package.json');
13
+ /** Auth package version */
14
+ export const AUTH_VERSION = packageJson.version ?? '0.0.0-unknown';
15
+ // ============================================================================
16
+ // Auth Plugin
17
+ // ============================================================================
18
+ /**
19
+ * Creates the VeloxTS auth plugin (succinct API)
20
+ *
21
+ * This plugin provides:
22
+ * - JWT token management (access + refresh tokens)
23
+ * - Password hashing (bcrypt/argon2)
24
+ * - Request decorations for auth context
25
+ * - Auth middleware factory for procedures
26
+ *
27
+ * @example
28
+ * ```typescript
29
+ * import { authPlugin } from '@veloxts/auth';
30
+ *
31
+ * const auth = authPlugin({
32
+ * jwt: {
33
+ * secret: process.env.JWT_SECRET!,
34
+ * accessTokenExpiry: '15m',
35
+ * refreshTokenExpiry: '7d',
36
+ * },
37
+ * hash: {
38
+ * algorithm: 'bcrypt',
39
+ * bcryptRounds: 12,
40
+ * },
41
+ * userLoader: async (userId) => {
42
+ * return db.user.findUnique({ where: { id: userId } });
43
+ * },
44
+ * });
45
+ *
46
+ * // Register with VeloxApp
47
+ * await app.register(auth);
48
+ *
49
+ * // Use in procedures
50
+ * const { middleware, requireAuth } = app.auth.middleware;
51
+ *
52
+ * const getProfile = procedure()
53
+ * .use(requireAuth())
54
+ * .query(async ({ ctx }) => ctx.user);
55
+ * ```
56
+ */
57
+ export function authPlugin(options) {
58
+ return {
59
+ name: '@veloxts/auth',
60
+ version: AUTH_VERSION,
61
+ // No explicit dependencies - works with any Fastify instance
62
+ // The plugin decorates Fastify with auth functionality
63
+ async register(server, _opts) {
64
+ const config = { ...options, ..._opts };
65
+ const { debug = false } = config;
66
+ if (debug) {
67
+ server.log.info('Registering @veloxts/auth plugin');
68
+ }
69
+ // Create instances
70
+ const jwt = new JwtManager(config.jwt);
71
+ const hasher = new PasswordHasher(config.hash);
72
+ const authMiddleware = createAuthMiddleware(config);
73
+ // Create auth service
74
+ const authService = {
75
+ jwt,
76
+ hasher,
77
+ createTokens(user, additionalClaims) {
78
+ return jwt.createTokenPair(user, additionalClaims);
79
+ },
80
+ verifyToken(token) {
81
+ const payload = jwt.verifyToken(token);
82
+ return {
83
+ user: {
84
+ id: payload.sub,
85
+ email: payload.email,
86
+ },
87
+ token: payload,
88
+ isAuthenticated: true,
89
+ };
90
+ },
91
+ refreshTokens(refreshToken) {
92
+ if (config.userLoader) {
93
+ return jwt.refreshTokens(refreshToken, config.userLoader);
94
+ }
95
+ return jwt.refreshTokens(refreshToken);
96
+ },
97
+ middleware: authMiddleware,
98
+ };
99
+ // Decorate server with auth service
100
+ server.decorate('auth', authService);
101
+ // Decorate requests with auth context (undefined initial value)
102
+ server.decorateRequest('auth', undefined);
103
+ server.decorateRequest('user', undefined);
104
+ // Add preHandler hook to extract auth from headers (optional)
105
+ if (config.autoExtract !== false) {
106
+ server.addHook('preHandler', async (request) => {
107
+ const authHeader = request.headers.authorization;
108
+ const token = jwt.extractFromHeader(authHeader);
109
+ if (token) {
110
+ try {
111
+ const payload = jwt.verifyToken(token);
112
+ // Check if token is revoked
113
+ if (config.isTokenRevoked && payload.jti) {
114
+ const revoked = await config.isTokenRevoked(payload.jti);
115
+ if (revoked) {
116
+ // Token revoked - don't set auth context
117
+ return;
118
+ }
119
+ }
120
+ // Load user if loader provided
121
+ let user = null;
122
+ if (config.userLoader) {
123
+ user = await config.userLoader(payload.sub);
124
+ }
125
+ else {
126
+ user = {
127
+ id: payload.sub,
128
+ email: payload.email,
129
+ };
130
+ }
131
+ if (user) {
132
+ request.auth = {
133
+ user,
134
+ token: payload,
135
+ isAuthenticated: true,
136
+ };
137
+ request.user = user;
138
+ }
139
+ }
140
+ catch {
141
+ // Invalid token - silently ignore (optional auth)
142
+ if (debug) {
143
+ server.log.debug('Invalid auth token in request');
144
+ }
145
+ }
146
+ }
147
+ });
148
+ }
149
+ // Add shutdown hook for cleanup
150
+ server.addHook('onClose', async () => {
151
+ if (debug) {
152
+ server.log.info('Shutting down @veloxts/auth plugin');
153
+ }
154
+ });
155
+ if (debug) {
156
+ server.log.info('@veloxts/auth plugin registered successfully');
157
+ }
158
+ },
159
+ };
160
+ }
161
+ /**
162
+ * Creates the VeloxTS auth plugin
163
+ *
164
+ * @deprecated Use `authPlugin()` instead. Will be removed in v0.9.
165
+ */
166
+ export const createAuthPlugin = authPlugin;
167
+ /**
168
+ * Default auth plugin with minimal configuration
169
+ *
170
+ * Uses environment variables for configuration:
171
+ * - `JWT_SECRET` (required): Secret for signing JWT tokens
172
+ *
173
+ * @throws {Error} If JWT_SECRET environment variable is not set
174
+ *
175
+ * @example
176
+ * ```typescript
177
+ * import { defaultAuthPlugin } from '@veloxts/auth';
178
+ *
179
+ * // Requires JWT_SECRET environment variable
180
+ * await app.register(defaultAuthPlugin());
181
+ * ```
182
+ */
183
+ export function defaultAuthPlugin() {
184
+ const secret = process.env.JWT_SECRET;
185
+ if (!secret) {
186
+ throw new Error('JWT_SECRET environment variable is required for auth plugin. ' +
187
+ 'Set it to a secure random string of at least 32 characters.');
188
+ }
189
+ return authPlugin({
190
+ jwt: { secret },
191
+ });
192
+ }
193
+ //# sourceMappingURL=plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAK5C,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtC,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAGvD,6CAA6C;AAC7C,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/C,MAAM,WAAW,GAAG,OAAO,CAAC,iBAAiB,CAAwB,CAAC;AAEtE,2BAA2B;AAC3B,MAAM,CAAC,MAAM,YAAY,GAAW,WAAW,CAAC,OAAO,IAAI,eAAe,CAAC;AAwE3E,+EAA+E;AAC/E,cAAc;AACd,+EAA+E;AAE/E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,MAAM,UAAU,UAAU,CAAC,OAA0B;IACnD,OAAO;QACL,IAAI,EAAE,eAAe;QACrB,OAAO,EAAE,YAAY;QACrB,6DAA6D;QAC7D,uDAAuD;QAEvD,KAAK,CAAC,QAAQ,CAAC,MAAuB,EAAE,KAAwB;YAC9D,MAAM,MAAM,GAAG,EAAE,GAAG,OAAO,EAAE,GAAG,KAAK,EAAE,CAAC;YACxC,MAAM,EAAE,KAAK,GAAG,KAAK,EAAE,GAAG,MAAM,CAAC;YAEjC,IAAI,KAAK,EAAE,CAAC;gBACV,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,kCAAkC,CAAC,CAAC;YACtD,CAAC;YAED,mBAAmB;YACnB,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACvC,MAAM,MAAM,GAAG,IAAI,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YAC/C,MAAM,cAAc,GAAG,oBAAoB,CAAC,MAAM,CAAC,CAAC;YAEpD,sBAAsB;YACtB,MAAM,WAAW,GAAgB;gBAC/B,GAAG;gBACH,MAAM;gBAEN,YAAY,CAAC,IAAU,EAAE,gBAA0C;oBACjE,OAAO,GAAG,CAAC,eAAe,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC;gBACrD,CAAC;gBAED,WAAW,CAAC,KAAa;oBACvB,MAAM,OAAO,GAAG,GAAG,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;oBACvC,OAAO;wBACL,IAAI,EAAE;4BACJ,EAAE,EAAE,OAAO,CAAC,GAAG;4BACf,KAAK,EAAE,OAAO,CAAC,KAAK;yBACrB;wBACD,KAAK,EAAE,OAAO;wBACd,eAAe,EAAE,IAAI;qBACtB,CAAC;gBACJ,CAAC;gBAED,aAAa,CAAC,YAAoB;oBAChC,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;wBACtB,OAAO,GAAG,CAAC,aAAa,CAAC,YAAY,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;oBAC5D,CAAC;oBACD,OAAO,GAAG,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC;gBACzC,CAAC;gBAED,UAAU,EAAE,cAAc;aAC3B,CAAC;YAEF,oCAAoC;YACpC,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;YAErC,gEAAgE;YAChE,MAAM,CAAC,eAAe,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;YAC1C,MAAM,CAAC,eAAe,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;YAE1C,8DAA8D;YAC9D,IAAI,MAAM,CAAC,WAAW,KAAK,KAAK,EAAE,CAAC;gBACjC,MAAM,CAAC,OAAO,CAAC,YAAY,EAAE,KAAK,EAAE,OAAuB,EAAE,EAAE;oBAC7D,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC;oBACjD,MAAM,KAAK,GAAG,GAAG,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC;oBAEhD,IAAI,KAAK,EAAE,CAAC;wBACV,IAAI,CAAC;4BACH,MAAM,OAAO,GAAG,GAAG,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;4BAEvC,4BAA4B;4BAC5B,IAAI,MAAM,CAAC,cAAc,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;gCACzC,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;gCACzD,IAAI,OAAO,EAAE,CAAC;oCACZ,yCAAyC;oCACzC,OAAO;gCACT,CAAC;4BACH,CAAC;4BAED,+BAA+B;4BAC/B,IAAI,IAAI,GAAgB,IAAI,CAAC;4BAC7B,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;gCACtB,IAAI,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;4BAC9C,CAAC;iCAAM,CAAC;gCACN,IAAI,GAAG;oCACL,EAAE,EAAE,OAAO,CAAC,GAAG;oCACf,KAAK,EAAE,OAAO,CAAC,KAAK;iCACrB,CAAC;4BACJ,CAAC;4BAED,IAAI,IAAI,EAAE,CAAC;gCACT,OAAO,CAAC,IAAI,GAAG;oCACb,IAAI;oCACJ,KAAK,EAAE,OAAO;oCACd,eAAe,EAAE,IAAI;iCACtB,CAAC;gCACF,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;4BACtB,CAAC;wBACH,CAAC;wBAAC,MAAM,CAAC;4BACP,kDAAkD;4BAClD,IAAI,KAAK,EAAE,CAAC;gCACV,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,+BAA+B,CAAC,CAAC;4BACpD,CAAC;wBACH,CAAC;oBACH,CAAC;gBACH,CAAC,CAAC,CAAC;YACL,CAAC;YAED,gCAAgC;YAChC,MAAM,CAAC,OAAO,CAAC,SAAS,EAAE,KAAK,IAAI,EAAE;gBACnC,IAAI,KAAK,EAAE,CAAC;oBACV,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,oCAAoC,CAAC,CAAC;gBACxD,CAAC;YACH,CAAC,CAAC,CAAC;YAEH,IAAI,KAAK,EAAE,CAAC;gBACV,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,8CAA8C,CAAC,CAAC;YAClE,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,UAAU,CAAC;AAE3C;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,iBAAiB;IAC/B,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC;IACtC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CACb,+DAA+D;YAC7D,6DAA6D,CAChE,CAAC;IACJ,CAAC;IAED,OAAO,UAAU,CAAC;QAChB,GAAG,EAAE,EAAE,MAAM,EAAE;KAChB,CAAC,CAAC;AACL,CAAC"}