From 19c20816f8d074d7156f01edd309631cb82057c7 Mon Sep 17 00:00:00 2001 From: Stephan Richter Date: Sat, 23 Apr 2022 16:56:36 +0200 Subject: [PATCH] confirmation mail now template based. --- .gitignore | 3 +- pom.xml | 2 +- .../de/srsoftware/widerhall/Constants.java | 3 +- .../srsoftware/widerhall/data/ListMember.java | 23 +++++++++++++-- .../widerhall/data/MailingList.java | 28 ++++++++----------- .../widerhall/web/TemplateServlet.java | 6 +++- .../java/de/srsoftware/widerhall/web/Web.java | 10 +++++-- static/templates/confirmation_mail.st | 17 +++++++++++ static/templates/subscribe_mail.st | 6 ++++ 9 files changed, 70 insertions(+), 28 deletions(-) create mode 100644 static/templates/confirmation_mail.st create mode 100644 static/templates/subscribe_mail.st diff --git a/.gitignore b/.gitignore index 9f758d2..89546fa 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,5 @@ archive target config/config.json *.sqlite3 -jquery-3.6.0.min.js \ No newline at end of file +jquery-3.6.0.min.js +src/main/resources/logback-test.xml \ No newline at end of file diff --git a/pom.xml b/pom.xml index 4856ed2..6b9afda 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ org.example Widerhall - 0.2.31 + 0.2.32 diff --git a/src/main/java/de/srsoftware/widerhall/Constants.java b/src/main/java/de/srsoftware/widerhall/Constants.java index fc3ca19..dae10b7 100644 --- a/src/main/java/de/srsoftware/widerhall/Constants.java +++ b/src/main/java/de/srsoftware/widerhall/Constants.java @@ -28,8 +28,7 @@ public class Constants { public static final String SUBJECT = "subject"; public static final String TEXT = "text"; public static final String TOKEN = "token"; + public static final String URL = "url"; public static final String USER = "user"; public static final String VARCHAR = "VARCHAR(255)"; - - } diff --git a/src/main/java/de/srsoftware/widerhall/data/ListMember.java b/src/main/java/de/srsoftware/widerhall/data/ListMember.java index f17f8b7..967f967 100644 --- a/src/main/java/de/srsoftware/widerhall/data/ListMember.java +++ b/src/main/java/de/srsoftware/widerhall/data/ListMember.java @@ -1,9 +1,13 @@ package de.srsoftware.widerhall.data; +import de.srsoftware.widerhall.Configuration; import de.srsoftware.widerhall.Util; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.stringtemplate.v4.ST; +import javax.mail.MessagingException; +import java.io.UnsupportedEncodingException; import java.sql.ResultSet; import java.sql.SQLException; import java.util.*; @@ -87,7 +91,7 @@ public class ListMember { * @return * @throws SQLException */ - public static User confirm(String token) throws SQLException { + public static ListMember confirm(String token) throws SQLException { var rs = Database.open().select(TABLE_NAME).where(TOKEN,token).compile().exec(); if (rs.next()){ var lm = ListMember.from(rs); @@ -103,12 +107,25 @@ public class ListMember { .compile() .run(); } - return lm.user; + return lm; } return null; } - + public void sendConfirmationMail(ST template) throws SQLException, MessagingException { + var subject = t("[{}] Subscription complete!",list.name()); + var data = new HashMap(); + data.put(USER,user.safeMap()); + data.put(LIST,list.minimalMap()); + data.put(URL,Configuration.instance().baseUrl()+"/web/index"); + if (list.isOpenForSubscribers()) data.put("open_list",true); + var text = template.add("data",data).render(); + try { + list.smtp().send(list.email(),list.name(),user.email(),subject,text); + } catch (UnsupportedEncodingException e) { + LOG.warn("Failed to send list subscription confirmation!",e); + } + } /** * Create a new list member entry in the database. * If the member has the state AWAITING_CONFIRMATION, a token is assigned with the member, too. diff --git a/src/main/java/de/srsoftware/widerhall/data/MailingList.java b/src/main/java/de/srsoftware/widerhall/data/MailingList.java index 5d3fcd0..33ad39c 100644 --- a/src/main/java/de/srsoftware/widerhall/data/MailingList.java +++ b/src/main/java/de/srsoftware/widerhall/data/MailingList.java @@ -7,6 +7,7 @@ import de.srsoftware.widerhall.mail.ProblemListener; import de.srsoftware.widerhall.mail.SmtpClient; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.stringtemplate.v4.ST; import javax.mail.*; import javax.mail.internet.AddressException; @@ -60,6 +61,7 @@ public class MailingList implements MessageHandler, ProblemListener { private static final int DEFAULT_STATE = STATE_PENDING|STATE_HIDE_RECEIVERS|STATE_PUBLIC_ARCHIVE; private static final String RETAINED_FOLDER = "retained"; private static final String LAST_ERROR = "last_error"; + private static final String LIST_NAME = "list_name"; private String email, name, lastError; private int state; private SmtpClient smtp; @@ -532,21 +534,6 @@ public class MailingList implements MessageHandler, ProblemListener { return this; } - /** - * send an email to a potential subscriber asking for confirmation - * @param user - * @param token - * @throws MessagingException - * @throws UnsupportedEncodingException - */ - private void sendConfirmationRequest(User user, String token) throws MessagingException, UnsupportedEncodingException { - var subject = t("Please confirm your list subscription"); - var config = Configuration.instance(); - var url = new StringBuilder(config.baseUrl()).append("/web/confirm?token=").append(token); - var text = t("Please go to {} in order to complete your list subscription!",url); - smtp.send(email(),name(),user.email(),subject,text); - } - private void sentRetentionNotification(String senderEmail) { try { var receivers = members() @@ -641,17 +628,24 @@ public class MailingList implements MessageHandler, ProblemListener { * @throws SQLException * @throws MessagingException */ - public void requestSubscription(User user, boolean skipConfirmation) throws SQLException, MessagingException { + public void requestSubscription(User user, boolean skipConfirmation, ST template) throws SQLException, MessagingException { var state = skipConfirmation ? ListMember.STATE_SUBSCRIBER : ListMember.STATE_AWAITING_CONFIRMATION; var member = ListMember.create(this,user,state); if (skipConfirmation) return; try { - sendConfirmationRequest(user, member.token()); + var config = Configuration.instance(); + var url = new StringBuilder(config.baseUrl()).append("/web/confirm?token=").append(member.token()).toString(); + var subject = t("[{}] Please confirm your list subscription",name()); + var text = template.add(URL,url).add(LIST_NAME,name()).render(); + smtp.send(email(),name(),user.email(),subject,text); } catch (UnsupportedEncodingException e) { throw new MessagingException(t("Failed to send email to {}",user.email()),e); } } + protected SmtpClient smtp(){ + return smtp; + } private String stamp() { return "["+name+"]"; diff --git a/src/main/java/de/srsoftware/widerhall/web/TemplateServlet.java b/src/main/java/de/srsoftware/widerhall/web/TemplateServlet.java index 43eacbf..bd55559 100644 --- a/src/main/java/de/srsoftware/widerhall/web/TemplateServlet.java +++ b/src/main/java/de/srsoftware/widerhall/web/TemplateServlet.java @@ -1,6 +1,7 @@ package de.srsoftware.widerhall.web; import de.srsoftware.widerhall.Configuration; +import org.stringtemplate.v4.ST; import org.stringtemplate.v4.STGroup; import org.stringtemplate.v4.STRawGroupDir; @@ -8,7 +9,6 @@ import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletResponse; import java.io.File; import java.io.IOException; -import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.util.Map; @@ -24,6 +24,10 @@ public abstract class TemplateServlet extends HttpServlet { loadTemplates(); } + protected ST getTemplate(String name){ + return templates.getInstanceOf(name); + } + protected String loadFile(String filename, HttpServletResponse resp) { var path = String.join(File.separator,baseDir,"static",filename); var file = new File(path); diff --git a/src/main/java/de/srsoftware/widerhall/web/Web.java b/src/main/java/de/srsoftware/widerhall/web/Web.java index 2e76d6f..792547b 100644 --- a/src/main/java/de/srsoftware/widerhall/web/Web.java +++ b/src/main/java/de/srsoftware/widerhall/web/Web.java @@ -142,8 +142,12 @@ public class Web extends TemplateServlet { try { var token = req.getParameter(TOKEN); if (token== null || token.isBlank()) return t("Invalid or missing token!"); - var user = ListMember.confirm(token); - if (user != null) return loadTemplate(INDEX,Map.of(USER,user.safeMap(),NOTES,"Confirmed list subscription!"),resp); + var listMember = ListMember.confirm(token); + if (listMember != null) { + listMember.sendConfirmationMail(getTemplate("confirmation_mail")); + + return loadTemplate(INDEX,Map.of(USER,listMember.user().safeMap(),NOTES,"Confirmed list subscription!"),resp); + } return t("Unknown user or token"); } catch (Exception e) { LOG.debug("Failed to confirm list membership:",e); @@ -517,7 +521,7 @@ public class Web extends TemplateServlet { } try { - list.requestSubscription(user,skipConfirmation); + list.requestSubscription(user,skipConfirmation,getTemplate("subscribe_mail")); if (skipConfirmation) { data.put(NOTES, t("Successfully subscribed '{}' to '{}'.", user.email(), list.email())); } else { diff --git a/static/templates/confirmation_mail.st b/static/templates/confirmation_mail.st new file mode 100644 index 0000000..9b1afb8 --- /dev/null +++ b/static/templates/confirmation_mail.st @@ -0,0 +1,17 @@ +Welcome, «data.user.name»! + +You successfully subscribed to the "«data.list.name»" Mailing list! + +«if(data.open_list)» +This is an open list. This means you may, at any time, send emails to «data.list.email» and we will forward your mail to the other subscribers. +«else» +This is a moderated list. This means, you (and all other subscribers) will receive any mails sent by a moderator. However, if you write (answer) messages to the list, only the moderators will receive your mail. +«endif» + +If you want to answer exclusively to the author of an email you received via the list, you may find the respective address in the subject line of the received email. + +If you wish to leave the list, you may, at any time, go to «data.url» and un-subscribe. + +best wishes, + +Stephan Richter (the software author) \ No newline at end of file diff --git a/static/templates/subscribe_mail.st b/static/templates/subscribe_mail.st new file mode 100644 index 0000000..d28fe7b --- /dev/null +++ b/static/templates/subscribe_mail.st @@ -0,0 +1,6 @@ +Welcome to the "«list_name»" Mailing list subscription! + +Someone, probably you, tried to register your email address! +If that was you, go to «url» in order to complete your list subscription. + +If you did not wish to subscribe to the list, you may ignore this mail. \ No newline at end of file