diff --git a/CHANGELOG.md b/CHANGELOG.md index b3af0bec..31e5cdfe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ ## untagged +- fix metadata dictproxy which would confuse transactions + resulting in missed notifications and other issues. + ([#393](https://github.com/deltachat/chatmail/pull/388)) + ([#394](https://github.com/deltachat/chatmail/pull/389)) + - add optional "imap_rawlog" config option. If true, .in/.out files are created in user home dirs containing the imap protocol messages. diff --git a/chatmaild/src/chatmaild/dictproxy.py b/chatmaild/src/chatmaild/dictproxy.py index 21ced67d..56f91c23 100644 --- a/chatmaild/src/chatmaild/dictproxy.py +++ b/chatmaild/src/chatmaild/dictproxy.py @@ -44,7 +44,10 @@ def handle_dovecot_request(self, msg, transactions): elif short_command == "C": return self.handle_commit_transaction(transaction_id, parts, transactions) elif short_command == "S": - return self.handle_set(transaction_id, parts, transactions) + addr = transactions[transaction_id]["addr"] + if not self.handle_set(addr, parts): + transactions[transaction_id]["res"] = "F\n" + logging.error(f"dictproxy-set failed for {addr!r}: {msg!r}") def handle_lookup(self, parts): logging.warning(f"lookup ignored: {parts!r}") @@ -59,11 +62,10 @@ def handle_begin_transaction(self, transaction_id, parts, transactions): addr = parts[1] transactions[transaction_id] = dict(addr=addr, res="O\n") - def handle_set(self, transaction_id, parts, transactions): + def handle_set(self, addr, parts): # For documentation on key structure see # https://github.com/dovecot/core/blob/main/src/lib-storage/mailbox-attribute.h - - transactions[transaction_id]["res"] = "F\n" + return False def handle_commit_transaction(self, transaction_id, parts, transactions): # return whatever "set" command(s) set as result. diff --git a/chatmaild/src/chatmaild/lastlogin.py b/chatmaild/src/chatmaild/lastlogin.py index ab5f546f..c9a531a1 100644 --- a/chatmaild/src/chatmaild/lastlogin.py +++ b/chatmaild/src/chatmaild/lastlogin.py @@ -9,20 +9,19 @@ def __init__(self, config): super().__init__() self.config = config - def handle_set(self, transaction_id, parts, transactions): + def handle_set(self, addr, parts): keyname = parts[1].split("/") value = parts[2] if len(parts) > 2 else "" - addr = transactions[transaction_id]["addr"] if keyname[0] == "shared" and keyname[1] == "last-login": if addr.startswith("echo@"): - return + return True addr = keyname[2] timestamp = int(value) user = self.config.get_user(addr) user.set_last_login_timestamp(timestamp) - else: - # Transaction failed. - transactions[transaction_id]["res"] = "F\n" + return True + + return False def main(): diff --git a/chatmaild/src/chatmaild/metadata.py b/chatmaild/src/chatmaild/metadata.py index 71c8d928..e48e007b 100644 --- a/chatmaild/src/chatmaild/metadata.py +++ b/chatmaild/src/chatmaild/metadata.py @@ -62,24 +62,19 @@ def handle_lookup(self, parts): logging.warning(f"lookup ignored: {parts!r}") return "N\n" - def handle_set(self, transaction_id, parts, transactions): + def handle_set(self, addr, parts): # For documentation on key structure see # https://github.com/dovecot/core/blob/main/src/lib-storage/mailbox-attribute.h keyname = parts[1].split("/") value = parts[2] if len(parts) > 2 else "" - addr = transactions[transaction_id]["addr"] if keyname[0] == "priv" and keyname[2] == self.metadata.DEVICETOKEN_KEY: self.metadata.add_token_to_addr(addr, value) + return True elif keyname[0] == "priv" and keyname[2] == "messagenew": self.notifier.new_message_for_addr(addr, self.metadata) - else: - # Transaction failed. - try: - transactions[transaction_id]["res"] = "F\n" - except KeyError: - logging.error( - f"could not mark tx as failed: {transaction_id} {transactions}" - ) + return True + + return False def main():