forked from aarondoet/AccountSwitcher
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathAccountSwitcher.plugin.js
More file actions
executable file
·38 lines (38 loc) · 13.5 KB
/
AccountSwitcher.plugin.js
File metadata and controls
executable file
·38 lines (38 loc) · 13.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
module.exports=(()=>{const a={info:{name:"AccountSwitcher",authors:[{name:"l0c4lh057",discord_id:"226677096091484160",github_username:"l0c4lh057",twitter_username:"l0c4lh057"}],version:"1.3.2",description:"Simply switch between accounts with the ease of pressing a single key.",github:"https://github.com/l0c4lh057/AccountSwitcher",github_raw:"https://raw.githubusercontent.com/l0c4lh057/AccountSwitcher/master/AccountSwitcher.plugin.js"},changelog:[{title:"Changed",type:"progress",items:["Switched to a newer, even more secure encryption method."]},{title:"Fixed",type:"fixed",items:["Showing the keybinds in the settings again. (The toggle for encryption still does not work but that is added by ZeresPluginLibrary which I do not control.)"]}]};let b=null;const c="aes-256-cbc",d=require("buffer").Buffer;return global.ZeresPluginLibrary?(([e,f])=>{return((e,f)=>{const{WebpackModules:g,PluginUtilities:h,DiscordModules:i,Settings:j,Toasts:k,Modals:l,DOMTools:m}=f,{React:n,ReactDOM:o,UserStore:p,UserInfoStore:q}=i,r=g.getByProps("loginToken"),s=g.getByDisplayName("Markdown"),t=g.getByProps("inputEventUnregister").inputEventUnregister.bind(g.getByProps("inputEventUnregister")),u=g.getByProps("inputEventRegister").inputEventRegister.bind(g.getByProps("inputEventUnregister")),v=require("crypto");BdApi.Plugins.get("BugReportHelper")||BdApi.getData(a.info.name,"didShowIssueHelperPopup")||(BdApi.saveData(a.info.name,"didShowIssueHelperPopup",!0),BdApi.showConfirmationModal("Do you want to download a helper plugin?",[`Do you want to download a helper plugin that makes it easier for you to report issues? That plugin is not needed to anything else to function correctly but nice to have when reporting iissues, shortening the time until the problem gets resolved by asking you for specific information and also including additional information you did not provide.`],{confirmText:"Download",cancelText:"Cancel",onConfirm:()=>{require("request").get("https://raw.githubusercontent.com/l0c4lh057/BetterDiscordStuff/master/Plugins/BugReportHelper/BugReportHelper.plugin.js",(a,b,c)=>a?require("electron").shell.openExternal("https://betterdiscord.net/ghdl?url=https://raw.githubusercontent.com/l0c4lh057/BetterDiscordStuff/master/Plugins/BugReportHelper/BugReportHelper.plugin.js"):void require("fs").writeFile(require("path").join(BdApi.Plugins.folder,"BugReportHelper.plugin.js"),c,()=>{window.setTimeout(()=>BdApi.Plugins.enable("BugReportHelper"),1e3)}))}}));const w=class extends g.getByDisplayName("KeyRecorder"){render(){const a=g.getByProps("ButtonLink"),b=a.default,c=super.render();return c.props.children.props.children.props.children.push(n.createElement(i.FlexChild,{style:{margin:0}},n.createElement(b,{className:g.getByProps("editIcon","button").button.split(" ")[1],size:b.Sizes.MIN,color:a.ButtonColors.GREY,look:a.ButtonLooks.GHOST,onClick:this.props.onRemove},"Remove"))),c}},x=class extends i.Keybind{constructor(a){super(a)}render(){const a=super.render();return a.type=w,a.props.account=this.props.account,a.props.onRemove=this.props.onRemove,a}},y=class extends j.SettingField{constructor(a,b,c){super(a.name+" ("+a.id+")","",b,x,{defaultValue:-1!==a.keybind[0]&&a.keybind.map(b=>[0,b])||[],onChange:a=>b=>{Array.isArray(b)&&(a.props.value=b,this.onChange(b.map(b=>b[1])))},account:a,onRemove:c})}};return class extends e{updateAvatars(){this.settings.accounts.forEach(a=>{const b=p.getUser(a.id);b&&(a.avatar=b.avatarURL)})}onStart(){b=null,this.loadSettings(),this.settings.salt===void 0&&(this.settings.salt=v.randomBytes(32).toString("base64")),this.settings.accounts.forEach(a=>this.registerKeybind(a)),this.openMenu=this.openMenu.bind(this),h.addStyle("accountswitcher-style",`
.accountswitcher-switchmenu {
position: fixed;
width: auto;
height: auto;
background-color: #202225;
border-radius: 10px;
overflow: hidden;
z-index: 1000;
}
.accountswitcher-accountwrapper {
position: relative;
display: inline-block;
margin: 10px;
width: 64px;
height: 64px;
}
.accountswitcher-menuavatar {
width: 64px;
height: 64px;
}
.accountswitcher-removeaccount {
position: absolute;
top: -4px;
right: -4px;
background-color: #111;
width: 1em;
height: 1em;
border-radius: 0.5em;
color: #ccc;
text-align: center;
border: 2px solid #444;
}
.accountswitcher-settingsbtnwrapper {
right: 0;
position: absolute;
}
`),document.addEventListener("mouseup",this.openMenu),this.updateAvatars(),2!==this.settings.encryptionVersion&&(this.settings.encrypted?this.requirePassword("The encryption algorithm got updated for better security. Please enter your password to decrypt your tokens and encrypt them again with the new algorithm.").then(()=>{this.settings.encTest=this.encryptUpdated("test",b),this.settings.accounts.forEach(a=>{a.token=this.encryptUpdated(this.encryptUpdated(this.decryptDeprecated(this.decryptDeprecated(a.token,b),a.id),a.id),b)}),this.settings.encryptionVersion=2,this.saveSettings()}):(this.settings.accounts.forEach(a=>{a.token=this.encryptUpdated(this.decryptDeprecated(a.token,a.id),a.id)}),this.settings.encryptionVersion=2,this.saveSettings()))}onStop(){this.settings.accounts.forEach(a=>this.unregisterKeybind(a)),document.removeEventListener("mouseup",this.openMenu),h.removeStyle("accountswitcher-style")}get defaultSettings(){return{accounts:[],encrypted:!1,encTest:"test",pluginsToRestart:["AccountDetailsPlus","AutoStartRichPresence"],encryptionVersion:1}}openMenu(a){if(2!=a.which)return;if(!a.target||!a.target.classList)return;if(!a.target.classList.contains(g.getByProps("avatar","container","nameTag").avatar.split(" ")[0]))return;a.preventDefault();const b=document.createElement("div"),c=a=>n.createElement("div",{className:"accountswitcher-accountwrapper"},n.createElement("img",{src:a.avatar,className:"accountswitcher-menuavatar",onClick:()=>this.login(a)}),n.createElement("div",{className:"accountswitcher-removeaccount",onClick:()=>{this.unregisterKeybind(a),this.settings.accounts=this.settings.accounts.filter(b=>b.id!=a.id),this.saveSettings(),k.show("Account "+a.name+" removed",{type:k.ToastTypes.success})}},"\u2A2F"));if(0<this.settings.accounts.length){const d=m.offset(a.target);o.render(n.createElement("div",{className:"accountswitcher-switchmenu",style:{bottom:d.bottom-d.top+27,left:d.left-5}},this.settings.accounts.map(a=>n.createElement(c,a))),b),document.body.appendChild(b)}else k.show("No accounts to display",{type:k.ToastTypes.warning});const d=a=>{a.target&&a.target.classList&&(a.target.classList.contains("accountswitcher-switchmenu")||a.target.classList.contains("accountswitcher-removeaccount")||(b.remove(),document.removeEventListener(d)))};document.addEventListener("click",d)}login(a){return console.log("Logging in as "+a.name),a.id==p.getCurrentUser().id?k.show("Already using account "+a.name,{type:k.ToastTypes.warning}):void(console.log("Logging in as "+a.name),this.requirePassword().then(()=>{const c=null===b?a.token:this.decrypt(a.token,b);r.loginToken(this.decrypt(c,a.id)),window.setTimeout(this.updateAvatars,5e3),this.settings.pluginsToRestart.forEach(a=>{BdApi.Plugins.isEnabled(a)&&(BdApi.Plugins.disable(a),window.setTimeout(()=>BdApi.Plugins.enable(a),5e3))})}))}getSettingsPanel(){const a=document.createElement("div");a.className="form",a.style="width:100%;";const c=new j.SettingGroup("Accounts",{shown:!0}),d=a=>{if(!a){let a=p.getCurrentUser(),c=this.encrypt(q.getToken(),a.id),e={name:a.tag,id:a.id,avatar:a.avatarURL,keybind:[64,10+this.settings.accounts.length],token:this.settings.encrypted?this.encrypt(c,b):c};return this.settings.accounts.push(e),this.saveSettings(),this.registerKeybind(e),d(e)}const e=new y(a,b=>{this.unregisterKeybind(a),a.keybind=b,this.saveSettings(),this.registerKeybind(a)},()=>{this.unregisterKeybind(a),this.settings.accounts=this.settings.accounts.filter(b=>b.id!=a.id),this.saveSettings(),k.show("Account "+a.name+" got removed. After reopening the settings it will also be gone from this list.",{type:k.ToastTypes.success})});c.append(e)},e=document.createElement("button");return e.className="button-38aScr lookFilled-1Gx00P colorBrand-3pXr91 sizeMedium-1AC_Sl grow-q77ONN",e.addEventListener("click",()=>this.settings.accounts.some(a=>a.id==p.getCurrentUser().id)?k.show("You already saved this account",{type:k.ToastTypes.error}):void this.requirePassword().then(()=>{d()})),e.innerText="Save Account",new j.SettingGroup(this.getName(),{shown:!0}).appendTo(a).append(new j.Switch("Encrypt tokens","Encrypting tokens makes sure that nobody will be able to get the tokens without knowing the password.",this.settings.encrypted,a=>{if(a!==this.settings.encrypted)if(a){const a=()=>{let c="",d="";l.showModal("Set password",n.createElement("div",{},n.createElement("input",{type:"password",placeholder:"Password",onChange:a=>{c=a.target.value}}),n.createElement("input",{type:"password",placeholder:"Repeat password",onChange:a=>{d=a.target.value}})),{onConfirm:()=>c==d?void(b=c,this.settings.encrypted=!0,this.settings.encTest=this.encrypt("test",b),this.settings.accounts.forEach(a=>a.token=this.encrypt(a.token,b)),this.saveSettings()):(k.show("Passwords don't match",{type:k.ToastTypes.error}),a())})};a()}else{const a=()=>{let c="";l.showModal("Disable encryption",n.createElement("div",{},n.createElement(s,{},"Are you sure that you want to disable encryption? To verify please input your current password. You can also choose the 'Forgot Password' option which will remove all saved accounts. To abort just click outside of this popout."),n.createElement("input",{type:"password",placeholder:"Password",onChange:a=>{c=a.target.value}})),{onConfirm:()=>{try{if("test"!==this.decrypt(this.settings.encTest,c))return k.show("Passwords incorrect",{type:k.ToastTypes.error}),a();this.settings.encrypted=!1,this.settings.encTest="test",this.settings.accounts.forEach(a=>a.token=this.decrypt(a.token,c)),b=null,this.saveSettings()}catch(b){return k.show("Passwords incorrect",{type:k.ToastTypes.error}),a()}},onCancel:()=>{l.showConfirmationModal("Are you sure?","You are about to disable encryption which will remove all your currently saved accounts without an option to recover them. Only use this if you really forgot your password.",{onConfirm:()=>{this.settings.encTest="test",this.settings.encrypted=!1,this.settings.accounts=[],b=null,this.saveSettings()}})},confirmText:"Disable encryption",cancelText:"Forgot Password"})};a()}})).append(c).append(e).append(new j.Textbox("Plugins to restart","Put the name of all plugins that should get restarted when you switch accounts in this textbox separated by a comma",this.settings.pluginsToRestart.join(","),a=>{this.settings.pluginsToRestart=a.split(",").map(a=>a.trim()).filter(a=>a),this.saveSettings()})),this.settings.accounts.forEach(a=>d(a)),a}async requirePassword(a){return this.settings.encrypted&&null===b?new Promise(c=>{const d=e=>{let f="";l.showModal("Password required",n.createElement(n.Fragment,a?a:null,a?n.createElement("br"):null,n.createElement("input",{type:"password",onChange:a=>{f=a.target.value}})),{onConfirm:()=>{try{if("test"!==this.decrypt(this.settings.encTest,f))return k.show("Wrong password",{type:k.ToastTypes.error}),d(e+1);b=f,c()}catch(a){k.show("Wrong password",{type:k.ToastTypes.error}),d(e+1)}}})};d(0)}):Promise.resolve()}encryptDeprecated(a,b){const c=v.createCipher("aes-128-cbc",b);return c.update(a,"utf8","hex")+c.final("hex")}decryptDeprecated(a,b){const c=v.createDecipher("aes-128-cbc",b);return c.update(a,"hex","utf8")+c.final("utf8")}generateEncryptionKey(a){return v.pbkdf2Sync(d.from(a,"utf8"),this.settings.salt,1e5,32,"sha512")}encryptUpdated(a,b){const e=v.randomBytes(16),f=v.createCipheriv(c,this.generateEncryptionKey(b),e),g=d.concat([f.update(a),f.final()]);return e.toString("base64")+":"+g.toString("base64")}decryptUpdated(a,b){const e=a.split(":"),f=d.from(e.shift(),"base64"),g=d.from(e.join(":"),"base64"),h=v.createDecipheriv(c,this.generateEncryptionKey(b),f),i=d.concat([h.update(g),h.final()]);return i.toString()}encrypt(a,b){return 2===this.settings.encryptionVersion?this.encryptUpdated(a,b):this.encryptDeprecated(a,b)}decrypt(a,b){return 2===this.settings.encryptionVersion?this.decryptUpdated(a,b):this.decryptDeprecated(a,b)}registerKeybind(a){u("119"+a.id,a.keybind.map(b=>[0,b]),()=>{this.login(a)},{blurred:!1,focused:!0,keydown:!0,keyup:!1})}unregisterKeybind(a){t("119"+a.id)}loadSettings(){this.settings=h.loadSettings(this.getName(),this.defaultSettings),Array.isArray(this.settings.accounts)||(this.settings.accounts=Object.values(this.settings.accounts)),this.settings.accounts.forEach(a=>{Array.isArray(a.keybind)||(a.keybind=Object.values(a.keybind))})}saveSettings(){h.saveSettings(this.getName(),this.settings)}}})(e,f)})(global.ZeresPluginLibrary.buildPlugin(a)):class{constructor(){this._config=a}getName(){return a.info.name}getAuthor(){return a.info.authors.map(b=>b.name).join(", ")}getDescription(){return a.info.description}getVersion(){return a.info.version}load(){BdApi.showConfirmationModal("Library plugin is needed",[`The library plugin needed for ${a.info.name} is missing. Please click Download Now to install it.`],{confirmText:"Download",cancelText:"Cancel",onConfirm:()=>{require("request").get("https://rauenzi.github.io/BDPluginLibrary/release/0PluginLibrary.plugin.js",async(a,b,c)=>a?require("electron").shell.openExternal("https://betterdiscord.net/ghdl?url=https://raw.githubusercontent.com/rauenzi/BDPluginLibrary/master/release/0PluginLibrary.plugin.js"):void(await new Promise(a=>require("fs").writeFile(require("path").join(BdApi.Plugins.folder,"0PluginLibrary.plugin.js"),c,a))))}})}start(){}stop(){}}})();