@digilogiclabs/platform-core 1.6.0 → 1.7.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.
- package/dist/auth.d.mts +174 -1
- package/dist/auth.d.ts +174 -1
- package/dist/auth.js +108 -3
- package/dist/auth.js.map +1 -1
- package/dist/auth.mjs +101 -2
- package/dist/auth.mjs.map +1 -1
- package/dist/{index-CkyVz0hQ.d.mts → env-DerQ7Da-.d.mts} +2 -2
- package/dist/{index-CkyVz0hQ.d.ts → env-DerQ7Da-.d.ts} +2 -2
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +5 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/auth.mjs
CHANGED
|
@@ -168,7 +168,11 @@ function buildKeycloakCallbacks(config) {
|
|
|
168
168
|
* Compatible with Auth.js v5 JWT callback signature.
|
|
169
169
|
*/
|
|
170
170
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
171
|
-
async jwt({
|
|
171
|
+
async jwt({
|
|
172
|
+
token,
|
|
173
|
+
user,
|
|
174
|
+
account
|
|
175
|
+
}) {
|
|
172
176
|
if (user) {
|
|
173
177
|
token.id = token.sub ?? user.id;
|
|
174
178
|
}
|
|
@@ -729,6 +733,44 @@ function resolveIdentifier(session, clientIp) {
|
|
|
729
733
|
return { identifier: `ip:${clientIp ?? "unknown"}`, isAuthenticated: false };
|
|
730
734
|
}
|
|
731
735
|
|
|
736
|
+
// src/auth/rate-limit-store-redis.ts
|
|
737
|
+
function createRedisRateLimitStore(redis, options = {}) {
|
|
738
|
+
const prefix = options.keyPrefix ?? "";
|
|
739
|
+
return {
|
|
740
|
+
async increment(key, windowMs, now) {
|
|
741
|
+
const fullKey = `${prefix}${key}`;
|
|
742
|
+
const windowStart = now - windowMs;
|
|
743
|
+
const windowSeconds = Math.ceil(windowMs / 1e3) + 60;
|
|
744
|
+
await redis.zremrangebyscore(fullKey, 0, windowStart);
|
|
745
|
+
const current = await redis.zcard(fullKey);
|
|
746
|
+
const member = `${now}:${Math.random().toString(36).slice(2, 10)}`;
|
|
747
|
+
await redis.zadd(fullKey, now, member);
|
|
748
|
+
await redis.expire(fullKey, windowSeconds);
|
|
749
|
+
return { count: current + 1 };
|
|
750
|
+
},
|
|
751
|
+
async isBlocked(key) {
|
|
752
|
+
const fullKey = `${prefix}${key}`;
|
|
753
|
+
const value = await redis.get(fullKey);
|
|
754
|
+
if (!value) {
|
|
755
|
+
return { blocked: false, ttlMs: 0 };
|
|
756
|
+
}
|
|
757
|
+
const ttlSeconds = await redis.ttl(fullKey);
|
|
758
|
+
if (ttlSeconds <= 0) {
|
|
759
|
+
return { blocked: false, ttlMs: 0 };
|
|
760
|
+
}
|
|
761
|
+
return { blocked: true, ttlMs: ttlSeconds * 1e3 };
|
|
762
|
+
},
|
|
763
|
+
async setBlock(key, durationSeconds) {
|
|
764
|
+
const fullKey = `${prefix}${key}`;
|
|
765
|
+
await redis.setex(fullKey, durationSeconds, "1");
|
|
766
|
+
},
|
|
767
|
+
async reset(key) {
|
|
768
|
+
const fullKey = `${prefix}${key}`;
|
|
769
|
+
await redis.del(fullKey);
|
|
770
|
+
}
|
|
771
|
+
};
|
|
772
|
+
}
|
|
773
|
+
|
|
732
774
|
// src/auth/audit.ts
|
|
733
775
|
var StandardAuditActions = {
|
|
734
776
|
// Authentication
|
|
@@ -1013,6 +1055,57 @@ function buildPagination(page, limit, total) {
|
|
|
1013
1055
|
};
|
|
1014
1056
|
}
|
|
1015
1057
|
|
|
1058
|
+
// src/auth/nextjs-api.ts
|
|
1059
|
+
async function enforceRateLimit(request, operation, rule, options) {
|
|
1060
|
+
const identifier = options?.identifier ?? (options?.userId ? `user:${options.userId}` : void 0) ?? `ip:${extractClientIp((name) => request.headers.get(name))}`;
|
|
1061
|
+
const isAuthenticated = !!options?.userId;
|
|
1062
|
+
const result = await checkRateLimit(operation, identifier, rule, {
|
|
1063
|
+
...options?.rateLimitOptions,
|
|
1064
|
+
isAuthenticated
|
|
1065
|
+
});
|
|
1066
|
+
if (!result.allowed) {
|
|
1067
|
+
const headers = buildRateLimitResponseHeaders(result);
|
|
1068
|
+
return new Response(
|
|
1069
|
+
JSON.stringify({
|
|
1070
|
+
error: "Rate limit exceeded. Please try again later.",
|
|
1071
|
+
retryAfter: result.retryAfterSeconds
|
|
1072
|
+
}),
|
|
1073
|
+
{
|
|
1074
|
+
status: 429,
|
|
1075
|
+
headers: { "Content-Type": "application/json", ...headers }
|
|
1076
|
+
}
|
|
1077
|
+
);
|
|
1078
|
+
}
|
|
1079
|
+
return null;
|
|
1080
|
+
}
|
|
1081
|
+
function errorResponse(error, options) {
|
|
1082
|
+
const isDev = options?.isDevelopment ?? process.env.NODE_ENV === "development";
|
|
1083
|
+
const { status, body } = classifyError(error, isDev);
|
|
1084
|
+
return new Response(JSON.stringify(body), {
|
|
1085
|
+
status,
|
|
1086
|
+
headers: { "Content-Type": "application/json" }
|
|
1087
|
+
});
|
|
1088
|
+
}
|
|
1089
|
+
function zodErrorResponse(error) {
|
|
1090
|
+
const firstIssue = error.issues[0];
|
|
1091
|
+
const message = firstIssue ? `${firstIssue.path.join(".") || "input"}: ${firstIssue.message}` : "Validation error";
|
|
1092
|
+
return new Response(JSON.stringify({ error: message }), {
|
|
1093
|
+
status: 400,
|
|
1094
|
+
headers: { "Content-Type": "application/json" }
|
|
1095
|
+
});
|
|
1096
|
+
}
|
|
1097
|
+
function extractBearerToken(request) {
|
|
1098
|
+
const auth = request.headers.get("authorization");
|
|
1099
|
+
if (!auth?.startsWith("Bearer ")) return null;
|
|
1100
|
+
return auth.slice(7).trim() || null;
|
|
1101
|
+
}
|
|
1102
|
+
function isValidBearerToken(request, secret) {
|
|
1103
|
+
if (!secret) return false;
|
|
1104
|
+
const token = extractBearerToken(request);
|
|
1105
|
+
if (!token) return false;
|
|
1106
|
+
return constantTimeEqual(token, secret);
|
|
1107
|
+
}
|
|
1108
|
+
|
|
1016
1109
|
// src/env.ts
|
|
1017
1110
|
function getRequiredEnv(key) {
|
|
1018
1111
|
const value = process.env[key];
|
|
@@ -1141,12 +1234,16 @@ export {
|
|
|
1141
1234
|
createAuditLogger,
|
|
1142
1235
|
createFeatureFlags,
|
|
1143
1236
|
createMemoryRateLimitStore,
|
|
1237
|
+
createRedisRateLimitStore,
|
|
1144
1238
|
createSafeTextSchema,
|
|
1145
1239
|
detectStage,
|
|
1240
|
+
enforceRateLimit,
|
|
1241
|
+
errorResponse,
|
|
1146
1242
|
escapeHtml,
|
|
1147
1243
|
extractAuditIp,
|
|
1148
1244
|
extractAuditRequestId,
|
|
1149
1245
|
extractAuditUserAgent,
|
|
1246
|
+
extractBearerToken,
|
|
1150
1247
|
extractClientIp,
|
|
1151
1248
|
getBoolEnv,
|
|
1152
1249
|
getCorrelationId,
|
|
@@ -1163,6 +1260,7 @@ export {
|
|
|
1163
1260
|
isAllowlisted,
|
|
1164
1261
|
isApiError,
|
|
1165
1262
|
isTokenExpired,
|
|
1263
|
+
isValidBearerToken,
|
|
1166
1264
|
parseKeycloakRoles,
|
|
1167
1265
|
refreshKeycloakToken,
|
|
1168
1266
|
resetRateLimitForKey,
|
|
@@ -1170,6 +1268,7 @@ export {
|
|
|
1170
1268
|
resolveRateLimitIdentifier,
|
|
1171
1269
|
sanitizeApiError,
|
|
1172
1270
|
stripHtml,
|
|
1173
|
-
validateEnvVars
|
|
1271
|
+
validateEnvVars,
|
|
1272
|
+
zodErrorResponse
|
|
1174
1273
|
};
|
|
1175
1274
|
//# sourceMappingURL=auth.mjs.map
|