@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.
- package/admin/package.json +5 -0
- package/dist/adapters/PostgresAdapter.d.ts +8 -0
- package/dist/adapters/PostgresAdapter.d.ts.map +1 -0
- package/dist/adapters/RedisAdapter.d.ts +10 -0
- package/dist/adapters/RedisAdapter.d.ts.map +1 -0
- package/dist/adapters/index.d.ts +13 -0
- package/dist/adapters/index.d.ts.map +1 -0
- package/dist/adapters/types.d.ts +30 -0
- package/dist/adapters/types.d.ts.map +1 -0
- package/dist/admin/gemini_sessionTernSecure.d.ts +10 -0
- package/dist/admin/gemini_sessionTernSecure.d.ts.map +1 -0
- package/dist/admin/index.d.ts +8 -0
- package/dist/admin/index.d.ts.map +1 -0
- package/dist/admin/index.js +705 -0
- package/dist/admin/index.js.map +1 -0
- package/dist/admin/index.mjs +512 -0
- package/dist/admin/index.mjs.map +1 -0
- package/dist/admin/nextSessionTernSecure.d.ts +28 -0
- package/dist/admin/nextSessionTernSecure.d.ts.map +1 -0
- package/dist/admin/sessionTernSecure.d.ts +6 -0
- package/dist/admin/sessionTernSecure.d.ts.map +1 -0
- package/dist/admin/tenant.d.ts.map +1 -0
- package/dist/api/createBackendApi.d.ts +8 -0
- package/dist/api/createBackendApi.d.ts.map +1 -0
- package/dist/api/endpoints/SessionApi.d.ts +12 -0
- package/dist/api/endpoints/SessionApi.d.ts.map +1 -0
- package/dist/api/endpoints/index.d.ts +2 -0
- package/dist/api/endpoints/index.d.ts.map +1 -0
- package/dist/api/index.d.ts +2 -0
- package/dist/api/index.d.ts.map +1 -0
- package/dist/api/request.d.ts +36 -0
- package/dist/api/request.d.ts.map +1 -0
- package/dist/chunk-JFOTE3Y5.mjs +157 -0
- package/dist/chunk-JFOTE3Y5.mjs.map +1 -0
- package/dist/chunk-WZYVAHZ3.mjs +318 -0
- package/dist/chunk-WZYVAHZ3.mjs.map +1 -0
- package/dist/constants.d.ts +63 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1307 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +839 -0
- package/dist/index.mjs.map +1 -0
- package/dist/instance/backendFireInstance.d.ts +7 -0
- package/dist/instance/backendFireInstance.d.ts.map +1 -0
- package/dist/instance/backendInstance.d.ts +20 -0
- package/dist/instance/backendInstance.d.ts.map +1 -0
- package/dist/instance/backendInstanceEdge.d.ts +13 -0
- package/dist/instance/backendInstanceEdge.d.ts.map +1 -0
- package/dist/jwt/algorithms.d.ts +3 -0
- package/dist/jwt/algorithms.d.ts.map +1 -0
- package/dist/jwt/cryptoKeys.d.ts +3 -0
- package/dist/jwt/cryptoKeys.d.ts.map +1 -0
- package/dist/jwt/guardReturn.d.ts +3 -0
- package/dist/jwt/guardReturn.d.ts.map +1 -0
- package/dist/jwt/index.d.ts +4 -0
- package/dist/jwt/index.d.ts.map +1 -0
- package/dist/jwt/index.js +332 -0
- package/dist/jwt/index.js.map +1 -0
- package/dist/jwt/index.mjs +139 -0
- package/dist/jwt/index.mjs.map +1 -0
- package/dist/jwt/jwt.d.ts +4 -0
- package/dist/jwt/jwt.d.ts.map +1 -0
- package/dist/jwt/signJwt.d.ts +5 -0
- package/dist/jwt/signJwt.d.ts.map +1 -0
- package/dist/jwt/types.d.ts +8 -0
- package/dist/jwt/types.d.ts.map +1 -0
- package/dist/jwt/verifyContent.d.ts +7 -0
- package/dist/jwt/verifyContent.d.ts.map +1 -0
- package/dist/jwt/verifyJwt.d.ts +12 -0
- package/dist/jwt/verifyJwt.d.ts.map +1 -0
- package/dist/runtime/browser/crypto.mjs +1 -0
- package/dist/runtime/node/crypto.js +1 -0
- package/dist/runtime/node/crypto.mjs +1 -0
- package/dist/runtime.d.ts +26 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/ternsecureauth.d.ts.map +1 -0
- package/dist/tokens/authstate.d.ts +61 -0
- package/dist/tokens/authstate.d.ts.map +1 -0
- package/dist/tokens/keys.d.ts +16 -0
- package/dist/tokens/keys.d.ts.map +1 -0
- package/dist/tokens/request.d.ts +16 -0
- package/dist/tokens/request.d.ts.map +1 -0
- package/dist/tokens/requestFire.d.ts +17 -0
- package/dist/tokens/requestFire.d.ts.map +1 -0
- package/dist/tokens/sessionConfig.d.ts +14 -0
- package/dist/tokens/sessionConfig.d.ts.map +1 -0
- package/dist/tokens/ternSecureRequest.d.ts +20 -0
- package/dist/tokens/ternSecureRequest.d.ts.map +1 -0
- package/dist/tokens/ternUrl.d.ts +15 -0
- package/dist/tokens/ternUrl.d.ts.map +1 -0
- package/dist/tokens/types.d.ts +41 -0
- package/dist/tokens/types.d.ts.map +1 -0
- package/dist/tokens/verify.d.ts +11 -0
- package/dist/tokens/verify.d.ts.map +1 -0
- package/dist/utils/admin-init.d.ts +13 -0
- package/dist/utils/admin-init.d.ts.map +1 -0
- package/dist/{types/utils → utils}/config.d.ts +1 -1
- package/dist/utils/config.d.ts.map +1 -0
- package/dist/utils/enableDebugLogging.d.ts +5 -0
- package/dist/utils/enableDebugLogging.d.ts.map +1 -0
- package/dist/utils/errors.d.ts +29 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/gemini_admin-init.d.ts +10 -0
- package/dist/utils/gemini_admin-init.d.ts.map +1 -0
- package/dist/utils/logger.d.ts +28 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/mapDecode.d.ts +4 -0
- package/dist/utils/mapDecode.d.ts.map +1 -0
- package/dist/utils/options.d.ts +5 -0
- package/dist/utils/options.d.ts.map +1 -0
- package/dist/utils/path.d.ts +4 -0
- package/dist/utils/path.d.ts.map +1 -0
- package/dist/utils/redis.d.ts +10 -0
- package/dist/utils/redis.d.ts.map +1 -0
- package/dist/utils/rfc4648.d.ts +26 -0
- package/dist/utils/rfc4648.d.ts.map +1 -0
- package/jwt/package.json +5 -0
- package/package.json +58 -10
- package/dist/cjs/admin/sessionTernSecure.js +0 -256
- package/dist/cjs/admin/sessionTernSecure.js.map +0 -1
- package/dist/cjs/admin/tenant.js +0 -68
- package/dist/cjs/admin/tenant.js.map +0 -1
- package/dist/cjs/global.d.js +0 -2
- package/dist/cjs/global.d.js.map +0 -1
- package/dist/cjs/index.js +0 -48
- package/dist/cjs/index.js.map +0 -1
- package/dist/cjs/ternsecureauth.js +0 -40
- package/dist/cjs/ternsecureauth.js.map +0 -1
- package/dist/cjs/utils/admin-init.js +0 -60
- package/dist/cjs/utils/admin-init.js.map +0 -1
- package/dist/cjs/utils/config.js +0 -113
- package/dist/cjs/utils/config.js.map +0 -1
- package/dist/esm/admin/sessionTernSecure.js +0 -226
- package/dist/esm/admin/sessionTernSecure.js.map +0 -1
- package/dist/esm/admin/tenant.js +0 -43
- package/dist/esm/admin/tenant.js.map +0 -1
- package/dist/esm/global.d.js +0 -1
- package/dist/esm/global.d.js.map +0 -1
- package/dist/esm/index.js +0 -24
- package/dist/esm/index.js.map +0 -1
- package/dist/esm/ternsecureauth.js +0 -16
- package/dist/esm/ternsecureauth.js.map +0 -1
- package/dist/esm/utils/admin-init.js +0 -24
- package/dist/esm/utils/admin-init.js.map +0 -1
- package/dist/esm/utils/config.js +0 -84
- package/dist/esm/utils/config.js.map +0 -1
- package/dist/types/admin/sessionTernSecure.d.ts +0 -36
- package/dist/types/admin/sessionTernSecure.d.ts.map +0 -1
- package/dist/types/admin/tenant.d.ts.map +0 -1
- package/dist/types/index.d.ts +0 -5
- package/dist/types/index.d.ts.map +0 -1
- package/dist/types/ternsecureauth.d.ts.map +0 -1
- package/dist/types/utils/admin-init.d.ts +0 -5
- package/dist/types/utils/admin-init.d.ts.map +0 -1
- package/dist/types/utils/config.d.ts.map +0 -1
- /package/dist/{types/admin → admin}/tenant.d.ts +0 -0
- /package/dist/{types/ternsecureauth.d.ts → ternsecureauth.d.ts} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/admin/sessionTernSecure.ts","../../src/utils/admin-init.ts","../../src/utils/config.ts","../../src/admin/tenant.ts","../../src/admin/nextSessionTernSecure.ts","../../src/instance/backendInstance.ts"],"sourcesContent":["\"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 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 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":"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","names":["handleFirebaseAuthError","SESSION_CONSTANTS","handleFirebaseAuthError"]}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { TernVerificationResult } from "@tern-secure/types";
|
|
2
|
+
export declare function CreateNextSessionCookie(idToken: string): Promise<{
|
|
3
|
+
success: boolean;
|
|
4
|
+
message: string;
|
|
5
|
+
}>;
|
|
6
|
+
export declare function GetNextServerSessionCookie(): Promise<{
|
|
7
|
+
token: string;
|
|
8
|
+
userId: string;
|
|
9
|
+
}>;
|
|
10
|
+
export declare function GetNextIdToken(): Promise<{
|
|
11
|
+
token: string;
|
|
12
|
+
userId: string;
|
|
13
|
+
}>;
|
|
14
|
+
export declare function SetNextServerSession(token: string): Promise<{
|
|
15
|
+
success: boolean;
|
|
16
|
+
message: string;
|
|
17
|
+
}>;
|
|
18
|
+
export declare function SetNextServerToken(token: string): Promise<{
|
|
19
|
+
success: boolean;
|
|
20
|
+
message: string;
|
|
21
|
+
}>;
|
|
22
|
+
export declare function VerifyNextTernIdToken(token: string): Promise<TernVerificationResult>;
|
|
23
|
+
export declare function VerifyNextTernSessionCookie(session: string): Promise<TernVerificationResult>;
|
|
24
|
+
export declare function ClearNextSessionCookie(tenantId?: string): Promise<{
|
|
25
|
+
success: boolean;
|
|
26
|
+
message: string;
|
|
27
|
+
}>;
|
|
28
|
+
//# sourceMappingURL=nextSessionTernSecure.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nextSessionTernSecure.d.ts","sourceRoot":"","sources":["../../src/admin/nextSessionTernSecure.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAajE,wBAAsB,uBAAuB,CAAC,OAAO,EAAE,MAAM;;;GAkB5D;AAED,wBAAsB,0BAA0B;;;GAqB/C;AAED,wBAAsB,cAAc;;;GAkBnC;AAED,wBAAsB,oBAAoB,CAAC,KAAK,EAAE,MAAM;;;GAcvD;AAED,wBAAsB,kBAAkB,CAAC,KAAK,EAAE,MAAM;;;GAcrD;AAED,wBAAsB,qBAAqB,CACzC,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,sBAAsB,CAAC,CAejC;AAED,wBAAsB,2BAA2B,CAC/C,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,sBAAsB,CAAC,CAsBjC;AAED,wBAAsB,sBAAsB,CAAC,QAAQ,CAAC,EAAE,MAAM;;;GAmC7D"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { CookieStore, SessionParams, SessionResult } from "@tern-secure/types";
|
|
2
|
+
import type { RequestOptions } from "../tokens/types";
|
|
3
|
+
export declare function createSessionCookie(params: SessionParams | string, cookieStore: CookieStore, options?: RequestOptions): Promise<SessionResult>;
|
|
4
|
+
export declare function clearSessionCookie(cookieStore: CookieStore, options?: RequestOptions): Promise<SessionResult>;
|
|
5
|
+
export declare function createCustomToken(uid: string, options?: RequestOptions): Promise<string | null>;
|
|
6
|
+
//# sourceMappingURL=sessionTernSecure.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sessionTernSecure.d.ts","sourceRoot":"","sources":["../../src/admin/sessionTernSecure.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,WAAW,EACX,aAAa,EACb,aAAa,EACd,MAAM,oBAAoB,CAAC;AAG5B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAoBtD,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,aAAa,GAAG,MAAM,EAC9B,WAAW,EAAE,WAAW,EACxB,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,aAAa,CAAC,CA+HxB;AAED,wBAAsB,kBAAkB,CACtC,WAAW,EAAE,WAAW,EACxB,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,aAAa,CAAC,CA6CxB;AAED,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CASrG"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tenant.d.ts","sourceRoot":"","sources":["../../src/admin/tenant.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAKzD,wBAAsB,YAAY,CAChC,WAAW,EAAE,MAAM,EACnB,iBAAiB,EAAE;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,gBAAgB,EAAE,OAAO,CAAC;CAC3B,EACD,iBAAiB,CAAC,EAAE;IAClB,KAAK,EAAE,SAAS,GAAG,UAAU,CAAC;IAC9B,SAAS,EAAE,OAAO,EAAE,CAAC;IACrB,gBAAgB,CAAC,EAAE;QACf,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAAC;KACjC,CAAA;CACF;;;;GAoBF;AAED,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,cAAc,CAAC,CAoBzB"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { SessionApi } from "./endpoints";
|
|
2
|
+
import { createRequest } from './request';
|
|
3
|
+
export type CreateBackendApiOptions = Parameters<typeof createRequest>[0];
|
|
4
|
+
export type ApiClient = ReturnType<typeof createBackendApi>;
|
|
5
|
+
export declare function createBackendApi(options: CreateBackendApiOptions): {
|
|
6
|
+
sessions: SessionApi;
|
|
7
|
+
};
|
|
8
|
+
//# sourceMappingURL=createBackendApi.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createBackendApi.d.ts","sourceRoot":"","sources":["../../src/api/createBackendApi.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAA;AAEzC,MAAM,MAAM,uBAAuB,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;AAC1E,MAAM,MAAM,SAAS,GAAG,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE5D,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,uBAAuB;;EAKhE"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { RequestFunction } from "../request";
|
|
2
|
+
type CreateSessionParams = {
|
|
3
|
+
idToken: string;
|
|
4
|
+
csrfToken: string;
|
|
5
|
+
};
|
|
6
|
+
export declare class SessionApi {
|
|
7
|
+
protected request: RequestFunction;
|
|
8
|
+
constructor(request: RequestFunction);
|
|
9
|
+
createSession(params: CreateSessionParams): Promise<import("../request").BackendApiResponse<unknown>>;
|
|
10
|
+
}
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=SessionApi.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SessionApi.d.ts","sourceRoot":"","sources":["../../../src/api/endpoints/SessionApi.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAIlD,KAAK,mBAAmB,GAAG;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,qBAAa,UAAU;IACT,SAAS,CAAC,OAAO,EAAE,eAAe;gBAAxB,OAAO,EAAE,eAAe;IAEjC,aAAa,CAAC,MAAM,EAAE,mBAAmB;CAOvD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/api/endpoints/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":"AACA,cAAc,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { TernSecureAPIError, TernSecureApiErrorJSON } from "@tern-secure/types";
|
|
2
|
+
export type HTTPMethod = "DELETE" | "GET" | "PATCH" | "POST" | "PUT";
|
|
3
|
+
export type BackendApiRequestOptions = {
|
|
4
|
+
method?: HTTPMethod;
|
|
5
|
+
queryParams?: Record<string, unknown>;
|
|
6
|
+
headerParams?: Record<string, string>;
|
|
7
|
+
bodyParams?: Record<string, unknown>;
|
|
8
|
+
formData?: FormData;
|
|
9
|
+
} & ({
|
|
10
|
+
url: string;
|
|
11
|
+
path?: string;
|
|
12
|
+
} | {
|
|
13
|
+
url?: string;
|
|
14
|
+
path: string;
|
|
15
|
+
});
|
|
16
|
+
export type BackendApiResponse<T> = {
|
|
17
|
+
data: T;
|
|
18
|
+
errors: null;
|
|
19
|
+
totalCount?: number;
|
|
20
|
+
} | {
|
|
21
|
+
data: null;
|
|
22
|
+
errors: TernSecureAPIError[];
|
|
23
|
+
totalCount?: never;
|
|
24
|
+
status?: number;
|
|
25
|
+
statusText?: string;
|
|
26
|
+
retryAfter?: number;
|
|
27
|
+
};
|
|
28
|
+
export type RequestFunction = ReturnType<typeof createRequest>;
|
|
29
|
+
type CreateRequestOptions = {
|
|
30
|
+
apiUrl?: string;
|
|
31
|
+
apiVersion?: string;
|
|
32
|
+
};
|
|
33
|
+
export declare function createRequest(options: CreateRequestOptions): <T>(requestOptions: BackendApiRequestOptions) => Promise<BackendApiResponse<T>>;
|
|
34
|
+
export declare function parseError(error: TernSecureApiErrorJSON): TernSecureAPIError;
|
|
35
|
+
export {};
|
|
36
|
+
//# sourceMappingURL=request.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../../src/api/request.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,kBAAkB,EAClB,sBAAsB,EACvB,MAAM,oBAAoB,CAAC;AAM5B,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,KAAK,GAAG,OAAO,GAAG,MAAM,GAAG,KAAK,CAAC;AACrE,MAAM,MAAM,wBAAwB,GAAG;IACrC,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB,GAAG,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAEtE,MAAM,MAAM,kBAAkB,CAAC,CAAC,IAC5B;IACE,IAAI,EAAE,CAAC,CAAC;IACR,MAAM,EAAE,IAAI,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,GACD;IACE,IAAI,EAAE,IAAI,CAAC;IACX,MAAM,EAAE,kBAAkB,EAAE,CAAC;IAC7B,UAAU,CAAC,EAAE,KAAK,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEN,MAAM,MAAM,eAAe,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;AAE/D,KAAK,oBAAoB,GAAG;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,wBAAgB,aAAa,CAAC,OAAO,EAAE,oBAAoB,IAChC,CAAC,kBACR,wBAAwB,KACvC,OAAO,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAkFlC;AAUD,wBAAgB,UAAU,CAAC,KAAK,EAAE,sBAAsB,GAAG,kBAAkB,CAK5E"}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
// src/constants.ts
|
|
2
|
+
var SESSION_COOKIE_PUBLIC_KEYS_URL = "https://www.googleapis.com/identitytoolkit/v3/relyingparty/publicKeys";
|
|
3
|
+
var MAX_CACHE_LAST_UPDATED_AT_SECONDS = 5 * 60;
|
|
4
|
+
var DEFAULT_CACHE_DURATION = 3600 * 1e3;
|
|
5
|
+
var CACHE_CONTROL_REGEX = /max-age=(\d+)/;
|
|
6
|
+
var Attributes = {
|
|
7
|
+
AuthToken: "__ternsecureAuthToken",
|
|
8
|
+
AuthSignature: "__ternsecureAuthSignature",
|
|
9
|
+
AuthStatus: "__ternsecureAuthStatus",
|
|
10
|
+
AuthReason: "__ternsecureAuthReason",
|
|
11
|
+
AuthMessage: "__ternsecureAuthMessage",
|
|
12
|
+
TernSecureUrl: "__ternsecureUrl"
|
|
13
|
+
};
|
|
14
|
+
var Cookies = {
|
|
15
|
+
Session: "__session",
|
|
16
|
+
IdToken: "_tern",
|
|
17
|
+
SessionCookie: "_session_cookie",
|
|
18
|
+
SessionToken: "_session_token",
|
|
19
|
+
Refresh: "__refresh",
|
|
20
|
+
Handshake: "__ternsecure_handshake",
|
|
21
|
+
DevBrowser: "__ternsecure_db_jwt",
|
|
22
|
+
RedirectCount: "__ternsecure_redirect_count",
|
|
23
|
+
HandshakeNonce: "__ternsecure_handshake_nonce"
|
|
24
|
+
};
|
|
25
|
+
var Headers = {
|
|
26
|
+
Accept: "accept",
|
|
27
|
+
AuthMessage: "x-ternsecure-auth-message",
|
|
28
|
+
Authorization: "authorization",
|
|
29
|
+
AuthReason: "x-ternsecure-auth-reason",
|
|
30
|
+
AuthSignature: "x-ternsecure-auth-signature",
|
|
31
|
+
AuthStatus: "x-ternsecure-auth-status",
|
|
32
|
+
AuthToken: "x-ternsecure-auth-token",
|
|
33
|
+
CacheControl: "cache-control",
|
|
34
|
+
TernSecureRedirectTo: "x-ternsecure-redirect-to",
|
|
35
|
+
TernSecureRequestData: "x-ternsecure-request-data",
|
|
36
|
+
TernSecureUrl: "x-ternsecure-url",
|
|
37
|
+
CloudFrontForwardedProto: "cloudfront-forwarded-proto",
|
|
38
|
+
ContentType: "content-type",
|
|
39
|
+
ContentSecurityPolicy: "content-security-policy",
|
|
40
|
+
ContentSecurityPolicyReportOnly: "content-security-policy-report-only",
|
|
41
|
+
EnableDebug: "x-ternsecure-debug",
|
|
42
|
+
ForwardedHost: "x-forwarded-host",
|
|
43
|
+
ForwardedPort: "x-forwarded-port",
|
|
44
|
+
ForwardedProto: "x-forwarded-proto",
|
|
45
|
+
Host: "host",
|
|
46
|
+
Location: "location",
|
|
47
|
+
Nonce: "x-nonce",
|
|
48
|
+
Origin: "origin",
|
|
49
|
+
Referrer: "referer",
|
|
50
|
+
SecFetchDest: "sec-fetch-dest",
|
|
51
|
+
UserAgent: "user-agent",
|
|
52
|
+
ReportingEndpoints: "reporting-endpoints"
|
|
53
|
+
};
|
|
54
|
+
var ContentTypes = {
|
|
55
|
+
Json: "application/json"
|
|
56
|
+
};
|
|
57
|
+
var constants = {
|
|
58
|
+
Attributes,
|
|
59
|
+
Cookies,
|
|
60
|
+
Headers,
|
|
61
|
+
ContentTypes
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
// src/tokens/ternSecureRequest.ts
|
|
65
|
+
import { parse } from "cookie";
|
|
66
|
+
|
|
67
|
+
// src/tokens/ternUrl.ts
|
|
68
|
+
var TernUrl = class extends URL {
|
|
69
|
+
isCrossOrigin(other) {
|
|
70
|
+
return this.origin !== new URL(other.toString()).origin;
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
var createTernUrl = (...args) => {
|
|
74
|
+
return new TernUrl(...args);
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
// src/tokens/ternSecureRequest.ts
|
|
78
|
+
var TernSecureRequest = class extends Request {
|
|
79
|
+
ternUrl;
|
|
80
|
+
cookies;
|
|
81
|
+
constructor(input, init) {
|
|
82
|
+
const url = typeof input !== "string" && "url" in input ? input.url : String(input);
|
|
83
|
+
super(url, init || typeof input === "string" ? void 0 : input);
|
|
84
|
+
this.ternUrl = this.deriveUrlFromHeaders(this);
|
|
85
|
+
this.cookies = this.parseCookies(this);
|
|
86
|
+
}
|
|
87
|
+
toJSON() {
|
|
88
|
+
return {
|
|
89
|
+
url: this.ternUrl.href,
|
|
90
|
+
method: this.method,
|
|
91
|
+
headers: JSON.stringify(Object.fromEntries(this.headers)),
|
|
92
|
+
ternUrl: this.ternUrl.toString(),
|
|
93
|
+
cookies: JSON.stringify(Object.fromEntries(this.cookies))
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
deriveUrlFromHeaders(req) {
|
|
97
|
+
const initialUrl = new URL(req.url);
|
|
98
|
+
const forwardedProto = req.headers.get(constants.Headers.ForwardedProto);
|
|
99
|
+
const forwardedHost = req.headers.get(constants.Headers.ForwardedHost);
|
|
100
|
+
const host = req.headers.get(constants.Headers.Host);
|
|
101
|
+
const protocol = initialUrl.protocol;
|
|
102
|
+
const resolvedHost = this.getFirstValueFromHeader(forwardedHost) ?? host;
|
|
103
|
+
const resolvedProtocol = this.getFirstValueFromHeader(forwardedProto) ?? protocol?.replace(/[:/]/, "");
|
|
104
|
+
const origin = resolvedHost && resolvedProtocol ? `${resolvedProtocol}://${resolvedHost}` : initialUrl.origin;
|
|
105
|
+
if (origin === initialUrl.origin) {
|
|
106
|
+
return createTernUrl(initialUrl);
|
|
107
|
+
}
|
|
108
|
+
return createTernUrl(initialUrl.pathname + initialUrl.search, origin);
|
|
109
|
+
}
|
|
110
|
+
getFirstValueFromHeader(value) {
|
|
111
|
+
return value?.split(",")[0];
|
|
112
|
+
}
|
|
113
|
+
parseCookies(req) {
|
|
114
|
+
const cookiesRecord = parse(
|
|
115
|
+
this.decodeCookieValue(req.headers.get("cookie") || "")
|
|
116
|
+
);
|
|
117
|
+
return new Map(Object.entries(cookiesRecord));
|
|
118
|
+
}
|
|
119
|
+
decodeCookieValue(str) {
|
|
120
|
+
return str ? str.replace(/(%[0-9A-Z]{2})+/g, decodeURIComponent) : str;
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
var createTernSecureRequest = (...args) => {
|
|
124
|
+
return args[0] instanceof TernSecureRequest ? args[0] : new TernSecureRequest(...args);
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
// src/tokens/sessionConfig.ts
|
|
128
|
+
var getSessionConfig = (options) => {
|
|
129
|
+
const cookieConfig = options?.cookies?.session_cookie;
|
|
130
|
+
return {
|
|
131
|
+
COOKIE_NAME: cookieConfig?.name,
|
|
132
|
+
DEFAULT_EXPIRES_IN_MS: cookieConfig?.attributes?.maxAge,
|
|
133
|
+
DEFAULT_EXPIRES_IN_SECONDS: Math.floor((cookieConfig?.attributes?.maxAge || 0) / 1e3),
|
|
134
|
+
REVOKE_REFRESH_TOKENS_ON_SIGNOUT: cookieConfig?.revokeRefreshTokensOnSignOut
|
|
135
|
+
};
|
|
136
|
+
};
|
|
137
|
+
var getCookieOptions = (options) => {
|
|
138
|
+
const cookieConfig = options?.cookies?.session_cookie;
|
|
139
|
+
return {
|
|
140
|
+
httpOnly: cookieConfig?.attributes?.httpOnly,
|
|
141
|
+
secure: cookieConfig?.attributes?.secure,
|
|
142
|
+
sameSite: cookieConfig?.attributes?.sameSite,
|
|
143
|
+
path: cookieConfig?.attributes?.path
|
|
144
|
+
};
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
export {
|
|
148
|
+
SESSION_COOKIE_PUBLIC_KEYS_URL,
|
|
149
|
+
MAX_CACHE_LAST_UPDATED_AT_SECONDS,
|
|
150
|
+
DEFAULT_CACHE_DURATION,
|
|
151
|
+
CACHE_CONTROL_REGEX,
|
|
152
|
+
constants,
|
|
153
|
+
createTernSecureRequest,
|
|
154
|
+
getSessionConfig,
|
|
155
|
+
getCookieOptions
|
|
156
|
+
};
|
|
157
|
+
//# sourceMappingURL=chunk-JFOTE3Y5.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/constants.ts","../src/tokens/ternSecureRequest.ts","../src/tokens/ternUrl.ts","../src/tokens/sessionConfig.ts"],"sourcesContent":["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","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","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 { 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};"],"mappings":"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","names":[]}
|