From a2bd841f6faabb5ab03ec6832ac82eaff8a11b62 Mon Sep 17 00:00:00 2001 From: Muhammad Irfan Ayub Date: Wed, 14 Feb 2024 22:01:09 +0500 Subject: [PATCH 01/16] feature: Initial Implementation of `lost-password` api endpoint --- .../org/lowcoder/domain/user/service/UserService.java | 2 ++ .../lowcoder/domain/user/service/UserServiceImpl.java | 10 ++++++++++ .../lowcoder/api/usermanagement/UserApiService.java | 4 ++++ .../lowcoder/api/usermanagement/UserController.java | 9 +++++++++ .../org/lowcoder/api/usermanagement/UserEndpoints.java | 6 ++++++ 5 files changed, 31 insertions(+) diff --git a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/user/service/UserService.java b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/user/service/UserService.java index aebed82ef..497f50f1e 100644 --- a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/user/service/UserService.java +++ b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/user/service/UserService.java @@ -50,6 +50,8 @@ public interface UserService { Mono resetPassword(String userId); + Mono lostPassword(String userEmail); + Mono setPassword(String userId, String password); Mono buildUserDetail(User user, boolean withoutDynamicGroups); diff --git a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/user/service/UserServiceImpl.java b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/user/service/UserServiceImpl.java index e7526be8d..073f9644c 100644 --- a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/user/service/UserServiceImpl.java +++ b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/user/service/UserServiceImpl.java @@ -40,6 +40,8 @@ import javax.annotation.Nonnull; import java.security.SecureRandom; +import java.time.Duration; +import java.time.LocalDate; import java.util.*; import java.util.function.Function; import java.util.stream.Collectors; @@ -262,6 +264,14 @@ public Mono resetPassword(String userId) { }); } + @Override + public Mono lostPassword(String userEmail) { + return findByName(userEmail) + .flatMap(user -> { + return Mono.justOrEmpty(user.getName()); + }); + } + @SuppressWarnings("SpellCheckingInspection") @Nonnull private static String generateNewRandomPwd() { diff --git a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/usermanagement/UserApiService.java b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/usermanagement/UserApiService.java index 42161bd5a..5016bc73d 100644 --- a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/usermanagement/UserApiService.java +++ b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/usermanagement/UserApiService.java @@ -65,6 +65,10 @@ public Mono resetPassword(String userId) { .then(userService.resetPassword(userId)); } + public Mono lostPassword(String userEmail) { + return userService.lostPassword(userEmail); + } + // ========================== TOKEN OPERATIONS START ========================== public Mono saveToken(String userId, String source, String token) { diff --git a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/usermanagement/UserController.java b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/usermanagement/UserController.java index d865cba4f..8eaeba8b0 100644 --- a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/usermanagement/UserController.java +++ b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/usermanagement/UserController.java @@ -146,6 +146,15 @@ public Mono> resetPassword(@RequestBody ResetPasswordReques } + @Override + public Mono> lostPassword(@RequestBody LostPasswordRequest request) { + if (StringUtils.isBlank(request.userEmail())) { + return ofError(BizError.INVALID_PARAMETER, "INVALID_USER_EMAIL"); + } + return userApiService.lostPassword(request.userEmail()) + .map(ResponseView::success); + } + @Override public Mono> setPassword(@RequestParam String password) { if (StringUtils.isBlank(password)) { diff --git a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/usermanagement/UserEndpoints.java b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/usermanagement/UserEndpoints.java index 96c93c472..54d9ff5b5 100644 --- a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/usermanagement/UserEndpoints.java +++ b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/usermanagement/UserEndpoints.java @@ -121,6 +121,9 @@ public interface UserEndpoints @PostMapping("/reset-password") public Mono> resetPassword(@RequestBody ResetPasswordRequest request); + @PostMapping("/lost-password") + public Mono> lostPassword(@RequestBody LostPasswordRequest userEmail); + @Operation( tags = TAG_USER_PASSWORD_MANAGEMENT, operationId = "setPassword", @@ -151,6 +154,9 @@ public interface UserEndpoints public record ResetPasswordRequest(String userId) { } + public record LostPasswordRequest(String userEmail) { + } + public record UpdatePasswordRequest(String oldPassword, String newPassword) { } From ceabd3bb03943d7e6c98a36cafc742e5a6956bd9 Mon Sep 17 00:00:00 2001 From: Muhammad Irfan Ayub Date: Sun, 18 Feb 2024 00:09:48 +0500 Subject: [PATCH 02/16] feature: Initial Implementation of Email Sending Feature with dummy Data. --- server/api-service/lowcoder-domain/pom.xml | 4 ++ .../org/lowcoder/domain/user/model/User.java | 5 ++ .../service/EmailCommunicationService.java | 49 +++++++++++++++++++ .../domain/user/service/UserService.java | 2 +- .../domain/user/service/UserServiceImpl.java | 18 +++++-- .../org/lowcoder/sdk/config/CommonConfig.java | 8 +++ .../api/usermanagement/UserApiService.java | 2 +- .../api/usermanagement/UserController.java | 2 +- .../api/usermanagement/UserEndpoints.java | 2 +- .../main/resources/application-lowcoder.yml | 14 +++++- 10 files changed, 98 insertions(+), 8 deletions(-) create mode 100644 server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/user/service/EmailCommunicationService.java diff --git a/server/api-service/lowcoder-domain/pom.xml b/server/api-service/lowcoder-domain/pom.xml index 2150c484a..8eec5df20 100644 --- a/server/api-service/lowcoder-domain/pom.xml +++ b/server/api-service/lowcoder-domain/pom.xml @@ -50,6 +50,10 @@ org.lowcoder lowcoder-infra + + org.springframework.boot + spring-boot-starter-mail + com.github.cloudyrock.mongock diff --git a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/user/model/User.java b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/user/model/User.java index 80efd4ac5..a8350e0b5 100644 --- a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/user/model/User.java +++ b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/user/model/User.java @@ -3,6 +3,7 @@ import static com.google.common.base.Suppliers.memoize; import static org.lowcoder.infra.util.AssetUtils.toAssetPath; +import java.time.Instant; import java.util.*; import java.util.function.Supplier; @@ -52,6 +53,10 @@ public class User extends HasIdAndAuditing implements BeforeMongodbWrite, AfterM @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) private String password; + private String passwordResetToken; + + private Instant passwordResetTokenExpiry; + @Transient Boolean isAnonymous = false; diff --git a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/user/service/EmailCommunicationService.java b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/user/service/EmailCommunicationService.java new file mode 100644 index 000000000..7b88c3104 --- /dev/null +++ b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/user/service/EmailCommunicationService.java @@ -0,0 +1,49 @@ +package org.lowcoder.domain.user.service; + +import jakarta.mail.internet.MimeMessage; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.mail.javamail.JavaMailSender; +import org.springframework.mail.javamail.MimeMessageHelper; +import org.springframework.stereotype.Service; + +@Service +@Slf4j(topic = "EmailCommunicationService") +public class EmailCommunicationService { + + @Autowired + private JavaMailSender javaMailSender; + + @Value("${spring.mail.username}") + private String fromEmail; + + public boolean sendMail(String to, String token, String message) { + try { + String subject = "Lost Password Email"; + MimeMessage mimeMessage = javaMailSender.createMimeMessage(); + + MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true); + + mimeMessageHelper.setFrom(fromEmail); + mimeMessageHelper.setTo(to); + mimeMessageHelper.setSubject(subject); + + // Construct the message with the token link + String resetLink = "http://localhost:8080/lost-password?token=" + token; + String messageWithLink = message + "\n\nReset your password here: " + resetLink; + mimeMessageHelper.setText(messageWithLink, true); // Set HTML to true to allow links + + javaMailSender.send(mimeMessage); + + return true; + + } catch (Exception e) { + log.error("Failed to send mail to: {}, Exception: {}", to, e); + return false; + } + + + } + +} diff --git a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/user/service/UserService.java b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/user/service/UserService.java index 497f50f1e..658e1e6a0 100644 --- a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/user/service/UserService.java +++ b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/user/service/UserService.java @@ -50,7 +50,7 @@ public interface UserService { Mono resetPassword(String userId); - Mono lostPassword(String userEmail); + Mono lostPassword(String userEmail); Mono setPassword(String userId, String password); diff --git a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/user/service/UserServiceImpl.java b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/user/service/UserServiceImpl.java index 073f9644c..5ee1aa9ae 100644 --- a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/user/service/UserServiceImpl.java +++ b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/user/service/UserServiceImpl.java @@ -29,6 +29,7 @@ import org.lowcoder.sdk.constants.WorkspaceMode; import org.lowcoder.sdk.exception.BizError; import org.lowcoder.sdk.exception.BizException; +import org.lowcoder.sdk.util.HashUtils; import org.lowcoder.sdk.util.LocaleUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.DuplicateKeyException; @@ -41,7 +42,9 @@ import javax.annotation.Nonnull; import java.security.SecureRandom; import java.time.Duration; +import java.time.Instant; import java.time.LocalDate; +import java.time.temporal.ChronoUnit; import java.util.*; import java.util.function.Function; import java.util.stream.Collectors; @@ -76,7 +79,8 @@ public class UserServiceImpl implements UserService { private CommonConfig commonConfig; @Autowired private AuthenticationService authenticationService; - + @Autowired + private EmailCommunicationService emailCommunicationService; private Conf avatarMaxSizeInKb; @PostConstruct @@ -265,10 +269,18 @@ public Mono resetPassword(String userId) { } @Override - public Mono lostPassword(String userEmail) { + public Mono lostPassword(String userEmail) { return findByName(userEmail) .flatMap(user -> { - return Mono.justOrEmpty(user.getName()); + String token = generateNewRandomPwd(); + Instant tokenExpiry = Instant.now().plus(12, ChronoUnit.HOURS); + // TODO - IRFAN this is just a dummy email. + if (!emailCommunicationService.sendMail("notify@lowcoder.org", token, "Click Here")) { + return ofError(BizError.USER_NOT_EXIST, "SENDING_EMAIL_FAILED"); + } + user.setPasswordResetToken(HashUtils.hash(token.getBytes())); + user.setPasswordResetTokenExpiry(tokenExpiry); + return Mono.empty(); }); } diff --git a/server/api-service/lowcoder-sdk/src/main/java/org/lowcoder/sdk/config/CommonConfig.java b/server/api-service/lowcoder-sdk/src/main/java/org/lowcoder/sdk/config/CommonConfig.java index 7d32ed0d8..06fcd486a 100644 --- a/server/api-service/lowcoder-sdk/src/main/java/org/lowcoder/sdk/config/CommonConfig.java +++ b/server/api-service/lowcoder-sdk/src/main/java/org/lowcoder/sdk/config/CommonConfig.java @@ -44,6 +44,7 @@ public class CommonConfig { private Cookie cookie = new Cookie(); private JsExecutor jsExecutor = new JsExecutor(); private Set disallowedHosts = new HashSet<>(); + private SMTP smtp = new SMTP(); public boolean isSelfHost() { return !isCloud(); @@ -145,6 +146,13 @@ public static class JsExecutor { private String host; } + @Data + public static class SMTP { + private String email; + private String host; + private String port; + } + @Getter @Setter diff --git a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/usermanagement/UserApiService.java b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/usermanagement/UserApiService.java index 5016bc73d..751001cb3 100644 --- a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/usermanagement/UserApiService.java +++ b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/usermanagement/UserApiService.java @@ -65,7 +65,7 @@ public Mono resetPassword(String userId) { .then(userService.resetPassword(userId)); } - public Mono lostPassword(String userEmail) { + public Mono lostPassword(String userEmail) { return userService.lostPassword(userEmail); } diff --git a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/usermanagement/UserController.java b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/usermanagement/UserController.java index 8eaeba8b0..d045cbf0e 100644 --- a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/usermanagement/UserController.java +++ b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/usermanagement/UserController.java @@ -147,7 +147,7 @@ public Mono> resetPassword(@RequestBody ResetPasswordReques } @Override - public Mono> lostPassword(@RequestBody LostPasswordRequest request) { + public Mono> lostPassword(@RequestBody LostPasswordRequest request) { if (StringUtils.isBlank(request.userEmail())) { return ofError(BizError.INVALID_PARAMETER, "INVALID_USER_EMAIL"); } diff --git a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/usermanagement/UserEndpoints.java b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/usermanagement/UserEndpoints.java index 54d9ff5b5..f65ded4a1 100644 --- a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/usermanagement/UserEndpoints.java +++ b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/usermanagement/UserEndpoints.java @@ -122,7 +122,7 @@ public interface UserEndpoints public Mono> resetPassword(@RequestBody ResetPasswordRequest request); @PostMapping("/lost-password") - public Mono> lostPassword(@RequestBody LostPasswordRequest userEmail); + public Mono> lostPassword(@RequestBody LostPasswordRequest userEmail); @Operation( tags = TAG_USER_PASSWORD_MANAGEMENT, diff --git a/server/api-service/lowcoder-server/src/main/resources/application-lowcoder.yml b/server/api-service/lowcoder-server/src/main/resources/application-lowcoder.yml index 75ae0dba9..532554b9c 100644 --- a/server/api-service/lowcoder-server/src/main/resources/application-lowcoder.yml +++ b/server/api-service/lowcoder-server/src/main/resources/application-lowcoder.yml @@ -9,6 +9,18 @@ spring: main: allow-bean-definition-overriding: true allow-circular-references: true + mail: +# TODO - IRFAN this is just a test email to check the email sending. + username: "irfan.ayub@ikhwatech.com" + password: "abcd" + host: "smtp.freesmtpservers.com" + port: 25 +# properties: +# mail: +# smtp: +# starttls: +# enable: true +# auth: true server: compression: @@ -62,4 +74,4 @@ auth: email: enable: true enable-register: true - workspace-creation: true \ No newline at end of file + workspace-creation: true From c4b18bd65055c3a298b11faeadbbd33ee6cb8ffb Mon Sep 17 00:00:00 2001 From: Muhammad Irfan Ayub Date: Sun, 18 Feb 2024 13:51:04 +0500 Subject: [PATCH 03/16] feature: Initial Password reset flow implementation --- .../service/EmailCommunicationService.java | 2 +- .../domain/user/service/UserService.java | 2 ++ .../domain/user/service/UserServiceImpl.java | 25 ++++++++++++++++++- .../api/usermanagement/UserApiService.java | 4 +++ .../api/usermanagement/UserController.java | 11 ++++++++ .../api/usermanagement/UserEndpoints.java | 8 +++++- 6 files changed, 49 insertions(+), 3 deletions(-) diff --git a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/user/service/EmailCommunicationService.java b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/user/service/EmailCommunicationService.java index 7b88c3104..1a8c30896 100644 --- a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/user/service/EmailCommunicationService.java +++ b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/user/service/EmailCommunicationService.java @@ -30,7 +30,7 @@ public boolean sendMail(String to, String token, String message) { mimeMessageHelper.setSubject(subject); // Construct the message with the token link - String resetLink = "http://localhost:8080/lost-password?token=" + token; + String resetLink = "http://localhost:8080/api/users/lost-password/" + token; String messageWithLink = message + "\n\nReset your password here: " + resetLink; mimeMessageHelper.setText(messageWithLink, true); // Set HTML to true to allow links diff --git a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/user/service/UserService.java b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/user/service/UserService.java index 658e1e6a0..ec0e7e235 100644 --- a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/user/service/UserService.java +++ b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/user/service/UserService.java @@ -52,6 +52,8 @@ public interface UserService { Mono lostPassword(String userEmail); + Mono resetLostPassword(String userEmail, String token, String newPassword); + Mono setPassword(String userId, String password); Mono buildUserDetail(User user, boolean withoutDynamicGroups); diff --git a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/user/service/UserServiceImpl.java b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/user/service/UserServiceImpl.java index 5ee1aa9ae..1fe36c169 100644 --- a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/user/service/UserServiceImpl.java +++ b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/user/service/UserServiceImpl.java @@ -280,7 +280,30 @@ public Mono lostPassword(String userEmail) { } user.setPasswordResetToken(HashUtils.hash(token.getBytes())); user.setPasswordResetTokenExpiry(tokenExpiry); - return Mono.empty(); + return repository.save(user).then(Mono.empty()); + }); + } + + @Override + public Mono resetLostPassword(String userEmail, String token, String newPassword) { + return findByName(userEmail) + .flatMap(user -> { + if (Instant.now().until(user.getPasswordResetTokenExpiry(), ChronoUnit.MINUTES) <= 0) { + return ofError(BizError.LOGIN_EXPIRED, "TOKEN_EXPIRED"); + } + + if (!StringUtils.equals(HashUtils.hash(token.getBytes()), user.getPasswordResetToken())) { + return ofError(BizError.INVALID_PASSWORD, "INVALID_TOKEN"); + } + + if (StringUtils.isBlank(newPassword)) { + return ofError(BizError.INVALID_PASSWORD, "PASSWORD_NOT_SET_YET"); + } + + user.setPassword(encryptionService.encryptPassword(newPassword)); + user.setPasswordResetToken(StringUtils.EMPTY); + user.setPasswordResetTokenExpiry(Instant.now()); + return repository.save(user).then(Mono.empty()); }); } diff --git a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/usermanagement/UserApiService.java b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/usermanagement/UserApiService.java index 751001cb3..e2b6e847c 100644 --- a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/usermanagement/UserApiService.java +++ b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/usermanagement/UserApiService.java @@ -69,6 +69,10 @@ public Mono lostPassword(String userEmail) { return userService.lostPassword(userEmail); } + public Mono resetLostPassword(String userEmail, String token, String newPassword) { + return userService.resetLostPassword(userEmail, token, newPassword); + } + // ========================== TOKEN OPERATIONS START ========================== public Mono saveToken(String userId, String source, String token) { diff --git a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/usermanagement/UserController.java b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/usermanagement/UserController.java index d045cbf0e..02dca02ff 100644 --- a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/usermanagement/UserController.java +++ b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/usermanagement/UserController.java @@ -155,6 +155,17 @@ public Mono> lostPassword(@RequestBody LostPasswordRequest re .map(ResponseView::success); } + @Override + public Mono> resetLostPassword(@PathVariable String token, @RequestBody ResetLostPasswordRequest request) { + if (StringUtils.isBlank(request.userEmail()) || StringUtils.isBlank(token) + || StringUtils.isBlank(request.newPassword())) { + return ofError(BizError.INVALID_PARAMETER, "INVALID_PARAMETER"); + } + + return userApiService.resetLostPassword(request.userEmail(), token, request.newPassword()) + .map(ResponseView::success); + } + @Override public Mono> setPassword(@RequestParam String password) { if (StringUtils.isBlank(password)) { diff --git a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/usermanagement/UserEndpoints.java b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/usermanagement/UserEndpoints.java index f65ded4a1..e5d3f517c 100644 --- a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/usermanagement/UserEndpoints.java +++ b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/usermanagement/UserEndpoints.java @@ -122,7 +122,10 @@ public interface UserEndpoints public Mono> resetPassword(@RequestBody ResetPasswordRequest request); @PostMapping("/lost-password") - public Mono> lostPassword(@RequestBody LostPasswordRequest userEmail); + public Mono> lostPassword(@RequestBody LostPasswordRequest request); + + @PostMapping("/lost-password/{token}") + public Mono> resetLostPassword(@PathVariable String token, @RequestBody ResetLostPasswordRequest request); @Operation( tags = TAG_USER_PASSWORD_MANAGEMENT, @@ -157,6 +160,9 @@ public record ResetPasswordRequest(String userId) { public record LostPasswordRequest(String userEmail) { } + public record ResetLostPasswordRequest(String userEmail, String newPassword) { + } + public record UpdatePasswordRequest(String oldPassword, String newPassword) { } From 96081d3691c022501790d374c6ade7231f7ea11d Mon Sep 17 00:00:00 2001 From: Muhammad Irfan Ayub Date: Wed, 21 Feb 2024 01:05:27 +0500 Subject: [PATCH 04/16] feature: Added email template in OrganizationCommonSettings, Added public url env variable and some code optimizations. --- .../organization/model/Organization.java | 2 +- .../service/EmailCommunicationService.java | 4 ++-- .../domain/user/service/UserService.java | 4 ++-- .../domain/user/service/UserServiceImpl.java | 24 +++++++++++++------ .../api/usermanagement/UserApiService.java | 4 ++-- .../api/usermanagement/UserController.java | 4 ++-- .../api/usermanagement/UserEndpoints.java | 4 ++-- .../main/resources/application-lowcoder.yml | 1 + 8 files changed, 29 insertions(+), 18 deletions(-) diff --git a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/organization/model/Organization.java b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/organization/model/Organization.java index 984788f5a..6b4d2b05c 100644 --- a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/organization/model/Organization.java +++ b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/organization/model/Organization.java @@ -86,7 +86,7 @@ public OrganizationCommonSettings getCommonSettings() { public static class OrganizationCommonSettings extends HashMap { public static final String USER_EXTRA_TRANSFORMER = "userExtraTransformer"; public static final String USER_EXTRA_TRANSFORMER_UPDATE_TIME = "userExtraTransformer_updateTime"; - + public static final String PASSWORD_RESET_EMAIL_TEMPLATE = "passwordRestEmailTemplate"; // custom branding configs public static final String CUSTOM_BRANDING_KEY = "branding"; } diff --git a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/user/service/EmailCommunicationService.java b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/user/service/EmailCommunicationService.java index 1a8c30896..16fa8f196 100644 --- a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/user/service/EmailCommunicationService.java +++ b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/user/service/EmailCommunicationService.java @@ -20,7 +20,7 @@ public class EmailCommunicationService { public boolean sendMail(String to, String token, String message) { try { - String subject = "Lost Password Email"; + String subject = "Reset Your Password"; MimeMessage mimeMessage = javaMailSender.createMimeMessage(); MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true); @@ -30,7 +30,7 @@ public boolean sendMail(String to, String token, String message) { mimeMessageHelper.setSubject(subject); // Construct the message with the token link - String resetLink = "http://localhost:8080/api/users/lost-password/" + token; + String resetLink = lowcoderPublicUrl + "/api/users/lost-password/" + token; String messageWithLink = message + "\n\nReset your password here: " + resetLink; mimeMessageHelper.setText(messageWithLink, true); // Set HTML to true to allow links diff --git a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/user/service/UserService.java b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/user/service/UserService.java index ec0e7e235..667f48c44 100644 --- a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/user/service/UserService.java +++ b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/user/service/UserService.java @@ -50,9 +50,9 @@ public interface UserService { Mono resetPassword(String userId); - Mono lostPassword(String userEmail); + Mono lostPassword(String userEmail); - Mono resetLostPassword(String userEmail, String token, String newPassword); + Mono resetLostPassword(String userEmail, String token, String newPassword); Mono setPassword(String userId, String password); diff --git a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/user/service/UserServiceImpl.java b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/user/service/UserServiceImpl.java index 1fe36c169..62e2f8e3b 100644 --- a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/user/service/UserServiceImpl.java +++ b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/user/service/UserServiceImpl.java @@ -16,6 +16,7 @@ import org.lowcoder.domain.group.service.GroupService; import org.lowcoder.domain.organization.model.OrgMember; import org.lowcoder.domain.organization.service.OrgMemberService; +import org.lowcoder.domain.organization.service.OrganizationService; import org.lowcoder.domain.user.model.*; import org.lowcoder.domain.user.model.User.TransformedUserInfo; import org.lowcoder.domain.user.repository.UserRepository; @@ -74,6 +75,8 @@ public class UserServiceImpl implements UserService { @Autowired private OrgMemberService orgMemberService; @Autowired + private OrganizationService organizationService; + @Autowired private GroupService groupService; @Autowired private CommonConfig commonConfig; @@ -269,14 +272,20 @@ public Mono resetPassword(String userId) { } @Override - public Mono lostPassword(String userEmail) { + public Mono lostPassword(String userEmail) { return findByName(userEmail) - .flatMap(user -> { + .zipWhen(user -> orgMemberService.getCurrentOrgMember(user.getId()) + .flatMap(orgMember -> organizationService.getById(orgMember.getOrgId())) + .map(organization -> organization.getCommonSettings().get("PASSWORD_RESET_EMAIL_TEMPLATE"))) + .flatMap(tuple -> { + User user = tuple.getT1(); + String emailTemplate = (String)tuple.getT2(); + String token = generateNewRandomPwd(); Instant tokenExpiry = Instant.now().plus(12, ChronoUnit.HOURS); - // TODO - IRFAN this is just a dummy email. - if (!emailCommunicationService.sendMail("notify@lowcoder.org", token, "Click Here")) { - return ofError(BizError.USER_NOT_EXIST, "SENDING_EMAIL_FAILED"); + + if (!emailCommunicationService.sendMail(userEmail, token, emailTemplate)) { + return ofError(BizError.AUTH_ERROR, "SENDING_EMAIL_FAILED"); } user.setPasswordResetToken(HashUtils.hash(token.getBytes())); user.setPasswordResetTokenExpiry(tokenExpiry); @@ -285,7 +294,7 @@ public Mono lostPassword(String userEmail) { } @Override - public Mono resetLostPassword(String userEmail, String token, String newPassword) { + public Mono resetLostPassword(String userEmail, String token, String newPassword) { return findByName(userEmail) .flatMap(user -> { if (Instant.now().until(user.getPasswordResetTokenExpiry(), ChronoUnit.MINUTES) <= 0) { @@ -303,7 +312,8 @@ public Mono resetLostPassword(String userEmail, String token, String newPa user.setPassword(encryptionService.encryptPassword(newPassword)); user.setPasswordResetToken(StringUtils.EMPTY); user.setPasswordResetTokenExpiry(Instant.now()); - return repository.save(user).then(Mono.empty()); + return repository.save(user) + .thenReturn(true); }); } diff --git a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/usermanagement/UserApiService.java b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/usermanagement/UserApiService.java index e2b6e847c..619ca5b00 100644 --- a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/usermanagement/UserApiService.java +++ b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/usermanagement/UserApiService.java @@ -65,11 +65,11 @@ public Mono resetPassword(String userId) { .then(userService.resetPassword(userId)); } - public Mono lostPassword(String userEmail) { + public Mono lostPassword(String userEmail) { return userService.lostPassword(userEmail); } - public Mono resetLostPassword(String userEmail, String token, String newPassword) { + public Mono resetLostPassword(String userEmail, String token, String newPassword) { return userService.resetLostPassword(userEmail, token, newPassword); } diff --git a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/usermanagement/UserController.java b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/usermanagement/UserController.java index 02dca02ff..feac3deb2 100644 --- a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/usermanagement/UserController.java +++ b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/usermanagement/UserController.java @@ -147,7 +147,7 @@ public Mono> resetPassword(@RequestBody ResetPasswordReques } @Override - public Mono> lostPassword(@RequestBody LostPasswordRequest request) { + public Mono> lostPassword(@RequestBody LostPasswordRequest request) { if (StringUtils.isBlank(request.userEmail())) { return ofError(BizError.INVALID_PARAMETER, "INVALID_USER_EMAIL"); } @@ -156,7 +156,7 @@ public Mono> lostPassword(@RequestBody LostPasswordRequest re } @Override - public Mono> resetLostPassword(@PathVariable String token, @RequestBody ResetLostPasswordRequest request) { + public Mono> resetLostPassword(@PathVariable String token, @RequestBody ResetLostPasswordRequest request) { if (StringUtils.isBlank(request.userEmail()) || StringUtils.isBlank(token) || StringUtils.isBlank(request.newPassword())) { return ofError(BizError.INVALID_PARAMETER, "INVALID_PARAMETER"); diff --git a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/usermanagement/UserEndpoints.java b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/usermanagement/UserEndpoints.java index e5d3f517c..62939c471 100644 --- a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/usermanagement/UserEndpoints.java +++ b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/usermanagement/UserEndpoints.java @@ -122,10 +122,10 @@ public interface UserEndpoints public Mono> resetPassword(@RequestBody ResetPasswordRequest request); @PostMapping("/lost-password") - public Mono> lostPassword(@RequestBody LostPasswordRequest request); + public Mono> lostPassword(@RequestBody LostPasswordRequest request); @PostMapping("/lost-password/{token}") - public Mono> resetLostPassword(@PathVariable String token, @RequestBody ResetLostPasswordRequest request); + public Mono> resetLostPassword(@PathVariable String token, @RequestBody ResetLostPasswordRequest request); @Operation( tags = TAG_USER_PASSWORD_MANAGEMENT, diff --git a/server/api-service/lowcoder-server/src/main/resources/application-lowcoder.yml b/server/api-service/lowcoder-server/src/main/resources/application-lowcoder.yml index 532554b9c..c217ce86e 100644 --- a/server/api-service/lowcoder-server/src/main/resources/application-lowcoder.yml +++ b/server/api-service/lowcoder-server/src/main/resources/application-lowcoder.yml @@ -56,6 +56,7 @@ common: block-hound-enable: false js-executor: host: http://127.0.0.1:6060 + lowcoder_public_url: http://localhost:8080 material: mongodb-grid-fs: From d5c63ea1c953ce0a46801bc21d21d53b97d9d8cd Mon Sep 17 00:00:00 2001 From: Muhammad Irfan Ayub Date: Thu, 22 Feb 2024 20:59:03 +0500 Subject: [PATCH 05/16] feature: Added emailTemplate in common-settings. --- .../organization/service/OrganizationServiceImpl.java | 9 +++++++++ .../domain/user/service/EmailCommunicationService.java | 9 ++++++--- .../lowcoder/domain/user/service/UserServiceImpl.java | 5 +---- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/organization/service/OrganizationServiceImpl.java b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/organization/service/OrganizationServiceImpl.java index 48e4bc6de..c102ff1b0 100644 --- a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/organization/service/OrganizationServiceImpl.java +++ b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/organization/service/OrganizationServiceImpl.java @@ -1,6 +1,7 @@ package org.lowcoder.domain.organization.service; import static org.lowcoder.domain.authentication.AuthenticationService.DEFAULT_AUTH_CONFIG; +import static org.lowcoder.domain.organization.model.Organization.OrganizationCommonSettings.PASSWORD_RESET_EMAIL_TEMPLATE; import static org.lowcoder.domain.organization.model.OrganizationState.ACTIVE; import static org.lowcoder.domain.organization.model.OrganizationState.DELETED; import static org.lowcoder.domain.util.QueryDslUtils.fieldName; @@ -56,6 +57,12 @@ public class OrganizationServiceImpl implements OrganizationService { private final Conf logoMaxSizeInKb; + private static final String PASSWORD_RESET_EMAIL_TEMPLATE_DEFAULT = "

Hi, %s
" + + "Here is the link to reset your password: %s
" + + "Please note that the link will expire after 12 hours.

" + + "Regards,
" + + "The Lowcoder Team

"; + @Autowired private AssetRepository assetRepository; @@ -151,6 +158,8 @@ public Mono create(Organization organization, String creatorId) { if (organization == null || StringUtils.isNotBlank(organization.getId())) { return Mono.error(new BizException(BizError.INVALID_PARAMETER, "INVALID_PARAMETER", FieldName.ORGANIZATION)); } + organization.getCommonSettings().put(PASSWORD_RESET_EMAIL_TEMPLATE, + PASSWORD_RESET_EMAIL_TEMPLATE_DEFAULT); organization.setState(ACTIVE); return Mono.just(organization); }) diff --git a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/user/service/EmailCommunicationService.java b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/user/service/EmailCommunicationService.java index 16fa8f196..8373b60fc 100644 --- a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/user/service/EmailCommunicationService.java +++ b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/user/service/EmailCommunicationService.java @@ -18,7 +18,10 @@ public class EmailCommunicationService { @Value("${spring.mail.username}") private String fromEmail; - public boolean sendMail(String to, String token, String message) { + @Value("${common.lowcoder_public_url}") + private String lowcoderPublicUrl; + + public boolean sendPasswordResetEmail(String to, String token, String message) { try { String subject = "Reset Your Password"; MimeMessage mimeMessage = javaMailSender.createMimeMessage(); @@ -31,8 +34,8 @@ public boolean sendMail(String to, String token, String message) { // Construct the message with the token link String resetLink = lowcoderPublicUrl + "/api/users/lost-password/" + token; - String messageWithLink = message + "\n\nReset your password here: " + resetLink; - mimeMessageHelper.setText(messageWithLink, true); // Set HTML to true to allow links + String formattedMessage = String.format(message, to, resetLink); + mimeMessageHelper.setText(formattedMessage, true); // Set HTML to true to allow links javaMailSender.send(mimeMessage); diff --git a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/user/service/UserServiceImpl.java b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/user/service/UserServiceImpl.java index 62e2f8e3b..7819779aa 100644 --- a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/user/service/UserServiceImpl.java +++ b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/user/service/UserServiceImpl.java @@ -42,9 +42,7 @@ import javax.annotation.Nonnull; import java.security.SecureRandom; -import java.time.Duration; import java.time.Instant; -import java.time.LocalDate; import java.time.temporal.ChronoUnit; import java.util.*; import java.util.function.Function; @@ -283,8 +281,7 @@ public Mono lostPassword(String userEmail) { String token = generateNewRandomPwd(); Instant tokenExpiry = Instant.now().plus(12, ChronoUnit.HOURS); - - if (!emailCommunicationService.sendMail(userEmail, token, emailTemplate)) { + if (!emailCommunicationService.sendPasswordResetEmail(userEmail, token, emailTemplate)) { return ofError(BizError.AUTH_ERROR, "SENDING_EMAIL_FAILED"); } user.setPasswordResetToken(HashUtils.hash(token.getBytes())); From 65d9e2a0af759cca84bceef35cf0cdf8b6925f1c Mon Sep 17 00:00:00 2001 From: Abdul Qadir Date: Mon, 26 Feb 2024 02:12:20 +0500 Subject: [PATCH 06/16] Misc fixes --- .../user/service/EmailCommunicationService.java | 17 +++++++---------- .../org/lowcoder/sdk/config/CommonConfig.java | 10 ++-------- .../api/framework/security/SecurityConfig.java | 2 ++ .../api/usermanagement/UserController.java | 2 +- .../src/main/resources/application-lowcoder.yml | 14 +++----------- 5 files changed, 15 insertions(+), 30 deletions(-) diff --git a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/user/service/EmailCommunicationService.java b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/user/service/EmailCommunicationService.java index 8373b60fc..81f91756f 100644 --- a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/user/service/EmailCommunicationService.java +++ b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/user/service/EmailCommunicationService.java @@ -2,8 +2,8 @@ import jakarta.mail.internet.MimeMessage; import lombok.extern.slf4j.Slf4j; +import org.lowcoder.sdk.config.CommonConfig; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; import org.springframework.mail.javamail.JavaMailSender; import org.springframework.mail.javamail.MimeMessageHelper; import org.springframework.stereotype.Service; @@ -15,25 +15,22 @@ public class EmailCommunicationService { @Autowired private JavaMailSender javaMailSender; - @Value("${spring.mail.username}") - private String fromEmail; - - @Value("${common.lowcoder_public_url}") - private String lowcoderPublicUrl; + @Autowired + private CommonConfig config; public boolean sendPasswordResetEmail(String to, String token, String message) { try { - String subject = "Reset Your Password"; + String subject = "Reset Your Lost Password"; MimeMessage mimeMessage = javaMailSender.createMimeMessage(); MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true); - mimeMessageHelper.setFrom(fromEmail); + mimeMessageHelper.setFrom(config.getLostPasswordEmailSender()); mimeMessageHelper.setTo(to); mimeMessageHelper.setSubject(subject); // Construct the message with the token link - String resetLink = lowcoderPublicUrl + "/api/users/lost-password/" + token; + String resetLink = config.getLowcoderPublicUrl() + "lost-password?token=" + token; String formattedMessage = String.format(message, to, resetLink); mimeMessageHelper.setText(formattedMessage, true); // Set HTML to true to allow links @@ -42,7 +39,7 @@ public boolean sendPasswordResetEmail(String to, String token, String message) { return true; } catch (Exception e) { - log.error("Failed to send mail to: {}, Exception: {}", to, e); + log.error("Failed to send mail to: {}, Exception: ", to, e); return false; } diff --git a/server/api-service/lowcoder-sdk/src/main/java/org/lowcoder/sdk/config/CommonConfig.java b/server/api-service/lowcoder-sdk/src/main/java/org/lowcoder/sdk/config/CommonConfig.java index 2186b8101..08f8730f5 100644 --- a/server/api-service/lowcoder-sdk/src/main/java/org/lowcoder/sdk/config/CommonConfig.java +++ b/server/api-service/lowcoder-sdk/src/main/java/org/lowcoder/sdk/config/CommonConfig.java @@ -45,7 +45,8 @@ public class CommonConfig { private JsExecutor jsExecutor = new JsExecutor(); private Set disallowedHosts = new HashSet<>(); private Marketplace marketplace = new Marketplace(); - private SMTP smtp = new SMTP(); + private String lowcoderPublicUrl; + private String lostPasswordEmailSender; public boolean isSelfHost() { return !isCloud(); @@ -147,13 +148,6 @@ public static class JsExecutor { private String host; } - @Data - public static class SMTP { - private String email; - private String host; - private String port; - } - @Data public static class Marketplace { diff --git a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/framework/security/SecurityConfig.java b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/framework/security/SecurityConfig.java index b933a63e1..9b1b99a0c 100644 --- a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/framework/security/SecurityConfig.java +++ b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/framework/security/SecurityConfig.java @@ -113,6 +113,7 @@ SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) { ServerWebExchangeMatchers.pathMatchers(HttpMethod.GET, USER_URL + "/me"), ServerWebExchangeMatchers.pathMatchers(HttpMethod.GET, USER_URL + "/currentUser"), + ServerWebExchangeMatchers.pathMatchers(HttpMethod.POST, USER_URL + "/lost-password"), ServerWebExchangeMatchers.pathMatchers(HttpMethod.GET, GROUP_URL + "/list"), // application view ServerWebExchangeMatchers.pathMatchers(HttpMethod.POST, QUERY_URL + "/execute"), // application view @@ -139,6 +140,7 @@ SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) { ServerWebExchangeMatchers.pathMatchers(HttpMethod.GET, NewUrl.APPLICATION_URL + "/marketplace-apps"), // marketplace apps ServerWebExchangeMatchers.pathMatchers(HttpMethod.GET, NewUrl.USER_URL + "/me"), ServerWebExchangeMatchers.pathMatchers(HttpMethod.GET, NewUrl.USER_URL + "/currentUser"), + ServerWebExchangeMatchers.pathMatchers(HttpMethod.POST, NewUrl.USER_URL + "/lost-password"), ServerWebExchangeMatchers.pathMatchers(HttpMethod.GET, NewUrl.GROUP_URL + "/list"), ServerWebExchangeMatchers.pathMatchers(HttpMethod.POST, NewUrl.QUERY_URL + "/execute"), ServerWebExchangeMatchers.pathMatchers(HttpMethod.GET, NewUrl.MATERIAL_URL + "/**"), diff --git a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/usermanagement/UserController.java b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/usermanagement/UserController.java index feac3deb2..970f129ae 100644 --- a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/usermanagement/UserController.java +++ b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/usermanagement/UserController.java @@ -149,7 +149,7 @@ public Mono> resetPassword(@RequestBody ResetPasswordReques @Override public Mono> lostPassword(@RequestBody LostPasswordRequest request) { if (StringUtils.isBlank(request.userEmail())) { - return ofError(BizError.INVALID_PARAMETER, "INVALID_USER_EMAIL"); + return ofError(BizError.INVALID_PARAMETER, "INVALID_PARAMETER"); } return userApiService.lostPassword(request.userEmail()) .map(ResponseView::success); diff --git a/server/api-service/lowcoder-server/src/main/resources/application-lowcoder.yml b/server/api-service/lowcoder-server/src/main/resources/application-lowcoder.yml index b08b9680f..b91887386 100644 --- a/server/api-service/lowcoder-server/src/main/resources/application-lowcoder.yml +++ b/server/api-service/lowcoder-server/src/main/resources/application-lowcoder.yml @@ -10,17 +10,8 @@ spring: allow-bean-definition-overriding: true allow-circular-references: true mail: -# TODO - IRFAN this is just a test email to check the email sending. - username: "irfan.ayub@ikhwatech.com" - password: "abcd" - host: "smtp.freesmtpservers.com" + host: smtp.freesmtpservers.com port: 25 -# properties: -# mail: -# smtp: -# starttls: -# enable: true -# auth: true server: compression: @@ -58,7 +49,8 @@ common: host: http://127.0.0.1:6060 marketplace: private-mode: false - lowcoder_public_url: http://localhost:8080 + lowcoder-public-url: http://localhost:8080 + lost-password-email-sender: business@ikhwatech.com material: mongodb-grid-fs: From 39ad3ac732ff15948ff51d27db66945908164487 Mon Sep 17 00:00:00 2001 From: Abdul Qadir Date: Mon, 26 Feb 2024 19:15:29 +0500 Subject: [PATCH 07/16] Misc fixes --- .../lowcoder/domain/organization/model/Organization.java | 2 +- .../organization/service/OrganizationServiceImpl.java | 3 ++- .../domain/user/service/EmailCommunicationService.java | 2 +- .../org/lowcoder/domain/user/service/UserServiceImpl.java | 8 ++------ .../lowcoder-sdk/src/main/resources/locale_en.properties | 3 +++ .../lowcoder/api/framework/security/SecurityConfig.java | 2 ++ .../org/lowcoder/api/usermanagement/UserController.java | 6 +++--- .../org/lowcoder/api/usermanagement/UserEndpoints.java | 6 +++--- 8 files changed, 17 insertions(+), 15 deletions(-) diff --git a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/organization/model/Organization.java b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/organization/model/Organization.java index 6b4d2b05c..21584ba8f 100644 --- a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/organization/model/Organization.java +++ b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/organization/model/Organization.java @@ -86,7 +86,7 @@ public OrganizationCommonSettings getCommonSettings() { public static class OrganizationCommonSettings extends HashMap { public static final String USER_EXTRA_TRANSFORMER = "userExtraTransformer"; public static final String USER_EXTRA_TRANSFORMER_UPDATE_TIME = "userExtraTransformer_updateTime"; - public static final String PASSWORD_RESET_EMAIL_TEMPLATE = "passwordRestEmailTemplate"; + public static final String PASSWORD_RESET_EMAIL_TEMPLATE = "passwordResetEmailTemplate"; // custom branding configs public static final String CUSTOM_BRANDING_KEY = "branding"; } diff --git a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/organization/service/OrganizationServiceImpl.java b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/organization/service/OrganizationServiceImpl.java index c102ff1b0..fb1e55db5 100644 --- a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/organization/service/OrganizationServiceImpl.java +++ b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/organization/service/OrganizationServiceImpl.java @@ -158,7 +158,8 @@ public Mono create(Organization organization, String creatorId) { if (organization == null || StringUtils.isNotBlank(organization.getId())) { return Mono.error(new BizException(BizError.INVALID_PARAMETER, "INVALID_PARAMETER", FieldName.ORGANIZATION)); } - organization.getCommonSettings().put(PASSWORD_RESET_EMAIL_TEMPLATE, + organization.setCommonSettings(new OrganizationCommonSettings()); + organization.getCommonSettings().put("PASSWORD_RESET_EMAIL_TEMPLATE", PASSWORD_RESET_EMAIL_TEMPLATE_DEFAULT); organization.setState(ACTIVE); return Mono.just(organization); diff --git a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/user/service/EmailCommunicationService.java b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/user/service/EmailCommunicationService.java index 81f91756f..439aa65a8 100644 --- a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/user/service/EmailCommunicationService.java +++ b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/user/service/EmailCommunicationService.java @@ -30,7 +30,7 @@ public boolean sendPasswordResetEmail(String to, String token, String message) { mimeMessageHelper.setSubject(subject); // Construct the message with the token link - String resetLink = config.getLowcoderPublicUrl() + "lost-password?token=" + token; + String resetLink = config.getLowcoderPublicUrl() + "/lost-password?token=" + token; String formattedMessage = String.format(message, to, resetLink); mimeMessageHelper.setText(formattedMessage, true); // Set HTML to true to allow links diff --git a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/user/service/UserServiceImpl.java b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/user/service/UserServiceImpl.java index 7819779aa..677a15a49 100644 --- a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/user/service/UserServiceImpl.java +++ b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/user/service/UserServiceImpl.java @@ -295,15 +295,11 @@ public Mono resetLostPassword(String userEmail, String token, String ne return findByName(userEmail) .flatMap(user -> { if (Instant.now().until(user.getPasswordResetTokenExpiry(), ChronoUnit.MINUTES) <= 0) { - return ofError(BizError.LOGIN_EXPIRED, "TOKEN_EXPIRED"); + return ofError(BizError.INVALID_PARAMETER, "TOKEN_EXPIRED"); } if (!StringUtils.equals(HashUtils.hash(token.getBytes()), user.getPasswordResetToken())) { - return ofError(BizError.INVALID_PASSWORD, "INVALID_TOKEN"); - } - - if (StringUtils.isBlank(newPassword)) { - return ofError(BizError.INVALID_PASSWORD, "PASSWORD_NOT_SET_YET"); + return ofError(BizError.INVALID_PARAMETER, "INVALID_TOKEN"); } user.setPassword(encryptionService.encryptPassword(newPassword)); diff --git a/server/api-service/lowcoder-sdk/src/main/resources/locale_en.properties b/server/api-service/lowcoder-sdk/src/main/resources/locale_en.properties index d81ecbdf2..1e3a18c31 100644 --- a/server/api-service/lowcoder-sdk/src/main/resources/locale_en.properties +++ b/server/api-service/lowcoder-sdk/src/main/resources/locale_en.properties @@ -17,6 +17,9 @@ CANNOT_DELETE_SYSTEM_GROUP=System group cannot be deleted. NEED_DEV_TO_CREATE_RESOURCE=Invalid operation, workspace developers or admin required. UNABLE_TO_FIND_VALID_ORG=Cannot find a valid workspace for current user. USER_BANNED=Current account is frozen. +SENDING_EMAIL_FAILED=Email could not be sent. Please check the smtp settings for the org. +TOKEN_EXPIRED=Token to reset the password has expired +INVALID_TOKEN=Invalid token received for password reset request # invitation INVALID_INVITATION_CODE=Invitation code not found. ALREADY_IN_ORGANIZATION=You are already in this workspace. diff --git a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/framework/security/SecurityConfig.java b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/framework/security/SecurityConfig.java index 9b1b99a0c..82174984f 100644 --- a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/framework/security/SecurityConfig.java +++ b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/framework/security/SecurityConfig.java @@ -114,6 +114,7 @@ SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) { ServerWebExchangeMatchers.pathMatchers(HttpMethod.GET, USER_URL + "/me"), ServerWebExchangeMatchers.pathMatchers(HttpMethod.GET, USER_URL + "/currentUser"), ServerWebExchangeMatchers.pathMatchers(HttpMethod.POST, USER_URL + "/lost-password"), + ServerWebExchangeMatchers.pathMatchers(HttpMethod.POST, USER_URL + "/reset-lost-password"), ServerWebExchangeMatchers.pathMatchers(HttpMethod.GET, GROUP_URL + "/list"), // application view ServerWebExchangeMatchers.pathMatchers(HttpMethod.POST, QUERY_URL + "/execute"), // application view @@ -141,6 +142,7 @@ SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) { ServerWebExchangeMatchers.pathMatchers(HttpMethod.GET, NewUrl.USER_URL + "/me"), ServerWebExchangeMatchers.pathMatchers(HttpMethod.GET, NewUrl.USER_URL + "/currentUser"), ServerWebExchangeMatchers.pathMatchers(HttpMethod.POST, NewUrl.USER_URL + "/lost-password"), + ServerWebExchangeMatchers.pathMatchers(HttpMethod.POST, NewUrl.USER_URL + "/reset-lost-password"), ServerWebExchangeMatchers.pathMatchers(HttpMethod.GET, NewUrl.GROUP_URL + "/list"), ServerWebExchangeMatchers.pathMatchers(HttpMethod.POST, NewUrl.QUERY_URL + "/execute"), ServerWebExchangeMatchers.pathMatchers(HttpMethod.GET, NewUrl.MATERIAL_URL + "/**"), diff --git a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/usermanagement/UserController.java b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/usermanagement/UserController.java index 970f129ae..ee4aac0bb 100644 --- a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/usermanagement/UserController.java +++ b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/usermanagement/UserController.java @@ -156,13 +156,13 @@ public Mono> lostPassword(@RequestBody LostPasswordRequest } @Override - public Mono> resetLostPassword(@PathVariable String token, @RequestBody ResetLostPasswordRequest request) { - if (StringUtils.isBlank(request.userEmail()) || StringUtils.isBlank(token) + public Mono> resetLostPassword(@RequestBody ResetLostPasswordRequest request) { + if (StringUtils.isBlank(request.userEmail()) || StringUtils.isBlank(request.token()) || StringUtils.isBlank(request.newPassword())) { return ofError(BizError.INVALID_PARAMETER, "INVALID_PARAMETER"); } - return userApiService.resetLostPassword(request.userEmail(), token, request.newPassword()) + return userApiService.resetLostPassword(request.userEmail(), request.token(), request.newPassword()) .map(ResponseView::success); } diff --git a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/usermanagement/UserEndpoints.java b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/usermanagement/UserEndpoints.java index 62939c471..196925134 100644 --- a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/usermanagement/UserEndpoints.java +++ b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/usermanagement/UserEndpoints.java @@ -124,8 +124,8 @@ public interface UserEndpoints @PostMapping("/lost-password") public Mono> lostPassword(@RequestBody LostPasswordRequest request); - @PostMapping("/lost-password/{token}") - public Mono> resetLostPassword(@PathVariable String token, @RequestBody ResetLostPasswordRequest request); + @PostMapping("/reset-lost-password") + public Mono> resetLostPassword(@RequestBody ResetLostPasswordRequest request); @Operation( tags = TAG_USER_PASSWORD_MANAGEMENT, @@ -160,7 +160,7 @@ public record ResetPasswordRequest(String userId) { public record LostPasswordRequest(String userEmail) { } - public record ResetLostPasswordRequest(String userEmail, String newPassword) { + public record ResetLostPasswordRequest(String token, String userEmail, String newPassword) { } public record UpdatePasswordRequest(String oldPassword, String newPassword) { From 72518dc21c84238e9b0242e278d96f65c4547570 Mon Sep 17 00:00:00 2001 From: Abdul Qadir Date: Mon, 26 Feb 2024 19:19:26 +0500 Subject: [PATCH 08/16] Update application.props --- .../lowcoder-server/src/main/resources/application-lowcoder.yml | 2 +- .../src/main/resources/selfhost/ce/application.yml | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/server/api-service/lowcoder-server/src/main/resources/application-lowcoder.yml b/server/api-service/lowcoder-server/src/main/resources/application-lowcoder.yml index b91887386..31774d18d 100644 --- a/server/api-service/lowcoder-server/src/main/resources/application-lowcoder.yml +++ b/server/api-service/lowcoder-server/src/main/resources/application-lowcoder.yml @@ -50,7 +50,7 @@ common: marketplace: private-mode: false lowcoder-public-url: http://localhost:8080 - lost-password-email-sender: business@ikhwatech.com + lost-password-email-sender: info@lowcoder.org material: mongodb-grid-fs: diff --git a/server/api-service/lowcoder-server/src/main/resources/selfhost/ce/application.yml b/server/api-service/lowcoder-server/src/main/resources/selfhost/ce/application.yml index 11c0511c2..b8c979354 100644 --- a/server/api-service/lowcoder-server/src/main/resources/selfhost/ce/application.yml +++ b/server/api-service/lowcoder-server/src/main/resources/selfhost/ce/application.yml @@ -55,6 +55,8 @@ common: mode: ${LOWCODER_WORKSPACE_MODE:SAAS} marketplace: private-mode: ${MARKETPLACE_PRIVATE_MODE:true} + lowcoder-public-url: ${LOWCODER_PUBLIC_URL:http://localhost:8080} + lost-password-email-sender: ${LOWCODER_LOST_PASSWORD_EMAIL_SENDER:info@lowcoder.org} material: mongodb-grid-fs: From d3844185a384dd7864b3db5da3051fb81fcfeb7c Mon Sep 17 00:00:00 2001 From: Abdul Qadir Date: Tue, 27 Feb 2024 00:27:35 +0500 Subject: [PATCH 09/16] Update application.props to include smtp server auth --- .../src/main/resources/application-lowcoder.yml | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/server/api-service/lowcoder-server/src/main/resources/application-lowcoder.yml b/server/api-service/lowcoder-server/src/main/resources/application-lowcoder.yml index 31774d18d..61c9f527f 100644 --- a/server/api-service/lowcoder-server/src/main/resources/application-lowcoder.yml +++ b/server/api-service/lowcoder-server/src/main/resources/application-lowcoder.yml @@ -10,8 +10,19 @@ spring: allow-bean-definition-overriding: true allow-circular-references: true mail: - host: smtp.freesmtpservers.com - port: 25 + host: smtp.gmail.com + port: 587 + username: yourmail@gmail.com + password: yourpass + properties: + mail: + smtp: + auth: true + starttls: + enable: true + required: true + transport: + protocol: smtp server: compression: From 0391d2a1bf23560d8ff712889ff1dd791ac91be7 Mon Sep 17 00:00:00 2001 From: Muhammad Irfan Ayub Date: Tue, 27 Feb 2024 17:51:15 +0500 Subject: [PATCH 10/16] feature: Added Env Variables for SMPT server --- .../src/main/resources/selfhost/ce/application.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/server/api-service/lowcoder-server/src/main/resources/selfhost/ce/application.yml b/server/api-service/lowcoder-server/src/main/resources/selfhost/ce/application.yml index 15b146493..a0a328f0d 100644 --- a/server/api-service/lowcoder-server/src/main/resources/selfhost/ce/application.yml +++ b/server/api-service/lowcoder-server/src/main/resources/selfhost/ce/application.yml @@ -18,6 +18,11 @@ spring: max-in-memory-size: 20MB webflux: context-path: / + mail: + host: ${LOWCODER_SMTP_HOST:smtp.gmail.com} + port: ${LOWCODER_SMTP_PORT:587} + username: ${LOWCODER_SMTP_USERNAME:yourmail@gmail.com} + password: ${LOWCODER_SMTP_PASSWORD:yourpass} server: compression: From bc74e8ac373de7b1291223e23c0b8104898b8261 Mon Sep 17 00:00:00 2001 From: Muhammad Irfan Ayub Date: Tue, 27 Feb 2024 17:56:23 +0500 Subject: [PATCH 11/16] feature: Rename SMTP Env variable to ADMIN --- .../src/main/resources/selfhost/ce/application.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/server/api-service/lowcoder-server/src/main/resources/selfhost/ce/application.yml b/server/api-service/lowcoder-server/src/main/resources/selfhost/ce/application.yml index a0a328f0d..ca9b5b06a 100644 --- a/server/api-service/lowcoder-server/src/main/resources/selfhost/ce/application.yml +++ b/server/api-service/lowcoder-server/src/main/resources/selfhost/ce/application.yml @@ -19,10 +19,10 @@ spring: webflux: context-path: / mail: - host: ${LOWCODER_SMTP_HOST:smtp.gmail.com} - port: ${LOWCODER_SMTP_PORT:587} - username: ${LOWCODER_SMTP_USERNAME:yourmail@gmail.com} - password: ${LOWCODER_SMTP_PASSWORD:yourpass} + host: ${LOWCODER_ADMIN_SMTP_HOST:smtp.gmail.com} + port: ${LOWCODER_ADMIN_SMTP_PORT:587} + username: ${LOWCODER_ADMIN_SMTP_USERNAME:yourmail@gmail.com} + password: ${LOWCODER_ADMIN_SMTP_PASSWORD:yourpass} server: compression: From 53439456094f04b0038c00b9284a6086162966c8 Mon Sep 17 00:00:00 2001 From: Muhammad Irfan Ayub Date: Wed, 13 Mar 2024 16:33:54 +0500 Subject: [PATCH 12/16] changed the API response to empty in case user does not exist. --- .../java/org/lowcoder/domain/user/service/UserServiceImpl.java | 2 +- .../java/org/lowcoder/api/usermanagement/UserController.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/user/service/UserServiceImpl.java b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/user/service/UserServiceImpl.java index 677a15a49..0eec56527 100644 --- a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/user/service/UserServiceImpl.java +++ b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/user/service/UserServiceImpl.java @@ -282,7 +282,7 @@ public Mono lostPassword(String userEmail) { String token = generateNewRandomPwd(); Instant tokenExpiry = Instant.now().plus(12, ChronoUnit.HOURS); if (!emailCommunicationService.sendPasswordResetEmail(userEmail, token, emailTemplate)) { - return ofError(BizError.AUTH_ERROR, "SENDING_EMAIL_FAILED"); + return Mono.empty(); } user.setPasswordResetToken(HashUtils.hash(token.getBytes())); user.setPasswordResetTokenExpiry(tokenExpiry); diff --git a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/usermanagement/UserController.java b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/usermanagement/UserController.java index ee4aac0bb..56cccffd5 100644 --- a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/usermanagement/UserController.java +++ b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/usermanagement/UserController.java @@ -149,7 +149,7 @@ public Mono> resetPassword(@RequestBody ResetPasswordReques @Override public Mono> lostPassword(@RequestBody LostPasswordRequest request) { if (StringUtils.isBlank(request.userEmail())) { - return ofError(BizError.INVALID_PARAMETER, "INVALID_PARAMETER"); + return Mono.empty(); } return userApiService.lostPassword(request.userEmail()) .map(ResponseView::success); From 833c22bcf9ec29f3fff239692fb5966eb7ca9e42 Mon Sep 17 00:00:00 2001 From: Muhammad Irfan Ayub Date: Wed, 13 Mar 2024 16:34:11 +0500 Subject: [PATCH 13/16] Added env Variables. --- .../src/main/resources/selfhost/ce/application.yml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/server/api-service/lowcoder-server/src/main/resources/selfhost/ce/application.yml b/server/api-service/lowcoder-server/src/main/resources/selfhost/ce/application.yml index ca9b5b06a..44dd8a3f1 100644 --- a/server/api-service/lowcoder-server/src/main/resources/selfhost/ce/application.yml +++ b/server/api-service/lowcoder-server/src/main/resources/selfhost/ce/application.yml @@ -23,7 +23,15 @@ spring: port: ${LOWCODER_ADMIN_SMTP_PORT:587} username: ${LOWCODER_ADMIN_SMTP_USERNAME:yourmail@gmail.com} password: ${LOWCODER_ADMIN_SMTP_PASSWORD:yourpass} - + properties: + mail: + smtp: + auth: ${LOWCODER_ADMIN_SMTP_AUTH:true} + starttls: + enable: ${LOWCODER_ADMIN_SMTP_STARTTLS_ENABLED:true} + required: ${LOWCODER_ADMIN_SMTP_STARTTLS_REQUIRED:true} + transport: + protocol: smtp server: compression: enabled: true From c5447c3a152034f68526ad658b53c176f9fa022b Mon Sep 17 00:00:00 2001 From: Muhammad Irfan Ayub Date: Thu, 14 Mar 2024 15:39:23 +0500 Subject: [PATCH 14/16] Added ssl auth. --- .../lowcoder-server/src/main/resources/application-lowcoder.yml | 2 ++ .../src/main/resources/selfhost/ce/application.yml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/server/api-service/lowcoder-server/src/main/resources/application-lowcoder.yml b/server/api-service/lowcoder-server/src/main/resources/application-lowcoder.yml index 61c9f527f..817cc0c4f 100644 --- a/server/api-service/lowcoder-server/src/main/resources/application-lowcoder.yml +++ b/server/api-service/lowcoder-server/src/main/resources/application-lowcoder.yml @@ -18,6 +18,8 @@ spring: mail: smtp: auth: true + ssl: + enable: false starttls: enable: true required: true diff --git a/server/api-service/lowcoder-server/src/main/resources/selfhost/ce/application.yml b/server/api-service/lowcoder-server/src/main/resources/selfhost/ce/application.yml index 44dd8a3f1..7146b1d27 100644 --- a/server/api-service/lowcoder-server/src/main/resources/selfhost/ce/application.yml +++ b/server/api-service/lowcoder-server/src/main/resources/selfhost/ce/application.yml @@ -27,6 +27,8 @@ spring: mail: smtp: auth: ${LOWCODER_ADMIN_SMTP_AUTH:true} + ssl: + enable: ${LOWCODER_ADMIN_SMTP_SSL_ENABLED:false} starttls: enable: ${LOWCODER_ADMIN_SMTP_STARTTLS_ENABLED:true} required: ${LOWCODER_ADMIN_SMTP_STARTTLS_REQUIRED:true} From e5613c5e8fb7697cdd359a8ccb28a89942e8220e Mon Sep 17 00:00:00 2001 From: Muhammad Irfan Ayub Date: Thu, 14 Mar 2024 19:33:51 +0500 Subject: [PATCH 15/16] updated email sender filed name --- .../lowcoder-server/src/main/resources/application-lowcoder.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/api-service/lowcoder-server/src/main/resources/application-lowcoder.yml b/server/api-service/lowcoder-server/src/main/resources/application-lowcoder.yml index 817cc0c4f..39d69fe29 100644 --- a/server/api-service/lowcoder-server/src/main/resources/application-lowcoder.yml +++ b/server/api-service/lowcoder-server/src/main/resources/application-lowcoder.yml @@ -63,7 +63,7 @@ common: marketplace: private-mode: false lowcoder-public-url: http://localhost:8080 - lost-password-email-sender: info@lowcoder.org + notifications-email-sender: info@lowcoder.org material: mongodb-grid-fs: From a8b2ece63975baecb5189bdd4c79992ee118c8f4 Mon Sep 17 00:00:00 2001 From: Muhammad Irfan Ayub Date: Thu, 14 Mar 2024 19:35:13 +0500 Subject: [PATCH 16/16] updated email sender filed name --- .../src/main/resources/selfhost/ce/application.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/api-service/lowcoder-server/src/main/resources/selfhost/ce/application.yml b/server/api-service/lowcoder-server/src/main/resources/selfhost/ce/application.yml index 7146b1d27..6365dd8a7 100644 --- a/server/api-service/lowcoder-server/src/main/resources/selfhost/ce/application.yml +++ b/server/api-service/lowcoder-server/src/main/resources/selfhost/ce/application.yml @@ -71,7 +71,7 @@ common: marketplace: private-mode: ${LOWCODER_MARKETPLACE_PRIVATE_MODE:true} lowcoder-public-url: ${LOWCODER_PUBLIC_URL:http://localhost:8080} - lost-password-email-sender: ${LOWCODER_LOST_PASSWORD_EMAIL_SENDER:info@lowcoder.org} + notifications-email-sender: ${LOWCODER_LOST_PASSWORD_EMAIL_SENDER:info@lowcoder.org} material: mongodb-grid-fs: