Compare commits

..
7 Commits
Author SHA1 Message Date
auto 3eb4970407 Refactor toHtml() method in Form.java
Enhanced `toHtml()` to split multiline values into paragraphs using streams and filters. This improves HTML output readability by ensuring each line is wrapped in `<p>` tags. Also updated workspace.xml with the correct description for the recent changes.
2024-08-11 18:47:36 +02:00
auto ab74360571 Add IP address tracking for form submissions
Included IP and timestamp columns in the database schema to track form submissions. Updated methods to handle and store the IP information upon form submission. Adjusted related test cases to validate the new implementation.
2024-08-11 18:31:15 +02:00
auto fcda4c9e53 Update toHtml() method in Form.java
Simplified the HTML structure for the `toHtml` method by switching from a table layout to paragraph tags. This removes unnecessary table formatting for improved readability and maintainability. Also updated workspace.xml with task tracking and removed outdated comments.
2024-08-11 18:24:37 +02:00
auto 4a0aebce82 Improve email handling with Mailable interface
Added a new Mailable interface for extracting email-related data like receiver and subject. Updated StaffAppFormData and ContactFormData to implement this interface, and refactored MailForm to utilize these details. This enhances flexibility and decouples email details from form classes.
2024-08-11 18:21:16 +02:00
auto 47f6eebd8b Add branch condition to Discord notification stage
The Discord notification stage now runs only on 'main' or 'master' branches. This helps to avoid unnecessary notifications for feature or bugfix branches.
2024-08-11 18:10:36 +02:00
auto 1dbb80e5a2 Add @JsonIgnore annotations to sensitive methods
Added @JsonIgnore annotations to override methods in StaffAppFormData and ContactFormData classes to prevent them from being serialized.
2024-08-10 04:30:37 +02:00
auto ed098513f5 Change fields from final to mutable in form classes
Refactored `StaffAppFormData` and `ContactFormData` to allow updating fields by removing the `final` modifier. Added default constructors to both classes for easier instantiation and management. This change improves the flexibility and maintainability of the codebase.
2024-08-10 04:24:08 +02:00
12 changed files with 156 additions and 66 deletions
+60 -15
View File
@@ -4,11 +4,9 @@
<option name="autoReloadType" value="SELECTIVE" />
</component>
<component name="ChangeListManager">
<list default="true" id="ce59df2a-8d56-446a-867b-80e627daf479" name="Changes" comment="Ensure NOT NULL constraints in SQL tables&#10;&#10;Refactor SQL table creation scripts to add NOT NULL constraints where necessary. This change ensures data integrity by preventing null values in critical columns across the 'verify_form', 'form', 'rate_limit', and 'form_active' tables.">
<change afterPath="$PROJECT_DIR$/src/main/java/com/alttd/forms/controlers/form_active/BooleanResponse.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/com/alttd/forms/controlers/form_active/FormActiveController.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/com/alttd/forms/controlers/form_active/FormActiveController.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/com/alttd/forms/controlers/form_active/FormActiveData.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/com/alttd/forms/controlers/form_active/FormActiveData.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/resources/application.properties" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/resources/application.properties" afterDir="false" />
<list default="true" id="ce59df2a-8d56-446a-867b-80e627daf479" name="Changes" comment="Add IP address tracking for form submissions&#10;&#10;Included IP and timestamp columns in the database schema to track form submissions. Updated methods to handle and store the IP information upon form submission. Adjusted related test cases to validate the new implementation.">
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/com/alttd/forms/form/Form.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/com/alttd/forms/form/Form.java" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
@@ -53,6 +51,7 @@
<option value="package.json" />
<option value="Class" />
<option value="Record" />
<option value="Interface" />
</list>
</option>
</component>
@@ -79,6 +78,14 @@
&quot;accountId&quot;: &quot;ad9eb076-a98f-40c2-b7e5-9fc28b23038f&quot;
}
}</component>
<component name="HighlightingSettingsPerFile">
<setting file="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/javax.mail/mail/1.4/1aa1579ae5ecd41920c4f355b0a9ef40b68315dd/mail-1.4.jar!/javax/mail/Part.class" root0="SKIP_INSPECTION" />
</component>
<component name="Jenkins.Settings">
<option name="jenkinsUrl" value="https://jenkins.alttd.com" />
<option name="lastSelectedView" value="all" />
<option name="username" value="stijn" />
</component>
<component name="KubernetesApiProvider">{
&quot;isMigrated&quot;: true
}</component>
@@ -120,10 +127,9 @@
"RequestMappingsPanelWidth1": "75",
"RunOnceActivity.OpenProjectViewOnStart": "true",
"RunOnceActivity.ShowReadmeOnStart": "true",
"SHARE_PROJECT_CONFIGURATION_FILES": "true",
"Spring Boot.Main.executor": "Run",
"Tomcat Server.Tomcat 10.1.17.executor": "Run",
"git-widget-placeholder": "rate__limit",
"git-widget-placeholder": "master",
"ignore.virus.scanning.warn.message": "true",
"kotlin-language-version-configured": "true",
"last_opened_file_path": "P:/Code/Plugins/forms",
@@ -136,7 +142,7 @@
"project.structure.proportion": "0.0",
"project.structure.side.proportion": "0.0",
"run.code.analysis.last.selected.profile": "pProject Default",
"settings.editor.selected.configurable": "preferences.lookFeel",
"settings.editor.selected.configurable": "org.codinjutsu.tools.jenkins.servers",
"vue.rearranger.settings.migration": "true"
},
"keyToStringList": {
@@ -385,6 +391,9 @@
<workItem from="1723138548381" duration="1949000" />
<workItem from="1723230192640" duration="55000" />
<workItem from="1723242314809" duration="9799000" />
<workItem from="1723307861750" duration="2179000" />
<workItem from="1723392202182" duration="258000" />
<workItem from="1723392471077" duration="2183000" />
</task>
<task id="LOCAL-00001" summary="Initial commit for site for forms">
<option name="closed" value="true" />
@@ -650,7 +659,39 @@
<option name="project" value="LOCAL" />
<updated>1723249968746</updated>
</task>
<option name="localTasksCounter" value="34" />
<task id="LOCAL-00034" summary="Add branch condition to Discord notification stage&#10;&#10;The Discord notification stage now runs only on 'main' or 'master' branches. This helps to avoid unnecessary notifications for feature or bugfix branches.">
<option name="closed" value="true" />
<created>1723392636255</created>
<option name="number" value="00034" />
<option name="presentableId" value="LOCAL-00034" />
<option name="project" value="LOCAL" />
<updated>1723392636255</updated>
</task>
<task id="LOCAL-00035" summary="Improve email handling with Mailable interface&#10;&#10;Added a new Mailable interface for extracting email-related data like receiver and subject. Updated StaffAppFormData and ContactFormData to implement this interface, and refactored MailForm to utilize these details. This enhances flexibility and decouples email details from form classes.">
<option name="closed" value="true" />
<created>1723393276632</created>
<option name="number" value="00035" />
<option name="presentableId" value="LOCAL-00035" />
<option name="project" value="LOCAL" />
<updated>1723393276632</updated>
</task>
<task id="LOCAL-00036" summary="Update `toHtml()` method in `Form.java`&#10;&#10;Simplified the HTML structure for the `toHtml` method by switching from a table layout to paragraph tags. This removes unnecessary table formatting for improved readability and maintainability. Also updated workspace.xml with task tracking and removed outdated comments.">
<option name="closed" value="true" />
<created>1723393478027</created>
<option name="number" value="00036" />
<option name="presentableId" value="LOCAL-00036" />
<option name="project" value="LOCAL" />
<updated>1723393478027</updated>
</task>
<task id="LOCAL-00037" summary="Add IP address tracking for form submissions&#10;&#10;Included IP and timestamp columns in the database schema to track form submissions. Updated methods to handle and store the IP information upon form submission. Adjusted related test cases to validate the new implementation.">
<option name="closed" value="true" />
<created>1723393877624</created>
<option name="number" value="00037" />
<option name="presentableId" value="LOCAL-00037" />
<option name="project" value="LOCAL" />
<updated>1723393877624</updated>
</task>
<option name="localTasksCounter" value="38" />
<servers />
</component>
<component name="TypeScriptGeneratedFilesManager">
@@ -668,11 +709,6 @@
</option>
</component>
<component name="VcsManagerConfiguration">
<MESSAGE value="Configure system property for conditional test execution&#10;&#10;Added a system property 'doNotRunDatabaseTests' in the test configuration to allow conditional skipping of database tests. This helps in running tests selectively during different build scenarios." />
<MESSAGE value="Add CORS support for production server&#10;&#10;Updated the CORS configuration to include the production server URL. This change ensures that requests from the production environment are properly handled." />
<MESSAGE value="Refactor logging for better granularity&#10;&#10;Updated logging levels in multiple classes to differentiate between debug and trace information. Improved log messages to support parameterized logs, ensuring sensitive or variable information is handled appropriately without concatenation." />
<MESSAGE value="Enhance logging for mail verification details&#10;&#10;Updated logging to provide more detailed information about user credentials and email actions. This helps in debugging and monitoring mail verification processes more effectively. Adjusted trace messages to include username and password for better traceability." />
<MESSAGE value="Update URI to point to Discord bot endpoint&#10;&#10;Changed the URI in VerifyController to use the Discord bot's endpoint for form submission. This adjustment is part of the process to route form data correctly through the specified internal service." />
<MESSAGE value="Rename StoreFormQuery package to forms.form&#10;&#10;Updated the package name for consistency and better categorization. Adjusted imports in related test files to reflect the new package structure." />
<MESSAGE value="Refactor HTML generation in ContactFormData&#10;&#10;Extract the HTML generation logic to a reusable method in the Form class. This change reduces code duplication and enhances maintainability by centralizing the table generation functionality." />
<MESSAGE value="Add Staff Application Form handling&#10;&#10;Introduced `StaffAppController` and `StaffAppFormData` to handle staff application form submissions. The controller now stores user data, initiates email verification, and provides appropriate responses based on the verification outcome. Additionally, updated `application.properties` and cleaned up IntelliJ workspace.xml." />
@@ -693,6 +729,15 @@
<MESSAGE value="Refactor form request handling and add rate limiting.&#10;&#10;Consolidate email verification logic into FormRequestHandler to simplify code maintenance. Implement a new rate limiting feature to restrict form submissions based on IP and email address, improving server security and performance." />
<MESSAGE value="Add form activity checking and global rate limiting&#10;&#10;Implemented new features to track form activity and enforce global rate limits. Added a `form_active` table and created endpoints to check form activity. Also, introduced a rate-limiting filter to restrict API requests to 30 per minute per IP." />
<MESSAGE value="Ensure NOT NULL constraints in SQL tables&#10;&#10;Refactor SQL table creation scripts to add NOT NULL constraints where necessary. This change ensures data integrity by preventing null values in critical columns across the 'verify_form', 'form', 'rate_limit', and 'form_active' tables." />
<option name="LAST_COMMIT_MESSAGE" value="Ensure NOT NULL constraints in SQL tables&#10;&#10;Refactor SQL table creation scripts to add NOT NULL constraints where necessary. This change ensures data integrity by preventing null values in critical columns across the 'verify_form', 'form', 'rate_limit', and 'form_active' tables." />
<MESSAGE value="Add JSON response handling for form activity check&#10;&#10;Refactor `FormActiveController` to return JSON responses using `BooleanResponse`. Introduce exception handling for JSON processing errors and update `FormActiveData` to allow object initialization without parameters." />
<MESSAGE value="Add branch condition to Discord notification stage&#10;&#10;The Discord notification stage now runs only on 'main' or 'master' branches. This helps to avoid unnecessary notifications for feature or bugfix branches." />
<MESSAGE value="Improve email handling with Mailable interface&#10;&#10;Added a new Mailable interface for extracting email-related data like receiver and subject. Updated StaffAppFormData and ContactFormData to implement this interface, and refactored MailForm to utilize these details. This enhances flexibility and decouples email details from form classes." />
<MESSAGE value="Update `toHtml()` method in `Form.java`&#10;&#10;Simplified the HTML structure for the `toHtml` method by switching from a table layout to paragraph tags. This removes unnecessary table formatting for improved readability and maintainability. Also updated workspace.xml with task tracking and removed outdated comments." />
<MESSAGE value="Add IP address tracking for form submissions&#10;&#10;Included IP and timestamp columns in the database schema to track form submissions. Updated methods to handle and store the IP information upon form submission. Adjusted related test cases to validate the new implementation." />
<option name="LAST_COMMIT_MESSAGE" value="Add IP address tracking for form submissions&#10;&#10;Included IP and timestamp columns in the database schema to track form submissions. Updated methods to handle and store the IP information upon form submission. Adjusted related test cases to validate the new implementation." />
</component>
<component name="XSLT-Support.FileAssociations.UIState">
<expand />
<select />
</component>
</project>
Vendored
+6
View File
@@ -12,6 +12,12 @@ pipeline {
}
}
stage('discord') {
when {
anyOf {
branch 'main'
branch 'master'
}
}
steps {
discordSend description: "Build: ${BUILD_NUMBER}", showChangeset: true, result: currentBuild.currentResult, title: currentBuild.fullProjectName, webhookURL: env.discordwebhook
}
@@ -16,7 +16,7 @@ public class FormRequestHandler {
private static final Logger logger = LoggerFactory.getLogger(FormRequestHandler.class);
public static CompletableFuture<ResponseEntity<String>> handleRequestWithVerifyMail(Form form, String ip) {
CompletableFuture<Integer> storeFormForVerificationCode = new StoreFormQuery().storeFormForVerificationCode(form.getSender(), form);
CompletableFuture<Integer> storeFormForVerificationCode = new StoreFormQuery().storeFormForVerificationCode(form.getSender(), form, ip);
return storeFormForVerificationCode.thenCompose(code -> Verify.verifyEmail(ip, form.getSender(), code, form).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
@@ -1,6 +1,8 @@
package com.alttd.forms.controlers.apply;
import com.alttd.forms.form.Form;
import com.alttd.forms.mail.mail_forms.Mailable;
import com.fasterxml.jackson.annotation.JsonIgnore;
import jakarta.validation.constraints.*;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.Range;
@@ -8,7 +10,9 @@ import org.hibernate.validator.constraints.Range;
import java.time.LocalDate;
import java.util.Optional;
public class StaffAppFormData extends Form {
public class StaffAppFormData extends Form implements Mailable {
public StaffAppFormData() {}
public StaffAppFormData(String username, String email, String discord, String pc_requirements, int age, String pronoun, LocalDate join_date, int avg_time, String available_days, String available_time, String staff_experience, String plugin_experience, String why_staff, String expectations_mod, String other) {
this.username = username;
@@ -31,63 +35,64 @@ public class StaffAppFormData extends Form {
@NotEmpty(message = "Username is required")
@Length(min = 3, max = 16, message = "Username should be between 3 and 16 characters")
@Pattern(regexp = "^[a-zA-Z0-9_]*$", message = "Username should only include alphanumeric characters and underscore")
public final String username;
public String username;
@NotEmpty(message = "E-mail address is required")
@Email(message = "Invalid email")
@Length(min = 3, max = 254, message = "Email should be between 3 and 254 characters")
public final String email;
public String email;
@NotEmpty(message = "Discord name is required")
@Length(min = 2, max = 32, message = "Discord name should be between 2 and 32 characters")
@Pattern(regexp = "^([a-z0-9._]{2,32})$", message = "Please enter a valid Discord name")
public final String discord;
public String discord;
@NotEmpty(message = "An answer is required")
@Length(min = 2, max = 3, message = "Please answer yes or no")
@Pattern(regexp = "(?i)^(yes|no)$", message = "Yes or no")
public final String pc_requirements;
public String pc_requirements;
@Min(value = 0, message = "Please enter a valid age")
@Max(value = 999, message = "We do not accept players older than 999 years old sorry!")
public final int age;
public int age;
@Length(max = 16, message = "Pronouns can't be longer than 16 characters")
public final String pronoun;
public String pronoun;
@NotNull(message = "Your join date is required, if you're not sure enter an estimated date")
public final LocalDate join_date;
public LocalDate join_date;
@Range(min = 0, max = 168, message = "The only valid values are 0-168")
public final int avg_time;
public int avg_time;
@NotEmpty(message = "Available days are required")
@Length(min = 6, max = 128, message = "Available days should be between 6 and 128 characters")
public final String available_days;
public String available_days;
@NotEmpty(message = "Available time is required")
@Length(min = 3, max = 256, message = "Available time should be between 3 and 256 characters")
public final String available_time;
public String available_time;
@NotEmpty(message = "Staff experience is required")
@Length(min = 2, max = 2000, message = "Experience should be between 2 and 2000 characters")
public final String staff_experience;
public String staff_experience;
@NotEmpty(message = "Plugin experience is required")
@Length(min = 2, max = 2000, message = "Experience should be between 2 and 2000 characters")
public final String plugin_experience;
public String plugin_experience;
@NotEmpty(message = "Reason for wanting to be a moderator is required")
@Length(min = 2, max =2000, message = "Reason should be between 2 and 2000 characters")
public final String why_staff;
public String why_staff;
@NotEmpty(message = "Expectations of a moderator is required")
@Length(min = 2, max = 2000, message = "Expectation should be between 2 and 2000 characters")
public final String expectations_mod;
public String expectations_mod;
@Length(max = 2000, message = "Text can't be longer than 2000 characters")
public final String other;
public String other;
@JsonIgnore
@Override
public String toString() {
return "StaffAppFormData{" +
@@ -109,21 +114,31 @@ public class StaffAppFormData extends Form {
'}';
}
@JsonIgnore
@Override
public Optional<String> getDiscordBotUrl() {
return Optional.empty();
}
@JsonIgnore
@Override
public String getReceiver() {
return "[email protected]";
}
@JsonIgnore
@Override
public String getSubject() {
return "Staff Application: " + username;
}
@JsonIgnore
@Override
public String getSender() {
return email;
}
@JsonIgnore
@Override
public String toHtml() {
String[] fields = {"Username", "Email", "Discord", "PC requirements", "Age", "Pronoun", "Join date", "Avg time", "Available days", "Available time", "Staff experience", "Plugin experience", "Why staff", "Expectations mod", "Other"};
@@ -1,6 +1,8 @@
package com.alttd.forms.controlers.contact;
import com.alttd.forms.form.Form;
import com.alttd.forms.mail.mail_forms.Mailable;
import com.fasterxml.jackson.annotation.JsonIgnore;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.Pattern;
@@ -8,7 +10,9 @@ import org.hibernate.validator.constraints.Length;
import java.util.Optional;
public class ContactFormData extends Form {
public class ContactFormData extends Form implements Mailable {
public ContactFormData() {}
public ContactFormData(String username, String email, String question) {
this.username = username;
@@ -19,16 +23,17 @@ public class ContactFormData extends Form {
@NotEmpty(message = "You have to provide a username")
@Length(min = 3, max = 16, message = "Usernames have to be between 3 and 16 characters")
@Pattern(regexp = "[a-zA-Z-0-9_]{3,16}", message = "Your username has to be a valid Minecraft username")
public final String username;
public String username;
@NotEmpty(message = "You have to provide an e-mail address")
@Email(regexp = "(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21-\\x5a\\x53-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)])",
message = "This is not a valid e-mail address")
public final String email;
public String email;
@Length(min = 11, max = 2000, message = "Your question should have between 10 and 2000 characters")
public final String question;
public String question;
@JsonIgnore
@Override
public String toString() {
return "ContactFormData{" +
@@ -38,21 +43,31 @@ public class ContactFormData extends Form {
'}';
}
@JsonIgnore
@Override
public Optional<String> getDiscordBotUrl() {
return Optional.of("http://discordbot:8001/api/contact/submitContactForm");
}
@JsonIgnore
@Override
public String getReceiver() {
return "[email protected]";
}
@JsonIgnore
@Override
public String getSubject() {
return "Contact form: " + username;
}
@JsonIgnore
@Override
public String getSender() {
return email;
}
@JsonIgnore
@Override
public String toHtml() {
String[] fields = {"Username", "Email", "Question"};
@@ -8,7 +8,7 @@ import java.sql.SQLException;
public class Database {
private static final Logger logger = LoggerFactory.getLogger(Database.class); //TODO can be replaced with library and that one db file that creates the db
private static final Logger logger = LoggerFactory.getLogger(Database.class);
public static void createTables() {
String[] createTables = {
@@ -28,6 +28,8 @@ public class Database {
creation_date BIGINT NOT NULL,
form_json TEXT NOT NULL,
form_class VARCHAR(64) NOT NULL,
ip VARCHAR(45) not null,
time TIMESTAMP default current_timestamp() not null,
PRIMARY KEY(formId)
)
""",
+9 -15
View File
@@ -4,7 +4,9 @@ import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import java.util.Arrays;
import java.util.Optional;
import java.util.stream.Collectors;
public abstract class Form {
@@ -18,25 +20,19 @@ public abstract class Form {
public String toHtml(String[] fields, String[] values) {
StringBuilder htmlOutput = new StringBuilder();
//language=HTML
htmlOutput.append("<table style='border-collapse: collapse; width: 100%;'>");
for (int i = 0; i < fields.length; i++) {
String paragraphs = Arrays.stream(values[i].split("\n"))
.filter(str -> !str.isBlank())
.map(str -> String.format("<p>%s</p>", str))
.collect(Collectors.joining("\n"));
htmlOutput.append(
String.format(
//language=HTML
"""
<tr style='border: 1px solid #ddd;'>
<td style='border: 1px solid #ddd; padding: 10px; font-weight: bold;'>
%s
</td>
<td style='border: 1px solid #ddd; padding: 10px;'>
%s
</td>
</tr>
""", fields[i], values[i]));
<p><strong>%s</strong></p>
<p>%s</p>
""", fields[i], paragraphs));
}
//language=HTML
htmlOutput.append("</table>");
return htmlOutput.toString();
}
@@ -45,7 +41,5 @@ public abstract class Form {
public abstract Optional<String> getDiscordBotUrl();
public abstract String getReceiver();
public abstract String getSender();
}
@@ -21,29 +21,30 @@ public class StoreFormQuery {
return 100000 + random.nextInt(900000);
}
private Optional<Long> insertForm(Connection connection, Form form) {
String insertForm = "INSERT INTO form (creation_date, form_json, form_class) VALUES (?, ?, ?)";
private Optional<Long> insertForm(Connection connection, Form form, String ip) {
String insertForm = "INSERT INTO form (creation_date, form_json, form_class, ip) VALUES (?, ?, ?, ?)";
try (PreparedStatement stmt = connection.prepareStatement(insertForm, Statement.RETURN_GENERATED_KEYS)) {
stmt.setLong(1, Instant.now().toEpochMilli());
stmt.setString(2, form.toJsonString());
stmt.setString(3, form.getClass().getSimpleName());
stmt.setString(4, ip);
int affectedRows = stmt.executeUpdate();
if (affectedRows == 0) {
logger.error("No rows affected during insert of form: " + form);
logger.error("No rows affected during insert of form: {}", form);
return Optional.empty();
}
ResultSet generatedKeys = stmt.getGeneratedKeys();
if (generatedKeys.next()) {
return Optional.of(generatedKeys.getLong(1));
} else {
logger.error("No primary key generated when inserting form " + form);
logger.error("No primary key generated when inserting form {}", form);
return Optional.empty();
}
} catch (SQLException e) {
logger.error("Failed insert form query for: " + form, e);
logger.error("Failed insert form query for: {}", form, e);
return Optional.empty();
} catch (JsonProcessingException e) {
logger.error("Invalid class for JSON, failed insert form query for: " + form, e);
logger.error("Invalid class for JSON, failed insert form query for: {}", form, e);
return Optional.empty();
}
}
@@ -58,17 +59,17 @@ public class StoreFormQuery {
stmt.executeUpdate();
return Optional.of(verificationCode);
} catch (SQLException e) {
logger.error("Failed to insert verification code for form with id: " + formId);
logger.error("Failed to insert verification code for form with id: {}", formId);
return Optional.empty();
}
}
public CompletableFuture<Integer> storeFormForVerificationCode(String eMail, Form form) {
public CompletableFuture<Integer> storeFormForVerificationCode(String eMail, Form form, String ip) {
logger.debug("storeFormForVerificationCode");
Connection connection = DatabaseConnection.getConnection();
logger.trace("Connection: {}", connection);
return CompletableFuture.supplyAsync(() -> {
Optional<Long> optionalFormId = insertForm(connection, form);
Optional<Long> optionalFormId = insertForm(connection, form, ip);
logger.trace("Form id: {}", optionalFormId);
if (optionalFormId.isEmpty()) {
throw new RuntimeException("Failed to store form");
@@ -15,7 +15,8 @@ public class MailForm {
private static final Logger logger = LoggerFactory.getLogger(MailForm.class);
public static void sendForm(String receiver, Form form) {
public static void sendForm(Form form, Mailable mailable) {
String receiver = mailable.getReceiver();
Properties mailProperties = MailSettings.getMailProperties();
Optional<PasswordAuthentication> accountDetails = MailSettings.getAccountDetails();
if (accountDetails.isEmpty()) {
@@ -32,8 +33,7 @@ public class MailForm {
Message.RecipientType.TO,
InternetAddress.parse(receiver)
);
message.setSubject("Altitude Form");
//TODO add something above the html form probably
message.setSubject(mailable.getSubject());
message.setContent(form.toHtml(), "text/html");
try {
Transport.send(message);
@@ -0,0 +1,9 @@
package com.alttd.forms.mail.mail_forms;
public interface Mailable {
String getReceiver();
String getSubject();
}
@@ -1,7 +1,9 @@
package com.alttd.forms.verify_mail;
import com.alttd.forms.controlers.apply.StaffAppFormData;
import com.alttd.forms.form.Form;
import com.alttd.forms.mail.mail_forms.MailForm;
import com.alttd.forms.mail.mail_forms.Mailable;
import com.fasterxml.jackson.core.JsonProcessingException;
import jakarta.validation.Valid;
import org.slf4j.Logger;
@@ -41,7 +43,8 @@ public class VerifyController {
return stringResponseEntity.get();
}
}
MailForm.sendForm(form.getReceiver(), form);
if (form instanceof Mailable mailable)
MailForm.sendForm(form, mailable);
try {
return ResponseEntity.ok(form.toJsonString());
} catch (JsonProcessingException e) {
+1 -1
View File
@@ -23,7 +23,7 @@ public class TestForm {
Assertions.assertDoesNotThrow(() -> DatabaseConnection.initialize());
StoreFormQuery storeFormQuery = new StoreFormQuery();
ContactFormData contactFormData = new ContactFormData("akastijn", "[email protected]", "This is a test question.");
storeFormQuery.storeFormForVerificationCode("[email protected]", contactFormData).
storeFormQuery.storeFormForVerificationCode("[email protected]", contactFormData, "0.0.0.0").
thenAccept(code -> {
TestForm.code = code;
Assertions.assertTrue(code > 999 && code < 10000);