@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
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/admin/index.ts","../../src/admin/sessionTernSecure.ts","../../src/tokens/sessionConfig.ts","../../src/utils/admin-init.ts","../../src/utils/config.ts","../../src/admin/tenant.ts","../../src/admin/nextSessionTernSecure.ts","../../src/tokens/ternSecureRequest.ts","../../src/constants.ts","../../src/tokens/ternUrl.ts","../../src/instance/backendInstance.ts"],"sourcesContent":["export { \n createSessionCookie, \n clearSessionCookie\n} from './sessionTernSecure'\nexport { \n adminTernSecureAuth, \n adminTernSecureDb, \n TernSecureTenantManager \n} from '../utils/admin-init'\nexport { initializeAdminConfig } from '../utils/config'\nexport { createTenant, createTenantUser } from './tenant'\nexport { \n CreateNextSessionCookie,\n GetNextServerSessionCookie,\n GetNextIdToken,\n SetNextServerSession,\n SetNextServerToken,\n VerifyNextTernIdToken,\n VerifyNextTernSessionCookie,\n ClearNextSessionCookie\n} from './nextSessionTernSecure'\n\nexport type { SignInAuthObject, RequestState } from '../instance/backendInstance'\nexport { createBackendInstance, authenticateRequest, signedIn } from '../instance/backendInstance'","\"use server\";\r\n\r\nimport { handleFirebaseAuthError } from \"@tern-secure/shared/errors\";\r\nimport type {\r\n CookieStore,\r\n SessionParams,\r\n SessionResult,\r\n} from \"@tern-secure/types\";\r\n\r\nimport { getCookieOptions, getSessionConfig } from \"../tokens/sessionConfig\";\r\nimport type { RequestOptions } from \"../tokens/types\";\r\nimport { getAuthForTenant } from \"../utils/admin-init\";\r\n\r\nconst SESSION_CONSTANTS = {\r\n COOKIE_NAME: \"_session_cookie\",\r\n //DEFAULT_EXPIRES_IN_MS: 60 * 60 * 24 * 5 * 1000, // 5 days\r\n //DEFAULT_EXPIRES_IN_SECONDS: 60 * 60 * 24 * 5, // 5days\r\n DEFAULT_EXPIRES_IN_MS: 5 * 60 * 1000, // 5 minutes\r\n DEFAULT_EXPIRES_IN_SECONDS: 5 * 60,\r\n REVOKE_REFRESH_TOKENS_ON_SIGNOUT: true,\r\n} as const;\r\n\r\nconst COOKIE_OPTIONS = {\r\n httpOnly: true,\r\n secure: process.env.NODE_ENV === \"production\",\r\n sameSite: \"strict\" as const,\r\n path: \"/\",\r\n} as const;\r\n\r\n\r\nexport async function createSessionCookie(\r\n params: SessionParams | string,\r\n cookieStore: CookieStore,\r\n options?: RequestOptions\r\n): Promise<SessionResult> {\r\n try {\r\n const tenantAuth = getAuthForTenant(options?.tenantId);\r\n\r\n const sessionConfig = getSessionConfig(options);\r\n const cookieOptions = getCookieOptions(options);\r\n \r\n let decodedToken;\r\n let sessionCookie;\r\n\r\n const idToken = typeof params === \"string\" ? params : params.idToken;\r\n\r\n if (!idToken) {\r\n const error = new Error(\"ID token is required for session creation\");\r\n console.error(\"[createSessionCookie] Missing ID token:\", error);\r\n return {\r\n success: false,\r\n message: \"ID token is required\",\r\n error: \"INVALID_TOKEN\",\r\n cookieSet: false,\r\n };\r\n }\r\n\r\n try {\r\n console.log(\"Verifying ID token for tenant:\", options?.tenantId);\r\n decodedToken = await tenantAuth.verifyIdToken(idToken);\r\n } catch (verifyError) {\r\n console.error(\r\n \"[createSessionCookie] ID token verification failed:\",\r\n verifyError\r\n );\r\n const authError = handleFirebaseAuthError(verifyError);\r\n return {\r\n success: false,\r\n message: authError.message,\r\n error: authError.code,\r\n cookieSet: false,\r\n };\r\n }\r\n\r\n if (!decodedToken) {\r\n const error = new Error(\"Invalid ID token - verification returned null\");\r\n console.error(\r\n \"[createSessionCookie] Token verification returned null:\",\r\n error\r\n );\r\n return {\r\n success: false,\r\n message: \"Invalid ID token\",\r\n error: \"INVALID_TOKEN\",\r\n cookieSet: false,\r\n };\r\n }\r\n\r\n try {\r\n sessionCookie = await tenantAuth.createSessionCookie(idToken, {\r\n expiresIn: SESSION_CONSTANTS.DEFAULT_EXPIRES_IN_MS,\r\n });\r\n } catch (sessionError) {\r\n console.error(\r\n \"[createSessionCookie] Firebase session cookie creation failed:\",\r\n sessionError\r\n );\r\n const authError = handleFirebaseAuthError(sessionError);\r\n return {\r\n success: false,\r\n message: authError.message,\r\n error: authError.code,\r\n cookieSet: false,\r\n };\r\n }\r\n\r\n // Set the cookie and verify it was set\r\n let cookieSetSuccessfully = false;\r\n try {\r\n //const cookieStore = await cookies();\r\n cookieStore.set(SESSION_CONSTANTS.COOKIE_NAME, sessionCookie, {\r\n maxAge: SESSION_CONSTANTS.DEFAULT_EXPIRES_IN_SECONDS,\r\n ...COOKIE_OPTIONS,\r\n });\r\n\r\n // Verify the cookie was actually set\r\n const verifySetCookie = await cookieStore.get(\r\n SESSION_CONSTANTS.COOKIE_NAME\r\n );\r\n cookieSetSuccessfully = !!verifySetCookie?.value;\r\n\r\n if (!cookieSetSuccessfully) {\r\n const error = new Error(\"Session cookie was not set successfully\");\r\n console.error(\r\n \"[createSessionCookie] Cookie verification failed:\",\r\n error\r\n );\r\n throw error;\r\n }\r\n } catch (cookieError) {\r\n console.error(\r\n \"[createSessionCookie] Failed to set session cookie:\",\r\n cookieError\r\n );\r\n return {\r\n success: false,\r\n message: \"Failed to set session cookie\",\r\n error: \"COOKIE_SET_FAILED\",\r\n cookieSet: false,\r\n };\r\n }\r\n\r\n console.log(\r\n `[createSessionCookie] Session cookie created successfully for user: ${decodedToken.uid}`\r\n );\r\n return {\r\n success: true,\r\n message: \"Session created successfully\",\r\n expiresIn: SESSION_CONSTANTS.DEFAULT_EXPIRES_IN_SECONDS,\r\n cookieSet: cookieSetSuccessfully,\r\n };\r\n } catch (error) {\r\n console.error(\"[createSessionCookie] Unexpected error:\", error);\r\n const authError = handleFirebaseAuthError(error);\r\n return {\r\n success: false,\r\n message: authError.message || \"Failed to create session\",\r\n error: authError.code || \"INTERNAL_ERROR\",\r\n cookieSet: false,\r\n };\r\n }\r\n}\r\n\r\nexport async function clearSessionCookie(\r\n cookieStore: CookieStore,\r\n options?: RequestOptions\r\n): Promise<SessionResult> {\r\n try {\r\n const adminAuth = getAuthForTenant(options?.tenantId);\r\n const sessionCookie = await cookieStore.get(SESSION_CONSTANTS.COOKIE_NAME);\r\n\r\n await cookieStore.delete(SESSION_CONSTANTS.COOKIE_NAME);\r\n await cookieStore.delete(\"_session_token\");\r\n await cookieStore.delete(\"_session\");\r\n\r\n if (\r\n SESSION_CONSTANTS.REVOKE_REFRESH_TOKENS_ON_SIGNOUT &&\r\n sessionCookie?.value\r\n ) {\r\n try {\r\n const decodedClaims = await adminAuth.verifySessionCookie(\r\n sessionCookie.value\r\n );\r\n await adminAuth.revokeRefreshTokens(decodedClaims.sub);\r\n console.log(\r\n `[clearSessionCookie] Successfully revoked tokens for user: ${decodedClaims.sub}`\r\n );\r\n } catch (revokeError) {\r\n console.error(\r\n \"[clearSessionCookie] Failed to revoke refresh tokens:\",\r\n revokeError\r\n );\r\n }\r\n }\r\n\r\n console.log(\"[clearSessionCookie] Session cookies cleared successfully\");\r\n return {\r\n success: true,\r\n message: \"Session cleared successfully\",\r\n cookieSet: false,\r\n };\r\n } catch (error) {\r\n console.error(\"[clearSessionCookie] Unexpected error:\", error);\r\n const authError = handleFirebaseAuthError(error);\r\n return {\r\n success: false,\r\n message: authError.message || \"Failed to clear session\",\r\n error: authError.code || \"INTERNAL_ERROR\",\r\n cookieSet: false,\r\n };\r\n }\r\n}\r\n\r\nexport async function createCustomToken(uid: string, options?: RequestOptions): Promise<string | null> {\r\n const adminAuth = getAuthForTenant(options?.tenantId);\r\n try {\r\n const customToken = await adminAuth.createCustomToken(uid);\r\n return customToken;\r\n } catch (error) {\r\n console.error(\"[createCustomToken] Error creating custom token:\", error);\r\n return null;\r\n }\r\n}\r\n","import type { RequestOptions } from \"./types\";\n\nexport const getSessionConfig = (options?: RequestOptions) => {\n const cookieConfig = options?.cookies?.session_cookie;\n \n return {\n COOKIE_NAME: cookieConfig?.name,\n DEFAULT_EXPIRES_IN_MS: cookieConfig?.attributes?.maxAge,\n DEFAULT_EXPIRES_IN_SECONDS: Math.floor((cookieConfig?.attributes?.maxAge || 0) / 1000),\n REVOKE_REFRESH_TOKENS_ON_SIGNOUT: cookieConfig?.revokeRefreshTokensOnSignOut,\n };\n};\n\n\nexport const getCookieOptions = (options?: RequestOptions) => {\n const cookieConfig = options?.cookies?.session_cookie;\n \n return {\n httpOnly: cookieConfig?.attributes?.httpOnly,\n secure: cookieConfig?.attributes?.secure,\n sameSite: cookieConfig?.attributes?.sameSite,\n path: cookieConfig?.attributes?.path,\n };\n};","import admin from 'firebase-admin';\r\n\r\nimport { initializeAdminConfig } from './config';\r\n\r\nif (!admin.apps.length) {\r\n try {\r\n const config = initializeAdminConfig();\r\n admin.initializeApp({\r\n credential: admin.credential.cert({\r\n ...config,\r\n privateKey: config.privateKey.replace(/\\\\n/g, '\\n'),\r\n }),\r\n });\r\n } catch (error) {\r\n console.error('Firebase admin initialization error', error);\r\n }\r\n}\r\n\r\nexport const adminTernSecureAuth: admin.auth.Auth = admin.auth();\r\nexport const adminTernSecureDb: admin.firestore.Firestore = admin.firestore();\r\nexport const TernSecureTenantManager: admin.auth.TenantManager = admin.auth().tenantManager();\r\n\r\n/**\r\n * Gets the appropriate Firebase Auth instance.\r\n * If a tenantId is provided, it returns the Auth instance for that tenant.\r\n * Otherwise, it returns the default project-level Auth instance.\r\n * @param tenantId - The optional tenant ID.\r\n * @returns An admin.auth.Auth instance.\r\n */\r\nexport function getAuthForTenant(tenantId?: string): admin.auth.Auth {\r\n if (tenantId) {\r\n return TernSecureTenantManager.authForTenant(tenantId) as unknown as admin.auth.Auth;\r\n }\r\n return admin.auth();\r\n}","import type { \r\n AdminConfigValidationResult, \r\n ConfigValidationResult, \r\n TernSecureAdminConfig, \r\n TernSecureConfig} from '@tern-secure/types'\r\n\r\n/**\r\n * Loads Firebase configuration from environment variables\r\n * @returns {TernSecureConfig} Firebase configuration object\r\n */\r\nexport const loadFireConfig = (): TernSecureConfig => ({\r\n apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY || '',\r\n authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN || '',\r\n projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID || '',\r\n storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET || '',\r\n messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID || '',\r\n appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID || '',\r\n measurementId: process.env.NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID || undefined,\r\n})\r\n\r\n/**\r\n * Validates Firebase configuration\r\n * @param {TernSecureConfig} config - Firebase configuration object\r\n * @throws {Error} If required configuration values are missing\r\n * @returns {TernSecureConfig} Validated configuration object\r\n */\r\nexport const validateConfig = (config: TernSecureConfig): ConfigValidationResult => {\r\n const requiredFields: (keyof TernSecureConfig)[] = [\r\n 'apiKey',\r\n 'authDomain',\r\n 'projectId',\r\n 'storageBucket',\r\n 'messagingSenderId',\r\n 'appId'\r\n ]\r\n\r\n const errors: string[] = []\r\n \r\n requiredFields.forEach(field => {\r\n if (!config[field]) {\r\n errors.push(`Missing required field: NEXT_PUBLIC_FIREBASE_${String(field).toUpperCase()}`)\r\n }\r\n })\r\n\r\n return {\r\n isValid: errors.length === 0,\r\n errors,\r\n config\r\n }\r\n}\r\n\r\n/**\r\n * Initializes configuration with validation\r\n * @throws {Error} If configuration is invalid\r\n */\r\nexport const initializeConfig = (): TernSecureConfig => {\r\n const config = loadFireConfig()\r\n const validationResult = validateConfig(config)\r\n\r\n if (!validationResult.isValid) {\r\n throw new Error(\r\n `Firebase configuration validation failed:\\n${validationResult.errors.join('\\n')}`\r\n )\r\n }\r\n\r\n return config\r\n}\r\n\r\n/**\r\n * Loads Firebase Admin configuration from environment variables\r\n * @returns {AdminConfig} Firebase Admin configuration object\r\n */\r\nexport const loadAdminConfig = (): TernSecureAdminConfig => ({\r\n projectId: process.env.FIREBASE_PROJECT_ID || '',\r\n clientEmail: process.env.FIREBASE_CLIENT_EMAIL || '',\r\n privateKey: process.env.FIREBASE_PRIVATE_KEY || '',\r\n})\r\n\r\n/**\r\n * Validates Firebase Admin configuration\r\n * @param {AdminConfig} config - Firebase Admin configuration object\r\n * @returns {ConfigValidationResult} Validation result\r\n */\r\nexport const validateAdminConfig = (config: TernSecureAdminConfig): AdminConfigValidationResult => {\r\n const requiredFields: (keyof TernSecureAdminConfig)[] = [\r\n 'projectId',\r\n 'clientEmail',\r\n 'privateKey'\r\n ]\r\n\r\n const errors: string[] = []\r\n \r\n requiredFields.forEach(field => {\r\n if (!config[field]) {\r\n errors.push(`Missing required field: FIREBASE_${String(field).toUpperCase()}`)\r\n }\r\n })\r\n\r\n return {\r\n isValid: errors.length === 0,\r\n errors,\r\n config\r\n }\r\n}\r\n\r\n/**\r\n * Initializes admin configuration with validation\r\n * @throws {Error} If configuration is invalid\r\n */\r\nexport const initializeAdminConfig = (): TernSecureAdminConfig => {\r\n const config = loadAdminConfig()\r\n const validationResult = validateAdminConfig(config)\r\n\r\n if (!validationResult.isValid) {\r\n throw new Error(\r\n `Firebase Admin configuration validation failed:\\n${validationResult.errors.join('\\n')}`\r\n )\r\n }\r\n\r\n return config\r\n}","import type { SignInResponse } from '@tern-secure/types';\r\n\r\nimport { TernSecureTenantManager } from \"../utils/admin-init\";\r\n\r\n\r\nexport async function createTenant(\r\n displayName: string,\r\n emailSignInConfig: {\r\n enabled: boolean;\r\n passwordRequired: boolean;\r\n },\r\n multiFactorConfig?: {\r\n state: 'ENABLED' | 'DISABLED';\r\n factorIds: \"phone\"[];\r\n testPhoneNumbers?: {\r\n [phoneNumber: string]: string;\r\n }\r\n }\r\n) {\r\n try {\r\n const tenantConfig = {\r\n displayName,\r\n emailSignInConfig,\r\n ...(multiFactorConfig && { multiFactorConfig })\r\n };\r\n\r\n const tenant = await TernSecureTenantManager.createTenant(tenantConfig);\r\n \r\n return {\r\n success: true,\r\n tenantId: tenant.tenantId,\r\n displayName: tenant.displayName,\r\n };\r\n } catch (error) {\r\n console.error('Error creating tenant:', error);\r\n throw new Error('Failed to create tenant');\r\n }\r\n}\r\n\r\nexport async function createTenantUser(\r\n email: string,\r\n password: string,\r\n tenantId: string\r\n): Promise<SignInResponse> {\r\n try {\r\n const tenantAuth = TernSecureTenantManager.authForTenant(tenantId);\r\n \r\n const userRecord = await tenantAuth.createUser({\r\n email,\r\n password,\r\n emailVerified: false,\r\n disabled: false\r\n });\r\n\r\n return {\r\n success: true,\r\n message: 'Tenant user created successfully',\r\n user: userRecord.uid,\r\n };\r\n } catch (error) {\r\n console.error('Error creating tenant user:', error);\r\n throw new Error('Failed to create tenant user');\r\n }\r\n}\r\n","\"use server\";\n\nimport { handleFirebaseAuthError } from \"@tern-secure/shared/errors\";\nimport type { TernVerificationResult } from \"@tern-secure/types\";\nimport { cookies } from \"next/headers\";\n\nimport { adminTernSecureAuth as adminAuth, getAuthForTenant } from \"../utils/admin-init\";\n\n\nconst SESSION_CONSTANTS = {\n COOKIE_NAME: \"_session_cookie\",\n DEFAULT_EXPIRES_IN_MS: 60 * 60 * 24 * 5 * 1000, // 5 days\n DEFAULT_EXPIRES_IN_SECONDS: 60 * 60 * 24 * 5,\n REVOKE_REFRESH_TOKENS_ON_SIGNOUT: true,\n} as const;\n\nexport async function CreateNextSessionCookie(idToken: string) {\n try {\n const expiresIn = 60 * 60 * 24 * 5 * 1000;\n const sessionCookie = await adminAuth.createSessionCookie(idToken, {\n expiresIn,\n });\n\n const cookieStore = await cookies();\n cookieStore.set(\"_session_cookie\", sessionCookie, {\n maxAge: expiresIn,\n httpOnly: true,\n secure: process.env.NODE_ENV === \"production\",\n path: \"/\",\n });\n return { success: true, message: \"Session created\" };\n } catch (error) {\n return { success: false, message: \"Failed to create session\" };\n }\n}\n\nexport async function GetNextServerSessionCookie() {\n const cookieStore = await cookies();\n const sessionCookie = cookieStore.get(\"_session_cookie\")?.value;\n\n if (!sessionCookie) {\n throw new Error(\"No session cookie found\");\n }\n\n try {\n const decondeClaims = await adminAuth.verifySessionCookie(\n sessionCookie,\n true\n );\n return {\n token: sessionCookie,\n userId: decondeClaims.uid,\n };\n } catch (error) {\n console.error(\"Error verifying session:\", error);\n throw new Error(\"Invalid Session\");\n }\n}\n\nexport async function GetNextIdToken() {\n const cookieStore = await cookies();\n const token = cookieStore.get(\"_session_token\")?.value;\n\n if (!token) {\n throw new Error(\"No session cookie found\");\n }\n\n try {\n const decodedClaims = await adminAuth.verifyIdToken(token);\n return {\n token: token,\n userId: decodedClaims.uid,\n };\n } catch (error) {\n console.error(\"Error verifying session:\", error);\n throw new Error(\"Invalid Session\");\n }\n}\n\nexport async function SetNextServerSession(token: string) {\n try {\n const cookieStore = await cookies();\n cookieStore.set(\"_session_token\", token, {\n httpOnly: true,\n secure: process.env.NODE_ENV === \"production\",\n sameSite: \"strict\",\n maxAge: 60 * 60, // 1 hour\n path: \"/\",\n });\n return { success: true, message: \"Session created\" };\n } catch {\n return { success: false, message: \"Failed to create session\" };\n }\n}\n\nexport async function SetNextServerToken(token: string) {\n try {\n const cookieStore = await cookies();\n cookieStore.set(\"_tern\", token, {\n httpOnly: true,\n secure: process.env.NODE_ENV === \"production\",\n sameSite: \"strict\",\n maxAge: 60 * 60, // 1 hour\n path: \"/\",\n });\n return { success: true, message: \"Session created\" };\n } catch {\n return { success: false, message: \"Failed to create session\" };\n }\n}\n\nexport async function VerifyNextTernIdToken(\n token: string\n): Promise<TernVerificationResult> {\n try {\n const decodedToken = await adminAuth.verifyIdToken(token);\n return {\n ...decodedToken,\n valid: true,\n };\n } catch (error) {\n console.error(\"[VerifyNextTernIdToken] Error verifying session:\", error);\n const authError = handleFirebaseAuthError(error);\n return {\n valid: false,\n error: authError,\n };\n }\n}\n\nexport async function VerifyNextTernSessionCookie(\n session: string\n): Promise<TernVerificationResult> {\n try {\n const res = await adminAuth.verifySessionCookie(session);\n console.warn(\n \"[VerifyNextTernSessionCookie] uid in Decoded Token:\",\n res.uid\n );\n return {\n valid: true,\n ...res,\n };\n } catch (error) {\n console.error(\n \"[VerifyNextTernSessionCookie] Error verifying session:\",\n error\n );\n const authError = handleFirebaseAuthError(error);\n return {\n valid: false,\n error: authError,\n };\n }\n}\n\nexport async function ClearNextSessionCookie(tenantId?: string) {\n try {\n console.log(\"[clearSessionCookie] Clearing session for tenant:\", tenantId);\n const tenantAuth = getAuthForTenant(tenantId);\n const cookieStore = await cookies();\n const sessionCookie = cookieStore.get(SESSION_CONSTANTS.COOKIE_NAME);\n\n cookieStore.delete(SESSION_CONSTANTS.COOKIE_NAME);\n cookieStore.delete(\"_session_token\");\n cookieStore.delete(\"_session\");\n\n if (\n SESSION_CONSTANTS.REVOKE_REFRESH_TOKENS_ON_SIGNOUT &&\n sessionCookie?.value\n ) {\n try {\n const decodedClaims = await tenantAuth.verifySessionCookie(\n sessionCookie.value\n );\n await tenantAuth.revokeRefreshTokens(decodedClaims.sub);\n console.log(\n `[clearSessionCookie] Successfully revoked tokens for user: ${decodedClaims.sub}`\n );\n } catch (revokeError) {\n console.error(\n \"[ClearNextSessionCookie] Failed to revoke refresh tokens:\",\n revokeError\n );\n }\n }\n return { success: true, message: \"Session cleared successfully\" };\n } catch (error) {\n console.error(\"Error clearing session:\", error);\n return { success: false, message: \"Failed to clear session cookies\" };\n }\n}\n","import { parse } from \"cookie\";\n\nimport { constants } from \"../constants\";\nimport type { TernUrl } from \"./ternUrl\";\nimport { createTernUrl } from \"./ternUrl\";\n\nclass TernSecureRequest extends Request {\n readonly ternUrl: TernUrl;\n readonly cookies: Map<string, string | undefined>;\n\n public constructor(\n input: TernSecureRequest | Request | RequestInfo,\n init?: RequestInit\n ) {\n const url =\n typeof input !== \"string\" && \"url\" in input ? input.url : String(input);\n super(url, init || typeof input === \"string\" ? undefined : input);\n this.ternUrl = this.deriveUrlFromHeaders(this);\n this.cookies = this.parseCookies(this);\n }\n\n public toJSON() {\n return {\n url: this.ternUrl.href,\n method: this.method,\n headers: JSON.stringify(Object.fromEntries(this.headers)),\n ternUrl: this.ternUrl.toString(),\n cookies: JSON.stringify(Object.fromEntries(this.cookies)),\n };\n }\n\n private deriveUrlFromHeaders(req: Request) {\n const initialUrl = new URL(req.url);\n const forwardedProto = req.headers.get(constants.Headers.ForwardedProto);\n const forwardedHost = req.headers.get(constants.Headers.ForwardedHost);\n const host = req.headers.get(constants.Headers.Host);\n const protocol = initialUrl.protocol;\n\n const resolvedHost = this.getFirstValueFromHeader(forwardedHost) ?? host;\n const resolvedProtocol =\n this.getFirstValueFromHeader(forwardedProto) ??\n protocol?.replace(/[:/]/, \"\");\n const origin =\n resolvedHost && resolvedProtocol\n ? `${resolvedProtocol}://${resolvedHost}`\n : initialUrl.origin;\n\n if (origin === initialUrl.origin) {\n return createTernUrl(initialUrl);\n }\n\n return createTernUrl(initialUrl.pathname + initialUrl.search, origin);\n }\n\n private getFirstValueFromHeader(value?: string | null) {\n return value?.split(\",\")[0];\n }\n\n private parseCookies(req: Request) {\n const cookiesRecord = parse(\n this.decodeCookieValue(req.headers.get(\"cookie\") || \"\")\n );\n return new Map(Object.entries(cookiesRecord));\n }\n\n private decodeCookieValue(str: string) {\n return str ? str.replace(/(%[0-9A-Z]{2})+/g, decodeURIComponent) : str;\n }\n}\n\nexport const createTernSecureRequest = (\n ...args: ConstructorParameters<typeof TernSecureRequest>\n): TernSecureRequest => {\n return args[0] instanceof TernSecureRequest\n ? args[0]\n : new TernSecureRequest(...args);\n};\n\nexport type { TernSecureRequest };\n","export const GOOGLE_PUBLIC_KEYS_URL =\n 'https://www.googleapis.com/robot/v1/metadata/x509/securetoken@system.gserviceaccount.com';\nexport const SESSION_COOKIE_PUBLIC_KEYS_URL =\n 'https://www.googleapis.com/identitytoolkit/v3/relyingparty/publicKeys';\nexport const MAX_CACHE_LAST_UPDATED_AT_SECONDS = 5 * 60;\nexport const DEFAULT_CACHE_DURATION = 3600 * 1000; // 1 hour in milliseconds\nexport const CACHE_CONTROL_REGEX = /max-age=(\\d+)/;\n\nconst Attributes = {\n AuthToken: '__ternsecureAuthToken',\n AuthSignature: '__ternsecureAuthSignature',\n AuthStatus: '__ternsecureAuthStatus',\n AuthReason: '__ternsecureAuthReason',\n AuthMessage: '__ternsecureAuthMessage',\n TernSecureUrl: '__ternsecureUrl',\n} as const;\n\nconst Cookies = {\n Session: '__session',\n IdToken: '_tern',\n SessionCookie: '_session_cookie',\n SessionToken: '_session_token',\n Refresh: '__refresh',\n Handshake: '__ternsecure_handshake',\n DevBrowser: '__ternsecure_db_jwt',\n RedirectCount: '__ternsecure_redirect_count',\n HandshakeNonce: '__ternsecure_handshake_nonce',\n} as const;\n\nconst Headers = {\n Accept: 'accept',\n AuthMessage: 'x-ternsecure-auth-message',\n Authorization: 'authorization',\n AuthReason: 'x-ternsecure-auth-reason',\n AuthSignature: 'x-ternsecure-auth-signature',\n AuthStatus: 'x-ternsecure-auth-status',\n AuthToken: 'x-ternsecure-auth-token',\n CacheControl: 'cache-control',\n TernSecureRedirectTo: 'x-ternsecure-redirect-to',\n TernSecureRequestData: 'x-ternsecure-request-data',\n TernSecureUrl: 'x-ternsecure-url',\n CloudFrontForwardedProto: 'cloudfront-forwarded-proto',\n ContentType: 'content-type',\n ContentSecurityPolicy: 'content-security-policy',\n ContentSecurityPolicyReportOnly: 'content-security-policy-report-only',\n EnableDebug: 'x-ternsecure-debug',\n ForwardedHost: 'x-forwarded-host',\n ForwardedPort: 'x-forwarded-port',\n ForwardedProto: 'x-forwarded-proto',\n Host: 'host',\n Location: 'location',\n Nonce: 'x-nonce',\n Origin: 'origin',\n Referrer: 'referer',\n SecFetchDest: 'sec-fetch-dest',\n UserAgent: 'user-agent',\n ReportingEndpoints: 'reporting-endpoints',\n} as const;\n\nconst ContentTypes = {\n Json: 'application/json',\n} as const;\n\n/**\n * @internal\n */\nexport const constants = {\n Attributes,\n Cookies,\n Headers,\n ContentTypes,\n} as const;\n\nexport type Constants = typeof constants;\n","class TernUrl extends URL {\n public isCrossOrigin(other: URL | string) {\n return this.origin !== new URL(other.toString()).origin;\n }\n}\n\nexport type WithTernUrl<T> = T & {\n /**\n * When a NextJs app is hosted on a platform different from Vercel\n * or inside a container (Netlify, Fly.io, AWS Amplify, docker etc),\n * req.url is always set to `localhost:3000` instead of the actual host of the app.\n *\n */\n ternUrl: TernUrl;\n};\n\nexport const createTernUrl = (\n ...args: ConstructorParameters<typeof TernUrl>\n): TernUrl => {\n return new TernUrl(...args);\n};\n\nexport type { TernUrl };\n","import type { CheckCustomClaims, DecodedIdToken,SharedSignInAuthObjectProperties } from \"@tern-secure/types\";\n\nimport { VerifyNextTernSessionCookie } from \"../admin/nextSessionTernSecure\";\nimport type { TernSecureRequest} from \"../tokens/ternSecureRequest\";\nimport { createTernSecureRequest } from \"../tokens/ternSecureRequest\";\n\nexport type SignInAuthObject = SharedSignInAuthObjectProperties & {\n has: CheckCustomClaims\n}\n\nexport type SignInState = {\n auth: () => SignInAuthObject\n token: string\n headers: Headers\n}\n\nexport type RequestState = SignInState\n\nexport interface BackendInstance {\n ternSecureRequest: TernSecureRequest;\n requestState: RequestState;\n}\n\nexport const createBackendInstance = async (request: Request): Promise<BackendInstance> => {\n const ternSecureRequest = createTernSecureRequest(request);\n const requestState = await authenticateRequest(request);\n \n return {\n ternSecureRequest,\n requestState,\n };\n};\n\nexport async function authenticateRequest(request: Request): Promise<RequestState> {\n const sessionCookie = request.headers.get('cookie');\n const sessionToken = sessionCookie?.split(';')\n .find(c => c.trim().startsWith('_session_cookie='))\n ?.split('=')[1];\n \n if (!sessionToken) {\n throw new Error(\"No session token found\");\n }\n\n const verificationResult = await VerifyNextTernSessionCookie(sessionToken);\n\n if (!verificationResult.valid) {\n throw new Error(\"Invalid session token\");\n }\n\n return signedIn(\n verificationResult as DecodedIdToken,\n new Headers(request.headers),\n sessionToken\n );\n}\n\nexport function signInAuthObject(\n session: DecodedIdToken,\n): SignInAuthObject {\n return {\n session,\n userId: session.uid,\n has: {} as CheckCustomClaims,\n };\n}\n\nexport function signedIn(\n session: DecodedIdToken,\n headers: Headers = new Headers(),\n token: string\n): SignInState {\n const authObject = signInAuthObject(session);\n return {\n auth: () => authObject,\n token,\n headers,\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACEA,oBAAwC;;;ACAjC,IAAM,mBAAmB,CAAC,YAA6B;AAC5D,QAAM,eAAe,SAAS,SAAS;AAEvC,SAAO;AAAA,IACL,aAAa,cAAc;AAAA,IAC3B,uBAAuB,cAAc,YAAY;AAAA,IACjD,4BAA4B,KAAK,OAAO,cAAc,YAAY,UAAU,KAAK,GAAI;AAAA,IACrF,kCAAkC,cAAc;AAAA,EAClD;AACF;AAGO,IAAM,mBAAmB,CAAC,YAA6B;AAC5D,QAAM,eAAe,SAAS,SAAS;AAEvC,SAAO;AAAA,IACL,UAAU,cAAc,YAAY;AAAA,IACpC,QAAQ,cAAc,YAAY;AAAA,IAClC,UAAU,cAAc,YAAY;AAAA,IACpC,MAAM,cAAc,YAAY;AAAA,EAClC;AACF;;;ACvBA,4BAAkB;;;ACwEX,IAAM,kBAAkB,OAA8B;AAAA,EAC3D,WAAW,QAAQ,IAAI,uBAAuB;AAAA,EAC9C,aAAa,QAAQ,IAAI,yBAAyB;AAAA,EAClD,YAAY,QAAQ,IAAI,wBAAwB;AAClD;AAOO,IAAM,sBAAsB,CAAC,WAA+D;AACjG,QAAM,iBAAkD;AAAA,IACtD;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,QAAM,SAAmB,CAAC;AAE1B,iBAAe,QAAQ,WAAS;AAC9B,QAAI,CAAC,OAAO,KAAK,GAAG;AAClB,aAAO,KAAK,oCAAoC,OAAO,KAAK,EAAE,YAAY,CAAC,EAAE;AAAA,IAC/E;AAAA,EACF,CAAC;AAED,SAAO;AAAA,IACL,SAAS,OAAO,WAAW;AAAA,IAC3B;AAAA,IACA;AAAA,EACF;AACF;AAMO,IAAM,wBAAwB,MAA6B;AAChE,QAAM,SAAS,gBAAgB;AAC/B,QAAM,mBAAmB,oBAAoB,MAAM;AAEnD,MAAI,CAAC,iBAAiB,SAAS;AAC7B,UAAM,IAAI;AAAA,MACR;AAAA,EAAoD,iBAAiB,OAAO,KAAK,IAAI,CAAC;AAAA,IACxF;AAAA,EACF;AAEA,SAAO;AACT;;;ADpHA,IAAI,CAAC,sBAAAA,QAAM,KAAK,QAAQ;AACtB,MAAI;AACF,UAAM,SAAS,sBAAsB;AACrC,0BAAAA,QAAM,cAAc;AAAA,MAClB,YAAY,sBAAAA,QAAM,WAAW,KAAK;AAAA,QAChC,GAAG;AAAA,QACH,YAAY,OAAO,WAAW,QAAQ,QAAQ,IAAI;AAAA,MACpD,CAAC;AAAA,IACH,CAAC;AAAA,EACH,SAAS,OAAO;AACd,YAAQ,MAAM,uCAAuC,KAAK;AAAA,EAC5D;AACF;AAEO,IAAM,sBAAuC,sBAAAA,QAAM,KAAK;AACxD,IAAM,oBAA+C,sBAAAA,QAAM,UAAU;AACrE,IAAM,0BAAoD,sBAAAA,QAAM,KAAK,EAAE,cAAc;AASrF,SAAS,iBAAiB,UAAoC;AACnE,MAAI,UAAU;AACZ,WAAO,wBAAwB,cAAc,QAAQ;AAAA,EACvD;AACA,SAAO,sBAAAA,QAAM,KAAK;AACpB;;;AFrBA,IAAM,oBAAoB;AAAA,EACxB,aAAa;AAAA;AAAA;AAAA,EAGb,uBAAuB,IAAI,KAAK;AAAA;AAAA,EAChC,4BAA4B,IAAI;AAAA,EAChC,kCAAkC;AACpC;AAEA,IAAM,iBAAiB;AAAA,EACrB,UAAU;AAAA,EACV,QAAQ,QAAQ,IAAI,aAAa;AAAA,EACjC,UAAU;AAAA,EACV,MAAM;AACR;AAGA,eAAsB,oBACpB,QACA,aACA,SACwB;AACxB,MAAI;AACF,UAAM,aAAa,iBAAiB,SAAS,QAAQ;AAErD,UAAM,gBAAgB,iBAAiB,OAAO;AAC9C,UAAM,gBAAgB,iBAAiB,OAAO;AAE9C,QAAI;AACJ,QAAI;AAEJ,UAAM,UAAU,OAAO,WAAW,WAAW,SAAS,OAAO;AAE7D,QAAI,CAAC,SAAS;AACZ,YAAM,QAAQ,IAAI,MAAM,2CAA2C;AACnE,cAAQ,MAAM,2CAA2C,KAAK;AAC9D,aAAO;AAAA,QACL,SAAS;AAAA,QACT,SAAS;AAAA,QACT,OAAO;AAAA,QACP,WAAW;AAAA,MACb;AAAA,IACF;AAEA,QAAI;AACF,cAAQ,IAAI,kCAAkC,SAAS,QAAQ;AAC/D,qBAAe,MAAM,WAAW,cAAc,OAAO;AAAA,IACvD,SAAS,aAAa;AACpB,cAAQ;AAAA,QACN;AAAA,QACA;AAAA,MACF;AACA,YAAM,gBAAY,uCAAwB,WAAW;AACrD,aAAO;AAAA,QACL,SAAS;AAAA,QACT,SAAS,UAAU;AAAA,QACnB,OAAO,UAAU;AAAA,QACjB,WAAW;AAAA,MACb;AAAA,IACF;AAEA,QAAI,CAAC,cAAc;AACjB,YAAM,QAAQ,IAAI,MAAM,+CAA+C;AACvE,cAAQ;AAAA,QACN;AAAA,QACA;AAAA,MACF;AACA,aAAO;AAAA,QACL,SAAS;AAAA,QACT,SAAS;AAAA,QACT,OAAO;AAAA,QACP,WAAW;AAAA,MACb;AAAA,IACF;AAEA,QAAI;AACF,sBAAgB,MAAM,WAAW,oBAAoB,SAAS;AAAA,QAC5D,WAAW,kBAAkB;AAAA,MAC/B,CAAC;AAAA,IACH,SAAS,cAAc;AACrB,cAAQ;AAAA,QACN;AAAA,QACA;AAAA,MACF;AACA,YAAM,gBAAY,uCAAwB,YAAY;AACtD,aAAO;AAAA,QACL,SAAS;AAAA,QACT,SAAS,UAAU;AAAA,QACnB,OAAO,UAAU;AAAA,QACjB,WAAW;AAAA,MACb;AAAA,IACF;AAGA,QAAI,wBAAwB;AAC5B,QAAI;AAEF,kBAAY,IAAI,kBAAkB,aAAa,eAAe;AAAA,QAC5D,QAAQ,kBAAkB;AAAA,QAC1B,GAAG;AAAA,MACL,CAAC;AAGD,YAAM,kBAAkB,MAAM,YAAY;AAAA,QACxC,kBAAkB;AAAA,MACpB;AACA,8BAAwB,CAAC,CAAC,iBAAiB;AAE3C,UAAI,CAAC,uBAAuB;AAC1B,cAAM,QAAQ,IAAI,MAAM,yCAAyC;AACjE,gBAAQ;AAAA,UACN;AAAA,UACA;AAAA,QACF;AACA,cAAM;AAAA,MACR;AAAA,IACF,SAAS,aAAa;AACpB,cAAQ;AAAA,QACN;AAAA,QACA;AAAA,MACF;AACA,aAAO;AAAA,QACL,SAAS;AAAA,QACT,SAAS;AAAA,QACT,OAAO;AAAA,QACP,WAAW;AAAA,MACb;AAAA,IACF;AAEA,YAAQ;AAAA,MACN,uEAAuE,aAAa,GAAG;AAAA,IACzF;AACA,WAAO;AAAA,MACL,SAAS;AAAA,MACT,SAAS;AAAA,MACT,WAAW,kBAAkB;AAAA,MAC7B,WAAW;AAAA,IACb;AAAA,EACF,SAAS,OAAO;AACd,YAAQ,MAAM,2CAA2C,KAAK;AAC9D,UAAM,gBAAY,uCAAwB,KAAK;AAC/C,WAAO;AAAA,MACL,SAAS;AAAA,MACT,SAAS,UAAU,WAAW;AAAA,MAC9B,OAAO,UAAU,QAAQ;AAAA,MACzB,WAAW;AAAA,IACb;AAAA,EACF;AACF;AAEA,eAAsB,mBACpB,aACA,SACwB;AACxB,MAAI;AACF,UAAM,YAAY,iBAAiB,SAAS,QAAQ;AACpD,UAAM,gBAAgB,MAAM,YAAY,IAAI,kBAAkB,WAAW;AAEzE,UAAM,YAAY,OAAO,kBAAkB,WAAW;AACtD,UAAM,YAAY,OAAO,gBAAgB;AACzC,UAAM,YAAY,OAAO,UAAU;AAEnC,QACE,kBAAkB,oCAClB,eAAe,OACf;AACA,UAAI;AACF,cAAM,gBAAgB,MAAM,UAAU;AAAA,UACpC,cAAc;AAAA,QAChB;AACA,cAAM,UAAU,oBAAoB,cAAc,GAAG;AACrD,gBAAQ;AAAA,UACN,8DAA8D,cAAc,GAAG;AAAA,QACjF;AAAA,MACF,SAAS,aAAa;AACpB,gBAAQ;AAAA,UACN;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,YAAQ,IAAI,2DAA2D;AACvE,WAAO;AAAA,MACL,SAAS;AAAA,MACT,SAAS;AAAA,MACT,WAAW;AAAA,IACb;AAAA,EACF,SAAS,OAAO;AACd,YAAQ,MAAM,0CAA0C,KAAK;AAC7D,UAAM,gBAAY,uCAAwB,KAAK;AAC/C,WAAO;AAAA,MACL,SAAS;AAAA,MACT,SAAS,UAAU,WAAW;AAAA,MAC9B,OAAO,UAAU,QAAQ;AAAA,MACzB,WAAW;AAAA,IACb;AAAA,EACF;AACF;;;AI9MA,eAAsB,aACpB,aACA,mBAIA,mBAOA;AACA,MAAI;AACF,UAAM,eAAe;AAAA,MACnB;AAAA,MACA;AAAA,MACA,GAAI,qBAAqB,EAAE,kBAAkB;AAAA,IAC/C;AAEA,UAAM,SAAS,MAAM,wBAAwB,aAAa,YAAY;AAEtE,WAAO;AAAA,MACL,SAAS;AAAA,MACT,UAAU,OAAO;AAAA,MACjB,aAAa,OAAO;AAAA,IACtB;AAAA,EACF,SAAS,OAAO;AACd,YAAQ,MAAM,0BAA0B,KAAK;AAC7C,UAAM,IAAI,MAAM,yBAAyB;AAAA,EAC3C;AACF;AAEA,eAAsB,iBACpB,OACA,UACA,UACyB;AACzB,MAAI;AACF,UAAM,aAAa,wBAAwB,cAAc,QAAQ;AAEjE,UAAM,aAAa,MAAM,WAAW,WAAW;AAAA,MAC7C;AAAA,MACA;AAAA,MACA,eAAe;AAAA,MACf,UAAU;AAAA,IACZ,CAAC;AAED,WAAO;AAAA,MACL,SAAS;AAAA,MACT,SAAS;AAAA,MACT,MAAM,WAAW;AAAA,IACnB;AAAA,EACF,SAAS,OAAO;AACd,YAAQ,MAAM,+BAA+B,KAAK;AAClD,UAAM,IAAI,MAAM,8BAA8B;AAAA,EAChD;AACF;;;AC7DA,IAAAC,iBAAwC;AAExC,qBAAwB;AAKxB,IAAMC,qBAAoB;AAAA,EACxB,aAAa;AAAA,EACb,uBAAuB,KAAK,KAAK,KAAK,IAAI;AAAA;AAAA,EAC1C,4BAA4B,KAAK,KAAK,KAAK;AAAA,EAC3C,kCAAkC;AACpC;AAEA,eAAsB,wBAAwB,SAAiB;AAC7D,MAAI;AACF,UAAM,YAAY,KAAK,KAAK,KAAK,IAAI;AACrC,UAAM,gBAAgB,MAAM,oBAAU,oBAAoB,SAAS;AAAA,MACjE;AAAA,IACF,CAAC;AAED,UAAM,cAAc,UAAM,wBAAQ;AAClC,gBAAY,IAAI,mBAAmB,eAAe;AAAA,MAChD,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,QAAQ,QAAQ,IAAI,aAAa;AAAA,MACjC,MAAM;AAAA,IACR,CAAC;AACD,WAAO,EAAE,SAAS,MAAM,SAAS,kBAAkB;AAAA,EACrD,SAAS,OAAO;AACd,WAAO,EAAE,SAAS,OAAO,SAAS,2BAA2B;AAAA,EAC/D;AACF;AAEA,eAAsB,6BAA6B;AACjD,QAAM,cAAc,UAAM,wBAAQ;AAClC,QAAM,gBAAgB,YAAY,IAAI,iBAAiB,GAAG;AAE1D,MAAI,CAAC,eAAe;AAClB,UAAM,IAAI,MAAM,yBAAyB;AAAA,EAC3C;AAEA,MAAI;AACF,UAAM,gBAAgB,MAAM,oBAAU;AAAA,MACpC;AAAA,MACA;AAAA,IACF;AACA,WAAO;AAAA,MACL,OAAO;AAAA,MACP,QAAQ,cAAc;AAAA,IACxB;AAAA,EACF,SAAS,OAAO;AACd,YAAQ,MAAM,4BAA4B,KAAK;AAC/C,UAAM,IAAI,MAAM,iBAAiB;AAAA,EACnC;AACF;AAEA,eAAsB,iBAAiB;AACrC,QAAM,cAAc,UAAM,wBAAQ;AAClC,QAAM,QAAQ,YAAY,IAAI,gBAAgB,GAAG;AAEjD,MAAI,CAAC,OAAO;AACV,UAAM,IAAI,MAAM,yBAAyB;AAAA,EAC3C;AAEA,MAAI;AACF,UAAM,gBAAgB,MAAM,oBAAU,cAAc,KAAK;AACzD,WAAO;AAAA,MACL;AAAA,MACA,QAAQ,cAAc;AAAA,IACxB;AAAA,EACF,SAAS,OAAO;AACd,YAAQ,MAAM,4BAA4B,KAAK;AAC/C,UAAM,IAAI,MAAM,iBAAiB;AAAA,EACnC;AACF;AAEA,eAAsB,qBAAqB,OAAe;AACxD,MAAI;AACF,UAAM,cAAc,UAAM,wBAAQ;AAClC,gBAAY,IAAI,kBAAkB,OAAO;AAAA,MACvC,UAAU;AAAA,MACV,QAAQ,QAAQ,IAAI,aAAa;AAAA,MACjC,UAAU;AAAA,MACV,QAAQ,KAAK;AAAA;AAAA,MACb,MAAM;AAAA,IACR,CAAC;AACD,WAAO,EAAE,SAAS,MAAM,SAAS,kBAAkB;AAAA,EACrD,QAAQ;AACN,WAAO,EAAE,SAAS,OAAO,SAAS,2BAA2B;AAAA,EAC/D;AACF;AAEA,eAAsB,mBAAmB,OAAe;AACtD,MAAI;AACF,UAAM,cAAc,UAAM,wBAAQ;AAClC,gBAAY,IAAI,SAAS,OAAO;AAAA,MAC9B,UAAU;AAAA,MACV,QAAQ,QAAQ,IAAI,aAAa;AAAA,MACjC,UAAU;AAAA,MACV,QAAQ,KAAK;AAAA;AAAA,MACb,MAAM;AAAA,IACR,CAAC;AACD,WAAO,EAAE,SAAS,MAAM,SAAS,kBAAkB;AAAA,EACrD,QAAQ;AACN,WAAO,EAAE,SAAS,OAAO,SAAS,2BAA2B;AAAA,EAC/D;AACF;AAEA,eAAsB,sBACpB,OACiC;AACjC,MAAI;AACF,UAAM,eAAe,MAAM,oBAAU,cAAc,KAAK;AACxD,WAAO;AAAA,MACL,GAAG;AAAA,MACH,OAAO;AAAA,IACT;AAAA,EACF,SAAS,OAAO;AACd,YAAQ,MAAM,oDAAoD,KAAK;AACvE,UAAM,gBAAY,wCAAwB,KAAK;AAC/C,WAAO;AAAA,MACL,OAAO;AAAA,MACP,OAAO;AAAA,IACT;AAAA,EACF;AACF;AAEA,eAAsB,4BACpB,SACiC;AACjC,MAAI;AACF,UAAM,MAAM,MAAM,oBAAU,oBAAoB,OAAO;AACvD,YAAQ;AAAA,MACN;AAAA,MACA,IAAI;AAAA,IACN;AACA,WAAO;AAAA,MACL,OAAO;AAAA,MACP,GAAG;AAAA,IACL;AAAA,EACF,SAAS,OAAO;AACd,YAAQ;AAAA,MACN;AAAA,MACA;AAAA,IACF;AACA,UAAM,gBAAY,wCAAwB,KAAK;AAC/C,WAAO;AAAA,MACL,OAAO;AAAA,MACP,OAAO;AAAA,IACT;AAAA,EACF;AACF;AAEA,eAAsB,uBAAuB,UAAmB;AAC9D,MAAI;AACF,YAAQ,IAAI,qDAAqD,QAAQ;AACzE,UAAM,aAAa,iBAAiB,QAAQ;AAC5C,UAAM,cAAc,UAAM,wBAAQ;AAClC,UAAM,gBAAgB,YAAY,IAAIA,mBAAkB,WAAW;AAEnE,gBAAY,OAAOA,mBAAkB,WAAW;AAChD,gBAAY,OAAO,gBAAgB;AACnC,gBAAY,OAAO,UAAU;AAE7B,QACEA,mBAAkB,oCAClB,eAAe,OACf;AACA,UAAI;AACF,cAAM,gBAAgB,MAAM,WAAW;AAAA,UACrC,cAAc;AAAA,QAChB;AACA,cAAM,WAAW,oBAAoB,cAAc,GAAG;AACtD,gBAAQ;AAAA,UACN,8DAA8D,cAAc,GAAG;AAAA,QACjF;AAAA,MACF,SAAS,aAAa;AACpB,gBAAQ;AAAA,UACN;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACA,WAAO,EAAE,SAAS,MAAM,SAAS,+BAA+B;AAAA,EAClE,SAAS,OAAO;AACd,YAAQ,MAAM,2BAA2B,KAAK;AAC9C,WAAO,EAAE,SAAS,OAAO,SAAS,kCAAkC;AAAA,EACtE;AACF;;;AC/LA,oBAAsB;;;ACIf,IAAM,oCAAoC,IAAI;AAC9C,IAAM,yBAAyB,OAAO;AAG7C,IAAM,aAAa;AAAA,EACjB,WAAW;AAAA,EACX,eAAe;AAAA,EACf,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,aAAa;AAAA,EACb,eAAe;AACjB;AAEA,IAAM,UAAU;AAAA,EACd,SAAS;AAAA,EACT,SAAS;AAAA,EACT,eAAe;AAAA,EACf,cAAc;AAAA,EACd,SAAS;AAAA,EACT,WAAW;AAAA,EACX,YAAY;AAAA,EACZ,eAAe;AAAA,EACf,gBAAgB;AAClB;AAEA,IAAMC,WAAU;AAAA,EACd,QAAQ;AAAA,EACR,aAAa;AAAA,EACb,eAAe;AAAA,EACf,YAAY;AAAA,EACZ,eAAe;AAAA,EACf,YAAY;AAAA,EACZ,WAAW;AAAA,EACX,cAAc;AAAA,EACd,sBAAsB;AAAA,EACtB,uBAAuB;AAAA,EACvB,eAAe;AAAA,EACf,0BAA0B;AAAA,EAC1B,aAAa;AAAA,EACb,uBAAuB;AAAA,EACvB,iCAAiC;AAAA,EACjC,aAAa;AAAA,EACb,eAAe;AAAA,EACf,eAAe;AAAA,EACf,gBAAgB;AAAA,EAChB,MAAM;AAAA,EACN,UAAU;AAAA,EACV,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,cAAc;AAAA,EACd,WAAW;AAAA,EACX,oBAAoB;AACtB;AAEA,IAAM,eAAe;AAAA,EACnB,MAAM;AACR;AAKO,IAAM,YAAY;AAAA,EACvB;AAAA,EACA;AAAA,EACA,SAAAA;AAAA,EACA;AACF;;;ACvEA,IAAM,UAAN,cAAsB,IAAI;AAAA,EACjB,cAAc,OAAqB;AACxC,WAAO,KAAK,WAAW,IAAI,IAAI,MAAM,SAAS,CAAC,EAAE;AAAA,EACnD;AACF;AAYO,IAAM,gBAAgB,IACxB,SACS;AACZ,SAAO,IAAI,QAAQ,GAAG,IAAI;AAC5B;;;AFdA,IAAM,oBAAN,cAAgC,QAAQ;AAAA,EAC7B;AAAA,EACA;AAAA,EAEF,YACL,OACA,MACA;AACA,UAAM,MACJ,OAAO,UAAU,YAAY,SAAS,QAAQ,MAAM,MAAM,OAAO,KAAK;AACxE,UAAM,KAAK,QAAQ,OAAO,UAAU,WAAW,SAAY,KAAK;AAChE,SAAK,UAAU,KAAK,qBAAqB,IAAI;AAC7C,SAAK,UAAU,KAAK,aAAa,IAAI;AAAA,EACvC;AAAA,EAEO,SAAS;AACd,WAAO;AAAA,MACL,KAAK,KAAK,QAAQ;AAAA,MAClB,QAAQ,KAAK;AAAA,MACb,SAAS,KAAK,UAAU,OAAO,YAAY,KAAK,OAAO,CAAC;AAAA,MACxD,SAAS,KAAK,QAAQ,SAAS;AAAA,MAC/B,SAAS,KAAK,UAAU,OAAO,YAAY,KAAK,OAAO,CAAC;AAAA,IAC1D;AAAA,EACF;AAAA,EAEQ,qBAAqB,KAAc;AACzC,UAAM,aAAa,IAAI,IAAI,IAAI,GAAG;AAClC,UAAM,iBAAiB,IAAI,QAAQ,IAAI,UAAU,QAAQ,cAAc;AACvE,UAAM,gBAAgB,IAAI,QAAQ,IAAI,UAAU,QAAQ,aAAa;AACrE,UAAM,OAAO,IAAI,QAAQ,IAAI,UAAU,QAAQ,IAAI;AACnD,UAAM,WAAW,WAAW;AAE5B,UAAM,eAAe,KAAK,wBAAwB,aAAa,KAAK;AACpE,UAAM,mBACJ,KAAK,wBAAwB,cAAc,KAC3C,UAAU,QAAQ,QAAQ,EAAE;AAC9B,UAAM,SACJ,gBAAgB,mBACZ,GAAG,gBAAgB,MAAM,YAAY,KACrC,WAAW;AAEjB,QAAI,WAAW,WAAW,QAAQ;AAChC,aAAO,cAAc,UAAU;AAAA,IACjC;AAEA,WAAO,cAAc,WAAW,WAAW,WAAW,QAAQ,MAAM;AAAA,EACtE;AAAA,EAEQ,wBAAwB,OAAuB;AACrD,WAAO,OAAO,MAAM,GAAG,EAAE,CAAC;AAAA,EAC5B;AAAA,EAEQ,aAAa,KAAc;AACjC,UAAM,oBAAgB;AAAA,MACpB,KAAK,kBAAkB,IAAI,QAAQ,IAAI,QAAQ,KAAK,EAAE;AAAA,IACxD;AACA,WAAO,IAAI,IAAI,OAAO,QAAQ,aAAa,CAAC;AAAA,EAC9C;AAAA,EAEQ,kBAAkB,KAAa;AACrC,WAAO,MAAM,IAAI,QAAQ,oBAAoB,kBAAkB,IAAI;AAAA,EACrE;AACF;AAEO,IAAM,0BAA0B,IAClC,SACmB;AACtB,SAAO,KAAK,CAAC,aAAa,oBACtB,KAAK,CAAC,IACN,IAAI,kBAAkB,GAAG,IAAI;AACnC;;;AGrDO,IAAM,wBAAwB,OAAO,YAA+C;AACzF,QAAM,oBAAoB,wBAAwB,OAAO;AACzD,QAAM,eAAe,MAAM,oBAAoB,OAAO;AAEtD,SAAO;AAAA,IACL;AAAA,IACA;AAAA,EACF;AACF;AAEA,eAAsB,oBAAoB,SAAyC;AACjF,QAAM,gBAAgB,QAAQ,QAAQ,IAAI,QAAQ;AAClD,QAAM,eAAe,eAAe,MAAM,GAAG,EAC1C,KAAK,OAAK,EAAE,KAAK,EAAE,WAAW,kBAAkB,CAAC,GAChD,MAAM,GAAG,EAAE,CAAC;AAEhB,MAAI,CAAC,cAAc;AACjB,UAAM,IAAI,MAAM,wBAAwB;AAAA,EAC1C;AAEA,QAAM,qBAAqB,MAAM,4BAA4B,YAAY;AAEzE,MAAI,CAAC,mBAAmB,OAAO;AAC7B,UAAM,IAAI,MAAM,uBAAuB;AAAA,EACzC;AAEA,SAAO;AAAA,IACL;AAAA,IACA,IAAI,QAAQ,QAAQ,OAAO;AAAA,IAC3B;AAAA,EACF;AACF;AAEO,SAAS,iBACd,SACkB;AAClB,SAAO;AAAA,IACL;AAAA,IACA,QAAQ,QAAQ;AAAA,IAChB,KAAK,CAAC;AAAA,EACR;AACF;AAEO,SAAS,SACd,SACA,UAAmB,IAAI,QAAQ,GAC/B,OACa;AACb,QAAM,aAAa,iBAAiB,OAAO;AAC3C,SAAO;AAAA,IACL,MAAM,MAAM;AAAA,IACZ;AAAA,IACA;AAAA,EACF;AACF;","names":["admin","import_errors","SESSION_CONSTANTS","Headers"]}
@@ -0,0 +1,512 @@
1
+ import {
2
+ createTernSecureRequest,
3
+ getCookieOptions,
4
+ getSessionConfig
5
+ } from "../chunk-JFOTE3Y5.mjs";
6
+
7
+ // src/admin/sessionTernSecure.ts
8
+ import { handleFirebaseAuthError } from "@tern-secure/shared/errors";
9
+
10
+ // src/utils/admin-init.ts
11
+ import admin from "firebase-admin";
12
+
13
+ // src/utils/config.ts
14
+ var loadAdminConfig = () => ({
15
+ projectId: process.env.FIREBASE_PROJECT_ID || "",
16
+ clientEmail: process.env.FIREBASE_CLIENT_EMAIL || "",
17
+ privateKey: process.env.FIREBASE_PRIVATE_KEY || ""
18
+ });
19
+ var validateAdminConfig = (config) => {
20
+ const requiredFields = [
21
+ "projectId",
22
+ "clientEmail",
23
+ "privateKey"
24
+ ];
25
+ const errors = [];
26
+ requiredFields.forEach((field) => {
27
+ if (!config[field]) {
28
+ errors.push(`Missing required field: FIREBASE_${String(field).toUpperCase()}`);
29
+ }
30
+ });
31
+ return {
32
+ isValid: errors.length === 0,
33
+ errors,
34
+ config
35
+ };
36
+ };
37
+ var initializeAdminConfig = () => {
38
+ const config = loadAdminConfig();
39
+ const validationResult = validateAdminConfig(config);
40
+ if (!validationResult.isValid) {
41
+ throw new Error(
42
+ `Firebase Admin configuration validation failed:
43
+ ${validationResult.errors.join("\n")}`
44
+ );
45
+ }
46
+ return config;
47
+ };
48
+
49
+ // src/utils/admin-init.ts
50
+ if (!admin.apps.length) {
51
+ try {
52
+ const config = initializeAdminConfig();
53
+ admin.initializeApp({
54
+ credential: admin.credential.cert({
55
+ ...config,
56
+ privateKey: config.privateKey.replace(/\\n/g, "\n")
57
+ })
58
+ });
59
+ } catch (error) {
60
+ console.error("Firebase admin initialization error", error);
61
+ }
62
+ }
63
+ var adminTernSecureAuth = admin.auth();
64
+ var adminTernSecureDb = admin.firestore();
65
+ var TernSecureTenantManager = admin.auth().tenantManager();
66
+ function getAuthForTenant(tenantId) {
67
+ if (tenantId) {
68
+ return TernSecureTenantManager.authForTenant(tenantId);
69
+ }
70
+ return admin.auth();
71
+ }
72
+
73
+ // src/admin/sessionTernSecure.ts
74
+ var SESSION_CONSTANTS = {
75
+ COOKIE_NAME: "_session_cookie",
76
+ //DEFAULT_EXPIRES_IN_MS: 60 * 60 * 24 * 5 * 1000, // 5 days
77
+ //DEFAULT_EXPIRES_IN_SECONDS: 60 * 60 * 24 * 5, // 5days
78
+ DEFAULT_EXPIRES_IN_MS: 5 * 60 * 1e3,
79
+ // 5 minutes
80
+ DEFAULT_EXPIRES_IN_SECONDS: 5 * 60,
81
+ REVOKE_REFRESH_TOKENS_ON_SIGNOUT: true
82
+ };
83
+ var COOKIE_OPTIONS = {
84
+ httpOnly: true,
85
+ secure: process.env.NODE_ENV === "production",
86
+ sameSite: "strict",
87
+ path: "/"
88
+ };
89
+ async function createSessionCookie(params, cookieStore, options) {
90
+ try {
91
+ const tenantAuth = getAuthForTenant(options?.tenantId);
92
+ const sessionConfig = getSessionConfig(options);
93
+ const cookieOptions = getCookieOptions(options);
94
+ let decodedToken;
95
+ let sessionCookie;
96
+ const idToken = typeof params === "string" ? params : params.idToken;
97
+ if (!idToken) {
98
+ const error = new Error("ID token is required for session creation");
99
+ console.error("[createSessionCookie] Missing ID token:", error);
100
+ return {
101
+ success: false,
102
+ message: "ID token is required",
103
+ error: "INVALID_TOKEN",
104
+ cookieSet: false
105
+ };
106
+ }
107
+ try {
108
+ console.log("Verifying ID token for tenant:", options?.tenantId);
109
+ decodedToken = await tenantAuth.verifyIdToken(idToken);
110
+ } catch (verifyError) {
111
+ console.error(
112
+ "[createSessionCookie] ID token verification failed:",
113
+ verifyError
114
+ );
115
+ const authError = handleFirebaseAuthError(verifyError);
116
+ return {
117
+ success: false,
118
+ message: authError.message,
119
+ error: authError.code,
120
+ cookieSet: false
121
+ };
122
+ }
123
+ if (!decodedToken) {
124
+ const error = new Error("Invalid ID token - verification returned null");
125
+ console.error(
126
+ "[createSessionCookie] Token verification returned null:",
127
+ error
128
+ );
129
+ return {
130
+ success: false,
131
+ message: "Invalid ID token",
132
+ error: "INVALID_TOKEN",
133
+ cookieSet: false
134
+ };
135
+ }
136
+ try {
137
+ sessionCookie = await tenantAuth.createSessionCookie(idToken, {
138
+ expiresIn: SESSION_CONSTANTS.DEFAULT_EXPIRES_IN_MS
139
+ });
140
+ } catch (sessionError) {
141
+ console.error(
142
+ "[createSessionCookie] Firebase session cookie creation failed:",
143
+ sessionError
144
+ );
145
+ const authError = handleFirebaseAuthError(sessionError);
146
+ return {
147
+ success: false,
148
+ message: authError.message,
149
+ error: authError.code,
150
+ cookieSet: false
151
+ };
152
+ }
153
+ let cookieSetSuccessfully = false;
154
+ try {
155
+ cookieStore.set(SESSION_CONSTANTS.COOKIE_NAME, sessionCookie, {
156
+ maxAge: SESSION_CONSTANTS.DEFAULT_EXPIRES_IN_SECONDS,
157
+ ...COOKIE_OPTIONS
158
+ });
159
+ const verifySetCookie = await cookieStore.get(
160
+ SESSION_CONSTANTS.COOKIE_NAME
161
+ );
162
+ cookieSetSuccessfully = !!verifySetCookie?.value;
163
+ if (!cookieSetSuccessfully) {
164
+ const error = new Error("Session cookie was not set successfully");
165
+ console.error(
166
+ "[createSessionCookie] Cookie verification failed:",
167
+ error
168
+ );
169
+ throw error;
170
+ }
171
+ } catch (cookieError) {
172
+ console.error(
173
+ "[createSessionCookie] Failed to set session cookie:",
174
+ cookieError
175
+ );
176
+ return {
177
+ success: false,
178
+ message: "Failed to set session cookie",
179
+ error: "COOKIE_SET_FAILED",
180
+ cookieSet: false
181
+ };
182
+ }
183
+ console.log(
184
+ `[createSessionCookie] Session cookie created successfully for user: ${decodedToken.uid}`
185
+ );
186
+ return {
187
+ success: true,
188
+ message: "Session created successfully",
189
+ expiresIn: SESSION_CONSTANTS.DEFAULT_EXPIRES_IN_SECONDS,
190
+ cookieSet: cookieSetSuccessfully
191
+ };
192
+ } catch (error) {
193
+ console.error("[createSessionCookie] Unexpected error:", error);
194
+ const authError = handleFirebaseAuthError(error);
195
+ return {
196
+ success: false,
197
+ message: authError.message || "Failed to create session",
198
+ error: authError.code || "INTERNAL_ERROR",
199
+ cookieSet: false
200
+ };
201
+ }
202
+ }
203
+ async function clearSessionCookie(cookieStore, options) {
204
+ try {
205
+ const adminAuth = getAuthForTenant(options?.tenantId);
206
+ const sessionCookie = await cookieStore.get(SESSION_CONSTANTS.COOKIE_NAME);
207
+ await cookieStore.delete(SESSION_CONSTANTS.COOKIE_NAME);
208
+ await cookieStore.delete("_session_token");
209
+ await cookieStore.delete("_session");
210
+ if (SESSION_CONSTANTS.REVOKE_REFRESH_TOKENS_ON_SIGNOUT && sessionCookie?.value) {
211
+ try {
212
+ const decodedClaims = await adminAuth.verifySessionCookie(
213
+ sessionCookie.value
214
+ );
215
+ await adminAuth.revokeRefreshTokens(decodedClaims.sub);
216
+ console.log(
217
+ `[clearSessionCookie] Successfully revoked tokens for user: ${decodedClaims.sub}`
218
+ );
219
+ } catch (revokeError) {
220
+ console.error(
221
+ "[clearSessionCookie] Failed to revoke refresh tokens:",
222
+ revokeError
223
+ );
224
+ }
225
+ }
226
+ console.log("[clearSessionCookie] Session cookies cleared successfully");
227
+ return {
228
+ success: true,
229
+ message: "Session cleared successfully",
230
+ cookieSet: false
231
+ };
232
+ } catch (error) {
233
+ console.error("[clearSessionCookie] Unexpected error:", error);
234
+ const authError = handleFirebaseAuthError(error);
235
+ return {
236
+ success: false,
237
+ message: authError.message || "Failed to clear session",
238
+ error: authError.code || "INTERNAL_ERROR",
239
+ cookieSet: false
240
+ };
241
+ }
242
+ }
243
+
244
+ // src/admin/tenant.ts
245
+ async function createTenant(displayName, emailSignInConfig, multiFactorConfig) {
246
+ try {
247
+ const tenantConfig = {
248
+ displayName,
249
+ emailSignInConfig,
250
+ ...multiFactorConfig && { multiFactorConfig }
251
+ };
252
+ const tenant = await TernSecureTenantManager.createTenant(tenantConfig);
253
+ return {
254
+ success: true,
255
+ tenantId: tenant.tenantId,
256
+ displayName: tenant.displayName
257
+ };
258
+ } catch (error) {
259
+ console.error("Error creating tenant:", error);
260
+ throw new Error("Failed to create tenant");
261
+ }
262
+ }
263
+ async function createTenantUser(email, password, tenantId) {
264
+ try {
265
+ const tenantAuth = TernSecureTenantManager.authForTenant(tenantId);
266
+ const userRecord = await tenantAuth.createUser({
267
+ email,
268
+ password,
269
+ emailVerified: false,
270
+ disabled: false
271
+ });
272
+ return {
273
+ success: true,
274
+ message: "Tenant user created successfully",
275
+ user: userRecord.uid
276
+ };
277
+ } catch (error) {
278
+ console.error("Error creating tenant user:", error);
279
+ throw new Error("Failed to create tenant user");
280
+ }
281
+ }
282
+
283
+ // src/admin/nextSessionTernSecure.ts
284
+ import { handleFirebaseAuthError as handleFirebaseAuthError2 } from "@tern-secure/shared/errors";
285
+ import { cookies } from "next/headers";
286
+ var SESSION_CONSTANTS2 = {
287
+ COOKIE_NAME: "_session_cookie",
288
+ DEFAULT_EXPIRES_IN_MS: 60 * 60 * 24 * 5 * 1e3,
289
+ // 5 days
290
+ DEFAULT_EXPIRES_IN_SECONDS: 60 * 60 * 24 * 5,
291
+ REVOKE_REFRESH_TOKENS_ON_SIGNOUT: true
292
+ };
293
+ async function CreateNextSessionCookie(idToken) {
294
+ try {
295
+ const expiresIn = 60 * 60 * 24 * 5 * 1e3;
296
+ const sessionCookie = await adminTernSecureAuth.createSessionCookie(idToken, {
297
+ expiresIn
298
+ });
299
+ const cookieStore = await cookies();
300
+ cookieStore.set("_session_cookie", sessionCookie, {
301
+ maxAge: expiresIn,
302
+ httpOnly: true,
303
+ secure: process.env.NODE_ENV === "production",
304
+ path: "/"
305
+ });
306
+ return { success: true, message: "Session created" };
307
+ } catch (error) {
308
+ return { success: false, message: "Failed to create session" };
309
+ }
310
+ }
311
+ async function GetNextServerSessionCookie() {
312
+ const cookieStore = await cookies();
313
+ const sessionCookie = cookieStore.get("_session_cookie")?.value;
314
+ if (!sessionCookie) {
315
+ throw new Error("No session cookie found");
316
+ }
317
+ try {
318
+ const decondeClaims = await adminTernSecureAuth.verifySessionCookie(
319
+ sessionCookie,
320
+ true
321
+ );
322
+ return {
323
+ token: sessionCookie,
324
+ userId: decondeClaims.uid
325
+ };
326
+ } catch (error) {
327
+ console.error("Error verifying session:", error);
328
+ throw new Error("Invalid Session");
329
+ }
330
+ }
331
+ async function GetNextIdToken() {
332
+ const cookieStore = await cookies();
333
+ const token = cookieStore.get("_session_token")?.value;
334
+ if (!token) {
335
+ throw new Error("No session cookie found");
336
+ }
337
+ try {
338
+ const decodedClaims = await adminTernSecureAuth.verifyIdToken(token);
339
+ return {
340
+ token,
341
+ userId: decodedClaims.uid
342
+ };
343
+ } catch (error) {
344
+ console.error("Error verifying session:", error);
345
+ throw new Error("Invalid Session");
346
+ }
347
+ }
348
+ async function SetNextServerSession(token) {
349
+ try {
350
+ const cookieStore = await cookies();
351
+ cookieStore.set("_session_token", token, {
352
+ httpOnly: true,
353
+ secure: process.env.NODE_ENV === "production",
354
+ sameSite: "strict",
355
+ maxAge: 60 * 60,
356
+ // 1 hour
357
+ path: "/"
358
+ });
359
+ return { success: true, message: "Session created" };
360
+ } catch {
361
+ return { success: false, message: "Failed to create session" };
362
+ }
363
+ }
364
+ async function SetNextServerToken(token) {
365
+ try {
366
+ const cookieStore = await cookies();
367
+ cookieStore.set("_tern", token, {
368
+ httpOnly: true,
369
+ secure: process.env.NODE_ENV === "production",
370
+ sameSite: "strict",
371
+ maxAge: 60 * 60,
372
+ // 1 hour
373
+ path: "/"
374
+ });
375
+ return { success: true, message: "Session created" };
376
+ } catch {
377
+ return { success: false, message: "Failed to create session" };
378
+ }
379
+ }
380
+ async function VerifyNextTernIdToken(token) {
381
+ try {
382
+ const decodedToken = await adminTernSecureAuth.verifyIdToken(token);
383
+ return {
384
+ ...decodedToken,
385
+ valid: true
386
+ };
387
+ } catch (error) {
388
+ console.error("[VerifyNextTernIdToken] Error verifying session:", error);
389
+ const authError = handleFirebaseAuthError2(error);
390
+ return {
391
+ valid: false,
392
+ error: authError
393
+ };
394
+ }
395
+ }
396
+ async function VerifyNextTernSessionCookie(session) {
397
+ try {
398
+ const res = await adminTernSecureAuth.verifySessionCookie(session);
399
+ console.warn(
400
+ "[VerifyNextTernSessionCookie] uid in Decoded Token:",
401
+ res.uid
402
+ );
403
+ return {
404
+ valid: true,
405
+ ...res
406
+ };
407
+ } catch (error) {
408
+ console.error(
409
+ "[VerifyNextTernSessionCookie] Error verifying session:",
410
+ error
411
+ );
412
+ const authError = handleFirebaseAuthError2(error);
413
+ return {
414
+ valid: false,
415
+ error: authError
416
+ };
417
+ }
418
+ }
419
+ async function ClearNextSessionCookie(tenantId) {
420
+ try {
421
+ console.log("[clearSessionCookie] Clearing session for tenant:", tenantId);
422
+ const tenantAuth = getAuthForTenant(tenantId);
423
+ const cookieStore = await cookies();
424
+ const sessionCookie = cookieStore.get(SESSION_CONSTANTS2.COOKIE_NAME);
425
+ cookieStore.delete(SESSION_CONSTANTS2.COOKIE_NAME);
426
+ cookieStore.delete("_session_token");
427
+ cookieStore.delete("_session");
428
+ if (SESSION_CONSTANTS2.REVOKE_REFRESH_TOKENS_ON_SIGNOUT && sessionCookie?.value) {
429
+ try {
430
+ const decodedClaims = await tenantAuth.verifySessionCookie(
431
+ sessionCookie.value
432
+ );
433
+ await tenantAuth.revokeRefreshTokens(decodedClaims.sub);
434
+ console.log(
435
+ `[clearSessionCookie] Successfully revoked tokens for user: ${decodedClaims.sub}`
436
+ );
437
+ } catch (revokeError) {
438
+ console.error(
439
+ "[ClearNextSessionCookie] Failed to revoke refresh tokens:",
440
+ revokeError
441
+ );
442
+ }
443
+ }
444
+ return { success: true, message: "Session cleared successfully" };
445
+ } catch (error) {
446
+ console.error("Error clearing session:", error);
447
+ return { success: false, message: "Failed to clear session cookies" };
448
+ }
449
+ }
450
+
451
+ // src/instance/backendInstance.ts
452
+ var createBackendInstance = async (request) => {
453
+ const ternSecureRequest = createTernSecureRequest(request);
454
+ const requestState = await authenticateRequest(request);
455
+ return {
456
+ ternSecureRequest,
457
+ requestState
458
+ };
459
+ };
460
+ async function authenticateRequest(request) {
461
+ const sessionCookie = request.headers.get("cookie");
462
+ const sessionToken = sessionCookie?.split(";").find((c) => c.trim().startsWith("_session_cookie="))?.split("=")[1];
463
+ if (!sessionToken) {
464
+ throw new Error("No session token found");
465
+ }
466
+ const verificationResult = await VerifyNextTernSessionCookie(sessionToken);
467
+ if (!verificationResult.valid) {
468
+ throw new Error("Invalid session token");
469
+ }
470
+ return signedIn(
471
+ verificationResult,
472
+ new Headers(request.headers),
473
+ sessionToken
474
+ );
475
+ }
476
+ function signInAuthObject(session) {
477
+ return {
478
+ session,
479
+ userId: session.uid,
480
+ has: {}
481
+ };
482
+ }
483
+ function signedIn(session, headers = new Headers(), token) {
484
+ const authObject = signInAuthObject(session);
485
+ return {
486
+ auth: () => authObject,
487
+ token,
488
+ headers
489
+ };
490
+ }
491
+ export {
492
+ ClearNextSessionCookie,
493
+ CreateNextSessionCookie,
494
+ GetNextIdToken,
495
+ GetNextServerSessionCookie,
496
+ SetNextServerSession,
497
+ SetNextServerToken,
498
+ TernSecureTenantManager,
499
+ VerifyNextTernIdToken,
500
+ VerifyNextTernSessionCookie,
501
+ adminTernSecureAuth,
502
+ adminTernSecureDb,
503
+ authenticateRequest,
504
+ clearSessionCookie,
505
+ createBackendInstance,
506
+ createSessionCookie,
507
+ createTenant,
508
+ createTenantUser,
509
+ initializeAdminConfig,
510
+ signedIn
511
+ };
512
+ //# sourceMappingURL=index.mjs.map