diff --git a/src/main/java/de/srsoftware/widerhall/Constants.java b/src/main/java/de/srsoftware/widerhall/Constants.java index 190cd86..b460f6f 100644 --- a/src/main/java/de/srsoftware/widerhall/Constants.java +++ b/src/main/java/de/srsoftware/widerhall/Constants.java @@ -5,6 +5,7 @@ public class Constants { public static final String BASE = "base"; public static final String BASE_URL = "base_url"; public static final String DB = "database"; + public static final String DOMAIN = "domain"; public static final String EMAIL = "email"; public static final String ERROR = "error"; public static final String HOST = "host"; @@ -17,6 +18,7 @@ public class Constants { public static final String NOTES = "notes"; public static final String PASSWORD = "password"; public static final Object PORT = "port"; + public static final String PREFIX = "prefix"; public static final String PROTOCOL = "mail.store.protocol"; public static final String STATE = "state"; public static final String USER = "user"; diff --git a/src/main/java/de/srsoftware/widerhall/data/MailingList.java b/src/main/java/de/srsoftware/widerhall/data/MailingList.java index 52a5a6d..bdb5493 100644 --- a/src/main/java/de/srsoftware/widerhall/data/MailingList.java +++ b/src/main/java/de/srsoftware/widerhall/data/MailingList.java @@ -66,6 +66,12 @@ public class MailingList { Database.open().query(sql.toString()).run(); } + public static void enable(String listEmail, boolean enable) throws SQLException { + // https://stackoverflow.com/questions/16440831/bitwise-xor-in-sqlite-bitwise-not-not-working-as-i-expect + String expression = enable ? "state = state | "+ENABLED : "state = (~(state & "+ENABLED+"))&(state|"+ENABLED+")"; + Database.open().query("UPDATE " + TABLE_NAME + " SET "+expression).where(EMAIL, listEmail).run(); + } + public static void hide(String listEmail, boolean hide) throws SQLException { // https://stackoverflow.com/questions/16440831/bitwise-xor-in-sqlite-bitwise-not-not-working-as-i-expect String expression = hide ? "state = (~(state & "+PUBLIC+"))&(state|"+PUBLIC+")" : ("state = state | "+PUBLIC); @@ -119,7 +125,8 @@ public class MailingList { public Map safeMap() { var map = new HashMap(); - map.put(EMAIL,email); + String[] parts = email.split("@", 2); + map.put(EMAIL,Map.of(PREFIX,parts[0],DOMAIN,parts[1])); map.put(NAME, name); if (imapHost != null) map.put(IMAP_HOST, imapHost); if (imapPort != 0) map.put(IMAP_PORT, imapPort); diff --git a/src/main/java/de/srsoftware/widerhall/web/Rest.java b/src/main/java/de/srsoftware/widerhall/web/Rest.java index 0329d32..a85dafc 100644 --- a/src/main/java/de/srsoftware/widerhall/web/Rest.java +++ b/src/main/java/de/srsoftware/widerhall/web/Rest.java @@ -22,6 +22,8 @@ import static de.srsoftware.widerhall.Util.t; public class Rest extends HttpServlet { private static final Logger LOG = LoggerFactory.getLogger(Rest.class); private static final String LIST_LIST = "list/list"; + private static final String LIST_DISABLE = "list/disable"; + private static final String LIST_ENABLE = "list/enable"; private static final String LIST_HIDE = "list/hide"; private static final String LIST_SHOW = "list/show"; private static final String USER_LIST = "user/list"; @@ -79,14 +81,25 @@ public class Rest extends HttpServlet { JSONObject json = new JSONObject(); var path = req.getPathInfo(); path = path == null ? INDEX : path.substring(1); + if (o instanceof User user){ json.put(USER,user.safeMap()); - switch (path) { + + var listEmail = req.getParameter(LIST); + if (listEmail == null || listEmail.isBlank()) { + json.putAll(Map.of(ERROR,"no list email provided!")); + } else switch (path) { + case LIST_DISABLE: + json.putAll(enableList(listEmail,user,false)); + break; + case LIST_ENABLE: + json.putAll(enableList(listEmail,user,true)); + break; case LIST_HIDE: - json.putAll(hideList(req,user,true)); + json.putAll(hideList(listEmail,user,true)); break; case LIST_SHOW: - json.putAll(hideList(req,user,false)); + json.putAll(hideList(listEmail,user,false)); break; default: json.put(ERROR,t("No handler for path '{}'!",path)); @@ -104,9 +117,22 @@ public class Rest extends HttpServlet { } } - private Map hideList(HttpServletRequest req, User user, boolean hide) { - var listEmail = req.getParameter(LIST); - if (listEmail == null || listEmail.isBlank()) return Map.of(ERROR,"no list email provided!"); + private Map enableList(String listEmail, User user, boolean enable) { + if (user.is(ADMIN) || ListMember.listsOwnedBy(user).contains(listEmail)){ + try { + MailingList.enable(listEmail,enable); + return Map.of("success",t("Mailing list '{}' was {}!",listEmail,enable ? "enabled" : "disabled")); + } catch (SQLException e) { + LOG.error("Failed to enable/disable mailing list: ",e); + return Map.of("error",t("Failed to update list '{}'",listEmail)); + } + + } else { + return Map.of("error",t("You are not allowed to edit '{}'",listEmail)); + } + } + + private Map hideList(String listEmail, User user, boolean hide) { if (user.is(ADMIN) || ListMember.listsOwnedBy(user).contains(listEmail)){ try { MailingList.hide(listEmail,hide); diff --git a/static/templates/admin.st b/static/templates/admin.st index d2fb414..a6652a4 100644 --- a/static/templates/admin.st +++ b/static/templates/admin.st @@ -11,7 +11,7 @@ «userinfo()»

Widerhall Administration

«messages()» - «userlist()» «listadminlist()» + «userlist()» \ No newline at end of file diff --git a/static/templates/css.st b/static/templates/css.st index 0a28940..97936e7 100644 --- a/static/templates/css.st +++ b/static/templates/css.st @@ -24,6 +24,9 @@ h1 { background: yellow; } +.right{ + text-align: right +} .user{ background: lime; float: right; diff --git a/static/templates/js.st b/static/templates/js.st index c249afb..77985d3 100644 --- a/static/templates/js.st +++ b/static/templates/js.st @@ -1,5 +1,5 @@ function disableList(listEmail){ - console.log('disableList('+listEmail+')'); + $.post('/api/list/disable',{list:listEmail},showListResult,'json'); } function dropList(listEmail){ @@ -7,11 +7,11 @@ function dropList(listEmail){ } function enableList(listEmail){ - console.log('enableList('+listEmail+')'); + $.post('/api/list/enable',{list:listEmail},showListResult,'json'); } function hideList(listEmail){ - $.post('/api/list/hide',{list:listEmail},showListResult,'json'); + $.post('/api/list/hide',{list:listEmail},showListResult,'json'); } function loadListAdminList(){ @@ -42,12 +42,13 @@ function showListAdminList(data){ for (let i in data.lists){ let list = data.lists[i]; let row = $(''); + let addr = list.email.prefix+'@'+list.email.domain; $('').text(list.name).appendTo(row); - $('').text(list.email).appendTo(row); + $('').text(addr).appendTo(row); $('').text(list.state).appendTo(row); - let select = $('',{name:addr}).change(function () { let action = $(this).children("option:selected").val(); let list = $(this).attr('name'); if (confirm("This will "+action+" '"+list+"'. Are you sure?"))self[action+'List'](list); @@ -76,10 +77,14 @@ function showListList(data){ for (let i in data.lists){ let list = data.lists[i]; let row = $(''); + let subBtn = $('