├── .github └── FUNDING.yml ├── .gitignore ├── LICENSE ├── README.md ├── background.js ├── content.js ├── icons ├── 128.png ├── 48.png └── 96.png └── manifest.json /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: CanadaHonk 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | web-ext-artifacts 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2021 GooseMod 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
16 | A light, secure, and easy to use Discord mod; now in your browser. 17 |
18 | -------------------------------------------------------------------------------- /background.js: -------------------------------------------------------------------------------- 1 | const cspAllowAll = [ 2 | 'connect-src', 3 | 'style-src', 4 | 'img-src', 5 | 'font-src' 6 | ]; 7 | 8 | chrome.webRequest.onHeadersReceived.addListener(({ responseHeaders, url }) => { 9 | let csp = responseHeaders.find((x) => x.name === 'content-security-policy'); 10 | 11 | if (csp) { 12 | for (let p of cspAllowAll) { 13 | csp.value = csp.value.replace(`${p}`, `${p} * blob: data:`); // * does not include data: URIs 14 | } 15 | 16 | // Fix Discord's broken CSP which disallows unsafe-inline due to having a nonce (which they don't even use?) 17 | csp.value = csp.value.replace(/'nonce-.*?' /, ''); 18 | } 19 | 20 | return { 21 | responseHeaders 22 | }; 23 | }, 24 | 25 | { 26 | urls: [ 27 | '*://*.discord.com/*' 28 | ] 29 | }, 30 | 31 | ['blocking', 'responseHeaders'] 32 | ); -------------------------------------------------------------------------------- /content.js: -------------------------------------------------------------------------------- 1 | const extVersion = chrome.runtime.getManifest().version; 2 | 3 | const inject = async (branch, version) => { 4 | console.log('[GooseMod for Web] Injecting...'); 5 | 6 | window.gmExtension = version; 7 | 8 | const branchURLs = { 9 | release: 'https://api.goosemod.com/inject.js', 10 | dev: 'https://raw.githubusercontent.com/GooseMod/GooseMod/dist-dev/index.js', 11 | local: 'http://localhost:1234/index.js' 12 | }; 13 | 14 | console.log('[GooseMod for Web] Branch =', branch); 15 | console.log('[GooseMod for Web] JS Url =', branchURLs[branch]); 16 | 17 | const js = await (await fetch(branchURLs[branch])).text(); // JSON.parse(localStorage.getItem('goosemodCoreJSCache')); 18 | 19 | const el = document.createElement('script'); 20 | 21 | el.appendChild(document.createTextNode(js)); 22 | 23 | document.body.appendChild(el); 24 | 25 | console.log('[GooseMod for Web] Injected fetched JS'); 26 | }; 27 | 28 | 29 | // Extension Storage (v10) 30 | const storageCache = {}; 31 | 32 | chrome.storage.local.get(null, (data) => { 33 | Object.assign(storageCache, data); 34 | 35 | if (Object.keys(storageCache).length === 0 && Object.keys(localStorage).find((x) => x.toLowerCase().startsWith('goosemod'))) { // Nothing stored in Extension storage and something GM in localStorage - migrate from LS to Ext 36 | const gmKeys = Object.keys(localStorage).filter((x) => x.toLowerCase().startsWith('goosemod')); 37 | 38 | const setObj = {}; 39 | 40 | for (const k of gmKeys) { 41 | setObj[k] = localStorage.getItem(k); 42 | localStorage.removeItem(k); 43 | } 44 | 45 | console.log('[GooseMod For Web] Migrated from localStorage to Extension', setObj); 46 | 47 | Object.assign(storageCache, setObj); 48 | chrome.storage.local.set(setObj); 49 | } 50 | 51 | 52 | const el = document.createElement('script'); 53 | 54 | el.appendChild(document.createTextNode(`(${inject.toString()})(${JSON.stringify(storageCache['goosemodUntetheredBranch'] || 'release')}, ${JSON.stringify(extVersion)})`)); 55 | 56 | document.body.appendChild(el); 57 | }); 58 | 59 | 60 | document.addEventListener('gmes_get', ({ }) => { 61 | document.dispatchEvent(new CustomEvent('gmes_get_return', { 62 | // Firefox requires cloneInto as doesn't like sending objects from content -> page 63 | detail: typeof cloneInto === 'undefined' ? storageCache : cloneInto(storageCache, window) 64 | })); 65 | }); 66 | 67 | document.addEventListener('gmes_set', ({ detail: { key, value }}) => { 68 | storageCache[key] = value; // Repopulate cache with updated value 69 | 70 | const obj = {}; // Create object for set 71 | obj[key] = value; 72 | 73 | chrome.storage.local.set(obj); // Actually store change 74 | }); 75 | 76 | document.addEventListener('gmes_remove', ({ detail: { key }}) => { 77 | delete storageCache[key]; // Repopulate cache with updated value 78 | 79 | chrome.storage.local.remove(key); // Actually store change 80 | }); -------------------------------------------------------------------------------- /icons/128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GooseMod/Extension/42968c7a543b437992c70039e8786888d2413c31/icons/128.png -------------------------------------------------------------------------------- /icons/48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GooseMod/Extension/42968c7a543b437992c70039e8786888d2413c31/icons/48.png -------------------------------------------------------------------------------- /icons/96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GooseMod/Extension/42968c7a543b437992c70039e8786888d2413c31/icons/96.png -------------------------------------------------------------------------------- /manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "GooseMod for Web", 3 | "description": "A light, secure, and easy to use Discord mod; now in your browser.", 4 | 5 | "version": "1.2.2", 6 | 7 | "author": "GooseMod Team", 8 | "homepage_url": "https://goosemod.com", 9 | 10 | "icons": { 11 | "48": "icons/48.png", 12 | "96": "icons/96.png", 13 | "128": "icons/128.png" 14 | }, 15 | 16 | "background": { 17 | "scripts": [ 18 | "background.js" 19 | ] 20 | }, 21 | 22 | "content_scripts": [ 23 | { 24 | "matches": ["*://*.discord.com/*"], 25 | "js": ["content.js"] 26 | } 27 | ], 28 | 29 | "permissions": [ 30 | "storage", 31 | "webRequest", 32 | "webRequestBlocking", 33 | "*://*.discord.com/*" 34 | ], 35 | 36 | "manifest_version": 2, 37 | 38 | "browser_specific_settings": { 39 | "gecko": { 40 | "id": "invalid@goosemod.com" 41 | } 42 | } 43 | } 44 | --------------------------------------------------------------------------------