UNPKG

impersonation-banner

Version:

A banner that shows when a Keycloak impersonator is active

89 lines (73 loc) 2.84 kB
(function (factory) { typeof define === 'function' && define.amd ? define(factory) : factory(); })((function () { 'use strict'; (function (global) { function parseJwt(token) { try { const payload = token.split('.')[1]; return JSON.parse(atob(payload)); } catch (e) { console.error('[impersonation-banner] Invalid token:', e); return null; } } function checkImpersonation(token) { const decoded = parseJwt(token); const impersonator = decoded?.impersonator; if (impersonator && Object.keys(impersonator).length > 0) { return { isImpersonating: true, impersonator, user: decoded?.preferred_username || decoded?.sub, }; } return { isImpersonating: false }; } function showBanner({ isImpersonating, impersonator, user }) { if (!isImpersonating) return; if (document.getElementById('impersonation-banner')) return; const banner = document.createElement('div'); banner.id = 'impersonation-banner'; banner.style.cssText = ` position: fixed; bottom: 20px; right: 20px; z-index: 9999; background: #f44336; color: white; padding: 15px 20px; border-radius: 8px; font-family: sans-serif; font-size: 14px; box-shadow: 0 0 10px rgba(0,0,0,0.3); `; banner.innerHTML = ` 🔒 You are impersonating <strong>User ${user}</strong><br/> <small>As ${impersonator?.username || 'Unknown'}</small> <button id="stop-impersonation" style="margin-top: 10px; background: white; color: #f44336; border: none; padding: 5px 10px; border-radius: 4px; cursor: pointer;"> Stop Impersonation </button> `; document.body.appendChild(banner); document.getElementById('stop-impersonation')?.addEventListener('click', () => { global.keycloak?.logout?.() ?? location.reload(); }); } function init() { const keycloak = global.keycloak; if (!keycloak || !keycloak.token) { console.warn('[impersonation-banner] Keycloak instance or token not found'); return; } const result = checkImpersonation(keycloak.token); showBanner(result); } // Export if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') { module.exports = { init }; } else { global.ImpersonationBanner = { init }; } })(typeof window !== 'undefined' ? window : globalThis); }));