diff --git a/src/main/java/com/libraryman_api/newsletter/EmailService1.java b/src/main/java/com/libraryman_api/newsletter/EmailService1.java new file mode 100644 index 0000000..b1f2086 --- /dev/null +++ b/src/main/java/com/libraryman_api/newsletter/EmailService1.java @@ -0,0 +1,32 @@ +package com.libraryman_api.newsletter; + + +import jakarta.mail.MessagingException; +import jakarta.mail.internet.MimeMessage; +import org.springframework.mail.javamail.JavaMailSender; +import org.springframework.mail.javamail.MimeMessageHelper; +import org.springframework.stereotype.Service; + +@Service +public class EmailService1 { + + private final JavaMailSender mailSender; + + public EmailService1(JavaMailSender mailSender) { + this.mailSender = mailSender; + } + + public void send(String to, String body, String subject, Object notification) { + try { + MimeMessage mimeMessage = mailSender.createMimeMessage(); + MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, "utf-8"); + helper.setText(body, true); + helper.setTo(to); + helper.setSubject(subject); + helper.setFrom("your-email@gmail.com"); + mailSender.send(mimeMessage); + } catch (MessagingException e) { + throw new IllegalStateException("Failed to send email", e); + } + } +} diff --git a/src/main/java/com/libraryman_api/newsletter/MailConfig.java b/src/main/java/com/libraryman_api/newsletter/MailConfig.java new file mode 100644 index 0000000..37d1a55 --- /dev/null +++ b/src/main/java/com/libraryman_api/newsletter/MailConfig.java @@ -0,0 +1,27 @@ +package com.libraryman_api.newsletter; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.mail.javamail.JavaMailSender; +import org.springframework.mail.javamail.JavaMailSenderImpl; + +import java.util.Properties; + +@Configuration +public class MailConfig { + + @Bean + public JavaMailSender javaMailSender() { + JavaMailSenderImpl mailSender = new JavaMailSenderImpl(); + mailSender.setHost("smtp.gmail.com"); + mailSender.setPort(587); + mailSender.setUsername("your-email@gmail.com"); + mailSender.setPassword("your-password"); + + Properties props = mailSender.getJavaMailProperties(); + props.put("mail.transport.protocol", "smtp"); + props.put("mail.smtp.auth", "true"); + props.put("mail.smtp.starttls.enable", "true"); + return mailSender; + } +} diff --git a/src/main/java/com/libraryman_api/newsletter/NewsletterController.java b/src/main/java/com/libraryman_api/newsletter/NewsletterController.java index fe038fe..f454111 100644 --- a/src/main/java/com/libraryman_api/newsletter/NewsletterController.java +++ b/src/main/java/com/libraryman_api/newsletter/NewsletterController.java @@ -1,44 +1,26 @@ package com.libraryman_api.newsletter; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; -import java.util.Map; - @RestController -@RequestMapping("/api/newsletter") +@RequestMapping("/newsletter") public class NewsletterController { + private final NewsletterService newsletterService; + @Autowired - private NewsletterService newsletterService; + public NewsletterController(NewsletterService newsletterService) { + this.newsletterService = newsletterService; + } - // Subscribe endpoint @PostMapping("/subscribe") - public ResponseEntity subscribe(@RequestBody Map requestBody) { - String email = requestBody.get("email"); - - // Call the service to handle subscription - String response = newsletterService.subscribe(email); - - // Return response from the service - if (response.equals("Invalid email format.") || response.equals("Email is already subscribed.")) { - return ResponseEntity.badRequest().body(response); - } - - return ResponseEntity.ok(response); + public String subscribe(@RequestParam String email) { + return newsletterService.subscribe(email); } - // Unsubscribe endpoint using token - @GetMapping("/unsubscribe/{token}") - public ResponseEntity unsubscribe(@PathVariable String token) { - String response = newsletterService.unsubscribe(token); - - // Check if the response indicates an error - if (response.equals("Invalid or expired token.") || response.equals("You are already unsubscribed.")) { - return ResponseEntity.badRequest().body(response); - } - - return ResponseEntity.ok(response); + @GetMapping("/unsubscribe") + public String unsubscribe(@RequestParam String token) { + return newsletterService.unsubscribe(token); } } diff --git a/src/main/java/com/libraryman_api/newsletter/NewsletterService.java b/src/main/java/com/libraryman_api/newsletter/NewsletterService.java index 034fd78..ea19e7d 100644 --- a/src/main/java/com/libraryman_api/newsletter/NewsletterService.java +++ b/src/main/java/com/libraryman_api/newsletter/NewsletterService.java @@ -1,74 +1,73 @@ package com.libraryman_api.newsletter; +import com.libraryman_api.email.EmailService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; - import java.util.Optional; -import java.util.regex.Matcher; import java.util.regex.Pattern; @Service public class NewsletterService { + private final NewsletterSubscriberRepository subscriberRepository; + private final EmailService emailService; + @Autowired - private NewsletterSubscriberRepository subscriberRepository; + public NewsletterService(NewsletterSubscriberRepository subscriberRepository, EmailService emailService) { + this.subscriberRepository = subscriberRepository; + this.emailService = emailService; + } - // Subscribe user after validating email public String subscribe(String email) { - if (!isValidEmail(email)) { - return "Invalid email format."; - } + if (!isValidEmail(email)) return "Invalid email format."; - // Check if the email already exists Optional optionalSubscriber = subscriberRepository.findByEmail(email); - if (optionalSubscriber.isPresent()) { NewsletterSubscriber subscriber = optionalSubscriber.get(); - - // If the subscriber is inactive, reactivate them if (!subscriber.isActive()) { - subscriber.setActive(true); // Reactivate the subscriber - subscriber.regenerateToken(); // Generate a new token - subscriberRepository.save(subscriber); // Save the updated subscriber + subscriber.setActive(true); + subscriber.regenerateToken(); + subscriberRepository.save(subscriber); + sendSubscriptionEmail(email, subscriber.getUnsubscribeToken()); return "You have successfully re-subscribed!"; - } else { - return "Email is already subscribed."; } + return "Email is already subscribed."; } - // Save new subscriber if not present - NewsletterSubscriber subscriber = new NewsletterSubscriber(email); - subscriberRepository.save(subscriber); + NewsletterSubscriber newSubscriber = new NewsletterSubscriber(email); + subscriberRepository.save(newSubscriber); + sendSubscriptionEmail(email, newSubscriber.getUnsubscribeToken()); return "You have successfully subscribed!"; } - // Unsubscribe user using the token public String unsubscribe(String token) { Optional optionalSubscriber = subscriberRepository.findByUnsubscribeToken(token); - - if (optionalSubscriber.isEmpty()) { - return "Invalid or expired token."; - } + if (optionalSubscriber.isEmpty()) return "Invalid or expired token."; NewsletterSubscriber subscriber = optionalSubscriber.get(); + if (!subscriber.isActive()) return "You are already unsubscribed."; - if (!subscriber.isActive()) { - return "You are already unsubscribed."; - } - - subscriber.setActive(false); // Set active to false - subscriberRepository.save(subscriber); // Save the updated subscriber + subscriber.setActive(false); + subscriberRepository.save(subscriber); + sendUnsubscribeEmail(subscriber.getEmail()); return "You have successfully unsubscribed!"; } - // Email validation logic private boolean isValidEmail(String email) { - if (email == null || email.trim().isEmpty()) { - return false; - } String emailRegex = "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"; - Pattern pattern = Pattern.compile(emailRegex); - Matcher matcher = pattern.matcher(email); - return matcher.matches(); + return Pattern.compile(emailRegex).matcher(email).matches(); + } + + private void sendSubscriptionEmail(String email, String token) { + String subject = "Welcome to Our Newsletter!"; + String body = "Thank you for subscribing! To unsubscribe, click the link:\n" + + "http://localhost:8080/newsletter/unsubscribe?token=" + token; + emailService.send(email, body, subject, null); + } + + private void sendUnsubscribeEmail(String email) { + String subject = "You have been unsubscribed"; + String body = "You have successfully unsubscribed. If this was a mistake, you can re-subscribe."; + emailService.send(email, body, subject, null); } } diff --git a/src/main/java/com/libraryman_api/newsletter/NewsletterSubscriber.java b/src/main/java/com/libraryman_api/newsletter/NewsletterSubscriber.java index aa099c0..e6c73a2 100644 --- a/src/main/java/com/libraryman_api/newsletter/NewsletterSubscriber.java +++ b/src/main/java/com/libraryman_api/newsletter/NewsletterSubscriber.java @@ -1,7 +1,6 @@ package com.libraryman_api.newsletter; import jakarta.persistence.*; - import java.util.UUID; @Entity @@ -16,53 +15,28 @@ public class NewsletterSubscriber { private String email; @Column(nullable = false) - private boolean active = true; // Manage subscription status + private boolean active = true; @Column(name = "unsubscribe_token", nullable = false, unique = true) - private String unsubscribeToken; // Token for unsubscribing + private String unsubscribeToken; - // Default constructor that initializes the token + // Default constructor initializing unsubscribe token public NewsletterSubscriber() { - this.unsubscribeToken = UUID.randomUUID().toString(); // Generate token by default + this.unsubscribeToken = UUID.randomUUID().toString(); } - // Constructor to initialize with email + // Constructor initializing with email public NewsletterSubscriber(String email) { this(); this.email = email; } - // Getters and setters - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - public String getEmail() { - return email; - } - - public void setEmail(String email) { - this.email = email; - } - - public boolean isActive() { - return active; - } - - public void setActive(boolean active) { - this.active = active; - } - - public String getUnsubscribeToken() { - return unsubscribeToken; - } - - // Method to regenerate a new token - public void regenerateToken() { - this.unsubscribeToken = UUID.randomUUID().toString(); - } + // Getters and Setters + public Long getId() { return id; } + public String getEmail() { return email; } + public void setEmail(String email) { this.email = email; } + public boolean isActive() { return active; } + public void setActive(boolean active) { this.active = active; } + public String getUnsubscribeToken() { return unsubscribeToken; } + public void regenerateToken() { this.unsubscribeToken = UUID.randomUUID().toString(); } } diff --git a/src/main/java/com/libraryman_api/newsletter/NewsletterSubscriberRepository.java b/src/main/java/com/libraryman_api/newsletter/NewsletterSubscriberRepository.java index 1e6d215..2604620 100644 --- a/src/main/java/com/libraryman_api/newsletter/NewsletterSubscriberRepository.java +++ b/src/main/java/com/libraryman_api/newsletter/NewsletterSubscriberRepository.java @@ -1,14 +1,9 @@ package com.libraryman_api.newsletter; import org.springframework.data.jpa.repository.JpaRepository; - import java.util.Optional; public interface NewsletterSubscriberRepository extends JpaRepository { - - // Find a subscriber by email Optional findByEmail(String email); - - // Find a subscriber by unsubscribe token Optional findByUnsubscribeToken(String unsubscribeToken); } diff --git a/src/main/resources/application-development.properties b/src/main/resources/application-development.properties index 30ef46b..a1b8ca0 100644 --- a/src/main/resources/application-development.properties +++ b/src/main/resources/application-development.properties @@ -40,4 +40,4 @@ spring.mail.username=Add_Your_Mail_Service_Username spring.mail.password=Add_Your_Mail_Service_Password spring.mail.properties.mail.smtp.auth=Add_Your_Mail_Service_SMTP spring.mail.properties.mail.starttls.enable=Add_Your_Mail_Service_Start_TLS -spring.mail.properties.domain_name=Add_Your_Mail_Service_Domain_Name +spring.mail.properties.domain_name=Add_Your_Mail_Service_Domain_Name \ No newline at end of file