mirror of
https://github.com/Frooodle/Stirling-PDF.git
synced 2025-09-12 17:52:13 +02:00
add smtp with starttls
This commit is contained in:
parent
d95f169ebd
commit
a811da987d
18
.github/labeler-config.yml
vendored
18
.github/labeler-config.yml
vendored
@ -27,18 +27,34 @@ Back End:
|
|||||||
|
|
||||||
Security:
|
Security:
|
||||||
- changed-files:
|
- changed-files:
|
||||||
|
- any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/config/interfaces/DatabaseInterface.java'
|
||||||
- any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/config/security/**/*'
|
- any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/config/security/**/*'
|
||||||
|
- any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/controller/api/DatabaseController.java'
|
||||||
|
- any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/controller/api/EmailController.java'
|
||||||
|
- any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/controller/api/H2SQLController.java'
|
||||||
|
- any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/controller/web/AccountWebController.java'
|
||||||
|
- any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/controller/web/DatabaseWebController.java'
|
||||||
|
- any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/controller/api/UserController.java'
|
||||||
|
- any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/model/api/Email.java'
|
||||||
|
- any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/model/exception/BackupNotFoundException.java'
|
||||||
|
- any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/model/exception/NoProviderFoundExceptionjava'
|
||||||
- any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/model/provider/**/*'
|
- any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/model/provider/**/*'
|
||||||
- any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/model/AuthenticationType.java'
|
- any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/model/AuthenticationType.java'
|
||||||
- any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/model/BackupNotFoundException.java'
|
- any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/model/ApiKeyAuthenticationToken.java'
|
||||||
|
- any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/model/AttemptCounter.java'
|
||||||
|
- any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/model/Authority.java'
|
||||||
|
- any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/model/PersistentLogin.java'
|
||||||
|
- any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/model/SessionEntity.java'
|
||||||
- any-glob-to-any-file: 'scripts/download-security-jar.sh'
|
- any-glob-to-any-file: 'scripts/download-security-jar.sh'
|
||||||
- any-glob-to-any-file: '.github/workflows/dependency-review.yml'
|
- any-glob-to-any-file: '.github/workflows/dependency-review.yml'
|
||||||
- any-glob-to-any-file: '.github/workflows/scorecards.yml'
|
- any-glob-to-any-file: '.github/workflows/scorecards.yml'
|
||||||
|
|
||||||
API:
|
API:
|
||||||
- changed-files:
|
- changed-files:
|
||||||
|
- any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/config/OpenApiConfig.java'
|
||||||
- any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/controller/web/MetricsController.java'
|
- any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/controller/web/MetricsController.java'
|
||||||
- any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/controller/api/**/*'
|
- any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/controller/api/**/*'
|
||||||
|
- any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/model/api/**/*'
|
||||||
- any-glob-to-any-file: 'scripts/png_to_webp.py'
|
- any-glob-to-any-file: 'scripts/png_to_webp.py'
|
||||||
- any-glob-to-any-file: 'split_photos.py'
|
- any-glob-to-any-file: 'split_photos.py'
|
||||||
- any-glob-to-any-file: '.github/workflows/swagger.yml'
|
- any-glob-to-any-file: '.github/workflows/swagger.yml'
|
||||||
|
@ -0,0 +1,61 @@
|
|||||||
|
package stirling.software.SPDF.config.security.mail;
|
||||||
|
|
||||||
|
import org.springframework.mail.javamail.JavaMailSender;
|
||||||
|
import org.springframework.mail.javamail.MimeMessageHelper;
|
||||||
|
import org.springframework.scheduling.annotation.Async;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import jakarta.mail.MessagingException;
|
||||||
|
import jakarta.mail.internet.MimeMessage;
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
|
import stirling.software.SPDF.model.ApplicationProperties;
|
||||||
|
import stirling.software.SPDF.model.api.Email;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Service class responsible for sending emails, including those with attachments. It uses
|
||||||
|
* JavaMailSender to send the email and is designed to handle both the message content and file
|
||||||
|
* attachments.
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class EmailService {
|
||||||
|
|
||||||
|
private final JavaMailSender mailSender;
|
||||||
|
private final ApplicationProperties applicationProperties;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends an email with an attachment asynchronously. This method is annotated with @Async, which
|
||||||
|
* means it will be executed asynchronously.
|
||||||
|
*
|
||||||
|
* @param email The Email object containing the recipient, subject, body, and file attachment.
|
||||||
|
* @throws MessagingException If there is an issue with creating or sending the email.
|
||||||
|
*/
|
||||||
|
@Async
|
||||||
|
public void sendEmailWithAttachment(Email email) throws MessagingException {
|
||||||
|
ApplicationProperties.Mail mailProperties = applicationProperties.getMail();
|
||||||
|
MultipartFile file = email.getFileInput();
|
||||||
|
|
||||||
|
// Creates a MimeMessage to represent the email
|
||||||
|
MimeMessage message = mailSender.createMimeMessage();
|
||||||
|
|
||||||
|
// Helper class to set up the message content and attachments
|
||||||
|
MimeMessageHelper helper = new MimeMessageHelper(message, true);
|
||||||
|
|
||||||
|
// Sets the recipient, subject, body, and sender email
|
||||||
|
helper.addTo(email.getTo());
|
||||||
|
helper.setSubject(email.getSubject());
|
||||||
|
helper.setText(
|
||||||
|
email.getBody(),
|
||||||
|
true); // The "true" here indicates that the body contains HTML content.
|
||||||
|
helper.setFrom(mailProperties.getFrom());
|
||||||
|
|
||||||
|
// Adds the attachment to the email
|
||||||
|
helper.addAttachment(file.getOriginalFilename(), file);
|
||||||
|
|
||||||
|
// Sends the email via the configured mail sender
|
||||||
|
mailSender.send(message);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,52 @@
|
|||||||
|
package stirling.software.SPDF.config.security.mail;
|
||||||
|
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
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 lombok.AllArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import stirling.software.SPDF.model.ApplicationProperties;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This configuration class provides the JavaMailSender bean, which is used to send emails. It reads
|
||||||
|
* email server settings from the configuration (ApplicationProperties) and configures the mail
|
||||||
|
* client (JavaMailSender).
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
@Slf4j
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class MailConfig {
|
||||||
|
|
||||||
|
private final ApplicationProperties applicationProperties;
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public JavaMailSender javaMailSender() {
|
||||||
|
|
||||||
|
ApplicationProperties.Mail mailProperties = applicationProperties.getMail();
|
||||||
|
|
||||||
|
// Creates a new instance of JavaMailSenderImpl, which is a Spring implementation
|
||||||
|
JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
|
||||||
|
mailSender.setHost(mailProperties.getHost());
|
||||||
|
mailSender.setPort(mailProperties.getPort());
|
||||||
|
mailSender.setUsername(mailProperties.getUsername());
|
||||||
|
mailSender.setPassword(mailProperties.getPassword());
|
||||||
|
mailSender.setDefaultEncoding("UTF-8");
|
||||||
|
|
||||||
|
// Retrieves the JavaMail properties to configure additional SMTP parameters
|
||||||
|
Properties props = mailSender.getJavaMailProperties();
|
||||||
|
|
||||||
|
// Enables SMTP authentication
|
||||||
|
props.put("mail.smtp.auth", "true");
|
||||||
|
|
||||||
|
// Enables STARTTLS to encrypt the connection if supported by the SMTP server
|
||||||
|
props.put("mail.smtp.starttls.enable", "true");
|
||||||
|
|
||||||
|
// Returns the configured mail sender, ready to send emails
|
||||||
|
return mailSender;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,66 @@
|
|||||||
|
package stirling.software.SPDF.controller.api;
|
||||||
|
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Content;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import io.swagger.v3.oas.annotations.parameters.RequestBody;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
|
import jakarta.mail.MessagingException;
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import stirling.software.SPDF.config.security.mail.EmailService;
|
||||||
|
import stirling.software.SPDF.model.api.Email;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Controller for handling email-related API requests. This controller exposes an endpoint for
|
||||||
|
* sending emails with attachments.
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/v1/general")
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@Slf4j
|
||||||
|
@Tag(name = "General", description = "General APIs")
|
||||||
|
public class EmailController {
|
||||||
|
private final EmailService emailService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Endpoint to send an email with an attachment. This method consumes a multipart/form-data
|
||||||
|
* request containing the email details and attachment.
|
||||||
|
*
|
||||||
|
* @param email The Email object containing recipient address, subject, body, and file
|
||||||
|
* attachment.
|
||||||
|
* @return ResponseEntity with success or error message.
|
||||||
|
*/
|
||||||
|
@PostMapping(consumes = "multipart/form-data", value = "/send-email")
|
||||||
|
public ResponseEntity<String> sendEmailWithAttachment(
|
||||||
|
@RequestBody(
|
||||||
|
description =
|
||||||
|
"Email object containing the recipient's email address,"
|
||||||
|
+ " subject, body, and attachment",
|
||||||
|
required = true,
|
||||||
|
content =
|
||||||
|
@Content(
|
||||||
|
mediaType = "multipart/form-data",
|
||||||
|
schema = @Schema(implementation = Email.class)))
|
||||||
|
Email email) {
|
||||||
|
try {
|
||||||
|
// Calls the service to send the email with attachment
|
||||||
|
emailService.sendEmailWithAttachment(email);
|
||||||
|
return ResponseEntity.ok("Email sent successfully");
|
||||||
|
} catch (MessagingException e) {
|
||||||
|
// Catches any messaging exception (e.g., invalid email address, SMTP server issues)
|
||||||
|
String errorMsg = "Failed to send email: " + e.getMessage();
|
||||||
|
log.error(errorMsg, e); // Logging the detailed error
|
||||||
|
// Returns an error response with status 500 (Internal Server Error)
|
||||||
|
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorMsg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -82,6 +82,8 @@ public class ApplicationProperties {
|
|||||||
private Metrics metrics = new Metrics();
|
private Metrics metrics = new Metrics();
|
||||||
private AutomaticallyGenerated automaticallyGenerated = new AutomaticallyGenerated();
|
private AutomaticallyGenerated automaticallyGenerated = new AutomaticallyGenerated();
|
||||||
|
|
||||||
|
private Mail mail = new Mail();
|
||||||
|
|
||||||
private Premium premium = new Premium();
|
private Premium premium = new Premium();
|
||||||
private EnterpriseEdition enterpriseEdition = new EnterpriseEdition();
|
private EnterpriseEdition enterpriseEdition = new EnterpriseEdition();
|
||||||
private AutoPipeline autoPipeline = new AutoPipeline();
|
private AutoPipeline autoPipeline = new AutoPipeline();
|
||||||
@ -420,6 +422,15 @@ public class ApplicationProperties {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class Mail {
|
||||||
|
private String host;
|
||||||
|
private int port;
|
||||||
|
private String username;
|
||||||
|
@ToString.Exclude private String password;
|
||||||
|
private String from;
|
||||||
|
}
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public static class Premium {
|
public static class Premium {
|
||||||
private boolean enabled;
|
private boolean enabled;
|
||||||
|
42
src/main/java/stirling/software/SPDF/model/api/Email.java
Normal file
42
src/main/java/stirling/software/SPDF/model/api/Email.java
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
package stirling.software.SPDF.model.api;
|
||||||
|
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@EqualsAndHashCode
|
||||||
|
public class Email {
|
||||||
|
@Schema(
|
||||||
|
description = "The input file",
|
||||||
|
requiredMode = Schema.RequiredMode.REQUIRED,
|
||||||
|
format = "binary")
|
||||||
|
private MultipartFile fileInput;
|
||||||
|
|
||||||
|
@Schema(
|
||||||
|
description = "The recipient's email address",
|
||||||
|
requiredMode = Schema.RequiredMode.REQUIRED,
|
||||||
|
format = "email")
|
||||||
|
private String to;
|
||||||
|
|
||||||
|
@Schema(
|
||||||
|
description = "The subject of the email",
|
||||||
|
defaultValue = "Stirling Software PDF Notification",
|
||||||
|
requiredMode = Schema.RequiredMode.NOT_REQUIRED)
|
||||||
|
private String subject;
|
||||||
|
|
||||||
|
@Schema(
|
||||||
|
description = "The body of the email",
|
||||||
|
requiredMode = Schema.RequiredMode.NOT_REQUIRED,
|
||||||
|
defaultValue =
|
||||||
|
"This message was automatically generated by Stirling-PDF, an innovative"
|
||||||
|
+ " solution from Stirling Software. For more information, visit our <a"
|
||||||
|
+ " href=\"https://stirling-software.com\">website</a>.<br><br>Please do"
|
||||||
|
+ " not reply directly to this email.")
|
||||||
|
private String body;
|
||||||
|
}
|
@ -76,6 +76,13 @@ premium:
|
|||||||
apiKey: ''
|
apiKey: ''
|
||||||
appId: ''
|
appId: ''
|
||||||
|
|
||||||
|
mail:
|
||||||
|
host: smtp.example.com # SMTP server hostname
|
||||||
|
port: 587 # SMTP server port
|
||||||
|
username: '' # SMTP server username
|
||||||
|
password: '' # SMTP server password
|
||||||
|
from: '' # sender email address
|
||||||
|
|
||||||
legal:
|
legal:
|
||||||
termsAndConditions: https://www.stirlingpdf.com/terms-and-conditions # URL to the terms and conditions of your application (e.g. https://example.com/terms). Empty string to disable or filename to load from local file in static folder
|
termsAndConditions: https://www.stirlingpdf.com/terms-and-conditions # URL to the terms and conditions of your application (e.g. https://example.com/terms). Empty string to disable or filename to load from local file in static folder
|
||||||
privacyPolicy: https://www.stirlingpdf.com/privacy-policy # URL to the privacy policy of your application (e.g. https://example.com/privacy). Empty string to disable or filename to load from local file in static folder
|
privacyPolicy: https://www.stirlingpdf.com/privacy-policy # URL to the privacy policy of your application (e.g. https://example.com/privacy). Empty string to disable or filename to load from local file in static folder
|
||||||
|
Loading…
Reference in New Issue
Block a user