@tern-secure/backend 1.1.5 → 1.1.7

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.
Files changed (159) hide show
  1. package/admin/package.json +5 -0
  2. package/dist/adapters/PostgresAdapter.d.ts +8 -0
  3. package/dist/adapters/PostgresAdapter.d.ts.map +1 -0
  4. package/dist/adapters/RedisAdapter.d.ts +10 -0
  5. package/dist/adapters/RedisAdapter.d.ts.map +1 -0
  6. package/dist/adapters/index.d.ts +13 -0
  7. package/dist/adapters/index.d.ts.map +1 -0
  8. package/dist/adapters/types.d.ts +30 -0
  9. package/dist/adapters/types.d.ts.map +1 -0
  10. package/dist/admin/gemini_sessionTernSecure.d.ts +10 -0
  11. package/dist/admin/gemini_sessionTernSecure.d.ts.map +1 -0
  12. package/dist/admin/index.d.ts +8 -0
  13. package/dist/admin/index.d.ts.map +1 -0
  14. package/dist/admin/index.js +705 -0
  15. package/dist/admin/index.js.map +1 -0
  16. package/dist/admin/index.mjs +512 -0
  17. package/dist/admin/index.mjs.map +1 -0
  18. package/dist/admin/nextSessionTernSecure.d.ts +28 -0
  19. package/dist/admin/nextSessionTernSecure.d.ts.map +1 -0
  20. package/dist/admin/sessionTernSecure.d.ts +6 -0
  21. package/dist/admin/sessionTernSecure.d.ts.map +1 -0
  22. package/dist/admin/tenant.d.ts.map +1 -0
  23. package/dist/api/createBackendApi.d.ts +8 -0
  24. package/dist/api/createBackendApi.d.ts.map +1 -0
  25. package/dist/api/endpoints/SessionApi.d.ts +12 -0
  26. package/dist/api/endpoints/SessionApi.d.ts.map +1 -0
  27. package/dist/api/endpoints/index.d.ts +2 -0
  28. package/dist/api/endpoints/index.d.ts.map +1 -0
  29. package/dist/api/index.d.ts +2 -0
  30. package/dist/api/index.d.ts.map +1 -0
  31. package/dist/api/request.d.ts +36 -0
  32. package/dist/api/request.d.ts.map +1 -0
  33. package/dist/chunk-JFOTE3Y5.mjs +157 -0
  34. package/dist/chunk-JFOTE3Y5.mjs.map +1 -0
  35. package/dist/chunk-WZYVAHZ3.mjs +318 -0
  36. package/dist/chunk-WZYVAHZ3.mjs.map +1 -0
  37. package/dist/constants.d.ts +63 -0
  38. package/dist/constants.d.ts.map +1 -0
  39. package/dist/index.d.ts +14 -0
  40. package/dist/index.d.ts.map +1 -0
  41. package/dist/index.js +1307 -0
  42. package/dist/index.js.map +1 -0
  43. package/dist/index.mjs +839 -0
  44. package/dist/index.mjs.map +1 -0
  45. package/dist/instance/backendFireInstance.d.ts +7 -0
  46. package/dist/instance/backendFireInstance.d.ts.map +1 -0
  47. package/dist/instance/backendInstance.d.ts +20 -0
  48. package/dist/instance/backendInstance.d.ts.map +1 -0
  49. package/dist/instance/backendInstanceEdge.d.ts +13 -0
  50. package/dist/instance/backendInstanceEdge.d.ts.map +1 -0
  51. package/dist/jwt/algorithms.d.ts +3 -0
  52. package/dist/jwt/algorithms.d.ts.map +1 -0
  53. package/dist/jwt/cryptoKeys.d.ts +3 -0
  54. package/dist/jwt/cryptoKeys.d.ts.map +1 -0
  55. package/dist/jwt/guardReturn.d.ts +3 -0
  56. package/dist/jwt/guardReturn.d.ts.map +1 -0
  57. package/dist/jwt/index.d.ts +4 -0
  58. package/dist/jwt/index.d.ts.map +1 -0
  59. package/dist/jwt/index.js +332 -0
  60. package/dist/jwt/index.js.map +1 -0
  61. package/dist/jwt/index.mjs +139 -0
  62. package/dist/jwt/index.mjs.map +1 -0
  63. package/dist/jwt/jwt.d.ts +4 -0
  64. package/dist/jwt/jwt.d.ts.map +1 -0
  65. package/dist/jwt/signJwt.d.ts +5 -0
  66. package/dist/jwt/signJwt.d.ts.map +1 -0
  67. package/dist/jwt/types.d.ts +8 -0
  68. package/dist/jwt/types.d.ts.map +1 -0
  69. package/dist/jwt/verifyContent.d.ts +7 -0
  70. package/dist/jwt/verifyContent.d.ts.map +1 -0
  71. package/dist/jwt/verifyJwt.d.ts +12 -0
  72. package/dist/jwt/verifyJwt.d.ts.map +1 -0
  73. package/dist/runtime/browser/crypto.mjs +1 -0
  74. package/dist/runtime/node/crypto.js +1 -0
  75. package/dist/runtime/node/crypto.mjs +1 -0
  76. package/dist/runtime.d.ts +26 -0
  77. package/dist/runtime.d.ts.map +1 -0
  78. package/dist/ternsecureauth.d.ts.map +1 -0
  79. package/dist/tokens/authstate.d.ts +61 -0
  80. package/dist/tokens/authstate.d.ts.map +1 -0
  81. package/dist/tokens/keys.d.ts +16 -0
  82. package/dist/tokens/keys.d.ts.map +1 -0
  83. package/dist/tokens/request.d.ts +16 -0
  84. package/dist/tokens/request.d.ts.map +1 -0
  85. package/dist/tokens/requestFire.d.ts +17 -0
  86. package/dist/tokens/requestFire.d.ts.map +1 -0
  87. package/dist/tokens/sessionConfig.d.ts +14 -0
  88. package/dist/tokens/sessionConfig.d.ts.map +1 -0
  89. package/dist/tokens/ternSecureRequest.d.ts +20 -0
  90. package/dist/tokens/ternSecureRequest.d.ts.map +1 -0
  91. package/dist/tokens/ternUrl.d.ts +15 -0
  92. package/dist/tokens/ternUrl.d.ts.map +1 -0
  93. package/dist/tokens/types.d.ts +41 -0
  94. package/dist/tokens/types.d.ts.map +1 -0
  95. package/dist/tokens/verify.d.ts +11 -0
  96. package/dist/tokens/verify.d.ts.map +1 -0
  97. package/dist/utils/admin-init.d.ts +13 -0
  98. package/dist/utils/admin-init.d.ts.map +1 -0
  99. package/dist/{types/utils → utils}/config.d.ts +1 -1
  100. package/dist/utils/config.d.ts.map +1 -0
  101. package/dist/utils/enableDebugLogging.d.ts +5 -0
  102. package/dist/utils/enableDebugLogging.d.ts.map +1 -0
  103. package/dist/utils/errors.d.ts +29 -0
  104. package/dist/utils/errors.d.ts.map +1 -0
  105. package/dist/utils/gemini_admin-init.d.ts +10 -0
  106. package/dist/utils/gemini_admin-init.d.ts.map +1 -0
  107. package/dist/utils/logger.d.ts +28 -0
  108. package/dist/utils/logger.d.ts.map +1 -0
  109. package/dist/utils/mapDecode.d.ts +4 -0
  110. package/dist/utils/mapDecode.d.ts.map +1 -0
  111. package/dist/utils/options.d.ts +5 -0
  112. package/dist/utils/options.d.ts.map +1 -0
  113. package/dist/utils/path.d.ts +4 -0
  114. package/dist/utils/path.d.ts.map +1 -0
  115. package/dist/utils/redis.d.ts +10 -0
  116. package/dist/utils/redis.d.ts.map +1 -0
  117. package/dist/utils/rfc4648.d.ts +26 -0
  118. package/dist/utils/rfc4648.d.ts.map +1 -0
  119. package/jwt/package.json +5 -0
  120. package/package.json +58 -10
  121. package/dist/cjs/admin/sessionTernSecure.js +0 -256
  122. package/dist/cjs/admin/sessionTernSecure.js.map +0 -1
  123. package/dist/cjs/admin/tenant.js +0 -68
  124. package/dist/cjs/admin/tenant.js.map +0 -1
  125. package/dist/cjs/global.d.js +0 -2
  126. package/dist/cjs/global.d.js.map +0 -1
  127. package/dist/cjs/index.js +0 -48
  128. package/dist/cjs/index.js.map +0 -1
  129. package/dist/cjs/ternsecureauth.js +0 -40
  130. package/dist/cjs/ternsecureauth.js.map +0 -1
  131. package/dist/cjs/utils/admin-init.js +0 -60
  132. package/dist/cjs/utils/admin-init.js.map +0 -1
  133. package/dist/cjs/utils/config.js +0 -113
  134. package/dist/cjs/utils/config.js.map +0 -1
  135. package/dist/esm/admin/sessionTernSecure.js +0 -226
  136. package/dist/esm/admin/sessionTernSecure.js.map +0 -1
  137. package/dist/esm/admin/tenant.js +0 -43
  138. package/dist/esm/admin/tenant.js.map +0 -1
  139. package/dist/esm/global.d.js +0 -1
  140. package/dist/esm/global.d.js.map +0 -1
  141. package/dist/esm/index.js +0 -24
  142. package/dist/esm/index.js.map +0 -1
  143. package/dist/esm/ternsecureauth.js +0 -16
  144. package/dist/esm/ternsecureauth.js.map +0 -1
  145. package/dist/esm/utils/admin-init.js +0 -24
  146. package/dist/esm/utils/admin-init.js.map +0 -1
  147. package/dist/esm/utils/config.js +0 -84
  148. package/dist/esm/utils/config.js.map +0 -1
  149. package/dist/types/admin/sessionTernSecure.d.ts +0 -36
  150. package/dist/types/admin/sessionTernSecure.d.ts.map +0 -1
  151. package/dist/types/admin/tenant.d.ts.map +0 -1
  152. package/dist/types/index.d.ts +0 -5
  153. package/dist/types/index.d.ts.map +0 -1
  154. package/dist/types/ternsecureauth.d.ts.map +0 -1
  155. package/dist/types/utils/admin-init.d.ts +0 -5
  156. package/dist/types/utils/admin-init.d.ts.map +0 -1
  157. package/dist/types/utils/config.d.ts.map +0 -1
  158. /package/dist/{types/admin → admin}/tenant.d.ts +0 -0
  159. /package/dist/{types/ternsecureauth.d.ts → ternsecureauth.d.ts} +0 -0
package/dist/index.js ADDED
@@ -0,0 +1,1307 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ AuthStatus: () => AuthStatus,
24
+ LogLevel: () => LogLevel,
25
+ PostgresAdapter: () => PostgresAdapter,
26
+ RedisAdapter: () => RedisAdapter,
27
+ constants: () => constants,
28
+ createAdapter: () => createAdapter,
29
+ createBackendInstanceClient: () => createBackendInstanceClient,
30
+ createFireClient: () => createFireClient,
31
+ createTernSecureRequest: () => createTernSecureRequest,
32
+ disableDebugLogging: () => disableDebugLogging,
33
+ enableDebugLogging: () => enableDebugLogging,
34
+ setLogLevel: () => setLogLevel,
35
+ signedIn: () => signedIn,
36
+ signedInAuthObject: () => signedInAuthObject,
37
+ signedOutAuthObject: () => signedOutAuthObject,
38
+ validateCheckRevokedOptions: () => validateCheckRevokedOptions
39
+ });
40
+ module.exports = __toCommonJS(index_exports);
41
+
42
+ // src/constants.ts
43
+ var SESSION_COOKIE_PUBLIC_KEYS_URL = "https://www.googleapis.com/identitytoolkit/v3/relyingparty/publicKeys";
44
+ var MAX_CACHE_LAST_UPDATED_AT_SECONDS = 5 * 60;
45
+ var DEFAULT_CACHE_DURATION = 3600 * 1e3;
46
+ var CACHE_CONTROL_REGEX = /max-age=(\d+)/;
47
+ var Attributes = {
48
+ AuthToken: "__ternsecureAuthToken",
49
+ AuthSignature: "__ternsecureAuthSignature",
50
+ AuthStatus: "__ternsecureAuthStatus",
51
+ AuthReason: "__ternsecureAuthReason",
52
+ AuthMessage: "__ternsecureAuthMessage",
53
+ TernSecureUrl: "__ternsecureUrl"
54
+ };
55
+ var Cookies = {
56
+ Session: "__session",
57
+ IdToken: "_tern",
58
+ SessionCookie: "_session_cookie",
59
+ SessionToken: "_session_token",
60
+ Refresh: "__refresh",
61
+ Handshake: "__ternsecure_handshake",
62
+ DevBrowser: "__ternsecure_db_jwt",
63
+ RedirectCount: "__ternsecure_redirect_count",
64
+ HandshakeNonce: "__ternsecure_handshake_nonce"
65
+ };
66
+ var Headers2 = {
67
+ Accept: "accept",
68
+ AuthMessage: "x-ternsecure-auth-message",
69
+ Authorization: "authorization",
70
+ AuthReason: "x-ternsecure-auth-reason",
71
+ AuthSignature: "x-ternsecure-auth-signature",
72
+ AuthStatus: "x-ternsecure-auth-status",
73
+ AuthToken: "x-ternsecure-auth-token",
74
+ CacheControl: "cache-control",
75
+ TernSecureRedirectTo: "x-ternsecure-redirect-to",
76
+ TernSecureRequestData: "x-ternsecure-request-data",
77
+ TernSecureUrl: "x-ternsecure-url",
78
+ CloudFrontForwardedProto: "cloudfront-forwarded-proto",
79
+ ContentType: "content-type",
80
+ ContentSecurityPolicy: "content-security-policy",
81
+ ContentSecurityPolicyReportOnly: "content-security-policy-report-only",
82
+ EnableDebug: "x-ternsecure-debug",
83
+ ForwardedHost: "x-forwarded-host",
84
+ ForwardedPort: "x-forwarded-port",
85
+ ForwardedProto: "x-forwarded-proto",
86
+ Host: "host",
87
+ Location: "location",
88
+ Nonce: "x-nonce",
89
+ Origin: "origin",
90
+ Referrer: "referer",
91
+ SecFetchDest: "sec-fetch-dest",
92
+ UserAgent: "user-agent",
93
+ ReportingEndpoints: "reporting-endpoints"
94
+ };
95
+ var ContentTypes = {
96
+ Json: "application/json"
97
+ };
98
+ var constants = {
99
+ Attributes,
100
+ Cookies,
101
+ Headers: Headers2,
102
+ ContentTypes
103
+ };
104
+
105
+ // src/tokens/ternSecureRequest.ts
106
+ var import_cookie = require("cookie");
107
+
108
+ // src/tokens/ternUrl.ts
109
+ var TernUrl = class extends URL {
110
+ isCrossOrigin(other) {
111
+ return this.origin !== new URL(other.toString()).origin;
112
+ }
113
+ };
114
+ var createTernUrl = (...args) => {
115
+ return new TernUrl(...args);
116
+ };
117
+
118
+ // src/tokens/ternSecureRequest.ts
119
+ var TernSecureRequest = class extends Request {
120
+ ternUrl;
121
+ cookies;
122
+ constructor(input, init) {
123
+ const url = typeof input !== "string" && "url" in input ? input.url : String(input);
124
+ super(url, init || typeof input === "string" ? void 0 : input);
125
+ this.ternUrl = this.deriveUrlFromHeaders(this);
126
+ this.cookies = this.parseCookies(this);
127
+ }
128
+ toJSON() {
129
+ return {
130
+ url: this.ternUrl.href,
131
+ method: this.method,
132
+ headers: JSON.stringify(Object.fromEntries(this.headers)),
133
+ ternUrl: this.ternUrl.toString(),
134
+ cookies: JSON.stringify(Object.fromEntries(this.cookies))
135
+ };
136
+ }
137
+ deriveUrlFromHeaders(req) {
138
+ const initialUrl = new URL(req.url);
139
+ const forwardedProto = req.headers.get(constants.Headers.ForwardedProto);
140
+ const forwardedHost = req.headers.get(constants.Headers.ForwardedHost);
141
+ const host = req.headers.get(constants.Headers.Host);
142
+ const protocol = initialUrl.protocol;
143
+ const resolvedHost = this.getFirstValueFromHeader(forwardedHost) ?? host;
144
+ const resolvedProtocol = this.getFirstValueFromHeader(forwardedProto) ?? protocol?.replace(/[:/]/, "");
145
+ const origin = resolvedHost && resolvedProtocol ? `${resolvedProtocol}://${resolvedHost}` : initialUrl.origin;
146
+ if (origin === initialUrl.origin) {
147
+ return createTernUrl(initialUrl);
148
+ }
149
+ return createTernUrl(initialUrl.pathname + initialUrl.search, origin);
150
+ }
151
+ getFirstValueFromHeader(value) {
152
+ return value?.split(",")[0];
153
+ }
154
+ parseCookies(req) {
155
+ const cookiesRecord = (0, import_cookie.parse)(
156
+ this.decodeCookieValue(req.headers.get("cookie") || "")
157
+ );
158
+ return new Map(Object.entries(cookiesRecord));
159
+ }
160
+ decodeCookieValue(str) {
161
+ return str ? str.replace(/(%[0-9A-Z]{2})+/g, decodeURIComponent) : str;
162
+ }
163
+ };
164
+ var createTernSecureRequest = (...args) => {
165
+ return args[0] instanceof TernSecureRequest ? args[0] : new TernSecureRequest(...args);
166
+ };
167
+
168
+ // src/utils/mapDecode.ts
169
+ function mapJwtPayloadToDecodedIdToken(payload) {
170
+ const decodedIdToken = payload;
171
+ decodedIdToken.uid = decodedIdToken.sub;
172
+ return decodedIdToken;
173
+ }
174
+
175
+ // src/tokens/authstate.ts
176
+ var AuthStatus = {
177
+ SignedIn: "signed-in",
178
+ SignedOut: "signed-out"
179
+ };
180
+ var AuthErrorReason = {
181
+ SessionTokenAndUATMissing: "session-token-and-uat-missing",
182
+ SessionTokenMissing: "session-token-missing",
183
+ SessionTokenExpired: "session-token-expired",
184
+ SessionTokenIATBeforeClientUAT: "session-token-iat-before-client-uat",
185
+ SessionTokenNBF: "session-token-nbf",
186
+ SessionTokenIatInTheFuture: "session-token-iat-in-the-future",
187
+ ActiveOrganizationMismatch: "active-organization-mismatch",
188
+ UnexpectedError: "unexpected-error"
189
+ };
190
+ function createHasAuthorization(decodedIdToken) {
191
+ return (authorizationParams) => {
192
+ if (!authorizationParams || typeof authorizationParams !== "object" || Array.isArray(authorizationParams)) {
193
+ return false;
194
+ }
195
+ const claims = decodedIdToken;
196
+ return Object.entries(authorizationParams).every(([key, value]) => {
197
+ const claimValue = claims[key];
198
+ if (typeof claimValue === "undefined") {
199
+ return false;
200
+ }
201
+ if (Array.isArray(value)) {
202
+ if (Array.isArray(claimValue)) {
203
+ return value.some((v) => claimValue.includes(v));
204
+ }
205
+ return value.includes(claimValue);
206
+ }
207
+ if (Array.isArray(claimValue)) {
208
+ return claimValue.includes(value);
209
+ }
210
+ return claimValue === value;
211
+ });
212
+ };
213
+ }
214
+ function signedInAuthObject(sessionToken, sessionClaims) {
215
+ const decodedIdToken = mapJwtPayloadToDecodedIdToken(sessionClaims);
216
+ return {
217
+ sessionClaims: {
218
+ ...decodedIdToken
219
+ },
220
+ userId: decodedIdToken.uid,
221
+ token: sessionToken,
222
+ require: createHasAuthorization(decodedIdToken),
223
+ error: null
224
+ };
225
+ }
226
+ function signedOutAuthObject() {
227
+ return {
228
+ sessionClaims: null,
229
+ userId: null,
230
+ require: () => false,
231
+ error: "No active session"
232
+ };
233
+ }
234
+ function signedIn(sessionClaims, headers = new Headers(), token) {
235
+ const authObject = signedInAuthObject(token, sessionClaims);
236
+ return {
237
+ status: AuthStatus.SignedIn,
238
+ reason: null,
239
+ isSignedIn: true,
240
+ auth: () => authObject,
241
+ token,
242
+ headers
243
+ };
244
+ }
245
+ function signedOut(reason, headers = new Headers()) {
246
+ return decorateHeaders({
247
+ status: AuthStatus.SignedOut,
248
+ reason,
249
+ isSignedIn: false,
250
+ auth: () => signedOutAuthObject(),
251
+ token: null,
252
+ headers
253
+ });
254
+ }
255
+ var decorateHeaders = (requestState) => {
256
+ const headers = new Headers(requestState.headers || {});
257
+ if (requestState.reason) {
258
+ try {
259
+ headers.set(constants.Headers.AuthReason, requestState.reason);
260
+ } catch {
261
+ }
262
+ }
263
+ if (requestState.status) {
264
+ try {
265
+ headers.set(constants.Headers.AuthStatus, requestState.status);
266
+ } catch {
267
+ }
268
+ }
269
+ requestState.headers = headers;
270
+ return requestState;
271
+ };
272
+
273
+ // src/api/endpoints/SessionApi.ts
274
+ var rootPath = "/sessions";
275
+ var SessionApi = class {
276
+ constructor(request) {
277
+ this.request = request;
278
+ }
279
+ async createSession(params) {
280
+ return this.request({
281
+ method: "POST",
282
+ path: rootPath,
283
+ bodyParams: params
284
+ });
285
+ }
286
+ };
287
+
288
+ // src/runtime.ts
289
+ var import_crypto = require("#crypto");
290
+ var globalFetch = fetch.bind(globalThis);
291
+ var runtime = {
292
+ crypto: import_crypto.webcrypto,
293
+ get fetch() {
294
+ return process.env.NODE_ENV === "test" ? fetch : globalFetch;
295
+ },
296
+ AbortController: globalThis.AbortController,
297
+ Blob: globalThis.Blob,
298
+ FormData: globalThis.FormData,
299
+ Headers: globalThis.Headers,
300
+ Request: globalThis.Request,
301
+ Response: globalThis.Response
302
+ };
303
+
304
+ // src/utils/path.ts
305
+ var SEPARATOR = "/";
306
+ var MULTIPLE_SEPARATOR_REGEX = new RegExp("(?<!:)" + SEPARATOR + "{1,}", "g");
307
+ function joinPaths(...args) {
308
+ return args.filter((p) => p).join(SEPARATOR).replace(MULTIPLE_SEPARATOR_REGEX, SEPARATOR);
309
+ }
310
+
311
+ // src/api/request.ts
312
+ function createRequest(options) {
313
+ const requestFn = async (requestOptions) => {
314
+ const { apiUrl, apiVersion } = options;
315
+ const { path, method, queryParams, headerParams, bodyParams, formData } = requestOptions;
316
+ const url = joinPaths(apiUrl, apiVersion, path);
317
+ const finalUrl = new URL(url);
318
+ if (queryParams) {
319
+ Object.entries(queryParams).forEach(([key, value]) => {
320
+ if (value) {
321
+ [value].flat().forEach((v) => finalUrl.searchParams.append(key, v));
322
+ }
323
+ });
324
+ }
325
+ const headers = {
326
+ ...headerParams
327
+ };
328
+ let res;
329
+ try {
330
+ if (formData) {
331
+ res = await runtime.fetch(finalUrl.href, {
332
+ method,
333
+ headers,
334
+ body: formData
335
+ });
336
+ } else {
337
+ headers["Content-Type"] = "application/json";
338
+ const hasBody = method !== "GET" && bodyParams && Object.keys(bodyParams).length > 0;
339
+ const body = hasBody ? { body: JSON.stringify(bodyParams) } : null;
340
+ res = await runtime.fetch(finalUrl.href, {
341
+ method,
342
+ headers,
343
+ ...body
344
+ });
345
+ }
346
+ const isJSONResponse = res?.headers && res.headers?.get(constants.Headers.ContentType) === constants.ContentTypes.Json;
347
+ const responseBody = await (isJSONResponse ? res.json() : res.text());
348
+ if (!res.ok) {
349
+ return {
350
+ data: null,
351
+ errors: parseErrors(responseBody),
352
+ status: res?.status,
353
+ statusText: res?.statusText
354
+ };
355
+ }
356
+ return {
357
+ data: responseBody,
358
+ errors: null
359
+ };
360
+ } catch (error) {
361
+ if (error instanceof Error) {
362
+ return {
363
+ data: null,
364
+ errors: [
365
+ {
366
+ code: "unexpected_error",
367
+ message: error.message || "An unexpected error occurred"
368
+ }
369
+ ]
370
+ };
371
+ }
372
+ return {
373
+ data: null,
374
+ errors: parseErrors(error),
375
+ status: res?.status,
376
+ statusText: res?.statusText
377
+ };
378
+ }
379
+ };
380
+ return requestFn;
381
+ }
382
+ function parseErrors(data) {
383
+ if (!!data && typeof data === "object" && "errors" in data) {
384
+ const errors = data.errors;
385
+ return errors.length > 0 ? errors.map(parseError) : [];
386
+ }
387
+ return [];
388
+ }
389
+ function parseError(error) {
390
+ return {
391
+ code: error.code,
392
+ message: error.message
393
+ };
394
+ }
395
+
396
+ // src/api/createBackendApi.ts
397
+ function createBackendApi(options) {
398
+ const request = createRequest(options);
399
+ return {
400
+ sessions: new SessionApi(request)
401
+ };
402
+ }
403
+
404
+ // src/utils/options.ts
405
+ var defaultOptions = {
406
+ apiUrl: void 0,
407
+ apiVersion: void 0
408
+ };
409
+ function mergePreDefinedOptions(userOptions = {}) {
410
+ return {
411
+ ...defaultOptions,
412
+ ...userOptions
413
+ };
414
+ }
415
+
416
+ // src/tokens/sessionConfig.ts
417
+ var getSessionConfig = (options) => {
418
+ const cookieConfig = options?.cookies?.session_cookie;
419
+ return {
420
+ COOKIE_NAME: cookieConfig?.name,
421
+ DEFAULT_EXPIRES_IN_MS: cookieConfig?.attributes?.maxAge,
422
+ DEFAULT_EXPIRES_IN_SECONDS: Math.floor((cookieConfig?.attributes?.maxAge || 0) / 1e3),
423
+ REVOKE_REFRESH_TOKENS_ON_SIGNOUT: cookieConfig?.revokeRefreshTokensOnSignOut
424
+ };
425
+ };
426
+
427
+ // src/jwt/verifyJwt.ts
428
+ var import_jose2 = require("jose");
429
+
430
+ // src/utils/errors.ts
431
+ var TokenVerificationErrorReason = {
432
+ TokenExpired: "token-expired",
433
+ TokenInvalid: "token-invalid",
434
+ TokenInvalidAlgorithm: "token-invalid-algorithm",
435
+ TokenInvalidAuthorizedParties: "token-invalid-authorized-parties",
436
+ TokenInvalidSignature: "token-invalid-signature",
437
+ TokenNotActiveYet: "token-not-active-yet",
438
+ TokenIatInTheFuture: "token-iat-in-the-future",
439
+ TokenVerificationFailed: "token-verification-failed",
440
+ InvalidSecretKey: "secret-key-invalid",
441
+ LocalJWKMissing: "jwk-local-missing",
442
+ RemoteJWKFailedToLoad: "jwk-remote-failed-to-load",
443
+ RemoteJWKInvalid: "jwk-remote-invalid",
444
+ RemoteJWKMissing: "jwk-remote-missing",
445
+ JWKFailedToResolve: "jwk-failed-to-resolve",
446
+ JWKKidMismatch: "jwk-kid-mismatch"
447
+ };
448
+ var TokenVerificationError = class _TokenVerificationError extends Error {
449
+ reason;
450
+ tokenCarrier;
451
+ constructor({
452
+ message,
453
+ reason
454
+ }) {
455
+ super(message);
456
+ Object.setPrototypeOf(this, _TokenVerificationError.prototype);
457
+ this.reason = reason;
458
+ this.message = message;
459
+ }
460
+ getFullMessage() {
461
+ return `${[this.message].filter((m) => m).join(" ")} (reason=${this.reason}, token-carrier=${this.tokenCarrier})`;
462
+ }
463
+ };
464
+
465
+ // src/utils/rfc4648.ts
466
+ var base64url = {
467
+ parse(string, opts) {
468
+ return parse2(string, base64UrlEncoding, opts);
469
+ },
470
+ stringify(data, opts) {
471
+ return stringify(data, base64UrlEncoding, opts);
472
+ }
473
+ };
474
+ var base64UrlEncoding = {
475
+ chars: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_",
476
+ bits: 6
477
+ };
478
+ function parse2(string, encoding, opts = {}) {
479
+ if (!encoding.codes) {
480
+ encoding.codes = {};
481
+ for (let i = 0; i < encoding.chars.length; ++i) {
482
+ encoding.codes[encoding.chars[i]] = i;
483
+ }
484
+ }
485
+ if (!opts.loose && string.length * encoding.bits & 7) {
486
+ throw new SyntaxError("Invalid padding");
487
+ }
488
+ let end = string.length;
489
+ while (string[end - 1] === "=") {
490
+ --end;
491
+ if (!opts.loose && !((string.length - end) * encoding.bits & 7)) {
492
+ throw new SyntaxError("Invalid padding");
493
+ }
494
+ }
495
+ const out = new (opts.out ?? Uint8Array)(end * encoding.bits / 8 | 0);
496
+ let bits = 0;
497
+ let buffer = 0;
498
+ let written = 0;
499
+ for (let i = 0; i < end; ++i) {
500
+ const value = encoding.codes[string[i]];
501
+ if (value === void 0) {
502
+ throw new SyntaxError("Invalid character " + string[i]);
503
+ }
504
+ buffer = buffer << encoding.bits | value;
505
+ bits += encoding.bits;
506
+ if (bits >= 8) {
507
+ bits -= 8;
508
+ out[written++] = 255 & buffer >> bits;
509
+ }
510
+ }
511
+ if (bits >= encoding.bits || 255 & buffer << 8 - bits) {
512
+ throw new SyntaxError("Unexpected end of data");
513
+ }
514
+ return out;
515
+ }
516
+ function stringify(data, encoding, opts = {}) {
517
+ const { pad = true } = opts;
518
+ const mask = (1 << encoding.bits) - 1;
519
+ let out = "";
520
+ let bits = 0;
521
+ let buffer = 0;
522
+ for (let i = 0; i < data.length; ++i) {
523
+ buffer = buffer << 8 | 255 & data[i];
524
+ bits += 8;
525
+ while (bits > encoding.bits) {
526
+ bits -= encoding.bits;
527
+ out += encoding.chars[mask & buffer >> bits];
528
+ }
529
+ }
530
+ if (bits) {
531
+ out += encoding.chars[mask & buffer << encoding.bits - bits];
532
+ }
533
+ if (pad) {
534
+ while (out.length * encoding.bits & 7) {
535
+ out += "=";
536
+ }
537
+ }
538
+ return out;
539
+ }
540
+
541
+ // src/jwt/cryptoKeys.ts
542
+ var import_jose = require("jose");
543
+ async function importKey(key, algorithm) {
544
+ if (typeof key === "object") {
545
+ const result = await (0, import_jose.importJWK)(key, algorithm);
546
+ if (result instanceof Uint8Array) {
547
+ throw new Error("Unexpected Uint8Array result from JWK import");
548
+ }
549
+ return result;
550
+ }
551
+ const keyString = key.trim();
552
+ if (keyString.includes("-----BEGIN CERTIFICATE-----")) {
553
+ return await (0, import_jose.importX509)(keyString, algorithm);
554
+ }
555
+ if (keyString.includes("-----BEGIN PUBLIC KEY-----")) {
556
+ return await (0, import_jose.importSPKI)(keyString, algorithm);
557
+ }
558
+ try {
559
+ return await (0, import_jose.importSPKI)(keyString, algorithm);
560
+ } catch (error) {
561
+ throw new Error(
562
+ `Unsupported key format. Supported formats: X.509 certificate (PEM), SPKI (PEM), JWK (JSON object or string). Error: ${error}`
563
+ );
564
+ }
565
+ }
566
+
567
+ // src/jwt/algorithms.ts
568
+ var algToHash = {
569
+ RS256: "SHA-256",
570
+ RS384: "SHA-384",
571
+ RS512: "SHA-512"
572
+ };
573
+ var algs = Object.keys(algToHash);
574
+
575
+ // src/jwt/verifyContent.ts
576
+ var verifyHeaderKid = (kid) => {
577
+ if (typeof kid === "undefined") {
578
+ return;
579
+ }
580
+ if (typeof kid !== "string") {
581
+ throw new TokenVerificationError({
582
+ reason: TokenVerificationErrorReason.TokenInvalid,
583
+ message: `Invalid JWT kid ${JSON.stringify(kid)}. Expected a string.`
584
+ });
585
+ }
586
+ };
587
+ var verifySubClaim = (sub) => {
588
+ if (typeof sub !== "string") {
589
+ throw new TokenVerificationError({
590
+ reason: TokenVerificationErrorReason.TokenVerificationFailed,
591
+ message: `Subject claim (sub) is required and must be a string. Received ${JSON.stringify(sub)}.`
592
+ });
593
+ }
594
+ };
595
+ var verifyExpirationClaim = (exp, clockSkewInMs) => {
596
+ if (typeof exp !== "number") {
597
+ throw new TokenVerificationError({
598
+ reason: TokenVerificationErrorReason.TokenVerificationFailed,
599
+ message: `Invalid JWT expiry date (exp) claim ${JSON.stringify(exp)}. Expected a number.`
600
+ });
601
+ }
602
+ const currentDate = new Date(Date.now());
603
+ const expiryDate = /* @__PURE__ */ new Date(0);
604
+ expiryDate.setUTCSeconds(exp);
605
+ const expired = expiryDate.getTime() <= currentDate.getTime() - clockSkewInMs;
606
+ if (expired) {
607
+ throw new TokenVerificationError({
608
+ reason: TokenVerificationErrorReason.TokenExpired,
609
+ message: `JWT is expired. Expiry date: ${expiryDate.toUTCString()}, Current date: ${currentDate.toUTCString()}.`
610
+ });
611
+ }
612
+ };
613
+ var verifyIssuedAtClaim = (iat, clockSkewInMs) => {
614
+ if (typeof iat === "undefined") {
615
+ return;
616
+ }
617
+ if (typeof iat !== "number") {
618
+ throw new TokenVerificationError({
619
+ reason: TokenVerificationErrorReason.TokenVerificationFailed,
620
+ message: `Invalid JWT issued at date claim (iat) ${JSON.stringify(iat)}. Expected a number.`
621
+ });
622
+ }
623
+ const currentDate = new Date(Date.now());
624
+ const issuedAtDate = /* @__PURE__ */ new Date(0);
625
+ issuedAtDate.setUTCSeconds(iat);
626
+ const postIssued = issuedAtDate.getTime() > currentDate.getTime() + clockSkewInMs;
627
+ if (postIssued) {
628
+ throw new TokenVerificationError({
629
+ reason: TokenVerificationErrorReason.TokenIatInTheFuture,
630
+ message: `JWT issued at date claim (iat) is in the future. Issued at date: ${issuedAtDate.toUTCString()}; Current date: ${currentDate.toUTCString()};`
631
+ });
632
+ }
633
+ };
634
+
635
+ // src/jwt/verifyJwt.ts
636
+ var DEFAULT_CLOCK_SKEW_IN_MS = 5 * 1e3;
637
+ async function verifySignature(jwt, key) {
638
+ const { header, raw } = jwt;
639
+ const joseAlgorithm = header.alg || "RS256";
640
+ try {
641
+ const publicKey = await importKey(key, joseAlgorithm);
642
+ const { payload } = await (0, import_jose2.jwtVerify)(raw.text, publicKey);
643
+ return { data: payload };
644
+ } catch (error) {
645
+ return {
646
+ errors: [
647
+ new TokenVerificationError({
648
+ reason: TokenVerificationErrorReason.TokenInvalidSignature,
649
+ message: error.message
650
+ })
651
+ ]
652
+ };
653
+ }
654
+ }
655
+ function ternDecodeJwt(token) {
656
+ try {
657
+ const header = (0, import_jose2.decodeProtectedHeader)(token);
658
+ const payload = (0, import_jose2.decodeJwt)(token);
659
+ const tokenParts = (token || "").toString().split(".");
660
+ if (tokenParts.length !== 3) {
661
+ return {
662
+ errors: [
663
+ new TokenVerificationError({
664
+ reason: TokenVerificationErrorReason.TokenInvalid,
665
+ message: "Invalid JWT format"
666
+ })
667
+ ]
668
+ };
669
+ }
670
+ const [rawHeader, rawPayload, rawSignature] = tokenParts;
671
+ const signature = base64url.parse(rawSignature, { loose: true });
672
+ const data = {
673
+ header,
674
+ payload,
675
+ signature,
676
+ raw: {
677
+ header: rawHeader,
678
+ payload: rawPayload,
679
+ signature: rawSignature,
680
+ text: token
681
+ }
682
+ };
683
+ return { data };
684
+ } catch (error) {
685
+ return {
686
+ errors: [
687
+ new TokenVerificationError({
688
+ reason: TokenVerificationErrorReason.TokenInvalid,
689
+ message: error.message
690
+ })
691
+ ]
692
+ };
693
+ }
694
+ }
695
+ async function verifyJwt(token, options) {
696
+ const { key } = options;
697
+ const clockSkew = options.clockSkewInMs || DEFAULT_CLOCK_SKEW_IN_MS;
698
+ const { data: decoded, errors } = ternDecodeJwt(token);
699
+ if (errors) {
700
+ return { errors };
701
+ }
702
+ const { header, payload } = decoded;
703
+ try {
704
+ verifyHeaderKid(header.kid);
705
+ verifySubClaim(payload.sub);
706
+ verifyExpirationClaim(payload.exp, clockSkew);
707
+ verifyIssuedAtClaim(payload.iat, clockSkew);
708
+ } catch (error) {
709
+ return { errors: [error] };
710
+ }
711
+ const { data: verifiedPayload, errors: signatureErrors } = await verifySignature(decoded, key);
712
+ if (signatureErrors) {
713
+ return {
714
+ errors: [
715
+ new TokenVerificationError({
716
+ reason: TokenVerificationErrorReason.TokenInvalidSignature,
717
+ message: "Token signature verification failed."
718
+ })
719
+ ]
720
+ };
721
+ }
722
+ const decodedIdToken = mapJwtPayloadToDecodedIdToken(verifiedPayload);
723
+ return { data: decodedIdToken };
724
+ }
725
+
726
+ // src/tokens/keys.ts
727
+ var cache = {};
728
+ var lastUpdatedAt = 0;
729
+ var googleExpiresAt = 0;
730
+ function getFromCache(kid) {
731
+ return cache[kid];
732
+ }
733
+ function getCacheValues() {
734
+ return Object.values(cache);
735
+ }
736
+ function setInCache(kid, certificate, shouldExpire = true) {
737
+ cache[kid] = certificate;
738
+ lastUpdatedAt = shouldExpire ? Date.now() : -1;
739
+ }
740
+ async function fetchPublicKeys(keyUrl) {
741
+ const url = new URL(keyUrl);
742
+ const response = await fetch(url);
743
+ if (!response.ok) {
744
+ throw new TokenVerificationError({
745
+ message: `Error loading public keys from ${url.href} with code=${response.status} `,
746
+ reason: TokenVerificationErrorReason.TokenInvalid
747
+ });
748
+ }
749
+ const data = await response.json();
750
+ const expiresAt = getExpiresAt(response);
751
+ return {
752
+ keys: data,
753
+ expiresAt
754
+ };
755
+ }
756
+ async function loadJWKFromRemote({
757
+ keyURL = SESSION_COOKIE_PUBLIC_KEYS_URL,
758
+ skipJwksCache,
759
+ kid
760
+ }) {
761
+ if (skipJwksCache || isCacheExpired() || !getFromCache(kid)) {
762
+ const { keys, expiresAt } = await fetchPublicKeys(keyURL);
763
+ if (!keys || Object.keys(keys).length === 0) {
764
+ throw new TokenVerificationError({
765
+ message: `The JWKS endpoint ${keyURL} returned no keys`,
766
+ reason: TokenVerificationErrorReason.RemoteJWKFailedToLoad
767
+ });
768
+ }
769
+ googleExpiresAt = expiresAt;
770
+ Object.entries(keys).forEach(([keyId, cert2]) => {
771
+ setInCache(keyId, cert2);
772
+ });
773
+ }
774
+ const cert = getFromCache(kid);
775
+ if (!cert) {
776
+ getCacheValues();
777
+ const availableKids = Object.keys(cache).sort().join(", ");
778
+ throw new TokenVerificationError({
779
+ message: `No public key found for kid "${kid}". Available kids: [${availableKids}]`,
780
+ reason: TokenVerificationErrorReason.TokenInvalid
781
+ });
782
+ }
783
+ return cert;
784
+ }
785
+ function isCacheExpired() {
786
+ const now = Date.now();
787
+ if (lastUpdatedAt === -1) {
788
+ return false;
789
+ }
790
+ const cacheAge = now - lastUpdatedAt;
791
+ const maxCacheAge = MAX_CACHE_LAST_UPDATED_AT_SECONDS * 1e3;
792
+ const localCacheExpired = cacheAge >= maxCacheAge;
793
+ const googleCacheExpired = now >= googleExpiresAt;
794
+ const isExpired = localCacheExpired || googleCacheExpired;
795
+ if (isExpired) {
796
+ cache = {};
797
+ }
798
+ return isExpired;
799
+ }
800
+ function getExpiresAt(res) {
801
+ const cacheControlHeader = res.headers.get("cache-control");
802
+ if (!cacheControlHeader) {
803
+ return Date.now() + DEFAULT_CACHE_DURATION;
804
+ }
805
+ const maxAgeMatch = cacheControlHeader.match(CACHE_CONTROL_REGEX);
806
+ const maxAge = maxAgeMatch ? parseInt(maxAgeMatch[1], 10) : DEFAULT_CACHE_DURATION / 1e3;
807
+ return Date.now() + maxAge * 1e3;
808
+ }
809
+
810
+ // src/tokens/verify.ts
811
+ async function verifyToken(token, options) {
812
+ const { data: decodedResult, errors } = ternDecodeJwt(token);
813
+ if (errors) {
814
+ return { errors };
815
+ }
816
+ const { header } = decodedResult;
817
+ const { kid } = header;
818
+ if (!kid) {
819
+ return {
820
+ errors: [
821
+ new TokenVerificationError({
822
+ reason: TokenVerificationErrorReason.TokenInvalid,
823
+ message: 'JWT "kid" header is missing.'
824
+ })
825
+ ]
826
+ };
827
+ }
828
+ try {
829
+ const key = options.jwtKey || await loadJWKFromRemote({ ...options, kid });
830
+ if (!key) {
831
+ return {
832
+ errors: [
833
+ new TokenVerificationError({
834
+ reason: TokenVerificationErrorReason.TokenInvalid,
835
+ message: `No public key found for kid "${kid}".`
836
+ })
837
+ ]
838
+ };
839
+ }
840
+ return await verifyJwt(token, { ...options, key });
841
+ } catch (error) {
842
+ if (error instanceof TokenVerificationError) {
843
+ return { errors: [error] };
844
+ }
845
+ return {
846
+ errors: [error]
847
+ };
848
+ }
849
+ }
850
+
851
+ // src/tokens/request.ts
852
+ var BEARER_PREFIX = "Bearer ";
853
+ var AUTH_COOKIE_NAME = "_session_cookie";
854
+ function extractTokenFromHeader(request) {
855
+ const authHeader = request.headers.get("Authorization");
856
+ if (!authHeader || !authHeader.startsWith(BEARER_PREFIX)) {
857
+ return null;
858
+ }
859
+ return authHeader.slice(BEARER_PREFIX.length);
860
+ }
861
+ function extractTokenFromCookie(request, opts) {
862
+ const cookieHeader = request.headers.get("Cookie") || void 0;
863
+ const sessionName = getSessionConfig(opts).COOKIE_NAME;
864
+ if (!cookieHeader) {
865
+ return null;
866
+ }
867
+ const cookies = cookieHeader.split(";").reduce(
868
+ (acc, cookie) => {
869
+ const [name, value] = cookie.trim().split("=");
870
+ acc[name] = value;
871
+ return acc;
872
+ },
873
+ {}
874
+ );
875
+ return cookies[AUTH_COOKIE_NAME] || null;
876
+ }
877
+ function hasAuthorizationHeader(request) {
878
+ return request.headers.has("Authorization");
879
+ }
880
+ async function authenticateRequest(request, options) {
881
+ async function authenticateRequestWithTokenInCookie() {
882
+ const token = extractTokenFromCookie(request, options);
883
+ if (!token) {
884
+ return signedOut(AuthErrorReason.SessionTokenMissing);
885
+ }
886
+ const { data, errors } = await verifyToken(token, options);
887
+ if (errors) {
888
+ throw errors[0];
889
+ }
890
+ const signedInRequestState = signedIn(data, void 0, token);
891
+ return signedInRequestState;
892
+ }
893
+ async function authenticateRequestWithTokenInHeader() {
894
+ const token = extractTokenFromHeader(request);
895
+ if (!token) {
896
+ return signedOut(AuthErrorReason.SessionTokenMissing);
897
+ }
898
+ const { data, errors } = await verifyToken(token, options);
899
+ if (errors) {
900
+ throw errors[0];
901
+ }
902
+ const signedInRequestState = signedIn(data, void 0, token);
903
+ return signedInRequestState;
904
+ }
905
+ if (hasAuthorizationHeader(request)) {
906
+ return authenticateRequestWithTokenInHeader();
907
+ }
908
+ return authenticateRequestWithTokenInCookie();
909
+ }
910
+ function createAuthenticateRequest(params) {
911
+ const buildTimeOptions = mergePreDefinedOptions(params.options);
912
+ const apiClient = params.apiClient;
913
+ const handleAuthenticateRequest = (request, options = {}) => {
914
+ const { apiUrl } = buildTimeOptions;
915
+ return authenticateRequest(request, { ...options, apiUrl, apiClient });
916
+ };
917
+ return {
918
+ authenticateRequest: handleAuthenticateRequest
919
+ };
920
+ }
921
+
922
+ // src/instance/backendInstanceEdge.ts
923
+ function createBackendInstanceClient(options) {
924
+ const opts = { ...options };
925
+ const apiClient = createBackendApi(opts);
926
+ const requestState = createAuthenticateRequest({ options: opts, apiClient });
927
+ return {
928
+ ...apiClient,
929
+ ...requestState
930
+ };
931
+ }
932
+
933
+ // src/tokens/requestFire.ts
934
+ var defaultFirebaseOptions = {
935
+ apiKey: "",
936
+ authDomain: "",
937
+ projectId: "",
938
+ tenantId: void 0
939
+ };
940
+ function mergePreDefinedOptions2(preDefinedOptions, options) {
941
+ return Object.keys(preDefinedOptions).reduce(
942
+ (obj, key) => {
943
+ return { ...obj, [key]: options[key] || obj[key] };
944
+ },
945
+ { ...preDefinedOptions }
946
+ );
947
+ }
948
+ var BEARER_PREFIX2 = "Bearer ";
949
+ var AUTH_COOKIE_NAME2 = "_session_cookie";
950
+ function extractTokenFromHeader2(request) {
951
+ const authHeader = request.headers.get("Authorization");
952
+ if (!authHeader || !authHeader.startsWith(BEARER_PREFIX2)) {
953
+ return null;
954
+ }
955
+ return authHeader.slice(BEARER_PREFIX2.length);
956
+ }
957
+ function extractTokenFromCookie2(request, opts) {
958
+ const cookieHeader = request.headers.get("Cookie") || void 0;
959
+ const sessionName = getSessionConfig(opts).COOKIE_NAME;
960
+ if (!cookieHeader) {
961
+ return null;
962
+ }
963
+ const cookies = cookieHeader.split(";").reduce(
964
+ (acc, cookie) => {
965
+ const [name, value] = cookie.trim().split("=");
966
+ acc[name] = value;
967
+ return acc;
968
+ },
969
+ {}
970
+ );
971
+ return cookies[AUTH_COOKIE_NAME2] || null;
972
+ }
973
+ function hasAuthorizationHeader2(request) {
974
+ return request.headers.has("Authorization");
975
+ }
976
+ async function authenticateRequest2(request, options) {
977
+ async function authenticateRequestWithTokenInCookie() {
978
+ const token = extractTokenFromCookie2(request, options);
979
+ if (!token) {
980
+ return signedOut(AuthErrorReason.SessionTokenMissing);
981
+ }
982
+ const { data, errors } = await verifyToken(token, options);
983
+ if (errors) {
984
+ throw errors[0];
985
+ }
986
+ const signedInRequestState = signedIn(data, void 0, token);
987
+ return signedInRequestState;
988
+ }
989
+ async function authenticateRequestWithTokenInHeader() {
990
+ const token = extractTokenFromHeader2(request);
991
+ if (!token) {
992
+ return signedOut(AuthErrorReason.SessionTokenMissing);
993
+ }
994
+ const { data, errors } = await verifyToken(token, options);
995
+ if (errors) {
996
+ throw errors[0];
997
+ }
998
+ const signedInRequestState = signedIn(data, void 0, token);
999
+ return signedInRequestState;
1000
+ }
1001
+ if (hasAuthorizationHeader2(request)) {
1002
+ return authenticateRequestWithTokenInHeader();
1003
+ }
1004
+ return authenticateRequestWithTokenInCookie();
1005
+ }
1006
+ function createFireAuthenticateRequest(params) {
1007
+ const buildTimeOptions = mergePreDefinedOptions2(defaultFirebaseOptions, params.options);
1008
+ const handleAuthenticateRequest = (request, options = {}) => {
1009
+ const runtimeOptions = { ...buildTimeOptions, ...options };
1010
+ return authenticateRequest2(request, runtimeOptions);
1011
+ };
1012
+ return {
1013
+ authenticateRequest: handleAuthenticateRequest
1014
+ };
1015
+ }
1016
+
1017
+ // src/instance/backendFireInstance.ts
1018
+ function createFireClient(options) {
1019
+ const opts = { ...options };
1020
+ const apiClient = createBackendApi(opts);
1021
+ const requestState = createFireAuthenticateRequest({ options: opts });
1022
+ return {
1023
+ ...apiClient,
1024
+ ...requestState
1025
+ };
1026
+ }
1027
+
1028
+ // src/utils/logger.ts
1029
+ var LogLevel = /* @__PURE__ */ ((LogLevel2) => {
1030
+ LogLevel2[LogLevel2["ERROR"] = 0] = "ERROR";
1031
+ LogLevel2[LogLevel2["WARN"] = 1] = "WARN";
1032
+ LogLevel2[LogLevel2["INFO"] = 2] = "INFO";
1033
+ LogLevel2[LogLevel2["DEBUG"] = 3] = "DEBUG";
1034
+ return LogLevel2;
1035
+ })(LogLevel || {});
1036
+ var Logger = class {
1037
+ options;
1038
+ constructor(options = {}) {
1039
+ this.options = {
1040
+ enabled: false,
1041
+ level: 2 /* INFO */,
1042
+ prefix: "[TernSecure-Backend]",
1043
+ ...options
1044
+ };
1045
+ }
1046
+ enable() {
1047
+ this.options.enabled = true;
1048
+ }
1049
+ disable() {
1050
+ this.options.enabled = false;
1051
+ }
1052
+ setLevel(level) {
1053
+ this.options.level = level;
1054
+ }
1055
+ setPrefix(prefix) {
1056
+ this.options.prefix = prefix;
1057
+ }
1058
+ log(level, levelName, message, ...args) {
1059
+ if (!this.options.enabled || level > this.options.level) {
1060
+ return;
1061
+ }
1062
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString();
1063
+ const formattedMessage = `${timestamp} ${this.options.prefix} [${levelName}] ${message}`;
1064
+ switch (level) {
1065
+ case 0 /* ERROR */:
1066
+ console.error(formattedMessage, ...args);
1067
+ break;
1068
+ case 1 /* WARN */:
1069
+ console.warn(formattedMessage, ...args);
1070
+ break;
1071
+ case 2 /* INFO */:
1072
+ console.info(formattedMessage, ...args);
1073
+ break;
1074
+ case 3 /* DEBUG */:
1075
+ console.debug(formattedMessage, ...args);
1076
+ break;
1077
+ }
1078
+ }
1079
+ error(message, ...args) {
1080
+ this.log(0 /* ERROR */, "ERROR", message, ...args);
1081
+ }
1082
+ warn(message, ...args) {
1083
+ this.log(1 /* WARN */, "WARN", message, ...args);
1084
+ }
1085
+ info(message, ...args) {
1086
+ this.log(2 /* INFO */, "INFO", message, ...args);
1087
+ }
1088
+ debug(message, ...args) {
1089
+ this.log(3 /* DEBUG */, "DEBUG", message, ...args);
1090
+ }
1091
+ };
1092
+ var createLogger = (options) => {
1093
+ return new Logger(options);
1094
+ };
1095
+ var redisLogger = createLogger({ prefix: "[TernSecure-Redis]" });
1096
+ var authLogger = createLogger({ prefix: "[TernSecure-Auth]" });
1097
+
1098
+ // src/utils/enableDebugLogging.ts
1099
+ function enableDebugLogging() {
1100
+ authLogger.enable();
1101
+ authLogger.setLevel(3 /* DEBUG */);
1102
+ redisLogger.enable();
1103
+ redisLogger.setLevel(3 /* DEBUG */);
1104
+ }
1105
+ function disableDebugLogging() {
1106
+ authLogger.disable();
1107
+ redisLogger.disable();
1108
+ }
1109
+ function setLogLevel(level) {
1110
+ authLogger.setLevel(level);
1111
+ redisLogger.setLevel(level);
1112
+ }
1113
+
1114
+ // src/adapters/PostgresAdapter.ts
1115
+ var PostgresAdapter = class {
1116
+ config;
1117
+ tableName;
1118
+ constructor(config) {
1119
+ this.config = config;
1120
+ this.tableName = config.table || "disabled_users";
1121
+ }
1122
+ getDisabledUser = async (uid) => {
1123
+ try {
1124
+ const response = await fetch(this.config.url, {
1125
+ method: "POST",
1126
+ headers: {
1127
+ "Content-Type": "application/json",
1128
+ "Authorization": `Bearer ${this.config.token}`
1129
+ },
1130
+ body: JSON.stringify({
1131
+ query: `SELECT uid, email, disabled_time as "disabledTime" FROM ${this.tableName} WHERE uid = $1`,
1132
+ params: [uid]
1133
+ })
1134
+ });
1135
+ if (!response.ok) {
1136
+ throw new Error(`HTTP error! status: ${response.status}`);
1137
+ }
1138
+ const result = await response.json();
1139
+ if (result.rows && result.rows.length > 0) {
1140
+ const row = result.rows[0];
1141
+ const disabledUser = {
1142
+ uid: row.uid,
1143
+ email: row.email,
1144
+ disabledTime: row.disabledTime
1145
+ };
1146
+ authLogger.debug(`Found disabled user: ${uid}`);
1147
+ return disabledUser;
1148
+ }
1149
+ authLogger.debug(`No disabled user found: ${uid}`);
1150
+ return null;
1151
+ } catch (error) {
1152
+ authLogger.error("Failed to fetch disabled user from Postgres:", error);
1153
+ return null;
1154
+ }
1155
+ };
1156
+ };
1157
+
1158
+ // src/adapters/RedisAdapter.ts
1159
+ var import_redis = require("@upstash/redis");
1160
+ var TTLCache = class {
1161
+ cache = /* @__PURE__ */ new Map();
1162
+ defaultTTL;
1163
+ constructor(defaultTTLMs = 6e4) {
1164
+ this.defaultTTL = defaultTTLMs;
1165
+ }
1166
+ set(key, value, ttlMs) {
1167
+ const expiresAt = Date.now() + (ttlMs ?? this.defaultTTL);
1168
+ this.cache.set(key, { value, expiresAt });
1169
+ console.log(`TTLCache.set: key=${key}, value=${JSON.stringify(value)}, expiresAt=${expiresAt}, cacheSize=${this.cache.size}`);
1170
+ }
1171
+ getEntry(key) {
1172
+ const entry = this.cache.get(key);
1173
+ if (!entry) return void 0;
1174
+ const now = Date.now();
1175
+ if (now > entry.expiresAt) {
1176
+ console.log(`TTLCache: key=${key} expired (now=${now}, expiresAt=${entry.expiresAt})`);
1177
+ this.cache.delete(key);
1178
+ return void 0;
1179
+ }
1180
+ return entry;
1181
+ }
1182
+ get(key) {
1183
+ const entry = this.getEntry(key);
1184
+ const hasEntry = entry !== void 0;
1185
+ const cacheHasKey = this.cache.has(key);
1186
+ const rawEntry = this.cache.get(key);
1187
+ console.log(`TTLCache.get: key=${key}, hasEntry=${hasEntry}, cacheHasKey=${cacheHasKey}`);
1188
+ console.log(`TTLCache.get: rawEntry=${JSON.stringify(rawEntry)}, entry=${JSON.stringify(entry)}`);
1189
+ if (!entry) {
1190
+ console.log(`TTLCache.get: no entry found for key=${key}, returning undefined`);
1191
+ return void 0;
1192
+ }
1193
+ console.log(`TTLCache.get: returning value=${JSON.stringify(entry.value)} for key=${key}`);
1194
+ return entry.value;
1195
+ }
1196
+ delete(key) {
1197
+ return this.cache.delete(key);
1198
+ }
1199
+ clear() {
1200
+ this.cache.clear();
1201
+ }
1202
+ cleanup() {
1203
+ const now = Date.now();
1204
+ for (const [key, entry] of this.cache.entries()) {
1205
+ if (now > entry.expiresAt) {
1206
+ this.cache.delete(key);
1207
+ }
1208
+ }
1209
+ }
1210
+ };
1211
+ var RedisAdapter = class {
1212
+ redis;
1213
+ cache;
1214
+ keyPrefix;
1215
+ constructor(config) {
1216
+ this.redis = new import_redis.Redis({
1217
+ url: config.url,
1218
+ token: config.token
1219
+ });
1220
+ this.keyPrefix = config.keyPrefix || "disabled_user:";
1221
+ const cacheTTL = config.ttl || 3e4;
1222
+ this.cache = new TTLCache(cacheTTL);
1223
+ setInterval(() => this.cache.cleanup(), 5 * 60 * 1e3);
1224
+ }
1225
+ getDisabledUser = async (uid) => {
1226
+ const cacheKey = `${this.keyPrefix}${uid}`;
1227
+ authLogger.debug(`RedisAdapter: Checking cache for key: ${cacheKey}`);
1228
+ const cachedResult = this.cache.get(cacheKey);
1229
+ authLogger.debug(`RedisAdapter: Cache get result for ${cacheKey}:`, {
1230
+ cachedResult: JSON.stringify(cachedResult),
1231
+ isUndefined: cachedResult === void 0,
1232
+ type: typeof cachedResult
1233
+ });
1234
+ if (cachedResult !== void 0) {
1235
+ authLogger.debug(`Cache hit for disabled user: ${uid}`, {
1236
+ cacheKey,
1237
+ cachedResult: JSON.stringify(cachedResult)
1238
+ });
1239
+ return cachedResult;
1240
+ }
1241
+ authLogger.debug(
1242
+ `Cache miss for disabled user: ${uid}, fetching from Redis with key: ${cacheKey}`
1243
+ );
1244
+ try {
1245
+ const disabledUser = await this.redis.get(cacheKey);
1246
+ authLogger.debug(`Redis returned for key ${cacheKey}:`, {
1247
+ disabledUser: JSON.stringify(disabledUser),
1248
+ type: typeof disabledUser
1249
+ });
1250
+ this.cache.set(cacheKey, disabledUser);
1251
+ authLogger.debug(`Cached disabled user result for: ${uid}`, {
1252
+ cacheKey,
1253
+ isDisabled: !!disabledUser,
1254
+ cachedValue: JSON.stringify(disabledUser)
1255
+ });
1256
+ return disabledUser;
1257
+ } catch (error) {
1258
+ authLogger.error("Failed to fetch disabled user from Redis:", error);
1259
+ return null;
1260
+ }
1261
+ };
1262
+ invalidateCache(uid) {
1263
+ const cacheKey = `${this.keyPrefix}${uid}`;
1264
+ this.cache.delete(cacheKey);
1265
+ }
1266
+ };
1267
+
1268
+ // src/adapters/index.ts
1269
+ function createAdapter(config) {
1270
+ switch (config.type) {
1271
+ case "redis":
1272
+ return new RedisAdapter(config.config);
1273
+ case "postgres":
1274
+ return new PostgresAdapter(config.config);
1275
+ default:
1276
+ throw new Error(`Unsupported adapter type: ${config.type}`);
1277
+ }
1278
+ }
1279
+ function validateCheckRevokedOptions(options) {
1280
+ if (options?.enabled && !options.adapter) {
1281
+ return {
1282
+ isValid: false,
1283
+ error: "When checkRevoked.enabled is true, an adapter must be provided"
1284
+ };
1285
+ }
1286
+ return { isValid: true };
1287
+ }
1288
+ // Annotate the CommonJS export names for ESM import in node:
1289
+ 0 && (module.exports = {
1290
+ AuthStatus,
1291
+ LogLevel,
1292
+ PostgresAdapter,
1293
+ RedisAdapter,
1294
+ constants,
1295
+ createAdapter,
1296
+ createBackendInstanceClient,
1297
+ createFireClient,
1298
+ createTernSecureRequest,
1299
+ disableDebugLogging,
1300
+ enableDebugLogging,
1301
+ setLogLevel,
1302
+ signedIn,
1303
+ signedInAuthObject,
1304
+ signedOutAuthObject,
1305
+ validateCheckRevokedOptions
1306
+ });
1307
+ //# sourceMappingURL=index.js.map