From 98e7163bd24262ab938d95b7ce8d4a55dd090d2a Mon Sep 17 00:00:00 2001 From: Alex Bogdanovski Date: Thu, 24 Oct 2024 19:20:10 +0300 Subject: [PATCH] added support for setting a preffered starting space each user individually, closes #461 --- .../java/com/erudika/scoold/ScooldConfig.java | 8 ++++++++ .../controllers/SettingsController.java | 1 + .../scoold/controllers/SigninController.java | 4 ++-- .../java/com/erudika/scoold/core/Profile.java | 13 +++++++++++++ .../com/erudika/scoold/utils/HttpUtils.java | 18 +++++++++++++----- .../com/erudika/scoold/utils/ScooldUtils.java | 5 +++-- src/main/resources/lang_en.properties | 1 + src/main/resources/static/styles/style.css | 2 +- src/main/resources/templates/settings.vm | 19 +++++++++++++++++-- 9 files changed, 59 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/erudika/scoold/ScooldConfig.java b/src/main/java/com/erudika/scoold/ScooldConfig.java index 65c4478b..f8af4331 100644 --- a/src/main/java/com/erudika/scoold/ScooldConfig.java +++ b/src/main/java/com/erudika/scoold/ScooldConfig.java @@ -1807,6 +1807,14 @@ public String autoAssignSpaces() { return getConfigParam("auto_assign_spaces", ""); } + @Documented(position = 1681, + identifier = "default_starting_space", + category = "Spaces", + description = "The starting space to be selected for all users upon sign in.") + public String defaultStartingSpace() { + return getConfigParam("default_starting_space", ""); + } + @Documented(position = 1690, identifier = "reset_spaces_on_new_assignment", value = "true", diff --git a/src/main/java/com/erudika/scoold/controllers/SettingsController.java b/src/main/java/com/erudika/scoold/controllers/SettingsController.java index c1864a26..0e042c51 100755 --- a/src/main/java/com/erudika/scoold/controllers/SettingsController.java +++ b/src/main/java/com/erudika/scoold/controllers/SettingsController.java @@ -110,6 +110,7 @@ public String post(@RequestParam(required = false) String tags, @RequestParam(re } setAnonymity(authUser, req.getParameter("anon")); setDarkMode(authUser, req.getParameter("dark")); + authUser.setPreferredSpace(req.getParameter("preferredSpace")); authUser.setReplyEmailsEnabled(Boolean.valueOf(replyEmailsOn) && utils.isReplyNotificationAllowed()); authUser.setCommentEmailsEnabled(Boolean.valueOf(commentEmailsOn) && utils.isCommentNotificationAllowed()); authUser.setFavtagsEmailsEnabled(Boolean.valueOf(favtagsEmailsOn) && utils.isFavTagsNotificationAllowed()); diff --git a/src/main/java/com/erudika/scoold/controllers/SigninController.java b/src/main/java/com/erudika/scoold/controllers/SigninController.java index ecc9f621..8c101ffa 100755 --- a/src/main/java/com/erudika/scoold/controllers/SigninController.java +++ b/src/main/java/com/erudika/scoold/controllers/SigninController.java @@ -166,7 +166,7 @@ public String signup(@RequestParam String name, @RequestParam String email, @Req if (!isEmailRegistered(email) && approvedDomain && isSubmittedByHuman(req) && goodPass) { User u = pc.signIn("password", email + ":" + name + ":" + passw, false); if (u != null && u.getActive()) { - setAuthCookie(u.getPassword(), req, res); + setAuthCookie(u, req, res); triggerLoginEvent(u, req); return "redirect:" + getBackToUrl(req); } else { @@ -359,7 +359,7 @@ private String loginWithIdToken(String jwt, HttpServletRequest req, HttpServletR private String onAuthSuccess(User u, HttpServletRequest req, HttpServletResponse res) { if (u != null && utils.isEmailDomainApproved(u.getEmail())) { // the user password in this case is a Bearer token (JWT) - setAuthCookie(u.getPassword(), req, res); + setAuthCookie(u, req, res); triggerLoginEvent(u, req); return "redirect:" + getBackToUrl(req); } else if (u != null && !utils.isEmailDomainApproved(u.getEmail())) { diff --git a/src/main/java/com/erudika/scoold/core/Profile.java b/src/main/java/com/erudika/scoold/core/Profile.java index 41351dd7..c91c3958 100755 --- a/src/main/java/com/erudika/scoold/core/Profile.java +++ b/src/main/java/com/erudika/scoold/core/Profile.java @@ -77,6 +77,7 @@ public class Profile extends Sysprop { @Stored private List> customBadges; @Stored private String pendingEmail; @Stored private Boolean editorRoleEnabled; + @Stored private String preferredSpace; private transient String currentSpace; private transient String newbadges; @@ -368,6 +369,18 @@ public void setFavspaces(Set favspaces) { this.favspaces = favspaces; } + public String getPreferredSpace() { + // returns a preferred staring space upon login + if (StringUtils.isBlank(preferredSpace)) { + preferredSpace = ScooldUtils.getConfig().defaultStartingSpace(); + } + return preferredSpace; + } + + public void setPreferredSpace(String preferredSpace) { + this.preferredSpace = preferredSpace; + } + public boolean isModInCurrentSpace() { return isModInSpace(currentSpace); } diff --git a/src/main/java/com/erudika/scoold/utils/HttpUtils.java b/src/main/java/com/erudika/scoold/utils/HttpUtils.java index cbdcc308..3d8ce48d 100644 --- a/src/main/java/com/erudika/scoold/utils/HttpUtils.java +++ b/src/main/java/com/erudika/scoold/utils/HttpUtils.java @@ -23,6 +23,7 @@ import com.erudika.para.core.utils.Utils; import com.erudika.scoold.ScooldConfig; import static com.erudika.scoold.ScooldServer.HOMEPAGE; +import com.erudika.scoold.core.Profile; import jakarta.servlet.http.Cookie; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; @@ -269,15 +270,22 @@ public static void getDefaultAvatarImage(HttpServletResponse res) { /** * Sets the session cookie. - * @param jwt a JWT from Para + * @param authUser auth user * @param req req * @param res res */ - public static void setAuthCookie(String jwt, HttpServletRequest req, HttpServletResponse res) { - if (StringUtils.isBlank(jwt)) { - return; + public static void setAuthCookie(User authUser, HttpServletRequest req, HttpServletResponse res) { + if (!StringUtils.isBlank(authUser.getPassword())) { + setRawCookie(CONF.authCookie(), authUser.getPassword(), req, res, "Lax", CONF.sessionTimeoutSec()); + } + try { + Profile authu = ScooldUtils.getInstance().getParaClient().read(Profile.id(authUser.getId())); + if (authu != null && !StringUtils.isBlank(authu.getPreferredSpace())) { + ScooldUtils.getInstance().storeSpaceIdInCookie(authu.getPreferredSpace(), req, res); + } + } catch (Exception ex) { + logger.error(null, ex); } - setRawCookie(CONF.authCookie(), jwt, req, res, "Lax", CONF.sessionTimeoutSec()); } /** diff --git a/src/main/java/com/erudika/scoold/utils/ScooldUtils.java b/src/main/java/com/erudika/scoold/utils/ScooldUtils.java index cc7a7fe8..176cb40e 100755 --- a/src/main/java/com/erudika/scoold/utils/ScooldUtils.java +++ b/src/main/java/com/erudika/scoold/utils/ScooldUtils.java @@ -67,6 +67,7 @@ import jakarta.validation.ConstraintViolation; import java.io.IOException; import java.io.InputStream; +import java.net.URI; import java.net.URL; import java.nio.ByteBuffer; import java.security.InvalidKeyException; @@ -233,7 +234,7 @@ public static ScooldConfig getConfig() { public static void setParaEndpointAndApiPath(ParaClient pc) { try { - URL endpoint = new URL(CONF.paraEndpoint()); + URL endpoint = new URI(CONF.paraEndpoint()).toURL(); if (!StringUtils.isBlank(endpoint.getPath()) && !"/".equals(endpoint.getPath())) { // support Para deployed under a specific context path pc.setEndpoint(StringUtils.removeEnd(CONF.paraEndpoint(), endpoint.getPath())); @@ -1455,7 +1456,7 @@ public void storeSpaceIdInCookie(String space, HttpServletRequest req, HttpServl // used for setting the space from a direct URL to a particular space req.setAttribute(CONF.spaceCookie(), space); HttpUtils.setRawCookie(CONF.spaceCookie(), Utils.base64encURL(space.getBytes()), - req, res, "Strict", StringUtils.isBlank(space) ? 0 : 365 * 24 * 60 * 60); + req, res, "Lax", StringUtils.isBlank(space) ? 0 : 365 * 24 * 60 * 60); } public String verifyExistingSpace(Profile authUser, String space) { diff --git a/src/main/resources/lang_en.properties b/src/main/resources/lang_en.properties index c39082da..5622c6da 100644 --- a/src/main/resources/lang_en.properties +++ b/src/main/resources/lang_en.properties @@ -335,6 +335,7 @@ settings.scancode = Scan the QR code with an app like Google Authenticator and e settings.savecode = Save this recovery code - it's only shown once! settings.twofaon = Two-factor authentication is enabled. settings.twofaoff = To disable, enter the two-factor authentication code or the recovery code. +settings.preferredspace = Preferred starting space reports.spam = Spam or commercial content reports.offensive = Offensive content, violence or abuse diff --git a/src/main/resources/static/styles/style.css b/src/main/resources/static/styles/style.css index 05788368..c60c815a 100755 --- a/src/main/resources/static/styles/style.css +++ b/src/main/resources/static/styles/style.css @@ -344,7 +344,7 @@ img.profile-pic { } .user-card img.profile-pic, .user-card-compact img.profile-pic { width: 100%; - padding: 6px 0px 0px 6px; + padding: 6px 0px 0px 7px; } img.profile-pic:before { content: " "; diff --git a/src/main/resources/templates/settings.vm b/src/main/resources/templates/settings.vm index b1c80620..7003579e 100755 --- a/src/main/resources/templates/settings.vm +++ b/src/main/resources/templates/settings.vm @@ -83,8 +83,23 @@
+ #set($userSpaces = $authUser.allSpaces) +

$!lang.get('settings.preferredspace')

+
+
+ + +
+
+ #if($scooldUtils.isNearMeFeatureEnabled()) -

$!lang.get('posts.locationfilter')

+

$!lang.get('posts.locationfilter')

$!lang.get('settings.location')

@@ -179,7 +194,7 @@