Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added backend functionalities for newsletter signup. #75

Merged
merged 5 commits into from
Oct 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
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")
public class NewsletterController {

@Autowired
private NewsletterService newsletterService;

// Subscribe endpoint
@PostMapping("/subscribe")
public ResponseEntity<String> subscribe(@RequestBody Map<String, String> 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);
}

// Unsubscribe endpoint using token
@GetMapping("/unsubscribe/{token}")
public ResponseEntity<String> 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);
}
}
74 changes: 74 additions & 0 deletions src/main/java/com/libraryman_api/newsletter/NewsletterService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package com.libraryman_api.newsletter;

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 {

@Autowired
private NewsletterSubscriberRepository subscriberRepository;

// Subscribe user after validating email
public String subscribe(String email) {
if (!isValidEmail(email)) {
return "Invalid email format.";
}

// Check if the email already exists
Optional<NewsletterSubscriber> 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
return "You have successfully re-subscribed!";
} else {
return "Email is already subscribed.";
}
}

// Save new subscriber if not present
NewsletterSubscriber subscriber = new NewsletterSubscriber(email);
subscriberRepository.save(subscriber);
return "You have successfully subscribed!";
}

// Unsubscribe user using the token
public String unsubscribe(String token) {
Optional<NewsletterSubscriber> optionalSubscriber = subscriberRepository.findByUnsubscribeToken(token);

if (optionalSubscriber.isEmpty()) {
return "Invalid or expired token.";
}

NewsletterSubscriber subscriber = optionalSubscriber.get();

if (!subscriber.isActive()) {
return "You are already unsubscribed.";
}

subscriber.setActive(false); // Set active to false
subscriberRepository.save(subscriber); // Save the updated subscriber
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();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package com.libraryman_api.newsletter;

import jakarta.persistence.*;
import java.util.UUID;

@Entity
@Table(name = "newsletter_subscribers")
public class NewsletterSubscriber {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@Column(nullable = false, unique = true)
private String email;

@Column(nullable = false)
private boolean active = true; // Manage subscription status

@Column(name = "unsubscribe_token", nullable = false, unique = true)
private String unsubscribeToken; // Token for unsubscribing

// Default constructor that initializes the token
public NewsletterSubscriber() {
this.unsubscribeToken = UUID.randomUUID().toString(); // Generate token by default
}

// Constructor to initialize 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();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.libraryman_api.newsletter;

import org.springframework.data.jpa.repository.JpaRepository;

import java.util.Optional;

public interface NewsletterSubscriberRepository extends JpaRepository<NewsletterSubscriber, Long> {

// Find a subscriber by email
Optional<NewsletterSubscriber> findByEmail(String email);

// Find a subscriber by unsubscribe token
Optional<NewsletterSubscriber> findByUnsubscribeToken(String unsubscribeToken);
}
Loading