@getstrata/core 0.5.55 → 0.5.57
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/README.md +3 -1
- package/dist/{domain/abilities.d.ts → core/auth/abilityCatalog.d.ts} +9 -1
- package/dist/core/auth/accessControl.d.ts +1 -1
- package/dist/core/auth/membershipContext.d.ts +6 -4
- package/dist/core/auth/membershipService.d.ts +5 -6
- package/dist/core/contracts/authUserDirectory.d.ts +11 -0
- package/dist/core/contracts/membership.d.ts +20 -0
- package/dist/core/http/clientIp.d.ts +3 -0
- package/dist/core/jobs/dispatchWebhookJob.d.ts +2 -0
- package/dist/core/media/imageTransform.d.ts +13 -0
- package/dist/core/scheduler/osCron.d.ts +14 -0
- package/dist/core/tenant/tenancyConfig.d.ts +5 -0
- package/dist/core/tenant/tenantMiddleware.d.ts +1 -1
- package/dist/core/terminal/runShell.d.ts +6 -0
- package/dist/core/view/assertEtaHtmlSource.d.ts +5 -0
- package/dist/core/view/etaViewEngine.d.ts +4 -0
- package/dist/entries/audit/exportAuditLogs.js +2 -2
- package/dist/entries/audit/siemFormatter.js +2 -2
- package/dist/entries/auth/accessControl.js +4 -4
- package/dist/entries/auth/membershipMiddleware.js +21 -161
- package/dist/entries/auth/membershipScope.js +26 -166
- package/dist/entries/auth/membershipService.js +21 -161
- package/dist/entries/auth/oauth/providers.js +2 -2
- package/dist/entries/auth/password.js +2 -2
- package/dist/entries/auth/policy.js +2 -2
- package/dist/entries/auth/scimAuthMiddleware.js +22 -4
- package/dist/entries/auth/sessionCookie.js +4 -4
- package/dist/entries/auth/sessionGuard.js +12 -349
- package/dist/entries/auth/tokenHash.js +2 -2
- package/dist/entries/config/envSchema.js +2 -2
- package/dist/entries/contracts/container.js +2 -2
- package/dist/entries/contracts/di.js +2 -2
- package/dist/entries/contracts/serviceTokens.js +6 -6
- package/dist/entries/crypto/fieldEncryption.js +8 -8
- package/dist/entries/crypto/mfaSecret.js +2 -2
- package/dist/entries/database/errors.js +2 -2
- package/dist/entries/database/migrations.js +8 -8
- package/dist/entries/database/model.js +5 -5
- package/dist/entries/database/query.js +19 -19
- package/dist/entries/database/relationships.js +13 -13
- package/dist/entries/database/schema.js +13 -13
- package/dist/entries/database/seeders.js +2 -2
- package/dist/entries/facades.js +8 -8
- package/dist/entries/http/authMiddleware.js +2 -2
- package/dist/entries/http/bodySizeLimitMiddleware.js +2 -2
- package/dist/entries/http/clientIp.js +19 -0
- package/dist/entries/http/cookies.js +2 -2
- package/dist/entries/http/csrfMiddleware.js +2 -1
- package/dist/entries/http/csrfProtection.js +2 -2
- package/dist/entries/http/csrfToken.js +8 -7
- package/dist/entries/http/etag.js +8 -8
- package/dist/entries/http/flashSession.js +4 -4
- package/dist/entries/http/formRequest.js +2 -2
- package/dist/entries/http/loginThrottleMiddleware.js +20 -3
- package/dist/entries/http/memoryThrottleMiddleware.js +16 -1
- package/dist/entries/http/metricsMiddleware.js +2 -2
- package/dist/entries/http/pagination.js +4 -4
- package/dist/entries/http/parseFormBody.js +2 -2
- package/dist/entries/http/parseMultipartUpload.js +2 -2
- package/dist/entries/http/resources.js +2 -2
- package/dist/entries/http/response.js +214 -395
- package/dist/entries/http/scimThrottleMiddleware.js +40 -1
- package/dist/entries/http/securedRouteModelBinding.js +2 -2
- package/dist/entries/http/throttleMiddleware.js +20 -3
- package/dist/entries/http/validation.js +13 -13
- package/dist/entries/http/webErrorResponse.js +212 -393
- package/dist/entries/jobs/dispatchWebhookJob.js +111 -5
- package/dist/entries/lifecycle/gracefulShutdown.js +3 -3
- package/dist/entries/logging/logger.js +2 -2
- package/dist/entries/logging/requestLoggingMiddleware.js +16 -1
- package/dist/entries/mail/mailer.js +6 -6
- package/dist/entries/mail/markdownMail.js +3 -3
- package/dist/entries/mail/markdownMailable.js +2 -2
- package/dist/entries/media/imageTransform.js +40 -0
- package/dist/entries/metrics/prometheus.js +2 -2
- package/dist/entries/openapi/generator.js +2 -2
- package/dist/entries/queue/createAppQueue.js +4 -4
- package/dist/entries/queue/publicQueue.js +10 -10
- package/dist/entries/queue/queueMetrics.js +2 -2
- package/dist/entries/queue/redisQueue.js +7 -7
- package/dist/entries/queue.js +3 -3
- package/dist/entries/scheduler/osCron.js +27 -0
- package/dist/entries/scheduler/schedule.js +2 -2
- package/dist/entries/security/oauthState.js +3 -3
- package/dist/entries/security/publicReads.js +2 -2
- package/dist/entries/security/safeFetch.js +2 -2
- package/dist/entries/security/safeUrl.js +5 -5
- package/dist/entries/security/scimTenantTokens.js +3 -6
- package/dist/entries/security/totp.js +2 -2
- package/dist/entries/storage/storage.js +7 -7
- package/dist/entries/tenant/tenancyConfig.js +12 -0
- package/dist/entries/tenant/tenantDatabaseScope.js +13 -2
- package/dist/entries/terminal/runShell.js +18 -0
- package/dist/entries/validation/rules.js +12 -12
- package/dist/entries/view.js +212 -393
- package/dist/framework/public-api.d.ts +4 -1
- package/dist/index.js +2591 -2686
- package/package.json +27 -2
- package/dist/config/database.d.ts +0 -10
- package/dist/db/connection/createConnection.d.ts +0 -6
- package/dist/db/connection/index.d.ts +0 -11
- package/dist/domain/auth.d.ts +0 -4
- package/dist/domain/scim.d.ts +0 -9
- package/dist/modules/organization/memberRepository.d.ts +0 -14
- package/dist/modules/organization/memberTypes.d.ts +0 -9
- package/dist/modules/user/apiTokenRepository.d.ts +0 -8
- package/dist/modules/user/apiTokenTable.d.ts +0 -3
- package/dist/modules/user/authService.d.ts +0 -23
- package/dist/modules/user/notificationRepository.d.ts +0 -6
- package/dist/modules/user/notificationService.d.ts +0 -25
- package/dist/modules/user/notificationTable.d.ts +0 -3
- package/dist/modules/user/notificationTypes.d.ts +0 -12
- package/dist/modules/user/oauthIdentityRepository.d.ts +0 -9
- package/dist/modules/user/provider.d.ts +0 -11
- package/dist/modules/user/repository.d.ts +0 -13
- package/dist/modules/user/table.d.ts +0 -3
- package/dist/modules/user/tokenService.d.ts +0 -29
- package/dist/modules/user/types.d.ts +0 -46
|
@@ -1,10 +1,44 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
// ../../src/core/http/scimThrottleMiddleware.ts
|
|
3
3
|
var {RedisClient } = globalThis.Bun;
|
|
4
|
+
|
|
5
|
+
// ../../src/core/http/clientIp.ts
|
|
6
|
+
function trustForwardedFor(env = process.env) {
|
|
7
|
+
return (env.TRUST_FORWARDED_FOR ?? "false") === "true";
|
|
8
|
+
}
|
|
9
|
+
function readClientIp(request, env = process.env) {
|
|
10
|
+
if (!trustForwardedFor(env)) {
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
const forwarded = request.headers.get("x-forwarded-for")?.split(",")[0]?.trim();
|
|
14
|
+
if (forwarded) {
|
|
15
|
+
return forwarded;
|
|
16
|
+
}
|
|
17
|
+
return request.headers.get("x-real-ip")?.trim() || undefined;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// ../../src/core/http/scimThrottleMiddleware.ts
|
|
21
|
+
var memoryBuckets = new Map;
|
|
22
|
+
function resolveScimIdentity(request) {
|
|
23
|
+
return request.headers.get("authorization")?.slice("Bearer ".length, "Bearer ".length + 16) ?? readClientIp(request) ?? "unknown";
|
|
24
|
+
}
|
|
25
|
+
function throttleFromMemory(key, maxAttempts, decaySeconds) {
|
|
26
|
+
const now = Date.now();
|
|
27
|
+
const existing = memoryBuckets.get(key);
|
|
28
|
+
if (!existing || existing.resetAt <= now) {
|
|
29
|
+
memoryBuckets.set(key, { count: 1, resetAt: now + decaySeconds * 1000 });
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
existing.count += 1;
|
|
33
|
+
if (existing.count > maxAttempts) {
|
|
34
|
+
return Response.json({ error: "Too many SCIM requests." }, { status: 429, headers: { "retry-after": String(decaySeconds) } });
|
|
35
|
+
}
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
4
38
|
function createScimThrottleMiddleware(options) {
|
|
5
39
|
const client = options.redisUrl ? new RedisClient(options.redisUrl) : null;
|
|
6
40
|
return async (request, next) => {
|
|
7
|
-
const identity =
|
|
41
|
+
const identity = resolveScimIdentity(request);
|
|
8
42
|
const key = `workhub:scim-throttle:${identity}`;
|
|
9
43
|
if (client) {
|
|
10
44
|
const attempts = Number(await client.incr(key));
|
|
@@ -14,6 +48,11 @@ function createScimThrottleMiddleware(options) {
|
|
|
14
48
|
if (attempts > options.maxAttempts) {
|
|
15
49
|
return Response.json({ error: "Too many SCIM requests." }, { status: 429, headers: { "retry-after": String(options.decaySeconds) } });
|
|
16
50
|
}
|
|
51
|
+
return await next();
|
|
52
|
+
}
|
|
53
|
+
const limited = throttleFromMemory(key, options.maxAttempts, options.decaySeconds);
|
|
54
|
+
if (limited) {
|
|
55
|
+
return limited;
|
|
17
56
|
}
|
|
18
57
|
return await next();
|
|
19
58
|
};
|
|
@@ -3,6 +3,23 @@
|
|
|
3
3
|
import { currentAuthUser } from "@getstrata/core/auth/authContext";
|
|
4
4
|
import { currentTenant, rateLimitMultiplierForPlan } from "@getstrata/core/tenant/tenantContext";
|
|
5
5
|
var {RedisClient } = globalThis.Bun;
|
|
6
|
+
|
|
7
|
+
// ../../src/core/http/clientIp.ts
|
|
8
|
+
function trustForwardedFor(env = process.env) {
|
|
9
|
+
return (env.TRUST_FORWARDED_FOR ?? "false") === "true";
|
|
10
|
+
}
|
|
11
|
+
function readClientIp(request, env = process.env) {
|
|
12
|
+
if (!trustForwardedFor(env)) {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
const forwarded = request.headers.get("x-forwarded-for")?.split(",")[0]?.trim();
|
|
16
|
+
if (forwarded) {
|
|
17
|
+
return forwarded;
|
|
18
|
+
}
|
|
19
|
+
return request.headers.get("x-real-ip")?.trim() || undefined;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// ../../src/core/http/throttleMiddleware.ts
|
|
6
23
|
function resolveThrottleIdentity(request) {
|
|
7
24
|
const user = currentAuthUser();
|
|
8
25
|
if (user?.tokenId !== undefined) {
|
|
@@ -11,7 +28,7 @@ function resolveThrottleIdentity(request) {
|
|
|
11
28
|
if (user) {
|
|
12
29
|
return `user:${user.id}`;
|
|
13
30
|
}
|
|
14
|
-
return request
|
|
31
|
+
return readClientIp(request) ?? "unknown";
|
|
15
32
|
}
|
|
16
33
|
function createThrottleMiddleware(options) {
|
|
17
34
|
const client = new RedisClient(options.redisUrl);
|
|
@@ -37,6 +54,6 @@ function createThrottleMiddleware(options) {
|
|
|
37
54
|
};
|
|
38
55
|
}
|
|
39
56
|
export {
|
|
40
|
-
|
|
41
|
-
|
|
57
|
+
createThrottleMiddleware,
|
|
58
|
+
resolveThrottleIdentity
|
|
42
59
|
};
|
|
@@ -128,18 +128,18 @@ function parsePositiveIntParam(value, name = "id") {
|
|
|
128
128
|
return parsed;
|
|
129
129
|
}
|
|
130
130
|
export {
|
|
131
|
-
|
|
132
|
-
readRequiredPositiveInt,
|
|
133
|
-
readRequiredEnum,
|
|
134
|
-
readOptionalString,
|
|
135
|
-
readOptionalPositiveInt,
|
|
136
|
-
readOptionalEnum,
|
|
137
|
-
parsePositiveIntParam,
|
|
138
|
-
parseOptionalPositiveIntQueryParam,
|
|
139
|
-
parseOptionalEnumQueryParam,
|
|
140
|
-
parseOptionalBooleanQueryParam,
|
|
141
|
-
parseJsonBody,
|
|
142
|
-
getQueryParams,
|
|
131
|
+
buildRequestCacheKey,
|
|
143
132
|
expectObject,
|
|
144
|
-
|
|
133
|
+
getQueryParams,
|
|
134
|
+
parseJsonBody,
|
|
135
|
+
parseOptionalBooleanQueryParam,
|
|
136
|
+
parseOptionalEnumQueryParam,
|
|
137
|
+
parseOptionalPositiveIntQueryParam,
|
|
138
|
+
parsePositiveIntParam,
|
|
139
|
+
readOptionalEnum,
|
|
140
|
+
readOptionalPositiveInt,
|
|
141
|
+
readOptionalString,
|
|
142
|
+
readRequiredEnum,
|
|
143
|
+
readRequiredPositiveInt,
|
|
144
|
+
readRequiredString
|
|
145
145
|
};
|