@rabstack/rab-api 1.12.0 → 1.15.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.
package/index.cjs.js CHANGED
@@ -244,8 +244,8 @@ const isCallBackPipe = (pipe)=>typeof pipe === 'function' && pipe.length == 1;
244
244
  /**
245
245
  * @param message - Human-readable error message (default: 'Unauthorized')
246
246
  * @param errorCode - Optional machine-readable error code
247
- */ constructor(message = 'Unauthorized', errorCode){
248
- super(message, 401, errorCode);
247
+ */ constructor(message = 'Unauthorized', errorCode, errors){
248
+ super(message, 401, errorCode, errors);
249
249
  this.name = 'UnauthorizedException';
250
250
  Error.captureStackTrace(this, this.constructor);
251
251
  }
@@ -262,8 +262,8 @@ const isCallBackPipe = (pipe)=>typeof pipe === 'function' && pipe.length == 1;
262
262
  /**
263
263
  * @param message - Human-readable error message (default: 'Forbidden')
264
264
  * @param errorCode - Optional machine-readable error code
265
- */ constructor(message = 'Forbidden', errorCode){
266
- super(message, 403, errorCode);
265
+ */ constructor(message = 'Forbidden', errorCode, errors){
266
+ super(message, 403, errorCode, errors);
267
267
  this.name = 'ForbiddenException';
268
268
  Error.captureStackTrace(this, this.constructor);
269
269
  }
@@ -280,8 +280,8 @@ const isCallBackPipe = (pipe)=>typeof pipe === 'function' && pipe.length == 1;
280
280
  /**
281
281
  * @param message - Human-readable error message (default: 'Not Found')
282
282
  * @param errorCode - Optional machine-readable error code
283
- */ constructor(message = 'Not Found', errorCode){
284
- super(message, 404, errorCode);
283
+ */ constructor(message = 'Not Found', errorCode, errors){
284
+ super(message, 404, errorCode, errors);
285
285
  this.name = 'NotFoundException';
286
286
  Error.captureStackTrace(this, this.constructor);
287
287
  }
@@ -298,8 +298,8 @@ const isCallBackPipe = (pipe)=>typeof pipe === 'function' && pipe.length == 1;
298
298
  /**
299
299
  * @param message - Human-readable error message (default: 'Method Not Allowed')
300
300
  * @param errorCode - Optional machine-readable error code
301
- */ constructor(message = 'Method Not Allowed', errorCode){
302
- super(message, 405, errorCode);
301
+ */ constructor(message = 'Method Not Allowed', errorCode, errors){
302
+ super(message, 405, errorCode, errors);
303
303
  this.name = 'MethodNotAllowedException';
304
304
  Error.captureStackTrace(this, this.constructor);
305
305
  }
@@ -316,8 +316,8 @@ const isCallBackPipe = (pipe)=>typeof pipe === 'function' && pipe.length == 1;
316
316
  /**
317
317
  * @param message - Human-readable error message (default: 'Request Timeout')
318
318
  * @param errorCode - Optional machine-readable error code
319
- */ constructor(message = 'Request Timeout', errorCode){
320
- super(message, 408, errorCode);
319
+ */ constructor(message = 'Request Timeout', errorCode, errors){
320
+ super(message, 408, errorCode, errors);
321
321
  this.name = 'RequestTimeoutException';
322
322
  Error.captureStackTrace(this, this.constructor);
323
323
  }
@@ -334,8 +334,8 @@ const isCallBackPipe = (pipe)=>typeof pipe === 'function' && pipe.length == 1;
334
334
  /**
335
335
  * @param message - Human-readable error message
336
336
  * @param errorCode - Optional machine-readable error code
337
- */ constructor(message, errorCode){
338
- super(message, 409, errorCode);
337
+ */ constructor(message, errorCode, errors){
338
+ super(message, 409, errorCode, errors);
339
339
  this.name = 'ConflictException';
340
340
  Error.captureStackTrace(this, this.constructor);
341
341
  }
@@ -352,8 +352,8 @@ const isCallBackPipe = (pipe)=>typeof pipe === 'function' && pipe.length == 1;
352
352
  /**
353
353
  * @param message - Human-readable error message (default: 'Payload Too Large')
354
354
  * @param errorCode - Optional machine-readable error code
355
- */ constructor(message = 'Payload Too Large', errorCode){
356
- super(message, 413, errorCode);
355
+ */ constructor(message = 'Payload Too Large', errorCode, errors){
356
+ super(message, 413, errorCode, errors);
357
357
  this.name = 'PayloadTooLargeException';
358
358
  Error.captureStackTrace(this, this.constructor);
359
359
  }
@@ -393,8 +393,8 @@ const isCallBackPipe = (pipe)=>typeof pipe === 'function' && pipe.length == 1;
393
393
  /**
394
394
  * @param message - Human-readable error message (default: 'Too Many Requests')
395
395
  * @param errorCode - Optional machine-readable error code
396
- */ constructor(message = 'Too Many Requests', errorCode){
397
- super(message, 429, errorCode);
396
+ */ constructor(message = 'Too Many Requests', errorCode, errors){
397
+ super(message, 429, errorCode, errors);
398
398
  this.name = 'TooManyRequestsException';
399
399
  Error.captureStackTrace(this, this.constructor);
400
400
  }
@@ -411,8 +411,8 @@ const isCallBackPipe = (pipe)=>typeof pipe === 'function' && pipe.length == 1;
411
411
  /**
412
412
  * @param message - Human-readable error message (default: 'Internal Server Error')
413
413
  * @param errorCode - Optional machine-readable error code
414
- */ constructor(message = 'Internal Server Error', errorCode){
415
- super(message, 500, errorCode);
414
+ */ constructor(message = 'Internal Server Error', errorCode, errors){
415
+ super(message, 500, errorCode, errors);
416
416
  this.name = 'InternalServerErrorException';
417
417
  Error.captureStackTrace(this, this.constructor);
418
418
  }
@@ -429,8 +429,8 @@ const isCallBackPipe = (pipe)=>typeof pipe === 'function' && pipe.length == 1;
429
429
  /**
430
430
  * @param message - Human-readable error message (default: 'Service Unavailable')
431
431
  * @param errorCode - Optional machine-readable error code
432
- */ constructor(message = 'Service Unavailable', errorCode){
433
- super(message, 503, errorCode);
432
+ */ constructor(message = 'Service Unavailable', errorCode, errors){
433
+ super(message, 503, errorCode, errors);
434
434
  this.name = 'ServiceUnavailableException';
435
435
  Error.captureStackTrace(this, this.constructor);
436
436
  }
@@ -688,22 +688,28 @@ const controllerHandler = (controller, config)=>{
688
688
  };
689
689
 
690
690
  const authHandler = (isProtected, config)=>(req, res, next)=>{
691
- console.log('authHandler:', req.path, ':isProtected:', isProtected);
691
+ var _config_debug;
692
+ const debug = (_config_debug = config.debug) != null ? _config_debug : false;
693
+ if (debug) console.log('authHandler:', req.path, ':isProtected:', isProtected);
692
694
  const token = extractTokenFromHeader(req);
693
695
  // If not protected and no token, just continue
694
696
  if (!isProtected && !token) return next();
695
697
  // If no token but route is protected, throw error
696
698
  if (!token) {
697
- console.log('authHandler:UnauthorizedException:Token Not Found');
699
+ if (debug) console.log('authHandler:UnauthorizedException:Token Not Found');
698
700
  throw new UnauthorizedException('Unauthorized', config.errorCode);
699
701
  }
700
- // Token exists - verify it (must be valid regardless of protection)
702
+ // Token exists - verify it
701
703
  try {
702
- const payload = jwt.verify(token, config.jwt.secret_key);
704
+ const payload = jwt.verify(token, config.jwt.secret_key, {
705
+ algorithms: config.jwt.algorithms
706
+ });
703
707
  req['auth'] = payload;
704
708
  return next();
705
709
  } catch (err) {
706
- console.error('authHandler:JWT Error:', err.message);
710
+ // If route is not protected, silently continue without auth
711
+ if (!isProtected) return next();
712
+ if (debug) console.error('authHandler:JWT Error:', err.message);
707
713
  throw new UnauthorizedException('Unauthorized', config.errorCode);
708
714
  }
709
715
  };
@@ -1131,7 +1137,9 @@ class AtomExpressApp {
1131
1137
  //auth middleware
1132
1138
  if (this.options.auth) {
1133
1139
  var _config_isProtected;
1134
- allPipes.unshift(authHandler((_config_isProtected = config.isProtected) != null ? _config_isProtected : this.options.enforceRouteProtection, this.options.auth));
1140
+ allPipes.unshift(authHandler((_config_isProtected = config.isProtected) != null ? _config_isProtected : this.options.enforceRouteProtection, _extends({}, this.options.auth, {
1141
+ debug: this.options.debug
1142
+ })));
1135
1143
  }
1136
1144
  //add body validation to validate the schema and inject request context
1137
1145
  if (config.bodySchema && !config.disableBodyValidation) {
package/index.esm.d.ts CHANGED
@@ -78,6 +78,7 @@ export declare type AtomExpressOptions = {
78
78
  errorHandler?: (err: any, req: Request_2, res: Response_2, next: NextFunction) => any;
79
79
  enforceBodyValidation?: boolean;
80
80
  enforceRouteProtection?: boolean;
81
+ debug?: boolean;
81
82
  auth?: AuthHandlerOptions;
82
83
  openapi?: {
83
84
  enabled?: boolean;
@@ -124,6 +125,7 @@ export declare const authHandler: (isProtected: boolean, config: AuthHandlerOpti
124
125
 
125
126
  export declare type AuthHandlerOptions = {
126
127
  errorCode?: string;
128
+ debug?: boolean;
127
129
  jwt: {
128
130
  secret_key: string;
129
131
  algorithms: any;
@@ -207,7 +209,7 @@ export declare class ConflictException extends RabApiError {
207
209
  * @param message - Human-readable error message
208
210
  * @param errorCode - Optional machine-readable error code
209
211
  */
210
- constructor(message: string, errorCode?: string);
212
+ constructor(message: string, errorCode?: string, errors?: string[]);
211
213
  }
212
214
 
213
215
  /**
@@ -405,7 +407,7 @@ export declare class ForbiddenException extends RabApiError {
405
407
  * @param message - Human-readable error message (default: 'Forbidden')
406
408
  * @param errorCode - Optional machine-readable error code
407
409
  */
408
- constructor(message?: string, errorCode?: string);
410
+ constructor(message?: string, errorCode?: string, errors?: string[]);
409
411
  }
410
412
 
411
413
  /**
@@ -555,7 +557,7 @@ export declare class InternalServerErrorException extends RabApiError {
555
557
  * @param message - Human-readable error message (default: 'Internal Server Error')
556
558
  * @param errorCode - Optional machine-readable error code
557
559
  */
558
- constructor(message?: string, errorCode?: string);
560
+ constructor(message?: string, errorCode?: string, errors?: string[]);
559
561
  }
560
562
 
561
563
  export declare const isCallBackPipe: (pipe: PipeFn | PipeFnCallBack) => pipe is PipeFnCallBack;
@@ -594,7 +596,7 @@ export declare class MethodNotAllowedException extends RabApiError {
594
596
  * @param message - Human-readable error message (default: 'Method Not Allowed')
595
597
  * @param errorCode - Optional machine-readable error code
596
598
  */
597
- constructor(message?: string, errorCode?: string);
599
+ constructor(message?: string, errorCode?: string, errors?: string[]);
598
600
  }
599
601
 
600
602
  /**
@@ -616,7 +618,7 @@ export declare class NotFoundException extends RabApiError {
616
618
  * @param message - Human-readable error message (default: 'Not Found')
617
619
  * @param errorCode - Optional machine-readable error code
618
620
  */
619
- constructor(message?: string, errorCode?: string);
621
+ constructor(message?: string, errorCode?: string, errors?: string[]);
620
622
  }
621
623
 
622
624
  export declare type OpenApiDocsMetadata = {
@@ -713,7 +715,7 @@ export declare class PayloadTooLargeException extends RabApiError {
713
715
  * @param message - Human-readable error message (default: 'Payload Too Large')
714
716
  * @param errorCode - Optional machine-readable error code
715
717
  */
716
- constructor(message?: string, errorCode?: string);
718
+ constructor(message?: string, errorCode?: string, errors?: string[]);
717
719
  }
718
720
 
719
721
  /**
@@ -939,7 +941,7 @@ export declare class RequestTimeoutException extends RabApiError {
939
941
  * @param message - Human-readable error message (default: 'Request Timeout')
940
942
  * @param errorCode - Optional machine-readable error code
941
943
  */
942
- constructor(message?: string, errorCode?: string);
944
+ constructor(message?: string, errorCode?: string, errors?: string[]);
943
945
  }
944
946
 
945
947
  /**
@@ -975,7 +977,7 @@ export declare class ServiceUnavailableException extends RabApiError {
975
977
  * @param message - Human-readable error message (default: 'Service Unavailable')
976
978
  * @param errorCode - Optional machine-readable error code
977
979
  */
978
- constructor(message?: string, errorCode?: string);
980
+ constructor(message?: string, errorCode?: string, errors?: string[]);
979
981
  }
980
982
 
981
983
  /**
@@ -997,7 +999,7 @@ export declare class TooManyRequestsException extends RabApiError {
997
999
  * @param message - Human-readable error message (default: 'Too Many Requests')
998
1000
  * @param errorCode - Optional machine-readable error code
999
1001
  */
1000
- constructor(message?: string, errorCode?: string);
1002
+ constructor(message?: string, errorCode?: string, errors?: string[]);
1001
1003
  }
1002
1004
 
1003
1005
  /**
@@ -1014,7 +1016,7 @@ export declare class UnauthorizedException extends RabApiError {
1014
1016
  * @param message - Human-readable error message (default: 'Unauthorized')
1015
1017
  * @param errorCode - Optional machine-readable error code
1016
1018
  */
1017
- constructor(message?: string, errorCode?: string);
1019
+ constructor(message?: string, errorCode?: string, errors?: string[]);
1018
1020
  }
1019
1021
 
1020
1022
  /**
package/index.esm.js CHANGED
@@ -242,8 +242,8 @@ const isCallBackPipe = (pipe)=>typeof pipe === 'function' && pipe.length == 1;
242
242
  /**
243
243
  * @param message - Human-readable error message (default: 'Unauthorized')
244
244
  * @param errorCode - Optional machine-readable error code
245
- */ constructor(message = 'Unauthorized', errorCode){
246
- super(message, 401, errorCode);
245
+ */ constructor(message = 'Unauthorized', errorCode, errors){
246
+ super(message, 401, errorCode, errors);
247
247
  this.name = 'UnauthorizedException';
248
248
  Error.captureStackTrace(this, this.constructor);
249
249
  }
@@ -260,8 +260,8 @@ const isCallBackPipe = (pipe)=>typeof pipe === 'function' && pipe.length == 1;
260
260
  /**
261
261
  * @param message - Human-readable error message (default: 'Forbidden')
262
262
  * @param errorCode - Optional machine-readable error code
263
- */ constructor(message = 'Forbidden', errorCode){
264
- super(message, 403, errorCode);
263
+ */ constructor(message = 'Forbidden', errorCode, errors){
264
+ super(message, 403, errorCode, errors);
265
265
  this.name = 'ForbiddenException';
266
266
  Error.captureStackTrace(this, this.constructor);
267
267
  }
@@ -278,8 +278,8 @@ const isCallBackPipe = (pipe)=>typeof pipe === 'function' && pipe.length == 1;
278
278
  /**
279
279
  * @param message - Human-readable error message (default: 'Not Found')
280
280
  * @param errorCode - Optional machine-readable error code
281
- */ constructor(message = 'Not Found', errorCode){
282
- super(message, 404, errorCode);
281
+ */ constructor(message = 'Not Found', errorCode, errors){
282
+ super(message, 404, errorCode, errors);
283
283
  this.name = 'NotFoundException';
284
284
  Error.captureStackTrace(this, this.constructor);
285
285
  }
@@ -296,8 +296,8 @@ const isCallBackPipe = (pipe)=>typeof pipe === 'function' && pipe.length == 1;
296
296
  /**
297
297
  * @param message - Human-readable error message (default: 'Method Not Allowed')
298
298
  * @param errorCode - Optional machine-readable error code
299
- */ constructor(message = 'Method Not Allowed', errorCode){
300
- super(message, 405, errorCode);
299
+ */ constructor(message = 'Method Not Allowed', errorCode, errors){
300
+ super(message, 405, errorCode, errors);
301
301
  this.name = 'MethodNotAllowedException';
302
302
  Error.captureStackTrace(this, this.constructor);
303
303
  }
@@ -314,8 +314,8 @@ const isCallBackPipe = (pipe)=>typeof pipe === 'function' && pipe.length == 1;
314
314
  /**
315
315
  * @param message - Human-readable error message (default: 'Request Timeout')
316
316
  * @param errorCode - Optional machine-readable error code
317
- */ constructor(message = 'Request Timeout', errorCode){
318
- super(message, 408, errorCode);
317
+ */ constructor(message = 'Request Timeout', errorCode, errors){
318
+ super(message, 408, errorCode, errors);
319
319
  this.name = 'RequestTimeoutException';
320
320
  Error.captureStackTrace(this, this.constructor);
321
321
  }
@@ -332,8 +332,8 @@ const isCallBackPipe = (pipe)=>typeof pipe === 'function' && pipe.length == 1;
332
332
  /**
333
333
  * @param message - Human-readable error message
334
334
  * @param errorCode - Optional machine-readable error code
335
- */ constructor(message, errorCode){
336
- super(message, 409, errorCode);
335
+ */ constructor(message, errorCode, errors){
336
+ super(message, 409, errorCode, errors);
337
337
  this.name = 'ConflictException';
338
338
  Error.captureStackTrace(this, this.constructor);
339
339
  }
@@ -350,8 +350,8 @@ const isCallBackPipe = (pipe)=>typeof pipe === 'function' && pipe.length == 1;
350
350
  /**
351
351
  * @param message - Human-readable error message (default: 'Payload Too Large')
352
352
  * @param errorCode - Optional machine-readable error code
353
- */ constructor(message = 'Payload Too Large', errorCode){
354
- super(message, 413, errorCode);
353
+ */ constructor(message = 'Payload Too Large', errorCode, errors){
354
+ super(message, 413, errorCode, errors);
355
355
  this.name = 'PayloadTooLargeException';
356
356
  Error.captureStackTrace(this, this.constructor);
357
357
  }
@@ -391,8 +391,8 @@ const isCallBackPipe = (pipe)=>typeof pipe === 'function' && pipe.length == 1;
391
391
  /**
392
392
  * @param message - Human-readable error message (default: 'Too Many Requests')
393
393
  * @param errorCode - Optional machine-readable error code
394
- */ constructor(message = 'Too Many Requests', errorCode){
395
- super(message, 429, errorCode);
394
+ */ constructor(message = 'Too Many Requests', errorCode, errors){
395
+ super(message, 429, errorCode, errors);
396
396
  this.name = 'TooManyRequestsException';
397
397
  Error.captureStackTrace(this, this.constructor);
398
398
  }
@@ -409,8 +409,8 @@ const isCallBackPipe = (pipe)=>typeof pipe === 'function' && pipe.length == 1;
409
409
  /**
410
410
  * @param message - Human-readable error message (default: 'Internal Server Error')
411
411
  * @param errorCode - Optional machine-readable error code
412
- */ constructor(message = 'Internal Server Error', errorCode){
413
- super(message, 500, errorCode);
412
+ */ constructor(message = 'Internal Server Error', errorCode, errors){
413
+ super(message, 500, errorCode, errors);
414
414
  this.name = 'InternalServerErrorException';
415
415
  Error.captureStackTrace(this, this.constructor);
416
416
  }
@@ -427,8 +427,8 @@ const isCallBackPipe = (pipe)=>typeof pipe === 'function' && pipe.length == 1;
427
427
  /**
428
428
  * @param message - Human-readable error message (default: 'Service Unavailable')
429
429
  * @param errorCode - Optional machine-readable error code
430
- */ constructor(message = 'Service Unavailable', errorCode){
431
- super(message, 503, errorCode);
430
+ */ constructor(message = 'Service Unavailable', errorCode, errors){
431
+ super(message, 503, errorCode, errors);
432
432
  this.name = 'ServiceUnavailableException';
433
433
  Error.captureStackTrace(this, this.constructor);
434
434
  }
@@ -686,22 +686,28 @@ const controllerHandler = (controller, config)=>{
686
686
  };
687
687
 
688
688
  const authHandler = (isProtected, config)=>(req, res, next)=>{
689
- console.log('authHandler:', req.path, ':isProtected:', isProtected);
689
+ var _config_debug;
690
+ const debug = (_config_debug = config.debug) != null ? _config_debug : false;
691
+ if (debug) console.log('authHandler:', req.path, ':isProtected:', isProtected);
690
692
  const token = extractTokenFromHeader(req);
691
693
  // If not protected and no token, just continue
692
694
  if (!isProtected && !token) return next();
693
695
  // If no token but route is protected, throw error
694
696
  if (!token) {
695
- console.log('authHandler:UnauthorizedException:Token Not Found');
697
+ if (debug) console.log('authHandler:UnauthorizedException:Token Not Found');
696
698
  throw new UnauthorizedException('Unauthorized', config.errorCode);
697
699
  }
698
- // Token exists - verify it (must be valid regardless of protection)
700
+ // Token exists - verify it
699
701
  try {
700
- const payload = jwt.verify(token, config.jwt.secret_key);
702
+ const payload = jwt.verify(token, config.jwt.secret_key, {
703
+ algorithms: config.jwt.algorithms
704
+ });
701
705
  req['auth'] = payload;
702
706
  return next();
703
707
  } catch (err) {
704
- console.error('authHandler:JWT Error:', err.message);
708
+ // If route is not protected, silently continue without auth
709
+ if (!isProtected) return next();
710
+ if (debug) console.error('authHandler:JWT Error:', err.message);
705
711
  throw new UnauthorizedException('Unauthorized', config.errorCode);
706
712
  }
707
713
  };
@@ -1129,7 +1135,9 @@ class AtomExpressApp {
1129
1135
  //auth middleware
1130
1136
  if (this.options.auth) {
1131
1137
  var _config_isProtected;
1132
- allPipes.unshift(authHandler((_config_isProtected = config.isProtected) != null ? _config_isProtected : this.options.enforceRouteProtection, this.options.auth));
1138
+ allPipes.unshift(authHandler((_config_isProtected = config.isProtected) != null ? _config_isProtected : this.options.enforceRouteProtection, _extends({}, this.options.auth, {
1139
+ debug: this.options.debug
1140
+ })));
1133
1141
  }
1134
1142
  //add body validation to validate the schema and inject request context
1135
1143
  if (config.bodySchema && !config.disableBodyValidation) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rabstack/rab-api",
3
- "version": "1.12.0",
3
+ "version": "1.15.0",
4
4
  "description": "A TypeScript REST API framework built on Express.js with decorator-based routing, dependency injection, and built-in validation",
5
5
  "author": "Softin",
6
6
  "license": "MIT",