Skip to content

Commit

Permalink
api!: make QR code type for proxy not specific to SOCKS5
Browse files Browse the repository at this point in the history
  • Loading branch information
link2xt committed Sep 18, 2024
1 parent 060fd55 commit 251f0d7
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 83 deletions.
2 changes: 1 addition & 1 deletion deltachat-ffi/deltachat.h
Original file line number Diff line number Diff line change
Expand Up @@ -2501,7 +2501,7 @@ void dc_stop_ongoing_process (dc_context_t* context);
#define DC_QR_BACKUP 251
#define DC_QR_BACKUP2 252
#define DC_QR_WEBRTC_INSTANCE 260 // text1=domain, text2=instance pattern
#define DC_QR_SOCKS5_PROXY 270 // text1=host, text2=port
#define DC_QR_PROXY 271 // text1=address, text2=protocol (e.g. "SOCKS5")
#define DC_QR_ADDR 320 // id=contact
#define DC_QR_TEXT 330 // text1=text
#define DC_QR_URL 332 // text1=URL
Expand Down
42 changes: 21 additions & 21 deletions deltachat-ffi/src/lot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,42 +34,42 @@ pub enum Meaning {
}

impl Lot {
pub fn get_text1(&self) -> Option<&str> {
pub fn get_text1(&self) -> Option<Cow<str>> {
match self {
Self::Summary(summary) => match &summary.prefix {
None => None,
Some(SummaryPrefix::Draft(text)) => Some(text),
Some(SummaryPrefix::Username(username)) => Some(username),
Some(SummaryPrefix::Me(text)) => Some(text),
Some(SummaryPrefix::Draft(text)) => Some(Cow::Borrowed(text)),
Some(SummaryPrefix::Username(username)) => Some(Cow::Borrowed(username)),
Some(SummaryPrefix::Me(text)) => Some(Cow::Borrowed(text)),
},
Self::Qr(qr) => match qr {
Qr::AskVerifyContact { .. } => None,
Qr::AskVerifyGroup { grpname, .. } => Some(grpname),
Qr::AskVerifyGroup { grpname, .. } => Some(Cow::Borrowed(grpname)),
Qr::FprOk { .. } => None,
Qr::FprMismatch { .. } => None,
Qr::FprWithoutAddr { fingerprint, .. } => Some(fingerprint),
Qr::Account { domain } => Some(domain),
Qr::FprWithoutAddr { fingerprint, .. } => Some(Cow::Borrowed(fingerprint)),
Qr::Account { domain } => Some(Cow::Borrowed(domain)),
Qr::Backup2 { .. } => None,
Qr::WebrtcInstance { domain, .. } => Some(domain),
Qr::Socks5Proxy { host, .. } => Some(host),
Qr::Addr { draft, .. } => draft.as_deref(),
Qr::Url { url } => Some(url),
Qr::Text { text } => Some(text),
Qr::WebrtcInstance { domain, .. } => Some(Cow::Borrowed(domain)),
Qr::Proxy { host, port, .. } => Some(Cow::Owned(format!("{host}:{port}"))),
Qr::Addr { draft, .. } => draft.as_deref().map(Cow::Borrowed),
Qr::Url { url } => Some(Cow::Borrowed(url)),
Qr::Text { text } => Some(Cow::Borrowed(text)),
Qr::WithdrawVerifyContact { .. } => None,
Qr::WithdrawVerifyGroup { grpname, .. } => Some(grpname),
Qr::WithdrawVerifyGroup { grpname, .. } => Some(Cow::Borrowed(grpname)),
Qr::ReviveVerifyContact { .. } => None,
Qr::ReviveVerifyGroup { grpname, .. } => Some(grpname),
Qr::Login { address, .. } => Some(address),
Qr::ReviveVerifyGroup { grpname, .. } => Some(Cow::Borrowed(grpname)),
Qr::Login { address, .. } => Some(Cow::Borrowed(address)),
},
Self::Error(err) => Some(err),
Self::Error(err) => Some(Cow::Borrowed(err)),
}
}

pub fn get_text2(&self) -> Option<Cow<str>> {
match self {
Self::Summary(summary) => Some(summary.truncated_text(160)),
Self::Qr(qr) => match qr {
Qr::Socks5Proxy { port, .. } => Some(Cow::Owned(format!("{port}"))),
Qr::Proxy { protocol, .. } => Some(protocol.into()),
_ => None,
},
Self::Error(_) => None,
Expand Down Expand Up @@ -107,7 +107,7 @@ impl Lot {
Qr::Account { .. } => LotState::QrAccount,
Qr::Backup2 { .. } => LotState::QrBackup2,
Qr::WebrtcInstance { .. } => LotState::QrWebrtcInstance,
Qr::Socks5Proxy { .. } => LotState::QrSocks5Proxy,
Qr::Proxy { .. } => LotState::QrProxy,
Qr::Addr { .. } => LotState::QrAddr,
Qr::Url { .. } => LotState::QrUrl,
Qr::Text { .. } => LotState::QrText,
Expand All @@ -133,7 +133,7 @@ impl Lot {
Qr::Account { .. } => Default::default(),
Qr::Backup2 { .. } => Default::default(),
Qr::WebrtcInstance { .. } => Default::default(),
Qr::Socks5Proxy { .. } => Default::default(),
Qr::Proxy { .. } => Default::default(),
Qr::Addr { contact_id, .. } => contact_id.to_u32(),
Qr::Url { .. } => Default::default(),
Qr::Text { .. } => Default::default(),
Expand Down Expand Up @@ -188,8 +188,8 @@ pub enum LotState {
/// text1=domain, text2=instance pattern
QrWebrtcInstance = 260,

/// text1=host, text2=port
QrSocks5Proxy = 270,
/// text1=address, text2=protocol
QrProxy = 271,

/// id=contact
QrAddr = 320,
Expand Down
18 changes: 9 additions & 9 deletions deltachat-jsonrpc/src/api/types/qr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,11 @@ pub enum QrObject {
domain: String,
instance_pattern: String,
},
Socks5Proxy {
Proxy {
url: String,
host: String,
port: u16,
user: Option<String>,
pass: Option<String>,
protocol: String,
},
Addr {
contact_id: u32,
Expand Down Expand Up @@ -152,16 +152,16 @@ impl From<Qr> for QrObject {
domain,
instance_pattern,
},
Qr::Socks5Proxy {
Qr::Proxy {
url,
host,
port,
user,
pass,
} => QrObject::Socks5Proxy {
protocol,
} => QrObject::Proxy {
url,
host,
port,
user,
pass,
protocol,
},
Qr::Addr { contact_id, draft } => {
let contact_id = contact_id.to_u32();
Expand Down
2 changes: 1 addition & 1 deletion node/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -134,9 +134,9 @@ module.exports = {
DC_QR_FPR_OK: 210,
DC_QR_FPR_WITHOUT_ADDR: 230,
DC_QR_LOGIN: 520,
DC_QR_PROXY: 271,
DC_QR_REVIVE_VERIFYCONTACT: 510,
DC_QR_REVIVE_VERIFYGROUP: 512,
DC_QR_SOCKS5_PROXY: 270,
DC_QR_TEXT: 330,
DC_QR_URL: 332,
DC_QR_WEBRTC_INSTANCE: 260,
Expand Down
2 changes: 1 addition & 1 deletion node/lib/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,9 +134,9 @@ export enum C {
DC_QR_FPR_OK = 210,
DC_QR_FPR_WITHOUT_ADDR = 230,
DC_QR_LOGIN = 520,
DC_QR_PROXY = 271,
DC_QR_REVIVE_VERIFYCONTACT = 510,
DC_QR_REVIVE_VERIFYGROUP = 512,
DC_QR_SOCKS5_PROXY = 270,
DC_QR_TEXT = 330,
DC_QR_URL = 332,
DC_QR_WEBRTC_INSTANCE = 260,
Expand Down
96 changes: 46 additions & 50 deletions src/qr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,19 +127,21 @@ pub enum Qr {
instance_pattern: String,
},

/// Ask the user if they want to add or use the given SOCKS5 proxy
Socks5Proxy {
/// SOCKS5 server
/// Ask the user if they want to use the given proxy.
Proxy {
/// Proxy URL.
///
/// This is the URL that is going to be added.
url: String,

/// Host extracted from the URL to display in the UI.
host: String,

/// SOCKS5 port
/// Port extracted from the URL to display in the UI.
port: u16,

/// SOCKS5 user
user: Option<String>,

/// SOCKS5 password
pass: Option<String>,
/// Protocol such as "SOCKS5" to display in the UI.
protocol: String,
},

/// Contact address is scanned.
Expand Down Expand Up @@ -558,16 +560,27 @@ fn decode_tg_socks_proxy(_context: &Context, qr: &str) -> Result<Qr> {
}
}

if let Some(host) = host {
Ok(Qr::Socks5Proxy {
host,
port,
user,
pass,
})
} else {
let Some(host) = host else {
bail!("Bad t.me/socks url: {:?}", url);
}
};

let mut url = "socks5://".to_string();
if let Some(pass) = pass {
url += &percent_encode(user.unwrap_or_default().as_bytes(), NON_ALPHANUMERIC).to_string();
url += ":";
url += &percent_encode(pass.as_bytes(), NON_ALPHANUMERIC).to_string();
url += "@";
};
url += &host;
url += ":";
url += &port.to_string();

Ok(Qr::Proxy {
url,
host,
port,
protocol: "SOCKS5".to_string(),
})
}

/// Decodes a [`DCBACKUP2_SCHEME`] QR code.
Expand Down Expand Up @@ -655,33 +668,16 @@ pub async fn set_config_from_qr(context: &Context, qr: &str) -> Result<()> {
.set_config_internal(Config::WebrtcInstance, Some(&instance_pattern))
.await?;
}
Qr::Socks5Proxy {
host,
port,
user,
pass,
} => {
let mut proxy_url = "socks5://".to_string();
if let Some(pass) = pass {
proxy_url += &percent_encode(user.unwrap_or_default().as_bytes(), NON_ALPHANUMERIC)
.to_string();
proxy_url += ":";
proxy_url += &percent_encode(pass.as_bytes(), NON_ALPHANUMERIC).to_string();
proxy_url += "@";
};
proxy_url += &host;
proxy_url += ":";
proxy_url += &port.to_string();

Qr::Proxy { url, .. } => {
let old_proxy_url_value = context
.get_config(Config::ProxyUrl)
.await?
.unwrap_or_default();
let proxy_urls: Vec<&str> = std::iter::once(proxy_url.as_str())
let proxy_urls: Vec<&str> = std::iter::once(url.as_str())
.chain(
old_proxy_url_value
.split('\n')
.filter(|s| !s.is_empty() && *s != proxy_url),
.filter(|s| !s.is_empty() && *s != url),
)
.collect();
context
Expand Down Expand Up @@ -1523,33 +1519,33 @@ mod tests {
let qr = check_qr(&t, "https://t.me/socks?server=84.53.239.95&port=4145").await?;
assert_eq!(
qr,
Qr::Socks5Proxy {
Qr::Proxy {
url: "socks5://84.53.239.95:4145".to_string(),
host: "84.53.239.95".to_string(),
port: 4145,
user: None,
pass: None,
protocol: "SOCKS5".to_string(),
}
);

let qr = check_qr(&t, "https://t.me/socks?server=foo.bar&port=123").await?;
assert_eq!(
qr,
Qr::Socks5Proxy {
Qr::Proxy {
url: "socks5://foo.bar:123".to_string(),
host: "foo.bar".to_string(),
port: 123,
user: None,
pass: None,
protocol: "SOCKS5".to_string(),
}
);

let qr = check_qr(&t, "https://t.me/socks?server=foo.baz").await?;
assert_eq!(
qr,
Qr::Socks5Proxy {
Qr::Proxy {
url: "socks5://foo.baz:1080".to_string(),
host: "foo.baz".to_string(),
port: 1080,
user: None,
pass: None,
protocol: "SOCKS5".to_string(),
}
);

Expand All @@ -1560,11 +1556,11 @@ mod tests {
.await?;
assert_eq!(
qr,
Qr::Socks5Proxy {
Qr::Proxy {
url: "socks5://foo.baz:12345".to_string(),
host: "foo.baz".to_string(),
port: 12345,
user: Some("ada".to_string()),
pass: Some("ms!/$".to_string()),
protocol: "SOCKS5".to_string(),
}
);

Expand Down

0 comments on commit 251f0d7

Please sign in to comment.