From 69316d7850a85e1cca818057de563f12c5a36e9f Mon Sep 17 00:00:00 2001 From: LoneWeeb <73281112+Tharki-God@users.noreply.github.com> Date: Fri, 7 Jul 2023 04:15:55 +0530 Subject: [PATCH 1/6] should be fixed now --- cspell.json | 1 + 1 file changed, 1 insertion(+) diff --git a/cspell.json b/cspell.json index d07002b60..c17c3f4a8 100644 --- a/cspell.json +++ b/cspell.json @@ -33,6 +33,7 @@ "installdir", "Jsonifiable", "konami", + "keybind", "lezer", "LOCALAPPDATA", "logname", From 6ee72b8f228b40c73da62f7f4a453507e85f0269 Mon Sep 17 00:00:00 2001 From: Tharki-God Date: Thu, 21 Dec 2023 17:38:00 +0530 Subject: [PATCH 2/6] fixiii fixoo uwu --- src/main/index.ts | 5 +- src/main/ipc/plugins.ts | 41 +++++++++----- src/main/ipc/themes.ts | 121 +++++++++++++++++++++++----------------- src/types/index.ts | 2 + src/util.mts | 39 +++++++++++-- 5 files changed, 137 insertions(+), 71 deletions(-) diff --git a/src/main/index.ts b/src/main/index.ts index acbb2dc45..5f56ef28a 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -4,7 +4,6 @@ import electron from "electron"; import { CONFIG_PATHS } from "src/util.mjs"; import type { RepluggedWebContents } from "../types"; import { getSetting } from "./ipc/settings"; - const electronPath = require.resolve("electron"); const discordPath = join(dirname(require.main!.filename), "..", "app.orig.asar"); // require.main!.filename = discordMain; @@ -170,10 +169,10 @@ electron.app.once("ready", () => { filePath = join(CONFIG_PATHS.quickcss, reqUrl.pathname); break; case "theme": - filePath = join(CONFIG_PATHS.themes, reqUrl.pathname); + filePath = join(reqUrl.pathname.includes(".asar") ? CONFIG_PATHS.temp_themes : CONFIG_PATHS.themes, reqUrl.pathname.replace(".asar", "")); break; case "plugin": - filePath = join(CONFIG_PATHS.plugins, reqUrl.pathname); + filePath = join(reqUrl.pathname.includes(".asar") ? CONFIG_PATHS.temp_plugins : CONFIG_PATHS.plugins, reqUrl.pathname.replace(".asar", "")); break; } cb({ path: filePath }); diff --git a/src/main/ipc/plugins.ts b/src/main/ipc/plugins.ts index 67b9bc884..3e3165008 100644 --- a/src/main/ipc/plugins.ts +++ b/src/main/ipc/plugins.ts @@ -4,23 +4,30 @@ IPC events: - REPLUGGED_UNINSTALL_PLUGIN: returns whether a plugin by the provided name was successfully uninstalled */ -import { readFile, readdir, readlink, rm, stat } from "fs/promises"; +import { readFile, readdir, readlink, stat } from "fs/promises"; import { extname, join, sep } from "path"; import { ipcMain, shell } from "electron"; import { RepluggedIpcChannels, type RepluggedPlugin } from "../../types"; import { plugin } from "../../types/addon"; -import type { Dirent, Stats } from "fs"; -import { CONFIG_PATHS } from "src/util.mjs"; +import { type Dirent, type Stats, rmdirSync, unlinkSync } from "fs"; +import { CONFIG_PATHS, extractAddon } from "src/util.mjs"; const PLUGINS_DIR = CONFIG_PATHS.plugins; +const TEMP_PLUGINS_DIR = CONFIG_PATHS.temp_plugins; export const isFileAPlugin = (f: Dirent | Stats, name: string): boolean => { return f.isDirectory() || (f.isFile() && extname(name) === ".asar"); }; async function getPlugin(pluginName: string): Promise { - const manifestPath = join(PLUGINS_DIR, pluginName, "manifest.json"); - if (!manifestPath.startsWith(`${PLUGINS_DIR}${sep}`)) { + const isAsar = pluginName.includes('.asar'); + const pluginPath = join(PLUGINS_DIR, pluginName); + const realPluginPath = isAsar ? join(TEMP_PLUGINS_DIR, pluginName.replace(/\.asar$/, "")) : pluginPath; // Remove ".asar" from the directory name + if (isAsar) + await extractAddon(pluginPath, realPluginPath); + + const manifestPath = join(realPluginPath, "manifest.json"); + if (!manifestPath.startsWith(`${realPluginPath}${sep}`)) { // Ensure file changes are restricted to the base path throw new Error("Invalid plugin name"); } @@ -40,7 +47,7 @@ async function getPlugin(pluginName: string): Promise { const cssPath = data.manifest.renderer?.replace(/\.js$/, ".css"); const hasCSS = cssPath && - (await stat(join(PLUGINS_DIR, pluginName, cssPath)) + (await stat(join(realPluginPath, cssPath)) .then(() => true) .catch(() => false)); @@ -49,12 +56,13 @@ async function getPlugin(pluginName: string): Promise { return data; } + ipcMain.handle( RepluggedIpcChannels.GET_PLUGIN, async (_, pluginName: string): Promise => { try { return await getPlugin(pluginName); - } catch {} + } catch { } }, ); @@ -90,17 +98,24 @@ ipcMain.handle(RepluggedIpcChannels.LIST_PLUGINS, async (): Promise { +ipcMain.handle(RepluggedIpcChannels.UNINSTALL_PLUGIN, (_, pluginName: string) => { + const isAsar = pluginName.includes('.asar'); const pluginPath = join(PLUGINS_DIR, pluginName); - if (!pluginPath.startsWith(`${PLUGINS_DIR}${sep}`)) { + const realPluginPath = isAsar ? join(TEMP_PLUGINS_DIR, pluginName.replace(".asar", "")) : pluginPath; // Remove ".asar" from the directory name + + if (!realPluginPath.startsWith(`${isAsar ? TEMP_PLUGINS_DIR : PLUGINS_DIR}${sep}`)) { // Ensure file changes are restricted to the base path throw new Error("Invalid plugin name"); } - await rm(pluginPath, { - recursive: true, - force: true, - }); + if (isAsar) { + unlinkSync(pluginPath); + rmdirSync(realPluginPath, { recursive: true, }); + } + else rmdirSync(pluginPath, { recursive: true, }); }); + ipcMain.on(RepluggedIpcChannels.OPEN_PLUGINS_FOLDER, () => shell.openPath(PLUGINS_DIR)); + +ipcMain.on(RepluggedIpcChannels.CLEAR_TEMP_THEME, () => { try { rmdirSync(TEMP_PLUGINS_DIR, { recursive: true }) } catch { } }); diff --git a/src/main/ipc/themes.ts b/src/main/ipc/themes.ts index 740bed3f3..83a0f9f80 100644 --- a/src/main/ipc/themes.ts +++ b/src/main/ipc/themes.ts @@ -3,28 +3,40 @@ IPC events: - REPLUGGED_LIST_THEMES: returns an array of all valid themes available - REPLUGGED_UNINSTALL_THEME: uninstalls a theme by name */ +import { type Dirent, type Stats, rmdirSync, unlinkSync } from 'fs'; +import { readFile, readdir, readlink, stat, } from 'fs/promises'; +import { extname, join, sep } from 'path'; +import { ipcMain, shell } from 'electron'; +import { RepluggedIpcChannels, type RepluggedTheme } from '../../types'; +import { theme } from '../../types/addon'; +import { CONFIG_PATHS, extractAddon } from 'src/util.mjs'; + + + -import { readFile, readdir, readlink, rm, stat } from "fs/promises"; -import { extname, join, sep } from "path"; -import { ipcMain, shell } from "electron"; -import { RepluggedIpcChannels, type RepluggedTheme } from "../../types"; -import { theme } from "../../types/addon"; -import { CONFIG_PATHS } from "src/util.mjs"; -import type { Dirent, Stats } from "fs"; const THEMES_DIR = CONFIG_PATHS.themes; +const TEMP_THEMES_DIR = CONFIG_PATHS.temp_themes; + export const isFileATheme = (f: Dirent | Stats, name: string): boolean => { - return f.isDirectory() || (f.isFile() && extname(name) === ".asar"); + return f.isDirectory() || (f.isFile() && extname(name) === '.asar'); }; + async function getTheme(path: string): Promise { - const manifestPath = join(THEMES_DIR, path, "manifest.json"); - if (!manifestPath.startsWith(`${THEMES_DIR}${sep}`)) { + const isAsar = path.includes('.asar'); + const themePath = join(THEMES_DIR, path); + const realThemePath = isAsar ? join(TEMP_THEMES_DIR, path.replace(/\.asar$/, "")) : themePath; // Remove ".asar" from the directory name + if (isAsar) + await extractAddon(themePath, realThemePath); + + const manifestPath = join(realThemePath, 'manifest.json'); + + if (!manifestPath.startsWith(`${realThemePath}${sep}`)) { // Ensure file changes are restricted to the base path - throw new Error("Invalid theme name"); + throw new Error("Invalid plugin name"); } - const manifest: unknown = JSON.parse( await readFile(manifestPath, { encoding: "utf-8", @@ -37,57 +49,66 @@ async function getTheme(path: string): Promise { }; } + + ipcMain.handle( RepluggedIpcChannels.GET_THEME, async (_, path: string): Promise => { try { return await getTheme(path); - } catch {} + } catch { } }, ); -ipcMain.handle(RepluggedIpcChannels.LIST_THEMES, async (): Promise => { - const themes = []; - - const themeDirs = ( - await Promise.all( - ( - await readdir(THEMES_DIR, { - withFileTypes: true, - }) - ).map(async (f) => { - if (isFileATheme(f, f.name)) return f; - if (f.isSymbolicLink()) { - const actualPath = await readlink(join(THEMES_DIR, f.name)); - const actualFile = await stat(actualPath); - if (isFileATheme(actualFile, actualPath)) return f; - } - }), - ) - ).filter(Boolean) as Dirent[]; - - for (const themeDir of themeDirs) { - try { - themes.push(await getTheme(themeDir.name)); - } catch (e) { - console.error(e); +ipcMain.handle( + RepluggedIpcChannels.LIST_THEMES, + async (): Promise => { + const themes = []; + + const themeDirs = ( + await Promise.all( + ( + await readdir(THEMES_DIR, { + withFileTypes: true, + }) + ).map(async (f) => { + if (isFileATheme(f, f.name)) return f; + if (f.isSymbolicLink()) { + const actualPath = await readlink(join(THEMES_DIR, f.name)); + const actualFile = await stat(actualPath); + if (isFileATheme(actualFile, actualPath)) return f; + } + }), + ) + ).filter(Boolean) as Dirent[]; + + for (const themeDir of themeDirs) { + try { + themes.push(await getTheme(themeDir.name)); + } catch (e) { + console.error(e); + } } - } - return themes; -}); + return themes; + }, +); -ipcMain.handle(RepluggedIpcChannels.UNINSTALL_THEME, async (_, themeName: string) => { +ipcMain.handle(RepluggedIpcChannels.UNINSTALL_THEME, (_, themeName: string) => { + const isAsar = themeName.includes('.asar'); const themePath = join(THEMES_DIR, themeName); - if (!themePath.startsWith(`${THEMES_DIR}${sep}`)) { - // Ensure file changes are restricted to the base path - throw new Error("Invalid theme name"); - } + const realThemePath = isAsar ? join(TEMP_THEMES_DIR, themeName.replace(/\.asar$/, "")) : themePath; // Remove ".asar" from the directory name - await rm(themePath, { - recursive: true, - force: true, - }); + if (!realThemePath.startsWith(`${isAsar ? TEMP_THEMES_DIR : THEMES_DIR}${sep}`)) { + throw new Error('Invalid theme name'); + } + if (isAsar) { + unlinkSync(themePath); + rmdirSync(realThemePath, { recursive: true, }); + } + else rmdirSync(themePath, { recursive: true, }); }); ipcMain.on(RepluggedIpcChannels.OPEN_THEMES_FOLDER, () => shell.openPath(THEMES_DIR)); + +ipcMain.on(RepluggedIpcChannels.CLEAR_TEMP_THEME, () => { try { rmdirSync(TEMP_THEMES_DIR, { recursive: true }) } catch { } }); diff --git a/src/types/index.ts b/src/types/index.ts index e614b2c92..bf5c9b692 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -29,6 +29,8 @@ export enum RepluggedIpcChannels { INSTALL_ADDON = "REPLUGGED_INSTALL_ADDON", OPEN_PLUGINS_FOLDER = "REPLUGGED_OPEN_PLUGINS_FOLDER", OPEN_THEMES_FOLDER = "REPLUGGED_OPEN_THEMES_FOLDER", + CLEAR_TEMP_PLUGIN = "REPLUGGED_CLEAR_PLUGIN_TEMP", + CLEAR_TEMP_THEME = "REPLUGGED_CLEAR_THEME_TEMP", OPEN_SETTINGS_FOLDER = "REPLUGGED_OPEN_SETTINGS_FOLDER", OPEN_QUICKCSS_FOLDER = "REPLUGGED_OPEN_QUICKCSS_FOLDER", GET_REPLUGGED_VERSION = "REPLUGGED_GET_REPLUGGED_VERSION", diff --git a/src/util.mts b/src/util.mts index 99a1f8a85..248237ae8 100644 --- a/src/util.mts +++ b/src/util.mts @@ -1,9 +1,12 @@ import esbuild from "esbuild"; import { execSync } from "child_process"; -import { chownSync, existsSync, mkdirSync, statSync, writeFileSync } from "fs"; +import { extractAll } from '@electron/asar'; +import { tmpdir } from "os"; +import { chownSync, existsSync, mkdirSync, mkdtempSync, statSync, writeFileSync } from "fs"; import path, { join } from "path"; import chalk from "chalk"; + const REPLUGGED_FOLDER_NAME = "replugged"; export const configPathFn = (): string => { const realUser = process.env.SUDO_USER || process.env.DOAS_USER; @@ -55,18 +58,31 @@ const CONFIG_FOLDER_NAMES = [ "settings", "quickcss", "react-devtools", + "temp_themes", "temp_plugins" ] as const; export const CONFIG_PATHS = Object.fromEntries( CONFIG_FOLDER_NAMES.map((name) => { - const path = join(CONFIG_PATH, name); - if (!existsSync(path)) { - mkdirSync(path); + switch (name) { + case "temp_themes": { + return [name, mkdtempSync(join(tmpdir(), 'replugged-theme-'))] + } + case "temp_plugins": { + return [name, mkdtempSync(join(tmpdir(), 'replugged-plugin-'))] + } + default: { + const path = join(CONFIG_PATH, name); + if (!existsSync(path)) { + mkdirSync(path); + } + return [name, path]; + } } - return [name, path]; }), ) as Record<(typeof CONFIG_FOLDER_NAMES)[number], string>; + + const { uid: REAL_UID, gid: REAL_GID } = statSync(join(CONFIG_PATH, "..")); const shouldChown = process.platform === "linux"; if (shouldChown) { @@ -145,3 +161,16 @@ export const logBuildPlugin: esbuild.Plugin = { }); }, }; + + + +export const extractAddon = async (srcPath: string, destPath: string): Promise => { + return new Promise((res) => { + // Ensure the destination directory exists + mkdirSync(destPath, { recursive: true }); + + // Extract the contents of the asar archive directly into the destination directory + extractAll(srcPath, destPath); + res() + }); +} From 435c45875726f8373e2a401e3bcafd248a58fa8a Mon Sep 17 00:00:00 2001 From: Tharki-God Date: Thu, 21 Dec 2023 17:41:27 +0530 Subject: [PATCH 3/6] idk how it got here --- cspell.json | 1 - 1 file changed, 1 deletion(-) diff --git a/cspell.json b/cspell.json index a47eb787a..2e4895344 100644 --- a/cspell.json +++ b/cspell.json @@ -37,7 +37,6 @@ "installdir", "Jsonifiable", "konami", - "keybind", "lezer", "LOCALAPPDATA", "logname", From d3c63c7a8b7669e9a0c31b9c3d3aa8980e70ab49 Mon Sep 17 00:00:00 2001 From: Tharki-God Date: Thu, 21 Dec 2023 17:43:49 +0530 Subject: [PATCH 4/6] pretty?? --- src/main/index.ts | 10 +++- src/main/ipc/plugins.ts | 30 ++++++----- src/main/ipc/themes.ts | 111 +++++++++++++++++++--------------------- src/util.mts | 18 +++---- 4 files changed, 84 insertions(+), 85 deletions(-) diff --git a/src/main/index.ts b/src/main/index.ts index 5f56ef28a..da8b3de8b 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -169,10 +169,16 @@ electron.app.once("ready", () => { filePath = join(CONFIG_PATHS.quickcss, reqUrl.pathname); break; case "theme": - filePath = join(reqUrl.pathname.includes(".asar") ? CONFIG_PATHS.temp_themes : CONFIG_PATHS.themes, reqUrl.pathname.replace(".asar", "")); + filePath = join( + reqUrl.pathname.includes(".asar") ? CONFIG_PATHS.temp_themes : CONFIG_PATHS.themes, + reqUrl.pathname.replace(".asar", ""), + ); break; case "plugin": - filePath = join(reqUrl.pathname.includes(".asar") ? CONFIG_PATHS.temp_plugins : CONFIG_PATHS.plugins, reqUrl.pathname.replace(".asar", "")); + filePath = join( + reqUrl.pathname.includes(".asar") ? CONFIG_PATHS.temp_plugins : CONFIG_PATHS.plugins, + reqUrl.pathname.replace(".asar", ""), + ); break; } cb({ path: filePath }); diff --git a/src/main/ipc/plugins.ts b/src/main/ipc/plugins.ts index 3e3165008..9b824de99 100644 --- a/src/main/ipc/plugins.ts +++ b/src/main/ipc/plugins.ts @@ -20,11 +20,12 @@ export const isFileAPlugin = (f: Dirent | Stats, name: string): boolean => { }; async function getPlugin(pluginName: string): Promise { - const isAsar = pluginName.includes('.asar'); + const isAsar = pluginName.includes(".asar"); const pluginPath = join(PLUGINS_DIR, pluginName); - const realPluginPath = isAsar ? join(TEMP_PLUGINS_DIR, pluginName.replace(/\.asar$/, "")) : pluginPath; // Remove ".asar" from the directory name - if (isAsar) - await extractAddon(pluginPath, realPluginPath); + const realPluginPath = isAsar + ? join(TEMP_PLUGINS_DIR, pluginName.replace(/\.asar$/, "")) + : pluginPath; // Remove ".asar" from the directory name + if (isAsar) await extractAddon(pluginPath, realPluginPath); const manifestPath = join(realPluginPath, "manifest.json"); if (!manifestPath.startsWith(`${realPluginPath}${sep}`)) { @@ -56,13 +57,12 @@ async function getPlugin(pluginName: string): Promise { return data; } - ipcMain.handle( RepluggedIpcChannels.GET_PLUGIN, async (_, pluginName: string): Promise => { try { return await getPlugin(pluginName); - } catch { } + } catch {} }, ); @@ -99,9 +99,11 @@ ipcMain.handle(RepluggedIpcChannels.LIST_PLUGINS, async (): Promise { - const isAsar = pluginName.includes('.asar'); + const isAsar = pluginName.includes(".asar"); const pluginPath = join(PLUGINS_DIR, pluginName); - const realPluginPath = isAsar ? join(TEMP_PLUGINS_DIR, pluginName.replace(".asar", "")) : pluginPath; // Remove ".asar" from the directory name + const realPluginPath = isAsar + ? join(TEMP_PLUGINS_DIR, pluginName.replace(".asar", "")) + : pluginPath; // Remove ".asar" from the directory name if (!realPluginPath.startsWith(`${isAsar ? TEMP_PLUGINS_DIR : PLUGINS_DIR}${sep}`)) { // Ensure file changes are restricted to the base path @@ -110,12 +112,14 @@ ipcMain.handle(RepluggedIpcChannels.UNINSTALL_PLUGIN, (_, pluginName: string) => if (isAsar) { unlinkSync(pluginPath); - rmdirSync(realPluginPath, { recursive: true, }); - } - else rmdirSync(pluginPath, { recursive: true, }); + rmdirSync(realPluginPath, { recursive: true }); + } else rmdirSync(pluginPath, { recursive: true }); }); - ipcMain.on(RepluggedIpcChannels.OPEN_PLUGINS_FOLDER, () => shell.openPath(PLUGINS_DIR)); -ipcMain.on(RepluggedIpcChannels.CLEAR_TEMP_THEME, () => { try { rmdirSync(TEMP_PLUGINS_DIR, { recursive: true }) } catch { } }); +ipcMain.on(RepluggedIpcChannels.CLEAR_TEMP_THEME, () => { + try { + rmdirSync(TEMP_PLUGINS_DIR, { recursive: true }); + } catch {} +}); diff --git a/src/main/ipc/themes.ts b/src/main/ipc/themes.ts index 83a0f9f80..8d69914c9 100644 --- a/src/main/ipc/themes.ts +++ b/src/main/ipc/themes.ts @@ -3,35 +3,28 @@ IPC events: - REPLUGGED_LIST_THEMES: returns an array of all valid themes available - REPLUGGED_UNINSTALL_THEME: uninstalls a theme by name */ -import { type Dirent, type Stats, rmdirSync, unlinkSync } from 'fs'; -import { readFile, readdir, readlink, stat, } from 'fs/promises'; -import { extname, join, sep } from 'path'; -import { ipcMain, shell } from 'electron'; -import { RepluggedIpcChannels, type RepluggedTheme } from '../../types'; -import { theme } from '../../types/addon'; -import { CONFIG_PATHS, extractAddon } from 'src/util.mjs'; - - - - +import { type Dirent, type Stats, rmdirSync, unlinkSync } from "fs"; +import { readFile, readdir, readlink, stat } from "fs/promises"; +import { extname, join, sep } from "path"; +import { ipcMain, shell } from "electron"; +import { RepluggedIpcChannels, type RepluggedTheme } from "../../types"; +import { theme } from "../../types/addon"; +import { CONFIG_PATHS, extractAddon } from "src/util.mjs"; const THEMES_DIR = CONFIG_PATHS.themes; const TEMP_THEMES_DIR = CONFIG_PATHS.temp_themes; - export const isFileATheme = (f: Dirent | Stats, name: string): boolean => { - return f.isDirectory() || (f.isFile() && extname(name) === '.asar'); + return f.isDirectory() || (f.isFile() && extname(name) === ".asar"); }; - async function getTheme(path: string): Promise { - const isAsar = path.includes('.asar'); + const isAsar = path.includes(".asar"); const themePath = join(THEMES_DIR, path); const realThemePath = isAsar ? join(TEMP_THEMES_DIR, path.replace(/\.asar$/, "")) : themePath; // Remove ".asar" from the directory name - if (isAsar) - await extractAddon(themePath, realThemePath); + if (isAsar) await extractAddon(themePath, realThemePath); - const manifestPath = join(realThemePath, 'manifest.json'); + const manifestPath = join(realThemePath, "manifest.json"); if (!manifestPath.startsWith(`${realThemePath}${sep}`)) { // Ensure file changes are restricted to the base path @@ -49,66 +42,66 @@ async function getTheme(path: string): Promise { }; } - - ipcMain.handle( RepluggedIpcChannels.GET_THEME, async (_, path: string): Promise => { try { return await getTheme(path); - } catch { } + } catch {} }, ); -ipcMain.handle( - RepluggedIpcChannels.LIST_THEMES, - async (): Promise => { - const themes = []; - - const themeDirs = ( - await Promise.all( - ( - await readdir(THEMES_DIR, { - withFileTypes: true, - }) - ).map(async (f) => { - if (isFileATheme(f, f.name)) return f; - if (f.isSymbolicLink()) { - const actualPath = await readlink(join(THEMES_DIR, f.name)); - const actualFile = await stat(actualPath); - if (isFileATheme(actualFile, actualPath)) return f; - } - }), - ) - ).filter(Boolean) as Dirent[]; - - for (const themeDir of themeDirs) { - try { - themes.push(await getTheme(themeDir.name)); - } catch (e) { - console.error(e); - } +ipcMain.handle(RepluggedIpcChannels.LIST_THEMES, async (): Promise => { + const themes = []; + + const themeDirs = ( + await Promise.all( + ( + await readdir(THEMES_DIR, { + withFileTypes: true, + }) + ).map(async (f) => { + if (isFileATheme(f, f.name)) return f; + if (f.isSymbolicLink()) { + const actualPath = await readlink(join(THEMES_DIR, f.name)); + const actualFile = await stat(actualPath); + if (isFileATheme(actualFile, actualPath)) return f; + } + }), + ) + ).filter(Boolean) as Dirent[]; + + for (const themeDir of themeDirs) { + try { + themes.push(await getTheme(themeDir.name)); + } catch (e) { + console.error(e); } + } - return themes; - }, -); + return themes; +}); ipcMain.handle(RepluggedIpcChannels.UNINSTALL_THEME, (_, themeName: string) => { - const isAsar = themeName.includes('.asar'); + const isAsar = themeName.includes(".asar"); const themePath = join(THEMES_DIR, themeName); - const realThemePath = isAsar ? join(TEMP_THEMES_DIR, themeName.replace(/\.asar$/, "")) : themePath; // Remove ".asar" from the directory name + const realThemePath = isAsar + ? join(TEMP_THEMES_DIR, themeName.replace(/\.asar$/, "")) + : themePath; // Remove ".asar" from the directory name if (!realThemePath.startsWith(`${isAsar ? TEMP_THEMES_DIR : THEMES_DIR}${sep}`)) { - throw new Error('Invalid theme name'); + throw new Error("Invalid theme name"); } if (isAsar) { unlinkSync(themePath); - rmdirSync(realThemePath, { recursive: true, }); - } - else rmdirSync(themePath, { recursive: true, }); + rmdirSync(realThemePath, { recursive: true }); + } else rmdirSync(themePath, { recursive: true }); }); ipcMain.on(RepluggedIpcChannels.OPEN_THEMES_FOLDER, () => shell.openPath(THEMES_DIR)); -ipcMain.on(RepluggedIpcChannels.CLEAR_TEMP_THEME, () => { try { rmdirSync(TEMP_THEMES_DIR, { recursive: true }) } catch { } }); +ipcMain.on(RepluggedIpcChannels.CLEAR_TEMP_THEME, () => { + try { + rmdirSync(TEMP_THEMES_DIR, { recursive: true }); + } catch {} +}); diff --git a/src/util.mts b/src/util.mts index 248237ae8..3157755b2 100644 --- a/src/util.mts +++ b/src/util.mts @@ -1,12 +1,11 @@ import esbuild from "esbuild"; import { execSync } from "child_process"; -import { extractAll } from '@electron/asar'; +import { extractAll } from "@electron/asar"; import { tmpdir } from "os"; import { chownSync, existsSync, mkdirSync, mkdtempSync, statSync, writeFileSync } from "fs"; import path, { join } from "path"; import chalk from "chalk"; - const REPLUGGED_FOLDER_NAME = "replugged"; export const configPathFn = (): string => { const realUser = process.env.SUDO_USER || process.env.DOAS_USER; @@ -58,17 +57,18 @@ const CONFIG_FOLDER_NAMES = [ "settings", "quickcss", "react-devtools", - "temp_themes", "temp_plugins" + "temp_themes", + "temp_plugins", ] as const; export const CONFIG_PATHS = Object.fromEntries( CONFIG_FOLDER_NAMES.map((name) => { switch (name) { case "temp_themes": { - return [name, mkdtempSync(join(tmpdir(), 'replugged-theme-'))] + return [name, mkdtempSync(join(tmpdir(), "replugged-theme-"))]; } case "temp_plugins": { - return [name, mkdtempSync(join(tmpdir(), 'replugged-plugin-'))] + return [name, mkdtempSync(join(tmpdir(), "replugged-plugin-"))]; } default: { const path = join(CONFIG_PATH, name); @@ -81,8 +81,6 @@ export const CONFIG_PATHS = Object.fromEntries( }), ) as Record<(typeof CONFIG_FOLDER_NAMES)[number], string>; - - const { uid: REAL_UID, gid: REAL_GID } = statSync(join(CONFIG_PATH, "..")); const shouldChown = process.platform === "linux"; if (shouldChown) { @@ -162,8 +160,6 @@ export const logBuildPlugin: esbuild.Plugin = { }, }; - - export const extractAddon = async (srcPath: string, destPath: string): Promise => { return new Promise((res) => { // Ensure the destination directory exists @@ -171,6 +167,6 @@ export const extractAddon = async (srcPath: string, destPath: string): Promise Date: Thu, 4 Apr 2024 04:11:27 +0530 Subject: [PATCH 5/6] Update src/main/ipc/themes.ts Co-authored-by: Federico Di Leo <38290480+FedeIlLeone@users.noreply.github.com> --- src/main/ipc/themes.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/ipc/themes.ts b/src/main/ipc/themes.ts index 8d69914c9..795271cf5 100644 --- a/src/main/ipc/themes.ts +++ b/src/main/ipc/themes.ts @@ -28,7 +28,7 @@ async function getTheme(path: string): Promise { if (!manifestPath.startsWith(`${realThemePath}${sep}`)) { // Ensure file changes are restricted to the base path - throw new Error("Invalid plugin name"); + throw new Error("Invalid theme name"); } const manifest: unknown = JSON.parse( await readFile(manifestPath, { From 0f1b8ea4b2a156f4f21cbdcb0ba15748afe861da Mon Sep 17 00:00:00 2001 From: Tharki-God Date: Tue, 18 Jun 2024 03:07:06 +0530 Subject: [PATCH 6/6] linux build fix --- src/util.mts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/util.mts b/src/util.mts index 3157755b2..c0ca1d1d2 100644 --- a/src/util.mts +++ b/src/util.mts @@ -85,7 +85,12 @@ const { uid: REAL_UID, gid: REAL_GID } = statSync(join(CONFIG_PATH, "..")); const shouldChown = process.platform === "linux"; if (shouldChown) { chownSync(CONFIG_PATH, REAL_UID, REAL_GID); - CONFIG_FOLDER_NAMES.forEach((folder) => chownSync(join(CONFIG_PATH, folder), REAL_UID, REAL_GID)); + CONFIG_FOLDER_NAMES.forEach( + (folder) => + folder !== "temp_themes" && + folder !== "temp_plugins" && + chownSync(join(CONFIG_PATH, folder), REAL_UID, REAL_GID), + ); } const QUICK_CSS_FILE = join(CONFIG_PATHS.quickcss, "main.css");