init
This commit is contained in:
@@ -0,0 +1,11 @@
|
||||
package de.champonthis.abi;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication()
|
||||
public class AbiApplication {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(AbiApplication.class, args);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package de.champonthis.abi.buisinesslogic;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import de.champonthis.abi.entity.Contact;
|
||||
import de.champonthis.abi.entity.ContactData;
|
||||
import de.champonthis.abi.repository.ContactDataRepository;
|
||||
|
||||
@Component
|
||||
public class ContactDataManager {
|
||||
|
||||
private final ContactDataRepository contactDataRepository;
|
||||
private final EmailService mailService;
|
||||
|
||||
public ContactDataManager(ContactDataRepository contactDataRepository, EmailService mailService) {
|
||||
this.contactDataRepository = contactDataRepository;
|
||||
this.mailService = mailService;
|
||||
}
|
||||
|
||||
public ContactData findByContactAndReportedBy(Long contact, Long reportedBy) {
|
||||
return contactDataRepository.findByContactAndReportedBy(contact, reportedBy).orElse(null);
|
||||
}
|
||||
|
||||
public ContactData findByinviteToken(String inviteToken) {
|
||||
return contactDataRepository.findByinviteToken(inviteToken).orElse(null);
|
||||
}
|
||||
|
||||
public void save(ContactData contactData) {
|
||||
contactDataRepository.save(contactData);
|
||||
}
|
||||
|
||||
public void sendInviteMail(Contact contact, ContactData contactData, Contact reportedBy) {
|
||||
if (StringUtils.isNoneEmpty(contactData.getEmail()) && StringUtils.isNoneEmpty(contactData.getInviteToken())) {
|
||||
Map<String, Object> variables = new HashMap<>();
|
||||
variables.put("contact", contact);
|
||||
variables.put("reportedBy", reportedBy);
|
||||
variables.put("inviteToken", contactData.getInviteToken());
|
||||
|
||||
String to = (StringUtils.isNoneEmpty(contact.getUpdatedName()) ? contact.getUpdatedName()
|
||||
: contact.getName()) + " <" + contactData.getEmail() + ">";
|
||||
|
||||
mailService.sendTemplateEmail(to, "Du wurdest zum Abi-Treffen eingeladen",
|
||||
"invite", variables);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
package de.champonthis.abi.buisinesslogic;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Base64;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.text.similarity.LevenshteinDistance;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import de.champonthis.abi.entity.Contact;
|
||||
import de.champonthis.abi.entity.ContactData;
|
||||
import de.champonthis.abi.repository.ContactRepository;
|
||||
import jakarta.annotation.PostConstruct;
|
||||
|
||||
@Component
|
||||
public class ContactManager {
|
||||
|
||||
private Logger logger = LoggerFactory.getLogger(ContactManager.class);
|
||||
|
||||
private final ContactRepository contactRepository;
|
||||
private final EmailService mailService;
|
||||
private LevenshteinDistance levenshteinDistance = LevenshteinDistance.getDefaultInstance();
|
||||
|
||||
public ContactManager(ContactRepository contactRepository, EmailService mailService) {
|
||||
this.contactRepository = contactRepository;
|
||||
this.mailService = mailService;
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void loadCsv() {
|
||||
try {
|
||||
File resource = new File("namen.csv");
|
||||
if (resource.exists() && resource.isFile()) {
|
||||
try (BufferedReader reader = new BufferedReader(
|
||||
new InputStreamReader(new FileInputStream(resource), StandardCharsets.UTF_8))) {
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
line = line.trim();
|
||||
if (StringUtils.isNoneEmpty(line) && !line.startsWith("#")
|
||||
&& contactRepository.findByName(line).isEmpty()) {
|
||||
Contact contact = new Contact();
|
||||
contact.setName(line);
|
||||
save(contact);
|
||||
logger.info("Created contact: #" + contact.getId() + ": " + contact.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
logger.warn("No names.csv found!");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.warn("Could not read names.csv!");
|
||||
}
|
||||
}
|
||||
|
||||
public Contact findById(Long id) {
|
||||
return contactRepository.findById(id).orElse(null);
|
||||
}
|
||||
|
||||
public Contact findByName(String name) {
|
||||
return contactRepository.findByName(name).orElse(null);
|
||||
}
|
||||
|
||||
public Contact findByToken(String token) {
|
||||
return contactRepository.findByToken(token).orElse(null);
|
||||
}
|
||||
|
||||
public Contact findByLevenshteinDistance(String name) {
|
||||
return findByLevenshteinDistance(name, 3);
|
||||
}
|
||||
|
||||
public Contact findByLevenshteinDistance(String name, int threshold) {
|
||||
Contact result = null;
|
||||
for (Contact contact : contactRepository.findAll()) {
|
||||
int distance = levenshteinDistance.apply(name.toLowerCase(), contact.getName().toLowerCase());
|
||||
if (distance <= threshold) {
|
||||
result = contact;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public void save(Contact contact) {
|
||||
contactRepository.save(contact);
|
||||
}
|
||||
|
||||
public void sendTokenMail(Contact contact, ContactData contactData) {
|
||||
if (StringUtils.isNoneEmpty(contact.getToken()) && StringUtils.isNoneEmpty(contactData.getEmail())) {
|
||||
Map<String, Object> variables = new HashMap<>();
|
||||
variables.put("contact", contact);
|
||||
variables.put("token", contact.getToken());
|
||||
|
||||
String to = (StringUtils.isNoneEmpty(contact.getUpdatedName()) ? contact.getUpdatedName()
|
||||
: contact.getName()) + " <" + contactData.getEmail() + ">";
|
||||
|
||||
mailService.sendTemplateEmail(to, "Dein persönlicher Link für das Abi-Treffen",
|
||||
"confirmation", variables);
|
||||
}
|
||||
}
|
||||
|
||||
private static final SecureRandom secureRandom = new SecureRandom();
|
||||
private static final Base64.Encoder base64Encoder = Base64.getUrlEncoder().withoutPadding();
|
||||
|
||||
public static String generateToken() {
|
||||
return generateToken(32);
|
||||
}
|
||||
|
||||
public static String generateToken(int byteLength) {
|
||||
byte[] randomBytes = new byte[byteLength];
|
||||
secureRandom.nextBytes(randomBytes);
|
||||
return base64Encoder.encodeToString(randomBytes);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package de.champonthis.abi.buisinesslogic;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.mail.javamail.JavaMailSender;
|
||||
import org.springframework.mail.javamail.MimeMessageHelper;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.thymeleaf.TemplateEngine;
|
||||
import org.thymeleaf.context.Context;
|
||||
|
||||
import jakarta.mail.MessagingException;
|
||||
import jakarta.mail.internet.MimeMessage;
|
||||
|
||||
@Service
|
||||
public class EmailService {
|
||||
|
||||
private final JavaMailSender mailSender;
|
||||
private final TemplateEngine templateEngine;
|
||||
|
||||
@Value("${app.url:}")
|
||||
private String url;
|
||||
@Value("${app.mail.from:}")
|
||||
private String from;
|
||||
@Value("${app.mail.fromMail:}")
|
||||
private String fromMail;
|
||||
|
||||
public EmailService(JavaMailSender mailSender, TemplateEngine templateEngine) {
|
||||
this.mailSender = mailSender;
|
||||
this.templateEngine = templateEngine;
|
||||
}
|
||||
|
||||
public void sendTemplateEmail(String to, String subject, String templateName, Map<String, Object> variables) {
|
||||
Context context = new Context();
|
||||
variables.put("url", url);
|
||||
context.setVariables(variables);
|
||||
|
||||
String htmlContent = templateEngine.process("email/" + templateName, context);
|
||||
|
||||
MimeMessage message = mailSender.createMimeMessage();
|
||||
try {
|
||||
MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8");
|
||||
|
||||
helper.setFrom(from + " <" + fromMail + ">");
|
||||
helper.setTo(to);
|
||||
helper.setSubject(subject);
|
||||
helper.setText(htmlContent, true);
|
||||
|
||||
mailSender.send(message);
|
||||
} catch (MessagingException e) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
package de.champonthis.abi.controller;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestHeader;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.server.ResponseStatusException;
|
||||
|
||||
import de.champonthis.abi.buisinesslogic.ContactDataManager;
|
||||
import de.champonthis.abi.buisinesslogic.ContactManager;
|
||||
import de.champonthis.abi.controller.request.ContactRequest;
|
||||
import de.champonthis.abi.entity.Contact;
|
||||
import de.champonthis.abi.entity.ContactData;
|
||||
import jakarta.validation.Valid;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/v1/contact")
|
||||
public class ContactController {
|
||||
|
||||
private final ContactManager contactManager;
|
||||
private final ContactDataManager contactDataManager;
|
||||
|
||||
public ContactController(ContactManager contactManager, ContactDataManager contactDataManager) {
|
||||
this.contactManager = contactManager;
|
||||
this.contactDataManager = contactDataManager;
|
||||
}
|
||||
|
||||
@GetMapping()
|
||||
public Contact find(@RequestHeader(name = HttpHeaders.AUTHORIZATION, required = false) String authToken,
|
||||
@RequestParam String name) {
|
||||
Contact contact = contactManager.findByLevenshteinDistance(name);
|
||||
if (contact == null) {
|
||||
throw new ResponseStatusException(HttpStatus.NOT_FOUND);
|
||||
}
|
||||
|
||||
if (StringUtils.isNoneEmpty(contact.getToken()) && !contact.getToken().equals(authToken)) {
|
||||
throw new ResponseStatusException(HttpStatus.ALREADY_REPORTED);
|
||||
}
|
||||
|
||||
return contact;
|
||||
}
|
||||
|
||||
@PostMapping()
|
||||
public void update(@RequestHeader(name = HttpHeaders.AUTHORIZATION, required = false) String authToken,
|
||||
@Valid @RequestBody ContactRequest request) {
|
||||
Contact contact = contactManager.findByName(request.getName());
|
||||
if (contact == null) {
|
||||
throw new ResponseStatusException(HttpStatus.NOT_FOUND);
|
||||
}
|
||||
|
||||
if (StringUtils.isNoneEmpty(contact.getToken()) && !contact.getToken().equals(authToken)) {
|
||||
throw new ResponseStatusException(HttpStatus.ALREADY_REPORTED);
|
||||
}
|
||||
|
||||
contact.setUpdatedName(request.getUpdatedName());
|
||||
|
||||
boolean sendToken = false;
|
||||
|
||||
if (request.getCommitted() != null) {
|
||||
contact.setCommitted(request.getCommitted());
|
||||
|
||||
if (StringUtils.isEmpty(contact.getToken())) {
|
||||
String token = ContactManager.generateToken();
|
||||
while (contactManager.findByToken(token) != null) {
|
||||
token = ContactManager.generateToken();
|
||||
}
|
||||
contact.setToken(token);
|
||||
sendToken = true;
|
||||
}
|
||||
}
|
||||
|
||||
contactManager.save(contact);
|
||||
|
||||
if (sendToken) {
|
||||
ContactData contactData = contactDataManager.findByContactAndReportedBy(contact.getId(), contact.getId());
|
||||
if (contactData != null) {
|
||||
contactManager.sendTokenMail(contact, contactData);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
package de.champonthis.abi.controller;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.http.HttpStatus;
|
||||
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 org.springframework.web.server.ResponseStatusException;
|
||||
|
||||
import de.champonthis.abi.buisinesslogic.ContactDataManager;
|
||||
import de.champonthis.abi.buisinesslogic.ContactManager;
|
||||
import de.champonthis.abi.controller.request.ContactDataRequest;
|
||||
import de.champonthis.abi.entity.Contact;
|
||||
import de.champonthis.abi.entity.ContactData;
|
||||
import jakarta.validation.Valid;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/v1/contact/data")
|
||||
public class ContactDataController {
|
||||
|
||||
private final ContactManager contactManager;
|
||||
private final ContactDataManager contactDataManager;
|
||||
|
||||
public ContactDataController(ContactManager contactManager, ContactDataManager contactDataManager) {
|
||||
this.contactManager = contactManager;
|
||||
this.contactDataManager = contactDataManager;
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
public ResponseEntity<ContactData> create(@Valid @RequestBody ContactDataRequest request) {
|
||||
Contact contact = contactManager.findByName(request.getName());
|
||||
Contact reportedBy = contactManager.findByName(request.getReportedBy());
|
||||
|
||||
if (contact == null || reportedBy == null) {
|
||||
throw new ResponseStatusException(HttpStatus.UNPROCESSABLE_ENTITY);
|
||||
}
|
||||
|
||||
ContactData contactData = contactDataManager.findByContactAndReportedBy(contact.getId(), reportedBy.getId());
|
||||
|
||||
HttpStatus status = HttpStatus.OK;
|
||||
boolean sendToken = false;
|
||||
|
||||
if (contactData == null) {
|
||||
contactData = new ContactData();
|
||||
contactData.setContact(contact.getId());
|
||||
contactData.setReportedBy(reportedBy.getId());
|
||||
status = HttpStatus.CREATED;
|
||||
}
|
||||
|
||||
if (contact.getId().equals(reportedBy.getId())
|
||||
&& StringUtils.isNotEmpty(contact.getToken())
|
||||
&& (status.isSameCodeAs(HttpStatus.CREATED) || !request.getEmail().equals(contactData.getEmail()))) {
|
||||
sendToken = true;
|
||||
}
|
||||
|
||||
contactData.setEmail(request.getEmail());
|
||||
contactData.setPhone(request.getPhone());
|
||||
|
||||
if (!contact.getId().equals(reportedBy.getId())
|
||||
&& (contactData.getInviteToken() == null || StringUtils.isEmpty(contactData.getInviteToken()))) {
|
||||
String inviteToken = ContactManager.generateToken();
|
||||
while (contactDataManager.findByinviteToken(inviteToken) != null) {
|
||||
inviteToken = ContactManager.generateToken();
|
||||
}
|
||||
contactData.setInviteToken(inviteToken);
|
||||
contactDataManager.sendInviteMail(contact, contactData, reportedBy);
|
||||
}
|
||||
|
||||
contactDataManager.save(contactData);
|
||||
|
||||
if (sendToken) {
|
||||
contactManager.sendTokenMail(contact, contactData);
|
||||
}
|
||||
|
||||
return ResponseEntity.status(status.value()).body(contactData);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
package de.champonthis.abi.controller;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
import de.champonthis.abi.buisinesslogic.ContactDataManager;
|
||||
import de.champonthis.abi.buisinesslogic.ContactManager;
|
||||
import de.champonthis.abi.entity.Contact;
|
||||
import de.champonthis.abi.entity.ContactData;
|
||||
|
||||
@Controller
|
||||
public class FrontendController {
|
||||
|
||||
private final ContactManager contactManager;
|
||||
private final ContactDataManager contactDataManager;
|
||||
|
||||
public FrontendController(ContactManager contactManager, ContactDataManager contactDataManager) {
|
||||
this.contactManager = contactManager;
|
||||
this.contactDataManager = contactDataManager;
|
||||
}
|
||||
|
||||
@GetMapping("/")
|
||||
public String index(
|
||||
@RequestParam(required = false) String token,
|
||||
@RequestParam(required = false) String invite,
|
||||
Model model) {
|
||||
if (token != null && !token.isEmpty()) {
|
||||
Contact contact = contactManager.findByToken(token);
|
||||
if (contact != null) {
|
||||
model.addAttribute("token", token);
|
||||
model.addAttribute("userName", contact.getName());
|
||||
model.addAttribute("altName", contact.getUpdatedName());
|
||||
model.addAttribute("altName", contact.getUpdatedName());
|
||||
|
||||
ContactData contactData = contactDataManager.findByContactAndReportedBy(contact.getId(),
|
||||
contact.getId());
|
||||
if (contactData != null) {
|
||||
model.addAttribute("email", contactData.getEmail());
|
||||
model.addAttribute("phone", contactData.getPhone());
|
||||
}
|
||||
|
||||
}
|
||||
} else if (invite != null && !invite.isEmpty()) {
|
||||
ContactData contactData = contactDataManager.findByinviteToken(invite);
|
||||
|
||||
if (contactData != null) {
|
||||
Contact contact = contactManager.findById(contactData.getContact());
|
||||
if (contact != null && StringUtils.isEmpty(contact.getToken())) {
|
||||
model.addAttribute("userName", contact.getName());
|
||||
model.addAttribute("altName", contact.getUpdatedName());
|
||||
model.addAttribute("email", contactData.getEmail());
|
||||
model.addAttribute("phone", contactData.getPhone());
|
||||
}
|
||||
}
|
||||
}
|
||||
return "index";
|
||||
}
|
||||
|
||||
@GetMapping("/imprint")
|
||||
public String imprint() {
|
||||
return "imprint";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package de.champonthis.abi.controller.request;
|
||||
|
||||
import jakarta.validation.constraints.Email;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.Pattern;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class ContactDataRequest {
|
||||
|
||||
@NotBlank(message = "name must not be empty")
|
||||
private String name;
|
||||
@NotBlank(message = "email must not be empty")
|
||||
@Email(message = "Invalid email format")
|
||||
private String email;
|
||||
// Accept empty or valid phone number
|
||||
@Pattern(regexp = "^$|^(\\+49|0)[1-9][0-9]{7,14}$", message = "Invalid phone number")
|
||||
private String phone;
|
||||
@NotBlank(message = "reportedBy must not be empty")
|
||||
private String reportedBy;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package de.champonthis.abi.controller.request;
|
||||
|
||||
import de.champonthis.abi.entity.Commitment;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class ContactRequest {
|
||||
|
||||
@NotBlank(message = "name must not be empty")
|
||||
private String name;
|
||||
private String updatedName;
|
||||
private Commitment committed;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package de.champonthis.abi.entity;
|
||||
|
||||
public enum Commitment {
|
||||
UNKNOWN, YES, NO
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package de.champonthis.abi.entity;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.EnumType;
|
||||
import jakarta.persistence.Enumerated;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.GenerationType;
|
||||
import jakarta.persistence.Id;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@Entity
|
||||
public class Contact {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@Column(name = "id", nullable = false)
|
||||
@JsonIgnore
|
||||
private Long id;
|
||||
private String name;
|
||||
private String updatedName;
|
||||
@Enumerated(EnumType.STRING)
|
||||
private Commitment committed = Commitment.UNKNOWN;
|
||||
@JsonIgnore
|
||||
private String token;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package de.champonthis.abi.entity;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.GenerationType;
|
||||
import jakarta.persistence.Id;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@Entity
|
||||
public class ContactData {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@Column(name = "id", nullable = false)
|
||||
private Long id;
|
||||
@Column(nullable = false)
|
||||
private Long contact;
|
||||
private String email;
|
||||
private String phone;
|
||||
@Column(nullable = false)
|
||||
private Long reportedBy;
|
||||
@JsonIgnore
|
||||
private String inviteToken;
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package de.champonthis.abi.repository;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import de.champonthis.abi.entity.ContactData;
|
||||
|
||||
@Repository
|
||||
public interface ContactDataRepository extends JpaRepository<ContactData, Long> {
|
||||
|
||||
Optional<ContactData> findByContactAndReportedBy(Long contact, Long reportedBy);
|
||||
|
||||
Optional<ContactData> findByinviteToken(String inviteToken);
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package de.champonthis.abi.repository;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import de.champonthis.abi.entity.Contact;
|
||||
|
||||
@Repository
|
||||
public interface ContactRepository extends JpaRepository<Contact, Long> {
|
||||
|
||||
Optional<Contact> findByName(String name);
|
||||
|
||||
Optional<Contact> findByToken(String token);
|
||||
}
|
||||
Reference in New Issue
Block a user