diff options
Diffstat (limited to 'src/ipcMain')
| -rw-r--r-- | src/ipcMain/constants.ts | 35 | ||||
| -rw-r--r-- | src/ipcMain/crxToZip.ts | 57 | ||||
| -rw-r--r-- | src/ipcMain/extensions.ts | 85 | ||||
| -rw-r--r-- | src/ipcMain/index.ts | 99 | ||||
| -rw-r--r-- | src/ipcMain/simpleGet.ts | 37 | ||||
| -rw-r--r-- | src/ipcMain/updater/common.ts | 59 | ||||
| -rw-r--r-- | src/ipcMain/updater/git.ts | 83 | ||||
| -rw-r--r-- | src/ipcMain/updater/http.ts | 88 | ||||
| -rw-r--r-- | src/ipcMain/updater/index.ts | 19 |
9 files changed, 0 insertions, 562 deletions
diff --git a/src/ipcMain/constants.ts b/src/ipcMain/constants.ts deleted file mode 100644 index 7133757..0000000 --- a/src/ipcMain/constants.ts +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Vencord, a modification for Discord's desktop app - * Copyright (c) 2022 Vendicated and contributors - * - * 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 <https://www.gnu.org/licenses/>. -*/ - -import { app } from "electron"; -import { join } from "path"; - -export const DATA_DIR = process.env.VENCORD_USER_DATA_DIR ?? ( - process.env.DISCORD_USER_DATA_DIR - ? join(process.env.DISCORD_USER_DATA_DIR, "..", "VencordData") - : join(app.getPath("userData"), "..", "Vencord") -); -export const SETTINGS_DIR = join(DATA_DIR, "settings"); -export const QUICKCSS_PATH = join(SETTINGS_DIR, "quickCss.css"); -export const SETTINGS_FILE = join(SETTINGS_DIR, "settings.json"); -export const ALLOWED_PROTOCOLS = [ - "https:", - "http:", - "steam:", - "spotify:" -]; diff --git a/src/ipcMain/crxToZip.ts b/src/ipcMain/crxToZip.ts deleted file mode 100644 index ca43890..0000000 --- a/src/ipcMain/crxToZip.ts +++ /dev/null @@ -1,57 +0,0 @@ -/* eslint-disable header/header */ - -/*! - * crxToZip - * Copyright (c) 2013 Rob Wu <rob@robwu.nl> - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -export function crxToZip(buf: Buffer) { - function calcLength(a: number, b: number, c: number, d: number) { - let length = 0; - - length += a << 0; - length += b << 8; - length += c << 16; - length += d << 24 >>> 0; - return length; - } - - // 50 4b 03 04 - // This is actually a zip file - if (buf[0] === 80 && buf[1] === 75 && buf[2] === 3 && buf[3] === 4) { - return buf; - } - - // 43 72 32 34 (Cr24) - if (buf[0] !== 67 || buf[1] !== 114 || buf[2] !== 50 || buf[3] !== 52) { - throw new Error("Invalid header: Does not start with Cr24"); - } - - // 02 00 00 00 - // or - // 03 00 00 00 - const isV3 = buf[4] === 3; - const isV2 = buf[4] === 2; - - if ((!isV2 && !isV3) || buf[5] || buf[6] || buf[7]) { - throw new Error("Unexpected crx format version number."); - } - - if (isV2) { - const publicKeyLength = calcLength(buf[8], buf[9], buf[10], buf[11]); - const signatureLength = calcLength(buf[12], buf[13], buf[14], buf[15]); - - // 16 = Magic number (4), CRX format version (4), lengths (2x4) - const zipStartOffset = 16 + publicKeyLength + signatureLength; - - return buf.subarray(zipStartOffset, buf.length); - } - // v3 format has header size and then header - const headerSize = calcLength(buf[8], buf[9], buf[10], buf[11]); - const zipStartOffset = 12 + headerSize; - - return buf.subarray(zipStartOffset, buf.length); -} diff --git a/src/ipcMain/extensions.ts b/src/ipcMain/extensions.ts deleted file mode 100644 index d8f8437..0000000 --- a/src/ipcMain/extensions.ts +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Vencord, a modification for Discord's desktop app - * Copyright (c) 2022 Vendicated and contributors - * - * 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 <https://www.gnu.org/licenses/>. -*/ - -import { session } from "electron"; -import { unzip } from "fflate"; -import { constants as fsConstants } from "fs"; -import { access, mkdir, rm, writeFile } from "fs/promises"; -import { join } from "path"; - -import { DATA_DIR } from "./constants"; -import { crxToZip } from "./crxToZip"; -import { get } from "./simpleGet"; - -const extensionCacheDir = join(DATA_DIR, "ExtensionCache"); - -async function extract(data: Buffer, outDir: string) { - await mkdir(outDir, { recursive: true }); - return new Promise<void>((resolve, reject) => { - unzip(data, (err, files) => { - if (err) return void reject(err); - Promise.all(Object.keys(files).map(async f => { - // Signature stuff - // 'Cannot load extension with file or directory name - // _metadata. Filenames starting with "_" are reserved for use by the system.'; - if (f.startsWith("_metadata/")) return; - - if (f.endsWith("/")) return void mkdir(join(outDir, f), { recursive: true }); - - const pathElements = f.split("/"); - const name = pathElements.pop()!; - const directories = pathElements.join("/"); - const dir = join(outDir, directories); - - if (directories) { - await mkdir(dir, { recursive: true }); - } - - await writeFile(join(dir, name), files[f]); - })) - .then(() => resolve()) - .catch(err => { - rm(outDir, { recursive: true, force: true }); - reject(err); - }); - }); - }); -} - -export async function installExt(id: string) { - const extDir = join(extensionCacheDir, `${id}`); - - try { - await access(extDir, fsConstants.F_OK); - } catch (err) { - const url = id === "fmkadmapgofadopljbjfkapdkoienihi" - // React Devtools v4.25 - // v4.27 is broken in Electron, see https://github.com/facebook/react/issues/25843 - // Unfortunately, Google does not serve old versions, so this is the only way - ? "https://raw.githubusercontent.com/Vendicated/random-files/f6f550e4c58ac5f2012095a130406c2ab25b984d/fmkadmapgofadopljbjfkapdkoienihi.zip" - : `https://clients2.google.com/service/update2/crx?response=redirect&acceptformat=crx2,crx3&x=id%3D${id}%26uc&prodversion=32`; - const buf = await get(url, { - headers: { - "User-Agent": "Vencord (https://github.com/Vendicated/Vencord)" - } - }); - await extract(crxToZip(buf), extDir).catch(console.error); - } - - session.defaultSession.loadExtension(extDir); -} diff --git a/src/ipcMain/index.ts b/src/ipcMain/index.ts deleted file mode 100644 index 6fb31d1..0000000 --- a/src/ipcMain/index.ts +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Vencord, a modification for Discord's desktop app - * Copyright (c) 2022 Vendicated and contributors - * - * 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 <https://www.gnu.org/licenses/>. -*/ - -import "./updater"; - -import { debounce } from "@utils/debounce"; -import IpcEvents from "@utils/IpcEvents"; -import { Queue } from "@utils/Queue"; -import { BrowserWindow, ipcMain, shell } from "electron"; -import { mkdirSync, readFileSync, watch } from "fs"; -import { open, readFile, writeFile } from "fs/promises"; -import { join } from "path"; - -import monacoHtml from "~fileContent/../components/monacoWin.html;base64"; - -import { ALLOWED_PROTOCOLS, QUICKCSS_PATH, SETTINGS_DIR, SETTINGS_FILE } from "./constants"; - -mkdirSync(SETTINGS_DIR, { recursive: true }); - -function readCss() { - return readFile(QUICKCSS_PATH, "utf-8").catch(() => ""); -} - -export function readSettings() { - try { - return readFileSync(SETTINGS_FILE, "utf-8"); - } catch { - return "{}"; - } -} - -ipcMain.handle(IpcEvents.OPEN_QUICKCSS, () => shell.openPath(QUICKCSS_PATH)); - -ipcMain.handle(IpcEvents.OPEN_EXTERNAL, (_, url) => { - try { - var { protocol } = new URL(url); - } catch { - throw "Malformed URL"; - } - if (!ALLOWED_PROTOCOLS.includes(protocol)) - throw "Disallowed protocol."; - - shell.openExternal(url); -}); - -const cssWriteQueue = new Queue(); -const settingsWriteQueue = new Queue(); - -ipcMain.handle(IpcEvents.GET_QUICK_CSS, () => readCss()); -ipcMain.handle(IpcEvents.SET_QUICK_CSS, (_, css) => - cssWriteQueue.push(() => writeFile(QUICKCSS_PATH, css)) -); - -ipcMain.handle(IpcEvents.GET_SETTINGS_DIR, () => SETTINGS_DIR); -ipcMain.on(IpcEvents.GET_SETTINGS, e => e.returnValue = readSettings()); - -ipcMain.handle(IpcEvents.SET_SETTINGS, (_, s) => { - settingsWriteQueue.push(() => writeFile(SETTINGS_FILE, s)); -}); - - -export function initIpc(mainWindow: BrowserWindow) { - open(QUICKCSS_PATH, "a+").then(fd => { - fd.close(); - watch(QUICKCSS_PATH, { persistent: false }, debounce(async () => { - mainWindow.webContents.postMessage(IpcEvents.QUICK_CSS_UPDATE, await readCss()); - }, 50)); - }); -} - -ipcMain.handle(IpcEvents.OPEN_MONACO_EDITOR, async () => { - const win = new BrowserWindow({ - title: "QuickCss Editor", - autoHideMenuBar: true, - darkTheme: true, - webPreferences: { - preload: join(__dirname, "preload.js"), - contextIsolation: true, - nodeIntegration: false, - sandbox: false - } - }); - await win.loadURL(`data:text/html;base64,${monacoHtml}`); -}); diff --git a/src/ipcMain/simpleGet.ts b/src/ipcMain/simpleGet.ts deleted file mode 100644 index 1a8302c..0000000 --- a/src/ipcMain/simpleGet.ts +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Vencord, a modification for Discord's desktop app - * Copyright (c) 2022 Vendicated and contributors - * - * 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 <https://www.gnu.org/licenses/>. -*/ - -import https from "https"; - -export function get(url: string, options: https.RequestOptions = {}) { - return new Promise<Buffer>((resolve, reject) => { - https.get(url, options, res => { - const { statusCode, statusMessage, headers } = res; - if (statusCode! >= 400) - return void reject(`${statusCode}: ${statusMessage} - ${url}`); - if (statusCode! >= 300) - return void resolve(get(headers.location!, options)); - - const chunks = [] as Buffer[]; - res.on("error", reject); - - res.on("data", chunk => chunks.push(chunk)); - res.once("end", () => resolve(Buffer.concat(chunks))); - }); - }); -} diff --git a/src/ipcMain/updater/common.ts b/src/ipcMain/updater/common.ts deleted file mode 100644 index 3729c6d..0000000 --- a/src/ipcMain/updater/common.ts +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Vencord, a modification for Discord's desktop app - * Copyright (c) 2022 Vendicated and contributors - * - * 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 <https://www.gnu.org/licenses/>. -*/ - -import { createHash } from "crypto"; -import { createReadStream } from "fs"; -import { join } from "path"; - -export async function calculateHashes() { - const hashes = {} as Record<string, string>; - - await Promise.all( - ["patcher.js", "preload.js", "renderer.js", "renderer.css"].map(file => new Promise<void>(r => { - const fis = createReadStream(join(__dirname, file)); - const hash = createHash("sha1", { encoding: "hex" }); - fis.once("end", () => { - hash.end(); - hashes[file] = hash.read(); - r(); - }); - fis.pipe(hash); - })) - ); - - return hashes; -} - -export function serializeErrors(func: (...args: any[]) => any) { - return async function () { - try { - return { - ok: true, - value: await func(...arguments) - }; - } catch (e: any) { - return { - ok: false, - error: e instanceof Error ? { - // prototypes get lost, so turn error into plain object - ...e - } : e - }; - } - }; -} diff --git a/src/ipcMain/updater/git.ts b/src/ipcMain/updater/git.ts deleted file mode 100644 index 89c2d3c..0000000 --- a/src/ipcMain/updater/git.ts +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Vencord, a modification for Discord's desktop app - * Copyright (c) 2022 Vendicated and contributors - * - * 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 <https://www.gnu.org/licenses/>. -*/ - -import IpcEvents from "@utils/IpcEvents"; -import { execFile as cpExecFile } from "child_process"; -import { ipcMain } from "electron"; -import { join } from "path"; -import { promisify } from "util"; - -import { calculateHashes, serializeErrors } from "./common"; - -const VENCORD_SRC_DIR = join(__dirname, ".."); - -const execFile = promisify(cpExecFile); - -const isFlatpak = process.platform === "linux" && Boolean(process.env.FLATPAK_ID?.includes("discordapp") || process.env.FLATPAK_ID?.includes("Discord")); - -if (process.platform === "darwin") process.env.PATH = `/usr/local/bin:${process.env.PATH}`; - -function git(...args: string[]) { - const opts = { cwd: VENCORD_SRC_DIR }; - - if (isFlatpak) return execFile("flatpak-spawn", ["--host", "git", ...args], opts); - else return execFile("git", args, opts); -} - -async function getRepo() { - const res = await git("remote", "get-url", "origin"); - return res.stdout.trim() - .replace(/git@(.+):/, "https://$1/") - .replace(/\.git$/, ""); -} - -async function calculateGitChanges() { - await git("fetch"); - - const res = await git("log", "HEAD...origin/main", "--pretty=format:%an/%h/%s"); - - const commits = res.stdout.trim(); - return commits ? commits.split("\n").map(line => { - const [author, hash, ...rest] = line.split("/"); - return { - hash, author, message: rest.join("/") - }; - }) : []; -} - -async function pull() { - const res = await git("pull"); - return res.stdout.includes("Fast-forward"); -} - -async function build() { - const opts = { cwd: VENCORD_SRC_DIR }; - - const command = isFlatpak ? "flatpak-spawn" : "node"; - const args = isFlatpak ? ["--host", "node", "scripts/build/build.mjs"] : ["scripts/build/build.mjs"]; - - const res = await execFile(command, args, opts); - - return !res.stderr.includes("Build failed"); -} - -ipcMain.handle(IpcEvents.GET_HASHES, serializeErrors(calculateHashes)); -ipcMain.handle(IpcEvents.GET_REPO, serializeErrors(getRepo)); -ipcMain.handle(IpcEvents.GET_UPDATES, serializeErrors(calculateGitChanges)); -ipcMain.handle(IpcEvents.UPDATE, serializeErrors(pull)); -ipcMain.handle(IpcEvents.BUILD, serializeErrors(build)); diff --git a/src/ipcMain/updater/http.ts b/src/ipcMain/updater/http.ts deleted file mode 100644 index cc10631..0000000 --- a/src/ipcMain/updater/http.ts +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Vencord, a modification for Discord's desktop app - * Copyright (c) 2022 Vendicated and contributors - * - * 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 <https://www.gnu.org/licenses/>. -*/ - -import { VENCORD_USER_AGENT } from "@utils/constants"; -import IpcEvents from "@utils/IpcEvents"; -import { ipcMain } from "electron"; -import { writeFile } from "fs/promises"; -import { join } from "path"; - -import gitHash from "~git-hash"; -import gitRemote from "~git-remote"; - -import { get } from "../simpleGet"; -import { calculateHashes, serializeErrors } from "./common"; - -const API_BASE = `https://api.github.com/repos/${gitRemote}`; -let PendingUpdates = [] as [string, string][]; - -async function githubGet(endpoint: string) { - return get(API_BASE + endpoint, { - headers: { - Accept: "application/vnd.github+json", - // "All API requests MUST include a valid User-Agent header. - // Requests with no User-Agent header will be rejected." - "User-Agent": VENCORD_USER_AGENT - } - }); -} - -async function calculateGitChanges() { - const isOutdated = await fetchUpdates(); - if (!isOutdated) return []; - - const res = await githubGet(`/compare/${gitHash}...HEAD`); - - const data = JSON.parse(res.toString("utf-8")); - return data.commits.map((c: any) => ({ - // github api only sends the long sha - hash: c.sha.slice(0, 7), - author: c.author.login, - message: c.commit.message - })); -} - -async function fetchUpdates() { - const release = await githubGet("/releases/latest"); - - const data = JSON.parse(release.toString()); - const hash = data.name.slice(data.name.lastIndexOf(" ") + 1); - if (hash === gitHash) - return false; - - data.assets.forEach(({ name, browser_download_url }) => { - if (["patcher.js", "preload.js", "renderer.js", "renderer.css"].some(s => name.startsWith(s))) { - PendingUpdates.push([name, browser_download_url]); - } - }); - return true; -} - -async function applyUpdates() { - await Promise.all(PendingUpdates.map( - async ([name, data]) => writeFile(join(__dirname, name), await get(data))) - ); - PendingUpdates = []; - return true; -} - -ipcMain.handle(IpcEvents.GET_HASHES, serializeErrors(calculateHashes)); -ipcMain.handle(IpcEvents.GET_REPO, serializeErrors(() => `https://github.com/${gitRemote}`)); -ipcMain.handle(IpcEvents.GET_UPDATES, serializeErrors(calculateGitChanges)); -ipcMain.handle(IpcEvents.UPDATE, serializeErrors(fetchUpdates)); -ipcMain.handle(IpcEvents.BUILD, serializeErrors(applyUpdates)); diff --git a/src/ipcMain/updater/index.ts b/src/ipcMain/updater/index.ts deleted file mode 100644 index 7036112..0000000 --- a/src/ipcMain/updater/index.ts +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Vencord, a modification for Discord's desktop app - * Copyright (c) 2022 Vendicated and contributors - * - * 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 <https://www.gnu.org/licenses/>. -*/ - -import(IS_STANDALONE ? "./http" : "./git"); |
