Skip to content

Commit

Permalink
Merge pull request #100 from team9502/dev
Browse files Browse the repository at this point in the history
feat: ์ด๋ฉ”์ผ ์ธ์ฆ&๊ฒ€์ฆ + ํšŒ์›๊ฐ€์ž…/ํ”„๋กœํ•„ ์ˆ˜์ •์‹œ ์ด๋ฉ”์ผ ์ธ์ฆ&๊ฒ€์ฆ ์ถ”๊ฐ€
  • Loading branch information
EUNCHAEv1006 authored Jun 16, 2024
2 parents ac8a1a4 + f6f641b commit 7775780
Show file tree
Hide file tree
Showing 23 changed files with 528 additions and 15 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/sinChul.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ jobs:
export S3_NAME="${{ secrets.S3_NAME }}"
export S3_REGION="${{ secrets.S3_REGION }}"
export SECRET_ACCESS_KEY="${{ secrets.SECRET_ACCESS_KEY }}"
export GOOGLE_ACCOUNT="${{ secrets.GOOGLE_ACCOUNT }}"
export GOOGLE_PASSWORD="${{ secrets.GOOGLE_PASSWORD }}"
# JAR ํŒŒ์ผ์„ /home/ec2-user ๋””๋ ‰ํ† ๋ฆฌ์—์„œ ์‹คํ–‰
nohup java -jar /home/ec2-user/*.jar > nohup.out 2>&1 &
Expand All @@ -65,3 +67,5 @@ jobs:
S3_NAME: ${{ secrets.S3_NAME }}
S3_REGION: ${{ secrets.S3_REGION }}
SECRET_ACCESS_KEY: ${{ secrets.SECRET_ACCESS_KEY }}
GOOGLE_ACCOUNT: ${{ secrets.GOOGLE_ACCOUNT }}
GOOGLE_PASSWORD: ${{ secrets.GOOGLE_PASSWORD }}
Original file line number Diff line number Diff line change
Expand Up @@ -27,20 +27,26 @@
@RestController
@RequestMapping("/auth")
@RequiredArgsConstructor
@Tag(name = "Auth", description = "์ธ์ฆ ๊ด€๋ จ API")
@Tag(name = "Auth", description = "์ธ์ฆ ๊ด€๋ จ API [๊น€์€์ฑ„]")
public class AuthController {

private final AuthService authService;

@PostMapping("/signup")
@Operation(summary = "๊ตฌ์ง์ž ํšŒ์› ๊ฐ€์ž…", description = "์ƒˆ๋กœ์šด ์‚ฌ์šฉ์ž๋ฅผ ๋“ฑ๋กํ•ฉ๋‹ˆ๋‹ค. ๊ตฌ์ง์ž ํšŒ์›๊ฐ€์ž…์ž…๋‹ˆ๋‹ค.")
@ApiResponses({
@ApiResponse(responseCode = "200", description = "ํšŒ์› ๊ฐ€์ž… ์„ฑ๊ณต",
@ApiResponse(responseCode = "201", description = "๊ตฌ์ง์ž ํšŒ์› ๊ฐ€์ž… ์„ฑ๊ณต",
content = @Content(mediaType = "application/json",
examples = @ExampleObject(value = "{ \"code\": \"200\", \"message\": \"ํšŒ์› ๊ฐ€์ž… ์„ฑ๊ณต\", \"data\": null }"))),
@ApiResponse(responseCode = "400", description = "ํšŒ์› ๊ฐ€์ž… ์‹คํŒจ",
examples = @ExampleObject(value = "{ \"code\": \"201\", \"message\": \"๊ตฌ์ง์ž ํšŒ์› ๊ฐ€์ž… ์„ฑ๊ณต\", \"data\": null }"))),
@ApiResponse(responseCode = "400", description = "์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ์‹คํŒจ",
content = @Content(mediaType = "application/json",
examples = @ExampleObject(value = "{ \"code\": \"400\", \"message\": \"ํšŒ์› ๊ฐ€์ž… ์‹คํŒจ\", \"data\": null }"))),
examples = @ExampleObject(value = "{ \"code\": \"400\", \"message\": \"์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ์‹คํŒจ\", \"data\": null }"))),
@ApiResponse(responseCode = "400", description = "์ด๋ฉ”์ผ ์ธ์ฆ ํ•„์š”",
content = @Content(mediaType = "application/json",
examples = @ExampleObject(value = "{ \"code\": \"400\", \"message\": \"์ด๋ฉ”์ผ ์ธ์ฆ ํ•„์š”\", \"data\": null }"))),
@ApiResponse(responseCode = "409", description = "์ค‘๋ณต๋œ ์ด๋ฉ”์ผ",
content = @Content(mediaType = "application/json",
examples = @ExampleObject(value = "{ \"code\": \"409\", \"message\": \"์ค‘๋ณต๋œ ์ด๋ฉ”์ผ\", \"data\": null }"))),
@ApiResponse(responseCode = "500", description = "์„œ๋ฒ„ ์—๋Ÿฌ",
content = @Content(mediaType = "application/json",
examples = @ExampleObject(value = "{ \"code\": \"500\", \"message\": \"์„œ๋ฒ„ ์—๋Ÿฌ\", \"data\": null }")))
Expand All @@ -60,14 +66,20 @@ public ResponseEntity<GlobalApiResponse<Object>> signup(
}

@PostMapping("/cp-signup")
@Operation(summary = "๊ธฐ์—… ํšŒ์› ๊ฐ€์ž…", description = "์ƒˆ๋กœ์šด ๊ธฐ์—… ์‚ฌ์šฉ์ž๋ฅผ ๋“ฑ๋กํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ์—…/๊ตฌ์ง์ž ํšŒ์›๊ฐ€์ž…์ž…๋‹ˆ๋‹ค.")
@Operation(summary = "๊ธฐ์—… ํšŒ์› ๊ฐ€์ž…", description = "์ƒˆ๋กœ์šด ๊ธฐ์—… ์‚ฌ์šฉ์ž๋ฅผ ๋“ฑ๋กํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ์—…(ํšŒ์›) ํšŒ์›๊ฐ€์ž…์ž…๋‹ˆ๋‹ค.")
@ApiResponses({
@ApiResponse(responseCode = "200", description = "ํšŒ์› ๊ฐ€์ž… ์„ฑ๊ณต",
@ApiResponse(responseCode = "201", description = "๊ธฐ์—… ํšŒ์› ๊ฐ€์ž… ์„ฑ๊ณต",
content = @Content(mediaType = "application/json",
examples = @ExampleObject(value = "{ \"code\": \"201\", \"message\": \"๊ธฐ์—… ํšŒ์› ๊ฐ€์ž… ์„ฑ๊ณต\", \"data\": null }"))),
@ApiResponse(responseCode = "400", description = "์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ์‹คํŒจ",
content = @Content(mediaType = "application/json",
examples = @ExampleObject(value = "{ \"code\": \"400\", \"message\": \"์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ์‹คํŒจ\", \"data\": null }"))),
@ApiResponse(responseCode = "400", description = "์ด๋ฉ”์ผ ์ธ์ฆ ํ•„์š”",
content = @Content(mediaType = "application/json",
examples = @ExampleObject(value = "{ \"code\": \"200\", \"message\": \"ํšŒ์› ๊ฐ€์ž… ์„ฑ๊ณต\", \"data\": null }"))),
@ApiResponse(responseCode = "400", description = "ํšŒ์› ๊ฐ€์ž… ์‹คํŒจ",
examples = @ExampleObject(value = "{ \"code\": \"400\", \"message\": \"์ด๋ฉ”์ผ ์ธ์ฆ ํ•„์š”\", \"data\": null }"))),
@ApiResponse(responseCode = "409", description = "์ค‘๋ณต๋œ ์ด๋ฉ”์ผ",
content = @Content(mediaType = "application/json",
examples = @ExampleObject(value = "{ \"code\": \"400\", \"message\": \"ํšŒ์› ๊ฐ€์ž… ์‹คํŒจ\", \"data\": null }"))),
examples = @ExampleObject(value = "{ \"code\": \"409\", \"message\": \"์ค‘๋ณต๋œ ์ด๋ฉ”์ผ\", \"data\": null }"))),
@ApiResponse(responseCode = "500", description = "์„œ๋ฒ„ ์—๋Ÿฌ",
content = @Content(mediaType = "application/json",
examples = @ExampleObject(value = "{ \"code\": \"500\", \"message\": \"์„œ๋ฒ„ ์—๋Ÿฌ\", \"data\": null }")))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import team9502.sinchulgwinong.domain.companyUser.entity.CompanyUser;
import team9502.sinchulgwinong.domain.companyUser.repository.CompanyUserRepository;
import team9502.sinchulgwinong.domain.companyUser.service.EncryptionService;
import team9502.sinchulgwinong.domain.email.service.EmailVerificationService;
import team9502.sinchulgwinong.domain.point.enums.SpType;
import team9502.sinchulgwinong.domain.point.service.PointService;
import team9502.sinchulgwinong.domain.user.entity.User;
Expand All @@ -40,12 +41,18 @@ public class AuthService {
private final AuthenticationManager authenticationManager;
private final JwtTokenProvider jwtTokenProvider;
private final PointService pointService;
private final EmailVerificationService emailVerificationService;

@Transactional
public void signup(UserSignupRequestDTO signupRequest) {

validateUserSignupRequest(signupRequest.getEmail(), signupRequest.getPassword(),
signupRequest.getConfirmPassword(), signupRequest.isAgreeToTerms());

if (!emailVerificationService.isEmailVerified(signupRequest.getEmail())) {
throw new ApiException(ErrorCode.EMAIL_NOT_VERIFIED);
}

try {
User user = User.builder()
.username(signupRequest.getUsername())
Expand All @@ -66,9 +73,14 @@ public void signup(UserSignupRequestDTO signupRequest) {

@Transactional
public void cpSignup(CpUserSignupRequestDTO requestDTO) {

validateCpSignupRequest(requestDTO.getCpEmail(), requestDTO.getCpPassword(),
requestDTO.getCpConfirmPassword(), requestDTO.isAgreeToTerms());

if (!emailVerificationService.isEmailVerified(requestDTO.getCpEmail())) {
throw new ApiException(ErrorCode.EMAIL_NOT_VERIFIED);
}

try {
CompanyUser companyUser = CompanyUser.builder()
.hiringStatus(requestDTO.getHiringStatus())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ public ResponseEntity<GlobalApiResponse<CpUserProfileResponseDTO>> getCompanyUse
@ApiResponse(responseCode = "400", description = "์ž˜๋ชป๋œ ์š”์ฒญ ๋ฐ์ดํ„ฐ",
content = @Content(mediaType = "application/json",
examples = @ExampleObject(value = "{ \"code\": \"400\", \"message\": \"์š”์ฒญ ๋ฐ์ดํ„ฐ๊ฐ€ ์œ ํšจํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.\", \"data\": null }"))),
@ApiResponse(responseCode = "400", description = "์ด๋ฉ”์ผ ์ธ์ฆ ํ•„์š”",
content = @Content(mediaType = "application/json",
examples = @ExampleObject(value = "{ \"code\": \"400\", \"message\": \"์ด๋ฉ”์ผ ์ธ์ฆ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.\", \"data\": null }"))),
@ApiResponse(responseCode = "404", description = "๊ธฐ์—…(ํšŒ์›)์„ ์ฐพ์„ ์ˆ˜ ์—†์Œ",
content = @Content(mediaType = "application/json",
examples = @ExampleObject(value = "{ \"code\": \"404\", \"message\": \"๊ธฐ์—…(ํšŒ์›)์„ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.\", \"data\": null }"))),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package team9502.sinchulgwinong.domain.companyUser.service;


import lombok.RequiredArgsConstructor;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
Expand All @@ -10,6 +9,7 @@
import team9502.sinchulgwinong.domain.companyUser.dto.response.CpUserProfileResponseDTO;
import team9502.sinchulgwinong.domain.companyUser.entity.CompanyUser;
import team9502.sinchulgwinong.domain.companyUser.repository.CompanyUserRepository;
import team9502.sinchulgwinong.domain.email.service.EmailVerificationService;
import team9502.sinchulgwinong.global.exception.ApiException;
import team9502.sinchulgwinong.global.exception.ErrorCode;

Expand All @@ -20,6 +20,7 @@ public class CpUserService {
private final CompanyUserRepository companyUserRepository;
private final EncryptionService encryptionService;
private final PasswordEncoder passwordEncoder;
private final EmailVerificationService emailVerificationService;

@Transactional(readOnly = true)
public CpUserProfileResponseDTO getCpUserProfile(Long cpUserId) {
Expand Down Expand Up @@ -59,6 +60,9 @@ public CpUserProfileResponseDTO updateCpUserProfile(Long cpUserId, CpUserProfile
companyUser.setDescription(updateRequestDTO.getDescription());
}
if (updateRequestDTO.getCpEmail() != null) {
if (!emailVerificationService.isEmailVerified(updateRequestDTO.getCpEmail())) {
throw new ApiException(ErrorCode.EMAIL_NOT_VERIFIED);
}
companyUser.setCpEmail(updateRequestDTO.getCpEmail());
}
if (updateRequestDTO.getCpPhoneNumber() != null) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package team9502.sinchulgwinong.domain.email.controller;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.ExampleObject;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
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;
import team9502.sinchulgwinong.domain.email.dto.request.EmailVerificationCodeRequestDTO;
import team9502.sinchulgwinong.domain.email.dto.request.EmailVerificationRequestDTO;
import team9502.sinchulgwinong.domain.email.service.EmailVerificationService;
import team9502.sinchulgwinong.global.response.GlobalApiResponse;

import static team9502.sinchulgwinong.global.response.SuccessCode.SUCCESS_EMAIL_VERIFICATION;
import static team9502.sinchulgwinong.global.response.SuccessCode.SUCCESS_EMAIL_VERIFICATION_SENT;

@RestController
@RequiredArgsConstructor
@RequestMapping("/email")
@Tag(name = "Email Verification", description = "์ด๋ฉ”์ผ ์ธ์ฆ ๊ด€๋ จ API [๊น€์€์ฑ„]")
public class EmailVerificationController {

private final EmailVerificationService emailVerificationService;

@PostMapping("/sendCode")
@Operation(summary = "์ด๋ฉ”์ผ ์ธ์ฆ ์ฝ”๋“œ ๋ฐœ์†ก", description = "์‚ฌ์šฉ์ž ์ด๋ฉ”์ผ๋กœ ์ธ์ฆ ์ฝ”๋“œ๋ฅผ ๋ฐœ์†กํ•ฉ๋‹ˆ๋‹ค.")
@ApiResponse(responseCode = "200", description = "์ธ์ฆ ์ฝ”๋“œ ๋ฐœ์†ก ์„ฑ๊ณต",
content = @Content(mediaType = "application/json",
examples = @ExampleObject(value = "{ \"code\": \"200\", \"message\": \"์ธ์ฆ ์ฝ”๋“œ ๋ฐœ์†ก ์„ฑ๊ณต\", \"data\": null }")))
@ApiResponse(responseCode = "400", description = "์ž˜๋ชป๋œ ์ž…๋ ฅ",
content = @Content(mediaType = "application/json",
examples = @ExampleObject(value = "{ \"code\": \"400\", \"message\": \"์ž˜๋ชป๋œ ์ž…๋ ฅ์ž…๋‹ˆ๋‹ค.\", \"data\": null }")))
@ApiResponse(responseCode = "401", description = "์ด๋ฉ”์ผ ์ธ์ฆ ์‹คํŒจ",
content = @Content(mediaType = "application/json",
examples = @ExampleObject(value = "{ \"code\": \"401\", \"message\": \"์ด๋ฉ”์ผ ์ธ์ฆ์— ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค.\", \"data\": null }")))
@ApiResponse(responseCode = "500", description = "์„œ๋ฒ„ ์—๋Ÿฌ",
content = @Content(mediaType = "application/json",
examples = @ExampleObject(value = "{ \"code\": \"500\", \"message\": \"์„œ๋ฒ„ ์—๋Ÿฌ\", \"data\": null }")))
public ResponseEntity<GlobalApiResponse<Void>> sendVerificationCode(
@RequestBody EmailVerificationRequestDTO requestDTO) {

emailVerificationService.createVerification(requestDTO.getEmail(), requestDTO.getUserType());

return ResponseEntity.status(SUCCESS_EMAIL_VERIFICATION_SENT.getHttpStatus())
.body(
GlobalApiResponse.of(
SUCCESS_EMAIL_VERIFICATION_SENT.getMessage(),
null
)
);
}

@PostMapping("/verifyCode")
@Operation(summary = "์ด๋ฉ”์ผ ์ธ์ฆ ์ฝ”๋“œ ๊ฒ€์ฆ", description = "์ œ๊ณต๋œ ์ด๋ฉ”์ผ๊ณผ ์ธ์ฆ ์ฝ”๋“œ์˜ ์œ ํšจ์„ฑ์„ ๊ฒ€์ฆํ•ฉ๋‹ˆ๋‹ค.")
@ApiResponse(responseCode = "200", description = "์ด๋ฉ”์ผ ์ธ์ฆ ์„ฑ๊ณต",
content = @Content(mediaType = "application/json",
examples = @ExampleObject(value = "{ \"code\": \"200\", \"message\": \"์ด๋ฉ”์ผ ์ธ์ฆ ์„ฑ๊ณต\", \"data\": null }")))
@ApiResponse(responseCode = "400", description = "์œ ํšจํ•˜์ง€ ์•Š๊ฑฐ๋‚˜ ๋งŒ๋ฃŒ๋œ ์ฝ”๋“œ",
content = @Content(mediaType = "application/json",
examples = @ExampleObject(value = "{ \"code\": \"400\", \"message\": \"์œ ํšจํ•˜์ง€ ์•Š๊ฑฐ๋‚˜ ๋งŒ๋ฃŒ๋œ ์ธ์ฆ ์ฝ”๋“œ\", \"data\": null }")))
@ApiResponse(responseCode = "401", description = "์ž˜๋ชป๋œ ์ž…๋ ฅ",
content = @Content(mediaType = "application/json",
examples = @ExampleObject(value = "{ \"code\": \"400\", \"message\": \"์ž˜๋ชป๋œ ์ž…๋ ฅ์ž…๋‹ˆ๋‹ค.\", \"data\": null }")))
@ApiResponse(responseCode = "500", description = "์„œ๋ฒ„ ์—๋Ÿฌ",
content = @Content(mediaType = "application/json",
examples = @ExampleObject(value = "{ \"code\": \"500\", \"message\": \"์„œ๋ฒ„ ์—๋Ÿฌ\", \"data\": null }")))
public ResponseEntity<GlobalApiResponse<Void>> verifyCode(
@RequestBody EmailVerificationCodeRequestDTO requestDTO) {

emailVerificationService.verifyCode(requestDTO.getEmail(), requestDTO.getCode());


return ResponseEntity.status(SUCCESS_EMAIL_VERIFICATION.getHttpStatus())
.body(
GlobalApiResponse.of(
SUCCESS_EMAIL_VERIFICATION.getMessage(),
null
)
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package team9502.sinchulgwinong.domain.email.dto.request;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Data
@Getter
@NoArgsConstructor
@AllArgsConstructor
public class EmailVerificationCodeRequestDTO {

@Schema(description = "์ด๋ฉ”์ผ ์ฃผ์†Œ", example = "[email protected]")
private String email;

@Schema(description = "์ธ์ฆ ์ฝ”๋“œ", example = "123456")
private String code;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package team9502.sinchulgwinong.domain.email.dto.request;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;
import lombok.NoArgsConstructor;
import team9502.sinchulgwinong.domain.email.enums.UserType;

@Data
@Getter
@NoArgsConstructor
@AllArgsConstructor
public class EmailVerificationRequestDTO {

@Schema(description = "์ด๋ฉ”์ผ ์ฃผ์†Œ", example = "[email protected]")
private String email;

@Schema(description = "์‚ฌ์šฉ์ž ์œ ํ˜•", example = "USER")
private UserType userType;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package team9502.sinchulgwinong.domain.email.entity;

import jakarta.persistence.*;
import lombok.*;
import team9502.sinchulgwinong.domain.email.enums.UserType;
import team9502.sinchulgwinong.domain.email.enums.VerificationStatus;

import java.util.Date;

@Entity
@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "EmailVerifications", indexes = {
@Index(name = "idx_expires_at_status", columnList = "expiresAt, status")
})
public class EmailVerifications {

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

@Column(nullable = false, length = 250)
private String email;

@Column(nullable = false)
@Enumerated(EnumType.STRING)
private UserType userType;

@Column
private Long userReferenceId;

@Column(nullable = false, length = 6)
private String verificationCode;

@Column(nullable = false)
@Temporal(TemporalType.TIMESTAMP)
private Date createdAt;

@Column(nullable = false)
@Temporal(TemporalType.TIMESTAMP)
private Date expiresAt;

@Setter
@Column(nullable = false)
@Enumerated(EnumType.STRING)
private VerificationStatus status;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package team9502.sinchulgwinong.domain.email.enums;

public enum UserType {

USER, CPUSER
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package team9502.sinchulgwinong.domain.email.enums;

public enum VerificationStatus {

PENDING, VERIFIED, EXPIRED
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package team9502.sinchulgwinong.domain.email.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import team9502.sinchulgwinong.domain.email.entity.EmailVerifications;
import team9502.sinchulgwinong.domain.email.enums.VerificationStatus;

import java.util.Date;
import java.util.List;
import java.util.Optional;

public interface EmailVerificationRepository extends JpaRepository<EmailVerifications, Long> {

Optional<EmailVerifications> findByEmailAndVerificationCodeAndExpiresAtAfterAndStatus(String email, String verificationCode, Date now, VerificationStatus status);

List<EmailVerifications> findByExpiresAtBeforeAndStatus(Date expiresAt, VerificationStatus status);

void deleteByExpiresAtBeforeAndStatus(Date expiresAt, VerificationStatus status);

boolean existsByEmailAndStatus(String email, VerificationStatus status);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package team9502.sinchulgwinong.domain.email.service;

public interface EmailService {

void sendSimpleMessage(String to, String subject, String text);
}
Loading

0 comments on commit 7775780

Please sign in to comment.