mirror of
https://github.com/chatmail/core.git
synced 2026-05-21 07:46:31 +03:00
handle withdraw/revive qr code actions
This commit is contained in:
@@ -2076,6 +2076,10 @@ void dc_stop_ongoing_process (dc_context_t* context);
|
|||||||
#define DC_QR_TEXT 330 // text1=text
|
#define DC_QR_TEXT 330 // text1=text
|
||||||
#define DC_QR_URL 332 // text1=URL
|
#define DC_QR_URL 332 // text1=URL
|
||||||
#define DC_QR_ERROR 400 // text1=error string
|
#define DC_QR_ERROR 400 // text1=error string
|
||||||
|
#define DC_QR_WITHDRAW_VERIFYCONTACT 500
|
||||||
|
#define DC_QR_WITHDRAW_VERIFYGROUP 502 // text1=groupname
|
||||||
|
#define DC_QR_REVIVE_VERIFYCONTACT 510
|
||||||
|
#define DC_QR_REVIVE_VERIFYGROUP 512 // text1=groupname
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check a scanned QR code.
|
* Check a scanned QR code.
|
||||||
@@ -2097,6 +2101,12 @@ void dc_stop_ongoing_process (dc_context_t* context);
|
|||||||
* - DC_QR_TEXT with dc_lot_t::text1=Text
|
* - DC_QR_TEXT with dc_lot_t::text1=Text
|
||||||
* - DC_QR_URL with dc_lot_t::text1=URL
|
* - DC_QR_URL with dc_lot_t::text1=URL
|
||||||
* - DC_QR_ERROR with dc_lot_t::text1=Error string
|
* - DC_QR_ERROR with dc_lot_t::text1=Error string
|
||||||
|
* - DC_QR_WITHDRAW_VERIFYCONTACT, DC_QR_WITHDRAW_VERIFYGROUP
|
||||||
|
* withdraw own qr-codes, with text1=groupname for groups
|
||||||
|
* to actually withdraw, call dc_set_config_from_qr() with the code.
|
||||||
|
* - DC_QR_REVIVE_VERIFYCONTACT, DC_QR_REVIVE_VERIFYGROUP,
|
||||||
|
* revive withdrawn qr-codes, with text1=groupname for groups,
|
||||||
|
* to actually revive, call dc_set_config_from_qr() with the code.
|
||||||
*
|
*
|
||||||
* @memberof dc_context_t
|
* @memberof dc_context_t
|
||||||
* @param context The context object.
|
* @param context The context object.
|
||||||
|
|||||||
10
src/lot.rs
10
src/lot.rs
@@ -110,6 +110,16 @@ pub enum LotState {
|
|||||||
/// text1=error string
|
/// text1=error string
|
||||||
QrError = 400,
|
QrError = 400,
|
||||||
|
|
||||||
|
QrWithdrawVerifyContact = 500,
|
||||||
|
|
||||||
|
/// text1=groupname
|
||||||
|
QrWithdrawVerifyGroup = 502,
|
||||||
|
|
||||||
|
QrReviveVerifyContact = 510,
|
||||||
|
|
||||||
|
/// text1=groupname
|
||||||
|
QrReviveVerifyGroup = 512,
|
||||||
|
|
||||||
// Message States
|
// Message States
|
||||||
MsgInFresh = 10,
|
MsgInFresh = 10,
|
||||||
MsgInNoticed = 13,
|
MsgInNoticed = 13,
|
||||||
|
|||||||
68
src/qr.rs
68
src/qr.rs
@@ -6,7 +6,7 @@ use percent_encoding::percent_decode_str;
|
|||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
use crate::chat::{self, ChatIdBlocked};
|
use crate::chat::{self, get_chat_id_by_grpid, ChatIdBlocked};
|
||||||
use crate::config::Config;
|
use crate::config::Config;
|
||||||
use crate::constants::Blocked;
|
use crate::constants::Blocked;
|
||||||
use crate::contact::{addr_normalize, may_be_valid_addr, Contact, Origin};
|
use crate::contact::{addr_normalize, may_be_valid_addr, Contact, Origin};
|
||||||
@@ -16,6 +16,7 @@ use crate::log::LogExt;
|
|||||||
use crate::lot::{Lot, LotState};
|
use crate::lot::{Lot, LotState};
|
||||||
use crate::message::Message;
|
use crate::message::Message;
|
||||||
use crate::peerstate::Peerstate;
|
use crate::peerstate::Peerstate;
|
||||||
|
use crate::token;
|
||||||
|
|
||||||
const OPENPGP4FPR_SCHEME: &str = "OPENPGP4FPR:"; // yes: uppercase
|
const OPENPGP4FPR_SCHEME: &str = "OPENPGP4FPR:"; // yes: uppercase
|
||||||
const DCACCOUNT_SCHEME: &str = "DCACCOUNT:";
|
const DCACCOUNT_SCHEME: &str = "DCACCOUNT:";
|
||||||
@@ -189,6 +190,27 @@ async fn decode_openpgp(context: &Context, qr: &str) -> Lot {
|
|||||||
lot.fingerprint = Some(fingerprint);
|
lot.fingerprint = Some(fingerprint);
|
||||||
lot.invitenumber = invitenumber;
|
lot.invitenumber = invitenumber;
|
||||||
lot.auth = auth;
|
lot.auth = auth;
|
||||||
|
|
||||||
|
// scanning own qr-code offers withdraw/revive instead of secure-join
|
||||||
|
if context.is_self_addr(&addr).await.unwrap_or_default() {
|
||||||
|
if let Some(ref invitenumber) = lot.invitenumber {
|
||||||
|
lot.state =
|
||||||
|
if token::exists(context, token::Namespace::InviteNumber, &*invitenumber).await
|
||||||
|
{
|
||||||
|
if lot.state == LotState::QrAskVerifyContact {
|
||||||
|
LotState::QrWithdrawVerifyContact
|
||||||
|
} else {
|
||||||
|
LotState::QrWithdrawVerifyGroup
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if lot.state == LotState::QrAskVerifyContact {
|
||||||
|
LotState::QrReviveVerifyContact
|
||||||
|
} else {
|
||||||
|
LotState::QrReviveVerifyGroup
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return format_err!("Missing address").into();
|
return format_err!("Missing address").into();
|
||||||
}
|
}
|
||||||
@@ -275,7 +297,8 @@ async fn set_account_from_qr(context: &Context, qr: &str) -> Result<(), Error> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn set_config_from_qr(context: &Context, qr: &str) -> Result<(), Error> {
|
pub async fn set_config_from_qr(context: &Context, qr: &str) -> Result<(), Error> {
|
||||||
match check_qr(context, qr).await.state {
|
let lot = check_qr(context, qr).await;
|
||||||
|
match lot.state {
|
||||||
LotState::QrAccount => set_account_from_qr(context, qr).await,
|
LotState::QrAccount => set_account_from_qr(context, qr).await,
|
||||||
LotState::QrWebrtcInstance => {
|
LotState::QrWebrtcInstance => {
|
||||||
let val = decode_webrtc_instance(context, qr).text2;
|
let val = decode_webrtc_instance(context, qr).text2;
|
||||||
@@ -284,6 +307,47 @@ pub async fn set_config_from_qr(context: &Context, qr: &str) -> Result<(), Error
|
|||||||
.await?;
|
.await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
LotState::QrWithdrawVerifyContact | LotState::QrWithdrawVerifyGroup => {
|
||||||
|
token::delete(
|
||||||
|
context,
|
||||||
|
token::Namespace::InviteNumber,
|
||||||
|
lot.invitenumber.unwrap_or_default().as_str(),
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
token::delete(
|
||||||
|
context,
|
||||||
|
token::Namespace::Auth,
|
||||||
|
lot.auth.unwrap_or_default().as_str(),
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
LotState::QrReviveVerifyContact | LotState::QrReviveVerifyGroup => {
|
||||||
|
let chat_id = if lot.state == LotState::QrReviveVerifyContact {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(
|
||||||
|
get_chat_id_by_grpid(context, &lot.text2.unwrap_or_default())
|
||||||
|
.await?
|
||||||
|
.0,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
token::save(
|
||||||
|
context,
|
||||||
|
token::Namespace::InviteNumber,
|
||||||
|
chat_id,
|
||||||
|
lot.invitenumber.unwrap_or_default(),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
token::save(
|
||||||
|
context,
|
||||||
|
token::Namespace::Auth,
|
||||||
|
chat_id,
|
||||||
|
lot.auth.unwrap_or_default(),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
_ => bail!("qr code does not contain config: {}", qr),
|
_ => bail!("qr code does not contain config: {}", qr),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
11
src/token.rs
11
src/token.rs
@@ -111,3 +111,14 @@ pub async fn exists(context: &Context, namespace: Namespace, token: &str) -> boo
|
|||||||
.await
|
.await
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn delete(context: &Context, namespace: Namespace, token: &str) -> Result<()> {
|
||||||
|
context
|
||||||
|
.sql
|
||||||
|
.execute(
|
||||||
|
"DELETE FROM tokens WHERE namespc=? AND token=?;",
|
||||||
|
paramsv![namespace, token],
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user