Skip to content
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,58 @@
package org.justjava.gymcore.config.smtp;

public abstract class AbstractSmtpConfig {
private String host;
private String port;
private String username; //use with encryption
private String password; //use with encryption
Comment thread
abdulkeremkilic marked this conversation as resolved.
private String auth;
private String starttls;
Comment thread
abdulkeremkilic marked this conversation as resolved.
Comment thread
abdulkeremkilic marked this conversation as resolved.

public String getHost() {
return host;
}

public void setHost(String host) {
this.host = host;
}

public String getPort() {
return port;
}

public void setPort(String port) {
this.port = port;
}

public String getUsername() {
return username;
}

public void setUsername(String username) {
this.username = username;
}

public String getPassword() {
return password;
}

public void setPassword(String password) {
this.password = password;
}

public String getAuth() {
return auth;
}

public void setAuth(String auth) {
this.auth = auth;
}

public String getStarttls() {
return starttls;
}

public void setStarttls(String starttls) {
this.starttls = starttls;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package org.justjava.gymcore.config.smtp;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

@Configuration
@ConfigurationProperties(prefix = "smtp.google")
public class GoogleSmtpConfig extends AbstractSmtpConfig {
}
35 changes: 35 additions & 0 deletions src/main/java/org/justjava/gymcore/controller/MailController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package org.justjava.gymcore.controller;

import jakarta.mail.MessagingException;
import jakarta.validation.Valid;
import jakarta.validation.constraints.Email;
import lombok.RequiredArgsConstructor;
import org.justjava.gymcore.model.MailModel;
import org.justjava.gymcore.service.MailService;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping(value = "/mail")
@RequiredArgsConstructor
public class MailController {

private final MailService mailService;

@PostMapping("/sendMail/{to}")
public ResponseEntity<String> sendMail( @PathVariable("to")
@Email(message = "Invalid email address format")
String to,
@Valid @RequestBody MailModel mailModel) {
try {
mailService.sendMail(to, mailModel.subject(), mailModel.body());
return ResponseEntity.ok()
.body("Email sent successfully to: " + to);
} catch (MessagingException e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body("Failed to send email: " + e.getMessage());
}
}

}
15 changes: 15 additions & 0 deletions src/main/java/org/justjava/gymcore/model/MailModel.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package org.justjava.gymcore.model;

import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;

public record MailModel(
@NotBlank(message = "Email subject cannot be blank")
@Size(max = 998, message = "Email subject cannot exceed 998 characters")
String subject,

@NotBlank(message = "Email body cannot be blank")
@Size(max = 50000, message = "Email body cannot exceed 50KB")
String body
) {
}
47 changes: 47 additions & 0 deletions src/main/java/org/justjava/gymcore/service/MailService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package org.justjava.gymcore.service;

import jakarta.mail.*;
import jakarta.mail.internet.InternetAddress;
import jakarta.mail.internet.MimeMessage;
import lombok.RequiredArgsConstructor;
Comment thread
abdulkeremkilic marked this conversation as resolved.
import lombok.extern.slf4j.Slf4j;
import org.justjava.gymcore.config.smtp.GoogleSmtpConfig;
import org.springframework.stereotype.Service;

import java.util.Properties;

@Slf4j
@Service
@RequiredArgsConstructor
public class MailService {

private final GoogleSmtpConfig googleSmtpConfig;

// Host, Host e-mail, password and port will be provided under yaml file. If you want to get configurations from yaml file use smtpConfigurationService.
public void sendMail(String to, String subject, String body) throws MessagingException {

Properties props = new Properties();
props.put("mail.transport.protocol", "smtp");
props.put("mail.smtp.host", googleSmtpConfig.getHost());
props.put("mail.smtp.auth", googleSmtpConfig.getAuth());
props.put("mail.smtp.port", googleSmtpConfig.getPort());
props.put("mail.smtp.starttls.enable", googleSmtpConfig.getStarttls());


Authenticator authenticator = new Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(googleSmtpConfig.getUsername(), googleSmtpConfig.getPassword());
Comment thread
abdulkeremkilic marked this conversation as resolved.
}
};

Session session = Session.getInstance(props, authenticator);
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress(googleSmtpConfig.getUsername()));
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(to, false));
message.setSubject(subject);
message.setText(body);

Transport.send(message);
log.info("Email sent successfully to: {}", to);
}
}
13 changes: 13 additions & 0 deletions src/main/resources/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,16 @@ logging.file.name=gymcore.log
logging.appender.type=FILE
logging.level.root=INFO
logging.level.org.justjava.gymcore=INFO

#Google SMTP configurations
smtp.google.host: smtp.gmail.com
smtp.google.port: 587
# smtp.google.username: ${SMTP_USERNAME:your-email@gmail.com}
# smtp.google.password: ${SMTP_PASSWORD:your-app-password}
smtp.google.auth: true
smtp.google.starttls: true

# Security Note:
# 1. Use environment variables for credentials in production
# 2. For Gmail, use App Passwords instead of regular passwords
# 3. Enable 2FA on your Google account before generating App Passwords
Loading