mirror of
https://github.com/chatmail/core.git
synced 2026-07-23 03:13:06 +03:00
Compare commits
7 Commits
v1.156.3
...
link2xt/ac
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
491d6abe49 | ||
|
|
8e9c79061f | ||
|
|
94f57e786d | ||
|
|
db1a7f6084 | ||
|
|
25df14707e | ||
|
|
26672900d5 | ||
|
|
82573dc78c |
6
Cargo.lock
generated
6
Cargo.lock
generated
@@ -297,9 +297,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "async-imap"
|
||||
version = "0.10.2"
|
||||
version = "0.10.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5488cd022c3c7bc41a9b34a540d9ac0d9c5cd42fdb106a67616521b7592d5b4e"
|
||||
checksum = "932fcbfc3b9e93f73022bf70446cfd9fe540ba62779944d5363797ff7009cb16"
|
||||
dependencies = [
|
||||
"async-channel 2.3.1",
|
||||
"async-compression",
|
||||
@@ -4174,7 +4174,7 @@ dependencies = [
|
||||
"aes-gcm",
|
||||
"aes-kw",
|
||||
"argon2",
|
||||
"base64 0.21.7",
|
||||
"base64 0.22.1",
|
||||
"bitfield",
|
||||
"block-padding",
|
||||
"blowfish",
|
||||
|
||||
@@ -41,7 +41,7 @@ ratelimit = { path = "./deltachat-ratelimit" }
|
||||
anyhow = { workspace = true }
|
||||
async-broadcast = "0.7.2"
|
||||
async-channel = { workspace = true }
|
||||
async-imap = { version = "0.10.2", default-features = false, features = ["runtime-tokio", "compress"] }
|
||||
async-imap = { version = "0.10.3", default-features = false, features = ["runtime-tokio", "compress"] }
|
||||
async-native-tls = { version = "0.5", default-features = false, features = ["runtime-tokio"] }
|
||||
async-smtp = { version = "0.10", default-features = false, features = ["runtime-tokio"] }
|
||||
async_zip = { version = "0.0.17", default-features = false, features = ["deflate", "tokio-fs"] }
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
from pathlib import Path
|
||||
from tempfile import TemporaryDirectory
|
||||
from typing import TYPE_CHECKING, Optional, Union
|
||||
from warnings import warn
|
||||
|
||||
@@ -38,6 +40,16 @@ class Account:
|
||||
"""Remove the account."""
|
||||
self._rpc.remove_account(self.id)
|
||||
|
||||
def clone(self) -> "Account":
|
||||
"""Clone given account."""
|
||||
with TemporaryDirectory() as tmp_dir:
|
||||
tmp_path = Path(tmp_dir)
|
||||
self.export_backup(tmp_path)
|
||||
files = list(tmp_path.glob("*.tar"))
|
||||
new_account = self.manager.add_account()
|
||||
new_account.import_backup(files[0])
|
||||
return new_account
|
||||
|
||||
def start_io(self) -> None:
|
||||
"""Start the account I/O."""
|
||||
self._rpc.start_io(self.id)
|
||||
@@ -83,6 +95,10 @@ class Account:
|
||||
return self.get_config("selfavatar")
|
||||
|
||||
def check_qr(self, qr):
|
||||
"""Parse QR code contents.
|
||||
|
||||
This function takes the raw text scanned
|
||||
and checks what can be done with it."""
|
||||
return self._rpc.check_qr(self.id, qr)
|
||||
|
||||
def set_config_from_qr(self, qr: str):
|
||||
@@ -125,6 +141,9 @@ class Account:
|
||||
return self._rpc.make_vcard(self.id, contact_ids)
|
||||
|
||||
def import_vcard(self, vcard: str) -> list[Contact]:
|
||||
"""Import vCard.
|
||||
|
||||
Return created or modified contacts in the order they appear in vCard."""
|
||||
contact_ids = self._rpc.import_vcard_contents(self.id, vcard)
|
||||
return [Contact(self, contact_id) for contact_id in contact_ids]
|
||||
|
||||
@@ -133,6 +152,10 @@ class Account:
|
||||
[contact] = self.import_vcard(vcard)
|
||||
return contact.create_chat()
|
||||
|
||||
def get_device_chat(self) -> Chat:
|
||||
"""Return device chat."""
|
||||
return self.device_contact.create_chat()
|
||||
|
||||
def get_contact_by_id(self, contact_id: int) -> Contact:
|
||||
"""Return Contact instance for the given contact ID."""
|
||||
return Contact(self, contact_id)
|
||||
@@ -193,6 +216,11 @@ class Account:
|
||||
"""This account's identity as a Contact."""
|
||||
return Contact(self, SpecialContactId.SELF)
|
||||
|
||||
@property
|
||||
def device_contact(self) -> Chat:
|
||||
"""This account's device contact."""
|
||||
return Contact(self, SpecialContactId.DEVICE)
|
||||
|
||||
def get_chatlist(
|
||||
self,
|
||||
query: Optional[str] = None,
|
||||
@@ -318,6 +346,13 @@ class Account:
|
||||
if event.kind == EventType.MSGS_CHANGED:
|
||||
return event
|
||||
|
||||
def wait_for_msgs_noticed_event(self):
|
||||
"""Wait for messages noticed event and return it."""
|
||||
while True:
|
||||
event = self.wait_for_event()
|
||||
if event.kind == EventType.MSGS_NOTICED:
|
||||
return event
|
||||
|
||||
def wait_for_incoming_msg(self):
|
||||
"""Wait for incoming message and return it.
|
||||
|
||||
|
||||
@@ -157,11 +157,7 @@ def get_multi_account_test_setup(acfactory: ACFactory) -> [Account, Account, Acc
|
||||
|
||||
bob.wait_for_incoming_msg_event()
|
||||
|
||||
alice_second_device: Account = acfactory.get_unconfigured_account()
|
||||
|
||||
alice._rpc.provide_backup.future(alice.id)
|
||||
backup_code = alice._rpc.get_backup_qr(alice.id)
|
||||
alice_second_device._rpc.get_backup(alice_second_device.id, backup_code)
|
||||
alice_second_device = alice.clone()
|
||||
alice_second_device.start_io()
|
||||
alice.clear_all_events()
|
||||
alice_second_device.clear_all_events()
|
||||
|
||||
@@ -60,15 +60,12 @@ def test_qr_setup_contact_svg(acfactory) -> None:
|
||||
|
||||
|
||||
@pytest.mark.parametrize("protect", [True, False])
|
||||
def test_qr_securejoin(acfactory, protect, tmp_path):
|
||||
def test_qr_securejoin(acfactory, protect):
|
||||
alice, bob, fiona = acfactory.get_online_accounts(3)
|
||||
|
||||
# Setup second device for Alice
|
||||
# to test observing securejoin protocol.
|
||||
alice.export_backup(tmp_path)
|
||||
files = list(tmp_path.glob("*.tar"))
|
||||
alice2 = acfactory.get_unconfigured_account()
|
||||
alice2.import_backup(files[0])
|
||||
alice2 = alice.clone()
|
||||
|
||||
logging.info("Alice creates a group")
|
||||
alice_chat = alice.create_group("Group", protect=protect)
|
||||
|
||||
@@ -287,12 +287,9 @@ def test_message(acfactory) -> None:
|
||||
assert reactions == snapshot.reactions
|
||||
|
||||
|
||||
def test_reaction_seen_on_another_dev(acfactory, tmp_path) -> None:
|
||||
def test_reaction_seen_on_another_dev(acfactory) -> None:
|
||||
alice, bob = acfactory.get_online_accounts(2)
|
||||
alice.export_backup(tmp_path)
|
||||
files = list(tmp_path.glob("*.tar"))
|
||||
alice2 = acfactory.get_unconfigured_account()
|
||||
alice2.import_backup(files[0])
|
||||
alice2 = alice.clone()
|
||||
alice2.start_io()
|
||||
|
||||
bob_addr = bob.get_config("addr")
|
||||
@@ -661,7 +658,7 @@ def test_download_limit_chat_assignment(acfactory, tmp_path, n_accounts):
|
||||
assert snapshot.chat == bob_chat_alice
|
||||
|
||||
|
||||
def test_markseen_contact_request(acfactory, tmp_path):
|
||||
def test_markseen_contact_request(acfactory):
|
||||
"""
|
||||
Test that seen status is synchronized for contact request messages
|
||||
even though read receipt is not sent.
|
||||
@@ -669,10 +666,7 @@ def test_markseen_contact_request(acfactory, tmp_path):
|
||||
alice, bob = acfactory.get_online_accounts(2)
|
||||
|
||||
# Bob sets up a second device.
|
||||
bob.export_backup(tmp_path)
|
||||
files = list(tmp_path.glob("*.tar"))
|
||||
bob2 = acfactory.get_unconfigured_account()
|
||||
bob2.import_backup(files[0])
|
||||
bob2 = bob.clone()
|
||||
bob2.start_io()
|
||||
|
||||
alice_chat_bob = alice.create_chat(bob)
|
||||
|
||||
Reference in New Issue
Block a user