fix: storing rpc encrypted password

This commit is contained in:
Chubby Granny Chaser
2025-05-09 10:29:25 +01:00
parent 408adb566c
commit a01c77b424
7 changed files with 42 additions and 17 deletions

View File

@@ -6,7 +6,7 @@ import type { TrendingGame } from "@types";
const getTrendingGames = async (_event: Electron.IpcMainInvokeEvent) => {
const language = await db
.get<string, string>(levelKeys.language, {
valueEncoding: "utf-8",
valueEncoding: "utf8",
})
.then((language) => language || "en");

View File

@@ -6,7 +6,7 @@ import { db, levelKeys } from "@main/level";
const getBadges = async (_event: Electron.IpcMainInvokeEvent) => {
const language = await db
.get<string, string>(levelKeys.language, {
valueEncoding: "utf-8",
valueEncoding: "utf8",
})
.then((language) => language || "en");

View File

@@ -16,7 +16,7 @@ const updateUserPreferences = async (
if (preferences.language) {
await db.put<string, string>(levelKeys.language, preferences.language, {
valueEncoding: "utf-8",
valueEncoding: "utf8",
});
i18next.changeLanguage(preferences.language);

View File

@@ -60,7 +60,7 @@ app.whenReady().then(async () => {
await loadState();
const language = await db.get<string, string>(levelKeys.language, {
valueEncoding: "utf-8",
valueEncoding: "utf8",
});
if (language) i18n.changeLanguage(language);

View File

@@ -14,4 +14,5 @@ export const levelKeys = {
userPreferences: "userPreferences",
language: "language",
screenState: "screenState",
rpcPassword: "rpcPassword",
};

View File

@@ -25,7 +25,7 @@ export const getGameAchievementData = async (
const language = await db
.get<string, string>(levelKeys.language, {
valueEncoding: "utf-8",
valueEncoding: "utf8",
})
.then((language) => language || "en");

View File

@@ -1,4 +1,4 @@
import axios from "axios";
import axios, { AxiosInstance } from "axios";
import cp from "node:child_process";
import fs from "node:fs";
@@ -7,7 +7,8 @@ import crypto from "node:crypto";
import { pythonRpcLogger } from "./logger";
import { Readable } from "node:stream";
import { app, dialog } from "electron";
import { app, dialog, safeStorage } from "electron";
import { db, levelKeys } from "@main/level";
interface GamePayload {
game_id: string;
@@ -30,17 +31,10 @@ const rustBinaryNameByPlatform: Partial<Record<NodeJS.Platform, string>> = {
export class PythonRPC {
public static readonly BITTORRENT_PORT = "5881";
public static readonly RPC_PORT = "8084";
private static readonly RPC_PASSWORD = crypto.randomBytes(32).toString("hex");
public static rpc: AxiosInstance;
private static pythonProcess: cp.ChildProcess | null = null;
public static readonly rpc = axios.create({
baseURL: `http://localhost:${this.RPC_PORT}`,
headers: {
"x-hydra-rpc-password": this.RPC_PASSWORD,
},
});
private static logStderr(readable: Readable | null) {
if (!readable) return;
@@ -48,14 +42,37 @@ export class PythonRPC {
readable.on("data", pythonRpcLogger.log);
}
public static spawn(
private static async getRPCPassword() {
const existingPassword = await db.get(levelKeys.rpcPassword, {
valueEncoding: "utf8",
});
if (existingPassword)
return safeStorage.decryptString(Buffer.from(existingPassword, "hex"));
const newPassword = crypto.randomBytes(32).toString("hex");
await db.put(
levelKeys.rpcPassword,
safeStorage.encryptString(newPassword).toString("hex"),
{
valueEncoding: "utf8",
}
);
return newPassword;
}
public static async spawn(
initialDownload?: GamePayload,
initialSeeding?: GamePayload[]
) {
const rpcPassword = await this.getRPCPassword();
const commonArgs = [
this.BITTORRENT_PORT,
this.RPC_PORT,
this.RPC_PASSWORD,
rpcPassword,
initialDownload ? JSON.stringify(initialDownload) : "",
initialSeeding ? JSON.stringify(initialSeeding) : "",
app.isPackaged
@@ -116,6 +133,13 @@ export class PythonRPC {
this.pythonProcess = childProcess;
}
this.rpc = axios.create({
baseURL: `http://localhost:${this.RPC_PORT}`,
headers: {
"x-hydra-rpc-password": rpcPassword,
},
});
}
public static kill() {