mirror of
https://github.com/chatmail/core.git
synced 2026-05-02 21:06:31 +03:00
apply updates
This commit is contained in:
@@ -20,3 +20,215 @@ fn maybe_empty_string_to_option(string: String) -> Option<String> {
|
|||||||
Some(string)
|
Some(string)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#[derive(Serialize, TypeDef)]
|
||||||
|
#[serde(rename = "Qr", rename_all = "camelCase")]
|
||||||
|
#[serde(tag = "type")]
|
||||||
|
pub enum QrObject {
|
||||||
|
AskVerifyContact {
|
||||||
|
contact_id: u32,
|
||||||
|
fingerprint: String,
|
||||||
|
invitenumber: String,
|
||||||
|
authcode: String,
|
||||||
|
},
|
||||||
|
AskVerifyGroup {
|
||||||
|
grpname: String,
|
||||||
|
grpid: String,
|
||||||
|
contact_id: u32,
|
||||||
|
fingerprint: String,
|
||||||
|
invitenumber: String,
|
||||||
|
authcode: String,
|
||||||
|
},
|
||||||
|
FprOk {
|
||||||
|
contact_id: u32,
|
||||||
|
},
|
||||||
|
FprMismatch {
|
||||||
|
contact_id: Option<u32>,
|
||||||
|
},
|
||||||
|
FprWithoutAddr {
|
||||||
|
fingerprint: String,
|
||||||
|
},
|
||||||
|
Account {
|
||||||
|
domain: String,
|
||||||
|
},
|
||||||
|
WebrtcInstance {
|
||||||
|
domain: String,
|
||||||
|
instance_pattern: String,
|
||||||
|
},
|
||||||
|
Addr {
|
||||||
|
contact_id: u32,
|
||||||
|
draft: Option<String>,
|
||||||
|
},
|
||||||
|
Url {
|
||||||
|
url: String,
|
||||||
|
},
|
||||||
|
Text {
|
||||||
|
text: String,
|
||||||
|
},
|
||||||
|
WithdrawVerifyContact {
|
||||||
|
contact_id: u32,
|
||||||
|
fingerprint: String,
|
||||||
|
invitenumber: String,
|
||||||
|
authcode: String,
|
||||||
|
},
|
||||||
|
WithdrawVerifyGroup {
|
||||||
|
grpname: String,
|
||||||
|
grpid: String,
|
||||||
|
contact_id: u32,
|
||||||
|
fingerprint: String,
|
||||||
|
invitenumber: String,
|
||||||
|
authcode: String,
|
||||||
|
},
|
||||||
|
ReviveVerifyContact {
|
||||||
|
contact_id: u32,
|
||||||
|
fingerprint: String,
|
||||||
|
invitenumber: String,
|
||||||
|
authcode: String,
|
||||||
|
},
|
||||||
|
ReviveVerifyGroup {
|
||||||
|
grpname: String,
|
||||||
|
grpid: String,
|
||||||
|
contact_id: u32,
|
||||||
|
fingerprint: String,
|
||||||
|
invitenumber: String,
|
||||||
|
authcode: String,
|
||||||
|
},
|
||||||
|
Login {
|
||||||
|
address: String,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Qr> for QrObject {
|
||||||
|
fn from(qr: Qr) -> Self {
|
||||||
|
match qr {
|
||||||
|
Qr::AskVerifyContact {
|
||||||
|
contact_id,
|
||||||
|
fingerprint,
|
||||||
|
invitenumber,
|
||||||
|
authcode,
|
||||||
|
} => {
|
||||||
|
let contact_id = contact_id.to_u32();
|
||||||
|
let fingerprint = fingerprint.to_string();
|
||||||
|
QrObject::AskVerifyContact {
|
||||||
|
contact_id,
|
||||||
|
fingerprint,
|
||||||
|
invitenumber,
|
||||||
|
authcode,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Qr::AskVerifyGroup {
|
||||||
|
grpname,
|
||||||
|
grpid,
|
||||||
|
contact_id,
|
||||||
|
fingerprint,
|
||||||
|
invitenumber,
|
||||||
|
authcode,
|
||||||
|
} => {
|
||||||
|
let contact_id = contact_id.to_u32();
|
||||||
|
let fingerprint = fingerprint.to_string();
|
||||||
|
QrObject::AskVerifyGroup {
|
||||||
|
grpname,
|
||||||
|
grpid,
|
||||||
|
contact_id,
|
||||||
|
fingerprint,
|
||||||
|
invitenumber,
|
||||||
|
authcode,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Qr::FprOk { contact_id } => {
|
||||||
|
let contact_id = contact_id.to_u32();
|
||||||
|
QrObject::FprOk { contact_id }
|
||||||
|
}
|
||||||
|
Qr::FprMismatch { contact_id } => {
|
||||||
|
let contact_id = contact_id.map(|contact_id| contact_id.to_u32());
|
||||||
|
QrObject::FprMismatch { contact_id }
|
||||||
|
}
|
||||||
|
Qr::FprWithoutAddr { fingerprint } => QrObject::FprWithoutAddr { fingerprint },
|
||||||
|
Qr::Account { domain } => QrObject::Account { domain },
|
||||||
|
Qr::WebrtcInstance {
|
||||||
|
domain,
|
||||||
|
instance_pattern,
|
||||||
|
} => QrObject::WebrtcInstance {
|
||||||
|
domain,
|
||||||
|
instance_pattern,
|
||||||
|
},
|
||||||
|
Qr::Addr { contact_id, draft } => {
|
||||||
|
let contact_id = contact_id.to_u32();
|
||||||
|
QrObject::Addr { contact_id, draft }
|
||||||
|
}
|
||||||
|
Qr::Url { url } => QrObject::Url { url },
|
||||||
|
Qr::Text { text } => QrObject::Text { text },
|
||||||
|
Qr::WithdrawVerifyContact {
|
||||||
|
contact_id,
|
||||||
|
fingerprint,
|
||||||
|
invitenumber,
|
||||||
|
authcode,
|
||||||
|
} => {
|
||||||
|
let contact_id = contact_id.to_u32();
|
||||||
|
let fingerprint = fingerprint.to_string();
|
||||||
|
QrObject::WithdrawVerifyContact {
|
||||||
|
contact_id,
|
||||||
|
fingerprint,
|
||||||
|
invitenumber,
|
||||||
|
authcode,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Qr::WithdrawVerifyGroup {
|
||||||
|
grpname,
|
||||||
|
grpid,
|
||||||
|
contact_id,
|
||||||
|
fingerprint,
|
||||||
|
invitenumber,
|
||||||
|
authcode,
|
||||||
|
} => {
|
||||||
|
let contact_id = contact_id.to_u32();
|
||||||
|
let fingerprint = fingerprint.to_string();
|
||||||
|
QrObject::WithdrawVerifyGroup {
|
||||||
|
grpname,
|
||||||
|
grpid,
|
||||||
|
contact_id,
|
||||||
|
fingerprint,
|
||||||
|
invitenumber,
|
||||||
|
authcode,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Qr::ReviveVerifyContact {
|
||||||
|
contact_id,
|
||||||
|
fingerprint,
|
||||||
|
invitenumber,
|
||||||
|
authcode,
|
||||||
|
} => {
|
||||||
|
let contact_id = contact_id.to_u32();
|
||||||
|
let fingerprint = fingerprint.to_string();
|
||||||
|
QrObject::ReviveVerifyContact {
|
||||||
|
contact_id,
|
||||||
|
fingerprint,
|
||||||
|
invitenumber,
|
||||||
|
authcode,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Qr::ReviveVerifyGroup {
|
||||||
|
grpname,
|
||||||
|
grpid,
|
||||||
|
contact_id,
|
||||||
|
fingerprint,
|
||||||
|
invitenumber,
|
||||||
|
authcode,
|
||||||
|
} => {
|
||||||
|
let contact_id = contact_id.to_u32();
|
||||||
|
let fingerprint = fingerprint.to_string();
|
||||||
|
QrObject::ReviveVerifyGroup {
|
||||||
|
grpname,
|
||||||
|
grpid,
|
||||||
|
contact_id,
|
||||||
|
fingerprint,
|
||||||
|
invitenumber,
|
||||||
|
authcode,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Qr::Login { address, .. } => QrObject::Login { address },
|
||||||
|
Qr::Backup { ticket } => QrObject::Backup {
|
||||||
|
ticket: ticket.as_bytes(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -489,7 +489,7 @@ pub async fn cmdline(context: Context, line: &str, chat_id: &mut ChatId) -> Resu
|
|||||||
"Ticket: {}",
|
"Ticket: {}",
|
||||||
multibase::encode(multibase::Base::Base64, &ticket_bytes)
|
multibase::encode(multibase::Base::Base64, &ticket_bytes)
|
||||||
);
|
);
|
||||||
let qr_code = deltachat::qr_code_generator::generate_backup_qr_code(&ticket)?;
|
let qr_code = deltachat::qr_code_generator::generate_backup_qr_code(ticket)?;
|
||||||
let file = dir.join("qr.svg");
|
let file = dir.join("qr.svg");
|
||||||
tokio::fs::write(file, qr_code.as_bytes()).await?;
|
tokio::fs::write(file, qr_code.as_bytes()).await?;
|
||||||
|
|
||||||
@@ -497,7 +497,7 @@ pub async fn cmdline(context: Context, line: &str, chat_id: &mut ChatId) -> Resu
|
|||||||
}
|
}
|
||||||
"receive-backup" => {
|
"receive-backup" => {
|
||||||
ensure!(!arg1.is_empty(), "Argument <ticket> is missing.");
|
ensure!(!arg1.is_empty(), "Argument <ticket> is missing.");
|
||||||
let (_, ticket) = multibase::decode(&arg1.to_string())?;
|
let (_, ticket) = multibase::decode(&arg1)?;
|
||||||
receive_backup(&context, ticket, Some(arg2.to_string())).await?;
|
receive_backup(&context, ticket, Some(arg2.to_string())).await?;
|
||||||
}
|
}
|
||||||
"import-backup" => {
|
"import-backup" => {
|
||||||
|
|||||||
26
src/imex.rs
26
src/imex.rs
@@ -151,11 +151,11 @@ pub async fn receive_backup_inner(
|
|||||||
);
|
);
|
||||||
let ticket = Ticket::from_bytes(&ticket_bytes)?;
|
let ticket = Ticket::from_bytes(&ticket_bytes)?;
|
||||||
|
|
||||||
let sender_dir = tempfile::tempdir().unwrap();
|
let recv_dir = tempfile::tempdir().unwrap();
|
||||||
let sender_db = sender_dir.path().join("db");
|
let recv_db = recv_dir.path().join("db");
|
||||||
|
|
||||||
let port = 9991;
|
let port = 9991;
|
||||||
let receiver = Receiver::new(port, &sender_db)
|
|
||||||
|
let receiver = Receiver::new(port, &recv_db)
|
||||||
.await
|
.await
|
||||||
.context("failed to create sender")?;
|
.context("failed to create sender")?;
|
||||||
let mut receiver_transfer = receiver
|
let mut receiver_transfer = receiver
|
||||||
@@ -190,16 +190,20 @@ pub async fn receive_backup_inner(
|
|||||||
|
|
||||||
let out = context.get_blobdir();
|
let out = context.get_blobdir();
|
||||||
|
|
||||||
for link in data.read_dir().unwrap() {
|
let mut read_dir_stream = data
|
||||||
|
.read_dir()?
|
||||||
|
.ok_or_else(|| anyhow::anyhow!("unexpected data structure"))?;
|
||||||
|
|
||||||
|
while let Some(link) = read_dir_stream.next().await {
|
||||||
let link = link?;
|
let link = link?;
|
||||||
let file_content = data.read_file(&link).await?;
|
let file_content = data.read_file(&link).await?;
|
||||||
let name = link.name.unwrap_or_default();
|
let name = link.name.unwrap_or_default();
|
||||||
let path = out.join(&name);
|
let path = out.join(&name);
|
||||||
println!("Writing {}", path.display());
|
|
||||||
let mut file = tokio::fs::File::create(&path)
|
let mut file = tokio::fs::File::create(&path)
|
||||||
.await
|
.await
|
||||||
.with_context(|| format!("create file: {}", path.display()))?;
|
.with_context(|| format!("create file: {}", path.display()))?;
|
||||||
let mut content = file_content.pretty();
|
let mut content = file_content.pretty()?;
|
||||||
tokio::io::copy(&mut content, &mut file)
|
tokio::io::copy(&mut content, &mut file)
|
||||||
.await
|
.await
|
||||||
.context("copy")?;
|
.context("copy")?;
|
||||||
@@ -223,7 +227,7 @@ pub async fn receive_backup_inner(
|
|||||||
progress_task.await?;
|
progress_task.await?;
|
||||||
receiver_transfer.finish().await?;
|
receiver_transfer.finish().await?;
|
||||||
|
|
||||||
println!("Received all data, written to: {}", out.display());
|
info!(context, "Received all data, written to: {}", out.display());
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -246,10 +250,10 @@ pub async fn send_backup(
|
|||||||
|
|
||||||
if let Err(err) = res.as_ref() {
|
if let Err(err) = res.as_ref() {
|
||||||
// We are using Anyhow's .context() and to show the inner error, too, we need the {:#}:
|
// We are using Anyhow's .context() and to show the inner error, too, we need the {:#}:
|
||||||
error!(context, "IMEX failed to complete: {:#}", err);
|
error!(context, "Send backup failed to complete: {:#}", err);
|
||||||
context.emit_event(EventType::ImexProgress(0));
|
context.emit_event(EventType::ImexProgress(0));
|
||||||
} else {
|
} else {
|
||||||
info!(context, "IMEX successfully completed");
|
info!(context, "Send backup successfully completed");
|
||||||
context.emit_event(EventType::ImexProgress(1000));
|
context.emit_event(EventType::ImexProgress(1000));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -261,7 +265,7 @@ async fn send_backup_inner(
|
|||||||
path: &Path,
|
path: &Path,
|
||||||
passphrase: Option<String>,
|
passphrase: Option<String>,
|
||||||
) -> Result<iroh_share::SenderTransfer> {
|
) -> Result<iroh_share::SenderTransfer> {
|
||||||
info!(context, "Import/export dir: {}", path.display());
|
info!(context, "Send backup dir: {}", path.display());
|
||||||
ensure!(context.sql.is_open().await, "Database not opened.");
|
ensure!(context.sql.is_open().await, "Database not opened.");
|
||||||
context.emit_event(EventType::ImexProgress(10));
|
context.emit_event(EventType::ImexProgress(10));
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ const HTTP_SCHEME: &str = "http://";
|
|||||||
const HTTPS_SCHEME: &str = "https://";
|
const HTTPS_SCHEME: &str = "https://";
|
||||||
pub const DCBACKUP_SCHEME: &str = "DCBACKUP:";
|
pub const DCBACKUP_SCHEME: &str = "DCBACKUP:";
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub enum Qr {
|
pub enum Qr {
|
||||||
AskVerifyContact {
|
AskVerifyContact {
|
||||||
contact_id: ContactId,
|
contact_id: ContactId,
|
||||||
|
|||||||
Reference in New Issue
Block a user