Skip to content
Open
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
2 changes: 1 addition & 1 deletion Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Spin up container with:
```
docker network create track-debts-net
docker run -d -v ./data:/var/lib/postgresql/data -e POSTGRES_DB=track-debts --network track-debts-net --name track-debts-pg postgres
docker run -d --network track-debts-net -e "LIQPAY_PUBLIC_KEY=<public key>" -e "LIQPAY_PRIVATE_KEY=<private key>" -e "APP_SECRET=<secret>" -e DB_HOST=track-debts-pg -e DB_PORT=5432 --name track-debts freefly19/track-debts
docker run -d --network track-debts-net -e "LIQPAY_PUBLIC_KEY=<public key>" -e "LIQPAY_PRIVATE_KEY=<private key>" -e "APP_SECRET=<secret>" -e DB_HOST=track-debts-pg -e DB_PORT=5432 -e SMTP_HOST=smtp.google.com -e SMTP_PORT=587 -e SMTP_USERNAME=<gmail_username> -e SMTP_PASSWORD=<gmail_pass> -e SMTP_START_TLS=true --name track-debts freefly19/track-debts
```
_**secret** should be longer than 86 chars_

Expand Down
5 changes: 5 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,14 @@ dependencies {

compile('com.spencerwi:Either.java:2.0.0')

compile 'org.springframework.boot:spring-boot-starter-mail:2.1.3.RELEASE'

compile('io.springfox:springfox-swagger2:2.9.2')
compile('io.springfox:springfox-swagger-ui:2.9.2')

compile group: 'org.thymeleaf', name: 'thymeleaf', version: '3.0.11.RELEASE'
compile group: 'org.thymeleaf', name: 'thymeleaf-spring5', version: '3.0.11.RELEASE'

compile('io.jsonwebtoken:jjwt-api:0.10.5')
runtime('io.jsonwebtoken:jjwt-impl:0.10.5')
runtime('io.jsonwebtoken:jjwt-jackson:0.10.5')
Expand Down
7 changes: 6 additions & 1 deletion dev/docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,9 @@ services:
environment:
POSTGRES_DB: track-debts-test
ports:
- 5434:5432
- 5434:5432
track-debts-mailhog:
image: mailhog/mailhog
ports:
- "1021:1025"
- "8021:8025"
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.annotation.EnableAsync;

import java.util.Date;

@SpringBootApplication(exclude = SecurityAutoConfiguration.class)
@EnableAsync
public class TrackDebtsApplication {

@Bean
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.freefly19.trackdebts.bill.user;

import com.freefly19.trackdebts.AppEvent;
import lombok.Getter;
import lombok.RequiredArgsConstructor;

@RequiredArgsConstructor
@Getter
public class BillUserCreatedEvent implements AppEvent {
private final long billUserId;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@

import com.freefly19.trackdebts.bill.Bill;
import com.freefly19.trackdebts.bill.BillRepository;
import com.freefly19.trackdebts.notification.EmailService;
import com.freefly19.trackdebts.security.UserRequestContext;
import com.freefly19.trackdebts.user.UserDto;
import com.freefly19.trackdebts.user.UserRepository;
import com.spencerwi.either.Either;
import lombok.RequiredArgsConstructor;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
Expand All @@ -24,6 +26,7 @@ public class BillUserService {
private final BillUserRepository billUserRepository;
private final UserRepository userRepository;
private final BillRepository billRepository;
private final ApplicationEventPublisher eventPublisher;

@Transactional
public Either<String, Optional<BillUserDto>> save(UserRequestContext context, CreateBillUserCommand command, Long billId) {
Expand Down Expand Up @@ -57,6 +60,8 @@ public Either<String, Optional<BillUserDto>> save(UserRequestContext context, Cr
return billUserRepository.save(bu);
});

eventPublisher.publishEvent(new BillUserCreatedEvent(billUser.getId()));

return Either.right(Optional.of(new BillUserDto(billUser)));
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.freefly19.trackdebts;
package com.freefly19.trackdebts.eventhandlers;

import com.freefly19.trackdebts.bill.Bill;
import com.freefly19.trackdebts.bill.BillRepository;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.freefly19.trackdebts.eventhandlers;

import com.freefly19.trackdebts.bill.user.BillUser;
import com.freefly19.trackdebts.bill.user.BillUserCreatedEvent;
import com.freefly19.trackdebts.bill.user.BillUserRepository;
import com.freefly19.trackdebts.notification.Email;
import com.freefly19.trackdebts.notification.EmailService;
import lombok.RequiredArgsConstructor;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;

@RequiredArgsConstructor
@Component
public class BillUserCreatedEmailGeneratorHandler {
private final EmailService emailService;
private final TemplateEngine templateEngine;
private final BillUserRepository repository;

@EventListener
public void onBillUserCreatedEvent(BillUserCreatedEvent event) {
BillUser billUser = repository.getOne(event.getBillUserId());
Email email = Email.builder()
.sender("no-reply@track-debts.com")
.receiver(billUser.getUser().getEmail())
.subject("You've been added to " + billUser.getBill().getTitle() + " bill")
.body(templateForBillUserEmail(billUser))
.build();
emailService.sendNotification(email);
}

private String templateForBillUserEmail(BillUser billUser) {
Context context = new Context();
context.setVariable("USER", billUser.getUser().getDisplayName());
context.setVariable("BILL", billUser.getBill().getTitle());

return templateEngine.process("email", context);
}
}
15 changes: 15 additions & 0 deletions src/main/java/com/freefly19/trackdebts/notification/Email.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.freefly19.trackdebts.notification;

import lombok.Builder;
import lombok.Getter;
import lombok.RequiredArgsConstructor;

@Builder
@RequiredArgsConstructor
@Getter
public class Email {
private final String sender;
private final String receiver;
private final String subject;
private final String body;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.freefly19.trackdebts.notification;

import lombok.RequiredArgsConstructor;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;

@RequiredArgsConstructor
@Service
public class EmailService {
private final JavaMailSender javaEmailSender;

@Async
public void sendNotification(Email mail) {
MimeMessage email = javaEmailSender.createMimeMessage();

try {
MimeMessageHelper helper = new MimeMessageHelper(email, true);

helper.setFrom(mail.getSender());
helper.setTo(mail.getReceiver());
helper.setSubject(mail.getSubject());
helper.setText(mail.getBody(), true);

javaEmailSender.send(email);
} catch (MessagingException e) {
e.printStackTrace();
}
}
}
11 changes: 11 additions & 0 deletions src/main/java/com/freefly19/trackdebts/user/User.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

@NoArgsConstructor
@AllArgsConstructor
Expand All @@ -29,4 +30,14 @@ public class User {
@OneToMany(mappedBy = "user")
private List<BillUser> billUsers = new ArrayList<>();

public String getFullName() {
if (firstName == null) {
return Optional.ofNullable(lastName).orElse(null);
}
return firstName + (lastName == null ? "" : (" " + lastName));
}

public String getDisplayName() {
return Optional.ofNullable(getFullName()).orElse(email);
}
}
7 changes: 7 additions & 0 deletions src/main/resources/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,10 @@ spring.jpa.database-platform=org.hibernate.dialect.PostgreSQL95Dialect
spring.datasource.url=jdbc:postgresql://${DB_HOST:localhost}:${DB_PORT:5433}/track-debts
spring.datasource.username=${DB_USERNAME:postgres}
spring.datasource.password=${DB_PASSWORD:}

spring.mail.host=${SMTP_HOST:localhost}
spring.mail.port=${SMTP_PORT:1021}
spring.mail.username=${SMTP_USERNAME:user@test.com}
spring.mail.password=${SMTP_PASSWORD:somepass}
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=${SMTP_START_TLS:false}
72 changes: 72 additions & 0 deletions src/main/resources/templates/BillUserCreatedEmailNotification.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Check</title>
</head>
<body>
<table
border="0"
cellpadding="0"
cellspacing="0"
style="
margin:0;
padding:0;
font-family: sans-serif;
font-size: 16px;
background-color: #fbfbfb;"
width="100%">
<tr>
<td align="center">
<table
border="0"
cellpadding="0"
cellspacing="0"
style="
margin:0;
padding:0;
max-width: 600px;
width: 100%;
border: 1px solid #0273d4;
background-color: white;"
width="100%">
<tr>
<td
colspan="3"
style="
height: 60px;
background-color: #0273d4;
text-align: center;
line-height: 50px;
font-size: 30px;
font-weight: bold;
color: #fff;">

<h3>Track debts</h3>
</td>
</tr>
<tr>
<td
style="
padding: 20px;
text-align: center;">
<table border="0" align="center">
<tr>
<td style="font-size: 19px;" th:text="'Hello, ' + ${USER}"></td>
</tr>
<tr>
<td style="padding-top: 16px;line-height: 25px;">
<span th:text=" 'You took part in the ' +
${BILL} + ' bill. Please, check in there.'"></span>
</td>
</tr>
<tr>
</table>
</td>
</tr>
</table>
</td>
</tr>
</table>
</body>
</html>