Add sha256sum check for update downloads
This commit is contained in:
6
bun.lock
6
bun.lock
@@ -18,7 +18,7 @@
|
|||||||
"@eslint/eslintrc": "3.3.1",
|
"@eslint/eslintrc": "3.3.1",
|
||||||
"@tailwindcss/postcss": "4.1.16",
|
"@tailwindcss/postcss": "4.1.16",
|
||||||
"@tauri-apps/cli": "2.9.2",
|
"@tauri-apps/cli": "2.9.2",
|
||||||
"@types/node": "24.9.2",
|
"@types/node": "24.10.0",
|
||||||
"@types/react": "19.2.2",
|
"@types/react": "19.2.2",
|
||||||
"@types/react-dom": "19.2.2",
|
"@types/react-dom": "19.2.2",
|
||||||
"eslint": "9.39.0",
|
"eslint": "9.39.0",
|
||||||
@@ -257,7 +257,7 @@
|
|||||||
|
|
||||||
"@types/json5": ["@types/json5@0.0.29", "", {}, "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ=="],
|
"@types/json5": ["@types/json5@0.0.29", "", {}, "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ=="],
|
||||||
|
|
||||||
"@types/node": ["@types/node@24.9.2", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-uWN8YqxXxqFMX2RqGOrumsKeti4LlmIMIyV0lgut4jx7KQBcBiW6vkDtIBvHnHIquwNfJhk8v2OtmO8zXWHfPA=="],
|
"@types/node": ["@types/node@24.10.0", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-qzQZRBqkFsYyaSWXuEHc2WR9c0a0CXwiE5FWUvn7ZM+vdy1uZLfCunD38UzhuB7YN/J11ndbDBcTmOdxJo9Q7A=="],
|
||||||
|
|
||||||
"@types/react": ["@types/react@19.2.2", "", { "dependencies": { "csstype": "^3.0.2" } }, "sha512-6mDvHUFSjyT2B2yeNx2nUgMxh9LtOWvkhIU3uePn2I2oyNymUAX1NIsdgviM4CH+JSrp2D2hsMvJOkxY+0wNRA=="],
|
"@types/react": ["@types/react@19.2.2", "", { "dependencies": { "csstype": "^3.0.2" } }, "sha512-6mDvHUFSjyT2B2yeNx2nUgMxh9LtOWvkhIU3uePn2I2oyNymUAX1NIsdgviM4CH+JSrp2D2hsMvJOkxY+0wNRA=="],
|
||||||
|
|
||||||
@@ -381,7 +381,7 @@
|
|||||||
|
|
||||||
"callsites": ["callsites@3.1.0", "", {}, "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="],
|
"callsites": ["callsites@3.1.0", "", {}, "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="],
|
||||||
|
|
||||||
"caniuse-lite": ["caniuse-lite@1.0.30001752", "", {}, "sha512-vKUk7beoukxE47P5gcVNKkDRzXdVofotshHwfR9vmpeFKxmI5PBpgOMC18LUJUA/DvJ70Y7RveasIBraqsyO/g=="],
|
"caniuse-lite": ["caniuse-lite@1.0.30001753", "", {}, "sha512-Bj5H35MD/ebaOV4iDLqPEtiliTN29qkGtEHCwawWn4cYm+bPJM2NsaP30vtZcnERClMzp52J4+aw2UNbK4o+zw=="],
|
||||||
|
|
||||||
"chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
|
"chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@tauri-apps/cli": "2.9.2",
|
"@tauri-apps/cli": "2.9.2",
|
||||||
"typescript": "5.9.3",
|
"typescript": "5.9.3",
|
||||||
"@types/node": "24.9.2",
|
"@types/node": "24.10.0",
|
||||||
"@types/react": "19.2.2",
|
"@types/react": "19.2.2",
|
||||||
"@types/react-dom": "19.2.2",
|
"@types/react-dom": "19.2.2",
|
||||||
"@tailwindcss/postcss": "4.1.16",
|
"@tailwindcss/postcss": "4.1.16",
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ tauri-plugin-os = "2.3.2"
|
|||||||
reqwest = { version = "0.12.24", default-features = false, features = ["stream", "rustls-tls"] }
|
reqwest = { version = "0.12.24", default-features = false, features = ["stream", "rustls-tls"] }
|
||||||
tauri-plugin-opener = "2.5.2"
|
tauri-plugin-opener = "2.5.2"
|
||||||
tauri-plugin-dialog = "2.4.2"
|
tauri-plugin-dialog = "2.4.2"
|
||||||
|
sha2 = "0.10.9"
|
||||||
|
|
||||||
[target.'cfg(not(any(target_os = "android", target_os = "ios")))'.dependencies]
|
[target.'cfg(not(any(target_os = "android", target_os = "ios")))'.dependencies]
|
||||||
tauri-plugin-single-instance = "2.3.6"
|
tauri-plugin-single-instance = "2.3.6"
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
use sha2::{Digest, Sha256};
|
||||||
use std::{
|
use std::{
|
||||||
fs::{File, create_dir_all},
|
fs::{File, create_dir_all},
|
||||||
io::{BufReader, copy},
|
io::{BufReader, copy},
|
||||||
@@ -41,6 +42,13 @@ async fn unzip_to_dir(zip_path: PathBuf, out_dir: PathBuf) -> String {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_sha256_hash(data: &[u8]) -> String {
|
||||||
|
let mut hasher = Sha256::new();
|
||||||
|
hasher.update(data);
|
||||||
|
let hash = hasher.finalize();
|
||||||
|
format!("{:x}", hash)
|
||||||
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
async fn check_latest_ver(app: AppHandle, version: String) -> String {
|
async fn check_latest_ver(app: AppHandle, version: String) -> String {
|
||||||
let updates_path = app.path().app_local_data_dir().unwrap().join("updates");
|
let updates_path = app.path().app_local_data_dir().unwrap().join("updates");
|
||||||
@@ -55,7 +63,7 @@ async fn check_latest_ver(app: AppHandle, version: String) -> String {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
async fn download(app: AppHandle, url: String, name: String) -> String {
|
async fn download(app: AppHandle, url: String, name: String, hash: String) -> String {
|
||||||
let client = reqwest::Client::new();
|
let client = reqwest::Client::new();
|
||||||
let resp = match client.get(&url).send().await {
|
let resp = match client.get(&url).send().await {
|
||||||
Ok(r) => r,
|
Ok(r) => r,
|
||||||
@@ -66,6 +74,11 @@ async fn download(app: AppHandle, url: String, name: String) -> String {
|
|||||||
Err(_) => return "-1".to_string(),
|
Err(_) => return "-1".to_string(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let download_hash = get_sha256_hash(&bytes);
|
||||||
|
if hash != download_hash {
|
||||||
|
return "-2".to_string();
|
||||||
|
}
|
||||||
|
|
||||||
let downloads_path = app.path().app_local_data_dir().unwrap().join("downloads");
|
let downloads_path = app.path().app_local_data_dir().unwrap().join("downloads");
|
||||||
let updates_path = app.path().app_local_data_dir().unwrap().join("updates");
|
let updates_path = app.path().app_local_data_dir().unwrap().join("updates");
|
||||||
|
|
||||||
|
|||||||
@@ -66,11 +66,15 @@ export default function Home () {
|
|||||||
if (!launcherUpdateData) return
|
if (!launcherUpdateData) return
|
||||||
const downloadResult = await invoke('download', {
|
const downloadResult = await invoke('download', {
|
||||||
url: getDownloadLink(launcherUpdateData),
|
url: getDownloadLink(launcherUpdateData),
|
||||||
name: launcherLatestRequest.data
|
name: launcherLatestRequest.data,
|
||||||
|
hash: getDownloadHash(launcherUpdateData)
|
||||||
})
|
})
|
||||||
if (downloadResult !== '1') {
|
if (downloadResult == '-1') {
|
||||||
setState('Failed. Check internet connection.')
|
setState('Failed. Check internet connection.')
|
||||||
return
|
return
|
||||||
|
} else if (downloadResult == '-2') {
|
||||||
|
setState('File integrity check failed.')
|
||||||
|
return
|
||||||
}
|
}
|
||||||
setState('Starting...')
|
setState('Starting...')
|
||||||
}
|
}
|
||||||
@@ -101,6 +105,26 @@ export default function Home () {
|
|||||||
return undefined
|
return undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getDownloadHash (version: LauncherUpdate): string | undefined {
|
||||||
|
const p = platform()
|
||||||
|
const a = arch()
|
||||||
|
|
||||||
|
const findUrl = (plat: string) => {
|
||||||
|
const i = version.platforms.indexOf(plat)
|
||||||
|
return i >= 0 ? version.sha256sums[i] : undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p === 'windows') {
|
||||||
|
if (a === 'x86_64') return findUrl('windows-x64')
|
||||||
|
if (a === 'aarch64') return findUrl('windows-arm64')
|
||||||
|
} else if (p === 'macos') {
|
||||||
|
if (a === 'x86_64') return findUrl('macos-intel')
|
||||||
|
if (a === 'aarch64') return findUrl('macos-silicon')
|
||||||
|
} else if (p === 'linux') return findUrl(p)
|
||||||
|
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className='absolute left-1/2 top-[20%] -translate-x-1/2 flex flex-col items-center'>
|
<div className='absolute left-1/2 top-[20%] -translate-x-1/2 flex flex-col items-center'>
|
||||||
|
|||||||
@@ -3,5 +3,5 @@ export interface LauncherUpdate {
|
|||||||
releaseDate: number
|
releaseDate: number
|
||||||
downloadUrls: string[]
|
downloadUrls: string[]
|
||||||
platforms: string[]
|
platforms: string[]
|
||||||
executables: string[]
|
sha256sums: string[]
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user