Skip to main content

Mountain/Track/Effect/CreateEffectForRequest/
NativeHost.rs

1#![allow(non_snake_case, unused_variables, dead_code, unused_imports)]
2
3use std::{future::Future, pin::Pin, sync::Arc};
4
5use serde_json::{Value, json};
6use tauri::Runtime;
7
8use crate::{RunTime::ApplicationRunTime::ApplicationRunTime, Track::Effect::MappedEffectType::MappedEffect, dev_log};
9
10pub fn CreateEffect<R:Runtime>(MethodName:&str, Parameters:Value) -> Option<Result<MappedEffect, String>> {
11	match MethodName {
12		"NativeHost.OpenExternal" => {
13			let effect =
14				move |_run_time:Arc<ApplicationRunTime>| -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send>> {
15
16					Box::pin(async move {
17						let uri = Parameters
18							.get(0)
19							.and_then(Value::as_str)
20							.unwrap_or("")
21							.to_string();
22						let lower = uri.to_ascii_lowercase();
23						const BlockedSchemes:&[&str] =
24							&["javascript:", "data:", "vbscript:", "file:"];
25						for scheme in BlockedSchemes {
26							if lower.starts_with(scheme) {
27								dev_log!(
28									"ipc",
29
30									"warn: [NativeHost.OpenExternal] rejected scheme '{}': {}",
31
32									scheme,
33
34									uri
35								);
36								return Err(format!(
37									"NativeHost.OpenExternal: scheme '{}' is not allowed",
38
39									scheme
40								));
41							}
42						}
43						if uri.is_empty() {
44							return Err("NativeHost.OpenExternal: empty URI".to_string());
45						}
46						let uri_owned = uri.clone();
47						let result =
48							tokio::task::spawn_blocking(move || open::that_detached(uri_owned))
49								.await
50								.map_err(|e| format!("NativeHost.OpenExternal join error: {}", e))?;
51						match result {
52							Ok(()) => {
53								dev_log!("ipc", "[NativeHost.OpenExternal] opened {}", uri);
54								Ok(json!(true))
55							},
56							Err(e) => {
57								dev_log!(
58									"ipc",
59
60									"warn: [NativeHost.OpenExternal] failed uri={} error={}",
61
62									uri,
63
64									e
65								);
66								Err(e.to_string())
67							},
68						}
69					})
70				};
71
72			Some(Ok(Box::new(effect)))
73		},
74
75		_ => None,
76	}
77}