Further work
This commit is contained in:
35
src/main/groovy/io/kamax/mxisd/config/SessionConfig.java
Normal file
35
src/main/groovy/io/kamax/mxisd/config/SessionConfig.java
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.kamax.mxisd.config;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
@ConfigurationProperties("session")
|
||||
public class SessionConfig {
|
||||
|
||||
private static Logger log = LoggerFactory.getLogger(SessionConfig.class);
|
||||
|
||||
|
||||
}
|
@@ -1,67 +0,0 @@
|
||||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.kamax.mxisd.config.invite.medium;
|
||||
|
||||
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;
|
||||
import java.io.File;
|
||||
|
||||
@Configuration
|
||||
@ConfigurationProperties("invite.medium.email")
|
||||
public class EmailInviteConfig {
|
||||
|
||||
private Logger log = LoggerFactory.getLogger(EmailInviteConfig.class);
|
||||
|
||||
private String template;
|
||||
|
||||
public String getTemplate() {
|
||||
return template;
|
||||
}
|
||||
|
||||
public void setTemplate(String template) {
|
||||
this.template = template;
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void build() {
|
||||
log.info("--- E-mail invites config ---");
|
||||
|
||||
if (!StringUtils.startsWith(getTemplate(), "classpath:")) {
|
||||
if (StringUtils.isBlank(getTemplate())) {
|
||||
log.warn("invite.medium.email is empty! Will not send invites");
|
||||
} else {
|
||||
File cp = new File(getTemplate()).getAbsoluteFile();
|
||||
log.info("Template: {}", cp.getAbsolutePath());
|
||||
if (!cp.exists() || !cp.isFile() || !cp.canRead()) {
|
||||
log.warn(getTemplate() + " does not exist, is not a file or cannot be read");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
log.info("Template: Built-in: {}", getTemplate());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -29,7 +29,7 @@ import org.springframework.context.annotation.Configuration;
|
||||
import javax.annotation.PostConstruct;
|
||||
|
||||
@Configuration
|
||||
@ConfigurationProperties(prefix = "threepid.email.connector.provider.smtp")
|
||||
@ConfigurationProperties(prefix = "threepid.medium.email.connectors.smtp")
|
||||
public class EmailSmtpConfig {
|
||||
|
||||
private Logger log = LoggerFactory.getLogger(EmailSmtpConfig.class);
|
||||
|
@@ -21,6 +21,7 @@
|
||||
package io.kamax.mxisd.config.threepid.medium;
|
||||
|
||||
import io.kamax.mxisd.config.MatrixConfig;
|
||||
import io.kamax.mxisd.exception.ConfigurationException;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.lang.WordUtils;
|
||||
import org.slf4j.Logger;
|
||||
@@ -35,43 +36,81 @@ import javax.annotation.PostConstruct;
|
||||
@ConfigurationProperties("threepid.medium.email")
|
||||
public class EmailConfig {
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private String generator;
|
||||
private String connector;
|
||||
|
||||
private Logger log = LoggerFactory.getLogger(EmailConfig.class);
|
||||
|
||||
private MatrixConfig mxCfg;
|
||||
|
||||
private String from;
|
||||
private String name;
|
||||
private Identity identity = new Identity();
|
||||
|
||||
@Autowired
|
||||
public EmailConfig(MatrixConfig mxCfg) {
|
||||
this.mxCfg = mxCfg;
|
||||
}
|
||||
|
||||
public String getFrom() {
|
||||
return from;
|
||||
public Identity getIdentity() {
|
||||
return identity;
|
||||
}
|
||||
|
||||
public void setFrom(String from) {
|
||||
this.from = from;
|
||||
public String getGenerator() {
|
||||
return generator;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
public void setGenerator(String generator) {
|
||||
this.generator = generator;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
public String getConnector() {
|
||||
return connector;
|
||||
}
|
||||
|
||||
public void setConnector(String connector) {
|
||||
this.connector = connector;
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void build() {
|
||||
log.info("--- E-mail config ---");
|
||||
log.info("From: {}", getFrom());
|
||||
|
||||
if (StringUtils.isBlank(getName())) {
|
||||
setName(WordUtils.capitalize(mxCfg.getDomain()) + " Identity Server");
|
||||
if (StringUtils.isBlank(getGenerator())) {
|
||||
throw new ConfigurationException("generator");
|
||||
}
|
||||
log.info("Name: {}", getName());
|
||||
|
||||
if (StringUtils.isBlank(getConnector())) {
|
||||
throw new ConfigurationException("connector");
|
||||
}
|
||||
|
||||
log.info("From: {}", identity.getFrom());
|
||||
|
||||
if (StringUtils.isBlank(identity.getName())) {
|
||||
identity.setName(WordUtils.capitalize(mxCfg.getDomain()) + " Identity Server");
|
||||
}
|
||||
log.info("Name: {}", identity.getName());
|
||||
log.info("Generator: {}", getGenerator());
|
||||
log.info("Connector: {}", getConnector());
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.kamax.mxisd.config.threepid.medium;
|
||||
|
||||
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("threepid.medium.email.generators.template")
|
||||
public class EmailTemplateConfig {
|
||||
|
||||
private static Logger log = LoggerFactory.getLogger(EmailTemplateConfig.class);
|
||||
private static final String classpathPrefix = "classpath:";
|
||||
|
||||
private static String getName(String path) {
|
||||
if (StringUtils.startsWith(path, classpathPrefix)) {
|
||||
return "Built-in (" + path.substring(classpathPrefix.length()) + ")";
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
public static class Session {
|
||||
|
||||
private String validation;
|
||||
|
||||
public String getValidation() {
|
||||
return validation;
|
||||
}
|
||||
|
||||
public void setValidation(String validation) {
|
||||
this.validation = validation;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private String invite;
|
||||
private Session session = new Session();
|
||||
|
||||
public String getInvite() {
|
||||
return invite;
|
||||
}
|
||||
|
||||
public void setInvite(String invite) {
|
||||
this.invite = invite;
|
||||
}
|
||||
|
||||
public Session getSession() {
|
||||
return session;
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void build() {
|
||||
log.info("--- E-mail Generator templates config ---");
|
||||
log.info("Invite: {}", getName(getInvite()));
|
||||
log.info("Session validation: {}", getName(getSession().getValidation()));
|
||||
}
|
||||
|
||||
}
|
@@ -29,7 +29,7 @@ import io.kamax.mxisd.controller.v1.io.SessionPhoneTokenRequestJson
|
||||
import io.kamax.mxisd.exception.BadRequestException
|
||||
import io.kamax.mxisd.invitation.InvitationManager
|
||||
import io.kamax.mxisd.lookup.ThreePidValidation
|
||||
import io.kamax.mxisd.mapping.MappingManager
|
||||
import io.kamax.mxisd.session.SessionMananger
|
||||
import org.apache.commons.io.IOUtils
|
||||
import org.apache.http.HttpStatus
|
||||
import org.slf4j.Logger
|
||||
@@ -48,7 +48,7 @@ import java.nio.charset.StandardCharsets
|
||||
class SessionController {
|
||||
|
||||
@Autowired
|
||||
private MappingManager mgr
|
||||
private SessionMananger mgr
|
||||
|
||||
@Autowired
|
||||
private InvitationManager invMgr;
|
||||
|
@@ -24,5 +24,10 @@ import org.springframework.http.HttpStatus
|
||||
import org.springframework.web.bind.annotation.ResponseStatus
|
||||
|
||||
@ResponseStatus(value = HttpStatus.NOT_IMPLEMENTED)
|
||||
class NotImplementedException extends RuntimeException {
|
||||
public class NotImplementedException extends RuntimeException {
|
||||
|
||||
public NotImplementedException(String s) {
|
||||
super(s);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -26,14 +26,13 @@ import io.kamax.mxisd.config.DnsOverwrite;
|
||||
import io.kamax.mxisd.config.DnsOverwriteEntry;
|
||||
import io.kamax.mxisd.exception.BadRequestException;
|
||||
import io.kamax.mxisd.exception.MappingAlreadyExistsException;
|
||||
import io.kamax.mxisd.invitation.generator.IInviteContentGenerator;
|
||||
import io.kamax.mxisd.lookup.SingleLookupReply;
|
||||
import io.kamax.mxisd.lookup.ThreePidMapping;
|
||||
import io.kamax.mxisd.lookup.strategy.LookupStrategy;
|
||||
import io.kamax.mxisd.notification.NotificationManager;
|
||||
import io.kamax.mxisd.signature.SignatureManager;
|
||||
import io.kamax.mxisd.storage.IStorage;
|
||||
import io.kamax.mxisd.storage.ormlite.ThreePidInviteIO;
|
||||
import io.kamax.mxisd.threepid.connector.IThreePidConnector;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang.RandomStringUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
@@ -84,35 +83,15 @@ public class InvitationManager {
|
||||
@Autowired
|
||||
private DnsOverwrite dns;
|
||||
|
||||
private Map<String, IInviteContentGenerator> generators;
|
||||
private Map<String, IThreePidConnector> connectors;
|
||||
private NotificationManager notifMgr;
|
||||
|
||||
private CloseableHttpClient client;
|
||||
private Gson gson;
|
||||
private Timer refreshTimer;
|
||||
|
||||
@Autowired
|
||||
public InvitationManager(
|
||||
List<IInviteContentGenerator> generatorList,
|
||||
List<IThreePidConnector> connectorList
|
||||
) {
|
||||
generators = new HashMap<>();
|
||||
generatorList.forEach(sender -> { // FIXME to support several possible implementations
|
||||
if (generators.containsKey(sender.getMedium())) {
|
||||
throw new RuntimeException("More than one " + sender.getMedium() + " content generator");
|
||||
}
|
||||
|
||||
generators.put(sender.getMedium(), sender);
|
||||
});
|
||||
|
||||
connectors = new HashMap<>();
|
||||
connectorList.forEach(connector -> { // FIXME to support several possible implementations
|
||||
if (connectors.containsKey(connector.getMedium())) {
|
||||
throw new RuntimeException("More than one " + connector.getMedium() + " connector");
|
||||
}
|
||||
|
||||
connectors.put(connector.getMedium(), connector);
|
||||
});
|
||||
public InvitationManager(NotificationManager notifMgr) {
|
||||
this.notifMgr = notifMgr;
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
@@ -221,9 +200,7 @@ public class InvitationManager {
|
||||
}
|
||||
|
||||
public synchronized IThreePidInviteReply storeInvite(IThreePidInvite invitation) { // TODO better sync
|
||||
IInviteContentGenerator generator = generators.get(invitation.getMedium());
|
||||
IThreePidConnector connector = connectors.get(invitation.getMedium());
|
||||
if (generator == null || connector == null) {
|
||||
if (!notifMgr.isMediumSupported(invitation.getMedium())) {
|
||||
throw new BadRequestException("Medium type " + invitation.getMedium() + " is not supported");
|
||||
}
|
||||
|
||||
@@ -246,7 +223,7 @@ public class InvitationManager {
|
||||
IThreePidInviteReply reply = new ThreePidInviteReply(invId, invitation, token, displayName);
|
||||
|
||||
log.info("Performing invite to {}:{}", invitation.getMedium(), invitation.getAddress());
|
||||
connector.send(reply, generator.generate(reply));
|
||||
notifMgr.send(reply);
|
||||
|
||||
log.info("Storing invite under ID {}", invId);
|
||||
storage.insertInvite(reply);
|
||||
|
@@ -18,14 +18,17 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.kamax.mxisd.invitation.generator;
|
||||
package io.kamax.mxisd.notification;
|
||||
|
||||
import io.kamax.mxisd.invitation.IThreePidInviteReply;
|
||||
import io.kamax.mxisd.threepid.session.IThreePidSession;
|
||||
|
||||
public interface IInviteContentGenerator {
|
||||
public interface INotificationHandler {
|
||||
|
||||
String getMedium();
|
||||
|
||||
String generate(IThreePidInviteReply invite);
|
||||
void notify(IThreePidInviteReply invite);
|
||||
|
||||
void notify(IThreePidSession session);
|
||||
|
||||
}
|
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.kamax.mxisd.notification;
|
||||
|
||||
import io.kamax.mxisd.exception.NotImplementedException;
|
||||
import io.kamax.mxisd.invitation.IThreePidInviteReply;
|
||||
import io.kamax.mxisd.threepid.session.IThreePidSession;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Component
|
||||
public class NotificationManager {
|
||||
|
||||
private Map<String, INotificationHandler> handlers;
|
||||
|
||||
@Autowired
|
||||
public NotificationManager(List<INotificationHandler> handlers) {
|
||||
this.handlers = new HashMap<>();
|
||||
handlers.forEach(h -> this.handlers.put(h.getMedium(), h));
|
||||
}
|
||||
|
||||
private INotificationHandler ensureMedium(String medium) {
|
||||
INotificationHandler handler = handlers.get(medium);
|
||||
if (handler == null) {
|
||||
throw new NotImplementedException(medium + " is not a supported 3PID medium type");
|
||||
}
|
||||
|
||||
return handler;
|
||||
}
|
||||
|
||||
public boolean isMediumSupported(String medium) {
|
||||
return handlers.containsKey(medium);
|
||||
}
|
||||
|
||||
public void sendForInvite(IThreePidInviteReply invite) {
|
||||
ensureMedium(invite.getInvite().getMedium()).notify(invite);
|
||||
}
|
||||
|
||||
public void sendForValidation(IThreePidSession session) {
|
||||
ensureMedium(session.getThreePid().getMedium()).notify(session);
|
||||
}
|
||||
|
||||
public void sendforRemotePublish(IThreePidSession session) {
|
||||
throw new NotImplementedException("Remote publish of 3PID bind");
|
||||
}
|
||||
|
||||
}
|
@@ -18,14 +18,16 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.kamax.mxisd.mapping;
|
||||
package io.kamax.mxisd.session;
|
||||
|
||||
import io.kamax.matrix.ThreePidMedium;
|
||||
import io.kamax.mxisd.ThreePid;
|
||||
import io.kamax.mxisd.config.SessionConfig;
|
||||
import io.kamax.mxisd.exception.InvalidCredentialsException;
|
||||
import io.kamax.mxisd.lookup.SingleLookupReply;
|
||||
import io.kamax.mxisd.lookup.ThreePidValidation;
|
||||
import io.kamax.mxisd.lookup.strategy.LookupStrategy;
|
||||
import io.kamax.mxisd.notification.NotificationManager;
|
||||
import io.kamax.mxisd.storage.IStorage;
|
||||
import io.kamax.mxisd.storage.dao.IThreePidSessionDao;
|
||||
import io.kamax.mxisd.threepid.session.ThreePidSession;
|
||||
@@ -40,16 +42,21 @@ import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
@Component
|
||||
public class MappingManager {
|
||||
public class SessionMananger {
|
||||
|
||||
private Logger log = LoggerFactory.getLogger(MappingManager.class);
|
||||
private Logger log = LoggerFactory.getLogger(SessionMananger.class);
|
||||
|
||||
private SessionConfig cfg;
|
||||
private IStorage storage;
|
||||
private LookupStrategy lookup;
|
||||
private NotificationManager notifMgr;
|
||||
|
||||
@Autowired
|
||||
public MappingManager(IStorage storage, LookupStrategy lookup) {
|
||||
public SessionMananger(SessionConfig cfg, IStorage storage, LookupStrategy lookup, NotificationManager notifMgr) {
|
||||
this.cfg = cfg;
|
||||
this.storage = storage;
|
||||
this.lookup = lookup;
|
||||
this.notifMgr = notifMgr;
|
||||
}
|
||||
|
||||
private ThreePidSession getSession(String sid, String secret) {
|
||||
@@ -78,7 +85,8 @@ public class MappingManager {
|
||||
log.info("We already have a session for {}: {}", tpid, session.getId());
|
||||
if (session.getAttempt() < attempt) {
|
||||
log.info("Received attempt {} is greater than stored attempt {}, sending validation communication", attempt, session.getAttempt());
|
||||
// TODO send via connector
|
||||
notifMgr.sendForValidation(session);
|
||||
log.info("Sent validation notification to {}", tpid);
|
||||
session.increaseAttempt();
|
||||
storage.updateThreePidSession(session.getDao());
|
||||
}
|
||||
@@ -95,8 +103,8 @@ public class MappingManager {
|
||||
ThreePidSession session = new ThreePidSession(sessionId, server, tpid, secret, attempt, nextLink, token);
|
||||
log.info("Generated new session {} to validate {} from server {}", sessionId, tpid, server);
|
||||
|
||||
// TODO send via connector
|
||||
// log.info("Sent validation notification to {}", tpid);
|
||||
notifMgr.sendForValidation(session);
|
||||
log.info("Sent validation notification to {}", tpid);
|
||||
|
||||
storage.insertThreePidSession(session.getDao());
|
||||
log.info("Stored session {}", sessionId, tpid, server);
|
||||
@@ -124,13 +132,7 @@ public class MappingManager {
|
||||
ThreePidSession session = getSessionIfValidated(sid, secret);
|
||||
log.info("Attempting bind of {} on session {} from server {}", mxid, session.getId(), session.getServer());
|
||||
|
||||
// We lookup if the 3PID is already known locally.
|
||||
// If it is, we do not need to process any further as it is already bound.
|
||||
Optional<SingleLookupReply> rLocal = lookup.findLocal(session.getThreePid().getMedium(), session.getThreePid().getAddress());
|
||||
boolean knownLocal = rLocal.isPresent() && StringUtils.equals(rLocal.get().getMxid().getId(), mxid);
|
||||
log.info("Mapping {} -> {} is " + (knownLocal ? "already" : "not") + " known locally", mxid, session.getThreePid());
|
||||
|
||||
// MXID is not known locally, checking remotely
|
||||
// We lookup if the 3PID is already known remotely.
|
||||
Optional<SingleLookupReply> rRemote = lookup.findRemote(session.getThreePid().getMedium(), session.getThreePid().getAddress());
|
||||
boolean knownRemote = rRemote.isPresent() && StringUtils.equals(rRemote.get().getMxid().getId(), mxid);
|
||||
log.info("Mapping {} -> {} is " + (knownRemote ? "already" : "not") + " known remotely", mxid, session.getThreePid());
|
||||
@@ -143,25 +145,28 @@ public class MappingManager {
|
||||
isLocalDomain = session.getThreePid().getAddress().isEmpty(); // FIXME only for testing
|
||||
}
|
||||
if (knownRemote) {
|
||||
if (isLocalDomain && !knownLocal) {
|
||||
log.warn("Mapping {} -> {} is not known locally but is about a local domain!");
|
||||
}
|
||||
|
||||
log.info("No further action needed for Mapping {} -> {}");
|
||||
return;
|
||||
}
|
||||
|
||||
// We lookup if the 3PID is already known locally.
|
||||
Optional<SingleLookupReply> rLocal = lookup.findLocal(session.getThreePid().getMedium(), session.getThreePid().getAddress());
|
||||
boolean knownLocal = rLocal.isPresent() && StringUtils.equals(rLocal.get().getMxid().getId(), mxid);
|
||||
log.info("Mapping {} -> {} is " + (knownLocal ? "already" : "not") + " known locally", mxid, session.getThreePid());
|
||||
|
||||
// This might need a configuration by medium type?
|
||||
if (knownLocal) { // 3PID is ony known local
|
||||
if (isLocalDomain) {
|
||||
// TODO
|
||||
// 1. Check if global publishing is enabled, allowed and offered. If one is no, return.
|
||||
// 2. Publish globally
|
||||
notifMgr.sendforRemotePublish(session);
|
||||
}
|
||||
|
||||
if (System.currentTimeMillis() % 2 == 0) {
|
||||
if (System.currentTimeMillis() % 2 == 0) { // FIXME only for testing
|
||||
// TODO
|
||||
// 1. Check if configured to publish globally non-local domain. If no, return
|
||||
notifMgr.sendforRemotePublish(session);
|
||||
}
|
||||
|
||||
// TODO
|
||||
@@ -172,6 +177,7 @@ public class MappingManager {
|
||||
// 2. call mxisd-specific endpoint to publish globally
|
||||
// 3. check regularly on client page for a binding
|
||||
// 4. when found, show page "Done globally!"
|
||||
notifMgr.sendforRemotePublish(session);
|
||||
} else {
|
||||
if (isLocalDomain) { // 3PID is not known anywhere but is a local domain
|
||||
// TODO
|
||||
@@ -180,6 +186,7 @@ public class MappingManager {
|
||||
} else { // 3PID is not known anywhere and is remote
|
||||
// TODO
|
||||
// Proxy to configurable IS, by default Matrix.org
|
||||
notifMgr.sendforRemotePublish(session);
|
||||
}
|
||||
}
|
||||
}
|
@@ -20,12 +20,10 @@
|
||||
|
||||
package io.kamax.mxisd.threepid.connector;
|
||||
|
||||
import io.kamax.mxisd.invitation.IThreePidInviteReply;
|
||||
|
||||
public interface IThreePidConnector {
|
||||
|
||||
String getId();
|
||||
|
||||
String getMedium();
|
||||
|
||||
void send(IThreePidInviteReply invite, String content);
|
||||
|
||||
}
|
||||
|
@@ -18,14 +18,11 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.kamax.mxisd.threepid.connector;
|
||||
package io.kamax.mxisd.threepid.connector.email;
|
||||
|
||||
import com.sun.mail.smtp.SMTPTransport;
|
||||
import io.kamax.matrix.ThreePidMedium;
|
||||
import io.kamax.mxisd.config.threepid.connector.EmailSmtpConfig;
|
||||
import io.kamax.mxisd.config.threepid.medium.EmailConfig;
|
||||
import io.kamax.mxisd.exception.ConfigurationException;
|
||||
import io.kamax.mxisd.invitation.IThreePidInviteReply;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -42,26 +39,22 @@ import java.nio.charset.StandardCharsets;
|
||||
import java.util.Date;
|
||||
|
||||
@Component
|
||||
public class EmailSmtpConnector implements IThreePidConnector {
|
||||
public class EmailSmtpConnector implements IEmailConnector {
|
||||
|
||||
private Logger log = LoggerFactory.getLogger(EmailSmtpConnector.class);
|
||||
|
||||
private EmailSmtpConfig cfg;
|
||||
|
||||
private Session session;
|
||||
private InternetAddress sender;
|
||||
|
||||
@Autowired
|
||||
public EmailSmtpConnector(EmailConfig cfg, EmailSmtpConfig smtpCfg) {
|
||||
try {
|
||||
session = Session.getInstance(System.getProperties());
|
||||
sender = new InternetAddress(cfg.getFrom(), cfg.getName());
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
// What are we supposed to do with this?!
|
||||
throw new ConfigurationException(e);
|
||||
}
|
||||
public EmailSmtpConnector(EmailSmtpConfig cfg) {
|
||||
this.cfg = cfg;
|
||||
session = Session.getInstance(System.getProperties());
|
||||
}
|
||||
|
||||
this.cfg = smtpCfg;
|
||||
@Override
|
||||
public String getId() {
|
||||
return "smtp";
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -70,20 +63,17 @@ public class EmailSmtpConnector implements IThreePidConnector {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void send(IThreePidInviteReply invite, String content) {
|
||||
if (!ThreePidMedium.Email.is(invite.getInvite().getMedium())) {
|
||||
throw new IllegalArgumentException(invite.getInvite().getMedium() + " is not a supported 3PID type");
|
||||
}
|
||||
|
||||
public void send(String senderAddress, String senderName, String recipient, String content) {
|
||||
try {
|
||||
InternetAddress sender = new InternetAddress(senderAddress, senderName);
|
||||
MimeMessage msg = new MimeMessage(session, IOUtils.toInputStream(content, StandardCharsets.UTF_8));
|
||||
msg.setHeader("X-Mailer", "mxisd"); // TODO set version
|
||||
msg.setHeader("X-Mailer", "mxisd"); // FIXME set version
|
||||
msg.setSentDate(new Date());
|
||||
msg.setFrom(sender);
|
||||
msg.setRecipients(Message.RecipientType.TO, invite.getInvite().getAddress());
|
||||
msg.setRecipients(Message.RecipientType.TO, recipient);
|
||||
msg.saveChanges();
|
||||
|
||||
log.info("Sending invite to {} via SMTP using {}:{}", invite.getInvite().getAddress(), cfg.getHost(), cfg.getPort());
|
||||
log.info("Sending invite to {} via SMTP using {}:{}", recipient, cfg.getHost(), cfg.getPort());
|
||||
SMTPTransport transport = (SMTPTransport) session.getTransport("smtp");
|
||||
transport.setStartTLS(cfg.getTls() > 0);
|
||||
transport.setRequireStartTLS(cfg.getTls() > 1);
|
||||
@@ -91,13 +81,13 @@ public class EmailSmtpConnector implements IThreePidConnector {
|
||||
log.info("Connecting to {}:{}", cfg.getHost(), cfg.getPort());
|
||||
transport.connect(cfg.getHost(), cfg.getPort(), cfg.getLogin(), cfg.getPassword());
|
||||
try {
|
||||
transport.sendMessage(msg, InternetAddress.parse(invite.getInvite().getAddress()));
|
||||
log.info("Invite to {} was sent", invite.getInvite().getAddress());
|
||||
transport.sendMessage(msg, InternetAddress.parse(recipient));
|
||||
log.info("Invite to {} was sent", recipient);
|
||||
} finally {
|
||||
transport.close();
|
||||
}
|
||||
} catch (MessagingException e) {
|
||||
throw new RuntimeException("Unable to send e-mail invite to " + invite.getInvite().getAddress(), e);
|
||||
} catch (UnsupportedEncodingException | MessagingException e) {
|
||||
throw new RuntimeException("Unable to send e-mail invite to " + recipient, e);
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.kamax.mxisd.threepid.connector.email;
|
||||
|
||||
import io.kamax.matrix.ThreePidMedium;
|
||||
import io.kamax.mxisd.threepid.connector.IThreePidConnector;
|
||||
|
||||
public interface IEmailConnector extends IThreePidConnector {
|
||||
|
||||
@Override
|
||||
default String getMedium() {
|
||||
return ThreePidMedium.Email.getId();
|
||||
}
|
||||
|
||||
void send(String senderAddress, String senderName, String recipient, String content);
|
||||
|
||||
}
|
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.kamax.mxisd.threepid.notification;
|
||||
|
||||
import io.kamax.mxisd.invitation.IThreePidInviteReply;
|
||||
import io.kamax.mxisd.threepid.session.IThreePidSession;
|
||||
|
||||
public interface INotificationGenerator {
|
||||
|
||||
String getId();
|
||||
|
||||
String getMedium();
|
||||
|
||||
String get(IThreePidInviteReply invite);
|
||||
|
||||
String getForValidation(IThreePidSession session);
|
||||
|
||||
String getForRemotePublishingValidation(IThreePidSession session);
|
||||
|
||||
}
|
@@ -18,13 +18,14 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.kamax.mxisd.invitation.generator;
|
||||
package io.kamax.mxisd.threepid.notification.email;
|
||||
|
||||
import io.kamax.matrix.ThreePidMedium;
|
||||
import io.kamax.mxisd.ThreePid;
|
||||
import io.kamax.mxisd.config.MatrixConfig;
|
||||
import io.kamax.mxisd.config.invite.medium.EmailInviteConfig;
|
||||
import io.kamax.mxisd.config.threepid.medium.EmailConfig;
|
||||
import io.kamax.mxisd.config.threepid.medium.EmailTemplateConfig;
|
||||
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;
|
||||
@@ -34,55 +35,68 @@ import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
@Component
|
||||
public class EmailInviteContentGenerator implements IInviteContentGenerator {
|
||||
public class EmailNotificationGenerator implements IEmailNotificationGenerator {
|
||||
|
||||
private EmailConfig cfg;
|
||||
private EmailInviteConfig invCfg;
|
||||
private EmailTemplateConfig templateCfg;
|
||||
private MatrixConfig mxCfg;
|
||||
private ApplicationContext app;
|
||||
|
||||
@Autowired // FIXME ApplicationContext shouldn't be injected, find another way from config (?)
|
||||
public EmailInviteContentGenerator(EmailConfig cfg, EmailInviteConfig invCfg, MatrixConfig mxCfg, ApplicationContext app) {
|
||||
public EmailNotificationGenerator(EmailConfig cfg, EmailTemplateConfig templateCfg, MatrixConfig mxCfg, ApplicationContext app) {
|
||||
this.cfg = cfg;
|
||||
this.invCfg = invCfg;
|
||||
this.templateCfg = templateCfg;
|
||||
this.mxCfg = mxCfg;
|
||||
this.app = app;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMedium() {
|
||||
return ThreePidMedium.Email.getId();
|
||||
public String getId() {
|
||||
return "template";
|
||||
}
|
||||
|
||||
private String getTemplateContent(String location) throws IOException {
|
||||
InputStream is = StringUtils.startsWith(location, "classpath:") ?
|
||||
app.getResource(location).getInputStream() : new FileInputStream(location);
|
||||
return IOUtils.toString(is, StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
private String populateCommon(String content, ThreePid recipient) {
|
||||
String domainPretty = WordUtils.capitalizeFully(mxCfg.getDomain());
|
||||
|
||||
content = content.replace("%DOMAIN%", mxCfg.getDomain());
|
||||
content = content.replace("%DOMAIN_PRETTY%", domainPretty);
|
||||
content = content.replace("%FROM_EMAIL%", cfg.getIdentity().getFrom());
|
||||
content = content.replace("%FROM_NAME%", cfg.getIdentity().getName());
|
||||
content = content.replace("%RECIPIENT_MEDIUM%", recipient.getMedium());
|
||||
content = content.replace("%RECIPIENT_ADDRESS%", recipient.getAddress());
|
||||
return content;
|
||||
}
|
||||
|
||||
private String getTemplateAndPopulate(String location, ThreePid recipient) throws IOException {
|
||||
return populateCommon(getTemplateContent(location), recipient);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String generate(IThreePidInviteReply invite) {
|
||||
if (!ThreePidMedium.Email.is(invite.getInvite().getMedium())) {
|
||||
throw new IllegalArgumentException(invite.getInvite().getMedium() + " is not a supported 3PID type");
|
||||
}
|
||||
|
||||
public String get(IThreePidInviteReply invite) {
|
||||
try {
|
||||
String domainPretty = WordUtils.capitalizeFully(mxCfg.getDomain());
|
||||
ThreePid tpid = new ThreePid(invite.getInvite().getMedium(), invite.getInvite().getAddress());
|
||||
String templateBody = getTemplateAndPopulate(templateCfg.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());
|
||||
|
||||
String templateBody = IOUtils.toString(
|
||||
StringUtils.startsWith(invCfg.getTemplate(), "classpath:") ?
|
||||
app.getResource(invCfg.getTemplate()).getInputStream() : new FileInputStream(invCfg.getTemplate()),
|
||||
StandardCharsets.UTF_8);
|
||||
templateBody = templateBody.replace("%DOMAIN%", mxCfg.getDomain());
|
||||
templateBody = templateBody.replace("%DOMAIN_PRETTY%", domainPretty);
|
||||
templateBody = templateBody.replace("%FROM_EMAIL%", cfg.getFrom());
|
||||
templateBody = templateBody.replace("%FROM_NAME%", cfg.getName());
|
||||
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%", invite.getInvite().getMedium());
|
||||
templateBody = templateBody.replace("%INVITE_ADDRESS%", invite.getInvite().getAddress());
|
||||
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);
|
||||
@@ -93,4 +107,14 @@ public class EmailInviteContentGenerator implements IInviteContentGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getForValidation(IThreePidSession session) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getForRemotePublishingValidation(IThreePidSession session) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.kamax.mxisd.threepid.notification.email;
|
||||
|
||||
import io.kamax.matrix.ThreePidMedium;
|
||||
import io.kamax.mxisd.config.threepid.medium.EmailConfig;
|
||||
import io.kamax.mxisd.exception.ConfigurationException;
|
||||
import io.kamax.mxisd.invitation.IThreePidInviteReply;
|
||||
import io.kamax.mxisd.notification.INotificationHandler;
|
||||
import io.kamax.mxisd.threepid.connector.email.IEmailConnector;
|
||||
import io.kamax.mxisd.threepid.session.IThreePidSession;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
public class EmailNotificationHandler implements INotificationHandler {
|
||||
|
||||
private EmailConfig cfg;
|
||||
private IEmailNotificationGenerator generator;
|
||||
private IEmailConnector connector;
|
||||
|
||||
@Autowired
|
||||
public EmailNotificationHandler(EmailConfig cfg, List<IEmailNotificationGenerator> generators, List<IEmailConnector> connectors) {
|
||||
generator = generators.stream()
|
||||
.filter(o -> StringUtils.equals(cfg.getGenerator(), o.getId()))
|
||||
.findFirst()
|
||||
.orElseThrow(() -> new ConfigurationException("Email notification generator [" + cfg.getGenerator() + "] could not be found"));
|
||||
|
||||
connector = connectors.stream()
|
||||
.filter(o -> StringUtils.equals(cfg.getConnector(), o.getId()))
|
||||
.findFirst()
|
||||
.orElseThrow(() -> new ConfigurationException("Email sender connector [" + cfg.getConnector() + "] could not be found"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMedium() {
|
||||
return ThreePidMedium.Email.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notify(IThreePidInviteReply invite) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notify(IThreePidSession session) {
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.kamax.mxisd.threepid.notification.email;
|
||||
|
||||
import io.kamax.matrix.ThreePidMedium;
|
||||
import io.kamax.mxisd.threepid.notification.INotificationGenerator;
|
||||
|
||||
public interface IEmailNotificationGenerator extends INotificationGenerator {
|
||||
|
||||
@Override
|
||||
default String getMedium() {
|
||||
return ThreePidMedium.Email.getId();
|
||||
}
|
||||
|
||||
}
|
@@ -29,8 +29,6 @@ public interface IThreePidSession {
|
||||
|
||||
String getId();
|
||||
|
||||
String getHash();
|
||||
|
||||
Instant getCreationTime();
|
||||
|
||||
String getServer();
|
||||
@@ -43,6 +41,8 @@ public interface IThreePidSession {
|
||||
|
||||
Optional<String> getNextLink();
|
||||
|
||||
String getToken();
|
||||
|
||||
void validate(String token);
|
||||
|
||||
boolean isValidated();
|
||||
|
@@ -113,6 +113,11 @@ public class ThreePidSession implements IThreePidSession {
|
||||
return Optional.ofNullable(nextLink);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getToken() {
|
||||
return token;
|
||||
}
|
||||
|
||||
public synchronized void setAttempt(int attempt) {
|
||||
if (isValidated()) {
|
||||
throw new IllegalStateException();
|
||||
|
@@ -63,18 +63,25 @@ forward:
|
||||
- "https://vector.im"
|
||||
|
||||
threepid:
|
||||
email:
|
||||
connector:
|
||||
active: 'smtp'
|
||||
provider:
|
||||
smtp:
|
||||
port: 587
|
||||
tls: 1
|
||||
|
||||
invite:
|
||||
medium:
|
||||
email:
|
||||
template: 'classpath:email/invite-template.eml'
|
||||
identity:
|
||||
from: ''
|
||||
name: ''
|
||||
connector: 'smtp'
|
||||
generator: 'template'
|
||||
connectors:
|
||||
smtp:
|
||||
host: ''
|
||||
port: 587
|
||||
tls: 1
|
||||
login: ''
|
||||
password: ''
|
||||
generators:
|
||||
template:
|
||||
invite: 'classpath:email/invite-template.eml'
|
||||
session:
|
||||
validation: 'classpath:email/validate-template.eml'
|
||||
|
||||
storage:
|
||||
backend: 'sqlite'
|
||||
|
66
src/main/resources/email/validate-template.eml
Normal file
66
src/main/resources/email/validate-template.eml
Normal file
@@ -0,0 +1,66 @@
|
||||
Subject: Your Matrix Validation Token
|
||||
MIME-Version: 1.0
|
||||
Content-Type: multipart/alternative;
|
||||
boundary="7REaIwWQCioQ6NaBlAQlg8ztbUQj6PKJ"
|
||||
|
||||
--7REaIwWQCioQ6NaBlAQlg8ztbUQj6PKJ
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Disposition: inline
|
||||
|
||||
Hello,
|
||||
|
||||
We have received a request to link this email address with a Matrix account.
|
||||
If this was you who made this request, you may use the following link to complete the verification of your email address:
|
||||
|
||||
%VALIDATION_LINK%
|
||||
|
||||
If your client requires a code, the code is %VALIDATION_TOKEN%
|
||||
|
||||
If you aren't aware of making such a request, please disregard this email.
|
||||
|
||||
Regards,
|
||||
%DOMAIN_PRETTY% Admins
|
||||
|
||||
--7REaIwWQCioQ6NaBlAQlg8ztbUQj6PKJ
|
||||
Content-Type: text/html; charset=UTF-8
|
||||
Content-Disposition: inline
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title></title>
|
||||
<style>
|
||||
body {
|
||||
font-family: "Myriad Pro", "Myriad", Helvetica, Arial, sans-serif;
|
||||
font-size: 12pt;
|
||||
margin: 0px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<p>Hello,</p>
|
||||
|
||||
<p>We have received a request to link this email address with a Matrix account.
|
||||
If this was you who made this request, you may use the following link to
|
||||
complete the verification of your email address:</p>
|
||||
|
||||
<p><a href=%VALIDATION_LINK%">Complete email verification</a></p>
|
||||
|
||||
<p>...or copy this link into your web browser:</p>
|
||||
|
||||
<p>%VALIDATION_LINK%</p>
|
||||
|
||||
<p>If your client requires a code, the code is %VALIDATION_TOKEN%</p>
|
||||
|
||||
<p>If you aren't aware of making such a request, please disregard this
|
||||
email.</p>
|
||||
|
||||
<br>
|
||||
<p>Regards,<br>
|
||||
%DOMAIN_PRETTY% Admins</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
--7REaIwWQCioQ6NaBlAQlg8ztbUQj6PKJ--
|
Reference in New Issue
Block a user