diff --git a/src/main/java/com/alttd/forms/contact/ContactController.java b/src/main/java/com/alttd/forms/contact/ContactController.java index ed4f797..9af7a39 100644 --- a/src/main/java/com/alttd/forms/contact/ContactController.java +++ b/src/main/java/com/alttd/forms/contact/ContactController.java @@ -21,7 +21,7 @@ public class ContactController { public CompletableFuture> submitForm(@Valid @RequestBody ContactFormData formData) { logger.debug(formData.toString()); - CompletableFuture storeFormForVerificationCode = new StoreFormQuery().storeFormForVerificationCode(formData.toJsonString(), formData.email); + CompletableFuture storeFormForVerificationCode = new StoreFormQuery().storeFormForVerificationCode(formData.email, formData); return storeFormForVerificationCode.thenCompose(code -> Verify.verifyEmail(formData.email, code).thenApply(verificationResult -> { if (verificationResult == VerificationResult.VERIFICATION_SENT) { //TODO if this is ok tell the user they have x min to verify if they fail to do so they have to remake the form diff --git a/src/main/java/com/alttd/forms/contact/StoreFormQuery.java b/src/main/java/com/alttd/forms/contact/StoreFormQuery.java index 5271ade..aa7c746 100644 --- a/src/main/java/com/alttd/forms/contact/StoreFormQuery.java +++ b/src/main/java/com/alttd/forms/contact/StoreFormQuery.java @@ -7,6 +7,8 @@ import java.time.Instant; import java.util.Optional; import java.util.Random; import java.util.concurrent.CompletableFuture; + +import com.alttd.forms.form.Form; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -19,11 +21,12 @@ public class StoreFormQuery { return 100000 + random.nextInt(900000); } - private Optional insertForm(Connection connection, String form) { - String insertForm = "INSERT INTO form (creation_date, form_json) VALUES (?, ?)"; + private Optional insertForm(Connection connection, Form form) { + String insertForm = "INSERT INTO form (creation_date, form_json, form_class) VALUES (?, ?, ?)"; try (PreparedStatement stmt = connection.prepareStatement(insertForm, Statement.RETURN_GENERATED_KEYS)) { stmt.setLong(1, Instant.now().toEpochMilli()); - stmt.setString(2, form); + stmt.setString(2, form.toJsonString()); + stmt.setString(3, form.getClass().getSimpleName()); int affectedRows = stmt.executeUpdate(); if (affectedRows == 0) { logger.error("No rows affected during insert of form: " + form); @@ -57,7 +60,7 @@ public class StoreFormQuery { } } - public CompletableFuture storeFormForVerificationCode(String form, String eMail) { + public CompletableFuture storeFormForVerificationCode(String eMail, Form form) { Connection connection = DatabaseConnection.getConnection(); return CompletableFuture.supplyAsync(() -> { Optional optionalFormId = insertForm(connection, form); diff --git a/src/main/java/com/alttd/forms/database/Database.java b/src/main/java/com/alttd/forms/database/Database.java index 6188f0d..ebd8117 100644 --- a/src/main/java/com/alttd/forms/database/Database.java +++ b/src/main/java/com/alttd/forms/database/Database.java @@ -13,7 +13,7 @@ public class Database { public static void createTables() { String[] createTables = { "CREATE TABLE IF NOT EXISTS verify_form (e_mail VARCHAR(256), verification_code INT, formId INT, PRIMARY KEY(e_mail, verification_code))", - "CREATE TABLE IF NOT EXISTS form (formId INT AUTO_INCREMENT, creation_date BIGINT, form_json TEXT, PRIMARY KEY(formId))" + "CREATE TABLE IF NOT EXISTS form (formId INT AUTO_INCREMENT, creation_date BIGINT, form_json TEXT, form_class VARCHAR(64), PRIMARY KEY(formId))" }; Connection connection = DatabaseConnection.getConnection(); for (String query : createTables) { diff --git a/src/main/java/com/alttd/forms/mail/mail_forms/MailForm.java b/src/main/java/com/alttd/forms/mail/mail_forms/MailForm.java index 0263ae4..3d81d03 100644 --- a/src/main/java/com/alttd/forms/mail/mail_forms/MailForm.java +++ b/src/main/java/com/alttd/forms/mail/mail_forms/MailForm.java @@ -1,9 +1,7 @@ package com.alttd.forms.mail.mail_forms; -import com.alttd.forms.contact.ContactFormData; import com.alttd.forms.form.Form; import com.alttd.forms.mail.MailSettings; -import com.google.gson.Gson; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -17,19 +15,16 @@ public class MailForm { private static final Logger logger = LoggerFactory.getLogger(MailForm.class); - public static void sendForm(String receiver, String json) { //TODO something to convert json back to the right object, might need to store classname in db? - ContactFormData contactFormData = new Gson().fromJson(json, ContactFormData.class); + public static void sendForm(String receiver, Form form) { Properties mailProperties = MailSettings.getMailProperties(); Optional accountDetails = MailSettings.getAccountDetails(); if (accountDetails.isEmpty()) { - logger.error("No account details, can't send email to " + receiver + " with data " + contactFormData.toString()); + logger.error("No account details, can't send email to " + receiver + " with data " + form.toString()); return; } PasswordAuthentication passwordAuthentication = accountDetails.get(); Session session = MailSettings.getSession(mailProperties, passwordAuthentication); - //TODO rate limiting should be handled before anything ever gets here - try { Message message = new MimeMessage(session); message.setFrom(new InternetAddress(passwordAuthentication.getUserName())); @@ -39,12 +34,12 @@ public class MailForm { ); message.setSubject("Altitude Form"); //TODO add something above the html form probably - message.setContent(contactFormData.toHtml(), "text/html"); + message.setContent(form.toHtml(), "text/html"); try { Transport.send(message); - logger.debug("Send mail to " + receiver + " containing " + contactFormData) ; + logger.debug("Send mail to " + receiver + " containing " + form) ; } catch (MessagingException e) { - logger.error("Unable to send mail to " + receiver + " with data " + contactFormData, e); + logger.error("Unable to send mail to " + receiver + " with data " + form, e); } } catch (MessagingException e) { logger.error("Failed to create MimeMessage", e); diff --git a/src/main/java/com/alttd/forms/verify_mail/FormQuery.java b/src/main/java/com/alttd/forms/verify_mail/FormQuery.java index 328ea1a..b5643f4 100644 --- a/src/main/java/com/alttd/forms/verify_mail/FormQuery.java +++ b/src/main/java/com/alttd/forms/verify_mail/FormQuery.java @@ -1,6 +1,10 @@ package com.alttd.forms.verify_mail; +import com.alttd.forms.contact.ContactFormData; +import com.alttd.forms.contact.StoreFormQuery; import com.alttd.forms.database.DatabaseConnection; +import com.alttd.forms.form.Form; +import com.google.gson.Gson; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -15,7 +19,7 @@ public class FormQuery { private static final Logger logger = LoggerFactory.getLogger(FormQuery.class); - public static Optional getFormId(Connection connection, int verificationCode, String eMail) throws SQLException { + public Optional getFormId(Connection connection, int verificationCode, String eMail) throws SQLException { String sql = "SELECT formId FROM verify_form WHERE verification_code = ? AND e_mail = ?"; try (PreparedStatement stmt = connection.prepareStatement(sql)) { @@ -33,7 +37,7 @@ public class FormQuery { } } - private static Optional getFormForId(Connection connection, int formId) throws SQLException { + private Optional
getFormForId(Connection connection, int formId) throws SQLException { String sql = "SELECT form_json FROM form WHERE formId = ?"; try (PreparedStatement stmt = connection.prepareStatement(sql)) { @@ -43,14 +47,30 @@ public class FormQuery { logger.warn("Could not find form with id: " + formId); return Optional.empty(); } - return Optional.of(resultSet.getString("form_json")); + String json = resultSet.getString("form_json"); + String formClass = resultSet.getString("form_class"); + try { + return Optional.of(getForm(formClass, json)); + } catch (IllegalArgumentException e) { + logger.error("Invalid form class in database", e); + return Optional.empty(); + } } catch (SQLException e) { logger.error("Failed select form query for form with id: " + formId, e); throw e; } } - public static CompletableFuture getFormForCode(String verificationCode, String eMail) { + private Form getForm(String className, String json) throws IllegalArgumentException { + switch (className) { + case "ContactFormData" -> { + return new Gson().fromJson(json, ContactFormData.class); + } + default -> throw new IllegalArgumentException("Invalid form class name: " + className); + } + } + + public CompletableFuture getFormForCode(String verificationCode, String eMail) { Connection connection = DatabaseConnection.getConnection(); int code; try { @@ -73,7 +93,7 @@ public class FormQuery { try { return getFormForId(connection, formId.get()) - .map(formJson -> new FormQueryResult(Optional.of(formJson), "Success")) + .map(form -> new FormQueryResult(Optional.of(form), "Success")) .orElse(new FormQueryResult(Optional.empty(), "Unable to find your form")); } catch (SQLException e) { throw new RuntimeException(e); diff --git a/src/main/java/com/alttd/forms/verify_mail/FormQueryResult.java b/src/main/java/com/alttd/forms/verify_mail/FormQueryResult.java index 8d5e3df..83970ff 100644 --- a/src/main/java/com/alttd/forms/verify_mail/FormQueryResult.java +++ b/src/main/java/com/alttd/forms/verify_mail/FormQueryResult.java @@ -1,6 +1,8 @@ package com.alttd.forms.verify_mail; +import com.alttd.forms.form.Form; + import java.util.Optional; -public record FormQueryResult(Optional formJson, String failReason) { +public record FormQueryResult(Optional form, String failReason) { } diff --git a/src/main/java/com/alttd/forms/verify_mail/VerifyController.java b/src/main/java/com/alttd/forms/verify_mail/VerifyController.java index 86498fb..537aae5 100644 --- a/src/main/java/com/alttd/forms/verify_mail/VerifyController.java +++ b/src/main/java/com/alttd/forms/verify_mail/VerifyController.java @@ -1,5 +1,6 @@ package com.alttd.forms.verify_mail; +import com.alttd.forms.form.Form; import com.alttd.forms.mail.mail_forms.MailForm; import jakarta.validation.Valid; import org.slf4j.Logger; @@ -21,12 +22,12 @@ public class VerifyController { @PostMapping("/form") public CompletableFuture> validateEmailFromForm(@Valid @RequestBody VerificationData verificationData) { logger.debug(verificationData.toString()); - return FormQuery.getFormForCode(verificationData.code, verificationData.eMail).thenApply(form -> form.formJson() - .map(body -> { - MailForm.sendForm("akastijn@alttd.com", body); - return ResponseEntity.ok(body); + return new FormQuery().getFormForCode(verificationData.code, verificationData.eMail).thenApply(result -> result.form() + .map(form -> { + MailForm.sendForm("akastijn@alttd.com", form); + return ResponseEntity.ok(form.toJsonString()); }) - .orElse(ResponseEntity.ok(form.failReason())) + .orElse(ResponseEntity.ok(result.failReason())) ).exceptionally(throwable -> ResponseEntity.internalServerError() .body("The server was unable to process your request, if this issue persists please contact admin@alttd.com")); }