@tern-secure/auth 1.1.0-canary.v20251023005301 → 1.1.0-canary.v20251028151628

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 (37) hide show
  1. package/dist/cjs/auth/cookies/session.js +2 -2
  2. package/dist/cjs/auth/cookies/session.js.map +1 -1
  3. package/dist/cjs/index.js.map +1 -1
  4. package/dist/cjs/instance/TernAuth.js +14 -11
  5. package/dist/cjs/instance/TernAuth.js.map +1 -1
  6. package/dist/cjs/resources/SignIn.js +7 -14
  7. package/dist/cjs/resources/SignIn.js.map +1 -1
  8. package/dist/cjs/resources/SignUp.js +31 -2
  9. package/dist/cjs/resources/SignUp.js.map +1 -1
  10. package/dist/cjs/utils/construct.js +1 -0
  11. package/dist/cjs/utils/construct.js.map +1 -1
  12. package/dist/cjs/utils/redirectUrls.js +1 -0
  13. package/dist/cjs/utils/redirectUrls.js.map +1 -1
  14. package/dist/esm/auth/cookies/session.js +2 -2
  15. package/dist/esm/auth/cookies/session.js.map +1 -1
  16. package/dist/esm/index.js.map +1 -1
  17. package/dist/esm/instance/TernAuth.js +14 -11
  18. package/dist/esm/instance/TernAuth.js.map +1 -1
  19. package/dist/esm/resources/SignIn.js +7 -14
  20. package/dist/esm/resources/SignIn.js.map +1 -1
  21. package/dist/esm/resources/SignUp.js +31 -2
  22. package/dist/esm/resources/SignUp.js.map +1 -1
  23. package/dist/esm/utils/construct.js +1 -0
  24. package/dist/esm/utils/construct.js.map +1 -1
  25. package/dist/esm/utils/redirectUrls.js +1 -0
  26. package/dist/esm/utils/redirectUrls.js.map +1 -1
  27. package/dist/types/index.d.ts +1 -1
  28. package/dist/types/index.d.ts.map +1 -1
  29. package/dist/types/instance/TernAuth.d.ts +2 -2
  30. package/dist/types/instance/TernAuth.d.ts.map +1 -1
  31. package/dist/types/resources/SignIn.d.ts +2 -2
  32. package/dist/types/resources/SignIn.d.ts.map +1 -1
  33. package/dist/types/resources/SignUp.d.ts +10 -7
  34. package/dist/types/resources/SignUp.d.ts.map +1 -1
  35. package/dist/types/utils/construct.d.ts.map +1 -1
  36. package/dist/types/utils/redirectUrls.d.ts.map +1 -1
  37. package/package.json +3 -3
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/auth/cookies/session.ts"],"sourcesContent":["import { cookieHandler, getCookieName, getCookiePrefix } from '@tern-secure/shared/cookie';\n\nconst SESSION_COOKIE_NAME = '__session';\nconst ID_TOKEN_COOKIE_NAME = 'FIREBASE_[DEFAULT]';\nconst REFRESH_TOKEN_COOKIE_NAME = 'FIREBASEID_[DEFAULT]';\nconst CUSTOM_COOKIE_NAME = '__custom';\n\nexport type SessionCookieHandler = {\n set: (token: string) => void;\n remove: () => void;\n get: () => string | undefined;\n};\n\nexport const createSessionCookie = (): SessionCookieHandler => {\n const sessionCookie = cookieHandler(SESSION_COOKIE_NAME);\n\n const set = (token: string) => {\n sessionCookie.set(token, {\n httpOnly: false,\n secure: true,\n sameSite: 'strict',\n path: '/',\n });\n };\n\n const remove = () => {\n sessionCookie.remove({\n path: '/',\n });\n };\n\n const get = () => {\n return sessionCookie.get();\n };\n\n return {\n set,\n remove,\n get,\n };\n};\n\nexport const createIdTokenCookie = (): SessionCookieHandler => {\n const prefix = getCookiePrefix();\n const cookieName = getCookieName(ID_TOKEN_COOKIE_NAME, prefix);\n const sessionCookie = cookieHandler(cookieName);\n\n const set = (token: string) => {\n sessionCookie.set(token, {\n httpOnly: false,\n secure: true,\n sameSite: 'strict',\n path: '/',\n });\n };\n\n const remove = () => {\n sessionCookie.remove({\n path: '/',\n });\n };\n\n const get = () => sessionCookie.get();\n\n return {\n set,\n remove,\n get,\n };\n};\n"],"mappings":"AAAA,SAAS,eAAe,eAAe,uBAAuB;AAE9D,MAAM,sBAAsB;AAC5B,MAAM,uBAAuB;AAC7B,MAAM,4BAA4B;AAClC,MAAM,qBAAqB;AAQpB,MAAM,sBAAsB,MAA4B;AAC7D,QAAM,gBAAgB,cAAc,mBAAmB;AAEvD,QAAM,MAAM,CAAC,UAAkB;AAC7B,kBAAc,IAAI,OAAO;AAAA,MACvB,UAAU;AAAA,MACV,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAEA,QAAM,SAAS,MAAM;AACnB,kBAAc,OAAO;AAAA,MACnB,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAEA,QAAM,MAAM,MAAM;AAChB,WAAO,cAAc,IAAI;AAAA,EAC3B;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEO,MAAM,sBAAsB,MAA4B;AAC7D,QAAM,SAAS,gBAAgB;AAC/B,QAAM,aAAa,cAAc,sBAAsB,MAAM;AAC7D,QAAM,gBAAgB,cAAc,UAAU;AAE9C,QAAM,MAAM,CAAC,UAAkB;AAC7B,kBAAc,IAAI,OAAO;AAAA,MACvB,UAAU;AAAA,MACV,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAEA,QAAM,SAAS,MAAM;AACnB,kBAAc,OAAO;AAAA,MACnB,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAEA,QAAM,MAAM,MAAM,cAAc,IAAI;AAEpC,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;","names":[]}
1
+ {"version":3,"sources":["../../../../src/auth/cookies/session.ts"],"sourcesContent":["import { cookieHandler, getCookieName, getCookiePrefix } from '@tern-secure/shared/cookie';\n\nconst SESSION_COOKIE_NAME = '__session';\nconst ID_TOKEN_COOKIE_NAME = 'TernSecure_[DEFAULT]';\nconst REFRESH_TOKEN_COOKIE_NAME = 'TernSecureID_[DEFAULT]';\nconst CUSTOM_COOKIE_NAME = '__custom';\n\nexport type SessionCookieHandler = {\n set: (token: string) => void;\n remove: () => void;\n get: () => string | undefined;\n};\n\nexport const createSessionCookie = (): SessionCookieHandler => {\n const sessionCookie = cookieHandler(SESSION_COOKIE_NAME);\n\n const set = (token: string) => {\n sessionCookie.set(token, {\n httpOnly: false,\n secure: true,\n sameSite: 'strict',\n path: '/',\n });\n };\n\n const remove = () => {\n sessionCookie.remove({\n path: '/',\n });\n };\n\n const get = () => {\n return sessionCookie.get();\n };\n\n return {\n set,\n remove,\n get,\n };\n};\n\nexport const createIdTokenCookie = (): SessionCookieHandler => {\n const prefix = getCookiePrefix();\n const cookieName = getCookieName(ID_TOKEN_COOKIE_NAME, prefix);\n const sessionCookie = cookieHandler(cookieName);\n\n const set = (token: string) => {\n sessionCookie.set(token, {\n httpOnly: false,\n secure: true,\n sameSite: 'strict',\n path: '/',\n });\n };\n\n const remove = () => {\n sessionCookie.remove({\n path: '/',\n });\n };\n\n const get = () => sessionCookie.get();\n\n return {\n set,\n remove,\n get,\n };\n};\n"],"mappings":"AAAA,SAAS,eAAe,eAAe,uBAAuB;AAE9D,MAAM,sBAAsB;AAC5B,MAAM,uBAAuB;AAC7B,MAAM,4BAA4B;AAClC,MAAM,qBAAqB;AAQpB,MAAM,sBAAsB,MAA4B;AAC7D,QAAM,gBAAgB,cAAc,mBAAmB;AAEvD,QAAM,MAAM,CAAC,UAAkB;AAC7B,kBAAc,IAAI,OAAO;AAAA,MACvB,UAAU;AAAA,MACV,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAEA,QAAM,SAAS,MAAM;AACnB,kBAAc,OAAO;AAAA,MACnB,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAEA,QAAM,MAAM,MAAM;AAChB,WAAO,cAAc,IAAI;AAAA,EAC3B;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEO,MAAM,sBAAsB,MAA4B;AAC7D,QAAM,SAAS,gBAAgB;AAC/B,QAAM,aAAa,cAAc,sBAAsB,MAAM;AAC7D,QAAM,gBAAgB,cAAc,UAAU;AAE9C,QAAM,MAAM,CAAC,UAAkB;AAC7B,kBAAc,IAAI,OAAO;AAAA,MACvB,UAAU;AAAA,MACV,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAEA,QAAM,SAAS,MAAM;AACnB,kBAAc,OAAO;AAAA,MACnB,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAEA,QAAM,MAAM,MAAM,cAAc,IAAI;AAEpC,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/index.ts"],"sourcesContent":["export { TernSecureAuth } from './instance/TernAuth';\nexport type { TernAuth } from './instance/TernAuth';\nexport { TernServerAuth } from './instance/TernAuthServer';\nexport type { TernServerAuthOptions, AuthenticatedApp } from './instance/TernAuthServer';\n\nexport { CoreApiClient, coreApiClient } from './instance/coreApiClient';\nexport type { \n ApiResponse, \n ApiResponseJSON, \n RequestOptions,\n BeforeRequestHook,\n AfterResponseHook\n} from './instance/coreApiClient';\n\nexport { SignIn, TernSecureBase, buildURL } from './resources/internal';\n\nexport type {\n AuthErrorTree,\n TernSecureConfig,\n SignInFormValues,\n SignInProps,\n SignUpProps,\n SignInResponse,\n SignInForceRedirectUrl,\n SignUpForceRedirectUrl,\n ResendEmailVerification,\n TernSecureUser,\n TernSecureState\n} from '@tern-secure/types';\n\nexport { RedirectUrls } from './utils/redirectUrls';"],"mappings":"AAAA,SAAS,sBAAsB;AAE/B,SAAS,sBAAsB;AAG/B,SAAS,eAAe,qBAAqB;AAS7C,SAAS,QAAQ,gBAAgB,gBAAgB;AAgBjD,SAAS,oBAAoB;","names":[]}
1
+ {"version":3,"sources":["../../src/index.ts"],"sourcesContent":["export { TernSecureAuth } from './instance/TernAuth';\nexport type { TernAuth } from './instance/TernAuth';\nexport { TernServerAuth } from './instance/TernAuthServer';\nexport type { TernServerAuthOptions, AuthenticatedApp } from './instance/TernAuthServer';\n\nexport { CoreApiClient, coreApiClient } from './instance/coreApiClient';\nexport type { \n ApiResponse, \n ApiResponseJSON, \n RequestOptions,\n BeforeRequestHook,\n AfterResponseHook\n} from './instance/coreApiClient';\n\nexport { SignIn, TernSecureBase, buildURL } from './resources/internal';\n\nexport type {\n AuthErrorTree,\n TernSecureConfig,\n SignInFormValues,\n SignInProps,\n SignUpProps,\n SignInResponse,\n SignInForceRedirectUrl,\n SignUpForceRedirectUrl,\n SignInFallbackRedirectUrl,\n SignUpFallbackRedirectUrl,\n ResendEmailVerification,\n TernSecureUser,\n TernSecureState\n} from '@tern-secure/types';\n\nexport { RedirectUrls } from './utils/redirectUrls';"],"mappings":"AAAA,SAAS,sBAAsB;AAE/B,SAAS,sBAAsB;AAG/B,SAAS,eAAe,qBAAqB;AAS7C,SAAS,QAAQ,gBAAgB,gBAAgB;AAkBjD,SAAS,oBAAoB;","names":[]}
@@ -27,10 +27,10 @@ function inBrowser() {
27
27
  return typeof window !== "undefined";
28
28
  }
29
29
  class TernSecureAuth {
30
- static version = "1.1.0-canary.v20251023005301";
30
+ static version = "1.1.0-canary.v20251028151628";
31
31
  static sdkMetadata = {
32
32
  name: "@tern-secure/auth",
33
- version: "1.1.0-canary.v20251023005301",
33
+ version: "1.1.0-canary.v20251028151628",
34
34
  environment: process.env.NODE_ENV || "production"
35
35
  };
36
36
  static instance = null;
@@ -165,7 +165,10 @@ class TernSecureAuth {
165
165
  if (!this.#options.apiUrl) {
166
166
  throw new Error("apiUrl is required to initialize TernSecureAuth");
167
167
  }
168
- this.initializeFirebaseApp(this.#options.ternSecureConfig);
168
+ this.initializeFirebaseApp(this.#options.ternSecureConfig, {
169
+ appName: this.#options.appName,
170
+ tenantId: this.#options.tenantId
171
+ });
169
172
  const isBrowserCookiePersistence = this.#options.persistence === "browserCookie";
170
173
  if (!isBrowserCookiePersistence) {
171
174
  this.authStateUnsubscribe = this.initAuthStateListener();
@@ -188,8 +191,8 @@ class TernSecureAuth {
188
191
  throw error;
189
192
  }
190
193
  };
191
- initializeFirebaseApp(config) {
192
- const appName = config.appName || "[DEFAULT]";
194
+ initializeFirebaseApp(config, options) {
195
+ const appName = (options == null ? void 0 : options.appName) || "[DEFAULT]";
193
196
  this.firebaseClientApp = getApps().length === 0 ? initializeApp(config, appName) : getApps()[0];
194
197
  const persistence = this.#setPersistence();
195
198
  const auth = initializeAuth(this.firebaseClientApp, {
@@ -197,8 +200,8 @@ class TernSecureAuth {
197
200
  popupRedirectResolver: browserPopupRedirectResolver
198
201
  });
199
202
  this.auth = auth;
200
- if (config.tenantId) {
201
- this.auth.tenantId = config.tenantId;
203
+ if (options == null ? void 0 : options.tenantId) {
204
+ this.auth.tenantId = options.tenantId;
202
205
  }
203
206
  this.#configureEmulator();
204
207
  getInstallations(this.firebaseClientApp);
@@ -311,7 +314,7 @@ class TernSecureAuth {
311
314
  this.signedInSession = null;
312
315
  }
313
316
  }
314
- async checkRedirectResult() {
317
+ checkRedirectResult = async () => {
315
318
  try {
316
319
  const result = await getRedirectResult(this.auth);
317
320
  if (result) {
@@ -329,9 +332,9 @@ class TernSecureAuth {
329
332
  error: authError.code
330
333
  };
331
334
  }
332
- }
335
+ };
333
336
  getRedirectResult = async () => {
334
- throw new Error("getRedirectResult not implemented");
337
+ return this.checkRedirectResult();
335
338
  };
336
339
  addListener = (listener) => {
337
340
  this.#listeners.push(listener);
@@ -531,7 +534,7 @@ class TernSecureAuth {
531
534
  }
532
535
  const emulatorUrl = host.startsWith("http") ? host : `http://${host}`;
533
536
  try {
534
- connectAuthEmulator(this.auth, emulatorUrl, { disableWarnings: true });
537
+ connectAuthEmulator(this.auth, emulatorUrl, { disableWarnings: false });
535
538
  console.warn(`[TernSecure] Firebase Auth Emulator connected at ${emulatorUrl}`);
536
539
  } catch (error) {
537
540
  console.error("[TernSecure] Error connecting to Firebase Auth Emulator:", error);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/instance/TernAuth.ts"],"sourcesContent":["import { handleFirebaseAuthError } from '@tern-secure/shared/errors';\nimport { createTernAuthEventBus, ternEvents } from '@tern-secure/shared/ternStatusEvent';\nimport { stripScheme } from '@tern-secure/shared/url';\nimport { handleValueOrFn } from '@tern-secure/shared/utils';\nimport type {\n CreateActiveSession,\n DomainOrProxyUrl,\n InstanceType,\n ListenerCallback,\n NavigateOptions,\n RedirectOptions,\n SessionResource,\n SignedInSession,\n SignInRedirectOptions,\n SignInResource,\n SignInResponse,\n SignOut,\n SignOutOptions,\n SignUpRedirectOptions,\n SignUpResource,\n TernAuthSDK,\n TernSecureAuth as TernSecureAuthInterface,\n TernSecureAuthOptions,\n TernSecureAuthStatus,\n TernSecureConfig,\n TernSecureResources,\n TernSecureUser,\n TernSecureUserData,\n UnsubscribeCallback,\n} from '@tern-secure/types';\nimport type { FirebaseApp } from 'firebase/app';\nimport { getApps, initializeApp } from 'firebase/app';\nimport type { Auth, Auth as TernAuth } from 'firebase/auth';\nimport {\n browserLocalPersistence,\n browserPopupRedirectResolver,\n browserSessionPersistence,\n connectAuthEmulator,\n getIdToken,\n getRedirectResult,\n initializeAuth,\n inMemoryPersistence,\n onAuthStateChanged,\n onIdTokenChanged,\n} from 'firebase/auth';\nimport { getInstallations } from 'firebase/installations';\n\nimport { type ClientAuthRequest, createClientAuthRequest } from '../auth/request';\nimport { AuthCookieManager, Session, SignIn, SignUp, TernSecureBase } from '../resources/internal';\nimport { ALLOWED_PROTOCOLS, buildURL, stripOrigin, windowNavigate } from '../utils/';\nimport { RedirectUrls } from '../utils/redirectUrls';\nimport { type ApiClient, createCoreApiClient } from './c_coreApiClient';\nimport { eventBus, events } from './events';\nimport { createClientFromJwt } from './jwtClient';\n\nexport function inBrowser(): boolean {\n return typeof window !== 'undefined';\n}\n\nexport { TernAuth };\n\n/**\n * Firebase implementation of the TernSecureAuth interface\n */\nexport class TernSecureAuth implements TernSecureAuthInterface {\n public static version: string = PACKAGE_VERSION;\n public static sdkMetadata: TernAuthSDK = {\n name: PACKAGE_NAME,\n version: PACKAGE_VERSION,\n environment: process.env.NODE_ENV || 'production',\n };\n private static instance: TernSecureAuth | null = null;\n private _currentUser: TernSecureUser | null = null;\n private signedInSession: SignedInSession | null = null;\n private firebaseClientApp: FirebaseApp | undefined;\n private authStateUnsubscribe: (() => void) | null = null;\n private auth!: Auth;\n private csrfToken: string | undefined;\n public isLoading = false;\n public error: Error | null = null;\n public user: TernSecureUser | null | undefined = null;\n public __internal_country?: string | null;\n #domain: DomainOrProxyUrl['domain'];\n #apiClient: ApiClient;\n #apiUrl: string;\n #instanceType?: InstanceType;\n #status: TernSecureAuthInterface['status'] = 'loading';\n #listeners: Array<(emission: TernSecureResources) => void> = [];\n #options: TernSecureAuthOptions = {};\n #authCookieManager?: AuthCookieManager;\n #clientAuthRequest?: ClientAuthRequest;\n #publicEventBus = createTernAuthEventBus();\n\n signIn!: SignInResource | null | undefined;\n signUp!: SignUpResource | null | undefined;\n session!: SessionResource | null | undefined;\n\n get isReady(): boolean {\n return this.status === 'ready';\n }\n\n get status(): TernSecureAuthInterface['status'] {\n return this.#status;\n }\n\n get version(): string {\n return TernSecureAuth.version;\n }\n\n set sdkMetadata(metadata: TernAuthSDK) {\n TernSecureAuth.sdkMetadata = metadata;\n }\n\n get sdkMetadata(): TernAuthSDK {\n return TernSecureAuth.sdkMetadata;\n }\n\n get requiresVerification(): boolean {\n return this.#options.requiresVerification ?? true;\n }\n\n get apiUrl(): string {\n return this.#apiUrl;\n }\n\n get domain(): string {\n if (inBrowser()) {\n const strippedDomainString = stripScheme(\n handleValueOrFn(this.#domain, new URL(window.location.href)),\n );\n if (this.#instanceType === 'production') {\n return strippedDomainString;\n }\n return strippedDomainString;\n }\n return '';\n }\n\n get instanceType() {\n return this.#instanceType;\n }\n\n public constructor(options?: TernSecureAuthOptions) {\n this.#domain = options?.ternSecureConfig?.authDomain;\n this.#apiUrl = options?.apiUrl || '';\n this.#instanceType = (process.env.NODE_ENV as InstanceType) || 'production';\n\n this.#apiClient = createCoreApiClient({\n domain: this.#domain,\n apiUrl: options?.apiUrl,\n instanceType: this.instanceType as InstanceType,\n });\n\n this.#publicEventBus.emit(ternEvents.Status, 'loading');\n TernSecureBase.ternsecure = this;\n }\n\n public getApiClient = (): ApiClient => this.#apiClient;\n\n /**\n * Get user data for the provided ID token via backend API\n */\n public async getUserData(): Promise<TernSecureUserData | null> {\n if (!this.#clientAuthRequest) {\n throw new Error('Client auth request not initialized');\n }\n\n return this.#clientAuthRequest.getUserData();\n }\n\n public setLoading(isLoading: boolean): void {\n this.isLoading = isLoading;\n }\n\n public authCookieManager(): AuthCookieManager | undefined {\n return this.#authCookieManager;\n }\n\n public _internal_getOption<K extends keyof TernSecureAuthOptions>(\n key: K,\n ): TernSecureAuthOptions[K] {\n return this.#options[key];\n }\n\n public _internal_getAllOptions(): Readonly<TernSecureAuthOptions> {\n return Object.freeze({ ...this.#options });\n }\n\n static getOrCreateInstance(options?: TernSecureAuthOptions): TernSecureAuth {\n if (!this.instance) {\n this.instance = new TernSecureAuth(options);\n }\n return this.instance;\n }\n\n static clearInstance() {\n if (TernSecureAuth.instance) {\n if (TernSecureAuth.instance.authStateUnsubscribe) {\n TernSecureAuth.instance.authStateUnsubscribe();\n TernSecureAuth.instance.authStateUnsubscribe = null;\n }\n TernSecureAuth.instance = null;\n }\n }\n\n public static initialize(options: TernSecureAuthOptions): TernSecureAuth {\n const instance = this.getOrCreateInstance(options);\n instance.#initialize(options);\n return instance;\n }\n\n initialize = async (options?: TernSecureAuthOptions): Promise<void> => {\n void this.#initialize(options || {});\n };\n\n public static create(options: TernSecureAuthOptions): TernSecureAuth {\n const instance = this.getOrCreateInstance();\n void instance.initialize(options);\n return instance;\n }\n\n #initialize = (options: TernSecureAuthOptions): void => {\n this.#options = this.#initOptions(options);\n\n try {\n if (!this.#options.ternSecureConfig) {\n throw new Error('TernSecureConfig is required to initialize TernSecureAuth');\n }\n\n if (!this.#options.apiUrl) {\n throw new Error('apiUrl is required to initialize TernSecureAuth');\n }\n\n this.initializeFirebaseApp(this.#options.ternSecureConfig);\n\n const isBrowserCookiePersistence = this.#options.persistence === 'browserCookie';\n\n if (!isBrowserCookiePersistence) {\n this.authStateUnsubscribe = this.initAuthStateListener();\n }\n\n this.#authCookieManager = new AuthCookieManager();\n this.csrfToken = this.#authCookieManager.getCSRFToken();\n\n this.#clientAuthRequest = createClientAuthRequest();\n\n this.signIn = new SignIn(this.auth, this.csrfToken);\n this.signUp = new SignUp(this.auth);\n\n eventBus.on(events.SessionChanged, () => {\n this.#setCreatedActiveSession(this.user || null);\n this.#emit();\n });\n\n this.#setStatus('ready');\n this.#publicEventBus.emit(ternEvents.Status, 'ready');\n\n //return this;\n } catch (error) {\n this.error = error as Error;\n this.#setStatus('error');\n this.#publicEventBus.emit(ternEvents.Status, 'error');\n throw error;\n }\n };\n\n private initializeFirebaseApp(config: TernSecureConfig) {\n const appName = config.appName || '[DEFAULT]';\n this.firebaseClientApp = getApps().length === 0 ? initializeApp(config, appName) : getApps()[0];\n\n const persistence = this.#setPersistence();\n const auth = initializeAuth(this.firebaseClientApp, {\n persistence,\n popupRedirectResolver: browserPopupRedirectResolver,\n });\n\n this.auth = auth;\n\n if (config.tenantId) {\n this.auth.tenantId = config.tenantId;\n }\n\n this.#configureEmulator();\n\n getInstallations(this.firebaseClientApp);\n }\n\n /**\n * use when cookie are not httpOnly\n */\n initClient = () => {\n const idTokenInCookie = this.#authCookieManager?.getIdTokenCookie();\n const jwtClient = createClientFromJwt(idTokenInCookie || null);\n this.user = jwtClient as TernSecureUser | null;\n this.#emit();\n };\n\n /**\n * @deprecated will be removed in future releases.\n */\n initClientAuthRequest = () => {\n this.#clientAuthRequest\n ?.getIdTokenFromCookie()\n .then(idTokenInCookie => {\n const { token } = idTokenInCookie;\n const jwtClient = createClientFromJwt(token || null);\n this.user = jwtClient as TernSecureUser | null;\n this.#emit();\n })\n .catch(error => {\n console.error('[ternauth] Error during client auth request initialization:', error);\n this.user = null;\n this.#emit();\n });\n };\n\n public signOut: SignOut = async (options?: SignOutOptions) => {\n const redirectUrl = options?.redirectUrl || this.#constructAfterSignOutUrl();\n if (options?.onBeforeSignOut) {\n await options.onBeforeSignOut();\n }\n\n await this.auth.signOut();\n\n if (options?.onAfterSignOut) {\n await options.onAfterSignOut();\n }\n \n await this.navigate(redirectUrl);\n\n eventBus.emit(events.UserSignOut, null);\n eventBus.emit(events.TokenUpdate, { token: null });\n this.#emit();\n };\n\n get currentSession(): SignedInSession | null {\n return this.signedInSession;\n }\n\n private initAuthListener(): () => void {\n (async () => {\n await this.auth.authStateReady();\n const user = this.auth.currentUser as TernSecureUser | null;\n this._currentUser = user;\n this.user = user;\n await this.updateCurrentSession();\n this.#emit();\n })();\n\n // Return a no-op unsubscribe function since we're not setting up a listener\n return () => {\n // No-op: nothing to unsubscribe from\n };\n }\n\n private initAuthStateListener(): () => void {\n return onAuthStateChanged(this.auth, async (user: TernSecureUser | null) => {\n await this.auth.authStateReady();\n this._currentUser = user;\n this.user = user;\n await this.updateCurrentSession();\n\n this.#emit();\n });\n }\n\n private _onIdTokenChanged(): () => void {\n return onIdTokenChanged(this.auth, async (user: TernSecureUser | null) => {\n await this.auth.authStateReady();\n this._currentUser = user;\n this.user = user;\n await this.updateCurrentSession();\n\n this.#emit();\n });\n }\n\n private async getIdToken(): Promise<string | null> {\n await this.auth.authStateReady();\n if (!this.auth.currentUser) {\n return null;\n }\n return getIdToken(this.auth.currentUser);\n }\n\n public onAuthStateChanged(callback: (cb: any) => void): () => void {\n return onAuthStateChanged(this.auth, callback);\n }\n\n public onIdTokenChanged(callback: (cb: any) => void): () => void {\n return onIdTokenChanged(this.auth, callback);\n }\n\n private async updateCurrentSession(): Promise<void> {\n if (!this._currentUser) {\n this.signedInSession = null;\n return;\n }\n\n try {\n const res = await this._currentUser.getIdTokenResult();\n this.signedInSession = {\n status: 'active',\n token: res.token,\n claims: res.claims,\n issuedAtTime: res.issuedAtTime,\n expirationTime: res.expirationTime,\n authTime: res.authTime,\n signInProvider: res.signInProvider || 'unknown',\n signInSecondFactor: res.signInSecondFactor,\n };\n } catch (error) {\n console.error('[TernSecureAuth] Error updating session:', error);\n this.signedInSession = null;\n }\n }\n\n public async checkRedirectResult(): Promise<SignInResponse | null> {\n try {\n const result = await getRedirectResult(this.auth);\n if (result) {\n return {\n status: 'success',\n user: result.user as TernSecureUser,\n };\n }\n return null;\n } catch (error) {\n const authError = handleFirebaseAuthError(error);\n return {\n status: 'error',\n message: authError.message,\n error: authError.code,\n };\n }\n }\n\n public getRedirectResult = async (): Promise<any> => {\n throw new Error('getRedirectResult not implemented');\n };\n\n public addListener = (listener: ListenerCallback): UnsubscribeCallback => {\n this.#listeners.push(listener);\n if (this._currentUser) {\n listener({\n user: this._currentUser,\n session: this.signedInSession,\n });\n }\n\n const unsubscribe = () => {\n this.#listeners = this.#listeners.filter(l => l !== listener);\n };\n return unsubscribe;\n };\n\n public on: TernSecureAuthInterface['on'] = (...args) => {\n this.#publicEventBus.on(...args);\n };\n\n public off: TernSecureAuthInterface['off'] = (...args) => {\n this.#publicEventBus.off(...args);\n };\n\n public createActiveSession: CreateActiveSession = async ({\n session,\n redirectUrl,\n }): Promise<void> => {\n try {\n if (!session) {\n throw new Error('No session provided to createActiveSession');\n }\n const sessionResult = await session.getIdTokenResult();\n const sessionData = new Session(sessionResult);\n await sessionData.create(this.csrfToken || '');\n\n if (redirectUrl) {\n await this.navigate(this.constructUrlWithAuthRedirect(redirectUrl));\n }\n\n this.#setCreatedActiveSession(session);\n this.#emit();\n } catch (error) {\n console.error('[TernSecureAuth] Error creating active session:', error);\n }\n };\n\n public navigate = async (to: string | undefined, options?: NavigateOptions): Promise<unknown> => {\n if (!to || !inBrowser()) {\n return;\n }\n\n let toURL = new URL(to, window.location.href);\n\n if (!this.#allowedRedirectProtocols.includes(toURL.protocol)) {\n console.warn(\n `TernSecureAuth: \"${toURL.protocol}\" is not a valid protocol. Redirecting to \"/\" instead. If you think this is a mistake, please open an issue.`,\n );\n toURL = new URL('/', window.location.href);\n }\n\n const customNavigate =\n options?.replace && this.#options.routerReplace\n ? this.#options.routerReplace\n : this.#options.routerPush;\n\n if ((toURL.origin !== 'null' && toURL.origin !== window.location.origin) || !customNavigate) {\n windowNavigate(toURL);\n return;\n }\n\n const metadata = {\n ...(options?.metadata ? { __internal_metadata: options?.metadata } : {}),\n windowNavigate,\n };\n\n // React router only wants the path, search or hash portion.\n return await customNavigate(stripOrigin(toURL), metadata);\n };\n\n public constructUrlWithAuthRedirect = (to: string): string => {\n if (this.#instanceType === 'production') {\n return to;\n }\n const baseUrl = window.location.origin;\n const url = new URL(to, baseUrl);\n\n if (url.origin === window.location.origin) {\n return url.href;\n }\n\n return url.toString();\n };\n\n #buildUrl = (key: 'signInUrl' | 'signUpUrl', options: RedirectOptions): string => {\n if (!key || !this.isReady) {\n return '';\n }\n\n const baseUrlConfig = key === 'signInUrl' ? this.#options.signInUrl : this.#options.signUpUrl;\n const defaultPagePath = key === 'signInUrl' ? '/sign-in' : '/sign-up';\n const base = baseUrlConfig || defaultPagePath;\n\n const redirectUrls = new RedirectUrls(this.#options, options).toSearchParams();\n const constructedUrl = buildURL(\n {\n base,\n hashSearchParams: [redirectUrls],\n },\n {\n stringify: true,\n skipOrigin: false,\n },\n );\n return this.constructUrlWithAuthRedirect(constructedUrl);\n };\n\n #constructAfterSignInUrl = (): string => {\n return this.constructUrlWithAuthRedirect(new RedirectUrls(this.#options).getAfterSignInUrl());\n };\n\n #constructAfterSignOutUrl = (): string => {\n if (!this.#options.afterSignOutUrl) {\n return '/';\n }\n return this.constructUrlWithAuthRedirect(this.#options.afterSignOutUrl);\n };\n\n public redirectToSignIn = async (options?: SignInRedirectOptions): Promise<unknown> => {\n if (inBrowser()) {\n return this.navigate(this.constructSignInUrl(options));\n }\n return;\n };\n\n public redirectToSignUp = async (options?: SignUpRedirectOptions): Promise<unknown> => {\n if (inBrowser()) {\n return this.navigate(this.constructSignUpUrl());\n }\n return;\n };\n\n public redirectAfterSignIn = async (): Promise<unknown> => {\n if (inBrowser()) {\n return this.navigate(this.#constructAfterSignInUrl());\n }\n return;\n };\n\n redirectAfterSignUp = (): void => {\n throw new Error('redirectAfterSignUp is not implemented yet');\n };\n\n public constructSignInUrl = (options?: SignInRedirectOptions): string => {\n return this.#buildUrl('signInUrl', {\n ...options,\n signInForceRedirectUrl: options?.signInForceRedirectUrl || window.location.href,\n });\n };\n\n public constructSignUpUrl = (options?: SignUpRedirectOptions): string => {\n return this.#buildUrl('signUpUrl', {\n ...options,\n signUpForceRedirectUrl: options?.signUpForceRedirectUrl || window.location.href,\n });\n };\n\n get #allowedRedirectProtocols() {\n let allowedProtocols = ALLOWED_PROTOCOLS;\n\n if (this.#options.allowedRedirectProtocols) {\n allowedProtocols = allowedProtocols.concat(this.#options.allowedRedirectProtocols);\n }\n\n return allowedProtocols;\n }\n\n __internal_setCountry = (country: string | null) => {\n if (!this.__internal_country) {\n this.__internal_country = country;\n }\n };\n\n #initOptions = (options: TernSecureAuthOptions): TernSecureAuthOptions => {\n return {\n ...options,\n };\n };\n\n #emit = (): void => {\n for (const listener of this.#listeners) {\n listener({\n user: this.user,\n session: this.signedInSession,\n });\n }\n };\n\n #setStatus(newStatus: TernSecureAuthStatus): void {\n if (this.#status !== newStatus) {\n this.#status = newStatus;\n this.#publicEventBus.emit(ternEvents.Status, this.#status);\n\n if (newStatus === 'ready') {\n this.#publicEventBus.emit(ternEvents.Status, 'ready');\n }\n }\n }\n\n #setCreatedActiveSession = (session: TernSecureUser | null) => {\n this.user = session;\n };\n\n #setPersistence = () => {\n const persistenceType = this.#options.persistence;\n\n switch (persistenceType) {\n case 'browserCookie':\n return inMemoryPersistence;\n case 'session':\n return browserSessionPersistence;\n case 'local':\n return browserLocalPersistence;\n case 'none':\n default:\n return inMemoryPersistence;\n }\n };\n\n #emulatorHost = (): string | undefined => {\n if (typeof process === 'undefined') return undefined;\n return process.env.FIREBASE_AUTH_EMULATOR_HOST;\n };\n\n #configureEmulator = (): void => {\n const host = this.#emulatorHost();\n const isDev = this.#instanceType === 'development';\n const shouldUseEmulator = isDev && !!host;\n if (!shouldUseEmulator || !host) {\n return;\n }\n\n const emulatorUrl = host.startsWith('http') ? host : `http://${host}`;\n\n try {\n //(this.auth as unknown as any)._canInitEmulator = true;\n connectAuthEmulator(this.auth, emulatorUrl, { disableWarnings: true });\n console.warn(`[TernSecure] Firebase Auth Emulator connected at ${emulatorUrl}`);\n } catch (error) {\n console.error('[TernSecure] Error connecting to Firebase Auth Emulator:', error);\n }\n };\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/instance/TernAuth.ts"],"sourcesContent":["import { handleFirebaseAuthError } from '@tern-secure/shared/errors';\nimport { createTernAuthEventBus, ternEvents } from '@tern-secure/shared/ternStatusEvent';\nimport { stripScheme } from '@tern-secure/shared/url';\nimport { handleValueOrFn } from '@tern-secure/shared/utils';\nimport type {\n CreateActiveSession,\n DomainOrProxyUrl,\n InstanceType,\n ListenerCallback,\n NavigateOptions,\n RedirectOptions,\n SessionResource,\n SignedInSession,\n SignInRedirectOptions,\n SignInResource,\n SignInResponse,\n SignOut,\n SignOutOptions,\n SignUpRedirectOptions,\n SignUpResource,\n TernAuthSDK,\n TernSecureAuth as TernSecureAuthInterface,\n TernSecureAuthOptions,\n TernSecureAuthStatus,\n TernSecureConfig,\n TernSecureResources,\n TernSecureUser,\n TernSecureUserData,\n UnsubscribeCallback,\n} from '@tern-secure/types';\nimport type { FirebaseApp } from 'firebase/app';\nimport { getApps, initializeApp } from 'firebase/app';\nimport type { Auth, Auth as TernAuth } from 'firebase/auth';\nimport {\n browserLocalPersistence,\n browserPopupRedirectResolver,\n browserSessionPersistence,\n connectAuthEmulator,\n getIdToken,\n getRedirectResult,\n initializeAuth,\n inMemoryPersistence,\n onAuthStateChanged,\n onIdTokenChanged,\n} from 'firebase/auth';\nimport { getInstallations } from 'firebase/installations';\n\nimport { type ClientAuthRequest, createClientAuthRequest } from '../auth/request';\nimport { AuthCookieManager, Session, SignIn, SignUp, TernSecureBase } from '../resources/internal';\nimport { ALLOWED_PROTOCOLS, buildURL, stripOrigin, windowNavigate } from '../utils/';\nimport { RedirectUrls } from '../utils/redirectUrls';\nimport { type ApiClient, createCoreApiClient } from './c_coreApiClient';\nimport { eventBus, events } from './events';\nimport { createClientFromJwt } from './jwtClient';\n\nexport function inBrowser(): boolean {\n return typeof window !== 'undefined';\n}\n\nexport { TernAuth };\n\n/**\n * Firebase implementation of the TernSecureAuth interface\n */\nexport class TernSecureAuth implements TernSecureAuthInterface {\n public static version: string = PACKAGE_VERSION;\n public static sdkMetadata: TernAuthSDK = {\n name: PACKAGE_NAME,\n version: PACKAGE_VERSION,\n environment: process.env.NODE_ENV || 'production',\n };\n private static instance: TernSecureAuth | null = null;\n private _currentUser: TernSecureUser | null = null;\n private signedInSession: SignedInSession | null = null;\n private firebaseClientApp: FirebaseApp | undefined;\n private authStateUnsubscribe: (() => void) | null = null;\n private auth!: Auth;\n private csrfToken: string | undefined;\n public isLoading = false;\n public error: Error | null = null;\n public user: TernSecureUser | null | undefined = null;\n public __internal_country?: string | null;\n #domain: DomainOrProxyUrl['domain'];\n #apiClient: ApiClient;\n #apiUrl: string;\n #instanceType?: InstanceType;\n #status: TernSecureAuthInterface['status'] = 'loading';\n #listeners: Array<(emission: TernSecureResources) => void> = [];\n #options: TernSecureAuthOptions = {};\n #authCookieManager?: AuthCookieManager;\n #clientAuthRequest?: ClientAuthRequest;\n #publicEventBus = createTernAuthEventBus();\n\n signIn!: SignInResource | null | undefined;\n signUp!: SignUpResource | null | undefined;\n session!: SessionResource | null | undefined;\n\n get isReady(): boolean {\n return this.status === 'ready';\n }\n\n get status(): TernSecureAuthInterface['status'] {\n return this.#status;\n }\n\n get version(): string {\n return TernSecureAuth.version;\n }\n\n set sdkMetadata(metadata: TernAuthSDK) {\n TernSecureAuth.sdkMetadata = metadata;\n }\n\n get sdkMetadata(): TernAuthSDK {\n return TernSecureAuth.sdkMetadata;\n }\n\n get requiresVerification(): boolean {\n return this.#options.requiresVerification ?? true;\n }\n\n get apiUrl(): string {\n return this.#apiUrl;\n }\n\n get domain(): string {\n if (inBrowser()) {\n const strippedDomainString = stripScheme(\n handleValueOrFn(this.#domain, new URL(window.location.href)),\n );\n if (this.#instanceType === 'production') {\n return strippedDomainString;\n }\n return strippedDomainString;\n }\n return '';\n }\n\n get instanceType() {\n return this.#instanceType;\n }\n\n public constructor(options?: TernSecureAuthOptions) {\n this.#domain = options?.ternSecureConfig?.authDomain;\n this.#apiUrl = options?.apiUrl || '';\n this.#instanceType = (process.env.NODE_ENV as InstanceType) || 'production';\n\n this.#apiClient = createCoreApiClient({\n domain: this.#domain,\n apiUrl: options?.apiUrl,\n instanceType: this.instanceType as InstanceType,\n });\n\n this.#publicEventBus.emit(ternEvents.Status, 'loading');\n TernSecureBase.ternsecure = this;\n }\n\n public getApiClient = (): ApiClient => this.#apiClient;\n\n /**\n * Get user data for the provided ID token via backend API\n */\n public async getUserData(): Promise<TernSecureUserData | null> {\n if (!this.#clientAuthRequest) {\n throw new Error('Client auth request not initialized');\n }\n\n return this.#clientAuthRequest.getUserData();\n }\n\n public setLoading(isLoading: boolean): void {\n this.isLoading = isLoading;\n }\n\n public authCookieManager(): AuthCookieManager | undefined {\n return this.#authCookieManager;\n }\n\n public _internal_getOption<K extends keyof TernSecureAuthOptions>(\n key: K,\n ): TernSecureAuthOptions[K] {\n return this.#options[key];\n }\n\n public _internal_getAllOptions(): Readonly<TernSecureAuthOptions> {\n return Object.freeze({ ...this.#options });\n }\n\n static getOrCreateInstance(options?: TernSecureAuthOptions): TernSecureAuth {\n if (!this.instance) {\n this.instance = new TernSecureAuth(options);\n }\n return this.instance;\n }\n\n static clearInstance() {\n if (TernSecureAuth.instance) {\n if (TernSecureAuth.instance.authStateUnsubscribe) {\n TernSecureAuth.instance.authStateUnsubscribe();\n TernSecureAuth.instance.authStateUnsubscribe = null;\n }\n TernSecureAuth.instance = null;\n }\n }\n\n public static initialize(options: TernSecureAuthOptions): TernSecureAuth {\n const instance = this.getOrCreateInstance(options);\n instance.#initialize(options);\n return instance;\n }\n\n initialize = async (options?: TernSecureAuthOptions): Promise<void> => {\n void this.#initialize(options || {});\n };\n\n public static create(options: TernSecureAuthOptions): TernSecureAuth {\n const instance = this.getOrCreateInstance();\n void instance.initialize(options);\n return instance;\n }\n\n #initialize = (options: TernSecureAuthOptions): void => {\n this.#options = this.#initOptions(options);\n\n try {\n if (!this.#options.ternSecureConfig) {\n throw new Error('TernSecureConfig is required to initialize TernSecureAuth');\n }\n\n if (!this.#options.apiUrl) {\n throw new Error('apiUrl is required to initialize TernSecureAuth');\n }\n\n this.initializeFirebaseApp(this.#options.ternSecureConfig, {\n appName: this.#options.appName,\n tenantId: this.#options.tenantId,\n });\n\n const isBrowserCookiePersistence = this.#options.persistence === 'browserCookie';\n\n if (!isBrowserCookiePersistence) {\n this.authStateUnsubscribe = this.initAuthStateListener();\n }\n\n this.#authCookieManager = new AuthCookieManager();\n this.csrfToken = this.#authCookieManager.getCSRFToken();\n\n this.#clientAuthRequest = createClientAuthRequest();\n\n this.signIn = new SignIn(this.auth, this.csrfToken);\n this.signUp = new SignUp(this.auth);\n\n eventBus.on(events.SessionChanged, () => {\n this.#setCreatedActiveSession(this.user || null);\n this.#emit();\n });\n\n this.#setStatus('ready');\n this.#publicEventBus.emit(ternEvents.Status, 'ready');\n\n //return this;\n } catch (error) {\n this.error = error as Error;\n this.#setStatus('error');\n this.#publicEventBus.emit(ternEvents.Status, 'error');\n throw error;\n }\n };\n\n private initializeFirebaseApp(\n config: TernSecureConfig,\n options?: { appName?: string; tenantId?: string },\n ): void {\n const appName = options?.appName || '[DEFAULT]';\n this.firebaseClientApp = getApps().length === 0 ? initializeApp(config, appName) : getApps()[0];\n\n const persistence = this.#setPersistence();\n const auth = initializeAuth(this.firebaseClientApp, {\n persistence,\n popupRedirectResolver: browserPopupRedirectResolver,\n });\n\n this.auth = auth;\n\n if (options?.tenantId) {\n this.auth.tenantId = options.tenantId;\n }\n\n this.#configureEmulator();\n\n getInstallations(this.firebaseClientApp);\n }\n\n /**\n * use when cookie are not httpOnly\n */\n initClient = () => {\n const idTokenInCookie = this.#authCookieManager?.getIdTokenCookie();\n const jwtClient = createClientFromJwt(idTokenInCookie || null);\n this.user = jwtClient as TernSecureUser | null;\n this.#emit();\n };\n\n /**\n * @deprecated will be removed in future releases.\n */\n initClientAuthRequest = () => {\n this.#clientAuthRequest\n ?.getIdTokenFromCookie()\n .then(idTokenInCookie => {\n const { token } = idTokenInCookie;\n const jwtClient = createClientFromJwt(token || null);\n this.user = jwtClient as TernSecureUser | null;\n this.#emit();\n })\n .catch(error => {\n console.error('[ternauth] Error during client auth request initialization:', error);\n this.user = null;\n this.#emit();\n });\n };\n\n public signOut: SignOut = async (options?: SignOutOptions) => {\n const redirectUrl = options?.redirectUrl || this.#constructAfterSignOutUrl();\n if (options?.onBeforeSignOut) {\n await options.onBeforeSignOut();\n }\n\n await this.auth.signOut();\n\n if (options?.onAfterSignOut) {\n await options.onAfterSignOut();\n }\n\n await this.navigate(redirectUrl);\n\n eventBus.emit(events.UserSignOut, null);\n eventBus.emit(events.TokenUpdate, { token: null });\n this.#emit();\n };\n\n get currentSession(): SignedInSession | null {\n return this.signedInSession;\n }\n\n private initAuthListener(): () => void {\n (async () => {\n await this.auth.authStateReady();\n const user = this.auth.currentUser as TernSecureUser | null;\n this._currentUser = user;\n this.user = user;\n await this.updateCurrentSession();\n this.#emit();\n })();\n\n // Return a no-op unsubscribe function since we're not setting up a listener\n return () => {\n // No-op: nothing to unsubscribe from\n };\n }\n\n private initAuthStateListener(): () => void {\n return onAuthStateChanged(this.auth, async (user: TernSecureUser | null) => {\n await this.auth.authStateReady();\n this._currentUser = user;\n this.user = user;\n await this.updateCurrentSession();\n\n this.#emit();\n });\n }\n\n private _onIdTokenChanged(): () => void {\n return onIdTokenChanged(this.auth, async (user: TernSecureUser | null) => {\n await this.auth.authStateReady();\n this._currentUser = user;\n this.user = user;\n await this.updateCurrentSession();\n\n this.#emit();\n });\n }\n\n private async getIdToken(): Promise<string | null> {\n await this.auth.authStateReady();\n if (!this.auth.currentUser) {\n return null;\n }\n return getIdToken(this.auth.currentUser);\n }\n\n public onAuthStateChanged(callback: (cb: any) => void): () => void {\n return onAuthStateChanged(this.auth, callback);\n }\n\n public onIdTokenChanged(callback: (cb: any) => void): () => void {\n return onIdTokenChanged(this.auth, callback);\n }\n\n private async updateCurrentSession(): Promise<void> {\n if (!this._currentUser) {\n this.signedInSession = null;\n return;\n }\n\n try {\n const res = await this._currentUser.getIdTokenResult();\n this.signedInSession = {\n status: 'active',\n token: res.token,\n claims: res.claims,\n issuedAtTime: res.issuedAtTime,\n expirationTime: res.expirationTime,\n authTime: res.authTime,\n signInProvider: res.signInProvider || 'unknown',\n signInSecondFactor: res.signInSecondFactor,\n };\n } catch (error) {\n console.error('[TernSecureAuth] Error updating session:', error);\n this.signedInSession = null;\n }\n }\n\n private checkRedirectResult = async (): Promise<SignInResponse | null> => {\n try {\n const result = await getRedirectResult(this.auth);\n if (result) {\n return {\n status: 'success',\n user: result.user as TernSecureUser,\n };\n }\n return null;\n } catch (error) {\n const authError = handleFirebaseAuthError(error);\n return {\n status: 'error',\n message: authError.message,\n error: authError.code,\n };\n }\n };\n\n public getRedirectResult = async (): Promise<any> => {\n return this.checkRedirectResult();\n };\n\n public addListener = (listener: ListenerCallback): UnsubscribeCallback => {\n this.#listeners.push(listener);\n if (this._currentUser) {\n listener({\n user: this._currentUser,\n session: this.signedInSession,\n });\n }\n\n const unsubscribe = () => {\n this.#listeners = this.#listeners.filter(l => l !== listener);\n };\n return unsubscribe;\n };\n\n public on: TernSecureAuthInterface['on'] = (...args) => {\n this.#publicEventBus.on(...args);\n };\n\n public off: TernSecureAuthInterface['off'] = (...args) => {\n this.#publicEventBus.off(...args);\n };\n\n public createActiveSession: CreateActiveSession = async ({\n session,\n redirectUrl,\n }): Promise<void> => {\n try {\n if (!session) {\n throw new Error('No session provided to createActiveSession');\n }\n const sessionResult = await session.getIdTokenResult();\n const sessionData = new Session(sessionResult);\n await sessionData.create(this.csrfToken || '');\n\n if (redirectUrl) {\n await this.navigate(this.constructUrlWithAuthRedirect(redirectUrl));\n }\n\n this.#setCreatedActiveSession(session);\n this.#emit();\n } catch (error) {\n console.error('[TernSecureAuth] Error creating active session:', error);\n }\n };\n\n public navigate = async (to: string | undefined, options?: NavigateOptions): Promise<unknown> => {\n if (!to || !inBrowser()) {\n return;\n }\n\n let toURL = new URL(to, window.location.href);\n\n if (!this.#allowedRedirectProtocols.includes(toURL.protocol)) {\n console.warn(\n `TernSecureAuth: \"${toURL.protocol}\" is not a valid protocol. Redirecting to \"/\" instead. If you think this is a mistake, please open an issue.`,\n );\n toURL = new URL('/', window.location.href);\n }\n\n const customNavigate =\n options?.replace && this.#options.routerReplace\n ? this.#options.routerReplace\n : this.#options.routerPush;\n\n if ((toURL.origin !== 'null' && toURL.origin !== window.location.origin) || !customNavigate) {\n windowNavigate(toURL);\n return;\n }\n\n const metadata = {\n ...(options?.metadata ? { __internal_metadata: options?.metadata } : {}),\n windowNavigate,\n };\n\n // React router only wants the path, search or hash portion.\n return await customNavigate(stripOrigin(toURL), metadata);\n };\n\n public constructUrlWithAuthRedirect = (to: string): string => {\n if (this.#instanceType === 'production') {\n return to;\n }\n const baseUrl = window.location.origin;\n const url = new URL(to, baseUrl);\n\n if (url.origin === window.location.origin) {\n return url.href;\n }\n\n return url.toString();\n };\n\n #buildUrl = (key: 'signInUrl' | 'signUpUrl', options: RedirectOptions): string => {\n if (!key || !this.isReady) {\n return '';\n }\n\n const baseUrlConfig = key === 'signInUrl' ? this.#options.signInUrl : this.#options.signUpUrl;\n const defaultPagePath = key === 'signInUrl' ? '/sign-in' : '/sign-up';\n const base = baseUrlConfig || defaultPagePath;\n\n const redirectUrls = new RedirectUrls(this.#options, options).toSearchParams();\n const constructedUrl = buildURL(\n {\n base,\n hashSearchParams: [redirectUrls],\n },\n {\n stringify: true,\n skipOrigin: false,\n },\n );\n return this.constructUrlWithAuthRedirect(constructedUrl);\n };\n\n #constructAfterSignInUrl = (): string => {\n return this.constructUrlWithAuthRedirect(new RedirectUrls(this.#options).getAfterSignInUrl());\n };\n\n #constructAfterSignOutUrl = (): string => {\n if (!this.#options.afterSignOutUrl) {\n return '/';\n }\n return this.constructUrlWithAuthRedirect(this.#options.afterSignOutUrl);\n };\n\n public redirectToSignIn = async (options?: SignInRedirectOptions): Promise<unknown> => {\n if (inBrowser()) {\n return this.navigate(this.constructSignInUrl(options));\n }\n return;\n };\n\n public redirectToSignUp = async (options?: SignUpRedirectOptions): Promise<unknown> => {\n if (inBrowser()) {\n return this.navigate(this.constructSignUpUrl());\n }\n return;\n };\n\n public redirectAfterSignIn = async (): Promise<unknown> => {\n if (inBrowser()) {\n return this.navigate(this.#constructAfterSignInUrl());\n }\n return;\n };\n\n redirectAfterSignUp = (): void => {\n throw new Error('redirectAfterSignUp is not implemented yet');\n };\n\n public constructSignInUrl = (options?: SignInRedirectOptions): string => {\n return this.#buildUrl('signInUrl', {\n ...options,\n signInForceRedirectUrl: options?.signInForceRedirectUrl || window.location.href,\n });\n };\n\n public constructSignUpUrl = (options?: SignUpRedirectOptions): string => {\n return this.#buildUrl('signUpUrl', {\n ...options,\n signUpForceRedirectUrl: options?.signUpForceRedirectUrl || window.location.href,\n });\n };\n\n get #allowedRedirectProtocols() {\n let allowedProtocols = ALLOWED_PROTOCOLS;\n\n if (this.#options.allowedRedirectProtocols) {\n allowedProtocols = allowedProtocols.concat(this.#options.allowedRedirectProtocols);\n }\n\n return allowedProtocols;\n }\n\n __internal_setCountry = (country: string | null) => {\n if (!this.__internal_country) {\n this.__internal_country = country;\n }\n };\n\n #initOptions = (options: TernSecureAuthOptions): TernSecureAuthOptions => {\n return {\n ...options,\n };\n };\n\n #emit = (): void => {\n for (const listener of this.#listeners) {\n listener({\n user: this.user,\n session: this.signedInSession,\n });\n }\n };\n\n #setStatus(newStatus: TernSecureAuthStatus): void {\n if (this.#status !== newStatus) {\n this.#status = newStatus;\n this.#publicEventBus.emit(ternEvents.Status, this.#status);\n\n if (newStatus === 'ready') {\n this.#publicEventBus.emit(ternEvents.Status, 'ready');\n }\n }\n }\n\n #setCreatedActiveSession = (session: TernSecureUser | null) => {\n this.user = session;\n };\n\n #setPersistence = () => {\n const persistenceType = this.#options.persistence;\n\n switch (persistenceType) {\n case 'browserCookie':\n return inMemoryPersistence;\n case 'session':\n return browserSessionPersistence;\n case 'local':\n return browserLocalPersistence;\n case 'none':\n default:\n return inMemoryPersistence;\n }\n };\n\n #emulatorHost = (): string | undefined => {\n if (typeof process === 'undefined') return undefined;\n return process.env.FIREBASE_AUTH_EMULATOR_HOST;\n };\n\n #configureEmulator = (): void => {\n const host = this.#emulatorHost();\n const isDev = this.#instanceType === 'development';\n const shouldUseEmulator = isDev && !!host;\n if (!shouldUseEmulator || !host) {\n return;\n }\n\n const emulatorUrl = host.startsWith('http') ? host : `http://${host}`;\n\n try {\n //(this.auth as unknown as any)._canInitEmulator = true;\n connectAuthEmulator(this.auth, emulatorUrl, { disableWarnings: false });\n console.warn(`[TernSecure] Firebase Auth Emulator connected at ${emulatorUrl}`);\n } catch (error) {\n console.error('[TernSecure] Error connecting to Firebase Auth Emulator:', error);\n }\n };\n}\n"],"mappings":"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","names":[]}
@@ -11,7 +11,7 @@ import {
11
11
  import { TernSecureBase } from "./Base";
12
12
  class SignIn extends TernSecureBase {
13
13
  pathRoot = "/sessions/createsession";
14
- status;
14
+ status = null;
15
15
  auth;
16
16
  csrfToken;
17
17
  _currentUser = null;
@@ -74,8 +74,7 @@ class SignIn extends TernSecureBase {
74
74
  if (redirectResult) {
75
75
  return redirectResult;
76
76
  }
77
- await this._signInWithRedirect(provider, options);
78
- return;
77
+ return await this._signInWithRedirect(provider, options);
79
78
  } else {
80
79
  return await this._signInWithPopUp(provider, options);
81
80
  }
@@ -208,19 +207,13 @@ class SignIn extends TernSecureBase {
208
207
  try {
209
208
  const config = this.getProviderConfig(providerName);
210
209
  this.configureProvider(config.provider, options);
211
- const credential = await authMethod(this.auth, config.provider);
212
- if (credential) {
213
- return {
214
- status: "success",
215
- message: "Authentication successful",
216
- user: credential.user,
217
- providerId: credential.providerId,
218
- operationType: credential.operationType
219
- };
220
- }
210
+ const { user, providerId, operationType } = await authMethod(this.auth, config.provider);
221
211
  return {
222
212
  status: "success",
223
- message: "Redirect initiated"
213
+ message: "Authentication successful",
214
+ user,
215
+ providerId,
216
+ operationType
224
217
  };
225
218
  } catch (error) {
226
219
  const authError = handleFirebaseAuthError(error);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/resources/SignIn.ts"],"sourcesContent":["import { handleFirebaseAuthError } from '@tern-secure/shared/errors';\nimport type {\n ResendEmailVerification,\n SignInFormValues,\n SignInResource,\n SignInResponse as SignInResponseFromTypes,\n SignInStatus,\n SocialProviderOptions,\n TernSecureUser,\n} from '@tern-secure/types';\nimport type { Auth, UserCredential } from 'firebase/auth';\nimport {\n getRedirectResult,\n GoogleAuthProvider,\n OAuthProvider,\n sendEmailVerification,\n signInWithEmailAndPassword,\n signInWithPopup,\n signInWithRedirect,\n} from 'firebase/auth';\n\nimport { TernSecureBase } from './Base';\n\ntype SignInResponse = SignInResponseFromTypes;\n\ninterface ProviderConfig {\n provider: GoogleAuthProvider | OAuthProvider;\n //customParameters: Record<string, string>;\n}\n\nexport type TernRequestInit = RequestInit;\n\nexport type SignInParams = {\n idToken: string;\n csrfToken: string | undefined;\n};\n\ntype FirebaseAuthResult = UserCredential | void;\n\ntype AuthMethodFunction = (\n auth: Auth,\n provider: GoogleAuthProvider | OAuthProvider,\n) => Promise<FirebaseAuthResult>;\n\n/**\n * Supported OAuth providers\n */\nexport type SupportedProvider =\n | 'google'\n | 'apple'\n | 'microsoft'\n | 'github'\n | 'twitter'\n | 'facebook'\n | string; // Allow custom providers like 'custom.provider.com'\n\n\nexport class SignIn extends TernSecureBase implements SignInResource {\n pathRoot = '/sessions/createsession';\n\n status?: SignInStatus | undefined;\n private auth: Auth;\n private csrfToken: string | undefined;\n private _currentUser: TernSecureUser | null = null;\n\n constructor(auth: Auth, csrfToken: string | undefined) {\n super();\n this.auth = auth;\n this.csrfToken = csrfToken;\n }\n\n signInWithCredential = async (credential: UserCredential) => {\n const idToken = await credential.user.getIdToken();\n const params = {\n idToken: idToken,\n csrfToken: this.csrfToken,\n };\n\n return this._post({\n path: this.pathRoot,\n body: params,\n });\n };\n\n withEmailAndPassword = async (params: SignInFormValues): Promise<SignInResponse> => {\n try {\n const { email, password } = params;\n const { user, providerId, operationType } = await signInWithEmailAndPassword(\n this.auth,\n email,\n password,\n );\n return {\n status: 'success',\n user,\n providerId,\n operationType,\n message: 'Authentication successful',\n error: !user.emailVerified ? 'REQUIRES_VERIFICATION' : 'AUTHENTICATED',\n };\n } catch (error) {\n const authError = handleFirebaseAuthError(error);\n return {\n status: 'error',\n message: authError.message,\n error: authError.code,\n };\n }\n };\n\n withCredential = async (params: SignInFormValues): Promise<void> => {\n try {\n const { email, password } = params;\n const userCredential = await signInWithEmailAndPassword(this.auth, email, password);\n await this.signInWithCredential(userCredential);\n } catch (error) {\n const authError = handleFirebaseAuthError(error);\n console.error(authError);\n }\n };\n\n withSocialProvider = async (\n provider: SupportedProvider,\n options: SocialProviderOptions = {},\n ): Promise<SignInResponse | void> => {\n try {\n const { mode = 'popup' } = options;\n if (mode === 'redirect') {\n const redirectResult = await this.authRedirectResult();\n\n if (redirectResult) {\n return redirectResult;\n }\n\n await this._signInWithRedirect(provider, options);\n return;\n } else {\n return await this._signInWithPopUp(provider, options);\n }\n } catch (error: any) {\n return {\n status: 'error',\n message: error.message || `Sign in with ${provider} failed`,\n error,\n };\n }\n };\n\n completeMfaSignIn = async (_mfaToken: string, _mfaContext?: any): Promise<SignInResponse> => {\n throw new Error('Method not implemented.');\n };\n\n sendPasswordResetEmail = async (email: string): Promise<void> => {\n console.log(`Sending password reset email to ${email}`);\n };\n\n resendEmailVerification = async (): Promise<ResendEmailVerification> => {\n const user = this._currentUser;\n if (!user) {\n throw new Error('No user is currently signed in');\n }\n\n await user.reload();\n\n if (user.emailVerified) {\n return {\n isVerified: true,\n };\n }\n\n const actionCodeSettings = {\n url: '/sign-in', // TODO: Make this configurable\n handleCodeInApp: true,\n };\n\n await sendEmailVerification(user, actionCodeSettings);\n return {\n isVerified: false,\n };\n };\n\n private getProviderConfig(providerName: SupportedProvider): ProviderConfig {\n switch (providerName.toLowerCase()) {\n case 'google': {\n const googleProvider = new GoogleAuthProvider();\n return { provider: googleProvider };\n }\n case 'apple': {\n const appleProvider = new OAuthProvider('apple.com');\n return { provider: appleProvider };\n }\n case 'microsoft': {\n const microsoftProvider = new OAuthProvider('microsoft.com');\n return { provider: microsoftProvider };\n }\n case 'github': {\n const githubProvider = new OAuthProvider('github.com');\n return { provider: githubProvider };\n }\n case 'twitter': {\n const twitterProvider = new OAuthProvider('twitter.com');\n return { provider: twitterProvider };\n }\n case 'facebook': {\n const facebookProvider = new OAuthProvider('facebook.com');\n return { provider: facebookProvider };\n }\n default:\n throw new Error(`Unsupported provider: ${providerName}`);\n }\n }\n\n private async authRedirectResult(): Promise<SignInResponse | null> {\n try {\n const result = await getRedirectResult(this.auth);\n\n if (result) {\n const { user, providerId, operationType } = result;\n return {\n status: 'success',\n user,\n providerId,\n operationType,\n };\n }\n return null;\n } catch (error) {\n const authError = handleFirebaseAuthError(error);\n return {\n status: 'error',\n message: authError.message,\n error: authError.code,\n };\n }\n }\n\n /**\n * Sets custom OAuth parameters on the provider if provided by consumer\n * @param provider - Firebase auth provider instance\n * @param customParameters - Consumer-provided OAuth parameters\n */\n private setProviderCustomParameters(\n provider: GoogleAuthProvider | OAuthProvider,\n customParameters?: Record<string, string>,\n ): void {\n if (!customParameters || Object.keys(customParameters).length === 0) {\n return;\n }\n\n provider.setCustomParameters(customParameters);\n }\n\n /**\n * Adds OAuth scopes to the provider if provided by consumer\n * Handles provider-specific scope setting logic\n * @param provider - Firebase auth provider instance\n * @param scopes - Array of OAuth scopes to request\n */\n private setProviderScopes(provider: GoogleAuthProvider | OAuthProvider, scopes?: string[]): void {\n if (!scopes || scopes.length === 0) {\n return;\n }\n\n if (provider instanceof GoogleAuthProvider) {\n // Google provider supports individual scope addition\n scopes.forEach(scope => {\n (provider as GoogleAuthProvider).addScope(scope);\n });\n } else if (provider instanceof OAuthProvider) {\n // OAuth providers expect space-separated scope string\n (provider as OAuthProvider).addScope(scopes.join(' '));\n }\n }\n\n /**\n * Configures OAuth provider with consumer-provided options\n * @param provider - Firebase auth provider instance\n * @param options - Consumer options containing custom parameters and scopes\n */\n private configureProvider(\n provider: GoogleAuthProvider | OAuthProvider,\n options: SocialProviderOptions,\n ): void {\n this.setProviderCustomParameters(provider, options.customParameters);\n this.setProviderScopes(provider, options.scopes);\n }\n\n private executeAuthMethod = async (\n authMethod: AuthMethodFunction,\n providerName: SupportedProvider,\n options: SocialProviderOptions = {},\n ): Promise<SignInResponse> => {\n try {\n const config = this.getProviderConfig(providerName);\n\n this.configureProvider(config.provider, options);\n\n const credential = await authMethod(this.auth, config.provider);\n\n if (credential) {\n return {\n status: 'success',\n message: 'Authentication successful',\n user: credential.user,\n providerId: credential.providerId,\n operationType: credential.operationType,\n };\n }\n\n return {\n status: 'success',\n message: 'Redirect initiated',\n };\n } catch (error) {\n const authError = handleFirebaseAuthError(error);\n return {\n status: 'error',\n message: authError.message,\n error: authError.code,\n };\n }\n };\n\n private async _signInWithRedirect(\n providerName: SupportedProvider,\n options: SocialProviderOptions = {},\n ): Promise<SignInResponse> {\n return this.executeAuthMethod(signInWithRedirect, providerName, options);\n }\n\n private async _signInWithPopUp(\n providerName: SupportedProvider,\n options: SocialProviderOptions = {},\n ): Promise<SignInResponse> {\n return this.executeAuthMethod(signInWithPopup, providerName, options);\n }\n\n public async checkRedirectResult(): Promise<SignInResponse | null> {\n return this.authRedirectResult();\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/resources/SignIn.ts"],"sourcesContent":["import { handleFirebaseAuthError } from '@tern-secure/shared/errors';\nimport type {\n ResendEmailVerification,\n SignInFormValues,\n SignInResource,\n SignInResponse as SignInResponseFromTypes,\n SignInStatus,\n SocialProviderOptions,\n TernSecureUser,\n} from '@tern-secure/types';\nimport type { Auth, UserCredential } from 'firebase/auth';\nimport {\n getRedirectResult,\n GoogleAuthProvider,\n OAuthProvider,\n sendEmailVerification,\n signInWithEmailAndPassword,\n signInWithPopup,\n signInWithRedirect,\n} from 'firebase/auth';\n\nimport { TernSecureBase } from './Base';\n\ntype SignInResponse = SignInResponseFromTypes;\n\ninterface ProviderConfig {\n provider: GoogleAuthProvider | OAuthProvider;\n //customParameters: Record<string, string>;\n}\n\nexport type TernRequestInit = RequestInit;\n\nexport type SignInParams = {\n idToken: string;\n csrfToken: string | undefined;\n};\n\ntype FirebaseAuthResult = UserCredential;\n\ntype AuthMethodFunction = (\n auth: Auth,\n provider: GoogleAuthProvider | OAuthProvider,\n) => Promise<FirebaseAuthResult>;\n\n/**\n * Supported OAuth providers\n */\nexport type SupportedProvider =\n | 'google'\n | 'apple'\n | 'microsoft'\n | 'github'\n | 'twitter'\n | 'facebook'\n | string; // Allow custom providers like 'custom.provider.com'\n\nexport class SignIn extends TernSecureBase implements SignInResource {\n pathRoot = '/sessions/createsession';\n\n status: SignInStatus | null = null;\n private auth: Auth;\n private csrfToken: string | undefined;\n private _currentUser: TernSecureUser | null = null;\n\n constructor(auth: Auth, csrfToken: string | undefined) {\n super();\n this.auth = auth;\n this.csrfToken = csrfToken;\n }\n\n signInWithCredential = async (credential: UserCredential) => {\n const idToken = await credential.user.getIdToken();\n const params = {\n idToken: idToken,\n csrfToken: this.csrfToken,\n };\n\n return this._post({\n path: this.pathRoot,\n body: params,\n });\n };\n\n withEmailAndPassword = async (params: SignInFormValues): Promise<SignInResponse> => {\n try {\n const { email, password } = params;\n const { user, providerId, operationType } = await signInWithEmailAndPassword(\n this.auth,\n email,\n password,\n );\n return {\n status: 'success',\n user,\n providerId,\n operationType,\n message: 'Authentication successful',\n error: !user.emailVerified ? 'REQUIRES_VERIFICATION' : 'AUTHENTICATED',\n };\n } catch (error) {\n const authError = handleFirebaseAuthError(error);\n return {\n status: 'error',\n message: authError.message,\n error: authError.code,\n };\n }\n };\n\n withCredential = async (params: SignInFormValues): Promise<void> => {\n try {\n const { email, password } = params;\n const userCredential = await signInWithEmailAndPassword(this.auth, email, password);\n await this.signInWithCredential(userCredential);\n } catch (error) {\n const authError = handleFirebaseAuthError(error);\n console.error(authError);\n }\n };\n\n withSocialProvider = async (\n provider: SupportedProvider,\n options: SocialProviderOptions = {},\n ): Promise<SignInResponse> => {\n try {\n const { mode = 'popup' } = options;\n if (mode === 'redirect') {\n const redirectResult = await this.authRedirectResult();\n\n if (redirectResult) {\n return redirectResult;\n }\n\n return await this._signInWithRedirect(provider, options);\n } else {\n return await this._signInWithPopUp(provider, options);\n }\n } catch (error: any) {\n return {\n status: 'error',\n message: error.message || `Sign in with ${provider} failed`,\n error,\n };\n }\n };\n\n completeMfaSignIn = async (_mfaToken: string, _mfaContext?: any): Promise<SignInResponse> => {\n throw new Error('Method not implemented.');\n };\n\n sendPasswordResetEmail = async (email: string): Promise<void> => {\n console.log(`Sending password reset email to ${email}`);\n };\n\n resendEmailVerification = async (): Promise<ResendEmailVerification> => {\n const user = this._currentUser;\n if (!user) {\n throw new Error('No user is currently signed in');\n }\n\n await user.reload();\n\n if (user.emailVerified) {\n return {\n isVerified: true,\n };\n }\n\n const actionCodeSettings = {\n url: '/sign-in', // TODO: Make this configurable\n handleCodeInApp: true,\n };\n\n await sendEmailVerification(user, actionCodeSettings);\n return {\n isVerified: false,\n };\n };\n\n private getProviderConfig(providerName: SupportedProvider): ProviderConfig {\n switch (providerName.toLowerCase()) {\n case 'google': {\n const googleProvider = new GoogleAuthProvider();\n return { provider: googleProvider };\n }\n case 'apple': {\n const appleProvider = new OAuthProvider('apple.com');\n return { provider: appleProvider };\n }\n case 'microsoft': {\n const microsoftProvider = new OAuthProvider('microsoft.com');\n return { provider: microsoftProvider };\n }\n case 'github': {\n const githubProvider = new OAuthProvider('github.com');\n return { provider: githubProvider };\n }\n case 'twitter': {\n const twitterProvider = new OAuthProvider('twitter.com');\n return { provider: twitterProvider };\n }\n case 'facebook': {\n const facebookProvider = new OAuthProvider('facebook.com');\n return { provider: facebookProvider };\n }\n default:\n throw new Error(`Unsupported provider: ${providerName}`);\n }\n }\n\n private async authRedirectResult(): Promise<SignInResponse | null> {\n try {\n const result = await getRedirectResult(this.auth);\n\n if (result) {\n const { user, providerId, operationType } = result;\n return {\n status: 'success',\n user,\n providerId,\n operationType,\n };\n }\n return null;\n } catch (error) {\n const authError = handleFirebaseAuthError(error);\n return {\n status: 'error',\n message: authError.message,\n error: authError.code,\n };\n }\n }\n\n /**\n * Sets custom OAuth parameters on the provider if provided by consumer\n * @param provider - Firebase auth provider instance\n * @param customParameters - Consumer-provided OAuth parameters\n */\n private setProviderCustomParameters(\n provider: GoogleAuthProvider | OAuthProvider,\n customParameters?: Record<string, string>,\n ): void {\n if (!customParameters || Object.keys(customParameters).length === 0) {\n return;\n }\n\n provider.setCustomParameters(customParameters);\n }\n\n /**\n * Adds OAuth scopes to the provider if provided by consumer\n * Handles provider-specific scope setting logic\n * @param provider - Firebase auth provider instance\n * @param scopes - Array of OAuth scopes to request\n */\n private setProviderScopes(provider: GoogleAuthProvider | OAuthProvider, scopes?: string[]): void {\n if (!scopes || scopes.length === 0) {\n return;\n }\n\n if (provider instanceof GoogleAuthProvider) {\n // Google provider supports individual scope addition\n scopes.forEach(scope => {\n (provider as GoogleAuthProvider).addScope(scope);\n });\n } else if (provider instanceof OAuthProvider) {\n // OAuth providers expect space-separated scope string\n (provider as OAuthProvider).addScope(scopes.join(' '));\n }\n }\n\n /**\n * Configures OAuth provider with consumer-provided options\n * @param provider - Firebase auth provider instance\n * @param options - Consumer options containing custom parameters and scopes\n */\n private configureProvider(\n provider: GoogleAuthProvider | OAuthProvider,\n options: SocialProviderOptions,\n ): void {\n this.setProviderCustomParameters(provider, options.customParameters);\n this.setProviderScopes(provider, options.scopes);\n }\n\n private executeAuthMethod = async (\n authMethod: AuthMethodFunction,\n providerName: SupportedProvider,\n options: SocialProviderOptions = {},\n ): Promise<SignInResponse> => {\n try {\n const config = this.getProviderConfig(providerName);\n\n this.configureProvider(config.provider, options);\n\n const { user, providerId, operationType } = await authMethod(this.auth, config.provider);\n\n return {\n status: 'success',\n message: 'Authentication successful',\n user,\n providerId,\n operationType,\n };\n } catch (error) {\n const authError = handleFirebaseAuthError(error);\n return {\n status: 'error',\n message: authError.message,\n error: authError.code,\n };\n }\n };\n\n private async _signInWithRedirect(\n providerName: SupportedProvider,\n options: SocialProviderOptions = {},\n ): Promise<SignInResponse> {\n return this.executeAuthMethod(signInWithRedirect, providerName, options);\n }\n\n private async _signInWithPopUp(\n providerName: SupportedProvider,\n options: SocialProviderOptions = {},\n ): Promise<SignInResponse> {\n return this.executeAuthMethod(signInWithPopup, providerName, options);\n }\n\n public async checkRedirectResult(): Promise<SignInResponse | null> {\n return this.authRedirectResult();\n }\n}\n"],"mappings":"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","names":[]}
@@ -1,14 +1,43 @@
1
- class SignUp {
1
+ import { handleFirebaseAuthError } from "@tern-secure/shared/errors";
2
+ import { createUserWithEmailAndPassword } from "firebase/auth";
3
+ import { TernSecureBase } from "./Base";
4
+ class SignUp extends TernSecureBase {
2
5
  status = null;
3
6
  username = null;
4
7
  firstName = null;
5
8
  lastName = null;
9
+ displayName = null;
6
10
  email = null;
11
+ phoneNumber = null;
7
12
  auth;
8
- ternSecureConfig;
9
13
  constructor(auth) {
14
+ super();
10
15
  this.auth = auth;
11
16
  }
17
+ withEmailAndPassword = async (params) => {
18
+ try {
19
+ const { email, password } = params;
20
+ const { user, providerId, operationType } = await createUserWithEmailAndPassword(
21
+ this.auth,
22
+ email,
23
+ password
24
+ );
25
+ return {
26
+ status: "complete",
27
+ user,
28
+ providerId,
29
+ operationType,
30
+ message: "User registration successful"
31
+ };
32
+ } catch (error) {
33
+ const authError = handleFirebaseAuthError(error);
34
+ return {
35
+ status: "error",
36
+ message: authError.message,
37
+ error: authError.code
38
+ };
39
+ }
40
+ };
12
41
  withSocialProvider() {
13
42
  throw new Error("Method not implemented.");
14
43
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/resources/SignUp.ts"],"sourcesContent":["import type {\n SignUpResource,\n SignUpStatus,\n TernSecureConfig\n} from '@tern-secure/types';\nimport type { Auth } from 'firebase/auth';\n\nexport class SignUp implements SignUpResource {\n status?: SignUpStatus | null = null;\n username?: string | null = null;\n firstName?: string | null = null;\n lastName?: string | null = null\n email: string | null = null;\n private auth: Auth;\n private ternSecureConfig?: TernSecureConfig;\n\n constructor(auth: Auth) {\n this.auth = auth;\n }\n\n withSocialProvider(): Promise<void> {\n throw new Error('Method not implemented.');\n }\n}"],"mappings":"AAOO,MAAM,OAAiC;AAAA,EAC1C,SAA+B;AAAA,EAC/B,WAA2B;AAAA,EAC3B,YAA4B;AAAA,EAC5B,WAA2B;AAAA,EAC3B,QAAuB;AAAA,EACf;AAAA,EACA;AAAA,EAER,YAAY,MAAY;AACpB,SAAK,OAAO;AAAA,EAChB;AAAA,EAEF,qBAAoC;AAClC,UAAM,IAAI,MAAM,yBAAyB;AAAA,EAC3C;AACF;","names":[]}
1
+ {"version":3,"sources":["../../../src/resources/SignUp.ts"],"sourcesContent":["import { handleFirebaseAuthError } from '@tern-secure/shared/errors';\nimport type {\n SignUpInitialValue,\n SignUpResource,\n SignUpResponse,\n SignUpStatus,\n} from '@tern-secure/types';\nimport type { Auth } from 'firebase/auth';\nimport { createUserWithEmailAndPassword } from 'firebase/auth';\n\nimport { TernSecureBase } from './Base';\n\nexport class SignUp extends TernSecureBase implements SignUpResource {\n status: SignUpStatus | null = null;\n username: string | null = null;\n firstName: string | null = null;\n lastName: string | null = null;\n displayName: string | null = null;\n email: string | null = null;\n phoneNumber: string | null = null;\n private auth: Auth;\n\n constructor(auth: Auth) {\n super();\n this.auth = auth;\n }\n\n withEmailAndPassword = async (params: SignUpInitialValue): Promise<SignUpResponse> => {\n try {\n const { email, password } = params;\n const { user, providerId, operationType } = await createUserWithEmailAndPassword(\n this.auth,\n email,\n password,\n );\n return {\n status: 'complete',\n user,\n providerId,\n operationType,\n message: 'User registration successful',\n };\n } catch (error) {\n const authError = handleFirebaseAuthError(error);\n return {\n status: 'error',\n message: authError.message,\n error: authError.code,\n };\n }\n };\n\n withSocialProvider(): Promise<void> {\n throw new Error('Method not implemented.');\n }\n}\n"],"mappings":"AAAA,SAAS,+BAA+B;AAQxC,SAAS,sCAAsC;AAE/C,SAAS,sBAAsB;AAExB,MAAM,eAAe,eAAyC;AAAA,EACnE,SAA8B;AAAA,EAC9B,WAA0B;AAAA,EAC1B,YAA2B;AAAA,EAC3B,WAA0B;AAAA,EAC1B,cAA6B;AAAA,EAC7B,QAAuB;AAAA,EACvB,cAA6B;AAAA,EACrB;AAAA,EAER,YAAY,MAAY;AACtB,UAAM;AACN,SAAK,OAAO;AAAA,EACd;AAAA,EAEA,uBAAuB,OAAO,WAAwD;AACpF,QAAI;AACF,YAAM,EAAE,OAAO,SAAS,IAAI;AAC5B,YAAM,EAAE,MAAM,YAAY,cAAc,IAAI,MAAM;AAAA,QAChD,KAAK;AAAA,QACL;AAAA,QACA;AAAA,MACF;AACA,aAAO;AAAA,QACL,QAAQ;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,QACA,SAAS;AAAA,MACX;AAAA,IACF,SAAS,OAAO;AACd,YAAM,YAAY,wBAAwB,KAAK;AAC/C,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,SAAS,UAAU;AAAA,QACnB,OAAO,UAAU;AAAA,MACnB;AAAA,IACF;AAAA,EACF;AAAA,EAEA,qBAAoC;AAClC,UAAM,IAAI,MAAM,yBAAyB;AAAA,EAC3C;AACF;","names":[]}
@@ -176,6 +176,7 @@ function hasBannedProtocol(val) {
176
176
  return BANNED_URI_PROTOCOLS.some((bp) => bp === protocol);
177
177
  }
178
178
  const isAllowedRedirect = (allowedRedirectOrigins, currentOrigin) => (_url) => {
179
+ if (!currentOrigin) return true;
179
180
  let url = _url;
180
181
  if (typeof url === "string") {
181
182
  url = relativeToAbsoluteUrl(url, currentOrigin);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/utils/construct.ts"],"sourcesContent":["import { camelToSnake } from '@tern-secure/shared/caseUtils';\nimport { globs } from '@tern-secure/shared/globs';\nimport { logger } from '@tern-secure/shared/logger';\n\nimport { joinPaths } from './path';\nimport { getQueryParams } from './querystring';\n\nconst DUMMY_URL_BASE = 'http://ternsecure-dummy';\n\nconst BANNED_URI_PROTOCOLS = ['javascript:'] as const;\n\nexport type constructUrlWithRedirectProps = {\n signInUrl: string;\n signInPathParam?: string;\n currentPath: string;\n signUpUrl?: string;\n signUpPathParam?: string;\n};\n\ninterface BuildURLParams extends Partial<URL> {\n base?: string;\n hashPath?: string;\n hashSearch?: string;\n hashSearchParams?:\n | URLSearchParams\n | Record<string, string>\n | Array<URLSearchParams | Record<string, string>>;\n}\n\ninterface BuildURLOptions<T> {\n skipOrigin?: boolean;\n stringify?: T;\n}\n\n/**\n *\n * buildURL(params: URLParams, options: BuildURLOptions): string\n *\n * Builds a URL safely by using the native URL() constructor. It can\n * also build a secondary path and search URL that lives inside the hash\n * of the main URL. For example:\n *\n * https://foo.com/bar?qux=42#/hash-bar?hash-qux=42\n *\n * References:\n * https://developer.mozilla.org/en-US/docs/Web/API/URL\n *\n * @param {BuildURLParams} params\n * @param {BuildURLOptions} options\n * @returns {URL | string} Returns the URL href\n */\nexport function buildURL<B extends boolean>(\n params: BuildURLParams,\n options?: BuildURLOptions<B>,\n): B extends true ? string : URL;\n\nexport function buildURL(\n params: BuildURLParams,\n options: BuildURLOptions<boolean> = {},\n): URL | string {\n const { base, hashPath, hashSearch, searchParams, hashSearchParams, ...rest } = params;\n\n let baseFallback = '';\n if (typeof window !== 'undefined' && !!window.location) {\n baseFallback = window.location.href;\n } else {\n baseFallback = 'http://react-native-fake-base-url';\n }\n\n const url = new URL(base || '', baseFallback);\n\n // Handle search parameters\n // params.searchParams comes from Partial<URL>, so it's URLSearchParams | undefined\n if (searchParams instanceof URLSearchParams) {\n searchParams.forEach((value, key) => {\n if (value !== null && value !== undefined) {\n url.searchParams.set(camelToSnake(key), value);\n }\n });\n }\n\n Object.assign(url, rest);\n\n // Handle hash-related parameters\n if (hashPath || hashSearch || hashSearchParams) {\n const dummyUrlForHash = new URL(DUMMY_URL_BASE + url.hash.substring(1));\n\n dummyUrlForHash.pathname = joinPaths(dummyUrlForHash.pathname, hashPath || '');\n\n const searchParamsFromHashSearchString = getQueryParams(hashSearch || '');\n\n for (const [key, val] of Object.entries(searchParamsFromHashSearchString)) {\n dummyUrlForHash.searchParams.append(key, val);\n }\n\n if (hashSearchParams) {\n const paramsArr = Array.isArray(hashSearchParams) ? hashSearchParams : [hashSearchParams];\n for (const _params of paramsArr) {\n if (!(_params instanceof URLSearchParams) && typeof _params !== 'object') {\n continue;\n }\n const params = new URLSearchParams(_params);\n params.forEach((value, key) => {\n if (value !== null && value !== undefined) {\n dummyUrlForHash.searchParams.set(camelToSnake(key), value);\n }\n });\n }\n }\n\n const newHash = dummyUrlForHash.href.replace(DUMMY_URL_BASE, '');\n if (newHash !== '/') {\n // Assign them to the hash of the main url\n url.hash = newHash;\n }\n }\n\n const { stringify, skipOrigin } = options;\n if (stringify) {\n return skipOrigin ? url.href.replace(url.origin, '') : url.href;\n }\n return url;\n}\n\n/**\n * Constructs a full URL with the current origin\n * @param path - The path to construct the URL for\n * @returns The full URL with origin\n */\nexport const constructFullUrl = (path: string) => {\n if (typeof window === 'undefined') return path;\n const baseUrl = window.location.origin;\n if (path.startsWith('http')) {\n return path;\n }\n return `${baseUrl}${path.startsWith('/') ? path : `/${path}`}`;\n};\n\n/**\n * Checks if the current URL has a redirect loop\n * @param currentPath - The current pathname\n * @param redirectPath - The path we're trying to redirect to\n * @returns boolean indicating if there's a redirect loop\n */\nexport const hasRedirectLoop = (currentPath: string, redirectPath: string): boolean => {\n if (!currentPath || !redirectPath) return false;\n\n // Remove any query parameters for comparison\n const cleanCurrentPath = currentPath.split('?')[0];\n const cleanRedirectPath = redirectPath.split('?')[0];\n\n return cleanCurrentPath === cleanRedirectPath;\n};\n\nexport const urlWithRedirect = (options: constructUrlWithRedirectProps): string => {\n const {\n signInUrl,\n signInPathParam = '/sign-in',\n currentPath,\n signUpUrl,\n signUpPathParam = '/sign-up',\n } = options;\n\n const baseUrl = window.location.origin;\n\n if (typeof window === 'undefined') {\n return signInUrl;\n }\n\n const url = new URL(signInUrl, baseUrl);\n\n if (!currentPath.includes(signInPathParam) && !currentPath.includes(signUpPathParam)) {\n url.searchParams.set('redirect', currentPath);\n }\n\n return url.toString();\n};\n\n/**\n * Stores the current path before signing out\n */\nexport const storePreviousPath = (path: string): void => {\n if (typeof window !== 'undefined') {\n sessionStorage.setItem('previousPath', path);\n }\n};\n\n/**\n * Gets the stored previous path\n */\nexport const getPreviousPath = (): string | null => {\n if (typeof window !== 'undefined') {\n return sessionStorage.getItem('previousPath');\n }\n return null;\n};\n\n/**\n * Gets a validated redirect URL ensuring it's from the same origin\n * @param redirectUrl - The URL to validate\n * @param searchParams - The search parameters to check for redirect\n * @returns A validated redirect URL\n */\nexport const getValidRedirectUrl = (\n searchParams: URLSearchParams,\n configuredRedirect?: string,\n): string => {\n // Check URL search param first (highest priority)\n const urlRedirect = searchParams.get('redirect');\n if (urlRedirect) {\n return validateUrl(urlRedirect);\n }\n\n // Then check configured redirect (for first visits)\n if (configuredRedirect) {\n return validateUrl(configuredRedirect);\n }\n\n // Default fallback\n return '/';\n};\n\n/**\n * Validates and sanitizes URLs\n */\nconst validateUrl = (url: string): string => {\n try {\n // For absolute URLs\n if (url.startsWith('http')) {\n const urlObj = new URL(url);\n if (typeof window !== 'undefined' && urlObj.origin !== window.location.origin) {\n return '/';\n }\n }\n\n // For relative URLs\n return '/';\n } catch {\n return '/';\n }\n};\n\nexport function toURL(url: string | URL): URL {\n return new URL(url.toString(), window.location.origin);\n}\n\n/**\n *\n * stripOrigin(url: URL | string): string\n *\n * Strips the origin part of a URL and preserves path, search and hash is applicable\n *\n * References:\n * https://developer.mozilla.org/en-US/docs/Web/API/URL\n *\n * @param {URL | string} url\n * @returns {string} Returns the URL href without the origin\n */\nexport function stripOrigin(url: URL | string): string {\n url = toURL(url);\n return url.href.replace(url.origin, '');\n}\n\n/**\n * trimTrailingSlash(path: string): string\n *\n * Strips the trailing slashes from a string\n *\n * @returns {string} Returns the string without trailing slashes\n * @param path\n */\nexport const trimTrailingSlash = (path: string): string => {\n return (path || '').replace(/\\/+$/, '');\n};\n\nexport function isValidUrl(val: unknown): val is string {\n if (!val) {\n return false;\n }\n\n try {\n new URL(val as string);\n return true;\n } catch {\n return false;\n }\n}\n\nexport function relativeToAbsoluteUrl(url: string, origin: string | URL): URL {\n try {\n return new URL(url);\n } catch {\n return new URL(url, origin);\n }\n}\n\n// Regular expression to detect disallowed patterns\nconst disallowedPatterns = [\n /\\0/, // Null bytes\n /^\\/\\//, // Protocol-relative\n // eslint-disable-next-line no-control-regex\n /[\\x00-\\x1F]/, // Control characters\n];\n\n/**\n * Check for potentially problematic URLs that could have been crafted to intentionally bypass the origin check. Note that the URLs passed to this\n * function are assumed to be from an \"allowed origin\", so we are not executing origin-specific checks here.\n */\nexport function isProblematicUrl(url: URL): boolean {\n if (hasBannedProtocol(url)) {\n return true;\n }\n // Check against disallowed patterns\n for (const pattern of disallowedPatterns) {\n if (pattern.test(url.pathname)) {\n return true;\n }\n }\n\n return false;\n}\n\nexport function hasBannedProtocol(val: string | URL) {\n if (!isValidUrl(val)) {\n return false;\n }\n const protocol = new URL(val).protocol;\n return BANNED_URI_PROTOCOLS.some(bp => bp === protocol);\n}\n\nexport const isAllowedRedirect =\n (allowedRedirectOrigins: Array<string | RegExp> | undefined, currentOrigin: string) =>\n (_url: URL | string) => {\n let url = _url;\n if (typeof url === 'string') {\n url = relativeToAbsoluteUrl(url, currentOrigin);\n }\n\n if (!allowedRedirectOrigins) {\n return true;\n }\n\n const isSameOrigin = currentOrigin === url.origin;\n\n const isAllowed =\n !isProblematicUrl(url) &&\n (isSameOrigin ||\n allowedRedirectOrigins\n .map(origin =>\n typeof origin === 'string' ? globs.toRegexp(trimTrailingSlash(origin)) : origin,\n )\n .some(origin => origin.test(trimTrailingSlash(url.origin))));\n\n if (!isAllowed) {\n logger.warnOnce(\n `Clerk: Redirect URL ${url} is not on one of the allowedRedirectOrigins, falling back to the default redirect URL.`,\n );\n }\n return isAllowed;\n };\n"],"mappings":"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","names":["params"]}
1
+ {"version":3,"sources":["../../../src/utils/construct.ts"],"sourcesContent":["import { camelToSnake } from '@tern-secure/shared/caseUtils';\nimport { globs } from '@tern-secure/shared/globs';\nimport { logger } from '@tern-secure/shared/logger';\n\nimport { joinPaths } from './path';\nimport { getQueryParams } from './querystring';\n\nconst DUMMY_URL_BASE = 'http://ternsecure-dummy';\n\nconst BANNED_URI_PROTOCOLS = ['javascript:'] as const;\n\nexport type constructUrlWithRedirectProps = {\n signInUrl: string;\n signInPathParam?: string;\n currentPath: string;\n signUpUrl?: string;\n signUpPathParam?: string;\n};\n\ninterface BuildURLParams extends Partial<URL> {\n base?: string;\n hashPath?: string;\n hashSearch?: string;\n hashSearchParams?:\n | URLSearchParams\n | Record<string, string>\n | Array<URLSearchParams | Record<string, string>>;\n}\n\ninterface BuildURLOptions<T> {\n skipOrigin?: boolean;\n stringify?: T;\n}\n\n/**\n *\n * buildURL(params: URLParams, options: BuildURLOptions): string\n *\n * Builds a URL safely by using the native URL() constructor. It can\n * also build a secondary path and search URL that lives inside the hash\n * of the main URL. For example:\n *\n * https://foo.com/bar?qux=42#/hash-bar?hash-qux=42\n *\n * References:\n * https://developer.mozilla.org/en-US/docs/Web/API/URL\n *\n * @param {BuildURLParams} params\n * @param {BuildURLOptions} options\n * @returns {URL | string} Returns the URL href\n */\nexport function buildURL<B extends boolean>(\n params: BuildURLParams,\n options?: BuildURLOptions<B>,\n): B extends true ? string : URL;\n\nexport function buildURL(\n params: BuildURLParams,\n options: BuildURLOptions<boolean> = {},\n): URL | string {\n const { base, hashPath, hashSearch, searchParams, hashSearchParams, ...rest } = params;\n\n let baseFallback = '';\n if (typeof window !== 'undefined' && !!window.location) {\n baseFallback = window.location.href;\n } else {\n baseFallback = 'http://react-native-fake-base-url';\n }\n\n const url = new URL(base || '', baseFallback);\n\n // Handle search parameters\n // params.searchParams comes from Partial<URL>, so it's URLSearchParams | undefined\n if (searchParams instanceof URLSearchParams) {\n searchParams.forEach((value, key) => {\n if (value !== null && value !== undefined) {\n url.searchParams.set(camelToSnake(key), value);\n }\n });\n }\n\n Object.assign(url, rest);\n\n // Handle hash-related parameters\n if (hashPath || hashSearch || hashSearchParams) {\n const dummyUrlForHash = new URL(DUMMY_URL_BASE + url.hash.substring(1));\n\n dummyUrlForHash.pathname = joinPaths(dummyUrlForHash.pathname, hashPath || '');\n\n const searchParamsFromHashSearchString = getQueryParams(hashSearch || '');\n\n for (const [key, val] of Object.entries(searchParamsFromHashSearchString)) {\n dummyUrlForHash.searchParams.append(key, val);\n }\n\n if (hashSearchParams) {\n const paramsArr = Array.isArray(hashSearchParams) ? hashSearchParams : [hashSearchParams];\n for (const _params of paramsArr) {\n if (!(_params instanceof URLSearchParams) && typeof _params !== 'object') {\n continue;\n }\n const params = new URLSearchParams(_params);\n params.forEach((value, key) => {\n if (value !== null && value !== undefined) {\n dummyUrlForHash.searchParams.set(camelToSnake(key), value);\n }\n });\n }\n }\n\n const newHash = dummyUrlForHash.href.replace(DUMMY_URL_BASE, '');\n if (newHash !== '/') {\n // Assign them to the hash of the main url\n url.hash = newHash;\n }\n }\n\n const { stringify, skipOrigin } = options;\n if (stringify) {\n return skipOrigin ? url.href.replace(url.origin, '') : url.href;\n }\n return url;\n}\n\n/**\n * Constructs a full URL with the current origin\n * @param path - The path to construct the URL for\n * @returns The full URL with origin\n */\nexport const constructFullUrl = (path: string) => {\n if (typeof window === 'undefined') return path;\n const baseUrl = window.location.origin;\n if (path.startsWith('http')) {\n return path;\n }\n return `${baseUrl}${path.startsWith('/') ? path : `/${path}`}`;\n};\n\n/**\n * Checks if the current URL has a redirect loop\n * @param currentPath - The current pathname\n * @param redirectPath - The path we're trying to redirect to\n * @returns boolean indicating if there's a redirect loop\n */\nexport const hasRedirectLoop = (currentPath: string, redirectPath: string): boolean => {\n if (!currentPath || !redirectPath) return false;\n\n // Remove any query parameters for comparison\n const cleanCurrentPath = currentPath.split('?')[0];\n const cleanRedirectPath = redirectPath.split('?')[0];\n\n return cleanCurrentPath === cleanRedirectPath;\n};\n\nexport const urlWithRedirect = (options: constructUrlWithRedirectProps): string => {\n const {\n signInUrl,\n signInPathParam = '/sign-in',\n currentPath,\n signUpUrl,\n signUpPathParam = '/sign-up',\n } = options;\n\n const baseUrl = window.location.origin;\n\n if (typeof window === 'undefined') {\n return signInUrl;\n }\n\n const url = new URL(signInUrl, baseUrl);\n\n if (!currentPath.includes(signInPathParam) && !currentPath.includes(signUpPathParam)) {\n url.searchParams.set('redirect', currentPath);\n }\n\n return url.toString();\n};\n\n/**\n * Stores the current path before signing out\n */\nexport const storePreviousPath = (path: string): void => {\n if (typeof window !== 'undefined') {\n sessionStorage.setItem('previousPath', path);\n }\n};\n\n/**\n * Gets the stored previous path\n */\nexport const getPreviousPath = (): string | null => {\n if (typeof window !== 'undefined') {\n return sessionStorage.getItem('previousPath');\n }\n return null;\n};\n\n/**\n * Gets a validated redirect URL ensuring it's from the same origin\n * @param redirectUrl - The URL to validate\n * @param searchParams - The search parameters to check for redirect\n * @returns A validated redirect URL\n */\nexport const getValidRedirectUrl = (\n searchParams: URLSearchParams,\n configuredRedirect?: string,\n): string => {\n // Check URL search param first (highest priority)\n const urlRedirect = searchParams.get('redirect');\n if (urlRedirect) {\n return validateUrl(urlRedirect);\n }\n\n // Then check configured redirect (for first visits)\n if (configuredRedirect) {\n return validateUrl(configuredRedirect);\n }\n\n // Default fallback\n return '/';\n};\n\n/**\n * Validates and sanitizes URLs\n */\nconst validateUrl = (url: string): string => {\n try {\n // For absolute URLs\n if (url.startsWith('http')) {\n const urlObj = new URL(url);\n if (typeof window !== 'undefined' && urlObj.origin !== window.location.origin) {\n return '/';\n }\n }\n\n // For relative URLs\n return '/';\n } catch {\n return '/';\n }\n};\n\nexport function toURL(url: string | URL): URL {\n return new URL(url.toString(), window.location.origin);\n}\n\n/**\n *\n * stripOrigin(url: URL | string): string\n *\n * Strips the origin part of a URL and preserves path, search and hash is applicable\n *\n * References:\n * https://developer.mozilla.org/en-US/docs/Web/API/URL\n *\n * @param {URL | string} url\n * @returns {string} Returns the URL href without the origin\n */\nexport function stripOrigin(url: URL | string): string {\n url = toURL(url);\n return url.href.replace(url.origin, '');\n}\n\n/**\n * trimTrailingSlash(path: string): string\n *\n * Strips the trailing slashes from a string\n *\n * @returns {string} Returns the string without trailing slashes\n * @param path\n */\nexport const trimTrailingSlash = (path: string): string => {\n return (path || '').replace(/\\/+$/, '');\n};\n\nexport function isValidUrl(val: unknown): val is string {\n if (!val) {\n return false;\n }\n\n try {\n new URL(val as string);\n return true;\n } catch {\n return false;\n }\n}\n\nexport function relativeToAbsoluteUrl(url: string, origin: string | URL): URL {\n try {\n return new URL(url);\n } catch {\n return new URL(url, origin);\n }\n}\n\n// Regular expression to detect disallowed patterns\nconst disallowedPatterns = [\n /\\0/, // Null bytes\n /^\\/\\//, // Protocol-relative\n // eslint-disable-next-line no-control-regex\n /[\\x00-\\x1F]/, // Control characters\n];\n\n/**\n * Check for potentially problematic URLs that could have been crafted to intentionally bypass the origin check. Note that the URLs passed to this\n * function are assumed to be from an \"allowed origin\", so we are not executing origin-specific checks here.\n */\nexport function isProblematicUrl(url: URL): boolean {\n if (hasBannedProtocol(url)) {\n return true;\n }\n // Check against disallowed patterns\n for (const pattern of disallowedPatterns) {\n if (pattern.test(url.pathname)) {\n return true;\n }\n }\n\n return false;\n}\n\nexport function hasBannedProtocol(val: string | URL) {\n if (!isValidUrl(val)) {\n return false;\n }\n const protocol = new URL(val).protocol;\n return BANNED_URI_PROTOCOLS.some(bp => bp === protocol);\n}\n\nexport const isAllowedRedirect =\n (allowedRedirectOrigins: Array<string | RegExp> | undefined, currentOrigin: string) =>\n (_url: URL | string) => {\n // On server-side (no origin), allow all redirects\n // They will be validated on client-side\n if (!currentOrigin) return true;\n\n let url = _url;\n if (typeof url === 'string') {\n url = relativeToAbsoluteUrl(url, currentOrigin);\n }\n\n if (!allowedRedirectOrigins) {\n return true;\n }\n\n const isSameOrigin = currentOrigin === url.origin;\n\n const isAllowed =\n !isProblematicUrl(url) &&\n (isSameOrigin ||\n allowedRedirectOrigins\n .map(origin =>\n typeof origin === 'string' ? globs.toRegexp(trimTrailingSlash(origin)) : origin,\n )\n .some(origin => origin.test(trimTrailingSlash(url.origin))));\n\n if (!isAllowed) {\n logger.warnOnce(\n `Clerk: Redirect URL ${url} is not on one of the allowedRedirectOrigins, falling back to the default redirect URL.`,\n );\n }\n return isAllowed;\n };\n"],"mappings":"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","names":["params"]}
@@ -117,6 +117,7 @@ class RedirectUrls {
117
117
  }
118
118
  #toAbsoluteUrls(obj) {
119
119
  const origin = typeof window !== "undefined" ? window.location.origin : "";
120
+ if (!origin) return obj;
120
121
  return applyFunctionToObj(obj, (url) => relativeToAbsoluteUrl(url, origin));
121
122
  }
122
123
  #filterRedirects = (obj) => {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/utils/redirectUrls.ts"],"sourcesContent":["import { camelToSnake } from '@tern-secure/shared/caseUtils';\nimport { applyFunctionToObj, filterProps, removeUndefined } from '@tern-secure/shared/object';\nimport type { RedirectOptions, TernSecureAuthOptions } from '@tern-secure/types';\n\nimport { isAllowedRedirect, relativeToAbsoluteUrl } from './construct';\n\n/**\n * RedirectUrls class handles all redirect URL construction logic\n * for sign-in, sign-up, and post-authentication flows.\n *\n * This class centralizes the redirect logic previously scattered across\n * multiple methods, making it reusable and maintainable.\n */\nexport class RedirectUrls {\n private static keys: (keyof RedirectOptions)[] = [\n 'signInForceRedirectUrl',\n 'signInFallbackRedirectUrl',\n 'signUpForceRedirectUrl',\n 'signUpFallbackRedirectUrl',\n 'afterSignInUrl',\n 'afterSignUpUrl',\n 'redirectUrl',\n ];\n\n private static preserved = ['redirectUrl'];\n\n private readonly options: TernSecureAuthOptions;\n private readonly fromOptions: RedirectOptions;\n private readonly fromProps: RedirectOptions;\n private readonly fromSearchParams: RedirectOptions & { redirectUrl?: string | null };\n\n constructor(options: TernSecureAuthOptions, props: RedirectOptions = {}, searchParams: any = {}) {\n this.options = options;\n this.fromOptions = this.#parse(options || {});\n this.fromProps = this.#parse(props || {});\n this.fromSearchParams = this.#parseSearchParams(searchParams || {});\n }\n\n getAfterSignInUrl() {\n return this.#getRedirectUrl('signIn');\n }\n\n getAfterSignUpUrl() {\n return this.#getRedirectUrl('signUp');\n }\n\n getPreservedSearchParams() {\n return this.#toSearchParams(this.#flattenPreserved());\n }\n\n toSearchParams() {\n return this.#toSearchParams(this.#flattenAll());\n }\n\n #toSearchParams(obj: Record<string, string | undefined | null>): URLSearchParams {\n const camelCased = Object.fromEntries(\n Object.entries(obj).map(([key, value]) => [camelToSnake(key), value]),\n );\n return new URLSearchParams(removeUndefined(camelCased) as Record<string, string>);\n }\n\n #flattenPreserved() {\n return Object.fromEntries(\n Object.entries({ ...this.fromSearchParams }).filter(([key]) =>\n RedirectUrls.preserved.includes(key),\n ),\n );\n }\n\n #flattenAll() {\n const signUpForceRedirectUrl =\n this.fromSearchParams.signUpForceRedirectUrl ||\n this.fromProps.signUpForceRedirectUrl ||\n this.fromOptions.signUpForceRedirectUrl;\n const signUpFallbackRedirectUrl =\n this.fromSearchParams.signUpFallbackRedirectUrl ||\n this.fromProps.signUpFallbackRedirectUrl ||\n this.fromOptions.signUpFallbackRedirectUrl;\n const signInForceRedirectUrl =\n this.fromSearchParams.signInForceRedirectUrl ||\n this.fromProps.signInForceRedirectUrl ||\n this.fromOptions.signInForceRedirectUrl;\n const signInFallbackRedirectUrl =\n this.fromSearchParams.signInFallbackRedirectUrl ||\n this.fromProps.signInFallbackRedirectUrl ||\n this.fromOptions.signInFallbackRedirectUrl;\n const afterSignInUrl =\n this.fromSearchParams.afterSignInUrl ||\n this.fromProps.afterSignInUrl ||\n this.fromOptions.afterSignInUrl;\n const afterSignUpUrl =\n this.fromSearchParams.afterSignUpUrl ||\n this.fromProps.afterSignUpUrl ||\n this.fromOptions.afterSignUpUrl;\n const redirectUrl =\n this.fromSearchParams.redirectUrl ||\n this.fromProps.redirectUrl ||\n this.fromOptions.redirectUrl;\n\n const res: RedirectOptions = {\n signUpForceRedirectUrl,\n signUpFallbackRedirectUrl,\n signInForceRedirectUrl,\n signInFallbackRedirectUrl,\n afterSignInUrl,\n afterSignUpUrl,\n redirectUrl,\n };\n return res;\n }\n\n #getRedirectUrl(prefix: 'signIn' | 'signUp') {\n const forceKey = `${prefix}ForceRedirectUrl` as const;\n const fallbackKey = `${prefix}FallbackRedirectUrl` as const;\n\n let newKeyInUse: string | undefined;\n\n let result;\n // Prioritize forceRedirectUrl\n result =\n this.fromSearchParams[forceKey] || this.fromProps[forceKey] || this.fromOptions[forceKey];\n if (result) {\n newKeyInUse = forceKey;\n }\n\n // Try to get redirect_url, only allowed as a search param\n result ||= this.fromSearchParams.redirectUrl;\n if (result) {\n newKeyInUse = 'redirectUrl';\n }\n\n // Otherwise, fallback to fallbackRedirectUrl\n result ||=\n this.fromSearchParams[fallbackKey] ||\n this.fromProps[fallbackKey] ||\n this.fromOptions[fallbackKey];\n if (result) {\n newKeyInUse = fallbackKey;\n }\n\n if (!result) {\n if (typeof window === 'undefined') {\n return '/';\n }\n return window.location.href;\n }\n return result || '/';\n }\n\n #parse(obj: unknown) {\n const res = {} as RedirectOptions;\n RedirectUrls.keys.forEach(key => {\n // @ts-expect-error\n res[key] = obj[key];\n });\n\n //const absoluteUrls = this.#toAbsoluteUrls(filterProps(res, Boolean));\n //const filtered = this.#filterRedirects(absoluteUrls);\n //return applyFunctionToObj(filtered, val => val.toString());\n\n return applyFunctionToObj(\n this.#filterRedirects(this.#toAbsoluteUrls(filterProps(res, Boolean))),\n val => val.toString(),\n );\n }\n\n #parseSearchParams(obj: any) {\n const res = {} as typeof this.fromSearchParams;\n RedirectUrls.keys.forEach(key => {\n if (obj instanceof URLSearchParams) {\n res[key] = obj.get(camelToSnake(key));\n } else {\n res[key] = obj[camelToSnake(key)];\n }\n });\n\n return applyFunctionToObj(\n this.#filterRedirects(this.#toAbsoluteUrls(filterProps(res, Boolean))),\n val => val.toString(),\n );\n }\n\n #toAbsoluteUrls(obj: RedirectOptions) {\n const origin = typeof window !== 'undefined' ? window.location.origin : '';\n return applyFunctionToObj(obj, (url: string) => relativeToAbsoluteUrl(url, origin));\n }\n\n #filterRedirects = (obj: RedirectOptions) => {\n const origin = typeof window !== 'undefined' ? window.location.origin : '';\n return filterProps(obj, isAllowedRedirect(this.options?.allowedRedirectOrigins, origin));\n };\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/utils/redirectUrls.ts"],"sourcesContent":["import { camelToSnake } from '@tern-secure/shared/caseUtils';\nimport { applyFunctionToObj, filterProps, removeUndefined } from '@tern-secure/shared/object';\nimport type { RedirectOptions, TernSecureAuthOptions } from '@tern-secure/types';\n\nimport { isAllowedRedirect, relativeToAbsoluteUrl } from './construct';\n\n/**\n * RedirectUrls class handles all redirect URL construction logic\n * for sign-in, sign-up, and post-authentication flows.\n *\n * This class centralizes the redirect logic previously scattered across\n * multiple methods, making it reusable and maintainable.\n */\nexport class RedirectUrls {\n private static keys: (keyof RedirectOptions)[] = [\n 'signInForceRedirectUrl',\n 'signInFallbackRedirectUrl',\n 'signUpForceRedirectUrl',\n 'signUpFallbackRedirectUrl',\n 'afterSignInUrl',\n 'afterSignUpUrl',\n 'redirectUrl',\n ];\n\n private static preserved = ['redirectUrl'];\n\n private readonly options: TernSecureAuthOptions;\n private readonly fromOptions: RedirectOptions;\n private readonly fromProps: RedirectOptions;\n private readonly fromSearchParams: RedirectOptions & { redirectUrl?: string | null };\n\n constructor(options: TernSecureAuthOptions, props: RedirectOptions = {}, searchParams: any = {}) {\n this.options = options;\n this.fromOptions = this.#parse(options || {});\n this.fromProps = this.#parse(props || {});\n this.fromSearchParams = this.#parseSearchParams(searchParams || {});\n }\n\n getAfterSignInUrl() {\n return this.#getRedirectUrl('signIn');\n }\n\n getAfterSignUpUrl() {\n return this.#getRedirectUrl('signUp');\n }\n\n getPreservedSearchParams() {\n return this.#toSearchParams(this.#flattenPreserved());\n }\n\n toSearchParams() {\n return this.#toSearchParams(this.#flattenAll());\n }\n\n #toSearchParams(obj: Record<string, string | undefined | null>): URLSearchParams {\n const camelCased = Object.fromEntries(\n Object.entries(obj).map(([key, value]) => [camelToSnake(key), value]),\n );\n return new URLSearchParams(removeUndefined(camelCased) as Record<string, string>);\n }\n\n #flattenPreserved() {\n return Object.fromEntries(\n Object.entries({ ...this.fromSearchParams }).filter(([key]) =>\n RedirectUrls.preserved.includes(key),\n ),\n );\n }\n\n #flattenAll() {\n const signUpForceRedirectUrl =\n this.fromSearchParams.signUpForceRedirectUrl ||\n this.fromProps.signUpForceRedirectUrl ||\n this.fromOptions.signUpForceRedirectUrl;\n const signUpFallbackRedirectUrl =\n this.fromSearchParams.signUpFallbackRedirectUrl ||\n this.fromProps.signUpFallbackRedirectUrl ||\n this.fromOptions.signUpFallbackRedirectUrl;\n const signInForceRedirectUrl =\n this.fromSearchParams.signInForceRedirectUrl ||\n this.fromProps.signInForceRedirectUrl ||\n this.fromOptions.signInForceRedirectUrl;\n const signInFallbackRedirectUrl =\n this.fromSearchParams.signInFallbackRedirectUrl ||\n this.fromProps.signInFallbackRedirectUrl ||\n this.fromOptions.signInFallbackRedirectUrl;\n const afterSignInUrl =\n this.fromSearchParams.afterSignInUrl ||\n this.fromProps.afterSignInUrl ||\n this.fromOptions.afterSignInUrl;\n const afterSignUpUrl =\n this.fromSearchParams.afterSignUpUrl ||\n this.fromProps.afterSignUpUrl ||\n this.fromOptions.afterSignUpUrl;\n const redirectUrl =\n this.fromSearchParams.redirectUrl ||\n this.fromProps.redirectUrl ||\n this.fromOptions.redirectUrl;\n\n const res: RedirectOptions = {\n signUpForceRedirectUrl,\n signUpFallbackRedirectUrl,\n signInForceRedirectUrl,\n signInFallbackRedirectUrl,\n afterSignInUrl,\n afterSignUpUrl,\n redirectUrl,\n };\n return res;\n }\n\n #getRedirectUrl(prefix: 'signIn' | 'signUp') {\n const forceKey = `${prefix}ForceRedirectUrl` as const;\n const fallbackKey = `${prefix}FallbackRedirectUrl` as const;\n\n let newKeyInUse: string | undefined;\n\n let result;\n // Prioritize forceRedirectUrl\n result =\n this.fromSearchParams[forceKey] || this.fromProps[forceKey] || this.fromOptions[forceKey];\n if (result) {\n newKeyInUse = forceKey;\n }\n\n // Try to get redirect_url, only allowed as a search param\n result ||= this.fromSearchParams.redirectUrl;\n if (result) {\n newKeyInUse = 'redirectUrl';\n }\n\n // Otherwise, fallback to fallbackRedirectUrl\n result ||=\n this.fromSearchParams[fallbackKey] ||\n this.fromProps[fallbackKey] ||\n this.fromOptions[fallbackKey];\n if (result) {\n newKeyInUse = fallbackKey;\n }\n\n if (!result) {\n if (typeof window === 'undefined') {\n return '/';\n }\n return window.location.href;\n }\n return result || '/';\n }\n\n #parse(obj: unknown) {\n const res = {} as RedirectOptions;\n RedirectUrls.keys.forEach(key => {\n // @ts-expect-error\n res[key] = obj[key];\n });\n\n //const absoluteUrls = this.#toAbsoluteUrls(filterProps(res, Boolean));\n //const filtered = this.#filterRedirects(absoluteUrls);\n //return applyFunctionToObj(filtered, val => val.toString());\n\n return applyFunctionToObj(\n this.#filterRedirects(this.#toAbsoluteUrls(filterProps(res, Boolean))),\n val => val.toString(),\n );\n }\n\n #parseSearchParams(obj: any) {\n const res = {} as typeof this.fromSearchParams;\n RedirectUrls.keys.forEach(key => {\n if (obj instanceof URLSearchParams) {\n res[key] = obj.get(camelToSnake(key));\n } else {\n res[key] = obj[camelToSnake(key)];\n }\n });\n\n return applyFunctionToObj(\n this.#filterRedirects(this.#toAbsoluteUrls(filterProps(res, Boolean))),\n val => val.toString(),\n );\n }\n\n #toAbsoluteUrls(obj: RedirectOptions) {\n const origin = typeof window !== 'undefined' ? window.location.origin : '';\n // If no origin (server-side), return URLs as-is without conversion\n // They will be properly converted on the client-side\n if (!origin) return obj;\n\n return applyFunctionToObj(obj, (url: string) => relativeToAbsoluteUrl(url, origin));\n }\n\n #filterRedirects = (obj: RedirectOptions) => {\n const origin = typeof window !== 'undefined' ? window.location.origin : '';\n return filterProps(obj, isAllowedRedirect(this.options?.allowedRedirectOrigins, origin));\n };\n}\n"],"mappings":"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","names":[]}
@@ -5,6 +5,6 @@ export type { TernServerAuthOptions, AuthenticatedApp } from './instance/TernAut
5
5
  export { CoreApiClient, coreApiClient } from './instance/coreApiClient';
6
6
  export type { ApiResponse, ApiResponseJSON, RequestOptions, BeforeRequestHook, AfterResponseHook } from './instance/coreApiClient';
7
7
  export { SignIn, TernSecureBase, buildURL } from './resources/internal';
8
- export type { AuthErrorTree, TernSecureConfig, SignInFormValues, SignInProps, SignUpProps, SignInResponse, SignInForceRedirectUrl, SignUpForceRedirectUrl, ResendEmailVerification, TernSecureUser, TernSecureState } from '@tern-secure/types';
8
+ export type { AuthErrorTree, TernSecureConfig, SignInFormValues, SignInProps, SignUpProps, SignInResponse, SignInForceRedirectUrl, SignUpForceRedirectUrl, SignInFallbackRedirectUrl, SignUpFallbackRedirectUrl, ResendEmailVerification, TernSecureUser, TernSecureState } from '@tern-secure/types';
9
9
  export { RedirectUrls } from './utils/redirectUrls';
10
10
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,YAAY,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,YAAY,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAEzF,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACxE,YAAY,EACR,WAAW,EACX,eAAe,EACf,cAAc,EACd,iBAAiB,EACjB,iBAAiB,EACpB,MAAM,0BAA0B,CAAC;AAElC,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAExE,YAAY,EACR,aAAa,EACb,gBAAgB,EAChB,gBAAgB,EAChB,WAAW,EACX,WAAW,EACX,cAAc,EACd,sBAAsB,EACtB,sBAAsB,EACtB,uBAAuB,EACvB,cAAc,EACd,eAAe,EAClB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,YAAY,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,YAAY,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAEzF,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACxE,YAAY,EACR,WAAW,EACX,eAAe,EACf,cAAc,EACd,iBAAiB,EACjB,iBAAiB,EACpB,MAAM,0BAA0B,CAAC;AAElC,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAExE,YAAY,EACR,aAAa,EACb,gBAAgB,EAChB,gBAAgB,EAChB,WAAW,EACX,WAAW,EACX,cAAc,EACd,sBAAsB,EACtB,sBAAsB,EACtB,yBAAyB,EACzB,yBAAyB,EACzB,uBAAuB,EACvB,cAAc,EACd,eAAe,EAClB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC"}
@@ -1,4 +1,4 @@
1
- import type { CreateActiveSession, InstanceType, ListenerCallback, NavigateOptions, SessionResource, SignedInSession, SignInRedirectOptions, SignInResource, SignInResponse, SignOut, SignUpRedirectOptions, SignUpResource, TernAuthSDK, TernSecureAuth as TernSecureAuthInterface, TernSecureAuthOptions, TernSecureUser, TernSecureUserData, UnsubscribeCallback } from '@tern-secure/types';
1
+ import type { CreateActiveSession, InstanceType, ListenerCallback, NavigateOptions, SessionResource, SignedInSession, SignInRedirectOptions, SignInResource, SignOut, SignUpRedirectOptions, SignUpResource, TernAuthSDK, TernSecureAuth as TernSecureAuthInterface, TernSecureAuthOptions, TernSecureUser, TernSecureUserData, UnsubscribeCallback } from '@tern-secure/types';
2
2
  import type { Auth as TernAuth } from 'firebase/auth';
3
3
  import { AuthCookieManager } from '../resources/internal';
4
4
  import { type ApiClient } from './c_coreApiClient';
@@ -67,7 +67,7 @@ export declare class TernSecureAuth implements TernSecureAuthInterface {
67
67
  onAuthStateChanged(callback: (cb: any) => void): () => void;
68
68
  onIdTokenChanged(callback: (cb: any) => void): () => void;
69
69
  private updateCurrentSession;
70
- checkRedirectResult(): Promise<SignInResponse | null>;
70
+ private checkRedirectResult;
71
71
  getRedirectResult: () => Promise<any>;
72
72
  addListener: (listener: ListenerCallback) => UnsubscribeCallback;
73
73
  on: TernSecureAuthInterface['on'];