diff --git a/synapse/config/experimental.py b/synapse/config/experimental.py
index dbaeb10918..e4719d19b8 100644
--- a/synapse/config/experimental.py
+++ b/synapse/config/experimental.py
@@ -24,8 +24,6 @@ class ExperimentalConfig(Config):
def read_config(self, config: JsonDict, **kwargs):
experimental = config.get("experimental_features") or {}
- # Whether to enable experimental MSC1849 (aka relations) support
- self.msc1849_enabled = config.get("experimental_msc1849_support_enabled", True)
# MSC3440 (thread relation)
self.msc3440_enabled: bool = experimental.get("msc3440_enabled", False)
@@ -54,3 +52,10 @@ class ExperimentalConfig(Config):
self.msc3202_device_masquerading_enabled: bool = experimental.get(
"msc3202_device_masquerading", False
)
+
+ # MSC2409 (this setting only relates to optionally sending to-device messages).
+ # Presence, typing and read receipt EDUs are already sent to application services that
+ # have opted in to receive them. If enabled, this adds to-device messages to that list.
+ self.msc2409_to_device_messages_enabled: bool = experimental.get(
+ "msc2409_to_device_messages_enabled", False
+ )
diff --git a/synapse/config/modules.py b/synapse/config/modules.py
index 85fb05890d..2ef02b8f55 100644
--- a/synapse/config/modules.py
+++ b/synapse/config/modules.py
@@ -41,9 +41,9 @@ class ModulesConfig(Config):
# documentation on how to configure or create custom modules for Synapse.
#
modules:
- # - module: my_super_module.MySuperClass
- # config:
- # do_thing: true
- # - module: my_other_super_module.SomeClass
- # config: {}
+ #- module: my_super_module.MySuperClass
+ # config:
+ # do_thing: true
+ #- module: my_other_super_module.SomeClass
+ # config: {}
"""
diff --git a/synapse/config/ratelimiting.py b/synapse/config/ratelimiting.py
index 36636ab07e..e9ccf1bd62 100644
--- a/synapse/config/ratelimiting.py
+++ b/synapse/config/ratelimiting.py
@@ -134,6 +134,14 @@ class RatelimitConfig(Config):
defaults={"per_second": 0.003, "burst_count": 5},
)
+ self.rc_third_party_invite = RateLimitConfig(
+ config.get("rc_third_party_invite", {}),
+ defaults={
+ "per_second": self.rc_message.per_second,
+ "burst_count": self.rc_message.burst_count,
+ },
+ )
+
def generate_config_section(self, **kwargs):
return """\
## Ratelimiting ##
@@ -168,6 +176,9 @@ class RatelimitConfig(Config):
# - one for ratelimiting how often a user or IP can attempt to validate a 3PID.
# - two for ratelimiting how often invites can be sent in a room or to a
# specific user.
+ # - one for ratelimiting 3PID invites (i.e. invites sent to a third-party ID
+ # such as an email address or a phone number) based on the account that's
+ # sending the invite.
#
# The defaults are as shown below.
#
@@ -217,6 +228,10 @@ class RatelimitConfig(Config):
# per_user:
# per_second: 0.003
# burst_count: 5
+ #
+ #rc_third_party_invite:
+ # per_second: 0.2
+ # burst_count: 10
# Ratelimiting settings for incoming federation
#
diff --git a/synapse/config/registration.py b/synapse/config/registration.py
index 7a059c6dec..ea9b50fe97 100644
--- a/synapse/config/registration.py
+++ b/synapse/config/registration.py
@@ -190,6 +190,8 @@ class RegistrationConfig(Config):
# The success template used during fallback auth.
self.fallback_success_template = self.read_template("auth_success.html")
+ self.inhibit_user_in_use_error = config.get("inhibit_user_in_use_error", False)
+
def generate_config_section(self, generate_secrets=False, **kwargs):
if generate_secrets:
registration_shared_secret = 'registration_shared_secret: "%s"' % (
@@ -446,6 +448,16 @@ class RegistrationConfig(Config):
# Defaults to true.
#
#auto_join_rooms_for_guests: false
+
+ # Whether to inhibit errors raised when registering a new account if the user ID
+ # already exists. If turned on, that requests to /register/available will always
+ # show a user ID as available, and Synapse won't raise an error when starting
+ # a registration with a user ID that already exists. However, Synapse will still
+ # raise an error if the registration completes and the username conflicts.
+ #
+ # Defaults to false.
+ #
+ #inhibit_user_in_use_error: true
"""
% locals()
)
diff --git a/synapse/config/server.py b/synapse/config/server.py
index f200d0c1f1..7bc9624546 100644
--- a/synapse/config/server.py
+++ b/synapse/config/server.py
@@ -179,7 +179,6 @@ KNOWN_RESOURCES = {
"openid",
"replication",
"static",
- "webclient",
}
@@ -489,6 +488,19 @@ class ServerConfig(Config):
# events with profile information that differ from the target's global profile.
self.allow_per_room_profiles = config.get("allow_per_room_profiles", True)
+ # The maximum size an avatar can have, in bytes.
+ self.max_avatar_size = config.get("max_avatar_size")
+ if self.max_avatar_size is not None:
+ self.max_avatar_size = self.parse_size(self.max_avatar_size)
+
+ # The MIME types allowed for an avatar.
+ self.allowed_avatar_mimetypes = config.get("allowed_avatar_mimetypes")
+ if self.allowed_avatar_mimetypes and not isinstance(
+ self.allowed_avatar_mimetypes,
+ list,
+ ):
+ raise ConfigError("allowed_avatar_mimetypes must be a list")
+
self.listeners = [parse_listener_def(x) for x in config.get("listeners", [])]
# no_tls is not really supported any more, but let's grandfather it in
@@ -506,16 +518,12 @@ class ServerConfig(Config):
self.listeners = l2
self.web_client_location = config.get("web_client_location", None)
- self.web_client_location_is_redirect = self.web_client_location and (
+ # Non-HTTP(S) web client location is not supported.
+ if self.web_client_location and not (
self.web_client_location.startswith("http://")
or self.web_client_location.startswith("https://")
- )
- # A non-HTTP(S) web client location is deprecated.
- if self.web_client_location and not self.web_client_location_is_redirect:
- logger.warning(NO_MORE_NONE_HTTP_WEB_CLIENT_LOCATION_WARNING)
-
- # Warn if webclient is configured for a worker.
- _warn_if_webclient_configured(self.listeners)
+ ):
+ raise ConfigError("web_client_location must point to a HTTP(S) URL.")
self.gc_thresholds = read_gc_thresholds(config.get("gc_thresholds", None))
self.gc_seconds = self.read_gc_intervals(config.get("gc_min_interval", None))
@@ -643,19 +651,6 @@ class ServerConfig(Config):
False,
)
- # List of users trialing the new experimental default push rules. This setting is
- # not included in the sample configuration file on purpose as it's a temporary
- # hack, so that some users can trial the new defaults without impacting every
- # user on the homeserver.
- users_new_default_push_rules: list = (
- config.get("users_new_default_push_rules") or []
- )
- if not isinstance(users_new_default_push_rules, list):
- raise ConfigError("'users_new_default_push_rules' must be a list")
-
- # Turn the list into a set to improve lookup speed.
- self.users_new_default_push_rules: set = set(users_new_default_push_rules)
-
# Whitelist of domain names that given next_link parameters must have
next_link_domain_whitelist: Optional[List[str]] = config.get(
"next_link_domain_whitelist"
@@ -1168,6 +1163,20 @@ class ServerConfig(Config):
#
#allow_per_room_profiles: false
+ # The largest allowed file size for a user avatar. Defaults to no restriction.
+ #
+ # Note that user avatar changes will not work if this is set without
+ # using Synapse's media repository.
+ #
+ #max_avatar_size: 10M
+
+ # The MIME types allowed for user avatars. Defaults to no restriction.
+ #
+ # Note that user avatar changes will not work if this is set without
+ # using Synapse's media repository.
+ #
+ #allowed_avatar_mimetypes: ["image/png", "image/jpeg", "image/gif"]
+
# How long to keep redacted events in unredacted form in the database. After
# this period redacted events get replaced with their redacted form in the DB.
#
@@ -1337,11 +1346,16 @@ def parse_listener_def(listener: Any) -> ListenerConfig:
http_config = None
if listener_type == "http":
+ try:
+ resources = [
+ HttpResourceConfig(**res) for res in listener.get("resources", [])
+ ]
+ except ValueError as e:
+ raise ConfigError("Unknown listener resource") from e
+
http_config = HttpListenerConfig(
x_forwarded=listener.get("x_forwarded", False),
- resources=[
- HttpResourceConfig(**res) for res in listener.get("resources", [])
- ],
+ resources=resources,
additional_resources=listener.get("additional_resources", {}),
tag=listener.get("tag"),
)
@@ -1349,30 +1363,6 @@ def parse_listener_def(listener: Any) -> ListenerConfig:
return ListenerConfig(port, bind_addresses, listener_type, tls, http_config)
-NO_MORE_NONE_HTTP_WEB_CLIENT_LOCATION_WARNING = """
-Synapse no longer supports serving a web client. To remove this warning,
-configure 'web_client_location' with an HTTP(S) URL.
-"""
-
-
-NO_MORE_WEB_CLIENT_WARNING = """
-Synapse no longer includes a web client. To redirect the root resource to a web client, configure
-'web_client_location'. To remove this warning, remove 'webclient' from the 'listeners'
-configuration.
-"""
-
-
-def _warn_if_webclient_configured(listeners: Iterable[ListenerConfig]) -> None:
- for listener in listeners:
- if not listener.http_options:
- continue
- for res in listener.http_options.resources:
- for name in res.names:
- if name == "webclient":
- logger.warning(NO_MORE_WEB_CLIENT_WARNING)
- return
-
-
_MANHOLE_SETTINGS_SCHEMA = {
"type": "object",
"properties": {
|