Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Accept an optional web-client argument for the invite. #326

Merged
merged 4 commits into from
Dec 18, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
.vscode/
*.iml
_trial_temp
*.egg
*.egg-info
.python-version

# Runtime files
sydent.conf
Expand Down
1 change: 1 addition & 0 deletions changelog.d/326.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Accept an optional `web_client_location` argument to the invite endpoint which allows customisation of the email template.
2 changes: 1 addition & 1 deletion res/invite_template.eml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is still quite Element-specific. Would this work with Hydrogen for instance? We could be fancy and allow the client to provide a URL filled with named placeholders.

Perhaps we don't care about this for right now though.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll see if it is reasonable for a homeserver to calculate the other items here. 👍

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The way that sydent currently works I don't think this is easily doable since a unique key is included in this URL that sydent generates (ephemeral_private_key), see the code around:

tokenStore = JoinTokenStore(self.sydent)
ephemeralPrivateKey = nacl.signing.SigningKey.generate()
ephemeralPublicKey = ephemeralPrivateKey.verify_key
ephemeralPrivateKeyBase64 = encode_base64(ephemeralPrivateKey.encode(), True)
ephemeralPublicKeyBase64 = encode_base64(ephemeralPublicKey.encode(), True)
tokenStore.storeEphemeralPublicKey(ephemeralPublicKeyBase64)
tokenStore.storeToken(medium, address, roomId, sender, token)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, thanks for digging. Note that I think we've talked about this key being either unhelpful or broken in Synapse's current implementation: matrix-org/synapse#6036



About Matrix:
Expand Down
2 changes: 1 addition & 1 deletion res/invite_template_vector.eml
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
14 changes: 11 additions & 3 deletions sydent/http/servlets/store_invite_servlet.py
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh this is an unrelated fix, but send_display_name was here twice, I'm fairly certain this is supposed to be sender_avatar_url as that's a speced property.

'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()

Expand Down
9 changes: 9 additions & 0 deletions sydent/sydent.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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"
))
Expand Down