1// ì´ë민 ë리 ë¡ê·¸ì¸ í í°ì¸ì§ (ìë² JWTData.impersonatedByAdminId). 2// utils/impersonation.ts ì isImpersonatedToken ê³¼ ê°ì íì â ì´ íì¼ì ë²ë¤ ë° ì ì ì¤í¬ë¦½í¸ë¼ 3// import í ì ìì´ ë¶ê°í¼íê² ë³µì íë¤. í쪽ì ê³ ì¹ë©´ ë¤ë¥¸ 쪽ë ê³ ì¹ ê² (impersonation.test.ts ê° ë ë¤ ê²ì¦). 4// ì´ í í°ì ìë¹ì¤ì커ì ë기면 ìë¹ì¤ìì»¤ê° background sync ë¡ ê·¸ íì ê³ì ì í¸ì 구ë ì 5// ë±ë¡í´, ì´ë민 ë¸ë¼ì°ì ê° íìì í¸ì ê¸°ê¸°ë¡ ë¨ëë¤. íë³ ì¤í¨ ììë 기존 ëìì ì ì§íë¤ 6// (ìë²ë ê°ì claim ì ë³´ê³ ë±ë¡ì ê±°ë¶íë¯ë¡ ì¬ê¸°ì 못 걸ë¬ë ë±ë¡ëì§ë ìëë¤). 7function isImpersonatedAuthToken(token) { 8 try { 9 var payload = token.split('.')[1]; 10 if (!payload) return false; 11 var normalized = payload.replace(/-/g, '+').replace(/_/g, '/'); 12 return Boolean(JSON.parse(atob(normalized)).impersonatedByAdminId); 13 } catch (error) { 14 return false; 15 } 16} 17 18// Function to send auth token to service worker 19function sendAuthTokenToServiceWorker(serviceWorker) { 20 try { 21 // Define known production domains 22 let productionDomains = ['app.flowworks.io', 'flowworks.io', 'api.flowworks.io', 'cdn.flowworks.io']; 23 24 // Define known development domains 25 let developmentDomains = ['dev.flowworks.io', 'dev-api.flowworks.io', 'dev-cdn.flowworks.io']; 26 27 let hostname = window.location.hostname; 28 let tokenName; 29 30 // Explicit environment detection 31 if (productionDomains.includes(hostname)) { 32 tokenName = 'flowworks_accesstoken'; 33 } else if (developmentDomains.includes(hostname) || hostname.includes('dev-')) { 34 tokenName = 'dev_flowworks_accesstoken'; 35 } else if (hostname === 'localhost' || hostname === '127.0.0.1' || hostname.includes('mydomain.com')) { 36 tokenName = 'local_flowworks_accesstoken'; 37 } else { 38 // Fallback for unknown domains - default to development for safety 39 console.warn('Unknown hostname detected:', hostname, '- defaulting to development token'); 40 tokenName = 'dev_flowworks_accesstoken'; 41 } 42 43 // Get auth token from localStorage 44 let token = localStorage.getItem(tokenName); 45 46 if (token && isImpersonatedAuthToken(token)) { 47 return; 48 } 49 50 if (token && serviceWorker) { 51 // Send token to service worker 52 serviceWorker.postMessage({ 53 type: 'UPDATE_AUTH_TOKEN', 54 token: token, 55 }); 56 } 57 } catch (error) { 58 console.error('Failed to send auth token to service worker:', error); 59 } 60} 61 62if ('serviceWorker' in navigator) { 63 console.log('Will the service worker register?'); 64 navigator.serviceWorker 65 .register('/sw.js') 66 .then(function (reg) { 67 console.log('Yes, it did.'); 68 69 // Send auth token to service worker when it's ready 70 if (reg.active) { 71 sendAuthTokenToServiceWorker(reg.active); 72 } 73 74 // Handle service worker updates 75 reg.addEventListener('updatefound', function () { 76 let newWorker = reg.installing; 77 newWorker.addEventListener('statechange', function () { 78 if (newWorker.state === 'activated') { 79 sendAuthTokenToServiceWorker(newWorker); 80 } 81 }); 82 }); 83 }) 84 .catch(function (err) { 85 console.log("No it didn't. This happened:", err); 86 }); 87 88 // ì¼ë¶ íêµ ì¸ì± ë¸ë¼ì°ì (ë¤ì´ë² ì±, ì¹´ì¹´ì¤ ì¹ë·° ë±) / ê´ê³ ì°¨ë¨ íì¥ì´ addEventListener를 89 // íí¹íë©´ì listener targetì ëí´ .tagNameì ê°ì íë¤. window/navigatorë tagNameì´ ìì´ 90 // 그쪽 íí¹ì´ TypeError를 ëì§ëë°, ê·¸ê² ê¸ë¡ë² ìë¬ë¡ ìì ì°ë¦¬ ì림 ìì¤í ê¹ì§ íë¬ì´. 91 // try/catchë¡ ê·¸ ë ¸ì´ì¦ë¥¼ ì°¨ë¨(ì°ë¦¬ 측 ê¸°ë¥ ëììë ìí¥ ìì). 92 try { 93 // Listen for navigation messages from service worker (fallback for browsers without client.navigate support) 94 navigator.serviceWorker.addEventListener('message', function (event) { 95 if (event.data && event.data.type === 'NAVIGATE_TO' && event.data.url) { 96 // Navigate to the specified URL 97 window.location.href = event.data.url; 98 } 99 }); 100 } catch (_e) { /* external addEventListener hook noise */ } 101 102 try { 103 // Update token when storage changes 104 window.addEventListener('storage', function (event) {
105 let tokenNames = ['flowworks_accesstoken', 'dev_flowworks_accesstoken', 'local_flowworks_accesstoken']; 106 if (tokenNames.includes(event.key) && navigator.serviceWorker.controller) { 107 sendAuthTokenToServiceWorker(navigator.serviceWorker.controller); 108 } 109 }); 110 } catch (_e) { /* external addEventListener hook noise */ } 111}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.