@digilogiclabs/platform-core 1.5.1 → 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 +110 -1047
- package/dist/auth.d.ts +110 -1047
- package/dist/auth.js +406 -6
- package/dist/auth.js.map +1 -1
- package/dist/auth.mjs +379 -5
- package/dist/auth.mjs.map +1 -1
- package/dist/env-DerQ7Da-.d.mts +1367 -0
- package/dist/env-DerQ7Da-.d.ts +1367 -0
- package/dist/index.d.mts +2 -257
- package/dist/index.d.ts +2 -257
- package/dist/index.js +94 -95
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +94 -95
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/auth.mjs
CHANGED
|
@@ -167,6 +167,7 @@ function buildKeycloakCallbacks(config) {
|
|
|
167
167
|
*
|
|
168
168
|
* Compatible with Auth.js v5 JWT callback signature.
|
|
169
169
|
*/
|
|
170
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
170
171
|
async jwt({
|
|
171
172
|
token,
|
|
172
173
|
user,
|
|
@@ -217,10 +218,8 @@ function buildKeycloakCallbacks(config) {
|
|
|
217
218
|
*
|
|
218
219
|
* Compatible with Auth.js v5 session callback signature.
|
|
219
220
|
*/
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
token
|
|
223
|
-
}) {
|
|
221
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
222
|
+
async session({ session, token }) {
|
|
224
223
|
const user = session.user;
|
|
225
224
|
if (user) {
|
|
226
225
|
user.id = token.id || token.sub;
|
|
@@ -344,9 +343,53 @@ var WrapperPresets = {
|
|
|
344
343
|
import { z } from "zod";
|
|
345
344
|
|
|
346
345
|
// src/security.ts
|
|
346
|
+
import { timingSafeEqual } from "crypto";
|
|
347
347
|
var URL_PROTOCOL_PATTERN = /(https?:\/\/|ftp:\/\/|www\.)\S+/i;
|
|
348
348
|
var URL_DOMAIN_PATTERN = /\b[\w.-]+\.(com|net|org|io|co|dev|app|xyz|info|biz|me|us|uk|edu|gov)\b/i;
|
|
349
349
|
var HTML_TAG_PATTERN = /<[^>]*>/;
|
|
350
|
+
function escapeHtml(str) {
|
|
351
|
+
return str.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
352
|
+
}
|
|
353
|
+
function containsUrls(str) {
|
|
354
|
+
return URL_PROTOCOL_PATTERN.test(str) || URL_DOMAIN_PATTERN.test(str);
|
|
355
|
+
}
|
|
356
|
+
function containsHtml(str) {
|
|
357
|
+
return HTML_TAG_PATTERN.test(str);
|
|
358
|
+
}
|
|
359
|
+
function stripHtml(str) {
|
|
360
|
+
return str.replace(/<[^>]*>/g, "");
|
|
361
|
+
}
|
|
362
|
+
function constantTimeEqual(a, b) {
|
|
363
|
+
try {
|
|
364
|
+
const aBuf = Buffer.from(a, "utf-8");
|
|
365
|
+
const bBuf = Buffer.from(b, "utf-8");
|
|
366
|
+
if (aBuf.length !== bBuf.length) return false;
|
|
367
|
+
return timingSafeEqual(aBuf, bBuf);
|
|
368
|
+
} catch {
|
|
369
|
+
return false;
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
function sanitizeApiError(error, statusCode, isDevelopment = false) {
|
|
373
|
+
if (statusCode >= 400 && statusCode < 500) {
|
|
374
|
+
const message = error instanceof Error ? error.message : String(error || "Bad request");
|
|
375
|
+
return { message };
|
|
376
|
+
}
|
|
377
|
+
const result = {
|
|
378
|
+
message: "An internal error occurred. Please try again later.",
|
|
379
|
+
code: "INTERNAL_ERROR"
|
|
380
|
+
};
|
|
381
|
+
if (isDevelopment && error instanceof Error) {
|
|
382
|
+
result.stack = error.stack;
|
|
383
|
+
}
|
|
384
|
+
return result;
|
|
385
|
+
}
|
|
386
|
+
function getCorrelationId(headers) {
|
|
387
|
+
const get = typeof headers === "function" ? headers : (name) => {
|
|
388
|
+
const val = headers[name] ?? headers[name.toLowerCase()];
|
|
389
|
+
return Array.isArray(val) ? val[0] : val;
|
|
390
|
+
};
|
|
391
|
+
return get("x-request-id") || get("X-Request-ID") || get("x-correlation-id") || get("X-Correlation-ID") || crypto.randomUUID();
|
|
392
|
+
}
|
|
350
393
|
|
|
351
394
|
// src/auth/schemas.ts
|
|
352
395
|
var EmailSchema = z.string().trim().toLowerCase().email("Invalid email address");
|
|
@@ -690,6 +733,44 @@ function resolveIdentifier(session, clientIp) {
|
|
|
690
733
|
return { identifier: `ip:${clientIp ?? "unknown"}`, isAuthenticated: false };
|
|
691
734
|
}
|
|
692
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
|
+
|
|
693
774
|
// src/auth/audit.ts
|
|
694
775
|
var StandardAuditActions = {
|
|
695
776
|
// Authentication
|
|
@@ -848,7 +929,277 @@ function createAuditLogger(options = {}) {
|
|
|
848
929
|
}
|
|
849
930
|
return { log, createTimedAudit };
|
|
850
931
|
}
|
|
932
|
+
|
|
933
|
+
// src/api.ts
|
|
934
|
+
var ApiErrorCode = {
|
|
935
|
+
VALIDATION_ERROR: "VALIDATION_ERROR",
|
|
936
|
+
UNAUTHORIZED: "UNAUTHORIZED",
|
|
937
|
+
FORBIDDEN: "FORBIDDEN",
|
|
938
|
+
NOT_FOUND: "NOT_FOUND",
|
|
939
|
+
CONFLICT: "CONFLICT",
|
|
940
|
+
RATE_LIMIT_EXCEEDED: "RATE_LIMIT_EXCEEDED",
|
|
941
|
+
INTERNAL_ERROR: "INTERNAL_ERROR",
|
|
942
|
+
DATABASE_ERROR: "DATABASE_ERROR",
|
|
943
|
+
EXTERNAL_SERVICE_ERROR: "EXTERNAL_SERVICE_ERROR",
|
|
944
|
+
CONFIGURATION_ERROR: "CONFIGURATION_ERROR"
|
|
945
|
+
};
|
|
946
|
+
var ApiError = class extends Error {
|
|
947
|
+
statusCode;
|
|
948
|
+
code;
|
|
949
|
+
details;
|
|
950
|
+
constructor(statusCode, message, code = ApiErrorCode.INTERNAL_ERROR, details) {
|
|
951
|
+
super(message);
|
|
952
|
+
this.name = "ApiError";
|
|
953
|
+
this.statusCode = statusCode;
|
|
954
|
+
this.code = code;
|
|
955
|
+
this.details = details;
|
|
956
|
+
}
|
|
957
|
+
};
|
|
958
|
+
function isApiError(error) {
|
|
959
|
+
return error instanceof ApiError;
|
|
960
|
+
}
|
|
961
|
+
var CommonApiErrors = {
|
|
962
|
+
unauthorized: (msg = "Unauthorized") => new ApiError(401, msg, ApiErrorCode.UNAUTHORIZED),
|
|
963
|
+
forbidden: (msg = "Forbidden") => new ApiError(403, msg, ApiErrorCode.FORBIDDEN),
|
|
964
|
+
notFound: (resource = "Resource") => new ApiError(404, `${resource} not found`, ApiErrorCode.NOT_FOUND),
|
|
965
|
+
conflict: (msg = "Resource already exists") => new ApiError(409, msg, ApiErrorCode.CONFLICT),
|
|
966
|
+
rateLimitExceeded: (msg = "Rate limit exceeded") => new ApiError(429, msg, ApiErrorCode.RATE_LIMIT_EXCEEDED),
|
|
967
|
+
validationError: (details) => new ApiError(
|
|
968
|
+
400,
|
|
969
|
+
"Validation failed",
|
|
970
|
+
ApiErrorCode.VALIDATION_ERROR,
|
|
971
|
+
details
|
|
972
|
+
),
|
|
973
|
+
internalError: (msg = "Internal server error") => new ApiError(500, msg, ApiErrorCode.INTERNAL_ERROR)
|
|
974
|
+
};
|
|
975
|
+
var PG_ERROR_MAP = {
|
|
976
|
+
"23505": {
|
|
977
|
+
status: 409,
|
|
978
|
+
code: ApiErrorCode.CONFLICT,
|
|
979
|
+
message: "Resource already exists"
|
|
980
|
+
},
|
|
981
|
+
"23503": {
|
|
982
|
+
status: 404,
|
|
983
|
+
code: ApiErrorCode.NOT_FOUND,
|
|
984
|
+
message: "Referenced resource not found"
|
|
985
|
+
},
|
|
986
|
+
PGRST116: {
|
|
987
|
+
status: 404,
|
|
988
|
+
code: ApiErrorCode.NOT_FOUND,
|
|
989
|
+
message: "Resource not found"
|
|
990
|
+
}
|
|
991
|
+
};
|
|
992
|
+
function classifyError(error, isDev = false) {
|
|
993
|
+
if (isApiError(error)) {
|
|
994
|
+
return {
|
|
995
|
+
status: error.statusCode,
|
|
996
|
+
body: { error: error.message, code: error.code, details: error.details }
|
|
997
|
+
};
|
|
998
|
+
}
|
|
999
|
+
if (error && typeof error === "object" && "issues" in error && Array.isArray(error.issues)) {
|
|
1000
|
+
return {
|
|
1001
|
+
status: 400,
|
|
1002
|
+
body: {
|
|
1003
|
+
error: "Validation failed",
|
|
1004
|
+
code: ApiErrorCode.VALIDATION_ERROR,
|
|
1005
|
+
details: error.issues.map((i) => ({
|
|
1006
|
+
field: i.path?.join("."),
|
|
1007
|
+
message: i.message
|
|
1008
|
+
}))
|
|
1009
|
+
}
|
|
1010
|
+
};
|
|
1011
|
+
}
|
|
1012
|
+
if (error && typeof error === "object" && "code" in error && typeof error.code === "string") {
|
|
1013
|
+
const pgCode = error.code;
|
|
1014
|
+
const mapped = PG_ERROR_MAP[pgCode];
|
|
1015
|
+
if (mapped) {
|
|
1016
|
+
return {
|
|
1017
|
+
status: mapped.status,
|
|
1018
|
+
body: { error: mapped.message, code: mapped.code }
|
|
1019
|
+
};
|
|
1020
|
+
}
|
|
1021
|
+
return {
|
|
1022
|
+
status: 500,
|
|
1023
|
+
body: {
|
|
1024
|
+
error: "Database error",
|
|
1025
|
+
code: ApiErrorCode.DATABASE_ERROR,
|
|
1026
|
+
details: isDev ? error.message : void 0
|
|
1027
|
+
}
|
|
1028
|
+
};
|
|
1029
|
+
}
|
|
1030
|
+
if (error instanceof Error) {
|
|
1031
|
+
return {
|
|
1032
|
+
status: 500,
|
|
1033
|
+
body: {
|
|
1034
|
+
error: isDev ? error.message : "Internal server error",
|
|
1035
|
+
code: ApiErrorCode.INTERNAL_ERROR,
|
|
1036
|
+
details: isDev ? error.stack : void 0
|
|
1037
|
+
}
|
|
1038
|
+
};
|
|
1039
|
+
}
|
|
1040
|
+
return {
|
|
1041
|
+
status: 500,
|
|
1042
|
+
body: {
|
|
1043
|
+
error: "An unexpected error occurred",
|
|
1044
|
+
code: ApiErrorCode.INTERNAL_ERROR
|
|
1045
|
+
}
|
|
1046
|
+
};
|
|
1047
|
+
}
|
|
1048
|
+
function buildPagination(page, limit, total) {
|
|
1049
|
+
return {
|
|
1050
|
+
page,
|
|
1051
|
+
limit,
|
|
1052
|
+
total,
|
|
1053
|
+
totalPages: Math.ceil(total / limit),
|
|
1054
|
+
hasMore: page * limit < total
|
|
1055
|
+
};
|
|
1056
|
+
}
|
|
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
|
+
|
|
1109
|
+
// src/env.ts
|
|
1110
|
+
function getRequiredEnv(key) {
|
|
1111
|
+
const value = process.env[key];
|
|
1112
|
+
if (!value) {
|
|
1113
|
+
throw new Error(`Missing required environment variable: ${key}`);
|
|
1114
|
+
}
|
|
1115
|
+
return value;
|
|
1116
|
+
}
|
|
1117
|
+
function getOptionalEnv(key, defaultValue) {
|
|
1118
|
+
return process.env[key] || defaultValue;
|
|
1119
|
+
}
|
|
1120
|
+
function getBoolEnv(key, defaultValue = false) {
|
|
1121
|
+
const value = process.env[key];
|
|
1122
|
+
if (value === void 0 || value === "") return defaultValue;
|
|
1123
|
+
return value === "true" || value === "1";
|
|
1124
|
+
}
|
|
1125
|
+
function getIntEnv(key, defaultValue) {
|
|
1126
|
+
const value = process.env[key];
|
|
1127
|
+
if (value === void 0 || value === "") return defaultValue;
|
|
1128
|
+
const parsed = parseInt(value, 10);
|
|
1129
|
+
return isNaN(parsed) ? defaultValue : parsed;
|
|
1130
|
+
}
|
|
1131
|
+
function validateEnvVars(config) {
|
|
1132
|
+
const result = checkEnvVars(config);
|
|
1133
|
+
if (!result.valid) {
|
|
1134
|
+
const lines = [];
|
|
1135
|
+
if (result.missing.length > 0) {
|
|
1136
|
+
lines.push(
|
|
1137
|
+
"Missing required environment variables:",
|
|
1138
|
+
...result.missing.map((v) => ` - ${v}`)
|
|
1139
|
+
);
|
|
1140
|
+
}
|
|
1141
|
+
if (result.missingOneOf.length > 0) {
|
|
1142
|
+
for (const group of result.missingOneOf) {
|
|
1143
|
+
lines.push(`Missing one of: ${group.join(" | ")}`);
|
|
1144
|
+
}
|
|
1145
|
+
}
|
|
1146
|
+
if (result.invalid.length > 0) {
|
|
1147
|
+
lines.push(
|
|
1148
|
+
"Invalid environment variables:",
|
|
1149
|
+
...result.invalid.map((v) => ` - ${v.key}: ${v.reason}`)
|
|
1150
|
+
);
|
|
1151
|
+
}
|
|
1152
|
+
throw new Error(lines.join("\n"));
|
|
1153
|
+
}
|
|
1154
|
+
}
|
|
1155
|
+
function checkEnvVars(config) {
|
|
1156
|
+
const missing = [];
|
|
1157
|
+
const invalid = [];
|
|
1158
|
+
const missingOneOf = [];
|
|
1159
|
+
if (config.required) {
|
|
1160
|
+
for (const key of config.required) {
|
|
1161
|
+
if (!process.env[key]) {
|
|
1162
|
+
missing.push(key);
|
|
1163
|
+
}
|
|
1164
|
+
}
|
|
1165
|
+
}
|
|
1166
|
+
if (config.requireOneOf) {
|
|
1167
|
+
for (const group of config.requireOneOf) {
|
|
1168
|
+
const hasAny = group.some((key) => !!process.env[key]);
|
|
1169
|
+
if (!hasAny) {
|
|
1170
|
+
missingOneOf.push(group);
|
|
1171
|
+
}
|
|
1172
|
+
}
|
|
1173
|
+
}
|
|
1174
|
+
if (config.validators) {
|
|
1175
|
+
for (const [key, validator] of Object.entries(config.validators)) {
|
|
1176
|
+
const value = process.env[key];
|
|
1177
|
+
if (value) {
|
|
1178
|
+
const result = validator(value);
|
|
1179
|
+
if (result !== true) {
|
|
1180
|
+
invalid.push({ key, reason: result });
|
|
1181
|
+
}
|
|
1182
|
+
}
|
|
1183
|
+
}
|
|
1184
|
+
}
|
|
1185
|
+
return {
|
|
1186
|
+
valid: missing.length === 0 && invalid.length === 0 && missingOneOf.length === 0,
|
|
1187
|
+
missing,
|
|
1188
|
+
invalid,
|
|
1189
|
+
missingOneOf
|
|
1190
|
+
};
|
|
1191
|
+
}
|
|
1192
|
+
function getEnvSummary(keys) {
|
|
1193
|
+
const summary = {};
|
|
1194
|
+
for (const key of keys) {
|
|
1195
|
+
summary[key] = !!process.env[key];
|
|
1196
|
+
}
|
|
1197
|
+
return summary;
|
|
1198
|
+
}
|
|
851
1199
|
export {
|
|
1200
|
+
ApiError,
|
|
1201
|
+
ApiErrorCode,
|
|
1202
|
+
CommonApiErrors,
|
|
852
1203
|
CommonRateLimits,
|
|
853
1204
|
DateRangeSchema,
|
|
854
1205
|
EmailSchema,
|
|
@@ -868,33 +1219,56 @@ export {
|
|
|
868
1219
|
buildAuthCookies,
|
|
869
1220
|
buildErrorBody,
|
|
870
1221
|
buildKeycloakCallbacks,
|
|
1222
|
+
buildPagination,
|
|
871
1223
|
buildRateLimitHeaders,
|
|
872
1224
|
buildRateLimitResponseHeaders,
|
|
873
1225
|
buildRedirectCallback,
|
|
874
1226
|
buildTokenRefreshParams,
|
|
1227
|
+
checkEnvVars,
|
|
875
1228
|
checkRateLimit,
|
|
1229
|
+
classifyError,
|
|
1230
|
+
constantTimeEqual,
|
|
1231
|
+
containsHtml,
|
|
1232
|
+
containsUrls,
|
|
876
1233
|
createAuditActor,
|
|
877
1234
|
createAuditLogger,
|
|
878
1235
|
createFeatureFlags,
|
|
879
1236
|
createMemoryRateLimitStore,
|
|
1237
|
+
createRedisRateLimitStore,
|
|
880
1238
|
createSafeTextSchema,
|
|
881
1239
|
detectStage,
|
|
1240
|
+
enforceRateLimit,
|
|
1241
|
+
errorResponse,
|
|
1242
|
+
escapeHtml,
|
|
882
1243
|
extractAuditIp,
|
|
883
1244
|
extractAuditRequestId,
|
|
884
1245
|
extractAuditUserAgent,
|
|
1246
|
+
extractBearerToken,
|
|
885
1247
|
extractClientIp,
|
|
1248
|
+
getBoolEnv,
|
|
1249
|
+
getCorrelationId,
|
|
886
1250
|
getEndSessionEndpoint,
|
|
1251
|
+
getEnvSummary,
|
|
1252
|
+
getIntEnv,
|
|
1253
|
+
getOptionalEnv,
|
|
887
1254
|
getRateLimitStatus,
|
|
1255
|
+
getRequiredEnv,
|
|
888
1256
|
getTokenEndpoint,
|
|
889
1257
|
hasAllRoles,
|
|
890
1258
|
hasAnyRole,
|
|
891
1259
|
hasRole,
|
|
892
1260
|
isAllowlisted,
|
|
1261
|
+
isApiError,
|
|
893
1262
|
isTokenExpired,
|
|
1263
|
+
isValidBearerToken,
|
|
894
1264
|
parseKeycloakRoles,
|
|
895
1265
|
refreshKeycloakToken,
|
|
896
1266
|
resetRateLimitForKey,
|
|
897
1267
|
resolveIdentifier,
|
|
898
|
-
resolveRateLimitIdentifier
|
|
1268
|
+
resolveRateLimitIdentifier,
|
|
1269
|
+
sanitizeApiError,
|
|
1270
|
+
stripHtml,
|
|
1271
|
+
validateEnvVars,
|
|
1272
|
+
zodErrorResponse
|
|
899
1273
|
};
|
|
900
1274
|
//# sourceMappingURL=auth.mjs.map
|