{"version":3,"file":"app-d5402680.xxxxxxxx.bundle.js","mappings":"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","sources":["webpack://iadviser/./src/config/plugins.ts","webpack://iadviser/./src/core/events/logout.ts","webpack://iadviser/./src/core/events/base-event.ts","webpack://iadviser/./src/core/events/index.ts","webpack://iadviser/./src/core/fetch-with-retry.ts","webpack://iadviser/./src/core/http-client-config.ts","webpack://iadviser/./src/core/sentry.ts"],"sourcesContent":["import { initialState } from 'store/state';\r\nimport { Aurelia, PLATFORM } from 'aurelia-framework';\r\nimport { I18N, TCustomAttribute } from 'aurelia-i18n';\r\nimport * as Backend from 'i18next-xhr-backend';\r\nimport { environment } from 'environment';\r\nimport { FeatureFlag } from 'feature-flags';\r\n\r\nexport function configurePlugins(aurelia: Aurelia) {\r\n aurelia.use\r\n .standardConfiguration()\r\n .plugin(PLATFORM.moduleName('aurelia-animator-css'))\r\n .plugin(PLATFORM.moduleName('aurelia-dynamic-html'))\r\n .plugin(PLATFORM.moduleName('aurelia-validation'))\r\n .feature(PLATFORM.moduleName('components/forms/phone-number/index'))\r\n .feature(PLATFORM.moduleName('resources/index'))\r\n .feature(PLATFORM.moduleName('components/index'))\r\n .feature(PLATFORM.moduleName('resources/plugins/aurelia-table/index'))\r\n .plugin(PLATFORM.moduleName('aurelia-portal-attribute'))\r\n .plugin(PLATFORM.moduleName('aurelia-application-insights'), (config) => {\r\n config.init('d182b2db-211c-4a36-b950-289015ad8436');\r\n config.attach({\r\n logging: {\r\n enabled: true,\r\n },\r\n logForwarding: {\r\n enabled: true,\r\n },\r\n pageTracking: {\r\n enabled: true,\r\n },\r\n clickTracking: {\r\n enabled: true,\r\n },\r\n });\r\n })\r\n .plugin(PLATFORM.moduleName('aurelia-i18n'), async (instance: I18N) => {\r\n const aliases = ['t', 'i18n'];\r\n // add aliases for 't' attribute\r\n TCustomAttribute.configureAliases(aliases);\r\n\r\n // register backend plugin\r\n instance.i18next.use(Backend);\r\n\r\n // adapt options to your needs (see http://i18next.com/docs/options/)\r\n // make sure to return the promise of the setup method, in order to guarantee proper loading\r\n return instance.setup({\r\n backend: {\r\n // <-- configure backend settings\r\n loadPath: './locales/{{lng}}/{{ns}}.json', // <-- XHR settings for where to get the files from\r\n },\r\n attributes: aliases,\r\n lng: environment.defaultLocale,\r\n ns: ['translation', 'buttonLabels', 'errors', 'lookups', 'navigation'],\r\n defaultNS: 'translation',\r\n fallbackLng: 'en',\r\n debug: false,\r\n });\r\n })\r\n .plugin(PLATFORM.moduleName('aurelia-store'), {\r\n initialState,\r\n measurePerformance: false,\r\n history: {\r\n limit: 2,\r\n },\r\n })\r\n .plugin(PLATFORM.moduleName('resources/plugins/feature-flags/index'), {\r\n defaultFlags: {\r\n [FeatureFlag.christmas]: false,\r\n // Add other default flags as needed\r\n }\r\n });\r\n\r\n if (environment.testing) {\r\n aurelia.use.plugin(PLATFORM.moduleName('aurelia-testing'));\r\n }\r\n}\r\n","import { momentToLocalDateTimeString, newMoment } from 'resources/moment-helpers';\r\nimport { BaseEvent } from './base-event';\r\n\r\nexport class LogoutEvent extends BaseEvent {\r\n protected getEventName(): string {\r\n return 'ia-logout';\r\n }\r\n\r\n protected handleEvent(): void {\r\n // Save the data that should persist across logouts\r\n const RECENT_CLIENTS = JSON.parse(localStorage.getItem('ia_recent_clients')) ?? [];\r\n const THEME = localStorage.getItem('theme');\r\n const DEVICE_ID = localStorage.getItem('deviceId');\r\n const DEVICE_TOKENS = JSON.parse(localStorage.getItem('device_tokens')) ?? [];\r\n\r\n // Clear the localStorage and navigate to the root\r\n localStorage.clear();\r\n window.location.href = '/';\r\n\r\n // Restore the saved data\r\n localStorage.setItem('ia_recent_clients', JSON.stringify(RECENT_CLIENTS));\r\n localStorage.setItem('theme', THEME);\r\n localStorage.setItem('deviceId', DEVICE_ID);\r\n localStorage.setItem('device_tokens', JSON.stringify(DEVICE_TOKENS));\r\n\r\n // Debug information\r\n localStorage.setItem('debug', JSON.stringify({ lastLogout: this.generateLastLogoutDebugInfo() }));\r\n }\r\n\r\n private generateLastLogoutDebugInfo(): string {\r\n return momentToLocalDateTimeString(newMoment());\r\n }\r\n}\r\n","import { EventAggregator } from 'aurelia-event-aggregator';\r\n\r\nexport abstract class BaseEvent {\r\n constructor(protected ea: EventAggregator) {\r\n this.ea.subscribe(this.getEventName(), (data: T) => this.handleEvent(data));\r\n }\r\n\r\n protected abstract getEventName(): string;\r\n protected abstract handleEvent(data: T): void;\r\n}\r\n","import { EventAggregator } from 'aurelia-event-aggregator';\r\nimport { LogoutEvent } from './logout';\r\n\r\nexport function configureEvents(ea: EventAggregator) {\r\n new LogoutEvent(ea);\r\n\r\n // You can add more events here, and configure them similarly\r\n // new SomeOtherEvent(ea);\r\n}\r\n","import { HttpClient } from 'aurelia-fetch-client';\r\n\r\nexport async function fetchWithRetry(http: HttpClient, url: string, maxAttempts = 5) {\r\n for (let attempt = 1; attempt <= maxAttempts; attempt++) {\r\n try {\r\n const response = await http.fetch(url);\r\n return response;\r\n } catch (error) {\r\n if (attempt === maxAttempts) {\r\n throw error; // If this was the last attempt, throw the error\r\n }\r\n await new Promise((resolve) => setTimeout(resolve, attempt * 3000));\r\n }\r\n }\r\n}\r\n","import { EventAggregator } from 'aurelia-event-aggregator';\r\nimport { TokenService } from 'resources/services/token-service';\r\nimport { HttpClient } from 'aurelia-fetch-client';\r\nimport { fetchWithRetry } from './fetch-with-retry';\r\nimport { parseJwt } from 'resources/parse-jwt';\r\nimport { getDeviceTokenForUser } from 'resources/device-token-manager';\r\nimport { httpErrorResponseHandler } from 'resources/utilities/api-error-handler';\r\n\r\nexport function configureHttpClient(http: HttpClient, tokenService: TokenService, ea: EventAggregator) {\r\n http.configure((config) => {\r\n config.withInterceptor({\r\n async request(request: Request) {\r\n const token = tokenService.getAuthToken();\r\n request.headers.append('Authorization', 'Bearer ' + token);\r\n if (tokenService.getDeviceId()) {\r\n request.headers.append('X-Device-Id', tokenService.getDeviceId());\r\n }\r\n if (token) {\r\n const emailAddress = parseJwt(token).sub;\r\n const deviceToken = getDeviceTokenForUser(emailAddress);\r\n if (deviceToken) {\r\n request.headers.append('X-Device-Token', deviceToken);\r\n }\r\n }\r\n return request;\r\n },\r\n async response(response: Response, request: Request) {\r\n if (response.status === 401) {\r\n try {\r\n if (tokenService.getRefreshToken()) {\r\n await tokenService.refreshAuthToken();\r\n const retry: any = await fetchWithRetry(http, response.url);\r\n return retry;\r\n } else {\r\n if (ea) {\r\n ea.publish('ia-logout');\r\n }\r\n }\r\n } catch (e) {\r\n if (ea) {\r\n ea.publish('ia-logout');\r\n }\r\n }\r\n } else if (response.status === 403) {\r\n // 2FA checks not passed - user must login again (all subsequent API requests will be rejected until the user authenticates again)\r\n if (ea) {\r\n ea.publish('ia-logout');\r\n }\r\n } else if (response.status === 400) {\r\n // cloning the response is extremely important so we don't step on other code's toes,\r\n // this is because a Response object's body can only be read once\r\n const responseClone = response.clone();\r\n const responseJSON = await responseClone.json();\r\n\r\n httpErrorResponseHandler(response);\r\n\r\n if (responseJSON && responseJSON.grant_type) {\r\n const redirectEvents = ['invalid_refresh_token', 'invalid_client', 'expired_refresh'];\r\n if (redirectEvents.includes(responseJSON.grant_type)) {\r\n ea.publish('ia-logout');\r\n }\r\n }\r\n } else if (response.status === 500) {\r\n httpErrorResponseHandler(response);\r\n }\r\n\r\n return response;\r\n },\r\n });\r\n });\r\n\r\n return http;\r\n}\r\n","import { Event, init, Replay } from '@sentry/browser';\r\n\r\nconst isNotLocalHost = !window.location.href.includes('localhost');\r\n\r\nconst sentryDsn = 'https://40b9a8f8fd5d41228df0835f956bd078@o217251.ingest.sentry.io/1358951';\r\n\r\nif (isNotLocalHost) {\r\n init({\r\n dsn: sentryDsn,\r\n // Reduce the replaysSessionSampleRate from 0.1 to 0.05 (5% of sessions)\r\n replaysSessionSampleRate: 0.05,\r\n replaysOnErrorSampleRate: 1.0,\r\n integrations: [new Replay()],\r\n beforeSend(event: Event) {\r\n event.extra = event.extra || {};\r\n event.extra.featureFlags = window.featureFlags;\r\n return event;\r\n }\r\n });\r\n}\r\n"],"names":["configurePlugins","aurelia","use","standardConfiguration","plugin","feature","config","init","attach","logging","enabled","logForwarding","pageTracking","clickTracking","instance","aliases","TCustomAttribute","i18next","setup","backend","loadPath","attributes","lng","ns","defaultNS","fallbackLng","debug","initialState","measurePerformance","history","limit","defaultFlags","getEventName","handleEvent","RECENT_CLIENTS","JSON","parse","localStorage","getItem","THEME","DEVICE_ID","DEVICE_TOKENS","clear","window","location","href","setItem","stringify","lastLogout","this","generateLastLogoutDebugInfo","ea","subscribe","data","configureEvents","LogoutEvent","fetchWithRetry","http","url","maxAttempts","attempt","fetch","Promise","resolve","setTimeout","configureHttpClient","tokenService","configure","withInterceptor","request","token","getAuthToken","headers","append","getDeviceId","emailAddress","sub","deviceToken","response","status","getRefreshToken","refreshAuthToken","publish","clone","json","responseJSON","grant_type","includes","dsn","replaysSessionSampleRate","replaysOnErrorSampleRate","integrations","beforeSend","event","extra","featureFlags"],"sourceRoot":""}