Tighten up puppet DM invites
This commit is contained in:
parent
0dd2cf60b1
commit
3868c19b71
@ -16,12 +16,12 @@
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from mautrix.bridge import BaseMatrixHandler
|
||||
from mautrix.types import (Event, ReactionEvent, MessageEvent, StateEvent, EncryptedEvent, RedactionEvent,
|
||||
ReceiptEvent, SingleReceiptEventContent,
|
||||
from mautrix.types import (Event, EventType, MessageEvent, StateEvent, EncryptedEvent,
|
||||
ReceiptEvent, SingleReceiptEventContent, TextMessageEventContent,
|
||||
EventID, RoomID, UserID)
|
||||
from mautrix.errors import MatrixError
|
||||
|
||||
from . import portal as po, puppet as pu, user as u
|
||||
from .db import Message as DBMessage
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .__main__ import MessagesBridge
|
||||
@ -54,17 +54,78 @@ class MatrixHandler(BaseMatrixHandler):
|
||||
|
||||
async def handle_puppet_invite(self, room_id: RoomID, puppet: 'pu.Puppet',
|
||||
invited_by: 'u.User', _: EventID) -> None:
|
||||
chat_id = puppet.mid
|
||||
portal = await po.Portal.get_by_chat_id(chat_id, create=True)
|
||||
if portal.mxid:
|
||||
# TODO Allow creating a LINE group/room from a Matrix invite
|
||||
await portal.main_intent.error_and_leave(room_id, "You already have an existing chat with me!")
|
||||
intent = puppet.intent
|
||||
self.log.debug(f"{invited_by.mxid} invited puppet for {puppet.mid} to {room_id}")
|
||||
if not await invited_by.is_logged_in():
|
||||
await intent.error_and_leave(room_id, text="Please log in before inviting "
|
||||
"LINE puppets to private chats.")
|
||||
return
|
||||
|
||||
portal = await po.Portal.get_by_mxid(room_id)
|
||||
if portal:
|
||||
if portal.is_direct:
|
||||
await intent.error_and_leave(room_id, text="You can not invite additional users "
|
||||
"to private chats.")
|
||||
else:
|
||||
# TODO Send invite in LINE
|
||||
await intent.error_and_leave(room_id, text="Inviting additional users to an existing "
|
||||
"group chat is not yet supported.")
|
||||
return
|
||||
|
||||
await intent.join_room(room_id)
|
||||
try:
|
||||
members = await intent.get_room_members(room_id)
|
||||
except MatrixError:
|
||||
self.log.exception(f"Failed to get member list after joining {room_id}")
|
||||
await intent.leave_room(room_id)
|
||||
return
|
||||
if len(members) > 2:
|
||||
# TODO Add LINE group/room creating. Must also distinguish between the two!
|
||||
await intent.send_notice(room_id, "You can not invite LINE puppets to "
|
||||
"multi-user rooms.")
|
||||
await intent.leave_room(room_id)
|
||||
return
|
||||
|
||||
portal = await po.Portal.get_by_chat_id(puppet.mid, create=True)
|
||||
if portal.mxid:
|
||||
try:
|
||||
await intent.invite_user(portal.mxid, invited_by.mxid, check_cache=False)
|
||||
await intent.send_notice(room_id,
|
||||
text=("You already have a private chat with me "
|
||||
f"in room {portal.mxid}"),
|
||||
html=("You already have a private chat with me: "
|
||||
f"<a href='https://matrix.to/#/{portal.mxid}'>"
|
||||
"Link to room"
|
||||
"</a>"))
|
||||
await intent.leave_room(room_id)
|
||||
return
|
||||
except MatrixError:
|
||||
pass
|
||||
|
||||
portal.mxid = room_id
|
||||
e2be_ok = await portal.check_dm_encryption()
|
||||
# TODO Consider setting other power levels that get set on portal creation,
|
||||
# but they're of little use when the inviting user has an equal PL...
|
||||
await portal.save()
|
||||
if e2be_ok is True:
|
||||
evt_type, content = await self.e2ee.encrypt(
|
||||
room_id, EventType.ROOM_MESSAGE,
|
||||
TextMessageEventContent(msgtype=MessageType.NOTICE,
|
||||
body="Portal to private chat created and end-to-bridge"
|
||||
" encryption enabled."))
|
||||
await intent.send_message_event(room_id, evt_type, content)
|
||||
else:
|
||||
message = "Portal to private chat created."
|
||||
if e2be_ok is False:
|
||||
message += "\n\nWarning: Failed to enable end-to-bridge encryption"
|
||||
await intent.send_notice(room_id, message)
|
||||
|
||||
# TODO Put pause/resume in portal methods, with a lock or something
|
||||
# TODO Consider not backfilling on invite.
|
||||
# To do so, must set the last-seen message ID appropriately
|
||||
await invited_by.client.pause()
|
||||
try:
|
||||
chat_info = await invited_by.client.get_chat(chat_id)
|
||||
chat_info = await invited_by.client.get_chat(puppet.mid)
|
||||
await portal.update_matrix_room(invited_by, chat_info)
|
||||
finally:
|
||||
await invited_by.client.resume()
|
||||
|
@ -189,7 +189,8 @@ class Portal(DBPortal, BasePortal):
|
||||
async def handle_matrix_leave(self, user: 'u.User') -> None:
|
||||
self.log.info(f"{user.mxid} left portal to {self.chat_id}, "
|
||||
f"cleaning up and deleting...")
|
||||
# TODO Delete room history in LINE to prevent a re-sync from happening
|
||||
if await user.is_logged_in():
|
||||
await user.client.forget_chat(self.chat_id)
|
||||
await self.cleanup_and_delete()
|
||||
|
||||
async def _bridge_own_message_pm(self, source: 'u.User', puppet: Optional['p.Puppet'], mid: str,
|
||||
@ -501,10 +502,6 @@ class Portal(DBPortal, BasePortal):
|
||||
return MediaInfo(mxc, decryption_info, mime_type, file_name, len(data))
|
||||
|
||||
async def update_info(self, conv: ChatInfo, client: Optional[Client]) -> None:
|
||||
if self.is_direct:
|
||||
self.other_user = conv.participants[0].id
|
||||
if self._main_intent is self.az.intent:
|
||||
self._main_intent = (await p.Puppet.get_by_mid(self.other_user)).intent
|
||||
for participant in conv.participants:
|
||||
# REMINDER: multi-user chats include your own LINE user in the participant list
|
||||
if participant.id != None:
|
||||
@ -806,7 +803,8 @@ class Portal(DBPortal, BasePortal):
|
||||
self.by_chat_id[self.chat_id] = self
|
||||
if self.mxid:
|
||||
self.by_mxid[self.mxid] = self
|
||||
if self.other_user:
|
||||
if self.is_direct:
|
||||
self.other_user = self.chat_id
|
||||
self._main_intent = (await p.Puppet.get_by_mid(self.other_user)).intent
|
||||
else:
|
||||
self._main_intent = self.az.intent
|
||||
|
@ -88,6 +88,9 @@ class Client(RPCClient):
|
||||
async def set_last_message_ids(self, msg_ids: Dict[str, int], own_msg_ids: Dict[str, int], rct_ids: Dict[str, Dict[int, int]]) -> None:
|
||||
await self.request("set_last_message_ids", msg_ids=msg_ids, own_msg_ids=own_msg_ids, rct_ids=rct_ids)
|
||||
|
||||
async def forget_chat(self, chat_id: str) -> None:
|
||||
await self.request("forget_chat", chat_id=chat_id)
|
||||
|
||||
async def on_message(self, func: Callable[[Message], Awaitable[None]]) -> None:
|
||||
async def wrapper(data: Dict[str, Any]) -> None:
|
||||
await func(Message.deserialize(data["message"]))
|
||||
|
@ -258,6 +258,7 @@ export default class Client {
|
||||
send: req => this.puppet.sendMessage(req.chat_id, req.text),
|
||||
send_file: req => this.puppet.sendFile(req.chat_id, req.file_path),
|
||||
set_last_message_ids: req => this.puppet.setLastMessageIDs(req.msg_ids, req.own_msg_ids, req.rct_ids),
|
||||
forget_chat: req => this.puppet.forgetChat(req.chat_id),
|
||||
pause: () => this.puppet.stopObserving(),
|
||||
resume: () => this.puppet.startObserving(),
|
||||
get_own_profile: () => this.puppet.getOwnProfile(),
|
||||
|
@ -538,6 +538,13 @@ export default class MessagesPuppeteer {
|
||||
}
|
||||
}
|
||||
|
||||
forgetChat(chatID) {
|
||||
this.mostRecentMessages.delete(chatID)
|
||||
this.mostRecentOwnMessages.delete(chatID)
|
||||
this.mostRecentReceipts.delete(chatID)
|
||||
// TODO Delete chat from recents list
|
||||
}
|
||||
|
||||
async readImage(imageUrl) {
|
||||
return await this.taskQueue.push(() =>
|
||||
this.page.evaluate(
|
||||
|
Loading…
Reference in New Issue
Block a user