{"version":3,"sources":["../node_modules/@echino/echino.ui.framework/components/common/externalComponent sync","../node_modules/typescript/lib sync","App.tsx","serviceWorker.ts","index.tsx"],"names":["webpackEmptyContext","req","e","Error","code","keys","resolve","module","exports","id","App","React","Component","constructor","props","super","_refreshTokenTimer","this","state","loaded","inspectorEnabled","window","toggleInspector","setState","console","log","concat","componentDidMount","clearTimeout","user","timeToExpireMs","getTimeToTokenExpiration","setTimeout","refreshExpiredToken","err","warn","componentWillUnmount","progress","s","getLogo","tenant","global","logoUrl","createElement","src","alt","displayName","className","getMode","theme","undefined","matchMedia","matches","retrieveInputs","Object","fromEntries","URLSearchParams","location","search","entries","identityToken","identityTokenKey","name","cookies","document","cookie","split","c","trim","startsWith","slice","length","expires","parseJwt","exp","timeToExpiresMs","Date","getTime","timeToExpireStr","msToTime","toISOString","ms","seconds","Math","floor","minutes","hours","timeString","token","base64","replace","jsonPayload","decodeURIComponent","atob","map","charCodeAt","toString","join","JSON","parse","render","inputs","toLowerCase","aumlManifest","appManifest","auml","_unused","SpaRenderWithBrowserRouter","appDescription","aumlContent","serviceName","packageVersions","languages","onProgress","input","manifest","redirectUrl","href","url","clusterUrl","encodeURIComponent","fetch","ok","isLocalhost","Boolean","hostname","match","register","appName","config","navigator","URL","process","origin","addEventListener","swUrl","headers","then","response","contentType","get","status","indexOf","serviceWorker","ready","registration","unregister","reload","registerValidSW","catch","checkValidServiceWorker","scope","onupdatefound","installingWorker","installing","onstatechange","controller","onUpdate","onSuccess","error","ReactDOM","StrictMode","getElementById"],"mappings":"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","file":"static/js/main.ace8935c.chunk.js","sourcesContent":["function webpackEmptyContext(req) {\n\tvar e = new Error(\"Cannot find module '\" + req + \"'\");\n\te.code = 'MODULE_NOT_FOUND';\n\tthrow e;\n}\nwebpackEmptyContext.keys = function() { return []; };\nwebpackEmptyContext.resolve = webpackEmptyContext;\nmodule.exports = webpackEmptyContext;\nwebpackEmptyContext.id = 1423;","function webpackEmptyContext(req) {\n\tvar e = new Error(\"Cannot find module '\" + req + \"'\");\n\te.code = 'MODULE_NOT_FOUND';\n\tthrow e;\n}\nwebpackEmptyContext.keys = function() { return []; };\nwebpackEmptyContext.resolve = webpackEmptyContext;\nmodule.exports = webpackEmptyContext;\nwebpackEmptyContext.id = 504;","import React from 'react';\r\nimport './App.scss';\r\n\r\nimport { SpaRenderWithBrowserRouter } from '@echino/echino.ui.framework'\r\nimport { SpaRenderStatus } from '@echino/echino.ui.framework/components/SpaBuilder/common/ISpaRenderProps';\r\n\r\n// Global variables coming from the server\r\n// 'declare' them here to avoid typescript compilation errors\r\n\r\n// The auml code of the app to display\r\ndeclare var aumlContent: string;\r\n\r\n// Name of the scenario project this app belongs to\r\ndeclare var serviceName: string;\r\n\r\n// A dicitonary containing the default version of each package\r\ndeclare var packageVersions: { [name: string]: string };\r\n\r\n// Information on the tenant\r\ndeclare var tenant: any;\r\n\r\n// Information on the authenticated user\r\ndeclare var user: any;\r\n\r\n// The languages available for this app\r\ndeclare var languages: string[];\r\n\r\ndeclare var appManifest: string;\r\n\r\ninterface IAppProps {\r\n\r\n}\r\n\r\ninterface IAppState {\r\n loaded: boolean;\r\n inspectorEnabled: boolean;\r\n}\r\n\r\nexport default class App extends React.Component {\r\n\r\n _refreshTokenTimer: NodeJS.Timeout | undefined;\r\n\r\n constructor(props: IAppProps) {\r\n super(props);\r\n\r\n this.state = {\r\n loaded: false,\r\n inspectorEnabled: false\r\n }\r\n\r\n // Add a function that we can call from the browser console, allowing us to debug the page\r\n //TODO we may not want to do that for prod pages\r\n //@ts-ignore\r\n window.toggleInspector = () => {\r\n this.setState({\r\n inspectorEnabled: !this.state.inspectorEnabled\r\n },\r\n () => console.log(`Auml inspector is now ${this.state.inspectorEnabled ? 'enabled' : 'disabled'}`)\r\n )\r\n\r\n } \r\n }\r\n\r\n componentDidMount() {\r\n\r\n try {\r\n // Setup a method to refresh our access token when it expires\r\n if (this._refreshTokenTimer) {\r\n clearTimeout(this._refreshTokenTimer);\r\n }\r\n\r\n if (!user) {\r\n console.log(\"No user found, will not refresh the token\");\r\n return;\r\n }\r\n\r\n let timeToExpireMs = this.getTimeToTokenExpiration();\r\n\r\n if (timeToExpireMs === null) {\r\n console.log(\"No identity token found, attempting refreshing the token in 5 minutes\");\r\n setTimeout(() => this.refreshExpiredToken(), 5 * 60 * 1000);\r\n return;\r\n }\r\n\r\n if (timeToExpireMs <= 0) {\r\n\r\n // Refresh it immediatelty\r\n this.refreshExpiredToken();\r\n }\r\n else {\r\n this._refreshTokenTimer = setTimeout(() => this.refreshExpiredToken(), timeToExpireMs);\r\n }\r\n }\r\n catch (err) {\r\n console.warn(\"Could not setup token refresh timer: \" + err)\r\n }\r\n }\r\n\r\n componentWillUnmount() {\r\n\r\n // Cleanup the refresh of the token\r\n if (this._refreshTokenTimer) {\r\n clearTimeout(this._refreshTokenTimer);\r\n }\r\n }\r\n\r\n progress(s: SpaRenderStatus) {\r\n //console.log('progessStatus ', s);\r\n if (s === 'completed') {\r\n this.setState({ loaded: true })\r\n }\r\n }\r\n\r\n getLogo() {\r\n //@ts-ignore\r\n let tenant: any = global.tenant;\r\n\r\n if (tenant.logoUrl) {\r\n return {tenant.displayName}\r\n }\r\n else {\r\n return
{tenant.displayName}
\r\n }\r\n }\r\n\r\n getMode(theme: boolean | undefined) {\r\n\r\n if (theme !== undefined) {\r\n return theme ? 'dark' : 'light';\r\n }\r\n\r\n if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {\r\n return 'dark'\r\n }\r\n\r\n return 'light'\r\n }\r\n\r\n // Get input from the query parameters in the url\r\n retrieveInputs() {\r\n\r\n return Object.fromEntries(new URLSearchParams(window.location.search).entries());\r\n\r\n }\r\n\r\n getTimeToTokenExpiration(): number | null {\r\n\r\n // The identity token is the only one we have access here on the client\r\n // We use it to know when the access token (which we can't read) will expire\r\n let identityToken: string | null = null;\r\n\r\n let identityTokenKey = `${tenant.name}IdToken=`;\r\n let cookies = document.cookie.split(';');\r\n for (let c of cookies) {\r\n\r\n if (c.trim().startsWith(identityTokenKey))\r\n {\r\n identityToken = c.trim().slice(identityTokenKey.length);\r\n break;\r\n }\r\n }\r\n\r\n if (identityToken === null) {\r\n return null; // token not found\r\n }\r\n\r\n let identityTokenParsed = this.parseJwt(identityToken);\r\n\r\n let expires = identityTokenParsed.exp; // Timestamp in second since Unix epoch\r\n let timeToExpiresMs = expires * 1000 - new Date().getTime();\r\n\r\n let timeToExpireStr = this.msToTime(timeToExpiresMs);\r\n\r\n console.log(`Token will expire at ${new Date(expires * 1000).toISOString()} (in ${timeToExpireStr}), setting up a timer to refresh it`);\r\n\r\n // Refresh it a bit before the expiration (5 min)\r\n timeToExpiresMs -= 5 * 60 * 1000;\r\n\r\n return timeToExpiresMs;\r\n }\r\n\r\n msToTime(ms: number) {\r\n\r\n let seconds = Math.floor((ms / 1000) % 60),\r\n minutes = Math.floor((ms / (1000 * 60)) % 60),\r\n hours = Math.floor((ms / (1000 * 60 * 60)) % 24);\r\n\r\n let timeString = seconds + \" seconds\";\r\n\r\n if (minutes > 0) {\r\n timeString = minutes + \" minutes \" + timeString;\r\n }\r\n\r\n if (hours > 0) {\r\n timeString = hours + \" hours \" + timeString;\r\n }\r\n\r\n return timeString;\r\n }\r\n\r\n parseJwt(token: string) {\r\n var base64Url = token.split('.')[1];\r\n var base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');\r\n var jsonPayload = decodeURIComponent(window.atob(base64).split('').map(function (c) {\r\n return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);\r\n }).join(''));\r\n\r\n return JSON.parse(jsonPayload);\r\n }\r\n\r\n render() {\r\n\r\n //var clusterUrl = this.figureOutClusterUrl();\r\n\r\n let inputs = this.retrieveInputs();\r\n\r\n let theme = undefined;\r\n if (inputs[\"_theme\"]) {\r\n theme = inputs[\"_theme\"].toLowerCase() === \"dark\";\r\n }\r\n\r\n let aumlManifest = null;\r\n\r\n try {\r\n let appManifestObj = JSON.parse(appManifest); \r\n aumlManifest = appManifestObj.auml\r\n }\r\n catch { }\r\n\r\n return (\r\n
\r\n this.progress(s)}\r\n input={inputs}\r\n manifest={aumlManifest}\r\n theme={theme}\r\n inspectorEnabled={this.state.inspectorEnabled}\r\n />\r\n\r\n {!this.state.loaded &&\r\n
\r\n {this.getLogo()}\r\n\r\n \r\n
\r\n }\r\n
\r\n );\r\n }\r\n\r\n async refreshExpiredToken() {\r\n\r\n console.log(\"Token will expire soon, requesting a new one...\");\r\n\r\n // Using the refresh token we ask for a new access token using /portal/login/refresh\r\n // If the refresh token has also expired, we will be redirected to the login page\r\n //TODO the redirection in case of refresh failure doesn't seem to work and if the page is public this is probably not the right move\r\n\r\n let redirectUrl = window.location.href; // Where to send us back in case we need to be redirected to the login page\r\n let url = `${tenant.clusterUrl}/portal/login/refresh?redirectUrl=${encodeURIComponent(redirectUrl)}`;\r\n\r\n let response = await fetch(url);\r\n\r\n if (response.ok) {\r\n // Setup next refresh\r\n let timeToExpireMs = this.getTimeToTokenExpiration();\r\n\r\n if (timeToExpireMs === null) {\r\n console.log(\"No identity token found\");\r\n return;\r\n }\r\n\r\n this._refreshTokenTimer = setTimeout(() => this.refreshExpiredToken(), timeToExpireMs);\r\n }\r\n }\r\n\r\n /*\r\n figureOutClusterUrl(): string {\r\n\r\n //TODO this only work if going through SF reverse proxy\r\n var origin = window.location.origin;\r\n if (typeof fabricAppName !== 'undefined') // Check if the variable has been declared\r\n {\r\n return `${origin}/${fabricAppName}`;\r\n }\r\n\r\n return origin;\r\n }\r\n */\r\n}\r\n\r\n","// This optional code is used to register a service worker.\r\n// register() is not called by default.\r\n\r\n// This lets the app load faster on subsequent visits in production, and gives\r\n// it offline capabilities. However, it also means that developers (and users)\r\n// will only see deployed updates on subsequent visits to a page, after all the\r\n// existing tabs open on the page have been closed, since previously cached\r\n// resources are updated in the background.\r\n\r\n// To learn more about the benefits of this model and instructions on how to\r\n// opt-in, read https://bit.ly/CRA-PWA\r\n\r\nconst isLocalhost = Boolean(\r\n window.location.hostname === 'localhost' ||\r\n // [::1] is the IPv6 localhost address.\r\n window.location.hostname === '[::1]' ||\r\n // 127.0.0.0/8 are considered localhost for IPv4.\r\n window.location.hostname.match(\r\n /^127(?:\\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/\r\n )\r\n);\r\n\r\ntype Config = {\r\n onSuccess?: (registration: ServiceWorkerRegistration) => void;\r\n onUpdate?: (registration: ServiceWorkerRegistration) => void;\r\n};\r\n\r\nexport function register(appName: string, config?: Config) {\r\n if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {\r\n // The URL constructor is available in all browsers that support SW.\r\n const publicUrl = new URL(\r\n process.env.PUBLIC_URL,\r\n window.location.href\r\n );\r\n if (publicUrl.origin !== window.location.origin) {\r\n // Our service worker won't work if PUBLIC_URL is on a different origin\r\n // from what our page is served on. This might happen if a CDN is used to\r\n // serve assets; see https://github.com/facebook/create-react-app/issues/2374\r\n return;\r\n }\r\n\r\n window.addEventListener('load', () => {\r\n //const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`; //React default service worker\r\n const swUrl = `${process.env.PUBLIC_URL}/sw.js`; // Our own service worker\r\n\r\n if (isLocalhost) {\r\n // This is running on localhost. Let's check if a service worker still exists or not.\r\n checkValidServiceWorker(appName, swUrl, config);\r\n\r\n // Add some additional logging to localhost, pointing developers to the\r\n // service worker/PWA documentation.\r\n navigator.serviceWorker.ready.then(() => {\r\n console.log(\r\n 'This web app is being served cache-first by a service ' +\r\n 'worker. To learn more, visit https://bit.ly/CRA-PWA'\r\n );\r\n });\r\n } else {\r\n // Is not localhost. Just register service worker\r\n registerValidSW(appName, swUrl, config);\r\n }\r\n });\r\n }\r\n}\r\n\r\nfunction askNotificationPermission() {\r\n return new Promise(function (resolve, reject) {\r\n const permissionResult = Notification.requestPermission(function (result) {\r\n resolve(result);\r\n });\r\n\r\n if (permissionResult) {\r\n permissionResult.then(resolve, reject);\r\n }\r\n }).then(function (permissionResult) {\r\n return permissionResult === 'granted'\r\n });\r\n}\r\n\r\nfunction registerValidSW(appName: string, swUrl: string, config?: Config) {\r\n\r\n navigator.serviceWorker\r\n .register(swUrl, { scope: `../${appName}` })\r\n .then(registration => {\r\n registration.onupdatefound = () => {\r\n const installingWorker = registration.installing;\r\n if (installingWorker == null) {\r\n return;\r\n }\r\n installingWorker.onstatechange = () => {\r\n if (installingWorker.state === 'installed') {\r\n if (navigator.serviceWorker.controller) {\r\n // At this point, the updated precached content has been fetched,\r\n // but the previous service worker will still serve the older\r\n // content until all client tabs are closed.\r\n console.log(\r\n 'New content is available and will be used when all ' +\r\n 'tabs for this page are closed. See https://bit.ly/CRA-PWA.'\r\n );\r\n\r\n // Execute callback\r\n if (config && config.onUpdate) {\r\n config.onUpdate(registration);\r\n }\r\n } else {\r\n // At this point, everything has been precached.\r\n // It's the perfect time to display a\r\n // \"Content is cached for offline use.\" message.\r\n console.log('Content is cached for offline use.');\r\n\r\n // Execute callback\r\n if (config && config.onSuccess) {\r\n config.onSuccess(registration);\r\n }\r\n }\r\n }\r\n };\r\n };\r\n\r\n // Subscribe to Push Notifications\r\n // --> This is now handled by SpaRender on an user interaction\r\n /*\r\n if (!('PushManager' in window)) {\r\n // Push isn't supported on this browser\r\n console.log(\"Push notification not supported on this browser\");\r\n return;\r\n }\r\n // For the moment, only valid if logged in\r\n //TODO do not subscribe if not logged in\r\n\r\n askNotificationPermission().then((permissionGranted) => {\r\n\r\n console.log(permissionGranted);\r\n\r\n if (!permissionGranted) {\r\n console.log(\"User refused to grant notification permissions\");\r\n return;\r\n }\r\n\r\n const publicVapidKey = \"BBaXk-M1XVuQsQhqXJDIVd6dKiBTOFFhh4BDX9lpichV9CnLrtOjdPnXY8o0jpJmdpmUkttHWA0am6KPFmNbqB8\"; //TODO to be passed by AbstractProject\r\n\r\n // Subcribe will ask for permission if we haven't already but it may not work on some browsers\r\n registration.pushManager.subscribe({\r\n userVisibleOnly: true,\r\n applicationServerKey: publicVapidKey,\r\n }).then(subscription => {\r\n\r\n let parts = registration.scope.split('/');\r\n let projectRoot = parts.slice(0, -1).join('/')\r\n let appName = parts[parts.length - 1];\r\n\r\n fetch(`${projectRoot}/notifications/${appName}/subscribe`, {\r\n method: \"POST\",\r\n body: JSON.stringify(subscription),\r\n headers: {\r\n \"Content-Type\": \"application/json\",\r\n }\r\n })\r\n\r\n });\r\n })\r\n */\r\n\r\n \r\n })\r\n .catch(error => {\r\n console.error('Error during service worker registration:', error);\r\n });\r\n}\r\n\r\nfunction checkValidServiceWorker(appName: string, swUrl: string, config?: Config) {\r\n // Check if the service worker can be found. If it can't reload the page.\r\n fetch(swUrl, {\r\n headers: { 'Service-Worker': 'script' }\r\n })\r\n .then(response => {\r\n // Ensure service worker exists, and that we really are getting a JS file.\r\n const contentType = response.headers.get('content-type');\r\n if (\r\n response.status === 404 ||\r\n (contentType != null && contentType.indexOf('javascript') === -1)\r\n ) {\r\n // No service worker found. Probably a different app. Reload the page.\r\n navigator.serviceWorker.ready.then(registration => {\r\n registration.unregister().then(() => {\r\n window.location.reload();\r\n });\r\n });\r\n } else {\r\n // Service worker found. Proceed as normal.\r\n registerValidSW(appName, swUrl, config);\r\n }\r\n })\r\n .catch(() => {\r\n console.log(\r\n 'No internet connection found. App is running in offline mode.'\r\n );\r\n });\r\n}\r\n\r\nexport function unregister() {\r\n if ('serviceWorker' in navigator) {\r\n navigator.serviceWorker.ready\r\n .then(registration => {\r\n registration.unregister();\r\n })\r\n .catch(error => {\r\n console.error(error.message);\r\n });\r\n }\r\n}\r\n","import React from 'react';\r\nimport ReactDOM from 'react-dom';\r\nimport './index.css';\r\nimport App from './App';\r\nimport * as serviceWorker from './serviceWorker';\r\nimport \"regenerator-runtime/runtime\";\r\n\r\ndeclare var appName: string\r\n\r\n/*const supportsContainerQueries = \"container\" in document.documentElement.style;\r\nif (!supportsContainerQueries) {\r\n import(\"container-query-polyfill\");\r\n}*/\r\n\r\nif(process && process.env.NODE_ENV === 'development'){\r\n //@ts-ignore\r\n global.appName = \"appName\";\r\n //@ts-ignore\r\n global.serviceName = \"serviceName\";\r\n //@ts-ignore\r\n global.tenant = {\r\n tint:'#00704A',\r\n displayName:'Starbucks',\r\n logoUrl:'https://upload.wikimedia.org/wikipedia/fr/d/d3/Starbucks_Corporation_Logo_2011.svg'\r\n };\r\n //@ts-ignore\r\n global.packageVersions = {};\r\n //@ts-ignore\r\n global.user = {\r\n firstName:'John',\r\n lastName:'Doe',\r\n email:'john.doe@gmail.com'\r\n };\r\n //@ts-ignore\r\n global.languages = [\"fr\"];\r\n\r\n //@ts-ignore\r\n //global.aumlContent = import('./devApp.auml').then(v => {return v});\r\n\r\n global.aumlContent = `\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n `\r\n\r\n}\r\n\r\n\r\nReactDOM.render(\r\n \r\n \r\n ,\r\n document.getElementById('root')\r\n);\r\n\r\nconst updateHandler = (registration: ServiceWorkerRegistration) => {\r\n if (window.confirm(\"Update available. Do you want to reload?\")) {\r\n window.location.reload();\r\n }\r\n};\r\n\r\n// Now handled in spaRender\r\n/*\r\n// Listen to notifications from the service worker\r\nnavigator.serviceWorker.onmessage = (event) => {\r\n if (event.data && event.data.type === 'PUSH_NOTIFICATION') {\r\n\r\n //TODO Callbacks\r\n\r\n console.log(event.data);\r\n\r\n }\r\n};\r\n*/\r\n\r\n// If you want your app to work offline and load faster, you can change\r\n// unregister() to register() below. Note this comes with some pitfalls.\r\n// Learn more about service workers: https://bit.ly/CRA-PWA\r\n/*\r\nserviceWorker.register({\r\n onUpdate: updateHandler,\r\n});\r\n*/\r\n//serviceWorker.unregister();\r\n\r\nserviceWorker.register(appName);\r\n"],"sourceRoot":""}