diff --git a/changelog.d/376.feature b/changelog.d/376.feature
new file mode 100644
index 00000000..d1ad46ee
--- /dev/null
+++ b/changelog.d/376.feature
@@ -0,0 +1 @@
+Add support for using Jinja2 in e-mail templates. Contributed by H-Shay.
\ No newline at end of file
diff --git a/matrix_is_test/res/is-test/invite_template.eml.j2 b/matrix_is_test/res/is-test/invite_template.eml.j2
new file mode 100644
index 00000000..0b09cb12
--- /dev/null
+++ b/matrix_is_test/res/is-test/invite_template.eml.j2
@@ -0,0 +1,8 @@
+{
+ "token": "{{ token }}",
+ "room_alias": "{{ room_alias }}",
+ "room_avatar_url": "{{ room_avatar_url }}",
+ "room_name": "{{ room_name }}",
+ "sender_display_name": "{{ sender_display_name }}",
+ "sender_avatar_url": "{{ sender_avatar_url }}"
+}
diff --git a/matrix_is_test/res/is-test/verification_template.eml.j2 b/matrix_is_test/res/is-test/verification_template.eml.j2
new file mode 100644
index 00000000..d74f9a83
--- /dev/null
+++ b/matrix_is_test/res/is-test/verification_template.eml.j2
@@ -0,0 +1 @@
+<<<{{ token }}>>>
diff --git a/res/matrix-org/invite_template.eml.j2 b/res/matrix-org/invite_template.eml.j2
new file mode 100644
index 00000000..9fd23212
--- /dev/null
+++ b/res/matrix-org/invite_template.eml.j2
@@ -0,0 +1,146 @@
+Date: {{ date|safe }}
+From: {{ from|safe }}
+To: {{ to|safe }}
+Message-ID: {{ messageid|safe }}
+Subject: {{ subject_header_value|safe }}
+MIME-Version: 1.0
+Content-Type: multipart/alternative;
+ boundary="{{ multipart_boundary|safe }}"
+
+--{{ multipart_boundary|safe }}
+Content-Type: text/plain; charset=UTF-8
+Content-Disposition: inline
+
+Hi,
+
+{{ sender_display_name|safe }} {{ bracketed_verified_sender|safe }}has invited you into a room
+{{ bracketed_room_name|safe }}on 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)
+
+
+{{ web_client_location }}/#/room/{{ room_id|urlencode }}?email={{ to|urlencode }}&signurl=https%3A%2F%2Fmatrix.org%2F_matrix%2Fidentity%2Fapi%2Fv1%2Fsign-ed25519%3Ftoken%3D{{ token|urlencode }}%26private_key%3D{{ ephemeral_private_key|urlencode }}&room_name={{ room_name|urlencode }}&room_avatar_url={{ room_avatar_url|urlencode }}&inviter_name={{ sender_display_name|urlencode }}&guest_access_token={{ guest_access_token|urlencode }}&guest_user_id={{ guest_user_id|urlencode }}
+
+
+About Matrix:
+
+Matrix.org is an open standard for interoperable, decentralised, real-time communication
+over IP, supporting group chat, file transfer, voice and video calling, integrations to
+other apps, bridges to other communication systems and much more. It can be used to power
+Instant Messaging, VoIP/WebRTC signalling, Internet of Things communication - or anywhere
+you need a standard HTTP API for publishing and subscribing to data whilst tracking the
+conversation history.
+
+Matrix defines the standard, and provides open source reference implementations of
+Matrix-compatible Servers, Clients, Client SDKs and Application Services to help you
+create new communication solutions or extend the capabilities and reach of existing ones.
+
+Thanks,
+
+Matrix
+
+--{{ multipart_boundary|safe }}
+Content-Type: text/html; charset=UTF-8
+Content-Disposition: inline
+
+
+
+
+
+
+
+
+
+ |
+
+
+
+ Hi,
+
+{{ sender_display_name }} {{ bracketed_verified_sender }} has invited you into a room {{ bracketed_room_name }} on
+Matrix. To join the conversation, either pick a Matrix client or use the single-click
+link below to join via Element (requires
+Chrome,
+Firefox or
+Safari on the web,
+or iOS or Android on mobile.)
+
+
+
+ Join the conversation.
+
+
+
+About Matrix:
+
+Matrix.org is an open standard for interoperable, decentralised, real-time communication
+over IP, supporting group chat, file transfer, voice and video calling, integrations to
+other apps, bridges to other communication systems and much more. It can be used to power
+Instant Messaging, VoIP/WebRTC signalling, Internet of Things communication - or anywhere
+you need a standard HTTP API for publishing and subscribing to data whilst tracking the
+conversation history.
+
+Matrix defines the standard, and provides open source reference implementations of
+Matrix-compatible Servers, Clients, Client SDKs and Application Services to help you
+create new communication solutions or extend the capabilities and reach of existing ones.
+
+Thanks,
+
+Matrix
+ |
+ |
+
+
+
+
+
+--{{ multipart_boundary|safe }}--
diff --git a/res/matrix-org/verification_template.eml.j2 b/res/matrix-org/verification_template.eml.j2
new file mode 100644
index 00000000..fffbb87e
--- /dev/null
+++ b/res/matrix-org/verification_template.eml.j2
@@ -0,0 +1,88 @@
+Date: {{ date|safe }}
+From: {{ from|safe }}
+To: {{ to|safe }}
+Message-ID: {{ messageid|safe }}
+Subject: Confirm your email address for Matrix
+MIME-Version: 1.0
+Content-Type: multipart/alternative;
+ boundary="{{ multipart_boundary|safe }}"
+
+--{{ multipart_boundary|safe }}
+Content-Type: text/plain; charset=UTF-8
+Content-Disposition: inline
+
+Hello,
+
+We have received a request to use this email address with a matrix.org identity
+server. If this was you who made this request, you may use the following link
+to complete the verification of your email address:
+
+{{ link|safe }}
+
+If your client requires a code, the code is {{ token|safe }}
+
+If you aren't aware of making such a request, please disregard this email.
+
+
+About Matrix:
+
+Matrix is an open standard for interoperable, decentralised, real-time communication
+over IP. It can be used to power Instant Messaging, VoIP/WebRTC signalling, Internet
+of Things communication - or anywhere you need a standard HTTP API for publishing and
+subscribing to data whilst tracking the conversation history.
+
+Matrix defines the standard, and provides open source reference implementations of
+Matrix-compatible Servers, Clients, Client SDKs and Application Services to help you
+create new communication solutions or extend the capabilities and reach of existing ones.
+
+--{{ multipart_boundary|safe }}
+Content-Type: text/html; charset=UTF-8
+Content-Disposition: inline
+
+
+
+
+
+
+
+
+
+Hello,
+
+We have received a request to use this email address with a matrix.org
+identity server. If this was you who made this request, you may use the
+following link to complete the verification of your email address:
+
+Complete email verification
+
+...or copy this link into your web browser:
+
+{{ link }}
+
+If your client requires a code, the code is {{ token }}
+
+If you aren't aware of making such a request, please disregard this
+email.
+
+
+About Matrix:
+
+Matrix is an open standard for interoperable, decentralised, real-time communication
+over IP. It can be used to power Instant Messaging, VoIP/WebRTC signalling, Internet
+of Things communication - or anywhere you need a standard HTTP API for publishing and
+subscribing to data whilst tracking the conversation history.
+
+Matrix defines the standard, and provides open source reference implementations of
+Matrix-compatible Servers, Clients, Client SDKs and Application Services to help you
+create new communication solutions or extend the capabilities and reach of existing ones.
+
+
+
+
+--{{ multipart_boundary|safe }}--
diff --git a/res/vector-im/invite_template.eml.j2 b/res/vector-im/invite_template.eml.j2
new file mode 100644
index 00000000..d35a4342
--- /dev/null
+++ b/res/vector-im/invite_template.eml.j2
@@ -0,0 +1,177 @@
+Date: {{ date|safe }}
+From: {{ from|safe }}
+To: {{ to|safe }}
+Message-ID: {{ messageid|safe }}
+Subject: {{ subject_header_value|safe }}
+MIME-Version: 1.0
+Content-Type: multipart/alternative;
+ boundary="{{ multipart_boundary|safe }}"
+
+--{{ multipart_boundary|safe }}
+Content-Type: text/plain; charset=UTF-8
+Content-Disposition: inline
+
+Hi,
+
+{{ sender_display_name|safe }} {{ bracketed_verified_sender|safe }}has invited you into a room
+{{ bracketed_room_name|safe }}on Element. To join the conversation please follow the
+link below.
+
+{{ web_client_location }}/#/room/{{ room_id|urlencode }}?email={{ to|urlencode }}&signurl=https%3A%2F%2Fvector.im%2F_matrix%2Fidentity%2Fapi%2Fv1%2Fsign-ed25519%3Ftoken%3D{{ token|urlencode }}%26private_key%3D{{ ephemeral_private_key|urlencode }}&room_name={{ room_name|urlencode }}&room_avatar_url={{ room_avatar_url|urlencode }}&inviter_name={{ sender_display_name|urlencode }}&guest_access_token={{ guest_access_token|urlencode }}&guest_user_id={{ guest_user_id|urlencode }}
+
+Element is an open source collaboration app built on the Matrix.org
+open standard for interoperable communication: supporting group chat,
+file transfer, voice and video calling, integrations to other apps, bridges
+to other communication systems and much more.
+
+Please note that you will need to use Chrome, Firefox or Safari on the web, or
+iOS or Android on mobile.
+
+Thanks,
+
+Element
+
+
+About Element:
+
+Break through - Element allows teams to communicate across a wide range of collaboration
+apps. If some team members use Element while others use IRC, Slack or Gitter, Element will
+allow these team members to seamlessly work together. Element offers the richest
+network of communication bridges.
+
+Own Your Own Data - No one should control your communication and data but you. Element
+lets you run your own server, and provides users and teams with the most advanced
+crypto ratchet technology available today for a decentralized secure Internet.
+
+Open Source - Element is entirely open source: all the code is published on GitHub
+(Apache License) for anyone to see and extend. This means teams can customize or
+contribute to the code and everyone can benefit from the speed of community innovation.
+
+Made on Matrix - Element is built on top of Matrix. Matrix is an open network for secure,
+decentralized communication delivering a community of users, bridged networks,
+integrated bots and applications plus full end-to-end encryption. To learn more about
+Matrix visit https://matrix.org.
+
+--{{ multipart_boundary|safe }}
+Content-Type: text/html; charset=UTF-8
+Content-Disposition: inline
+
+
+
+
+
+
+
+
+
+ |
+
+
+
+ Hi,
+
+{{ sender_display_name }} {{ bracketed_verified_sender }} has invited you into a
+room {{ bracketed_room_name }} on Element.
+
+
+ Join the conversation.
+
+
+Element is an open source collaboration app built on the Matrix.org
+open standard for interoperable communication: supporting group chat, file
+transfer, voice and video calling, integrations to other apps, bridges
+to other communication systems and much more.
+
+Please note that Element requires
+Chrome,
+Firefox or
+Safari on the web,
+or iOS or Android on mobile.
+
+Thanks,
+
+Element
+
+
+About Element:
+
+Break through - Element allows teams to communicate across a wide range of collaboration
+apps. If some team members use Element while others use IRC, Slack or Gitter, Element will
+allow these team members to seamlessly work together. Element offers the richest
+network of communication bridges.
+
+Own Your Own Data - No one should control your communication and data but you. Element
+lets you run your own server, and provides users and teams with the most advanced
+crypto ratchet technology available today for a decentralized secure Internet.
+
+Open Source - Element is entirely open source: all the code is published on GitHub
+(Apache License) for anyone to see and extend. This means teams can customize or
+contribute to the code and everyone can benefit from the speed of community innovation.
+
+Made on Matrix - Element is built on top of Matrix. Matrix is an open network for secure,
+decentralized communication delivering a community of users, bridged networks,
+integrated bots and applications plus full end-to-end encryption. To learn more about
+Matrix visit https://matrix.org.
+
+ |
+ |
+
+
+
+
+
+--{{ multipart_boundary|safe }}--
diff --git a/res/vector-im/verification_template.eml.j2 b/res/vector-im/verification_template.eml.j2
new file mode 100644
index 00000000..66f15396
--- /dev/null
+++ b/res/vector-im/verification_template.eml.j2
@@ -0,0 +1,171 @@
+Date: {{ date|safe }}
+From: {{ from|safe }}
+To: {{ to|safe }}
+Message-ID: {{ messageid|safe }}
+Subject: Confirm your email address for Element
+MIME-Version: 1.0
+Content-Type: multipart/alternative;
+ boundary="{{ multipart_boundary|safe }}"
+
+--{{ multipart_boundary|safe }}
+Content-Type: text/plain; charset=UTF-8
+Content-Disposition: inline
+
+Hello there!
+
+You have asked us to register this email address with element.io - the open source,
+distributed and secure shared workspace for the web that's built on Matrix.
+
+If it was really you who made this request, you can click on the following link to
+complete the verification of your email address:
+
+{{ link|safe }}
+
+Please note that you will need to use Chrome, Firefox or Safari on the web, or
+iOS or Android on mobile.
+
+If you didn't make this request, you can safely disregard this email.
+
+Thanks!
+
+Element
+
+
+About Element:
+
+Break through - Element allows teams to communicate across a wide range of collaboration
+apps. If some team members use Element while others use IRC, Slack or Gitter, Element will
+allow these team members to seamlessly work together. Element offers the richest
+network of communication bridges.
+
+Own Your Own Data - No one should control your communication and data but you. Element
+lets you run your own server, and provides users and teams with the most advanced
+crypto ratchet technology available today for a decentralized secure Internet.
+
+Open Source - Element is entirely open source: all the code is published on GitHub
+(Apache License) for anyone to see and extend. This means teams can customize or
+contribute to the code and everyone can benefit from the speed of community innovation.
+
+Made on Matrix - Element is built on top of Matrix. Matrix is an open network for secure,
+decentralized communication delivering a community of users, bridged networks,
+integrated bots and applications plus full end-to-end encryption. To learn more about
+Matrix visit https://matrix.org.
+
+--{{ multipart_boundary|safe }}
+Content-Type: text/html; charset=UTF-8
+Content-Disposition: inline
+
+
+
+
+
+
+
+
+
+ |
+
+
+
+ Hello there!
+
+ You have asked us to register this email address with element.io - the open source,
+ distributed and secure shared workspace for the web that's built on Matrix.
+
+ If it was really you who made this request, you can click on the following link to
+ complete the verification of your email address:
+
+ Complete email verification
+
+
+ Please note that Element requires
+ Chrome,
+ Firefox or
+ Safari on the web,
+ or iOS or Android on mobile.
+
+ If you didn't make this request, you can safely disregard this email.
+
+ Thanks!
+
+ Element
+
+
+ About Element:
+
+ Break through - Element allows teams to communicate across a wide range of collaboration
+ apps. If some team members use Element while others use IRC, Slack or Gitter, Element will
+ allow these team members to seamlessly work together. Element offers the richest
+ network of communication bridges.
+
+ Own Your Own Data - No one should control your communication and data but you. Element
+ lets you run your own server, and provides users and teams with the most advanced
+ crypto ratchet technology available today for a decentralized secure Internet.
+
+ Open Source - Element is entirely open source: all the code is published on GitHub
+ (Apache License) for anyone to see and extend. This means teams can customize or
+ contribute to the code and everyone can benefit from the speed of community innovation.
+
+ Made on Matrix - Element is built on top of Matrix. Matrix is an open network for secure,
+ decentralized communication delivering a community of users, bridged networks,
+ integrated bots and applications plus full end-to-end encryption. To learn more about
+ Matrix visit https://matrix.org.
+
+ |
+ |
+
+
+
+
+
+--{{ multipart_boundary|safe }}--
diff --git a/res/vector_verification_sample.txt b/res/vector_verification_sample.txt
new file mode 100644
index 00000000..e48dce85
--- /dev/null
+++ b/res/vector_verification_sample.txt
@@ -0,0 +1,158 @@
+Hello there!
+
+You have asked us to register this email address with element.io - the open source,
+distributed and secure shared workspace for the web that's built on Matrix.
+
+If it was really you who made this request, you can click on the following link to
+complete the verification of your email address:
+
+https://link_test.com
+
+Please note that you will need to use Chrome, Firefox or Safari on the web, or
+iOS or Android on mobile.
+
+If you didn't make this request, you can safely disregard this email.
+
+Thanks!
+
+Element
+
+
+About Element:
+
+Break through - Element allows teams to communicate across a wide range of collaboration
+apps. If some team members use Element while others use IRC, Slack or Gitter, Element will
+allow these team members to seamlessly work together. Element offers the richest
+network of communication bridges.
+
+Own Your Own Data - No one should control your communication and data but you. Element
+lets you run your own server, and provides users and teams with the most advanced
+crypto ratchet technology available today for a decentralized secure Internet.
+
+Open Source - Element is entirely open source: all the code is published on GitHub
+(Apache License) for anyone to see and extend. This means teams can customize or
+contribute to the code and everyone can benefit from the speed of community innovation.
+
+Made on Matrix - Element is built on top of Matrix. Matrix is an open network for secure,
+decentralized communication delivering a community of users, bridged networks,
+integrated bots and applications plus full end-to-end encryption. To learn more about
+Matrix visit https://matrix.org.
+
+--aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+Content-Type: text/html; charset=UTF-8
+Content-Disposition: inline
+
+
+
+
+
+
+
+
+
+ |
+
+
+
+ Hello there!
+
+ You have asked us to register this email address with element.io - the open source,
+ distributed and secure shared workspace for the web that's built on Matrix.
+
+ If it was really you who made this request, you can click on the following link to
+ complete the verification of your email address:
+
+ Complete email verification
+
+
+ Please note that Element requires
+ Chrome,
+ Firefox or
+ Safari on the web,
+ or iOS or Android on mobile.
+
+ If you didn't make this request, you can safely disregard this email.
+
+ Thanks!
+
+ Element
+
+
+ About Element:
+
+ Break through - Element allows teams to communicate across a wide range of collaboration
+ apps. If some team members use Element while others use IRC, Slack or Gitter, Element will
+ allow these team members to seamlessly work together. Element offers the richest
+ network of communication bridges.
+
+ Own Your Own Data - No one should control your communication and data but you. Element
+ lets you run your own server, and provides users and teams with the most advanced
+ crypto ratchet technology available today for a decentralized secure Internet.
+
+ Open Source - Element is entirely open source: all the code is published on GitHub
+ (Apache License) for anyone to see and extend. This means teams can customize or
+ contribute to the code and everyone can benefit from the speed of community innovation.
+
+ Made on Matrix - Element is built on top of Matrix. Matrix is an open network for secure,
+ decentralized communication delivering a community of users, bridged networks,
+ integrated bots and applications plus full end-to-end encryption. To learn more about
+ Matrix visit https://matrix.org.
+
+ |
+ |
+
+
+
+
+
+--aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa--
\ No newline at end of file
diff --git a/setup.py b/setup.py
index 034a4704..92a2c70f 100644
--- a/setup.py
+++ b/setup.py
@@ -41,6 +41,7 @@ def read(fname):
description="Reference Matrix Identity Verification and Lookup Server",
python_requires=">=3.6",
install_requires=[
+ "jinja2>=3.0.0",
"signedjson==1.1.1",
"unpaddedbase64==1.1.0",
"Twisted>=18.4.0",
diff --git a/sydent/sydent.py b/sydent/sydent.py
index e7579ca2..0f27657a 100644
--- a/sydent/sydent.py
+++ b/sydent/sydent.py
@@ -23,6 +23,7 @@
from typing import Set
import twisted.internet.reactor
+from jinja2 import Environment, FileSystemLoader
from twisted.internet import address, task
from twisted.python import log
@@ -294,6 +295,10 @@ def __init__(
"email", "email.third_party_invite_domain_obfuscate_characters"
)
)
+ self.template_environment = Environment(
+ loader=FileSystemLoader(self.cfg.get("general", "templates.path")),
+ autoescape=True,
+ )
# See if a pepper already exists in the database
# Note: This MUST be run before we start serving requests, otherwise lookups for
@@ -472,7 +477,14 @@ def get_branded_template(self, brand, template_name, deprecated_template_name):
brand = self.cfg.get("general", "brand.default")
root_template_path = self.cfg.get("general", "templates.path")
- return os.path.join(root_template_path, brand, template_name)
+
+ # Grab jinja template if it exists
+ if os.path.exists(
+ os.path.join(root_template_path, brand, template_name + ".j2")
+ ):
+ return os.path.join(brand, template_name + ".j2")
+ else:
+ return os.path.join(root_template_path, brand, template_name)
class Validators:
diff --git a/sydent/util/emailutils.py b/sydent/util/emailutils.py
index e9de0ac6..6e532dc3 100644
--- a/sydent/util/emailutils.py
+++ b/sydent/util/emailutils.py
@@ -63,17 +63,23 @@ def sendEmail(
}
)
- allSubstitutions = {}
- for k, v in substitutions.items():
- allSubstitutions[k] = v
- allSubstitutions[k + "_forhtml"] = escape(v)
- allSubstitutions[k + "_forurl"] = urllib.parse.quote(v)
+ # use jinja for rendering if jinja templates are present
+ if templateFile.endswith(".j2"):
+ # We add randomize the multipart boundary to stop user input from
+ # conflicting with it.
+ substitutions["multipart_boundary"] = generateAlphanumericTokenOfLength(32)
+ template = sydent.template_environment.get_template(templateFile)
+ mailString = template.render(substitutions)
+ else:
+ allSubstitutions = {}
+ for k, v in substitutions.items():
+ allSubstitutions[k] = v
+ allSubstitutions[k + "_forhtml"] = escape(v)
+ allSubstitutions[k + "_forurl"] = urllib.parse.quote(v)
+ allSubstitutions["multipart_boundary"] = generateAlphanumericTokenOfLength(32)
+ with open(templateFile) as template_file:
+ mailString = template_file.read() % allSubstitutions
- # We add randomize the multipart boundary to stop user input from
- # conflicting with it.
- allSubstitutions["multipart_boundary"] = generateAlphanumericTokenOfLength(32)
-
- mailString = open(templateFile).read() % allSubstitutions
parsedFrom = email.utils.parseaddr(mailFrom)[1]
parsedTo = email.utils.parseaddr(mailTo)[1]
if parsedFrom == "" or parsedTo == "":
diff --git a/tests/test_jinja_templates.py b/tests/test_jinja_templates.py
new file mode 100644
index 00000000..06ef612b
--- /dev/null
+++ b/tests/test_jinja_templates.py
@@ -0,0 +1,224 @@
+# Copyright 2021 The Matrix.org Foundation C.I.C.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import os.path
+import urllib
+from unittest.mock import Mock, patch
+
+from twisted.trial import unittest
+
+from sydent.util.emailutils import sendEmail
+from tests.utils import make_sydent
+
+
+class TestTemplate(unittest.TestCase):
+ def setUp(self):
+ # Create a new sydent
+ config = {
+ "general": {
+ "templates.path": os.path.join(
+ os.path.dirname(os.path.dirname(__file__)), "res"
+ ),
+ },
+ }
+ self.sydent = make_sydent(test_config=config)
+
+ def test_jinja_vector_invite(self):
+ substitutions = {
+ "address": "foo@example.com",
+ "medium": "email",
+ "room_alias": "#somewhere:exmaple.org",
+ "room_avatar_url": "mxc://example.org/s0meM3dia",
+ "room_id": "!something:example.org",
+ "room_name": "Bob's Emporium of Messages",
+ "sender": "@bob:example.com",
+ "sender_avatar_url": "mxc://example.org/an0th3rM3dia",
+ "sender_display_name": "",
+ "bracketed_verified_sender": "Bob Smith",
+ "bracketed_room_name": "Bob's Emporium of Messages",
+ "to": "person@test.test",
+ "token": "a_token",
+ "ephemeral_private_key": "mystery_key",
+ "web_client_location": "https://app.element.io",
+ }
+
+ templateFile = self.sydent.get_branded_template(
+ "vector-im",
+ "invite_template.eml",
+ ("email", "email.invite_template"),
+ )
+
+ with patch("sydent.util.emailutils.smtplib") as smtplib:
+ sendEmail(self.sydent, templateFile, "test@test.com", substitutions)
+
+ smtp = smtplib.SMTP.return_value
+ email_contents = smtp.sendmail.call_args[0][2].decode("utf-8")
+
+ # test url input is encoded
+ self.assertIn(urllib.parse.quote("mxc://example.org/s0meM3dia"), email_contents)
+
+ # test html input is escaped
+ self.assertIn("Bob's Emporium of Messages", email_contents)
+
+ # test safe values are not escaped
+ self.assertIn("", email_contents)
+
+ # test our link is as expected
+ expected_url = (
+ "https://app.element.io/#/room/"
+ + urllib.parse.quote("!something:example.org")
+ + "?email="
+ + urllib.parse.quote("test@test.com")
+ + "&signurl=https%3A%2F%2Fvector.im%2F_matrix%2Fidentity%2Fapi%2Fv1%2Fsign-ed25519%3Ftoken%3D"
+ + urllib.parse.quote("a_token")
+ + "%26private_key%3D"
+ + urllib.parse.quote("mystery_key")
+ + "&room_name="
+ + urllib.parse.quote("Bob's Emporium of Messages")
+ + "&room_avatar_url="
+ + urllib.parse.quote("mxc://example.org/s0meM3dia")
+ + "&inviter_name="
+ + urllib.parse.quote("")
+ + "&guest_access_token=&guest_user_id="
+ )
+ text = email_contents.splitlines()
+ link = text[19]
+ self.assertEqual(link, expected_url)
+
+ def test_jinja_matrix_invite(self):
+ substitutions = {
+ "address": "foo@example.com",
+ "medium": "email",
+ "room_alias": "#somewhere:exmaple.org",
+ "room_avatar_url": "mxc://example.org/s0meM3dia",
+ "room_id": "!something:example.org",
+ "room_name": "Bob's Emporium of Messages",
+ "sender": "@bob:example.com",
+ "sender_avatar_url": "mxc://example.org/an0th3rM3dia",
+ "sender_display_name": "",
+ "bracketed_verified_sender": "Bob Smith",
+ "bracketed_room_name": "Bob's Emporium of Messages",
+ "to": "person@test.test",
+ "token": "a_token",
+ "ephemeral_private_key": "mystery_key",
+ "web_client_location": "https://matrix.org",
+ }
+
+ templateFile = self.sydent.get_branded_template(
+ "matrix-org",
+ "invite_template.eml",
+ ("email", "email.invite_template"),
+ )
+
+ with patch("sydent.util.emailutils.smtplib") as smtplib:
+ sendEmail(self.sydent, templateFile, "test@test.com", substitutions)
+
+ smtp = smtplib.SMTP.return_value
+ email_contents = smtp.sendmail.call_args[0][2].decode("utf-8")
+
+ # test url input is encoded
+ self.assertIn(urllib.parse.quote("mxc://example.org/s0meM3dia"), email_contents)
+
+ # test html input is escaped
+ self.assertIn("Bob's Emporium of Messages", email_contents)
+
+ # test safe values are not escaped
+ self.assertIn("", email_contents)
+
+ # test our link is as expected
+ expected_url = (
+ "https://matrix.org/#/room/"
+ + urllib.parse.quote("!something:example.org")
+ + "?email="
+ + urllib.parse.quote("test@test.com")
+ + "&signurl=https%3A%2F%2Fmatrix.org%2F_matrix%2Fidentity%2Fapi%2Fv1%2Fsign-ed25519%3Ftoken%3D"
+ + urllib.parse.quote("a_token")
+ + "%26private_key%3D"
+ + urllib.parse.quote("mystery_key")
+ + "&room_name="
+ + urllib.parse.quote("Bob's Emporium of Messages")
+ + "&room_avatar_url="
+ + urllib.parse.quote("mxc://example.org/s0meM3dia")
+ + "&inviter_name="
+ + urllib.parse.quote("")
+ + "&guest_access_token=&guest_user_id="
+ )
+ text = email_contents.splitlines()
+ link = text[22]
+ self.assertEqual(link, expected_url)
+
+ def test_jinja_matrix_verification(self):
+ substitutions = {
+ "address": "foo@example.com",
+ "medium": "email",
+ "to": "person@test.test",
+ "token": "<>",
+ "link": "https://link_test.com",
+ }
+
+ templateFile = self.sydent.get_branded_template(
+ "matrix-org",
+ "verification_template.eml",
+ ("email", "email.verification_template"),
+ )
+
+ with patch("sydent.util.emailutils.smtplib") as smtplib:
+ sendEmail(self.sydent, templateFile, "test@test.com", substitutions)
+
+ smtp = smtplib.SMTP.return_value
+ email_contents = smtp.sendmail.call_args[0][2].decode("utf-8")
+
+ # test html input is escaped
+ self.assertIn("<<token>>", email_contents)
+
+ # test safe values are not escaped
+ self.assertIn("<>", email_contents)
+
+ @patch(
+ "sydent.util.emailutils.generateAlphanumericTokenOfLength",
+ Mock(return_value="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"),
+ )
+ def test_jinja_vector_verification(self):
+ substitutions = {
+ "address": "foo@example.com",
+ "medium": "email",
+ "to": "person@test.test",
+ "link": "https://link_test.com",
+ }
+
+ templateFile = self.sydent.get_branded_template(
+ "vector-im",
+ "verification_template.eml",
+ ("email", "email.verification_template"),
+ )
+
+ with patch("sydent.util.emailutils.smtplib") as smtplib:
+ sendEmail(self.sydent, templateFile, "test@test.com", substitutions)
+
+ smtp = smtplib.SMTP.return_value
+ email_contents = smtp.sendmail.call_args[0][2].decode("utf-8")
+
+ path = os.path.join(
+ self.sydent.cfg.get("general", "templates.path"),
+ "vector_verification_sample.txt",
+ )
+
+ with open(path, "r") as file:
+ expected_text = file.read()
+
+ # remove the email headers as they are variable
+ email_contents = email_contents[email_contents.index("Hello") :]
+
+ # test all ouput is as expected
+ self.assertEqual(email_contents, expected_text)