Skip to content

Commit d90e28c

Browse files
authored
Merge pull request #1640 from lowcoder-org/invite_email
Invite by email
2 parents dbe38fc + 3e490d3 commit d90e28c

File tree

6 files changed

+82
-9
lines changed

6 files changed

+82
-9
lines changed

server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/user/service/EmailCommunicationService.java

+1
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@
22

33
public interface EmailCommunicationService {
44
boolean sendPasswordResetEmail(String to, String token, String message);
5+
boolean sendInvitationEmails(String[] to, String inviteLink, String message);
56
}

server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/user/service/EmailCommunicationServiceImpl.java

+28
Original file line numberDiff line numberDiff line change
@@ -49,4 +49,32 @@ public boolean sendPasswordResetEmail(String to, String token, String message) {
4949

5050
}
5151

52+
@Override
53+
public boolean sendInvitationEmails(String[] to, String inviteLink, String message) {
54+
try {
55+
String subject = "You've been invited!";
56+
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
57+
58+
MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true);
59+
60+
mimeMessageHelper.setFrom(config.getNotificationsEmailSender());
61+
mimeMessageHelper.setTo(to);
62+
mimeMessageHelper.setSubject(subject);
63+
64+
// Construct the message with the invite link
65+
String formattedMessage = String.format(message, inviteLink);
66+
mimeMessageHelper.setText(formattedMessage, true); // Set HTML to true to allow links
67+
68+
javaMailSender.send(mimeMessage);
69+
70+
return true;
71+
72+
} catch (Exception e) {
73+
log.error("Failed to send mail to: {}, Exception: ", to, e);
74+
return false;
75+
}
76+
77+
78+
}
79+
5280
}

server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/authentication/AuthenticationController.java

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package org.lowcoder.api.authentication;
22

3-
import lombok.RequiredArgsConstructor;
3+
import java.util.List;
4+
45
import org.lowcoder.api.authentication.dto.APIKeyRequest;
56
import org.lowcoder.api.authentication.dto.AuthConfigRequest;
67
import org.lowcoder.api.authentication.service.AuthenticationApiService;
@@ -20,9 +21,9 @@
2021
import org.springframework.web.bind.annotation.RequestParam;
2122
import org.springframework.web.bind.annotation.RestController;
2223
import org.springframework.web.server.ServerWebExchange;
23-
import reactor.core.publisher.Mono;
2424

25-
import java.util.List;
25+
import lombok.RequiredArgsConstructor;
26+
import reactor.core.publisher.Mono;
2627

2728
@RequiredArgsConstructor
2829
@RestController

server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/authentication/AuthenticationEndpoints.java

+16-6
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package org.lowcoder.api.authentication;
22

3-
import com.fasterxml.jackson.annotation.JsonView;
4-
import io.swagger.v3.oas.annotations.Operation;
3+
import java.util.List;
4+
55
import org.lowcoder.api.authentication.dto.APIKeyRequest;
66
import org.lowcoder.api.authentication.dto.AuthConfigRequest;
77
import org.lowcoder.api.framework.view.ResponseView;
@@ -13,11 +13,20 @@
1313
import org.lowcoder.sdk.auth.AbstractAuthConfig;
1414
import org.lowcoder.sdk.config.JsonViews;
1515
import org.lowcoder.sdk.constants.AuthSourceConstants;
16-
import org.springframework.web.bind.annotation.*;
16+
import org.springframework.web.bind.annotation.DeleteMapping;
17+
import org.springframework.web.bind.annotation.GetMapping;
18+
import org.springframework.web.bind.annotation.PathVariable;
19+
import org.springframework.web.bind.annotation.PostMapping;
20+
import org.springframework.web.bind.annotation.RequestBody;
21+
import org.springframework.web.bind.annotation.RequestMapping;
22+
import org.springframework.web.bind.annotation.RequestParam;
23+
import org.springframework.web.bind.annotation.RestController;
1724
import org.springframework.web.server.ServerWebExchange;
18-
import reactor.core.publisher.Mono;
1925

20-
import java.util.List;
26+
import com.fasterxml.jackson.annotation.JsonView;
27+
28+
import io.swagger.v3.oas.annotations.Operation;
29+
import reactor.core.publisher.Mono;
2130

2231
@RestController
2332
@RequestMapping(value = {NewUrl.CUSTOM_AUTH})
@@ -159,4 +168,5 @@ public Mono<ResponseView<Boolean>> linkAccountWithThirdParty(
159168
*/
160169
public record FormLoginRequest(String loginId, String password, boolean register, String source, String authId) {
161170
}
162-
}
171+
}
172+

server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/usermanagement/InvitationController.java

+17
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
import org.lowcoder.api.framework.view.ResponseView;
88
import org.lowcoder.api.home.SessionUserService;
99
import org.lowcoder.api.usermanagement.view.InvitationVO;
10+
import org.lowcoder.domain.user.service.EmailCommunicationService;
11+
import org.lowcoder.sdk.config.CommonConfig;
1012
import org.springframework.beans.factory.annotation.Autowired;
1113
import org.springframework.web.bind.annotation.PathVariable;
1214
import org.springframework.web.bind.annotation.RequestParam;
@@ -24,6 +26,12 @@ public class InvitationController implements InvitationEndpoints
2426
@Autowired
2527
private SessionUserService sessionUserService;
2628

29+
@Autowired
30+
private EmailCommunicationService emailCommunicationService;
31+
32+
@Autowired
33+
private CommonConfig config;
34+
2735
@Override
2836
public Mono<ResponseView<InvitationVO>> create(@RequestParam String orgId) {
2937
return invitationApiService.create(orgId)
@@ -50,4 +58,13 @@ public Mono<ResponseView<?>> inviteUser(@PathVariable String invitationId) {
5058
);
5159
}
5260

61+
@Override
62+
public Mono<ResponseView<Boolean>> sendInvitationEmails(InviteEmailRequest req) {
63+
return invitationApiService.create(req.orgId()).map(invitation ->
64+
emailCommunicationService.sendInvitationEmails(req.emails(),
65+
config.getLowcoderPublicUrl() + "/invite/" + invitation.getInviteCode(),
66+
"You have been invited to join our platform. Click here to accept the invitation: %s"))
67+
.map(ResponseView::success);
68+
}
69+
5370
}

server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/usermanagement/InvitationEndpoints.java

+16
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import org.springframework.web.bind.annotation.GetMapping;
88
import org.springframework.web.bind.annotation.PathVariable;
99
import org.springframework.web.bind.annotation.PostMapping;
10+
import org.springframework.web.bind.annotation.RequestBody;
1011
import org.springframework.web.bind.annotation.RequestMapping;
1112
import org.springframework.web.bind.annotation.RequestParam;
1213
import org.springframework.web.bind.annotation.RestController;
@@ -46,5 +47,20 @@ public interface InvitationEndpoints
4647
)
4748
@GetMapping("/{invitationId}/invite")
4849
public Mono<ResponseView<?>> inviteUser(@PathVariable String invitationId);
50+
51+
@Operation(
52+
tags = TAG_INVITATION_MANAGEMENT,
53+
operationId = "sendInvitationEmails",
54+
summary = "Send invitation emails",
55+
description = "Send invitation emails to the specified addresses"
56+
)
57+
@PostMapping("/email/invite")
58+
public Mono<ResponseView<Boolean>> sendInvitationEmails(@RequestBody InviteEmailRequest req);
59+
/**
60+
* @param emails email addresses to send the invitation to
61+
* @param inviteLink the link to be included in the email
62+
*/
63+
public record InviteEmailRequest(String[] emails, String orgId) {
64+
}
4965

5066
}

0 commit comments

Comments
 (0)