diff --git a/build.gradle b/build.gradle
index d12e571..b93d4fa 100644
--- a/build.gradle
+++ b/build.gradle
@@ -119,6 +119,9 @@ dependencies {
// Twilio SDK for SMS
compile 'com.twilio.sdk:twilio:7.14.5'
+ // SendGrid SDK to send emails from GCE
+ compile 'com.sendgrid:sendgrid-java:2.2.2'
+
testCompile 'junit:junit:4.12'
testCompile 'com.github.tomakehurst:wiremock:2.8.0'
}
diff --git a/src/main/java/io/kamax/mxisd/config/threepid/connector/EmailSendGridConfig.java b/src/main/java/io/kamax/mxisd/config/threepid/connector/EmailSendGridConfig.java
new file mode 100644
index 0000000..6c6c0da
--- /dev/null
+++ b/src/main/java/io/kamax/mxisd/config/threepid/connector/EmailSendGridConfig.java
@@ -0,0 +1,202 @@
+/*
+ * mxisd - Matrix Identity Server Daemon
+ * Copyright (C) 2017 Maxime Dor
+ *
+ * https://max.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.threepid.connector;
+
+import io.kamax.mxisd.util.GsonUtil;
+import org.apache.commons.lang.StringUtils;
+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("notification.handlers.sendgrid")
+public class EmailSendGridConfig {
+
+ public static class EmailTemplate {
+
+ public static class EmailBody {
+
+ private String text;
+ private String html;
+
+ public String getText() {
+ return text;
+ }
+
+ public void setText(String text) {
+ this.text = text;
+ }
+
+ public String getHtml() {
+ return html;
+ }
+
+ public void setHtml(String html) {
+ this.html = html;
+ }
+
+ }
+
+ private String subject;
+ private EmailBody body = new EmailBody();
+
+ public String getSubject() {
+ return subject;
+ }
+
+ public void setSubject(String subject) {
+ this.subject = subject;
+ }
+
+ public EmailBody getBody() {
+ return body;
+ }
+
+ public void setBody(EmailBody body) {
+ this.body = body;
+ }
+
+ }
+
+ public static class Api {
+
+ private String key;
+
+ public String getKey() {
+ return key;
+ }
+
+ public void setKey(String key) {
+ this.key = key;
+ }
+
+ }
+
+ public static class Identity {
+
+ private String from;
+ private String name;
+
+ public String getFrom() {
+ return from;
+ }
+
+ public void setFrom(String from) {
+ this.from = from;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ }
+
+ public static class Templates {
+
+ public static class TemplateSession {
+
+ private EmailTemplate local = new EmailTemplate();
+ private EmailTemplate remote = new EmailTemplate();
+
+ public EmailTemplate getLocal() {
+ return local;
+ }
+
+ public void setLocal(EmailTemplate local) {
+ this.local = local;
+ }
+
+ public EmailTemplate getRemote() {
+ return remote;
+ }
+
+ public void setRemote(EmailTemplate remote) {
+ this.remote = remote;
+ }
+ }
+
+ private EmailTemplate invite = new EmailTemplate();
+ private TemplateSession session = new TemplateSession();
+
+ public EmailTemplate getInvite() {
+ return invite;
+ }
+
+ public void setInvite(EmailTemplate invite) {
+ this.invite = invite;
+ }
+
+ public TemplateSession getSession() {
+ return session;
+ }
+
+ public void setSession(TemplateSession session) {
+ this.session = session;
+ }
+
+ }
+
+ private Logger log = LoggerFactory.getLogger(EmailSendGridConfig.class);
+
+ private Api api = new Api();
+ private Identity identity = new Identity();
+ private Templates templates = new Templates();
+
+ public Api getApi() {
+ return api;
+ }
+
+ public void setApi(Api api) {
+ this.api = api;
+ }
+
+ public Identity getIdentity() {
+ return identity;
+ }
+
+ public void setIdentity(Identity identity) {
+ this.identity = identity;
+ }
+
+ public Templates getTemplates() {
+ return templates;
+ }
+
+ public void setTemplates(Templates templates) {
+ this.templates = templates;
+ }
+
+ @PostConstruct
+ public void build() {
+ log.info("--- Email SendGrid connector config ---");
+ log.info("API key configured?: {}", StringUtils.isNotBlank(api.getKey()));
+ log.info("Identity: {}", GsonUtil.build().toJson(identity));
+ log.info("Templates: {}", GsonUtil.build().toJson(templates));
+ }
+
+}
diff --git a/src/main/java/io/kamax/mxisd/config/threepid/notification/NotificationConfig.java b/src/main/java/io/kamax/mxisd/config/threepid/notification/NotificationConfig.java
new file mode 100644
index 0000000..fbba700
--- /dev/null
+++ b/src/main/java/io/kamax/mxisd/config/threepid/notification/NotificationConfig.java
@@ -0,0 +1,57 @@
+/*
+ * mxisd - Matrix Identity Server Daemon
+ * Copyright (C) 2017 Maxime Dor
+ *
+ * https://max.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.threepid.notification;
+
+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;
+import java.util.HashMap;
+import java.util.Map;
+
+@Configuration
+@ConfigurationProperties("notification")
+public class NotificationConfig {
+
+ private Logger log = LoggerFactory.getLogger(NotificationConfig.class);
+
+ private Map handler = new HashMap<>();
+
+ public Map getHandler() {
+ return handler;
+ }
+
+ public void setHandler(Map handler) {
+ this.handler = handler;
+ }
+
+ @PostConstruct
+ public void build() {
+ log.info("--- Notification config ---");
+ log.info("Handlers:");
+ handler.forEach((k, v) -> {
+ log.info("\t{}: {}", k, v);
+ });
+ }
+
+}
diff --git a/src/main/java/io/kamax/mxisd/notification/INotificationHandler.java b/src/main/java/io/kamax/mxisd/notification/INotificationHandler.java
index e42735f..2bfc1e2 100644
--- a/src/main/java/io/kamax/mxisd/notification/INotificationHandler.java
+++ b/src/main/java/io/kamax/mxisd/notification/INotificationHandler.java
@@ -25,6 +25,8 @@ import io.kamax.mxisd.threepid.session.IThreePidSession;
public interface INotificationHandler {
+ String getId();
+
String getMedium();
void sendForInvite(IThreePidInviteReply invite);
diff --git a/src/main/java/io/kamax/mxisd/notification/NotificationManager.java b/src/main/java/io/kamax/mxisd/notification/NotificationManager.java
index 78a38a2..ef5fbdd 100644
--- a/src/main/java/io/kamax/mxisd/notification/NotificationManager.java
+++ b/src/main/java/io/kamax/mxisd/notification/NotificationManager.java
@@ -20,9 +20,13 @@
package io.kamax.mxisd.notification;
+import io.kamax.mxisd.config.threepid.notification.NotificationConfig;
import io.kamax.mxisd.exception.NotImplementedException;
import io.kamax.mxisd.invitation.IThreePidInviteReply;
import io.kamax.mxisd.threepid.session.IThreePidSession;
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -33,12 +37,25 @@ import java.util.Map;
@Component
public class NotificationManager {
+ private Logger log = LoggerFactory.getLogger(NotificationManager.class);
+
private Map handlers;
@Autowired
- public NotificationManager(List handlers) {
+ public NotificationManager(NotificationConfig cfg, List handlers) {
this.handlers = new HashMap<>();
- handlers.forEach(h -> this.handlers.put(h.getMedium(), h));
+ handlers.forEach(h -> {
+ log.info("Found handler {} for medium {}", h.getId(), h.getMedium());
+ String handlerId = cfg.getHandler().get(h.getMedium());
+ if (StringUtils.isBlank(handlerId) || StringUtils.equals(handlerId, h.getId())) {
+ this.handlers.put(h.getMedium(), h);
+ }
+ });
+
+ log.info("--- Notification handler ---");
+ this.handlers.forEach((k, v) -> {
+ log.info("\tHandler for {}: {}", k, v.getId());
+ });
}
private INotificationHandler ensureMedium(String medium) {
@@ -46,7 +63,6 @@ public class NotificationManager {
if (handler == null) {
throw new NotImplementedException(medium + " is not a supported 3PID medium type");
}
-
return handler;
}
diff --git a/src/main/java/io/kamax/mxisd/threepid/connector/email/EmailSendGridNotificationHandler.java b/src/main/java/io/kamax/mxisd/threepid/connector/email/EmailSendGridNotificationHandler.java
new file mode 100644
index 0000000..d7644ee
--- /dev/null
+++ b/src/main/java/io/kamax/mxisd/threepid/connector/email/EmailSendGridNotificationHandler.java
@@ -0,0 +1,136 @@
+/*
+ * mxisd - Matrix Identity Server Daemon
+ * Copyright (C) 2017 Maxime Dor
+ *
+ * https://max.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.threepid.connector.email;
+
+import com.sendgrid.SendGrid;
+import com.sendgrid.SendGridException;
+import io.kamax.matrix.ThreePidMedium;
+import io.kamax.mxisd.config.MatrixConfig;
+import io.kamax.mxisd.config.ServerConfig;
+import io.kamax.mxisd.config.threepid.connector.EmailSendGridConfig;
+import io.kamax.mxisd.invitation.IThreePidInviteReply;
+import io.kamax.mxisd.notification.INotificationHandler;
+import io.kamax.mxisd.threepid.notification.PlaceholderNotificationGenerator;
+import io.kamax.mxisd.threepid.session.IThreePidSession;
+import org.apache.commons.io.IOUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+
+import static com.sendgrid.SendGrid.Email;
+import static com.sendgrid.SendGrid.Response;
+import static io.kamax.mxisd.config.threepid.connector.EmailSendGridConfig.EmailTemplate;
+
+@Component
+public class EmailSendGridNotificationHandler extends PlaceholderNotificationGenerator implements INotificationHandler {
+
+ private Logger log = LoggerFactory.getLogger(EmailSendGridNotificationHandler.class);
+
+ private EmailSendGridConfig cfg;
+ private SendGrid sendgrid;
+
+ @Autowired
+ public EmailSendGridNotificationHandler(MatrixConfig mxCfg, ServerConfig srvCfg, EmailSendGridConfig cfg) {
+ super(mxCfg, srvCfg);
+ this.cfg = cfg;
+ this.sendgrid = new SendGrid(cfg.getApi().getKey());
+ }
+
+ @Override
+ public String getId() {
+ return "sendgrid";
+ }
+
+ @Override
+ public String getMedium() {
+ return ThreePidMedium.Email.getId();
+ }
+
+ protected Email getEmail() {
+ Email email = new Email();
+ email.setFrom(cfg.getIdentity().getFrom());
+ email.setFromName(cfg.getIdentity().getName());
+ return email;
+ }
+
+ private String getFromFile(String path) {
+ try {
+ return IOUtils.toString(new FileInputStream(path), StandardCharsets.UTF_8);
+ } catch (IOException e) {
+ throw new RuntimeException("Couldn't create notification content using file " + path, e);
+ }
+ }
+
+ @Override
+ public void sendForInvite(IThreePidInviteReply invite) {
+ EmailTemplate template = cfg.getTemplates().getInvite();
+ Email email = getEmail();
+ email.setSubject(populateForInvite(invite, template.getSubject()));
+ email.setText(populateForInvite(invite, getFromFile(template.getBody().getText())));
+ email.setHtml(populateForInvite(invite, getFromFile(template.getBody().getHtml())));
+
+ send(invite.getInvite().getAddress(), email);
+ }
+
+ @Override
+ public void sendForValidation(IThreePidSession session) {
+ EmailTemplate template = cfg.getTemplates().getSession().getLocal();
+ Email email = getEmail();
+ email.setSubject(populateForValidation(session, template.getSubject()));
+ email.setText(populateForValidation(session, getFromFile(template.getBody().getText())));
+ email.setHtml(populateForValidation(session, getFromFile(template.getBody().getHtml())));
+
+ send(session.getThreePid().getAddress(), email);
+ }
+
+ @Override
+ public void sendForRemoteValidation(IThreePidSession session) {
+ EmailTemplate template = cfg.getTemplates().getSession().getLocal();
+ Email email = getEmail();
+ email.setSubject(populateForRemoteValidation(session, template.getSubject()));
+ email.setText(populateForRemoteValidation(session, getFromFile(template.getBody().getText())));
+ email.setHtml(populateForRemoteValidation(session, getFromFile(template.getBody().getHtml())));
+
+ send(session.getThreePid().getAddress(), email);
+ }
+
+ private void send(String recipient, Email email) {
+ try {
+ email.addTo(recipient);
+ email.setFrom(cfg.getIdentity().getFrom());
+ email.setFromName(cfg.getIdentity().getName());
+ Response response = sendgrid.send(email);
+ if (response.getStatus()) {
+ log.info("Successfully sent email to {} using SendGrid", recipient);
+ } else {
+ throw new RuntimeException("Error sending via SendGrid to " + recipient + ": " + response.getMessage());
+ }
+ } catch (SendGridException e) {
+ throw new RuntimeException("Unable to send e-mail invite via SendGrid to " + recipient, e);
+ }
+ }
+
+}
diff --git a/src/main/java/io/kamax/mxisd/threepid/notification/GenericTemplateNotificationGenerator.java b/src/main/java/io/kamax/mxisd/threepid/notification/GenericTemplateNotificationGenerator.java
index bf2ef50..a85cfbc 100644
--- a/src/main/java/io/kamax/mxisd/threepid/notification/GenericTemplateNotificationGenerator.java
+++ b/src/main/java/io/kamax/mxisd/threepid/notification/GenericTemplateNotificationGenerator.java
@@ -20,17 +20,14 @@
package io.kamax.mxisd.threepid.notification;
-import io.kamax.mxisd.ThreePid;
import io.kamax.mxisd.config.MatrixConfig;
import io.kamax.mxisd.config.ServerConfig;
import io.kamax.mxisd.config.threepid.medium.GenericTemplateConfig;
-import io.kamax.mxisd.controller.v1.IdentityAPIv1;
import io.kamax.mxisd.exception.InternalServerError;
import io.kamax.mxisd.invitation.IThreePidInviteReply;
import io.kamax.mxisd.threepid.session.IThreePidSession;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
-import org.apache.commons.lang.WordUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -43,39 +40,20 @@ import java.io.InputStream;
import java.nio.charset.StandardCharsets;
@Component
-public abstract class GenericTemplateNotificationGenerator implements INotificationGenerator {
+public abstract class GenericTemplateNotificationGenerator extends PlaceholderNotificationGenerator implements INotificationGenerator {
private Logger log = LoggerFactory.getLogger(GenericTemplateNotificationGenerator.class);
- private MatrixConfig mxCfg;
- private ServerConfig srvCfg;
private GenericTemplateConfig cfg;
@Autowired
private ApplicationContext app;
public GenericTemplateNotificationGenerator(MatrixConfig mxCfg, ServerConfig srvCfg, GenericTemplateConfig cfg) {
- this.mxCfg = mxCfg;
- this.srvCfg = srvCfg;
+ super(mxCfg, srvCfg);
this.cfg = cfg;
}
- protected String populateForCommon(String body, ThreePid recipient) {
- return body;
- }
-
- private String populateCommon(String body, ThreePid recipient) {
- body = populateForCommon(body, recipient);
-
- String domainPretty = WordUtils.capitalizeFully(mxCfg.getDomain());
- body = body.replace("%DOMAIN%", mxCfg.getDomain());
- body = body.replace("%DOMAIN_PRETTY%", domainPretty);
- body = body.replace("%RECIPIENT_MEDIUM%", recipient.getMedium());
- body = body.replace("%RECIPIENT_ADDRESS%", recipient.getAddress());
-
- return body;
- }
-
private String getTemplateContent(String location) {
try {
InputStream is = StringUtils.startsWith(location, "classpath:") ?
@@ -86,65 +64,22 @@ public abstract class GenericTemplateNotificationGenerator implements INotificat
}
}
- private String getTemplateAndPopulate(String location, ThreePid recipient) {
- return populateCommon(getTemplateContent(location), recipient);
- }
-
@Override
public String getForInvite(IThreePidInviteReply invite) {
- ThreePid tpid = new ThreePid(invite.getInvite().getMedium(), invite.getInvite().getAddress());
- String templateBody = getTemplateAndPopulate(cfg.getInvite(), tpid);
-
- String senderName = invite.getInvite().getProperties().getOrDefault("sender_display_name", "");
- String senderNameOrId = StringUtils.defaultIfBlank(senderName, invite.getInvite().getSender().getId());
- String roomName = invite.getInvite().getProperties().getOrDefault("room_name", "");
- String roomNameOrId = StringUtils.defaultIfBlank(roomName, invite.getInvite().getRoomId());
-
- templateBody = templateBody.replace("%SENDER_ID%", invite.getInvite().getSender().getId());
- templateBody = templateBody.replace("%SENDER_NAME%", senderName);
- templateBody = templateBody.replace("%SENDER_NAME_OR_ID%", senderNameOrId);
- templateBody = templateBody.replace("%INVITE_MEDIUM%", tpid.getMedium());
- templateBody = templateBody.replace("%INVITE_ADDRESS%", tpid.getAddress());
- templateBody = templateBody.replace("%ROOM_ID%", invite.getInvite().getRoomId());
- templateBody = templateBody.replace("%ROOM_NAME%", roomName);
- templateBody = templateBody.replace("%ROOM_NAME_OR_ID%", roomNameOrId);
-
- return templateBody;
+ log.info("Generating notification content for 3PID invite");
+ return populateForInvite(invite, getTemplateContent(cfg.getInvite()));
}
@Override
public String getForValidation(IThreePidSession session) {
log.info("Generating notification content for 3PID Session validation");
- String templateBody = getTemplateAndPopulate(cfg.getSession().getValidation().getLocal(), session.getThreePid());
-
- String validationLink = srvCfg.getPublicUrl() + IdentityAPIv1.getValidate(
- session.getThreePid().getMedium(),
- session.getId(),
- session.getSecret(),
- session.getToken());
-
- templateBody = templateBody.replace("%VALIDATION_LINK%", validationLink);
- templateBody = templateBody.replace("%VALIDATION_TOKEN%", session.getToken());
-
- return templateBody;
+ return populateForValidation(session, getTemplateContent(cfg.getSession().getValidation().getLocal()));
}
@Override
public String getForRemoteValidation(IThreePidSession session) {
log.info("Generating notification content for remote-only 3PID session");
- String templateBody = getTemplateAndPopulate(cfg.getSession().getValidation().getRemote(), session.getThreePid());
-
- String validationLink = srvCfg.getPublicUrl() + IdentityAPIv1.getValidate(
- session.getThreePid().getMedium(),
- session.getId(),
- session.getSecret(),
- session.getToken());
-
- templateBody = templateBody.replace("%VALIDATION_LINK%", validationLink);
- templateBody = templateBody.replace("%VALIDATION_TOKEN%", session.getToken());
- templateBody = templateBody.replace("%NEXT_URL%", validationLink);
-
- return templateBody;
+ return populateForRemoteValidation(session, getTemplateContent(cfg.getSession().getValidation().getRemote()));
}
}
diff --git a/src/main/java/io/kamax/mxisd/threepid/notification/PlaceholderNotificationGenerator.java b/src/main/java/io/kamax/mxisd/threepid/notification/PlaceholderNotificationGenerator.java
new file mode 100644
index 0000000..7a185b6
--- /dev/null
+++ b/src/main/java/io/kamax/mxisd/threepid/notification/PlaceholderNotificationGenerator.java
@@ -0,0 +1,89 @@
+/*
+ * mxisd - Matrix Identity Server Daemon
+ * Copyright (C) 2017 Maxime Dor
+ *
+ * https://max.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.threepid.notification;
+
+import io.kamax.mxisd.ThreePid;
+import io.kamax.mxisd.config.MatrixConfig;
+import io.kamax.mxisd.config.ServerConfig;
+import io.kamax.mxisd.controller.v1.IdentityAPIv1;
+import io.kamax.mxisd.invitation.IThreePidInviteReply;
+import io.kamax.mxisd.threepid.session.IThreePidSession;
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang.WordUtils;
+
+public abstract class PlaceholderNotificationGenerator {
+
+ private MatrixConfig mxCfg;
+ private ServerConfig srvCfg;
+
+ public PlaceholderNotificationGenerator(MatrixConfig mxCfg, ServerConfig srvCfg) {
+ this.mxCfg = mxCfg;
+ this.srvCfg = srvCfg;
+ }
+
+ protected String populateForCommon(String input, ThreePid recipient) {
+ String domainPretty = WordUtils.capitalizeFully(mxCfg.getDomain());
+
+ return input
+ .replace("%DOMAIN%", mxCfg.getDomain())
+ .replace("%DOMAIN_PRETTY%", domainPretty)
+ .replace("%RECIPIENT_MEDIUM%", recipient.getMedium())
+ .replace("%RECIPIENT_ADDRESS%", recipient.getAddress());
+ }
+
+ protected String populateForInvite(IThreePidInviteReply invite, String input) {
+ ThreePid tpid = new ThreePid(invite.getInvite().getMedium(), invite.getInvite().getAddress());
+
+ String senderName = invite.getInvite().getProperties().getOrDefault("sender_display_name", "");
+ String senderNameOrId = StringUtils.defaultIfBlank(senderName, invite.getInvite().getSender().getId());
+ String roomName = invite.getInvite().getProperties().getOrDefault("room_name", "");
+ String roomNameOrId = StringUtils.defaultIfBlank(roomName, invite.getInvite().getRoomId());
+
+ return populateForCommon(input, tpid)
+ .replace("%SENDER_ID%", invite.getInvite().getSender().getId())
+ .replace("%SENDER_NAME%", senderName)
+ .replace("%SENDER_NAME_OR_ID%", senderNameOrId)
+ .replace("%INVITE_MEDIUM%", tpid.getMedium())
+ .replace("%INVITE_ADDRESS%", tpid.getAddress())
+ .replace("%ROOM_ID%", invite.getInvite().getRoomId())
+ .replace("%ROOM_NAME%", roomName)
+ .replace("%ROOM_NAME_OR_ID%", roomNameOrId);
+ }
+
+ protected String populateForValidation(IThreePidSession session, String input) {
+ String validationLink = srvCfg.getPublicUrl() + IdentityAPIv1.getValidate(
+ session.getThreePid().getMedium(),
+ session.getId(),
+ session.getSecret(),
+ session.getToken()
+ );
+
+ return populateForCommon(input, session.getThreePid())
+ .replace("%VALIDATION_LINK%", validationLink)
+ .replace("%VALIDATION_TOKEN%", session.getToken())
+ .replace("%NEXT_URL%", validationLink);
+ }
+
+ protected String populateForRemoteValidation(IThreePidSession session, String input) {
+ return populateForValidation(session, input);
+ }
+
+}
diff --git a/src/main/java/io/kamax/mxisd/threepid/notification/email/EmailNotificationHandler.java b/src/main/java/io/kamax/mxisd/threepid/notification/email/EmailRawNotificationHandler.java
similarity index 85%
rename from src/main/java/io/kamax/mxisd/threepid/notification/email/EmailNotificationHandler.java
rename to src/main/java/io/kamax/mxisd/threepid/notification/email/EmailRawNotificationHandler.java
index 8991610..a46f009 100644
--- a/src/main/java/io/kamax/mxisd/threepid/notification/email/EmailNotificationHandler.java
+++ b/src/main/java/io/kamax/mxisd/threepid/notification/email/EmailRawNotificationHandler.java
@@ -30,16 +30,21 @@ import org.springframework.stereotype.Component;
import java.util.List;
@Component
-public class EmailNotificationHandler extends GenericNotificationHandler {
+public class EmailRawNotificationHandler extends GenericNotificationHandler {
private EmailConfig cfg;
@Autowired
- public EmailNotificationHandler(EmailConfig cfg, List generators, List connectors) {
+ public EmailRawNotificationHandler(EmailConfig cfg, List generators, List connectors) {
this.cfg = cfg;
process(connectors, generators);
}
+ @Override
+ public String getId() {
+ return "raw";
+ }
+
@Override
public String getMedium() {
return ThreePidMedium.Email.getId();
diff --git a/src/main/java/io/kamax/mxisd/threepid/notification/phone/PhoneNotificationHandler.java b/src/main/java/io/kamax/mxisd/threepid/notification/phone/PhoneNotificationHandler.java
index ff651b6..9ba5109 100644
--- a/src/main/java/io/kamax/mxisd/threepid/notification/phone/PhoneNotificationHandler.java
+++ b/src/main/java/io/kamax/mxisd/threepid/notification/phone/PhoneNotificationHandler.java
@@ -40,6 +40,11 @@ public class PhoneNotificationHandler extends GenericNotificationHandler