diff --git a/changelog.d/10596.removal b/changelog.d/10596.removal
new file mode 100644
index 0000000000..e69f632db4
--- /dev/null
+++ b/changelog.d/10596.removal
@@ -0,0 +1 @@
+The `template_dir` configuration settings in the `sso`, `account_validity` and `email` sections of the configuration file are now deprecated in favour of the global `templates.custom_template_directory` setting. See the [upgrade notes](https://matrix-org.github.io/synapse/latest/upgrade.html) for more information.
diff --git a/docs/SUMMARY.md b/docs/SUMMARY.md
index 3d320a1c43..56e0141c2b 100644
--- a/docs/SUMMARY.md
+++ b/docs/SUMMARY.md
@@ -21,6 +21,7 @@
- [Homeserver Sample Config File](usage/configuration/homeserver_sample_config.md)
- [Logging Sample Config File](usage/configuration/logging_sample_config.md)
- [Structured Logging](structured_logging.md)
+ - [Templates](templates.md)
- [User Authentication](usage/configuration/user_authentication/README.md)
- [Single-Sign On]()
- [OpenID Connect](openid.md)
diff --git a/docs/sample_config.yaml b/docs/sample_config.yaml
index aeebcaf45f..3ec76d5abf 100644
--- a/docs/sample_config.yaml
+++ b/docs/sample_config.yaml
@@ -565,6 +565,19 @@ retention:
#
#next_link_domain_whitelist: ["matrix.org"]
+# Templates to use when generating email or HTML page contents.
+#
+templates:
+ # Directory in which Synapse will try to find template files to use to generate
+ # email or HTML page contents.
+ # If not set, or a file is not found within the template directory, a default
+ # template from within the Synapse package will be used.
+ #
+ # See https://matrix-org.github.io/synapse/latest/templates.html for more
+ # information about using custom templates.
+ #
+ #custom_template_directory: /path/to/custom/templates/
+
## TLS ##
@@ -1895,6 +1908,9 @@ cas_config:
# Additional settings to use with single-sign on systems such as OpenID Connect,
# SAML2 and CAS.
#
+# Server admins can configure custom templates for pages related to SSO. See
+# https://matrix-org.github.io/synapse/latest/templates.html for more information.
+#
sso:
# A list of client URLs which are whitelisted so that the user does not
# have to confirm giving access to their account to the URL. Any client
@@ -1927,169 +1943,6 @@ sso:
#
#update_profile_information: true
- # Directory in which Synapse will try to find the template files below.
- # If not set, or the files named below are not found within the template
- # directory, default templates from within the Synapse package will be used.
- #
- # Synapse will look for the following templates in this directory:
- #
- # * HTML page to prompt the user to choose an Identity Provider during
- # login: 'sso_login_idp_picker.html'.
- #
- # This is only used if multiple SSO Identity Providers are configured.
- #
- # When rendering, this template is given the following variables:
- # * redirect_url: the URL that the user will be redirected to after
- # login.
- #
- # * server_name: the homeserver's name.
- #
- # * providers: a list of available Identity Providers. Each element is
- # an object with the following attributes:
- #
- # * idp_id: unique identifier for the IdP
- # * idp_name: user-facing name for the IdP
- # * idp_icon: if specified in the IdP config, an MXC URI for an icon
- # for the IdP
- # * idp_brand: if specified in the IdP config, a textual identifier
- # for the brand of the IdP
- #
- # The rendered HTML page should contain a form which submits its results
- # back as a GET request, with the following query parameters:
- #
- # * redirectUrl: the client redirect URI (ie, the `redirect_url` passed
- # to the template)
- #
- # * idp: the 'idp_id' of the chosen IDP.
- #
- # * HTML page to prompt new users to enter a userid and confirm other
- # details: 'sso_auth_account_details.html'. This is only shown if the
- # SSO implementation (with any user_mapping_provider) does not return
- # a localpart.
- #
- # When rendering, this template is given the following variables:
- #
- # * server_name: the homeserver's name.
- #
- # * idp: details of the SSO Identity Provider that the user logged in
- # with: an object with the following attributes:
- #
- # * idp_id: unique identifier for the IdP
- # * idp_name: user-facing name for the IdP
- # * idp_icon: if specified in the IdP config, an MXC URI for an icon
- # for the IdP
- # * idp_brand: if specified in the IdP config, a textual identifier
- # for the brand of the IdP
- #
- # * user_attributes: an object containing details about the user that
- # we received from the IdP. May have the following attributes:
- #
- # * display_name: the user's display_name
- # * emails: a list of email addresses
- #
- # The template should render a form which submits the following fields:
- #
- # * username: the localpart of the user's chosen user id
- #
- # * HTML page allowing the user to consent to the server's terms and
- # conditions. This is only shown for new users, and only if
- # `user_consent.require_at_registration` is set.
- #
- # When rendering, this template is given the following variables:
- #
- # * server_name: the homeserver's name.
- #
- # * user_id: the user's matrix proposed ID.
- #
- # * user_profile.display_name: the user's proposed display name, if any.
- #
- # * consent_version: the version of the terms that the user will be
- # shown
- #
- # * terms_url: a link to the page showing the terms.
- #
- # The template should render a form which submits the following fields:
- #
- # * accepted_version: the version of the terms accepted by the user
- # (ie, 'consent_version' from the input variables).
- #
- # * HTML page for a confirmation step before redirecting back to the client
- # with the login token: 'sso_redirect_confirm.html'.
- #
- # When rendering, this template is given the following variables:
- #
- # * redirect_url: the URL the user is about to be redirected to.
- #
- # * display_url: the same as `redirect_url`, but with the query
- # parameters stripped. The intention is to have a
- # human-readable URL to show to users, not to use it as
- # the final address to redirect to.
- #
- # * server_name: the homeserver's name.
- #
- # * new_user: a boolean indicating whether this is the user's first time
- # logging in.
- #
- # * user_id: the user's matrix ID.
- #
- # * user_profile.avatar_url: an MXC URI for the user's avatar, if any.
- # None if the user has not set an avatar.
- #
- # * user_profile.display_name: the user's display name. None if the user
- # has not set a display name.
- #
- # * HTML page which notifies the user that they are authenticating to confirm
- # an operation on their account during the user interactive authentication
- # process: 'sso_auth_confirm.html'.
- #
- # When rendering, this template is given the following variables:
- # * redirect_url: the URL the user is about to be redirected to.
- #
- # * description: the operation which the user is being asked to confirm
- #
- # * idp: details of the Identity Provider that we will use to confirm
- # the user's identity: an object with the following attributes:
- #
- # * idp_id: unique identifier for the IdP
- # * idp_name: user-facing name for the IdP
- # * idp_icon: if specified in the IdP config, an MXC URI for an icon
- # for the IdP
- # * idp_brand: if specified in the IdP config, a textual identifier
- # for the brand of the IdP
- #
- # * HTML page shown after a successful user interactive authentication session:
- # 'sso_auth_success.html'.
- #
- # Note that this page must include the JavaScript which notifies of a successful authentication
- # (see https://matrix.org/docs/spec/client_server/r0.6.0#fallback).
- #
- # This template has no additional variables.
- #
- # * HTML page shown after a user-interactive authentication session which
- # does not map correctly onto the expected user: 'sso_auth_bad_user.html'.
- #
- # When rendering, this template is given the following variables:
- # * server_name: the homeserver's name.
- # * user_id_to_verify: the MXID of the user that we are trying to
- # validate.
- #
- # * HTML page shown during single sign-on if a deactivated user (according to Synapse's database)
- # attempts to login: 'sso_account_deactivated.html'.
- #
- # This template has no additional variables.
- #
- # * HTML page to display to users if something goes wrong during the
- # OpenID Connect authentication process: 'sso_error.html'.
- #
- # When rendering, this template is given two variables:
- # * error: the technical name of the error
- # * error_description: a human-readable message for the error
- #
- # You can see the default templates at:
- # https://github.com/matrix-org/synapse/tree/master/synapse/res/templates
- #
- #template_dir: "res/templates"
-
# JSON web token integration. The following settings can be used to make
# Synapse JSON web tokens for authentication, instead of its internal
@@ -2220,6 +2073,9 @@ ui_auth:
# Configuration for sending emails from Synapse.
#
+# Server admins can configure custom templates for email content. See
+# https://matrix-org.github.io/synapse/latest/templates.html for more information.
+#
email:
# The hostname of the outgoing SMTP server to use. Defaults to 'localhost'.
#
@@ -2296,49 +2152,6 @@ email:
#
#invite_client_location: https://app.element.io
- # Directory in which Synapse will try to find the template files below.
- # If not set, or the files named below are not found within the template
- # directory, default templates from within the Synapse package will be used.
- #
- # Synapse will look for the following templates in this directory:
- #
- # * The contents of email notifications of missed events: 'notif_mail.html' and
- # 'notif_mail.txt'.
- #
- # * The contents of account expiry notice emails: 'notice_expiry.html' and
- # 'notice_expiry.txt'.
- #
- # * The contents of password reset emails sent by the homeserver:
- # 'password_reset.html' and 'password_reset.txt'
- #
- # * An HTML page that a user will see when they follow the link in the password
- # reset email. The user will be asked to confirm the action before their
- # password is reset: 'password_reset_confirmation.html'
- #
- # * HTML pages for success and failure that a user will see when they confirm
- # the password reset flow using the page above: 'password_reset_success.html'
- # and 'password_reset_failure.html'
- #
- # * The contents of address verification emails sent during registration:
- # 'registration.html' and 'registration.txt'
- #
- # * HTML pages for success and failure that a user will see when they follow
- # the link in an address verification email sent during registration:
- # 'registration_success.html' and 'registration_failure.html'
- #
- # * The contents of address verification emails sent when an address is added
- # to a Matrix account: 'add_threepid.html' and 'add_threepid.txt'
- #
- # * HTML pages for success and failure that a user will see when they follow
- # the link in an address verification email sent when an address is added
- # to a Matrix account: 'add_threepid_success.html' and
- # 'add_threepid_failure.html'
- #
- # You can see the default templates at:
- # https://github.com/matrix-org/synapse/tree/master/synapse/res/templates
- #
- #template_dir: "res/templates"
-
# Subjects to use when sending emails from Synapse.
#
# The placeholder '%(app)s' will be replaced with the value of the 'app_name'
diff --git a/docs/templates.md b/docs/templates.md
new file mode 100644
index 0000000000..a240f58b54
--- /dev/null
+++ b/docs/templates.md
@@ -0,0 +1,239 @@
+# Templates
+
+Synapse uses parametrised templates to generate the content of emails it sends and
+webpages it shows to users.
+
+By default, Synapse will use the templates listed [here](https://github.com/matrix-org/synapse/tree/master/synapse/res/templates).
+Server admins can configure an additional directory for Synapse to look for templates
+in, allowing them to specify custom templates:
+
+```yaml
+templates:
+ custom_templates_directory: /path/to/custom/templates/
+```
+
+If this setting is not set, or the files named below are not found within the directory,
+default templates from within the Synapse package will be used.
+
+Templates that are given variables when being rendered are rendered using [Jinja 2](https://jinja.palletsprojects.com/en/2.11.x/).
+Templates rendered by Jinja 2 can also access two functions on top of the functions
+already available as part of Jinja 2:
+
+```python
+format_ts(value: int, format: str) -> str
+```
+
+Formats a timestamp in milliseconds.
+
+Example: `reason.last_sent_ts|format_ts("%c")`
+
+```python
+mxc_to_http(value: str, width: int, height: int, resize_method: str = "crop") -> str
+```
+
+Turns a `mxc://` URL for media content into an HTTP(S) one using the homeserver's
+`public_baseurl` configuration setting as the URL's base.
+
+Example: `message.sender_avatar_url|mxc_to_http(32,32)`
+
+
+## Email templates
+
+Below are the templates Synapse will look for when generating the content of an email:
+
+* `notif_mail.html` and `notif_mail.txt`: The contents of email notifications of missed
+ events.
+ When rendering, this template is given the following variables:
+ * `user_display_name`: the display name for the user receiving the notification
+ * `unsubscribe_link`: the link users can click to unsubscribe from email notifications
+ * `summary_text`: a summary of the notification(s). The text used can be customised
+ by configuring the various settings in the `email.subjects` section of the
+ configuration file.
+ * `rooms`: a list of rooms containing events to include in the email. Each element is
+ an object with the following attributes:
+ * `title`: a human-readable name for the room
+ * `hash`: a hash of the ID of the room
+ * `invite`: a boolean, which is `True` if the room is an invite the user hasn't
+ accepted yet, `False` otherwise
+ * `notifs`: a list of events, or an empty list if `invite` is `True`. Each element
+ is an object with the following attributes:
+ * `link`: a `matrix.to` link to the event
+ * `ts`: the time in milliseconds at which the event was received
+ * `messages`: a list of messages containing one message before the event, the
+ message in the event, and one message after the event. Each element is an
+ object with the following attributes:
+ * `event_type`: the type of the event
+ * `is_historical`: a boolean, which is `False` if the message is the one
+ that triggered the notification, `True` otherwise
+ * `id`: the ID of the event
+ * `ts`: the time in milliseconds at which the event was sent
+ * `sender_name`: the display name for the event's sender
+ * `sender_avatar_url`: the avatar URL (as a `mxc://` URL) for the event's
+ sender
+ * `sender_hash`: a hash of the user ID of the sender
+ * `link`: a `matrix.to` link to the room
+ * `reason`: information on the event that triggered the email to be sent. It's an
+ object with the following attributes:
+ * `room_id`: the ID of the room the event was sent in
+ * `room_name`: a human-readable name for the room the event was sent in
+ * `now`: the current time in milliseconds
+ * `received_at`: the time in milliseconds at which the event was received
+ * `delay_before_mail_ms`: the amount of time in milliseconds Synapse always waits
+ before ever emailing about a notification (to give the user a chance to respond
+ to other push or notice the window)
+ * `last_sent_ts`: the time in milliseconds at which a notification was last sent
+ for an event in this room
+ * `throttle_ms`: the minimum amount of time in milliseconds between two
+ notifications can be sent for this room
+* `password_reset.html` and `password_reset.txt`: The contents of password reset emails
+ sent by the homeserver.
+ When rendering, these templates are given a `link` variable which contains the link the
+ user must click in order to reset their password.
+* `registration.html` and `registration.txt`: The contents of address verification emails
+ sent during registration.
+ When rendering, these templates are given a `link` variable which contains the link the
+ user must click in order to validate their email address.
+* `add_threepid.html` and `add_threepid.txt`: The contents of address verification emails
+ sent when an address is added to a Matrix account.
+ When rendering, these templates are given a `link` variable which contains the link the
+ user must click in order to validate their email address.
+
+
+## HTML page templates for registration and password reset
+
+Below are the templates Synapse will look for when generating pages related to
+registration and password reset:
+
+* `password_reset_confirmation.html`: An HTML page that a user will see when they follow
+ the link in the password reset email. The user will be asked to confirm the action
+ before their password is reset.
+ When rendering, this template is given the following variables:
+ * `sid`: the session ID for the password reset
+ * `token`: the token for the password reset
+ * `client_secret`: the client secret for the password reset
+* `password_reset_success.html` and `password_reset_failure.html`: HTML pages for success
+ and failure that a user will see when they confirm the password reset flow using the
+ page above.
+ When rendering, `password_reset_success.html` is given no variable, and
+ `password_reset_failure.html` is given a `failure_reason`, which contains the reason
+ for the password reset failure.
+* `registration_success.html` and `registration_failure.html`: HTML pages for success and
+ failure that a user will see when they follow the link in an address verification email
+ sent during registration.
+ When rendering, `registration_success.html` is given no variable, and
+ `registration_failure.html` is given a `failure_reason`, which contains the reason
+ for the registration failure.
+* `add_threepid_success.html` and `add_threepid_failure.html`: HTML pages for success and
+ failure that a user will see when they follow the link in an address verification email
+ sent when an address is added to a Matrix account.
+ When rendering, `add_threepid_success.html` is given no variable, and
+ `add_threepid_failure.html` is given a `failure_reason`, which contains the reason
+ for the registration failure.
+
+
+## HTML page templates for Single Sign-On (SSO)
+
+Below are the templates Synapse will look for when generating pages related to SSO:
+
+* `sso_login_idp_picker.html`: HTML page to prompt the user to choose an
+ Identity Provider during login.
+ This is only used if multiple SSO Identity Providers are configured.
+ When rendering, this template is given the following variables:
+ * `redirect_url`: the URL that the user will be redirected to after
+ login.
+ * `server_name`: the homeserver's name.
+ * `providers`: a list of available Identity Providers. Each element is
+ an object with the following attributes:
+ * `idp_id`: unique identifier for the IdP
+ * `idp_name`: user-facing name for the IdP
+ * `idp_icon`: if specified in the IdP config, an MXC URI for an icon
+ for the IdP
+ * `idp_brand`: if specified in the IdP config, a textual identifier
+ for the brand of the IdP
+ The rendered HTML page should contain a form which submits its results
+ back as a GET request, with the following query parameters:
+ * `redirectUrl`: the client redirect URI (ie, the `redirect_url` passed
+ to the template)
+ * `idp`: the 'idp_id' of the chosen IDP.
+* `sso_auth_account_details.html`: HTML page to prompt new users to enter a
+ userid and confirm other details. This is only shown if the
+ SSO implementation (with any `user_mapping_provider`) does not return
+ a localpart.
+ When rendering, this template is given the following variables:
+ * `server_name`: the homeserver's name.
+ * `idp`: details of the SSO Identity Provider that the user logged in
+ with: an object with the following attributes:
+ * `idp_id`: unique identifier for the IdP
+ * `idp_name`: user-facing name for the IdP
+ * `idp_icon`: if specified in the IdP config, an MXC URI for an icon
+ for the IdP
+ * `idp_brand`: if specified in the IdP config, a textual identifier
+ for the brand of the IdP
+ * `user_attributes`: an object containing details about the user that
+ we received from the IdP. May have the following attributes:
+ * display_name: the user's display_name
+ * emails: a list of email addresses
+ The template should render a form which submits the following fields:
+ * `username`: the localpart of the user's chosen user id
+* `sso_new_user_consent.html`: HTML page allowing the user to consent to the
+ server's terms and conditions. This is only shown for new users, and only if
+ `user_consent.require_at_registration` is set.
+ When rendering, this template is given the following variables:
+ * `server_name`: the homeserver's name.
+ * `user_id`: the user's matrix proposed ID.
+ * `user_profile.display_name`: the user's proposed display name, if any.
+ * consent_version: the version of the terms that the user will be
+ shown
+ * `terms_url`: a link to the page showing the terms.
+ The template should render a form which submits the following fields:
+ * `accepted_version`: the version of the terms accepted by the user
+ (ie, 'consent_version' from the input variables).
+* `sso_redirect_confirm.html`: HTML page for a confirmation step before redirecting back
+ to the client with the login token.
+ When rendering, this template is given the following variables:
+ * `redirect_url`: the URL the user is about to be redirected to.
+ * `display_url`: the same as `redirect_url`, but with the query
+ parameters stripped. The intention is to have a
+ human-readable URL to show to users, not to use it as
+ the final address to redirect to.
+ * `server_name`: the homeserver's name.
+ * `new_user`: a boolean indicating whether this is the user's first time
+ logging in.
+ * `user_id`: the user's matrix ID.
+ * `user_profile.avatar_url`: an MXC URI for the user's avatar, if any.
+ `None` if the user has not set an avatar.
+ * `user_profile.display_name`: the user's display name. `None` if the user
+ has not set a display name.
+* `sso_auth_confirm.html`: HTML page which notifies the user that they are authenticating
+ to confirm an operation on their account during the user interactive authentication
+ process.
+ When rendering, this template is given the following variables:
+ * `redirect_url`: the URL the user is about to be redirected to.
+ * `description`: the operation which the user is being asked to confirm
+ * `idp`: details of the Identity Provider that we will use to confirm
+ the user's identity: an object with the following attributes:
+ * `idp_id`: unique identifier for the IdP
+ * `idp_name`: user-facing name for the IdP
+ * `idp_icon`: if specified in the IdP config, an MXC URI for an icon
+ for the IdP
+ * `idp_brand`: if specified in the IdP config, a textual identifier
+ for the brand of the IdP
+* `sso_auth_success.html`: HTML page shown after a successful user interactive
+ authentication session.
+ Note that this page must include the JavaScript which notifies of a successful
+ authentication (see https://matrix.org/docs/spec/client_server/r0.6.0#fallback).
+ This template has no additional variables.
+* `sso_auth_bad_user.html`: HTML page shown after a user-interactive authentication
+ session which does not map correctly onto the expected user.
+ When rendering, this template is given the following variables:
+ * `server_name`: the homeserver's name.
+ * `user_id_to_verify`: the MXID of the user that we are trying to
+ validate.
+* `sso_account_deactivated.html`: HTML page shown during single sign-on if a deactivated
+ user (according to Synapse's database) attempts to login.
+ This template has no additional variables.
+* `sso_error.html`: HTML page to display to users if something goes wrong during the
+ OpenID Connect authentication process.
+ When rendering, this template is given two variables:
+ * `error`: the technical name of the error
+ * `error_description`: a human-readable message for the error
diff --git a/docs/upgrade.md b/docs/upgrade.md
index 8831c9d6cf..1c459d8e2b 100644
--- a/docs/upgrade.md
+++ b/docs/upgrade.md
@@ -112,6 +112,17 @@ environment variable.
See [using a forward proxy with Synapse documentation](setup/forward_proxy.md) for
details.
+## Deprecation of `template_dir`
+
+The `template_dir` settings in the `sso`, `account_validity` and `email` sections of the
+configuration file are now deprecated. Server admins should use the new
+`templates.custom_template_directory` setting in the configuration file and use one single
+custom template directory for all aforementioned features. Template file names remain
+unchanged. See [the related documentation](https://matrix-org.github.io/synapse/latest/templates.html)
+for more information and examples.
+
+We plan to remove support for these settings in October 2021.
+
# Upgrading to v1.39.0
diff --git a/synapse/config/account_validity.py b/synapse/config/account_validity.py
index 9acce5996e..52e63ab1f6 100644
--- a/synapse/config/account_validity.py
+++ b/synapse/config/account_validity.py
@@ -78,6 +78,11 @@ class AccountValidityConfig(Config):
)
# Read and store template content
+ custom_template_directories = (
+ self.root.server.custom_template_directory,
+ account_validity_template_dir,
+ )
+
(
self.account_validity_account_renewed_template,
self.account_validity_account_previously_renewed_template,
@@ -88,5 +93,5 @@ class AccountValidityConfig(Config):
"account_previously_renewed.html",
invalid_token_template_filename,
],
- (td for td in (account_validity_template_dir,) if td),
+ (td for td in custom_template_directories if td),
)
diff --git a/synapse/config/emailconfig.py b/synapse/config/emailconfig.py
index fc74b4a8b9..4477419196 100644
--- a/synapse/config/emailconfig.py
+++ b/synapse/config/emailconfig.py
@@ -258,7 +258,12 @@ class EmailConfig(Config):
add_threepid_template_success_html,
],
(
- td for td in (template_dir,) if td
+ td
+ for td in (
+ self.root.server.custom_template_directory,
+ template_dir,
+ )
+ if td
), # Filter out template_dir if not provided
)
@@ -299,7 +304,14 @@ class EmailConfig(Config):
self.email_notif_template_text,
) = self.read_templates(
[notif_template_html, notif_template_text],
- (td for td in (template_dir,) if td),
+ (
+ td
+ for td in (
+ self.root.server.custom_template_directory,
+ template_dir,
+ )
+ if td
+ ), # Filter out template_dir if not provided
)
self.email_notif_for_new_users = email_config.get(
@@ -322,7 +334,14 @@ class EmailConfig(Config):
self.account_validity_template_text,
) = self.read_templates(
[expiry_template_html, expiry_template_text],
- (td for td in (template_dir,) if td),
+ (
+ td
+ for td in (
+ self.root.server.custom_template_directory,
+ template_dir,
+ )
+ if td
+ ), # Filter out template_dir if not provided
)
subjects_config = email_config.get("subjects", {})
@@ -354,6 +373,9 @@ class EmailConfig(Config):
"""\
# Configuration for sending emails from Synapse.
#
+ # Server admins can configure custom templates for email content. See
+ # https://matrix-org.github.io/synapse/latest/templates.html for more information.
+ #
email:
# The hostname of the outgoing SMTP server to use. Defaults to 'localhost'.
#
@@ -430,49 +452,6 @@ class EmailConfig(Config):
#
#invite_client_location: https://app.element.io
- # Directory in which Synapse will try to find the template files below.
- # If not set, or the files named below are not found within the template
- # directory, default templates from within the Synapse package will be used.
- #
- # Synapse will look for the following templates in this directory:
- #
- # * The contents of email notifications of missed events: 'notif_mail.html' and
- # 'notif_mail.txt'.
- #
- # * The contents of account expiry notice emails: 'notice_expiry.html' and
- # 'notice_expiry.txt'.
- #
- # * The contents of password reset emails sent by the homeserver:
- # 'password_reset.html' and 'password_reset.txt'
- #
- # * An HTML page that a user will see when they follow the link in the password
- # reset email. The user will be asked to confirm the action before their
- # password is reset: 'password_reset_confirmation.html'
- #
- # * HTML pages for success and failure that a user will see when they confirm
- # the password reset flow using the page above: 'password_reset_success.html'
- # and 'password_reset_failure.html'
- #
- # * The contents of address verification emails sent during registration:
- # 'registration.html' and 'registration.txt'
- #
- # * HTML pages for success and failure that a user will see when they follow
- # the link in an address verification email sent during registration:
- # 'registration_success.html' and 'registration_failure.html'
- #
- # * The contents of address verification emails sent when an address is added
- # to a Matrix account: 'add_threepid.html' and 'add_threepid.txt'
- #
- # * HTML pages for success and failure that a user will see when they follow
- # the link in an address verification email sent when an address is added
- # to a Matrix account: 'add_threepid_success.html' and
- # 'add_threepid_failure.html'
- #
- # You can see the default templates at:
- # https://github.com/matrix-org/synapse/tree/master/synapse/res/templates
- #
- #template_dir: "res/templates"
-
# Subjects to use when sending emails from Synapse.
#
# The placeholder '%%(app)s' will be replaced with the value of the 'app_name'
diff --git a/synapse/config/server.py b/synapse/config/server.py
index 187b4301a0..8494795919 100644
--- a/synapse/config/server.py
+++ b/synapse/config/server.py
@@ -710,6 +710,18 @@ class ServerConfig(Config):
# Turn the list into a set to improve lookup speed.
self.next_link_domain_whitelist = set(next_link_domain_whitelist)
+ templates_config = config.get("templates") or {}
+ if not isinstance(templates_config, dict):
+ raise ConfigError("The 'templates' section must be a dictionary")
+
+ self.custom_template_directory = templates_config.get(
+ "custom_template_directory"
+ )
+ if self.custom_template_directory is not None and not isinstance(
+ self.custom_template_directory, str
+ ):
+ raise ConfigError("'custom_template_directory' must be a string")
+
def has_tls_listener(self) -> bool:
return any(listener.tls for listener in self.listeners)
@@ -1284,6 +1296,19 @@ class ServerConfig(Config):
# all domains.
#
#next_link_domain_whitelist: ["matrix.org"]
+
+ # Templates to use when generating email or HTML page contents.
+ #
+ templates:
+ # Directory in which Synapse will try to find template files to use to generate
+ # email or HTML page contents.
+ # If not set, or a file is not found within the template directory, a default
+ # template from within the Synapse package will be used.
+ #
+ # See https://matrix-org.github.io/synapse/latest/templates.html for more
+ # information about using custom templates.
+ #
+ #custom_template_directory: /path/to/custom/templates/
"""
% locals()
)
diff --git a/synapse/config/sso.py b/synapse/config/sso.py
index 4b590e0535..fe1177ab81 100644
--- a/synapse/config/sso.py
+++ b/synapse/config/sso.py
@@ -45,6 +45,11 @@ class SSOConfig(Config):
self.sso_template_dir = sso_config.get("template_dir")
# Read templates from disk
+ custom_template_directories = (
+ self.root.server.custom_template_directory,
+ self.sso_template_dir,
+ )
+
(
self.sso_login_idp_picker_template,
self.sso_redirect_confirm_template,
@@ -63,7 +68,7 @@ class SSOConfig(Config):
"sso_auth_success.html",
"sso_auth_bad_user.html",
],
- (td for td in (self.sso_template_dir,) if td),
+ (td for td in custom_template_directories if td),
)
# These templates have no placeholders, so render them here
@@ -94,6 +99,9 @@ class SSOConfig(Config):
# Additional settings to use with single-sign on systems such as OpenID Connect,
# SAML2 and CAS.
#
+ # Server admins can configure custom templates for pages related to SSO. See
+ # https://matrix-org.github.io/synapse/latest/templates.html for more information.
+ #
sso:
# A list of client URLs which are whitelisted so that the user does not
# have to confirm giving access to their account to the URL. Any client
@@ -125,167 +133,4 @@ class SSOConfig(Config):
# information when first signing in. Defaults to false.
#
#update_profile_information: true
-
- # Directory in which Synapse will try to find the template files below.
- # If not set, or the files named below are not found within the template
- # directory, default templates from within the Synapse package will be used.
- #
- # Synapse will look for the following templates in this directory:
- #
- # * HTML page to prompt the user to choose an Identity Provider during
- # login: 'sso_login_idp_picker.html'.
- #
- # This is only used if multiple SSO Identity Providers are configured.
- #
- # When rendering, this template is given the following variables:
- # * redirect_url: the URL that the user will be redirected to after
- # login.
- #
- # * server_name: the homeserver's name.
- #
- # * providers: a list of available Identity Providers. Each element is
- # an object with the following attributes:
- #
- # * idp_id: unique identifier for the IdP
- # * idp_name: user-facing name for the IdP
- # * idp_icon: if specified in the IdP config, an MXC URI for an icon
- # for the IdP
- # * idp_brand: if specified in the IdP config, a textual identifier
- # for the brand of the IdP
- #
- # The rendered HTML page should contain a form which submits its results
- # back as a GET request, with the following query parameters:
- #
- # * redirectUrl: the client redirect URI (ie, the `redirect_url` passed
- # to the template)
- #
- # * idp: the 'idp_id' of the chosen IDP.
- #
- # * HTML page to prompt new users to enter a userid and confirm other
- # details: 'sso_auth_account_details.html'. This is only shown if the
- # SSO implementation (with any user_mapping_provider) does not return
- # a localpart.
- #
- # When rendering, this template is given the following variables:
- #
- # * server_name: the homeserver's name.
- #
- # * idp: details of the SSO Identity Provider that the user logged in
- # with: an object with the following attributes:
- #
- # * idp_id: unique identifier for the IdP
- # * idp_name: user-facing name for the IdP
- # * idp_icon: if specified in the IdP config, an MXC URI for an icon
- # for the IdP
- # * idp_brand: if specified in the IdP config, a textual identifier
- # for the brand of the IdP
- #
- # * user_attributes: an object containing details about the user that
- # we received from the IdP. May have the following attributes:
- #
- # * display_name: the user's display_name
- # * emails: a list of email addresses
- #
- # The template should render a form which submits the following fields:
- #
- # * username: the localpart of the user's chosen user id
- #
- # * HTML page allowing the user to consent to the server's terms and
- # conditions. This is only shown for new users, and only if
- # `user_consent.require_at_registration` is set.
- #
- # When rendering, this template is given the following variables:
- #
- # * server_name: the homeserver's name.
- #
- # * user_id: the user's matrix proposed ID.
- #
- # * user_profile.display_name: the user's proposed display name, if any.
- #
- # * consent_version: the version of the terms that the user will be
- # shown
- #
- # * terms_url: a link to the page showing the terms.
- #
- # The template should render a form which submits the following fields:
- #
- # * accepted_version: the version of the terms accepted by the user
- # (ie, 'consent_version' from the input variables).
- #
- # * HTML page for a confirmation step before redirecting back to the client
- # with the login token: 'sso_redirect_confirm.html'.
- #
- # When rendering, this template is given the following variables:
- #
- # * redirect_url: the URL the user is about to be redirected to.
- #
- # * display_url: the same as `redirect_url`, but with the query
- # parameters stripped. The intention is to have a
- # human-readable URL to show to users, not to use it as
- # the final address to redirect to.
- #
- # * server_name: the homeserver's name.
- #
- # * new_user: a boolean indicating whether this is the user's first time
- # logging in.
- #
- # * user_id: the user's matrix ID.
- #
- # * user_profile.avatar_url: an MXC URI for the user's avatar, if any.
- # None if the user has not set an avatar.
- #
- # * user_profile.display_name: the user's display name. None if the user
- # has not set a display name.
- #
- # * HTML page which notifies the user that they are authenticating to confirm
- # an operation on their account during the user interactive authentication
- # process: 'sso_auth_confirm.html'.
- #
- # When rendering, this template is given the following variables:
- # * redirect_url: the URL the user is about to be redirected to.
- #
- # * description: the operation which the user is being asked to confirm
- #
- # * idp: details of the Identity Provider that we will use to confirm
- # the user's identity: an object with the following attributes:
- #
- # * idp_id: unique identifier for the IdP
- # * idp_name: user-facing name for the IdP
- # * idp_icon: if specified in the IdP config, an MXC URI for an icon
- # for the IdP
- # * idp_brand: if specified in the IdP config, a textual identifier
- # for the brand of the IdP
- #
- # * HTML page shown after a successful user interactive authentication session:
- # 'sso_auth_success.html'.
- #
- # Note that this page must include the JavaScript which notifies of a successful authentication
- # (see https://matrix.org/docs/spec/client_server/r0.6.0#fallback).
- #
- # This template has no additional variables.
- #
- # * HTML page shown after a user-interactive authentication session which
- # does not map correctly onto the expected user: 'sso_auth_bad_user.html'.
- #
- # When rendering, this template is given the following variables:
- # * server_name: the homeserver's name.
- # * user_id_to_verify: the MXID of the user that we are trying to
- # validate.
- #
- # * HTML page shown during single sign-on if a deactivated user (according to Synapse's database)
- # attempts to login: 'sso_account_deactivated.html'.
- #
- # This template has no additional variables.
- #
- # * HTML page to display to users if something goes wrong during the
- # OpenID Connect authentication process: 'sso_error.html'.
- #
- # When rendering, this template is given two variables:
- # * error: the technical name of the error
- # * error_description: a human-readable message for the error
- #
- # You can see the default templates at:
- # https://github.com/matrix-org/synapse/tree/master/synapse/res/templates
- #
- #template_dir: "res/templates"
"""
diff --git a/synapse/module_api/__init__.py b/synapse/module_api/__init__.py
index 82725853bc..2f99d31c42 100644
--- a/synapse/module_api/__init__.py
+++ b/synapse/module_api/__init__.py
@@ -91,6 +91,7 @@ class ModuleApi:
self._state = hs.get_state_handler()
self._clock: Clock = hs.get_clock()
self._send_email_handler = hs.get_send_email_handler()
+ self.custom_template_dir = hs.config.server.custom_template_directory
try:
app_name = self._hs.config.email_app_name
@@ -679,7 +680,7 @@ class ModuleApi:
"""
return self._hs.config.read_templates(
filenames,
- (td for td in (custom_template_directory,) if td),
+ (td for td in (self.custom_template_dir, custom_template_directory) if td),
)
diff --git a/synapse/rest/synapse/client/new_user_consent.py b/synapse/rest/synapse/client/new_user_consent.py
index 488b97b32e..fc62a09b7f 100644
--- a/synapse/rest/synapse/client/new_user_consent.py
+++ b/synapse/rest/synapse/client/new_user_consent.py
@@ -46,6 +46,8 @@ class NewUserConsentResource(DirectServeHtmlResource):
self._consent_version = hs.config.consent.user_consent_version
def template_search_dirs():
+ if hs.config.server.custom_template_directory:
+ yield hs.config.server.custom_template_directory
if hs.config.sso.sso_template_dir:
yield hs.config.sso.sso_template_dir
yield hs.config.sso.default_template_dir
diff --git a/synapse/rest/synapse/client/pick_username.py b/synapse/rest/synapse/client/pick_username.py
index ab24ec0a8e..c15b83c387 100644
--- a/synapse/rest/synapse/client/pick_username.py
+++ b/synapse/rest/synapse/client/pick_username.py
@@ -74,6 +74,8 @@ class AccountDetailsResource(DirectServeHtmlResource):
self._sso_handler = hs.get_sso_handler()
def template_search_dirs():
+ if hs.config.server.custom_template_directory:
+ yield hs.config.server.custom_template_directory
if hs.config.sso.sso_template_dir:
yield hs.config.sso.sso_template_dir
yield hs.config.sso.default_template_dir
|