@digilogiclabs/platform-core 1.9.0 → 1.10.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 +115 -3
- package/dist/auth.d.ts +115 -3
- package/dist/auth.js +81 -0
- package/dist/auth.js.map +1 -1
- package/dist/auth.mjs +76 -0
- package/dist/auth.mjs.map +1 -1
- package/dist/email-templates.js +13 -6
- package/dist/email-templates.js.map +1 -1
- package/dist/email-templates.mjs +13 -6
- package/dist/email-templates.mjs.map +1 -1
- package/dist/{env-DHPZR3Lv.d.mts → env-CYKVNpLl.d.mts} +6 -0
- package/dist/{env-DHPZR3Lv.d.ts → env-CYKVNpLl.d.ts} +6 -0
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +6 -0
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/auth.mjs
CHANGED
|
@@ -562,6 +562,12 @@ var CommonRateLimits = {
|
|
|
562
562
|
limit: 10,
|
|
563
563
|
windowSeconds: 3600,
|
|
564
564
|
blockDurationSeconds: 3600
|
|
565
|
+
},
|
|
566
|
+
/** Beta code validation: 5/min with 5min block (prevents brute force guessing) */
|
|
567
|
+
betaValidation: {
|
|
568
|
+
limit: 5,
|
|
569
|
+
windowSeconds: 60,
|
|
570
|
+
blockDurationSeconds: 300
|
|
565
571
|
}
|
|
566
572
|
};
|
|
567
573
|
function createMemoryRateLimitStore() {
|
|
@@ -1105,6 +1111,71 @@ function isValidBearerToken(request, secret) {
|
|
|
1105
1111
|
if (!token) return false;
|
|
1106
1112
|
return constantTimeEqual(token, secret);
|
|
1107
1113
|
}
|
|
1114
|
+
function verifyCronAuth(request, secret) {
|
|
1115
|
+
const authHeader = request.headers.get("authorization");
|
|
1116
|
+
if (!authHeader?.startsWith("Bearer ")) {
|
|
1117
|
+
return new Response(
|
|
1118
|
+
JSON.stringify({ error: "Missing authorization" }),
|
|
1119
|
+
{ status: 401, headers: { "Content-Type": "application/json" } }
|
|
1120
|
+
);
|
|
1121
|
+
}
|
|
1122
|
+
const token = authHeader.slice(7);
|
|
1123
|
+
const expectedSecret = secret ?? process.env.CRON_SECRET;
|
|
1124
|
+
if (!expectedSecret) {
|
|
1125
|
+
console.error("[verifyCronAuth] CRON_SECRET not configured");
|
|
1126
|
+
return new Response(
|
|
1127
|
+
JSON.stringify({ error: "Server configuration error" }),
|
|
1128
|
+
{ status: 500, headers: { "Content-Type": "application/json" } }
|
|
1129
|
+
);
|
|
1130
|
+
}
|
|
1131
|
+
if (!constantTimeEqual(token, expectedSecret)) {
|
|
1132
|
+
return new Response(
|
|
1133
|
+
JSON.stringify({ error: "Invalid authorization" }),
|
|
1134
|
+
{ status: 401, headers: { "Content-Type": "application/json" } }
|
|
1135
|
+
);
|
|
1136
|
+
}
|
|
1137
|
+
return null;
|
|
1138
|
+
}
|
|
1139
|
+
function getClientIp(request) {
|
|
1140
|
+
return request.headers.get("cf-connecting-ip") || request.headers.get("x-real-ip") || request.headers.get("x-forwarded-for")?.split(",")[0]?.trim() || "unknown";
|
|
1141
|
+
}
|
|
1142
|
+
function rateLimitResponse(result) {
|
|
1143
|
+
const retryAfter = Math.ceil(result.resetMs / 1e3);
|
|
1144
|
+
const resetTimestamp = Math.ceil(Date.now() / 1e3 + result.resetMs / 1e3);
|
|
1145
|
+
return new Response(
|
|
1146
|
+
JSON.stringify({ error: "Too many requests", retryAfter }),
|
|
1147
|
+
{
|
|
1148
|
+
status: 429,
|
|
1149
|
+
headers: {
|
|
1150
|
+
"Content-Type": "application/json",
|
|
1151
|
+
"X-RateLimit-Limit": String(result.limit),
|
|
1152
|
+
"X-RateLimit-Remaining": "0",
|
|
1153
|
+
"X-RateLimit-Reset": String(resetTimestamp),
|
|
1154
|
+
"Retry-After": String(retryAfter)
|
|
1155
|
+
}
|
|
1156
|
+
}
|
|
1157
|
+
);
|
|
1158
|
+
}
|
|
1159
|
+
function addRateLimitHeaders(response, result) {
|
|
1160
|
+
const resetTimestamp = Math.ceil(Date.now() / 1e3 + result.resetMs / 1e3);
|
|
1161
|
+
response.headers.set("X-RateLimit-Limit", String(result.limit));
|
|
1162
|
+
response.headers.set("X-RateLimit-Remaining", String(result.remaining));
|
|
1163
|
+
response.headers.set("X-RateLimit-Reset", String(resetTimestamp));
|
|
1164
|
+
return response;
|
|
1165
|
+
}
|
|
1166
|
+
function safeValidate(schema, data) {
|
|
1167
|
+
const result = schema.safeParse(data);
|
|
1168
|
+
if (result.success) {
|
|
1169
|
+
return { success: true, data: result.data };
|
|
1170
|
+
}
|
|
1171
|
+
return {
|
|
1172
|
+
success: false,
|
|
1173
|
+
errors: (result.error?.issues || []).map((issue) => ({
|
|
1174
|
+
field: issue.path.join("."),
|
|
1175
|
+
message: issue.message
|
|
1176
|
+
}))
|
|
1177
|
+
};
|
|
1178
|
+
}
|
|
1108
1179
|
|
|
1109
1180
|
// src/auth/beta-client.ts
|
|
1110
1181
|
var DEFAULT_CONFIG = {
|
|
@@ -1322,6 +1393,7 @@ export {
|
|
|
1322
1393
|
StandardAuditActions,
|
|
1323
1394
|
StandardRateLimitPresets,
|
|
1324
1395
|
WrapperPresets,
|
|
1396
|
+
addRateLimitHeaders,
|
|
1325
1397
|
buildAllowlist,
|
|
1326
1398
|
buildAuthCookies,
|
|
1327
1399
|
buildErrorBody,
|
|
@@ -1356,6 +1428,7 @@ export {
|
|
|
1356
1428
|
extractClientIp,
|
|
1357
1429
|
fetchBetaSettings,
|
|
1358
1430
|
getBoolEnv,
|
|
1431
|
+
getClientIp,
|
|
1359
1432
|
getCorrelationId,
|
|
1360
1433
|
getEndSessionEndpoint,
|
|
1361
1434
|
getEnvSummary,
|
|
@@ -1373,15 +1446,18 @@ export {
|
|
|
1373
1446
|
isTokenExpired,
|
|
1374
1447
|
isValidBearerToken,
|
|
1375
1448
|
parseKeycloakRoles,
|
|
1449
|
+
rateLimitResponse,
|
|
1376
1450
|
refreshKeycloakToken,
|
|
1377
1451
|
resetRateLimitForKey,
|
|
1378
1452
|
resolveIdentifier,
|
|
1379
1453
|
resolveRateLimitIdentifier,
|
|
1454
|
+
safeValidate,
|
|
1380
1455
|
sanitizeApiError,
|
|
1381
1456
|
storeBetaCode,
|
|
1382
1457
|
stripHtml,
|
|
1383
1458
|
validateBetaCode,
|
|
1384
1459
|
validateEnvVars,
|
|
1460
|
+
verifyCronAuth,
|
|
1385
1461
|
zodErrorResponse
|
|
1386
1462
|
};
|
|
1387
1463
|
//# sourceMappingURL=auth.mjs.map
|