Fix email notifications for invites without local state. (#8627)

This can happen if e.g. the room invited into is no longer on the
server (or if all users left the room).
pull/8639/head
Erik Johnston 2020-10-23 10:41:32 +01:00 committed by GitHub
parent 054a6b9538
commit db9ef792f0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 58 additions and 13 deletions

1
changelog.d/8627.bugfix Normal file
View File

@ -0,0 +1 @@
Fix email notifications for invites without local state.

View File

@ -24,7 +24,7 @@ from typing import Iterable, List, TypeVar
import bleach
import jinja2
from synapse.api.constants import EventTypes
from synapse.api.constants import EventTypes, Membership
from synapse.api.errors import StoreError
from synapse.config.emailconfig import EmailSubjectConfig
from synapse.logging.context import make_deferred_yieldable
@ -317,9 +317,14 @@ class Mailer:
async def get_room_vars(
self, room_id, user_id, notifs, notif_events, room_state_ids
):
my_member_event_id = room_state_ids[("m.room.member", user_id)]
my_member_event = await self.store.get_event(my_member_event_id)
is_invite = my_member_event.content["membership"] == "invite"
# Check if one of the notifs is an invite event for the user.
is_invite = False
for n in notifs:
ev = notif_events[n["event_id"]]
if ev.type == EventTypes.Member and ev.state_key == user_id:
if ev.content.get("membership") == Membership.INVITE:
is_invite = True
break
room_name = await calculate_room_name(self.store, room_state_ids, user_id)
@ -461,16 +466,26 @@ class Mailer:
self.store, room_state_ids[room_id], user_id, fallback_to_members=False
)
my_member_event_id = room_state_ids[room_id][("m.room.member", user_id)]
my_member_event = await self.store.get_event(my_member_event_id)
if my_member_event.content["membership"] == "invite":
inviter_member_event_id = room_state_ids[room_id][
("m.room.member", my_member_event.sender)
]
inviter_member_event = await self.store.get_event(
inviter_member_event_id
# See if one of the notifs is an invite event for the user
invite_event = None
for n in notifs_by_room[room_id]:
ev = notif_events[n["event_id"]]
if ev.type == EventTypes.Member and ev.state_key == user_id:
if ev.content.get("membership") == Membership.INVITE:
invite_event = ev
break
if invite_event:
inviter_member_event_id = room_state_ids[room_id].get(
("m.room.member", invite_event.sender)
)
inviter_name = name_from_member_event(inviter_member_event)
inviter_name = invite_event.sender
if inviter_member_event_id:
inviter_member_event = await self.store.get_event(
inviter_member_event_id, allow_none=True
)
if inviter_member_event:
inviter_name = name_from_member_event(inviter_member_event)
if room_name is None:
return self.email_subjects.invite_from_person % {

View File

@ -131,6 +131,35 @@ class EmailPusherTests(HomeserverTestCase):
# We should get emailed about that message
self._check_for_mail()
def test_invite_sends_email(self):
# Create a room and invite the user to it
room = self.helper.create_room_as(self.others[0].id, tok=self.others[0].token)
self.helper.invite(
room=room,
src=self.others[0].id,
tok=self.others[0].token,
targ=self.user_id,
)
# We should get emailed about the invite
self._check_for_mail()
def test_invite_to_empty_room_sends_email(self):
# Create a room and invite the user to it
room = self.helper.create_room_as(self.others[0].id, tok=self.others[0].token)
self.helper.invite(
room=room,
src=self.others[0].id,
tok=self.others[0].token,
targ=self.user_id,
)
# Then have the original user leave
self.helper.leave(room, self.others[0].id, tok=self.others[0].token)
# We should get emailed about the invite
self._check_for_mail()
def test_multiple_members_email(self):
# We want to test multiple notifications, so we pause processing of push
# while we send messages.