@morojs/moro 1.5.11 → 1.5.12

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.
@@ -13,6 +13,7 @@ export { session } from './session';
13
13
  export { cache } from './cache';
14
14
  export { cdn } from './cdn';
15
15
  export { requireAuth, requireRole, requirePermission, requireAdmin, guestOnly, optionalAuth, withAuth, protectedRoute, authUtils, authResponses, sessionHelpers, } from './auth-helpers';
16
+ export { safeVerifyJWT, extractJWTFromHeader, createAuthErrorResponse, type JWTVerificationResult, } from './jwt-helpers';
16
17
  export { extendedProviders, enterpriseProviders, createCustomOAuthProvider, createCustomOIDCProvider, } from './auth-providers';
17
18
  export declare const builtInMiddleware: {
18
19
  auth: (options: import("../../..").AuthOptions) => import("..").MiddlewareInterface;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.simpleMiddleware = exports.builtInMiddleware = exports.createCustomOIDCProvider = exports.createCustomOAuthProvider = exports.enterpriseProviders = exports.extendedProviders = exports.sessionHelpers = exports.authResponses = exports.authUtils = exports.protectedRoute = exports.withAuth = exports.optionalAuth = exports.guestOnly = exports.requireAdmin = exports.requirePermission = exports.requireRole = exports.requireAuth = exports.cdn = exports.cache = exports.session = exports.sse = exports.csp = exports.csrf = exports.cookie = exports.errorTracker = exports.performanceMonitor = exports.requestLogger = exports.validation = exports.cors = exports.rateLimit = exports.auth = void 0;
3
+ exports.simpleMiddleware = exports.builtInMiddleware = exports.createCustomOIDCProvider = exports.createCustomOAuthProvider = exports.enterpriseProviders = exports.extendedProviders = exports.createAuthErrorResponse = exports.extractJWTFromHeader = exports.safeVerifyJWT = exports.sessionHelpers = exports.authResponses = exports.authUtils = exports.protectedRoute = exports.withAuth = exports.optionalAuth = exports.guestOnly = exports.requireAdmin = exports.requirePermission = exports.requireRole = exports.requireAuth = exports.cdn = exports.cache = exports.session = exports.sse = exports.csp = exports.csrf = exports.cookie = exports.errorTracker = exports.performanceMonitor = exports.requestLogger = exports.validation = exports.cors = exports.rateLimit = exports.auth = void 0;
4
4
  // Built-in Middleware Exports
5
5
  var auth_1 = require("./auth");
6
6
  Object.defineProperty(exports, "auth", { enumerable: true, get: function () { return auth_1.auth; } });
@@ -45,6 +45,11 @@ Object.defineProperty(exports, "protectedRoute", { enumerable: true, get: functi
45
45
  Object.defineProperty(exports, "authUtils", { enumerable: true, get: function () { return auth_helpers_1.authUtils; } });
46
46
  Object.defineProperty(exports, "authResponses", { enumerable: true, get: function () { return auth_helpers_1.authResponses; } });
47
47
  Object.defineProperty(exports, "sessionHelpers", { enumerable: true, get: function () { return auth_helpers_1.sessionHelpers; } });
48
+ // JWT Utilities for Custom Middleware
49
+ var jwt_helpers_1 = require("./jwt-helpers");
50
+ Object.defineProperty(exports, "safeVerifyJWT", { enumerable: true, get: function () { return jwt_helpers_1.safeVerifyJWT; } });
51
+ Object.defineProperty(exports, "extractJWTFromHeader", { enumerable: true, get: function () { return jwt_helpers_1.extractJWTFromHeader; } });
52
+ Object.defineProperty(exports, "createAuthErrorResponse", { enumerable: true, get: function () { return jwt_helpers_1.createAuthErrorResponse; } });
48
53
  var auth_providers_1 = require("./auth-providers");
49
54
  Object.defineProperty(exports, "extendedProviders", { enumerable: true, get: function () { return auth_providers_1.extendedProviders; } });
50
55
  Object.defineProperty(exports, "enterpriseProviders", { enumerable: true, get: function () { return auth_providers_1.enterpriseProviders; } });
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/core/middleware/built-in/index.ts"],"names":[],"mappings":";;;AAAA,8BAA8B;AAC9B,+BAA8B;AAArB,4FAAA,IAAI,OAAA;AACb,2CAAyC;AAAhC,uGAAA,SAAS,OAAA;AAClB,+BAA8B;AAArB,4FAAA,IAAI,OAAA;AACb,2CAA0C;AAAjC,wGAAA,UAAU,OAAA;AACnB,mDAAiD;AAAxC,+GAAA,aAAa,OAAA;AACtB,6DAA2D;AAAlD,yHAAA,kBAAkB,OAAA;AAC3B,iDAA+C;AAAtC,6GAAA,YAAY,OAAA;AAErB,6CAA6C;AAC7C,mCAAkC;AAAzB,gGAAA,MAAM,OAAA;AACf,+BAA8B;AAArB,4FAAA,IAAI,OAAA;AACb,6BAA4B;AAAnB,0FAAA,GAAG,OAAA;AACZ,6BAA4B;AAAnB,0FAAA,GAAG,OAAA;AACZ,qCAAoC;AAA3B,kGAAA,OAAO,OAAA;AAEhB,gCAAgC;AAChC,iCAAgC;AAAvB,8FAAA,KAAK,OAAA;AACd,6BAA4B;AAAnB,0FAAA,GAAG,OAAA;AAEZ,sCAAsC;AACtC,+CAYwB;AAXtB,2GAAA,WAAW,OAAA;AACX,2GAAA,WAAW,OAAA;AACX,iHAAA,iBAAiB,OAAA;AACjB,4GAAA,YAAY,OAAA;AACZ,yGAAA,SAAS,OAAA;AACT,4GAAA,YAAY,OAAA;AACZ,wGAAA,QAAQ,OAAA;AACR,8GAAA,cAAc,OAAA;AACd,yGAAA,SAAS,OAAA;AACT,6GAAA,aAAa,OAAA;AACb,8GAAA,cAAc,OAAA;AAGhB,mDAK0B;AAJxB,mHAAA,iBAAiB,OAAA;AACjB,qHAAA,mBAAmB,OAAA;AACnB,2HAAA,yBAAyB,OAAA;AACzB,0HAAA,wBAAwB,OAAA;AAG1B,yBAAyB;AACzB,iCAA8B;AAC9B,6CAAyC;AACzC,iCAA8B;AAC9B,6CAA0C;AAC1C,qDAAiD;AACjD,+DAA2D;AAC3D,mDAA+C;AAC/C,qCAAkC;AAClC,iCAA8B;AAC9B,+BAA4B;AAC5B,+BAA4B;AAC5B,uCAAoC;AACpC,mCAAgC;AAChC,+BAA4B;AAEf,QAAA,iBAAiB,GAAG;IAC/B,IAAI,EAAJ,WAAI;IACJ,SAAS,EAAT,sBAAS;IACT,IAAI,EAAJ,WAAI;IACJ,UAAU,EAAV,uBAAU;IACV,sBAAsB;IACtB,MAAM,EAAN,eAAM;IACN,IAAI,EAAJ,WAAI;IACJ,GAAG,EAAH,SAAG;IACH,GAAG,EAAH,SAAG;IACH,OAAO,EAAP,iBAAO;IACP,gCAAgC;IAChC,KAAK,EAAL,aAAK;IACL,GAAG,EAAH,SAAG;CACJ,CAAC;AAEW,QAAA,gBAAgB,GAAG;IAC9B,aAAa,EAAb,8BAAa;IACb,kBAAkB,EAAlB,wCAAkB;IAClB,YAAY,EAAZ,4BAAY;CACb,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/core/middleware/built-in/index.ts"],"names":[],"mappings":";;;AAAA,8BAA8B;AAC9B,+BAA8B;AAArB,4FAAA,IAAI,OAAA;AACb,2CAAyC;AAAhC,uGAAA,SAAS,OAAA;AAClB,+BAA8B;AAArB,4FAAA,IAAI,OAAA;AACb,2CAA0C;AAAjC,wGAAA,UAAU,OAAA;AACnB,mDAAiD;AAAxC,+GAAA,aAAa,OAAA;AACtB,6DAA2D;AAAlD,yHAAA,kBAAkB,OAAA;AAC3B,iDAA+C;AAAtC,6GAAA,YAAY,OAAA;AAErB,6CAA6C;AAC7C,mCAAkC;AAAzB,gGAAA,MAAM,OAAA;AACf,+BAA8B;AAArB,4FAAA,IAAI,OAAA;AACb,6BAA4B;AAAnB,0FAAA,GAAG,OAAA;AACZ,6BAA4B;AAAnB,0FAAA,GAAG,OAAA;AACZ,qCAAoC;AAA3B,kGAAA,OAAO,OAAA;AAEhB,gCAAgC;AAChC,iCAAgC;AAAvB,8FAAA,KAAK,OAAA;AACd,6BAA4B;AAAnB,0FAAA,GAAG,OAAA;AAEZ,sCAAsC;AACtC,+CAYwB;AAXtB,2GAAA,WAAW,OAAA;AACX,2GAAA,WAAW,OAAA;AACX,iHAAA,iBAAiB,OAAA;AACjB,4GAAA,YAAY,OAAA;AACZ,yGAAA,SAAS,OAAA;AACT,4GAAA,YAAY,OAAA;AACZ,wGAAA,QAAQ,OAAA;AACR,8GAAA,cAAc,OAAA;AACd,yGAAA,SAAS,OAAA;AACT,6GAAA,aAAa,OAAA;AACb,8GAAA,cAAc,OAAA;AAGhB,sCAAsC;AACtC,6CAKuB;AAJrB,4GAAA,aAAa,OAAA;AACb,mHAAA,oBAAoB,OAAA;AACpB,sHAAA,uBAAuB,OAAA;AAIzB,mDAK0B;AAJxB,mHAAA,iBAAiB,OAAA;AACjB,qHAAA,mBAAmB,OAAA;AACnB,2HAAA,yBAAyB,OAAA;AACzB,0HAAA,wBAAwB,OAAA;AAG1B,yBAAyB;AACzB,iCAA8B;AAC9B,6CAAyC;AACzC,iCAA8B;AAC9B,6CAA0C;AAC1C,qDAAiD;AACjD,+DAA2D;AAC3D,mDAA+C;AAC/C,qCAAkC;AAClC,iCAA8B;AAC9B,+BAA4B;AAC5B,+BAA4B;AAC5B,uCAAoC;AACpC,mCAAgC;AAChC,+BAA4B;AAEf,QAAA,iBAAiB,GAAG;IAC/B,IAAI,EAAJ,WAAI;IACJ,SAAS,EAAT,sBAAS;IACT,IAAI,EAAJ,WAAI;IACJ,UAAU,EAAV,uBAAU;IACV,sBAAsB;IACtB,MAAM,EAAN,eAAM;IACN,IAAI,EAAJ,WAAI;IACJ,GAAG,EAAH,SAAG;IACH,GAAG,EAAH,SAAG;IACH,OAAO,EAAP,iBAAO;IACP,gCAAgC;IAChC,KAAK,EAAL,aAAK;IACL,GAAG,EAAH,SAAG;CACJ,CAAC;AAEW,QAAA,gBAAgB,GAAG;IAC9B,aAAa,EAAb,8BAAa;IACb,kBAAkB,EAAlB,wCAAkB;IAClB,YAAY,EAAZ,4BAAY;CACb,CAAC"}
@@ -0,0 +1,93 @@
1
+ /**
2
+ * JWT Error Handling Utilities for Custom Middleware
3
+ *
4
+ * This module provides utilities to help users handle JWT errors gracefully
5
+ * in their custom authentication middleware.
6
+ */
7
+ export interface JWTVerificationResult {
8
+ success: boolean;
9
+ payload?: any;
10
+ error?: {
11
+ type: 'expired' | 'invalid' | 'malformed' | 'missing_secret' | 'unknown';
12
+ message: string;
13
+ expiredAt?: Date;
14
+ date?: Date;
15
+ };
16
+ }
17
+ /**
18
+ * Safely verify a JWT token with proper error handling
19
+ *
20
+ * @param token - The JWT token to verify
21
+ * @param secret - The secret key for verification
22
+ * @param options - Additional JWT verification options
23
+ * @returns JWTVerificationResult with success status and payload or error details
24
+ */
25
+ export declare function safeVerifyJWT(token: string, secret: string, options?: any): JWTVerificationResult;
26
+ /**
27
+ * Extract JWT token from Authorization header
28
+ *
29
+ * @param authHeader - The Authorization header value
30
+ * @returns The JWT token or null if not found/invalid format
31
+ */
32
+ export declare function extractJWTFromHeader(authHeader: string | undefined): string | null;
33
+ /**
34
+ * Create a standardized auth middleware error response
35
+ *
36
+ * @param error - The JWT verification error
37
+ * @returns Standardized error response object
38
+ */
39
+ export declare function createAuthErrorResponse(error: JWTVerificationResult['error']): {
40
+ success: boolean;
41
+ error: string;
42
+ message: string;
43
+ expiredAt?: undefined;
44
+ availableAt?: undefined;
45
+ } | {
46
+ success: boolean;
47
+ error: string;
48
+ message: string;
49
+ expiredAt: Date | undefined;
50
+ availableAt?: undefined;
51
+ } | {
52
+ success: boolean;
53
+ error: string;
54
+ message: string;
55
+ availableAt: Date | undefined;
56
+ expiredAt?: undefined;
57
+ };
58
+ /**
59
+ * Example usage for custom middleware:
60
+ *
61
+ * ```typescript
62
+ * import { safeVerifyJWT, extractJWTFromHeader, createAuthErrorResponse } from '@morojs/moro';
63
+ *
64
+ * const authMiddleware = async (req: any, res: any, next: any) => {
65
+ * const token = extractJWTFromHeader(req.headers.authorization);
66
+ *
67
+ * if (!token) {
68
+ * return res.status(401).json({
69
+ * success: false,
70
+ * error: 'Missing token',
71
+ * message: 'Authorization header with Bearer token is required'
72
+ * });
73
+ * }
74
+ *
75
+ * const result = safeVerifyJWT(token, process.env.JWT_SECRET!);
76
+ *
77
+ * if (!result.success) {
78
+ * const errorResponse = createAuthErrorResponse(result.error);
79
+ * return res.status(401).json(errorResponse);
80
+ * }
81
+ *
82
+ * // Token is valid - attach user info to request
83
+ * req.user = result.payload;
84
+ * req.auth = {
85
+ * user: result.payload,
86
+ * isAuthenticated: true,
87
+ * token
88
+ * };
89
+ *
90
+ * next();
91
+ * };
92
+ * ```
93
+ */
@@ -0,0 +1,196 @@
1
+ "use strict";
2
+ /**
3
+ * JWT Error Handling Utilities for Custom Middleware
4
+ *
5
+ * This module provides utilities to help users handle JWT errors gracefully
6
+ * in their custom authentication middleware.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.safeVerifyJWT = safeVerifyJWT;
10
+ exports.extractJWTFromHeader = extractJWTFromHeader;
11
+ exports.createAuthErrorResponse = createAuthErrorResponse;
12
+ /**
13
+ * Safely verify a JWT token with proper error handling
14
+ *
15
+ * @param token - The JWT token to verify
16
+ * @param secret - The secret key for verification
17
+ * @param options - Additional JWT verification options
18
+ * @returns JWTVerificationResult with success status and payload or error details
19
+ */
20
+ function safeVerifyJWT(token, secret, options = {}) {
21
+ // Check if jsonwebtoken is available
22
+ let jwt;
23
+ try {
24
+ jwt = require('jsonwebtoken');
25
+ }
26
+ catch (error) {
27
+ return {
28
+ success: false,
29
+ error: {
30
+ type: 'missing_secret',
31
+ message: 'JWT verification requires the "jsonwebtoken" package. ' +
32
+ 'Please install it with: npm install jsonwebtoken @types/jsonwebtoken',
33
+ },
34
+ };
35
+ }
36
+ if (!secret) {
37
+ return {
38
+ success: false,
39
+ error: {
40
+ type: 'missing_secret',
41
+ message: 'JWT verification requires a secret. ' +
42
+ 'Please provide a secret for token verification.',
43
+ },
44
+ };
45
+ }
46
+ try {
47
+ const payload = jwt.verify(token, secret, options);
48
+ return {
49
+ success: true,
50
+ payload,
51
+ };
52
+ }
53
+ catch (error) {
54
+ // Handle specific JWT errors gracefully
55
+ if (error.name === 'TokenExpiredError') {
56
+ return {
57
+ success: false,
58
+ error: {
59
+ type: 'expired',
60
+ message: 'JWT token has expired',
61
+ expiredAt: error.expiredAt,
62
+ },
63
+ };
64
+ }
65
+ else if (error.name === 'JsonWebTokenError') {
66
+ return {
67
+ success: false,
68
+ error: {
69
+ type: 'invalid',
70
+ message: 'Invalid JWT token format or signature',
71
+ },
72
+ };
73
+ }
74
+ else if (error.name === 'NotBeforeError') {
75
+ return {
76
+ success: false,
77
+ error: {
78
+ type: 'malformed',
79
+ message: 'JWT token is not active yet',
80
+ date: error.date,
81
+ },
82
+ };
83
+ }
84
+ else {
85
+ return {
86
+ success: false,
87
+ error: {
88
+ type: 'unknown',
89
+ message: `JWT verification failed: ${error.message}`,
90
+ },
91
+ };
92
+ }
93
+ }
94
+ }
95
+ /**
96
+ * Extract JWT token from Authorization header
97
+ *
98
+ * @param authHeader - The Authorization header value
99
+ * @returns The JWT token or null if not found/invalid format
100
+ */
101
+ function extractJWTFromHeader(authHeader) {
102
+ if (!authHeader) {
103
+ return null;
104
+ }
105
+ if (!authHeader.startsWith('Bearer ')) {
106
+ return null;
107
+ }
108
+ const token = authHeader.substring(7);
109
+ return token.trim() || null;
110
+ }
111
+ /**
112
+ * Create a standardized auth middleware error response
113
+ *
114
+ * @param error - The JWT verification error
115
+ * @returns Standardized error response object
116
+ */
117
+ function createAuthErrorResponse(error) {
118
+ if (!error) {
119
+ return {
120
+ success: false,
121
+ error: 'Authentication failed',
122
+ message: 'Unknown authentication error',
123
+ };
124
+ }
125
+ switch (error.type) {
126
+ case 'expired':
127
+ return {
128
+ success: false,
129
+ error: 'Token expired',
130
+ message: 'Your session has expired. Please sign in again.',
131
+ expiredAt: error.expiredAt,
132
+ };
133
+ case 'invalid':
134
+ return {
135
+ success: false,
136
+ error: 'Invalid token',
137
+ message: 'The provided authentication token is invalid.',
138
+ };
139
+ case 'malformed':
140
+ return {
141
+ success: false,
142
+ error: 'Token not ready',
143
+ message: 'The authentication token is not yet valid.',
144
+ availableAt: error.date,
145
+ };
146
+ case 'missing_secret':
147
+ return {
148
+ success: false,
149
+ error: 'Configuration error',
150
+ message: 'Authentication service is not properly configured.',
151
+ };
152
+ default:
153
+ return {
154
+ success: false,
155
+ error: 'Authentication failed',
156
+ message: error.message || 'Authentication verification failed.',
157
+ };
158
+ }
159
+ }
160
+ /**
161
+ * Example usage for custom middleware:
162
+ *
163
+ * ```typescript
164
+ * import { safeVerifyJWT, extractJWTFromHeader, createAuthErrorResponse } from '@morojs/moro';
165
+ *
166
+ * const authMiddleware = async (req: any, res: any, next: any) => {
167
+ * const token = extractJWTFromHeader(req.headers.authorization);
168
+ *
169
+ * if (!token) {
170
+ * return res.status(401).json({
171
+ * success: false,
172
+ * error: 'Missing token',
173
+ * message: 'Authorization header with Bearer token is required'
174
+ * });
175
+ * }
176
+ *
177
+ * const result = safeVerifyJWT(token, process.env.JWT_SECRET!);
178
+ *
179
+ * if (!result.success) {
180
+ * const errorResponse = createAuthErrorResponse(result.error);
181
+ * return res.status(401).json(errorResponse);
182
+ * }
183
+ *
184
+ * // Token is valid - attach user info to request
185
+ * req.user = result.payload;
186
+ * req.auth = {
187
+ * user: result.payload,
188
+ * isAuthenticated: true,
189
+ * token
190
+ * };
191
+ *
192
+ * next();
193
+ * };
194
+ * ```
195
+ */
196
+ //# sourceMappingURL=jwt-helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jwt-helpers.js","sourceRoot":"","sources":["../../../../src/core/middleware/built-in/jwt-helpers.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@morojs/moro",
3
- "version": "1.5.11",
3
+ "version": "1.5.12",
4
4
  "description": "High-performance Node.js framework with intelligent routing, automatic middleware ordering, enterprise authentication (Auth.js), type-safe validation, and functional architecture",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -33,6 +33,14 @@ export {
33
33
  sessionHelpers,
34
34
  } from './auth-helpers';
35
35
 
36
+ // JWT Utilities for Custom Middleware
37
+ export {
38
+ safeVerifyJWT,
39
+ extractJWTFromHeader,
40
+ createAuthErrorResponse,
41
+ type JWTVerificationResult,
42
+ } from './jwt-helpers';
43
+
36
44
  export {
37
45
  extendedProviders,
38
46
  enterpriseProviders,
@@ -0,0 +1,215 @@
1
+ /**
2
+ * JWT Error Handling Utilities for Custom Middleware
3
+ *
4
+ * This module provides utilities to help users handle JWT errors gracefully
5
+ * in their custom authentication middleware.
6
+ */
7
+
8
+ export interface JWTVerificationResult {
9
+ success: boolean;
10
+ payload?: any;
11
+ error?: {
12
+ type: 'expired' | 'invalid' | 'malformed' | 'missing_secret' | 'unknown';
13
+ message: string;
14
+ expiredAt?: Date;
15
+ date?: Date;
16
+ };
17
+ }
18
+
19
+ /**
20
+ * Safely verify a JWT token with proper error handling
21
+ *
22
+ * @param token - The JWT token to verify
23
+ * @param secret - The secret key for verification
24
+ * @param options - Additional JWT verification options
25
+ * @returns JWTVerificationResult with success status and payload or error details
26
+ */
27
+ export function safeVerifyJWT(
28
+ token: string,
29
+ secret: string,
30
+ options: any = {}
31
+ ): JWTVerificationResult {
32
+ // Check if jsonwebtoken is available
33
+ let jwt: any;
34
+ try {
35
+ jwt = require('jsonwebtoken');
36
+ } catch (error) {
37
+ return {
38
+ success: false,
39
+ error: {
40
+ type: 'missing_secret',
41
+ message:
42
+ 'JWT verification requires the "jsonwebtoken" package. ' +
43
+ 'Please install it with: npm install jsonwebtoken @types/jsonwebtoken',
44
+ },
45
+ };
46
+ }
47
+
48
+ if (!secret) {
49
+ return {
50
+ success: false,
51
+ error: {
52
+ type: 'missing_secret',
53
+ message:
54
+ 'JWT verification requires a secret. ' +
55
+ 'Please provide a secret for token verification.',
56
+ },
57
+ };
58
+ }
59
+
60
+ try {
61
+ const payload = jwt.verify(token, secret, options);
62
+ return {
63
+ success: true,
64
+ payload,
65
+ };
66
+ } catch (error: any) {
67
+ // Handle specific JWT errors gracefully
68
+ if (error.name === 'TokenExpiredError') {
69
+ return {
70
+ success: false,
71
+ error: {
72
+ type: 'expired',
73
+ message: 'JWT token has expired',
74
+ expiredAt: error.expiredAt,
75
+ },
76
+ };
77
+ } else if (error.name === 'JsonWebTokenError') {
78
+ return {
79
+ success: false,
80
+ error: {
81
+ type: 'invalid',
82
+ message: 'Invalid JWT token format or signature',
83
+ },
84
+ };
85
+ } else if (error.name === 'NotBeforeError') {
86
+ return {
87
+ success: false,
88
+ error: {
89
+ type: 'malformed',
90
+ message: 'JWT token is not active yet',
91
+ date: error.date,
92
+ },
93
+ };
94
+ } else {
95
+ return {
96
+ success: false,
97
+ error: {
98
+ type: 'unknown',
99
+ message: `JWT verification failed: ${error.message}`,
100
+ },
101
+ };
102
+ }
103
+ }
104
+ }
105
+
106
+ /**
107
+ * Extract JWT token from Authorization header
108
+ *
109
+ * @param authHeader - The Authorization header value
110
+ * @returns The JWT token or null if not found/invalid format
111
+ */
112
+ export function extractJWTFromHeader(authHeader: string | undefined): string | null {
113
+ if (!authHeader) {
114
+ return null;
115
+ }
116
+
117
+ if (!authHeader.startsWith('Bearer ')) {
118
+ return null;
119
+ }
120
+
121
+ const token = authHeader.substring(7);
122
+ return token.trim() || null;
123
+ }
124
+
125
+ /**
126
+ * Create a standardized auth middleware error response
127
+ *
128
+ * @param error - The JWT verification error
129
+ * @returns Standardized error response object
130
+ */
131
+ export function createAuthErrorResponse(error: JWTVerificationResult['error']) {
132
+ if (!error) {
133
+ return {
134
+ success: false,
135
+ error: 'Authentication failed',
136
+ message: 'Unknown authentication error',
137
+ };
138
+ }
139
+
140
+ switch (error.type) {
141
+ case 'expired':
142
+ return {
143
+ success: false,
144
+ error: 'Token expired',
145
+ message: 'Your session has expired. Please sign in again.',
146
+ expiredAt: error.expiredAt,
147
+ };
148
+
149
+ case 'invalid':
150
+ return {
151
+ success: false,
152
+ error: 'Invalid token',
153
+ message: 'The provided authentication token is invalid.',
154
+ };
155
+
156
+ case 'malformed':
157
+ return {
158
+ success: false,
159
+ error: 'Token not ready',
160
+ message: 'The authentication token is not yet valid.',
161
+ availableAt: error.date,
162
+ };
163
+
164
+ case 'missing_secret':
165
+ return {
166
+ success: false,
167
+ error: 'Configuration error',
168
+ message: 'Authentication service is not properly configured.',
169
+ };
170
+
171
+ default:
172
+ return {
173
+ success: false,
174
+ error: 'Authentication failed',
175
+ message: error.message || 'Authentication verification failed.',
176
+ };
177
+ }
178
+ }
179
+
180
+ /**
181
+ * Example usage for custom middleware:
182
+ *
183
+ * ```typescript
184
+ * import { safeVerifyJWT, extractJWTFromHeader, createAuthErrorResponse } from '@morojs/moro';
185
+ *
186
+ * const authMiddleware = async (req: any, res: any, next: any) => {
187
+ * const token = extractJWTFromHeader(req.headers.authorization);
188
+ *
189
+ * if (!token) {
190
+ * return res.status(401).json({
191
+ * success: false,
192
+ * error: 'Missing token',
193
+ * message: 'Authorization header with Bearer token is required'
194
+ * });
195
+ * }
196
+ *
197
+ * const result = safeVerifyJWT(token, process.env.JWT_SECRET!);
198
+ *
199
+ * if (!result.success) {
200
+ * const errorResponse = createAuthErrorResponse(result.error);
201
+ * return res.status(401).json(errorResponse);
202
+ * }
203
+ *
204
+ * // Token is valid - attach user info to request
205
+ * req.user = result.payload;
206
+ * req.auth = {
207
+ * user: result.payload,
208
+ * isAuthenticated: true,
209
+ * token
210
+ * };
211
+ *
212
+ * next();
213
+ * };
214
+ * ```
215
+ */