@tern-secure/auth 1.1.0-canary.v20250919134427 → 1.1.0-canary.v20251002175916
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/instance/TernAuth.js +11 -11
- package/dist/cjs/instance/TernAuth.js.map +1 -1
- package/dist/cjs/instance/c_coreApiClient.js +0 -1
- package/dist/cjs/instance/c_coreApiClient.js.map +1 -1
- package/dist/cjs/instance/events.js +1 -1
- package/dist/cjs/instance/events.js.map +1 -1
- package/dist/cjs/resources/Base.js +12 -2
- package/dist/cjs/resources/Base.js.map +1 -1
- package/dist/cjs/resources/SignIn.js +2 -10
- package/dist/cjs/resources/SignIn.js.map +1 -1
- package/dist/esm/instance/TernAuth.js +14 -13
- package/dist/esm/instance/TernAuth.js.map +1 -1
- package/dist/esm/instance/c_coreApiClient.js +0 -1
- package/dist/esm/instance/c_coreApiClient.js.map +1 -1
- package/dist/esm/instance/events.js +1 -1
- package/dist/esm/instance/events.js.map +1 -1
- package/dist/esm/resources/Base.js +13 -3
- package/dist/esm/resources/Base.js.map +1 -1
- package/dist/esm/resources/SignIn.js +2 -10
- package/dist/esm/resources/SignIn.js.map +1 -1
- package/dist/types/instance/TernAuth.d.ts +1 -0
- package/dist/types/instance/TernAuth.d.ts.map +1 -1
- package/dist/types/instance/c_coreApiClient.d.ts.map +1 -1
- package/dist/types/instance/events.d.ts +0 -3
- package/dist/types/instance/events.d.ts.map +1 -1
- package/dist/types/resources/Base.d.ts +2 -1
- package/dist/types/resources/Base.d.ts.map +1 -1
- package/dist/types/resources/SignIn.d.ts +3 -3
- package/dist/types/resources/SignIn.d.ts.map +1 -1
- package/package.json +3 -3
|
@@ -38,10 +38,10 @@ function inBrowser() {
|
|
|
38
38
|
return typeof window !== "undefined";
|
|
39
39
|
}
|
|
40
40
|
class TernSecureAuth {
|
|
41
|
-
static version = "1.1.0-canary.
|
|
41
|
+
static version = "1.1.0-canary.v20251002175916";
|
|
42
42
|
static sdkMetadata = {
|
|
43
43
|
name: "@tern-secure/auth",
|
|
44
|
-
version: "1.1.0-canary.
|
|
44
|
+
version: "1.1.0-canary.v20251002175916",
|
|
45
45
|
environment: process.env.NODE_ENV || "production"
|
|
46
46
|
};
|
|
47
47
|
static instance = null;
|
|
@@ -122,6 +122,9 @@ class TernSecureAuth {
|
|
|
122
122
|
authCookieManager() {
|
|
123
123
|
return this.#authCookieManager;
|
|
124
124
|
}
|
|
125
|
+
_internal_getOption(key) {
|
|
126
|
+
return this.#options[key];
|
|
127
|
+
}
|
|
125
128
|
static getorCreateInstance(options) {
|
|
126
129
|
if (!this.instance) {
|
|
127
130
|
this.instance = new TernSecureAuth(options);
|
|
@@ -153,7 +156,6 @@ class TernSecureAuth {
|
|
|
153
156
|
}
|
|
154
157
|
this.initializeFirebaseApp(this.#options.ternSecureConfig);
|
|
155
158
|
this.authStateUnsubscribe = this.initAuthStateListener();
|
|
156
|
-
this._onIdTokenChanged();
|
|
157
159
|
this.#authCookieManager = new import_internal.AuthCookieManager();
|
|
158
160
|
this.csrfToken = this.#authCookieManager.getCSRFToken();
|
|
159
161
|
this.signIn = new import_internal.SignIn(this.auth, this.csrfToken);
|
|
@@ -172,15 +174,16 @@ class TernSecureAuth {
|
|
|
172
174
|
const appName = config.appName || "[DEFAULT]";
|
|
173
175
|
this.firebaseClientApp = (0, import_app.getApps)().length === 0 ? (0, import_app.initializeApp)(config, appName) : (0, import_app.getApps)()[0];
|
|
174
176
|
const persistence = this.#setPersistence();
|
|
175
|
-
const auth = (0, import_auth.
|
|
176
|
-
persistence
|
|
177
|
-
});
|
|
177
|
+
const auth = (0, import_auth.getAuth)(this.firebaseClientApp);
|
|
178
178
|
this.auth = auth;
|
|
179
179
|
if (config.tenantId) {
|
|
180
180
|
this.auth.tenantId = config.tenantId;
|
|
181
181
|
}
|
|
182
182
|
this.#configureEmulator();
|
|
183
183
|
(0, import_installations.getInstallations)(this.firebaseClientApp);
|
|
184
|
+
(0, import_auth.setPersistence)(this.auth, import_web_extension.browserCookiePersistence).catch((error) => {
|
|
185
|
+
console.error("[TernSecureAuth] Error setting persistence:", error);
|
|
186
|
+
});
|
|
184
187
|
}
|
|
185
188
|
signOut = async (options) => {
|
|
186
189
|
const redirectUrl = (options == null ? void 0 : options.redirectUrl) || this.#constructAfterSignOutUrl();
|
|
@@ -206,7 +209,6 @@ class TernSecureAuth {
|
|
|
206
209
|
await this.auth.authStateReady();
|
|
207
210
|
this._currentUser = user;
|
|
208
211
|
await this.updateCurrentSession();
|
|
209
|
-
import_events.eventBus.emit(import_events.events.UserChanged, this._currentUser);
|
|
210
212
|
this.#emit();
|
|
211
213
|
});
|
|
212
214
|
}
|
|
@@ -215,7 +217,6 @@ class TernSecureAuth {
|
|
|
215
217
|
await this.auth.authStateReady();
|
|
216
218
|
this._currentUser = user;
|
|
217
219
|
await this.updateCurrentSession();
|
|
218
|
-
import_events.eventBus.emit(import_events.events.TokenRefreshed, { token: user ? await user.getIdTokenResult() : null });
|
|
219
220
|
this.#emit();
|
|
220
221
|
});
|
|
221
222
|
}
|
|
@@ -417,7 +418,8 @@ class TernSecureAuth {
|
|
|
417
418
|
if (this._currentUser) {
|
|
418
419
|
for (const listener of this.#listeners) {
|
|
419
420
|
listener({
|
|
420
|
-
user: this._currentUser
|
|
421
|
+
user: this._currentUser,
|
|
422
|
+
session: this.signedInSession
|
|
421
423
|
});
|
|
422
424
|
}
|
|
423
425
|
}
|
|
@@ -434,8 +436,6 @@ class TernSecureAuth {
|
|
|
434
436
|
#setPersistence = () => {
|
|
435
437
|
const persistenceType = this.#options.persistence || "none";
|
|
436
438
|
switch (persistenceType) {
|
|
437
|
-
case "browserCookie":
|
|
438
|
-
return import_web_extension.browserCookiePersistence;
|
|
439
439
|
case "session":
|
|
440
440
|
return import_auth.browserSessionPersistence;
|
|
441
441
|
case "local":
|
|
@@ -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 DomainOrProxyUrl,\n InstanceType,\n ListenerCallback,\n RedirectOptions,\n SignedInSession,\n SignInRedirectOptions,\n SignInResource,\n SignInResponseTree,\n SignOut,\n SignOutOptions,\n SignUpRedirectOptions,\n SignUpResource,\n TernSecureAuth as TernSecureAuthInterface,\n TernSecureAuthOptions,\n TernSecureAuthStatus,\n TernSecureConfig,\n TernSecureResources,\n TernSecureSDK,\n TernSecureUser,\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 browserSessionPersistence,\n connectAuthEmulator,\n getRedirectResult,\n initializeAuth,\n inMemoryPersistence,\n onAuthStateChanged,\n onIdTokenChanged,\n} from 'firebase/auth';\nimport { browserCookiePersistence } from 'firebase/auth/web-extension';\nimport { getInstallations } from 'firebase/installations';\n\nimport { AuthCookieManager, SignIn, SignUp, TernSecureBase } from '../resources/internal';\nimport { buildURL } from '../utils/construct';\nimport { type ApiClient, createCoreApiClient } from './c_coreApiClient';\nimport { eventBus, events } from './events';\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: TernSecureSDK = {\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 = {} as TernSecureAuthOptions;\n #authCookieManager?: AuthCookieManager;\n #publicEventBus = createTernAuthEventBus();\n\n signIn!: SignInResource;\n signUp!: SignUpResource;\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: TernSecureSDK) {\n TernSecureAuth.sdkMetadata = metadata;\n }\n\n get sdkMetadata(): TernSecureSDK {\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 public setLoading(isLoading: boolean): void {\n this.isLoading = isLoading;\n }\n\n public authCookieManager(): AuthCookieManager | undefined {\n return this.#authCookieManager;\n }\n\n static getorCreateInstance(options?: TernSecureAuthOptions): TernSecureAuth {\n if (!this.instance) {\n this.instance = new TernSecureAuth(options);\n }\n //console.log('TernSecureAuth instance:', this.instance);\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 = (options: TernSecureAuthOptions): TernSecureAuth => {\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 this.authStateUnsubscribe = this.initAuthStateListener();\n this._onIdTokenChanged();\n\n this.#authCookieManager = new AuthCookieManager();\n this.csrfToken = this.#authCookieManager.getCSRFToken();\n\n this.signIn = new SignIn(this.auth, this.csrfToken);\n this.signUp = new SignUp(this.auth);\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 });\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 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 if (inBrowser()) {\n window.location.href = redirectUrl;\n }\n eventBus.emit(events.UserSignOut, null);\n eventBus.emit(events.TokenRefreshed, { token: null });\n this.#emit();\n };\n\n get currentSession(): SignedInSession | null {\n return this.signedInSession;\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 await this.updateCurrentSession();\n\n eventBus.emit(events.UserChanged, this._currentUser);\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 await this.updateCurrentSession();\n\n eventBus.emit(events.TokenRefreshed, { token: user ? await user.getIdTokenResult() : null });\n this.#emit();\n });\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 };\n } catch (error) {\n console.error('[TernSecureAuth] Error updating session:', error);\n this.signedInSession = null;\n }\n }\n\n public async checkRedirectResult(): Promise<SignInResponseTree | null> {\n try {\n const result = await getRedirectResult(this.auth);\n if (result) {\n return {\n success: true,\n user: result.user as TernSecureUser,\n };\n }\n return null;\n } catch (error) {\n const authError = handleFirebaseAuthError(error);\n return {\n success: false,\n message: authError.message,\n error: authError.code,\n user: null,\n };\n }\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 initialize(options: TernSecureAuthOptions): Promise<void> {\n this._initialize(options);\n return Promise.resolve();\n }\n\n public static create(options: TernSecureAuthOptions): TernSecureAuth {\n const instance = this.getorCreateInstance();\n instance.initialize(options);\n return instance;\n }\n\n _initialize = (options: TernSecureAuthOptions): void => {\n this.#options = this.#initOptions(options);\n try {\n if (!this.#options.ternSecureConfig) {\n throw new Error('TernSecureConfig is required to initialize TernSecureAuth');\n }\n\n this.initializeFirebaseApp(this.#options.ternSecureConfig);\n\n this.signIn = new SignIn(this.auth, this.csrfToken);\n this.signUp = new SignUp(this.auth);\n\n this.#setStatus('ready');\n } catch (error) {\n this.error = error as Error;\n this.#setStatus('error');\n throw error;\n }\n };\n\n public constructUrlWithAuthRedirect = (to: string): string => {\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 let effectiveRedirectUrl: string | null | undefined;\n\n // Priority 1: Get redirect URL from options (signInForceRedirectUrl or signUpForceRedirectUrl)\n if (key === 'signInUrl' && 'signInForceRedirectUrl' in options) {\n effectiveRedirectUrl = options.signInForceRedirectUrl;\n } else if (key === 'signUpUrl' && 'signUpForceRedirectUrl' in options) {\n effectiveRedirectUrl = options.signUpForceRedirectUrl;\n }\n\n // Priority 2: If no force redirect from options, check 'redirect' param in current URL (only in browser)\n if (!effectiveRedirectUrl && inBrowser()) {\n const currentUrlParams = new URLSearchParams(window.location.search);\n const existingRedirectParam = currentUrlParams.get('redirect_url');\n if (existingRedirectParam) {\n effectiveRedirectUrl = existingRedirectParam;\n }\n }\n\n // Priority 3: If still no redirect URL, fallback to current page's full path (only in browser)\n // This ensures that if the call originates from a page, it attempts to redirect back there by default.\n if (!effectiveRedirectUrl && inBrowser()) {\n effectiveRedirectUrl =\n window.location.pathname + window.location.search + window.location.hash;\n }\n\n if (effectiveRedirectUrl && inBrowser()) {\n let signInPagePath: string | undefined;\n try {\n signInPagePath = this.#options.signInUrl\n ? new URL(this.#options.signInUrl, window.location.origin).pathname\n : defaultPagePath;\n } catch {\n signInPagePath = defaultPagePath;\n }\n\n let signUpPagePath: string | undefined;\n try {\n signUpPagePath = this.#options.signUpUrl\n ? new URL(this.#options.signUpUrl, window.location.origin).pathname\n : key === 'signUpUrl'\n ? defaultPagePath\n : '/sign-in';\n } catch {\n signUpPagePath = key === 'signUpUrl' ? defaultPagePath : '/sign-in';\n }\n\n const redirectTargetObj = new URL(effectiveRedirectUrl, window.location.origin);\n\n if (\n redirectTargetObj.pathname === signInPagePath ||\n redirectTargetObj.pathname === signUpPagePath\n ) {\n // If the intended redirect path is the sign-in or sign-up page itself,\n // change the redirect target to the application root ('/').\n effectiveRedirectUrl = '/';\n }\n }\n\n const paramsForBuildUrl: Parameters<typeof buildURL>[0] = {\n base,\n searchParams: new URLSearchParams(),\n };\n\n if (effectiveRedirectUrl) {\n // Check if a redirect URL was determined\n if (inBrowser()) {\n const absoluteRedirectUrl = new URL(effectiveRedirectUrl, window.location.origin).href;\n paramsForBuildUrl.searchParams?.set('redirect', absoluteRedirectUrl);\n } else {\n // If not in browser, use the effectiveRedirectUrl as is.\n // This assumes it's either absolute or a path the server can interpret.\n paramsForBuildUrl.searchParams?.set('redirect', effectiveRedirectUrl);\n }\n }\n\n const constructedUrl = buildURL(paramsForBuildUrl, {\n stringify: true,\n skipOrigin: false,\n });\n\n if (typeof constructedUrl !== 'string') {\n console.error(\n '[TernSecure] Error: buildURL did not return a string as expected. Falling back to base URL.',\n );\n if (inBrowser()) {\n try {\n return new URL(base, window.location.origin).href;\n } catch {\n return base;\n }\n }\n return base;\n }\n\n return this.constructUrlWithAuthRedirect(constructedUrl);\n };\n\n #constructAfterSignOutUrl = (): string => {\n if (!this.#options.afterSignOutUrl) {\n return '/';\n }\n return this.constructUrlWithAuthRedirect(this.#options.afterSignOutUrl);\n };\n\n public constructSignInUrl = (options?: SignInRedirectOptions): string => {\n return this.#buildUrl('signInUrl', { ...options });\n };\n\n public constructSignUpUrl = (options?: SignUpRedirectOptions): string => {\n return this.#buildUrl('signUpUrl', { ...options });\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 if (this._currentUser) {\n for (const listener of this.#listeners) {\n listener({\n user: this._currentUser,\n });\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 #setPersistence = () => {\n const persistenceType = this.#options.persistence || 'none';\n\n switch (persistenceType) {\n case 'browserCookie':\n return browserCookiePersistence;\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 DomainOrProxyUrl,\n InstanceType,\n ListenerCallback,\n RedirectOptions,\n SignedInSession,\n SignInRedirectOptions,\n SignInResource,\n SignInResponseTree,\n SignOut,\n SignOutOptions,\n SignUpRedirectOptions,\n SignUpResource,\n TernSecureAuth as TernSecureAuthInterface,\n TernSecureAuthOptions,\n TernSecureAuthStatus,\n TernSecureConfig,\n TernSecureResources,\n TernSecureSDK,\n TernSecureUser,\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 browserSessionPersistence,\n connectAuthEmulator,\n getAuth,\n getRedirectResult,\n inMemoryPersistence,\n onAuthStateChanged,\n onIdTokenChanged,\n setPersistence,\n} from 'firebase/auth';\nimport { browserCookiePersistence } from 'firebase/auth/web-extension';\nimport { getInstallations } from 'firebase/installations';\n\nimport { AuthCookieManager, SignIn, SignUp, TernSecureBase } from '../resources/internal';\nimport { buildURL } from '../utils/construct';\nimport { type ApiClient, createCoreApiClient } from './c_coreApiClient';\nimport { eventBus, events } from './events';\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: TernSecureSDK = {\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 = {} as TernSecureAuthOptions;\n #authCookieManager?: AuthCookieManager;\n #publicEventBus = createTernAuthEventBus();\n\n signIn!: SignInResource;\n signUp!: SignUpResource;\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: TernSecureSDK) {\n TernSecureAuth.sdkMetadata = metadata;\n }\n\n get sdkMetadata(): TernSecureSDK {\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 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>(key: K): TernSecureAuthOptions[K] {\n return this.#options[key];\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 = (options: TernSecureAuthOptions): TernSecureAuth => {\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 this.authStateUnsubscribe = this.initAuthStateListener();\n // /this.authStateUnsubscribe = this._onIdTokenChanged();\n\n this.#authCookieManager = new AuthCookieManager();\n this.csrfToken = this.#authCookieManager.getCSRFToken();\n\n this.signIn = new SignIn(this.auth, this.csrfToken);\n this.signUp = new SignUp(this.auth);\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: browserCookiePersistence,\n //});\n\n const auth = getAuth(this.firebaseClientApp);\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 setPersistence(this.auth, browserCookiePersistence).catch(error => {\n console.error('[TernSecureAuth] Error setting persistence:', error);\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 if (inBrowser()) {\n window.location.href = redirectUrl;\n }\n eventBus.emit(events.UserSignOut, null);\n eventBus.emit(events.TokenRefreshed, { token: null });\n this.#emit();\n };\n\n get currentSession(): SignedInSession | null {\n return this.signedInSession;\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 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 await this.updateCurrentSession();\n\n //eventBus.emit(events.TokenRefreshed, { token: user ? await user.getIdTokenResult() : null });\n this.#emit();\n });\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 };\n } catch (error) {\n console.error('[TernSecureAuth] Error updating session:', error);\n this.signedInSession = null;\n }\n }\n\n public async checkRedirectResult(): Promise<SignInResponseTree | null> {\n try {\n const result = await getRedirectResult(this.auth);\n if (result) {\n return {\n success: true,\n user: result.user as TernSecureUser,\n };\n }\n return null;\n } catch (error) {\n const authError = handleFirebaseAuthError(error);\n return {\n success: false,\n message: authError.message,\n error: authError.code,\n user: null,\n };\n }\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 initialize(options: TernSecureAuthOptions): Promise<void> {\n this._initialize(options);\n return Promise.resolve();\n }\n\n public static create(options: TernSecureAuthOptions): TernSecureAuth {\n const instance = this.getorCreateInstance();\n instance.initialize(options);\n return instance;\n }\n\n _initialize = (options: TernSecureAuthOptions): void => {\n this.#options = this.#initOptions(options);\n try {\n if (!this.#options.ternSecureConfig) {\n throw new Error('TernSecureConfig is required to initialize TernSecureAuth');\n }\n\n this.initializeFirebaseApp(this.#options.ternSecureConfig);\n\n this.signIn = new SignIn(this.auth, this.csrfToken);\n this.signUp = new SignUp(this.auth);\n\n this.#setStatus('ready');\n } catch (error) {\n this.error = error as Error;\n this.#setStatus('error');\n throw error;\n }\n };\n\n public constructUrlWithAuthRedirect = (to: string): string => {\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 let effectiveRedirectUrl: string | null | undefined;\n\n // Priority 1: Get redirect URL from options (signInForceRedirectUrl or signUpForceRedirectUrl)\n if (key === 'signInUrl' && 'signInForceRedirectUrl' in options) {\n effectiveRedirectUrl = options.signInForceRedirectUrl;\n } else if (key === 'signUpUrl' && 'signUpForceRedirectUrl' in options) {\n effectiveRedirectUrl = options.signUpForceRedirectUrl;\n }\n\n // Priority 2: If no force redirect from options, check 'redirect' param in current URL (only in browser)\n if (!effectiveRedirectUrl && inBrowser()) {\n const currentUrlParams = new URLSearchParams(window.location.search);\n const existingRedirectParam = currentUrlParams.get('redirect_url');\n if (existingRedirectParam) {\n effectiveRedirectUrl = existingRedirectParam;\n }\n }\n\n // Priority 3: If still no redirect URL, fallback to current page's full path (only in browser)\n // This ensures that if the call originates from a page, it attempts to redirect back there by default.\n if (!effectiveRedirectUrl && inBrowser()) {\n effectiveRedirectUrl =\n window.location.pathname + window.location.search + window.location.hash;\n }\n\n if (effectiveRedirectUrl && inBrowser()) {\n let signInPagePath: string | undefined;\n try {\n signInPagePath = this.#options.signInUrl\n ? new URL(this.#options.signInUrl, window.location.origin).pathname\n : defaultPagePath;\n } catch {\n signInPagePath = defaultPagePath;\n }\n\n let signUpPagePath: string | undefined;\n try {\n signUpPagePath = this.#options.signUpUrl\n ? new URL(this.#options.signUpUrl, window.location.origin).pathname\n : key === 'signUpUrl'\n ? defaultPagePath\n : '/sign-in';\n } catch {\n signUpPagePath = key === 'signUpUrl' ? defaultPagePath : '/sign-in';\n }\n\n const redirectTargetObj = new URL(effectiveRedirectUrl, window.location.origin);\n\n if (\n redirectTargetObj.pathname === signInPagePath ||\n redirectTargetObj.pathname === signUpPagePath\n ) {\n // If the intended redirect path is the sign-in or sign-up page itself,\n // change the redirect target to the application root ('/').\n effectiveRedirectUrl = '/';\n }\n }\n\n const paramsForBuildUrl: Parameters<typeof buildURL>[0] = {\n base,\n searchParams: new URLSearchParams(),\n };\n\n if (effectiveRedirectUrl) {\n // Check if a redirect URL was determined\n if (inBrowser()) {\n const absoluteRedirectUrl = new URL(effectiveRedirectUrl, window.location.origin).href;\n paramsForBuildUrl.searchParams?.set('redirect', absoluteRedirectUrl);\n } else {\n // If not in browser, use the effectiveRedirectUrl as is.\n // This assumes it's either absolute or a path the server can interpret.\n paramsForBuildUrl.searchParams?.set('redirect', effectiveRedirectUrl);\n }\n }\n\n const constructedUrl = buildURL(paramsForBuildUrl, {\n stringify: true,\n skipOrigin: false,\n });\n\n if (typeof constructedUrl !== 'string') {\n console.error(\n '[TernSecure] Error: buildURL did not return a string as expected. Falling back to base URL.',\n );\n if (inBrowser()) {\n try {\n return new URL(base, window.location.origin).href;\n } catch {\n return base;\n }\n }\n return base;\n }\n\n return this.constructUrlWithAuthRedirect(constructedUrl);\n };\n\n #constructAfterSignOutUrl = (): string => {\n if (!this.#options.afterSignOutUrl) {\n return '/';\n }\n return this.constructUrlWithAuthRedirect(this.#options.afterSignOutUrl);\n };\n\n public constructSignInUrl = (options?: SignInRedirectOptions): string => {\n return this.#buildUrl('signInUrl', { ...options });\n };\n\n public constructSignUpUrl = (options?: SignUpRedirectOptions): string => {\n return this.#buildUrl('signUpUrl', { ...options });\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 if (this._currentUser) {\n for (const listener of this.#listeners) {\n listener({\n user: this._currentUser,\n session: this.signedInSession,\n });\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 #setPersistence = () => {\n const persistenceType = this.#options.persistence || 'none';\n\n switch (persistenceType) {\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":[]}
|
|
@@ -184,7 +184,6 @@ function createCoreApiClient(clientOptions) {
|
|
|
184
184
|
const { timeoutMs } = requestOptions;
|
|
185
185
|
const overwrittenRequestMethod = method === "GET" ? "GET" : "POST";
|
|
186
186
|
const url = requestInit.url.toString();
|
|
187
|
-
console.log("Request URL:", url);
|
|
188
187
|
requestInit.headers = new Headers(requestInit.headers);
|
|
189
188
|
if (method !== "GET" && !(body instanceof FormData) && !requestInit.headers.has("content-type")) {
|
|
190
189
|
requestInit.headers.set("content-type", "application/json");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/instance/c_coreApiClient.ts"],"sourcesContent":["import { camelToSnake, jitteredDelay } from '@tern-secure/shared/caseUtils'\nimport type { InstanceType, TernSecureApiErrorJSON } from '@tern-secure/types';\n\nimport { buildURL as buildUrlUtil, stringifyQueryParams } from '../utils';\n\nexport type HTTPMethod =\n | 'CONNECT'\n | 'DELETE'\n | 'GET'\n | 'HEAD'\n | 'OPTIONS'\n | 'PATCH'\n | 'POST'\n | 'PUT'\n | 'TRACE';\n\nexport type ApiRequestInit = RequestInit & {\n path?: string;\n search?: ConstructorParameters<typeof URLSearchParams>[0];\n sessionId?: string;\n url?: URL;\n};\n\nexport interface ApiResponseJSON<T> {\n response: T;\n errors?: TernSecureApiErrorJSON[];\n}\n\nexport type ApiResponse<T> = Response & { payload: ApiResponseJSON<T> | null };\n\nexport type ApiRequestCallback<T> = (request: ApiRequestInit, response?: ApiResponse<T>) => unknown;\n\nexport interface ApiRequestOptions {\n timeoutMs?: number;\n maxTries?: number;\n initialDelay?: number;\n factor?: number;\n maxDelay?: number;\n failureThreshold?: number;\n recoveryTimeoutMs?: number;\n}\n\nexport interface ApiClientOptions {\n domain?: string;\n apiUrl?: string;\n frontendApi?: string;\n instanceType?: InstanceType;\n apiBasePath?: string;\n}\n\nexport interface ApiClient {\n onBeforeRequest: (hook: BeforeRequestHook) => void;\n onAfterResponse: (hook: AfterResponseHook) => void;\n request: <T>(init: ApiRequestInit, opts?: ApiRequestOptions) => Promise<ApiResponse<T>>;\n}\n\nexport type BeforeRequestHook = () => boolean | Promise<boolean>;\nexport type AfterResponseHook = (response: ApiResponse<any>) => boolean | Promise<boolean>;\n\n// Error classes\nexport class NetworkError extends Error {\n constructor(\n public url: string,\n public original: Error,\n ) {\n super(`Network error for ${url}: ${original.message}`);\n this.name = 'NetworkError';\n }\n}\n\nexport class TimeoutError extends Error {\n constructor() {\n super('Request timed out');\n this.name = 'TimeoutError';\n }\n}\n\nexport class CircuitOpenError extends Error {\n constructor() {\n super('Circuit breaker is open');\n this.name = 'CircuitOpenError';\n }\n}\n\nexport class HTTPError extends Error {\n constructor(\n public status: number,\n public url: string,\n public body?: any,\n ) {\n super(`HTTP ${status} error for ${url}`);\n this.name = 'HTTPError';\n }\n}\n\n// Circuit breaker state interface\ninterface CircuitBreakerState {\n failures: number;\n lastFailureTime: number;\n state: 'closed' | 'open' | 'half-open';\n}\n\n// Client state interface\ninterface ClientState {\n circuitBreaker: CircuitBreakerState;\n beforeRequestHooks: BeforeRequestHook[];\n afterResponseHooks: AfterResponseHook[];\n clientOptions: ApiClientOptions;\n}\n\nfunction createInitialState(clientOptions: ApiClientOptions = {}): ClientState {\n return {\n circuitBreaker: {\n failures: 0,\n lastFailureTime: 0,\n state: 'closed',\n },\n beforeRequestHooks: [],\n afterResponseHooks: [],\n clientOptions,\n };\n}\n\nfunction addBeforeRequestHook(state: ClientState, hook: BeforeRequestHook): void {\n state.beforeRequestHooks.push(hook);\n}\n\nfunction addAfterResponseHook(state: ClientState, hook: AfterResponseHook): void {\n state.afterResponseHooks.push(hook);\n}\n\nasync function runBeforeRequestHooks(state: ClientState): Promise<boolean> {\n for (const hook of state.beforeRequestHooks) {\n const result = await hook();\n if (result === false) return false;\n }\n return true;\n}\n\nasync function runAfterResponseHooks(\n state: ClientState,\n response: ApiResponse<any>,\n): Promise<void> {\n for (const hook of state.afterResponseHooks) {\n await hook(response);\n }\n}\n\nfunction checkCircuitBreaker(state: ClientState, requestOptions: ApiRequestOptions): void {\n const { recoveryTimeoutMs = 60000 } = requestOptions;\n const now = Date.now();\n\n if (state.circuitBreaker.state === 'open') {\n if (now - state.circuitBreaker.lastFailureTime >= recoveryTimeoutMs) {\n state.circuitBreaker.state = 'half-open';\n } else {\n throw new CircuitOpenError();\n }\n }\n}\n\nfunction recordSuccess(state: ClientState): void {\n state.circuitBreaker.failures = 0;\n state.circuitBreaker.state = 'closed';\n}\n\nfunction recordFailure(state: ClientState, requestOptions: ApiRequestOptions): void {\n const { failureThreshold = 5 } = requestOptions;\n state.circuitBreaker.failures++;\n state.circuitBreaker.lastFailureTime = Date.now();\n\n if (state.circuitBreaker.failures >= failureThreshold) {\n state.circuitBreaker.state = 'open';\n }\n}\n\nfunction shouldRetry(\n state: ClientState,\n requestOptions: ApiRequestOptions,\n error: any,\n method: string,\n attempt: number,\n maxTries: number,\n): boolean {\n const isRetryable =\n error instanceof NetworkError && method.toUpperCase() === 'GET' && attempt < maxTries;\n\n if (!isRetryable) {\n recordFailure(state, requestOptions);\n }\n\n return isRetryable;\n}\n\nasync function retryWithBackoff<T>(\n state: ClientState,\n requestOptions: ApiRequestOptions,\n attemptFn: () => Promise<T>,\n shouldRetryFn: (error: any, attempt: number) => boolean,\n): Promise<T> {\n const {\n initialDelay = 700,\n factor = 2,\n maxDelay = 5000,\n maxTries = typeof navigator !== 'undefined' && navigator.onLine ? 4 : 11,\n } = requestOptions;\n\n let lastError: any;\n\n for (let attempt = 1; attempt <= maxTries; attempt++) {\n try {\n const result = await attemptFn();\n recordSuccess(state);\n return result;\n } catch (error) {\n lastError = error;\n\n if (!shouldRetryFn(error, attempt)) {\n throw error;\n }\n\n recordFailure(state, requestOptions);\n\n if (attempt < maxTries) {\n const delay = Math.min(initialDelay * Math.pow(factor, attempt - 1), maxDelay);\n await new Promise(resolve => setTimeout(resolve, jitteredDelay(delay)));\n }\n }\n }\n\n throw lastError;\n}\n\nexport function createCoreApiClient(clientOptions: ApiClientOptions): ApiClient {\n function buildUrl(requestInit: ApiRequestInit): URL {\n const isLocalhost = clientOptions.apiUrl?.includes('localhost') || clientOptions.apiUrl?.includes('127.0.0.1');\n const { path } = requestInit;\n const { instanceType, domain, apiUrl, apiBasePath = '/api/auth' } = clientOptions;\n const domainInProd = instanceType === 'production' ? domain : '';\n\n let baseUrl: string;\n if (isLocalhost) {\n // For localhost, use http and the apiUrl directly\n baseUrl = apiUrl?.startsWith('http') ? apiUrl : `http://${apiUrl}`;\n } else {\n //const domainInProd = instanceType === 'production' ? domain : '';\n baseUrl = `https://${domainInProd || apiUrl}`;\n }\n\n const fullPath = `${apiBasePath}/${path}`.replace(/\\/+/g, '/'); \n return buildUrlUtil(\n {\n base: baseUrl,\n pathname: fullPath,\n searchParams: requestInit.search ? new URLSearchParams(requestInit.search) : undefined,\n },\n { stringify: false },\n );\n }\n\n async function makeRequest<T>(\n state: ClientState,\n init: ApiRequestInit,\n opts: ApiRequestOptions = {},\n ): Promise<ApiResponse<T>> {\n const requestInit = { ...init };\n const { method = 'GET', body } = requestInit;\n const requestOptions = { ...opts };\n\n requestInit.url = buildUrl({ ...requestInit });\n checkCircuitBreaker(state, requestOptions);\n\n const shouldContinue = await runBeforeRequestHooks(state);\n if (!shouldContinue) {\n const mockResponse = new Response('{}', {\n status: 200,\n }) as ApiResponse<T>;\n mockResponse.payload = { response: {} as T };\n await runAfterResponseHooks(state, mockResponse);\n return mockResponse;\n }\n\n const { timeoutMs } = requestOptions;\n\n const overwrittenRequestMethod = method === 'GET' ? 'GET' : 'POST';\n const url = requestInit.url.toString();\n\n console.log('Request URL:', url);\n\n requestInit.headers = new Headers(requestInit.headers);\n\n if (\n method !== 'GET' &&\n !(body instanceof FormData) &&\n !requestInit.headers.has('content-type')\n ) {\n requestInit.headers.set('content-type', 'application/json');\n }\n\n if (requestInit.headers.get('content-type') === 'application/x-www-form-urlencoded') {\n requestInit.body = body\n ? stringifyQueryParams(body as any as Record<string, string>, {\n keyEncoder: camelToSnake,\n })\n : body;\n } else if (requestInit.headers.get('content-type') === 'application/json' && body) {\n requestInit.body = typeof body === 'string' ? body : JSON.stringify(body);\n }\n\n const attemptRequest = async (): Promise<ApiResponse<T>> => {\n const controller = new AbortController();\n const timeoutId = timeoutMs\n ? setTimeout(() => {\n controller.abort();\n }, timeoutMs)\n : null;\n\n let response: Response;\n const fetchOpts: ApiRequestInit = {\n ...requestInit,\n credentials: 'include',\n method: overwrittenRequestMethod,\n };\n\n try {\n response = await fetch(url, fetchOpts);\n\n if (timeoutId) clearTimeout(timeoutId);\n\n let payload: ApiResponseJSON<T> | null = null;\n\n if (response.status === 204) {\n payload = null;\n } else {\n try {\n const json = await response.json();\n payload = json;\n } catch {\n payload = { response: {} as T };\n }\n }\n\n const apiResponse = response as ApiResponse<T>;\n apiResponse.payload = payload;\n\n await runAfterResponseHooks(state, apiResponse);\n\n return apiResponse;\n } catch (error: any) {\n if (timeoutId) clearTimeout(timeoutId);\n\n if (error.name === 'AbortError') {\n throw new TimeoutError();\n }\n\n throw new NetworkError(url, error);\n }\n };\n\n return retryWithBackoff(state, requestOptions, attemptRequest, (error, attempt) =>\n shouldRetry(\n state,\n requestOptions,\n error,\n overwrittenRequestMethod,\n attempt,\n requestOptions.maxTries || (typeof navigator !== 'undefined' && navigator.onLine ? 4 : 11),\n ),\n );\n }\n const state = createInitialState(clientOptions);\n\n return {\n onBeforeRequest: (hook: BeforeRequestHook) => addBeforeRequestHook(state, hook),\n onAfterResponse: (hook: AfterResponseHook) => addAfterResponseHook(state, hook),\n request: <T>(init: ApiRequestInit, opts: ApiRequestOptions = {}) =>\n makeRequest<T>(state, init, opts),\n };\n}\n"],"mappings":"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","names":["buildUrlUtil","state"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/instance/c_coreApiClient.ts"],"sourcesContent":["import { camelToSnake, jitteredDelay } from '@tern-secure/shared/caseUtils'\nimport type { InstanceType, TernSecureApiErrorJSON } from '@tern-secure/types';\n\nimport { buildURL as buildUrlUtil, stringifyQueryParams } from '../utils';\n\nexport type HTTPMethod =\n | 'CONNECT'\n | 'DELETE'\n | 'GET'\n | 'HEAD'\n | 'OPTIONS'\n | 'PATCH'\n | 'POST'\n | 'PUT'\n | 'TRACE';\n\nexport type ApiRequestInit = RequestInit & {\n path?: string;\n search?: ConstructorParameters<typeof URLSearchParams>[0];\n sessionId?: string;\n url?: URL;\n};\n\nexport interface ApiResponseJSON<T> {\n response: T;\n errors?: TernSecureApiErrorJSON[];\n}\n\nexport type ApiResponse<T> = Response & { payload: ApiResponseJSON<T> | null };\n\nexport type ApiRequestCallback<T> = (request: ApiRequestInit, response?: ApiResponse<T>) => unknown;\n\nexport interface ApiRequestOptions {\n timeoutMs?: number;\n maxTries?: number;\n initialDelay?: number;\n factor?: number;\n maxDelay?: number;\n failureThreshold?: number;\n recoveryTimeoutMs?: number;\n}\n\nexport interface ApiClientOptions {\n domain?: string;\n apiUrl?: string;\n frontendApi?: string;\n instanceType?: InstanceType;\n apiBasePath?: string;\n}\n\nexport interface ApiClient {\n onBeforeRequest: (hook: BeforeRequestHook) => void;\n onAfterResponse: (hook: AfterResponseHook) => void;\n request: <T>(init: ApiRequestInit, opts?: ApiRequestOptions) => Promise<ApiResponse<T>>;\n}\n\nexport type BeforeRequestHook = () => boolean | Promise<boolean>;\nexport type AfterResponseHook = (response: ApiResponse<any>) => boolean | Promise<boolean>;\n\n// Error classes\nexport class NetworkError extends Error {\n constructor(\n public url: string,\n public original: Error,\n ) {\n super(`Network error for ${url}: ${original.message}`);\n this.name = 'NetworkError';\n }\n}\n\nexport class TimeoutError extends Error {\n constructor() {\n super('Request timed out');\n this.name = 'TimeoutError';\n }\n}\n\nexport class CircuitOpenError extends Error {\n constructor() {\n super('Circuit breaker is open');\n this.name = 'CircuitOpenError';\n }\n}\n\nexport class HTTPError extends Error {\n constructor(\n public status: number,\n public url: string,\n public body?: any,\n ) {\n super(`HTTP ${status} error for ${url}`);\n this.name = 'HTTPError';\n }\n}\n\n// Circuit breaker state interface\ninterface CircuitBreakerState {\n failures: number;\n lastFailureTime: number;\n state: 'closed' | 'open' | 'half-open';\n}\n\n// Client state interface\ninterface ClientState {\n circuitBreaker: CircuitBreakerState;\n beforeRequestHooks: BeforeRequestHook[];\n afterResponseHooks: AfterResponseHook[];\n clientOptions: ApiClientOptions;\n}\n\nfunction createInitialState(clientOptions: ApiClientOptions = {}): ClientState {\n return {\n circuitBreaker: {\n failures: 0,\n lastFailureTime: 0,\n state: 'closed',\n },\n beforeRequestHooks: [],\n afterResponseHooks: [],\n clientOptions,\n };\n}\n\nfunction addBeforeRequestHook(state: ClientState, hook: BeforeRequestHook): void {\n state.beforeRequestHooks.push(hook);\n}\n\nfunction addAfterResponseHook(state: ClientState, hook: AfterResponseHook): void {\n state.afterResponseHooks.push(hook);\n}\n\nasync function runBeforeRequestHooks(state: ClientState): Promise<boolean> {\n for (const hook of state.beforeRequestHooks) {\n const result = await hook();\n if (result === false) return false;\n }\n return true;\n}\n\nasync function runAfterResponseHooks(\n state: ClientState,\n response: ApiResponse<any>,\n): Promise<void> {\n for (const hook of state.afterResponseHooks) {\n await hook(response);\n }\n}\n\nfunction checkCircuitBreaker(state: ClientState, requestOptions: ApiRequestOptions): void {\n const { recoveryTimeoutMs = 60000 } = requestOptions;\n const now = Date.now();\n\n if (state.circuitBreaker.state === 'open') {\n if (now - state.circuitBreaker.lastFailureTime >= recoveryTimeoutMs) {\n state.circuitBreaker.state = 'half-open';\n } else {\n throw new CircuitOpenError();\n }\n }\n}\n\nfunction recordSuccess(state: ClientState): void {\n state.circuitBreaker.failures = 0;\n state.circuitBreaker.state = 'closed';\n}\n\nfunction recordFailure(state: ClientState, requestOptions: ApiRequestOptions): void {\n const { failureThreshold = 5 } = requestOptions;\n state.circuitBreaker.failures++;\n state.circuitBreaker.lastFailureTime = Date.now();\n\n if (state.circuitBreaker.failures >= failureThreshold) {\n state.circuitBreaker.state = 'open';\n }\n}\n\nfunction shouldRetry(\n state: ClientState,\n requestOptions: ApiRequestOptions,\n error: any,\n method: string,\n attempt: number,\n maxTries: number,\n): boolean {\n const isRetryable =\n error instanceof NetworkError && method.toUpperCase() === 'GET' && attempt < maxTries;\n\n if (!isRetryable) {\n recordFailure(state, requestOptions);\n }\n\n return isRetryable;\n}\n\nasync function retryWithBackoff<T>(\n state: ClientState,\n requestOptions: ApiRequestOptions,\n attemptFn: () => Promise<T>,\n shouldRetryFn: (error: any, attempt: number) => boolean,\n): Promise<T> {\n const {\n initialDelay = 700,\n factor = 2,\n maxDelay = 5000,\n maxTries = typeof navigator !== 'undefined' && navigator.onLine ? 4 : 11,\n } = requestOptions;\n\n let lastError: any;\n\n for (let attempt = 1; attempt <= maxTries; attempt++) {\n try {\n const result = await attemptFn();\n recordSuccess(state);\n return result;\n } catch (error) {\n lastError = error;\n\n if (!shouldRetryFn(error, attempt)) {\n throw error;\n }\n\n recordFailure(state, requestOptions);\n\n if (attempt < maxTries) {\n const delay = Math.min(initialDelay * Math.pow(factor, attempt - 1), maxDelay);\n await new Promise(resolve => setTimeout(resolve, jitteredDelay(delay)));\n }\n }\n }\n\n throw lastError;\n}\n\nexport function createCoreApiClient(clientOptions: ApiClientOptions): ApiClient {\n function buildUrl(requestInit: ApiRequestInit): URL {\n const isLocalhost = clientOptions.apiUrl?.includes('localhost') || clientOptions.apiUrl?.includes('127.0.0.1');\n const { path } = requestInit;\n const { instanceType, domain, apiUrl, apiBasePath = '/api/auth' } = clientOptions;\n const domainInProd = instanceType === 'production' ? domain : '';\n\n let baseUrl: string;\n if (isLocalhost) {\n // For localhost, use http and the apiUrl directly\n baseUrl = apiUrl?.startsWith('http') ? apiUrl : `http://${apiUrl}`;\n } else {\n //const domainInProd = instanceType === 'production' ? domain : '';\n baseUrl = `https://${domainInProd || apiUrl}`;\n }\n\n const fullPath = `${apiBasePath}/${path}`.replace(/\\/+/g, '/'); \n return buildUrlUtil(\n {\n base: baseUrl,\n pathname: fullPath,\n searchParams: requestInit.search ? new URLSearchParams(requestInit.search) : undefined,\n },\n { stringify: false },\n );\n }\n\n async function makeRequest<T>(\n state: ClientState,\n init: ApiRequestInit,\n opts: ApiRequestOptions = {},\n ): Promise<ApiResponse<T>> {\n const requestInit = { ...init };\n const { method = 'GET', body } = requestInit;\n const requestOptions = { ...opts };\n\n requestInit.url = buildUrl({ ...requestInit });\n checkCircuitBreaker(state, requestOptions);\n\n const shouldContinue = await runBeforeRequestHooks(state);\n if (!shouldContinue) {\n const mockResponse = new Response('{}', {\n status: 200,\n }) as ApiResponse<T>;\n mockResponse.payload = { response: {} as T };\n await runAfterResponseHooks(state, mockResponse);\n return mockResponse;\n }\n\n const { timeoutMs } = requestOptions;\n\n const overwrittenRequestMethod = method === 'GET' ? 'GET' : 'POST';\n const url = requestInit.url.toString();\n\n requestInit.headers = new Headers(requestInit.headers);\n\n if (\n method !== 'GET' &&\n !(body instanceof FormData) &&\n !requestInit.headers.has('content-type')\n ) {\n requestInit.headers.set('content-type', 'application/json');\n }\n\n if (requestInit.headers.get('content-type') === 'application/x-www-form-urlencoded') {\n requestInit.body = body\n ? stringifyQueryParams(body as any as Record<string, string>, {\n keyEncoder: camelToSnake,\n })\n : body;\n } else if (requestInit.headers.get('content-type') === 'application/json' && body) {\n requestInit.body = typeof body === 'string' ? body : JSON.stringify(body);\n }\n\n const attemptRequest = async (): Promise<ApiResponse<T>> => {\n const controller = new AbortController();\n const timeoutId = timeoutMs\n ? setTimeout(() => {\n controller.abort();\n }, timeoutMs)\n : null;\n\n let response: Response;\n const fetchOpts: ApiRequestInit = {\n ...requestInit,\n credentials: 'include',\n method: overwrittenRequestMethod,\n };\n\n try {\n response = await fetch(url, fetchOpts);\n\n if (timeoutId) clearTimeout(timeoutId);\n\n let payload: ApiResponseJSON<T> | null = null;\n\n if (response.status === 204) {\n payload = null;\n } else {\n try {\n const json = await response.json();\n payload = json;\n } catch {\n payload = { response: {} as T };\n }\n }\n\n const apiResponse = response as ApiResponse<T>;\n apiResponse.payload = payload;\n\n await runAfterResponseHooks(state, apiResponse);\n\n return apiResponse;\n } catch (error: any) {\n if (timeoutId) clearTimeout(timeoutId);\n\n if (error.name === 'AbortError') {\n throw new TimeoutError();\n }\n\n throw new NetworkError(url, error);\n }\n };\n\n return retryWithBackoff(state, requestOptions, attemptRequest, (error, attempt) =>\n shouldRetry(\n state,\n requestOptions,\n error,\n overwrittenRequestMethod,\n attempt,\n requestOptions.maxTries || (typeof navigator !== 'undefined' && navigator.onLine ? 4 : 11),\n ),\n );\n }\n const state = createInitialState(clientOptions);\n\n return {\n onBeforeRequest: (hook: BeforeRequestHook) => addBeforeRequestHook(state, hook),\n onAfterResponse: (hook: AfterResponseHook) => addAfterResponseHook(state, hook),\n request: <T>(init: ApiRequestInit, opts: ApiRequestOptions = {}) =>\n makeRequest<T>(state, init, opts),\n };\n}\n"],"mappings":"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","names":["buildUrlUtil","state"]}
|
|
@@ -24,7 +24,7 @@ __export(events_exports, {
|
|
|
24
24
|
module.exports = __toCommonJS(events_exports);
|
|
25
25
|
var import_eventBus = require("@tern-secure/shared/eventBus");
|
|
26
26
|
const events = {
|
|
27
|
-
UserChanged: "user:userChanged",
|
|
27
|
+
//UserChanged: "user:userChanged",
|
|
28
28
|
UserSignOut: "user:userSignOut",
|
|
29
29
|
SessionChanged: "session:sessionChanged",
|
|
30
30
|
TokenRefreshed: "token:tokenRefreshed"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/instance/events.ts"],"sourcesContent":["import { createEventBus } from \"@tern-secure/shared/eventBus\";\
|
|
1
|
+
{"version":3,"sources":["../../../src/instance/events.ts"],"sourcesContent":["import { createEventBus } from \"@tern-secure/shared/eventBus\";\n//import type { TernSecureUser } from \"@tern-secure/types\";\nimport type { IdTokenResult } from \"firebase/auth\";\n\nexport const events = {\n //UserChanged: \"user:userChanged\",\n UserSignOut: \"user:userSignOut\",\n SessionChanged: \"session:sessionChanged\",\n TokenRefreshed: \"token:tokenRefreshed\",\n} as const;\n\ntype TokenUpdatePayload = { token: IdTokenResult | null };\n\n\ntype InternalEvents = {\n //[events.UserChanged]: TernSecureUser | null;\n [events.UserSignOut]: null;\n [events.SessionChanged]: null;\n [events.TokenRefreshed]: TokenUpdatePayload;\n};\n\nexport const eventBus = createEventBus<InternalEvents>();\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,sBAA+B;AAIxB,MAAM,SAAS;AAAA;AAAA,EAEpB,aAAa;AAAA,EACb,gBAAgB;AAAA,EAChB,gBAAgB;AAClB;AAYO,MAAM,eAAW,gCAA+B;","names":[]}
|
|
@@ -44,11 +44,16 @@ class TernSecureBase {
|
|
|
44
44
|
try {
|
|
45
45
|
apiResponse = await TernSecureBase.apiClient.request(requestInit, { timeoutMs: 1e4 });
|
|
46
46
|
} catch (error) {
|
|
47
|
-
if (
|
|
47
|
+
if (this.shouldRethrowofflineNetworkError()) {
|
|
48
|
+
throw new import_Error.TernSecureRuntimeError((error == null ? void 0 : error.message) || String(error), {
|
|
49
|
+
code: "OFFLINE_NETWORK_ERROR"
|
|
50
|
+
});
|
|
51
|
+
} else if (!(0, import_browser.isValidBrowserOnline)()) {
|
|
48
52
|
console.warn(error);
|
|
49
53
|
return null;
|
|
54
|
+
} else {
|
|
55
|
+
throw error;
|
|
50
56
|
}
|
|
51
|
-
throw error;
|
|
52
57
|
}
|
|
53
58
|
const { payload, status, statusText, headers } = apiResponse;
|
|
54
59
|
if (headers) {
|
|
@@ -112,6 +117,11 @@ class TernSecureBase {
|
|
|
112
117
|
async makeApiRequest(requestInit) {
|
|
113
118
|
return this.fetchFromCoreApi(requestInit);
|
|
114
119
|
}
|
|
120
|
+
static shouldRethrowofflineNetworkError() {
|
|
121
|
+
var _a, _b;
|
|
122
|
+
const experimental = (_b = (_a = TernSecureBase.ternsecure) == null ? void 0 : _a._internal_getOption) == null ? void 0 : _b.call(_a, "experimental");
|
|
123
|
+
return (experimental == null ? void 0 : experimental.rethrowOfflineNetworkErrors) || false;
|
|
124
|
+
}
|
|
115
125
|
}
|
|
116
126
|
// Annotate the CommonJS export names for ESM import in node:
|
|
117
127
|
0 && (module.exports = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/resources/Base.ts"],"sourcesContent":["import { isValidBrowserOnline } from '@tern-secure/shared/browser';\nimport type { TernSecureApiErrorJSON } from '@tern-secure/types';\n\nimport type { ApiRequestInit, ApiResponse, ApiResponseJSON } from '../instance/coreApiClient';\n//import { coreApiClient} from '../instance/coreApiClient';\nimport { TernSecureAPIResponseError } from './Error';\nimport type { AuthCookieManager,TernSecureAuth } from './internal';\n\nexport type HTTPMethod =\n | 'CONNECT'\n | 'DELETE'\n | 'GET'\n | 'HEAD'\n | 'OPTIONS'\n | 'PATCH'\n | 'POST'\n | 'PUT'\n | 'TRACE';\n\nexport type PostMutateParams = {\n action?: string | undefined;\n body?: any;\n method?: HTTPMethod | undefined;\n path?: string;\n};\n\nexport abstract class TernSecureBase {\n static ternsecure: TernSecureAuth;\n\n static get apiClient() {\n return TernSecureBase.ternsecure.getApiClient();\n }\n\n static get authCookieManager(): AuthCookieManager | undefined {\n return this.ternsecure.authCookieManager();\n }\n protected get authCookieManager(): AuthCookieManager | undefined {\n return TernSecureBase.authCookieManager;\n }\n\n /**\n * Core method to fetch data from API endpoints using coreApiClient\n * This method handles the complete request lifecycle including error handling\n */\n static async fetchFromCoreApi(requestInit: ApiRequestInit): Promise<ApiResponseJSON<
|
|
1
|
+
{"version":3,"sources":["../../../src/resources/Base.ts"],"sourcesContent":["import { isValidBrowserOnline } from '@tern-secure/shared/browser';\nimport type { TernSecureApiErrorJSON } from '@tern-secure/types';\n\nimport type { ApiRequestInit, ApiResponse, ApiResponseJSON } from '../instance/coreApiClient';\n//import { coreApiClient} from '../instance/coreApiClient';\nimport { TernSecureAPIResponseError, TernSecureRuntimeError } from './Error';\nimport type { AuthCookieManager, TernSecureAuth } from './internal';\n\nexport type HTTPMethod =\n | 'CONNECT'\n | 'DELETE'\n | 'GET'\n | 'HEAD'\n | 'OPTIONS'\n | 'PATCH'\n | 'POST'\n | 'PUT'\n | 'TRACE';\n\nexport type PostMutateParams = {\n action?: string | undefined;\n body?: any;\n method?: HTTPMethod | undefined;\n path?: string;\n};\n\nexport abstract class TernSecureBase {\n static ternsecure: TernSecureAuth;\n\n static get apiClient() {\n return TernSecureBase.ternsecure.getApiClient();\n }\n\n static get authCookieManager(): AuthCookieManager | undefined {\n return this.ternsecure.authCookieManager();\n }\n protected get authCookieManager(): AuthCookieManager | undefined {\n return TernSecureBase.authCookieManager;\n }\n\n /**\n * Core method to fetch data from API endpoints using coreApiClient\n * This method handles the complete request lifecycle including error handling\n */\n protected static async fetchFromCoreApi<J>(\n requestInit: ApiRequestInit,\n ): Promise<ApiResponseJSON<J> | null> {\n let apiResponse: ApiResponse<J>;\n try {\n apiResponse = await TernSecureBase.apiClient.request<J>(requestInit, { timeoutMs: 10000 });\n } catch (error) {\n if (this.shouldRethrowofflineNetworkError()) {\n throw new TernSecureRuntimeError((error as Error)?.message || String(error), {\n code: 'OFFLINE_NETWORK_ERROR',\n });\n } else if (!isValidBrowserOnline()) {\n console.warn(error);\n return null;\n } else {\n throw error;\n }\n }\n\n const { payload, status, statusText, headers } = apiResponse;\n\n if (headers) {\n const country = headers.get('x-country');\n this.ternsecure.__internal_setCountry(country ? country.toLowerCase() : null);\n }\n\n if (status >= 200 && status <= 299) {\n return payload;\n }\n\n if (status >= 400) {\n const errors = payload?.errors as TernSecureApiErrorJSON[];\n const message = errors?.[0]?.message;\n\n const apiResponseOptions: ConstructorParameters<typeof TernSecureAPIResponseError>[1] = {\n data: errors,\n status,\n };\n if (status === 429 && headers) {\n const retryAfter = headers.get('retry-After');\n if (retryAfter) {\n const value = parseInt(retryAfter, 10);\n if (!isNaN(value)) {\n apiResponseOptions.retryAfter = value;\n }\n }\n }\n\n throw new TernSecureAPIResponseError(message || statusText, apiResponseOptions);\n }\n\n return null;\n }\n\n /**\n * Convenience method for making POST requests\n */\n static async basePost(params: PostMutateParams): Promise<ApiResponseJSON<any> | null> {\n return this.fetchFromCoreApi({ ...params, method: 'POST' });\n }\n\n /**\n * Instance method to fetch data from API endpoints\n */\n protected async fetchFromCoreApi(\n requestInit: ApiRequestInit,\n ): Promise<ApiResponseJSON<any> | null> {\n return TernSecureBase.fetchFromCoreApi(requestInit);\n }\n\n /**\n * Instance method for making POST requests\n */\n protected async basePost(params: PostMutateParams): Promise<ApiResponseJSON<any> | null> {\n return TernSecureBase.basePost(params);\n }\n\n /**\n * Protected instance method for making POST requests with specific path and body\n * This is designed to be used by child classes like SignIn\n */\n protected async _post(params: PostMutateParams): Promise<ApiResponseJSON<any> | null> {\n return this.basePost({\n path: params.path,\n body: params.body,\n });\n }\n\n static async makeApiRequest(requestInit: ApiRequestInit): Promise<ApiResponseJSON<any> | null> {\n return this.fetchFromCoreApi(requestInit);\n }\n\n protected async makeApiRequest(\n requestInit: ApiRequestInit,\n ): Promise<ApiResponseJSON<any> | null> {\n return this.fetchFromCoreApi(requestInit);\n }\n\n private static shouldRethrowofflineNetworkError(): boolean {\n const experimental = TernSecureBase.ternsecure?._internal_getOption?.('experimental');\n return experimental?.rethrowOfflineNetworkErrors || false;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qBAAqC;AAKrC,mBAAmE;AAqB5D,MAAe,eAAe;AAAA,EACnC,OAAO;AAAA,EAEP,WAAW,YAAY;AACrB,WAAO,eAAe,WAAW,aAAa;AAAA,EAChD;AAAA,EAEA,WAAW,oBAAmD;AAC5D,WAAO,KAAK,WAAW,kBAAkB;AAAA,EAC3C;AAAA,EACA,IAAc,oBAAmD;AAC/D,WAAO,eAAe;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,aAAuB,iBACrB,aACoC;AA9CxC;AA+CI,QAAI;AACJ,QAAI;AACF,oBAAc,MAAM,eAAe,UAAU,QAAW,aAAa,EAAE,WAAW,IAAM,CAAC;AAAA,IAC3F,SAAS,OAAO;AACd,UAAI,KAAK,iCAAiC,GAAG;AAC3C,cAAM,IAAI,qCAAwB,+BAAiB,YAAW,OAAO,KAAK,GAAG;AAAA,UAC3E,MAAM;AAAA,QACR,CAAC;AAAA,MACH,WAAW,KAAC,qCAAqB,GAAG;AAClC,gBAAQ,KAAK,KAAK;AAClB,eAAO;AAAA,MACT,OAAO;AACL,cAAM;AAAA,MACR;AAAA,IACF;AAEA,UAAM,EAAE,SAAS,QAAQ,YAAY,QAAQ,IAAI;AAEjD,QAAI,SAAS;AACX,YAAM,UAAU,QAAQ,IAAI,WAAW;AACvC,WAAK,WAAW,sBAAsB,UAAU,QAAQ,YAAY,IAAI,IAAI;AAAA,IAC9E;AAEA,QAAI,UAAU,OAAO,UAAU,KAAK;AAClC,aAAO;AAAA,IACT;AAEA,QAAI,UAAU,KAAK;AACjB,YAAM,SAAS,mCAAS;AACxB,YAAM,WAAU,sCAAS,OAAT,mBAAa;AAE7B,YAAM,qBAAkF;AAAA,QACtF,MAAM;AAAA,QACN;AAAA,MACF;AACA,UAAI,WAAW,OAAO,SAAS;AAC7B,cAAM,aAAa,QAAQ,IAAI,aAAa;AAC5C,YAAI,YAAY;AACd,gBAAM,QAAQ,SAAS,YAAY,EAAE;AACrC,cAAI,CAAC,MAAM,KAAK,GAAG;AACjB,+BAAmB,aAAa;AAAA,UAClC;AAAA,QACF;AAAA,MACF;AAEA,YAAM,IAAI,wCAA2B,WAAW,YAAY,kBAAkB;AAAA,IAChF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,aAAa,SAAS,QAAgE;AACpF,WAAO,KAAK,iBAAiB,EAAE,GAAG,QAAQ,QAAQ,OAAO,CAAC;AAAA,EAC5D;AAAA;AAAA;AAAA;AAAA,EAKA,MAAgB,iBACd,aACsC;AACtC,WAAO,eAAe,iBAAiB,WAAW;AAAA,EACpD;AAAA;AAAA;AAAA;AAAA,EAKA,MAAgB,SAAS,QAAgE;AACvF,WAAO,eAAe,SAAS,MAAM;AAAA,EACvC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAgB,MAAM,QAAgE;AACpF,WAAO,KAAK,SAAS;AAAA,MACnB,MAAM,OAAO;AAAA,MACb,MAAM,OAAO;AAAA,IACf,CAAC;AAAA,EACH;AAAA,EAEA,aAAa,eAAe,aAAmE;AAC7F,WAAO,KAAK,iBAAiB,WAAW;AAAA,EAC1C;AAAA,EAEA,MAAgB,eACd,aACsC;AACtC,WAAO,KAAK,iBAAiB,WAAW;AAAA,EAC1C;AAAA,EAEA,OAAe,mCAA4C;AA9I7D;AA+II,UAAM,gBAAe,0BAAe,eAAf,mBAA2B,wBAA3B,4BAAiD;AACtE,YAAO,6CAAc,gCAA+B;AAAA,EACtD;AACF;","names":[]}
|
|
@@ -49,11 +49,7 @@ class SignIn extends import_Base.TernSecureBase {
|
|
|
49
49
|
withEmailAndPassword = async (params) => {
|
|
50
50
|
try {
|
|
51
51
|
const { email, password } = params;
|
|
52
|
-
const userCredential = await (0, import_auth.signInWithEmailAndPassword)(
|
|
53
|
-
this.auth,
|
|
54
|
-
email,
|
|
55
|
-
password
|
|
56
|
-
);
|
|
52
|
+
const userCredential = await (0, import_auth.signInWithEmailAndPassword)(this.auth, email, password);
|
|
57
53
|
await this.signInWithCredential(userCredential);
|
|
58
54
|
const { user } = userCredential;
|
|
59
55
|
return {
|
|
@@ -75,11 +71,7 @@ class SignIn extends import_Base.TernSecureBase {
|
|
|
75
71
|
withCredential = async (params) => {
|
|
76
72
|
try {
|
|
77
73
|
const { email, password } = params;
|
|
78
|
-
const userCredential = await (0, import_auth.signInWithEmailAndPassword)(
|
|
79
|
-
this.auth,
|
|
80
|
-
email,
|
|
81
|
-
password
|
|
82
|
-
);
|
|
74
|
+
const userCredential = await (0, import_auth.signInWithEmailAndPassword)(this.auth, email, password);
|
|
83
75
|
await this.signInWithCredential(userCredential);
|
|
84
76
|
} catch (error) {
|
|
85
77
|
const authError = (0, import_errors.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 SignInFormValuesTree,\n SignInResource,\n SignInResponseTree,\n SignInStatus,\n TernSecureUser,\n} from \"@tern-secure/types\";\nimport type {\n Auth,\n 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\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\n\n\ntype FirebaseAuthResult = UserCredential | void;\n\ntype AuthMethodFunction = (\n auth: Auth,\n provider: GoogleAuthProvider | OAuthProvider\n) => Promise<FirebaseAuthResult>;\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\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 \n\n\n withEmailAndPassword = async (\n params: SignInFormValuesTree\n ): Promise<SignInResponseTree> => {\n try {\n const { email, password } = params;\n const userCredential = await signInWithEmailAndPassword(\n this.auth,\n email,\n password\n );\n \n await this.signInWithCredential(userCredential);\n\n const { user } = userCredential;\n return {\n success: true,\n message: \"Authentication successful\",\n user,\n error: !user.emailVerified ? \"REQUIRES_VERIFICATION\" : \"AUTHENTICATED\",\n };\n } catch (error) {\n const authError = handleFirebaseAuthError(error);\n return {\n success: false,\n message: authError.message,\n error: authError.code,\n user: null,\n };\n }\n };\n\n withCredential = async (params: SignInFormValuesTree): Promise<void> => {\n try {\n const { email, password } = params;\n const userCredential = await signInWithEmailAndPassword(\n this.auth,\n email,\n password\n );\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: string,\n options?: {\n mode?: \"popup\" | \"redirect\";\n }\n ): Promise<SignInResponseTree | void> => {\n try {\n if (options?.mode === \"redirect\") {\n const redirectResult = await this.authRedirectResult();\n\n if (redirectResult) {\n if (redirectResult.success) {\n console.log(\"Redirect after sign in\");\n }\n return redirectResult;\n }\n\n await this._signInWithRedirect(provider);\n return;\n } else {\n await this._signInWithPopUp(provider);\n return {\n success: true,\n message: \"Sign in successful\",\n };\n }\n } catch (error: any) {\n return {\n success: false,\n message: error.message || `Sign in with ${provider} failed`,\n error,\n user: null,\n };\n }\n };\n\n completeMfaSignIn = async (\n _mfaToken: string,\n _mfaContext?: any\n ): Promise<SignInResponseTree> => {\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 success: true,\n message: \"Email is already verified. You can sign in.\",\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 success: true,\n message: \"Verification email sent. Please check your inbox.\",\n isVerified: false,\n };\n };\n\n private getProviderConfig(providerName: string): ProviderConfig {\n switch (providerName.toLowerCase()) {\n case \"google\": {\n const googleProvider = new GoogleAuthProvider();\n return {\n provider: googleProvider,\n customParameters: {\n login_hint: \"user@example.com\",\n prompt: \"select_account\",\n },\n };\n }\n case \"microsoft\": {\n const microsoftProvider = new OAuthProvider(\"microsoft.com\");\n return {\n provider: microsoftProvider,\n customParameters: {\n prompt: \"consent\",\n },\n };\n }\n default:\n throw new Error(`Unsupported provider: ${providerName}`);\n }\n }\n\n private async authRedirectResult(): Promise<SignInResponseTree | null> {\n try {\n const result = await getRedirectResult(this.auth);\n\n if (result) {\n const user = result.user;\n return {\n success: true,\n user,\n };\n }\n return null;\n } catch (error) {\n const authError = handleFirebaseAuthError(error);\n return {\n success: false,\n message: authError.message,\n error: authError.code,\n user: null,\n };\n }\n }\n\n private async executeAuthMethod(\n authMethod: AuthMethodFunction,\n providerName: string\n ): Promise<SignInResponseTree> {\n const config = this.getProviderConfig(providerName);\n config.provider.setCustomParameters(config.customParameters);\n try {\n await authMethod(this.auth, config.provider);\n return { success: true, message: \"Authentication initiated\" };\n } catch (error) {\n const authError = handleFirebaseAuthError(error);\n return {\n success: false,\n message: authError.message,\n error: authError.code,\n user: null,\n };\n }\n }\n\n private async _signInWithRedirect(\n providerName: string\n ): Promise<SignInResponseTree> {\n return this.executeAuthMethod(signInWithRedirect, providerName);\n }\n\n private async _signInWithPopUp(\n providerName: string\n ): Promise<SignInResponseTree> {\n return this.executeAuthMethod(signInWithPopup, providerName);\n }\n\n public async checkRedirectResult(): Promise<SignInResponseTree | 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 SignInFormValuesTree,\n SignInResource,\n SignInResponseTree,\n SignInStatus,\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\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\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: SignInFormValuesTree): Promise<SignInResponseTree> => {\n try {\n const { email, password } = params;\n const userCredential = await signInWithEmailAndPassword(this.auth, email, password);\n\n await this.signInWithCredential(userCredential);\n\n const { user } = userCredential;\n return {\n success: true,\n message: 'Authentication successful',\n user,\n error: !user.emailVerified ? 'REQUIRES_VERIFICATION' : 'AUTHENTICATED',\n };\n } catch (error) {\n const authError = handleFirebaseAuthError(error);\n return {\n success: false,\n message: authError.message,\n error: authError.code,\n user: null,\n };\n }\n };\n\n withCredential = async (params: SignInFormValuesTree): 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: string,\n options?: {\n mode?: 'popup' | 'redirect';\n },\n ): Promise<SignInResponseTree | void> => {\n try {\n if (options?.mode === 'redirect') {\n const redirectResult = await this.authRedirectResult();\n\n if (redirectResult) {\n if (redirectResult.success) {\n console.log('Redirect after sign in');\n }\n return redirectResult;\n }\n\n await this._signInWithRedirect(provider);\n return;\n } else {\n await this._signInWithPopUp(provider);\n return {\n success: true,\n message: 'Sign in successful',\n };\n }\n } catch (error: any) {\n return {\n success: false,\n message: error.message || `Sign in with ${provider} failed`,\n error,\n user: null,\n };\n }\n };\n\n completeMfaSignIn = async (_mfaToken: string, _mfaContext?: any): Promise<SignInResponseTree> => {\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 success: true,\n message: 'Email is already verified. You can sign in.',\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 success: true,\n message: 'Verification email sent. Please check your inbox.',\n isVerified: false,\n };\n };\n\n private getProviderConfig(providerName: string): ProviderConfig {\n switch (providerName.toLowerCase()) {\n case 'google': {\n const googleProvider = new GoogleAuthProvider();\n return {\n provider: googleProvider,\n customParameters: {\n login_hint: 'user@example.com',\n prompt: 'select_account',\n },\n };\n }\n case 'microsoft': {\n const microsoftProvider = new OAuthProvider('microsoft.com');\n return {\n provider: microsoftProvider,\n customParameters: {\n prompt: 'consent',\n },\n };\n }\n default:\n throw new Error(`Unsupported provider: ${providerName}`);\n }\n }\n\n private async authRedirectResult(): Promise<SignInResponseTree | null> {\n try {\n const result = await getRedirectResult(this.auth);\n\n if (result) {\n const user = result.user;\n return {\n success: true,\n user,\n };\n }\n return null;\n } catch (error) {\n const authError = handleFirebaseAuthError(error);\n return {\n success: false,\n message: authError.message,\n error: authError.code,\n user: null,\n };\n }\n }\n\n private async executeAuthMethod(\n authMethod: AuthMethodFunction,\n providerName: string,\n ): Promise<SignInResponseTree> {\n const config = this.getProviderConfig(providerName);\n config.provider.setCustomParameters(config.customParameters);\n try {\n await authMethod(this.auth, config.provider);\n return { success: true, message: 'Authentication initiated' };\n } catch (error) {\n const authError = handleFirebaseAuthError(error);\n return {\n success: false,\n message: authError.message,\n error: authError.code,\n user: null,\n };\n }\n }\n\n private async _signInWithRedirect(providerName: string): Promise<SignInResponseTree> {\n return this.executeAuthMethod(signInWithRedirect, providerName);\n }\n\n private async _signInWithPopUp(providerName: string): Promise<SignInResponseTree> {\n return this.executeAuthMethod(signInWithPopup, providerName);\n }\n\n public async checkRedirectResult(): Promise<SignInResponseTree | null> {\n return this.authRedirectResult();\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAAwC;AAUxC,kBAQO;AAEP,kBAA+B;AAqBxB,MAAM,eAAe,2BAAyC;AAAA,EACnE,WAAW;AAAA,EAEX;AAAA,EACQ;AAAA,EACA;AAAA,EACA,eAAsC;AAAA,EAE9C,YAAY,MAAY,WAA+B;AACrD,UAAM;AACN,SAAK,OAAO;AACZ,SAAK,YAAY;AAAA,EACnB;AAAA,EAEA,uBAAuB,OAAO,eAA+B;AAC3D,UAAM,UAAU,MAAM,WAAW,KAAK,WAAW;AACjD,UAAM,SAAS;AAAA,MACb;AAAA,MACA,WAAW,KAAK;AAAA,IAClB;AAEA,WAAO,KAAK,MAAM;AAAA,MAChB,MAAM,KAAK;AAAA,MACX,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAAA,EAEA,uBAAuB,OAAO,WAA8D;AAC1F,QAAI;AACF,YAAM,EAAE,OAAO,SAAS,IAAI;AAC5B,YAAM,iBAAiB,UAAM,wCAA2B,KAAK,MAAM,OAAO,QAAQ;AAElF,YAAM,KAAK,qBAAqB,cAAc;AAE9C,YAAM,EAAE,KAAK,IAAI;AACjB,aAAO;AAAA,QACL,SAAS;AAAA,QACT,SAAS;AAAA,QACT;AAAA,QACA,OAAO,CAAC,KAAK,gBAAgB,0BAA0B;AAAA,MACzD;AAAA,IACF,SAAS,OAAO;AACd,YAAM,gBAAY,uCAAwB,KAAK;AAC/C,aAAO;AAAA,QACL,SAAS;AAAA,QACT,SAAS,UAAU;AAAA,QACnB,OAAO,UAAU;AAAA,QACjB,MAAM;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAAA,EAEA,iBAAiB,OAAO,WAAgD;AACtE,QAAI;AACF,YAAM,EAAE,OAAO,SAAS,IAAI;AAC5B,YAAM,iBAAiB,UAAM,wCAA2B,KAAK,MAAM,OAAO,QAAQ;AAClF,YAAM,KAAK,qBAAqB,cAAc;AAAA,IAChD,SAAS,OAAO;AACd,YAAM,gBAAY,uCAAwB,KAAK;AAC/C,cAAQ,MAAM,SAAS;AAAA,IACzB;AAAA,EACF;AAAA,EAEA,qBAAqB,OACnB,UACA,YAGuC;AACvC,QAAI;AACF,WAAI,mCAAS,UAAS,YAAY;AAChC,cAAM,iBAAiB,MAAM,KAAK,mBAAmB;AAErD,YAAI,gBAAgB;AAClB,cAAI,eAAe,SAAS;AAC1B,oBAAQ,IAAI,wBAAwB;AAAA,UACtC;AACA,iBAAO;AAAA,QACT;AAEA,cAAM,KAAK,oBAAoB,QAAQ;AACvC;AAAA,MACF,OAAO;AACL,cAAM,KAAK,iBAAiB,QAAQ;AACpC,eAAO;AAAA,UACL,SAAS;AAAA,UACT,SAAS;AAAA,QACX;AAAA,MACF;AAAA,IACF,SAAS,OAAY;AACnB,aAAO;AAAA,QACL,SAAS;AAAA,QACT,SAAS,MAAM,WAAW,gBAAgB,QAAQ;AAAA,QAClD;AAAA,QACA,MAAM;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAAA,EAEA,oBAAoB,OAAO,WAAmB,gBAAmD;AAC/F,UAAM,IAAI,MAAM,yBAAyB;AAAA,EAC3C;AAAA,EAEA,yBAAyB,OAAO,UAAiC;AAC/D,YAAQ,IAAI,mCAAmC,KAAK,EAAE;AAAA,EACxD;AAAA,EAEA,0BAA0B,YAA8C;AACtE,UAAM,OAAO,KAAK;AAClB,QAAI,CAAC,MAAM;AACT,YAAM,IAAI,MAAM,gCAAgC;AAAA,IAClD;AAEA,UAAM,KAAK,OAAO;AAElB,QAAI,KAAK,eAAe;AACtB,aAAO;AAAA,QACL,SAAS;AAAA,QACT,SAAS;AAAA,QACT,YAAY;AAAA,MACd;AAAA,IACF;AAEA,UAAM,qBAAqB;AAAA,MACzB,KAAK;AAAA;AAAA,MACL,iBAAiB;AAAA,IACnB;AAEA,cAAM,mCAAsB,MAAM,kBAAkB;AACpD,WAAO;AAAA,MACL,SAAS;AAAA,MACT,SAAS;AAAA,MACT,YAAY;AAAA,IACd;AAAA,EACF;AAAA,EAEQ,kBAAkB,cAAsC;AAC9D,YAAQ,aAAa,YAAY,GAAG;AAAA,MAClC,KAAK,UAAU;AACb,cAAM,iBAAiB,IAAI,+BAAmB;AAC9C,eAAO;AAAA,UACL,UAAU;AAAA,UACV,kBAAkB;AAAA,YAChB,YAAY;AAAA,YACZ,QAAQ;AAAA,UACV;AAAA,QACF;AAAA,MACF;AAAA,MACA,KAAK,aAAa;AAChB,cAAM,oBAAoB,IAAI,0BAAc,eAAe;AAC3D,eAAO;AAAA,UACL,UAAU;AAAA,UACV,kBAAkB;AAAA,YAChB,QAAQ;AAAA,UACV;AAAA,QACF;AAAA,MACF;AAAA,MACA;AACE,cAAM,IAAI,MAAM,yBAAyB,YAAY,EAAE;AAAA,IAC3D;AAAA,EACF;AAAA,EAEA,MAAc,qBAAyD;AACrE,QAAI;AACF,YAAM,SAAS,UAAM,+BAAkB,KAAK,IAAI;AAEhD,UAAI,QAAQ;AACV,cAAM,OAAO,OAAO;AACpB,eAAO;AAAA,UACL,SAAS;AAAA,UACT;AAAA,QACF;AAAA,MACF;AACA,aAAO;AAAA,IACT,SAAS,OAAO;AACd,YAAM,gBAAY,uCAAwB,KAAK;AAC/C,aAAO;AAAA,QACL,SAAS;AAAA,QACT,SAAS,UAAU;AAAA,QACnB,OAAO,UAAU;AAAA,QACjB,MAAM;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAc,kBACZ,YACA,cAC6B;AAC7B,UAAM,SAAS,KAAK,kBAAkB,YAAY;AAClD,WAAO,SAAS,oBAAoB,OAAO,gBAAgB;AAC3D,QAAI;AACF,YAAM,WAAW,KAAK,MAAM,OAAO,QAAQ;AAC3C,aAAO,EAAE,SAAS,MAAM,SAAS,2BAA2B;AAAA,IAC9D,SAAS,OAAO;AACd,YAAM,gBAAY,uCAAwB,KAAK;AAC/C,aAAO;AAAA,QACL,SAAS;AAAA,QACT,SAAS,UAAU;AAAA,QACnB,OAAO,UAAU;AAAA,QACjB,MAAM;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAc,oBAAoB,cAAmD;AACnF,WAAO,KAAK,kBAAkB,gCAAoB,YAAY;AAAA,EAChE;AAAA,EAEA,MAAc,iBAAiB,cAAmD;AAChF,WAAO,KAAK,kBAAkB,6BAAiB,YAAY;AAAA,EAC7D;AAAA,EAEA,MAAa,sBAA0D;AACrE,WAAO,KAAK,mBAAmB;AAAA,EACjC;AACF;","names":[]}
|
|
@@ -7,11 +7,12 @@ import {
|
|
|
7
7
|
browserLocalPersistence,
|
|
8
8
|
browserSessionPersistence,
|
|
9
9
|
connectAuthEmulator,
|
|
10
|
+
getAuth,
|
|
10
11
|
getRedirectResult,
|
|
11
|
-
initializeAuth,
|
|
12
12
|
inMemoryPersistence,
|
|
13
13
|
onAuthStateChanged,
|
|
14
|
-
onIdTokenChanged
|
|
14
|
+
onIdTokenChanged,
|
|
15
|
+
setPersistence
|
|
15
16
|
} from "firebase/auth";
|
|
16
17
|
import { browserCookiePersistence } from "firebase/auth/web-extension";
|
|
17
18
|
import { getInstallations } from "firebase/installations";
|
|
@@ -23,10 +24,10 @@ function inBrowser() {
|
|
|
23
24
|
return typeof window !== "undefined";
|
|
24
25
|
}
|
|
25
26
|
class TernSecureAuth {
|
|
26
|
-
static version = "1.1.0-canary.
|
|
27
|
+
static version = "1.1.0-canary.v20251002175916";
|
|
27
28
|
static sdkMetadata = {
|
|
28
29
|
name: "@tern-secure/auth",
|
|
29
|
-
version: "1.1.0-canary.
|
|
30
|
+
version: "1.1.0-canary.v20251002175916",
|
|
30
31
|
environment: process.env.NODE_ENV || "production"
|
|
31
32
|
};
|
|
32
33
|
static instance = null;
|
|
@@ -107,6 +108,9 @@ class TernSecureAuth {
|
|
|
107
108
|
authCookieManager() {
|
|
108
109
|
return this.#authCookieManager;
|
|
109
110
|
}
|
|
111
|
+
_internal_getOption(key) {
|
|
112
|
+
return this.#options[key];
|
|
113
|
+
}
|
|
110
114
|
static getorCreateInstance(options) {
|
|
111
115
|
if (!this.instance) {
|
|
112
116
|
this.instance = new TernSecureAuth(options);
|
|
@@ -138,7 +142,6 @@ class TernSecureAuth {
|
|
|
138
142
|
}
|
|
139
143
|
this.initializeFirebaseApp(this.#options.ternSecureConfig);
|
|
140
144
|
this.authStateUnsubscribe = this.initAuthStateListener();
|
|
141
|
-
this._onIdTokenChanged();
|
|
142
145
|
this.#authCookieManager = new AuthCookieManager();
|
|
143
146
|
this.csrfToken = this.#authCookieManager.getCSRFToken();
|
|
144
147
|
this.signIn = new SignIn(this.auth, this.csrfToken);
|
|
@@ -157,15 +160,16 @@ class TernSecureAuth {
|
|
|
157
160
|
const appName = config.appName || "[DEFAULT]";
|
|
158
161
|
this.firebaseClientApp = getApps().length === 0 ? initializeApp(config, appName) : getApps()[0];
|
|
159
162
|
const persistence = this.#setPersistence();
|
|
160
|
-
const auth =
|
|
161
|
-
persistence
|
|
162
|
-
});
|
|
163
|
+
const auth = getAuth(this.firebaseClientApp);
|
|
163
164
|
this.auth = auth;
|
|
164
165
|
if (config.tenantId) {
|
|
165
166
|
this.auth.tenantId = config.tenantId;
|
|
166
167
|
}
|
|
167
168
|
this.#configureEmulator();
|
|
168
169
|
getInstallations(this.firebaseClientApp);
|
|
170
|
+
setPersistence(this.auth, browserCookiePersistence).catch((error) => {
|
|
171
|
+
console.error("[TernSecureAuth] Error setting persistence:", error);
|
|
172
|
+
});
|
|
169
173
|
}
|
|
170
174
|
signOut = async (options) => {
|
|
171
175
|
const redirectUrl = (options == null ? void 0 : options.redirectUrl) || this.#constructAfterSignOutUrl();
|
|
@@ -191,7 +195,6 @@ class TernSecureAuth {
|
|
|
191
195
|
await this.auth.authStateReady();
|
|
192
196
|
this._currentUser = user;
|
|
193
197
|
await this.updateCurrentSession();
|
|
194
|
-
eventBus.emit(events.UserChanged, this._currentUser);
|
|
195
198
|
this.#emit();
|
|
196
199
|
});
|
|
197
200
|
}
|
|
@@ -200,7 +203,6 @@ class TernSecureAuth {
|
|
|
200
203
|
await this.auth.authStateReady();
|
|
201
204
|
this._currentUser = user;
|
|
202
205
|
await this.updateCurrentSession();
|
|
203
|
-
eventBus.emit(events.TokenRefreshed, { token: user ? await user.getIdTokenResult() : null });
|
|
204
206
|
this.#emit();
|
|
205
207
|
});
|
|
206
208
|
}
|
|
@@ -402,7 +404,8 @@ class TernSecureAuth {
|
|
|
402
404
|
if (this._currentUser) {
|
|
403
405
|
for (const listener of this.#listeners) {
|
|
404
406
|
listener({
|
|
405
|
-
user: this._currentUser
|
|
407
|
+
user: this._currentUser,
|
|
408
|
+
session: this.signedInSession
|
|
406
409
|
});
|
|
407
410
|
}
|
|
408
411
|
}
|
|
@@ -419,8 +422,6 @@ class TernSecureAuth {
|
|
|
419
422
|
#setPersistence = () => {
|
|
420
423
|
const persistenceType = this.#options.persistence || "none";
|
|
421
424
|
switch (persistenceType) {
|
|
422
|
-
case "browserCookie":
|
|
423
|
-
return browserCookiePersistence;
|
|
424
425
|
case "session":
|
|
425
426
|
return browserSessionPersistence;
|
|
426
427
|
case "local":
|
|
@@ -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 DomainOrProxyUrl,\n InstanceType,\n ListenerCallback,\n RedirectOptions,\n SignedInSession,\n SignInRedirectOptions,\n SignInResource,\n SignInResponseTree,\n SignOut,\n SignOutOptions,\n SignUpRedirectOptions,\n SignUpResource,\n TernSecureAuth as TernSecureAuthInterface,\n TernSecureAuthOptions,\n TernSecureAuthStatus,\n TernSecureConfig,\n TernSecureResources,\n TernSecureSDK,\n TernSecureUser,\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 browserSessionPersistence,\n connectAuthEmulator,\n getRedirectResult,\n initializeAuth,\n inMemoryPersistence,\n onAuthStateChanged,\n onIdTokenChanged,\n} from 'firebase/auth';\nimport { browserCookiePersistence } from 'firebase/auth/web-extension';\nimport { getInstallations } from 'firebase/installations';\n\nimport { AuthCookieManager, SignIn, SignUp, TernSecureBase } from '../resources/internal';\nimport { buildURL } from '../utils/construct';\nimport { type ApiClient, createCoreApiClient } from './c_coreApiClient';\nimport { eventBus, events } from './events';\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: TernSecureSDK = {\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 = {} as TernSecureAuthOptions;\n #authCookieManager?: AuthCookieManager;\n #publicEventBus = createTernAuthEventBus();\n\n signIn!: SignInResource;\n signUp!: SignUpResource;\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: TernSecureSDK) {\n TernSecureAuth.sdkMetadata = metadata;\n }\n\n get sdkMetadata(): TernSecureSDK {\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 public setLoading(isLoading: boolean): void {\n this.isLoading = isLoading;\n }\n\n public authCookieManager(): AuthCookieManager | undefined {\n return this.#authCookieManager;\n }\n\n static getorCreateInstance(options?: TernSecureAuthOptions): TernSecureAuth {\n if (!this.instance) {\n this.instance = new TernSecureAuth(options);\n }\n //console.log('TernSecureAuth instance:', this.instance);\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 = (options: TernSecureAuthOptions): TernSecureAuth => {\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 this.authStateUnsubscribe = this.initAuthStateListener();\n this._onIdTokenChanged();\n\n this.#authCookieManager = new AuthCookieManager();\n this.csrfToken = this.#authCookieManager.getCSRFToken();\n\n this.signIn = new SignIn(this.auth, this.csrfToken);\n this.signUp = new SignUp(this.auth);\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 });\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 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 if (inBrowser()) {\n window.location.href = redirectUrl;\n }\n eventBus.emit(events.UserSignOut, null);\n eventBus.emit(events.TokenRefreshed, { token: null });\n this.#emit();\n };\n\n get currentSession(): SignedInSession | null {\n return this.signedInSession;\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 await this.updateCurrentSession();\n\n eventBus.emit(events.UserChanged, this._currentUser);\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 await this.updateCurrentSession();\n\n eventBus.emit(events.TokenRefreshed, { token: user ? await user.getIdTokenResult() : null });\n this.#emit();\n });\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 };\n } catch (error) {\n console.error('[TernSecureAuth] Error updating session:', error);\n this.signedInSession = null;\n }\n }\n\n public async checkRedirectResult(): Promise<SignInResponseTree | null> {\n try {\n const result = await getRedirectResult(this.auth);\n if (result) {\n return {\n success: true,\n user: result.user as TernSecureUser,\n };\n }\n return null;\n } catch (error) {\n const authError = handleFirebaseAuthError(error);\n return {\n success: false,\n message: authError.message,\n error: authError.code,\n user: null,\n };\n }\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 initialize(options: TernSecureAuthOptions): Promise<void> {\n this._initialize(options);\n return Promise.resolve();\n }\n\n public static create(options: TernSecureAuthOptions): TernSecureAuth {\n const instance = this.getorCreateInstance();\n instance.initialize(options);\n return instance;\n }\n\n _initialize = (options: TernSecureAuthOptions): void => {\n this.#options = this.#initOptions(options);\n try {\n if (!this.#options.ternSecureConfig) {\n throw new Error('TernSecureConfig is required to initialize TernSecureAuth');\n }\n\n this.initializeFirebaseApp(this.#options.ternSecureConfig);\n\n this.signIn = new SignIn(this.auth, this.csrfToken);\n this.signUp = new SignUp(this.auth);\n\n this.#setStatus('ready');\n } catch (error) {\n this.error = error as Error;\n this.#setStatus('error');\n throw error;\n }\n };\n\n public constructUrlWithAuthRedirect = (to: string): string => {\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 let effectiveRedirectUrl: string | null | undefined;\n\n // Priority 1: Get redirect URL from options (signInForceRedirectUrl or signUpForceRedirectUrl)\n if (key === 'signInUrl' && 'signInForceRedirectUrl' in options) {\n effectiveRedirectUrl = options.signInForceRedirectUrl;\n } else if (key === 'signUpUrl' && 'signUpForceRedirectUrl' in options) {\n effectiveRedirectUrl = options.signUpForceRedirectUrl;\n }\n\n // Priority 2: If no force redirect from options, check 'redirect' param in current URL (only in browser)\n if (!effectiveRedirectUrl && inBrowser()) {\n const currentUrlParams = new URLSearchParams(window.location.search);\n const existingRedirectParam = currentUrlParams.get('redirect_url');\n if (existingRedirectParam) {\n effectiveRedirectUrl = existingRedirectParam;\n }\n }\n\n // Priority 3: If still no redirect URL, fallback to current page's full path (only in browser)\n // This ensures that if the call originates from a page, it attempts to redirect back there by default.\n if (!effectiveRedirectUrl && inBrowser()) {\n effectiveRedirectUrl =\n window.location.pathname + window.location.search + window.location.hash;\n }\n\n if (effectiveRedirectUrl && inBrowser()) {\n let signInPagePath: string | undefined;\n try {\n signInPagePath = this.#options.signInUrl\n ? new URL(this.#options.signInUrl, window.location.origin).pathname\n : defaultPagePath;\n } catch {\n signInPagePath = defaultPagePath;\n }\n\n let signUpPagePath: string | undefined;\n try {\n signUpPagePath = this.#options.signUpUrl\n ? new URL(this.#options.signUpUrl, window.location.origin).pathname\n : key === 'signUpUrl'\n ? defaultPagePath\n : '/sign-in';\n } catch {\n signUpPagePath = key === 'signUpUrl' ? defaultPagePath : '/sign-in';\n }\n\n const redirectTargetObj = new URL(effectiveRedirectUrl, window.location.origin);\n\n if (\n redirectTargetObj.pathname === signInPagePath ||\n redirectTargetObj.pathname === signUpPagePath\n ) {\n // If the intended redirect path is the sign-in or sign-up page itself,\n // change the redirect target to the application root ('/').\n effectiveRedirectUrl = '/';\n }\n }\n\n const paramsForBuildUrl: Parameters<typeof buildURL>[0] = {\n base,\n searchParams: new URLSearchParams(),\n };\n\n if (effectiveRedirectUrl) {\n // Check if a redirect URL was determined\n if (inBrowser()) {\n const absoluteRedirectUrl = new URL(effectiveRedirectUrl, window.location.origin).href;\n paramsForBuildUrl.searchParams?.set('redirect', absoluteRedirectUrl);\n } else {\n // If not in browser, use the effectiveRedirectUrl as is.\n // This assumes it's either absolute or a path the server can interpret.\n paramsForBuildUrl.searchParams?.set('redirect', effectiveRedirectUrl);\n }\n }\n\n const constructedUrl = buildURL(paramsForBuildUrl, {\n stringify: true,\n skipOrigin: false,\n });\n\n if (typeof constructedUrl !== 'string') {\n console.error(\n '[TernSecure] Error: buildURL did not return a string as expected. Falling back to base URL.',\n );\n if (inBrowser()) {\n try {\n return new URL(base, window.location.origin).href;\n } catch {\n return base;\n }\n }\n return base;\n }\n\n return this.constructUrlWithAuthRedirect(constructedUrl);\n };\n\n #constructAfterSignOutUrl = (): string => {\n if (!this.#options.afterSignOutUrl) {\n return '/';\n }\n return this.constructUrlWithAuthRedirect(this.#options.afterSignOutUrl);\n };\n\n public constructSignInUrl = (options?: SignInRedirectOptions): string => {\n return this.#buildUrl('signInUrl', { ...options });\n };\n\n public constructSignUpUrl = (options?: SignUpRedirectOptions): string => {\n return this.#buildUrl('signUpUrl', { ...options });\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 if (this._currentUser) {\n for (const listener of this.#listeners) {\n listener({\n user: this._currentUser,\n });\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 #setPersistence = () => {\n const persistenceType = this.#options.persistence || 'none';\n\n switch (persistenceType) {\n case 'browserCookie':\n return browserCookiePersistence;\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 DomainOrProxyUrl,\n InstanceType,\n ListenerCallback,\n RedirectOptions,\n SignedInSession,\n SignInRedirectOptions,\n SignInResource,\n SignInResponseTree,\n SignOut,\n SignOutOptions,\n SignUpRedirectOptions,\n SignUpResource,\n TernSecureAuth as TernSecureAuthInterface,\n TernSecureAuthOptions,\n TernSecureAuthStatus,\n TernSecureConfig,\n TernSecureResources,\n TernSecureSDK,\n TernSecureUser,\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 browserSessionPersistence,\n connectAuthEmulator,\n getAuth,\n getRedirectResult,\n inMemoryPersistence,\n onAuthStateChanged,\n onIdTokenChanged,\n setPersistence,\n} from 'firebase/auth';\nimport { browserCookiePersistence } from 'firebase/auth/web-extension';\nimport { getInstallations } from 'firebase/installations';\n\nimport { AuthCookieManager, SignIn, SignUp, TernSecureBase } from '../resources/internal';\nimport { buildURL } from '../utils/construct';\nimport { type ApiClient, createCoreApiClient } from './c_coreApiClient';\nimport { eventBus, events } from './events';\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: TernSecureSDK = {\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 = {} as TernSecureAuthOptions;\n #authCookieManager?: AuthCookieManager;\n #publicEventBus = createTernAuthEventBus();\n\n signIn!: SignInResource;\n signUp!: SignUpResource;\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: TernSecureSDK) {\n TernSecureAuth.sdkMetadata = metadata;\n }\n\n get sdkMetadata(): TernSecureSDK {\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 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>(key: K): TernSecureAuthOptions[K] {\n return this.#options[key];\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 = (options: TernSecureAuthOptions): TernSecureAuth => {\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 this.authStateUnsubscribe = this.initAuthStateListener();\n // /this.authStateUnsubscribe = this._onIdTokenChanged();\n\n this.#authCookieManager = new AuthCookieManager();\n this.csrfToken = this.#authCookieManager.getCSRFToken();\n\n this.signIn = new SignIn(this.auth, this.csrfToken);\n this.signUp = new SignUp(this.auth);\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: browserCookiePersistence,\n //});\n\n const auth = getAuth(this.firebaseClientApp);\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 setPersistence(this.auth, browserCookiePersistence).catch(error => {\n console.error('[TernSecureAuth] Error setting persistence:', error);\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 if (inBrowser()) {\n window.location.href = redirectUrl;\n }\n eventBus.emit(events.UserSignOut, null);\n eventBus.emit(events.TokenRefreshed, { token: null });\n this.#emit();\n };\n\n get currentSession(): SignedInSession | null {\n return this.signedInSession;\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 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 await this.updateCurrentSession();\n\n //eventBus.emit(events.TokenRefreshed, { token: user ? await user.getIdTokenResult() : null });\n this.#emit();\n });\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 };\n } catch (error) {\n console.error('[TernSecureAuth] Error updating session:', error);\n this.signedInSession = null;\n }\n }\n\n public async checkRedirectResult(): Promise<SignInResponseTree | null> {\n try {\n const result = await getRedirectResult(this.auth);\n if (result) {\n return {\n success: true,\n user: result.user as TernSecureUser,\n };\n }\n return null;\n } catch (error) {\n const authError = handleFirebaseAuthError(error);\n return {\n success: false,\n message: authError.message,\n error: authError.code,\n user: null,\n };\n }\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 initialize(options: TernSecureAuthOptions): Promise<void> {\n this._initialize(options);\n return Promise.resolve();\n }\n\n public static create(options: TernSecureAuthOptions): TernSecureAuth {\n const instance = this.getorCreateInstance();\n instance.initialize(options);\n return instance;\n }\n\n _initialize = (options: TernSecureAuthOptions): void => {\n this.#options = this.#initOptions(options);\n try {\n if (!this.#options.ternSecureConfig) {\n throw new Error('TernSecureConfig is required to initialize TernSecureAuth');\n }\n\n this.initializeFirebaseApp(this.#options.ternSecureConfig);\n\n this.signIn = new SignIn(this.auth, this.csrfToken);\n this.signUp = new SignUp(this.auth);\n\n this.#setStatus('ready');\n } catch (error) {\n this.error = error as Error;\n this.#setStatus('error');\n throw error;\n }\n };\n\n public constructUrlWithAuthRedirect = (to: string): string => {\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 let effectiveRedirectUrl: string | null | undefined;\n\n // Priority 1: Get redirect URL from options (signInForceRedirectUrl or signUpForceRedirectUrl)\n if (key === 'signInUrl' && 'signInForceRedirectUrl' in options) {\n effectiveRedirectUrl = options.signInForceRedirectUrl;\n } else if (key === 'signUpUrl' && 'signUpForceRedirectUrl' in options) {\n effectiveRedirectUrl = options.signUpForceRedirectUrl;\n }\n\n // Priority 2: If no force redirect from options, check 'redirect' param in current URL (only in browser)\n if (!effectiveRedirectUrl && inBrowser()) {\n const currentUrlParams = new URLSearchParams(window.location.search);\n const existingRedirectParam = currentUrlParams.get('redirect_url');\n if (existingRedirectParam) {\n effectiveRedirectUrl = existingRedirectParam;\n }\n }\n\n // Priority 3: If still no redirect URL, fallback to current page's full path (only in browser)\n // This ensures that if the call originates from a page, it attempts to redirect back there by default.\n if (!effectiveRedirectUrl && inBrowser()) {\n effectiveRedirectUrl =\n window.location.pathname + window.location.search + window.location.hash;\n }\n\n if (effectiveRedirectUrl && inBrowser()) {\n let signInPagePath: string | undefined;\n try {\n signInPagePath = this.#options.signInUrl\n ? new URL(this.#options.signInUrl, window.location.origin).pathname\n : defaultPagePath;\n } catch {\n signInPagePath = defaultPagePath;\n }\n\n let signUpPagePath: string | undefined;\n try {\n signUpPagePath = this.#options.signUpUrl\n ? new URL(this.#options.signUpUrl, window.location.origin).pathname\n : key === 'signUpUrl'\n ? defaultPagePath\n : '/sign-in';\n } catch {\n signUpPagePath = key === 'signUpUrl' ? defaultPagePath : '/sign-in';\n }\n\n const redirectTargetObj = new URL(effectiveRedirectUrl, window.location.origin);\n\n if (\n redirectTargetObj.pathname === signInPagePath ||\n redirectTargetObj.pathname === signUpPagePath\n ) {\n // If the intended redirect path is the sign-in or sign-up page itself,\n // change the redirect target to the application root ('/').\n effectiveRedirectUrl = '/';\n }\n }\n\n const paramsForBuildUrl: Parameters<typeof buildURL>[0] = {\n base,\n searchParams: new URLSearchParams(),\n };\n\n if (effectiveRedirectUrl) {\n // Check if a redirect URL was determined\n if (inBrowser()) {\n const absoluteRedirectUrl = new URL(effectiveRedirectUrl, window.location.origin).href;\n paramsForBuildUrl.searchParams?.set('redirect', absoluteRedirectUrl);\n } else {\n // If not in browser, use the effectiveRedirectUrl as is.\n // This assumes it's either absolute or a path the server can interpret.\n paramsForBuildUrl.searchParams?.set('redirect', effectiveRedirectUrl);\n }\n }\n\n const constructedUrl = buildURL(paramsForBuildUrl, {\n stringify: true,\n skipOrigin: false,\n });\n\n if (typeof constructedUrl !== 'string') {\n console.error(\n '[TernSecure] Error: buildURL did not return a string as expected. Falling back to base URL.',\n );\n if (inBrowser()) {\n try {\n return new URL(base, window.location.origin).href;\n } catch {\n return base;\n }\n }\n return base;\n }\n\n return this.constructUrlWithAuthRedirect(constructedUrl);\n };\n\n #constructAfterSignOutUrl = (): string => {\n if (!this.#options.afterSignOutUrl) {\n return '/';\n }\n return this.constructUrlWithAuthRedirect(this.#options.afterSignOutUrl);\n };\n\n public constructSignInUrl = (options?: SignInRedirectOptions): string => {\n return this.#buildUrl('signInUrl', { ...options });\n };\n\n public constructSignUpUrl = (options?: SignUpRedirectOptions): string => {\n return this.#buildUrl('signUpUrl', { ...options });\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 if (this._currentUser) {\n for (const listener of this.#listeners) {\n listener({\n user: this._currentUser,\n session: this.signedInSession,\n });\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 #setPersistence = () => {\n const persistenceType = this.#options.persistence || 'none';\n\n switch (persistenceType) {\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":[]}
|
|
@@ -157,7 +157,6 @@ function createCoreApiClient(clientOptions) {
|
|
|
157
157
|
const { timeoutMs } = requestOptions;
|
|
158
158
|
const overwrittenRequestMethod = method === "GET" ? "GET" : "POST";
|
|
159
159
|
const url = requestInit.url.toString();
|
|
160
|
-
console.log("Request URL:", url);
|
|
161
160
|
requestInit.headers = new Headers(requestInit.headers);
|
|
162
161
|
if (method !== "GET" && !(body instanceof FormData) && !requestInit.headers.has("content-type")) {
|
|
163
162
|
requestInit.headers.set("content-type", "application/json");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/instance/c_coreApiClient.ts"],"sourcesContent":["import { camelToSnake, jitteredDelay } from '@tern-secure/shared/caseUtils'\nimport type { InstanceType, TernSecureApiErrorJSON } from '@tern-secure/types';\n\nimport { buildURL as buildUrlUtil, stringifyQueryParams } from '../utils';\n\nexport type HTTPMethod =\n | 'CONNECT'\n | 'DELETE'\n | 'GET'\n | 'HEAD'\n | 'OPTIONS'\n | 'PATCH'\n | 'POST'\n | 'PUT'\n | 'TRACE';\n\nexport type ApiRequestInit = RequestInit & {\n path?: string;\n search?: ConstructorParameters<typeof URLSearchParams>[0];\n sessionId?: string;\n url?: URL;\n};\n\nexport interface ApiResponseJSON<T> {\n response: T;\n errors?: TernSecureApiErrorJSON[];\n}\n\nexport type ApiResponse<T> = Response & { payload: ApiResponseJSON<T> | null };\n\nexport type ApiRequestCallback<T> = (request: ApiRequestInit, response?: ApiResponse<T>) => unknown;\n\nexport interface ApiRequestOptions {\n timeoutMs?: number;\n maxTries?: number;\n initialDelay?: number;\n factor?: number;\n maxDelay?: number;\n failureThreshold?: number;\n recoveryTimeoutMs?: number;\n}\n\nexport interface ApiClientOptions {\n domain?: string;\n apiUrl?: string;\n frontendApi?: string;\n instanceType?: InstanceType;\n apiBasePath?: string;\n}\n\nexport interface ApiClient {\n onBeforeRequest: (hook: BeforeRequestHook) => void;\n onAfterResponse: (hook: AfterResponseHook) => void;\n request: <T>(init: ApiRequestInit, opts?: ApiRequestOptions) => Promise<ApiResponse<T>>;\n}\n\nexport type BeforeRequestHook = () => boolean | Promise<boolean>;\nexport type AfterResponseHook = (response: ApiResponse<any>) => boolean | Promise<boolean>;\n\n// Error classes\nexport class NetworkError extends Error {\n constructor(\n public url: string,\n public original: Error,\n ) {\n super(`Network error for ${url}: ${original.message}`);\n this.name = 'NetworkError';\n }\n}\n\nexport class TimeoutError extends Error {\n constructor() {\n super('Request timed out');\n this.name = 'TimeoutError';\n }\n}\n\nexport class CircuitOpenError extends Error {\n constructor() {\n super('Circuit breaker is open');\n this.name = 'CircuitOpenError';\n }\n}\n\nexport class HTTPError extends Error {\n constructor(\n public status: number,\n public url: string,\n public body?: any,\n ) {\n super(`HTTP ${status} error for ${url}`);\n this.name = 'HTTPError';\n }\n}\n\n// Circuit breaker state interface\ninterface CircuitBreakerState {\n failures: number;\n lastFailureTime: number;\n state: 'closed' | 'open' | 'half-open';\n}\n\n// Client state interface\ninterface ClientState {\n circuitBreaker: CircuitBreakerState;\n beforeRequestHooks: BeforeRequestHook[];\n afterResponseHooks: AfterResponseHook[];\n clientOptions: ApiClientOptions;\n}\n\nfunction createInitialState(clientOptions: ApiClientOptions = {}): ClientState {\n return {\n circuitBreaker: {\n failures: 0,\n lastFailureTime: 0,\n state: 'closed',\n },\n beforeRequestHooks: [],\n afterResponseHooks: [],\n clientOptions,\n };\n}\n\nfunction addBeforeRequestHook(state: ClientState, hook: BeforeRequestHook): void {\n state.beforeRequestHooks.push(hook);\n}\n\nfunction addAfterResponseHook(state: ClientState, hook: AfterResponseHook): void {\n state.afterResponseHooks.push(hook);\n}\n\nasync function runBeforeRequestHooks(state: ClientState): Promise<boolean> {\n for (const hook of state.beforeRequestHooks) {\n const result = await hook();\n if (result === false) return false;\n }\n return true;\n}\n\nasync function runAfterResponseHooks(\n state: ClientState,\n response: ApiResponse<any>,\n): Promise<void> {\n for (const hook of state.afterResponseHooks) {\n await hook(response);\n }\n}\n\nfunction checkCircuitBreaker(state: ClientState, requestOptions: ApiRequestOptions): void {\n const { recoveryTimeoutMs = 60000 } = requestOptions;\n const now = Date.now();\n\n if (state.circuitBreaker.state === 'open') {\n if (now - state.circuitBreaker.lastFailureTime >= recoveryTimeoutMs) {\n state.circuitBreaker.state = 'half-open';\n } else {\n throw new CircuitOpenError();\n }\n }\n}\n\nfunction recordSuccess(state: ClientState): void {\n state.circuitBreaker.failures = 0;\n state.circuitBreaker.state = 'closed';\n}\n\nfunction recordFailure(state: ClientState, requestOptions: ApiRequestOptions): void {\n const { failureThreshold = 5 } = requestOptions;\n state.circuitBreaker.failures++;\n state.circuitBreaker.lastFailureTime = Date.now();\n\n if (state.circuitBreaker.failures >= failureThreshold) {\n state.circuitBreaker.state = 'open';\n }\n}\n\nfunction shouldRetry(\n state: ClientState,\n requestOptions: ApiRequestOptions,\n error: any,\n method: string,\n attempt: number,\n maxTries: number,\n): boolean {\n const isRetryable =\n error instanceof NetworkError && method.toUpperCase() === 'GET' && attempt < maxTries;\n\n if (!isRetryable) {\n recordFailure(state, requestOptions);\n }\n\n return isRetryable;\n}\n\nasync function retryWithBackoff<T>(\n state: ClientState,\n requestOptions: ApiRequestOptions,\n attemptFn: () => Promise<T>,\n shouldRetryFn: (error: any, attempt: number) => boolean,\n): Promise<T> {\n const {\n initialDelay = 700,\n factor = 2,\n maxDelay = 5000,\n maxTries = typeof navigator !== 'undefined' && navigator.onLine ? 4 : 11,\n } = requestOptions;\n\n let lastError: any;\n\n for (let attempt = 1; attempt <= maxTries; attempt++) {\n try {\n const result = await attemptFn();\n recordSuccess(state);\n return result;\n } catch (error) {\n lastError = error;\n\n if (!shouldRetryFn(error, attempt)) {\n throw error;\n }\n\n recordFailure(state, requestOptions);\n\n if (attempt < maxTries) {\n const delay = Math.min(initialDelay * Math.pow(factor, attempt - 1), maxDelay);\n await new Promise(resolve => setTimeout(resolve, jitteredDelay(delay)));\n }\n }\n }\n\n throw lastError;\n}\n\nexport function createCoreApiClient(clientOptions: ApiClientOptions): ApiClient {\n function buildUrl(requestInit: ApiRequestInit): URL {\n const isLocalhost = clientOptions.apiUrl?.includes('localhost') || clientOptions.apiUrl?.includes('127.0.0.1');\n const { path } = requestInit;\n const { instanceType, domain, apiUrl, apiBasePath = '/api/auth' } = clientOptions;\n const domainInProd = instanceType === 'production' ? domain : '';\n\n let baseUrl: string;\n if (isLocalhost) {\n // For localhost, use http and the apiUrl directly\n baseUrl = apiUrl?.startsWith('http') ? apiUrl : `http://${apiUrl}`;\n } else {\n //const domainInProd = instanceType === 'production' ? domain : '';\n baseUrl = `https://${domainInProd || apiUrl}`;\n }\n\n const fullPath = `${apiBasePath}/${path}`.replace(/\\/+/g, '/'); \n return buildUrlUtil(\n {\n base: baseUrl,\n pathname: fullPath,\n searchParams: requestInit.search ? new URLSearchParams(requestInit.search) : undefined,\n },\n { stringify: false },\n );\n }\n\n async function makeRequest<T>(\n state: ClientState,\n init: ApiRequestInit,\n opts: ApiRequestOptions = {},\n ): Promise<ApiResponse<T>> {\n const requestInit = { ...init };\n const { method = 'GET', body } = requestInit;\n const requestOptions = { ...opts };\n\n requestInit.url = buildUrl({ ...requestInit });\n checkCircuitBreaker(state, requestOptions);\n\n const shouldContinue = await runBeforeRequestHooks(state);\n if (!shouldContinue) {\n const mockResponse = new Response('{}', {\n status: 200,\n }) as ApiResponse<T>;\n mockResponse.payload = { response: {} as T };\n await runAfterResponseHooks(state, mockResponse);\n return mockResponse;\n }\n\n const { timeoutMs } = requestOptions;\n\n const overwrittenRequestMethod = method === 'GET' ? 'GET' : 'POST';\n const url = requestInit.url.toString();\n\n console.log('Request URL:', url);\n\n requestInit.headers = new Headers(requestInit.headers);\n\n if (\n method !== 'GET' &&\n !(body instanceof FormData) &&\n !requestInit.headers.has('content-type')\n ) {\n requestInit.headers.set('content-type', 'application/json');\n }\n\n if (requestInit.headers.get('content-type') === 'application/x-www-form-urlencoded') {\n requestInit.body = body\n ? stringifyQueryParams(body as any as Record<string, string>, {\n keyEncoder: camelToSnake,\n })\n : body;\n } else if (requestInit.headers.get('content-type') === 'application/json' && body) {\n requestInit.body = typeof body === 'string' ? body : JSON.stringify(body);\n }\n\n const attemptRequest = async (): Promise<ApiResponse<T>> => {\n const controller = new AbortController();\n const timeoutId = timeoutMs\n ? setTimeout(() => {\n controller.abort();\n }, timeoutMs)\n : null;\n\n let response: Response;\n const fetchOpts: ApiRequestInit = {\n ...requestInit,\n credentials: 'include',\n method: overwrittenRequestMethod,\n };\n\n try {\n response = await fetch(url, fetchOpts);\n\n if (timeoutId) clearTimeout(timeoutId);\n\n let payload: ApiResponseJSON<T> | null = null;\n\n if (response.status === 204) {\n payload = null;\n } else {\n try {\n const json = await response.json();\n payload = json;\n } catch {\n payload = { response: {} as T };\n }\n }\n\n const apiResponse = response as ApiResponse<T>;\n apiResponse.payload = payload;\n\n await runAfterResponseHooks(state, apiResponse);\n\n return apiResponse;\n } catch (error: any) {\n if (timeoutId) clearTimeout(timeoutId);\n\n if (error.name === 'AbortError') {\n throw new TimeoutError();\n }\n\n throw new NetworkError(url, error);\n }\n };\n\n return retryWithBackoff(state, requestOptions, attemptRequest, (error, attempt) =>\n shouldRetry(\n state,\n requestOptions,\n error,\n overwrittenRequestMethod,\n attempt,\n requestOptions.maxTries || (typeof navigator !== 'undefined' && navigator.onLine ? 4 : 11),\n ),\n );\n }\n const state = createInitialState(clientOptions);\n\n return {\n onBeforeRequest: (hook: BeforeRequestHook) => addBeforeRequestHook(state, hook),\n onAfterResponse: (hook: AfterResponseHook) => addAfterResponseHook(state, hook),\n request: <T>(init: ApiRequestInit, opts: ApiRequestOptions = {}) =>\n makeRequest<T>(state, init, opts),\n };\n}\n"],"mappings":"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","names":["state"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/instance/c_coreApiClient.ts"],"sourcesContent":["import { camelToSnake, jitteredDelay } from '@tern-secure/shared/caseUtils'\nimport type { InstanceType, TernSecureApiErrorJSON } from '@tern-secure/types';\n\nimport { buildURL as buildUrlUtil, stringifyQueryParams } from '../utils';\n\nexport type HTTPMethod =\n | 'CONNECT'\n | 'DELETE'\n | 'GET'\n | 'HEAD'\n | 'OPTIONS'\n | 'PATCH'\n | 'POST'\n | 'PUT'\n | 'TRACE';\n\nexport type ApiRequestInit = RequestInit & {\n path?: string;\n search?: ConstructorParameters<typeof URLSearchParams>[0];\n sessionId?: string;\n url?: URL;\n};\n\nexport interface ApiResponseJSON<T> {\n response: T;\n errors?: TernSecureApiErrorJSON[];\n}\n\nexport type ApiResponse<T> = Response & { payload: ApiResponseJSON<T> | null };\n\nexport type ApiRequestCallback<T> = (request: ApiRequestInit, response?: ApiResponse<T>) => unknown;\n\nexport interface ApiRequestOptions {\n timeoutMs?: number;\n maxTries?: number;\n initialDelay?: number;\n factor?: number;\n maxDelay?: number;\n failureThreshold?: number;\n recoveryTimeoutMs?: number;\n}\n\nexport interface ApiClientOptions {\n domain?: string;\n apiUrl?: string;\n frontendApi?: string;\n instanceType?: InstanceType;\n apiBasePath?: string;\n}\n\nexport interface ApiClient {\n onBeforeRequest: (hook: BeforeRequestHook) => void;\n onAfterResponse: (hook: AfterResponseHook) => void;\n request: <T>(init: ApiRequestInit, opts?: ApiRequestOptions) => Promise<ApiResponse<T>>;\n}\n\nexport type BeforeRequestHook = () => boolean | Promise<boolean>;\nexport type AfterResponseHook = (response: ApiResponse<any>) => boolean | Promise<boolean>;\n\n// Error classes\nexport class NetworkError extends Error {\n constructor(\n public url: string,\n public original: Error,\n ) {\n super(`Network error for ${url}: ${original.message}`);\n this.name = 'NetworkError';\n }\n}\n\nexport class TimeoutError extends Error {\n constructor() {\n super('Request timed out');\n this.name = 'TimeoutError';\n }\n}\n\nexport class CircuitOpenError extends Error {\n constructor() {\n super('Circuit breaker is open');\n this.name = 'CircuitOpenError';\n }\n}\n\nexport class HTTPError extends Error {\n constructor(\n public status: number,\n public url: string,\n public body?: any,\n ) {\n super(`HTTP ${status} error for ${url}`);\n this.name = 'HTTPError';\n }\n}\n\n// Circuit breaker state interface\ninterface CircuitBreakerState {\n failures: number;\n lastFailureTime: number;\n state: 'closed' | 'open' | 'half-open';\n}\n\n// Client state interface\ninterface ClientState {\n circuitBreaker: CircuitBreakerState;\n beforeRequestHooks: BeforeRequestHook[];\n afterResponseHooks: AfterResponseHook[];\n clientOptions: ApiClientOptions;\n}\n\nfunction createInitialState(clientOptions: ApiClientOptions = {}): ClientState {\n return {\n circuitBreaker: {\n failures: 0,\n lastFailureTime: 0,\n state: 'closed',\n },\n beforeRequestHooks: [],\n afterResponseHooks: [],\n clientOptions,\n };\n}\n\nfunction addBeforeRequestHook(state: ClientState, hook: BeforeRequestHook): void {\n state.beforeRequestHooks.push(hook);\n}\n\nfunction addAfterResponseHook(state: ClientState, hook: AfterResponseHook): void {\n state.afterResponseHooks.push(hook);\n}\n\nasync function runBeforeRequestHooks(state: ClientState): Promise<boolean> {\n for (const hook of state.beforeRequestHooks) {\n const result = await hook();\n if (result === false) return false;\n }\n return true;\n}\n\nasync function runAfterResponseHooks(\n state: ClientState,\n response: ApiResponse<any>,\n): Promise<void> {\n for (const hook of state.afterResponseHooks) {\n await hook(response);\n }\n}\n\nfunction checkCircuitBreaker(state: ClientState, requestOptions: ApiRequestOptions): void {\n const { recoveryTimeoutMs = 60000 } = requestOptions;\n const now = Date.now();\n\n if (state.circuitBreaker.state === 'open') {\n if (now - state.circuitBreaker.lastFailureTime >= recoveryTimeoutMs) {\n state.circuitBreaker.state = 'half-open';\n } else {\n throw new CircuitOpenError();\n }\n }\n}\n\nfunction recordSuccess(state: ClientState): void {\n state.circuitBreaker.failures = 0;\n state.circuitBreaker.state = 'closed';\n}\n\nfunction recordFailure(state: ClientState, requestOptions: ApiRequestOptions): void {\n const { failureThreshold = 5 } = requestOptions;\n state.circuitBreaker.failures++;\n state.circuitBreaker.lastFailureTime = Date.now();\n\n if (state.circuitBreaker.failures >= failureThreshold) {\n state.circuitBreaker.state = 'open';\n }\n}\n\nfunction shouldRetry(\n state: ClientState,\n requestOptions: ApiRequestOptions,\n error: any,\n method: string,\n attempt: number,\n maxTries: number,\n): boolean {\n const isRetryable =\n error instanceof NetworkError && method.toUpperCase() === 'GET' && attempt < maxTries;\n\n if (!isRetryable) {\n recordFailure(state, requestOptions);\n }\n\n return isRetryable;\n}\n\nasync function retryWithBackoff<T>(\n state: ClientState,\n requestOptions: ApiRequestOptions,\n attemptFn: () => Promise<T>,\n shouldRetryFn: (error: any, attempt: number) => boolean,\n): Promise<T> {\n const {\n initialDelay = 700,\n factor = 2,\n maxDelay = 5000,\n maxTries = typeof navigator !== 'undefined' && navigator.onLine ? 4 : 11,\n } = requestOptions;\n\n let lastError: any;\n\n for (let attempt = 1; attempt <= maxTries; attempt++) {\n try {\n const result = await attemptFn();\n recordSuccess(state);\n return result;\n } catch (error) {\n lastError = error;\n\n if (!shouldRetryFn(error, attempt)) {\n throw error;\n }\n\n recordFailure(state, requestOptions);\n\n if (attempt < maxTries) {\n const delay = Math.min(initialDelay * Math.pow(factor, attempt - 1), maxDelay);\n await new Promise(resolve => setTimeout(resolve, jitteredDelay(delay)));\n }\n }\n }\n\n throw lastError;\n}\n\nexport function createCoreApiClient(clientOptions: ApiClientOptions): ApiClient {\n function buildUrl(requestInit: ApiRequestInit): URL {\n const isLocalhost = clientOptions.apiUrl?.includes('localhost') || clientOptions.apiUrl?.includes('127.0.0.1');\n const { path } = requestInit;\n const { instanceType, domain, apiUrl, apiBasePath = '/api/auth' } = clientOptions;\n const domainInProd = instanceType === 'production' ? domain : '';\n\n let baseUrl: string;\n if (isLocalhost) {\n // For localhost, use http and the apiUrl directly\n baseUrl = apiUrl?.startsWith('http') ? apiUrl : `http://${apiUrl}`;\n } else {\n //const domainInProd = instanceType === 'production' ? domain : '';\n baseUrl = `https://${domainInProd || apiUrl}`;\n }\n\n const fullPath = `${apiBasePath}/${path}`.replace(/\\/+/g, '/'); \n return buildUrlUtil(\n {\n base: baseUrl,\n pathname: fullPath,\n searchParams: requestInit.search ? new URLSearchParams(requestInit.search) : undefined,\n },\n { stringify: false },\n );\n }\n\n async function makeRequest<T>(\n state: ClientState,\n init: ApiRequestInit,\n opts: ApiRequestOptions = {},\n ): Promise<ApiResponse<T>> {\n const requestInit = { ...init };\n const { method = 'GET', body } = requestInit;\n const requestOptions = { ...opts };\n\n requestInit.url = buildUrl({ ...requestInit });\n checkCircuitBreaker(state, requestOptions);\n\n const shouldContinue = await runBeforeRequestHooks(state);\n if (!shouldContinue) {\n const mockResponse = new Response('{}', {\n status: 200,\n }) as ApiResponse<T>;\n mockResponse.payload = { response: {} as T };\n await runAfterResponseHooks(state, mockResponse);\n return mockResponse;\n }\n\n const { timeoutMs } = requestOptions;\n\n const overwrittenRequestMethod = method === 'GET' ? 'GET' : 'POST';\n const url = requestInit.url.toString();\n\n requestInit.headers = new Headers(requestInit.headers);\n\n if (\n method !== 'GET' &&\n !(body instanceof FormData) &&\n !requestInit.headers.has('content-type')\n ) {\n requestInit.headers.set('content-type', 'application/json');\n }\n\n if (requestInit.headers.get('content-type') === 'application/x-www-form-urlencoded') {\n requestInit.body = body\n ? stringifyQueryParams(body as any as Record<string, string>, {\n keyEncoder: camelToSnake,\n })\n : body;\n } else if (requestInit.headers.get('content-type') === 'application/json' && body) {\n requestInit.body = typeof body === 'string' ? body : JSON.stringify(body);\n }\n\n const attemptRequest = async (): Promise<ApiResponse<T>> => {\n const controller = new AbortController();\n const timeoutId = timeoutMs\n ? setTimeout(() => {\n controller.abort();\n }, timeoutMs)\n : null;\n\n let response: Response;\n const fetchOpts: ApiRequestInit = {\n ...requestInit,\n credentials: 'include',\n method: overwrittenRequestMethod,\n };\n\n try {\n response = await fetch(url, fetchOpts);\n\n if (timeoutId) clearTimeout(timeoutId);\n\n let payload: ApiResponseJSON<T> | null = null;\n\n if (response.status === 204) {\n payload = null;\n } else {\n try {\n const json = await response.json();\n payload = json;\n } catch {\n payload = { response: {} as T };\n }\n }\n\n const apiResponse = response as ApiResponse<T>;\n apiResponse.payload = payload;\n\n await runAfterResponseHooks(state, apiResponse);\n\n return apiResponse;\n } catch (error: any) {\n if (timeoutId) clearTimeout(timeoutId);\n\n if (error.name === 'AbortError') {\n throw new TimeoutError();\n }\n\n throw new NetworkError(url, error);\n }\n };\n\n return retryWithBackoff(state, requestOptions, attemptRequest, (error, attempt) =>\n shouldRetry(\n state,\n requestOptions,\n error,\n overwrittenRequestMethod,\n attempt,\n requestOptions.maxTries || (typeof navigator !== 'undefined' && navigator.onLine ? 4 : 11),\n ),\n );\n }\n const state = createInitialState(clientOptions);\n\n return {\n onBeforeRequest: (hook: BeforeRequestHook) => addBeforeRequestHook(state, hook),\n onAfterResponse: (hook: AfterResponseHook) => addAfterResponseHook(state, hook),\n request: <T>(init: ApiRequestInit, opts: ApiRequestOptions = {}) =>\n makeRequest<T>(state, init, opts),\n };\n}\n"],"mappings":"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","names":["state"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createEventBus } from "@tern-secure/shared/eventBus";
|
|
2
2
|
const events = {
|
|
3
|
-
UserChanged: "user:userChanged",
|
|
3
|
+
//UserChanged: "user:userChanged",
|
|
4
4
|
UserSignOut: "user:userSignOut",
|
|
5
5
|
SessionChanged: "session:sessionChanged",
|
|
6
6
|
TokenRefreshed: "token:tokenRefreshed"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/instance/events.ts"],"sourcesContent":["import { createEventBus } from \"@tern-secure/shared/eventBus\";\
|
|
1
|
+
{"version":3,"sources":["../../../src/instance/events.ts"],"sourcesContent":["import { createEventBus } from \"@tern-secure/shared/eventBus\";\n//import type { TernSecureUser } from \"@tern-secure/types\";\nimport type { IdTokenResult } from \"firebase/auth\";\n\nexport const events = {\n //UserChanged: \"user:userChanged\",\n UserSignOut: \"user:userSignOut\",\n SessionChanged: \"session:sessionChanged\",\n TokenRefreshed: \"token:tokenRefreshed\",\n} as const;\n\ntype TokenUpdatePayload = { token: IdTokenResult | null };\n\n\ntype InternalEvents = {\n //[events.UserChanged]: TernSecureUser | null;\n [events.UserSignOut]: null;\n [events.SessionChanged]: null;\n [events.TokenRefreshed]: TokenUpdatePayload;\n};\n\nexport const eventBus = createEventBus<InternalEvents>();\n"],"mappings":"AAAA,SAAS,sBAAsB;AAIxB,MAAM,SAAS;AAAA;AAAA,EAEpB,aAAa;AAAA,EACb,gBAAgB;AAAA,EAChB,gBAAgB;AAClB;AAYO,MAAM,WAAW,eAA+B;","names":[]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { isValidBrowserOnline } from "@tern-secure/shared/browser";
|
|
2
|
-
import { TernSecureAPIResponseError } from "./Error";
|
|
2
|
+
import { TernSecureAPIResponseError, TernSecureRuntimeError } from "./Error";
|
|
3
3
|
class TernSecureBase {
|
|
4
4
|
static ternsecure;
|
|
5
5
|
static get apiClient() {
|
|
@@ -21,11 +21,16 @@ class TernSecureBase {
|
|
|
21
21
|
try {
|
|
22
22
|
apiResponse = await TernSecureBase.apiClient.request(requestInit, { timeoutMs: 1e4 });
|
|
23
23
|
} catch (error) {
|
|
24
|
-
if (
|
|
24
|
+
if (this.shouldRethrowofflineNetworkError()) {
|
|
25
|
+
throw new TernSecureRuntimeError((error == null ? void 0 : error.message) || String(error), {
|
|
26
|
+
code: "OFFLINE_NETWORK_ERROR"
|
|
27
|
+
});
|
|
28
|
+
} else if (!isValidBrowserOnline()) {
|
|
25
29
|
console.warn(error);
|
|
26
30
|
return null;
|
|
31
|
+
} else {
|
|
32
|
+
throw error;
|
|
27
33
|
}
|
|
28
|
-
throw error;
|
|
29
34
|
}
|
|
30
35
|
const { payload, status, statusText, headers } = apiResponse;
|
|
31
36
|
if (headers) {
|
|
@@ -89,6 +94,11 @@ class TernSecureBase {
|
|
|
89
94
|
async makeApiRequest(requestInit) {
|
|
90
95
|
return this.fetchFromCoreApi(requestInit);
|
|
91
96
|
}
|
|
97
|
+
static shouldRethrowofflineNetworkError() {
|
|
98
|
+
var _a, _b;
|
|
99
|
+
const experimental = (_b = (_a = TernSecureBase.ternsecure) == null ? void 0 : _a._internal_getOption) == null ? void 0 : _b.call(_a, "experimental");
|
|
100
|
+
return (experimental == null ? void 0 : experimental.rethrowOfflineNetworkErrors) || false;
|
|
101
|
+
}
|
|
92
102
|
}
|
|
93
103
|
export {
|
|
94
104
|
TernSecureBase
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/resources/Base.ts"],"sourcesContent":["import { isValidBrowserOnline } from '@tern-secure/shared/browser';\nimport type { TernSecureApiErrorJSON } from '@tern-secure/types';\n\nimport type { ApiRequestInit, ApiResponse, ApiResponseJSON } from '../instance/coreApiClient';\n//import { coreApiClient} from '../instance/coreApiClient';\nimport { TernSecureAPIResponseError } from './Error';\nimport type { AuthCookieManager,TernSecureAuth } from './internal';\n\nexport type HTTPMethod =\n | 'CONNECT'\n | 'DELETE'\n | 'GET'\n | 'HEAD'\n | 'OPTIONS'\n | 'PATCH'\n | 'POST'\n | 'PUT'\n | 'TRACE';\n\nexport type PostMutateParams = {\n action?: string | undefined;\n body?: any;\n method?: HTTPMethod | undefined;\n path?: string;\n};\n\nexport abstract class TernSecureBase {\n static ternsecure: TernSecureAuth;\n\n static get apiClient() {\n return TernSecureBase.ternsecure.getApiClient();\n }\n\n static get authCookieManager(): AuthCookieManager | undefined {\n return this.ternsecure.authCookieManager();\n }\n protected get authCookieManager(): AuthCookieManager | undefined {\n return TernSecureBase.authCookieManager;\n }\n\n /**\n * Core method to fetch data from API endpoints using coreApiClient\n * This method handles the complete request lifecycle including error handling\n */\n static async fetchFromCoreApi(requestInit: ApiRequestInit): Promise<ApiResponseJSON<
|
|
1
|
+
{"version":3,"sources":["../../../src/resources/Base.ts"],"sourcesContent":["import { isValidBrowserOnline } from '@tern-secure/shared/browser';\nimport type { TernSecureApiErrorJSON } from '@tern-secure/types';\n\nimport type { ApiRequestInit, ApiResponse, ApiResponseJSON } from '../instance/coreApiClient';\n//import { coreApiClient} from '../instance/coreApiClient';\nimport { TernSecureAPIResponseError, TernSecureRuntimeError } from './Error';\nimport type { AuthCookieManager, TernSecureAuth } from './internal';\n\nexport type HTTPMethod =\n | 'CONNECT'\n | 'DELETE'\n | 'GET'\n | 'HEAD'\n | 'OPTIONS'\n | 'PATCH'\n | 'POST'\n | 'PUT'\n | 'TRACE';\n\nexport type PostMutateParams = {\n action?: string | undefined;\n body?: any;\n method?: HTTPMethod | undefined;\n path?: string;\n};\n\nexport abstract class TernSecureBase {\n static ternsecure: TernSecureAuth;\n\n static get apiClient() {\n return TernSecureBase.ternsecure.getApiClient();\n }\n\n static get authCookieManager(): AuthCookieManager | undefined {\n return this.ternsecure.authCookieManager();\n }\n protected get authCookieManager(): AuthCookieManager | undefined {\n return TernSecureBase.authCookieManager;\n }\n\n /**\n * Core method to fetch data from API endpoints using coreApiClient\n * This method handles the complete request lifecycle including error handling\n */\n protected static async fetchFromCoreApi<J>(\n requestInit: ApiRequestInit,\n ): Promise<ApiResponseJSON<J> | null> {\n let apiResponse: ApiResponse<J>;\n try {\n apiResponse = await TernSecureBase.apiClient.request<J>(requestInit, { timeoutMs: 10000 });\n } catch (error) {\n if (this.shouldRethrowofflineNetworkError()) {\n throw new TernSecureRuntimeError((error as Error)?.message || String(error), {\n code: 'OFFLINE_NETWORK_ERROR',\n });\n } else if (!isValidBrowserOnline()) {\n console.warn(error);\n return null;\n } else {\n throw error;\n }\n }\n\n const { payload, status, statusText, headers } = apiResponse;\n\n if (headers) {\n const country = headers.get('x-country');\n this.ternsecure.__internal_setCountry(country ? country.toLowerCase() : null);\n }\n\n if (status >= 200 && status <= 299) {\n return payload;\n }\n\n if (status >= 400) {\n const errors = payload?.errors as TernSecureApiErrorJSON[];\n const message = errors?.[0]?.message;\n\n const apiResponseOptions: ConstructorParameters<typeof TernSecureAPIResponseError>[1] = {\n data: errors,\n status,\n };\n if (status === 429 && headers) {\n const retryAfter = headers.get('retry-After');\n if (retryAfter) {\n const value = parseInt(retryAfter, 10);\n if (!isNaN(value)) {\n apiResponseOptions.retryAfter = value;\n }\n }\n }\n\n throw new TernSecureAPIResponseError(message || statusText, apiResponseOptions);\n }\n\n return null;\n }\n\n /**\n * Convenience method for making POST requests\n */\n static async basePost(params: PostMutateParams): Promise<ApiResponseJSON<any> | null> {\n return this.fetchFromCoreApi({ ...params, method: 'POST' });\n }\n\n /**\n * Instance method to fetch data from API endpoints\n */\n protected async fetchFromCoreApi(\n requestInit: ApiRequestInit,\n ): Promise<ApiResponseJSON<any> | null> {\n return TernSecureBase.fetchFromCoreApi(requestInit);\n }\n\n /**\n * Instance method for making POST requests\n */\n protected async basePost(params: PostMutateParams): Promise<ApiResponseJSON<any> | null> {\n return TernSecureBase.basePost(params);\n }\n\n /**\n * Protected instance method for making POST requests with specific path and body\n * This is designed to be used by child classes like SignIn\n */\n protected async _post(params: PostMutateParams): Promise<ApiResponseJSON<any> | null> {\n return this.basePost({\n path: params.path,\n body: params.body,\n });\n }\n\n static async makeApiRequest(requestInit: ApiRequestInit): Promise<ApiResponseJSON<any> | null> {\n return this.fetchFromCoreApi(requestInit);\n }\n\n protected async makeApiRequest(\n requestInit: ApiRequestInit,\n ): Promise<ApiResponseJSON<any> | null> {\n return this.fetchFromCoreApi(requestInit);\n }\n\n private static shouldRethrowofflineNetworkError(): boolean {\n const experimental = TernSecureBase.ternsecure?._internal_getOption?.('experimental');\n return experimental?.rethrowOfflineNetworkErrors || false;\n }\n}\n"],"mappings":"AAAA,SAAS,4BAA4B;AAKrC,SAAS,4BAA4B,8BAA8B;AAqB5D,MAAe,eAAe;AAAA,EACnC,OAAO;AAAA,EAEP,WAAW,YAAY;AACrB,WAAO,eAAe,WAAW,aAAa;AAAA,EAChD;AAAA,EAEA,WAAW,oBAAmD;AAC5D,WAAO,KAAK,WAAW,kBAAkB;AAAA,EAC3C;AAAA,EACA,IAAc,oBAAmD;AAC/D,WAAO,eAAe;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,aAAuB,iBACrB,aACoC;AA9CxC;AA+CI,QAAI;AACJ,QAAI;AACF,oBAAc,MAAM,eAAe,UAAU,QAAW,aAAa,EAAE,WAAW,IAAM,CAAC;AAAA,IAC3F,SAAS,OAAO;AACd,UAAI,KAAK,iCAAiC,GAAG;AAC3C,cAAM,IAAI,wBAAwB,+BAAiB,YAAW,OAAO,KAAK,GAAG;AAAA,UAC3E,MAAM;AAAA,QACR,CAAC;AAAA,MACH,WAAW,CAAC,qBAAqB,GAAG;AAClC,gBAAQ,KAAK,KAAK;AAClB,eAAO;AAAA,MACT,OAAO;AACL,cAAM;AAAA,MACR;AAAA,IACF;AAEA,UAAM,EAAE,SAAS,QAAQ,YAAY,QAAQ,IAAI;AAEjD,QAAI,SAAS;AACX,YAAM,UAAU,QAAQ,IAAI,WAAW;AACvC,WAAK,WAAW,sBAAsB,UAAU,QAAQ,YAAY,IAAI,IAAI;AAAA,IAC9E;AAEA,QAAI,UAAU,OAAO,UAAU,KAAK;AAClC,aAAO;AAAA,IACT;AAEA,QAAI,UAAU,KAAK;AACjB,YAAM,SAAS,mCAAS;AACxB,YAAM,WAAU,sCAAS,OAAT,mBAAa;AAE7B,YAAM,qBAAkF;AAAA,QACtF,MAAM;AAAA,QACN;AAAA,MACF;AACA,UAAI,WAAW,OAAO,SAAS;AAC7B,cAAM,aAAa,QAAQ,IAAI,aAAa;AAC5C,YAAI,YAAY;AACd,gBAAM,QAAQ,SAAS,YAAY,EAAE;AACrC,cAAI,CAAC,MAAM,KAAK,GAAG;AACjB,+BAAmB,aAAa;AAAA,UAClC;AAAA,QACF;AAAA,MACF;AAEA,YAAM,IAAI,2BAA2B,WAAW,YAAY,kBAAkB;AAAA,IAChF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,aAAa,SAAS,QAAgE;AACpF,WAAO,KAAK,iBAAiB,EAAE,GAAG,QAAQ,QAAQ,OAAO,CAAC;AAAA,EAC5D;AAAA;AAAA;AAAA;AAAA,EAKA,MAAgB,iBACd,aACsC;AACtC,WAAO,eAAe,iBAAiB,WAAW;AAAA,EACpD;AAAA;AAAA;AAAA;AAAA,EAKA,MAAgB,SAAS,QAAgE;AACvF,WAAO,eAAe,SAAS,MAAM;AAAA,EACvC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAgB,MAAM,QAAgE;AACpF,WAAO,KAAK,SAAS;AAAA,MACnB,MAAM,OAAO;AAAA,MACb,MAAM,OAAO;AAAA,IACf,CAAC;AAAA,EACH;AAAA,EAEA,aAAa,eAAe,aAAmE;AAC7F,WAAO,KAAK,iBAAiB,WAAW;AAAA,EAC1C;AAAA,EAEA,MAAgB,eACd,aACsC;AACtC,WAAO,KAAK,iBAAiB,WAAW;AAAA,EAC1C;AAAA,EAEA,OAAe,mCAA4C;AA9I7D;AA+II,UAAM,gBAAe,0BAAe,eAAf,mBAA2B,wBAA3B,4BAAiD;AACtE,YAAO,6CAAc,gCAA+B;AAAA,EACtD;AACF;","names":[]}
|
|
@@ -34,11 +34,7 @@ class SignIn extends TernSecureBase {
|
|
|
34
34
|
withEmailAndPassword = async (params) => {
|
|
35
35
|
try {
|
|
36
36
|
const { email, password } = params;
|
|
37
|
-
const userCredential = await signInWithEmailAndPassword(
|
|
38
|
-
this.auth,
|
|
39
|
-
email,
|
|
40
|
-
password
|
|
41
|
-
);
|
|
37
|
+
const userCredential = await signInWithEmailAndPassword(this.auth, email, password);
|
|
42
38
|
await this.signInWithCredential(userCredential);
|
|
43
39
|
const { user } = userCredential;
|
|
44
40
|
return {
|
|
@@ -60,11 +56,7 @@ class SignIn extends TernSecureBase {
|
|
|
60
56
|
withCredential = async (params) => {
|
|
61
57
|
try {
|
|
62
58
|
const { email, password } = params;
|
|
63
|
-
const userCredential = await signInWithEmailAndPassword(
|
|
64
|
-
this.auth,
|
|
65
|
-
email,
|
|
66
|
-
password
|
|
67
|
-
);
|
|
59
|
+
const userCredential = await signInWithEmailAndPassword(this.auth, email, password);
|
|
68
60
|
await this.signInWithCredential(userCredential);
|
|
69
61
|
} catch (error) {
|
|
70
62
|
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 SignInFormValuesTree,\n SignInResource,\n SignInResponseTree,\n SignInStatus,\n TernSecureUser,\n} from \"@tern-secure/types\";\nimport type {\n Auth,\n 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\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\n\n\ntype FirebaseAuthResult = UserCredential | void;\n\ntype AuthMethodFunction = (\n auth: Auth,\n provider: GoogleAuthProvider | OAuthProvider\n) => Promise<FirebaseAuthResult>;\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\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 \n\n\n withEmailAndPassword = async (\n params: SignInFormValuesTree\n ): Promise<SignInResponseTree> => {\n try {\n const { email, password } = params;\n const userCredential = await signInWithEmailAndPassword(\n this.auth,\n email,\n password\n );\n \n await this.signInWithCredential(userCredential);\n\n const { user } = userCredential;\n return {\n success: true,\n message: \"Authentication successful\",\n user,\n error: !user.emailVerified ? \"REQUIRES_VERIFICATION\" : \"AUTHENTICATED\",\n };\n } catch (error) {\n const authError = handleFirebaseAuthError(error);\n return {\n success: false,\n message: authError.message,\n error: authError.code,\n user: null,\n };\n }\n };\n\n withCredential = async (params: SignInFormValuesTree): Promise<void> => {\n try {\n const { email, password } = params;\n const userCredential = await signInWithEmailAndPassword(\n this.auth,\n email,\n password\n );\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: string,\n options?: {\n mode?: \"popup\" | \"redirect\";\n }\n ): Promise<SignInResponseTree | void> => {\n try {\n if (options?.mode === \"redirect\") {\n const redirectResult = await this.authRedirectResult();\n\n if (redirectResult) {\n if (redirectResult.success) {\n console.log(\"Redirect after sign in\");\n }\n return redirectResult;\n }\n\n await this._signInWithRedirect(provider);\n return;\n } else {\n await this._signInWithPopUp(provider);\n return {\n success: true,\n message: \"Sign in successful\",\n };\n }\n } catch (error: any) {\n return {\n success: false,\n message: error.message || `Sign in with ${provider} failed`,\n error,\n user: null,\n };\n }\n };\n\n completeMfaSignIn = async (\n _mfaToken: string,\n _mfaContext?: any\n ): Promise<SignInResponseTree> => {\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 success: true,\n message: \"Email is already verified. You can sign in.\",\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 success: true,\n message: \"Verification email sent. Please check your inbox.\",\n isVerified: false,\n };\n };\n\n private getProviderConfig(providerName: string): ProviderConfig {\n switch (providerName.toLowerCase()) {\n case \"google\": {\n const googleProvider = new GoogleAuthProvider();\n return {\n provider: googleProvider,\n customParameters: {\n login_hint: \"user@example.com\",\n prompt: \"select_account\",\n },\n };\n }\n case \"microsoft\": {\n const microsoftProvider = new OAuthProvider(\"microsoft.com\");\n return {\n provider: microsoftProvider,\n customParameters: {\n prompt: \"consent\",\n },\n };\n }\n default:\n throw new Error(`Unsupported provider: ${providerName}`);\n }\n }\n\n private async authRedirectResult(): Promise<SignInResponseTree | null> {\n try {\n const result = await getRedirectResult(this.auth);\n\n if (result) {\n const user = result.user;\n return {\n success: true,\n user,\n };\n }\n return null;\n } catch (error) {\n const authError = handleFirebaseAuthError(error);\n return {\n success: false,\n message: authError.message,\n error: authError.code,\n user: null,\n };\n }\n }\n\n private async executeAuthMethod(\n authMethod: AuthMethodFunction,\n providerName: string\n ): Promise<SignInResponseTree> {\n const config = this.getProviderConfig(providerName);\n config.provider.setCustomParameters(config.customParameters);\n try {\n await authMethod(this.auth, config.provider);\n return { success: true, message: \"Authentication initiated\" };\n } catch (error) {\n const authError = handleFirebaseAuthError(error);\n return {\n success: false,\n message: authError.message,\n error: authError.code,\n user: null,\n };\n }\n }\n\n private async _signInWithRedirect(\n providerName: string\n ): Promise<SignInResponseTree> {\n return this.executeAuthMethod(signInWithRedirect, providerName);\n }\n\n private async _signInWithPopUp(\n providerName: string\n ): Promise<SignInResponseTree> {\n return this.executeAuthMethod(signInWithPopup, providerName);\n }\n\n public async checkRedirectResult(): Promise<SignInResponseTree | 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 SignInFormValuesTree,\n SignInResource,\n SignInResponseTree,\n SignInStatus,\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\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\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: SignInFormValuesTree): Promise<SignInResponseTree> => {\n try {\n const { email, password } = params;\n const userCredential = await signInWithEmailAndPassword(this.auth, email, password);\n\n await this.signInWithCredential(userCredential);\n\n const { user } = userCredential;\n return {\n success: true,\n message: 'Authentication successful',\n user,\n error: !user.emailVerified ? 'REQUIRES_VERIFICATION' : 'AUTHENTICATED',\n };\n } catch (error) {\n const authError = handleFirebaseAuthError(error);\n return {\n success: false,\n message: authError.message,\n error: authError.code,\n user: null,\n };\n }\n };\n\n withCredential = async (params: SignInFormValuesTree): 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: string,\n options?: {\n mode?: 'popup' | 'redirect';\n },\n ): Promise<SignInResponseTree | void> => {\n try {\n if (options?.mode === 'redirect') {\n const redirectResult = await this.authRedirectResult();\n\n if (redirectResult) {\n if (redirectResult.success) {\n console.log('Redirect after sign in');\n }\n return redirectResult;\n }\n\n await this._signInWithRedirect(provider);\n return;\n } else {\n await this._signInWithPopUp(provider);\n return {\n success: true,\n message: 'Sign in successful',\n };\n }\n } catch (error: any) {\n return {\n success: false,\n message: error.message || `Sign in with ${provider} failed`,\n error,\n user: null,\n };\n }\n };\n\n completeMfaSignIn = async (_mfaToken: string, _mfaContext?: any): Promise<SignInResponseTree> => {\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 success: true,\n message: 'Email is already verified. You can sign in.',\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 success: true,\n message: 'Verification email sent. Please check your inbox.',\n isVerified: false,\n };\n };\n\n private getProviderConfig(providerName: string): ProviderConfig {\n switch (providerName.toLowerCase()) {\n case 'google': {\n const googleProvider = new GoogleAuthProvider();\n return {\n provider: googleProvider,\n customParameters: {\n login_hint: 'user@example.com',\n prompt: 'select_account',\n },\n };\n }\n case 'microsoft': {\n const microsoftProvider = new OAuthProvider('microsoft.com');\n return {\n provider: microsoftProvider,\n customParameters: {\n prompt: 'consent',\n },\n };\n }\n default:\n throw new Error(`Unsupported provider: ${providerName}`);\n }\n }\n\n private async authRedirectResult(): Promise<SignInResponseTree | null> {\n try {\n const result = await getRedirectResult(this.auth);\n\n if (result) {\n const user = result.user;\n return {\n success: true,\n user,\n };\n }\n return null;\n } catch (error) {\n const authError = handleFirebaseAuthError(error);\n return {\n success: false,\n message: authError.message,\n error: authError.code,\n user: null,\n };\n }\n }\n\n private async executeAuthMethod(\n authMethod: AuthMethodFunction,\n providerName: string,\n ): Promise<SignInResponseTree> {\n const config = this.getProviderConfig(providerName);\n config.provider.setCustomParameters(config.customParameters);\n try {\n await authMethod(this.auth, config.provider);\n return { success: true, message: 'Authentication initiated' };\n } catch (error) {\n const authError = handleFirebaseAuthError(error);\n return {\n success: false,\n message: authError.message,\n error: authError.code,\n user: null,\n };\n }\n }\n\n private async _signInWithRedirect(providerName: string): Promise<SignInResponseTree> {\n return this.executeAuthMethod(signInWithRedirect, providerName);\n }\n\n private async _signInWithPopUp(providerName: string): Promise<SignInResponseTree> {\n return this.executeAuthMethod(signInWithPopup, providerName);\n }\n\n public async checkRedirectResult(): Promise<SignInResponseTree | null> {\n return this.authRedirectResult();\n }\n}\n"],"mappings":"AAAA,SAAS,+BAA+B;AAUxC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP,SAAS,sBAAsB;AAqBxB,MAAM,eAAe,eAAyC;AAAA,EACnE,WAAW;AAAA,EAEX;AAAA,EACQ;AAAA,EACA;AAAA,EACA,eAAsC;AAAA,EAE9C,YAAY,MAAY,WAA+B;AACrD,UAAM;AACN,SAAK,OAAO;AACZ,SAAK,YAAY;AAAA,EACnB;AAAA,EAEA,uBAAuB,OAAO,eAA+B;AAC3D,UAAM,UAAU,MAAM,WAAW,KAAK,WAAW;AACjD,UAAM,SAAS;AAAA,MACb;AAAA,MACA,WAAW,KAAK;AAAA,IAClB;AAEA,WAAO,KAAK,MAAM;AAAA,MAChB,MAAM,KAAK;AAAA,MACX,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAAA,EAEA,uBAAuB,OAAO,WAA8D;AAC1F,QAAI;AACF,YAAM,EAAE,OAAO,SAAS,IAAI;AAC5B,YAAM,iBAAiB,MAAM,2BAA2B,KAAK,MAAM,OAAO,QAAQ;AAElF,YAAM,KAAK,qBAAqB,cAAc;AAE9C,YAAM,EAAE,KAAK,IAAI;AACjB,aAAO;AAAA,QACL,SAAS;AAAA,QACT,SAAS;AAAA,QACT;AAAA,QACA,OAAO,CAAC,KAAK,gBAAgB,0BAA0B;AAAA,MACzD;AAAA,IACF,SAAS,OAAO;AACd,YAAM,YAAY,wBAAwB,KAAK;AAC/C,aAAO;AAAA,QACL,SAAS;AAAA,QACT,SAAS,UAAU;AAAA,QACnB,OAAO,UAAU;AAAA,QACjB,MAAM;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAAA,EAEA,iBAAiB,OAAO,WAAgD;AACtE,QAAI;AACF,YAAM,EAAE,OAAO,SAAS,IAAI;AAC5B,YAAM,iBAAiB,MAAM,2BAA2B,KAAK,MAAM,OAAO,QAAQ;AAClF,YAAM,KAAK,qBAAqB,cAAc;AAAA,IAChD,SAAS,OAAO;AACd,YAAM,YAAY,wBAAwB,KAAK;AAC/C,cAAQ,MAAM,SAAS;AAAA,IACzB;AAAA,EACF;AAAA,EAEA,qBAAqB,OACnB,UACA,YAGuC;AACvC,QAAI;AACF,WAAI,mCAAS,UAAS,YAAY;AAChC,cAAM,iBAAiB,MAAM,KAAK,mBAAmB;AAErD,YAAI,gBAAgB;AAClB,cAAI,eAAe,SAAS;AAC1B,oBAAQ,IAAI,wBAAwB;AAAA,UACtC;AACA,iBAAO;AAAA,QACT;AAEA,cAAM,KAAK,oBAAoB,QAAQ;AACvC;AAAA,MACF,OAAO;AACL,cAAM,KAAK,iBAAiB,QAAQ;AACpC,eAAO;AAAA,UACL,SAAS;AAAA,UACT,SAAS;AAAA,QACX;AAAA,MACF;AAAA,IACF,SAAS,OAAY;AACnB,aAAO;AAAA,QACL,SAAS;AAAA,QACT,SAAS,MAAM,WAAW,gBAAgB,QAAQ;AAAA,QAClD;AAAA,QACA,MAAM;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAAA,EAEA,oBAAoB,OAAO,WAAmB,gBAAmD;AAC/F,UAAM,IAAI,MAAM,yBAAyB;AAAA,EAC3C;AAAA,EAEA,yBAAyB,OAAO,UAAiC;AAC/D,YAAQ,IAAI,mCAAmC,KAAK,EAAE;AAAA,EACxD;AAAA,EAEA,0BAA0B,YAA8C;AACtE,UAAM,OAAO,KAAK;AAClB,QAAI,CAAC,MAAM;AACT,YAAM,IAAI,MAAM,gCAAgC;AAAA,IAClD;AAEA,UAAM,KAAK,OAAO;AAElB,QAAI,KAAK,eAAe;AACtB,aAAO;AAAA,QACL,SAAS;AAAA,QACT,SAAS;AAAA,QACT,YAAY;AAAA,MACd;AAAA,IACF;AAEA,UAAM,qBAAqB;AAAA,MACzB,KAAK;AAAA;AAAA,MACL,iBAAiB;AAAA,IACnB;AAEA,UAAM,sBAAsB,MAAM,kBAAkB;AACpD,WAAO;AAAA,MACL,SAAS;AAAA,MACT,SAAS;AAAA,MACT,YAAY;AAAA,IACd;AAAA,EACF;AAAA,EAEQ,kBAAkB,cAAsC;AAC9D,YAAQ,aAAa,YAAY,GAAG;AAAA,MAClC,KAAK,UAAU;AACb,cAAM,iBAAiB,IAAI,mBAAmB;AAC9C,eAAO;AAAA,UACL,UAAU;AAAA,UACV,kBAAkB;AAAA,YAChB,YAAY;AAAA,YACZ,QAAQ;AAAA,UACV;AAAA,QACF;AAAA,MACF;AAAA,MACA,KAAK,aAAa;AAChB,cAAM,oBAAoB,IAAI,cAAc,eAAe;AAC3D,eAAO;AAAA,UACL,UAAU;AAAA,UACV,kBAAkB;AAAA,YAChB,QAAQ;AAAA,UACV;AAAA,QACF;AAAA,MACF;AAAA,MACA;AACE,cAAM,IAAI,MAAM,yBAAyB,YAAY,EAAE;AAAA,IAC3D;AAAA,EACF;AAAA,EAEA,MAAc,qBAAyD;AACrE,QAAI;AACF,YAAM,SAAS,MAAM,kBAAkB,KAAK,IAAI;AAEhD,UAAI,QAAQ;AACV,cAAM,OAAO,OAAO;AACpB,eAAO;AAAA,UACL,SAAS;AAAA,UACT;AAAA,QACF;AAAA,MACF;AACA,aAAO;AAAA,IACT,SAAS,OAAO;AACd,YAAM,YAAY,wBAAwB,KAAK;AAC/C,aAAO;AAAA,QACL,SAAS;AAAA,QACT,SAAS,UAAU;AAAA,QACnB,OAAO,UAAU;AAAA,QACjB,MAAM;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAc,kBACZ,YACA,cAC6B;AAC7B,UAAM,SAAS,KAAK,kBAAkB,YAAY;AAClD,WAAO,SAAS,oBAAoB,OAAO,gBAAgB;AAC3D,QAAI;AACF,YAAM,WAAW,KAAK,MAAM,OAAO,QAAQ;AAC3C,aAAO,EAAE,SAAS,MAAM,SAAS,2BAA2B;AAAA,IAC9D,SAAS,OAAO;AACd,YAAM,YAAY,wBAAwB,KAAK;AAC/C,aAAO;AAAA,QACL,SAAS;AAAA,QACT,SAAS,UAAU;AAAA,QACnB,OAAO,UAAU;AAAA,QACjB,MAAM;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAc,oBAAoB,cAAmD;AACnF,WAAO,KAAK,kBAAkB,oBAAoB,YAAY;AAAA,EAChE;AAAA,EAEA,MAAc,iBAAiB,cAAmD;AAChF,WAAO,KAAK,kBAAkB,iBAAiB,YAAY;AAAA,EAC7D;AAAA,EAEA,MAAa,sBAA0D;AACrE,WAAO,KAAK,mBAAmB;AAAA,EACjC;AACF;","names":[]}
|
|
@@ -37,6 +37,7 @@ export declare class TernSecureAuth implements TernSecureAuthInterface {
|
|
|
37
37
|
getApiClient: () => ApiClient;
|
|
38
38
|
setLoading(isLoading: boolean): void;
|
|
39
39
|
authCookieManager(): AuthCookieManager | undefined;
|
|
40
|
+
_internal_getOption<K extends keyof TernSecureAuthOptions>(key: K): TernSecureAuthOptions[K];
|
|
40
41
|
static getorCreateInstance(options?: TernSecureAuthOptions): TernSecureAuth;
|
|
41
42
|
static clearInstance(): void;
|
|
42
43
|
static initialize(options: TernSecureAuthOptions): TernSecureAuth;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TernAuth.d.ts","sourceRoot":"","sources":["../../../src/instance/TernAuth.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAEV,YAAY,EACZ,gBAAgB,EAEhB,eAAe,EACf,qBAAqB,EACrB,cAAc,EACd,kBAAkB,EAClB,OAAO,EAEP,qBAAqB,EACrB,cAAc,EACd,cAAc,IAAI,uBAAuB,EACzC,qBAAqB,EAIrB,aAAa,EACb,cAAc,EACd,mBAAmB,EACpB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,KAAK,EAAQ,IAAI,IAAI,QAAQ,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"TernAuth.d.ts","sourceRoot":"","sources":["../../../src/instance/TernAuth.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"c_coreApiClient.d.ts","sourceRoot":"","sources":["../../../src/instance/c_coreApiClient.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAI/E,MAAM,MAAM,UAAU,GAClB,SAAS,GACT,QAAQ,GACR,KAAK,GACL,MAAM,GACN,SAAS,GACT,OAAO,GACP,MAAM,GACN,KAAK,GACL,OAAO,CAAC;AAEZ,MAAM,MAAM,cAAc,GAAG,WAAW,GAAG;IACzC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,qBAAqB,CAAC,OAAO,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,GAAG,CAAC;CACX,CAAC;AAEF,MAAM,WAAW,eAAe,CAAC,CAAC;IAChC,QAAQ,EAAE,CAAC,CAAC;IACZ,MAAM,CAAC,EAAE,sBAAsB,EAAE,CAAC;CACnC;AAED,MAAM,MAAM,WAAW,CAAC,CAAC,IAAI,QAAQ,GAAG;IAAE,OAAO,EAAE,eAAe,CAAC,CAAC,CAAC,GAAG,IAAI,CAAA;CAAE,CAAC;AAE/E,MAAM,MAAM,kBAAkB,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,cAAc,EAAE,QAAQ,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC;AAEpG,MAAM,WAAW,iBAAiB;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,SAAS;IACxB,eAAe,EAAE,CAAC,IAAI,EAAE,iBAAiB,KAAK,IAAI,CAAC;IACnD,eAAe,EAAE,CAAC,IAAI,EAAE,iBAAiB,KAAK,IAAI,CAAC;IACnD,OAAO,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,CAAC,EAAE,iBAAiB,KAAK,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;CACzF;AAED,MAAM,MAAM,iBAAiB,GAAG,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AACjE,MAAM,MAAM,iBAAiB,GAAG,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,CAAC,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AAG3F,qBAAa,YAAa,SAAQ,KAAK;IAE5B,GAAG,EAAE,MAAM;IACX,QAAQ,EAAE,KAAK;gBADf,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,KAAK;CAKzB;AAED,qBAAa,YAAa,SAAQ,KAAK;;CAKtC;AAED,qBAAa,gBAAiB,SAAQ,KAAK;;CAK1C;AAED,qBAAa,SAAU,SAAQ,KAAK;IAEzB,MAAM,EAAE,MAAM;IACd,GAAG,EAAE,MAAM;IACX,IAAI,CAAC,EAAE,GAAG;gBAFV,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,MAAM,EACX,IAAI,CAAC,EAAE,GAAG,YAAA;CAKpB;AA4ID,wBAAgB,mBAAmB,CAAC,aAAa,EAAE,gBAAgB,GAAG,SAAS,
|
|
1
|
+
{"version":3,"file":"c_coreApiClient.d.ts","sourceRoot":"","sources":["../../../src/instance/c_coreApiClient.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAI/E,MAAM,MAAM,UAAU,GAClB,SAAS,GACT,QAAQ,GACR,KAAK,GACL,MAAM,GACN,SAAS,GACT,OAAO,GACP,MAAM,GACN,KAAK,GACL,OAAO,CAAC;AAEZ,MAAM,MAAM,cAAc,GAAG,WAAW,GAAG;IACzC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,qBAAqB,CAAC,OAAO,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,GAAG,CAAC;CACX,CAAC;AAEF,MAAM,WAAW,eAAe,CAAC,CAAC;IAChC,QAAQ,EAAE,CAAC,CAAC;IACZ,MAAM,CAAC,EAAE,sBAAsB,EAAE,CAAC;CACnC;AAED,MAAM,MAAM,WAAW,CAAC,CAAC,IAAI,QAAQ,GAAG;IAAE,OAAO,EAAE,eAAe,CAAC,CAAC,CAAC,GAAG,IAAI,CAAA;CAAE,CAAC;AAE/E,MAAM,MAAM,kBAAkB,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,cAAc,EAAE,QAAQ,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC;AAEpG,MAAM,WAAW,iBAAiB;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,SAAS;IACxB,eAAe,EAAE,CAAC,IAAI,EAAE,iBAAiB,KAAK,IAAI,CAAC;IACnD,eAAe,EAAE,CAAC,IAAI,EAAE,iBAAiB,KAAK,IAAI,CAAC;IACnD,OAAO,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,CAAC,EAAE,iBAAiB,KAAK,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;CACzF;AAED,MAAM,MAAM,iBAAiB,GAAG,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AACjE,MAAM,MAAM,iBAAiB,GAAG,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,CAAC,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AAG3F,qBAAa,YAAa,SAAQ,KAAK;IAE5B,GAAG,EAAE,MAAM;IACX,QAAQ,EAAE,KAAK;gBADf,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,KAAK;CAKzB;AAED,qBAAa,YAAa,SAAQ,KAAK;;CAKtC;AAED,qBAAa,gBAAiB,SAAQ,KAAK;;CAK1C;AAED,qBAAa,SAAU,SAAQ,KAAK;IAEzB,MAAM,EAAE,MAAM;IACd,GAAG,EAAE,MAAM;IACX,IAAI,CAAC,EAAE,GAAG;gBAFV,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,MAAM,EACX,IAAI,CAAC,EAAE,GAAG,YAAA;CAKpB;AA4ID,wBAAgB,mBAAmB,CAAC,aAAa,EAAE,gBAAgB,GAAG,SAAS,CA+I9E"}
|
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
import type { TernSecureUser } from "@tern-secure/types";
|
|
2
1
|
import type { IdTokenResult } from "firebase/auth";
|
|
3
2
|
export declare const events: {
|
|
4
|
-
readonly UserChanged: "user:userChanged";
|
|
5
3
|
readonly UserSignOut: "user:userSignOut";
|
|
6
4
|
readonly SessionChanged: "session:sessionChanged";
|
|
7
5
|
readonly TokenRefreshed: "token:tokenRefreshed";
|
|
@@ -10,7 +8,6 @@ type TokenUpdatePayload = {
|
|
|
10
8
|
token: IdTokenResult | null;
|
|
11
9
|
};
|
|
12
10
|
type InternalEvents = {
|
|
13
|
-
[events.UserChanged]: TernSecureUser | null;
|
|
14
11
|
[events.UserSignOut]: null;
|
|
15
12
|
[events.SessionChanged]: null;
|
|
16
13
|
[events.TokenRefreshed]: TokenUpdatePayload;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../../src/instance/events.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../../src/instance/events.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEnD,eAAO,MAAM,MAAM;;;;CAKT,CAAC;AAEX,KAAK,kBAAkB,GAAG;IAAE,KAAK,EAAE,aAAa,GAAG,IAAI,CAAA;CAAE,CAAC;AAG1D,KAAK,cAAc,GAAG;IAEpB,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,IAAI,CAAC;IAC3B,CAAC,MAAM,CAAC,cAAc,CAAC,EAAE,IAAI,CAAC;IAC9B,CAAC,MAAM,CAAC,cAAc,CAAC,EAAE,kBAAkB,CAAC;CAC7C,CAAC;AAEF,eAAO,MAAM,QAAQ;;cAClB,CAAC;;;;+EAAghB,GAAG;CAD/d,CAAC"}
|
|
@@ -16,7 +16,7 @@ export declare abstract class TernSecureBase {
|
|
|
16
16
|
* Core method to fetch data from API endpoints using coreApiClient
|
|
17
17
|
* This method handles the complete request lifecycle including error handling
|
|
18
18
|
*/
|
|
19
|
-
static fetchFromCoreApi(requestInit: ApiRequestInit): Promise<ApiResponseJSON<
|
|
19
|
+
protected static fetchFromCoreApi<J>(requestInit: ApiRequestInit): Promise<ApiResponseJSON<J> | null>;
|
|
20
20
|
/**
|
|
21
21
|
* Convenience method for making POST requests
|
|
22
22
|
*/
|
|
@@ -36,5 +36,6 @@ export declare abstract class TernSecureBase {
|
|
|
36
36
|
protected _post(params: PostMutateParams): Promise<ApiResponseJSON<any> | null>;
|
|
37
37
|
static makeApiRequest(requestInit: ApiRequestInit): Promise<ApiResponseJSON<any> | null>;
|
|
38
38
|
protected makeApiRequest(requestInit: ApiRequestInit): Promise<ApiResponseJSON<any> | null>;
|
|
39
|
+
private static shouldRethrowofflineNetworkError;
|
|
39
40
|
}
|
|
40
41
|
//# sourceMappingURL=Base.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Base.d.ts","sourceRoot":"","sources":["../../../src/resources/Base.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAe,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAG9F,OAAO,KAAK,EAAE,iBAAiB,
|
|
1
|
+
{"version":3,"file":"Base.d.ts","sourceRoot":"","sources":["../../../src/resources/Base.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAe,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAG9F,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEpE,MAAM,MAAM,UAAU,GAClB,SAAS,GACT,QAAQ,GACR,KAAK,GACL,MAAM,GACN,SAAS,GACT,OAAO,GACP,MAAM,GACN,KAAK,GACL,OAAO,CAAC;AAEZ,MAAM,MAAM,gBAAgB,GAAG;IAC7B,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,IAAI,CAAC,EAAE,GAAG,CAAC;IACX,MAAM,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,8BAAsB,cAAc;IAClC,MAAM,CAAC,UAAU,EAAE,cAAc,CAAC;IAElC,MAAM,KAAK,SAAS,oDAEnB;IAED,MAAM,KAAK,iBAAiB,IAAI,iBAAiB,GAAG,SAAS,CAE5D;IACD,SAAS,KAAK,iBAAiB,IAAI,iBAAiB,GAAG,SAAS,CAE/D;IAED;;;OAGG;qBACoB,gBAAgB,CAAC,CAAC,EACvC,WAAW,EAAE,cAAc,GAC1B,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IAoDrC;;OAEG;WACU,QAAQ,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;IAIrF;;OAEG;cACa,gBAAgB,CAC9B,WAAW,EAAE,cAAc,GAC1B,OAAO,CAAC,eAAe,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;IAIvC;;OAEG;cACa,QAAQ,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;IAIxF;;;OAGG;cACa,KAAK,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;WAOxE,cAAc,CAAC,WAAW,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;cAI9E,cAAc,CAC5B,WAAW,EAAE,cAAc,GAC1B,OAAO,CAAC,eAAe,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;IAIvC,OAAO,CAAC,MAAM,CAAC,gCAAgC;CAIhD"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { ResendEmailVerification, SignInFormValuesTree, SignInResource, SignInResponseTree, SignInStatus } from
|
|
2
|
-
import type { Auth, UserCredential } from
|
|
3
|
-
import { TernSecureBase } from
|
|
1
|
+
import type { ResendEmailVerification, SignInFormValuesTree, SignInResource, SignInResponseTree, SignInStatus } from '@tern-secure/types';
|
|
2
|
+
import type { Auth, UserCredential } from 'firebase/auth';
|
|
3
|
+
import { TernSecureBase } from './Base';
|
|
4
4
|
export type TernRequestInit = RequestInit;
|
|
5
5
|
export type SignInParams = {
|
|
6
6
|
idToken: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SignIn.d.ts","sourceRoot":"","sources":["../../../src/resources/SignIn.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,uBAAuB,EACvB,oBAAoB,EACpB,cAAc,EACd,kBAAkB,EAClB,YAAY,EAEb,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"SignIn.d.ts","sourceRoot":"","sources":["../../../src/resources/SignIn.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,uBAAuB,EACvB,oBAAoB,EACpB,cAAc,EACd,kBAAkB,EAClB,YAAY,EAEb,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAW1D,OAAO,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AAOxC,MAAM,MAAM,eAAe,GAAG,WAAW,CAAC;AAE1C,MAAM,MAAM,YAAY,GAAG;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;CAC/B,CAAC;AASF,qBAAa,MAAO,SAAQ,cAAe,YAAW,cAAc;IAClE,QAAQ,SAA6B;IAErC,MAAM,CAAC,EAAE,YAAY,GAAG,SAAS,CAAC;IAClC,OAAO,CAAC,IAAI,CAAO;IACnB,OAAO,CAAC,SAAS,CAAqB;IACtC,OAAO,CAAC,YAAY,CAA+B;gBAEvC,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,GAAG,SAAS;IAMrD,oBAAoB,GAAU,YAAY,cAAc,uDAWtD;IAEF,oBAAoB,GAAU,QAAQ,oBAAoB,KAAG,OAAO,CAAC,kBAAkB,CAAC,CAuBtF;IAEF,cAAc,GAAU,QAAQ,oBAAoB,KAAG,OAAO,CAAC,IAAI,CAAC,CASlE;IAEF,kBAAkB,GAChB,UAAU,MAAM,EAChB,UAAU;QACR,IAAI,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC;KAC7B,KACA,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CA6BnC;IAEF,iBAAiB,GAAU,WAAW,MAAM,EAAE,cAAc,GAAG,KAAG,OAAO,CAAC,kBAAkB,CAAC,CAE3F;IAEF,sBAAsB,GAAU,OAAO,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC,CAE3D;IAEF,uBAAuB,QAAa,OAAO,CAAC,uBAAuB,CAAC,CA2BlE;IAEF,OAAO,CAAC,iBAAiB;YA0BX,kBAAkB;YAuBlB,iBAAiB;YAoBjB,mBAAmB;YAInB,gBAAgB;IAIjB,mBAAmB,IAAI,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC;CAGvE"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tern-secure/auth",
|
|
3
|
-
"version": "1.1.0-canary.
|
|
3
|
+
"version": "1.1.0-canary.v20251002175916",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/TernSecure/auth.git",
|
|
@@ -25,8 +25,8 @@
|
|
|
25
25
|
"dependencies": {
|
|
26
26
|
"server-only": "^0.0.1",
|
|
27
27
|
"tslib": "2.4.1",
|
|
28
|
-
"@tern-secure/shared": "1.3.0-canary.
|
|
29
|
-
"@tern-secure/types": "1.1.0-canary.
|
|
28
|
+
"@tern-secure/shared": "1.3.0-canary.v20251002175916",
|
|
29
|
+
"@tern-secure/types": "1.1.0-canary.v20251002175916"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
32
|
"firebase": "^12.0.0",
|