hi-secure 1.0.0 → 1.0.3
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/dist/adapters/ExpressRLAdapter.d.ts.map +1 -1
- package/dist/adapters/ExpressRLAdapter.js +0 -29
- package/dist/adapters/ExpressRLAdapter.js.map +1 -1
- package/dist/adapters/GoogleAdapter.d.ts.map +1 -1
- package/dist/adapters/GoogleAdapter.js +4 -3
- package/dist/adapters/GoogleAdapter.js.map +1 -1
- package/dist/adapters/JWTAdapter.d.ts.map +1 -1
- package/dist/adapters/JWTAdapter.js +3 -1
- package/dist/adapters/JWTAdapter.js.map +1 -1
- package/dist/core/HiSecure.d.ts +3 -18
- package/dist/core/HiSecure.d.ts.map +1 -1
- package/dist/core/HiSecure.js +29 -132
- package/dist/core/HiSecure.js.map +1 -1
- package/dist/core/errors/HttpError.d.ts +17 -0
- package/dist/core/errors/HttpError.d.ts.map +1 -0
- package/dist/core/errors/HttpError.js +36 -0
- package/dist/core/errors/HttpError.js.map +1 -0
- package/dist/core/useSecure.d.ts +0 -7
- package/dist/core/useSecure.d.ts.map +1 -1
- package/dist/core/useSecure.js +65 -21
- package/dist/core/useSecure.js.map +1 -1
- package/dist/index.d.ts +3 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +19 -9
- package/dist/index.js.map +1 -1
- package/dist/managers/AuthManager.d.ts.map +1 -1
- package/dist/managers/AuthManager.js +18 -17
- package/dist/managers/AuthManager.js.map +1 -1
- package/dist/managers/ValidatorManager.d.ts +4 -6
- package/dist/managers/ValidatorManager.d.ts.map +1 -1
- package/dist/managers/ValidatorManager.js +97 -144
- package/dist/managers/ValidatorManager.js.map +1 -1
- package/dist/middlewares/errorHandler.js +2 -2
- package/dist/middlewares/errorHandler.js.map +1 -1
- package/dist/utils/normalizeOptions.d.ts.map +1 -1
- package/dist/utils/normalizeOptions.js +14 -4
- package/dist/utils/normalizeOptions.js.map +1 -1
- package/package.json +2 -2
- package/readme.md +195 -0
- package/src/adapters/ExpressRLAdapter.ts +0 -38
- package/src/adapters/GoogleAdapter.ts +5 -3
- package/src/adapters/JWTAdapter.ts +3 -1
- package/src/core/HiSecure.ts +414 -175
- package/src/core/useSecure.ts +91 -36
- package/src/index.ts +28 -12
- package/src/managers/AuthManager.ts +15 -13
- package/src/managers/ValidatorManager.ts +120 -182
- package/src/middlewares/errorHandler.ts +1 -1
- package/src/utils/normalizeOptions.ts +24 -9
- /package/src/core/errors/{HttpErrror.ts → HttpError.ts} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errorHandler.js","sourceRoot":"","sources":["../../src/middlewares/errorHandler.ts"],"names":[],"mappings":"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","sourcesContent":["// import { Request, Response, NextFunction } from \"express\";\r\n// import { logger } from \"../logging\";\r\n// import { AdapterError } from \"../core/errors/AdapterError\";\r\n// import { ValidationError } from \"../core/errors/ValidationError\";\r\n// import { SanitizerError } from \"../core/errors/SanitizerError\";\r\n// import { SecurityError } from \"../core/errors/SecurityError\";\r\n\r\n// export function errorHandler(\r\n// err: any,\r\n// req: Request,\r\n// res: Response,\r\n// _next: NextFunction\r\n// ) {\r\n// // Normalize unknown errors\r\n// const errorMessage =\r\n// typeof err === \"string\"\r\n// ? err\r\n// : err?.message || \"Unknown error occurred\";\r\n\r\n// const errorStack =\r\n// err instanceof Error && err.stack\r\n// ? err.stack.split(\"\\n\").slice(0, 2).join(\" | \")\r\n// : undefined;\r\n\r\n// // Log error centrally\r\n// logger.error(\"❌ HiSecure Error Captured\", {\r\n// message: errorMessage,\r\n// path: req.path,\r\n// method: req.method,\r\n// stack: errorStack,\r\n// raw: err\r\n// });\r\n\r\n// // ------------------------------\r\n// // CLASSIFIED ERROR RESPONSES\r\n// // ------------------------------\r\n\r\n// if (err instanceof ValidationError) {\r\n// return res.status(400).json({\r\n// success: false,\r\n// error: \"VALIDATION_ERROR\",\r\n// message: errorMessage\r\n// });\r\n// }\r\n\r\n// if (err instanceof SanitizerError) {\r\n// return res.status(400).json({\r\n// success: false,\r\n// error: \"SANITIZER_ERROR\",\r\n// message: errorMessage\r\n// });\r\n// }\r\n\r\n// if (err instanceof AdapterError) {\r\n// return res.status(500).json({\r\n// success: false,\r\n// error: \"ADAPTER_ERROR\",\r\n// message: errorMessage\r\n// });\r\n// }\r\n\r\n// if (err instanceof SecurityError) {\r\n// return res.status(500).json({\r\n// success: false,\r\n// error: \"SECURITY_ERROR\",\r\n// message: errorMessage\r\n// });\r\n// }\r\n\r\n// // ------------------------------\r\n// // UNEXPECTED ERROR\r\n// // ------------------------------\r\n// return res.status(500).json({\r\n// success: false,\r\n// error: \"INTERNAL_SERVER_ERROR\",\r\n// message: \"An unexpected error occurred in HiSecure middleware.\"\r\n// });\r\n// }\r\n\r\n\r\n\r\n\r\n// import { Request, Response, NextFunction } from \"express\";\r\n// import { logger } from \"../logging\";\r\n// import { AdapterError } from \"../core/errors/AdapterError\";\r\n// import { ValidationError } from \"../core/errors/ValidationError\";\r\n// import { SanitizerError } from \"../core/errors/SanitizerError\";\r\n// import { SecurityError } from \"../core/errors/SecurityError\";\r\n\r\n// export function errorHandler(\r\n// err: any,\r\n// req: Request,\r\n// res: Response,\r\n// _next: NextFunction\r\n// ) {\r\n// // Normalize unknown errors\r\n// const errorMessage =\r\n// typeof err === \"string\"\r\n// ? err\r\n// : err?.message || \"Unknown error occurred\";\r\n\r\n// const errorStack =\r\n// err instanceof Error && err.stack\r\n// ? err.stack.split(\"\\n\").slice(0, 2).join(\" | \")\r\n// : undefined;\r\n\r\n// // Log error centrally\r\n// logger.error(\"❌ HiSecure Error Captured\", {\r\n// message: errorMessage,\r\n// path: req.path,\r\n// method: req.method,\r\n// stack: errorStack,\r\n// raw: err\r\n// });\r\n\r\n// // ------------------------------\r\n// // CLASSIFIED ERROR RESPONSES\r\n// // ------------------------------\r\n\r\n// if (err instanceof ValidationError) {\r\n// return res.status(400).json({\r\n// success: false,\r\n// error: \"VALIDATION_ERROR\",\r\n// message: errorMessage\r\n// });\r\n// }\r\n\r\n// if (err instanceof SanitizerError) {\r\n// return res.status(400).json({\r\n// success: false,\r\n// error: \"SANITIZER_ERROR\",\r\n// message: errorMessage\r\n// });\r\n// }\r\n\r\n// if (err instanceof AdapterError) {\r\n// return res.status(500).json({\r\n// success: false,\r\n// error: \"ADAPTER_ERROR\",\r\n// message: errorMessage\r\n// });\r\n// }\r\n\r\n// if (err instanceof SecurityError) {\r\n// return res.status(500).json({\r\n// success: false,\r\n// error: \"SECURITY_ERROR\",\r\n// message: errorMessage\r\n// });\r\n// }\r\n\r\n// // ------------------------------\r\n// // UNEXPECTED ERROR\r\n// // ------------------------------\r\n// return res.status(500).json({\r\n// success: false,\r\n// error: \"INTERNAL_SERVER_ERROR\",\r\n// message: \"An unexpected error occurred in HiSecure middleware.\"\r\n// });\r\n// }\r\n\r\n\r\n\r\nimport { Request, Response, NextFunction } from \"express\";\r\nimport { logger } from \"../logging\";\r\n\r\nimport { AdapterError } from \"../core/errors/AdapterError.js\";\r\nimport { ValidationError } from \"../core/errors/ValidationError.js\";\r\nimport { SanitizerError } from \"../core/errors/SanitizerError.js\";\r\nimport { SecurityError } from \"../core/errors/SecurityError.js\";\r\nimport { HttpError } from \"../core/errors/HttpErrror.js\";\r\n\r\nexport function errorHandler(\r\n err: any,\r\n req: Request,\r\n res: Response,\r\n _next: NextFunction\r\n) {\r\n const message =\r\n typeof err === \"string\"\r\n ? err\r\n : err?.message || \"Unknown error\";\r\n\r\n const stack =\r\n err instanceof Error && err.stack\r\n ? err.stack.split(\"\\n\").slice(0, 2).join(\" | \")\r\n : undefined;\r\n\r\n // Unified logging\r\n logger.error(\"❌ HiSecure Error\", {\r\n type: err?.name || \"UnknownError\",\r\n message,\r\n status: err?.status,\r\n code: err?.code,\r\n path: req.path,\r\n method: req.method,\r\n stack,\r\n raw: err,\r\n });\r\n\r\n // ---------------------------------------------------\r\n // 1. HttpError (developer thrown)\r\n // ---------------------------------------------------\r\n if (err instanceof HttpError) {\r\n return res.status(err.status).json({\r\n success: false,\r\n error: err.code,\r\n message: err.message,\r\n details: err.details || undefined,\r\n });\r\n }\r\n\r\n // ---------------------------------------------------\r\n // 2. Validation Errors\r\n // ---------------------------------------------------\r\n if (err instanceof ValidationError) {\r\n return res.status(400).json({\r\n success: false,\r\n error: \"VALIDATION_ERROR\",\r\n message,\r\n });\r\n }\r\n\r\n // ---------------------------------------------------\r\n // 3. Sanitizer Errors\r\n // ---------------------------------------------------\r\n if (err instanceof SanitizerError) {\r\n return res.status(400).json({\r\n success: false,\r\n error: \"SANITIZER_ERROR\",\r\n message,\r\n });\r\n }\r\n\r\n // ---------------------------------------------------\r\n // 4. Adapter Errors (hashing, rate-limit, sanitizer, validator ...)\r\n // ---------------------------------------------------\r\n if (err instanceof AdapterError) {\r\n return res.status(500).json({\r\n success: false,\r\n error: \"ADAPTER_ERROR\",\r\n message,\r\n });\r\n }\r\n\r\n // ---------------------------------------------------\r\n // 5. Security Errors (internal library security logic)\r\n // ---------------------------------------------------\r\n if (err instanceof SecurityError) {\r\n return res.status(500).json({\r\n success: false,\r\n error: \"SECURITY_ERROR\",\r\n message,\r\n });\r\n }\r\n\r\n // ---------------------------------------------------\r\n // 6. Fallback → Unexpected\r\n // ---------------------------------------------------\r\n return res.status(500).json({\r\n success: false,\r\n error: \"INTERNAL_SERVER_ERROR\",\r\n message: \"An unexpected error occurred in HiSecure.\",\r\n });\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"errorHandler.js","sourceRoot":"","sources":["../../src/middlewares/errorHandler.ts"],"names":[],"mappings":"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","sourcesContent":["// import { Request, Response, NextFunction } from \"express\";\r\n// import { logger } from \"../logging\";\r\n// import { AdapterError } from \"../core/errors/AdapterError\";\r\n// import { ValidationError } from \"../core/errors/ValidationError\";\r\n// import { SanitizerError } from \"../core/errors/SanitizerError\";\r\n// import { SecurityError } from \"../core/errors/SecurityError\";\r\n\r\n// export function errorHandler(\r\n// err: any,\r\n// req: Request,\r\n// res: Response,\r\n// _next: NextFunction\r\n// ) {\r\n// // Normalize unknown errors\r\n// const errorMessage =\r\n// typeof err === \"string\"\r\n// ? err\r\n// : err?.message || \"Unknown error occurred\";\r\n\r\n// const errorStack =\r\n// err instanceof Error && err.stack\r\n// ? err.stack.split(\"\\n\").slice(0, 2).join(\" | \")\r\n// : undefined;\r\n\r\n// // Log error centrally\r\n// logger.error(\"❌ HiSecure Error Captured\", {\r\n// message: errorMessage,\r\n// path: req.path,\r\n// method: req.method,\r\n// stack: errorStack,\r\n// raw: err\r\n// });\r\n\r\n// // ------------------------------\r\n// // CLASSIFIED ERROR RESPONSES\r\n// // ------------------------------\r\n\r\n// if (err instanceof ValidationError) {\r\n// return res.status(400).json({\r\n// success: false,\r\n// error: \"VALIDATION_ERROR\",\r\n// message: errorMessage\r\n// });\r\n// }\r\n\r\n// if (err instanceof SanitizerError) {\r\n// return res.status(400).json({\r\n// success: false,\r\n// error: \"SANITIZER_ERROR\",\r\n// message: errorMessage\r\n// });\r\n// }\r\n\r\n// if (err instanceof AdapterError) {\r\n// return res.status(500).json({\r\n// success: false,\r\n// error: \"ADAPTER_ERROR\",\r\n// message: errorMessage\r\n// });\r\n// }\r\n\r\n// if (err instanceof SecurityError) {\r\n// return res.status(500).json({\r\n// success: false,\r\n// error: \"SECURITY_ERROR\",\r\n// message: errorMessage\r\n// });\r\n// }\r\n\r\n// // ------------------------------\r\n// // UNEXPECTED ERROR\r\n// // ------------------------------\r\n// return res.status(500).json({\r\n// success: false,\r\n// error: \"INTERNAL_SERVER_ERROR\",\r\n// message: \"An unexpected error occurred in HiSecure middleware.\"\r\n// });\r\n// }\r\n\r\n\r\n\r\n\r\n// import { Request, Response, NextFunction } from \"express\";\r\n// import { logger } from \"../logging\";\r\n// import { AdapterError } from \"../core/errors/AdapterError\";\r\n// import { ValidationError } from \"../core/errors/ValidationError\";\r\n// import { SanitizerError } from \"../core/errors/SanitizerError\";\r\n// import { SecurityError } from \"../core/errors/SecurityError\";\r\n\r\n// export function errorHandler(\r\n// err: any,\r\n// req: Request,\r\n// res: Response,\r\n// _next: NextFunction\r\n// ) {\r\n// // Normalize unknown errors\r\n// const errorMessage =\r\n// typeof err === \"string\"\r\n// ? err\r\n// : err?.message || \"Unknown error occurred\";\r\n\r\n// const errorStack =\r\n// err instanceof Error && err.stack\r\n// ? err.stack.split(\"\\n\").slice(0, 2).join(\" | \")\r\n// : undefined;\r\n\r\n// // Log error centrally\r\n// logger.error(\"❌ HiSecure Error Captured\", {\r\n// message: errorMessage,\r\n// path: req.path,\r\n// method: req.method,\r\n// stack: errorStack,\r\n// raw: err\r\n// });\r\n\r\n// // ------------------------------\r\n// // CLASSIFIED ERROR RESPONSES\r\n// // ------------------------------\r\n\r\n// if (err instanceof ValidationError) {\r\n// return res.status(400).json({\r\n// success: false,\r\n// error: \"VALIDATION_ERROR\",\r\n// message: errorMessage\r\n// });\r\n// }\r\n\r\n// if (err instanceof SanitizerError) {\r\n// return res.status(400).json({\r\n// success: false,\r\n// error: \"SANITIZER_ERROR\",\r\n// message: errorMessage\r\n// });\r\n// }\r\n\r\n// if (err instanceof AdapterError) {\r\n// return res.status(500).json({\r\n// success: false,\r\n// error: \"ADAPTER_ERROR\",\r\n// message: errorMessage\r\n// });\r\n// }\r\n\r\n// if (err instanceof SecurityError) {\r\n// return res.status(500).json({\r\n// success: false,\r\n// error: \"SECURITY_ERROR\",\r\n// message: errorMessage\r\n// });\r\n// }\r\n\r\n// // ------------------------------\r\n// // UNEXPECTED ERROR\r\n// // ------------------------------\r\n// return res.status(500).json({\r\n// success: false,\r\n// error: \"INTERNAL_SERVER_ERROR\",\r\n// message: \"An unexpected error occurred in HiSecure middleware.\"\r\n// });\r\n// }\r\n\r\n\r\n\r\nimport { Request, Response, NextFunction } from \"express\";\r\nimport { logger } from \"../logging\";\r\n\r\nimport { AdapterError } from \"../core/errors/AdapterError.js\";\r\nimport { ValidationError } from \"../core/errors/ValidationError.js\";\r\nimport { SanitizerError } from \"../core/errors/SanitizerError.js\";\r\nimport { SecurityError } from \"../core/errors/SecurityError.js\";\r\nimport { HttpError } from \"../core/errors/HttpError.js\";\r\n\r\nexport function errorHandler(\r\n err: any,\r\n req: Request,\r\n res: Response,\r\n _next: NextFunction\r\n) {\r\n const message =\r\n typeof err === \"string\"\r\n ? err\r\n : err?.message || \"Unknown error\";\r\n\r\n const stack =\r\n err instanceof Error && err.stack\r\n ? err.stack.split(\"\\n\").slice(0, 2).join(\" | \")\r\n : undefined;\r\n\r\n // Unified logging\r\n logger.error(\"❌ HiSecure Error\", {\r\n type: err?.name || \"UnknownError\",\r\n message,\r\n status: err?.status,\r\n code: err?.code,\r\n path: req.path,\r\n method: req.method,\r\n stack,\r\n raw: err,\r\n });\r\n\r\n // ---------------------------------------------------\r\n // 1. HttpError (developer thrown)\r\n // ---------------------------------------------------\r\n if (err instanceof HttpError) {\r\n return res.status(err.status).json({\r\n success: false,\r\n error: err.code,\r\n message: err.message,\r\n details: err.details || undefined,\r\n });\r\n }\r\n\r\n // ---------------------------------------------------\r\n // 2. Validation Errors\r\n // ---------------------------------------------------\r\n if (err instanceof ValidationError) {\r\n return res.status(400).json({\r\n success: false,\r\n error: \"VALIDATION_ERROR\",\r\n message,\r\n });\r\n }\r\n\r\n // ---------------------------------------------------\r\n // 3. Sanitizer Errors\r\n // ---------------------------------------------------\r\n if (err instanceof SanitizerError) {\r\n return res.status(400).json({\r\n success: false,\r\n error: \"SANITIZER_ERROR\",\r\n message,\r\n });\r\n }\r\n\r\n // ---------------------------------------------------\r\n // 4. Adapter Errors (hashing, rate-limit, sanitizer, validator ...)\r\n // ---------------------------------------------------\r\n if (err instanceof AdapterError) {\r\n return res.status(500).json({\r\n success: false,\r\n error: \"ADAPTER_ERROR\",\r\n message,\r\n });\r\n }\r\n\r\n // ---------------------------------------------------\r\n // 5. Security Errors (internal library security logic)\r\n // ---------------------------------------------------\r\n if (err instanceof SecurityError) {\r\n return res.status(500).json({\r\n success: false,\r\n error: \"SECURITY_ERROR\",\r\n message,\r\n });\r\n }\r\n\r\n // ---------------------------------------------------\r\n // 6. Fallback → Unexpected\r\n // ---------------------------------------------------\r\n return res.status(500).json({\r\n success: false,\r\n error: \"INTERNAL_SERVER_ERROR\",\r\n message: \"An unexpected error occurred in HiSecure.\",\r\n });\r\n}\r\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"normalizeOptions.d.ts","sourceRoot":"","sources":["../../src/utils/normalizeOptions.ts"],"names":[],"mappings":"AAqHA,OAAO,EACH,aAAa,EACO,aAAa;AACjC,gBAAgB,EAAI,eAAe;AACnC,eAAe,EAClB,MAAM,gCAAgC,CAAC;AAExC,MAAM,WAAW,iBAAiB;IAC9B,IAAI,EAAE;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7C,SAAS,EAAE;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,IAAI,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC;QAAC,OAAO,CAAC,EAAE,gBAAgB,CAAA;KAAE,CAAC;IACzF,QAAQ,EAAE;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,eAAe,CAAA;KAAE,CAAC;IAC1D,QAAQ,EAAE;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,GAAG,CAAA;KAAE,CAAC;IAC7C,IAAI,EAAE;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7C,IAAI,EAAE;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IAChE,WAAW,EAAE;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACvD;AAED,wBAAgB,gBAAgB,CAAC,KAAK,CAAC,EAAE,aAAa,GAAG,KAAK,GAAG,iBAAiB,
|
|
1
|
+
{"version":3,"file":"normalizeOptions.d.ts","sourceRoot":"","sources":["../../src/utils/normalizeOptions.ts"],"names":[],"mappings":"AAqHA,OAAO,EACH,aAAa,EACO,aAAa;AACjC,gBAAgB,EAAI,eAAe;AACnC,eAAe,EAClB,MAAM,gCAAgC,CAAC;AAExC,MAAM,WAAW,iBAAiB;IAC9B,IAAI,EAAE;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7C,SAAS,EAAE;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,IAAI,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC;QAAC,OAAO,CAAC,EAAE,gBAAgB,CAAA;KAAE,CAAC;IACzF,QAAQ,EAAE;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,eAAe,CAAA;KAAE,CAAC;IAC1D,QAAQ,EAAE;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,GAAG,CAAA;KAAE,CAAC;IAC7C,IAAI,EAAE;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7C,IAAI,EAAE;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IAChE,WAAW,EAAE;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACvD;AAED,wBAAgB,gBAAgB,CAAC,KAAK,CAAC,EAAE,aAAa,GAAG,KAAK,GAAG,iBAAiB,CAmDjF;AA8DD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,KAAK,GAAG,QAAQ,GAAG,QAAQ,GAAG,iBAAiB,CAgCvF"}
|
|
@@ -26,9 +26,13 @@ function normalizeOptions(input) {
|
|
|
26
26
|
enabled: opts.sanitize === undefined ? true : opts.sanitize !== false,
|
|
27
27
|
options: typeof opts.sanitize === "object" ? opts.sanitize : undefined
|
|
28
28
|
},
|
|
29
|
+
// validate: {
|
|
30
|
+
// enabled: !!opts.validate,
|
|
31
|
+
// schema: opts.validate || undefined
|
|
32
|
+
// },
|
|
29
33
|
validate: {
|
|
30
|
-
enabled:
|
|
31
|
-
schema: opts.validate
|
|
34
|
+
enabled: opts.validate !== undefined,
|
|
35
|
+
schema: opts.validate
|
|
32
36
|
},
|
|
33
37
|
json: {
|
|
34
38
|
enabled: opts.json === undefined ? true : opts.json !== false,
|
|
@@ -70,10 +74,16 @@ function normalizeRateLimit(value) {
|
|
|
70
74
|
return { enabled: true };
|
|
71
75
|
}
|
|
72
76
|
function normalizeAuth(value) {
|
|
73
|
-
if (value === false) {
|
|
77
|
+
// if (value === false) {
|
|
78
|
+
// return { enabled: false, required: false };
|
|
79
|
+
// }
|
|
80
|
+
// if (value === true || value === undefined) {
|
|
81
|
+
// return { enabled: true, required: true };
|
|
82
|
+
// }
|
|
83
|
+
if (value === undefined) {
|
|
74
84
|
return { enabled: false, required: false };
|
|
75
85
|
}
|
|
76
|
-
if (value === true
|
|
86
|
+
if (value === true) {
|
|
77
87
|
return { enabled: true, required: true };
|
|
78
88
|
}
|
|
79
89
|
const authOptions = value;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"normalizeOptions.js","sourceRoot":"","sources":["../../src/utils/normalizeOptions.ts"],"names":[],"mappings":"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","sourcesContent":["\r\n// import { SecureOptions } from \"../core/types/SecureOptions.js\";\r\n\r\n// export interface NormalizedOptions {\r\n// cors: { enabled: boolean; options?: any };\r\n// rateLimit: { enabled: boolean; mode?: \"strict\" | \"relaxed\" | undefined; options?: any };\r\n// sanitize: { enabled: boolean };\r\n// validate: { enabled: boolean; schema?: any };\r\n// json: { enabled: boolean; options?: any };\r\n\r\n// /** NEW */\r\n// auth: { enabled: boolean; required: boolean };\r\n// }\r\n\r\n// export function normalizeOptions(input?: SecureOptions | false): NormalizedOptions {\r\n// if (input === false) {\r\n// return {\r\n// cors: { enabled: false },\r\n// rateLimit: { enabled: false, mode: undefined, options: undefined },\r\n// sanitize: { enabled: false },\r\n// validate: { enabled: false },\r\n// json: { enabled: false },\r\n// auth: { enabled: false, required: true }\r\n// };\r\n// }\r\n\r\n// const opts = input || {};\r\n\r\n// return {\r\n// cors: {\r\n// enabled: opts.cors === undefined ? true : opts.cors !== false,\r\n// options: typeof opts.cors === \"object\" ? opts.cors : undefined\r\n// },\r\n\r\n// rateLimit: normalizeRateLimit(opts.rateLimit),\r\n\r\n// sanitize: {\r\n// enabled: opts.sanitize === undefined ? true : opts.sanitize !== false\r\n// },\r\n\r\n// validate: {\r\n// enabled: !!opts.validate,\r\n// schema: opts.validate || undefined\r\n// },\r\n\r\n// json: {\r\n// enabled: opts.json === undefined ? true : opts.json !== false,\r\n// options: typeof opts.json === \"object\" ? opts.json : undefined\r\n// },\r\n\r\n// auth: normalizeAuth(opts.auth)\r\n// };\r\n// }\r\n\r\n// // ---------------------------------------------------------------\r\n// // RATE LIMIT — EXACT TYPES, NO TS ERROR\r\n// // ---------------------------------------------------------------\r\n// function normalizeRateLimit(value: SecureOptions[\"rateLimit\"]): {\r\n// enabled: boolean;\r\n// mode?: \"strict\" | \"relaxed\" | undefined;\r\n// options?: any;\r\n// } {\r\n// if (value === false) {\r\n// return { enabled: false, mode: undefined, options: undefined };\r\n// }\r\n\r\n// if (value === \"strict\") {\r\n// return {\r\n// enabled: true,\r\n// mode: \"strict\",\r\n// options: { max: 5, windowMs: 10000 }\r\n// };\r\n// }\r\n\r\n// if (value === \"relaxed\") {\r\n// return {\r\n// enabled: true,\r\n// mode: \"relaxed\",\r\n// options: { max: 100, windowMs: 60000 }\r\n// };\r\n// }\r\n\r\n// if (typeof value === \"object\") {\r\n// return {\r\n// enabled: true,\r\n// mode: undefined, // VERY IMPORTANT!\r\n// options: value\r\n// };\r\n// }\r\n\r\n// // Default → enabled and optional fields omitted\r\n// return {\r\n// enabled: true,\r\n// mode: undefined,\r\n// options: undefined\r\n// };\r\n// }\r\n\r\n// // ---------------------------------------------------------------\r\n// // AUTH NORMALIZER — EXACT FOR useSecure\r\n// // ---------------------------------------------------------------\r\n// function normalizeAuth(value: SecureOptions[\"auth\"]) {\r\n// if (value === false) return { enabled: false, required: true };\r\n\r\n// if (value === true || value === undefined)\r\n// return { enabled: true, required: true };\r\n\r\n// return {\r\n// enabled: true,\r\n// required: value.required !== false\r\n// };\r\n// }\r\n\r\n\r\n\r\n\r\n// src/utils/normalizeOptions.ts\r\nimport { \r\n SecureOptions,\r\n AuthOptions, // ✅ ADD THIS\r\n RateLimitOptions, // ✅ ADD THIS \r\n SanitizeOptions // ✅ ADD THIS\r\n} from \"../core/types/SecureOptions.js\";\r\n\r\nexport interface NormalizedOptions {\r\n cors: { enabled: boolean; options?: object };\r\n rateLimit: { enabled: boolean; mode?: \"strict\" | \"relaxed\"; options?: RateLimitOptions };\r\n sanitize: { enabled: boolean; options?: SanitizeOptions };\r\n validate: { enabled: boolean; schema?: any };\r\n json: { enabled: boolean; options?: object };\r\n auth: { enabled: boolean; required: boolean; roles?: string[] };\r\n compression: { enabled: boolean; options?: object };\r\n}\r\n\r\nexport function normalizeOptions(input?: SecureOptions | false): NormalizedOptions {\r\n if (input === false) {\r\n return {\r\n cors: { enabled: false },\r\n rateLimit: { enabled: false },\r\n sanitize: { enabled: false },\r\n validate: { enabled: false },\r\n json: { enabled: false },\r\n auth: { enabled: false, required: false },\r\n compression: { enabled: false }\r\n };\r\n }\r\n\r\n const opts = input || {};\r\n\r\n return {\r\n cors: {\r\n enabled: opts.cors === undefined ? true : opts.cors !== false,\r\n options: typeof opts.cors === \"object\" ? opts.cors : undefined\r\n },\r\n\r\n rateLimit: normalizeRateLimit(opts.rateLimit),\r\n\r\n sanitize: {\r\n enabled: opts.sanitize === undefined ? true : opts.sanitize !== false,\r\n options: typeof opts.sanitize === \"object\" ? opts.sanitize : undefined\r\n },\r\n\r\n validate: {\r\n enabled: !!opts.validate,\r\n schema: opts.validate || undefined\r\n },\r\n\r\n json: {\r\n enabled: opts.json === undefined ? true : opts.json !== false,\r\n options: typeof opts.json === \"object\" ? opts.json : undefined\r\n },\r\n\r\n auth: normalizeAuth(opts.auth),\r\n\r\n compression: {\r\n enabled: opts.compression === undefined ? true : opts.compression !== false,\r\n options: typeof opts.compression === \"object\" ? opts.compression : undefined\r\n }\r\n };\r\n}\r\n\r\nfunction normalizeRateLimit(value: SecureOptions[\"rateLimit\"]): NormalizedOptions[\"rateLimit\"] {\r\n if (value === false) return { enabled: false };\r\n \r\n if (value === \"strict\") {\r\n return {\r\n enabled: true,\r\n mode: \"strict\",\r\n options: { max: 5, windowMs: 10000 }\r\n };\r\n }\r\n \r\n if (value === \"relaxed\") {\r\n return {\r\n enabled: true,\r\n mode: \"relaxed\",\r\n options: { max: 100, windowMs: 60000 }\r\n };\r\n }\r\n \r\n if (typeof value === \"object\") {\r\n const val = value as RateLimitOptions;\r\n const { mode, ...options } = val;\r\n return {\r\n enabled: true,\r\n mode: (mode === \"strict\" || mode === \"relaxed\") ? mode : undefined,\r\n options\r\n };\r\n }\r\n \r\n return { enabled: true };\r\n}\r\n\r\nfunction normalizeAuth(value: SecureOptions[\"auth\"]): NormalizedOptions[\"auth\"] {\r\n if (value === false) {\r\n return { enabled: false, required: false };\r\n }\r\n \r\n if (value === true || value === undefined) {\r\n return { enabled: true, required: true };\r\n }\r\n \r\n const authOptions = value as AuthOptions;\r\n const enabled = authOptions.required !== false;\r\n \r\n return {\r\n enabled,\r\n required: enabled,\r\n roles: authOptions.roles\r\n };\r\n}\r\n\r\nexport function getPresetOptions(preset: 'api' | 'strict' | 'public'): NormalizedOptions {\r\n const presets = {\r\n api: {\r\n cors: { enabled: true, options: { origin: '*' } },\r\n rateLimit: { enabled: true, mode: 'relaxed' as const },\r\n sanitize: { enabled: true },\r\n validate: { enabled: false },\r\n json: { enabled: true },\r\n auth: { enabled: false, required: false },\r\n compression: { enabled: true }\r\n },\r\n strict: {\r\n cors: { enabled: true, options: { origin: process.env.ALLOWED_ORIGIN || '*' } },\r\n rateLimit: { enabled: true, mode: 'strict' as const },\r\n sanitize: { enabled: true },\r\n validate: { enabled: true },\r\n json: { enabled: true },\r\n auth: { enabled: true, required: true },\r\n compression: { enabled: true }\r\n },\r\n public: {\r\n cors: { enabled: true, options: { origin: '*' } },\r\n rateLimit: { enabled: true },\r\n sanitize: { enabled: false },\r\n validate: { enabled: false },\r\n json: { enabled: true },\r\n auth: { enabled: false, required: false },\r\n compression: { enabled: true }\r\n }\r\n };\r\n \r\n return presets[preset] || presets.api;\r\n}"]}
|
|
1
|
+
{"version":3,"file":"normalizeOptions.js","sourceRoot":"","sources":["../../src/utils/normalizeOptions.ts"],"names":[],"mappings":"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","sourcesContent":["\r\n// import { SecureOptions } from \"../core/types/SecureOptions.js\";\r\n\r\n// export interface NormalizedOptions {\r\n// cors: { enabled: boolean; options?: any };\r\n// rateLimit: { enabled: boolean; mode?: \"strict\" | \"relaxed\" | undefined; options?: any };\r\n// sanitize: { enabled: boolean };\r\n// validate: { enabled: boolean; schema?: any };\r\n// json: { enabled: boolean; options?: any };\r\n\r\n// /** NEW */\r\n// auth: { enabled: boolean; required: boolean };\r\n// }\r\n\r\n// export function normalizeOptions(input?: SecureOptions | false): NormalizedOptions {\r\n// if (input === false) {\r\n// return {\r\n// cors: { enabled: false },\r\n// rateLimit: { enabled: false, mode: undefined, options: undefined },\r\n// sanitize: { enabled: false },\r\n// validate: { enabled: false },\r\n// json: { enabled: false },\r\n// auth: { enabled: false, required: true }\r\n// };\r\n// }\r\n\r\n// const opts = input || {};\r\n\r\n// return {\r\n// cors: {\r\n// enabled: opts.cors === undefined ? true : opts.cors !== false,\r\n// options: typeof opts.cors === \"object\" ? opts.cors : undefined\r\n// },\r\n\r\n// rateLimit: normalizeRateLimit(opts.rateLimit),\r\n\r\n// sanitize: {\r\n// enabled: opts.sanitize === undefined ? true : opts.sanitize !== false\r\n// },\r\n\r\n// validate: {\r\n// enabled: !!opts.validate,\r\n// schema: opts.validate || undefined\r\n// },\r\n\r\n// json: {\r\n// enabled: opts.json === undefined ? true : opts.json !== false,\r\n// options: typeof opts.json === \"object\" ? opts.json : undefined\r\n// },\r\n\r\n// auth: normalizeAuth(opts.auth)\r\n// };\r\n// }\r\n\r\n// // ---------------------------------------------------------------\r\n// // RATE LIMIT — EXACT TYPES, NO TS ERROR\r\n// // ---------------------------------------------------------------\r\n// function normalizeRateLimit(value: SecureOptions[\"rateLimit\"]): {\r\n// enabled: boolean;\r\n// mode?: \"strict\" | \"relaxed\" | undefined;\r\n// options?: any;\r\n// } {\r\n// if (value === false) {\r\n// return { enabled: false, mode: undefined, options: undefined };\r\n// }\r\n\r\n// if (value === \"strict\") {\r\n// return {\r\n// enabled: true,\r\n// mode: \"strict\",\r\n// options: { max: 5, windowMs: 10000 }\r\n// };\r\n// }\r\n\r\n// if (value === \"relaxed\") {\r\n// return {\r\n// enabled: true,\r\n// mode: \"relaxed\",\r\n// options: { max: 100, windowMs: 60000 }\r\n// };\r\n// }\r\n\r\n// if (typeof value === \"object\") {\r\n// return {\r\n// enabled: true,\r\n// mode: undefined, // VERY IMPORTANT!\r\n// options: value\r\n// };\r\n// }\r\n\r\n// // Default → enabled and optional fields omitted\r\n// return {\r\n// enabled: true,\r\n// mode: undefined,\r\n// options: undefined\r\n// };\r\n// }\r\n\r\n// // ---------------------------------------------------------------\r\n// // AUTH NORMALIZER — EXACT FOR useSecure\r\n// // ---------------------------------------------------------------\r\n// function normalizeAuth(value: SecureOptions[\"auth\"]) {\r\n// if (value === false) return { enabled: false, required: true };\r\n\r\n// if (value === true || value === undefined)\r\n// return { enabled: true, required: true };\r\n\r\n// return {\r\n// enabled: true,\r\n// required: value.required !== false\r\n// };\r\n// }\r\n\r\n\r\n\r\n\r\n// src/utils/normalizeOptions.ts\r\nimport { \r\n SecureOptions,\r\n AuthOptions, // ✅ ADD THIS\r\n RateLimitOptions, // ✅ ADD THIS \r\n SanitizeOptions // ✅ ADD THIS\r\n} from \"../core/types/SecureOptions.js\";\r\n\r\nexport interface NormalizedOptions {\r\n cors: { enabled: boolean; options?: object };\r\n rateLimit: { enabled: boolean; mode?: \"strict\" | \"relaxed\"; options?: RateLimitOptions };\r\n sanitize: { enabled: boolean; options?: SanitizeOptions };\r\n validate: { enabled: boolean; schema?: any };\r\n json: { enabled: boolean; options?: object };\r\n auth: { enabled: boolean; required: boolean; roles?: string[] };\r\n compression: { enabled: boolean; options?: object };\r\n}\r\n\r\nexport function normalizeOptions(input?: SecureOptions | false): NormalizedOptions {\r\n if (input === false) {\r\n return {\r\n cors: { enabled: false },\r\n rateLimit: { enabled: false },\r\n sanitize: { enabled: false },\r\n validate: { enabled: false },\r\n json: { enabled: false },\r\n auth: { enabled: false, required: false },\r\n compression: { enabled: false }\r\n };\r\n }\r\n\r\n const opts = input || {};\r\n\r\n return {\r\n cors: {\r\n enabled: opts.cors === undefined ? true : opts.cors !== false,\r\n options: typeof opts.cors === \"object\" ? opts.cors : undefined\r\n },\r\n\r\n rateLimit: normalizeRateLimit(opts.rateLimit),\r\n\r\n sanitize: {\r\n enabled: opts.sanitize === undefined ? true : opts.sanitize !== false,\r\n options: typeof opts.sanitize === \"object\" ? opts.sanitize : undefined\r\n },\r\n\r\n // validate: {\r\n // enabled: !!opts.validate,\r\n // schema: opts.validate || undefined\r\n // },\r\n\r\n validate: {\r\n enabled: opts.validate !== undefined,\r\n schema: opts.validate\r\n},\r\n\r\n\r\n json: {\r\n enabled: opts.json === undefined ? true : opts.json !== false,\r\n options: typeof opts.json === \"object\" ? opts.json : undefined\r\n },\r\n\r\n auth: normalizeAuth(opts.auth),\r\n\r\n compression: {\r\n enabled: opts.compression === undefined ? true : opts.compression !== false,\r\n options: typeof opts.compression === \"object\" ? opts.compression : undefined\r\n }\r\n };\r\n}\r\n\r\nfunction normalizeRateLimit(value: SecureOptions[\"rateLimit\"]): NormalizedOptions[\"rateLimit\"] {\r\n if (value === false) return { enabled: false };\r\n \r\n if (value === \"strict\") {\r\n return {\r\n enabled: true,\r\n mode: \"strict\",\r\n options: { max: 5, windowMs: 10000 }\r\n };\r\n }\r\n \r\n if (value === \"relaxed\") {\r\n return {\r\n enabled: true,\r\n mode: \"relaxed\",\r\n options: { max: 100, windowMs: 60000 }\r\n };\r\n }\r\n \r\n if (typeof value === \"object\") {\r\n const val = value as RateLimitOptions;\r\n const { mode, ...options } = val;\r\n return {\r\n enabled: true,\r\n mode: (mode === \"strict\" || mode === \"relaxed\") ? mode : undefined,\r\n options\r\n };\r\n }\r\n \r\n return { enabled: true };\r\n}\r\n\r\nfunction normalizeAuth(value: SecureOptions[\"auth\"]): NormalizedOptions[\"auth\"] {\r\n // if (value === false) {\r\n // return { enabled: false, required: false };\r\n // }\r\n \r\n // if (value === true || value === undefined) {\r\n // return { enabled: true, required: true };\r\n // }\r\n\r\n\r\n if (value === undefined) {\r\n return { enabled: false, required: false };\r\n}\r\nif (value === true) {\r\n return { enabled: true, required: true };\r\n}\r\n\r\n \r\n const authOptions = value as AuthOptions;\r\n const enabled = authOptions.required !== false;\r\n \r\n return {\r\n enabled,\r\n required: enabled,\r\n roles: authOptions.roles\r\n };\r\n}\r\n\r\nexport function getPresetOptions(preset: 'api' | 'strict' | 'public'): NormalizedOptions {\r\n const presets = {\r\n api: {\r\n cors: { enabled: true, options: { origin: '*' } },\r\n rateLimit: { enabled: true, mode: 'relaxed' as const },\r\n sanitize: { enabled: true },\r\n validate: { enabled: false },\r\n json: { enabled: true },\r\n auth: { enabled: false, required: false },\r\n compression: { enabled: true }\r\n },\r\n strict: {\r\n cors: { enabled: true, options: { origin: process.env.ALLOWED_ORIGIN || '*' } },\r\n rateLimit: { enabled: true, mode: 'strict' as const },\r\n sanitize: { enabled: true },\r\n validate: { enabled: true },\r\n json: { enabled: true },\r\n auth: { enabled: true, required: true },\r\n compression: { enabled: true }\r\n },\r\n public: {\r\n cors: { enabled: true, options: { origin: '*' } },\r\n rateLimit: { enabled: true },\r\n sanitize: { enabled: false },\r\n validate: { enabled: false },\r\n json: { enabled: true },\r\n auth: { enabled: false, required: false },\r\n compression: { enabled: true }\r\n }\r\n };\r\n \r\n return presets[preset] || presets.api;\r\n}"]}
|
package/package.json
CHANGED
package/readme.md
ADDED
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
<h1 align="center">🔒 HiSecure</h1>
|
|
2
|
+
<p align="center"><strong>One-line security for Express.js applications</strong></p>
|
|
3
|
+
|
|
4
|
+
<p align="center">
|
|
5
|
+
HiSecure is an all-in-one security framework for Express.js.<br/>
|
|
6
|
+
It bundles hashing, authentication, validation, sanitization, rate-limiting, logging, and security headers —
|
|
7
|
+
all through a <strong>single middleware line</strong>.
|
|
8
|
+
</p>
|
|
9
|
+
|
|
10
|
+
<br/>
|
|
11
|
+
|
|
12
|
+
<!-- 🌟 FEATURE SECTION -->
|
|
13
|
+
<div style="border-left:5px solid #6366F1; padding:20px; border-radius:8px; background:#fafafa;">
|
|
14
|
+
|
|
15
|
+
<h2>✨ Features</h2>
|
|
16
|
+
|
|
17
|
+
<h3 style="color:#10B981;">🔐 Password Security</h3>
|
|
18
|
+
<ul>
|
|
19
|
+
<li><strong>Argon2</strong> – Industry-leading hashing</li>
|
|
20
|
+
<li><strong>Bcrypt fallback</strong> – Auto-fallback system</li>
|
|
21
|
+
<li>Simple hash + verify utilities</li>
|
|
22
|
+
</ul>
|
|
23
|
+
|
|
24
|
+
<h3 style="color:#3B82F6;">🔑 Authentication</h3>
|
|
25
|
+
<ul>
|
|
26
|
+
<li><strong>JWT Authentication</strong> (issuer, audience, expiry)</li>
|
|
27
|
+
<li><strong>Google OAuth</strong> integration</li>
|
|
28
|
+
<li><strong>Route protection middleware</strong></li>
|
|
29
|
+
</ul>
|
|
30
|
+
|
|
31
|
+
<h3 style="color:#F59E0B;">⏱️ Rate Limiting</h3>
|
|
32
|
+
<ul>
|
|
33
|
+
<li><strong>express-rate-limit</strong> – (Primary)</li>
|
|
34
|
+
<li><strong>rate-limiter-flexible</strong> – (Fallback)</li>
|
|
35
|
+
<li>Modes:
|
|
36
|
+
<ul>
|
|
37
|
+
<li>🛑 <strong>Strict</strong>: 5 req / 10 sec</li>
|
|
38
|
+
<li>🟡 <strong>Relaxed</strong>: 100 req / 15 min</li>
|
|
39
|
+
<li>⚙️ <strong>API</strong>: Custom config</li>
|
|
40
|
+
</ul>
|
|
41
|
+
</li>
|
|
42
|
+
</ul>
|
|
43
|
+
|
|
44
|
+
<h3 style="color:#EC4899;">🧼 Input Sanitization</h3>
|
|
45
|
+
<ul>
|
|
46
|
+
<li><strong>sanitize-html</strong> – HTML sanitization</li>
|
|
47
|
+
<li><strong>xss</strong> – Fallback for XSS</li>
|
|
48
|
+
<li>Auto-cleans request body, query & params</li>
|
|
49
|
+
</ul>
|
|
50
|
+
|
|
51
|
+
<h3 style="color:#8B5CF6;">🛡️ Additional Security Layers</h3>
|
|
52
|
+
<ul>
|
|
53
|
+
<li>CORS • Helmet • HPP</li>
|
|
54
|
+
<li>Secure JSON parsing</li>
|
|
55
|
+
<li>Query parser hardening</li>
|
|
56
|
+
<li>Gzip compression</li>
|
|
57
|
+
<li>Structured logging</li>
|
|
58
|
+
</ul>
|
|
59
|
+
|
|
60
|
+
</div>
|
|
61
|
+
|
|
62
|
+
<br/>
|
|
63
|
+
|
|
64
|
+
<!-- 🚀 QUICK START SECTION -->
|
|
65
|
+
<div style="border-left:5px solid #10B981; padding:20px; border-radius:8px; background:#fafafa;">
|
|
66
|
+
|
|
67
|
+
<h2>🚀 Quick Start</h2>
|
|
68
|
+
|
|
69
|
+
<h3>📦 Installation</h3>
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
npm install hi-secure
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
<h3>🔥 Basic Setup</h3>
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
import express from "express";
|
|
79
|
+
import { HiSecure } from "hi-secure";
|
|
80
|
+
|
|
81
|
+
const app = express();
|
|
82
|
+
|
|
83
|
+
app.use(
|
|
84
|
+
HiSecure.middleware('api')
|
|
85
|
+
// { cors: true, rateLimit: "relaxed", sanitize: true }
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
app.listen(3000, () => console.log("Server running"));
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
<h3 style="color:#A855F7;">✔ Using inside secureRoute()</h3>
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
|
|
95
|
+
router.post(
|
|
96
|
+
"/feedback",
|
|
97
|
+
...secureRoute({
|
|
98
|
+
sanitize: true,
|
|
99
|
+
validate: z.object({
|
|
100
|
+
message: z.string().min(5),
|
|
101
|
+
rating: z.number().min(1).max(5)
|
|
102
|
+
}),
|
|
103
|
+
}),
|
|
104
|
+
handleFeedback
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
</div> <br/> <!-- 🧩 FULL AUTH SECTION --> <div style="border-left:5px solid #F43F5E; padding:20px; border-radius:8px; background:#fafafa;"> <h2>🧩 Full Authentication Example</h2> <h3 style="color:#F43F5E;">🔐 Register User</h3>
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
export const registerUser = async (req, res) => {
|
|
115
|
+
const { name, email, password } = req.body;
|
|
116
|
+
|
|
117
|
+
const hashed = await HiSecure.hash(password);
|
|
118
|
+
|
|
119
|
+
const user = await User.create({ name, email, password: hashed });
|
|
120
|
+
|
|
121
|
+
const token = HiSecure.jwt.sign({ userId: user._id });
|
|
122
|
+
|
|
123
|
+
res.json({ message: "Registered", token });
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
<h3 style="color:#F43F5E;">🔐 Login User</h3>
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
|
|
134
|
+
export const loginUser = async (req, res) => {
|
|
135
|
+
const { email, password } = req.body;
|
|
136
|
+
|
|
137
|
+
const user = await User.findOne({ email });
|
|
138
|
+
|
|
139
|
+
const valid = await HiSecure.verify(password, user.password);
|
|
140
|
+
if (!valid) return res.status(401).json({ error: "Invalid credentials" });
|
|
141
|
+
|
|
142
|
+
const token = HiSecure.jwt.sign({ userId: user._id });
|
|
143
|
+
|
|
144
|
+
res.json({ token });
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
<h3 style="color:#F43F5E;">👤 Protected Route</h3>
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
|
|
154
|
+
router.get("/profile", HiSecure.auth({ required: true }), getProfile);
|
|
155
|
+
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
</div> <br/> <!-- ROUTES --> <div style="border-left:5px solid #F59E0B; padding:20px; border-radius:8px; background:#fafafa;"> <h2>📌 Routes Example</h2>
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
|
|
165
|
+
router.post("/register",
|
|
166
|
+
HiSecure.validate(registerSchema),
|
|
167
|
+
registerUser
|
|
168
|
+
);
|
|
169
|
+
|
|
170
|
+
router.post(
|
|
171
|
+
"/login",
|
|
172
|
+
HiSecure.rateLimit("strict"),
|
|
173
|
+
HiSecure.validate(loginSchema),
|
|
174
|
+
loginUser
|
|
175
|
+
);
|
|
176
|
+
|
|
177
|
+
router.get(
|
|
178
|
+
"/profile",
|
|
179
|
+
HiSecure.auth({ required: true }),
|
|
180
|
+
getProfile
|
|
181
|
+
);
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
</div> <br/> <h2 align="center">🛠️ More features & docs coming soon…</h2>
|
|
188
|
+
<h3 align="center">Made with 🔒 for secure Node.js apps</h3>
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
|
|
@@ -1,41 +1,3 @@
|
|
|
1
|
-
// import rateLimit from "express-rate-limit";
|
|
2
|
-
// import { logger } from "../logging";
|
|
3
|
-
// import { AdapterError } from "../core/errors/AdapterError";
|
|
4
|
-
|
|
5
|
-
// export class ExpressRLAdapter {
|
|
6
|
-
|
|
7
|
-
// /**
|
|
8
|
-
// * Create express rate-limit middleware dynamically
|
|
9
|
-
// */
|
|
10
|
-
// getMiddleware(options: {
|
|
11
|
-
// windowMs?: number;
|
|
12
|
-
// max?: number;
|
|
13
|
-
// message?: any;
|
|
14
|
-
// } = {}) {
|
|
15
|
-
|
|
16
|
-
// try {
|
|
17
|
-
// const limiter = rateLimit({
|
|
18
|
-
// windowMs: options.windowMs ?? 15 * 60 * 1000, // default
|
|
19
|
-
// max: options.max ?? 100,
|
|
20
|
-
// message: options.message ?? { error: "Too many requests" },
|
|
21
|
-
// standardHeaders: true,
|
|
22
|
-
// legacyHeaders: false,
|
|
23
|
-
// });
|
|
24
|
-
|
|
25
|
-
// return limiter;
|
|
26
|
-
|
|
27
|
-
// } catch (err: any) {
|
|
28
|
-
// logger.error("❌ ExpressRLAdapter: failed to create limiter", {
|
|
29
|
-
// error: err?.message || err
|
|
30
|
-
// });
|
|
31
|
-
// throw new AdapterError("Express rate limiter creation failed.");
|
|
32
|
-
// }
|
|
33
|
-
// }
|
|
34
|
-
// }
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
1
|
// src/adapters/ExpressRLAdapter.ts - IMPROVED
|
|
40
2
|
import rateLimit from "express-rate-limit";
|
|
41
3
|
import { logger } from "../logging/index.js";
|
|
@@ -128,7 +128,9 @@
|
|
|
128
128
|
// src/adapters/GoogleAdapter.ts - FIXED
|
|
129
129
|
import { OAuth2Client, LoginTicket } from "google-auth-library";
|
|
130
130
|
import { AdapterError } from "../core/errors/AdapterError.js";
|
|
131
|
-
import { logWarn, logError } from "../logging/index.js";
|
|
131
|
+
// import { logWarn, logError } from "../logging/index.js";
|
|
132
|
+
|
|
133
|
+
import {logger} from '../logging';
|
|
132
134
|
|
|
133
135
|
export interface GoogleTokenPayload {
|
|
134
136
|
sub: string;
|
|
@@ -171,7 +173,7 @@ export class GoogleAdapter {
|
|
|
171
173
|
const payload = ticket.getPayload();
|
|
172
174
|
|
|
173
175
|
if (!payload) {
|
|
174
|
-
|
|
176
|
+
logger.warn("GoogleAdapter: Empty payload");
|
|
175
177
|
throw new AdapterError("Invalid Google ID token payload.");
|
|
176
178
|
}
|
|
177
179
|
|
|
@@ -191,7 +193,7 @@ export class GoogleAdapter {
|
|
|
191
193
|
return result;
|
|
192
194
|
|
|
193
195
|
} catch (err: any) {
|
|
194
|
-
|
|
196
|
+
logger.error("GoogleAdapter.verifyIdToken failed", {
|
|
195
197
|
error: err?.message,
|
|
196
198
|
hasClientId: !!this.clientId
|
|
197
199
|
});
|
|
@@ -256,6 +256,7 @@ import jwt from "jsonwebtoken";
|
|
|
256
256
|
import { randomUUID } from "crypto"; // Built-in Node.js
|
|
257
257
|
import { AdapterError } from "../core/errors/AdapterError.js";
|
|
258
258
|
import { logError } from "../logging/index.js";
|
|
259
|
+
import { logger } from "../logging";
|
|
259
260
|
|
|
260
261
|
export interface JWTAdapterOptions {
|
|
261
262
|
secret: string;
|
|
@@ -286,7 +287,8 @@ export class JWTAdapter {
|
|
|
286
287
|
}
|
|
287
288
|
|
|
288
289
|
if (options.secret.length < 32) {
|
|
289
|
-
|
|
290
|
+
logger.warn("🚨 JWT secret shorter than 32 chars. Consider using stronger secret.");
|
|
291
|
+
// logError("⚠ JWT secret is too short (minimum 32 characters recommended)");
|
|
290
292
|
}
|
|
291
293
|
|
|
292
294
|
this.secret = options.secret;
|