/** * Orchestrator boot adapter: JWT, enterprise scope, API base for copied WESP static UI. */ (function (global) { const cfg = global.__WESP_ORCH__ || {}; const API_BASE = cfg.apiBase || "/api/v1"; const AUTH_MAP = { "/api/auth/change_credentials": "/api/v1/users/me/password", }; const WESP_API_PREFIXES = [ "/api/admin/", "/api/notifications", "/api/updates/", "/api/sync/", "/api/feed_dispensers", "/api/components", "/api/recipes", "/api/reports", "/api/analytics/", "/api/feed-quality/", "/api/periods", "/api/sklad", "/api/feed-accounting", "/api/daily-plan", "/api/lab", "/api/auth/", ]; const TOKEN_KEY = "compton.access_token"; const ENTERPRISE_KEY = "compton.enterprise_id"; function readToken() { return ( (global.__WESP_ORCH__ && global.__WESP_ORCH__.accessToken) || global.localStorage.getItem(TOKEN_KEY) || "" ); } function readEnterpriseId() { return ( (global.__WESP_ORCH__ && global.__WESP_ORCH__.enterpriseId) || global.localStorage.getItem(ENTERPRISE_KEY) || "" ); } function persistAccessToken(token, user) { if (!token) return; global.localStorage.setItem(TOKEN_KEY, token); const entId = readEnterpriseId(); if (global.ComptonWespAuth && typeof global.ComptonWespAuth.persistSession === "function") { global.ComptonWespAuth.persistSession(token, user || null, entId); return; } global.__WESP_ORCH__ = Object.assign({}, global.__WESP_ORCH__ || {}, { accessToken: token, enterpriseId: entId, }); } let refreshInFlight = null; function tryRefreshAccessToken() { if (refreshInFlight) return refreshInFlight; refreshInFlight = nativeFetch("/api/v1/auth/refresh", { method: "POST", credentials: "include", headers: { "Content-Type": "application/json" }, }) .then(function (resp) { if (!resp.ok) return null; return resp.json(); }) .then(function (data) { if (!data || !data.access_token) return null; persistAccessToken(data.access_token, data.user); return data.access_token; }) .catch(function () { return null; }) .finally(function () { refreshInFlight = null; }); return refreshInFlight; } function shouldAttemptRefresh(url, init) { if (!url || (init && init._authRetried)) return false; if (url.indexOf("/api/v1/auth/refresh") >= 0) return false; if (url.indexOf("/api/auth/login") >= 0) return false; return true; } function retryWithToken(patched, authInit, token) { const retryHeaders = new Headers((authInit && authInit.headers) || {}); retryHeaders.set("Authorization", "Bearer " + token); const retryInit = Object.assign({}, authInit || {}, { headers: retryHeaders, _authRetried: true, }); return nativeFetch(patched, retryInit); } function isExternalUrl(url) { return /^https?:\/\//i.test(url); } function patchUrl(url) { if (typeof url !== "string" || isExternalUrl(url)) return url; for (const [from, to] of Object.entries(AUTH_MAP)) { if (url === from || url.startsWith(from + "?")) { return to + url.slice(from.length); } } if (url.startsWith("/api/v1/sync/")) { return url; } for (let i = 0; i < WESP_API_PREFIXES.length; i++) { if (url.startsWith(WESP_API_PREFIXES[i])) { return url; } } if (url.startsWith("/api/") && !url.startsWith("/api/v1/")) { const rewritten = API_BASE + url.slice(4); return rewritten; } return url; } function withAuth(url, init) { if (isExternalUrl(url)) { return init || {}; } const token = readToken(); const enterpriseId = readEnterpriseId(); const headers = new Headers((init && init.headers) || {}); if (token && !headers.has("Authorization")) { headers.set("Authorization", "Bearer " + token); } if (enterpriseId && !headers.has("X-Enterprise-Id")) { headers.set("X-Enterprise-Id", enterpriseId); } return Object.assign({}, init || {}, { headers }); } function appendEnterpriseQuery(url) { if (isExternalUrl(url)) return url; const enterpriseId = readEnterpriseId(); if (!enterpriseId || url.indexOf("enterprise_id=") >= 0) { return url; } const sep = url.indexOf("?") >= 0 ? "&" : "?"; return url + sep + "enterprise_id=" + encodeURIComponent(enterpriseId); } function needsEnterpriseScope(url) { if (isExternalUrl(url)) return false; for (let i = 0; i < WESP_API_PREFIXES.length; i++) { if (url.startsWith(WESP_API_PREFIXES[i])) { return url.indexOf("enterprise_id=") < 0; } } return false; } function awaitOrchestratorReady() { const ready = global.__WESP_ORCH__ && global.__WESP_ORCH__.ready; return ready && typeof ready.then === "function" ? ready : Promise.resolve(); } const nativeFetch = global.fetch.bind(global); global.fetch = function (input, init) { if (typeof input === "string") { const scopeReady = needsEnterpriseScope(input) ? awaitOrchestratorReady() : Promise.resolve(); return scopeReady.then(function () { const patched = appendEnterpriseQuery(patchUrl(input)); const authInit = withAuth(patched, init); return nativeFetch(patched, authInit).then(function (resp) { if (resp.status !== 401 || !shouldAttemptRefresh(patched, authInit)) { return resp; } return tryRefreshAccessToken().then(function (newToken) { if (!newToken) return resp; return retryWithToken(patched, authInit, newToken); }); }); }); } return nativeFetch(input, withAuth("", init)); }; global.WespOrchestratorBoot = { apiBase: API_BASE, get enterpriseId() { return readEnterpriseId(); }, }; })(window);