@tern-secure/backend 1.1.6 → 1.1.8
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/admin/package.json +5 -0
- package/dist/adapters/PostgresAdapter.d.ts +8 -0
- package/dist/adapters/PostgresAdapter.d.ts.map +1 -0
- package/dist/adapters/RedisAdapter.d.ts +10 -0
- package/dist/adapters/RedisAdapter.d.ts.map +1 -0
- package/dist/adapters/index.d.ts +13 -0
- package/dist/adapters/index.d.ts.map +1 -0
- package/dist/adapters/types.d.ts +30 -0
- package/dist/adapters/types.d.ts.map +1 -0
- package/dist/admin/gemini_sessionTernSecure.d.ts +10 -0
- package/dist/admin/gemini_sessionTernSecure.d.ts.map +1 -0
- package/dist/admin/index.d.ts +8 -0
- package/dist/admin/index.d.ts.map +1 -0
- package/dist/admin/index.js +705 -0
- package/dist/admin/index.js.map +1 -0
- package/dist/admin/index.mjs +512 -0
- package/dist/admin/index.mjs.map +1 -0
- package/dist/admin/nextSessionTernSecure.d.ts +28 -0
- package/dist/admin/nextSessionTernSecure.d.ts.map +1 -0
- package/dist/admin/sessionTernSecure.d.ts +6 -0
- package/dist/admin/sessionTernSecure.d.ts.map +1 -0
- package/dist/admin/tenant.d.ts.map +1 -0
- package/dist/api/createBackendApi.d.ts +8 -0
- package/dist/api/createBackendApi.d.ts.map +1 -0
- package/dist/api/endpoints/SessionApi.d.ts +12 -0
- package/dist/api/endpoints/SessionApi.d.ts.map +1 -0
- package/dist/api/endpoints/index.d.ts +2 -0
- package/dist/api/endpoints/index.d.ts.map +1 -0
- package/dist/api/index.d.ts +2 -0
- package/dist/api/index.d.ts.map +1 -0
- package/dist/api/request.d.ts +36 -0
- package/dist/api/request.d.ts.map +1 -0
- package/dist/chunk-JFOTE3Y5.mjs +157 -0
- package/dist/chunk-JFOTE3Y5.mjs.map +1 -0
- package/dist/chunk-WZYVAHZ3.mjs +318 -0
- package/dist/chunk-WZYVAHZ3.mjs.map +1 -0
- package/dist/constants.d.ts +63 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1307 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +839 -0
- package/dist/index.mjs.map +1 -0
- package/dist/instance/backendFireInstance.d.ts +7 -0
- package/dist/instance/backendFireInstance.d.ts.map +1 -0
- package/dist/instance/backendInstance.d.ts +20 -0
- package/dist/instance/backendInstance.d.ts.map +1 -0
- package/dist/instance/backendInstanceEdge.d.ts +13 -0
- package/dist/instance/backendInstanceEdge.d.ts.map +1 -0
- package/dist/jwt/algorithms.d.ts +3 -0
- package/dist/jwt/algorithms.d.ts.map +1 -0
- package/dist/jwt/cryptoKeys.d.ts +3 -0
- package/dist/jwt/cryptoKeys.d.ts.map +1 -0
- package/dist/jwt/guardReturn.d.ts +3 -0
- package/dist/jwt/guardReturn.d.ts.map +1 -0
- package/dist/jwt/index.d.ts +4 -0
- package/dist/jwt/index.d.ts.map +1 -0
- package/dist/jwt/index.js +332 -0
- package/dist/jwt/index.js.map +1 -0
- package/dist/jwt/index.mjs +139 -0
- package/dist/jwt/index.mjs.map +1 -0
- package/dist/jwt/jwt.d.ts +4 -0
- package/dist/jwt/jwt.d.ts.map +1 -0
- package/dist/jwt/signJwt.d.ts +5 -0
- package/dist/jwt/signJwt.d.ts.map +1 -0
- package/dist/jwt/types.d.ts +8 -0
- package/dist/jwt/types.d.ts.map +1 -0
- package/dist/jwt/verifyContent.d.ts +7 -0
- package/dist/jwt/verifyContent.d.ts.map +1 -0
- package/dist/jwt/verifyJwt.d.ts +12 -0
- package/dist/jwt/verifyJwt.d.ts.map +1 -0
- package/dist/runtime/browser/crypto.mjs +1 -0
- package/dist/runtime/node/crypto.js +1 -0
- package/dist/runtime/node/crypto.mjs +1 -0
- package/dist/runtime.d.ts +26 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/ternsecureauth.d.ts.map +1 -0
- package/dist/tokens/authstate.d.ts +61 -0
- package/dist/tokens/authstate.d.ts.map +1 -0
- package/dist/tokens/keys.d.ts +16 -0
- package/dist/tokens/keys.d.ts.map +1 -0
- package/dist/tokens/request.d.ts +16 -0
- package/dist/tokens/request.d.ts.map +1 -0
- package/dist/tokens/requestFire.d.ts +17 -0
- package/dist/tokens/requestFire.d.ts.map +1 -0
- package/dist/tokens/sessionConfig.d.ts +14 -0
- package/dist/tokens/sessionConfig.d.ts.map +1 -0
- package/dist/tokens/ternSecureRequest.d.ts +20 -0
- package/dist/tokens/ternSecureRequest.d.ts.map +1 -0
- package/dist/tokens/ternUrl.d.ts +15 -0
- package/dist/tokens/ternUrl.d.ts.map +1 -0
- package/dist/tokens/types.d.ts +41 -0
- package/dist/tokens/types.d.ts.map +1 -0
- package/dist/tokens/verify.d.ts +11 -0
- package/dist/tokens/verify.d.ts.map +1 -0
- package/dist/utils/admin-init.d.ts +13 -0
- package/dist/utils/admin-init.d.ts.map +1 -0
- package/dist/{types/utils → utils}/config.d.ts +1 -1
- package/dist/utils/config.d.ts.map +1 -0
- package/dist/utils/enableDebugLogging.d.ts +5 -0
- package/dist/utils/enableDebugLogging.d.ts.map +1 -0
- package/dist/utils/errors.d.ts +29 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/gemini_admin-init.d.ts +10 -0
- package/dist/utils/gemini_admin-init.d.ts.map +1 -0
- package/dist/utils/logger.d.ts +28 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/mapDecode.d.ts +4 -0
- package/dist/utils/mapDecode.d.ts.map +1 -0
- package/dist/utils/options.d.ts +5 -0
- package/dist/utils/options.d.ts.map +1 -0
- package/dist/utils/path.d.ts +4 -0
- package/dist/utils/path.d.ts.map +1 -0
- package/dist/utils/redis.d.ts +10 -0
- package/dist/utils/redis.d.ts.map +1 -0
- package/dist/utils/rfc4648.d.ts +26 -0
- package/dist/utils/rfc4648.d.ts.map +1 -0
- package/jwt/package.json +5 -0
- package/package.json +59 -10
- package/dist/cjs/admin/sessionTernSecure.js +0 -256
- package/dist/cjs/admin/sessionTernSecure.js.map +0 -1
- package/dist/cjs/admin/tenant.js +0 -68
- package/dist/cjs/admin/tenant.js.map +0 -1
- package/dist/cjs/global.d.js +0 -2
- package/dist/cjs/global.d.js.map +0 -1
- package/dist/cjs/index.js +0 -48
- package/dist/cjs/index.js.map +0 -1
- package/dist/cjs/ternsecureauth.js +0 -40
- package/dist/cjs/ternsecureauth.js.map +0 -1
- package/dist/cjs/utils/admin-init.js +0 -60
- package/dist/cjs/utils/admin-init.js.map +0 -1
- package/dist/cjs/utils/config.js +0 -113
- package/dist/cjs/utils/config.js.map +0 -1
- package/dist/esm/admin/sessionTernSecure.js +0 -226
- package/dist/esm/admin/sessionTernSecure.js.map +0 -1
- package/dist/esm/admin/tenant.js +0 -43
- package/dist/esm/admin/tenant.js.map +0 -1
- package/dist/esm/global.d.js +0 -1
- package/dist/esm/global.d.js.map +0 -1
- package/dist/esm/index.js +0 -24
- package/dist/esm/index.js.map +0 -1
- package/dist/esm/ternsecureauth.js +0 -16
- package/dist/esm/ternsecureauth.js.map +0 -1
- package/dist/esm/utils/admin-init.js +0 -24
- package/dist/esm/utils/admin-init.js.map +0 -1
- package/dist/esm/utils/config.js +0 -84
- package/dist/esm/utils/config.js.map +0 -1
- package/dist/types/admin/sessionTernSecure.d.ts +0 -36
- package/dist/types/admin/sessionTernSecure.d.ts.map +0 -1
- package/dist/types/admin/tenant.d.ts.map +0 -1
- package/dist/types/index.d.ts +0 -5
- package/dist/types/index.d.ts.map +0 -1
- package/dist/types/ternsecureauth.d.ts.map +0 -1
- package/dist/types/utils/admin-init.d.ts +0 -5
- package/dist/types/utils/admin-init.d.ts.map +0 -1
- package/dist/types/utils/config.d.ts.map +0 -1
- /package/dist/{types/admin → admin}/tenant.d.ts +0 -0
- /package/dist/{types/ternsecureauth.d.ts → ternsecureauth.d.ts} +0 -0
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,839 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CACHE_CONTROL_REGEX,
|
|
3
|
+
DEFAULT_CACHE_DURATION,
|
|
4
|
+
MAX_CACHE_LAST_UPDATED_AT_SECONDS,
|
|
5
|
+
SESSION_COOKIE_PUBLIC_KEYS_URL,
|
|
6
|
+
constants,
|
|
7
|
+
createTernSecureRequest,
|
|
8
|
+
getSessionConfig
|
|
9
|
+
} from "./chunk-JFOTE3Y5.mjs";
|
|
10
|
+
import {
|
|
11
|
+
TokenVerificationError,
|
|
12
|
+
TokenVerificationErrorReason,
|
|
13
|
+
mapJwtPayloadToDecodedIdToken,
|
|
14
|
+
ternDecodeJwt,
|
|
15
|
+
verifyJwt
|
|
16
|
+
} from "./chunk-WZYVAHZ3.mjs";
|
|
17
|
+
|
|
18
|
+
// src/tokens/authstate.ts
|
|
19
|
+
var AuthStatus = {
|
|
20
|
+
SignedIn: "signed-in",
|
|
21
|
+
SignedOut: "signed-out"
|
|
22
|
+
};
|
|
23
|
+
var AuthErrorReason = {
|
|
24
|
+
SessionTokenAndUATMissing: "session-token-and-uat-missing",
|
|
25
|
+
SessionTokenMissing: "session-token-missing",
|
|
26
|
+
SessionTokenExpired: "session-token-expired",
|
|
27
|
+
SessionTokenIATBeforeClientUAT: "session-token-iat-before-client-uat",
|
|
28
|
+
SessionTokenNBF: "session-token-nbf",
|
|
29
|
+
SessionTokenIatInTheFuture: "session-token-iat-in-the-future",
|
|
30
|
+
ActiveOrganizationMismatch: "active-organization-mismatch",
|
|
31
|
+
UnexpectedError: "unexpected-error"
|
|
32
|
+
};
|
|
33
|
+
function createHasAuthorization(decodedIdToken) {
|
|
34
|
+
return (authorizationParams) => {
|
|
35
|
+
if (!authorizationParams || typeof authorizationParams !== "object" || Array.isArray(authorizationParams)) {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
const claims = decodedIdToken;
|
|
39
|
+
return Object.entries(authorizationParams).every(([key, value]) => {
|
|
40
|
+
const claimValue = claims[key];
|
|
41
|
+
if (typeof claimValue === "undefined") {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
if (Array.isArray(value)) {
|
|
45
|
+
if (Array.isArray(claimValue)) {
|
|
46
|
+
return value.some((v) => claimValue.includes(v));
|
|
47
|
+
}
|
|
48
|
+
return value.includes(claimValue);
|
|
49
|
+
}
|
|
50
|
+
if (Array.isArray(claimValue)) {
|
|
51
|
+
return claimValue.includes(value);
|
|
52
|
+
}
|
|
53
|
+
return claimValue === value;
|
|
54
|
+
});
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
function signedInAuthObject(sessionToken, sessionClaims) {
|
|
58
|
+
const decodedIdToken = mapJwtPayloadToDecodedIdToken(sessionClaims);
|
|
59
|
+
return {
|
|
60
|
+
sessionClaims: {
|
|
61
|
+
...decodedIdToken
|
|
62
|
+
},
|
|
63
|
+
userId: decodedIdToken.uid,
|
|
64
|
+
token: sessionToken,
|
|
65
|
+
require: createHasAuthorization(decodedIdToken),
|
|
66
|
+
error: null
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
function signedOutAuthObject() {
|
|
70
|
+
return {
|
|
71
|
+
sessionClaims: null,
|
|
72
|
+
userId: null,
|
|
73
|
+
require: () => false,
|
|
74
|
+
error: "No active session"
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
function signedIn(sessionClaims, headers = new Headers(), token) {
|
|
78
|
+
const authObject = signedInAuthObject(token, sessionClaims);
|
|
79
|
+
return {
|
|
80
|
+
status: AuthStatus.SignedIn,
|
|
81
|
+
reason: null,
|
|
82
|
+
isSignedIn: true,
|
|
83
|
+
auth: () => authObject,
|
|
84
|
+
token,
|
|
85
|
+
headers
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
function signedOut(reason, headers = new Headers()) {
|
|
89
|
+
return decorateHeaders({
|
|
90
|
+
status: AuthStatus.SignedOut,
|
|
91
|
+
reason,
|
|
92
|
+
isSignedIn: false,
|
|
93
|
+
auth: () => signedOutAuthObject(),
|
|
94
|
+
token: null,
|
|
95
|
+
headers
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
var decorateHeaders = (requestState) => {
|
|
99
|
+
const headers = new Headers(requestState.headers || {});
|
|
100
|
+
if (requestState.reason) {
|
|
101
|
+
try {
|
|
102
|
+
headers.set(constants.Headers.AuthReason, requestState.reason);
|
|
103
|
+
} catch {
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
if (requestState.status) {
|
|
107
|
+
try {
|
|
108
|
+
headers.set(constants.Headers.AuthStatus, requestState.status);
|
|
109
|
+
} catch {
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
requestState.headers = headers;
|
|
113
|
+
return requestState;
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
// src/api/endpoints/SessionApi.ts
|
|
117
|
+
var rootPath = "/sessions";
|
|
118
|
+
var SessionApi = class {
|
|
119
|
+
constructor(request) {
|
|
120
|
+
this.request = request;
|
|
121
|
+
}
|
|
122
|
+
async createSession(params) {
|
|
123
|
+
return this.request({
|
|
124
|
+
method: "POST",
|
|
125
|
+
path: rootPath,
|
|
126
|
+
bodyParams: params
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
// src/runtime.ts
|
|
132
|
+
import { webcrypto as crypto } from "#crypto";
|
|
133
|
+
var globalFetch = fetch.bind(globalThis);
|
|
134
|
+
var runtime = {
|
|
135
|
+
crypto,
|
|
136
|
+
get fetch() {
|
|
137
|
+
return process.env.NODE_ENV === "test" ? fetch : globalFetch;
|
|
138
|
+
},
|
|
139
|
+
AbortController: globalThis.AbortController,
|
|
140
|
+
Blob: globalThis.Blob,
|
|
141
|
+
FormData: globalThis.FormData,
|
|
142
|
+
Headers: globalThis.Headers,
|
|
143
|
+
Request: globalThis.Request,
|
|
144
|
+
Response: globalThis.Response
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
// src/utils/path.ts
|
|
148
|
+
var SEPARATOR = "/";
|
|
149
|
+
var MULTIPLE_SEPARATOR_REGEX = new RegExp("(?<!:)" + SEPARATOR + "{1,}", "g");
|
|
150
|
+
function joinPaths(...args) {
|
|
151
|
+
return args.filter((p) => p).join(SEPARATOR).replace(MULTIPLE_SEPARATOR_REGEX, SEPARATOR);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// src/api/request.ts
|
|
155
|
+
function createRequest(options) {
|
|
156
|
+
const requestFn = async (requestOptions) => {
|
|
157
|
+
const { apiUrl, apiVersion } = options;
|
|
158
|
+
const { path, method, queryParams, headerParams, bodyParams, formData } = requestOptions;
|
|
159
|
+
const url = joinPaths(apiUrl, apiVersion, path);
|
|
160
|
+
const finalUrl = new URL(url);
|
|
161
|
+
if (queryParams) {
|
|
162
|
+
Object.entries(queryParams).forEach(([key, value]) => {
|
|
163
|
+
if (value) {
|
|
164
|
+
[value].flat().forEach((v) => finalUrl.searchParams.append(key, v));
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
const headers = {
|
|
169
|
+
...headerParams
|
|
170
|
+
};
|
|
171
|
+
let res;
|
|
172
|
+
try {
|
|
173
|
+
if (formData) {
|
|
174
|
+
res = await runtime.fetch(finalUrl.href, {
|
|
175
|
+
method,
|
|
176
|
+
headers,
|
|
177
|
+
body: formData
|
|
178
|
+
});
|
|
179
|
+
} else {
|
|
180
|
+
headers["Content-Type"] = "application/json";
|
|
181
|
+
const hasBody = method !== "GET" && bodyParams && Object.keys(bodyParams).length > 0;
|
|
182
|
+
const body = hasBody ? { body: JSON.stringify(bodyParams) } : null;
|
|
183
|
+
res = await runtime.fetch(finalUrl.href, {
|
|
184
|
+
method,
|
|
185
|
+
headers,
|
|
186
|
+
...body
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
const isJSONResponse = res?.headers && res.headers?.get(constants.Headers.ContentType) === constants.ContentTypes.Json;
|
|
190
|
+
const responseBody = await (isJSONResponse ? res.json() : res.text());
|
|
191
|
+
if (!res.ok) {
|
|
192
|
+
return {
|
|
193
|
+
data: null,
|
|
194
|
+
errors: parseErrors(responseBody),
|
|
195
|
+
status: res?.status,
|
|
196
|
+
statusText: res?.statusText
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
return {
|
|
200
|
+
data: responseBody,
|
|
201
|
+
errors: null
|
|
202
|
+
};
|
|
203
|
+
} catch (error) {
|
|
204
|
+
if (error instanceof Error) {
|
|
205
|
+
return {
|
|
206
|
+
data: null,
|
|
207
|
+
errors: [
|
|
208
|
+
{
|
|
209
|
+
code: "unexpected_error",
|
|
210
|
+
message: error.message || "An unexpected error occurred"
|
|
211
|
+
}
|
|
212
|
+
]
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
return {
|
|
216
|
+
data: null,
|
|
217
|
+
errors: parseErrors(error),
|
|
218
|
+
status: res?.status,
|
|
219
|
+
statusText: res?.statusText
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
};
|
|
223
|
+
return requestFn;
|
|
224
|
+
}
|
|
225
|
+
function parseErrors(data) {
|
|
226
|
+
if (!!data && typeof data === "object" && "errors" in data) {
|
|
227
|
+
const errors = data.errors;
|
|
228
|
+
return errors.length > 0 ? errors.map(parseError) : [];
|
|
229
|
+
}
|
|
230
|
+
return [];
|
|
231
|
+
}
|
|
232
|
+
function parseError(error) {
|
|
233
|
+
return {
|
|
234
|
+
code: error.code,
|
|
235
|
+
message: error.message
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// src/api/createBackendApi.ts
|
|
240
|
+
function createBackendApi(options) {
|
|
241
|
+
const request = createRequest(options);
|
|
242
|
+
return {
|
|
243
|
+
sessions: new SessionApi(request)
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
// src/utils/options.ts
|
|
248
|
+
var defaultOptions = {
|
|
249
|
+
apiUrl: void 0,
|
|
250
|
+
apiVersion: void 0
|
|
251
|
+
};
|
|
252
|
+
function mergePreDefinedOptions(userOptions = {}) {
|
|
253
|
+
return {
|
|
254
|
+
...defaultOptions,
|
|
255
|
+
...userOptions
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// src/tokens/keys.ts
|
|
260
|
+
var cache = {};
|
|
261
|
+
var lastUpdatedAt = 0;
|
|
262
|
+
var googleExpiresAt = 0;
|
|
263
|
+
function getFromCache(kid) {
|
|
264
|
+
return cache[kid];
|
|
265
|
+
}
|
|
266
|
+
function getCacheValues() {
|
|
267
|
+
return Object.values(cache);
|
|
268
|
+
}
|
|
269
|
+
function setInCache(kid, certificate, shouldExpire = true) {
|
|
270
|
+
cache[kid] = certificate;
|
|
271
|
+
lastUpdatedAt = shouldExpire ? Date.now() : -1;
|
|
272
|
+
}
|
|
273
|
+
async function fetchPublicKeys(keyUrl) {
|
|
274
|
+
const url = new URL(keyUrl);
|
|
275
|
+
const response = await fetch(url);
|
|
276
|
+
if (!response.ok) {
|
|
277
|
+
throw new TokenVerificationError({
|
|
278
|
+
message: `Error loading public keys from ${url.href} with code=${response.status} `,
|
|
279
|
+
reason: TokenVerificationErrorReason.TokenInvalid
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
const data = await response.json();
|
|
283
|
+
const expiresAt = getExpiresAt(response);
|
|
284
|
+
return {
|
|
285
|
+
keys: data,
|
|
286
|
+
expiresAt
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
async function loadJWKFromRemote({
|
|
290
|
+
keyURL = SESSION_COOKIE_PUBLIC_KEYS_URL,
|
|
291
|
+
skipJwksCache,
|
|
292
|
+
kid
|
|
293
|
+
}) {
|
|
294
|
+
if (skipJwksCache || isCacheExpired() || !getFromCache(kid)) {
|
|
295
|
+
const { keys, expiresAt } = await fetchPublicKeys(keyURL);
|
|
296
|
+
if (!keys || Object.keys(keys).length === 0) {
|
|
297
|
+
throw new TokenVerificationError({
|
|
298
|
+
message: `The JWKS endpoint ${keyURL} returned no keys`,
|
|
299
|
+
reason: TokenVerificationErrorReason.RemoteJWKFailedToLoad
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
googleExpiresAt = expiresAt;
|
|
303
|
+
Object.entries(keys).forEach(([keyId, cert2]) => {
|
|
304
|
+
setInCache(keyId, cert2);
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
const cert = getFromCache(kid);
|
|
308
|
+
if (!cert) {
|
|
309
|
+
getCacheValues();
|
|
310
|
+
const availableKids = Object.keys(cache).sort().join(", ");
|
|
311
|
+
throw new TokenVerificationError({
|
|
312
|
+
message: `No public key found for kid "${kid}". Available kids: [${availableKids}]`,
|
|
313
|
+
reason: TokenVerificationErrorReason.TokenInvalid
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
return cert;
|
|
317
|
+
}
|
|
318
|
+
function isCacheExpired() {
|
|
319
|
+
const now = Date.now();
|
|
320
|
+
if (lastUpdatedAt === -1) {
|
|
321
|
+
return false;
|
|
322
|
+
}
|
|
323
|
+
const cacheAge = now - lastUpdatedAt;
|
|
324
|
+
const maxCacheAge = MAX_CACHE_LAST_UPDATED_AT_SECONDS * 1e3;
|
|
325
|
+
const localCacheExpired = cacheAge >= maxCacheAge;
|
|
326
|
+
const googleCacheExpired = now >= googleExpiresAt;
|
|
327
|
+
const isExpired = localCacheExpired || googleCacheExpired;
|
|
328
|
+
if (isExpired) {
|
|
329
|
+
cache = {};
|
|
330
|
+
}
|
|
331
|
+
return isExpired;
|
|
332
|
+
}
|
|
333
|
+
function getExpiresAt(res) {
|
|
334
|
+
const cacheControlHeader = res.headers.get("cache-control");
|
|
335
|
+
if (!cacheControlHeader) {
|
|
336
|
+
return Date.now() + DEFAULT_CACHE_DURATION;
|
|
337
|
+
}
|
|
338
|
+
const maxAgeMatch = cacheControlHeader.match(CACHE_CONTROL_REGEX);
|
|
339
|
+
const maxAge = maxAgeMatch ? parseInt(maxAgeMatch[1], 10) : DEFAULT_CACHE_DURATION / 1e3;
|
|
340
|
+
return Date.now() + maxAge * 1e3;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
// src/tokens/verify.ts
|
|
344
|
+
async function verifyToken(token, options) {
|
|
345
|
+
const { data: decodedResult, errors } = ternDecodeJwt(token);
|
|
346
|
+
if (errors) {
|
|
347
|
+
return { errors };
|
|
348
|
+
}
|
|
349
|
+
const { header } = decodedResult;
|
|
350
|
+
const { kid } = header;
|
|
351
|
+
if (!kid) {
|
|
352
|
+
return {
|
|
353
|
+
errors: [
|
|
354
|
+
new TokenVerificationError({
|
|
355
|
+
reason: TokenVerificationErrorReason.TokenInvalid,
|
|
356
|
+
message: 'JWT "kid" header is missing.'
|
|
357
|
+
})
|
|
358
|
+
]
|
|
359
|
+
};
|
|
360
|
+
}
|
|
361
|
+
try {
|
|
362
|
+
const key = options.jwtKey || await loadJWKFromRemote({ ...options, kid });
|
|
363
|
+
if (!key) {
|
|
364
|
+
return {
|
|
365
|
+
errors: [
|
|
366
|
+
new TokenVerificationError({
|
|
367
|
+
reason: TokenVerificationErrorReason.TokenInvalid,
|
|
368
|
+
message: `No public key found for kid "${kid}".`
|
|
369
|
+
})
|
|
370
|
+
]
|
|
371
|
+
};
|
|
372
|
+
}
|
|
373
|
+
return await verifyJwt(token, { ...options, key });
|
|
374
|
+
} catch (error) {
|
|
375
|
+
if (error instanceof TokenVerificationError) {
|
|
376
|
+
return { errors: [error] };
|
|
377
|
+
}
|
|
378
|
+
return {
|
|
379
|
+
errors: [error]
|
|
380
|
+
};
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
// src/tokens/request.ts
|
|
385
|
+
var BEARER_PREFIX = "Bearer ";
|
|
386
|
+
var AUTH_COOKIE_NAME = "_session_cookie";
|
|
387
|
+
function extractTokenFromHeader(request) {
|
|
388
|
+
const authHeader = request.headers.get("Authorization");
|
|
389
|
+
if (!authHeader || !authHeader.startsWith(BEARER_PREFIX)) {
|
|
390
|
+
return null;
|
|
391
|
+
}
|
|
392
|
+
return authHeader.slice(BEARER_PREFIX.length);
|
|
393
|
+
}
|
|
394
|
+
function extractTokenFromCookie(request, opts) {
|
|
395
|
+
const cookieHeader = request.headers.get("Cookie") || void 0;
|
|
396
|
+
const sessionName = getSessionConfig(opts).COOKIE_NAME;
|
|
397
|
+
if (!cookieHeader) {
|
|
398
|
+
return null;
|
|
399
|
+
}
|
|
400
|
+
const cookies = cookieHeader.split(";").reduce(
|
|
401
|
+
(acc, cookie) => {
|
|
402
|
+
const [name, value] = cookie.trim().split("=");
|
|
403
|
+
acc[name] = value;
|
|
404
|
+
return acc;
|
|
405
|
+
},
|
|
406
|
+
{}
|
|
407
|
+
);
|
|
408
|
+
return cookies[AUTH_COOKIE_NAME] || null;
|
|
409
|
+
}
|
|
410
|
+
function hasAuthorizationHeader(request) {
|
|
411
|
+
return request.headers.has("Authorization");
|
|
412
|
+
}
|
|
413
|
+
async function authenticateRequest(request, options) {
|
|
414
|
+
async function authenticateRequestWithTokenInCookie() {
|
|
415
|
+
const token = extractTokenFromCookie(request, options);
|
|
416
|
+
if (!token) {
|
|
417
|
+
return signedOut(AuthErrorReason.SessionTokenMissing);
|
|
418
|
+
}
|
|
419
|
+
const { data, errors } = await verifyToken(token, options);
|
|
420
|
+
if (errors) {
|
|
421
|
+
throw errors[0];
|
|
422
|
+
}
|
|
423
|
+
const signedInRequestState = signedIn(data, void 0, token);
|
|
424
|
+
return signedInRequestState;
|
|
425
|
+
}
|
|
426
|
+
async function authenticateRequestWithTokenInHeader() {
|
|
427
|
+
const token = extractTokenFromHeader(request);
|
|
428
|
+
if (!token) {
|
|
429
|
+
return signedOut(AuthErrorReason.SessionTokenMissing);
|
|
430
|
+
}
|
|
431
|
+
const { data, errors } = await verifyToken(token, options);
|
|
432
|
+
if (errors) {
|
|
433
|
+
throw errors[0];
|
|
434
|
+
}
|
|
435
|
+
const signedInRequestState = signedIn(data, void 0, token);
|
|
436
|
+
return signedInRequestState;
|
|
437
|
+
}
|
|
438
|
+
if (hasAuthorizationHeader(request)) {
|
|
439
|
+
return authenticateRequestWithTokenInHeader();
|
|
440
|
+
}
|
|
441
|
+
return authenticateRequestWithTokenInCookie();
|
|
442
|
+
}
|
|
443
|
+
function createAuthenticateRequest(params) {
|
|
444
|
+
const buildTimeOptions = mergePreDefinedOptions(params.options);
|
|
445
|
+
const apiClient = params.apiClient;
|
|
446
|
+
const handleAuthenticateRequest = (request, options = {}) => {
|
|
447
|
+
const { apiUrl } = buildTimeOptions;
|
|
448
|
+
return authenticateRequest(request, { ...options, apiUrl, apiClient });
|
|
449
|
+
};
|
|
450
|
+
return {
|
|
451
|
+
authenticateRequest: handleAuthenticateRequest
|
|
452
|
+
};
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
// src/instance/backendInstanceEdge.ts
|
|
456
|
+
function createBackendInstanceClient(options) {
|
|
457
|
+
const opts = { ...options };
|
|
458
|
+
const apiClient = createBackendApi(opts);
|
|
459
|
+
const requestState = createAuthenticateRequest({ options: opts, apiClient });
|
|
460
|
+
return {
|
|
461
|
+
...apiClient,
|
|
462
|
+
...requestState
|
|
463
|
+
};
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
// src/tokens/requestFire.ts
|
|
467
|
+
var defaultFirebaseOptions = {
|
|
468
|
+
apiKey: "",
|
|
469
|
+
authDomain: "",
|
|
470
|
+
projectId: "",
|
|
471
|
+
tenantId: void 0
|
|
472
|
+
};
|
|
473
|
+
function mergePreDefinedOptions2(preDefinedOptions, options) {
|
|
474
|
+
return Object.keys(preDefinedOptions).reduce(
|
|
475
|
+
(obj, key) => {
|
|
476
|
+
return { ...obj, [key]: options[key] || obj[key] };
|
|
477
|
+
},
|
|
478
|
+
{ ...preDefinedOptions }
|
|
479
|
+
);
|
|
480
|
+
}
|
|
481
|
+
var BEARER_PREFIX2 = "Bearer ";
|
|
482
|
+
var AUTH_COOKIE_NAME2 = "_session_cookie";
|
|
483
|
+
function extractTokenFromHeader2(request) {
|
|
484
|
+
const authHeader = request.headers.get("Authorization");
|
|
485
|
+
if (!authHeader || !authHeader.startsWith(BEARER_PREFIX2)) {
|
|
486
|
+
return null;
|
|
487
|
+
}
|
|
488
|
+
return authHeader.slice(BEARER_PREFIX2.length);
|
|
489
|
+
}
|
|
490
|
+
function extractTokenFromCookie2(request, opts) {
|
|
491
|
+
const cookieHeader = request.headers.get("Cookie") || void 0;
|
|
492
|
+
const sessionName = getSessionConfig(opts).COOKIE_NAME;
|
|
493
|
+
if (!cookieHeader) {
|
|
494
|
+
return null;
|
|
495
|
+
}
|
|
496
|
+
const cookies = cookieHeader.split(";").reduce(
|
|
497
|
+
(acc, cookie) => {
|
|
498
|
+
const [name, value] = cookie.trim().split("=");
|
|
499
|
+
acc[name] = value;
|
|
500
|
+
return acc;
|
|
501
|
+
},
|
|
502
|
+
{}
|
|
503
|
+
);
|
|
504
|
+
return cookies[AUTH_COOKIE_NAME2] || null;
|
|
505
|
+
}
|
|
506
|
+
function hasAuthorizationHeader2(request) {
|
|
507
|
+
return request.headers.has("Authorization");
|
|
508
|
+
}
|
|
509
|
+
async function authenticateRequest2(request, options) {
|
|
510
|
+
async function authenticateRequestWithTokenInCookie() {
|
|
511
|
+
const token = extractTokenFromCookie2(request, options);
|
|
512
|
+
if (!token) {
|
|
513
|
+
return signedOut(AuthErrorReason.SessionTokenMissing);
|
|
514
|
+
}
|
|
515
|
+
const { data, errors } = await verifyToken(token, options);
|
|
516
|
+
if (errors) {
|
|
517
|
+
throw errors[0];
|
|
518
|
+
}
|
|
519
|
+
const signedInRequestState = signedIn(data, void 0, token);
|
|
520
|
+
return signedInRequestState;
|
|
521
|
+
}
|
|
522
|
+
async function authenticateRequestWithTokenInHeader() {
|
|
523
|
+
const token = extractTokenFromHeader2(request);
|
|
524
|
+
if (!token) {
|
|
525
|
+
return signedOut(AuthErrorReason.SessionTokenMissing);
|
|
526
|
+
}
|
|
527
|
+
const { data, errors } = await verifyToken(token, options);
|
|
528
|
+
if (errors) {
|
|
529
|
+
throw errors[0];
|
|
530
|
+
}
|
|
531
|
+
const signedInRequestState = signedIn(data, void 0, token);
|
|
532
|
+
return signedInRequestState;
|
|
533
|
+
}
|
|
534
|
+
if (hasAuthorizationHeader2(request)) {
|
|
535
|
+
return authenticateRequestWithTokenInHeader();
|
|
536
|
+
}
|
|
537
|
+
return authenticateRequestWithTokenInCookie();
|
|
538
|
+
}
|
|
539
|
+
function createFireAuthenticateRequest(params) {
|
|
540
|
+
const buildTimeOptions = mergePreDefinedOptions2(defaultFirebaseOptions, params.options);
|
|
541
|
+
const handleAuthenticateRequest = (request, options = {}) => {
|
|
542
|
+
const runtimeOptions = { ...buildTimeOptions, ...options };
|
|
543
|
+
return authenticateRequest2(request, runtimeOptions);
|
|
544
|
+
};
|
|
545
|
+
return {
|
|
546
|
+
authenticateRequest: handleAuthenticateRequest
|
|
547
|
+
};
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
// src/instance/backendFireInstance.ts
|
|
551
|
+
function createFireClient(options) {
|
|
552
|
+
const opts = { ...options };
|
|
553
|
+
const apiClient = createBackendApi(opts);
|
|
554
|
+
const requestState = createFireAuthenticateRequest({ options: opts });
|
|
555
|
+
return {
|
|
556
|
+
...apiClient,
|
|
557
|
+
...requestState
|
|
558
|
+
};
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
// src/utils/logger.ts
|
|
562
|
+
var LogLevel = /* @__PURE__ */ ((LogLevel2) => {
|
|
563
|
+
LogLevel2[LogLevel2["ERROR"] = 0] = "ERROR";
|
|
564
|
+
LogLevel2[LogLevel2["WARN"] = 1] = "WARN";
|
|
565
|
+
LogLevel2[LogLevel2["INFO"] = 2] = "INFO";
|
|
566
|
+
LogLevel2[LogLevel2["DEBUG"] = 3] = "DEBUG";
|
|
567
|
+
return LogLevel2;
|
|
568
|
+
})(LogLevel || {});
|
|
569
|
+
var Logger = class {
|
|
570
|
+
options;
|
|
571
|
+
constructor(options = {}) {
|
|
572
|
+
this.options = {
|
|
573
|
+
enabled: false,
|
|
574
|
+
level: 2 /* INFO */,
|
|
575
|
+
prefix: "[TernSecure-Backend]",
|
|
576
|
+
...options
|
|
577
|
+
};
|
|
578
|
+
}
|
|
579
|
+
enable() {
|
|
580
|
+
this.options.enabled = true;
|
|
581
|
+
}
|
|
582
|
+
disable() {
|
|
583
|
+
this.options.enabled = false;
|
|
584
|
+
}
|
|
585
|
+
setLevel(level) {
|
|
586
|
+
this.options.level = level;
|
|
587
|
+
}
|
|
588
|
+
setPrefix(prefix) {
|
|
589
|
+
this.options.prefix = prefix;
|
|
590
|
+
}
|
|
591
|
+
log(level, levelName, message, ...args) {
|
|
592
|
+
if (!this.options.enabled || level > this.options.level) {
|
|
593
|
+
return;
|
|
594
|
+
}
|
|
595
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
596
|
+
const formattedMessage = `${timestamp} ${this.options.prefix} [${levelName}] ${message}`;
|
|
597
|
+
switch (level) {
|
|
598
|
+
case 0 /* ERROR */:
|
|
599
|
+
console.error(formattedMessage, ...args);
|
|
600
|
+
break;
|
|
601
|
+
case 1 /* WARN */:
|
|
602
|
+
console.warn(formattedMessage, ...args);
|
|
603
|
+
break;
|
|
604
|
+
case 2 /* INFO */:
|
|
605
|
+
console.info(formattedMessage, ...args);
|
|
606
|
+
break;
|
|
607
|
+
case 3 /* DEBUG */:
|
|
608
|
+
console.debug(formattedMessage, ...args);
|
|
609
|
+
break;
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
error(message, ...args) {
|
|
613
|
+
this.log(0 /* ERROR */, "ERROR", message, ...args);
|
|
614
|
+
}
|
|
615
|
+
warn(message, ...args) {
|
|
616
|
+
this.log(1 /* WARN */, "WARN", message, ...args);
|
|
617
|
+
}
|
|
618
|
+
info(message, ...args) {
|
|
619
|
+
this.log(2 /* INFO */, "INFO", message, ...args);
|
|
620
|
+
}
|
|
621
|
+
debug(message, ...args) {
|
|
622
|
+
this.log(3 /* DEBUG */, "DEBUG", message, ...args);
|
|
623
|
+
}
|
|
624
|
+
};
|
|
625
|
+
var createLogger = (options) => {
|
|
626
|
+
return new Logger(options);
|
|
627
|
+
};
|
|
628
|
+
var redisLogger = createLogger({ prefix: "[TernSecure-Redis]" });
|
|
629
|
+
var authLogger = createLogger({ prefix: "[TernSecure-Auth]" });
|
|
630
|
+
|
|
631
|
+
// src/utils/enableDebugLogging.ts
|
|
632
|
+
function enableDebugLogging() {
|
|
633
|
+
authLogger.enable();
|
|
634
|
+
authLogger.setLevel(3 /* DEBUG */);
|
|
635
|
+
redisLogger.enable();
|
|
636
|
+
redisLogger.setLevel(3 /* DEBUG */);
|
|
637
|
+
}
|
|
638
|
+
function disableDebugLogging() {
|
|
639
|
+
authLogger.disable();
|
|
640
|
+
redisLogger.disable();
|
|
641
|
+
}
|
|
642
|
+
function setLogLevel(level) {
|
|
643
|
+
authLogger.setLevel(level);
|
|
644
|
+
redisLogger.setLevel(level);
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
// src/adapters/PostgresAdapter.ts
|
|
648
|
+
var PostgresAdapter = class {
|
|
649
|
+
config;
|
|
650
|
+
tableName;
|
|
651
|
+
constructor(config) {
|
|
652
|
+
this.config = config;
|
|
653
|
+
this.tableName = config.table || "disabled_users";
|
|
654
|
+
}
|
|
655
|
+
getDisabledUser = async (uid) => {
|
|
656
|
+
try {
|
|
657
|
+
const response = await fetch(this.config.url, {
|
|
658
|
+
method: "POST",
|
|
659
|
+
headers: {
|
|
660
|
+
"Content-Type": "application/json",
|
|
661
|
+
"Authorization": `Bearer ${this.config.token}`
|
|
662
|
+
},
|
|
663
|
+
body: JSON.stringify({
|
|
664
|
+
query: `SELECT uid, email, disabled_time as "disabledTime" FROM ${this.tableName} WHERE uid = $1`,
|
|
665
|
+
params: [uid]
|
|
666
|
+
})
|
|
667
|
+
});
|
|
668
|
+
if (!response.ok) {
|
|
669
|
+
throw new Error(`HTTP error! status: ${response.status}`);
|
|
670
|
+
}
|
|
671
|
+
const result = await response.json();
|
|
672
|
+
if (result.rows && result.rows.length > 0) {
|
|
673
|
+
const row = result.rows[0];
|
|
674
|
+
const disabledUser = {
|
|
675
|
+
uid: row.uid,
|
|
676
|
+
email: row.email,
|
|
677
|
+
disabledTime: row.disabledTime
|
|
678
|
+
};
|
|
679
|
+
authLogger.debug(`Found disabled user: ${uid}`);
|
|
680
|
+
return disabledUser;
|
|
681
|
+
}
|
|
682
|
+
authLogger.debug(`No disabled user found: ${uid}`);
|
|
683
|
+
return null;
|
|
684
|
+
} catch (error) {
|
|
685
|
+
authLogger.error("Failed to fetch disabled user from Postgres:", error);
|
|
686
|
+
return null;
|
|
687
|
+
}
|
|
688
|
+
};
|
|
689
|
+
};
|
|
690
|
+
|
|
691
|
+
// src/adapters/RedisAdapter.ts
|
|
692
|
+
import { Redis } from "@upstash/redis";
|
|
693
|
+
var TTLCache = class {
|
|
694
|
+
cache = /* @__PURE__ */ new Map();
|
|
695
|
+
defaultTTL;
|
|
696
|
+
constructor(defaultTTLMs = 6e4) {
|
|
697
|
+
this.defaultTTL = defaultTTLMs;
|
|
698
|
+
}
|
|
699
|
+
set(key, value, ttlMs) {
|
|
700
|
+
const expiresAt = Date.now() + (ttlMs ?? this.defaultTTL);
|
|
701
|
+
this.cache.set(key, { value, expiresAt });
|
|
702
|
+
console.log(`TTLCache.set: key=${key}, value=${JSON.stringify(value)}, expiresAt=${expiresAt}, cacheSize=${this.cache.size}`);
|
|
703
|
+
}
|
|
704
|
+
getEntry(key) {
|
|
705
|
+
const entry = this.cache.get(key);
|
|
706
|
+
if (!entry) return void 0;
|
|
707
|
+
const now = Date.now();
|
|
708
|
+
if (now > entry.expiresAt) {
|
|
709
|
+
console.log(`TTLCache: key=${key} expired (now=${now}, expiresAt=${entry.expiresAt})`);
|
|
710
|
+
this.cache.delete(key);
|
|
711
|
+
return void 0;
|
|
712
|
+
}
|
|
713
|
+
return entry;
|
|
714
|
+
}
|
|
715
|
+
get(key) {
|
|
716
|
+
const entry = this.getEntry(key);
|
|
717
|
+
const hasEntry = entry !== void 0;
|
|
718
|
+
const cacheHasKey = this.cache.has(key);
|
|
719
|
+
const rawEntry = this.cache.get(key);
|
|
720
|
+
console.log(`TTLCache.get: key=${key}, hasEntry=${hasEntry}, cacheHasKey=${cacheHasKey}`);
|
|
721
|
+
console.log(`TTLCache.get: rawEntry=${JSON.stringify(rawEntry)}, entry=${JSON.stringify(entry)}`);
|
|
722
|
+
if (!entry) {
|
|
723
|
+
console.log(`TTLCache.get: no entry found for key=${key}, returning undefined`);
|
|
724
|
+
return void 0;
|
|
725
|
+
}
|
|
726
|
+
console.log(`TTLCache.get: returning value=${JSON.stringify(entry.value)} for key=${key}`);
|
|
727
|
+
return entry.value;
|
|
728
|
+
}
|
|
729
|
+
delete(key) {
|
|
730
|
+
return this.cache.delete(key);
|
|
731
|
+
}
|
|
732
|
+
clear() {
|
|
733
|
+
this.cache.clear();
|
|
734
|
+
}
|
|
735
|
+
cleanup() {
|
|
736
|
+
const now = Date.now();
|
|
737
|
+
for (const [key, entry] of this.cache.entries()) {
|
|
738
|
+
if (now > entry.expiresAt) {
|
|
739
|
+
this.cache.delete(key);
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
};
|
|
744
|
+
var RedisAdapter = class {
|
|
745
|
+
redis;
|
|
746
|
+
cache;
|
|
747
|
+
keyPrefix;
|
|
748
|
+
constructor(config) {
|
|
749
|
+
this.redis = new Redis({
|
|
750
|
+
url: config.url,
|
|
751
|
+
token: config.token
|
|
752
|
+
});
|
|
753
|
+
this.keyPrefix = config.keyPrefix || "disabled_user:";
|
|
754
|
+
const cacheTTL = config.ttl || 3e4;
|
|
755
|
+
this.cache = new TTLCache(cacheTTL);
|
|
756
|
+
setInterval(() => this.cache.cleanup(), 5 * 60 * 1e3);
|
|
757
|
+
}
|
|
758
|
+
getDisabledUser = async (uid) => {
|
|
759
|
+
const cacheKey = `${this.keyPrefix}${uid}`;
|
|
760
|
+
authLogger.debug(`RedisAdapter: Checking cache for key: ${cacheKey}`);
|
|
761
|
+
const cachedResult = this.cache.get(cacheKey);
|
|
762
|
+
authLogger.debug(`RedisAdapter: Cache get result for ${cacheKey}:`, {
|
|
763
|
+
cachedResult: JSON.stringify(cachedResult),
|
|
764
|
+
isUndefined: cachedResult === void 0,
|
|
765
|
+
type: typeof cachedResult
|
|
766
|
+
});
|
|
767
|
+
if (cachedResult !== void 0) {
|
|
768
|
+
authLogger.debug(`Cache hit for disabled user: ${uid}`, {
|
|
769
|
+
cacheKey,
|
|
770
|
+
cachedResult: JSON.stringify(cachedResult)
|
|
771
|
+
});
|
|
772
|
+
return cachedResult;
|
|
773
|
+
}
|
|
774
|
+
authLogger.debug(
|
|
775
|
+
`Cache miss for disabled user: ${uid}, fetching from Redis with key: ${cacheKey}`
|
|
776
|
+
);
|
|
777
|
+
try {
|
|
778
|
+
const disabledUser = await this.redis.get(cacheKey);
|
|
779
|
+
authLogger.debug(`Redis returned for key ${cacheKey}:`, {
|
|
780
|
+
disabledUser: JSON.stringify(disabledUser),
|
|
781
|
+
type: typeof disabledUser
|
|
782
|
+
});
|
|
783
|
+
this.cache.set(cacheKey, disabledUser);
|
|
784
|
+
authLogger.debug(`Cached disabled user result for: ${uid}`, {
|
|
785
|
+
cacheKey,
|
|
786
|
+
isDisabled: !!disabledUser,
|
|
787
|
+
cachedValue: JSON.stringify(disabledUser)
|
|
788
|
+
});
|
|
789
|
+
return disabledUser;
|
|
790
|
+
} catch (error) {
|
|
791
|
+
authLogger.error("Failed to fetch disabled user from Redis:", error);
|
|
792
|
+
return null;
|
|
793
|
+
}
|
|
794
|
+
};
|
|
795
|
+
invalidateCache(uid) {
|
|
796
|
+
const cacheKey = `${this.keyPrefix}${uid}`;
|
|
797
|
+
this.cache.delete(cacheKey);
|
|
798
|
+
}
|
|
799
|
+
};
|
|
800
|
+
|
|
801
|
+
// src/adapters/index.ts
|
|
802
|
+
function createAdapter(config) {
|
|
803
|
+
switch (config.type) {
|
|
804
|
+
case "redis":
|
|
805
|
+
return new RedisAdapter(config.config);
|
|
806
|
+
case "postgres":
|
|
807
|
+
return new PostgresAdapter(config.config);
|
|
808
|
+
default:
|
|
809
|
+
throw new Error(`Unsupported adapter type: ${config.type}`);
|
|
810
|
+
}
|
|
811
|
+
}
|
|
812
|
+
function validateCheckRevokedOptions(options) {
|
|
813
|
+
if (options?.enabled && !options.adapter) {
|
|
814
|
+
return {
|
|
815
|
+
isValid: false,
|
|
816
|
+
error: "When checkRevoked.enabled is true, an adapter must be provided"
|
|
817
|
+
};
|
|
818
|
+
}
|
|
819
|
+
return { isValid: true };
|
|
820
|
+
}
|
|
821
|
+
export {
|
|
822
|
+
AuthStatus,
|
|
823
|
+
LogLevel,
|
|
824
|
+
PostgresAdapter,
|
|
825
|
+
RedisAdapter,
|
|
826
|
+
constants,
|
|
827
|
+
createAdapter,
|
|
828
|
+
createBackendInstanceClient,
|
|
829
|
+
createFireClient,
|
|
830
|
+
createTernSecureRequest,
|
|
831
|
+
disableDebugLogging,
|
|
832
|
+
enableDebugLogging,
|
|
833
|
+
setLogLevel,
|
|
834
|
+
signedIn,
|
|
835
|
+
signedInAuthObject,
|
|
836
|
+
signedOutAuthObject,
|
|
837
|
+
validateCheckRevokedOptions
|
|
838
|
+
};
|
|
839
|
+
//# sourceMappingURL=index.mjs.map
|