Skip to content

Commit

Permalink
feat(cli): update config migration script to add ipc: to CSP
Browse files Browse the repository at this point in the history
  • Loading branch information
lucasfernog committed Jun 24, 2023
1 parent 11935b6 commit cb05f57
Show file tree
Hide file tree
Showing 2 changed files with 165 additions and 7 deletions.
6 changes: 6 additions & 0 deletions .changes/migrate-csp.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"tauri-cli": patch:enhance
"@tauri-apps/cli": patch:enhance
---

Update migrate command to update the configuration CSP to include `ipc:` on the `connect-src` directive, needed by the new IPC using custom protocols.
166 changes: 159 additions & 7 deletions tooling/cli/src/migrate/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,13 @@ fn migrate_config(config: &mut Value) -> Result<()> {
process_allowlist(tauri_config, &mut plugins, allowlist)?;
}

if let Some(security) = tauri_config
.get_mut("security")
.and_then(|c| c.as_object_mut())
{
process_security(security)?;
}

// cli
if let Some(cli) = tauri_config.remove("cli") {
process_cli(&mut plugins, cli)?;
Expand All @@ -64,6 +71,42 @@ fn migrate_config(config: &mut Value) -> Result<()> {
Ok(())
}

fn process_security(security: &mut Map<String, Value>) -> Result<()> {
// migrate CSP: add `ipc:` to `connect-src`
if let Some(csp_value) = security.remove("csp") {
let csp = if csp_value.is_null() {
csp_value
} else {
let mut csp: tauri_utils_v1::config::Csp = serde_json::from_value(csp_value)?;
match &mut csp {
tauri_utils_v1::config::Csp::Policy(csp) => {
if csp.contains("connect-src") {
*csp = csp.replace("connect-src", "connect-src ipc:");
} else {
*csp = format!("{csp}; connect-src ipc:");
}
}
tauri_utils_v1::config::Csp::DirectiveMap(csp) => {
if let Some(connect_src) = csp.get_mut("connect-src") {
if !connect_src.contains("ipc:") {
connect_src.push("ipc:");
}
} else {
csp.insert(
"connect-src".into(),
tauri_utils_v1::config::CspDirectiveSources::List(vec!["ipc:".to_string()]),
);
}
}
}
serde_json::to_value(csp)?
};

security.insert("csp".into(), csp);
}
Ok(())
}

fn process_allowlist(
tauri_config: &mut Map<String, Value>,
plugins: &mut Map<String, Value>,
Expand Down Expand Up @@ -142,8 +185,19 @@ fn process_updater(

#[cfg(test)]
mod test {
fn migrate(original: &serde_json::Value) -> serde_json::Value {
let mut migrated = original.clone();
super::migrate_config(&mut migrated).expect("failed to migrate config");

if let Err(e) = serde_json::from_value::<tauri_utils::config::Config>(migrated.clone()) {
panic!("migrated config is not valid: {e}");
}

migrated
}

#[test]
fn migrate() {
fn migrate_full() {
let original = serde_json::json!({
"tauri": {
"bundle": {
Expand Down Expand Up @@ -199,16 +253,14 @@ mod test {
"http": {
"scope": ["http://localhost:3003/"]
}
},
"security": {
"csp": "default-src: 'self' tauri:"
}
}
});

let mut migrated = original.clone();
super::migrate_config(&mut migrated).expect("failed to migrate config");

if let Err(e) = serde_json::from_value::<tauri_utils::config::Config>(migrated.clone()) {
panic!("migrated config is not valid: {e}");
}
let migrated = migrate(&original);

// bundle > updater
assert_eq!(
Expand Down Expand Up @@ -268,5 +320,105 @@ mod test {
migrated["tauri"]["security"]["assetProtocol"]["scope"],
original["tauri"]["allowlist"]["protocol"]["assetScope"]
);

// security CSP
assert_eq!(
migrated["tauri"]["security"]["csp"],
format!(
"{}; connect-src ipc:",
original["tauri"]["security"]["csp"].as_str().unwrap()
)
);
}

#[test]
fn migrate_csp_object() {
let original = serde_json::json!({
"tauri": {
"security": {
"csp": {
"default-src": ["self", "tauri:"]
}
}
}
});

let migrated = migrate(&original);

assert_eq!(
migrated["tauri"]["security"]["csp"]["default-src"],
original["tauri"]["security"]["csp"]["default-src"]
);
assert!(migrated["tauri"]["security"]["csp"]["connect-src"]
.as_array()
.expect("connect-src isn't an array")
.contains(&"ipc:".into()));
}

#[test]
fn migrate_csp_existing_connect_src_string() {
let original = serde_json::json!({
"tauri": {
"security": {
"csp": {
"default-src": ["self", "tauri:"],
"connect-src": "self"
}
}
}
});

let migrated = migrate(&original);

assert_eq!(
migrated["tauri"]["security"]["csp"]["default-src"],
original["tauri"]["security"]["csp"]["default-src"]
);
assert_eq!(
migrated["tauri"]["security"]["csp"]["connect-src"]
.as_str()
.expect("connect-src isn't a string"),
format!(
"{} ipc:",
original["tauri"]["security"]["csp"]["connect-src"]
.as_str()
.unwrap()
)
);
}

#[test]
fn migrate_csp_existing_connect_src_array() {
let original = serde_json::json!({
"tauri": {
"security": {
"csp": {
"default-src": ["self", "tauri:"],
"connect-src": ["self", "asset:"]
}
}
}
});

let migrated = migrate(&original);

assert_eq!(
migrated["tauri"]["security"]["csp"]["default-src"],
original["tauri"]["security"]["csp"]["default-src"]
);

let migrated_connect_src = migrated["tauri"]["security"]["csp"]["connect-src"]
.as_array()
.expect("connect-src isn't an array");
let original_connect_src = original["tauri"]["security"]["csp"]["connect-src"]
.as_array()
.unwrap();
assert!(
migrated_connect_src
.iter()
.zip(original_connect_src.iter())
.all(|(a, b)| a == b),
"connect-src migration failed"
);
}
}

0 comments on commit cb05f57

Please sign in to comment.