Skip to content
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package earlybird.earlybird.email.address.check;

import org.springframework.stereotype.Service;

@Service
public class CheckEmailAddressService {
public Boolean checkEmailRegex(String email) {
String emailRegex = "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$";
return email.matches(emailRegex);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package earlybird.earlybird.email.address.save.controller;

import earlybird.earlybird.email.address.save.controller.request.SaveEmailAddressRequest;
import earlybird.earlybird.email.address.save.service.SaveEmailAddressService;
import earlybird.earlybird.email.address.save.service.request.SaveEmailAddressServiceRequest;

import jakarta.validation.Valid;

import lombok.RequiredArgsConstructor;

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RequiredArgsConstructor
@RequestMapping("/api/v1/marketing/email/address")
@RestController
public class SaveEmailAddressController {

private final SaveEmailAddressService saveEmailAddressService;

@PostMapping
public ResponseEntity<?> saveEmailAddress(@Valid @RequestBody SaveEmailAddressRequest request) {
SaveEmailAddressServiceRequest serviceRequest =
SaveEmailAddressServiceRequest.from(request);
saveEmailAddressService.save(serviceRequest);
return ResponseEntity.ok().build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package earlybird.earlybird.email.address.save.controller.request;

import earlybird.earlybird.email.address.save.entity.MarketingEvent;

import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Builder
@AllArgsConstructor
@Getter
@NoArgsConstructor
public class SaveEmailAddressRequest {

@NotBlank private String email;

@NotNull private MarketingEvent sourceEvent;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package earlybird.earlybird.email.address.save.entity;

import earlybird.earlybird.common.BaseTimeEntity;

import jakarta.persistence.*;

import lombok.*;

/** 마케팅을 통해 수집한 이메일 주소를 저장하는 엔티티 */
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@Builder
@Table(name = "email_address_for_marketing")
@Entity
public class MarketingEmailAddress extends BaseTimeEntity {

@Column(name = "email_address_for_marketing_id", nullable = false)
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Id
private Long id;

// 이메일 주소
@Column(name = "email_address_for_marketing_email", nullable = false)
private String email;

// 이메일 수집 출처 이벤트
@Enumerated(EnumType.STRING)
@Column(name = "email_address_for_marketing_source_event")
private MarketingEvent sourceEvent;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package earlybird.earlybird.email.address.save.entity;

import lombok.Getter;

public enum MarketingEvent {
WEB_MINI_GAME_1("홍보용 웹 미니 게임 - 1");

@Getter private final String description;

MarketingEvent(String description) {
this.description = description;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package earlybird.earlybird.email.address.save.repository;

import earlybird.earlybird.email.address.save.entity.MarketingEmailAddress;

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

public interface MarketingEmailAddressRepository
extends JpaRepository<MarketingEmailAddress, Long> {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package earlybird.earlybird.email.address.save.service;

import earlybird.earlybird.email.address.check.CheckEmailAddressService;
import earlybird.earlybird.email.address.save.entity.MarketingEmailAddress;
import earlybird.earlybird.email.address.save.repository.MarketingEmailAddressRepository;
import earlybird.earlybird.email.address.save.service.request.SaveEmailAddressServiceRequest;

import lombok.RequiredArgsConstructor;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Optional;

@RequiredArgsConstructor
@Service
public class SaveEmailAddressService {

private final CheckEmailAddressService checkEmailAddressService;
private final MarketingEmailAddressRepository marketingEmailAddressRepository;

@Transactional
public void save(SaveEmailAddressServiceRequest request) {

Optional.ofNullable(request.email())
.filter(checkEmailAddressService::checkEmailRegex)
.orElseThrow(
() ->
new IllegalArgumentException(
"Invalid email address: " + request.email()));

MarketingEmailAddress emailAddress =
MarketingEmailAddress.builder()
.email(request.email())
.sourceEvent(request.sourceEvent())
.build();

marketingEmailAddressRepository.save(emailAddress);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package earlybird.earlybird.email.address.save.service.request;

import earlybird.earlybird.email.address.save.controller.request.SaveEmailAddressRequest;
import earlybird.earlybird.email.address.save.entity.MarketingEvent;

import lombok.*;

@Builder
public record SaveEmailAddressServiceRequest(String email, MarketingEvent sourceEvent) {

public static SaveEmailAddressServiceRequest from(SaveEmailAddressRequest request) {
return SaveEmailAddressServiceRequest.builder()
.email(request.getEmail())
.sourceEvent(request.getSourceEvent())
.build();
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package earlybird.earlybird.email;
package earlybird.earlybird.email.send;

import static earlybird.earlybird.promotion.email.entity.PromotionEmailMessageType.BERKELEY_6_MONTH_FREE;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
import earlybird.earlybird.promotion.service.request.CreatePromotionCampaignServiceRequest;
import earlybird.earlybird.promotion.service.response.CreatePromotionCampaignServiceResponse;

import jakarta.validation.Valid;

import lombok.RequiredArgsConstructor;

import org.springframework.http.ResponseEntity;
Expand All @@ -23,7 +25,7 @@ public class PromotionCampaignController {

@PostMapping
public ResponseEntity<?> createPromotionCampaign(
@RequestBody CreatePromotionCampaignRequest request) {
@Valid @RequestBody CreatePromotionCampaignRequest request) {
CreatePromotionCampaignServiceRequest serviceRequest =
CreatePromotionCampaignServiceRequest.from(request);
CreatePromotionCampaignServiceResponse serviceResponse =
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package earlybird.earlybird.promotion.email.service;

import earlybird.earlybird.email.address.check.CheckEmailAddressService;
import earlybird.earlybird.promotion.email.entity.EmailPromotionAddressDomain;
import earlybird.earlybird.promotion.email.repository.EmailPromotionAddressDomainRepository;
import earlybird.earlybird.promotion.entity.PromotionCampaign;
Expand All @@ -15,23 +16,19 @@

@RequiredArgsConstructor
@Service
public class CheckEmailAddressService {
public class CheckPromotionEmailAddressService {

private final EmailPromotionAddressDomainRepository promotionDomainRepository;
private final PromotionCampaignRepository promotionCampaignRepository;
private final CheckEmailAddressService checkEmailAddressService;

@Transactional
public Boolean checkValidPromotionEmail(String email, Long promotionCampaignId) {
checkEmailRegex(email);
PromotionCampaign promotionCampaign = getPromotionCampaignById(promotionCampaignId);
return checkDomainName(email, promotionCampaign);
}

private void checkEmailRegex(String email) {
String emailRegex = "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$";
if (!email.matches(emailRegex)) {
if (!checkEmailAddressService.checkEmailRegex(email)) {
throw new IllegalArgumentException("Invalid email address");
}
PromotionCampaign promotionCampaign = getPromotionCampaignById(promotionCampaignId);
return checkDomainName(email, promotionCampaign);
}

private PromotionCampaign getPromotionCampaignById(Long promotionCampaignId) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package earlybird.earlybird.promotion.email.service;

import earlybird.earlybird.email.SendEmailService;
import earlybird.earlybird.email.send.SendEmailService;
import earlybird.earlybird.error.exception.InvalidPromotionEmailException;
import earlybird.earlybird.promotion.apple.service.GetApplePromotionUrlService;
import earlybird.earlybird.promotion.email.entity.EmailPromotionCodeIssuance;
Expand All @@ -23,7 +23,7 @@
public class SendPromotionEmailService {

private final GetApplePromotionUrlService getApplePromotionUrlService;
private final CheckEmailAddressService checkEmailAddressService;
private final CheckPromotionEmailAddressService checkPromotionEmailAddressService;
private final CreatePromotionUrlUuidService createPromotionUrlUuidService;
private final GetPromotionCampaignService getPromotionCampaignService;
private final SendEmailService sendEmailService;
Expand Down Expand Up @@ -78,7 +78,7 @@ private void sendFirstEmail(

private void checkEmailAddress(SendVerificationEmailServiceRequest request) {
Boolean isValidDomain =
checkEmailAddressService.checkValidPromotionEmail(
checkPromotionEmailAddressService.checkValidPromotionEmail(
request.getEmail(), request.getPromotionCampaignId());

if (!isValidDomain) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,10 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {

http.authorizeHttpRequests(
auth ->
auth.requestMatchers("/api/v1/login/oauth2")
.permitAll()
.anyRequest()
.authenticated());
//
// auth.requestMatchers("/api/v1/login/oauth2").permitAll()
// .anyRequest().authenticated());
auth.anyRequest().permitAll());

OAuth2AuthenticationFilter oAuth2AuthenticationFilter = oAuth2AuthenticationFilter();
oAuth2AuthenticationFilter.setAuthenticationManager(authenticationManager);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package earlybird.earlybird.email.address.check;

import static org.assertj.core.api.Assertions.assertThat;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import java.util.List;

class CheckEmailAddressServiceTest {

@DisplayName("올바른 이메일 형식이 주어지면 true를 반환한다.")
@Test
void checkValidEmail() {
// given
List<String> validEmails =
List.of(
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]");

CheckEmailAddressService service = new CheckEmailAddressService();

// when
List<Boolean> results = validEmails.stream().map(service::checkEmailRegex).toList();

// then
assertThat(results).containsOnly(true);
}

@DisplayName("올바르지 않은 이메일 형식이 주어지면 false를 반환한다.")
@Test
void checkInvalidEmail() {
// given
List<String> invalidEmails =
List.of("@naver.com", "testnaver.com", "test@gmail", "[email protected]", "abcde");

CheckEmailAddressService service = new CheckEmailAddressService();

// when
List<Boolean> results = invalidEmails.stream().map(service::checkEmailRegex).toList();

// then
assertThat(results).containsOnly(false);
}
}
Loading