UNPKG

@c8y/bootstrap

Version:

Bootstrap layer

178 lines 6.16 kB
export const TOKEN_KEY = '_tcy8'; export const TFATOKEN_KEY = 'TFAToken'; export const queryParamsThatRequireRedirectToLoginApp = [ // in case of password reset 'email', 'token', // others 'code', 'session_state', 'error', 'error_description' ]; function getClientLib() { return import('@c8y/client'); } export async function loadManifest(client, options) { try { const contextPath = getCurrentContextPath(options); const normalizedContextPath = contextPath?.split('@')[0]; const { data: applicationManifest } = await client.application.getManifestOfContextPath(normalizedContextPath); const { data: application } = await client.application.detail(applicationManifest.id); return application; } catch (ex) { throw ex; } } const attributes = ['key', 'name', 'contextPath']; export function addCssClassesForApp(app) { if (!app) { return; } for (const attr of attributes) { const value = app[attr]; if (!value || typeof value !== 'string') { continue; } const normalizedValue = value.toLowerCase().replace(/[^a-z0-9\-\_]+/g, '-'); document.body.classList.add(`c8y-app-${attr}_${normalizedValue}`); } } export function addCssVariablesForApp(app) { if (!app) { return; } let content = ''; for (const attr of attributes) { const value = app[attr]; if (!value || typeof value !== 'string') { continue; } content += `--c8y-app-${attr}: '${value}';\n`; } if (!content) { return; } const style = document.createElement('style'); style.setAttribute('id', 'app-css-variables'); style.appendChild(document.createTextNode(`:root {\n${content}\n}`)); document.querySelector('body').appendChild(style); } export function redirectToLoginApp(options) { // to redirect back to the current page after login const pathWithSearch = window.location.pathname + window.location.search + window.location.hash; sessionStorage.setItem('c8yRedirectAfterLoginPath', pathWithSearch); const basePathOfLoginApp = options?.loginRedirectPath || '/apps/public/login/'; // use the same query params on login app window.location.href = basePathOfLoginApp + window.location.search; } /** * Redirects to the login application in case the user is not logged in. */ export async function ensureLoggedInIfRequired(options) { const clientAndCurrentUser = await getCurrentUser(); const parsedQuery = new URLSearchParams(window.location.search); const requiresRedirect = queryParamsThatRequireRedirectToLoginApp.some(param => parsedQuery.has(param)); if ((!clientAndCurrentUser && !options?.noLogin) || requiresRedirect) { redirectToLoginApp(options); return false; } let currentTenant = null; if (clientAndCurrentUser) { try { const { data } = await clientAndCurrentUser.client.tenant.current({ withParent: true }); clientAndCurrentUser.client.core.tenant = data.name; currentTenant = data; } catch (ex) { console.warn('Error while getting current tenant', ex); } } let currentApp = { name: options.name, contextPath: getCurrentContextPath(), icon: options.icon }; if (clientAndCurrentUser) { try { currentApp = await loadManifest(clientAndCurrentUser.client, options); } catch (ex) { if (!(ex.res && ex.res.status === 404 && isLocal())) { // User was most likely already logged in, but does not have access to the app console.warn('Error while getting current app', ex); console.warn('You probably do not have access to this app'); redirectToLoginApp(options); return false; } } } addCssClassesForApp(currentApp); addCssVariablesForApp(currentApp); return { ...clientAndCurrentUser, currentApp, currentTenant }; } export function isLocal() { const hostname = window.location.hostname; const localhostRegExp = new RegExp('localhost'); const localhostIpRegExp = new RegExp('127.0.0.1'); return localhostIpRegExp.test(hostname) || localhostRegExp.test(hostname); } export function getCurrentContextPath(options = {}) { const match = window.location.pathname.match(/\/apps\/(public\/){0,1}(.+?)(\/|\?|#|$)/); return (match && match[2]) || options.contextPath; } export async function getCurrentUser() { let client; let currentUser; try { const clientLib = await getClientLib(); client = new clientLib.Client(await getAuthStrategy()); try { const { data } = await client.user.current(); currentUser = data; } catch (e) { if (e.res?.status === 403) { const { data } = await client.user.currentWithEffectiveRoles(); currentUser = data; } else { throw e; } } } catch (e) { return null; } return { client, currentUser }; } export function pickAuthStrategy(bearer, basic, cookie) { try { const authStrategy = new bearer(); console.log(`Using BearerAuthFromSessionStorage`); return authStrategy; } catch (e) { // do nothing } const token = getStoredToken(); const tfa = getStoredTfaToken(); if (token) { return new basic({ token, tfa }); } return new cookie(); } export async function getAuthStrategy() { const clientLib = await getClientLib(); return pickAuthStrategy(clientLib.BearerAuthFromSessionStorage, clientLib.BasicAuth, clientLib.CookieAuth); } export function getStoredToken() { return localStorage.getItem(TOKEN_KEY) || sessionStorage.getItem(TOKEN_KEY); } export function getStoredTfaToken() { return localStorage.getItem(TFATOKEN_KEY) || sessionStorage.getItem(TFATOKEN_KEY); } //# sourceMappingURL=login-check.js.map