@rebasepro/server-core 0.0.1-canary.4d4fb3e

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 (254) hide show
  1. package/LICENSE +6 -0
  2. package/README.md +40 -0
  3. package/build-errors.txt +52 -0
  4. package/coverage/clover.xml +3739 -0
  5. package/coverage/coverage-final.json +31 -0
  6. package/coverage/lcov-report/base.css +224 -0
  7. package/coverage/lcov-report/block-navigation.js +87 -0
  8. package/coverage/lcov-report/favicon.png +0 -0
  9. package/coverage/lcov-report/index.html +266 -0
  10. package/coverage/lcov-report/prettify.css +1 -0
  11. package/coverage/lcov-report/prettify.js +2 -0
  12. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  13. package/coverage/lcov-report/sorter.js +210 -0
  14. package/coverage/lcov-report/src/api/ast-schema-editor.ts.html +952 -0
  15. package/coverage/lcov-report/src/api/errors.ts.html +472 -0
  16. package/coverage/lcov-report/src/api/graphql/graphql-schema-generator.ts.html +1069 -0
  17. package/coverage/lcov-report/src/api/graphql/index.html +116 -0
  18. package/coverage/lcov-report/src/api/index.html +176 -0
  19. package/coverage/lcov-report/src/api/openapi-generator.ts.html +565 -0
  20. package/coverage/lcov-report/src/api/rest/api-generator.ts.html +994 -0
  21. package/coverage/lcov-report/src/api/rest/index.html +131 -0
  22. package/coverage/lcov-report/src/api/rest/query-parser.ts.html +550 -0
  23. package/coverage/lcov-report/src/api/schema-editor-routes.ts.html +202 -0
  24. package/coverage/lcov-report/src/api/server.ts.html +823 -0
  25. package/coverage/lcov-report/src/auth/admin-routes.ts.html +973 -0
  26. package/coverage/lcov-report/src/auth/index.html +176 -0
  27. package/coverage/lcov-report/src/auth/jwt.ts.html +574 -0
  28. package/coverage/lcov-report/src/auth/middleware.ts.html +745 -0
  29. package/coverage/lcov-report/src/auth/password.ts.html +310 -0
  30. package/coverage/lcov-report/src/auth/services.ts.html +2074 -0
  31. package/coverage/lcov-report/src/collections/index.html +116 -0
  32. package/coverage/lcov-report/src/collections/loader.ts.html +232 -0
  33. package/coverage/lcov-report/src/db/auth-schema.ts.html +523 -0
  34. package/coverage/lcov-report/src/db/data-transformer.ts.html +1753 -0
  35. package/coverage/lcov-report/src/db/entityService.ts.html +700 -0
  36. package/coverage/lcov-report/src/db/index.html +146 -0
  37. package/coverage/lcov-report/src/db/services/EntityFetchService.ts.html +4048 -0
  38. package/coverage/lcov-report/src/db/services/EntityPersistService.ts.html +883 -0
  39. package/coverage/lcov-report/src/db/services/RelationService.ts.html +3121 -0
  40. package/coverage/lcov-report/src/db/services/entity-helpers.ts.html +442 -0
  41. package/coverage/lcov-report/src/db/services/index.html +176 -0
  42. package/coverage/lcov-report/src/db/services/index.ts.html +124 -0
  43. package/coverage/lcov-report/src/generate-drizzle-schema-logic.ts.html +1960 -0
  44. package/coverage/lcov-report/src/index.html +116 -0
  45. package/coverage/lcov-report/src/services/driver-registry.ts.html +631 -0
  46. package/coverage/lcov-report/src/services/index.html +131 -0
  47. package/coverage/lcov-report/src/services/postgresDataDriver.ts.html +3025 -0
  48. package/coverage/lcov-report/src/storage/LocalStorageController.ts.html +1189 -0
  49. package/coverage/lcov-report/src/storage/S3StorageController.ts.html +970 -0
  50. package/coverage/lcov-report/src/storage/index.html +161 -0
  51. package/coverage/lcov-report/src/storage/storage-registry.ts.html +646 -0
  52. package/coverage/lcov-report/src/storage/types.ts.html +451 -0
  53. package/coverage/lcov-report/src/utils/drizzle-conditions.ts.html +3082 -0
  54. package/coverage/lcov-report/src/utils/index.html +116 -0
  55. package/coverage/lcov.info +7179 -0
  56. package/dist/common/src/collections/CollectionRegistry.d.ts +48 -0
  57. package/dist/common/src/collections/index.d.ts +1 -0
  58. package/dist/common/src/data/buildRebaseData.d.ts +14 -0
  59. package/dist/common/src/index.d.ts +3 -0
  60. package/dist/common/src/util/builders.d.ts +57 -0
  61. package/dist/common/src/util/callbacks.d.ts +6 -0
  62. package/dist/common/src/util/collections.d.ts +11 -0
  63. package/dist/common/src/util/common.d.ts +2 -0
  64. package/dist/common/src/util/conditions.d.ts +26 -0
  65. package/dist/common/src/util/entities.d.ts +36 -0
  66. package/dist/common/src/util/enums.d.ts +3 -0
  67. package/dist/common/src/util/index.d.ts +16 -0
  68. package/dist/common/src/util/navigation_from_path.d.ts +34 -0
  69. package/dist/common/src/util/navigation_utils.d.ts +20 -0
  70. package/dist/common/src/util/parent_references_from_path.d.ts +6 -0
  71. package/dist/common/src/util/paths.d.ts +14 -0
  72. package/dist/common/src/util/permissions.d.ts +5 -0
  73. package/dist/common/src/util/references.d.ts +2 -0
  74. package/dist/common/src/util/relations.d.ts +12 -0
  75. package/dist/common/src/util/resolutions.d.ts +72 -0
  76. package/dist/common/src/util/storage.d.ts +24 -0
  77. package/dist/index-BeMqpmfQ.js +239 -0
  78. package/dist/index-BeMqpmfQ.js.map +1 -0
  79. package/dist/index-bl4J3lNb.js +55823 -0
  80. package/dist/index-bl4J3lNb.js.map +1 -0
  81. package/dist/index.es.js +58 -0
  82. package/dist/index.es.js.map +1 -0
  83. package/dist/index.umd.js +56062 -0
  84. package/dist/index.umd.js.map +1 -0
  85. package/dist/server-core/src/api/ast-schema-editor.d.ts +21 -0
  86. package/dist/server-core/src/api/collections_for_test/callbacks_test_collection.d.ts +2 -0
  87. package/dist/server-core/src/api/errors.d.ts +35 -0
  88. package/dist/server-core/src/api/graphql/graphql-schema-generator.d.ts +35 -0
  89. package/dist/server-core/src/api/graphql/index.d.ts +1 -0
  90. package/dist/server-core/src/api/index.d.ts +9 -0
  91. package/dist/server-core/src/api/openapi-generator.d.ts +2 -0
  92. package/dist/server-core/src/api/rest/api-generator.d.ts +64 -0
  93. package/dist/server-core/src/api/rest/index.d.ts +1 -0
  94. package/dist/server-core/src/api/rest/query-parser.d.ts +9 -0
  95. package/dist/server-core/src/api/schema-editor-routes.d.ts +3 -0
  96. package/dist/server-core/src/api/server.d.ts +40 -0
  97. package/dist/server-core/src/api/types.d.ts +90 -0
  98. package/dist/server-core/src/auth/admin-routes.d.ts +7 -0
  99. package/dist/server-core/src/auth/google-oauth.d.ts +20 -0
  100. package/dist/server-core/src/auth/index.d.ts +12 -0
  101. package/dist/server-core/src/auth/interfaces.d.ts +270 -0
  102. package/dist/server-core/src/auth/jwt.d.ts +42 -0
  103. package/dist/server-core/src/auth/middleware.d.ts +56 -0
  104. package/dist/server-core/src/auth/password.d.ts +22 -0
  105. package/dist/server-core/src/auth/rate-limiter.d.ts +31 -0
  106. package/dist/server-core/src/auth/routes.d.ts +17 -0
  107. package/dist/server-core/src/bootstrappers/index.d.ts +0 -0
  108. package/dist/server-core/src/collections/BackendCollectionRegistry.d.ts +13 -0
  109. package/dist/server-core/src/collections/loader.d.ts +5 -0
  110. package/dist/server-core/src/db/interfaces.d.ts +18 -0
  111. package/dist/server-core/src/email/index.d.ts +6 -0
  112. package/dist/server-core/src/email/smtp-email-service.d.ts +25 -0
  113. package/dist/server-core/src/email/templates.d.ts +33 -0
  114. package/dist/server-core/src/email/types.d.ts +110 -0
  115. package/dist/server-core/src/functions/function-loader.d.ts +17 -0
  116. package/dist/server-core/src/functions/function-routes.d.ts +10 -0
  117. package/dist/server-core/src/functions/index.d.ts +3 -0
  118. package/dist/server-core/src/history/history-routes.d.ts +23 -0
  119. package/dist/server-core/src/history/index.d.ts +1 -0
  120. package/dist/server-core/src/index.d.ts +24 -0
  121. package/dist/server-core/src/init.d.ts +49 -0
  122. package/dist/server-core/src/serve-spa.d.ts +30 -0
  123. package/dist/server-core/src/services/driver-registry.d.ts +78 -0
  124. package/dist/server-core/src/storage/LocalStorageController.d.ts +46 -0
  125. package/dist/server-core/src/storage/S3StorageController.d.ts +36 -0
  126. package/dist/server-core/src/storage/index.d.ts +18 -0
  127. package/dist/server-core/src/storage/routes.d.ts +38 -0
  128. package/dist/server-core/src/storage/storage-registry.d.ts +78 -0
  129. package/dist/server-core/src/storage/types.d.ts +91 -0
  130. package/dist/server-core/src/types/index.d.ts +11 -0
  131. package/dist/server-core/src/utils/logging.d.ts +9 -0
  132. package/dist/server-core/src/utils/sql.d.ts +27 -0
  133. package/dist/types/src/controllers/analytics_controller.d.ts +7 -0
  134. package/dist/types/src/controllers/auth.d.ts +117 -0
  135. package/dist/types/src/controllers/client.d.ts +58 -0
  136. package/dist/types/src/controllers/collection_registry.d.ts +44 -0
  137. package/dist/types/src/controllers/customization_controller.d.ts +54 -0
  138. package/dist/types/src/controllers/data.d.ts +141 -0
  139. package/dist/types/src/controllers/data_driver.d.ts +168 -0
  140. package/dist/types/src/controllers/database_admin.d.ts +11 -0
  141. package/dist/types/src/controllers/dialogs_controller.d.ts +36 -0
  142. package/dist/types/src/controllers/effective_role.d.ts +4 -0
  143. package/dist/types/src/controllers/index.d.ts +17 -0
  144. package/dist/types/src/controllers/local_config_persistence.d.ts +20 -0
  145. package/dist/types/src/controllers/navigation.d.ts +213 -0
  146. package/dist/types/src/controllers/registry.d.ts +51 -0
  147. package/dist/types/src/controllers/side_dialogs_controller.d.ts +67 -0
  148. package/dist/types/src/controllers/side_entity_controller.d.ts +89 -0
  149. package/dist/types/src/controllers/snackbar.d.ts +24 -0
  150. package/dist/types/src/controllers/storage.d.ts +173 -0
  151. package/dist/types/src/index.d.ts +4 -0
  152. package/dist/types/src/rebase_context.d.ts +101 -0
  153. package/dist/types/src/types/backend.d.ts +533 -0
  154. package/dist/types/src/types/builders.d.ts +14 -0
  155. package/dist/types/src/types/chips.d.ts +5 -0
  156. package/dist/types/src/types/collections.d.ts +812 -0
  157. package/dist/types/src/types/data_source.d.ts +64 -0
  158. package/dist/types/src/types/entities.d.ts +145 -0
  159. package/dist/types/src/types/entity_actions.d.ts +98 -0
  160. package/dist/types/src/types/entity_callbacks.d.ts +173 -0
  161. package/dist/types/src/types/entity_link_builder.d.ts +7 -0
  162. package/dist/types/src/types/entity_overrides.d.ts +9 -0
  163. package/dist/types/src/types/entity_views.d.ts +61 -0
  164. package/dist/types/src/types/export_import.d.ts +21 -0
  165. package/dist/types/src/types/index.d.ts +22 -0
  166. package/dist/types/src/types/locales.d.ts +4 -0
  167. package/dist/types/src/types/modify_collections.d.ts +5 -0
  168. package/dist/types/src/types/plugins.d.ts +225 -0
  169. package/dist/types/src/types/properties.d.ts +1091 -0
  170. package/dist/types/src/types/property_config.d.ts +70 -0
  171. package/dist/types/src/types/relations.d.ts +336 -0
  172. package/dist/types/src/types/slots.d.ts +228 -0
  173. package/dist/types/src/types/translations.d.ts +826 -0
  174. package/dist/types/src/types/user_management_delegate.d.ts +120 -0
  175. package/dist/types/src/types/websockets.d.ts +78 -0
  176. package/dist/types/src/users/index.d.ts +2 -0
  177. package/dist/types/src/users/roles.d.ts +22 -0
  178. package/dist/types/src/users/user.d.ts +46 -0
  179. package/history_diff.log +385 -0
  180. package/jest.config.cjs +16 -0
  181. package/package.json +86 -0
  182. package/scratch.ts +8 -0
  183. package/src/api/ast-schema-editor.ts +289 -0
  184. package/src/api/collections_for_test/callbacks_test_collection.ts +57 -0
  185. package/src/api/errors.ts +155 -0
  186. package/src/api/graphql/graphql-schema-generator.ts +334 -0
  187. package/src/api/graphql/index.ts +2 -0
  188. package/src/api/index.ts +11 -0
  189. package/src/api/openapi-generator.ts +160 -0
  190. package/src/api/rest/api-generator.ts +466 -0
  191. package/src/api/rest/index.ts +2 -0
  192. package/src/api/rest/query-parser.ts +155 -0
  193. package/src/api/schema-editor-routes.ts +39 -0
  194. package/src/api/server.ts +245 -0
  195. package/src/api/types.ts +90 -0
  196. package/src/auth/admin-routes.ts +488 -0
  197. package/src/auth/google-oauth.ts +60 -0
  198. package/src/auth/index.ts +21 -0
  199. package/src/auth/interfaces.ts +316 -0
  200. package/src/auth/jwt.ts +164 -0
  201. package/src/auth/middleware.ts +235 -0
  202. package/src/auth/password.ts +75 -0
  203. package/src/auth/rate-limiter.ts +129 -0
  204. package/src/auth/routes.ts +730 -0
  205. package/src/bootstrappers/index.ts +1 -0
  206. package/src/collections/BackendCollectionRegistry.ts +20 -0
  207. package/src/collections/loader.ts +49 -0
  208. package/src/db/interfaces.ts +60 -0
  209. package/src/email/index.ts +17 -0
  210. package/src/email/smtp-email-service.ts +88 -0
  211. package/src/email/templates.ts +301 -0
  212. package/src/email/types.ts +112 -0
  213. package/src/functions/function-loader.ts +91 -0
  214. package/src/functions/function-routes.ts +31 -0
  215. package/src/functions/index.ts +3 -0
  216. package/src/history/history-routes.ts +128 -0
  217. package/src/history/index.ts +2 -0
  218. package/src/index.ts +56 -0
  219. package/src/init.ts +309 -0
  220. package/src/serve-spa.ts +81 -0
  221. package/src/services/driver-registry.ts +182 -0
  222. package/src/storage/LocalStorageController.ts +368 -0
  223. package/src/storage/S3StorageController.ts +295 -0
  224. package/src/storage/index.ts +32 -0
  225. package/src/storage/routes.ts +247 -0
  226. package/src/storage/storage-registry.ts +187 -0
  227. package/src/storage/types.ts +122 -0
  228. package/src/types/index.ts +27 -0
  229. package/src/utils/logging.ts +35 -0
  230. package/src/utils/sql.ts +38 -0
  231. package/test/admin-routes.test.ts +591 -0
  232. package/test/api-generator.test.ts +458 -0
  233. package/test/ast-schema-editor.test.ts +61 -0
  234. package/test/auth-middleware-hono.test.ts +321 -0
  235. package/test/auth-routes.test.ts +868 -0
  236. package/test/driver-registry.test.ts +280 -0
  237. package/test/errors-hono.test.ts +133 -0
  238. package/test/errors.test.ts +150 -0
  239. package/test/jwt-security.test.ts +173 -0
  240. package/test/jwt.test.ts +311 -0
  241. package/test/middleware.test.ts +295 -0
  242. package/test/password.test.ts +165 -0
  243. package/test/query-parser.test.ts +258 -0
  244. package/test/rate-limiter.test.ts +102 -0
  245. package/test/storage-local.test.ts +278 -0
  246. package/test/storage-registry.test.ts +280 -0
  247. package/test/storage-routes.test.ts +218 -0
  248. package/test/storage-s3.test.ts +301 -0
  249. package/test-ast.ts +28 -0
  250. package/test_output.txt +1133 -0
  251. package/tsconfig.json +49 -0
  252. package/tsconfig.prod.json +20 -0
  253. package/vite.config.ts +78 -0
  254. package/vite.config.ts.timestamp-1775065397568-8a853255edf6e.mjs +46 -0
@@ -0,0 +1,75 @@
1
+ import { scrypt, randomBytes, timingSafeEqual } from "crypto";
2
+ import { promisify } from "util";
3
+
4
+ const scryptAsync = promisify(scrypt);
5
+
6
+ // Scrypt parameters (recommended values for 2024+)
7
+ const SALT_LENGTH = 32;
8
+ const KEY_LENGTH = 64;
9
+ const SCRYPT_PARAMS = { N: 16384, r: 8, p: 1 };
10
+
11
+ export interface PasswordValidationResult {
12
+ valid: boolean;
13
+ errors: string[];
14
+ }
15
+
16
+ /**
17
+ * Password requirements:
18
+ * - Minimum 8 characters
19
+ * - At least 1 uppercase letter
20
+ * - At least 1 lowercase letter
21
+ * - At least 1 number
22
+ */
23
+ export function validatePasswordStrength(password: string): PasswordValidationResult {
24
+ const errors: string[] = [];
25
+
26
+ if (password.length < 8) {
27
+ errors.push("Password must be at least 8 characters long");
28
+ }
29
+
30
+ if (!/[A-Z]/.test(password)) {
31
+ errors.push("Password must contain at least one uppercase letter");
32
+ }
33
+
34
+ if (!/[a-z]/.test(password)) {
35
+ errors.push("Password must contain at least one lowercase letter");
36
+ }
37
+
38
+ if (!/[0-9]/.test(password)) {
39
+ errors.push("Password must contain at least one number");
40
+ }
41
+
42
+ return {
43
+ valid: errors.length === 0,
44
+ errors
45
+ };
46
+ }
47
+
48
+ /**
49
+ * Hash a password using Node's built-in scrypt
50
+ * Returns format: salt:hash (both hex encoded)
51
+ */
52
+ export async function hashPassword(password: string): Promise<string> {
53
+ const salt = randomBytes(SALT_LENGTH);
54
+ const derivedKey = await scryptAsync(password, salt, KEY_LENGTH) as Buffer;
55
+ return `${salt.toString("hex")}:${derivedKey.toString("hex")}`;
56
+ }
57
+
58
+ /**
59
+ * Verify a password against a scrypt hash
60
+ * Expects format: salt:hash (both hex encoded)
61
+ */
62
+ export async function verifyPassword(password: string, storedHash: string): Promise<boolean> {
63
+ const [saltHex, hashHex] = storedHash.split(":");
64
+ if (!saltHex || !hashHex) {
65
+ return false;
66
+ }
67
+
68
+ const salt = Buffer.from(saltHex, "hex");
69
+ const storedKey = Buffer.from(hashHex, "hex");
70
+
71
+ const derivedKey = await scryptAsync(password, salt, KEY_LENGTH) as Buffer;
72
+
73
+ // Use timing-safe comparison to prevent timing attacks
74
+ return timingSafeEqual(derivedKey, storedKey);
75
+ }
@@ -0,0 +1,129 @@
1
+ import { MiddlewareHandler } from "hono";
2
+ import { HonoEnv } from "../api/types";
3
+
4
+ /**
5
+ * In-memory sliding-window rate limiter for Hono.
6
+ *
7
+ * Suitable for single-instance and moderate-scale deployments.
8
+ * For multi-instance setups, consider a shared store
9
+ * (e.g. PostgreSQL-backed counters or an external rate-limit service).
10
+ */
11
+
12
+ interface RateLimitEntry {
13
+ timestamps: number[];
14
+ }
15
+
16
+ interface RateLimiterOptions {
17
+ /** Time window in milliseconds (default: 15 minutes) */
18
+ windowMs?: number;
19
+ /** Maximum requests per window (default: 100) */
20
+ limit?: number;
21
+ /** Key generator function. Defaults to IP-based keying. */
22
+ keyGenerator?: (c: Parameters<MiddlewareHandler<HonoEnv>>[0]) => string;
23
+ /** Custom message for rate limit responses */
24
+ message?: string;
25
+ }
26
+
27
+ /**
28
+ * Create a rate-limiting middleware.
29
+ *
30
+ * Uses a sliding window algorithm: only timestamps within the last
31
+ * `windowMs` milliseconds are counted. Old entries are garbage-collected
32
+ * every `windowMs` to prevent unbounded memory growth.
33
+ */
34
+ export function createRateLimiter(options: RateLimiterOptions = {}): MiddlewareHandler<HonoEnv> {
35
+ const {
36
+ windowMs = 15 * 60 * 1000,
37
+ limit = 100,
38
+ keyGenerator = defaultKeyGenerator,
39
+ message = "Too many requests, please try again later."
40
+ } = options;
41
+
42
+ const store = new Map<string, RateLimitEntry>();
43
+
44
+ // Periodic cleanup to prevent memory leak from expired entries
45
+ const cleanupInterval = setInterval(() => {
46
+ const now = Date.now();
47
+ for (const [key, entry] of store.entries()) {
48
+ entry.timestamps = entry.timestamps.filter(t => now - t < windowMs);
49
+ if (entry.timestamps.length === 0) {
50
+ store.delete(key);
51
+ }
52
+ }
53
+ }, windowMs);
54
+
55
+ // Allow the Node.js process to exit even if the interval is still running
56
+ if (cleanupInterval.unref) {
57
+ cleanupInterval.unref();
58
+ }
59
+
60
+ return async (c, next) => {
61
+ const key = keyGenerator(c);
62
+ const now = Date.now();
63
+
64
+ let entry = store.get(key);
65
+ if (!entry) {
66
+ entry = { timestamps: [] };
67
+ store.set(key, entry);
68
+ }
69
+
70
+ // Remove timestamps outside the current window
71
+ entry.timestamps = entry.timestamps.filter(t => now - t < windowMs);
72
+
73
+ if (entry.timestamps.length >= limit) {
74
+ const retryAfterMs = entry.timestamps[0] + windowMs - now;
75
+ const retryAfterSec = Math.ceil(retryAfterMs / 1000);
76
+
77
+ c.header("Retry-After", String(retryAfterSec));
78
+ c.header("X-RateLimit-Limit", String(limit));
79
+ c.header("X-RateLimit-Remaining", "0");
80
+ c.header("X-RateLimit-Reset", String(Math.ceil((now + retryAfterMs) / 1000)));
81
+
82
+ return c.json({
83
+ error: {
84
+ message,
85
+ code: "RATE_LIMITED"
86
+ }
87
+ }, 429);
88
+ }
89
+
90
+ entry.timestamps.push(now);
91
+
92
+ // Set rate limit headers
93
+ c.header("X-RateLimit-Limit", String(limit));
94
+ c.header("X-RateLimit-Remaining", String(limit - entry.timestamps.length));
95
+
96
+ return next();
97
+ };
98
+ }
99
+
100
+ /**
101
+ * Default key generator: extract client IP from standard headers.
102
+ */
103
+ function defaultKeyGenerator(c: Parameters<MiddlewareHandler<HonoEnv>>[0]): string {
104
+ return (
105
+ c.req.header("x-forwarded-for")?.split(",")[0]?.trim() ||
106
+ c.req.header("x-real-ip") ||
107
+ "unknown"
108
+ );
109
+ }
110
+
111
+ /**
112
+ * Pre-configured rate limiter for general auth endpoints (login, register).
113
+ * 20 requests per 15 minutes per IP.
114
+ */
115
+ export const defaultAuthLimiter = createRateLimiter({
116
+ windowMs: 15 * 60 * 1000,
117
+ limit: 20,
118
+ message: "Too many authentication attempts, please try again later."
119
+ });
120
+
121
+ /**
122
+ * Pre-configured strict rate limiter for sensitive endpoints (password reset, verification).
123
+ * 5 requests per 15 minutes per IP.
124
+ */
125
+ export const strictAuthLimiter = createRateLimiter({
126
+ windowMs: 15 * 60 * 1000,
127
+ limit: 5,
128
+ message: "Too many requests to this sensitive endpoint, please try again later."
129
+ });