From 26ed351bbc59767be8ce2500cbb5250de63df5c9 Mon Sep 17 00:00:00 2001 From: Vitaly Takmazov Date: Sat, 3 Sep 2016 11:06:41 +0300 Subject: Juick settings --- .../java/com/juick/server/CrosspostQueries.java | 37 ++- .../com/juick/server/SubscriptionsQueries.java | 25 ++ .../main/java/com/juick/server/UserQueries.java | 66 +++++- .../juick/server/helpers/ApplicationStatus.java | 25 ++ .../main/java/com/juick/server/helpers/Auth.java | 22 ++ .../java/com/juick/server/helpers/EmailOpts.java | 24 ++ .../java/com/juick/server/helpers/NotifyOpts.java | 34 +++ .../java/com/juick/server/helpers/UserInfo.java | 43 ++++ juick-www/build.gradle | 3 +- juick-www/src/main/java/com/juick/www/Main.java | 15 +- .../src/main/java/com/juick/www/PageTemplates.java | 3 - .../src/main/java/com/juick/www/Settings.java | 264 +++++++++++++++++---- .../resources/views/partial/settings_tabs.html | 5 + .../src/main/resources/views/settings_about.html | 20 ++ .../main/resources/views/settings_auth-email.html | 9 + .../src/main/resources/views/settings_main.html | 156 ++++++++++++ .../main/resources/views/settings_password.html | 17 ++ .../src/main/resources/views/settings_privacy.html | 9 + .../src/main/resources/views/settings_result.html | 9 + juick-www/src/main/static/style.css | 4 + 20 files changed, 734 insertions(+), 56 deletions(-) create mode 100644 juick-core/src/main/java/com/juick/server/helpers/ApplicationStatus.java create mode 100644 juick-core/src/main/java/com/juick/server/helpers/Auth.java create mode 100644 juick-core/src/main/java/com/juick/server/helpers/EmailOpts.java create mode 100644 juick-core/src/main/java/com/juick/server/helpers/NotifyOpts.java create mode 100644 juick-core/src/main/java/com/juick/server/helpers/UserInfo.java create mode 100644 juick-www/src/main/resources/views/partial/settings_tabs.html create mode 100644 juick-www/src/main/resources/views/settings_about.html create mode 100644 juick-www/src/main/resources/views/settings_auth-email.html create mode 100644 juick-www/src/main/resources/views/settings_main.html create mode 100644 juick-www/src/main/resources/views/settings_password.html create mode 100644 juick-www/src/main/resources/views/settings_privacy.html create mode 100644 juick-www/src/main/resources/views/settings_result.html diff --git a/juick-core/src/main/java/com/juick/server/CrosspostQueries.java b/juick-core/src/main/java/com/juick/server/CrosspostQueries.java index 04898d0a..827dad09 100644 --- a/juick-core/src/main/java/com/juick/server/CrosspostQueries.java +++ b/juick-core/src/main/java/com/juick/server/CrosspostQueries.java @@ -17,6 +17,7 @@ */ package com.juick.server; +import com.juick.server.helpers.ApplicationStatus; import org.apache.commons.lang3.tuple.Pair; import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.jdbc.core.JdbcTemplate; @@ -32,9 +33,7 @@ public class CrosspostQueries { public static Optional> getTwitterTokens(JdbcTemplate sql, int uid) { try { return sql.queryForObject("SELECT access_token,access_token_secret FROM twitter WHERE user_id=? AND crosspost=1", - (rs, num) -> { - return Optional.of(Pair.of(rs.getString(1), rs.getString(2))); - }, uid); + (rs, num) -> Optional.of(Pair.of(rs.getString(1), rs.getString(2))), uid); } catch (EmptyResultDataAccessException e) { return Optional.empty(); } @@ -48,13 +47,39 @@ public class CrosspostQueries { return Optional.empty(); } } + public static ApplicationStatus isFBCrossPostEnabled(JdbcTemplate sql, int uid) { + try { + return sql.queryForObject("SELECT 1, crosspost FROM facebook WHERE user_id=? LIMIT 1", (rs, num) -> { + ApplicationStatus status = new ApplicationStatus(); + status.setConnected(rs.getInt(1) > 0); + status.setCrosspostEnabled(rs.getBoolean(2)); + return status; + }, uid); + } catch (EmptyResultDataAccessException e) { + return new ApplicationStatus(); + } + } + + public static String getTwitterName(JdbcTemplate sql, int uid) { + try { + return sql.queryForObject("SELECT uname FROM twitter WHERE user_id=?", String.class, uid); + } catch (EmptyResultDataAccessException e) { + return ""; + } + } + + public static String getTelegramName(JdbcTemplate sql, int uid) { + try { + return sql.queryForObject("SELECT tg_name FROM telegram WHERE user_id=?", String.class, uid); + } catch (EmptyResultDataAccessException e) { + return ""; + } + } public static Optional> getVKTokens(JdbcTemplate sql, int uid) { try { return sql.queryForObject("SELECT vk_id,access_token FROM vk WHERE user_id=? AND crosspost=1", - (rs, num) -> { - return Optional.of(Pair.of(rs.getString(1), rs.getString(2))); - }, uid); + (rs, num) -> Optional.of(Pair.of(rs.getString(1), rs.getString(2))), uid); } catch (EmptyResultDataAccessException e) { return Optional.empty(); } diff --git a/juick-core/src/main/java/com/juick/server/SubscriptionsQueries.java b/juick-core/src/main/java/com/juick/server/SubscriptionsQueries.java index cedd2fd4..9a09a5cd 100644 --- a/juick-core/src/main/java/com/juick/server/SubscriptionsQueries.java +++ b/juick-core/src/main/java/com/juick/server/SubscriptionsQueries.java @@ -6,6 +6,8 @@ package com.juick.server; import com.juick.Tag; import com.juick.User; +import com.juick.server.helpers.NotifyOpts; +import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.util.StringUtils; @@ -97,4 +99,27 @@ public class SubscriptionsQueries { toTag.TID, user.getUID()) > 0; } + public static NotifyOpts getNotifyOptions(JdbcTemplate sql, User user) { + try { + return sql.queryForObject("SELECT jnotify,subscr_notify,recommendations FROM useroptions WHERE user_id=?", + (rs, num) -> { + NotifyOpts options = new NotifyOpts(); + options.setRepliesEnabled(rs.getInt(1) > 0); + options.setSubscriptionsEnabled(rs.getInt(2) > 0); + options.setRecommendationsEnabled(rs.getInt(3) > 0); + return options; + }, user.getUID()); + } catch (EmptyResultDataAccessException e) { + return new NotifyOpts(); + } + } + + public static boolean setNotifyOptions(JdbcTemplate sql, User user, NotifyOpts options) { + return sql.update("UPDATE useroptions SET jnotify=? WHERE user_id=?", options.isRepliesEnabled() ? 1 : 0, + user.getUID()) > 0 && + sql.update("UPDATE useroptions SET subscr_notify=? WHERE user_id=?", options.isSubscriptionsEnabled() ? 1 : 0, + user.getUID()) > 0 && + sql.update("UPDATE useroptions SET recommendations=? WHERE user_id=?", options.isRecommendationsEnabled() ? 1 : 0, + user.getUID()) > 0; + } } diff --git a/juick-core/src/main/java/com/juick/server/UserQueries.java b/juick-core/src/main/java/com/juick/server/UserQueries.java index b79f179c..50e3562f 100644 --- a/juick-core/src/main/java/com/juick/server/UserQueries.java +++ b/juick-core/src/main/java/com/juick/server/UserQueries.java @@ -18,6 +18,9 @@ package com.juick.server; import com.juick.User; +import com.juick.server.helpers.Auth; +import com.juick.server.helpers.EmailOpts; +import com.juick.server.helpers.UserInfo; import org.springframework.dao.DuplicateKeyException; import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.jdbc.core.JdbcTemplate; @@ -31,7 +34,6 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.*; -import java.util.stream.Collectors; /** * @@ -242,6 +244,18 @@ public class UserQueries { } } + public static boolean updatePassword(JdbcTemplate sql, User user, String newPassword) { + return user.getUID() > 0 && sql.update("UPDATE users SET passw=? WHERE id=?", newPassword, user.getUID()) > 0; + } + + public static String updateSecretEmail(JdbcTemplate sql, User user) { + String newHash = generateHash(16); + if (sql.update("INSERT INTO mail(user_id,hash) VALUES (?,?) ON DUPLICATE KEY UPDATE hash=?", user.getUID(), newHash, newHash) > 0) { + return newHash; + } + return ""; + } + public static int getUserOptionInt(JdbcTemplate sql, int uid, String option, int defaultValue) { try { return sql.queryForObject("SELECT " + option + " FROM useroptions WHERE user_id=?", Integer.class, uid); @@ -254,6 +268,28 @@ public class UserQueries { sql.update("UPDATE useroptions SET " + option + "=? WHERE user_id=?", value, uid); } + public static UserInfo getUserInfo(JdbcTemplate sql, User user) { + try { + return sql.queryForObject("SELECT fullname,country,url,descr FROM usersinfo WHERE user_id=?", ((rs, rowNum) -> { + UserInfo info = new UserInfo(); + info.setFullName(rs.getString(1)); + info.setCountry(rs.getString(2)); + info.setUrl(rs.getString(3)); + info.setDescription(rs.getString(4)); + return info; + }), user.getUID()); + } catch (EmptyResultDataAccessException e) { + return new UserInfo(); + } + } + + public static boolean updateUserInfo(JdbcTemplate sql, User user, UserInfo info) { + return sql.update("INSERT INTO usersinfo(user_id,fullname,country,url,descr) VALUES (?,?,?,?,?) " + + "ON DUPLICATE KEY UPDATE fullname=?,country=?,url=?,descr=?", user.getUID(), info.getFullName(), + info.getCountry(), info.getUrl(), info.getDescription(), info.getFullName(), + info.getCountry(), info.getUrl(), info.getDescription()) > 0; + } + public static boolean getCanMedia(JdbcTemplate sql, int uid) { try { int res = sql.queryForObject("SELECT users.lastphoto-UNIX_TIMESTAMP() FROM users WHERE id=?", @@ -429,4 +465,32 @@ public class UserQueries { } return false; } + public static List getAllJIDs(JdbcTemplate sql, User user) { + return sql.queryForList("SELECT jid FROM jids WHERE user_id=?", String.class, user.getUID()); + } + public static List getAuthCodes(JdbcTemplate sql, User user) { + return sql.query("SELECT account,authcode FROM auth WHERE user_id=? AND protocol='xmpp'", + (rs, num) -> new Auth(rs.getString(1), rs.getString(2)), user.getUID()); + } + + public static List getEmails(JdbcTemplate sql, User user) { + return sql.queryForList("SELECT email FROM emails WHERE user_id=?", String.class, user.getUID()); + } + + public static EmailOpts getEmailOpts(JdbcTemplate sql, User user) { + try { + return sql.queryForObject("SELECT email,subscr_hour FROM emails WHERE user_id=? AND subscr_hour IS NOT NULL", + (rs, num) ->new EmailOpts(rs.getString(1), rs.getInt(2)), user.getUID()); + } catch (EmptyResultDataAccessException e) { + return null; + } + } + public static String getEmailHash(JdbcTemplate sql, User user) { + try { + return sql.queryForObject("SELECT hash FROM mail WHERE user_id=?", String.class, user.getUID()) + + "@mail.juick.com"; + } catch (EmptyResultDataAccessException e) { + return ""; + } + } } diff --git a/juick-core/src/main/java/com/juick/server/helpers/ApplicationStatus.java b/juick-core/src/main/java/com/juick/server/helpers/ApplicationStatus.java new file mode 100644 index 00000000..986c8275 --- /dev/null +++ b/juick-core/src/main/java/com/juick/server/helpers/ApplicationStatus.java @@ -0,0 +1,25 @@ +package com.juick.server.helpers; + +/** + * Created by vt on 03/09/16. + */ +public class ApplicationStatus { + private boolean connected; + private boolean crosspostEnabled; + + public boolean isConnected() { + return connected; + } + + public void setConnected(boolean connected) { + this.connected = connected; + } + + public boolean isCrosspostEnabled() { + return crosspostEnabled; + } + + public void setCrosspostEnabled(boolean crosspostEnabled) { + this.crosspostEnabled = crosspostEnabled; + } +} diff --git a/juick-core/src/main/java/com/juick/server/helpers/Auth.java b/juick-core/src/main/java/com/juick/server/helpers/Auth.java new file mode 100644 index 00000000..3e1f0bd9 --- /dev/null +++ b/juick-core/src/main/java/com/juick/server/helpers/Auth.java @@ -0,0 +1,22 @@ +package com.juick.server.helpers; + +/** + * Created by vt on 09/02/16. + */ +public class Auth { + private String account; + private String authCode; + + public Auth(String account, String authCode) { + this.account = account; + this.authCode = authCode; + } + + public String getAccount() { + return account; + } + + public String getAuthCode() { + return authCode; + } +} \ No newline at end of file diff --git a/juick-core/src/main/java/com/juick/server/helpers/EmailOpts.java b/juick-core/src/main/java/com/juick/server/helpers/EmailOpts.java new file mode 100644 index 00000000..679d1a8d --- /dev/null +++ b/juick-core/src/main/java/com/juick/server/helpers/EmailOpts.java @@ -0,0 +1,24 @@ +package com.juick.server.helpers; + +import org.apache.commons.lang3.StringUtils; + +/** + * Created by vitalyster on 09.02.2016. + */ +public class EmailOpts { + private String email; + private String subscriptionHour; + + public EmailOpts(String email, int subscriptionHour) { + this.email = email; + this.subscriptionHour = StringUtils.leftPad(String.format("%d", subscriptionHour), 2, "0"); + } + + public String getSubscriptionHour() { + return subscriptionHour; + } + + public String getEmail() { + return email; + } +} \ No newline at end of file diff --git a/juick-core/src/main/java/com/juick/server/helpers/NotifyOpts.java b/juick-core/src/main/java/com/juick/server/helpers/NotifyOpts.java new file mode 100644 index 00000000..377b0a50 --- /dev/null +++ b/juick-core/src/main/java/com/juick/server/helpers/NotifyOpts.java @@ -0,0 +1,34 @@ +package com.juick.server.helpers; + +/** + * Created by vt on 03/09/16. + */ +public class NotifyOpts { + private boolean repliesEnabled; + private boolean subscriptionsEnabled; + private boolean recommendationsEnabled; + + public boolean isRepliesEnabled() { + return repliesEnabled; + } + + public void setRepliesEnabled(boolean repliesEnabled) { + this.repliesEnabled = repliesEnabled; + } + + public boolean isSubscriptionsEnabled() { + return subscriptionsEnabled; + } + + public void setSubscriptionsEnabled(boolean subscriptionsEnabled) { + this.subscriptionsEnabled = subscriptionsEnabled; + } + + public boolean isRecommendationsEnabled() { + return recommendationsEnabled; + } + + public void setRecommendationsEnabled(boolean recommendationsEnabled) { + this.recommendationsEnabled = recommendationsEnabled; + } +} diff --git a/juick-core/src/main/java/com/juick/server/helpers/UserInfo.java b/juick-core/src/main/java/com/juick/server/helpers/UserInfo.java new file mode 100644 index 00000000..5a4b6894 --- /dev/null +++ b/juick-core/src/main/java/com/juick/server/helpers/UserInfo.java @@ -0,0 +1,43 @@ +package com.juick.server.helpers; + +/** + * Created by vt on 03/09/16. + */ +public class UserInfo { + private String fullName; + private String country; + private String url; + private String description; + + public String getFullName() { + return fullName; + } + + public void setFullName(String fullName) { + this.fullName = fullName; + } + + public String getCountry() { + return country; + } + + public void setCountry(String country) { + this.country = country; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } +} diff --git a/juick-www/build.gradle b/juick-www/build.gradle index 891ee8f6..bebfaddc 100644 --- a/juick-www/build.gradle +++ b/juick-www/build.gradle @@ -38,6 +38,7 @@ dependencies { compile 'com.github.ooxi:serialized-php-parser:0.5.0' compile 'net.jodah:failsafe:0.9.2' compile 'com.mitchellbosecke:pebble:2.2.2' + compile 'com.sun.mail:javax.mail:1.5.6' providedCompile 'javax.servlet:javax.servlet-api:3.1.0' providedRuntime 'mysql:mysql-connector-java:5.1.39' } @@ -50,4 +51,4 @@ gretty { httpPort = 8080 contextPath = '' servletContainer = 'tomcat8' -} \ No newline at end of file +} diff --git a/juick-www/src/main/java/com/juick/www/Main.java b/juick-www/src/main/java/com/juick/www/Main.java index c67eced0..231c7f89 100644 --- a/juick-www/src/main/java/com/juick/www/Main.java +++ b/juick-www/src/main/java/com/juick/www/Main.java @@ -194,6 +194,7 @@ public class Main extends HttpServlet implements Stream.StreamListener { pm.doGetSent(sql, request, response, visitor); } catch (PebbleException e) { log("pebble exception", e); + response.sendError(500); } break; default: @@ -212,7 +213,12 @@ public class Main extends HttpServlet implements Stream.StreamListener { } else if (uri.equals("/logout")) { login.doGetLogout(sql, request, response); } else if (uri.equals("/settings")) { - settings.doGet(sql, request, response); + try { + settings.doGet(sql, request, response); + } catch (PebbleException e) { + log("pebble exception", e); + response.sendError(500); + } } else if (uri.equals("/_fblogin")) { loginFacebook.doGet(sql, request, response); } else if (uri.equals("/_vklogin")) { @@ -350,7 +356,12 @@ public class Main extends HttpServlet implements Stream.StreamListener { signup.doPost(sql, request, response); break; case "/settings": - settings.doPost(sql, request, response); + try { + settings.doPost(sql, request, response); + } catch (PebbleException e) { + log("pebble exception", e); + response.sendError(500); + } break; default: response.sendError(405); diff --git a/juick-www/src/main/java/com/juick/www/PageTemplates.java b/juick-www/src/main/java/com/juick/www/PageTemplates.java index c3b0d6f8..a036ecba 100644 --- a/juick-www/src/main/java/com/juick/www/PageTemplates.java +++ b/juick-www/src/main/java/com/juick/www/PageTemplates.java @@ -23,7 +23,6 @@ import com.juick.server.MessagesQueries; import com.juick.server.TagQueries; import com.juick.server.UserQueries; import org.apache.commons.lang3.StringEscapeUtils; -import com.mitchellbosecke.pebble.PebbleEngine; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.util.StringUtils; import ru.sape.Sape; @@ -39,8 +38,6 @@ import java.util.Date; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; -import java.util.regex.Matcher; -import java.util.regex.Pattern; import java.util.stream.Collectors; /** diff --git a/juick-www/src/main/java/com/juick/www/Settings.java b/juick-www/src/main/java/com/juick/www/Settings.java index 6364c869..c04a63fb 100644 --- a/juick-www/src/main/java/com/juick/www/Settings.java +++ b/juick-www/src/main/java/com/juick/www/Settings.java @@ -17,75 +17,253 @@ */ package com.juick.www; +import com.juick.server.CrosspostQueries; +import com.juick.server.SubscriptionsQueries; +import com.juick.server.TagQueries; +import com.juick.server.UserQueries; +import com.juick.server.helpers.NotifyOpts; +import com.juick.server.helpers.UserInfo; +import com.mitchellbosecke.pebble.error.PebbleException; +import com.mitchellbosecke.pebble.template.PebbleTemplate; +import org.apache.commons.lang3.StringUtils; +import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.jdbc.core.JdbcTemplate; +import javax.mail.Message; +import javax.mail.MessagingException; +import javax.mail.Session; +import javax.mail.Transport; +import javax.mail.internet.InternetAddress; +import javax.mail.internet.MimeMessage; import javax.servlet.ServletException; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.stream.Collectors; +import java.util.stream.IntStream; /** * * @author Ugnich Anton */ public class Settings { + private static final Logger logger = Logger.getLogger(Settings.class.getName()); - protected void doGet(JdbcTemplate sql, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + protected void doGet(JdbcTemplate sql, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException, PebbleException { com.juick.User visitor = Utils.getVisitorUser(sql, request, response); + if (visitor.getUID() == 0) { + response.sendRedirect("/login"); + } + List pages = Arrays.asList("main", "password", "about", "auth-email", "privacy"); + String page = request.getParameter("page"); + if (StringUtils.isEmpty(page) || !pages.contains(page)) { + page = "main"; + } response.setContentType("text/html; charset=UTF-8"); try (PrintWriter out = response.getWriter()) { - PageTemplates.pageHead(out, visitor, "Логин", ""); - PageTemplates.pageNavigation(out, visitor, null); - - out.println("
"); - out.println("
"); - out.println("
"); - out.println("
"); - out.println("

Имя пользователя:

"); - out.println("

Пароль:

"); - out.println("

"); - out.println("
"); - out.println("
"); - out.println("
"); - out.println("
"); // topwrapper - - PageTemplates.pageFooter(request, out, visitor, false); - PageTemplates.pageEnd(out); + PebbleTemplate template = Utils.getEngine().getTemplate(String.format("views/settings_%s.html", page)); + Map context = new HashMap<>(); + context.put("title", "Настройки"); + context.put("visitor", visitor); + context.put("tags", TagQueries.getPopularTags(sql)); + context.put("auths", UserQueries.getAuthCodes(sql, visitor)); + context.put("eopts", UserQueries.getEmailOpts(sql, visitor)); + context.put("ehash", UserQueries.getEmailHash(sql, visitor)); + context.put("emails", UserQueries.getEmails(sql, visitor)); + context.put("jids", UserQueries.getAllJIDs(sql, visitor)); + List hours = IntStream.rangeClosed(0, 23).boxed() + .map(i -> StringUtils.leftPad(String.format("%d", i), 2, "0")).collect(Collectors.toList()); + context.put("hours", hours); + context.put("fbstatus", CrosspostQueries.isFBCrossPostEnabled(sql, visitor.getUID())); + context.put("twitter_name", CrosspostQueries.getTwitterName(sql, visitor.getUID())); + context.put("telegram_name", CrosspostQueries.getTelegramName(sql, visitor.getUID())); + context.put("notify_options", SubscriptionsQueries.getNotifyOptions(sql, visitor)); + context.put("userinfo", UserQueries.getUserInfo(sql, visitor)); + if (page.equals("auth-email")) { + try { + String account = sql.queryForObject("SELECT account FROM auth WHERE user_id=? AND protocol='email' AND authcode=?", + String.class, visitor.getUID(), request.getParameter("code")); + sql.update("INSERT INTO emails(user_id,email) VALUES (?,?)", visitor.getUID(), account); + sql.update("DELETE FROM auth WHERE user_id=? AND authcode=?", visitor.getUID(), request.getParameter("code")); + context.put("result", "OK!"); + } catch (EmptyResultDataAccessException e) { + context.put("result", "Sorry, code unknown."); + } + } + template.evaluate(out, context); } } - protected void doPost(JdbcTemplate sql, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { - String username = request.getParameter("username"); - String password = request.getParameter("password"); - if (username == null || password == null || username.length() > 32 || password.isEmpty()) { + protected void doPost(JdbcTemplate sql, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException, PebbleException { + com.juick.User visitor = Utils.getVisitorUser(sql, request, response); + if (visitor.getUID() == 0) { response.sendError(400); return; } + List pages = Arrays.asList("main", "password", "about", "email", "email-add", "email-del", + "email-subscr", "auth-email", "privacy", "jid-del", "twitter-del", "telegram-del", "facebook-disable", + "facebook-enable", "vk-del"); + String page = request.getParameter("page"); + if (StringUtils.isEmpty(page) || !pages.contains(page)) { + response.sendError(400); + return; + } + String result = ""; + switch (page) { + case "password": + if (UserQueries.updatePassword(sql, visitor, request.getParameter("password"))) { + result = "

Password has been changed.

"; + String hash = com.juick.server.UserQueries.getHashByUID(sql, visitor.getUID()); + Cookie c = new Cookie("hash", hash); + c.setMaxAge(365 * 24 * 60 * 60); + response.addCookie(c); + } + break; + case "main": + NotifyOpts opts = new NotifyOpts(); + opts.setRepliesEnabled(StringUtils.isNotEmpty(request.getParameter("jnotify"))); + opts.setSubscriptionsEnabled(StringUtils.isNotEmpty(request.getParameter("subscr_notify"))); + opts.setRecommendationsEnabled(StringUtils.isNotEmpty(request.getParameter("recomm"))); + if (SubscriptionsQueries.setNotifyOptions(sql, visitor, opts)) { + result = "

Notification options has been updated

"; + } + break; + case "about": + UserInfo info = new UserInfo(); + info.setFullName(request.getParameter("fullname")); + info.setCountry(request.getParameter("country")); + info.setUrl(request.getParameter("url")); + info.setDescription(request.getParameter("descr")); + if (UserQueries.updateUserInfo(sql, visitor, info)) { + result = String.format("

Your info is updated.

Back to blog.

", visitor.getUName()); + } + break; + case "jid-del": + String[] params = request.getParameter("delete").split(";", 2); + int res = -1; + if (params[0].equals("xmpp")) { + res = sql.update("DELETE FROM jids WHERE user_id=? AND jid=?", visitor.getUID(), params[1]); + } else if (params[0].equals("xmpp-unauth")) { + res = sql.update("DELETE FROM auth WHERE user_id=? AND protocol='xmpp' AND account=?", visitor.getUID(), params[1]); + } + if (res == 1) { + result = "

Deleted. Back.

"; + } else { + result = "

Error

"; + } + break; + case "email": + String newHash = UserQueries.updateSecretEmail(sql, visitor); + if (StringUtils.isNotEmpty(newHash)) { + result = String.format("

New secret email: %s@mail.juick.com

" + + "

Back.

", newHash); + } else { + response.sendError(500); + return; + } + break; + case "email-add": + try { + sql.queryForObject("SELECT authcode FROM auth WHERE user_id=? AND protocol='email' " + + "AND account=?", String.class, visitor.getUID(), request.getParameter("account")); + } catch (EmptyResultDataAccessException e) { + String authCode = UserQueries.generateHash(8); + if (sql.update("INSERT INTO auth(user_id,protocol,account,authcode) VALUES (?,'email',?,?)", + visitor.getUID(), request.getParameter("account"), authCode) > 0) { + Session session = Session.getDefaultInstance(System.getProperties()); + try { + MimeMessage message = new MimeMessage(session); + message.setFrom(new InternetAddress("noreply@mail.juick.com")); + message.addRecipient(Message.RecipientType.TO, new InternetAddress(request.getParameter("account"))); + message.setSubject("Juick authorization link"); + message.setText(String.format("Follow link to attach this email to Juick account:\n" + + "http://juick.com/settings?page=auth-email&code=%s\n\n" + + "If you don't know, what this mean - just ignore this mail.\n", authCode)); + Transport.send(message); + result = "

Authorization link has been sent to your email. Follow it to proceed.

" + + "

Back

"; - int uid = com.juick.server.UserQueries.checkPassword(sql, username, password); - if (uid > 0) { - String hash = com.juick.server.UserQueries.getHashByUID(sql, uid); - Cookie c = new Cookie("hash", hash); - c.setDomain(".juick.com"); - c.setMaxAge(365 * 24 * 60 * 60); - response.addCookie(c); - - - if (uid > 0) { - throw new IOException("Settings"); - } - - String referer = request.getHeader("Referer"); - if (referer != null && referer.startsWith("http://juick.com/") && !referer.equals("http://juick.com/login")) { - response.sendRedirect(referer); - } else { - response.sendRedirect("/"); - } - } else { - response.sendError(403); + } catch (MessagingException ex) { + logger.log(Level.SEVERE, "mail exception", ex); + response.sendError(500); + return; + } + } + } + break; + case "email-del": + if (sql.update("DELETE FROM emails WHERE user_id=? AND email=?", visitor.getUID(), request.getParameter("account")) > 0) { + result = "

Deleted. Back.

"; + } else { + result = "

An error occured while deleting.

"; + } + break; + case "email-subscr": + sql.update("UPDATE emails SET subscr_hour=NULL WHERE user_id=?", visitor.getUID()); + String email = request.getParameter("account"); + if (StringUtils.isNotEmpty(email)) { + sql.update("UPDATE emails SET subscr_hour=? WHERE user_id=? AND email=?", + request.getParameter("time"), visitor.getUID(), email); + result = String.format("

Saved! Will send to %s at %s:00 GMT." + + "

Back

", email, request.getParameter("time")); + } else { + result = "

Disabled.

Back

"; + } + break; + case "twitter-del": + sql.update("DELETE FROM twitter WHERE user_id=?", visitor.getUID()); + sql.update("DELETE FROM subscr_users WHERE user_id=? AND suser_id=1741", visitor.getUID()); + for (Cookie cookie : request.getCookies()) { + if (cookie.getName().equals("request_token")) { + cookie.setMaxAge(0); + response.addCookie(cookie); + } + if (cookie.getName().equals("request_token_secret")) { + cookie.setMaxAge(0); + response.addCookie(cookie); + } + } + result = "

Back

"; + break; + case "telegram-del": + sql.update("DELETE FROM telegram WHERE user_id=?", visitor.getUID()); + result = "

Back

"; + break; + case "facebook-disable": + sql.update("UPDATE facebook SET crosspost=0 WHERE user_id=?", visitor.getUID()); + sql.update("DELETE FROM subscr_users WHERE user_id=? AND suser_id=5863", visitor.getUID()); + result = "

Back

"; + break; + case "facebook-enable": + sql.update("UPDATE facebook SET crosspost=1 WHERE user_id=?", visitor.getUID()); + sql.update("INSERT INTO subscr_users(user_id,suser_id,jid,active) VALUES (?,5863,'juick@facebook.juick.com',1)", visitor.getUID()); + result = "

Back

"; + break; + case "vk-del": + sql.update("DELETE FROM vk WHERE user_id=?", visitor.getUID()); + result = "

Back

"; + break; + default: + response.sendError(400); + return; + } + response.setContentType("text/html; charset=UTF-8"); + try (PrintWriter out = response.getWriter()) { + PebbleTemplate template = Utils.getEngine().getTemplate("views/settings_result.html"); + Map context = new HashMap<>(); + context.put("title", "Настройки"); + context.put("visitor", visitor); + context.put("result", result); + template.evaluate(out, context); } } } diff --git a/juick-www/src/main/resources/views/partial/settings_tabs.html b/juick-www/src/main/resources/views/partial/settings_tabs.html new file mode 100644 index 00000000..d7901d5e --- /dev/null +++ b/juick-www/src/main/resources/views/partial/settings_tabs.html @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/juick-www/src/main/resources/views/settings_about.html b/juick-www/src/main/resources/views/settings_about.html new file mode 100644 index 00000000..0252af35 --- /dev/null +++ b/juick-www/src/main/resources/views/settings_about.html @@ -0,0 +1,20 @@ +{% extends "layouts/content.html" %} +{% block content %} +
+
+

Full name:

+

Country:

+

URL:
+ Please, start with "http://"

+

About:
+
+ Max. 255 symbols

+

Avatar:
+ Recommendations: PNG, 96x96, <50Kb. Also, JPG and GIF supported.

+

+
+
+{% endblock %} +{% block "column" %} +{% include "views/partial/settings_tabs.html" %} +{% endblock %} \ No newline at end of file diff --git a/juick-www/src/main/resources/views/settings_auth-email.html b/juick-www/src/main/resources/views/settings_auth-email.html new file mode 100644 index 00000000..79691083 --- /dev/null +++ b/juick-www/src/main/resources/views/settings_auth-email.html @@ -0,0 +1,9 @@ +{% extends "layouts/content.html" %} +{% block content %} + +{% endblock %} +{% block "column" %} +{% include "views/partial/settings_tabs.html" %} +{% endblock %} \ No newline at end of file diff --git a/juick-www/src/main/resources/views/settings_main.html b/juick-www/src/main/resources/views/settings_main.html new file mode 100644 index 00000000..f4630be2 --- /dev/null +++ b/juick-www/src/main/resources/views/settings_main.html @@ -0,0 +1,156 @@ +{% extends "layouts/content.html" %} +{% block content %} +
+

Настройки

+
+
+ Notification options +

Reply notifications ("Message posted")

+

Subscriptions notifications ("@user subscribed...")

+

Posts recommendations ("Recommended by @user")

+

+
+
+
+ + Telegram + {% if telegram_name is not empty %} +
+
Telegram: {{ telegram_name }} — + + +
+
+ {% else %} +

To connect Telegram account: send any text message to @Juick_bot +

+ {% endif %} +
+
+
+ + XMPP accounts + +

Your accounts:

+

+ {% for jid in jids %} +
+ {% endfor %} + {% for auth in auths %} + + — Confirm
+ {% endfor %} +

+ {% if jids is not empty %} +

+ {% endif %} +

To add new jabber account: send any text message to juick@juick.com +

+
+
+
+ + E-mail + +
+

Add account:
+ + + +

+
+
+

Your accounts:

+

+ {% for email in emails %} +
+ {% endfor %} + {% if emails is empty %} + -

+ {% else %} +

+

+ {% endif %} +
+ {% if emails is not empty %} +
+

You can receive all your subscriptions by email:
+ Sent to every day at + +

+
+ {% endif %} +

 

+

You can post to Juick via e-mail. Send your plain text + messages to special secret e-mail. You can attach one photo or video file.

+

Secret email: {% if ehash is not empty %} {{ ehash }} {% else %}-{% endif %}

+
+

+
+
+
+ + Facebook + + {% if fbstatus.isConnected() %} + {% if fbstatus.isCrosspostEnabled() %} +
+
+ Facebook: Enabled — + + +
+
+ {% else %} +
+
+ Facebook: Disabled — + + +
+
+ {% endif %} + {% else %} +

Cross-posting to Facebook: Connect to Facebook

+ {% endif %} +
+
+ + Twitter + {% if twitter_name is not empty %} +
+
Twitter: {{ twitter_name }} — + + +
+
+ {% else %} +

Cross-posting to Twitter: Connect to Twitter

+ {% endif %} +
+ +
+{% endblock %} +{% block "column" %} +{% include "views/partial/settings_tabs.html" %} +{% endblock %} \ No newline at end of file diff --git a/juick-www/src/main/resources/views/settings_password.html b/juick-www/src/main/resources/views/settings_password.html new file mode 100644 index 00000000..e9c2dce0 --- /dev/null +++ b/juick-www/src/main/resources/views/settings_password.html @@ -0,0 +1,17 @@ +{% extends "layouts/content.html" %} +{% block content %} +
+
+ Changing your password +
+ +

Change password:
+ (max. length - 16 symbols)

+
+
+
+{% endblock %} +{% block "column" %} +{% include "views/partial/settings_tabs.html" %} +{% endblock %} \ No newline at end of file diff --git a/juick-www/src/main/resources/views/settings_privacy.html b/juick-www/src/main/resources/views/settings_privacy.html new file mode 100644 index 00000000..48756d8e --- /dev/null +++ b/juick-www/src/main/resources/views/settings_privacy.html @@ -0,0 +1,9 @@ +{% extends "layouts/content.html" %} +{% block content %} +
+

Privacy

+
+{% endblock %} +{% block "column" %} +{% include "views/partial/settings_tabs.html" %} +{% endblock %} \ No newline at end of file diff --git a/juick-www/src/main/resources/views/settings_result.html b/juick-www/src/main/resources/views/settings_result.html new file mode 100644 index 00000000..3f5482d4 --- /dev/null +++ b/juick-www/src/main/resources/views/settings_result.html @@ -0,0 +1,9 @@ +{% extends "layouts/content.html" %} +{% block content %} +
+

{{ result | raw }}

+
+{% endblock %} +{% block "column" %} +{% include "views/partial/settings_tabs.html" %} +{% endblock %} \ No newline at end of file diff --git a/juick-www/src/main/static/style.css b/juick-www/src/main/static/style.css index a80d58fa..e7c6f2cc 100644 --- a/juick-www/src/main/static/style.css +++ b/juick-www/src/main/static/style.css @@ -235,6 +235,10 @@ q { border-left: 1px dashed #CCC; margin: 10px 0 10px 10px; padding-left: 10px; .icon--ei-comment { margin-top: -3px; } +fieldset { + margin-top: 25px; + border: 1px dotted #ccc; +} /******************************************************************************/ @media screen and (max-width: 850px) { -- cgit v1.2.3