mirror of
https://github.com/chatmail/core.git
synced 2026-05-19 14:56:33 +03:00
* improve error handling for account setup from qrcode closes #3192 * replace issue id with pr id in changelog * Update src/qr.rs Co-authored-by: bjoern <r10s@b44t.com> * show response when it's invalid in success case, too * fix changelog entry Co-authored-by: bjoern <r10s@b44t.com>
This commit is contained in:
@@ -7,7 +7,7 @@
|
|||||||
### Changes
|
### Changes
|
||||||
|
|
||||||
### Fixes
|
### Fixes
|
||||||
|
- improved error handling for account setup from qrcode #3474
|
||||||
|
|
||||||
## 1.92.0
|
## 1.92.0
|
||||||
|
|
||||||
|
|||||||
59
src/qr.rs
59
src/qr.rs
@@ -1,6 +1,6 @@
|
|||||||
//! # QR code module.
|
//! # QR code module.
|
||||||
|
|
||||||
use anyhow::{bail, ensure, Context as _, Error, Result};
|
use anyhow::{anyhow, bail, ensure, Context as _, Error, Result};
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
use percent_encoding::percent_decode_str;
|
use percent_encoding::percent_decode_str;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
@@ -14,8 +14,8 @@ use crate::context::Context;
|
|||||||
use crate::key::Fingerprint;
|
use crate::key::Fingerprint;
|
||||||
use crate::message::Message;
|
use crate::message::Message;
|
||||||
use crate::peerstate::Peerstate;
|
use crate::peerstate::Peerstate;
|
||||||
use crate::token;
|
|
||||||
use crate::tools::time;
|
use crate::tools::time;
|
||||||
|
use crate::{token, EventType};
|
||||||
|
|
||||||
const OPENPGP4FPR_SCHEME: &str = "OPENPGP4FPR:"; // yes: uppercase
|
const OPENPGP4FPR_SCHEME: &str = "OPENPGP4FPR:"; // yes: uppercase
|
||||||
const DCACCOUNT_SCHEME: &str = "DCACCOUNT:";
|
const DCACCOUNT_SCHEME: &str = "DCACCOUNT:";
|
||||||
@@ -344,10 +344,14 @@ fn decode_webrtc_instance(_context: &Context, qr: &str) -> Result<Qr> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
struct CreateAccountResponse {
|
struct CreateAccountSuccessResponse {
|
||||||
email: String,
|
email: String,
|
||||||
password: String,
|
password: String,
|
||||||
}
|
}
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
struct CreateAccountErrorResponse {
|
||||||
|
reason: String,
|
||||||
|
}
|
||||||
|
|
||||||
/// take a qr of the type DC_QR_ACCOUNT, parse it's parameters,
|
/// take a qr of the type DC_QR_ACCOUNT, parse it's parameters,
|
||||||
/// download additional information from the contained url and set the parameters.
|
/// download additional information from the contained url and set the parameters.
|
||||||
@@ -355,23 +359,42 @@ struct CreateAccountResponse {
|
|||||||
#[allow(clippy::indexing_slicing)]
|
#[allow(clippy::indexing_slicing)]
|
||||||
async fn set_account_from_qr(context: &Context, qr: &str) -> Result<()> {
|
async fn set_account_from_qr(context: &Context, qr: &str) -> Result<()> {
|
||||||
let url_str = &qr[DCACCOUNT_SCHEME.len()..];
|
let url_str = &qr[DCACCOUNT_SCHEME.len()..];
|
||||||
|
let response = reqwest::Client::new().post(url_str).send().await?;
|
||||||
|
let response_status = response.status();
|
||||||
|
let response_text = response.text().await.with_context(|| {
|
||||||
|
format!(
|
||||||
|
"Cannot create account, request to {:?} failed: empty response",
|
||||||
|
url_str
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
|
||||||
let parsed: CreateAccountResponse = reqwest::Client::new()
|
if response_status.is_success() {
|
||||||
.post(url_str)
|
let CreateAccountSuccessResponse { password, email } = serde_json::from_str(&response_text)
|
||||||
.send()
|
.with_context(|| {
|
||||||
.await?
|
format!(
|
||||||
.json()
|
"Cannot create account, response from {:?} is malformed:\n{:?}",
|
||||||
.await
|
url_str, response_text
|
||||||
.with_context(|| format!("Cannot create account, request to {:?} failed", url_str))?;
|
)
|
||||||
|
})?;
|
||||||
|
context.set_config(Config::Addr, Some(&email)).await?;
|
||||||
|
context.set_config(Config::MailPw, Some(&password)).await?;
|
||||||
|
|
||||||
context
|
Ok(())
|
||||||
.set_config(Config::Addr, Some(&parsed.email))
|
} else {
|
||||||
.await?;
|
match serde_json::from_str::<CreateAccountErrorResponse>(&response_text) {
|
||||||
context
|
Ok(error) => Err(anyhow!(error.reason)),
|
||||||
.set_config(Config::MailPw, Some(&parsed.password))
|
Err(parse_error) => {
|
||||||
.await?;
|
context.emit_event(EventType::Error(format!(
|
||||||
|
"Cannot create account, server response could not be parsed:\n{:#}\nraw response:\n{}",
|
||||||
Ok(())
|
parse_error, response_text
|
||||||
|
)));
|
||||||
|
bail!(
|
||||||
|
"Cannot create account, unexpected server response:\n{:?}",
|
||||||
|
response_text
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn set_config_from_qr(context: &Context, qr: &str) -> Result<()> {
|
pub async fn set_config_from_qr(context: &Context, qr: &str) -> Result<()> {
|
||||||
|
|||||||
Reference in New Issue
Block a user