From 0ff6d3dd4168ee72f9216cfcccc9307bae5b25a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roman=20/=20Linnea=20Gr=C3=A4f?= Date: Thu, 1 Dec 2022 19:16:09 +0100 Subject: [PATCH] Add Firefox extension build (#277) --- .github/workflows/build.yml | 13 ++++++ README.md | 3 +- browser/background.js | 48 ++++++++++++++++++++ browser/manifestv2.json | 33 ++++++++++++++ browser/{manifest.json => manifestv3.json} | 0 package.json | 9 +++- scripts/build/buildWeb.mjs | 53 +++++++++++++++------- 7 files changed, 140 insertions(+), 19 deletions(-) create mode 100644 browser/background.js create mode 100644 browser/manifestv2.json rename browser/{manifest.json => manifestv3.json} (100%) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 48948290..60bebcc7 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -33,9 +33,22 @@ jobs: - name: Build web run: pnpm buildWeb --standalone + - name: Sign firefox extension + run: | + pnpx web-ext sign --api-key $WEBEXT_USER --api-secret $WEBEXT_SECRET + env: + WEBEXT_USER: ${{ secrets.WEBEXT_USER }} + WEBEXT_SECRET: ${{ secrets.WEBEXT_SECRET }} + - name: Build run: pnpm build --standalone + - name: Rename extensions for more user friendliness + run: | + mv dist/*.xpi dist/Vencord-for-Firefox.xpi + mv dist/extension-v3.zip dist/Vencord-for-Chrome-and-Edge.zip + + - name: Get some values needed for the release id: release_values run: | diff --git a/README.md b/README.md index 2b9e8655..7be2d472 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,8 @@ If you're a power user who wants to contribute and make plugins or just want to ## Installing on Browser -Install [the browser extension](https://github.com/Vendicated/Vencord/releases/latest/download/extension.zip) or [UserScript](https://github.com/Vendicated/Vencord/releases/download/devbuild/Vencord.user.js). Please note that they aren't automatically updated for now, so you will regularely have to reinstall it. +Install the browser extension for [![Chrome](https://img.shields.io/badge/chrome-ext-brightgreen)](https://github.com/Vendicated/Vencord/releases/latest/download/Vencord-for-Chrome-and-Edge.zip), [![Firefox](https://img.shields.io/badge/firefox-ext-brightgreen)](https://github.com/Vendicated/Vencord/releases/latest/download/Vencord-for-Firefox.xpi) or [UserScript](https://github.com/Vendicated/Vencord/releases/download/devbuild/Vencord.user.js). Please note that they aren't automatically updated for now, so you will regularely have to reinstall it. + You may also build them from source, to do that do the same steps as in the manual regular install method, except run `pnpm buildWeb` instead of `pnpm build`, and your outputs will be in the dist folder diff --git a/browser/background.js b/browser/background.js new file mode 100644 index 00000000..5c99dd8f --- /dev/null +++ b/browser/background.js @@ -0,0 +1,48 @@ +/* + * Vencord, a modification for Discord's desktop app + * Copyright (c) 2022 Linnea Gräf + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +function setContentTypeOnStylesheets(details) { + if (details.type === "stylesheet") { + details.responseHeaders = details.responseHeaders.filter(it => it.name.toLowerCase() !== 'content-type'); + details.responseHeaders.push({ name: "Content-Type", value: "text/css" }); + } + return { responseHeaders: details.responseHeaders }; +} + +var cspHeaders = [ + "content-security-policy", + "content-security-policy-report-only", +]; + +function removeCSPHeaders(details) { + return { + responseHeaders: details.responseHeaders.filter(header => + !cspHeaders.includes(header.name.toLowerCase())) + }; +} + + + + +browser.webRequest.onHeadersReceived.addListener( + setContentTypeOnStylesheets, { urls: ["https://raw.githubusercontent.com/*"] }, ["blocking", "responseHeaders"] +); + +browser.webRequest.onHeadersReceived.addListener( + removeCSPHeaders, { urls: ["https://raw.githubusercontent.com/*", "*://*.discord.com/*"] }, ["blocking", "responseHeaders"] +); diff --git a/browser/manifestv2.json b/browser/manifestv2.json new file mode 100644 index 00000000..f7115127 --- /dev/null +++ b/browser/manifestv2.json @@ -0,0 +1,33 @@ +{ + "manifest_version": 2, + "name": "Vencord Web", + "description": "The Vencord Client Mod for Discord Web.", + "version": "1.0.0", + "author": "Vendicated", + "homepage_url": "https://github.com/Vendicated/Vencord", + "permissions": [ + "webRequest", + "webRequestBlocking", + "*://*.discord.com/*", + "https://raw.githubusercontent.com/*" + ], + "content_scripts": [ + { + "run_at": "document_start", + "matches": [ + "*://*.discord.com/*" + ], + "js": [ + "content.js" + ] + } + ], + "web_accessible_resources": [ + "dist/Vencord.js" + ], + "background": { + "scripts": [ + "background.js" + ] + } +} diff --git a/browser/manifest.json b/browser/manifestv3.json similarity index 100% rename from browser/manifest.json rename to browser/manifestv3.json diff --git a/package.json b/package.json index 20eabb78..839e8742 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "vencord", "private": "true", - "version": "1.0.0", + "version": "1.0.1", "description": "A Discord client mod that does things differently", "keywords": [], "homepage": "https://github.com/Vendicated/Vencord#readme", @@ -61,5 +61,12 @@ "patchedDependencies": { "eslint-plugin-path-alias@1.0.0": "patches/eslint-plugin-path-alias@1.0.0.patch" } + }, + "webExt": { + "artifactsDir": "./dist", + "build": { + "overwriteDest": true + }, + "sourceDir": "./dist/extension-v2-unpacked" } } diff --git a/scripts/build/buildWeb.mjs b/scripts/build/buildWeb.mjs index a4ad87f7..7508937a 100755 --- a/scripts/build/buildWeb.mjs +++ b/scripts/build/buildWeb.mjs @@ -20,9 +20,9 @@ import esbuild from "esbuild"; import { zip } from "fflate"; -import { readFileSync, writeFileSync } from "fs"; +import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "fs"; import { readFile } from "fs/promises"; -import { join } from "path"; +import { join, resolve } from "path"; // wtf is this assert syntax import PackageJSON from "../../package.json" assert { type: "json" }; @@ -72,20 +72,39 @@ await Promise.all( ] ); -zip({ - dist: { - "Vencord.js": readFileSync("dist/browser.js") - }, - ...Object.fromEntries(await Promise.all(["modifyResponseHeaders.json", "content.js", "manifest.json"].map(async f => [ - f, - await readFile(join("browser", f)) - ]))), -}, {}, (err, data) => { - if (err) { - console.error(err); - process.exitCode = 1; +async function buildPluginZip(target, files, shouldZip) { + const entries = { + "dist/Vencord.js": readFileSync("dist/browser.js"), + ...Object.fromEntries(await Promise.all(files.map(async f => [ + (f.startsWith("manifest") ? "manifest.json" : f), + await readFile(join("browser", f)) + ]))), + }; + + if (shouldZip) { + zip(entries, {}, (err, data) => { + if (err) { + console.error(err); + process.exitCode = 1; + } else { + writeFileSync("dist/" + target, data); + console.info("Extension written to dist/" + target); + } + }); } else { - writeFileSync("dist/extension.zip", data); - console.info("Extension written to dist/extension.zip"); + if (existsSync(target)) + rmSync(target, { recursive: true }); + for (const entry in entries) { + const destination = "dist/" + target + "/" + entry; + const parentDirectory = resolve(destination, ".."); + mkdirSync(parentDirectory, { recursive: true }); + writeFileSync(destination, entries[entry]); + } + console.info("Unpacked Extension written to dist/" + target); } -}); +} + +await buildPluginZip("extension-v3.zip", ["modifyResponseHeaders.json", "content.js", "manifestv3.json"], true); +await buildPluginZip("extension-v2.zip", ["background.js", "content.js", "manifestv2.json"], true); +await buildPluginZip("extension-v2-unpacked", ["background.js", "content.js", "manifestv2.json"], false); +