// ==UserScript== // @name ao3 subscribe to feed // @version 1 // @require http://crypto.stanford.edu/sjcl/sjcl.js // @grant GM.getValue // @grant GM.setValue // @include https://archiveofourown.org/works/* // ==/UserScript== // User script for Firefox // Password management async function decodeOrPrompt(targVar, userPrompt, setValVarName, encKey) { if (targVar) { targVar = unStoreAndDecrypt(targVar, encKey); } else { targVar = prompt( userPrompt + ' not set for ' + location.hostname + '. Please enter it now:', '' ); await GM.setValue(setValVarName, encryptAndStore(targVar, encKey)); } return targVar; } function encryptAndStore(clearText, encKey) { return JSON.stringify(sjcl.encrypt(encKey, clearText)); } function unStoreAndDecrypt(jsonObj, encKey) { return sjcl.decrypt(encKey, JSON.parse(jsonObj)); } async function getCredentials() { var encKey = await GM.getValue("encKey", ""); var usr = await GM.getValue("ttrssUser", ""); var pword = await GM.getValue("ttrssPass", ""); if (!encKey) { encKey = prompt( 'Script key not set for ' + location.hostname + '. Please enter a random string:', '' ); await GM.setValue("encKey", encKey); usr = pword = ""; // New key makes prev stored values (if any) unable to decode. } usr = await decodeOrPrompt(usr, "TTRSS user", "ttrssUser", encKey); pword = await decodeOrPrompt(pword, "TTRSS password", "ttrssPass", encKey); return { usr: usr, pword: pword }; } // Function to add a button to the