@noony-serverless/core 0.1.1 → 0.2.0

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 (62) hide show
  1. package/build/core/core.d.ts +16 -48
  2. package/build/core/core.js +2 -61
  3. package/build/core/handler.d.ts +37 -16
  4. package/build/core/handler.js +131 -42
  5. package/build/core/index.d.ts +0 -1
  6. package/build/core/index.js +0 -1
  7. package/build/middlewares/ConsolidatedValidationMiddleware.d.ts +126 -0
  8. package/build/middlewares/ConsolidatedValidationMiddleware.js +330 -0
  9. package/build/middlewares/ProcessingMiddleware.d.ts +138 -0
  10. package/build/middlewares/ProcessingMiddleware.js +425 -0
  11. package/build/middlewares/SecurityMiddleware.d.ts +157 -0
  12. package/build/middlewares/SecurityMiddleware.js +307 -0
  13. package/build/middlewares/authenticationMiddleware.d.ts +379 -0
  14. package/build/middlewares/authenticationMiddleware.js +216 -0
  15. package/build/middlewares/bodyParserMiddleware.d.ts +99 -0
  16. package/build/middlewares/bodyParserMiddleware.js +99 -0
  17. package/build/middlewares/bodyValidationMiddleware.d.ts +69 -3
  18. package/build/middlewares/bodyValidationMiddleware.js +68 -2
  19. package/build/middlewares/dependencyInjectionMiddleware.d.ts +238 -0
  20. package/build/middlewares/dependencyInjectionMiddleware.js +238 -0
  21. package/build/middlewares/errorHandlerMiddleware.d.ts +94 -0
  22. package/build/middlewares/errorHandlerMiddleware.js +105 -0
  23. package/build/middlewares/guards/RouteGuards.d.ts +476 -21
  24. package/build/middlewares/guards/RouteGuards.js +418 -21
  25. package/build/middlewares/guards/adapters/CustomTokenVerificationPortAdapter.d.ts +271 -0
  26. package/build/middlewares/guards/adapters/CustomTokenVerificationPortAdapter.js +301 -0
  27. package/build/middlewares/guards/cache/CacheAdapter.d.ts +369 -28
  28. package/build/middlewares/guards/cache/CacheAdapter.js +124 -5
  29. package/build/middlewares/guards/cache/MemoryCacheAdapter.d.ts +113 -4
  30. package/build/middlewares/guards/cache/MemoryCacheAdapter.js +113 -4
  31. package/build/middlewares/guards/config/GuardConfiguration.d.ts +568 -18
  32. package/build/middlewares/guards/config/GuardConfiguration.js +266 -10
  33. package/build/middlewares/guards/guards/FastAuthGuard.d.ts +5 -5
  34. package/build/middlewares/guards/guards/PermissionGuardFactory.d.ts +5 -13
  35. package/build/middlewares/guards/guards/PermissionGuardFactory.js +4 -4
  36. package/build/middlewares/guards/index.d.ts +43 -1
  37. package/build/middlewares/guards/index.js +46 -1
  38. package/build/middlewares/guards/resolvers/ExpressionPermissionResolver.d.ts +1 -1
  39. package/build/middlewares/guards/resolvers/ExpressionPermissionResolver.js +1 -1
  40. package/build/middlewares/guards/resolvers/PermissionResolver.d.ts +1 -1
  41. package/build/middlewares/guards/resolvers/PlainPermissionResolver.d.ts +1 -1
  42. package/build/middlewares/guards/resolvers/WildcardPermissionResolver.d.ts +1 -1
  43. package/build/middlewares/guards/services/FastUserContextService.d.ts +20 -33
  44. package/build/middlewares/guards/services/FastUserContextService.js +19 -5
  45. package/build/middlewares/headerVariablesMiddleware.d.ts +118 -0
  46. package/build/middlewares/headerVariablesMiddleware.js +118 -0
  47. package/build/middlewares/httpAttributesMiddleware.d.ts +235 -0
  48. package/build/middlewares/httpAttributesMiddleware.js +236 -1
  49. package/build/middlewares/index.d.ts +3 -1
  50. package/build/middlewares/index.js +6 -1
  51. package/build/middlewares/queryParametersMiddleware.d.ts +105 -0
  52. package/build/middlewares/queryParametersMiddleware.js +105 -0
  53. package/build/middlewares/rateLimitingMiddleware.d.ts +601 -9
  54. package/build/middlewares/rateLimitingMiddleware.js +623 -11
  55. package/build/middlewares/responseWrapperMiddleware.d.ts +170 -1
  56. package/build/middlewares/responseWrapperMiddleware.js +170 -1
  57. package/build/middlewares/securityAuditMiddleware.js +5 -5
  58. package/package.json +11 -9
  59. package/build/core/containerPool.d.ts +0 -44
  60. package/build/core/containerPool.js +0 -103
  61. package/build/middlewares/validationMiddleware.d.ts +0 -9
  62. package/build/middlewares/validationMiddleware.js +0 -40
@@ -0,0 +1,307 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createSecurityMiddleware = exports.SecurityMiddleware = void 0;
4
+ const core_1 = require("../core");
5
+ /**
6
+ * Consolidated SecurityMiddleware that combines authentication, security headers, and audit logging.
7
+ *
8
+ * This middleware replaces the need for separate:
9
+ * - AuthenticationMiddleware
10
+ * - SecurityHeadersMiddleware
11
+ * - SecurityAuditMiddleware
12
+ *
13
+ * @example
14
+ * Basic security with authentication and headers:
15
+ * ```typescript
16
+ * const handler = new Handler()
17
+ * .use(new SecurityMiddleware({
18
+ * authentication: {
19
+ * tokenVerifier: {
20
+ * verifyToken: async (token) => jwt.verify(token, secret)
21
+ * },
22
+ * extractToken: (req) => req.headers.authorization?.replace('Bearer ', '')
23
+ * },
24
+ * headers: {
25
+ * contentSecurityPolicy: "default-src 'self'",
26
+ * xFrameOptions: 'DENY',
27
+ * strictTransportSecurity: 'max-age=31536000; includeSubDomains'
28
+ * },
29
+ * audit: {
30
+ * logFailedAuth: true,
31
+ * trackSuspiciousIPs: true
32
+ * }
33
+ * }))
34
+ * .handle(async (context) => {
35
+ * // context.user is populated if authentication succeeds
36
+ * const user = context.user;
37
+ * return { message: `Hello ${user?.name}` };
38
+ * });
39
+ * ```
40
+ *
41
+ * @example
42
+ * Advanced security with custom auditing:
43
+ * ```typescript
44
+ * const handler = new Handler()
45
+ * .use(new SecurityMiddleware({
46
+ * authentication: {
47
+ * tokenVerifier: customTokenVerifier,
48
+ * skipPaths: ['/health', '/metrics'],
49
+ * onAuthFailure: async (error, context) => {
50
+ * await logSecurityEvent('auth_failure', {
51
+ * ip: context.req.ip,
52
+ * error: error.message
53
+ * });
54
+ * }
55
+ * },
56
+ * audit: {
57
+ * customAuditor: async (event, context) => {
58
+ * await sendToSecuritySystem(event);
59
+ * },
60
+ * alertThresholds: {
61
+ * failedAttempts: 5,
62
+ * timeWindowMs: 300000 // 5 minutes
63
+ * }
64
+ * }
65
+ * }));
66
+ * ```
67
+ */
68
+ class SecurityMiddleware {
69
+ config;
70
+ failedAttempts = new Map();
71
+ constructor(config = {}) {
72
+ this.config = {
73
+ authentication: {},
74
+ headers: {
75
+ xFrameOptions: 'DENY',
76
+ xContentTypeOptions: 'nosniff',
77
+ xXssProtection: '1; mode=block',
78
+ referrerPolicy: 'strict-origin-when-cross-origin',
79
+ ...config.headers,
80
+ },
81
+ audit: {
82
+ logFailedAuth: true,
83
+ trackSuspiciousIPs: false,
84
+ enableMetrics: true,
85
+ ...config.audit,
86
+ },
87
+ ...config,
88
+ };
89
+ }
90
+ async before(context) {
91
+ // 1. Set security headers first (always apply)
92
+ await this.setSecurityHeaders(context);
93
+ // 2. Perform authentication if configured
94
+ if (this.config.authentication?.tokenVerifier) {
95
+ await this.authenticateRequest(context);
96
+ }
97
+ }
98
+ async after(context) {
99
+ // Audit successful operations if enabled
100
+ if (this.config.audit?.logSuccessfulAuth && context.user) {
101
+ await this.auditSecurityEvent({
102
+ type: 'AUTH_SUCCESS',
103
+ ip: context.req.ip,
104
+ userAgent: context.req.userAgent,
105
+ path: context.req.path,
106
+ timestamp: new Date(),
107
+ details: { userId: context.user?.id },
108
+ }, context);
109
+ }
110
+ }
111
+ async onError(error, context) {
112
+ // Audit authentication failures
113
+ if (error instanceof core_1.AuthenticationError &&
114
+ this.config.audit?.logFailedAuth) {
115
+ const ip = context.req.ip || 'unknown';
116
+ // Track failed attempts for suspicious IP detection
117
+ if (this.config.audit?.trackSuspiciousIPs) {
118
+ await this.trackFailedAttempt(ip, context);
119
+ }
120
+ await this.auditSecurityEvent({
121
+ type: 'AUTH_FAILURE',
122
+ ip,
123
+ userAgent: context.req.userAgent,
124
+ path: context.req.path,
125
+ timestamp: new Date(),
126
+ details: { error: error.message },
127
+ }, context);
128
+ // Custom auth failure handler
129
+ if (this.config.authentication?.onAuthFailure) {
130
+ await this.config.authentication.onAuthFailure(error, context);
131
+ }
132
+ }
133
+ }
134
+ async setSecurityHeaders(context) {
135
+ const headers = this.config.headers;
136
+ if (headers.contentSecurityPolicy) {
137
+ context.res.header('Content-Security-Policy', headers.contentSecurityPolicy);
138
+ }
139
+ if (headers.xFrameOptions) {
140
+ context.res.header('X-Frame-Options', headers.xFrameOptions);
141
+ }
142
+ if (headers.strictTransportSecurity) {
143
+ context.res.header('Strict-Transport-Security', headers.strictTransportSecurity);
144
+ }
145
+ if (headers.xContentTypeOptions) {
146
+ context.res.header('X-Content-Type-Options', headers.xContentTypeOptions);
147
+ }
148
+ if (headers.xXssProtection) {
149
+ context.res.header('X-XSS-Protection', headers.xXssProtection);
150
+ }
151
+ if (headers.referrerPolicy) {
152
+ context.res.header('Referrer-Policy', headers.referrerPolicy);
153
+ }
154
+ if (headers.permissionsPolicy) {
155
+ context.res.header('Permissions-Policy', headers.permissionsPolicy);
156
+ }
157
+ // Apply custom headers
158
+ if (headers.customHeaders) {
159
+ Object.entries(headers.customHeaders).forEach(([name, value]) => {
160
+ context.res.header(name, value);
161
+ });
162
+ }
163
+ }
164
+ async authenticateRequest(context) {
165
+ const authConfig = this.config.authentication;
166
+ // Skip authentication for specified paths
167
+ if (authConfig.skipPaths?.some((path) => context.req.path?.startsWith(path))) {
168
+ return;
169
+ }
170
+ // Extract token
171
+ const token = authConfig.extractToken
172
+ ? authConfig.extractToken(context.req)
173
+ : this.extractTokenFromHeader(context.req);
174
+ if (!token) {
175
+ if (!authConfig.optional) {
176
+ throw new core_1.AuthenticationError('No authentication token provided');
177
+ }
178
+ return;
179
+ }
180
+ try {
181
+ // Verify token using the provided verifier
182
+ const user = await authConfig.tokenVerifier.verifyToken(token);
183
+ context.user = user;
184
+ }
185
+ catch (error) {
186
+ throw new core_1.AuthenticationError('Invalid authentication token');
187
+ }
188
+ }
189
+ extractTokenFromHeader(req) {
190
+ const authHeader = req.headers?.authorization || req.headers?.Authorization;
191
+ if (typeof authHeader === 'string' && authHeader.startsWith('Bearer ')) {
192
+ return authHeader.substring(7);
193
+ }
194
+ return null;
195
+ }
196
+ async trackFailedAttempt(ip, context) {
197
+ const now = Date.now();
198
+ const threshold = this.config.audit?.alertThresholds?.failedAttempts || 5;
199
+ const timeWindow = this.config.audit?.alertThresholds?.timeWindowMs || 300000; // 5 minutes
200
+ const existing = this.failedAttempts.get(ip);
201
+ if (!existing) {
202
+ this.failedAttempts.set(ip, { count: 1, firstAttempt: now });
203
+ return;
204
+ }
205
+ // Reset if outside time window
206
+ if (now - existing.firstAttempt > timeWindow) {
207
+ this.failedAttempts.set(ip, { count: 1, firstAttempt: now });
208
+ return;
209
+ }
210
+ // Increment count
211
+ existing.count++;
212
+ // Check if threshold exceeded
213
+ if (existing.count >= threshold) {
214
+ await this.auditSecurityEvent({
215
+ type: 'THRESHOLD_EXCEEDED',
216
+ ip,
217
+ userAgent: context.req.userAgent,
218
+ path: context.req.path,
219
+ timestamp: new Date(),
220
+ details: {
221
+ failedAttempts: existing.count,
222
+ timeWindowMs: timeWindow,
223
+ firstAttemptTime: new Date(existing.firstAttempt),
224
+ },
225
+ }, context);
226
+ // Optionally reset counter or keep tracking
227
+ this.failedAttempts.delete(ip);
228
+ }
229
+ }
230
+ async auditSecurityEvent(event, context) {
231
+ // Use custom auditor if provided
232
+ if (this.config.audit?.customAuditor) {
233
+ await this.config.audit.customAuditor(event, context);
234
+ return;
235
+ }
236
+ // Default logging
237
+ const logLevel = event.type.includes('FAILURE') || event.type.includes('EXCEEDED')
238
+ ? 'warn'
239
+ : 'info';
240
+ console[logLevel]('[SecurityMiddleware]', {
241
+ type: event.type,
242
+ ip: event.ip,
243
+ path: event.path,
244
+ timestamp: event.timestamp.toISOString(),
245
+ userAgent: event.userAgent,
246
+ details: event.details,
247
+ });
248
+ // Store in business data for downstream processing
249
+ if (!context.businessData.has('securityEvents')) {
250
+ context.businessData.set('securityEvents', []);
251
+ }
252
+ context.businessData.get('securityEvents').push(event);
253
+ }
254
+ }
255
+ exports.SecurityMiddleware = SecurityMiddleware;
256
+ /**
257
+ * Factory function for creating SecurityMiddleware with common configurations
258
+ */
259
+ exports.createSecurityMiddleware = {
260
+ /**
261
+ * Basic security setup with common headers and JWT authentication
262
+ */
263
+ basic: (tokenVerifier) => new SecurityMiddleware({
264
+ authentication: { tokenVerifier },
265
+ headers: {
266
+ contentSecurityPolicy: "default-src 'self'",
267
+ xFrameOptions: 'DENY',
268
+ strictTransportSecurity: 'max-age=31536000',
269
+ },
270
+ audit: { logFailedAuth: true },
271
+ }),
272
+ /**
273
+ * Advanced security with audit tracking and suspicious IP monitoring
274
+ */
275
+ advanced: (tokenVerifier) => new SecurityMiddleware({
276
+ authentication: { tokenVerifier },
277
+ headers: {
278
+ contentSecurityPolicy: "default-src 'self'; script-src 'self' 'unsafe-inline'",
279
+ xFrameOptions: 'DENY',
280
+ strictTransportSecurity: 'max-age=31536000; includeSubDomains',
281
+ referrerPolicy: 'strict-origin-when-cross-origin',
282
+ permissionsPolicy: 'geolocation=(), microphone=(), camera=()',
283
+ },
284
+ audit: {
285
+ logFailedAuth: true,
286
+ logSuccessfulAuth: true,
287
+ trackSuspiciousIPs: true,
288
+ alertThresholds: {
289
+ failedAttempts: 5,
290
+ timeWindowMs: 300000,
291
+ },
292
+ },
293
+ }),
294
+ /**
295
+ * Headers only - no authentication
296
+ */
297
+ headersOnly: () => new SecurityMiddleware({
298
+ headers: {
299
+ contentSecurityPolicy: "default-src 'self'",
300
+ xFrameOptions: 'DENY',
301
+ xContentTypeOptions: 'nosniff',
302
+ xXssProtection: '1; mode=block',
303
+ referrerPolicy: 'strict-origin-when-cross-origin',
304
+ },
305
+ }),
306
+ };
307
+ //# sourceMappingURL=SecurityMiddleware.js.map
@@ -1,8 +1,107 @@
1
1
  import { BaseMiddleware } from '../core/handler';
2
2
  import { Context } from '../core/core';
3
+ /**
4
+ * Interface for custom token verification implementations.
5
+ * Allows integration with various authentication providers (JWT, OAuth, custom tokens).
6
+ *
7
+ * @template T - The type of user data returned after successful token verification
8
+ *
9
+ * @example
10
+ * JWT token verification:
11
+ * ```typescript
12
+ * import jwt from 'jsonwebtoken';
13
+ * import { CustomTokenVerificationPort } from '@noony-serverless/core';
14
+ *
15
+ * interface User {
16
+ * id: string;
17
+ * email: string;
18
+ * roles: string[];
19
+ * }
20
+ *
21
+ * class JWTVerificationPort implements CustomTokenVerificationPort<User> {
22
+ * constructor(private secret: string) {}
23
+ *
24
+ * async verifyToken(token: string): Promise<User> {
25
+ * try {
26
+ * const payload = jwt.verify(token, this.secret) as any;
27
+ * return {
28
+ * id: payload.sub,
29
+ * email: payload.email,
30
+ * roles: payload.roles || []
31
+ * };
32
+ * } catch (error) {
33
+ * throw new Error('Invalid token');
34
+ * }
35
+ * }
36
+ * }
37
+ * ```
38
+ *
39
+ * @example
40
+ * Custom API token verification:
41
+ * ```typescript
42
+ * class APIKeyVerificationPort implements CustomTokenVerificationPort<{ apiKey: string; permissions: string[] }> {
43
+ * async verifyToken(token: string): Promise<{ apiKey: string; permissions: string[] }> {
44
+ * const apiKey = await this.validateAPIKey(token);
45
+ * if (!apiKey) {
46
+ * throw new Error('Invalid API key');
47
+ * }
48
+ * return {
49
+ * apiKey: token,
50
+ * permissions: apiKey.permissions
51
+ * };
52
+ * }
53
+ *
54
+ * private async validateAPIKey(key: string) {
55
+ * // Validate against database or external service
56
+ * return { permissions: ['read', 'write'] };
57
+ * }
58
+ * }
59
+ * ```
60
+ */
3
61
  export interface CustomTokenVerificationPort<T> {
4
62
  verifyToken(token: string): Promise<T>;
5
63
  }
64
+ /**
65
+ * Standard JWT payload interface with common claims.
66
+ * Extends the payload with custom properties as needed.
67
+ *
68
+ * @example
69
+ * Basic JWT payload usage:
70
+ * ```typescript
71
+ * import { JWTPayload } from '@noony-serverless/core';
72
+ *
73
+ * interface CustomJWTPayload extends JWTPayload {
74
+ * userId: string;
75
+ * email: string;
76
+ * roles: string[];
77
+ * }
78
+ *
79
+ * const payload: CustomJWTPayload = {
80
+ * sub: 'user-123',
81
+ * exp: Math.floor(Date.now() / 1000) + 3600, // 1 hour
82
+ * iat: Math.floor(Date.now() / 1000),
83
+ * iss: 'my-app',
84
+ * aud: 'my-app-users',
85
+ * userId: 'user-123',
86
+ * email: 'user@example.com',
87
+ * roles: ['user', 'admin']
88
+ * };
89
+ * ```
90
+ *
91
+ * @example
92
+ * Token validation with custom claims:
93
+ * ```typescript
94
+ * function validateCustomClaims(payload: JWTPayload & { roles?: string[] }) {
95
+ * if (!payload.roles || payload.roles.length === 0) {
96
+ * throw new Error('User must have at least one role');
97
+ * }
98
+ *
99
+ * if (payload.exp && payload.exp < Date.now() / 1000) {
100
+ * throw new Error('Token has expired');
101
+ * }
102
+ * }
103
+ * ```
104
+ */
6
105
  export interface JWTPayload {
7
106
  exp?: number;
8
107
  iat?: number;
@@ -13,6 +112,70 @@ export interface JWTPayload {
13
112
  sub?: string;
14
113
  [key: string]: unknown;
15
114
  }
115
+ /**
116
+ * Configuration options for authentication middleware.
117
+ * Provides comprehensive security controls and validation settings.
118
+ *
119
+ * @example
120
+ * Basic authentication options:
121
+ * ```typescript
122
+ * import { AuthenticationOptions } from '@noony-serverless/core';
123
+ *
124
+ * const basicOptions: AuthenticationOptions = {
125
+ * maxTokenAge: 3600, // 1 hour
126
+ * clockTolerance: 60, // 1 minute
127
+ * requiredClaims: {
128
+ * issuer: 'my-app',
129
+ * audience: 'my-app-users'
130
+ * }
131
+ * };
132
+ * ```
133
+ *
134
+ * @example
135
+ * Advanced options with rate limiting and blacklisting:
136
+ * ```typescript
137
+ * const advancedOptions: AuthenticationOptions = {
138
+ * maxTokenAge: 7200, // 2 hours
139
+ * clockTolerance: 30,
140
+ * rateLimiting: {
141
+ * maxAttempts: 5,
142
+ * windowMs: 15 * 60 * 1000 // 15 minutes
143
+ * },
144
+ * isTokenBlacklisted: async (tokenId) => {
145
+ * // Check Redis or database for blacklisted tokens
146
+ * return await redis.sismember('blacklisted_tokens', tokenId);
147
+ * },
148
+ * requiredClaims: {
149
+ * issuer: 'secure-app',
150
+ * audience: ['web-app', 'mobile-app']
151
+ * }
152
+ * };
153
+ * ```
154
+ *
155
+ * @example
156
+ * Production security configuration:
157
+ * ```typescript
158
+ * const productionOptions: AuthenticationOptions = {
159
+ * maxTokenAge: 1800, // 30 minutes - short for security
160
+ * clockTolerance: 10, // Tight tolerance
161
+ * rateLimiting: {
162
+ * maxAttempts: 3, // Strict rate limiting
163
+ * windowMs: 30 * 60 * 1000 // 30 minutes lockout
164
+ * },
165
+ * isTokenBlacklisted: async (tokenId) => {
166
+ * const result = await database.query(
167
+ * 'SELECT 1 FROM revoked_tokens WHERE jti = ?',
168
+ * [tokenId]
169
+ * );
170
+ * return result.length > 0;
171
+ * },
172
+ * requiredClaims: {
173
+ * issuer: 'production-auth-server',
174
+ * audience: 'production-api'
175
+ * }
176
+ * };
177
+ * ```
178
+ */
16
179
  export interface AuthenticationOptions {
17
180
  /**
18
181
  * Maximum token age in seconds (overrides exp claim validation)
@@ -42,11 +205,227 @@ export interface AuthenticationOptions {
42
205
  audience?: string | string[];
43
206
  };
44
207
  }
208
+ /**
209
+ * Class-based authentication middleware with comprehensive security features.
210
+ * Provides JWT validation, rate limiting, token blacklisting, and security logging.
211
+ *
212
+ * @template T - The type of user data returned by the token verification port
213
+ *
214
+ * @example
215
+ * Basic JWT authentication:
216
+ * ```typescript
217
+ * import { Handler, AuthenticationMiddleware } from '@noony-serverless/core';
218
+ * import jwt from 'jsonwebtoken';
219
+ *
220
+ * interface User {
221
+ * id: string;
222
+ * email: string;
223
+ * roles: string[];
224
+ * }
225
+ *
226
+ * class JWTVerifier implements CustomTokenVerificationPort<User> {
227
+ * async verifyToken(token: string): Promise<User> {
228
+ * const payload = jwt.verify(token, process.env.JWT_SECRET!) as any;
229
+ * return {
230
+ * id: payload.sub,
231
+ * email: payload.email,
232
+ * roles: payload.roles || []
233
+ * };
234
+ * }
235
+ * }
236
+ *
237
+ * const protectedHandler = new Handler()
238
+ * .use(new AuthenticationMiddleware(new JWTVerifier()))
239
+ * .handle(async (request, context) => {
240
+ * const user = context.user as User;
241
+ * return {
242
+ * success: true,
243
+ * data: { message: `Hello ${user.email}`, userId: user.id }
244
+ * };
245
+ * });
246
+ * ```
247
+ *
248
+ * @example
249
+ * Advanced authentication with security options:
250
+ * ```typescript
251
+ * const secureAuthMiddleware = new AuthenticationMiddleware(
252
+ * new JWTVerifier(),
253
+ * {
254
+ * maxTokenAge: 1800, // 30 minutes
255
+ * rateLimiting: {
256
+ * maxAttempts: 5,
257
+ * windowMs: 15 * 60 * 1000 // 15 minutes
258
+ * },
259
+ * isTokenBlacklisted: async (tokenId) => {
260
+ * return await redis.sismember('revoked_tokens', tokenId);
261
+ * },
262
+ * requiredClaims: {
263
+ * issuer: 'my-auth-server',
264
+ * audience: 'my-api'
265
+ * }
266
+ * }
267
+ * );
268
+ *
269
+ * const secureHandler = new Handler()
270
+ * .use(secureAuthMiddleware)
271
+ * .handle(async (request, context) => {
272
+ * // Only authenticated users reach here
273
+ * return { success: true, data: 'Secure data' };
274
+ * });
275
+ * ```
276
+ *
277
+ * @example
278
+ * Google Cloud Functions integration:
279
+ * ```typescript
280
+ * import { http } from '@google-cloud/functions-framework';
281
+ *
282
+ * const userProfileHandler = new Handler()
283
+ * .use(new AuthenticationMiddleware(new JWTVerifier()))
284
+ * .handle(async (request, context) => {
285
+ * const user = context.user as User;
286
+ * const profile = await getUserProfile(user.id);
287
+ * return { success: true, data: profile };
288
+ * });
289
+ *
290
+ * export const getUserProfile = http('getUserProfile', (req, res) => {
291
+ * return userProfileHandler.execute(req, res);
292
+ * });
293
+ * ```
294
+ */
45
295
  export declare class AuthenticationMiddleware<T> implements BaseMiddleware {
46
296
  private tokenVerificationPort;
47
297
  private options;
48
298
  constructor(tokenVerificationPort: CustomTokenVerificationPort<T>, options?: AuthenticationOptions);
49
299
  before(context: Context): Promise<void>;
50
300
  }
301
+ /**
302
+ * Factory function that creates an authentication middleware with token verification.
303
+ * Provides a functional approach for authentication setup.
304
+ *
305
+ * @template T - The type of user data returned by the token verification port
306
+ * @param tokenVerificationPort - The token verification implementation
307
+ * @param options - Authentication configuration options
308
+ * @returns A BaseMiddleware object with authentication logic
309
+ *
310
+ * @example
311
+ * Simple JWT authentication:
312
+ * ```typescript
313
+ * import { Handler, verifyAuthTokenMiddleware } from '@noony-serverless/core';
314
+ *
315
+ * class SimpleJWTVerifier implements CustomTokenVerificationPort<{ userId: string }> {
316
+ * async verifyToken(token: string): Promise<{ userId: string }> {
317
+ * // Simple token verification logic
318
+ * if (token === 'valid-token') {
319
+ * return { userId: 'user-123' };
320
+ * }
321
+ * throw new Error('Invalid token');
322
+ * }
323
+ * }
324
+ *
325
+ * const handler = new Handler()
326
+ * .use(verifyAuthTokenMiddleware(new SimpleJWTVerifier()))
327
+ * .handle(async (request, context) => {
328
+ * const user = context.user as { userId: string };
329
+ * return { success: true, userId: user.userId };
330
+ * });
331
+ * ```
332
+ *
333
+ * @example
334
+ * API key authentication with rate limiting:
335
+ * ```typescript
336
+ * interface APIKeyUser {
337
+ * keyId: string;
338
+ * permissions: string[];
339
+ * organization: string;
340
+ * }
341
+ *
342
+ * class APIKeyVerifier implements CustomTokenVerificationPort<APIKeyUser> {
343
+ * async verifyToken(token: string): Promise<APIKeyUser> {
344
+ * const keyData = await this.validateAPIKey(token);
345
+ * if (!keyData) {
346
+ * throw new Error('Invalid API key');
347
+ * }
348
+ * return keyData;
349
+ * }
350
+ *
351
+ * private async validateAPIKey(key: string): Promise<APIKeyUser | null> {
352
+ * // Database lookup or external validation
353
+ * return {
354
+ * keyId: 'key-123',
355
+ * permissions: ['read', 'write'],
356
+ * organization: 'org-456'
357
+ * };
358
+ * }
359
+ * }
360
+ *
361
+ * const apiHandler = new Handler()
362
+ * .use(verifyAuthTokenMiddleware(
363
+ * new APIKeyVerifier(),
364
+ * {
365
+ * rateLimiting: {
366
+ * maxAttempts: 100,
367
+ * windowMs: 60 * 1000 // 1 minute
368
+ * }
369
+ * }
370
+ * ))
371
+ * .handle(async (request, context) => {
372
+ * const apiUser = context.user as APIKeyUser;
373
+ * return {
374
+ * success: true,
375
+ * data: { organization: apiUser.organization }
376
+ * };
377
+ * });
378
+ * ```
379
+ *
380
+ * @example
381
+ * Express-style middleware chain:
382
+ * ```typescript
383
+ * import { Handler, verifyAuthTokenMiddleware, errorHandler } from '@noony-serverless/core';
384
+ *
385
+ * const authMiddleware = verifyAuthTokenMiddleware(
386
+ * new JWTVerifier(),
387
+ * {
388
+ * maxTokenAge: 3600,
389
+ * requiredClaims: {
390
+ * issuer: 'my-app',
391
+ * audience: 'api-users'
392
+ * }
393
+ * }
394
+ * );
395
+ *
396
+ * const protectedEndpoint = new Handler()
397
+ * .use(authMiddleware)
398
+ * .use(errorHandler())
399
+ * .handle(async (request, context) => {
400
+ * // Authenticated user available in context.user
401
+ * return { success: true, data: 'Protected resource' };
402
+ * });
403
+ * ```
404
+ *
405
+ * @example
406
+ * Multiple authentication strategies:
407
+ * ```typescript
408
+ * // Different handlers for different auth types
409
+ * const jwtHandler = new Handler()
410
+ * .use(verifyAuthTokenMiddleware(new JWTVerifier()))
411
+ * .handle(jwtLogic);
412
+ *
413
+ * const apiKeyHandler = new Handler()
414
+ * .use(verifyAuthTokenMiddleware(new APIKeyVerifier()))
415
+ * .handle(apiKeyLogic);
416
+ *
417
+ * // Route based on authentication type
418
+ * export const handleRequest = (req: any, res: any) => {
419
+ * const authHeader = req.headers.authorization;
420
+ * if (authHeader?.startsWith('Bearer jwt.')) {
421
+ * return jwtHandler.execute(req, res);
422
+ * } else if (authHeader?.startsWith('Bearer ak_')) {
423
+ * return apiKeyHandler.execute(req, res);
424
+ * } else {
425
+ * res.status(401).json({ error: 'Authentication required' });
426
+ * }
427
+ * };
428
+ * ```
429
+ */
51
430
  export declare const verifyAuthTokenMiddleware: <T>(tokenVerificationPort: CustomTokenVerificationPort<T>, options?: AuthenticationOptions) => BaseMiddleware;
52
431
  //# sourceMappingURL=authenticationMiddleware.d.ts.map