{"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","i","App","props","_refreshTokenTimer","state","loaded","this","clearTimeout","user","console","log","timeToExpireMs","getTimeToTokenExpiration","setTimeout","refreshExpiredToken","err","warn","s","setState","tenant","global","logoUrl","src","alt","displayName","className","theme","undefined","window","matchMedia","matches","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","inputs","retrieveInputs","toLowerCase","aumlManifest","appManifest","auml","appDescription","aumlContent","serviceName","packageVersions","languages","onProgress","progress","input","manifest","getMode","getLogo","redirectUrl","href","url","clusterUrl","encodeURIComponent","fetch","ok","React","Component","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","render","StrictMode","getElementById"],"mappings":"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","file":"static/js/main.069b1664.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 = 1443;","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 = 404;","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}\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 }\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 />\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\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":""}