diff --git a/src-tauri/src/keys.rs b/src-tauri/src/keys.rs new file mode 100644 index 0000000..0bfebb6 --- /dev/null +++ b/src-tauri/src/keys.rs @@ -0,0 +1,8 @@ +pub struct Keys; + +impl Keys { + pub const SERVER_RECEIVE_TRANSFER_KEY: &str = ""; + pub const SERVER_SEND_TRANSFER_KEY: &str = ""; + pub const CONFIG_ENCRYPTION_KEY: &str = ""; + pub const VERSIONS_ENCRYPTION_KEY: &str = ""; +} diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index f2c9918..b0b770f 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -1,4 +1,7 @@ #[cfg_attr(mobile, tauri::mobile_entry_point)] + +mod keys; + use futures_util::stream::StreamExt; use std::{ fs::{File, create_dir_all}, @@ -12,6 +15,7 @@ use tauri_plugin_dialog::{DialogExt, MessageDialogKind}; use tauri_plugin_opener::OpenerExt; use tokio::{io::AsyncWriteExt, task::spawn_blocking, time::timeout}; use zip::ZipArchive; +use keys::Keys; #[cfg(target_os = "linux")] use std::{fs, os::unix::fs::PermissionsExt}; @@ -207,6 +211,17 @@ fn download_leaderboard(app: AppHandle, content: String) { }) } +#[tauri::command] +fn get_keys_config(key: i8) -> String { + match key { + 0 => Keys::SERVER_RECEIVE_TRANSFER_KEY.to_string(), + 1 => Keys::SERVER_SEND_TRANSFER_KEY.to_string(), + 2 => Keys::CONFIG_ENCRYPTION_KEY.to_string(), + 3 => Keys::VERSIONS_ENCRYPTION_KEY.to_string(), + _ => "".to_string(), + } +} + pub fn run() { #[allow(unused_variables)] tauri::Builder::default() @@ -225,7 +240,8 @@ pub fn run() { .invoke_handler(tauri::generate_handler![ download, launch_game, - download_leaderboard + download_leaderboard, + get_keys_config ]) .setup(|app| { #[cfg(target_os = "windows")] diff --git a/src/enums/Keys.ts b/src/enums/Keys.ts deleted file mode 100644 index 2918760..0000000 --- a/src/enums/Keys.ts +++ /dev/null @@ -1,6 +0,0 @@ -export enum Keys { - SERVER_RECEIVE_TRANSFER_KEY = '', - SERVER_SEND_TRANSFER_KEY = '', - CONFIG_ENCRYPTION_KEY = '', - VERSIONS_ENCRYPTION_KEY = '' -} diff --git a/src/routes/Leaderboards.tsx b/src/routes/Leaderboards.tsx index bf8f120..2c7f33f 100644 --- a/src/routes/Leaderboards.tsx +++ b/src/routes/Leaderboards.tsx @@ -14,21 +14,22 @@ export default function Leaderboards () { async function refresh () { setLoading(true) setLeaderboardData([]) - const launcherVersion = await app.getVersion() - axios - .get('https://berrydash.lncvrt.xyz/database/getTopPlayers.php', { + try { + const launcherVersion = await app.getVersion() + const response = await axios.get('https://berrydash.lncvrt.xyz/database/getTopPlayers.php', { headers: { Requester: 'BerryDashLauncher', LauncherVersion: launcherVersion, ClientPlatform: platform() } }) - .then(res => { - const decrypted = decrypt(res.data) - setLeaderboardData(JSON.parse(decrypted)) - }) - .catch(e => console.error('Error fetching leaderboard data:', e)) - .finally(() => setLoading(false)) + const decrypted = await decrypt(response.data) + setLeaderboardData(JSON.parse(decrypted)) + } catch (e) { + console.error('Error fetching leaderboard data:', e) + } finally { + setLoading(false) + } } function downloadLeaderboard () { diff --git a/src/routes/Settings.tsx b/src/routes/Settings.tsx index 13ffa03..a2e6991 100644 --- a/src/routes/Settings.tsx +++ b/src/routes/Settings.tsx @@ -8,6 +8,7 @@ export default function Settings () { useState(false) const [useWineOnUnixWhenNeeded, setUseWineOnUnixWhenNeeded] = useState(false) const [allowNotifications, setAllowNotifications] = useState(false) + const [loaded, setLoaded] = useState(false) useEffect(() => { ;(async () => { @@ -15,45 +16,48 @@ export default function Settings () { setCheckForNewVersionOnLoad(config.settings.checkForNewVersionOnLoad) setUseWineOnUnixWhenNeeded(config.settings.useWineOnUnixWhenNeeded) setAllowNotifications(config.settings.allowNotifications) + setLoaded(true) })() }, []) return ( <>

Settings

-
- { - setCheckForNewVersionOnLoad(!checkForNewVersionOnLoad) - const config = await readNormalConfig() - config.settings.checkForNewVersionOnLoad = !checkForNewVersionOnLoad - await writeNormalConfig(config) - }} - /> - { - setAllowNotifications(!allowNotifications) - const config = await readNormalConfig() - config.settings.allowNotifications = !allowNotifications - await writeNormalConfig(config) - }} - /> - { - setUseWineOnUnixWhenNeeded(!useWineOnUnixWhenNeeded) - const config = await readNormalConfig() - config.settings.useWineOnUnixWhenNeeded = !useWineOnUnixWhenNeeded - await writeNormalConfig(config) - }} - className={platform() == 'linux' || platform() == 'macos' ? '' : 'hidden'} - /> -
+ {loaded && ( +
+ { + setCheckForNewVersionOnLoad(!checkForNewVersionOnLoad) + const config = await readNormalConfig() + config.settings.checkForNewVersionOnLoad = !checkForNewVersionOnLoad + await writeNormalConfig(config) + }} + /> + { + setAllowNotifications(!allowNotifications) + const config = await readNormalConfig() + config.settings.allowNotifications = !allowNotifications + await writeNormalConfig(config) + }} + /> + { + setUseWineOnUnixWhenNeeded(!useWineOnUnixWhenNeeded) + const config = await readNormalConfig() + config.settings.useWineOnUnixWhenNeeded = !useWineOnUnixWhenNeeded + await writeNormalConfig(config) + }} + className={platform() == 'linux' || platform() == 'macos' ? '' : 'hidden'} + /> +
+ )} ) } diff --git a/src/util/BazookaManager.ts b/src/util/BazookaManager.ts index 2a42b21..a978057 100644 --- a/src/util/BazookaManager.ts +++ b/src/util/BazookaManager.ts @@ -9,8 +9,8 @@ import { writeFile } from '@tauri-apps/plugin-fs' import { decrypt, encrypt } from './Encryption' -import { Keys } from '../enums/Keys' import { VersionsConfig } from '../types/VersionsConfig' +import { getKey } from './KeysHelper' export async function readNormalConfig (): Promise { const version = await app.getVersion() @@ -26,9 +26,9 @@ export async function readNormalConfig (): Promise { const file = await create('config.dat', options) await file.write( new TextEncoder().encode( - encrypt( + await encrypt( JSON.stringify(new NormalConfig(version)), - Keys.CONFIG_ENCRYPTION_KEY + await getKey(2) ) ) ) @@ -37,7 +37,7 @@ export async function readNormalConfig (): Promise { } const config = await readTextFile('config.dat', options) return NormalConfig.import( - JSON.parse(decrypt(config, Keys.CONFIG_ENCRYPTION_KEY)) + JSON.parse(await decrypt(config, await getKey(2))) ) } @@ -54,7 +54,7 @@ export async function writeNormalConfig (data: NormalConfig) { const file = await create('config.dat', options) await file.write( new TextEncoder().encode( - encrypt(JSON.stringify(data), Keys.CONFIG_ENCRYPTION_KEY) + await encrypt(JSON.stringify(data), await getKey(2)) ) ) await file.close() @@ -62,7 +62,7 @@ export async function writeNormalConfig (data: NormalConfig) { await writeFile( 'config.dat', new TextEncoder().encode( - encrypt(JSON.stringify(data), Keys.CONFIG_ENCRYPTION_KEY) + await encrypt(JSON.stringify(data), await getKey(2)) ), options ) @@ -83,9 +83,9 @@ export async function readVersionsConfig (): Promise { const file = await create('versions.dat', options) await file.write( new TextEncoder().encode( - encrypt( + await encrypt( JSON.stringify(new VersionsConfig(version)), - Keys.VERSIONS_ENCRYPTION_KEY + await getKey(3) ) ) ) @@ -94,7 +94,7 @@ export async function readVersionsConfig (): Promise { } const config = await readTextFile('versions.dat', options) return VersionsConfig.import( - JSON.parse(decrypt(config, Keys.VERSIONS_ENCRYPTION_KEY)) + JSON.parse(await decrypt(config, await getKey(3))) ) } @@ -111,7 +111,7 @@ export async function writeVersionsConfig (data: VersionsConfig) { const file = await create('versions.dat', options) await file.write( new TextEncoder().encode( - encrypt(JSON.stringify(data), Keys.VERSIONS_ENCRYPTION_KEY) + await encrypt(JSON.stringify(data), await getKey(3)) ) ) await file.close() @@ -119,7 +119,7 @@ export async function writeVersionsConfig (data: VersionsConfig) { await writeFile( 'versions.dat', new TextEncoder().encode( - encrypt(JSON.stringify(data), Keys.VERSIONS_ENCRYPTION_KEY) + await encrypt(JSON.stringify(data), await getKey(3)) ), options ) diff --git a/src/util/Encryption.ts b/src/util/Encryption.ts index 0a8e325..a63a51d 100644 --- a/src/util/Encryption.ts +++ b/src/util/Encryption.ts @@ -1,7 +1,11 @@ import CryptoJS from 'crypto-js' -import { Keys } from '../enums/Keys' +import { getKey } from './KeysHelper' -export function encrypt (plainText: string, key: string = Keys.SERVER_SEND_TRANSFER_KEY): string { +export async function encrypt ( + plainText: string, + key?: string +): Promise { + if (!key) key = await getKey(1) const iv = CryptoJS.lib.WordArray.random(16) const encrypted = CryptoJS.AES.encrypt( plainText, @@ -16,7 +20,8 @@ export function encrypt (plainText: string, key: string = Keys.SERVER_SEND_TRANS return CryptoJS.enc.Base64.stringify(combined) } -export function decrypt (dataB64: string, key: string = Keys.SERVER_RECEIVE_TRANSFER_KEY): string { +export async function decrypt (dataB64: string, key?: string): Promise { + if (!key) key = await getKey(0) const data = CryptoJS.enc.Base64.parse(dataB64) const iv = CryptoJS.lib.WordArray.create(data.words.slice(0, 4), 16) const ciphertext = CryptoJS.lib.WordArray.create( @@ -35,6 +40,6 @@ export function decrypt (dataB64: string, key: string = Keys.SERVER_RECEIVE_TRAN } ) const result = decrypted.toString(CryptoJS.enc.Utf8) - if (!result) throw new Error(encrypt('-997')) + if (!result) throw new Error(await encrypt('-997')) return result } diff --git a/src/util/KeysHelper.ts b/src/util/KeysHelper.ts new file mode 100644 index 0000000..3b0398c --- /dev/null +++ b/src/util/KeysHelper.ts @@ -0,0 +1,11 @@ +import { invoke } from "@tauri-apps/api/core"; + +export async function getKey(key: number): Promise { + try { + const message = await invoke('get_keys_config', { key }); + return message as string; + } catch (error) { + console.error('Failed to get key from Tauri backend', error); + return ''; + } +} \ No newline at end of file