hi-secure 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (210) hide show
  1. package/dist/adapters/ArgonAdapter.d.ts +8 -0
  2. package/dist/adapters/ArgonAdapter.d.ts.map +1 -0
  3. package/dist/adapters/ArgonAdapter.js +45 -0
  4. package/dist/adapters/ArgonAdapter.js.map +1 -0
  5. package/dist/adapters/BcryptAdapter.d.ts +7 -0
  6. package/dist/adapters/BcryptAdapter.d.ts.map +1 -0
  7. package/dist/adapters/BcryptAdapter.js +48 -0
  8. package/dist/adapters/BcryptAdapter.js.map +1 -0
  9. package/dist/adapters/DomPurifyAdapter.d.ts +13 -0
  10. package/dist/adapters/DomPurifyAdapter.d.ts.map +1 -0
  11. package/dist/adapters/DomPurifyAdapter.js +61 -0
  12. package/dist/adapters/DomPurifyAdapter.js.map +1 -0
  13. package/dist/adapters/ExpressRLAdapter.d.ts +13 -0
  14. package/dist/adapters/ExpressRLAdapter.d.ts.map +1 -0
  15. package/dist/adapters/ExpressRLAdapter.js +68 -0
  16. package/dist/adapters/ExpressRLAdapter.js.map +1 -0
  17. package/dist/adapters/ExpressValidatorAdapter.d.ts +6 -0
  18. package/dist/adapters/ExpressValidatorAdapter.d.ts.map +1 -0
  19. package/dist/adapters/ExpressValidatorAdapter.js +78 -0
  20. package/dist/adapters/ExpressValidatorAdapter.js.map +1 -0
  21. package/dist/adapters/GoggleAdapter.d.ts +15 -0
  22. package/dist/adapters/GoggleAdapter.d.ts.map +1 -0
  23. package/dist/adapters/GoggleAdapter.js +91 -0
  24. package/dist/adapters/GoggleAdapter.js.map +1 -0
  25. package/dist/adapters/GoogleAdapter.d.ts +15 -0
  26. package/dist/adapters/GoogleAdapter.d.ts.map +1 -0
  27. package/dist/adapters/GoogleAdapter.js +159 -0
  28. package/dist/adapters/GoogleAdapter.js.map +1 -0
  29. package/dist/adapters/JWTAdapter.d.ts +28 -0
  30. package/dist/adapters/JWTAdapter.d.ts.map +1 -0
  31. package/dist/adapters/JWTAdapter.js +276 -0
  32. package/dist/adapters/JWTAdapter.js.map +1 -0
  33. package/dist/adapters/RLFlexibleAdapter.d.ts +11 -0
  34. package/dist/adapters/RLFlexibleAdapter.d.ts.map +1 -0
  35. package/dist/adapters/RLFlexibleAdapter.js +115 -0
  36. package/dist/adapters/RLFlexibleAdapter.js.map +1 -0
  37. package/dist/adapters/SanitizeHtmlAdapter.d.ts +12 -0
  38. package/dist/adapters/SanitizeHtmlAdapter.d.ts.map +1 -0
  39. package/dist/adapters/SanitizeHtmlAdapter.js +141 -0
  40. package/dist/adapters/SanitizeHtmlAdapter.js.map +1 -0
  41. package/dist/adapters/XSSAdapter.d.ts +33 -0
  42. package/dist/adapters/XSSAdapter.d.ts.map +1 -0
  43. package/dist/adapters/XSSAdapter.js +127 -0
  44. package/dist/adapters/XSSAdapter.js.map +1 -0
  45. package/dist/adapters/ZodAdapter.d.ts +7 -0
  46. package/dist/adapters/ZodAdapter.d.ts.map +1 -0
  47. package/dist/adapters/ZodAdapter.js +39 -0
  48. package/dist/adapters/ZodAdapter.js.map +1 -0
  49. package/dist/core/HiSecure.d.ts +62 -0
  50. package/dist/core/HiSecure.d.ts.map +1 -0
  51. package/dist/core/HiSecure.js +273 -0
  52. package/dist/core/HiSecure.js.map +1 -0
  53. package/dist/core/config.d.ts +3 -0
  54. package/dist/core/config.d.ts.map +1 -0
  55. package/dist/core/config.js +53 -0
  56. package/dist/core/config.js.map +1 -0
  57. package/dist/core/constants.d.ts +37 -0
  58. package/dist/core/constants.d.ts.map +1 -0
  59. package/dist/core/constants.js +67 -0
  60. package/dist/core/constants.js.map +1 -0
  61. package/dist/core/errors/AdapterError.d.ts +5 -0
  62. package/dist/core/errors/AdapterError.d.ts.map +1 -0
  63. package/dist/core/errors/AdapterError.js +15 -0
  64. package/dist/core/errors/AdapterError.js.map +1 -0
  65. package/dist/core/errors/HttpErrror.d.ts +17 -0
  66. package/dist/core/errors/HttpErrror.d.ts.map +1 -0
  67. package/dist/core/errors/HttpErrror.js +36 -0
  68. package/dist/core/errors/HttpErrror.js.map +1 -0
  69. package/dist/core/errors/SanitizerError.d.ts +5 -0
  70. package/dist/core/errors/SanitizerError.d.ts.map +1 -0
  71. package/dist/core/errors/SanitizerError.js +14 -0
  72. package/dist/core/errors/SanitizerError.js.map +1 -0
  73. package/dist/core/errors/SecurityError.d.ts +5 -0
  74. package/dist/core/errors/SecurityError.d.ts.map +1 -0
  75. package/dist/core/errors/SecurityError.js +14 -0
  76. package/dist/core/errors/SecurityError.js.map +1 -0
  77. package/dist/core/errors/ValidationError.d.ts +5 -0
  78. package/dist/core/errors/ValidationError.d.ts.map +1 -0
  79. package/dist/core/errors/ValidationError.js +14 -0
  80. package/dist/core/errors/ValidationError.js.map +1 -0
  81. package/dist/core/types/HiSecureConfig.d.ts +47 -0
  82. package/dist/core/types/HiSecureConfig.d.ts.map +1 -0
  83. package/dist/core/types/HiSecureConfig.js +3 -0
  84. package/dist/core/types/HiSecureConfig.js.map +1 -0
  85. package/dist/core/types/SecureOptions.d.ts +30 -0
  86. package/dist/core/types/SecureOptions.d.ts.map +1 -0
  87. package/dist/core/types/SecureOptions.js +4 -0
  88. package/dist/core/types/SecureOptions.js.map +1 -0
  89. package/dist/core/useSecure.d.ts +10 -0
  90. package/dist/core/useSecure.d.ts.map +1 -0
  91. package/dist/core/useSecure.js +85 -0
  92. package/dist/core/useSecure.js.map +1 -0
  93. package/dist/examples/e1.d.ts +1 -0
  94. package/dist/examples/e1.d.ts.map +1 -0
  95. package/dist/examples/e1.js +3 -0
  96. package/dist/examples/e1.js.map +1 -0
  97. package/dist/index.d.ts +9 -0
  98. package/dist/index.d.ts.map +1 -0
  99. package/dist/index.js +15 -0
  100. package/dist/index.js.map +1 -0
  101. package/dist/logging/index.d.ts +3 -0
  102. package/dist/logging/index.d.ts.map +1 -0
  103. package/dist/logging/index.js +19 -0
  104. package/dist/logging/index.js.map +1 -0
  105. package/dist/logging/morganSetup.d.ts +2 -0
  106. package/dist/logging/morganSetup.d.ts.map +1 -0
  107. package/dist/logging/morganSetup.js +9 -0
  108. package/dist/logging/morganSetup.js.map +1 -0
  109. package/dist/logging/winstonSetup.d.ts +6 -0
  110. package/dist/logging/winstonSetup.d.ts.map +1 -0
  111. package/dist/logging/winstonSetup.js +22 -0
  112. package/dist/logging/winstonSetup.js.map +1 -0
  113. package/dist/managers/AuthManager.d.ts +23 -0
  114. package/dist/managers/AuthManager.d.ts.map +1 -0
  115. package/dist/managers/AuthManager.js +190 -0
  116. package/dist/managers/AuthManager.js.map +1 -0
  117. package/dist/managers/CorsManager.d.ts +9 -0
  118. package/dist/managers/CorsManager.d.ts.map +1 -0
  119. package/dist/managers/CorsManager.js +55 -0
  120. package/dist/managers/CorsManager.js.map +1 -0
  121. package/dist/managers/HashManager.d.ts +22 -0
  122. package/dist/managers/HashManager.d.ts.map +1 -0
  123. package/dist/managers/HashManager.js +319 -0
  124. package/dist/managers/HashManager.js.map +1 -0
  125. package/dist/managers/JsonManager.d.ts +6 -0
  126. package/dist/managers/JsonManager.d.ts.map +1 -0
  127. package/dist/managers/JsonManager.js +142 -0
  128. package/dist/managers/JsonManager.js.map +1 -0
  129. package/dist/managers/RateLimitManager.d.ts +16 -0
  130. package/dist/managers/RateLimitManager.d.ts.map +1 -0
  131. package/dist/managers/RateLimitManager.js +108 -0
  132. package/dist/managers/RateLimitManager.js.map +1 -0
  133. package/dist/managers/SanitizerManager.d.ts +18 -0
  134. package/dist/managers/SanitizerManager.d.ts.map +1 -0
  135. package/dist/managers/SanitizerManager.js +296 -0
  136. package/dist/managers/SanitizerManager.js.map +1 -0
  137. package/dist/managers/ValidatorManager.d.ts +13 -0
  138. package/dist/managers/ValidatorManager.d.ts.map +1 -0
  139. package/dist/managers/ValidatorManager.js +218 -0
  140. package/dist/managers/ValidatorManager.js.map +1 -0
  141. package/dist/middlewares/errorHandler.d.ts +3 -0
  142. package/dist/middlewares/errorHandler.d.ts.map +1 -0
  143. package/dist/middlewares/errorHandler.js +94 -0
  144. package/dist/middlewares/errorHandler.js.map +1 -0
  145. package/dist/middlewares/index.d.ts +3 -0
  146. package/dist/middlewares/index.d.ts.map +1 -0
  147. package/dist/middlewares/index.js +19 -0
  148. package/dist/middlewares/index.js.map +1 -0
  149. package/dist/middlewares/requestLogger.d.ts +2 -0
  150. package/dist/middlewares/requestLogger.d.ts.map +1 -0
  151. package/dist/middlewares/requestLogger.js +8 -0
  152. package/dist/middlewares/requestLogger.js.map +1 -0
  153. package/dist/test/t1.d.ts +1 -0
  154. package/dist/test/t1.d.ts.map +1 -0
  155. package/dist/test/t1.js +3 -0
  156. package/dist/test/t1.js.map +1 -0
  157. package/dist/utils/deepFreeze.d.ts +2 -0
  158. package/dist/utils/deepFreeze.d.ts.map +1 -0
  159. package/dist/utils/deepFreeze.js +69 -0
  160. package/dist/utils/deepFreeze.js.map +1 -0
  161. package/dist/utils/deepMerge.d.ts +5 -0
  162. package/dist/utils/deepMerge.d.ts.map +1 -0
  163. package/dist/utils/deepMerge.js +68 -0
  164. package/dist/utils/deepMerge.js.map +1 -0
  165. package/dist/utils/normalizeOptions.d.ts +38 -0
  166. package/dist/utils/normalizeOptions.d.ts.map +1 -0
  167. package/dist/utils/normalizeOptions.js +119 -0
  168. package/dist/utils/normalizeOptions.js.map +1 -0
  169. package/package.json +50 -0
  170. package/src/adapters/ArgonAdapter.ts +41 -0
  171. package/src/adapters/BcryptAdapter.ts +49 -0
  172. package/src/adapters/ExpressRLAdapter.ts +84 -0
  173. package/src/adapters/ExpressValidatorAdapter.ts +99 -0
  174. package/src/adapters/GoogleAdapter.ts +206 -0
  175. package/src/adapters/JWTAdapter.ts +346 -0
  176. package/src/adapters/RLFlexibleAdapter.ts +139 -0
  177. package/src/adapters/SanitizeHtmlAdapter.ts +162 -0
  178. package/src/adapters/XSSAdapter.ts +153 -0
  179. package/src/adapters/ZodAdapter.ts +91 -0
  180. package/src/core/HiSecure.ts +955 -0
  181. package/src/core/config.ts +156 -0
  182. package/src/core/constants.ts +73 -0
  183. package/src/core/errors/AdapterError.ts +14 -0
  184. package/src/core/errors/HttpErrror.ts +46 -0
  185. package/src/core/errors/SanitizerError.ts +13 -0
  186. package/src/core/errors/SecurityError.ts +13 -0
  187. package/src/core/errors/ValidationError.ts +13 -0
  188. package/src/core/types/HiSecureConfig.ts +62 -0
  189. package/src/core/types/SecureOptions.ts +61 -0
  190. package/src/core/useSecure.ts +111 -0
  191. package/src/examples/e1.ts +1 -0
  192. package/src/index.ts +17 -0
  193. package/src/logging/index.ts +2 -0
  194. package/src/logging/morganSetup.ts +3 -0
  195. package/src/logging/winstonSetup.ts +17 -0
  196. package/src/managers/AuthManager.ts +237 -0
  197. package/src/managers/CorsManager.ts +58 -0
  198. package/src/managers/HashManager.ts +390 -0
  199. package/src/managers/JsonManager.ts +149 -0
  200. package/src/managers/RateLimitManager.ts +368 -0
  201. package/src/managers/SanitizerManager.ts +359 -0
  202. package/src/managers/ValidatorManager.ts +269 -0
  203. package/src/middlewares/errorHandler.ts +265 -0
  204. package/src/middlewares/index.ts +2 -0
  205. package/src/middlewares/requestLogger.ts +5 -0
  206. package/src/test/t1.ts +1 -0
  207. package/src/utils/deepFreeze.ts +76 -0
  208. package/src/utils/deepMerge.ts +87 -0
  209. package/src/utils/normalizeOptions.ts +265 -0
  210. package/tsconfig.json +30 -0
@@ -0,0 +1,153 @@
1
+ // src/adapters/XSSAdapter.ts - NEW FILE
2
+ import { FilterXSS, getDefaultWhiteList, whiteList } from 'xss';
3
+ import { AdapterError } from "../core/errors/AdapterError.js";
4
+ import { logger } from "../logging/index.js";
5
+
6
+ export interface XSSOptions {
7
+ whiteList?: typeof whiteList;
8
+ stripIgnoreTag?: boolean;
9
+ stripIgnoreTagBody?: string[];
10
+ allowCommentTag?: boolean;
11
+ css?: boolean | { [key: string]: boolean };
12
+ onTag?: (tag: string, html: string, options: any) => string;
13
+ onTagAttr?: (tag: string, name: string, value: string, isWhiteAttr: boolean) => string;
14
+ onIgnoreTag?: (tag: string, html: string, options: any) => string;
15
+ [key: string]: any;
16
+ }
17
+
18
+ export class XSSAdapter {
19
+ private globalOptions: XSSOptions;
20
+ private defaultFilter: FilterXSS;
21
+
22
+ constructor(options: XSSOptions = {}) {
23
+ this.globalOptions = options;
24
+
25
+ // Default safe configuration
26
+ const defaultOptions: XSSOptions = {
27
+ whiteList: getDefaultWhiteList(),
28
+ stripIgnoreTag: true, // Remove non-whitelisted tags completely
29
+ stripIgnoreTagBody: ['script', 'style', 'iframe', 'object', 'embed'],
30
+ allowCommentTag: false,
31
+ css: false, // Disable CSS by default
32
+ onTag: (tag, html, options) => {
33
+ // Add noopener/noreferrer to links for security
34
+ if (tag === 'a') {
35
+ return html.replace(/<a /i, '<a target="_blank" rel="noopener noreferrer" ');
36
+ }
37
+ return html;
38
+ }
39
+ };
40
+
41
+ const finalOptions = { ...defaultOptions, ...options };
42
+ this.defaultFilter = new FilterXSS(finalOptions);
43
+ }
44
+
45
+ /**
46
+ * Sanitize a string with global + dynamic merged options
47
+ */
48
+ sanitize(input: string, dynamicOptions?: XSSOptions): string {
49
+ try {
50
+ if (typeof input !== "string") {
51
+ return input as any;
52
+ }
53
+
54
+ // If no dynamic options, use default filter
55
+ if (!dynamicOptions || Object.keys(dynamicOptions).length === 0) {
56
+ return this.defaultFilter.process(input);
57
+ }
58
+
59
+ // Merge options for this specific call
60
+ const mergedOptions = { ...this.globalOptions, ...dynamicOptions };
61
+ const customFilter = new FilterXSS(mergedOptions);
62
+
63
+ return customFilter.process(input);
64
+
65
+ } catch (err: any) {
66
+ logger.error("❌ XSS sanitizer failed", {
67
+ error: err?.message,
68
+ preview: input?.slice?.(0, 80)
69
+ });
70
+ throw new AdapterError("XSS sanitizer failed.");
71
+ }
72
+ }
73
+
74
+ /**
75
+ * Middleware wrapper WITH dynamic options
76
+ * Doesn't mutate original request - creates sanitized copy
77
+ */
78
+ middleware(dynamicOptions?: XSSOptions) {
79
+ return (req: any, _res: any, next: any) => {
80
+ try {
81
+ if (req.body && typeof req.body === "object") {
82
+ const originalBody = req.body;
83
+ const sanitizedBody: any = Array.isArray(originalBody) ? [] : {};
84
+
85
+ for (const key of Object.keys(originalBody)) {
86
+ const val = originalBody[key];
87
+
88
+ if (typeof val === "string") {
89
+ sanitizedBody[key] = this.sanitize(val, dynamicOptions);
90
+ } else if (Array.isArray(val)) {
91
+ sanitizedBody[key] = val.map((v) =>
92
+ typeof v === "string"
93
+ ? this.sanitize(v, dynamicOptions)
94
+ : v
95
+ );
96
+ } else if (val && typeof val === "object") {
97
+ // Handle nested objects (simple recursion)
98
+ sanitizedBody[key] = this.deepSanitize(val, dynamicOptions);
99
+ } else {
100
+ sanitizedBody[key] = val;
101
+ }
102
+ }
103
+
104
+ // Store sanitized version separately
105
+ req.sanitizedBody = sanitizedBody;
106
+
107
+ logger.debug("🛡️ XSS sanitizer applied", {
108
+ originalKeys: Object.keys(originalBody),
109
+ sanitizedKeys: Object.keys(sanitizedBody)
110
+ });
111
+ }
112
+
113
+ next();
114
+ } catch (err: any) {
115
+ logger.error("❌ XSS middleware failed", {
116
+ error: err?.message || err
117
+ });
118
+ next(err);
119
+ }
120
+ };
121
+ }
122
+
123
+ /**
124
+ * Deep sanitize nested objects/arrays
125
+ */
126
+ private deepSanitize(obj: any, options?: XSSOptions, visited = new WeakSet()): any {
127
+ // Handle circular references
128
+ if (obj && typeof obj === "object") {
129
+ if (visited.has(obj)) {
130
+ return obj;
131
+ }
132
+ visited.add(obj);
133
+ }
134
+
135
+ if (typeof obj === "string") {
136
+ return this.sanitize(obj, options);
137
+ }
138
+
139
+ if (Array.isArray(obj)) {
140
+ return obj.map(item => this.deepSanitize(item, options, visited));
141
+ }
142
+
143
+ if (obj && typeof obj === "object") {
144
+ const result: any = {};
145
+ for (const key of Object.keys(obj)) {
146
+ result[key] = this.deepSanitize(obj[key], options, visited);
147
+ }
148
+ return result;
149
+ }
150
+
151
+ return obj;
152
+ }
153
+ }
@@ -0,0 +1,91 @@
1
+ // import { ZodSchema, ZodError } from "zod";
2
+ // import { ValidationError } from "../core/errors/ValidationError";
3
+ // import { logger } from "../logging";
4
+
5
+ // export class ZodAdapter {
6
+ // private globalSchema?: ZodSchema;
7
+
8
+ // constructor(globalSchema?: ZodSchema) {
9
+ // this.globalSchema = globalSchema as any;
10
+ // }
11
+
12
+ // /**
13
+ // * Validate with global + dynamic schema (dynamic overrides global)
14
+ // */
15
+ // validate(dynamicSchema?: ZodSchema) {
16
+ // return (req: any, res: any, next: any) => {
17
+ // const schema = dynamicSchema || this.globalSchema;
18
+
19
+ // if (!schema) return next(); // no validation for this route
20
+
21
+ // const result = schema.safeParse(req.body);
22
+
23
+ // if (result.success) return next();
24
+
25
+ // const zodErr: ZodError = result.error;
26
+
27
+ // const issues = zodErr.issues.map(issue => ({
28
+ // message: issue.message,
29
+ // path: issue.path.join("."),
30
+ // code: issue.code
31
+ // }));
32
+
33
+ // logger.warn("⚠ Zod validation failed", {
34
+ // path: req.path,
35
+ // method: req.method,
36
+ // issues,
37
+ // preview: JSON.stringify(req.body).slice(0, 200)
38
+ // });
39
+
40
+ // return next(
41
+ // new ValidationError(issues[0]?.message || "Validation failed.")
42
+ // );
43
+ // };
44
+ // }
45
+ // }
46
+
47
+
48
+
49
+ // src/adapters/ZodAdapter.ts - FIXED
50
+ import { ZodSchema, ZodError } from "zod";
51
+ import { ValidationError } from "../core/errors/ValidationError.js"; // ✅ Add .js
52
+ import { logger } from "../logging/index.js";
53
+
54
+ export class ZodAdapter {
55
+ private globalSchema?: ZodSchema;
56
+
57
+ constructor(globalSchema?: ZodSchema) {
58
+ this.globalSchema = globalSchema;
59
+ }
60
+
61
+ validate(dynamicSchema?: ZodSchema) {
62
+ return (req: any, res: any, next: any) => {
63
+ const schema = dynamicSchema || this.globalSchema;
64
+
65
+ if (!schema) return next();
66
+
67
+ const result = schema.safeParse(req.body);
68
+
69
+ if (result.success) return next();
70
+
71
+ const zodErr: ZodError = result.error;
72
+
73
+ const issues = zodErr.issues.map(issue => ({
74
+ message: issue.message,
75
+ path: issue.path.join("."),
76
+ code: issue.code
77
+ }));
78
+
79
+ logger.warn("⚠ Zod validation failed", {
80
+ path: req.path,
81
+ method: req.method,
82
+ issues,
83
+ preview: JSON.stringify(req.body).slice(0, 200)
84
+ });
85
+
86
+ return next(
87
+ new ValidationError("Validation failed.", issues as any) // ✅ Pass issues
88
+ );
89
+ };
90
+ }
91
+ }