mirror of
https://github.com/nimbold/Firelink.git
synced 2026-08-27 19:17:13 +00:00
fix(desktop): secure extension ping handler & fix UI alignment in settings
This commit is contained in:
@@ -90,12 +90,30 @@ pub async fn start_server(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn ping_handler(State(state): State<ServerState>) -> StatusCode {
|
async fn ping_handler(
|
||||||
if state.frontend_ready.load(Ordering::Acquire) {
|
State(state): State<ServerState>,
|
||||||
StatusCode::OK
|
headers: HeaderMap,
|
||||||
} else {
|
body: Bytes,
|
||||||
StatusCode::SERVICE_UNAVAILABLE
|
) -> StatusCode {
|
||||||
|
if !state.frontend_ready.load(Ordering::Acquire) {
|
||||||
|
return StatusCode::SERVICE_UNAVAILABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let signature = match headers.get("x-firelink-signature").and_then(|v| v.to_str().ok()) {
|
||||||
|
Some(v) => v,
|
||||||
|
None => return StatusCode::FORBIDDEN,
|
||||||
|
};
|
||||||
|
|
||||||
|
let timestamp_str = match headers.get("x-firelink-timestamp").and_then(|v| v.to_str().ok()) {
|
||||||
|
Some(v) => v,
|
||||||
|
None => return StatusCode::FORBIDDEN,
|
||||||
|
};
|
||||||
|
|
||||||
|
if verify_signature(signature, timestamp_str, &body, &state.pairing_token).is_err() {
|
||||||
|
return StatusCode::FORBIDDEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
StatusCode::OK
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn download_handler(
|
async fn download_handler(
|
||||||
@@ -107,25 +125,34 @@ async fn download_handler(
|
|||||||
return Err(StatusCode::SERVICE_UNAVAILABLE);
|
return Err(StatusCode::SERVICE_UNAVAILABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
let signature = headers
|
let signature = match headers.get("x-firelink-signature").and_then(|v| v.to_str().ok()) {
|
||||||
.get("x-firelink-signature")
|
Some(v) => v,
|
||||||
.and_then(|v| v.to_str().ok())
|
None => return Err(StatusCode::FORBIDDEN),
|
||||||
.ok_or(StatusCode::FORBIDDEN)?;
|
};
|
||||||
|
|
||||||
let timestamp_str = headers
|
let timestamp_str = match headers.get("x-firelink-timestamp").and_then(|v| v.to_str().ok()) {
|
||||||
.get("x-firelink-timestamp")
|
Some(v) => v,
|
||||||
.and_then(|v| v.to_str().ok())
|
None => return Err(StatusCode::FORBIDDEN),
|
||||||
.ok_or(StatusCode::FORBIDDEN)?;
|
};
|
||||||
|
|
||||||
let timestamp = verify_signature(signature, timestamp_str, &body, &state.pairing_token)
|
let timestamp = match verify_signature(signature, timestamp_str, &body, &state.pairing_token) {
|
||||||
.map_err(|_| StatusCode::FORBIDDEN)?;
|
Ok(v) => v,
|
||||||
|
Err(_) => return Err(StatusCode::FORBIDDEN),
|
||||||
|
};
|
||||||
|
|
||||||
if !claim_request(signature, timestamp, &state.replay_cache) {
|
if !claim_request(signature, timestamp, &state.replay_cache) {
|
||||||
return Err(StatusCode::FORBIDDEN);
|
return Err(StatusCode::FORBIDDEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
let payload: ExtensionRequest = serde_json::from_slice(&body).map_err(|_| StatusCode::BAD_REQUEST)?;
|
let payload: ExtensionRequest = match serde_json::from_slice(&body) {
|
||||||
let download = normalize_download(payload).ok_or(StatusCode::BAD_REQUEST)?;
|
Ok(v) => v,
|
||||||
|
Err(_) => return Err(StatusCode::BAD_REQUEST),
|
||||||
|
};
|
||||||
|
|
||||||
|
let download = match normalize_download(payload) {
|
||||||
|
Some(v) => v,
|
||||||
|
None => return Err(StatusCode::BAD_REQUEST),
|
||||||
|
};
|
||||||
|
|
||||||
if let Some(window) = state.app_handle.get_webview_window("main") {
|
if let Some(window) = state.app_handle.get_webview_window("main") {
|
||||||
let _ = window.show();
|
let _ = window.show();
|
||||||
|
|||||||
@@ -510,11 +510,11 @@ export default function SettingsView() {
|
|||||||
<div className="flex gap-2">
|
<div className="flex gap-2">
|
||||||
<input
|
<input
|
||||||
type="text" readOnly placeholder="Choose base folder..."
|
type="text" readOnly placeholder="Choose base folder..."
|
||||||
className="app-control w-48 text-text-muted text-[11px]"
|
className="app-control w-64 text-text-muted text-[11px] px-2"
|
||||||
/>
|
/>
|
||||||
<button
|
<button
|
||||||
onClick={handleBrowseBulk}
|
onClick={handleBrowseBulk}
|
||||||
className="app-icon-button bg-accent/10 hover:bg-accent/20 text-accent font-semibold px-3"
|
className="app-button px-3 text-xs font-semibold text-accent border border-accent/20 bg-accent/10 hover:bg-accent/20"
|
||||||
>
|
>
|
||||||
Browse
|
Browse
|
||||||
</button>
|
</button>
|
||||||
@@ -529,11 +529,11 @@ export default function SettingsView() {
|
|||||||
type="text"
|
type="text"
|
||||||
value={(settings.downloadDirectories || {})[category] || ''}
|
value={(settings.downloadDirectories || {})[category] || ''}
|
||||||
onChange={(e) => settings.setCategoryDirectory(category, e.target.value)}
|
onChange={(e) => settings.setCategoryDirectory(category, e.target.value)}
|
||||||
className="app-control w-48 text-[11px]"
|
className="app-control w-64 text-[11px] px-2"
|
||||||
/>
|
/>
|
||||||
<button
|
<button
|
||||||
onClick={() => handleBrowseCategory(category)}
|
onClick={() => handleBrowseCategory(category)}
|
||||||
className="app-icon-button hover:bg-item-hover text-text-secondary px-3"
|
className="app-button px-3 text-xs text-text-secondary hover:bg-item-hover"
|
||||||
>
|
>
|
||||||
Browse
|
Browse
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
Reference in New Issue
Block a user