async function generateSHA256Hash(data) { const buffer = new TextEncoder().encode(data); const hashBuffer = await crypto.subtle.digest("SHA-256", buffer); const hashArray = Array.from(new Uint8Array(hashBuffer)); // convert buffer to byte array const hashHex = hashArray .map((byte) => byte.toString(16).padStart(2, "0")) .join(""); return hashHex; } function validateBase64(s) { if ( !/^(?:[A-Za-z0-9+\/]{2}[A-Za-z0-9+\/]{2})*(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=)?$/.test( s, ) ) { throw new TypeError("invalid encoding"); } } function decodeBase64(s) { validateBase64(s); var i, d = atob(s), b = new Uint8Array(d.length); for (i = 0; i < d.length; i++) b[i] = d.charCodeAt(i); return b; } async function getSettingById(id) { return new Promise((resolve, reject) => { let openRequest = indexedDB.open("TimeSafari"); openRequest.onupgradeneeded = (event) => { // Handle database setup if necessary let db = event.target.result; if (!db.objectStoreNames.contains("settings")) { db.createObjectStore("settings", { keyPath: "id" }); } }; openRequest.onsuccess = (event) => { let db = event.target.result; let transaction = db.transaction("settings", "readonly"); let objectStore = transaction.objectStore("settings"); let getRequest = objectStore.get(id); getRequest.onsuccess = () => resolve(getRequest.result); getRequest.onerror = () => reject(getRequest.error); }; openRequest.onerror = () => reject(openRequest.error); }); } async function fetchAllAccounts() { return new Promise((resolve, reject) => { let openRequest = indexedDB.open("TimeSafariAccounts"); openRequest.onupgradeneeded = function (event) { let db = event.target.result; if (!db.objectStoreNames.contains("accounts")) { db.createObjectStore("accounts", { keyPath: "id" }); } }; openRequest.onsuccess = function (event) { let db = event.target.result; let transaction = db.transaction("accounts", "readonly"); let objectStore = transaction.objectStore("accounts"); let getAllRequest = objectStore.getAll(); getAllRequest.onsuccess = function () { resolve(getAllRequest.result); }; getAllRequest.onerror = function () { reject(getAllRequest.error); }; }; openRequest.onerror = function () { reject(openRequest.error); }; }); } async function getNotificationCount() { let secret = null; let accounts = []; let result = null; if ("secret" in self) { secret = self.secret; const secretUint8Array = self.decodeBase64(secret); const settings = await getSettingById(1); const activeDid = settings["activeDid"]; accounts = await fetchAllAccounts(); let did = null; for (var i = 0; i < accounts.length; i++) { let account = accounts[i]; let did = account["did"]; if (did == activeDid) { let publicKeyHex = account["publicKeyHex"]; let identity = account["identity"]; const messageWithNonceAsUint8Array = self.decodeBase64(identity); const nonce = messageWithNonceAsUint8Array.slice(0, 24); const message = messageWithNonceAsUint8Array.slice(24, identity.length); const decoder = new TextDecoder("utf-8"); const decrypted = self.secretbox.open(message, nonce, secretUint8Array); result = decrypted; break; } } return result; } } self.getNotificationCount = getNotificationCount; self.decodeBase64 = decodeBase64;