diff --git a/pom.xml b/pom.xml
index 46a9ad1..03eda40 100644
--- a/pom.xml
+++ b/pom.xml
@@ -67,6 +67,10 @@
org.springframework.boot
spring-boot-starter-security
+
+ org.springframework.boot
+ spring-boot-starter-mail
+
diff --git a/src/main/java/org/otherband/Utils.java b/src/main/java/org/otherband/Utils.java
index 415c83c..603c5a3 100644
--- a/src/main/java/org/otherband/Utils.java
+++ b/src/main/java/org/otherband/Utils.java
@@ -1,8 +1,12 @@
package org.otherband;
+import org.otherband.email.VerificationLinkEmailRequest;
import org.otherband.exceptions.UserInputException;
+import org.otherband.letter.RecommendationLetterController;
import static org.apache.commons.lang3.StringUtils.isBlank;
+import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
+import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn;
public class Utils {
@@ -11,4 +15,11 @@ private Utils() {
public static void validateNotBlank(String field, String fieldName) {
if (isBlank(field)) throw UserInputException.formatted("[%s] cannot be blank", fieldName);
}
+
+ public static String buildLetterVerificationLink(VerificationLinkEmailRequest verificationLinkEmailRequest) {
+ return linkTo(methodOn(RecommendationLetterController.class)
+ .verify(verificationLinkEmailRequest.getLetterId(),
+ verificationLinkEmailRequest.getTokenId(),
+ verificationLinkEmailRequest.getSecretToken())).withSelfRel().toString();
+ }
}
diff --git a/src/main/java/org/otherband/email/simulation/EmailServiceSimulator.java b/src/main/java/org/otherband/email/simulation/EmailServiceSimulator.java
index 3c9e78b..632eb89 100644
--- a/src/main/java/org/otherband/email/simulation/EmailServiceSimulator.java
+++ b/src/main/java/org/otherband/email/simulation/EmailServiceSimulator.java
@@ -1,15 +1,11 @@
package org.otherband.email.simulation;
+import org.otherband.Utils;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Component;
import org.otherband.email.EmailService;
import org.otherband.email.VerificationLinkEmailRequest;
-import org.otherband.letter.RecommendationLetterController;
-
import java.util.UUID;
-
-import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
-import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn;
import static org.otherband.email.simulation.SimulatedEmailsRepository.SimulatedEmail;
@Component
@@ -23,23 +19,17 @@ public EmailServiceSimulator(SimulatedEmailsRepository emailsRepository) {
@Override
public void sendLetterVerificationLink(VerificationLinkEmailRequest verificationLinkEmailRequest) {
- emailsRepository.save(buildEmail(verificationLinkEmailRequest.getLetterId(),
- verificationLinkEmailRequest.getTokenId(),
- verificationLinkEmailRequest.getSecretToken(),
- verificationLinkEmailRequest.getReceiverEmail()));
+ emailsRepository.save(buildEmail(verificationLinkEmailRequest));
}
- private static SimulatedEmail buildEmail(String letterId, String tokenId, String secretToken, String receiverAddress) {
+ private static SimulatedEmail buildEmail(VerificationLinkEmailRequest verificationLinkEmailRequest) {
SimulatedEmail simulatedEmail = new SimulatedEmail();
simulatedEmail.setId(UUID.randomUUID().toString());
- simulatedEmail.setEmailTitle(String.format("Verification link for recommendation letter [%s]", letterId));
- simulatedEmail.setEmailBody(buildLink(letterId, tokenId, secretToken));
- simulatedEmail.setReceiverAddress(receiverAddress);
+ simulatedEmail.setEmailTitle(String.format("Verification link for recommendation letter [%s]",
+ verificationLinkEmailRequest.getLetterId()));
+ simulatedEmail.setEmailBody(Utils.buildLetterVerificationLink(verificationLinkEmailRequest));
+ simulatedEmail.setReceiverAddress(verificationLinkEmailRequest.getReceiverEmail());
return simulatedEmail;
}
- private static String buildLink(String letterId, String tokenId, String secretToken) {
- return linkTo(methodOn(RecommendationLetterController.class)
- .verify(letterId, tokenId, secretToken)).withSelfRel().toString();
- }
}
diff --git a/src/main/java/org/otherband/email/smtp/SMTPEmailService.java b/src/main/java/org/otherband/email/smtp/SMTPEmailService.java
new file mode 100644
index 0000000..a51af51
--- /dev/null
+++ b/src/main/java/org/otherband/email/smtp/SMTPEmailService.java
@@ -0,0 +1,32 @@
+package org.otherband.email.smtp;
+
+import org.otherband.Utils;
+import org.otherband.email.EmailService;
+import org.otherband.email.VerificationLinkEmailRequest;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Profile;
+import org.springframework.mail.SimpleMailMessage;
+import org.springframework.mail.javamail.JavaMailSender;
+import org.springframework.stereotype.Service;
+
+@Profile("production")
+@Service
+public class SMTPEmailService implements EmailService {
+ private final String mailUserName;
+ private final JavaMailSender mailSender;
+
+ public SMTPEmailService(@Value("${spring.mail.username}") String mailUserName, JavaMailSender mailSender) {
+ this.mailUserName = mailUserName;
+ this.mailSender = mailSender;
+ }
+
+ @Override
+ public void sendLetterVerificationLink(VerificationLinkEmailRequest verificationLinkEmailRequest) {
+ SimpleMailMessage message = new SimpleMailMessage();
+ message.setFrom(mailUserName);
+ message.setTo(verificationLinkEmailRequest.getReceiverEmail());
+ message.setText(Utils.buildLetterVerificationLink(verificationLinkEmailRequest));
+ message.setSubject("Recommendation letter verification link");
+ mailSender.send(message);
+ }
+}
\ No newline at end of file
diff --git a/src/main/resources/application-mail.properties b/src/main/resources/application-mail.properties
new file mode 100644
index 0000000..4e99e57
--- /dev/null
+++ b/src/main/resources/application-mail.properties
@@ -0,0 +1,4 @@
+spring.mail.host=smtp.gmail.com
+spring.mail.port=587
+spring.mail.username=
+spring.mail.password=
diff --git a/src/test/java/org/otherband/email/smtp/SMTPEmailServiceTest.java b/src/test/java/org/otherband/email/smtp/SMTPEmailServiceTest.java
new file mode 100644
index 0000000..b9ddab8
--- /dev/null
+++ b/src/test/java/org/otherband/email/smtp/SMTPEmailServiceTest.java
@@ -0,0 +1,49 @@
+package org.otherband.email.smtp;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.ArgumentCaptor;
+import org.otherband.email.VerificationLinkEmailRequest;
+import org.springframework.mail.SimpleMailMessage;
+import org.springframework.mail.javamail.JavaMailSender;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+class SMTPEmailServiceTest {
+ private static final String EXPECTED_ID = "LETTER_ID";
+ public static final String EXPECTED_RECEIVER_EMAIL = "email@email.com";
+ public static final String TOKEN_ID = "TOKEN_ID";
+ public static final String SECRET = "SECRET";
+ private SMTPEmailService service;
+ private final static String SENDER_EMAIL = "test@email.com";
+ private JavaMailSender mailSender;
+
+ @BeforeEach
+ void setup() {
+ mailSender = mock(JavaMailSender.class);
+ service = new SMTPEmailService(SENDER_EMAIL, mailSender);
+ }
+
+ @Test
+ void testSendVerificationEmail() {
+ VerificationLinkEmailRequest verificationLinkEmailRequest = buildRequest();
+ service.sendLetterVerificationLink(verificationLinkEmailRequest);
+ ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(SimpleMailMessage.class);
+ verify(mailSender).send(argumentCaptor.capture());
+ SimpleMailMessage sentMessage = argumentCaptor.getValue();
+ assertArrayEquals(new String[]{EXPECTED_RECEIVER_EMAIL}, sentMessage.getTo());
+ assertEquals("Recommendation letter verification link", sentMessage.getSubject());
+ assertTrue(sentMessage.getText().contains("/api/v1/recommendation-letter/verify/LETTER_ID/TOKEN_ID/SECRET"));
+ }
+
+ private static VerificationLinkEmailRequest buildRequest() {
+ VerificationLinkEmailRequest request = new VerificationLinkEmailRequest();
+ request.setLetterId(EXPECTED_ID);
+ request.setTokenId(TOKEN_ID);
+ request.setSecretToken(SECRET);
+ request.setReceiverEmail(EXPECTED_RECEIVER_EMAIL);
+ return request;
+ }
+}
\ No newline at end of file