diff --git a/.gitignore b/.gitignore index 8d69ce07..fb2bf6cd 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,9 @@ .vscode/ *.iml _trial_temp +*.egg +*.egg-info +.python-version # Runtime files sydent.conf diff --git a/changelog.d/326.feature b/changelog.d/326.feature new file mode 100644 index 00000000..bf12d447 --- /dev/null +++ b/changelog.d/326.feature @@ -0,0 +1 @@ +Accept an optional `web_client_location` argument to the invite endpoint which allows customisation of the email template. diff --git a/res/invite_template.eml b/res/invite_template.eml index f253686b..826006c8 100644 --- a/res/invite_template.eml +++ b/res/invite_template.eml @@ -18,7 +18,7 @@ Matrix. To join the conversation, either pick a Matrix client from https://matrix.org/docs/projects/try-matrix-now.html or use the single-click link below to join via Element (requires Chrome, Firefox, Safari, iOS or Android) -https://app.element.io/#/room/%(room_id_forurl)s?email=%(to_forurl)s&signurl=https%%3A%%2F%%2Fmatrix.org%%2F_matrix%%2Fidentity%%2Fapi%%2Fv1%%2Fsign-ed25519%%3Ftoken%%3D%(token)s%%26private_key%%3D%(ephemeral_private_key)s&room_name=%(room_name_forurl)s&room_avatar_url=%(room_avatar_url_forurl)s&inviter_name=%(sender_display_name_forurl)s&guest_access_token=%(guest_access_token_forurl)s&guest_user_id=%(guest_user_id_forurl)s +%(web_client_location)/#/room/%(room_id_forurl)s?email=%(to_forurl)s&signurl=https%%3A%%2F%%2Fmatrix.org%%2F_matrix%%2Fidentity%%2Fapi%%2Fv1%%2Fsign-ed25519%%3Ftoken%%3D%(token)s%%26private_key%%3D%(ephemeral_private_key)s&room_name=%(room_name_forurl)s&room_avatar_url=%(room_avatar_url_forurl)s&inviter_name=%(sender_display_name_forurl)s&guest_access_token=%(guest_access_token_forurl)s&guest_user_id=%(guest_user_id_forurl)s About Matrix: diff --git a/res/invite_template_vector.eml b/res/invite_template_vector.eml index b6196bb1..38b98347 100644 --- a/res/invite_template_vector.eml +++ b/res/invite_template_vector.eml @@ -16,7 +16,7 @@ Hi, %(sender_display_name)s has invited you into a room %(bracketed_room_name)s on Element. To join the conversation please follow the link below. -https://app.element.io/#/room/%(room_id_forurl)s?email=%(to_forurl)s&signurl=https%%3A%%2F%%2Fvector.im%%2F_matrix%%2Fidentity%%2Fapi%%2Fv1%%2Fsign-ed25519%%3Ftoken%%3D%(token)s%%26private_key%%3D%(ephemeral_private_key)s&room_name=%(room_name_forurl)s&room_avatar_url=%(room_avatar_url_forurl)s&inviter_name=%(sender_display_name_forurl)s&guest_access_token=%(guest_access_token_forurl)s&guest_user_id=%(guest_user_id_forurl)s +%(web_client_location)/#/room/%(room_id_forurl)s?email=%(to_forurl)s&signurl=https%%3A%%2F%%2Fvector.im%%2F_matrix%%2Fidentity%%2Fapi%%2Fv1%%2Fsign-ed25519%%3Ftoken%%3D%(token)s%%26private_key%%3D%(ephemeral_private_key)s&room_name=%(room_name_forurl)s&room_avatar_url=%(room_avatar_url_forurl)s&inviter_name=%(sender_display_name_forurl)s&guest_access_token=%(guest_access_token_forurl)s&guest_user_id=%(guest_user_id_forurl)s Element is an open source collaboration app built on the Matrix.org open standard for interoperable communication: supporting group chat, diff --git a/sydent/http/servlets/store_invite_servlet.py b/sydent/http/servlets/store_invite_servlet.py index 5a6a7782..11d54093 100644 --- a/sydent/http/servlets/store_invite_servlet.py +++ b/sydent/http/servlets/store_invite_servlet.py @@ -79,29 +79,37 @@ def render_POST(self, request): tokenStore.storeEphemeralPublicKey(ephemeralPublicKeyBase64) tokenStore.storeToken(medium, address, roomId, sender, token) + # Variables to substitute in the template. substitutions = {} + # Include all arguments sent via the request. for k, v in args.items(): if isinstance(v, string_types): substitutions[k] = v substitutions["token"] = token - required = [ + # Substitutions that the template requires, but are optional to provide + # to the API. + extra_substitutions = [ 'sender_display_name', 'token', 'room_name', 'bracketed_room_name', 'room_avatar_url', - 'sender_display_name', + 'sender_avatar_url', 'guest_user_id', 'guest_access_token', ] - for k in required: + for k in extra_substitutions: substitutions.setdefault(k, '') substitutions["ephemeral_private_key"] = ephemeralPrivateKeyBase64 if substitutions["room_name"] != '': substitutions["bracketed_room_name"] = "(%s)" % substitutions["room_name"] + substitutions["web_client_location"] = self.sydent.default_web_client_location + if 'org.matrix.web_client_location' in substitutions: + substitutions["web_client_location"] = substitutions.pop("org.matrix.web_client_location") + subject_header = Header(self.sydent.cfg.get('email', 'email.invite.subject', raw=True) % substitutions, 'utf8') substitutions["subject_header_value"] = subject_header.encode() diff --git a/sydent/sydent.py b/sydent/sydent.py index 6782ddef..019ef9d0 100644 --- a/sydent/sydent.py +++ b/sydent/sydent.py @@ -126,6 +126,12 @@ 'email.smtppassword': '', 'email.hostname': '', 'email.tlsmode': '0', + # The web client location which will be used if it is not provided by + # the homeserver. + # + # This should be the scheme and hostname only, see res/invite_template.eml + # for the full URL that gets generated. + 'email.default_web_client_location': 'https://app.element.io', # When a user is invited to a room via their email address, that invite is # displayed in the room list using an obfuscated version of the user's email # address. These config options determine how much of the email address to @@ -205,6 +211,9 @@ def __init__(self, cfg, reactor=twisted.internet.reactor): self.cfg.get("general", "delete_tokens_on_bind") ) + self.default_web_client_location = self.cfg.get( + "email", "email.default_web_client_location" + ) self.username_obfuscate_characters = int(self.cfg.get( "email", "email.third_party_invite_username_obfuscate_characters" ))