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).
This commit is contained in:
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 bleach
import jinja2 import jinja2
from synapse.api.constants import EventTypes from synapse.api.constants import EventTypes, Membership
from synapse.api.errors import StoreError from synapse.api.errors import StoreError
from synapse.config.emailconfig import EmailSubjectConfig from synapse.config.emailconfig import EmailSubjectConfig
from synapse.logging.context import make_deferred_yieldable from synapse.logging.context import make_deferred_yieldable
@ -317,9 +317,14 @@ class Mailer:
async def get_room_vars( async def get_room_vars(
self, room_id, user_id, notifs, notif_events, room_state_ids self, room_id, user_id, notifs, notif_events, room_state_ids
): ):
my_member_event_id = room_state_ids[("m.room.member", user_id)] # Check if one of the notifs is an invite event for the user.
my_member_event = await self.store.get_event(my_member_event_id) is_invite = False
is_invite = my_member_event.content["membership"] == "invite" 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) 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 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)] # See if one of the notifs is an invite event for the user
my_member_event = await self.store.get_event(my_member_event_id) invite_event = None
if my_member_event.content["membership"] == "invite": for n in notifs_by_room[room_id]:
inviter_member_event_id = room_state_ids[room_id][ ev = notif_events[n["event_id"]]
("m.room.member", my_member_event.sender) if ev.type == EventTypes.Member and ev.state_key == user_id:
] if ev.content.get("membership") == Membership.INVITE:
inviter_member_event = await self.store.get_event( invite_event = ev
inviter_member_event_id 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: if room_name is None:
return self.email_subjects.invite_from_person % { return self.email_subjects.invite_from_person % {

View file

@ -131,6 +131,35 @@ class EmailPusherTests(HomeserverTestCase):
# We should get emailed about that message # We should get emailed about that message
self._check_for_mail() 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): def test_multiple_members_email(self):
# We want to test multiple notifications, so we pause processing of push # We want to test multiple notifications, so we pause processing of push
# while we send messages. # while we send messages.