diff options
Diffstat (limited to 'src/lib/git/nostr_url.rs')
| -rw-r--r-- | src/lib/git/nostr_url.rs | 62 |
1 files changed, 57 insertions, 5 deletions
diff --git a/src/lib/git/nostr_url.rs b/src/lib/git/nostr_url.rs index c26c56a..d6ee24e 100644 --- a/src/lib/git/nostr_url.rs +++ b/src/lib/git/nostr_url.rs | |||
| @@ -95,7 +95,7 @@ impl fmt::Display for NostrUrlDecoded { | |||
| 95 | ) | 95 | ) |
| 96 | )?; | 96 | )?; |
| 97 | } | 97 | } |
| 98 | write!(f, "{}", self.coordinate.identifier) | 98 | write!(f, "{}", urlencoding::encode(&self.coordinate.identifier)) |
| 99 | } | 99 | } |
| 100 | } | 100 | } |
| 101 | 101 | ||
| @@ -178,10 +178,11 @@ impl NostrUrlDecoded { | |||
| 178 | } else { | 178 | } else { |
| 179 | let npub_or_nip05 = part.to_owned(); | 179 | let npub_or_nip05 = part.to_owned(); |
| 180 | parts.remove(0); | 180 | parts.remove(0); |
| 181 | let identifier = parts | 181 | let identifier = urlencoding::decode(parts.pop().context( |
| 182 | .pop() | 182 | "nostr url must have an identifier eg. nostr://npub123/repo-identifier", |
| 183 | .context("nostr url must have an identifier eg. nostr://npub123/repo-identifier")? | 183 | )?) |
| 184 | .to_string(); | 184 | .context("could not percent-decode identifier in nostr git url")? |
| 185 | .into_owned(); | ||
| 185 | for relay in parts { | 186 | for relay in parts { |
| 186 | let mut decoded = urlencoding::decode(relay) | 187 | let mut decoded = urlencoding::decode(relay) |
| 187 | .context("could not parse relays in nostr git url")? | 188 | .context("could not parse relays in nostr git url")? |
| @@ -1058,6 +1059,31 @@ mod tests { | |||
| 1058 | } | 1059 | } |
| 1059 | 1060 | ||
| 1060 | #[test] | 1061 | #[test] |
| 1062 | fn identifier_with_spaces_is_percent_encoded() -> Result<()> { | ||
| 1063 | assert_eq!( | ||
| 1064 | format!("{}", NostrUrlDecoded { | ||
| 1065 | original_string: String::new(), | ||
| 1066 | coordinate: Nip19Coordinate { | ||
| 1067 | coordinate: Coordinate { | ||
| 1068 | identifier: "my repo".to_string(), | ||
| 1069 | public_key: PublicKey::parse( | ||
| 1070 | "npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr", | ||
| 1071 | ) | ||
| 1072 | .unwrap(), | ||
| 1073 | kind: nostr_sdk::Kind::GitRepoAnnouncement, | ||
| 1074 | }, | ||
| 1075 | relays: vec![], | ||
| 1076 | }, | ||
| 1077 | protocol: None, | ||
| 1078 | ssh_key_file: None, | ||
| 1079 | nip05: None, | ||
| 1080 | }), | ||
| 1081 | "nostr://npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/my%20repo", | ||
| 1082 | ); | ||
| 1083 | Ok(()) | ||
| 1084 | } | ||
| 1085 | |||
| 1086 | #[test] | ||
| 1061 | fn with_protocol() -> Result<()> { | 1087 | fn with_protocol() -> Result<()> { |
| 1062 | assert_eq!( | 1088 | assert_eq!( |
| 1063 | format!("{}", NostrUrlDecoded { | 1089 | format!("{}", NostrUrlDecoded { |
| @@ -1353,6 +1379,32 @@ mod tests { | |||
| 1353 | } | 1379 | } |
| 1354 | 1380 | ||
| 1355 | #[tokio::test] | 1381 | #[tokio::test] |
| 1382 | async fn percent_encoded_identifier_is_decoded() -> Result<()> { | ||
| 1383 | let url = "nostr://npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/my%20repo".to_string(); | ||
| 1384 | let decoded = NostrUrlDecoded::parse_and_resolve(&url, &None).await?; | ||
| 1385 | assert_eq!(decoded.coordinate.identifier, "my repo"); | ||
| 1386 | Ok(()) | ||
| 1387 | } | ||
| 1388 | |||
| 1389 | #[tokio::test] | ||
| 1390 | async fn percent_encoded_identifier_round_trips() -> Result<()> { | ||
| 1391 | // parse a URL with an encoded identifier, then re-display it and get the same | ||
| 1392 | // URL back | ||
| 1393 | let url = "nostr://npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/my%20repo".to_string(); | ||
| 1394 | let decoded = NostrUrlDecoded::parse_and_resolve(&url, &None).await?; | ||
| 1395 | // Display re-encodes, but original_string is stored so we need a fresh struct | ||
| 1396 | let redisplayed = format!( | ||
| 1397 | "{}", | ||
| 1398 | NostrUrlDecoded { | ||
| 1399 | original_string: String::new(), | ||
| 1400 | ..decoded | ||
| 1401 | } | ||
| 1402 | ); | ||
| 1403 | assert_eq!(redisplayed, url); | ||
| 1404 | Ok(()) | ||
| 1405 | } | ||
| 1406 | |||
| 1407 | #[tokio::test] | ||
| 1356 | async fn with_server_protocol() -> Result<()> { | 1408 | async fn with_server_protocol() -> Result<()> { |
| 1357 | let url = "nostr://ssh/npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/ngit".to_string(); | 1409 | let url = "nostr://ssh/npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/ngit".to_string(); |
| 1358 | assert_eq!( | 1410 | assert_eq!( |