var DBG = DBG || 0; var DBG1 = 1; // var _clientServerTimeDiff = 0; self.addEventListener('install', onInstall); self.addEventListener('activate', onActivate); self.addEventListener('fetch', onFetch); self.addEventListener('message', onMessage); // self.importScripts('') /** IAuthStatus { type: string "expired" | "logged_in" | "logged_in_again" login: string expire: int time: timestamp (seconds) } */ var sessionTimerBuffer = (function () { // var _timeoutId = null; var _lastTimeToExpireSec = null; var _responseTimeMs = null; var _loggedInUser = null; // login var setSessionExpirySec = function (timeToExpire, loggedInUser) { DBG && console.log('DBG:sw:sessionTimerBuffer setSessionExpirySec(', { timeToExpire, loggedInUser }, ')'); _lastTimeToExpireSec = parseInt(timeToExpire); _responseTimeMs = (new Date()).getTime(); if (loggedInUser) _loggedInUser = loggedInUser; }; var getSessionExpirySec = function () { var nowMs = (new Date()).getTime(); return (_lastTimeToExpireSec && _responseTimeMs) ? _lastTimeToExpireSec - Math.floor((nowMs - _responseTimeMs) / 1000) : null; }; var getDiffLastFetchedMs = function () { var nowMs = (new Date()).getTime(); return (_lastTimeToExpireSec && _responseTimeMs) ? (nowMs - _responseTimeMs) : null; }; var getLogin = function () { return _loggedInUser; }; return { setSessionExpirySec: setSessionExpirySec, getSessionExpirySec: getSessionExpirySec, getDiffLastFetchedMs: getDiffLastFetchedMs, getLogin: getLogin, }; })(); function onInstall(event) { DBG && console.log("DBG:sw:install", { event }) if (self.skipWaiting) self.skipWaiting(); } function onActivate(event) { DBG && console.log("DBG:sw:activate", { event }) } function onFetch(event) { // proxy all client requests DBG && console.log("DBG:sw:fetch", { url: event.request.url, clientId: event.clientId, event }) var url = event.request.url; if ('session-expire.php?task=getAuthStatus' === url.substr(url.lastIndexOf('/') + 1)) { var lastFetchedMs = sessionTimerBuffer.getDiffLastFetchedMs(); if (!lastFetchedMs || lastFetchedMs > 2000) { event.respondWith(new Promise(function (resolve, reject) { // var clientRequestTime = Math.floor(Date.now() / 1000); // var clientResponseTime = 0; // var serverResponseTime = 0; fetch(event.request).then(function (response) { // clientResponseTime = Math.floor(Date.now() / 1000); return response.text() }).then(function (responseText) { DBG && console.log("DBG:sw:fetch responseText", { url: event.request.url, clientId: event.clientId, responseText }) try { var json = JSON.parse(responseText); return json; } catch (e) { throw "session_expired"; // resolve(new Response(responseText, { status: 200 })); } }).then(function (data) { // data: IAuthStatus // serverResponseTime = parseInt(data.time); // _clientServerTimeDiff = serverResponseTime - (clientResponseTime + clientRequestTime) / 2; // DBG && console.log("DBG:sw:getAuthStatus timediff", { clientRequestTime, clientResponseTime, serverResponseTime, _clientServerTimeDiff }); var expire = parseInt(data.expire); sessionTimerBuffer.setSessionExpirySec(expire, data.login); resolve(new Response(JSON.stringify(data), { status: 200 })); }).catch(function (err) { resolve(new Response(err, { status: 200 })); }) })) } else { var generatedResponseData = { expire: sessionTimerBuffer.getSessionExpirySec(), login: sessionTimerBuffer.getLogin(), } event.respondWith(Promise.resolve(new Response(JSON.stringify(generatedResponseData), { status: 202 }))); // 202 - Accepted } } if ('session-expire.php?task=getTimer' === url.substr(url.lastIndexOf('/') + 1)) { var lastFetchedMs = sessionTimerBuffer.getDiffLastFetchedMs(); DBG && console.log("DBG:sw:fetch session-expire getTimer", { lastFetchedMs: lastFetchedMs, sesTimerSec: sessionTimerBuffer.getSessionExpirySec(), url: event.request.url, clientId: event.clientId, event }); if (!lastFetchedMs || lastFetchedMs > 2000) { event.respondWith(new Promise(function (resolve, reject) { fetch(event.request).then(function (response) { return response.text() }).then(function (data) { sessionTimerBuffer.setSessionExpirySec(data); resolve(new Response("" + data, { status: 200 })); }).catch(function (err) { reject(new Response("" + err, { status: 200 })); }) })) } else { event.respondWith(Promise.resolve(new Response("" + sessionTimerBuffer.getSessionExpirySec(), { status: 202 }))); // 202 - Accepted } } } function onMessage(event) { DBG && console.log("DBG:sw:Message recieved in service worker:", { data: event.data, clientId: event.source.id, event }); var data = event.data; var clientId = event.source.id; var msgType = (data && data.type) ? data.type || '' : ''; DBG && console.log("DBG:sw:Message type:", { msgType }); if ('logged_in' === msgType) { var lastLogin = sessionTimerBuffer.getLogin(); var login = data.login || ''; var isLoggedInAgain = (lastLogin && login && lastLogin === login); DBG && console.log("DBG:sw:Message logged_in:", { isLoggedInAgain, lastLogin, login, data: event.data, clientId: event.source.id, event }); sessionTimerBuffer.setSessionExpirySec(data.expire, data.login); sendStateToOtherClients( clientId, isLoggedInAgain ? Object.assign(data, { type: 'logged_in_again' }) : data ); } else { sendStateToAllClients(clientId, data); } } sendStateToAllClients = function(clientId, data) { DBG && console.log("DBG:sw:clients (global)", { clients }) clients.matchAll().then(function (clients) { clients.forEach(function (client) { client.postMessage(data); }) }) } sendStateToOtherClients = function(clientId, data) { DBG && console.log("DBG:sw:clients (global)", { clients }) clients.matchAll().then(function (clients) { clients.forEach(function (client) { if (client.id !== clientId) { client.postMessage(data); } }) }) } // versionCheck(); // // async function versionCheck() { // const response = await fetch(SW_VERSION_URL); // const version = await response.text(); // if (version !== VERSION) { // self.registration.update(); // } // }