Browse Source

Merge branch 'main' into lang_de

lang_de
Stephan Richter 2 years ago
parent
commit
fef9b78841
  1. 3
      .gitignore
  2. 2
      pom.xml
  3. 3
      src/main/java/de/srsoftware/widerhall/Constants.java
  4. 24
      src/main/java/de/srsoftware/widerhall/data/ListMember.java
  5. 28
      src/main/java/de/srsoftware/widerhall/data/MailingList.java
  6. 6
      src/main/java/de/srsoftware/widerhall/web/TemplateServlet.java
  7. 11
      src/main/java/de/srsoftware/widerhall/web/Web.java
  8. 17
      static/templates/confirmation_mail.st
  9. 6
      static/templates/subscribe_mail.st

3
.gitignore vendored

@ -3,4 +3,5 @@ archive
target target
config/config.json config/config.json
*.sqlite3 *.sqlite3
jquery-3.6.0.min.js jquery-3.6.0.min.js
src/main/resources/logback-test.xml

2
pom.xml

@ -6,7 +6,7 @@
<groupId>org.example</groupId> <groupId>org.example</groupId>
<artifactId>Widerhall</artifactId> <artifactId>Widerhall</artifactId>
<version>0.2.31</version> <version>0.2.32</version>
<build> <build>
<plugins> <plugins>
<plugin> <plugin>

3
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 SUBJECT = "subject";
public static final String TEXT = "text"; public static final String TEXT = "text";
public static final String TOKEN = "token"; public static final String TOKEN = "token";
public static final String URL = "url";
public static final String USER = "user"; public static final String USER = "user";
public static final String VARCHAR = "VARCHAR(255)"; public static final String VARCHAR = "VARCHAR(255)";
} }

24
src/main/java/de/srsoftware/widerhall/data/ListMember.java

@ -1,10 +1,13 @@
package de.srsoftware.widerhall.data; package de.srsoftware.widerhall.data;
import de.srsoftware.widerhall.Configuration;
import de.srsoftware.widerhall.Util; import de.srsoftware.widerhall.Util;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.stringtemplate.v4.ST;
import javax.ws.rs.HEAD; import javax.mail.MessagingException;
import java.io.UnsupportedEncodingException;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.*; import java.util.*;
@ -88,7 +91,7 @@ public class ListMember {
* @return * @return
* @throws SQLException * @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(); var rs = Database.open().select(TABLE_NAME).where(TOKEN,token).compile().exec();
if (rs.next()){ if (rs.next()){
var lm = ListMember.from(rs); var lm = ListMember.from(rs);
@ -104,12 +107,25 @@ public class ListMember {
.compile() .compile()
.run(); .run();
} }
return lm.user; return lm;
} }
return null; return null;
} }
public void sendConfirmationMail(ST template) throws SQLException, MessagingException {
var subject = t("[{}] Abonnement abgeschlossen!",list.name());
var data = new HashMap<String,Object>();
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. * 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. * If the member has the state AWAITING_CONFIRMATION, a token is assigned with the member, too.

28
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 de.srsoftware.widerhall.mail.SmtpClient;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.stringtemplate.v4.ST;
import javax.mail.*; import javax.mail.*;
import javax.mail.internet.AddressException; import javax.mail.internet.AddressException;
@ -61,6 +62,7 @@ public class MailingList implements MessageHandler, ProblemListener {
private static final int DEFAULT_STATE = STATE_PENDING|STATE_HIDE_RECEIVERS|STATE_PUBLIC_ARCHIVE; 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 RETAINED_FOLDER = "retained";
private static final String LAST_ERROR = "last_error"; private static final String LAST_ERROR = "last_error";
private static final String LIST_NAME = "list_name";
private String email, name, lastError; private String email, name, lastError;
private int state; private int state;
private SmtpClient smtp; private SmtpClient smtp;
@ -533,21 +535,6 @@ public class MailingList implements MessageHandler, ProblemListener {
return this; 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("Bitte bestätigen Sie ihr Listen-Abonnement");
var config = Configuration.instance();
var url = new StringBuilder(config.baseUrl()).append("/web/confirm?token=").append(token);
var text = t("Botte gehen Sie zu {} um das Abonnieren der Liste abzuschließen!",url);
smtp.send(email(),name(),user.email(),subject,text);
}
private void sentRetentionNotification(String senderEmail) { private void sentRetentionNotification(String senderEmail) {
try { try {
var receivers = members() var receivers = members()
@ -642,17 +629,24 @@ public class MailingList implements MessageHandler, ProblemListener {
* @throws SQLException * @throws SQLException
* @throws MessagingException * @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 state = skipConfirmation ? ListMember.STATE_SUBSCRIBER : ListMember.STATE_AWAITING_CONFIRMATION;
var member = ListMember.create(this,user,state); var member = ListMember.create(this,user,state);
if (skipConfirmation) return; if (skipConfirmation) return;
try { 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) { } catch (UnsupportedEncodingException e) {
throw new MessagingException(t("Senden der Email an {} fehlgeschlagen",user.email()),e); throw new MessagingException(t("Senden der Email an {} fehlgeschlagen",user.email()),e);
} }
} }
protected SmtpClient smtp(){
return smtp;
}
private String stamp() { private String stamp() {
return "["+name+"]"; return "["+name+"]";

6
src/main/java/de/srsoftware/widerhall/web/TemplateServlet.java

@ -1,6 +1,7 @@
package de.srsoftware.widerhall.web; package de.srsoftware.widerhall.web;
import de.srsoftware.widerhall.Configuration; import de.srsoftware.widerhall.Configuration;
import org.stringtemplate.v4.ST;
import org.stringtemplate.v4.STGroup; import org.stringtemplate.v4.STGroup;
import org.stringtemplate.v4.STRawGroupDir; import org.stringtemplate.v4.STRawGroupDir;
@ -8,7 +9,6 @@ import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files; import java.nio.file.Files;
import java.util.Map; import java.util.Map;
@ -24,6 +24,10 @@ public abstract class TemplateServlet extends HttpServlet {
loadTemplates(); loadTemplates();
} }
protected ST getTemplate(String name){
return templates.getInstanceOf(name);
}
protected String loadFile(String filename, HttpServletResponse resp) { protected String loadFile(String filename, HttpServletResponse resp) {
var path = String.join(File.separator,baseDir,"static",filename); var path = String.join(File.separator,baseDir,"static",filename);
var file = new File(path); var file = new File(path);

11
src/main/java/de/srsoftware/widerhall/web/Web.java

@ -11,6 +11,7 @@ import org.slf4j.LoggerFactory;
import javax.mail.MessagingException; import javax.mail.MessagingException;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.HEAD;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
import java.security.InvalidKeyException; import java.security.InvalidKeyException;
@ -142,8 +143,12 @@ public class Web extends TemplateServlet {
try { try {
var token = req.getParameter(TOKEN); var token = req.getParameter(TOKEN);
if (token== null || token.isBlank()) return t("Ungültiger oder fehlender Token!"); if (token== null || token.isBlank()) return t("Ungültiger oder fehlender Token!");
var user = ListMember.confirm(token); var listMember = ListMember.confirm(token);
if (user != null) return loadTemplate(INDEX,Map.of(USER,user.safeMap(),NOTES,"Listen-Mitgliedschaft bestätigt!"),resp); if (listMember != null) {
listMember.sendConfirmationMail(getTemplate("confirmation_mail"));
return loadTemplate(INDEX,Map.of(USER,listMember.user().safeMap(),NOTES,"Listen-Mitgliedschaft bestätigt!"),resp);
}
return t("Nutzer oder Token unbekannt"); return t("Nutzer oder Token unbekannt");
} catch (Exception e) { } catch (Exception e) {
LOG.debug("Bestätigung des Listen-Abonnements fehlgeschlagen:",e); LOG.debug("Bestätigung des Listen-Abonnements fehlgeschlagen:",e);
@ -517,7 +522,7 @@ public class Web extends TemplateServlet {
} }
try { try {
list.requestSubscription(user,skipConfirmation); list.requestSubscription(user,skipConfirmation,getTemplate("subscribe_mail"));
if (skipConfirmation) { if (skipConfirmation) {
data.put(NOTES, t("'{}' hat die Mailingliste '{}' erfolgreich abonniert.", user.email(), list.email())); data.put(NOTES, t("'{}' hat die Mailingliste '{}' erfolgreich abonniert.", user.email(), list.email()));
} else { } else {

17
static/templates/confirmation_mail.st

@ -0,0 +1,17 @@
Willkommen, «data.user.name»!
Du hast die «data.list.name»-Liste erfolgreich abonniert!
«if(data.open_list)»
Dabei handelt es sich um eine offene Liste. Das bedeutet, du kannst jederzeit E-Mails an «data.list.email» senden, und wir werden diese an alle anderen Abonnenten weiterleiten.
«else»
Dabei handelt es sich um eine moderierte Liste. Das bedeutet, du (und alle anderen Abonnenten) empfangen die Mails von den Moderatoren. Wenn du jedoch auf Mails von der Liste antwortest, wird deine Antwort auch nur an die Moderatoren zugestelt!
«endif»
Wenn du ausschließlich dem Absender einer Email, die über die Liste kam, antworten willst, findest du die entsprechende adresse im Betreff der empfangenen E-Mail.
Wenn du die Liste verlassen willst, kannst du jederzeit zu «data.url» gehen um dein Abonnement zu kündigen.
liebe Grüße,
Stephan Richter (der Software-Autor)

6
static/templates/subscribe_mail.st

@ -0,0 +1,6 @@
Willkommen beim Abo-Service der Mailing-Liste «list_name»!
Jemand wahrscheinlich du selbst hat versucht deine E-Mail bei der Liste zu registrieren!
Falls du das wars, gehe bitte zu «url» , um dein Abonnement abzuschließen!
Falls du dich gar nicht bei dieser Liste eintragen wolltest, kannst du die Mail einfach ignorieren.
Loading…
Cancel
Save