diff --git a/docs/features/identity.md b/docs/features/identity.md
index 2b5fa3e..72137cd 100644
--- a/docs/features/identity.md
+++ b/docs/features/identity.md
@@ -1,3 +1,18 @@
-To be documented.
+# Matrix Identity Service
+**WARNING**: This document is incomplete and can be missleading.
-Implementation of the [Matrix Identity service API](https://matrix.org/docs/spec/identity_service/unstable.html)
+Implementation of the [Unofficial Matrix Identity Service API](https://kamax.io/matrix/api/identity_service/unstable.html).
+
+## Invitation
+Resolution can be customized using the following configuration:
+
+`invite.resolution.recursive`
+- Default value: `true`
+- Description: Control if the pending invite resolution should be done recursively or not.
+ **DANGER ZONE:** This setting has the potential to create "an isolated island", which can have unexpected side effects
+ and break invites in rooms. This will most likely not have the effect you think it does. Only change the value if you
+ understand the consequences.
+
+`invite.resolution.timer`
+- Default value: `1`
+- Description: How often, in minutes, mxisd should try to resolve pending invites.
diff --git a/src/main/java/io/kamax/mxisd/config/InvitationConfig.java b/src/main/java/io/kamax/mxisd/config/InvitationConfig.java
new file mode 100644
index 0000000..1194b4b
--- /dev/null
+++ b/src/main/java/io/kamax/mxisd/config/InvitationConfig.java
@@ -0,0 +1,76 @@
+/*
+ * mxisd - Matrix Identity Server Daemon
+ * Copyright (C) 2018 Kamax Sàrl
+ *
+ * https://www.kamax.io/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package io.kamax.mxisd.config;
+
+import io.kamax.mxisd.util.GsonUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+import javax.annotation.PostConstruct;
+
+@Configuration
+@ConfigurationProperties("invite")
+public class InvitationConfig {
+
+ private final Logger log = LoggerFactory.getLogger(InvitationConfig.class);
+
+ public static class Resolution {
+
+ private boolean recursive;
+ private long timer;
+
+ public boolean isRecursive() {
+ return recursive;
+ }
+
+ public void setRecursive(boolean recursive) {
+ this.recursive = recursive;
+ }
+
+ public long getTimer() {
+ return timer;
+ }
+
+ public void setTimer(long timer) {
+ this.timer = timer;
+ }
+
+ }
+
+ private Resolution resolution;
+
+ public Resolution getResolution() {
+ return resolution;
+ }
+
+ public void setResolution(Resolution resolution) {
+ this.resolution = resolution;
+ }
+
+ @PostConstruct
+ public void build() {
+ log.info("--- Invite config ---");
+ log.info("Resolution: {}", GsonUtil.build().toJson(resolution));
+ }
+
+}
diff --git a/src/main/java/io/kamax/mxisd/invitation/InvitationManager.java b/src/main/java/io/kamax/mxisd/invitation/InvitationManager.java
index 5887495..b3d6412 100644
--- a/src/main/java/io/kamax/mxisd/invitation/InvitationManager.java
+++ b/src/main/java/io/kamax/mxisd/invitation/InvitationManager.java
@@ -24,6 +24,7 @@ import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import io.kamax.matrix.MatrixID;
+import io.kamax.mxisd.config.InvitationConfig;
import io.kamax.mxisd.dns.FederationDnsOverwrite;
import io.kamax.mxisd.exception.BadRequestException;
import io.kamax.mxisd.exception.MappingAlreadyExistsException;
@@ -72,6 +73,9 @@ public class InvitationManager {
private Map invitations = new ConcurrentHashMap<>();
+ @Autowired
+ private InvitationConfig cfg;
+
@Autowired
private IStorage storage;
@@ -137,7 +141,7 @@ public class InvitationManager {
log.error("Error when running background mapping refresh", t);
}
}
- }, 5000L, TimeUnit.MILLISECONDS.convert(1, TimeUnit.MINUTES)); // FIXME make configurable
+ }, 5000L, TimeUnit.MILLISECONDS.convert(cfg.getResolution().getTimer(), TimeUnit.MINUTES));
}
@PreDestroy
@@ -204,6 +208,14 @@ public class InvitationManager {
return "https://" + domain + ":8448";
}
+ private Optional lookup3pid(String medium, String address) {
+ if (!cfg.getResolution().isRecursive()) {
+ log.warn("/!\\ /!\\ --- RECURSIVE INVITE RESOLUTION HAS BEEN DISABLED --- /!\\ /!\\");
+ }
+
+ return lookupMgr.find(medium, address, cfg.getResolution().isRecursive());
+ }
+
public synchronized IThreePidInviteReply storeInvite(IThreePidInvite invitation) { // TODO better sync
if (!notifMgr.isMediumSupported(invitation.getMedium())) {
throw new BadRequestException("Medium type " + invitation.getMedium() + " is not supported");
@@ -223,7 +235,7 @@ public class InvitationManager {
return reply;
}
- Optional> result = lookupMgr.find(invitation.getMedium(), invitation.getAddress(), true);
+ Optional result = lookup3pid(invitation.getMedium(), invitation.getAddress());
if (result.isPresent()) {
log.info("Mapping for {}:{} already exists, refusing to store invite", invitation.getMedium(), invitation.getAddress());
throw new MappingAlreadyExistsException();
@@ -333,7 +345,7 @@ public class InvitationManager {
public void run() {
try {
log.info("Searching for mapping created since invite {} was created", getIdForLog(reply));
- Optional result = lookupMgr.find(reply.getInvite().getMedium(), reply.getInvite().getAddress(), true);
+ Optional result = lookup3pid(reply.getInvite().getMedium(), reply.getInvite().getAddress());
if (result.isPresent()) {
SingleLookupReply lookup = result.get();
log.info("Found mapping for pending invite {}", getIdForLog(reply));
diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml
index 71177ce..4168fef 100644
--- a/src/main/resources/application.yaml
+++ b/src/main/resources/application.yaml
@@ -264,6 +264,11 @@ view:
success: 'session/remote/checkSuccess'
failure: 'session/remote/checkFailure'
+invite:
+ resolution:
+ recursive: true
+ timer: 1
+
storage:
backend: 'sqlite'