Last active
December 28, 2024 10:57
Revisions
-
AngeloD2022 revised this gist
Dec 16, 2023 . 4 changed files with 18210 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,1760 @@ var pwlog = void 0, pwerror = void 0; function isStringEmpty(e) { return !e || 0 === e.length } function urlFromURLString(e) { try { return new URL(e) } catch { return null } } function humanReadableFormType(e) { switch (e) { case WBSAutoFillFormTypeUndetermined: return "Undetermined"; case WBSAutoFillFormTypeAutoFillableStandard: return "AutoFillable:Standard"; case WBSAutoFillFormTypeNonAutoFillable: return "NonAutoFillable"; case WBSAutoFillFormTypeAutoFillableLogin: return "AutoFillable:Login"; case WBSAutoFillFormTypeNewAccount: return "NewAccount"; case WBSAutoFillFormTypeChangePassword: return "ChangePassword"; case WBSAutoFillFormTypeFoundTOTPURI: return "FoundTOTPUri" } return "Unrecognized" } function domainsForDisplayFromUsernamesAndDomains(e, t) { const s = e.length; let a = t.map((function(e) { return e.replace(/^(www|m)\./, "") })), n = []; for (var r = 0; r < s; r++) n.push([e[r], a[r]]); for (r = 0; r < s; r++) { let e = []; for (var o = r + 1; o < s; o++) n[r].join("\n") === n[o].join("\n") && (e.length || e.push(r), e.push(o)); for (let s of e) a[s] = t[s] } return a } function urlIsBrowserURL(e) { const t = e.protocol; return "chrome:" === t || "edge:" === t || "about:" == t } function isExtensionContextInvalidatedError(e) { return "Extension context invalidated." === e.message } function capabilitiesDeclaresMacOS(e) { try { return "macos" === e.operatingSystem.name } catch { return !1 } } class Localizer { static configureDocumentElementForLanguage(e, t) { switch (t) { case "he": case "ar": case "fa": e.setAttribute("dir", "rtl"), e.setAttribute("lang", t) } } #e = {}; constructor(e) { e && (this.#e = e.operatingSystem) } getMessage(e, t, s) { const a = this.messageNamesToTry(e); for (let e of a) { let a; try { a = chrome.i18n.getMessage(e, t, s) } catch { a = chrome.i18n.getMessage(e, t) } if (a) return a } return "" } messageNamesToTry(e) { let t = []; const s = this.#e, a = s ? s.name : void 0, n = s ? s.majorVersion : void 0, r = s ? s.minorVersion : void 0, o = void 0 !== n; return a && o && void 0 !== r && t.push(`${e}_${a}_${n}_${r}`), a && o && t.push(`${e}_${a}_${n}`), a ? t.push(`${e}_${a}`) : t.push(`${e}_${this.#t}`), t.push(e), t } get #t() { return navigator.platform.startsWith("Mac") ? "macos" : "windows" } } class ExtensionSettings { #s = !1; #a = !0; #n = !0; eventTarget = new EventTarget; constructor(e = !1) { this.#s = e, this.#r(), this.#o() } get enableInPageAutoFill() { return this.#a } set enableInPageAutoFill(e) { this.#a = e, this.#i() } get allowExtensionToControlAutoFillSettings() { return this.#n } set allowExtensionToControlAutoFillSettings(e) { this.#n = e, this.#c().then(this.#i.bind(this)) } #c() { return this.#n ? this.attemptToControlBrowserAutoFillSettings() : this.clearControlOfBrowserAutoFillSettings() } async attemptToControlBrowserAutoFillSettings() { if (this.#s) throw new Error("This Settings instance does not allow writing browser settings"); const e = await Promise.allSettled([this.#l(chrome.privacy.services.passwordSavingEnabled, !1), this.#l(chrome.privacy.services.autofillCreditCardEnabled, !1), this.#l(chrome.privacy.services.autofillAddressEnabled, !1)]); return this.#d(), e } async clearControlOfBrowserAutoFillSettings() { if (this.#s) throw new Error("This Settings instance does not allow writing browser settings"); const e = await Promise.allSettled([this.#m(chrome.privacy.services.passwordSavingEnabled), this.#m(chrome.privacy.services.autofillCreditCardEnabled), this.#m(chrome.privacy.services.autofillAddressEnabled)]); return this.#d(), e } #r() { let e = new Promise((e => { chrome.storage.sync.get({ enableInPageAutoFill: !0, allowExtensionToControlAutoFillSettings: !0 }, (t => { this.#a = t.enableInPageAutoFill, this.#n = t.allowExtensionToControlAutoFillSettings, e() })) })); return this.#s || (e = e.then(this.#c.bind(this))), e.then(this.#d.bind(this)) } #i() { return new Promise((e => { chrome.storage.sync.set({ enableInPageAutoFill: this.#a, allowExtensionToControlAutoFillSettings: this.#n }, e) })).then(this.#d.bind(this)) } #o() { this.#s || (chrome.privacy.services.passwordSavingEnabled && chrome.privacy.services.passwordSavingEnabled.onChange.addListener((e => { this.#d() })), chrome.privacy.services.autofillCreditCardEnabled && chrome.privacy.services.autofillCreditCardEnabled.onChange.addListener((e => { this.#d() })), chrome.privacy.services.autofillAddressEnabled && chrome.privacy.services.autofillAddressEnabled.onChange.addListener((e => { this.#d() }))) } #d() { const e = new CustomEvent("settingsChanged", { detail: { enableInPageAutoFill: this.#a } }); this.eventTarget.dispatchEvent(e) } async #l(e, t) { let s; try { s = await this.#u(e) } catch (e) { return } if (s) { if (s.value === t) return { details: s, newValue: t }; try { s = await e.set({ value: t }) } catch (e) { return } return { details: s, newValue: t } } } async #u(e) { if (!e) throw new Error(`Unable to get ${e} setting.`); const t = await e.get({}); if ("not_controllable" === t.levelOfControl) throw new Error(`Cannot control ${e} setting.`); return t } async #m(e) { if (!e) throw new Error(`Unable to clear browser setting: ${e}.`); await e.clear({}) } } const ErrCodes = { ErrSuccess: "Success", InvalidMessage: "InvalidMessage", UnexpectedMessage: "UnexpectedMessage", InvalidSyntax: "InvalidSyntax", InvalidSessionKey: "InvalidSessionKey", CryptoError: "CryptoError", InvalidUserName: "InvalidUserName" }; class SecretSessionError extends Error { constructor(e, t = null) { super(t), this.code = e } } const SecretSessionVersion = { SRPWithOldVerification: 0, SRPWithRFCVerification: 1 }, scriptVersion = "1.0", appVersion = "1.0", MSGTypes = { MSG0: 0, MSG1: 1, MSG2: 2, MSG3: 3 }; SecretSession = function(e) { this.shouldUseBase64 = !1, e.shouldUseBase64 && (this.shouldUseBase64 = e.shouldUseBase64), this.protocolVersion = SecretSessionVersion.SRPWithOldVerification, e.secretSessionVersion && (this.protocolVersion = e.secretSessionVersion), this.grp = sjcl.keyexchange.srp.knownGroup(3072), this.keyLen = 128, this.tagLen = 128, this.setUpSRP() }, SecretSession.prototype = { createSMSG: function(e) { if ("object" == typeof e) try { e = JSON.stringify(e) } catch (e) { return ErrCodes.InvalidMessage } const t = sjcl.codec.utf8String.toBits(e), s = this.encrypt(t); if ("string" == typeof s) return s; let a = null; try { a = JSON.stringify({ TID: this.bitsToString(this.I.toBits()), SDATA: this.bitsToString(s, !1) }) } catch (e) { return ErrCodes.InvalidMessage } return a }, parseSMSG: function(e) { let t = e; if ("string" == typeof t) try { t = JSON.parse(e) } catch (t) { throw new SecretSessionError(ErrCodes.InvalidSyntax, `Unable to decode SMSG from string: ${t} ${e}`) } if ("string" != typeof t.SDATA) throw new SecretSessionError(ErrCodes.InvalidMessage, "Missing or invalid SDATA field in SMSG message."); if ("string" != typeof t.TID) throw new SecretSessionError(ErrCodes.InvalidUserName, "Missing or invalid 'TID' field in SMSG object."); const s = sjcl.bn.fromBits(this.stringToBits(t.TID)); if (!this.I.equals(s)) throw new SecretSessionError(ErrCodes.InvalidUserName, "Received SMSG message meant for another session."); return sjcl.codec.utf8String.fromBits(this.decrypt(this.stringToBits(t.SDATA))) }, setPin: function(e) { this.P = e }, stringToBase64: function(e) { let t = sjcl.codec.utf8String.toBits(e); return sjcl.codec.base64.fromBits(t, !1, !1) }, bitsToString: function(e, t = !0) { return this.shouldUseBase64 ? sjcl.codec.base64.fromBits(e) : (t ? "0x" : "") + sjcl.codec.hex.fromBits(e) }, stringToBits: function(e) { return this.shouldUseBase64 ? sjcl.codec.base64.toBits(e) : sjcl.codec.hex.toBits(e) }, setUpSRP: function() { this.I = sjcl.bn.fromBits(this._randomWords(4)), this.a = sjcl.bn.fromBits(this._randomWords(8)), this.A = this.grp.g.powermod(this.a, this.grp.N) }, currProtocols: function() { return [SecretSessionVersion.SRPWithOldVerification, SecretSessionVersion.SRPWithRFCVerification] }, initialMessage: function() { this.expectedMessage = MSGTypes.MSG1; let e = null; try { e = JSON.stringify({ TID: this.bitsToString(this.I.toBits()), MSG: 0, A: this.bitsToString(this.A.toBits()), VER: "1.0", PROTO: this.currProtocols() }) } catch (e) { return null } return this.stringToBase64(e) }, _padToModulusLength: function(e) { e = e.replace(/^0x/, ""); const t = 2 * (sjcl.bitArray.bitLength(this.grp.N.toBits()) + 7 >> 3) - e.length; if (0 === t) return e; return "0".repeat(t) + e }, processMessage: function(e) { const t = sjcl.codec.utf8String.fromBits(sjcl.codec.base64.toBits(e)); let s = null; try { s = JSON.parse(t) } catch (e) { throw new SecretSessionError(ErrCodes.InvalidMessage, `Unable to parse JSON message: ${e}`) } if ("string" != typeof s.TID) throw new SecretSessionError(ErrCodes.InvalidMessage, "Missing or invalid 'TID' field in PAKE message."); let a = sjcl.bn.fromBits(this.stringToBits(s.TID)); if (!this.I.equals(a)) throw new SecretSessionError(ErrCodes.UnexpectedMessage, "Unexpected message"); if (!s.MSG) throw new SecretSessionError(ErrCodes.InvalidMessage, "Missing 'MSG' field in PAKE message."); const n = parseInt(s.MSG, 10); if (this.expectedMessage !== n) throw new SecretSessionError(ErrCodes.UnexpectedMessage, `Received Message ${message.MSG}, but expected Message ${this.expectedMessage} `); let r = null; if (n === MSGTypes.MSG1) { var o = SecretSessionVersion.SRPWithOldVerification; "number" == typeof s.PROTO && (o = s.PROTO, Object.values(SecretSessionVersion).includes(o) || (o = SecretSessionVersion.SRPWithOldVerification)), this.protocolVersion = o, r = this.processMessage1(s) } else n === MSGTypes.MSG3 && (r = this.processMessage3(s)); return r }, createSessionKey: function(e, t) { const s = sjcl.hash.sha256.hash, a = this._calculateX(e, this.bitsToString(this.I.toBits()), this.P, s); this.v = this._calculateVerifier(this.grp.g, a, this.grp.N); const n = this.A.toString(), r = t.toString(), o = this._padToModulusLength(n).concat(this._padToModulusLength(r)), i = sjcl.bn.fromBits(s(sjcl.codec.hex.toBits(o))), c = this.a.add(i.mul(a)), l = this.grp.N.toString() + this._padToModulusLength(this.grp.g.toString()), d = sjcl.bn.fromBits(s(sjcl.codec.hex.toBits(l))).mulmod(this.v, this.grp.N); return s(t.sub(d).powermod(c, this.grp.N).toBits()) }, _calculateX: function(e, t, s, a) { const n = a(t + ":" + s); return sjcl.bn.fromBits(a(e.concat(n))) }, _calculateVerifier: function(e, t, s) { return e.powermod(t, s) }, _calculateM: function(e, t, s) { const a = sjcl.hash.sha256.hash; let n = a(this.grp.N.toBits()), r = a(sjcl.codec.hex.toBits(this._padToModulusLength(this.grp.g.toString()))); const o = sjcl.bitArray.bitLength(n) / 32; for (let e = 0; e < o; ++e) n[e] = n[e] ^ r[e]; let i = a(this.bitsToString(this.I.toBits())), c = new sjcl.hash.sha256; c.update(n), c.update(i), c.update(e), c.update(this.A.toBits()), c.update(t.toBits()), c.update(s); let l = c.finalize(); return c = new sjcl.hash.sha256, c.update(this.A.toBits()), c.update(l), c.update(s), this.hamk = c.finalize(), l }, processMessage1: function(e) { if ("string" != typeof e.s || "string" != typeof e.B) throw new SecretSessionError(ErrCodes.InvalidMessage, "Message 1 is missing some required keys."); e.VER && (this.appVer = e.VER); const t = this.stringToBits(e.s), s = sjcl.bn.fromBits(this.stringToBits(e.B)); let a = new sjcl.bn(1); if (0 == s.mulmod(a, this.grp.N)) throw new SecretSessionError(ErrCodes.CryptoError, "B.mulmod error"); const n = this.createSessionKey(t, s); this.encKey = sjcl.bitArray.bitSlice(n, 0, this.keyLen), this.expectedMessage = MSGTypes.MSG3; let r = { TID: this.bitsToString(this.I.toBits()), MSG: 2 }; switch (this.protocolVersion) { case SecretSessionVersion.SRPWithRFCVerification: r.M = this.bitsToString(this._calculateM(t, s, n), !1); break; case SecretSessionVersion.SRPWithOldVerification: const e = this.shouldUseBase64 ? this.v.toBits() : sjcl.codec.utf8String.toBits(this.v.toString()), a = this.encrypt(e); r.v = this.bitsToString(a, !1); break; default: throw new SecretSessionError(ErrCodes.UnexpectedMessage, `Unknown protocol version ${this.protocolVersion}`) } let o = null; try { o = JSON.stringify(r) } catch (e) { throw new SecretSessionError(ErrCodes.InvalidMessage, `Error encoding Message 2 to string:${e}`) } return this.stringToBase64(o) }, processMessage3: function(e) { let t = ErrCodes.ErrSuccess, s = ""; if (0 !== e.ErrCode) s = `Message 3 contained an error: ${e.ErrCode}`, t = ErrCodes.InvalidMessage; else switch (this.protocolVersion) { case SecretSessionVersion.SRPWithRFCVerification: if (e.HAMK) { const a = this.stringToBits(e.HAMK); sjcl.bitArray.equal(a, this.hamk) || (s = "Failed to verify server data.", this.msgExp = MSGTypes.MSG1, t = ErrCodes.InvalidSessionKey) } else s = `Message 3 does not contain necessary data:${e.ErrCode}`, t = ErrCodes.InvalidMessage; break; case SecretSessionVersion.SRPWithOldVerification: break; default: t = ErrCode.UnexpectedMessage, s = `Unknown SecretSessionVersion ${this.protocolVersion}.` } if (t != ErrCodes.ErrSuccess) throw this.sessionKey = null, this.expectedMessage = MSGTypes.MSG1, new SecretSessionError(t, s); return t === ErrCodes.ErrSuccess }, encrypt: function(e) { if (!this.encKey) throw new SecretSessionError(ErrCodes.InvalidSessionKey, "Called encrypt() without a session key"); const t = new sjcl.cipher.aes(this.encKey), s = this._randomWords(4); let a = null; try { a = sjcl.mode.gcm.encrypt(t, e, s) } catch (e) { throw new SecretSessionError(ErrCodes.CryptoError, e.message) } return sjcl.bitArray.concat(a, s) }, decrypt: function(e) { if (!this.encKey) throw new SecretSessionError(ErrCodes.InvalidSessionKey, "Called decrypt() without a session key!"); const t = new sjcl.cipher.aes(this.encKey), s = sjcl.bitArray.bitSlice(e, 0, this.keyLen), a = sjcl.bitArray.bitSlice(e, this.keyLen); let n = null; try { n = sjcl.mode.gcm.decrypt(t, a, s) } catch (e) { throw new SecretSessionError(ErrCodes.CryptoError, `Exception while decrypting message. ${e}`) } return n }, _randomWords: function(e) { const t = new Int32Array(e); return self.crypto.getRandomValues(t), Array.from(t) } }; const ContextState = { IncompatibleOS: "IncompatibleOS", NotInSession: "NotInSession", NativeSupportNotInstalled: "NativeSupportNotInstalled", CheckEngine: "CheckEngine", ChallengeSent: "ChallengeSent", MSG1Set: "MSG1Set", SessionKeySet: "SessionKeySet" }, DataState = { Initial: "Initial", Frame0Processed: "Frame0Processed", DataProcessed: "DataProcessed" }, RememberIC = { NoValueSet: "NoValueSet", UnknownPage: "UnknownPage", DoNotRemember: "DoNotRemember", RememberLoginAndPassword: "RememberLoginAndPassword" }, WBSAutoFillFormTypeUndetermined = 0, WBSAutoFillFormTypeAutoFillableStandard = 1, WBSAutoFillFormTypeNonAutoFillable = 2, WBSAutoFillFormTypeAutoFillableLogin = 3, WBSAutoFillFormTypeNewAccount = 4, WBSAutoFillFormTypeChangePassword = 5, WBSAutoFillFormTypeFoundTOTPURI = 6; class FrameDoesNotExistError extends Error { frame; constructor(e) { super(`Frame ${e.id} does not exist in tab ${e.tab.id}`), this.frame = e } } class FrameIsBrowserFrameError extends Error { frame; constructor(e) { super(`Frame ${e.id} in tab ${e.tab.id} is a browser frame.`), this.frame = e } } class ContentScriptNotSetUpInFrame extends Error { frame; constructor(e) { super(`Frame ${e.id} in tab ${e.tab.id} does not have active content script.`), this.frame = e } } class PromiseFulfillment { resolve; reject; constructor(e, t) { this.resolve = e, this.reject = t } } class DelayedMessageSender { static defaultDelayMS = 50; delayMS; messageName; #g = null; #p = []; #h = null; constructor(e, t = DelayedMessageSender.defaultDelayMS) { this.messageName = e, this.delayMS = t } get dateOfLastSentMessage() { return this.#h } enqueueRequest(e, t) { return new Promise(((s, a) => { this.#p.push(new PromiseFulfillment(s, a)), this.#g && (clearTimeout(this.#g), this.#g = null), this.#g = setTimeout((async () => { const s = e.tab.id, a = e.id; let n; try { n = await this.#S(s, a, this.messageName, t) } catch (t) { let s = t; return t.message.includes("Receiving end does not exist.") && (s = new FrameDoesNotExistError(e)), this.#h = null, void this.#f(null, s) } finally { this.#g = null } this.#h = new Date, this.#f(n) }).bind(this), this.delayMS) })) } cancelPendingRequests() { this.#g && (clearTimeout(this.#g), this.#g = null), this.#f(null, new Error("Cancelled")) } reset() { this.cancelPendingRequests(), this.#h = null } #S(e, t, s, a) { let n = { subject: s }; return a && (n = { ...n, ...a }), chrome.tabs.sendMessage(e, n, { frameId: t }) } #f(e, t = null) { for (; this.#p.length;) { const s = this.#p.shift(); t ? s.reject(t) : s.resolve(e) } } } class Frame { static delayForSettingUpContentScriptAfterFrameCreationMS = 50; static delayForRunningHeuristicsAfterFrameUpdateMS = 50; id; tab; url; state; #b = new DelayedMessageSender("setUp", Frame.delayForSettingUpContentScriptAfterFrameCreationMS); #C = new DelayedMessageSender("runFormMetadataHeuristics", Frame.delayForRunningHeuristicsAfterFrameUpdateMS); constructor(e, t) { this.id = e, this.tab = t } get isBrowserFrame() { const e = this.url; return !!e && urlIsBrowserURL(e) } get hasCompletedLoad() { return "complete" === this.state } get hasSetUpContentScript() { return !!this.#b.dateOfLastSentMessage } prepareForRemoval() { this.#b.cancelPendingRequests(), this.#C.cancelPendingRequests() } updateWithDetails(e, t) { this.state = e; const s = t.url; s && (this.url = urlFromURLString(s)) } setUpContentScript(e) { return this.isBrowserFrame ? Promise.reject(new FrameIsBrowserFrameError(this)) : (e = !!e, this.#b.enqueueRequest(this, { shouldEnableQRCodeScanning: e })) } async enableQRCodeScanning(e) { return this.hasSetUpContentScript ? this.#S("enableQRCodeScanner", { isEnabled: e }) : Promise.reject(new ContentScriptNotSetUpInFrame(this)) } runHeuristics() { return this.isBrowserFrame ? Promise.reject(new FrameIsBrowserFrameError(this)) : this.hasSetUpContentScript ? this.#C.enqueueRequest(this) : Promise.reject(new Error("Cannot run metadata heuristics before setting up content script")) } readyToReceiveMessages() { return this.#b.reset(), this.setUpContentScript(!0) } #S(e, t) { let s = { subject: e }; return t && (s = { ...s, ...t }), chrome.tabs.sendMessage(this.tab.id, s, { frameId: this.id }) } } class Tab { static delayForSettingUpFrameContentScript = 50; static delayForCleaningUpFrames = 2e3; static enableDeferredFrameCleanup = !0; id; state; framesById = new Map; url; #T = null; constructor(e) { this.id = e } get allFrames() { return chrome.webNavigation.getAllFrames({ tabId: this.id }) } async injectContentScripts(e = !0) { if (!this.url) return; const t = this.url.protocol; if ("http:" !== t && "https:" !== t) return; const s = chrome.runtime.getManifest().content_scripts[0], a = this.id; await chrome.scripting.executeScript({ target: { tabId: a, allFrames: e }, files: s.js }); for (const e of this.framesById.values()) try { await e.setUpContentScript() } catch (e) { if (e instanceof FrameIsBrowserFrameError) return } } prepareForRemoval() { for (const e of this.framesById.values()) e.prepareForRemoval() } activated(e) { this.#I(), chrome.contextMenus && chrome.contextMenus.removeAll() } update(e, t) { this.#I(), this.state = t.status, e ? (this.state = e.status, "loading" === e.status && (this.url = urlFromURLString(e.url))) : (this.state = t.status, this.url = urlFromURLString(t.url)) } addNewFrame(e, t, s = null) { this.#I(); const a = t.frameId, n = new Frame(a, this); this.framesById.set(a, n), this.frameUpdated(e, a, s, t) } async frameUpdated(e, t, s, a) { this.#I(); const n = this.ensureFrameExists(t); if (n.updateWithDetails(s, a), n.hasCompletedLoad) try { n.hasSetUpContentScript ? await n.runHeuristics() : await n.setUpContentScript(e.shouldEnableQRCodeScanning) } catch (e) { if (!(e instanceof FrameDoesNotExistError)) { if (e instanceof FrameIsBrowserFrameError) return; throw e } { const t = e.frameId; if (!this.framesById.get(t)) return; let s = await chrome.webNavigation.getFrame({ tabId: this.id, frameId: t }); s || (s.prepareForRemoval(), this.framesById.delete(t)) } } } async frameCompleted(e, t, s) { try { await this.frameUpdated(e, t, "complete", s) } catch (e) {} } frameIsReadyToReceiveMessages(e) { return this.ensureFrameExists(e).readyToReceiveMessages() } ensureFrameExists(e) { let t = this.framesById.get(e); return t || (t = new Frame(e, this), this.framesById.set(e, t)), t } #I() { Tab.enableDeferredFrameCleanup && (this.#T && (clearTimeout(this.#T), this.#T = null), this.#T = setTimeout((async () => { let e = new Map; const t = await this.allFrames, s = new Set((t || []).map((e => e.frameId))); if (!s.size && !this.framesById.size) return; for (const [t, a] of this.framesById) s.has(t) && e.set(t, a); this.framesById.size, e.size; this.framesById = e, this.#T = null }).bind(this), Tab.delayForCleaningUpFrames)) } } class TabMonitor { tabsById = new Map; #w; #y; constructor() { this.#A(), this.#v() } get extensionIsPaired() { return this.#w } set extensionIsPaired(e) { this.#w = e, this.#F() } get nativeAppSupportsQRCodeScanning() { return this.#y } set nativeAppSupportsQRCodeScanning(e) { this.#y = e, this.#F() } get shouldEnableQRCodeScanning() { return this.#w && this.#y } get #M() { return [...this.tabsById.values()].flatMap((e => [...e.framesById.values()])) } #F() { const e = this.shouldEnableQRCodeScanning; return Promise.allSettled(this.#M.map((t => t.enableQRCodeScanning(e).catch((e => {}))))) } async #A() { const e = await chrome.tabs.query({}); for (const t of e) { const e = t.id, s = new Tab(e); s.update(null, t), this.tabsById.set(e, s); const a = await chrome.webNavigation.getAllFrames({ tabId: e }); for (const e of a) { if (void 0 === e.frameId) break; s.addNewFrame(this, e, t.status) } } } #v() { chrome.tabs.onCreated.addListener((e => { const t = e.id; this.tabsById.set(t, new Tab(t)) })), chrome.tabs.onUpdated.addListener(((e, t, s) => { this.ensureTabExists(e).update(t, s) })), chrome.tabs.onActivated.addListener((e => { this.ensureTabExists(e.tabId).activated(e) })), chrome.tabs.onRemoved.addListener(((e, t) => { this.tabsById.delete(e) })), chrome.webNavigation.onBeforeNavigate.addListener((e => { const t = e.tabId; this.ensureTabExists(t).addNewFrame(this, e) })), chrome.webNavigation.onCompleted.addListener((async e => { const t = e.tabId, s = e.frameId, a = this.ensureTabExists(t); try { await a.frameCompleted(this, s, e) } catch (e) {} })), chrome.webNavigation.onHistoryStateUpdated.addListener((async e => { const t = e.tabId, s = e.frameId, a = this.ensureTabExists(t); try { await a.frameUpdated(this, s, "updated", e) } catch (e) {} })), chrome.webNavigation.onTabReplaced.addListener((e => { const t = e.replacedTabId; this.tabsById.get(t).prepareForRemoval(), this.tabsById.delete(t); const s = e.tabId; this.tabsById.set(s, new Tab(s)) })) } async performInitialSetup() { for (const e of this.tabsById.values()) await e.injectContentScripts() } ensureTabExists(e) { let t = this.tabsById.get(e); return t || (t = new Tab(e), this.tabsById.set(e, t)), t } frameIsReadyToReceiveMessages(e, t) { return this.ensureTabExists(e).frameIsReadyToReceiveMessages(t) } } "function" == typeof importScripts && importScripts("/sjcl.js"); const CmdEndOp = 0, CmdUnused1 = 1, CmdChallengePIN = 2, CmdSetIconNTitle = 3, CmdGetLoginNames4URL = 4, CmdGetPassword4LoginName = 5, CmdSetPassword4LoginName_URL = 6, CmdNewAccount4URL = 7, CmdTabEvent = 8, CmdPasswordsDisabled = 9, CmdReloginNeeded = 10, CmdLaunchiCP = 11, CmdiCPStateChange = 12, CmdLaunchPasswordsApp = 13, CmdHello = 14, CmdOneTimeCodeAvailable = 15, CmdGetOneTimeCodes = 16, CmdDidFillOneTimeCode = 17, CmdSetUpTOTPGenerator = 18, CmdOpenURLInSafari = 1984, QueryStatus = { Success: 0, NoResults: 3 }; function cmd2string(e) { switch (e) { case 0: return "CmdEndOp"; case 1: return "CmdUnused1"; case 2: return "CmdChallengePIN"; case 3: return "CmdSetIconNTitle"; case 4: return "CmdGetLoginNames4URL"; case 5: return "CmdGetPassword4LoginName"; case 6: return "CmdSetPassword4LoginName_URL"; case 7: return "CmdNewAccount4URL"; case 8: return "CmdTabEvent"; case 9: return "CmdPasswordsDisabled"; case 10: return "CmdReloginNeeded"; case 11: return "CmdLaunchiCP"; case 12: return "CmdiCPStateChange"; case 13: return "CmdLaunchPasswordsApp"; case 14: return "CmdHello"; case 15: return "CmdOneTimeCodeAvailable"; case 16: return "CmdGetOneTimeCodes"; case 17: return "CmdDidFillOneTimeCode"; case 1984: return "CmdOpenURLInSafari"; default: return "Unknown Command" } } var actUnknown = -1, actDelete = 0, actUpdate = 1, actSearch = 2, actAddNew = 3, actMaybeAdd = 4, actGhostSearch = 5; const DefaultCapabilities = { shouldUseBase64: !1, secretSessionVersion: SecretSessionVersion.SRPWithOldVerification, canFillOneTimeCodes: !1, operatingSystem: {}, supportsSubURLs: !1, scanForOTPURI: !1 }, AmountOfTimeToBlockRefreshForNativeAppDisconnection = 5e3; let g_tabMonitor = new TabMonitor; var g_lastToolbarIconImageName, g_timeStartedFetchingCredentials, g_nativeAppPort = null, g_portToCompletionList = null, g_portToPopup = null, thePAKE = null, g_theState = ContextState.NotInSession, g_tabIdToURL = new Map, g_Stage1Logins = new Map, g_TabsToStateMap = new Map, g_ErrorReturned = !1, g_secretSession = null, g_nativeAppCapabilities = null, g_localizer = new Localizer, g_extensionSettings = new ExtensionSettings, g_urlToDownloadNativeSupport = "https://support.apple.com/kb/DL1455", g_isDark = !1; function setIsDark(e) { g_isDark !== e && (g_isDark = e, chrome.storage.local.set({ isDark: e })) } function imageDataForName(e) { if (e) return { 16: "images/" + (g_lastToolbarIconImageName = e) + (g_isDark ? "-darkmode" : "") + "_icon16.png", 32: "images/" + g_lastToolbarIconImageName + (g_isDark ? "-darkmode" : "") + "_icon32.png" } } function setUpEventListners() { chrome.runtime.onInstalled && chrome.runtime.onInstalled.addListener((async e => { await g_tabMonitor.performInitialSetup(), chrome.declarativeContent && chrome.declarativeContent.onPageChanged.removeRules(void 0, (function() { chrome.declarativeContent.onPageChanged.addRules([{ conditions: [new chrome.declarativeContent.PageStateMatcher({ pageUrl: { schemes: ["https", "http"] } })], actions: [new chrome.declarativeContent.ShowPageAction] }]) })), "install" === e.reason && g_extensionSettings.attemptToControlBrowserAutoFillSettings().then((e => {})).catch((e => {})) })), chrome.runtime.onSuspend && chrome.runtime.onSuspend.addListener((function() { g_tabIdToURL.clear(), g_Stage1Logins.clear(), g_TabsToStateMap.clear(), g_nativeAppPort.postMessage({ cmd: 0 }) })), chrome.runtime.onSuspendCanceled && chrome.runtime.onSuspendCanceled.addListener((function() {})), chrome.runtime.onUpdateAvailable && chrome.runtime.onUpdateAvailable.addListener((function() {})) } function secdSTATUS2string(e) { switch (e) { case 0: return "secdSTATUSsuccess"; case 1: return "genericError"; case 2: return "invalidParam"; case 3: return "itemNotFound"; case 4: return "failedToDelete"; case 5: return "failedToUpdate"; case 6: return "invalidMessageFormat"; case 7: return "duplicateItem"; case 8: return "unknownAction"; case 9: return "invalidSession" } } function checkForValidOS() { if ("MacIntel" === navigator.platform) return g_urlToDownloadNativeSupport = "https://www.apple.com/macos", !0; const e = new RegExp("\\(Windows\\s*\\w*\\s*(\\d*)\\.(\\d*)", "i").exec(navigator.userAgent); return null !== e && 3 === e.length && (e[1] >= 10 ? (g_urlToDownloadNativeSupport = "ms-windows-store://pdp/?productid=9PKTQ5699M62", !0) : !(e[1] < 6) && !(e[2] < 1)) } function setGlobalState(e, t) { g_theState = e, g_tabMonitor.extensionIsPaired = g_theState === ContextState.SessionKeySet, setToolbarIcon(g_theState === ContextState.SessionKeySet ? "PasswordsToolbar" : "PasswordsToolbarUnpaired"), t || sendMessageToPopup({ subject: "nativeConnectionStateChanged", state: g_theState, appStoreURL: g_urlToDownloadNativeSupport }) } function resetTheSession(e) { setGlobalState(e), g_secretSession = new SecretSession(g_nativeAppCapabilities) } function STATUSErrorReturned(e) { switch (secdSTATUS2string(e), g_theState) { case ContextState.IncompatibleOS: case ContextState.NativeSupportNotInstalled: case ContextState.CheckEngine: case ContextState.MSG1Set: case ContextState.ChallengeSent: break; case ContextState.SessionKeySet: g_ErrorReturned = !0, resetTheSession(ContextState.NotInSession); case ContextState.NotInSession: chrome.tabs.query({ active: !0, currentWindow: !0 }, (function(e) { setToolbarIcon("PasswordsToolbarUnpaired") })) } } function logMapElements(e, t, s) {} function consultStage1Logins(e, t) { return isStringEmpty(e) ? g_Stage1Logins.has(t) ? (LoginName = g_Stage1Logins.get(t), LoginName, g_Stage1Logins.delete(t), LoginName) : "" : e } function entriesFromLoginNames4URLData(e) { let t = e.Entries; return t || (t = [], Object.entries(e).sort().map((([e, s]) => { e.includes("Entry_") && t.push(s) })), t) } function setToolbarIcon(e) { chrome.action && chrome.action.setIcon({ path: imageDataForName(e) }) } function sendMessageToPopupAndCompletionList(e) { sendMessageToPopup(e), sendMessageToCompletionList(e) } function sendMessageToPopup(e) { if (g_portToPopup) try { g_portToPopup.postMessage(e) } catch (e) {} } function sendMessageToCompletionList(e) { if (g_portToCompletionList) try { g_portToCompletionList.postMessage(e) } catch (e) {} } function onSetUpTOTPContextMenuClicked(e, t) { if (g_theState !== ContextState.SessionKeySet) window.alert(g_localizer.getMessage("enableAutoFillPasswordsMessage")); else { const t = new URL(e.pageUrl); t.hostname, e.menuItemId, setUpTOTP(t.hostname, e.menuItemId) } } function connectToBackgroundNativeAppAndSetUpListeners() { setToolbarIcon("PasswordsToolbarUnpaired"), g_nativeAppCapabilities || (g_nativeAppCapabilities = DefaultCapabilities), g_localizer = new Localizer(g_nativeAppCapabilities), g_secretSession = new SecretSession(g_nativeAppCapabilities), chrome.runtime.onMessage.addListener(((e, t, s) => { const a = t.tab.id, n = t.frameId, r = new URL(t.url); if (r.hostname, t.tab.id, t.frameId, e.from, "content" === e.from) switch (e.subject, e.subject) { case "CmdCheckEstablishSession": CheckEstablishSession(); break; case "SaveStage1LoginName": g_tabIdToURL.has(a) && (strURL = g_tabIdToURL.get(a), g_Stage1Logins.delete(strURL), g_tabIdToURL.delete(a)), r.hostname, e.theLogin, g_tabIdToURL.set(a, r.hostname), g_Stage1Logins.set(r.hostname, e.theLogin); break; case "CmdGetPassword4LoginName": const o = JSON.stringify({ ACT: actSearch, URL: r.hostname, USR: e.theLogin }), i = g_secretSession.createSMSG(o), c = { cmd: 5, tabId: t.tab.id, frameId: t.frameId, url: e.theURL, payload: JSON.stringify({ QID: e.subject, SMSG: i }) }; e.subject, e.subject, g_nativeAppPort.postMessage(c); break; case "CmdSetPassword4LoginName_URL": case "CmdNewAccount4URL": if (g_theState === ContextState.SessionKeySet) { e.theNLogin, r.hostname; let s = consultStage1Logins(e.theNLogin, r.hostname); if (!isStringEmpty(s)) { let a = JSON.stringify({ ACT: actMaybeAdd, URL: "", USR: "", PWD: "", NURL: e.theNURL, NUSR: s, NPWD: e.theNPassword }), n = g_secretSession.createSMSG(a), r = { cmd: 6, tabId: t.tab.id, frameId: t.frameId, payload: JSON.stringify({ QID: e.subject, SMSG: n }) }; e.subject, g_nativeAppPort.postMessage(r) } } break; case "CmdSetIconNTitle": { let s = e.hostPageType; setIsDark(e.isDark); let a = !1; switch (s) { case WBSAutoFillFormTypeUndetermined: case WBSAutoFillFormTypeAutoFillableStandard: case WBSAutoFillFormTypeNonAutoFillable: a = !1; break; case WBSAutoFillFormTypeAutoFillableLogin: case WBSAutoFillFormTypeNewAccount: case WBSAutoFillFormTypeChangePassword: a = !0 } switch (g_TabsToStateMap.has(t.tab.id) && g_TabsToStateMap.get(t.tab.id) || g_TabsToStateMap.set(t.tab.id, a), r.hostname, t.tab.id, t.frameId, humanReadableFormType(e.hostPageType), e.hostPageType, e.hostPageType) { case WBSAutoFillFormTypeUndetermined: case WBSAutoFillFormTypeAutoFillableStandard: case WBSAutoFillFormTypeNonAutoFillable: break; case WBSAutoFillFormTypeAutoFillableLogin: case WBSAutoFillFormTypeNewAccount: case WBSAutoFillFormTypeChangePassword: let e = { cmd: 3, tabId: t.tab.id, frameId: t.frameId, payload: JSON.stringify({ TID: "CmdSetIconNTitle", URL: r.hostname }) }; JSON.stringify(e), g_nativeAppPort.postMessage(e) } } break; case "ThemeChanged": chrome.action && (setIsDark(e.isDark), chrome.action.setIcon({ path: imageDataForName(g_lastToolbarIconImageName) })); break; case "fillOneTimeCodeIntoForm": chrome.webNavigation.getFrame({ tabId: t.tab.id, frameId: t.frameId }, (s => { s.frameId = t.frameId, didFillOneTimeCode(e.oneTimeCode, { id: t.tab.id }, s) })); break; case "typedUserNameChanged": case "keydown": sendMessageToCompletionList(e); break; case "CmdAddSetUpTOTPContextMenu": const l = !1; if (!chrome.contextMenus) break; chrome.contextMenus.create({ title: l ? `${g_localizer.getMessage("divTOTPMenu")} (${e.totpSetupURL})` : g_localizer.getMessage("divTOTPMenu"), id: e.totpSetupURL, contexts: ["all"] }), chrome.contextMenus.onClicked.addListener(onSetUpTOTPContextMenuClicked); break; case "CmdRemoveSetUpTOTPContextMenus": chrome.contextMenus && chrome.contextMenus.removeAll(); break; case "getCapabilities": s(g_nativeAppCapabilities); break; case "readyToReceiveMessages": g_tabMonitor.frameIsReadyToReceiveMessages(a, n) } })); try { (g_nativeAppPort = chrome.runtime.connectNative("com.apple.passwordmanager")).onMessage.addListener((async function(e) { switch (JSON.stringify(e), chrome.storage.local.remove(["lastRetryTimestamp"]), cmd2string(e.cmd), e.cmd, e.cmd) { case 9: case 10: resetTheSession(ContextState.CheckEngine), chrome.tabs.query({ active: !0, currentWindow: !0 }, (function(e) { setToolbarIcon("PasswordsToolbarUnpaired") })), setGlobalState(ContextState.NotInSession, !0); break; case 2: switch (e.payload.QID, e.payload.QID) { case "m0": thePAKE = e.payload.PAKE, setGlobalState(ContextState.MSG1Set); break; case "m2": try { g_secretSession.processMessage(e.payload.PAKE); setGlobalState(ContextState.SessionKeySet), thePAKE = null } catch (e) { e.code, e.message, resetTheSession(ContextState.NotInSession) } } break; case 3: var t = RememberIC.UnknownPage; switch (e.payload, e.payload) { case "DoNotRemember": t = RememberIC.DoNotRemember; break; case "RememberLoginAndPassword": t = RememberIC.RememberLoginAndPassword; break; case "UnknownPage": t = RememberIC.UnknownPage; break; case "NoValueSet": t = RememberIC.NoValueSet, STATUSErrorReturned(e.STATUS) } try { await chrome.tabs.sendMessage(e.tabId, { from: "background", subject: "RememberICSelection", tabId: e.tabId, frameId: e.frameId, theRememberICSelection: t, capabilities: g_nativeAppCapabilities }, { frameId: e.frameId }) } catch (t) { e.tabId, e.frameId, t.message } break; case 4: t = RememberIC.UnknownPage; var s = [], a = [], n = [], r = e.payload, o = e.tabId, i = e.frameId, c = g_secretSession.parseSMSG(r.SMSG); switch ((d = JSON.parse(c)).STATUS) { case QueryStatus.Success: performance.now(); var l = entriesFromLoginNames4URLData(d); l.sort(((e, t) => e.USR.localeCompare(t.USR, void 0, { numeric: !0, sensitivity: "base" }))), l.forEach((e => { if ("Passwords not saved" === e.USR) t = RememberIC.DoNotRemember; else if (s.push(e.USR), a.push(e.CDate || e.ModDate), n.push(e.sites[0]), "Not Included" === e.PWD) t = RememberIC.RememberLoginAndPassword; else t = RememberIC.UnknownPage })), sendMessageToPopupAndCompletionList({ from: "background", subject: "users", arrLoginNames: s, arrDates: a, arrHLDs: n, tabId: o, frameId: i, theRememberICSelection: t }); break; case QueryStatus.NoResults: sendMessageToPopupAndCompletionList({ from: "background", subject: "users", arrDates: [], tabId: o, frameId: i, arrLoginNames: [], arrHLDs: [], theRememberICSelection: RememberIC.UnknownPage }); break; default: STATUSErrorReturned(d.STATUS) } break; case 5: var d; r = e.payload, c = g_secretSession.parseSMSG(r.SMSG); switch ((d = JSON.parse(c)).STATUS) { case QueryStatus.Success: { const t = e.url, s = entriesFromLoginNames4URLData(d).find((e => e.sites.includes(t))); s && sendUsernameAndPasswordToFrameForFilling(e.tabId, e.frameId, t, s.USR, s.PWD); break } case QueryStatus.NoResults: break; default: STATUSErrorReturned(d.STATUS) } break; case 16: handleGetOneTimeCodesCommand(e); break; case 8: case 7: case 6: break; case 14: g_nativeAppCapabilities = e.capabilities ? e.capabilities : DefaultCapabilities, g_localizer = new Localizer(g_nativeAppCapabilities), g_tabMonitor.nativeAppSupportsQRCodeScanning = g_nativeAppCapabilities.scanForOTPURI, sendMessageToPopupAndCompletionList({ subject: "hello", capabilities: g_nativeAppCapabilities }), resetTheSession(ContextState.NotInSession); break; case 15: handleOneTimeCodeAvailableCommand(e); break; case 17: handleDidFillOneTimeCodeCommand(e); break; case 18: { let e = g_secretSession.parseSMSG(r.SMSG), t = JSON.parse(e); if (JSON.stringify(t), t.STATUS === QueryStatus.Success); else STATUSErrorReturned(t.STATUS); break } default: cmd2string(e.cmd) } })), g_nativeAppPort.onDisconnect.addListener((e => { const t = chrome.runtime.lastError; t.message, setTimeout((() => { if (t.message, "Native host has exited." === t.message) chrome.storage.local.get(["lastRetryTimestamp"], (e => { const t = e.lastRetryTimestamp; let s = !1; if (t) { s = Date.now() - t > 5e3 } else s = !0; s ? (chrome.storage.local.set({ lastRetryTimestamp: Date.now() }), connectToBackgroundNativeAppAndSetUpListeners()) : (chrome.storage.local.remove(["lastRetryTimestamp"]), resetTheSession(ContextState.NativeSupportNotInstalled)) })); else t.message, resetTheSession(ContextState.NativeSupportNotInstalled) }), 1e3) })), g_nativeAppPort.postMessage({ cmd: 14 }) } catch (e) { resetTheSession(ContextState.NativeSupportNotInstalled) } } async function sendUsernameAndPasswordToFrameForFilling(t, s, a, n, r) { try { await chrome.tabs.sendMessage(t, { from: "background", subject: "fillPassword", tabId: t, frameId: s, username: n, password: r, url: a }, { frameId: s }) } catch (t) { e.message } } function handleOneTimeCodeAvailableCommand(e) { getCurrentActiveTabAndFrame().then((e => getOneTimeCodes(e[0], e[1], null))).catch((e => {})) } function handleGetOneTimeCodesCommand(e) { let t = null; try { t = JSON.parse(g_secretSession.parseSMSG(e.payload.SMSG)) } catch (e) { return } let s = t.STATUS; if (s !== QueryStatus.Success) return s !== QueryStatus.NoResults && STATUSErrorReturned(s), void sendMessageToPopupAndCompletionList({ from: "background", subject: "oneTimeCodes", oneTimeCodes: [] }); let a = t.Entries; a && sendMessageToPopupAndCompletionList({ from: "background", subject: "oneTimeCodes", oneTimeCodes: a }) } async function handleDidFillOneTimeCodeCommand(e) { let t = null; try { t = JSON.parse(g_secretSession.parseSMSG(e.payload.SMSG)) } catch (e) { return } let s = t.STATUS; if (s !== QueryStatus.Success) return void(s !== QueryStatus.NoResults && STATUSErrorReturned(s)); let a = t.Entries; if (a && a.length) try { await chrome.tabs.sendMessage(e.tabId, { subject: "fillCurrentTOTPCodeIntoForm", oneTimeCodes: a }, { frameId: e.frameId }) } catch (e) {} } function CheckEstablishSession() { if (g_theState === ContextState.NotInSession) ChallengePIN() } function startiCloudControlPanel() { var e = { cmd: 11 }; JSON.stringify(e), g_nativeAppPort.postMessage(e) } function startPasswordsApp() { let e = { cmd: 13 }; JSON.stringify(e), g_nativeAppPort.postMessage(e) } function setUpTOTP(e, t) { if (!g_nativeAppCapabilities.scanForOTPURI) return; const s = { cmd: 13, setUpTOTPPageURL: e, setUpTOTPURI: t }; JSON.stringify(s), g_nativeAppPort.postMessage(s) } async function getUsernamesForMainFrameOfActiveTab() { if (g_theState !== ContextState.SessionKeySet) return; const e = await chrome.tabs.query({ active: !0, currentWindow: !0 }); if (!e.length) return; const t = e[0].id; GetLoginNames4URL(urlFromURLString((await chrome.webNavigation.getFrame({ tabId: t, frameId: 0 })).url).hostname, t, 0) } function GetLoginNames4URL(e, t, s) { let a = JSON.stringify({ ACT: actGhostSearch, URL: e }), n = g_secretSession.createSMSG(a), r = { cmd: 4, url: e, tabId: t, frameId: s, payload: JSON.stringify({ QID: "CmdGetLoginNames4URL", SMSG: n }) }; g_timeStartedFetchingCredentials = performance.now(), g_nativeAppPort.postMessage(r) } function getOneTimeCodes(e, t, s) { getAllParentFrameURLsOfFrame(e, t).then((a => { let n = { ACT: actGhostSearch, TYPE: "oneTimeCodes", frameURLs: a }; s && (n.username = s); let r = g_secretSession.createSMSG(n), o = { cmd: 16, tabId: e.id, frameId: t.frameId, payload: JSON.stringify({ QID: "CmdGetOneTimeCodes", SMSG: r }) }; g_nativeAppPort.postMessage(o) })).catch((e => {})) } function didFillOneTimeCode(e, t, s) { if ("totp" === e.source) getAllParentFrameURLsOfFrame(t, s).then((a => { let n = { ACT: actSearch, TYPE: "oneTimeCodes", frameURLs: a }, r = e.username; r && (n.username = r); let o = g_secretSession.createSMSG(n), i = { cmd: 17, tabId: t.id, frameId: s.frameId, payload: JSON.stringify({ QID: "CmdDidFillOneTimeCode", SMSG: o }) }; g_nativeAppPort.postMessage(i) })).catch((e => {})) } function openURLInSafari(e) { g_nativeAppPort.postMessage({ cmd: 1984, url: e }) } function getAllParentFrameURLsOfFrame(e, t) { let s = e.id; return new Promise((a => { -1 !== t.parentFrameId ? chrome.webNavigation.getFrame({ tabId: s, frameId: t.parentFrameId }, (s => { getAllParentFrameURLsOfFrame(e, s).then((e => { a([t.url].concat(e)) })).catch((e => {})) })) : a([t.url]) })) } function ChallengePIN() { if (g_theState === ContextState.NotInSession) { var e = { QID: "m0", PAKE: g_secretSession.initialMessage(), HSTBRSR: g_localizer.getMessage("browserName") }, t = { cmd: 2, msg: JSON.stringify(e) }; setGlobalState(ContextState.ChallengeSent); try { g_nativeAppPort.postMessage(t) } catch (e) { e.message, resetTheSession(ContextState.NativeSupportNotInstalled) } } } function PINSet(e) { g_secretSession.setPin(e); try { let e = { QID: "m2", PAKE: g_secretSession.processMessage(thePAKE) }, t = { cmd: 2, msg: JSON.stringify(e) }; g_nativeAppPort.postMessage(t) } catch (e) { e.code, e.message, resetTheSession(ContextState.NotInSession) } } function getCurrentActiveTabAndFrame() { return new Promise((e => { chrome.tabs.query({ active: !0, currentWindow: !0 }, (function(t) { chrome.webNavigation.getAllFrames({ tabId: t[0].id }, (function(s) { e([t[0], s[0]]) })) })) })) } function getCurrentActiveTabAndItsFrames() { return new Promise((e => { chrome.tabs.query({ active: !0, currentWindow: !0 }, (function(t) { chrome.webNavigation.getAllFrames({ tabId: t[0].id }, (function(s) { e([t[0], s]) })) })) })) } function canFillOneTimeCodes() { return (g_nativeAppCapabilities || DefaultCapabilities).canFillOneTimeCodes } function setUpPortToCompetionList(e) { g_portToCompletionList = e, e.onMessage.addListener((async function(t) { switch (JSON.stringify(t), t.subject) { case "getContextAndMetadataFromContent": getCurrentActiveTabAndItsFrames().then((function(t) { const s = t[0].id; for (const a of t[1]) { const t = a.frameId; chrome.tabs.sendMessage(s, { from: "background", subject: "getContextAndMetadataForActiveTextField" }, { frameId: t }, (function(a) { a && e.postMessage({ subject: "replyForGetContextAndMetadataFromContent", state: g_theState, tabId: s, frameId: t, url: a.url, textFieldMetadata: a.textFieldMetadata, formMetadata: a.formMetadata, presetUserName: a.presetUserName, hostname: a.hostname, canFillOneTimeCodes: canFillOneTimeCodes() }) })) } })).catch((e => {})); break; case "GetLoginNames4URL": GetLoginNames4URL(t.hostname, t.tabId, t.frameId); break; case "getOneTimeCodes": const s = t.tabId, a = t.frameId; chrome.webNavigation.getFrame({ tabId: s, frameId: a }, (e => { e.frameId = a, getOneTimeCodes({ id: t.tabId }, e, t.username) })); break; case "openPasswordManagerAndDismissCompletionList": startPasswordsApp(); try { await chrome.tabs.sendMessage(t.tabId, { subject: "dismissCompletionList" }, { frameId: t.frameId }) } catch (e) {} break; case "openURLInSafari": openURLInSafari(t.url); break; case "resizeCompletionList": case "fillLoginIntoForm": case "fillOneTimeCodeIntoForm": case "dismissCompletionList": try { await chrome.tabs.sendMessage(t.tabId, t, { frameId: t.frameId }) } catch (e) {} } })), e.onDisconnect.addListener((e => { e === g_portToCompletionList && (g_portToCompletionList = null) })), sendMessageToCompletionList({ subject: "hello", capabilities: g_nativeAppCapabilities }) } function setUpPortToPopup(e) { g_portToPopup = e, e.onMessage.addListener((function(t) { switch (JSON.stringify(t), t.subject) { case "getInitialPopupState": e.postMessage({ subject: "nativeConnectionStateChanged", state: g_theState, appStoreURL: g_urlToDownloadNativeSupport }); break; case "tryToEstablishNativeConnectionInResponseToUserActivatingPopup": chrome.storage.local.set({ lastRetryTimestamp: Date.now() }), connectToBackgroundNativeAppAndSetUpListeners(); break; case "challengePIN": ChallengePIN(); break; case "userEnteredPIN": PINSet(t.pin); break; case "GetLoginNames4URL": GetLoginNames4URL(t.hostname, t.tabId, t.frameId); break; case "openPasswordManager": startPasswordsApp(); break; case "startiCloudControlPanel": startiCloudControlPanel(); break; case "SetUpTOTP": setUpTOTP(t.theURL, t.theTOTPURI); break; case "openURLInSafari": openURLInSafari(t.url) } })), e.onDisconnect.addListener((function() { g_theState === ContextState.MSG1Set && PINSet(""), g_portToPopup = null })), sendMessageToPopup({ subject: "hello", capabilities: g_nativeAppCapabilities }) } chrome.storage.local.get("isDark", (function(e) { void 0 !== e.isDark && (g_isDark = e.isDark), g_lastToolbarIconImageName && setToolbarIcon(g_lastToolbarIconImageName) })), setUpEventListners(), checkForValidOS() ? connectToBackgroundNativeAppAndSetUpListeners() : (chrome.storage.local.get("hideUnsupportedOSPrompt", (function(e) { e.hideUnsupportedOSPrompt || (chrome.storage.local.set({ hideUnsupportedOSPrompt: 1 }), window.alert(g_localizer.getMessage("unsupportedOS"))) })), setGlobalState(ContextState.IncompatibleOS)), chrome.windows.onFocusChanged.addListener((async e => { if (!g_nativeAppPort || e === chrome.windows.WINDOW_ID_NONE) return; let t = await chrome.tabs.query({ active: !0, currentWindow: !0 }); if (t.length < 1) return; const s = t[0].id; if (!s) return; const a = { cmd: 8, tabId: s, event: 1 }; JSON.stringify(a), g_nativeAppPort.postMessage(a) })), chrome.tabs.onActivated.addListener((e => { if (JSON.stringify(e), !g_nativeAppPort) return; let t = { cmd: 8, tabId: e.tabId, event: 1 }; JSON.stringify(t), g_nativeAppPort.postMessage(t) })), chrome.tabs.onRemoved.addListener(((e, t) => { if (JSON.stringify(t), !g_nativeAppPort) return; let s = { cmd: 8, tabId: e, event: 0 }; JSON.stringify(s), g_nativeAppPort.postMessage(s), g_TabsToStateMap.delete(e) })), chrome.runtime.onConnect.addListener((function(e) { e.name, "completionList" === e.name ? setUpPortToCompetionList(e) : "popup" === e.name ? setUpPortToPopup(e) : e.name })); This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,685 @@ var pwlog = void 0, pwerror = void 0; function isStringEmpty(e) { return !e || 0 === e.length } function urlFromURLString(e) { try { return new URL(e) } catch { return null } } function humanReadableFormType(e) { switch (e) { case WBSAutoFillFormTypeUndetermined: return "Undetermined"; case WBSAutoFillFormTypeAutoFillableStandard: return "AutoFillable:Standard"; case WBSAutoFillFormTypeNonAutoFillable: return "NonAutoFillable"; case WBSAutoFillFormTypeAutoFillableLogin: return "AutoFillable:Login"; case WBSAutoFillFormTypeNewAccount: return "NewAccount"; case WBSAutoFillFormTypeChangePassword: return "ChangePassword"; case WBSAutoFillFormTypeFoundTOTPURI: return "FoundTOTPUri" } return "Unrecognized" } function domainsForDisplayFromUsernamesAndDomains(e, t) { const n = e.length; let o = t.map((function(e) { return e.replace(/^(www|m)\./, "") })), s = []; for (var a = 0; a < n; a++) s.push([e[a], o[a]]); for (a = 0; a < n; a++) { let e = []; for (var i = a + 1; i < n; i++) s[a].join("\n") === s[i].join("\n") && (e.length || e.push(a), e.push(i)); for (let n of e) o[n] = t[n] } return o } function urlIsBrowserURL(e) { const t = e.protocol; return "chrome:" === t || "edge:" === t || "about:" == t } function isExtensionContextInvalidatedError(e) { return "Extension context invalidated." === e.message } function capabilitiesDeclaresMacOS(e) { try { return "macos" === e.operatingSystem.name } catch { return !1 } } class Localizer { static configureDocumentElementForLanguage(e, t) { switch (t) { case "he": case "ar": case "fa": e.setAttribute("dir", "rtl"), e.setAttribute("lang", t) } } #e = {}; constructor(e) { e && (this.#e = e.operatingSystem) } getMessage(e, t, n) { const o = this.messageNamesToTry(e); for (let e of o) { let o; try { o = chrome.i18n.getMessage(e, t, n) } catch { o = chrome.i18n.getMessage(e, t) } if (o) return o } return "" } messageNamesToTry(e) { let t = []; const n = this.#e, o = n ? n.name : void 0, s = n ? n.majorVersion : void 0, a = n ? n.minorVersion : void 0, i = void 0 !== s; return o && i && void 0 !== a && t.push(`${e}_${o}_${s}_${a}`), o && i && t.push(`${e}_${o}_${s}`), o ? t.push(`${e}_${o}`) : t.push(`${e}_${this.#t}`), t.push(e), t } get #t() { return navigator.platform.startsWith("Mac") ? "macos" : "windows" } } class ExtensionSettings { #n = !1; #o = !0; #s = !0; eventTarget = new EventTarget; constructor(e = !1) { this.#n = e, this.#a(), this.#i() } get enableInPageAutoFill() { return this.#o } set enableInPageAutoFill(e) { this.#o = e, this.#r() } get allowExtensionToControlAutoFillSettings() { return this.#s } set allowExtensionToControlAutoFillSettings(e) { this.#s = e, this.#l().then(this.#r.bind(this)) } #l() { return this.#s ? this.attemptToControlBrowserAutoFillSettings() : this.clearControlOfBrowserAutoFillSettings() } async attemptToControlBrowserAutoFillSettings() { if (this.#n) throw new Error("This Settings instance does not allow writing browser settings"); const e = await Promise.allSettled([this.#d(chrome.privacy.services.passwordSavingEnabled, !1), this.#d(chrome.privacy.services.autofillCreditCardEnabled, !1), this.#d(chrome.privacy.services.autofillAddressEnabled, !1)]); return this.#c(), e } async clearControlOfBrowserAutoFillSettings() { if (this.#n) throw new Error("This Settings instance does not allow writing browser settings"); const e = await Promise.allSettled([this.#u(chrome.privacy.services.passwordSavingEnabled), this.#u(chrome.privacy.services.autofillCreditCardEnabled), this.#u(chrome.privacy.services.autofillAddressEnabled)]); return this.#c(), e } #a() { let e = new Promise((e => { chrome.storage.sync.get({ enableInPageAutoFill: !0, allowExtensionToControlAutoFillSettings: !0 }, (t => { this.#o = t.enableInPageAutoFill, this.#s = t.allowExtensionToControlAutoFillSettings, e() })) })); return this.#n || (e = e.then(this.#l.bind(this))), e.then(this.#c.bind(this)) } #r() { return new Promise((e => { chrome.storage.sync.set({ enableInPageAutoFill: this.#o, allowExtensionToControlAutoFillSettings: this.#s }, e) })).then(this.#c.bind(this)) } #i() { this.#n || (chrome.privacy.services.passwordSavingEnabled && chrome.privacy.services.passwordSavingEnabled.onChange.addListener((e => { this.#c() })), chrome.privacy.services.autofillCreditCardEnabled && chrome.privacy.services.autofillCreditCardEnabled.onChange.addListener((e => { this.#c() })), chrome.privacy.services.autofillAddressEnabled && chrome.privacy.services.autofillAddressEnabled.onChange.addListener((e => { this.#c() }))) } #c() { const e = new CustomEvent("settingsChanged", { detail: { enableInPageAutoFill: this.#o } }); this.eventTarget.dispatchEvent(e) } async #d(e, t) { let n; try { n = await this.#g(e) } catch (e) { return } if (n) { if (n.value === t) return { details: n, newValue: t }; try { n = await e.set({ value: t }) } catch (e) { return } return { details: n, newValue: t } } } async #g(e) { if (!e) throw new Error(`Unable to get ${e} setting.`); const t = await e.get({}); if ("not_controllable" === t.levelOfControl) throw new Error(`Cannot control ${e} setting.`); return t } async #u(e) { if (!e) throw new Error(`Unable to clear browser setting: ${e}.`); await e.clear({}) } } const ContextState = { IncompatibleOS: "IncompatibleOS", NotInSession: "NotInSession", NativeSupportNotInstalled: "NativeSupportNotInstalled", CheckEngine: "CheckEngine", ChallengeSent: "ChallengeSent", MSG1Set: "MSG1Set", SessionKeySet: "SessionKeySet" }, DataState = { Initial: "Initial", Frame0Processed: "Frame0Processed", DataProcessed: "DataProcessed" }, RememberIC = { NoValueSet: "NoValueSet", UnknownPage: "UnknownPage", DoNotRemember: "DoNotRemember", RememberLoginAndPassword: "RememberLoginAndPassword" }, WBSAutoFillFormTypeUndetermined = 0, WBSAutoFillFormTypeAutoFillableStandard = 1, WBSAutoFillFormTypeNonAutoFillable = 2, WBSAutoFillFormTypeAutoFillableLogin = 3, WBSAutoFillFormTypeNewAccount = 4, WBSAutoFillFormTypeChangePassword = 5, WBSAutoFillFormTypeFoundTOTPURI = 6; var g_lastUpdatedPopupContentsState, g_portToBackgroundPage = null, g_appStoreURL = null, g_capabilities = null, g_localizer = new Localizer; function setControlText(e, t) { var n = document.getElementById(e); n && (n.textContent = g_localizer.getMessage(t), n.textContent) } function setMessageTitle(e) { var t = document.getElementById("divMessageBoardTitle"); t && (t.textContent = g_localizer.getMessage(e), t.textContent) } function setMessageSubtitle(e) { var t = document.getElementById("divMessageBoardMessage"); t && (t.textContent = g_localizer.getMessage(e), t.textContent) } function showMessage(e, t, n) { document.querySelector("#iCloudIconId").style.display = n ? "block" : "none", setMessageTitle(e), setMessageSubtitle(t); let o = document.getElementById("divMessageBoard"); o.style.display = "block", n ? o.classList.add("logo-is-present") : o.classList.remove("logo-is-present") } function showMessageWithOpenPasswordManagerButton(e, t, n) { showMessage(e, t); let o = document.querySelector("#openPasswordManagerList"); if (!o.children.length) { o.appendChild(listItemForOpenPasswordManager()); capabilitiesDeclaresMacOS(g_capabilities) && n && o.appendChild(listItemForOpenPageInSafari()) } } function SetOpeniC4WTitleText(e) { var t = document.getElementById("idOpeniC4WTitle"); t && (t.textContent = g_localizer.getMessage(e), t.textContent) } function SetOpeniC4WButtonText(e) { var t = document.getElementById("idOpeniC4WButton"); t && (t.textContent = g_localizer.getMessage(e), t.textContent) } function clearCredentialListContents() { let e = document.getElementById("credentialList"); for (; e.firstChild;) e.removeChild(e.lastChild) } function tryToEstablishNativeConnectionInResponseToUserActivatingPopupAfterDelay() { setTimeout((function() { sendMessageToBackgroundPage({ subject: "tryToEstablishNativeConnectionInResponseToUserActivatingPopup" }) }), 50) } function updatePopupContents(e) { if (g_lastUpdatedPopupContentsState && g_lastUpdatedPopupContentsState === ContextState.NativeSupportNotInstalled && e === ContextState.NativeSupportNotInstalled) return; g_lastUpdatedPopupContentsState = e; let t = document.getElementById("divPIN"), n = document.getElementById("divMessageBoard"), o = document.getElementById("divICs"), s = document.getElementById("divDownloadPage"), a = document.getElementById("divOpeniC4WPage"); for (let e of [t, n, o, s, a]) e.style.display = "none"; chrome.tabs.query({ active: !0, currentWindow: !0 }, (function(n) { switch (e) { case ContextState.IncompatibleOS: document.querySelector("#openPasswordManagerList").remove(), showMessage("extName", "unsupportedOS", !0); break; case ContextState.NativeSupportNotInstalled: setControlText("downloadMessage", "downloadMessage"), g_appStoreURL ? setControlText("downloadButton", "downloadButton") : document.getElementById("downloadButton").display = "none", document.querySelector("#iCloudIconId").style.display = "block", s.classList.add("logo-is-present"), s.style.display = "block", tryToEstablishNativeConnectionInResponseToUserActivatingPopupAfterDelay(); break; case ContextState.NotInSession: showMessage("extName", "GettingPasswords"), sendMessageToBackgroundPage({ subject: "challengePIN" }); break; case ContextState.CheckEngine: SetOpeniC4WTitleText("CheckEngineMessage"), SetOpeniC4WButtonText("openiCloudForWindowsButtonText"), a.style.display = "block"; break; case ContextState.ChallengeSent: case ContextState.MSG1Set: setControlText("divPINTitle", "divPINTitle"), setControlText("divPINMessage", "divPINMessage"), mapOverPINFields((function(e) { e.value = "", e.onkeydown = pinKeyHandler })), t.style.display = "block", document.querySelector("#iCloudIconId").style.display = "block", document.getElementById("PIN0").focus(); break; case ContextState.SessionKeySet: { setMessageTitle("extName", "GettingPasswords"), setControlText("divICsMessage", "divICsMessage"), clearCredentialListContents(); const e = n[0].id; chrome.webNavigation.getAllFrames({ tabId: e }, (t => { t.forEach((async (t, o) => { JSON.stringify(t); const s = t.frameId, a = new URL(t.url), i = a.protocol; if ("http:" !== i && "https:" !== i) return t.url, void showMessageWithOpenPasswordManagerButton("GenericPopupTitle", "divNoPasswordsMessage", !1); let r; try { r = await chrome.tabs.sendMessage(e, { from: "popup", subject: "getPageType", URL: a.hostname, tabId: e, frameId: s }, { frameId: s }) } catch (e) { return void e.message } switch (r || (a.hostname, n[0].id, t.frameId, r = WBSAutoFillFormTypeUndetermined), a.hostname, n[0].id, t.frameId, humanReadableFormType(r), humanReadableFormType(r), r) { case WBSAutoFillFormTypeUndetermined: case WBSAutoFillFormTypeAutoFillableStandard: case WBSAutoFillFormTypeNonAutoFillable: showMessageWithOpenPasswordManagerButton("GenericPopupTitle", "divNoPasswordsMessage", !0); break; case WBSAutoFillFormTypeAutoFillableLogin: case WBSAutoFillFormTypeChangePassword: case WBSAutoFillFormTypeNewAccount: showMessage("extName", "GettingPasswords"), sendMessageToBackgroundPage({ subject: "GetLoginNames4URL", hostname: a.hostname, tabId: n[0].id, frameId: t.frameId }); break; case WBSAutoFillFormTypeFoundTOTPURI: { let e; try { e = await chrome.tabs.sendMessage(n[0].id, { from: "popup", subject: "getTOTPSetupInfo", URL: a.hostname, tabId: n[0].id, frameId: t.frameId }, { frameId: t.frameId }) } catch (e) { break } updatePopupContentsWithTOTPSetupInfo(e, a.hostname, n[0].id, t.frameId); break } } })) })); break } default: t.style.display = "block" } })) } function listItemMouseOverHandler(e) { let t = e.target.closest("li"); if (!t) return; let n = t.closest("ul"); if (n) { for (let e of n.querySelectorAll("li")) e.classList.remove("active"); t.classList.add("active") } } function listItemMouseOutHandler(e) { let t = e.target.closest("li"); t && t.classList.remove("active") } function updatePopupContentsWithTOTPSetupInfo(e, t, n, o) { let s = document.getElementById("divPIN"), a = document.getElementById("divMessageBoard"), i = document.getElementById("divICs"), r = document.getElementById("divDownloadPage"), l = document.getElementById("divOpeniC4WPage"); for (let e of [s, a, i, r, l]) e.style.display = "none"; let d = document.getElementById("credentialList"); try { document.querySelector("#iCloudIconId").style.display = "none", clearCredentialListContents(); for (const [n, o] of Object.entries(e)) { let e = document.createElement("li"); e.classList.add("selectable"), e.classList.add("credential"), e.onmouseover = listItemMouseOverHandler, e.onmouseout = listItemMouseOutHandler; let n = document.createElement("img"); n.setAttribute("src", "images/key.svg"), e.appendChild(n); let s = document.createElement("p"); s.classList.add("totpwebsite"), s.textContent = t, e.appendChild(s), e.addEventListener("click", (function() { chrome.tabs.query({ active: !0, currentWindow: !0 }, (function(e) { sendMessageToBackgroundPage({ subject: "SetUpTOTP", theURL: t, theTOTPURI: o }), window.close() })) })), d.appendChild(e) } d.appendChild(listItemForOpenPasswordManager()) } catch (e) { e.message } let c = document.querySelector("#divMessageBoard .credential-list"); c && c.remove(), setControlText("divICsMessage", "divTOTPTitle"), i.style.display = "block" } async function updatePopupContents_ICs(e, t, n, o, s, a) { var i = document.getElementById("divPIN"), r = document.getElementById("divMessageBoard"), l = document.getElementById("divICs"), d = document.getElementById("divDownloadPage"), c = document.getElementById("divOpeniC4WPage"); for (let e of [i, r, l, d, c]) e.style.display = "none"; let u = document.getElementById("credentialList"); switch (e) { case RememberIC.UnknownPage: showMessageWithOpenPasswordManagerButton("GenericPopupTitle", "divNoPasswordsMessage", !0); break; case RememberIC.DoNotRemember: showMessageWithOpenPasswordManagerButton("divDoNotRememberTitle", "divDoNotRememberMessage", !0); break; case RememberIC.RememberLoginAndPassword: { let a; try { a = await chrome.tabs.sendMessage(t, { from: "popup", subject: "getPresetUserNameAndURL", tabId: t, frameId: n }, { frameId: n }) } catch (e) { return } JSON.stringify(a), document.querySelector("#iCloudIconId").style.display = "none", clearCredentialListContents(); let i = ""; a.isPresetUserNamePresent && (i = a.presetUserName); const r = function() { const e = /(.*)@/.exec(i); return e ? e[1] : null }(), d = domainsForDisplayFromUsernamesAndDomains(o, s), c = o.length; let m = [], p = [], h = []; for (var g = 0; g < c; g++) { let a = s[g], l = o[g], c = d[g]; const u = l.toLowerCase().startsWith(i.toLowerCase()), S = u || l.toLowerCase().startsWith(r ? r.toLowerCase() : null); let w = document.createElement("li"); w.classList.add("selectable"), w.classList.add("credential"), w.onmouseover = listItemMouseOverHandler, w.onmouseout = listItemMouseOutHandler; let y = document.createElement("img"); y.setAttribute("src", "images/key.svg"), w.appendChild(y); let v = document.createElement("p"); v.classList.add("name"), isStringEmpty(l) ? (v.classList.add("no-user-name"), v.textContent = g_localizer.getMessage("NoUserName")) : v.textContent = l, w.appendChild(v); let C = document.createElement("p"); C.classList.add("website"), C.textContent = c, w.appendChild(C), w.addEventListener("click", (async function() { try { await chrome.tabs.sendMessage(t, { from: "popup", subject: "fillLoginIntoForm", theRememberICSelection: e, tabId: t, frameId: n, theLogin: l, theURL: a }, { frameId: n }) } catch (e) { return } window.close() })), u ? m.push(w) : S ? p.push(w) : h.push(w) } for (const e of m) u.appendChild(e); for (const e of p) u.appendChild(e); for (const e of h) u.appendChild(e); u.appendChild(listItemForOpenPasswordManager()); const S = capabilitiesDeclaresMacOS(g_capabilities), w = !urlIsBrowserURL(new URL(a.url)); S && w && u.appendChild(listItemForOpenPageInSafari()); let y = document.querySelector("#divMessageBoard .credential-list"); y && y.remove(), l.style.display = "block"; break } } } function listItemForOpenPasswordManager() { let e = document.createElement("li"); return e.classList.add("selectable"), e.classList.add("open-password-manager"), e.onmouseover = listItemMouseOverHandler, e.onmouseout = listItemMouseOutHandler, e.textContent = g_localizer.getMessage("divOpenPasswords"), e.addEventListener("click", openPasswordsButtonHandler), e } function listItemForOpenPageInSafari() { let e = document.createElement("li"); return e.classList.add("selectable"), e.classList.add("open-safari"), e.onmouseover = listItemMouseOverHandler, e.onmouseout = listItemMouseOutHandler, e.textContent = g_localizer.getMessage("openThisPageInSafari"), e.addEventListener("click", openThisPageInSafariButtonHandler), e } function sendMessageToBackgroundPage(e) { if (g_portToBackgroundPage) try { g_portToBackgroundPage.postMessage(e) } catch (e) {} } function mapOverPINFields(e) { return [document.getElementById("PIN0"), document.getElementById("PIN1"), document.getElementById("PIN2"), document.getElementById("PIN3"), document.getElementById("PIN4"), document.getElementById("PIN5")].map(e) } function pinKeyHandler(e) { let t = e.target, n = t ? t.previousElementSibling : null, o = t ? t.nextElementSibling : null, s = e.keyCode || e.charCode; switch (s) { case 46: t.value = "", e.preventDefault(); break; case 8: return t.value = "", e.preventDefault(), n && (n.focus(), n.select()), !1; case 37: n && (e.preventDefault(), n.focus(), n.select()); break; case 39: o && (e.preventDefault(), o.focus(), o.select()); break; default: if (e.preventDefault(), !(s >= 48 && s <= 57 || s >= 96 && s <= 105)) { t.value = ""; break } if (this.value = e.key, o) { o.focus(); break } let a = mapOverPINFields((function(e) { return e.onkeydown = null, e.value.trim() })).join(""); sendMessageToBackgroundPage({ subject: "userEnteredPIN", pin: a }) } } function openPasswordsButtonHandler(e) { sendMessageToBackgroundPage({ subject: "openPasswordManager" }), window.close() } function openThisPageInSafariButtonHandler(e) { chrome.tabs.query({ active: !0, currentWindow: !0 }, (e => { sendMessageToBackgroundPage({ subject: "openURLInSafari", url: e[0].url }), window.close() })) } document.documentElement.addEventListener("keydown", (function(e) { let t = document.querySelector("li.active"), n = e.key, o = t ? t.previousElementSibling : null, s = t ? t.nextElementSibling : null; switch (n) { case "ArrowUp": if (!t) break; return e.preventDefault(), t.classList.remove("active"), o && o.classList.add("active"), !1; case "ArrowDown": if (e.preventDefault(), !t) { let e = document.querySelector("li"); return e && e.classList.add("active"), !1 } return s && (t.classList.remove("active"), s.classList.add("active")), !1; case "Enter": if (t) return e.preventDefault(), t.click(), !1 } })), window.addEventListener("load", (e => { let t = chrome.i18n.getUILanguage(); Localizer.configureDocumentElementForLanguage(document.documentElement, t); try { (g_portToBackgroundPage = chrome.runtime.connect({ name: "popup" })).onMessage.addListener((function(e, t, n) { switch (JSON.stringify(e), e.subject) { case "hello": g_capabilities = e.capabilities, g_localizer = new Localizer(e.capabilities); break; case "nativeConnectionStateChanged": g_appStoreURL = e.appStoreURL, updatePopupContents(e.state); break; case "users": chrome.tabs.query({ active: !0, currentWindow: !0 }, (async function(t) { t[0].id === e.tabId && await updatePopupContents_ICs(e.theRememberICSelection, e.tabId, e.frameId, e.arrLoginNames, e.arrHLDs, e.arrDates) })); break; case "oneTimeCodes": break; default: e.from, e.subject } })), g_portToBackgroundPage.onDisconnect.addListener((() => { g_portToBackgroundPage = null })), sendMessageToBackgroundPage({ subject: "getInitialPopupState" }); let e = document.createElement("span"); e.textContent = g_localizer.getMessage("extName"); let t = document.createElement("img"); t.setAttribute("src", "images/PasswordsToolbar_icon32.png"), t.classList.add("fromiCloudPasswordsMenuIcon"), e.appendChild(t), document.querySelector("#fromiCloudPasswords").appendChild(e) } catch (e) { e.message } })), document.getElementById("downloadButton").onclick = function(e) { chrome.tabs.create({ url: g_appStoreURL }) }, document.getElementById("idOpeniC4WButton").onclick = function() { sendMessageToBackgroundPage({ subject: "startiCloudControlPanel" }), window.close() }, document.getElementById("dismiss").onclick = function() { window.close() }, window.onfocus = () => { sendMessageToBackgroundPage({ subject: "getInitialPopupState" }) }, chrome.runtime.onMessage.addListener(((e, t, n) => { e.from, e.subject })); This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,238 @@ var pwlog = void 0, pwerror = void 0; function isStringEmpty(e) { return !e || 0 === e.length } function urlFromURLString(e) { try { return new URL(e) } catch { return null } } function humanReadableFormType(e) { switch (e) { case WBSAutoFillFormTypeUndetermined: return "Undetermined"; case WBSAutoFillFormTypeAutoFillableStandard: return "AutoFillable:Standard"; case WBSAutoFillFormTypeNonAutoFillable: return "NonAutoFillable"; case WBSAutoFillFormTypeAutoFillableLogin: return "AutoFillable:Login"; case WBSAutoFillFormTypeNewAccount: return "NewAccount"; case WBSAutoFillFormTypeChangePassword: return "ChangePassword"; case WBSAutoFillFormTypeFoundTOTPURI: return "FoundTOTPUri" } return "Unrecognized" } function domainsForDisplayFromUsernamesAndDomains(e, t) { const n = e.length; let o = t.map((function(e) { return e.replace(/^(www|m)\./, "") })), i = []; for (var r = 0; r < n; r++) i.push([e[r], o[r]]); for (r = 0; r < n; r++) { let e = []; for (var s = r + 1; s < n; s++) i[r].join("\n") === i[s].join("\n") && (e.length || e.push(r), e.push(s)); for (let n of e) o[n] = t[n] } return o } function urlIsBrowserURL(e) { const t = e.protocol; return "chrome:" === t || "edge:" === t || "about:" == t } function isExtensionContextInvalidatedError(e) { return "Extension context invalidated." === e.message } function capabilitiesDeclaresMacOS(e) { try { return "macos" === e.operatingSystem.name } catch { return !1 } } class Localizer { static configureDocumentElementForLanguage(e, t) { switch (t) { case "he": case "ar": case "fa": e.setAttribute("dir", "rtl"), e.setAttribute("lang", t) } } #e = {}; constructor(e) { e && (this.#e = e.operatingSystem) } getMessage(e, t, n) { const o = this.messageNamesToTry(e); for (let e of o) { let o; try { o = chrome.i18n.getMessage(e, t, n) } catch { o = chrome.i18n.getMessage(e, t) } if (o) return o } return "" } messageNamesToTry(e) { let t = []; const n = this.#e, o = n ? n.name : void 0, i = n ? n.majorVersion : void 0, r = n ? n.minorVersion : void 0, s = void 0 !== i; return o && s && void 0 !== r && t.push(`${e}_${o}_${i}_${r}`), o && s && t.push(`${e}_${o}_${i}`), o ? t.push(`${e}_${o}`) : t.push(`${e}_${this.#t}`), t.push(e), t } get #t() { return navigator.platform.startsWith("Mac") ? "macos" : "windows" } } class ExtensionSettings { #n = !1; #o = !0; #i = !0; eventTarget = new EventTarget; constructor(e = !1) { this.#n = e, this.#r(), this.#s() } get enableInPageAutoFill() { return this.#o } set enableInPageAutoFill(e) { this.#o = e, this.#l() } get allowExtensionToControlAutoFillSettings() { return this.#i } set allowExtensionToControlAutoFillSettings(e) { this.#i = e, this.#a().then(this.#l.bind(this)) } #a() { return this.#i ? this.attemptToControlBrowserAutoFillSettings() : this.clearControlOfBrowserAutoFillSettings() } async attemptToControlBrowserAutoFillSettings() { if (this.#n) throw new Error("This Settings instance does not allow writing browser settings"); const e = await Promise.allSettled([this.#g(chrome.privacy.services.passwordSavingEnabled, !1), this.#g(chrome.privacy.services.autofillCreditCardEnabled, !1), this.#g(chrome.privacy.services.autofillAddressEnabled, !1)]); return this.#c(), e } async clearControlOfBrowserAutoFillSettings() { if (this.#n) throw new Error("This Settings instance does not allow writing browser settings"); const e = await Promise.allSettled([this.#u(chrome.privacy.services.passwordSavingEnabled), this.#u(chrome.privacy.services.autofillCreditCardEnabled), this.#u(chrome.privacy.services.autofillAddressEnabled)]); return this.#c(), e } #r() { let e = new Promise((e => { chrome.storage.sync.get({ enableInPageAutoFill: !0, allowExtensionToControlAutoFillSettings: !0 }, (t => { this.#o = t.enableInPageAutoFill, this.#i = t.allowExtensionToControlAutoFillSettings, e() })) })); return this.#n || (e = e.then(this.#a.bind(this))), e.then(this.#c.bind(this)) } #l() { return new Promise((e => { chrome.storage.sync.set({ enableInPageAutoFill: this.#o, allowExtensionToControlAutoFillSettings: this.#i }, e) })).then(this.#c.bind(this)) } #s() { this.#n || (chrome.privacy.services.passwordSavingEnabled && chrome.privacy.services.passwordSavingEnabled.onChange.addListener((e => { this.#c() })), chrome.privacy.services.autofillCreditCardEnabled && chrome.privacy.services.autofillCreditCardEnabled.onChange.addListener((e => { this.#c() })), chrome.privacy.services.autofillAddressEnabled && chrome.privacy.services.autofillAddressEnabled.onChange.addListener((e => { this.#c() }))) } #c() { const e = new CustomEvent("settingsChanged", { detail: { enableInPageAutoFill: this.#o } }); this.eventTarget.dispatchEvent(e) } async #g(e, t) { let n; try { n = await this.#h(e) } catch (e) { return } if (n) { if (n.value === t) return { details: n, newValue: t }; try { n = await e.set({ value: t }) } catch (e) { return } return { details: n, newValue: t } } } async #h(e) { if (!e) throw new Error(`Unable to get ${e} setting.`); const t = await e.get({}); if ("not_controllable" === t.levelOfControl) throw new Error(`Cannot control ${e} setting.`); return t } async #u(e) { if (!e) throw new Error(`Unable to clear browser setting: ${e}.`); await e.clear({}) } } let extensionSettings = new ExtensionSettings; function localizeSettingsPage() { document.title = chrome.i18n.getMessage("optionsTitle"), document.querySelectorAll(".localizedElement").forEach((e => { const t = e.dataset.localizedMessage; if (!t) return; const n = chrome.i18n.getMessage(t); e.textContent = n })) } window.addEventListener("DOMContentLoaded", (e => { Localizer.configureDocumentElementForLanguage(document.documentElement, chrome.i18n.getUILanguage()), localizeSettingsPage(); const setUpCheckbox = (e, t, n) => { const o = document.getElementById(e); o.checked = t, o.addEventListener("change", (e => { const t = e.target.checked; n(t) })) }; setUpCheckbox("enable-inpage-autofill-checkbox", extensionSettings.enableInPageAutoFill, (e => { extensionSettings.enableInPageAutoFill = e })), setUpCheckbox("allow-extention-to-control-autofill-checkbox", extensionSettings.allowExtensionToControlAutoFillSettings, (e => { extensionSettings.allowExtensionToControlAutoFillSettings = e })), extensionSettings.eventTarget.addEventListener("settingsChanged", (e => { const t = e.detail; void 0 !== t.enableInPageAutoFill && (document.getElementById("enable-inpage-autofill-checkbox").checked = t.enableInPageAutoFill), void 0 !== t.allowExtensionToControlAutoFillSettings && (document.getElementById("allow-extention-to-control-autofill-checkbox").checked = t.allowExtensionToControlAutoFillSettings) })) })); -
AngeloD2022 created this gist
Dec 16, 2023 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,1195 @@ "use strict"; var sjcl = { cipher: {}, hash: {}, keyexchange: {}, mode: {}, misc: {}, codec: {}, exception: { corrupt: function(a) { this.toString = function() { return "CORRUPT: " + this.message }; this.message = a }, invalid: function(a) { this.toString = function() { return "INVALID: " + this.message }; this.message = a }, bug: function(a) { this.toString = function() { return "BUG: " + this.message }; this.message = a }, notReady: function(a) { this.toString = function() { return "NOT READY: " + this.message }; this.message = a } } }; sjcl.cipher.aes = function(a) { this.w[0][0][0] || this.L(); var b, c, d, e, f = this.w[0][4], g = this.w[1]; b = a.length; var h = 1; if (4 !== b && 6 !== b && 8 !== b) throw new sjcl.exception.invalid("invalid aes key size"); this.b = [d = a.slice(0), e = []]; for (a = b; a < 4 * b + 28; a++) { c = d[a - 1]; if (0 === a % b || 8 === b && 4 === a % b) c = f[c >>> 24] << 24 ^ f[c >> 16 & 255] << 16 ^ f[c >> 8 & 255] << 8 ^ f[c & 255], 0 === a % b && (c = c << 8 ^ c >>> 24 ^ h << 24, h = h << 1 ^ 283 * (h >> 7)); d[a] = d[a - b] ^ c } for (b = 0; a; b++, a--) c = d[b & 3 ? a : a - 4], e[b] = 4 >= a || 4 > b ? c : g[0][f[c >>> 24]] ^ g[1][f[c >> 16 & 255]] ^ g[2][f[c >> 8 & 255]] ^ g[3][f[c & 255]] }; sjcl.cipher.aes.prototype = { encrypt: function(a) { return t(this, a, 0) }, decrypt: function(a) { return t(this, a, 1) }, w: [ [ [], [], [], [], [] ], [ [], [], [], [], [] ] ], L: function() { var a = this.w[0], b = this.w[1], c = a[4], d = b[4], e, f, g, h = [], k = [], m, p, l, n; for (e = 0; 0x100 > e; e++) k[(h[e] = e << 1 ^ 283 * (e >> 7)) ^ e] = e; for (f = g = 0; !c[f]; f ^= m || 1, g = k[g] || 1) for (l = g ^ g << 1 ^ g << 2 ^ g << 3 ^ g << 4, l = l >> 8 ^ l & 255 ^ 99, c[f] = l, d[l] = f, p = h[e = h[m = h[f]]], n = 0x1010101 * p ^ 0x10001 * e ^ 0x101 * m ^ 0x1010100 * f, p = 0x101 * h[l] ^ 0x1010100 * l, e = 0; 4 > e; e++) a[e][f] = p = p << 24 ^ p >>> 8, b[e][l] = n = n << 24 ^ n >>> 8; for (e = 0; 5 > e; e++) a[e] = a[e].slice(0), b[e] = b[e].slice(0) } }; function t(a, b, c) { if (4 !== b.length) throw new sjcl.exception.invalid("invalid aes block size"); var d = a.b[c], e = b[0] ^ d[0], f = b[c ? 3 : 1] ^ d[1], g = b[2] ^ d[2]; b = b[c ? 1 : 3] ^ d[3]; var h, k, m, p = d.length / 4 - 2, l, n = 4, r = [0, 0, 0, 0]; h = a.w[c]; a = h[0]; var q = h[1], u = h[2], x = h[3], y = h[4]; for (l = 0; l < p; l++) h = a[e >>> 24] ^ q[f >> 16 & 255] ^ u[g >> 8 & 255] ^ x[b & 255] ^ d[n], k = a[f >>> 24] ^ q[g >> 16 & 255] ^ u[b >> 8 & 255] ^ x[e & 255] ^ d[n + 1], m = a[g >>> 24] ^ q[b >> 16 & 255] ^ u[e >> 8 & 255] ^ x[f & 255] ^ d[n + 2], b = a[b >>> 24] ^ q[e >> 16 & 255] ^ u[f >> 8 & 255] ^ x[g & 255] ^ d[n + 3], n += 4, e = h, f = k, g = m; for (l = 0; 4 > l; l++) r[c ? 3 & -l : l] = y[e >>> 24] << 24 ^ y[f >> 16 & 255] << 16 ^ y[g >> 8 & 255] << 8 ^ y[b & 255] ^ d[n++], h = e, e = f, f = g, g = b, b = h; return r } sjcl.bitArray = { bitSlice: function(a, b, c) { a = sjcl.bitArray.X(a.slice(b / 32), 32 - (b & 31)).slice(1); return void 0 === c ? a : sjcl.bitArray.clamp(a, c - b) }, extract: function(a, b, c) { var d = Math.floor(-b - c & 31); return ((b + c - 1 ^ b) & -32 ? a[b / 32 | 0] << 32 - d ^ a[b / 32 + 1 | 0] >>> d : a[b / 32 | 0] >>> d) & (1 << c) - 1 }, concat: function(a, b) { if (0 === a.length || 0 === b.length) return a.concat(b); var c = a[a.length - 1], d = sjcl.bitArray.getPartial(c); return 32 === d ? a.concat(b) : sjcl.bitArray.X(b, d, c | 0, a.slice(0, a.length - 1)) }, bitLength: function(a) { var b = a.length; return 0 === b ? 0 : 32 * (b - 1) + sjcl.bitArray.getPartial(a[b - 1]) }, clamp: function(a, b) { if (32 * a.length < b) return a; a = a.slice(0, Math.ceil(b / 32)); var c = a.length; b = b & 31; 0 < c && b && (a[c - 1] = sjcl.bitArray.partial(b, a[c - 1] & 2147483648 >> b - 1, 1)); return a }, partial: function(a, b, c) { return 32 === a ? b : (c ? b | 0 : b << 32 - a) + 0x10000000000 * a }, getPartial: function(a) { return Math.round(a / 0x10000000000) || 32 }, equal: function(a, b) { if (sjcl.bitArray.bitLength(a) !== sjcl.bitArray.bitLength(b)) return !1; var c = 0, d; for (d = 0; d < a.length; d++) c |= a[d] ^ b[d]; return 0 === c }, X: function(a, b, c, d) { var e; e = 0; for (void 0 === d && (d = []); 32 <= b; b -= 32) d.push(c), c = 0; if (0 === b) return d.concat(a); for (e = 0; e < a.length; e++) d.push(c | a[e] >>> b), c = a[e] << 32 - b; e = a.length ? a[a.length - 1] : 0; a = sjcl.bitArray.getPartial(e); d.push(sjcl.bitArray.partial(b + a & 31, 32 < b + a ? c : d.pop(), 1)); return d }, ka: function(a, b) { return [a[0] ^ b[0], a[1] ^ b[1], a[2] ^ b[2], a[3] ^ b[3]] }, byteswapM: function(a) { var b, c; for (b = 0; b < a.length; ++b) c = a[b], a[b] = c >>> 24 | c >>> 8 & 0xff00 | (c & 0xff00) << 8 | c << 24; return a } }; sjcl.codec.utf8String = { fromBits: function(a) { var b = "", c = sjcl.bitArray.bitLength(a), d, e; for (d = 0; d < c / 8; d++) 0 === (d & 3) && (e = a[d / 4]), b += String.fromCharCode(e >>> 8 >>> 8 >>> 8), e <<= 8; return decodeURIComponent(escape(b)) }, toBits: function(a) { a = unescape(encodeURIComponent(a)); var b = [], c, d = 0; for (c = 0; c < a.length; c++) d = d << 8 | a.charCodeAt(c), 3 === (c & 3) && (b.push(d), d = 0); c & 3 && b.push(sjcl.bitArray.partial(8 * (c & 3), d)); return b } }; sjcl.codec.hex = { fromBits: function(a) { var b = "", c; for (c = 0; c < a.length; c++) b += ((a[c] | 0) + 0xf00000000000).toString(16).substr(4); return b.substr(0, sjcl.bitArray.bitLength(a) / 4) }, toBits: function(a) { var b, c = [], d; a = a.replace(/\s|0x/g, ""); d = a.length; a = a + "00000000"; for (b = 0; b < a.length; b += 8) c.push(parseInt(a.substr(b, 8), 16) ^ 0); return sjcl.bitArray.clamp(c, 4 * d) } }; sjcl.codec.base64 = { P: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", fromBits: function(a, b, c) { var d = "", e = 0, f = sjcl.codec.base64.P, g = 0, h = sjcl.bitArray.bitLength(a); c && (f = f.substr(0, 62) + "-_"); for (c = 0; 6 * d.length < h;) d += f.charAt((g ^ a[c] >>> e) >>> 26), 6 > e ? (g = a[c] << 6 - e, e += 26, c++) : (g <<= 6, e -= 6); for (; d.length & 3 && !b;) d += "="; return d }, toBits: function(a, b) { a = a.replace(/\s|=/g, ""); var c = [], d, e = 0, f = sjcl.codec.base64.P, g = 0, h; b && (f = f.substr(0, 62) + "-_"); for (d = 0; d < a.length; d++) { h = f.indexOf(a.charAt(d)); if (0 > h) throw new sjcl.exception.invalid("this isn't base64!"); 26 < e ? (e -= 26, c.push(g ^ h >>> e), g = h << 32 - e) : (e += 6, g ^= h << 32 - e) } e & 56 && c.push(sjcl.bitArray.partial(e & 56, g, 1)); return c } }; sjcl.codec.base64url = { fromBits: function(a) { return sjcl.codec.base64.fromBits(a, 1, 1) }, toBits: function(a) { return sjcl.codec.base64.toBits(a, 1) } }; sjcl.codec.bytes = { fromBits: function(a) { var b = [], c = sjcl.bitArray.bitLength(a), d, e; for (d = 0; d < c / 8; d++) 0 === (d & 3) && (e = a[d / 4]), b.push(e >>> 24), e <<= 8; return b }, toBits: function(a) { var b = [], c, d = 0; for (c = 0; c < a.length; c++) d = d << 8 | a[c], 3 === (c & 3) && (b.push(d), d = 0); c & 3 && b.push(sjcl.bitArray.partial(8 * (c & 3), d)); return b } }; sjcl.hash.sha256 = function(a) { this.b[0] || this.L(); a ? (this.i = a.i.slice(0), this.f = a.f.slice(0), this.c = a.c) : this.reset() }; sjcl.hash.sha256.hash = function(a) { return (new sjcl.hash.sha256).update(a).finalize() }; sjcl.hash.sha256.prototype = { blockSize: 512, reset: function() { this.i = this.C.slice(0); this.f = []; this.c = 0; return this }, update: function(a) { "string" === typeof a && (a = sjcl.codec.utf8String.toBits(a)); var b, c = this.f = sjcl.bitArray.concat(this.f, a); b = this.c; a = this.c = b + sjcl.bitArray.bitLength(a); if (0x1fffffffffffff < a) throw new sjcl.exception.invalid("Cannot hash more than 2^53 - 1 bits"); if ("undefined" !== typeof Uint32Array) { var d = new Uint32Array(c), e = 0; for (b = 512 + b - (512 + b & 0x1ff); b <= a; b += 512) this.m(d.subarray(16 * e, 16 * (e + 1))), e += 1; c.splice(0, 16 * e) } else for (b = 512 + b - (512 + b & 0x1ff); b <= a; b += 512) this.m(c.splice(0, 16)); return this }, finalize: function() { var a, b = this.f, c = this.i, b = sjcl.bitArray.concat(b, [sjcl.bitArray.partial(1, 1)]); for (a = b.length + 2; a & 15; a++) b.push(0); b.push(Math.floor(this.c / 0x100000000)); for (b.push(this.c | 0); b.length;) this.m(b.splice(0, 16)); this.reset(); return c }, C: [], b: [], L: function() { function a(a) { return 0x100000000 * (a - Math.floor(a)) | 0 } for (var b = 0, c = 2, d, e; 64 > b; c++) { e = !0; for (d = 2; d * d <= c; d++) if (0 === c % d) { e = !1; break } e && (8 > b && (this.C[b] = a(Math.pow(c, .5))), this.b[b] = a(Math.pow(c, 1 / 3)), b++) } }, m: function(a) { var b, c, d, e = this.i, f = this.b, g = e[0], h = e[1], k = e[2], m = e[3], p = e[4], l = e[5], n = e[6], r = e[7]; for (b = 0; 64 > b; b++) 16 > b ? c = a[b] : (c = a[b + 1 & 15], d = a[b + 14 & 15], c = a[b & 15] = (c >>> 7 ^ c >>> 18 ^ c >>> 3 ^ c << 25 ^ c << 14) + (d >>> 17 ^ d >>> 19 ^ d >>> 10 ^ d << 15 ^ d << 13) + a[b & 15] + a[b + 9 & 15] | 0), c = c + r + (p >>> 6 ^ p >>> 11 ^ p >>> 25 ^ p << 26 ^ p << 21 ^ p << 7) + (n ^ p & (l ^ n)) + f[b], r = n, n = l, l = p, p = m + c | 0, m = k, k = h, h = g, g = c + (h & k ^ m & (h ^ k)) + (h >>> 2 ^ h >>> 13 ^ h >>> 22 ^ h << 30 ^ h << 19 ^ h << 10) | 0; e[0] = e[0] + g | 0; e[1] = e[1] + h | 0; e[2] = e[2] + k | 0; e[3] = e[3] + m | 0; e[4] = e[4] + p | 0; e[5] = e[5] + l | 0; e[6] = e[6] + n | 0; e[7] = e[7] + r | 0 } }; sjcl.hash.sha1 = function(a) { a ? (this.i = a.i.slice(0), this.f = a.f.slice(0), this.c = a.c) : this.reset() }; sjcl.hash.sha1.hash = function(a) { return (new sjcl.hash.sha1).update(a).finalize() }; sjcl.hash.sha1.prototype = { blockSize: 512, reset: function() { this.i = this.C.slice(0); this.f = []; this.c = 0; return this }, update: function(a) { "string" === typeof a && (a = sjcl.codec.utf8String.toBits(a)); var b, c = this.f = sjcl.bitArray.concat(this.f, a); b = this.c; a = this.c = b + sjcl.bitArray.bitLength(a); if (0x1fffffffffffff < a) throw new sjcl.exception.invalid("Cannot hash more than 2^53 - 1 bits"); if ("undefined" !== typeof Uint32Array) { var d = new Uint32Array(c), e = 0; for (b = this.blockSize + b - (this.blockSize + b & this.blockSize - 1); b <= a; b += this.blockSize) this.m(d.subarray(16 * e, 16 * (e + 1))), e += 1; c.splice(0, 16 * e) } else for (b = this.blockSize + b - (this.blockSize + b & this.blockSize - 1); b <= a; b += this.blockSize) this.m(c.splice(0, 16)); return this }, finalize: function() { var a, b = this.f, c = this.i, b = sjcl.bitArray.concat(b, [sjcl.bitArray.partial(1, 1)]); for (a = b.length + 2; a & 15; a++) b.push(0); b.push(Math.floor(this.c / 0x100000000)); for (b.push(this.c | 0); b.length;) this.m(b.splice(0, 16)); this.reset(); return c }, C: [1732584193, 4023233417, 2562383102, 271733878, 3285377520], b: [1518500249, 1859775393, 2400959708, 3395469782], m: function(a) { var b, c, d, e, f, g, h = this.i, k; if ("undefined" !== typeof Uint32Array) for (k = Array(80), c = 0; 16 > c; c++) k[c] = a[c]; else k = a; c = h[0]; d = h[1]; e = h[2]; f = h[3]; g = h[4]; for (a = 0; 79 >= a; a++) 16 <= a && (b = k[a - 3] ^ k[a - 8] ^ k[a - 14] ^ k[a - 16], k[a] = b << 1 | b >>> 31), b = 19 >= a ? d & e | ~d & f : 39 >= a ? d ^ e ^ f : 59 >= a ? d & e | d & f | e & f : 79 >= a ? d ^ e ^ f : void 0, b = (c << 5 | c >>> 27) + b + g + k[a] + this.b[Math.floor(a / 20)] | 0, g = f, f = e, e = d << 30 | d >>> 2, d = c, c = b; h[0] = h[0] + c | 0; h[1] = h[1] + d | 0; h[2] = h[2] + e | 0; h[3] = h[3] + f | 0; h[4] = h[4] + g | 0 } }; sjcl.mode.gcm = { name: "gcm", encrypt: function(a, b, c, d, e) { var f = b.slice(0); b = sjcl.bitArray; d = d || []; a = sjcl.mode.gcm.S(!0, a, f, d, c, e || 128); return b.concat(a.data, a.tag) }, decrypt: function(a, b, c, d, e) { var f = b.slice(0), g = sjcl.bitArray, h = g.bitLength(f); e = e || 128; d = d || []; e <= h ? (b = g.bitSlice(f, h - e), f = g.bitSlice(f, 0, h - e)) : (b = f, f = []); a = sjcl.mode.gcm.S(!1, a, f, d, c, e); if (!g.equal(a.tag, b)) throw new sjcl.exception.corrupt("gcm: tag doesn't match"); return a.data }, ea: function(a, b) { var c, d, e, f, g, h = sjcl.bitArray.ka; e = [0, 0, 0, 0 ]; f = b.slice(0); for (c = 0; 128 > c; c++) { (d = 0 !== (a[Math.floor(c / 32)] & 1 << 31 - c % 32)) && (e = h(e, f)); g = 0 !== (f[3] & 1); for (d = 3; 0 < d; d--) f[d] = f[d] >>> 1 | (f[d - 1] & 1) << 31; f[0] >>>= 1; g && (f[0] ^= -0x1f000000) } return e }, s: function(a, b, c) { var d, e = c.length; b = b.slice(0); for (d = 0; d < e; d += 4) b[0] ^= 0xffffffff & c[d], b[1] ^= 0xffffffff & c[d + 1], b[2] ^= 0xffffffff & c[d + 2], b[3] ^= 0xffffffff & c[d + 3], b = sjcl.mode.gcm.ea(b, a); return b }, S: function(a, b, c, d, e, f) { var g, h, k, m, p, l, n, r, q = sjcl.bitArray; l = c.length; n = q.bitLength(c); r = q.bitLength(d); h = q.bitLength(e); g = b.encrypt([0, 0, 0, 0]); 96 === h ? (e = e.slice(0), e = q.concat(e, [1])) : (e = sjcl.mode.gcm.s(g, [0, 0, 0, 0], e), e = sjcl.mode.gcm.s(g, e, [0, 0, Math.floor(h / 0x100000000), h & 0xffffffff])); h = sjcl.mode.gcm.s(g, [0, 0, 0, 0], d); p = e.slice(0); d = h.slice(0); a || (d = sjcl.mode.gcm.s(g, h, c)); for (m = 0; m < l; m += 4) p[3]++, k = b.encrypt(p), c[m] ^= k[0], c[m + 1] ^= k[1], c[m + 2] ^= k[2], c[m + 3] ^= k[3]; c = q.clamp(c, n); a && (d = sjcl.mode.gcm.s(g, h, c)); a = [Math.floor(r / 0x100000000), r & 0xffffffff, Math.floor(n / 0x100000000), n & 0xffffffff]; d = sjcl.mode.gcm.s(g, d, a); k = b.encrypt(e); d[0] ^= k[0]; d[1] ^= k[1]; d[2] ^= k[2]; d[3] ^= k[3]; return { tag: q.bitSlice(d, 0, f), data: c } } }; sjcl.prng = function(a) { this.j = [new sjcl.hash.sha256]; this.u = [0]; this.M = 0; this.D = {}; this.K = 0; this.R = {}; this.W = this.l = this.v = this.da = 0; this.b = [0, 0, 0, 0, 0, 0, 0, 0]; this.o = [0, 0, 0, 0]; this.I = void 0; this.J = a; this.B = !1; this.H = { progress: {}, seeded: {} }; this.A = this.ca = 0; this.F = 1; this.G = 2; this.$ = 0x10000; this.O = [0, 48, 64, 96, 128, 192, 0x100, 384, 512, 768, 1024]; this.aa = 3E4; this.Z = 80 }; sjcl.prng.prototype = { randomWords: function(a, b) { var c = [], d; d = this.isReady(b); var e; if (d === this.A) throw new sjcl.exception.notReady("generator isn't seeded"); if (d & this.G) { d = !(d & this.F); e = []; var f = 0, g; this.W = e[0] = (new Date).valueOf() + this.aa; for (g = 0; 16 > g; g++) e.push(0x100000000 * Math.random() | 0); for (g = 0; g < this.j.length && (e = e.concat(this.j[g].finalize()), f += this.u[g], this.u[g] = 0, d || !(this.M & 1 << g)); g++); this.M >= 1 << this.j.length && (this.j.push(new sjcl.hash.sha256), this.u.push(0)); this.l -= f; f > this.v && (this.v = f); this.M++; this.b = sjcl.hash.sha256.hash(this.b.concat(e)); this.I = new sjcl.cipher.aes(this.b); for (d = 0; 4 > d && (this.o[d] = this.o[d] + 1 | 0, !this.o[d]); d++); } for (d = 0; d < a; d += 4) 0 === (d + 1) % this.$ && v(this), e = w(this), c.push(e[0], e[1], e[2], e[3]); v(this); return c.slice(0, a) }, setDefaultParanoia: function(a, b) { if (0 === a && "Setting paranoia=0 will ruin your security; use it only for testing" !== b) throw new sjcl.exception.invalid("Setting paranoia=0 will ruin your security; use it only for testing"); this.J = a }, addEntropy: function(a, b, c) { c = c || "user"; var d, e, f = (new Date).valueOf(), g = this.D[c], h = this.isReady(), k = 0; d = this.R[c]; void 0 === d && (d = this.R[c] = this.da++); void 0 === g && (g = this.D[c] = 0); this.D[c] = (this.D[c] + 1) % this.j.length; switch (typeof a) { case "number": void 0 === b && (b = 1); this.j[g].update([d, this.K++, 1, b, f, 1, a | 0]); break; case "object": c = Object.prototype.toString.call(a); if ("[object Uint32Array]" === c) { e = []; for (c = 0; c < a.length; c++) e.push(a[c]); a = e } else for ("[object Array]" !== c && (k = 1), c = 0; c < a.length && !k; c++) "number" !== typeof a[c] && (k = 1); if (!k) { if (void 0 === b) for (c = b = 0; c < a.length; c++) for (e = a[c]; 0 < e;) b++, e = e >>> 1; this.j[g].update([d, this.K++, 2, b, f, a.length].concat(a)) } break; case "string": void 0 === b && (b = a.length); this.j[g].update([d, this.K++, 3, b, f, a.length]); this.j[g].update(a); break; default: k = 1 } if (k) throw new sjcl.exception.bug("random: addEntropy only supports number, array of numbers or string"); this.u[g] += b; this.l += b; h === this.A && (this.isReady() !== this.A && z("seeded", Math.max(this.v, this.l)), z("progress", this.getProgress())) }, isReady: function(a) { a = this.O[void 0 !== a ? a : this.J]; return this.v && this.v >= a ? this.u[0] > this.Z && (new Date).valueOf() > this.W ? this.G | this.F : this.F : this.l >= a ? this.G | this.A : this.A }, getProgress: function(a) { a = this.O[a ? a : this.J]; return this.v >= a ? 1 : this.l > a ? 1 : this.l / a }, startCollectors: function() { if (!this.B) { this.a = { loadTimeCollector: A(this, this.ha), mouseCollector: A(this, this.ia), keyboardCollector: A(this, this.ga), accelerometerCollector: A(this, this.ba), touchCollector: A(this, this.ja) }; if (window.addEventListener) window.addEventListener("load", this.a.loadTimeCollector, !1), window.addEventListener("mousemove", this.a.mouseCollector, !1), window.addEventListener("keypress", this.a.keyboardCollector, !1), window.addEventListener("devicemotion", this.a.accelerometerCollector, !1), window.addEventListener("touchmove", this.a.touchCollector, !1); else if (document.attachEvent) document.attachEvent("onload", this.a.loadTimeCollector), document.attachEvent("onmousemove", this.a.mouseCollector), document.attachEvent("keypress", this.a.keyboardCollector); else throw new sjcl.exception.bug("can't attach event"); this.B = !0 } }, stopCollectors: function() { this.B && (window.removeEventListener ? (window.removeEventListener("load", this.a.loadTimeCollector, !1), window.removeEventListener("mousemove", this.a.mouseCollector, !1), window.removeEventListener("keypress", this.a.keyboardCollector, !1), window.removeEventListener("devicemotion", this.a.accelerometerCollector, !1), window.removeEventListener("touchmove", this.a.touchCollector, !1)) : document.detachEvent && (document.detachEvent("onload", this.a.loadTimeCollector), document.detachEvent("onmousemove", this.a.mouseCollector), document.detachEvent("keypress", this.a.keyboardCollector)), this.B = !1) }, addEventListener: function(a, b) { this.H[a][this.ca++] = b }, removeEventListener: function(a, b) { var c, d, e = this.H[a], f = []; for (d in e) e.hasOwnProperty(d) && e[d] === b && f.push(d); for (c = 0; c < f.length; c++) d = f[c], delete e[d] }, ga: function() { B(this, 1) }, ia: function(a) { var b, c; try { b = a.x || a.clientX || a.offsetX || 0, c = a.y || a.clientY || a.offsetY || 0 } catch (d) { c = b = 0 } 0 != b && 0 != c && this.addEntropy([b, c], 2, "mouse"); B(this, 0) }, ja: function(a) { a = a.touches[0] || a.changedTouches[0]; this.addEntropy([a.pageX || a.clientX, a.pageY || a.clientY], 1, "touch"); B(this, 0) }, ha: function() { B(this, 2) }, ba: function(a) { a = a.accelerationIncludingGravity.x || a.accelerationIncludingGravity.y || a.accelerationIncludingGravity.z; if (window.orientation) { var b = window.orientation; "number" === typeof b && this.addEntropy(b, 1, "accelerometer") } a && this.addEntropy(a, 2, "accelerometer"); B(this, 0) } }; function z(a, b) { var c, d = sjcl.random.H[a], e = []; for (c in d) d.hasOwnProperty(c) && e.push(d[c]); for (c = 0; c < e.length; c++) e[c](b) } function B(a, b) { "undefined" !== typeof window && window.performance && "function" === typeof window.performance.now ? a.addEntropy(window.performance.now(), b, "loadtime") : a.addEntropy((new Date).valueOf(), b, "loadtime") } function v(a) { a.b = w(a).concat(w(a)); a.I = new sjcl.cipher.aes(a.b) } function w(a) { for (var b = 0; 4 > b && (a.o[b] = a.o[b] + 1 | 0, !a.o[b]); b++); return a.I.encrypt(a.o) } function A(a, b) { return function() { b.apply(a, arguments) } } sjcl.random = new sjcl.prng(6); a: try { var C, D, E, F; if (F = "undefined" !== typeof module && module.exports) { var G; try { G = require("crypto") } catch (a) { G = null } F = D = G } if (F && D.randomBytes) C = D.randomBytes(128), C = new Uint32Array((new Uint8Array(C)).buffer), sjcl.random.addEntropy(C, 1024, "crypto['randomBytes']"); else if ("undefined" !== typeof window && "undefined" !== typeof Uint32Array) { E = new Uint32Array(32); if (window.crypto && window.crypto.getRandomValues) window.crypto.getRandomValues(E); else if (window.msCrypto && window.msCrypto.getRandomValues) window.msCrypto.getRandomValues(E); else break a; sjcl.random.addEntropy(E, 1024, "crypto['getRandomValues']") } } catch (a) { "undefined" !== typeof window && window.console && (pwlog("There was an error collecting entropy from the browser:"), pwlog(a)) } sjcl.bn = function(a) { this.initWith(a) }; sjcl.bn.prototype = { radix: 24, maxMul: 8, h: sjcl.bn, copy: function() { return new this.h(this) }, initWith: function(a) { var b = 0, c; switch (typeof a) { case "object": this.limbs = a.limbs.slice(0); break; case "number": this.limbs = [a]; this.normalize(); break; case "string": a = a.replace(/^0x/, ""); this.limbs = []; c = this.radix / 4; for (b = 0; b < a.length; b += c) this.limbs.push(parseInt(a.substring(Math.max(a.length - b - c, 0), a.length - b), 16)); break; default: this.limbs = [0] } return this }, equals: function(a) { "number" === typeof a && (a = new this.h(a)); var b = 0, c; this.fullReduce(); a.fullReduce(); for (c = 0; c < this.limbs.length || c < a.limbs.length; c++) b |= this.getLimb(c) ^ a.getLimb(c); return 0 === b }, getLimb: function(a) { return a >= this.limbs.length ? 0 : this.limbs[a] }, greaterEquals: function(a) { "number" === typeof a && (a = new this.h(a)); var b = 0, c = 0, d, e, f; for (d = Math.max(this.limbs.length, a.limbs.length) - 1; 0 <= d; d--) e = this.getLimb(d), f = a.getLimb(d), c |= f - e & ~b, b |= e - f & ~c; return (c | ~b) >>> 31 }, toString: function() { this.fullReduce(); var a = "", b, c, d = this.limbs; for (b = 0; b < this.limbs.length; b++) { for (c = d[b].toString(16); b < this.limbs.length - 1 && 6 > c.length;) c = "0" + c; a = c + a } return "0x" + a }, addM: function(a) { "object" !== typeof a && (a = new this.h(a)); var b = this.limbs, c = a.limbs; for (a = b.length; a < c.length; a++) b[a] = 0; for (a = 0; a < c.length; a++) b[a] += c[a]; return this }, doubleM: function() { var a, b = 0, c, d = this.radix, e = this.radixMask, f = this.limbs; for (a = 0; a < f.length; a++) c = f[a], c = c + c + b, f[a] = c & e, b = c >> d; b && f.push(b); return this }, halveM: function() { var a, b = 0, c, d = this.radix, e = this.limbs; for (a = e.length - 1; 0 <= a; a--) c = e[a], e[a] = c + b >> 1, b = (c & 1) << d; e[e.length - 1] || e.pop(); return this }, subM: function(a) { "object" !== typeof a && (a = new this.h(a)); var b = this.limbs, c = a.limbs; for (a = b.length; a < c.length; a++) b[a] = 0; for (a = 0; a < c.length; a++) b[a] -= c[a]; return this }, mod: function(a) { var b = !this.greaterEquals(new sjcl.bn(0)); a = (new sjcl.bn(a)).normalize(); var c = (new sjcl.bn(this)).normalize(), d = 0; for (b && (c = (new sjcl.bn(0)).subM(c).normalize()); c.greaterEquals(a); d++) a.doubleM(); for (b && (c = a.sub(c).normalize()); 0 < d; d--) a.halveM(), c.greaterEquals(a) && c.subM(a).normalize(); return c.trim() }, inverseMod: function(a) { var b = new sjcl.bn(1), c = new sjcl.bn(0), d = new sjcl.bn(this), e = new sjcl.bn(a), f, g = 1; if (!(a.limbs[0] & 1)) throw new sjcl.exception.invalid("inverseMod: p must be odd"); do for (d.limbs[0] & 1 && (d.greaterEquals(e) || (f = d, d = e, e = f, f = b, b = c, c = f), d.subM(e), d.normalize(), b.greaterEquals(c) || b.addM(a), b.subM(c)), d.halveM(), b.limbs[0] & 1 && b.addM(a), b.normalize(), b.halveM(), f = g = 0; f < d.limbs.length; f++) g |= d.limbs[f]; while (g); if (!e.equals(1)) throw new sjcl.exception.invalid("inverseMod: p and x must be relatively prime"); return c }, add: function(a) { return this.copy().addM(a) }, sub: function(a) { return this.copy().subM(a) }, mul: function(a) { "number" === typeof a ? a = new this.h(a) : a.normalize(); this.normalize(); var b, c = this.limbs, d = a.limbs, e = c.length, f = d.length, g = new this.h, h = g.limbs, k, m = this.maxMul; for (b = 0; b < this.limbs.length + a.limbs.length + 1; b++) h[b] = 0; for (b = 0; b < e; b++) { k = c[b]; for (a = 0; a < f; a++) h[b + a] += k * d[a]; --m || (m = this.maxMul, g.cnormalize()) } return g.cnormalize().reduce() }, square: function() { return this.mul(this) }, power: function(a) { a = (new sjcl.bn(a)).normalize().trim().limbs; var b, c, d = new this.h(1), e = this; for (b = 0; b < a.length; b++) for (c = 0; c < this.radix; c++) { a[b] & 1 << c && (d = d.mul(e)); if (b == a.length - 1 && 0 == a[b] >> c + 1) break; e = e.square() } return d }, mulmod: function(a, b) { return this.mod(b).mul(a.mod(b)).mod(b) }, powermod: function(a, b) { a = new sjcl.bn(a); b = new sjcl.bn(b); if (1 == (b.limbs[0] & 1)) { var c = this.montpowermod(a, b); if (0 != c) return c } for (var d, e = a.normalize().trim().limbs, f = new this.h(1), g = this, c = 0; c < e.length; c++) for (d = 0; d < this.radix; d++) { e[c] & 1 << d && (f = f.mulmod(g, b)); if (c == e.length - 1 && 0 == e[c] >> d + 1) break; g = g.mulmod(g, b) } return f }, montpowermod: function(a, b) { function c(a, b) { var c = b % a.radix; return (a.limbs[Math.floor(b / a.radix)] & 1 << c) >> c } function d(a, c) { var d, e, f = (1 << m + 1) - 1; d = a.mul(c); e = d.mul(r); e.limbs = e.limbs.slice(0, k.limbs.length); e.limbs.length == k.limbs.length && (e.limbs[k.limbs.length - 1] &= f); e = e.mul(b); e = d.add(e).normalize().trim(); e.limbs = e.limbs.slice(k.limbs.length - 1); for (d = 0; d < e.limbs.length; d++) 0 < d && (e.limbs[d - 1] |= (e.limbs[d] & f) << g - m - 1), e.limbs[d] >>= m + 1; e.greaterEquals(b) && e.subM(b); return e } a = (new sjcl.bn(a)).normalize().trim(); b = new sjcl.bn(b); var e, f, g = this.radix, h = new this.h(1); e = this.copy(); var k, m, p; p = a.bitLength(); k = new sjcl.bn({ limbs: b.copy().normalize().trim().limbs.map(function() { return 0 }) }); for (m = this.radix; 0 < m; m--) if (1 == (b.limbs[b.limbs.length - 1] >> m & 1)) { k.limbs[k.limbs.length - 1] = 1 << m; break } if (0 == p) return this; p = 18 > p ? 1 : 48 > p ? 3 : 144 > p ? 4 : 768 > p ? 5 : 6; var l = k.copy(), n = b.copy(); f = new sjcl.bn(1); for (var r = new sjcl.bn(0), q = k.copy(); q.greaterEquals(1);) q.halveM(), 0 == (f.limbs[0] & 1) ? (f.halveM(), r.halveM()) : (f.addM(n), f.halveM(), r.halveM(), r.addM(l)); f = f.normalize(); r = r.normalize(); l.doubleM(); n = l.mulmod(l, b); if (!l.mul(f).sub(b.mul(r)).equals(1)) return !1; e = d(e, n); h = d(h, n); l = {}; f = (1 << p - 1) - 1; l[1] = e.copy(); l[2] = d(e, e); for (e = 1; e <= f; e++) l[2 * e + 1] = d(l[2 * e - 1], l[2]); for (e = a.bitLength() - 1; 0 <= e;) if (0 == c(a, e)) h = d(h, h), --e; else { for (n = e - p + 1; 0 == c(a, n);) n++; q = 0; for (f = n; f <= e; f++) q += c(a, f) << f - n, h = d(h, h); h = d(h, l[q]); e = n - 1 } return d(h, 1) }, trim: function() { var a = this.limbs, b; do b = a.pop(); while (a.length && 0 === b); a.push(b); return this }, reduce: function() { return this }, fullReduce: function() { return this.normalize() }, normalize: function() { var a = 0, b, c = this.placeVal, d = this.ipv, e, f = this.limbs, g = f.length, h = this.radixMask; for (b = 0; b < g || 0 !== a && -1 !== a; b++) a = (f[b] || 0) + a, e = f[b] = a & h, a = (a - e) * d; - 1 === a && (f[b - 1] -= c); this.trim(); return this }, cnormalize: function() { var a = 0, b, c = this.ipv, d, e = this.limbs, f = e.length, g = this.radixMask; for (b = 0; b < f - 1; b++) a = e[b] + a, d = e[b] = a & g, a = (a - d) * c; e[b] += a; return this }, toBits: function(a) { this.fullReduce(); a = a || this.exponent || this.bitLength(); var b = Math.floor((a - 1) / 24), c = sjcl.bitArray, d = [c.partial((a + 7 & -8) % this.radix || this.radix, this.getLimb(b))]; for (b--; 0 <= b; b--) d = c.concat(d, [c.partial(Math.min(this.radix, a), this.getLimb(b))]), a -= this.radix; return d }, bitLength: function() { this.fullReduce(); for (var a = this.radix * (this.limbs.length - 1), b = this.limbs[this.limbs.length - 1]; b; b >>>= 1) a++; return a + 7 & -8 } }; sjcl.bn.fromBits = function(a) { var b = new this, c = [], d = sjcl.bitArray, e = this.prototype, f = Math.min(this.bitLength || 0x100000000, d.bitLength(a)), g = f % e.radix || e.radix; for (c[0] = d.extract(a, 0, g); g < f; g += e.radix) c.unshift(d.extract(a, g, e.radix)); b.limbs = c; return b }; sjcl.bn.prototype.ipv = 1 / (sjcl.bn.prototype.placeVal = Math.pow(2, sjcl.bn.prototype.radix)); sjcl.bn.prototype.radixMask = (1 << sjcl.bn.prototype.radix) - 1; sjcl.bn.pseudoMersennePrime = function(a, b) { function c(a) { this.initWith(a) } var d = c.prototype = new sjcl.bn, e, f, g; g = d.modOffset = Math.ceil(f = a / d.radix); d.exponent = a; d.offset = []; d.factor = []; d.minOffset = g; d.fullMask = 0; d.fullOffset = []; d.fullFactor = []; d.modulus = c.modulus = new sjcl.bn(Math.pow(2, a)); d.fullMask = 0 | -Math.pow(2, a % d.radix); for (e = 0; e < b.length; e++) d.offset[e] = Math.floor(b[e][0] / d.radix - f), d.fullOffset[e] = Math.floor(b[e][0] / d.radix) - g + 1, d.factor[e] = b[e][1] * Math.pow(.5, a - b[e][0] + d.offset[e] * d.radix), d.fullFactor[e] = b[e][1] * Math.pow(.5, a - b[e][0] + d.fullOffset[e] * d.radix), d.modulus.addM(new sjcl.bn(Math.pow(2, b[e][0]) * b[e][1])), d.minOffset = Math.min(d.minOffset, -d.offset[e]); d.h = c; d.modulus.cnormalize(); d.reduce = function() { var a, b, c, d = this.modOffset, e = this.limbs, f = this.offset, g = this.offset.length, q = this.factor, u; for (a = this.minOffset; e.length > d;) { c = e.pop(); u = e.length; for (b = 0; b < g; b++) e[u + f[b]] -= q[b] * c; a--; a || (e.push(0), this.cnormalize(), a = this.minOffset) } this.cnormalize(); return this }; d.Y = -1 === d.fullMask ? d.reduce : function() { var a = this.limbs, b = a.length - 1, c, d; this.reduce(); if (b === this.modOffset - 1) { d = a[b] & this.fullMask; a[b] -= d; for (c = 0; c < this.fullOffset.length; c++) a[b + this.fullOffset[c]] -= this.fullFactor[c] * d; this.normalize() } }; d.fullReduce = function() { var a, b; this.Y(); this.addM(this.modulus); this.addM(this.modulus); this.normalize(); this.Y(); for (b = this.limbs.length; b < this.modOffset; b++) this.limbs[b] = 0; a = this.greaterEquals(this.modulus); for (b = 0; b < this.limbs.length; b++) this.limbs[b] -= this.modulus.limbs[b] * a; this.cnormalize(); return this }; d.inverse = function() { return this.power(this.modulus.sub(2)) }; c.fromBits = sjcl.bn.fromBits; return c }; var H = sjcl.bn.pseudoMersennePrime; sjcl.bn.prime = { p127: H(127, [ [0, -1] ]), p25519: H(255, [ [0, -19] ]), p192k: H(192, [ [32, -1], [12, -1], [8, -1], [7, -1], [6, -1], [3, -1], [0, -1] ]), p224k: H(224, [ [32, -1], [12, -1], [11, -1], [9, -1], [7, -1], [4, -1], [1, -1], [0, -1] ]), p256k: H(0x100, [ [32, -1], [9, -1], [8, -1], [7, -1], [6, -1], [4, -1], [0, -1] ]), p192: H(192, [ [0, -1], [64, -1] ]), p224: H(224, [ [0, 1], [96, -1] ]), p256: H(0x100, [ [0, -1], [96, 1], [192, 1], [224, -1] ]), p384: H(384, [ [0, -1], [32, 1], [96, -1], [128, -1] ]), p521: H(521, [ [0, -1] ]) }; sjcl.bn.random = function(a, b) { "object" !== typeof a && (a = new sjcl.bn(a)); for (var c, d, e = a.limbs.length, f = a.limbs[e - 1] + 1, g = new sjcl.bn;;) { do c = sjcl.random.randomWords(e, b), 0 > c[e - 1] && (c[e - 1] += 0x100000000); while (Math.floor(c[e - 1] / f) === Math.floor(0x100000000 / f)); c[e - 1] %= f; for (d = 0; d < e - 1; d++) c[d] &= a.radixMask; g.limbs = c; if (!g.greaterEquals(a)) return g } }; sjcl.keyexchange.srp = { makeVerifier: function(a, b, c, d) { a = sjcl.keyexchange.srp.makeX(a, b, c); a = sjcl.bn.fromBits(a); return d.g.powermod(a, d.N) }, makeX: function(a, b, c) { a = sjcl.hash.sha1.hash(a + ":" + b); return sjcl.hash.sha1.hash(sjcl.bitArray.concat(c, a)) }, knownGroup: function(a) { "string" !== typeof a && (a = a.toString()); sjcl.keyexchange.srp.T || sjcl.keyexchange.srp.fa(); return sjcl.keyexchange.srp.V[a] }, T: !1, fa: function() { var a, b; for (a = 0; a < sjcl.keyexchange.srp.U.length; a++) b = sjcl.keyexchange.srp.U[a].toString(), b = sjcl.keyexchange.srp.V[b], b.N = new sjcl.bn(b.N), b.g = new sjcl.bn(b.g); sjcl.keyexchange.srp.T = !0 }, U: [1024, 1536, 2048, 3072, 0x1000, 6144, 8192], V: { 1024: { N: "EEAF0AB9ADB38DD69C33F80AFA8FC5E86072618775FF3C0B9EA2314C9C256576D674DF7496EA81D3383B4813D692C6E0E0D5D8E250B98BE48E495C1D6089DAD15DC7D7B46154D6B6CE8EF4AD69B15D4982559B297BCF1885C529F566660E57EC68EDBC3C05726CC02FD4CBF4976EAA9AFD5138FE8376435B9FC61D2FC0EB06E3", g: 2 }, 1536: { N: "9DEF3CAFB939277AB1F12A8617A47BBBDBA51DF499AC4C80BEEEA9614B19CC4D5F4F5F556E27CBDE51C6A94BE4607A291558903BA0D0F84380B655BB9A22E8DCDF028A7CEC67F0D08134B1C8B97989149B609E0BE3BAB63D47548381DBC5B1FC764E3F4B53DD9DA1158BFD3E2B9C8CF56EDF019539349627DB2FD53D24B7C48665772E437D6C7F8CE442734AF7CCB7AE837C264AE3A9BEB87F8A2FE9B8B5292E5A021FFF5E91479E8CE7A28C2442C6F315180F93499A234DCF76E3FED135F9BB", g: 2 }, 2048: { N: "AC6BDB41324A9A9BF166DE5E1389582FAF72B6651987EE07FC3192943DB56050A37329CBB4A099ED8193E0757767A13DD52312AB4B03310DCD7F48A9DA04FD50E8083969EDB767B0CF6095179A163AB3661A05FBD5FAAAE82918A9962F0B93B855F97993EC975EEAA80D740ADBF4FF747359D041D5C33EA71D281E446B14773BCA97B43A23FB801676BD207A436C6481F1D2B9078717461A5B9D32E688F87748544523B524B0D57D5EA77A2775D2ECFA032CFBDBF52FB3786160279004E57AE6AF874E7303CE53299CCC041C7BC308D82A5698F3A8D0C38271AE35F8E9DBFBB694B5C803D89F7AE435DE236D525F54759B65E372FCD68EF20FA7111F9E4AFF73", g: 2 }, 3072: { N: "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF", g: 5 }, 0x1000: { N: "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199FFFFFFFFFFFFFFFF", g: 5 }, 6144: { N: "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C93402849236C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BDF8FF9406AD9E530EE5DB382F413001AEB06A53ED9027D831179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1BDB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF5983CA01C64B92ECF032EA15D1721D03F482D7CE6E74FEF6D55E702F46980C82B5A84031900B1C9E59E7C97FBEC7E8F323A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AACC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE32806A1D58BB7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55CDA56C9EC2EF29632387FE8D76E3C0468043E8F663F4860EE12BF2D5B0B7474D6E694F91E6DCC4024FFFFFFFFFFFFFFFF", g: 5 }, 8192: { N: "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C93402849236C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BDF8FF9406AD9E530EE5DB382F413001AEB06A53ED9027D831179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1BDB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF5983CA01C64B92ECF032EA15D1721D03F482D7CE6E74FEF6D55E702F46980C82B5A84031900B1C9E59E7C97FBEC7E8F323A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AACC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE32806A1D58BB7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55CDA56C9EC2EF29632387FE8D76E3C0468043E8F663F4860EE12BF2D5B0B7474D6E694F91E6DBE115974A3926F12FEE5E438777CB6A932DF8CD8BEC4D073B931BA3BC832B68D9DD300741FA7BF8AFC47ED2576F6936BA424663AAB639C5AE4F5683423B4742BF1C978238F16CBE39D652DE3FDB8BEFC848AD922222E04A4037C0713EB57A81A23F0C73473FC646CEA306B4BCBC8862F8385DDFA9D4B7FA2C087E879683303ED5BDD3A062B3CF5B3A278A66D2A13F83F44F82DDF310EE074AB6A364597E899A0255DC164F31CC50846851DF9AB48195DED7EA1B1D510BD7EE74D73FAF36BC31ECFA268359046F4EB879F924009438B481C6CD7889A002ED5EE382BC9190DA6FC026E479558E4475677E9AA9E3050E2765694DFC81F56E880B96E7160C980DD98EDD3DFFFFFFFFFFFFFFFFF", g: 19 } } }; "undefined" !== typeof module && module.exports && (module.exports = sjcl); "function" === typeof define && define([], function() { return sjcl });