@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.
- package/LICENSE +6 -0
- package/README.md +40 -0
- package/build-errors.txt +52 -0
- package/coverage/clover.xml +3739 -0
- package/coverage/coverage-final.json +31 -0
- package/coverage/lcov-report/base.css +224 -0
- package/coverage/lcov-report/block-navigation.js +87 -0
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/index.html +266 -0
- package/coverage/lcov-report/prettify.css +1 -0
- package/coverage/lcov-report/prettify.js +2 -0
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +210 -0
- package/coverage/lcov-report/src/api/ast-schema-editor.ts.html +952 -0
- package/coverage/lcov-report/src/api/errors.ts.html +472 -0
- package/coverage/lcov-report/src/api/graphql/graphql-schema-generator.ts.html +1069 -0
- package/coverage/lcov-report/src/api/graphql/index.html +116 -0
- package/coverage/lcov-report/src/api/index.html +176 -0
- package/coverage/lcov-report/src/api/openapi-generator.ts.html +565 -0
- package/coverage/lcov-report/src/api/rest/api-generator.ts.html +994 -0
- package/coverage/lcov-report/src/api/rest/index.html +131 -0
- package/coverage/lcov-report/src/api/rest/query-parser.ts.html +550 -0
- package/coverage/lcov-report/src/api/schema-editor-routes.ts.html +202 -0
- package/coverage/lcov-report/src/api/server.ts.html +823 -0
- package/coverage/lcov-report/src/auth/admin-routes.ts.html +973 -0
- package/coverage/lcov-report/src/auth/index.html +176 -0
- package/coverage/lcov-report/src/auth/jwt.ts.html +574 -0
- package/coverage/lcov-report/src/auth/middleware.ts.html +745 -0
- package/coverage/lcov-report/src/auth/password.ts.html +310 -0
- package/coverage/lcov-report/src/auth/services.ts.html +2074 -0
- package/coverage/lcov-report/src/collections/index.html +116 -0
- package/coverage/lcov-report/src/collections/loader.ts.html +232 -0
- package/coverage/lcov-report/src/db/auth-schema.ts.html +523 -0
- package/coverage/lcov-report/src/db/data-transformer.ts.html +1753 -0
- package/coverage/lcov-report/src/db/entityService.ts.html +700 -0
- package/coverage/lcov-report/src/db/index.html +146 -0
- package/coverage/lcov-report/src/db/services/EntityFetchService.ts.html +4048 -0
- package/coverage/lcov-report/src/db/services/EntityPersistService.ts.html +883 -0
- package/coverage/lcov-report/src/db/services/RelationService.ts.html +3121 -0
- package/coverage/lcov-report/src/db/services/entity-helpers.ts.html +442 -0
- package/coverage/lcov-report/src/db/services/index.html +176 -0
- package/coverage/lcov-report/src/db/services/index.ts.html +124 -0
- package/coverage/lcov-report/src/generate-drizzle-schema-logic.ts.html +1960 -0
- package/coverage/lcov-report/src/index.html +116 -0
- package/coverage/lcov-report/src/services/driver-registry.ts.html +631 -0
- package/coverage/lcov-report/src/services/index.html +131 -0
- package/coverage/lcov-report/src/services/postgresDataDriver.ts.html +3025 -0
- package/coverage/lcov-report/src/storage/LocalStorageController.ts.html +1189 -0
- package/coverage/lcov-report/src/storage/S3StorageController.ts.html +970 -0
- package/coverage/lcov-report/src/storage/index.html +161 -0
- package/coverage/lcov-report/src/storage/storage-registry.ts.html +646 -0
- package/coverage/lcov-report/src/storage/types.ts.html +451 -0
- package/coverage/lcov-report/src/utils/drizzle-conditions.ts.html +3082 -0
- package/coverage/lcov-report/src/utils/index.html +116 -0
- package/coverage/lcov.info +7179 -0
- package/dist/common/src/collections/CollectionRegistry.d.ts +48 -0
- package/dist/common/src/collections/index.d.ts +1 -0
- package/dist/common/src/data/buildRebaseData.d.ts +14 -0
- package/dist/common/src/index.d.ts +3 -0
- package/dist/common/src/util/builders.d.ts +57 -0
- package/dist/common/src/util/callbacks.d.ts +6 -0
- package/dist/common/src/util/collections.d.ts +11 -0
- package/dist/common/src/util/common.d.ts +2 -0
- package/dist/common/src/util/conditions.d.ts +26 -0
- package/dist/common/src/util/entities.d.ts +36 -0
- package/dist/common/src/util/enums.d.ts +3 -0
- package/dist/common/src/util/index.d.ts +16 -0
- package/dist/common/src/util/navigation_from_path.d.ts +34 -0
- package/dist/common/src/util/navigation_utils.d.ts +20 -0
- package/dist/common/src/util/parent_references_from_path.d.ts +6 -0
- package/dist/common/src/util/paths.d.ts +14 -0
- package/dist/common/src/util/permissions.d.ts +5 -0
- package/dist/common/src/util/references.d.ts +2 -0
- package/dist/common/src/util/relations.d.ts +12 -0
- package/dist/common/src/util/resolutions.d.ts +72 -0
- package/dist/common/src/util/storage.d.ts +24 -0
- package/dist/index-BeMqpmfQ.js +239 -0
- package/dist/index-BeMqpmfQ.js.map +1 -0
- package/dist/index-bl4J3lNb.js +55823 -0
- package/dist/index-bl4J3lNb.js.map +1 -0
- package/dist/index.es.js +58 -0
- package/dist/index.es.js.map +1 -0
- package/dist/index.umd.js +56062 -0
- package/dist/index.umd.js.map +1 -0
- package/dist/server-core/src/api/ast-schema-editor.d.ts +21 -0
- package/dist/server-core/src/api/collections_for_test/callbacks_test_collection.d.ts +2 -0
- package/dist/server-core/src/api/errors.d.ts +35 -0
- package/dist/server-core/src/api/graphql/graphql-schema-generator.d.ts +35 -0
- package/dist/server-core/src/api/graphql/index.d.ts +1 -0
- package/dist/server-core/src/api/index.d.ts +9 -0
- package/dist/server-core/src/api/openapi-generator.d.ts +2 -0
- package/dist/server-core/src/api/rest/api-generator.d.ts +64 -0
- package/dist/server-core/src/api/rest/index.d.ts +1 -0
- package/dist/server-core/src/api/rest/query-parser.d.ts +9 -0
- package/dist/server-core/src/api/schema-editor-routes.d.ts +3 -0
- package/dist/server-core/src/api/server.d.ts +40 -0
- package/dist/server-core/src/api/types.d.ts +90 -0
- package/dist/server-core/src/auth/admin-routes.d.ts +7 -0
- package/dist/server-core/src/auth/google-oauth.d.ts +20 -0
- package/dist/server-core/src/auth/index.d.ts +12 -0
- package/dist/server-core/src/auth/interfaces.d.ts +270 -0
- package/dist/server-core/src/auth/jwt.d.ts +42 -0
- package/dist/server-core/src/auth/middleware.d.ts +56 -0
- package/dist/server-core/src/auth/password.d.ts +22 -0
- package/dist/server-core/src/auth/rate-limiter.d.ts +31 -0
- package/dist/server-core/src/auth/routes.d.ts +17 -0
- package/dist/server-core/src/bootstrappers/index.d.ts +0 -0
- package/dist/server-core/src/collections/BackendCollectionRegistry.d.ts +13 -0
- package/dist/server-core/src/collections/loader.d.ts +5 -0
- package/dist/server-core/src/db/interfaces.d.ts +18 -0
- package/dist/server-core/src/email/index.d.ts +6 -0
- package/dist/server-core/src/email/smtp-email-service.d.ts +25 -0
- package/dist/server-core/src/email/templates.d.ts +33 -0
- package/dist/server-core/src/email/types.d.ts +110 -0
- package/dist/server-core/src/functions/function-loader.d.ts +17 -0
- package/dist/server-core/src/functions/function-routes.d.ts +10 -0
- package/dist/server-core/src/functions/index.d.ts +3 -0
- package/dist/server-core/src/history/history-routes.d.ts +23 -0
- package/dist/server-core/src/history/index.d.ts +1 -0
- package/dist/server-core/src/index.d.ts +24 -0
- package/dist/server-core/src/init.d.ts +49 -0
- package/dist/server-core/src/serve-spa.d.ts +30 -0
- package/dist/server-core/src/services/driver-registry.d.ts +78 -0
- package/dist/server-core/src/storage/LocalStorageController.d.ts +46 -0
- package/dist/server-core/src/storage/S3StorageController.d.ts +36 -0
- package/dist/server-core/src/storage/index.d.ts +18 -0
- package/dist/server-core/src/storage/routes.d.ts +38 -0
- package/dist/server-core/src/storage/storage-registry.d.ts +78 -0
- package/dist/server-core/src/storage/types.d.ts +91 -0
- package/dist/server-core/src/types/index.d.ts +11 -0
- package/dist/server-core/src/utils/logging.d.ts +9 -0
- package/dist/server-core/src/utils/sql.d.ts +27 -0
- package/dist/types/src/controllers/analytics_controller.d.ts +7 -0
- package/dist/types/src/controllers/auth.d.ts +117 -0
- package/dist/types/src/controllers/client.d.ts +58 -0
- package/dist/types/src/controllers/collection_registry.d.ts +44 -0
- package/dist/types/src/controllers/customization_controller.d.ts +54 -0
- package/dist/types/src/controllers/data.d.ts +141 -0
- package/dist/types/src/controllers/data_driver.d.ts +168 -0
- package/dist/types/src/controllers/database_admin.d.ts +11 -0
- package/dist/types/src/controllers/dialogs_controller.d.ts +36 -0
- package/dist/types/src/controllers/effective_role.d.ts +4 -0
- package/dist/types/src/controllers/index.d.ts +17 -0
- package/dist/types/src/controllers/local_config_persistence.d.ts +20 -0
- package/dist/types/src/controllers/navigation.d.ts +213 -0
- package/dist/types/src/controllers/registry.d.ts +51 -0
- package/dist/types/src/controllers/side_dialogs_controller.d.ts +67 -0
- package/dist/types/src/controllers/side_entity_controller.d.ts +89 -0
- package/dist/types/src/controllers/snackbar.d.ts +24 -0
- package/dist/types/src/controllers/storage.d.ts +173 -0
- package/dist/types/src/index.d.ts +4 -0
- package/dist/types/src/rebase_context.d.ts +101 -0
- package/dist/types/src/types/backend.d.ts +533 -0
- package/dist/types/src/types/builders.d.ts +14 -0
- package/dist/types/src/types/chips.d.ts +5 -0
- package/dist/types/src/types/collections.d.ts +812 -0
- package/dist/types/src/types/data_source.d.ts +64 -0
- package/dist/types/src/types/entities.d.ts +145 -0
- package/dist/types/src/types/entity_actions.d.ts +98 -0
- package/dist/types/src/types/entity_callbacks.d.ts +173 -0
- package/dist/types/src/types/entity_link_builder.d.ts +7 -0
- package/dist/types/src/types/entity_overrides.d.ts +9 -0
- package/dist/types/src/types/entity_views.d.ts +61 -0
- package/dist/types/src/types/export_import.d.ts +21 -0
- package/dist/types/src/types/index.d.ts +22 -0
- package/dist/types/src/types/locales.d.ts +4 -0
- package/dist/types/src/types/modify_collections.d.ts +5 -0
- package/dist/types/src/types/plugins.d.ts +225 -0
- package/dist/types/src/types/properties.d.ts +1091 -0
- package/dist/types/src/types/property_config.d.ts +70 -0
- package/dist/types/src/types/relations.d.ts +336 -0
- package/dist/types/src/types/slots.d.ts +228 -0
- package/dist/types/src/types/translations.d.ts +826 -0
- package/dist/types/src/types/user_management_delegate.d.ts +120 -0
- package/dist/types/src/types/websockets.d.ts +78 -0
- package/dist/types/src/users/index.d.ts +2 -0
- package/dist/types/src/users/roles.d.ts +22 -0
- package/dist/types/src/users/user.d.ts +46 -0
- package/history_diff.log +385 -0
- package/jest.config.cjs +16 -0
- package/package.json +86 -0
- package/scratch.ts +8 -0
- package/src/api/ast-schema-editor.ts +289 -0
- package/src/api/collections_for_test/callbacks_test_collection.ts +57 -0
- package/src/api/errors.ts +155 -0
- package/src/api/graphql/graphql-schema-generator.ts +334 -0
- package/src/api/graphql/index.ts +2 -0
- package/src/api/index.ts +11 -0
- package/src/api/openapi-generator.ts +160 -0
- package/src/api/rest/api-generator.ts +466 -0
- package/src/api/rest/index.ts +2 -0
- package/src/api/rest/query-parser.ts +155 -0
- package/src/api/schema-editor-routes.ts +39 -0
- package/src/api/server.ts +245 -0
- package/src/api/types.ts +90 -0
- package/src/auth/admin-routes.ts +488 -0
- package/src/auth/google-oauth.ts +60 -0
- package/src/auth/index.ts +21 -0
- package/src/auth/interfaces.ts +316 -0
- package/src/auth/jwt.ts +164 -0
- package/src/auth/middleware.ts +235 -0
- package/src/auth/password.ts +75 -0
- package/src/auth/rate-limiter.ts +129 -0
- package/src/auth/routes.ts +730 -0
- package/src/bootstrappers/index.ts +1 -0
- package/src/collections/BackendCollectionRegistry.ts +20 -0
- package/src/collections/loader.ts +49 -0
- package/src/db/interfaces.ts +60 -0
- package/src/email/index.ts +17 -0
- package/src/email/smtp-email-service.ts +88 -0
- package/src/email/templates.ts +301 -0
- package/src/email/types.ts +112 -0
- package/src/functions/function-loader.ts +91 -0
- package/src/functions/function-routes.ts +31 -0
- package/src/functions/index.ts +3 -0
- package/src/history/history-routes.ts +128 -0
- package/src/history/index.ts +2 -0
- package/src/index.ts +56 -0
- package/src/init.ts +309 -0
- package/src/serve-spa.ts +81 -0
- package/src/services/driver-registry.ts +182 -0
- package/src/storage/LocalStorageController.ts +368 -0
- package/src/storage/S3StorageController.ts +295 -0
- package/src/storage/index.ts +32 -0
- package/src/storage/routes.ts +247 -0
- package/src/storage/storage-registry.ts +187 -0
- package/src/storage/types.ts +122 -0
- package/src/types/index.ts +27 -0
- package/src/utils/logging.ts +35 -0
- package/src/utils/sql.ts +38 -0
- package/test/admin-routes.test.ts +591 -0
- package/test/api-generator.test.ts +458 -0
- package/test/ast-schema-editor.test.ts +61 -0
- package/test/auth-middleware-hono.test.ts +321 -0
- package/test/auth-routes.test.ts +868 -0
- package/test/driver-registry.test.ts +280 -0
- package/test/errors-hono.test.ts +133 -0
- package/test/errors.test.ts +150 -0
- package/test/jwt-security.test.ts +173 -0
- package/test/jwt.test.ts +311 -0
- package/test/middleware.test.ts +295 -0
- package/test/password.test.ts +165 -0
- package/test/query-parser.test.ts +258 -0
- package/test/rate-limiter.test.ts +102 -0
- package/test/storage-local.test.ts +278 -0
- package/test/storage-registry.test.ts +280 -0
- package/test/storage-routes.test.ts +218 -0
- package/test/storage-s3.test.ts +301 -0
- package/test-ast.ts +28 -0
- package/test_output.txt +1133 -0
- package/tsconfig.json +49 -0
- package/tsconfig.prod.json +20 -0
- package/vite.config.ts +78 -0
- 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
|
+
});
|