@tern-secure/backend 1.1.6 → 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 +59 -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
@@ -0,0 +1,705 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/admin/index.ts
31
+ var admin_exports = {};
32
+ __export(admin_exports, {
33
+ ClearNextSessionCookie: () => ClearNextSessionCookie,
34
+ CreateNextSessionCookie: () => CreateNextSessionCookie,
35
+ GetNextIdToken: () => GetNextIdToken,
36
+ GetNextServerSessionCookie: () => GetNextServerSessionCookie,
37
+ SetNextServerSession: () => SetNextServerSession,
38
+ SetNextServerToken: () => SetNextServerToken,
39
+ TernSecureTenantManager: () => TernSecureTenantManager,
40
+ VerifyNextTernIdToken: () => VerifyNextTernIdToken,
41
+ VerifyNextTernSessionCookie: () => VerifyNextTernSessionCookie,
42
+ adminTernSecureAuth: () => adminTernSecureAuth,
43
+ adminTernSecureDb: () => adminTernSecureDb,
44
+ authenticateRequest: () => authenticateRequest,
45
+ clearSessionCookie: () => clearSessionCookie,
46
+ createBackendInstance: () => createBackendInstance,
47
+ createSessionCookie: () => createSessionCookie,
48
+ createTenant: () => createTenant,
49
+ createTenantUser: () => createTenantUser,
50
+ initializeAdminConfig: () => initializeAdminConfig,
51
+ signedIn: () => signedIn
52
+ });
53
+ module.exports = __toCommonJS(admin_exports);
54
+
55
+ // src/admin/sessionTernSecure.ts
56
+ var import_errors = require("@tern-secure/shared/errors");
57
+
58
+ // src/tokens/sessionConfig.ts
59
+ var getSessionConfig = (options) => {
60
+ const cookieConfig = options?.cookies?.session_cookie;
61
+ return {
62
+ COOKIE_NAME: cookieConfig?.name,
63
+ DEFAULT_EXPIRES_IN_MS: cookieConfig?.attributes?.maxAge,
64
+ DEFAULT_EXPIRES_IN_SECONDS: Math.floor((cookieConfig?.attributes?.maxAge || 0) / 1e3),
65
+ REVOKE_REFRESH_TOKENS_ON_SIGNOUT: cookieConfig?.revokeRefreshTokensOnSignOut
66
+ };
67
+ };
68
+ var getCookieOptions = (options) => {
69
+ const cookieConfig = options?.cookies?.session_cookie;
70
+ return {
71
+ httpOnly: cookieConfig?.attributes?.httpOnly,
72
+ secure: cookieConfig?.attributes?.secure,
73
+ sameSite: cookieConfig?.attributes?.sameSite,
74
+ path: cookieConfig?.attributes?.path
75
+ };
76
+ };
77
+
78
+ // src/utils/admin-init.ts
79
+ var import_firebase_admin = __toESM(require("firebase-admin"));
80
+
81
+ // src/utils/config.ts
82
+ var loadAdminConfig = () => ({
83
+ projectId: process.env.FIREBASE_PROJECT_ID || "",
84
+ clientEmail: process.env.FIREBASE_CLIENT_EMAIL || "",
85
+ privateKey: process.env.FIREBASE_PRIVATE_KEY || ""
86
+ });
87
+ var validateAdminConfig = (config) => {
88
+ const requiredFields = [
89
+ "projectId",
90
+ "clientEmail",
91
+ "privateKey"
92
+ ];
93
+ const errors = [];
94
+ requiredFields.forEach((field) => {
95
+ if (!config[field]) {
96
+ errors.push(`Missing required field: FIREBASE_${String(field).toUpperCase()}`);
97
+ }
98
+ });
99
+ return {
100
+ isValid: errors.length === 0,
101
+ errors,
102
+ config
103
+ };
104
+ };
105
+ var initializeAdminConfig = () => {
106
+ const config = loadAdminConfig();
107
+ const validationResult = validateAdminConfig(config);
108
+ if (!validationResult.isValid) {
109
+ throw new Error(
110
+ `Firebase Admin configuration validation failed:
111
+ ${validationResult.errors.join("\n")}`
112
+ );
113
+ }
114
+ return config;
115
+ };
116
+
117
+ // src/utils/admin-init.ts
118
+ if (!import_firebase_admin.default.apps.length) {
119
+ try {
120
+ const config = initializeAdminConfig();
121
+ import_firebase_admin.default.initializeApp({
122
+ credential: import_firebase_admin.default.credential.cert({
123
+ ...config,
124
+ privateKey: config.privateKey.replace(/\\n/g, "\n")
125
+ })
126
+ });
127
+ } catch (error) {
128
+ console.error("Firebase admin initialization error", error);
129
+ }
130
+ }
131
+ var adminTernSecureAuth = import_firebase_admin.default.auth();
132
+ var adminTernSecureDb = import_firebase_admin.default.firestore();
133
+ var TernSecureTenantManager = import_firebase_admin.default.auth().tenantManager();
134
+ function getAuthForTenant(tenantId) {
135
+ if (tenantId) {
136
+ return TernSecureTenantManager.authForTenant(tenantId);
137
+ }
138
+ return import_firebase_admin.default.auth();
139
+ }
140
+
141
+ // src/admin/sessionTernSecure.ts
142
+ var SESSION_CONSTANTS = {
143
+ COOKIE_NAME: "_session_cookie",
144
+ //DEFAULT_EXPIRES_IN_MS: 60 * 60 * 24 * 5 * 1000, // 5 days
145
+ //DEFAULT_EXPIRES_IN_SECONDS: 60 * 60 * 24 * 5, // 5days
146
+ DEFAULT_EXPIRES_IN_MS: 5 * 60 * 1e3,
147
+ // 5 minutes
148
+ DEFAULT_EXPIRES_IN_SECONDS: 5 * 60,
149
+ REVOKE_REFRESH_TOKENS_ON_SIGNOUT: true
150
+ };
151
+ var COOKIE_OPTIONS = {
152
+ httpOnly: true,
153
+ secure: process.env.NODE_ENV === "production",
154
+ sameSite: "strict",
155
+ path: "/"
156
+ };
157
+ async function createSessionCookie(params, cookieStore, options) {
158
+ try {
159
+ const tenantAuth = getAuthForTenant(options?.tenantId);
160
+ const sessionConfig = getSessionConfig(options);
161
+ const cookieOptions = getCookieOptions(options);
162
+ let decodedToken;
163
+ let sessionCookie;
164
+ const idToken = typeof params === "string" ? params : params.idToken;
165
+ if (!idToken) {
166
+ const error = new Error("ID token is required for session creation");
167
+ console.error("[createSessionCookie] Missing ID token:", error);
168
+ return {
169
+ success: false,
170
+ message: "ID token is required",
171
+ error: "INVALID_TOKEN",
172
+ cookieSet: false
173
+ };
174
+ }
175
+ try {
176
+ console.log("Verifying ID token for tenant:", options?.tenantId);
177
+ decodedToken = await tenantAuth.verifyIdToken(idToken);
178
+ } catch (verifyError) {
179
+ console.error(
180
+ "[createSessionCookie] ID token verification failed:",
181
+ verifyError
182
+ );
183
+ const authError = (0, import_errors.handleFirebaseAuthError)(verifyError);
184
+ return {
185
+ success: false,
186
+ message: authError.message,
187
+ error: authError.code,
188
+ cookieSet: false
189
+ };
190
+ }
191
+ if (!decodedToken) {
192
+ const error = new Error("Invalid ID token - verification returned null");
193
+ console.error(
194
+ "[createSessionCookie] Token verification returned null:",
195
+ error
196
+ );
197
+ return {
198
+ success: false,
199
+ message: "Invalid ID token",
200
+ error: "INVALID_TOKEN",
201
+ cookieSet: false
202
+ };
203
+ }
204
+ try {
205
+ sessionCookie = await tenantAuth.createSessionCookie(idToken, {
206
+ expiresIn: SESSION_CONSTANTS.DEFAULT_EXPIRES_IN_MS
207
+ });
208
+ } catch (sessionError) {
209
+ console.error(
210
+ "[createSessionCookie] Firebase session cookie creation failed:",
211
+ sessionError
212
+ );
213
+ const authError = (0, import_errors.handleFirebaseAuthError)(sessionError);
214
+ return {
215
+ success: false,
216
+ message: authError.message,
217
+ error: authError.code,
218
+ cookieSet: false
219
+ };
220
+ }
221
+ let cookieSetSuccessfully = false;
222
+ try {
223
+ cookieStore.set(SESSION_CONSTANTS.COOKIE_NAME, sessionCookie, {
224
+ maxAge: SESSION_CONSTANTS.DEFAULT_EXPIRES_IN_SECONDS,
225
+ ...COOKIE_OPTIONS
226
+ });
227
+ const verifySetCookie = await cookieStore.get(
228
+ SESSION_CONSTANTS.COOKIE_NAME
229
+ );
230
+ cookieSetSuccessfully = !!verifySetCookie?.value;
231
+ if (!cookieSetSuccessfully) {
232
+ const error = new Error("Session cookie was not set successfully");
233
+ console.error(
234
+ "[createSessionCookie] Cookie verification failed:",
235
+ error
236
+ );
237
+ throw error;
238
+ }
239
+ } catch (cookieError) {
240
+ console.error(
241
+ "[createSessionCookie] Failed to set session cookie:",
242
+ cookieError
243
+ );
244
+ return {
245
+ success: false,
246
+ message: "Failed to set session cookie",
247
+ error: "COOKIE_SET_FAILED",
248
+ cookieSet: false
249
+ };
250
+ }
251
+ console.log(
252
+ `[createSessionCookie] Session cookie created successfully for user: ${decodedToken.uid}`
253
+ );
254
+ return {
255
+ success: true,
256
+ message: "Session created successfully",
257
+ expiresIn: SESSION_CONSTANTS.DEFAULT_EXPIRES_IN_SECONDS,
258
+ cookieSet: cookieSetSuccessfully
259
+ };
260
+ } catch (error) {
261
+ console.error("[createSessionCookie] Unexpected error:", error);
262
+ const authError = (0, import_errors.handleFirebaseAuthError)(error);
263
+ return {
264
+ success: false,
265
+ message: authError.message || "Failed to create session",
266
+ error: authError.code || "INTERNAL_ERROR",
267
+ cookieSet: false
268
+ };
269
+ }
270
+ }
271
+ async function clearSessionCookie(cookieStore, options) {
272
+ try {
273
+ const adminAuth = getAuthForTenant(options?.tenantId);
274
+ const sessionCookie = await cookieStore.get(SESSION_CONSTANTS.COOKIE_NAME);
275
+ await cookieStore.delete(SESSION_CONSTANTS.COOKIE_NAME);
276
+ await cookieStore.delete("_session_token");
277
+ await cookieStore.delete("_session");
278
+ if (SESSION_CONSTANTS.REVOKE_REFRESH_TOKENS_ON_SIGNOUT && sessionCookie?.value) {
279
+ try {
280
+ const decodedClaims = await adminAuth.verifySessionCookie(
281
+ sessionCookie.value
282
+ );
283
+ await adminAuth.revokeRefreshTokens(decodedClaims.sub);
284
+ console.log(
285
+ `[clearSessionCookie] Successfully revoked tokens for user: ${decodedClaims.sub}`
286
+ );
287
+ } catch (revokeError) {
288
+ console.error(
289
+ "[clearSessionCookie] Failed to revoke refresh tokens:",
290
+ revokeError
291
+ );
292
+ }
293
+ }
294
+ console.log("[clearSessionCookie] Session cookies cleared successfully");
295
+ return {
296
+ success: true,
297
+ message: "Session cleared successfully",
298
+ cookieSet: false
299
+ };
300
+ } catch (error) {
301
+ console.error("[clearSessionCookie] Unexpected error:", error);
302
+ const authError = (0, import_errors.handleFirebaseAuthError)(error);
303
+ return {
304
+ success: false,
305
+ message: authError.message || "Failed to clear session",
306
+ error: authError.code || "INTERNAL_ERROR",
307
+ cookieSet: false
308
+ };
309
+ }
310
+ }
311
+
312
+ // src/admin/tenant.ts
313
+ async function createTenant(displayName, emailSignInConfig, multiFactorConfig) {
314
+ try {
315
+ const tenantConfig = {
316
+ displayName,
317
+ emailSignInConfig,
318
+ ...multiFactorConfig && { multiFactorConfig }
319
+ };
320
+ const tenant = await TernSecureTenantManager.createTenant(tenantConfig);
321
+ return {
322
+ success: true,
323
+ tenantId: tenant.tenantId,
324
+ displayName: tenant.displayName
325
+ };
326
+ } catch (error) {
327
+ console.error("Error creating tenant:", error);
328
+ throw new Error("Failed to create tenant");
329
+ }
330
+ }
331
+ async function createTenantUser(email, password, tenantId) {
332
+ try {
333
+ const tenantAuth = TernSecureTenantManager.authForTenant(tenantId);
334
+ const userRecord = await tenantAuth.createUser({
335
+ email,
336
+ password,
337
+ emailVerified: false,
338
+ disabled: false
339
+ });
340
+ return {
341
+ success: true,
342
+ message: "Tenant user created successfully",
343
+ user: userRecord.uid
344
+ };
345
+ } catch (error) {
346
+ console.error("Error creating tenant user:", error);
347
+ throw new Error("Failed to create tenant user");
348
+ }
349
+ }
350
+
351
+ // src/admin/nextSessionTernSecure.ts
352
+ var import_errors2 = require("@tern-secure/shared/errors");
353
+ var import_headers = require("next/headers");
354
+ var SESSION_CONSTANTS2 = {
355
+ COOKIE_NAME: "_session_cookie",
356
+ DEFAULT_EXPIRES_IN_MS: 60 * 60 * 24 * 5 * 1e3,
357
+ // 5 days
358
+ DEFAULT_EXPIRES_IN_SECONDS: 60 * 60 * 24 * 5,
359
+ REVOKE_REFRESH_TOKENS_ON_SIGNOUT: true
360
+ };
361
+ async function CreateNextSessionCookie(idToken) {
362
+ try {
363
+ const expiresIn = 60 * 60 * 24 * 5 * 1e3;
364
+ const sessionCookie = await adminTernSecureAuth.createSessionCookie(idToken, {
365
+ expiresIn
366
+ });
367
+ const cookieStore = await (0, import_headers.cookies)();
368
+ cookieStore.set("_session_cookie", sessionCookie, {
369
+ maxAge: expiresIn,
370
+ httpOnly: true,
371
+ secure: process.env.NODE_ENV === "production",
372
+ path: "/"
373
+ });
374
+ return { success: true, message: "Session created" };
375
+ } catch (error) {
376
+ return { success: false, message: "Failed to create session" };
377
+ }
378
+ }
379
+ async function GetNextServerSessionCookie() {
380
+ const cookieStore = await (0, import_headers.cookies)();
381
+ const sessionCookie = cookieStore.get("_session_cookie")?.value;
382
+ if (!sessionCookie) {
383
+ throw new Error("No session cookie found");
384
+ }
385
+ try {
386
+ const decondeClaims = await adminTernSecureAuth.verifySessionCookie(
387
+ sessionCookie,
388
+ true
389
+ );
390
+ return {
391
+ token: sessionCookie,
392
+ userId: decondeClaims.uid
393
+ };
394
+ } catch (error) {
395
+ console.error("Error verifying session:", error);
396
+ throw new Error("Invalid Session");
397
+ }
398
+ }
399
+ async function GetNextIdToken() {
400
+ const cookieStore = await (0, import_headers.cookies)();
401
+ const token = cookieStore.get("_session_token")?.value;
402
+ if (!token) {
403
+ throw new Error("No session cookie found");
404
+ }
405
+ try {
406
+ const decodedClaims = await adminTernSecureAuth.verifyIdToken(token);
407
+ return {
408
+ token,
409
+ userId: decodedClaims.uid
410
+ };
411
+ } catch (error) {
412
+ console.error("Error verifying session:", error);
413
+ throw new Error("Invalid Session");
414
+ }
415
+ }
416
+ async function SetNextServerSession(token) {
417
+ try {
418
+ const cookieStore = await (0, import_headers.cookies)();
419
+ cookieStore.set("_session_token", token, {
420
+ httpOnly: true,
421
+ secure: process.env.NODE_ENV === "production",
422
+ sameSite: "strict",
423
+ maxAge: 60 * 60,
424
+ // 1 hour
425
+ path: "/"
426
+ });
427
+ return { success: true, message: "Session created" };
428
+ } catch {
429
+ return { success: false, message: "Failed to create session" };
430
+ }
431
+ }
432
+ async function SetNextServerToken(token) {
433
+ try {
434
+ const cookieStore = await (0, import_headers.cookies)();
435
+ cookieStore.set("_tern", token, {
436
+ httpOnly: true,
437
+ secure: process.env.NODE_ENV === "production",
438
+ sameSite: "strict",
439
+ maxAge: 60 * 60,
440
+ // 1 hour
441
+ path: "/"
442
+ });
443
+ return { success: true, message: "Session created" };
444
+ } catch {
445
+ return { success: false, message: "Failed to create session" };
446
+ }
447
+ }
448
+ async function VerifyNextTernIdToken(token) {
449
+ try {
450
+ const decodedToken = await adminTernSecureAuth.verifyIdToken(token);
451
+ return {
452
+ ...decodedToken,
453
+ valid: true
454
+ };
455
+ } catch (error) {
456
+ console.error("[VerifyNextTernIdToken] Error verifying session:", error);
457
+ const authError = (0, import_errors2.handleFirebaseAuthError)(error);
458
+ return {
459
+ valid: false,
460
+ error: authError
461
+ };
462
+ }
463
+ }
464
+ async function VerifyNextTernSessionCookie(session) {
465
+ try {
466
+ const res = await adminTernSecureAuth.verifySessionCookie(session);
467
+ console.warn(
468
+ "[VerifyNextTernSessionCookie] uid in Decoded Token:",
469
+ res.uid
470
+ );
471
+ return {
472
+ valid: true,
473
+ ...res
474
+ };
475
+ } catch (error) {
476
+ console.error(
477
+ "[VerifyNextTernSessionCookie] Error verifying session:",
478
+ error
479
+ );
480
+ const authError = (0, import_errors2.handleFirebaseAuthError)(error);
481
+ return {
482
+ valid: false,
483
+ error: authError
484
+ };
485
+ }
486
+ }
487
+ async function ClearNextSessionCookie(tenantId) {
488
+ try {
489
+ console.log("[clearSessionCookie] Clearing session for tenant:", tenantId);
490
+ const tenantAuth = getAuthForTenant(tenantId);
491
+ const cookieStore = await (0, import_headers.cookies)();
492
+ const sessionCookie = cookieStore.get(SESSION_CONSTANTS2.COOKIE_NAME);
493
+ cookieStore.delete(SESSION_CONSTANTS2.COOKIE_NAME);
494
+ cookieStore.delete("_session_token");
495
+ cookieStore.delete("_session");
496
+ if (SESSION_CONSTANTS2.REVOKE_REFRESH_TOKENS_ON_SIGNOUT && sessionCookie?.value) {
497
+ try {
498
+ const decodedClaims = await tenantAuth.verifySessionCookie(
499
+ sessionCookie.value
500
+ );
501
+ await tenantAuth.revokeRefreshTokens(decodedClaims.sub);
502
+ console.log(
503
+ `[clearSessionCookie] Successfully revoked tokens for user: ${decodedClaims.sub}`
504
+ );
505
+ } catch (revokeError) {
506
+ console.error(
507
+ "[ClearNextSessionCookie] Failed to revoke refresh tokens:",
508
+ revokeError
509
+ );
510
+ }
511
+ }
512
+ return { success: true, message: "Session cleared successfully" };
513
+ } catch (error) {
514
+ console.error("Error clearing session:", error);
515
+ return { success: false, message: "Failed to clear session cookies" };
516
+ }
517
+ }
518
+
519
+ // src/tokens/ternSecureRequest.ts
520
+ var import_cookie = require("cookie");
521
+
522
+ // src/constants.ts
523
+ var MAX_CACHE_LAST_UPDATED_AT_SECONDS = 5 * 60;
524
+ var DEFAULT_CACHE_DURATION = 3600 * 1e3;
525
+ var Attributes = {
526
+ AuthToken: "__ternsecureAuthToken",
527
+ AuthSignature: "__ternsecureAuthSignature",
528
+ AuthStatus: "__ternsecureAuthStatus",
529
+ AuthReason: "__ternsecureAuthReason",
530
+ AuthMessage: "__ternsecureAuthMessage",
531
+ TernSecureUrl: "__ternsecureUrl"
532
+ };
533
+ var Cookies = {
534
+ Session: "__session",
535
+ IdToken: "_tern",
536
+ SessionCookie: "_session_cookie",
537
+ SessionToken: "_session_token",
538
+ Refresh: "__refresh",
539
+ Handshake: "__ternsecure_handshake",
540
+ DevBrowser: "__ternsecure_db_jwt",
541
+ RedirectCount: "__ternsecure_redirect_count",
542
+ HandshakeNonce: "__ternsecure_handshake_nonce"
543
+ };
544
+ var Headers2 = {
545
+ Accept: "accept",
546
+ AuthMessage: "x-ternsecure-auth-message",
547
+ Authorization: "authorization",
548
+ AuthReason: "x-ternsecure-auth-reason",
549
+ AuthSignature: "x-ternsecure-auth-signature",
550
+ AuthStatus: "x-ternsecure-auth-status",
551
+ AuthToken: "x-ternsecure-auth-token",
552
+ CacheControl: "cache-control",
553
+ TernSecureRedirectTo: "x-ternsecure-redirect-to",
554
+ TernSecureRequestData: "x-ternsecure-request-data",
555
+ TernSecureUrl: "x-ternsecure-url",
556
+ CloudFrontForwardedProto: "cloudfront-forwarded-proto",
557
+ ContentType: "content-type",
558
+ ContentSecurityPolicy: "content-security-policy",
559
+ ContentSecurityPolicyReportOnly: "content-security-policy-report-only",
560
+ EnableDebug: "x-ternsecure-debug",
561
+ ForwardedHost: "x-forwarded-host",
562
+ ForwardedPort: "x-forwarded-port",
563
+ ForwardedProto: "x-forwarded-proto",
564
+ Host: "host",
565
+ Location: "location",
566
+ Nonce: "x-nonce",
567
+ Origin: "origin",
568
+ Referrer: "referer",
569
+ SecFetchDest: "sec-fetch-dest",
570
+ UserAgent: "user-agent",
571
+ ReportingEndpoints: "reporting-endpoints"
572
+ };
573
+ var ContentTypes = {
574
+ Json: "application/json"
575
+ };
576
+ var constants = {
577
+ Attributes,
578
+ Cookies,
579
+ Headers: Headers2,
580
+ ContentTypes
581
+ };
582
+
583
+ // src/tokens/ternUrl.ts
584
+ var TernUrl = class extends URL {
585
+ isCrossOrigin(other) {
586
+ return this.origin !== new URL(other.toString()).origin;
587
+ }
588
+ };
589
+ var createTernUrl = (...args) => {
590
+ return new TernUrl(...args);
591
+ };
592
+
593
+ // src/tokens/ternSecureRequest.ts
594
+ var TernSecureRequest = class extends Request {
595
+ ternUrl;
596
+ cookies;
597
+ constructor(input, init) {
598
+ const url = typeof input !== "string" && "url" in input ? input.url : String(input);
599
+ super(url, init || typeof input === "string" ? void 0 : input);
600
+ this.ternUrl = this.deriveUrlFromHeaders(this);
601
+ this.cookies = this.parseCookies(this);
602
+ }
603
+ toJSON() {
604
+ return {
605
+ url: this.ternUrl.href,
606
+ method: this.method,
607
+ headers: JSON.stringify(Object.fromEntries(this.headers)),
608
+ ternUrl: this.ternUrl.toString(),
609
+ cookies: JSON.stringify(Object.fromEntries(this.cookies))
610
+ };
611
+ }
612
+ deriveUrlFromHeaders(req) {
613
+ const initialUrl = new URL(req.url);
614
+ const forwardedProto = req.headers.get(constants.Headers.ForwardedProto);
615
+ const forwardedHost = req.headers.get(constants.Headers.ForwardedHost);
616
+ const host = req.headers.get(constants.Headers.Host);
617
+ const protocol = initialUrl.protocol;
618
+ const resolvedHost = this.getFirstValueFromHeader(forwardedHost) ?? host;
619
+ const resolvedProtocol = this.getFirstValueFromHeader(forwardedProto) ?? protocol?.replace(/[:/]/, "");
620
+ const origin = resolvedHost && resolvedProtocol ? `${resolvedProtocol}://${resolvedHost}` : initialUrl.origin;
621
+ if (origin === initialUrl.origin) {
622
+ return createTernUrl(initialUrl);
623
+ }
624
+ return createTernUrl(initialUrl.pathname + initialUrl.search, origin);
625
+ }
626
+ getFirstValueFromHeader(value) {
627
+ return value?.split(",")[0];
628
+ }
629
+ parseCookies(req) {
630
+ const cookiesRecord = (0, import_cookie.parse)(
631
+ this.decodeCookieValue(req.headers.get("cookie") || "")
632
+ );
633
+ return new Map(Object.entries(cookiesRecord));
634
+ }
635
+ decodeCookieValue(str) {
636
+ return str ? str.replace(/(%[0-9A-Z]{2})+/g, decodeURIComponent) : str;
637
+ }
638
+ };
639
+ var createTernSecureRequest = (...args) => {
640
+ return args[0] instanceof TernSecureRequest ? args[0] : new TernSecureRequest(...args);
641
+ };
642
+
643
+ // src/instance/backendInstance.ts
644
+ var createBackendInstance = async (request) => {
645
+ const ternSecureRequest = createTernSecureRequest(request);
646
+ const requestState = await authenticateRequest(request);
647
+ return {
648
+ ternSecureRequest,
649
+ requestState
650
+ };
651
+ };
652
+ async function authenticateRequest(request) {
653
+ const sessionCookie = request.headers.get("cookie");
654
+ const sessionToken = sessionCookie?.split(";").find((c) => c.trim().startsWith("_session_cookie="))?.split("=")[1];
655
+ if (!sessionToken) {
656
+ throw new Error("No session token found");
657
+ }
658
+ const verificationResult = await VerifyNextTernSessionCookie(sessionToken);
659
+ if (!verificationResult.valid) {
660
+ throw new Error("Invalid session token");
661
+ }
662
+ return signedIn(
663
+ verificationResult,
664
+ new Headers(request.headers),
665
+ sessionToken
666
+ );
667
+ }
668
+ function signInAuthObject(session) {
669
+ return {
670
+ session,
671
+ userId: session.uid,
672
+ has: {}
673
+ };
674
+ }
675
+ function signedIn(session, headers = new Headers(), token) {
676
+ const authObject = signInAuthObject(session);
677
+ return {
678
+ auth: () => authObject,
679
+ token,
680
+ headers
681
+ };
682
+ }
683
+ // Annotate the CommonJS export names for ESM import in node:
684
+ 0 && (module.exports = {
685
+ ClearNextSessionCookie,
686
+ CreateNextSessionCookie,
687
+ GetNextIdToken,
688
+ GetNextServerSessionCookie,
689
+ SetNextServerSession,
690
+ SetNextServerToken,
691
+ TernSecureTenantManager,
692
+ VerifyNextTernIdToken,
693
+ VerifyNextTernSessionCookie,
694
+ adminTernSecureAuth,
695
+ adminTernSecureDb,
696
+ authenticateRequest,
697
+ clearSessionCookie,
698
+ createBackendInstance,
699
+ createSessionCookie,
700
+ createTenant,
701
+ createTenantUser,
702
+ initializeAdminConfig,
703
+ signedIn
704
+ });
705
+ //# sourceMappingURL=index.js.map