Compare commits
10 Commits
rate_limit
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
595e4eed27 | ||
|
|
a3fcab1c4b | ||
|
|
36c736f8d3 | ||
|
|
3eb4970407 | ||
|
|
ab74360571 | ||
|
|
fcda4c9e53 | ||
|
|
4a0aebce82 | ||
|
|
47f6eebd8b | ||
|
|
1dbb80e5a2 | ||
|
|
ed098513f5 |
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -9,6 +9,7 @@ build/
|
||||||
.idea/jarRepositories.xml
|
.idea/jarRepositories.xml
|
||||||
.idea/compiler.xml
|
.idea/compiler.xml
|
||||||
.idea/libraries/
|
.idea/libraries/
|
||||||
|
.idea/workspace.xml
|
||||||
*.iws
|
*.iws
|
||||||
*.iml
|
*.iml
|
||||||
*.ipr
|
*.ipr
|
||||||
|
|
|
||||||
|
|
@ -1,698 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="AutoImportSettings">
|
|
||||||
<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 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>
|
|
||||||
<option name="SHOW_DIALOG" value="false" />
|
|
||||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
|
||||||
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
|
||||||
<option name="LAST_RESOLUTION" value="IGNORE" />
|
|
||||||
</component>
|
|
||||||
<component name="ExternalProjectsData">
|
|
||||||
<projectState path="$PROJECT_DIR$">
|
|
||||||
<ProjectState />
|
|
||||||
</projectState>
|
|
||||||
</component>
|
|
||||||
<component name="ExternalProjectsManager">
|
|
||||||
<system id="GRADLE">
|
|
||||||
<state>
|
|
||||||
<task path="$PROJECT_DIR$">
|
|
||||||
<activation />
|
|
||||||
</task>
|
|
||||||
<projects_view>
|
|
||||||
<tree_state>
|
|
||||||
<expand>
|
|
||||||
<path>
|
|
||||||
<item name="" type="6a2764b6:ExternalProjectsStructure$RootNode" />
|
|
||||||
<item name="forms" type="f1a62948:ProjectNode" />
|
|
||||||
</path>
|
|
||||||
<path>
|
|
||||||
<item name="" type="6a2764b6:ExternalProjectsStructure$RootNode" />
|
|
||||||
<item name="forms" type="f1a62948:ProjectNode" />
|
|
||||||
<item name="Tasks" type="e4a08cd1:TasksNode" />
|
|
||||||
</path>
|
|
||||||
</expand>
|
|
||||||
<select />
|
|
||||||
</tree_state>
|
|
||||||
</projects_view>
|
|
||||||
</state>
|
|
||||||
</system>
|
|
||||||
</component>
|
|
||||||
<component name="FileTemplateManagerImpl">
|
|
||||||
<option name="RECENT_TEMPLATES">
|
|
||||||
<list>
|
|
||||||
<option value="Jsp File" />
|
|
||||||
<option value="package-info" />
|
|
||||||
<option value="package.json" />
|
|
||||||
<option value="Class" />
|
|
||||||
<option value="Record" />
|
|
||||||
</list>
|
|
||||||
</option>
|
|
||||||
</component>
|
|
||||||
<component name="Git.Settings">
|
|
||||||
<option name="RECENT_BRANCH_BY_REPOSITORY">
|
|
||||||
<map>
|
|
||||||
<entry key="$PROJECT_DIR$" value="master" />
|
|
||||||
</map>
|
|
||||||
</option>
|
|
||||||
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
|
|
||||||
</component>
|
|
||||||
<component name="GitHubPullRequestSearchHistory">{
|
|
||||||
"lastFilter": {
|
|
||||||
"state": "OPEN",
|
|
||||||
"assignee": "Teriuihi"
|
|
||||||
}
|
|
||||||
}</component>
|
|
||||||
<component name="GitToolBoxStore">
|
|
||||||
<option name="projectConfigVersion" value="5" />
|
|
||||||
</component>
|
|
||||||
<component name="GithubPullRequestsUISettings">{
|
|
||||||
"selectedUrlAndAccountId": {
|
|
||||||
"url": "git@github.com:Altitude-Devs/SiteBackend.git",
|
|
||||||
"accountId": "ad9eb076-a98f-40c2-b7e5-9fc28b23038f"
|
|
||||||
}
|
|
||||||
}</component>
|
|
||||||
<component name="KubernetesApiProvider">{
|
|
||||||
"isMigrated": true
|
|
||||||
}</component>
|
|
||||||
<component name="LogFilters">
|
|
||||||
<option name="FILTER_ERRORS" value="false" />
|
|
||||||
<option name="FILTER_WARNINGS" value="false" />
|
|
||||||
<option name="FILTER_INFO" value="true" />
|
|
||||||
<option name="FILTER_DEBUG" value="true" />
|
|
||||||
<option name="CUSTOM_FILTER" />
|
|
||||||
</component>
|
|
||||||
<component name="MarkdownSettingsMigration">
|
|
||||||
<option name="stateVersion" value="1" />
|
|
||||||
</component>
|
|
||||||
<component name="ProblemsViewState">
|
|
||||||
<option name="selectedTabId" value="ProjectErrors" />
|
|
||||||
</component>
|
|
||||||
<component name="ProjectColorInfo">{
|
|
||||||
"associatedIndex": 7
|
|
||||||
}</component>
|
|
||||||
<component name="ProjectId" id="2aJVOGgvEjzOGrKFJ1xKKH5Oshq" />
|
|
||||||
<component name="ProjectLevelVcsManager" settingsEditedManually="true" />
|
|
||||||
<component name="ProjectViewState">
|
|
||||||
<option name="hideEmptyMiddlePackages" value="true" />
|
|
||||||
<option name="showLibraryContents" value="true" />
|
|
||||||
</component>
|
|
||||||
<component name="PropertiesComponent"><![CDATA[{
|
|
||||||
"keyToString": {
|
|
||||||
"Downloaded.Files.Path.Enabled": "false",
|
|
||||||
"Gradle.Build forms.executor": "Run",
|
|
||||||
"Gradle.TestForm.executor": "Run",
|
|
||||||
"Gradle.TestForm.testFunctions.executor": "Debug",
|
|
||||||
"Gradle.TestForm.testRetrieveForm.executor": "Run",
|
|
||||||
"Repository.Attach.Annotations": "false",
|
|
||||||
"Repository.Attach.JavaDocs": "false",
|
|
||||||
"Repository.Attach.Sources": "false",
|
|
||||||
"RequestMappingsPanelOrder0": "0",
|
|
||||||
"RequestMappingsPanelOrder1": "1",
|
|
||||||
"RequestMappingsPanelWidth0": "75",
|
|
||||||
"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",
|
|
||||||
"ignore.virus.scanning.warn.message": "true",
|
|
||||||
"kotlin-language-version-configured": "true",
|
|
||||||
"last_opened_file_path": "P:/Code/Plugins/forms",
|
|
||||||
"node.js.detected.package.eslint": "true",
|
|
||||||
"node.js.detected.package.tslint": "true",
|
|
||||||
"node.js.selected.package.eslint": "(autodetect)",
|
|
||||||
"node.js.selected.package.tslint": "(autodetect)",
|
|
||||||
"nodejs_package_manager_path": "npm",
|
|
||||||
"project.structure.last.edited": "Project",
|
|
||||||
"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",
|
|
||||||
"vue.rearranger.settings.migration": "true"
|
|
||||||
},
|
|
||||||
"keyToStringList": {
|
|
||||||
"DatabaseDriversLRU": [
|
|
||||||
"mysql",
|
|
||||||
"mariadb"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}]]></component>
|
|
||||||
<component name="RecentsManager">
|
|
||||||
<key name="CreateClassDialog.RecentsKey">
|
|
||||||
<recent name="com.alttd.forms.apply" />
|
|
||||||
</key>
|
|
||||||
<key name="CopyClassDialog.RECENTS_KEY">
|
|
||||||
<recent name="com.alttd.forms.controlers.form_active" />
|
|
||||||
<recent name="com.alttd.forms.form" />
|
|
||||||
</key>
|
|
||||||
</component>
|
|
||||||
<component name="RunManager" selected="Spring Boot.Main">
|
|
||||||
<configuration name="TestForm" type="GradleRunConfiguration" factoryName="Gradle" temporary="true">
|
|
||||||
<ExternalSystemSettings>
|
|
||||||
<option name="executionName" />
|
|
||||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
|
||||||
<option name="externalSystemIdString" value="GRADLE" />
|
|
||||||
<option name="scriptParameters" value="" />
|
|
||||||
<option name="taskDescriptions">
|
|
||||||
<list />
|
|
||||||
</option>
|
|
||||||
<option name="taskNames">
|
|
||||||
<list>
|
|
||||||
<option value=":test" />
|
|
||||||
<option value="--tests" />
|
|
||||||
<option value=""TestForm"" />
|
|
||||||
</list>
|
|
||||||
</option>
|
|
||||||
<option name="vmOptions" />
|
|
||||||
</ExternalSystemSettings>
|
|
||||||
<ExternalSystemDebugServerProcess>false</ExternalSystemDebugServerProcess>
|
|
||||||
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
|
||||||
<DebugAllEnabled>false</DebugAllEnabled>
|
|
||||||
<RunAsTest>true</RunAsTest>
|
|
||||||
<method v="2" />
|
|
||||||
</configuration>
|
|
||||||
<configuration name="TestForm.testFunctions" type="GradleRunConfiguration" factoryName="Gradle" temporary="true">
|
|
||||||
<ExternalSystemSettings>
|
|
||||||
<option name="executionName" />
|
|
||||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
|
||||||
<option name="externalSystemIdString" value="GRADLE" />
|
|
||||||
<option name="scriptParameters" value="" />
|
|
||||||
<option name="taskDescriptions">
|
|
||||||
<list />
|
|
||||||
</option>
|
|
||||||
<option name="taskNames">
|
|
||||||
<list>
|
|
||||||
<option value=":test" />
|
|
||||||
<option value="--tests" />
|
|
||||||
<option value=""TestForm.testFunctions"" />
|
|
||||||
</list>
|
|
||||||
</option>
|
|
||||||
<option name="vmOptions" />
|
|
||||||
</ExternalSystemSettings>
|
|
||||||
<ExternalSystemDebugServerProcess>false</ExternalSystemDebugServerProcess>
|
|
||||||
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
|
||||||
<DebugAllEnabled>false</DebugAllEnabled>
|
|
||||||
<RunAsTest>true</RunAsTest>
|
|
||||||
<method v="2" />
|
|
||||||
</configuration>
|
|
||||||
<configuration name="TestForm.testRetrieveForm" type="GradleRunConfiguration" factoryName="Gradle" temporary="true">
|
|
||||||
<ExternalSystemSettings>
|
|
||||||
<option name="executionName" />
|
|
||||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
|
||||||
<option name="externalSystemIdString" value="GRADLE" />
|
|
||||||
<option name="scriptParameters" value="" />
|
|
||||||
<option name="taskDescriptions">
|
|
||||||
<list />
|
|
||||||
</option>
|
|
||||||
<option name="taskNames">
|
|
||||||
<list>
|
|
||||||
<option value=":test" />
|
|
||||||
<option value="--tests" />
|
|
||||||
<option value=""TestForm.testRetrieveForm"" />
|
|
||||||
</list>
|
|
||||||
</option>
|
|
||||||
<option name="vmOptions" />
|
|
||||||
</ExternalSystemSettings>
|
|
||||||
<ExternalSystemDebugServerProcess>false</ExternalSystemDebugServerProcess>
|
|
||||||
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
|
||||||
<DebugAllEnabled>false</DebugAllEnabled>
|
|
||||||
<RunAsTest>true</RunAsTest>
|
|
||||||
<method v="2" />
|
|
||||||
</configuration>
|
|
||||||
<configuration name="Main" type="SpringBootApplicationConfigurationType" factoryName="Spring Boot" nameIsGenerated="true">
|
|
||||||
<option name="ACTIVE_PROFILES" value="dev" />
|
|
||||||
<module name="forms.main" />
|
|
||||||
<option name="SPRING_BOOT_MAIN_CLASS" value="com.alttd.forms.Main" />
|
|
||||||
<method v="2">
|
|
||||||
<option name="Make" enabled="true" />
|
|
||||||
</method>
|
|
||||||
</configuration>
|
|
||||||
<configuration name="Tomcat 10.1.17" type="#com.intellij.j2ee.web.tomcat.TomcatRunConfigurationFactory" factoryName="Local" APPLICATION_SERVER_NAME="Tomcat 10.1.17" ALTERNATIVE_JRE_ENABLED="false">
|
|
||||||
<deployment>
|
|
||||||
<artifact name="Gradle : com.alttd : forms-1.0-SNAPSHOT.war">
|
|
||||||
<settings>
|
|
||||||
<option name="CONTEXT_PATH" value="/Gradle___com_alttd___forms_1_0_SNAPSHOT_war" />
|
|
||||||
</settings>
|
|
||||||
</artifact>
|
|
||||||
</deployment>
|
|
||||||
<server-settings>
|
|
||||||
<option name="BASE_DIRECTORY_NAME" value="f710d80b-33cf-48d5-9d94-7e9dacc0f171" />
|
|
||||||
</server-settings>
|
|
||||||
<predefined_log_file enabled="true" id="Tomcat" />
|
|
||||||
<predefined_log_file enabled="true" id="Tomcat Catalina" />
|
|
||||||
<predefined_log_file id="Tomcat Manager" />
|
|
||||||
<predefined_log_file id="Tomcat Host Manager" />
|
|
||||||
<predefined_log_file id="Tomcat Localhost Access" />
|
|
||||||
<RunnerSettings RunnerId="Debug">
|
|
||||||
<option name="DEBUG_PORT" value="51778" />
|
|
||||||
</RunnerSettings>
|
|
||||||
<ConfigurationWrapper VM_VAR="JAVA_OPTS" RunnerId="Cover">
|
|
||||||
<option name="USE_ENV_VARIABLES" value="true" />
|
|
||||||
<STARTUP>
|
|
||||||
<option name="USE_DEFAULT" value="true" />
|
|
||||||
<option name="SCRIPT" value="" />
|
|
||||||
<option name="VM_PARAMETERS" value="" />
|
|
||||||
<option name="PROGRAM_PARAMETERS" value="" />
|
|
||||||
</STARTUP>
|
|
||||||
<SHUTDOWN>
|
|
||||||
<option name="USE_DEFAULT" value="true" />
|
|
||||||
<option name="SCRIPT" value="" />
|
|
||||||
<option name="VM_PARAMETERS" value="" />
|
|
||||||
<option name="PROGRAM_PARAMETERS" value="" />
|
|
||||||
</SHUTDOWN>
|
|
||||||
</ConfigurationWrapper>
|
|
||||||
<ConfigurationWrapper VM_VAR="JAVA_OPTS" RunnerId="Debug">
|
|
||||||
<option name="USE_ENV_VARIABLES" value="true" />
|
|
||||||
<STARTUP>
|
|
||||||
<option name="USE_DEFAULT" value="true" />
|
|
||||||
<option name="SCRIPT" value="" />
|
|
||||||
<option name="VM_PARAMETERS" value="" />
|
|
||||||
<option name="PROGRAM_PARAMETERS" value="" />
|
|
||||||
</STARTUP>
|
|
||||||
<SHUTDOWN>
|
|
||||||
<option name="USE_DEFAULT" value="true" />
|
|
||||||
<option name="SCRIPT" value="" />
|
|
||||||
<option name="VM_PARAMETERS" value="" />
|
|
||||||
<option name="PROGRAM_PARAMETERS" value="" />
|
|
||||||
</SHUTDOWN>
|
|
||||||
</ConfigurationWrapper>
|
|
||||||
<ConfigurationWrapper VM_VAR="JAVA_OPTS" RunnerId="Profile">
|
|
||||||
<option name="USE_ENV_VARIABLES" value="true" />
|
|
||||||
<STARTUP>
|
|
||||||
<option name="USE_DEFAULT" value="true" />
|
|
||||||
<option name="SCRIPT" value="" />
|
|
||||||
<option name="VM_PARAMETERS" value="" />
|
|
||||||
<option name="PROGRAM_PARAMETERS" value="" />
|
|
||||||
</STARTUP>
|
|
||||||
<SHUTDOWN>
|
|
||||||
<option name="USE_DEFAULT" value="true" />
|
|
||||||
<option name="SCRIPT" value="" />
|
|
||||||
<option name="VM_PARAMETERS" value="" />
|
|
||||||
<option name="PROGRAM_PARAMETERS" value="" />
|
|
||||||
</SHUTDOWN>
|
|
||||||
</ConfigurationWrapper>
|
|
||||||
<ConfigurationWrapper VM_VAR="JAVA_OPTS" RunnerId="Run">
|
|
||||||
<option name="USE_ENV_VARIABLES" value="true" />
|
|
||||||
<STARTUP>
|
|
||||||
<option name="USE_DEFAULT" value="true" />
|
|
||||||
<option name="SCRIPT" value="" />
|
|
||||||
<option name="VM_PARAMETERS" value="" />
|
|
||||||
<option name="PROGRAM_PARAMETERS" value="" />
|
|
||||||
</STARTUP>
|
|
||||||
<SHUTDOWN>
|
|
||||||
<option name="USE_DEFAULT" value="true" />
|
|
||||||
<option name="SCRIPT" value="" />
|
|
||||||
<option name="VM_PARAMETERS" value="" />
|
|
||||||
<option name="PROGRAM_PARAMETERS" value="" />
|
|
||||||
</SHUTDOWN>
|
|
||||||
</ConfigurationWrapper>
|
|
||||||
<method v="2">
|
|
||||||
<option name="Make" enabled="true" />
|
|
||||||
<option name="BuildArtifacts" enabled="true">
|
|
||||||
<artifact name="Gradle : com.alttd : forms-1.0-SNAPSHOT.war" />
|
|
||||||
</option>
|
|
||||||
</method>
|
|
||||||
</configuration>
|
|
||||||
<list>
|
|
||||||
<item itemvalue="Gradle.TestForm" />
|
|
||||||
<item itemvalue="Gradle.TestForm.testFunctions" />
|
|
||||||
<item itemvalue="Gradle.TestForm.testRetrieveForm" />
|
|
||||||
<item itemvalue="Spring Boot.Main" />
|
|
||||||
<item itemvalue="Tomcat Server.Tomcat 10.1.17" />
|
|
||||||
</list>
|
|
||||||
<recent_temporary>
|
|
||||||
<list>
|
|
||||||
<item itemvalue="Gradle.TestForm" />
|
|
||||||
<item itemvalue="Gradle.TestForm.testRetrieveForm" />
|
|
||||||
<item itemvalue="Gradle.TestForm.testFunctions" />
|
|
||||||
</list>
|
|
||||||
</recent_temporary>
|
|
||||||
</component>
|
|
||||||
<component name="SharedIndexes">
|
|
||||||
<attachedChunks>
|
|
||||||
<set>
|
|
||||||
<option value="bundled-jdk-9823dce3aa75-b114ca120d71-intellij.indexing.shared.core-IU-242.20224.300" />
|
|
||||||
<option value="bundled-js-predefined-d6986cc7102b-410509235cf1-JavaScript-IU-242.20224.300" />
|
|
||||||
</set>
|
|
||||||
</attachedChunks>
|
|
||||||
</component>
|
|
||||||
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
|
|
||||||
<component name="TaskManager">
|
|
||||||
<task active="true" id="Default" summary="Default task">
|
|
||||||
<changelist id="ce59df2a-8d56-446a-867b-80e627daf479" name="Changes" comment="" />
|
|
||||||
<created>1704036635730</created>
|
|
||||||
<option name="number" value="Default" />
|
|
||||||
<option name="presentableId" value="Default" />
|
|
||||||
<updated>1704036635730</updated>
|
|
||||||
<workItem from="1704036636799" duration="105000" />
|
|
||||||
<workItem from="1704549979998" duration="2844000" />
|
|
||||||
<workItem from="1704629811001" duration="6145000" />
|
|
||||||
<workItem from="1704639914630" duration="2938000" />
|
|
||||||
<workItem from="1704742191416" duration="685000" />
|
|
||||||
<workItem from="1705152717665" duration="6704000" />
|
|
||||||
<workItem from="1705220399998" duration="6067000" />
|
|
||||||
<workItem from="1705262555334" duration="590000" />
|
|
||||||
<workItem from="1707329373408" duration="2000" />
|
|
||||||
<workItem from="1707329426177" duration="24000" />
|
|
||||||
<workItem from="1707417916223" duration="855000" />
|
|
||||||
<workItem from="1707418804088" duration="1078000" />
|
|
||||||
<workItem from="1707560440225" duration="1006000" />
|
|
||||||
<workItem from="1707643318784" duration="1003000" />
|
|
||||||
<workItem from="1707646300783" duration="1325000" />
|
|
||||||
<workItem from="1707656217023" duration="2305000" />
|
|
||||||
<workItem from="1708153393312" duration="669000" />
|
|
||||||
<workItem from="1708154142819" duration="609000" />
|
|
||||||
<workItem from="1714315469459" duration="9330000" />
|
|
||||||
<workItem from="1714839358412" duration="595000" />
|
|
||||||
<workItem from="1714855192234" duration="585000" />
|
|
||||||
<workItem from="1714898672231" duration="2676000" />
|
|
||||||
<workItem from="1722697616738" duration="2649000" />
|
|
||||||
<workItem from="1722718451005" duration="2120000" />
|
|
||||||
<workItem from="1722786481232" duration="617000" />
|
|
||||||
<workItem from="1722801254695" duration="6135000" />
|
|
||||||
<workItem from="1722879625782" duration="358000" />
|
|
||||||
<workItem from="1722973564053" duration="6695000" />
|
|
||||||
<workItem from="1723057624940" duration="2895000" />
|
|
||||||
<workItem from="1723138548381" duration="1949000" />
|
|
||||||
<workItem from="1723230192640" duration="55000" />
|
|
||||||
<workItem from="1723242314809" duration="9799000" />
|
|
||||||
</task>
|
|
||||||
<task id="LOCAL-00001" summary="Initial commit for site for forms">
|
|
||||||
<option name="closed" value="true" />
|
|
||||||
<created>1705159506039</created>
|
|
||||||
<option name="number" value="00001" />
|
|
||||||
<option name="presentableId" value="LOCAL-00001" />
|
|
||||||
<option name="project" value="LOCAL" />
|
|
||||||
<updated>1705159506039</updated>
|
|
||||||
</task>
|
|
||||||
<task id="LOCAL-00002" summary="Refactor code to use Form objects instead of JSON strings Several parts of the code have been altered to use Form objects instead of JSON strings. Changes include updating the FormQueryResult record type to hold an Optional<Form> instead of an Optional<String>, altering methods in the StoreFormQuery class to insert Form data into the database and replacing JSON handling methods in the FormQuery class with Form object oriented methods. A 'form_class' field has also been added to the 'form' table in the database to aid form identification and reconstruction from stored data.">
|
|
||||||
<option name="closed" value="true" />
|
|
||||||
<created>1705226962796</created>
|
|
||||||
<option name="number" value="00002" />
|
|
||||||
<option name="presentableId" value="LOCAL-00002" />
|
|
||||||
<option name="project" value="LOCAL" />
|
|
||||||
<updated>1705226962796</updated>
|
|
||||||
</task>
|
|
||||||
<task id="LOCAL-00003" summary="Add TestForm class and set up related unit tests The changes add a new TestForm class to implement unit tests for form handling in the application. The included tests verify the storing, retrieving, and verification of forms from a database, as well as form object creation and confirmation of form data. This is a step towards improving the code's reliability and making it easier to catch potential bugs or issues.">
|
|
||||||
<option name="closed" value="true" />
|
|
||||||
<created>1705226977031</created>
|
|
||||||
<option name="number" value="00003" />
|
|
||||||
<option name="presentableId" value="LOCAL-00003" />
|
|
||||||
<option name="project" value="LOCAL" />
|
|
||||||
<updated>1705226977031</updated>
|
|
||||||
</task>
|
|
||||||
<task id="LOCAL-00004" summary="Mark fields as final in VerificationData and ContactFormData The 'code', 'eMail' fields in the VerificationData class and 'username', 'email', 'question' fields in the ContactFormData class are now marked as 'final'. At the same time, some unused imports from ContactController, ContactFormData, FormQuery, and VerifyController have been removed for code cleanliness.">
|
|
||||||
<option name="closed" value="true" />
|
|
||||||
<created>1705227608210</created>
|
|
||||||
<option name="number" value="00004" />
|
|
||||||
<option name="presentableId" value="LOCAL-00004" />
|
|
||||||
<option name="project" value="LOCAL" />
|
|
||||||
<updated>1705227608210</updated>
|
|
||||||
</task>
|
|
||||||
<task id="LOCAL-00005" summary="Update Form HTML output and disable validation auto-configuration The form-to-HTML output process has been switched from a `<div>` approach to using a `StringBuilder` with a table structure in `ContactFormData.java`. Also, the spring validation auto-configuration has been disabled by adding `exclude = ValidationAutoConfiguration.class` in the `@SpringBootApplication` annotation of `Main.java`. Some changes in `.idea/workspace.xml` and `VerifyController.java` were made as well.">
|
|
||||||
<option name="closed" value="true" />
|
|
||||||
<created>1714319923708</created>
|
|
||||||
<option name="number" value="00005" />
|
|
||||||
<option name="presentableId" value="LOCAL-00005" />
|
|
||||||
<option name="project" value="LOCAL" />
|
|
||||||
<updated>1714319923708</updated>
|
|
||||||
</task>
|
|
||||||
<task id="LOCAL-00006" summary="Add database configuration via command-line arguments A new configuration setup now allows specifying a path for database properties via command-line arguments during application startup. This update also changes the call signature for `DatabaseConnection.initialize()` method to accept a path argument. Similarly, methods in `PropertiesLoader`, `PropertiesWriter`, and `MailSettings` classes were also updated to use the specified path when working with properties files. The `TestForm` class's tests were updated accordingly to handle these changes.">
|
|
||||||
<option name="closed" value="true" />
|
|
||||||
<created>1714332311321</created>
|
|
||||||
<option name="number" value="00006" />
|
|
||||||
<option name="presentableId" value="LOCAL-00006" />
|
|
||||||
<option name="project" value="LOCAL" />
|
|
||||||
<updated>1714332311321</updated>
|
|
||||||
</task>
|
|
||||||
<task id="LOCAL-00007" summary="Add DB config via command-line arguments A new setup allows specifying database properties path using command-line arguments during startup. The `DatabaseConnection.initialize()` method signature has been updated to accept a path argument. Methods in `PropertiesLoader`, `PropertiesWriter`, and `MailSettings` classes, along with tests in the `TestForm` class, were adjusted accordingly.">
|
|
||||||
<option name="closed" value="true" />
|
|
||||||
<created>1722804244115</created>
|
|
||||||
<option name="number" value="00007" />
|
|
||||||
<option name="presentableId" value="LOCAL-00007" />
|
|
||||||
<option name="project" value="LOCAL" />
|
|
||||||
<updated>1722804244115</updated>
|
|
||||||
</task>
|
|
||||||
<task id="LOCAL-00008" summary="Add Jenkins pipeline for Gradle build and notifications This commit introduces a new Jenkinsfile configured to build the project using Gradle and archive the resulting artifacts. Additionally, it includes a stage to send build notifications to Discord with details about the build status.">
|
|
||||||
<option name="closed" value="true" />
|
|
||||||
<created>1722804255328</created>
|
|
||||||
<option name="number" value="00008" />
|
|
||||||
<option name="presentableId" value="LOCAL-00008" />
|
|
||||||
<option name="project" value="LOCAL" />
|
|
||||||
<updated>1722804255328</updated>
|
|
||||||
</task>
|
|
||||||
<task id="LOCAL-00009" summary="Disable database tests in Jenkins Disabled tests that require a database connection to prevent failures in Jenkins where there isn't a database. Updated Jenkinsfile to include a property that skips these tests during the build process.">
|
|
||||||
<option name="closed" value="true" />
|
|
||||||
<created>1722804722354</created>
|
|
||||||
<option name="number" value="00009" />
|
|
||||||
<option name="presentableId" value="LOCAL-00009" />
|
|
||||||
<option name="project" value="LOCAL" />
|
|
||||||
<updated>1722804722354</updated>
|
|
||||||
</task>
|
|
||||||
<task id="LOCAL-00010" summary="Fix typo in Gradle build command in Jenkinsfile Corrected the parameter for skipping database tests from `dontRunDatabaseTests` to `doNotRunDatabaseTests` in the Gradle build step. This ensures the intended tests are skipped during the build process.">
|
|
||||||
<option name="closed" value="true" />
|
|
||||||
<created>1722804816532</created>
|
|
||||||
<option name="number" value="00010" />
|
|
||||||
<option name="presentableId" value="LOCAL-00010" />
|
|
||||||
<option name="project" value="LOCAL" />
|
|
||||||
<updated>1722804816532</updated>
|
|
||||||
</task>
|
|
||||||
<task id="LOCAL-00011" summary="Configure system property for conditional test execution 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.">
|
|
||||||
<option name="closed" value="true" />
|
|
||||||
<created>1722804890007</created>
|
|
||||||
<option name="number" value="00011" />
|
|
||||||
<option name="presentableId" value="LOCAL-00011" />
|
|
||||||
<option name="project" value="LOCAL" />
|
|
||||||
<updated>1722804890007</updated>
|
|
||||||
</task>
|
|
||||||
<task id="LOCAL-00012" summary="Add CORS support for production server Updated the CORS configuration to include the production server URL. This change ensures that requests from the production environment are properly handled.">
|
|
||||||
<option name="closed" value="true" />
|
|
||||||
<created>1722810187257</created>
|
|
||||||
<option name="number" value="00012" />
|
|
||||||
<option name="presentableId" value="LOCAL-00012" />
|
|
||||||
<option name="project" value="LOCAL" />
|
|
||||||
<updated>1722810187257</updated>
|
|
||||||
</task>
|
|
||||||
<task id="LOCAL-00013" summary="Refactor logging for better granularity 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.">
|
|
||||||
<option name="closed" value="true" />
|
|
||||||
<created>1722811549943</created>
|
|
||||||
<option name="number" value="00013" />
|
|
||||||
<option name="presentableId" value="LOCAL-00013" />
|
|
||||||
<option name="project" value="LOCAL" />
|
|
||||||
<updated>1722811549943</updated>
|
|
||||||
</task>
|
|
||||||
<task id="LOCAL-00014" summary="Enhance logging for mail verification details 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.">
|
|
||||||
<option name="closed" value="true" />
|
|
||||||
<created>1722812594171</created>
|
|
||||||
<option name="number" value="00014" />
|
|
||||||
<option name="presentableId" value="LOCAL-00014" />
|
|
||||||
<option name="project" value="LOCAL" />
|
|
||||||
<updated>1722812594171</updated>
|
|
||||||
</task>
|
|
||||||
<task id="LOCAL-00015" summary="Update URI to point to Discord bot endpoint 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.">
|
|
||||||
<option name="closed" value="true" />
|
|
||||||
<created>1722812932077</created>
|
|
||||||
<option name="number" value="00015" />
|
|
||||||
<option name="presentableId" value="LOCAL-00015" />
|
|
||||||
<option name="project" value="LOCAL" />
|
|
||||||
<updated>1722812932077</updated>
|
|
||||||
</task>
|
|
||||||
<task id="LOCAL-00016" summary="Rename StoreFormQuery package to forms.form Updated the package name for consistency and better categorization. Adjusted imports in related test files to reflect the new package structure.">
|
|
||||||
<option name="closed" value="true" />
|
|
||||||
<created>1722975667414</created>
|
|
||||||
<option name="number" value="00016" />
|
|
||||||
<option name="presentableId" value="LOCAL-00016" />
|
|
||||||
<option name="project" value="LOCAL" />
|
|
||||||
<updated>1722975667414</updated>
|
|
||||||
</task>
|
|
||||||
<task id="LOCAL-00017" summary="Refactor HTML generation in ContactFormData 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.">
|
|
||||||
<option name="closed" value="true" />
|
|
||||||
<created>1722975690755</created>
|
|
||||||
<option name="number" value="00017" />
|
|
||||||
<option name="presentableId" value="LOCAL-00017" />
|
|
||||||
<option name="project" value="LOCAL" />
|
|
||||||
<updated>1722975690755</updated>
|
|
||||||
</task>
|
|
||||||
<task id="LOCAL-00018" summary="Add Staff Application Form handling 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.">
|
|
||||||
<option name="closed" value="true" />
|
|
||||||
<created>1722975703502</created>
|
|
||||||
<option name="number" value="00018" />
|
|
||||||
<option name="presentableId" value="LOCAL-00018" />
|
|
||||||
<option name="project" value="LOCAL" />
|
|
||||||
<updated>1722975703502</updated>
|
|
||||||
</task>
|
|
||||||
<task id="LOCAL-00019" summary="Add REST annotations to StaffAppController Introduce `@RestController` and `@RequestMapping` annotations to the `StaffAppController` class. This change standardizes the API endpoint and ensures all methods within this class are mapped correctly under `/api/apply`.">
|
|
||||||
<option name="closed" value="true" />
|
|
||||||
<created>1722975785066</created>
|
|
||||||
<option name="number" value="00019" />
|
|
||||||
<option name="presentableId" value="LOCAL-00019" />
|
|
||||||
<option name="project" value="LOCAL" />
|
|
||||||
<updated>1722975785066</updated>
|
|
||||||
</task>
|
|
||||||
<task id="LOCAL-00020" summary="Update CORS allowed origins configuration Consolidated the allowed origins into a single `allowedOrigins` call. This ensures both local and production environments are correctly configured for CORS.">
|
|
||||||
<option name="closed" value="true" />
|
|
||||||
<created>1722978999091</created>
|
|
||||||
<option name="number" value="00020" />
|
|
||||||
<option name="presentableId" value="LOCAL-00020" />
|
|
||||||
<option name="project" value="LOCAL" />
|
|
||||||
<updated>1722978999091</updated>
|
|
||||||
</task>
|
|
||||||
<task id="LOCAL-00021" summary="Add REST annotations and refactor properties file handling Introduced `@RestController` and `@RequestMapping` in `StaffAppController` for standardized API endpoints. Refactored properties file handling in `PropertiesLoader` and `PropertiesWriter` to simplify file creation logic.">
|
|
||||||
<option name="closed" value="true" />
|
|
||||||
<created>1722979026190</created>
|
|
||||||
<option name="number" value="00021" />
|
|
||||||
<option name="presentableId" value="LOCAL-00021" />
|
|
||||||
<option name="project" value="LOCAL" />
|
|
||||||
<updated>1722979026190</updated>
|
|
||||||
</task>
|
|
||||||
<task id="LOCAL-00022" summary="Update Jackson config and refactor JSON handling Introduced Jackson dependencies to replace Gson for JSON processing. Updated application properties and controllers to handle Jackson-specific exceptions. Refactored form serialization to use Jackson's `ObjectMapper` for better date handling and consistency.">
|
|
||||||
<option name="closed" value="true" />
|
|
||||||
<created>1722981496092</created>
|
|
||||||
<option name="number" value="00022" />
|
|
||||||
<option name="presentableId" value="LOCAL-00022" />
|
|
||||||
<option name="project" value="LOCAL" />
|
|
||||||
<updated>1722981496092</updated>
|
|
||||||
</task>
|
|
||||||
<task id="LOCAL-00023" summary="Add getDiscordBotUrl method to form classes Implemented getDiscordBotUrl in form classes for dynamic URL handling. Updated VerifyController to use this method for constructing Discord bot URIs. This enhances flexibility and maintainability in form submission handling.">
|
|
||||||
<option name="closed" value="true" />
|
|
||||||
<created>1722981675331</created>
|
|
||||||
<option name="number" value="00023" />
|
|
||||||
<option name="presentableId" value="LOCAL-00023" />
|
|
||||||
<option name="project" value="LOCAL" />
|
|
||||||
<updated>1722981675331</updated>
|
|
||||||
</task>
|
|
||||||
<task id="LOCAL-00024" summary="Refactor form submission to use dynamic Discord URLs and emails Updated form classes to return Optional URLs for Discord bot submissions. Refactored VerifyController to handle these Optionals and improved error handling when sending forms. Added receiver email method in form classes for more flexible form submissions.">
|
|
||||||
<option name="closed" value="true" />
|
|
||||||
<created>1722983786557</created>
|
|
||||||
<option name="number" value="00024" />
|
|
||||||
<option name="presentableId" value="LOCAL-00024" />
|
|
||||||
<option name="project" value="LOCAL" />
|
|
||||||
<updated>1722983786557</updated>
|
|
||||||
</task>
|
|
||||||
<task id="LOCAL-00025" summary="Refactor packages and add exception handler. Renamed various classes to follow the "controlers" package structure for better organization and consistency. Added `ControllerExceptionHandler` to manage validation exceptions globally and improve error logging.">
|
|
||||||
<option name="closed" value="true" />
|
|
||||||
<created>1723059243750</created>
|
|
||||||
<option name="number" value="00025" />
|
|
||||||
<option name="presentableId" value="LOCAL-00025" />
|
|
||||||
<option name="project" value="LOCAL" />
|
|
||||||
<updated>1723059243750</updated>
|
|
||||||
</task>
|
|
||||||
<task id="LOCAL-00026" summary="Correct regex pattern for case-insensitive match Updated the regex pattern in `StaffAppFormData.java` to ensure that the "yes" or "no" answers are case-insensitive. This improves the form validation to accept "Yes", "YES", "No", or "NO" without errors.">
|
|
||||||
<option name="closed" value="true" />
|
|
||||||
<created>1723059265558</created>
|
|
||||||
<option name="number" value="00026" />
|
|
||||||
<option name="presentableId" value="LOCAL-00026" />
|
|
||||||
<option name="project" value="LOCAL" />
|
|
||||||
<updated>1723059265558</updated>
|
|
||||||
</task>
|
|
||||||
<task id="LOCAL-00027" summary="Remove restriction on dot character in Discord name validation This change allows Discord names to include dots anywhere within the name, increasing flexibility for valid usernames. The previous regex pattern incorrectly restricted dots, affecting valid user entries.">
|
|
||||||
<option name="closed" value="true" />
|
|
||||||
<created>1723242929470</created>
|
|
||||||
<option name="number" value="00027" />
|
|
||||||
<option name="presentableId" value="LOCAL-00027" />
|
|
||||||
<option name="project" value="LOCAL" />
|
|
||||||
<updated>1723242929470</updated>
|
|
||||||
</task>
|
|
||||||
<task id="LOCAL-00028" summary="Add StaffAppFormData handling in FormQuery Imported StaffAppFormData and updated deserialization logic to include it as a case in the FormQuery class. This allows the processing of staff application forms when parsing form data from JSON.">
|
|
||||||
<option name="closed" value="true" />
|
|
||||||
<created>1723242942749</created>
|
|
||||||
<option name="number" value="00028" />
|
|
||||||
<option name="presentableId" value="LOCAL-00028" />
|
|
||||||
<option name="project" value="LOCAL" />
|
|
||||||
<updated>1723242942749</updated>
|
|
||||||
</task>
|
|
||||||
<task id="LOCAL-00029" summary="workspace.xml update">
|
|
||||||
<option name="closed" value="true" />
|
|
||||||
<created>1723242960642</created>
|
|
||||||
<option name="number" value="00029" />
|
|
||||||
<option name="presentableId" value="LOCAL-00029" />
|
|
||||||
<option name="project" value="LOCAL" />
|
|
||||||
<updated>1723242960642</updated>
|
|
||||||
</task>
|
|
||||||
<task id="LOCAL-00030" summary="Add rate limiting functionality Introduces a new 'rate_limit' table to track request counts by IP and email. Adds `RateLimitQuery` class for querying and inserting rate limits, and `RateLimitEntryDTO` for passing rate limit data.">
|
|
||||||
<option name="closed" value="true" />
|
|
||||||
<created>1723243853994</created>
|
|
||||||
<option name="number" value="00030" />
|
|
||||||
<option name="presentableId" value="LOCAL-00030" />
|
|
||||||
<option name="project" value="LOCAL" />
|
|
||||||
<updated>1723243853994</updated>
|
|
||||||
</task>
|
|
||||||
<task id="LOCAL-00031" summary="Refactor form request handling and add rate limiting. 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.">
|
|
||||||
<option name="closed" value="true" />
|
|
||||||
<created>1723247556185</created>
|
|
||||||
<option name="number" value="00031" />
|
|
||||||
<option name="presentableId" value="LOCAL-00031" />
|
|
||||||
<option name="project" value="LOCAL" />
|
|
||||||
<updated>1723247556185</updated>
|
|
||||||
</task>
|
|
||||||
<task id="LOCAL-00032" summary="Add form activity checking and global rate limiting 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.">
|
|
||||||
<option name="closed" value="true" />
|
|
||||||
<created>1723249700073</created>
|
|
||||||
<option name="number" value="00032" />
|
|
||||||
<option name="presentableId" value="LOCAL-00032" />
|
|
||||||
<option name="project" value="LOCAL" />
|
|
||||||
<updated>1723249700073</updated>
|
|
||||||
</task>
|
|
||||||
<task id="LOCAL-00033" summary="Ensure NOT NULL constraints in SQL tables 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="closed" value="true" />
|
|
||||||
<created>1723249968746</created>
|
|
||||||
<option name="number" value="00033" />
|
|
||||||
<option name="presentableId" value="LOCAL-00033" />
|
|
||||||
<option name="project" value="LOCAL" />
|
|
||||||
<updated>1723249968746</updated>
|
|
||||||
</task>
|
|
||||||
<option name="localTasksCounter" value="34" />
|
|
||||||
<servers />
|
|
||||||
</component>
|
|
||||||
<component name="TypeScriptGeneratedFilesManager">
|
|
||||||
<option name="version" value="3" />
|
|
||||||
</component>
|
|
||||||
<component name="Vcs.Log.Tabs.Properties">
|
|
||||||
<option name="TAB_STATES">
|
|
||||||
<map>
|
|
||||||
<entry key="MAIN">
|
|
||||||
<value>
|
|
||||||
<State />
|
|
||||||
</value>
|
|
||||||
</entry>
|
|
||||||
</map>
|
|
||||||
</option>
|
|
||||||
</component>
|
|
||||||
<component name="VcsManagerConfiguration">
|
|
||||||
<MESSAGE value="Configure system property for conditional test execution 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 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 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 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 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 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 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 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." />
|
|
||||||
<MESSAGE value="Add REST annotations to StaffAppController Introduce `@RestController` and `@RequestMapping` annotations to the `StaffAppController` class. This change standardizes the API endpoint and ensures all methods within this class are mapped correctly under `/api/apply`." />
|
|
||||||
<MESSAGE value="Update CORS allowed origins configuration Consolidated the allowed origins into a single `allowedOrigins` call. This ensures both local and production environments are correctly configured for CORS." />
|
|
||||||
<MESSAGE value="Add REST annotations and refactor properties file handling Introduced `@RestController` and `@RequestMapping` in `StaffAppController` for standardized API endpoints. Refactored properties file handling in `PropertiesLoader` and `PropertiesWriter` to simplify file creation logic." />
|
|
||||||
<MESSAGE value="Update Jackson config and refactor JSON handling Introduced Jackson dependencies to replace Gson for JSON processing. Updated application properties and controllers to handle Jackson-specific exceptions. Refactored form serialization to use Jackson's `ObjectMapper` for better date handling and consistency." />
|
|
||||||
<MESSAGE value="Add getDiscordBotUrl method to form classes Implemented getDiscordBotUrl in form classes for dynamic URL handling. Updated VerifyController to use this method for constructing Discord bot URIs. This enhances flexibility and maintainability in form submission handling." />
|
|
||||||
<MESSAGE value="Refactor form submission to use dynamic Discord URLs and emails Updated form classes to return Optional URLs for Discord bot submissions. Refactored VerifyController to handle these Optionals and improved error handling when sending forms. Added receiver email method in form classes for more flexible form submissions." />
|
|
||||||
<MESSAGE value="Add validation exception handling to StaffAppController Introduced an `ExceptionHandler` for `MethodArgumentNotValidException` in `StaffAppController` to return detailed validation error messages. Updated the regex pattern in `StaffAppFormData` to be case-insensitive. This enhances error reporting and user input validation in the application." />
|
|
||||||
<MESSAGE value="Refactor packages and add exception handler. Renamed various classes to follow the "controlers" package structure for better organization and consistency. Added `ControllerExceptionHandler` to manage validation exceptions globally and improve error logging." />
|
|
||||||
<MESSAGE value="Correct regex pattern for case-insensitive match Updated the regex pattern in `StaffAppFormData.java` to ensure that the "yes" or "no" answers are case-insensitive. This improves the form validation to accept "Yes", "YES", "No", or "NO" without errors." />
|
|
||||||
<MESSAGE value="Remove restriction on dot character in Discord name validation This change allows Discord names to include dots anywhere within the name, increasing flexibility for valid usernames. The previous regex pattern incorrectly restricted dots, affecting valid user entries." />
|
|
||||||
<MESSAGE value="Add StaffAppFormData handling in FormQuery Imported StaffAppFormData and updated deserialization logic to include it as a case in the FormQuery class. This allows the processing of staff application forms when parsing form data from JSON." />
|
|
||||||
<MESSAGE value="workspace.xml update" />
|
|
||||||
<MESSAGE value="Add rate limiting functionality Introduces a new 'rate_limit' table to track request counts by IP and email. Adds `RateLimitQuery` class for querying and inserting rate limits, and `RateLimitEntryDTO` for passing rate limit data." />
|
|
||||||
<MESSAGE value="Add IP rate limiting for form submissions Added IP rate limiting to prevent abuse in form submissions by tracking IP and email address attempts. Updated the form submission methods to include IP in email verification and added detailed HTML email content." />
|
|
||||||
<MESSAGE value="Refactor form request handling and add rate limiting. 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 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 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 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." />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
6
Jenkinsfile
vendored
6
Jenkinsfile
vendored
|
|
@ -12,6 +12,12 @@ pipeline {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
stage('discord') {
|
stage('discord') {
|
||||||
|
when {
|
||||||
|
anyOf {
|
||||||
|
branch 'main'
|
||||||
|
branch 'master'
|
||||||
|
}
|
||||||
|
}
|
||||||
steps {
|
steps {
|
||||||
discordSend description: "Build: ${BUILD_NUMBER}", showChangeset: true, result: currentBuild.currentResult, title: currentBuild.fullProjectName, webhookURL: env.discordwebhook
|
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);
|
private static final Logger logger = LoggerFactory.getLogger(FormRequestHandler.class);
|
||||||
|
|
||||||
public static CompletableFuture<ResponseEntity<String>> handleRequestWithVerifyMail(Form form, String ip) {
|
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 -> {
|
return storeFormForVerificationCode.thenCompose(code -> Verify.verifyEmail(ip, form.getSender(), code, form).thenApply(verificationResult -> {
|
||||||
if (verificationResult == VerificationResult.VERIFICATION_SENT) {
|
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
|
//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;
|
package com.alttd.forms.controlers.apply;
|
||||||
|
|
||||||
import com.alttd.forms.form.Form;
|
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 jakarta.validation.constraints.*;
|
||||||
import org.hibernate.validator.constraints.Length;
|
import org.hibernate.validator.constraints.Length;
|
||||||
import org.hibernate.validator.constraints.Range;
|
import org.hibernate.validator.constraints.Range;
|
||||||
|
|
@ -8,7 +10,9 @@ import org.hibernate.validator.constraints.Range;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.util.Optional;
|
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) {
|
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;
|
this.username = username;
|
||||||
|
|
@ -31,63 +35,64 @@ public class StaffAppFormData extends Form {
|
||||||
@NotEmpty(message = "Username is required")
|
@NotEmpty(message = "Username is required")
|
||||||
@Length(min = 3, max = 16, message = "Username should be between 3 and 16 characters")
|
@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")
|
@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")
|
@NotEmpty(message = "E-mail address is required")
|
||||||
@Email(message = "Invalid email")
|
@Email(message = "Invalid email")
|
||||||
@Length(min = 3, max = 254, message = "Email should be between 3 and 254 characters")
|
@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")
|
@NotEmpty(message = "Discord name is required")
|
||||||
@Length(min = 2, max = 32, message = "Discord name should be between 2 and 32 characters")
|
@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")
|
@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")
|
@NotEmpty(message = "An answer is required")
|
||||||
@Length(min = 2, max = 3, message = "Please answer yes or no")
|
@Length(min = 2, max = 3, message = "Please answer yes or no")
|
||||||
@Pattern(regexp = "(?i)^(yes|no)$", message = "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")
|
@Min(value = 0, message = "Please enter a valid age")
|
||||||
@Max(value = 999, message = "We do not accept players older than 999 years old sorry!")
|
@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")
|
@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")
|
@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")
|
@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")
|
@NotEmpty(message = "Available days are required")
|
||||||
@Length(min = 6, max = 128, message = "Available days should be between 6 and 128 characters")
|
@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")
|
@NotEmpty(message = "Available time is required")
|
||||||
@Length(min = 3, max = 256, message = "Available time should be between 3 and 256 characters")
|
@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")
|
@NotEmpty(message = "Staff experience is required")
|
||||||
@Length(min = 2, max = 2000, message = "Experience should be between 2 and 2000 characters")
|
@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")
|
@NotEmpty(message = "Plugin experience is required")
|
||||||
@Length(min = 2, max = 2000, message = "Experience should be between 2 and 2000 characters")
|
@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")
|
@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")
|
@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")
|
@NotEmpty(message = "Expectations of a moderator is required")
|
||||||
@Length(min = 2, max = 2000, message = "Expectation should be between 2 and 2000 characters")
|
@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")
|
@Length(max = 2000, message = "Text can't be longer than 2000 characters")
|
||||||
public final String other;
|
public String other;
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "StaffAppFormData{" +
|
return "StaffAppFormData{" +
|
||||||
|
|
@ -109,21 +114,31 @@ public class StaffAppFormData extends Form {
|
||||||
'}';
|
'}';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
@Override
|
@Override
|
||||||
public Optional<String> getDiscordBotUrl() {
|
public Optional<String> getDiscordBotUrl() {
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
@Override
|
@Override
|
||||||
public String getReceiver() {
|
public String getReceiver() {
|
||||||
return "apply@alttd.com";
|
return "apply@alttd.com";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
@Override
|
||||||
|
public String getSubject() {
|
||||||
|
return "Staff Application: " + username;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
@Override
|
@Override
|
||||||
public String getSender() {
|
public String getSender() {
|
||||||
return email;
|
return email;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
@Override
|
@Override
|
||||||
public String toHtml() {
|
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"};
|
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;
|
package com.alttd.forms.controlers.contact;
|
||||||
|
|
||||||
import com.alttd.forms.form.Form;
|
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.Email;
|
||||||
import jakarta.validation.constraints.NotEmpty;
|
import jakarta.validation.constraints.NotEmpty;
|
||||||
import jakarta.validation.constraints.Pattern;
|
import jakarta.validation.constraints.Pattern;
|
||||||
|
|
@ -8,7 +10,9 @@ import org.hibernate.validator.constraints.Length;
|
||||||
|
|
||||||
import java.util.Optional;
|
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) {
|
public ContactFormData(String username, String email, String question) {
|
||||||
this.username = username;
|
this.username = username;
|
||||||
|
|
@ -19,16 +23,17 @@ public class ContactFormData extends Form {
|
||||||
@NotEmpty(message = "You have to provide a username")
|
@NotEmpty(message = "You have to provide a username")
|
||||||
@Length(min = 3, max = 16, message = "Usernames have to be between 3 and 16 characters")
|
@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")
|
@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")
|
@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])+)])",
|
@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")
|
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")
|
@Length(min = 11, max = 2000, message = "Your question should have between 10 and 2000 characters")
|
||||||
public final String question;
|
public String question;
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "ContactFormData{" +
|
return "ContactFormData{" +
|
||||||
|
|
@ -38,21 +43,31 @@ public class ContactFormData extends Form {
|
||||||
'}';
|
'}';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
@Override
|
@Override
|
||||||
public Optional<String> getDiscordBotUrl() {
|
public Optional<String> getDiscordBotUrl() {
|
||||||
return Optional.of("http://discordbot:8001/api/contact/submitContactForm");
|
return Optional.of("http://discordbot:8001/api/contact/submitContactForm");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
@Override
|
@Override
|
||||||
public String getReceiver() {
|
public String getReceiver() {
|
||||||
return "support@alttd.com";
|
return "support@alttd.com";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
@Override
|
||||||
|
public String getSubject() {
|
||||||
|
return "Contact form: " + username;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
@Override
|
@Override
|
||||||
public String getSender() {
|
public String getSender() {
|
||||||
return email;
|
return email;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
@Override
|
@Override
|
||||||
public String toHtml() {
|
public String toHtml() {
|
||||||
String[] fields = {"Username", "Email", "Question"};
|
String[] fields = {"Username", "Email", "Question"};
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
package com.alttd.forms.controlers.event_apply;
|
||||||
|
|
||||||
|
import com.alttd.forms.controlers.FormRequestHandler;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import jakarta.validation.Valid;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/event-apply")
|
||||||
|
public class EventAppController {
|
||||||
|
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(EventAppController.class);
|
||||||
|
|
||||||
|
@PostMapping("/eventApplication")
|
||||||
|
public CompletableFuture<ResponseEntity<String>> submitForm(@Valid @RequestBody EventAppFormData formData, HttpServletRequest request) {
|
||||||
|
logger.debug("submitForm");
|
||||||
|
logger.trace(formData.toString());
|
||||||
|
|
||||||
|
return FormRequestHandler.handleRequestWithVerifyMail(formData, request.getRemoteAddr());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,131 @@
|
||||||
|
package com.alttd.forms.controlers.event_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;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public class EventAppFormData extends Form implements Mailable {
|
||||||
|
|
||||||
|
public EventAppFormData() {}
|
||||||
|
|
||||||
|
public EventAppFormData(String username, String email, String discord, int age, String pronoun, int avg_time, String event_experience, String discord_vc, String good_builds, String bad_builds, String technical_aspects, String other) {
|
||||||
|
this.username = username;
|
||||||
|
this.email = email;
|
||||||
|
this.discord = discord;
|
||||||
|
this.age = age;
|
||||||
|
this.pronoun = pronoun;
|
||||||
|
this.avg_time = avg_time;
|
||||||
|
this.event_experience = event_experience;
|
||||||
|
this.discord_vc = discord_vc;
|
||||||
|
this.good_builds = good_builds;
|
||||||
|
this.bad_builds = bad_builds;
|
||||||
|
this.technical_aspects = technical_aspects;
|
||||||
|
this.other = other;
|
||||||
|
}
|
||||||
|
|
||||||
|
@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 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 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 String discord;
|
||||||
|
|
||||||
|
@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 int age;
|
||||||
|
|
||||||
|
@Length(max = 16, message = "Pronouns can't be longer than 16 characters")
|
||||||
|
public String pronoun;
|
||||||
|
|
||||||
|
@Range(min = 0, max = 168, message = "The only valid values are 0-168")
|
||||||
|
public int avg_time;
|
||||||
|
|
||||||
|
@NotEmpty(message = "Event experience is required")
|
||||||
|
@Length(min = 2, max = 2000, message = "Experience should be between 2 and 2000 characters")
|
||||||
|
public String event_experience;
|
||||||
|
|
||||||
|
@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 String discord_vc;
|
||||||
|
|
||||||
|
@NotEmpty(message = "Good build experience is required")
|
||||||
|
@Length(min = 2, max = 2000, message = "Good build experience should be between 2 and 2000 characters")
|
||||||
|
public String good_builds;
|
||||||
|
|
||||||
|
@NotEmpty(message = "Event experience is required")
|
||||||
|
@Length(min = 2, max = 2000, message = "Bad build experience between 2 and 2000 characters")
|
||||||
|
public String bad_builds;
|
||||||
|
|
||||||
|
@NotEmpty(message = "Technical aspects are required")
|
||||||
|
@Length(min = 2, max = 2000, message = "Technical aspects should be between 2 and 2000 characters")
|
||||||
|
public String technical_aspects;
|
||||||
|
|
||||||
|
@Length(max = 2000, message = "Text can't be longer than 2000 characters")
|
||||||
|
public String other;
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "EventAppFormData{" +
|
||||||
|
"username='" + username + '\'' +
|
||||||
|
", email='" + email + '\'' +
|
||||||
|
", discord='" + discord + '\'' +
|
||||||
|
", age=" + age +
|
||||||
|
", pronoun='" + pronoun + '\'' +
|
||||||
|
", avg_time=" + avg_time +
|
||||||
|
", event_experience='" + event_experience + '\'' +
|
||||||
|
", discord_vc='" + discord_vc + '\'' +
|
||||||
|
", good_builds='" + good_builds + '\'' +
|
||||||
|
", bad_builds='" + bad_builds + '\'' +
|
||||||
|
", technical_aspects='" + technical_aspects + '\'' +
|
||||||
|
", other='" + other + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
@Override
|
||||||
|
public Optional<String> getDiscordBotUrl() {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
@Override
|
||||||
|
public String getReceiver() {
|
||||||
|
return "events@alttd.com";
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
@Override
|
||||||
|
public String getSubject() {
|
||||||
|
return "Event Application: " + username;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
@Override
|
||||||
|
public String getSender() {
|
||||||
|
return email;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
@Override
|
||||||
|
public String toHtml() {
|
||||||
|
String[] fields = {"Username", "Email", "Discord", "Age", "Pronoun", "Avg time", "Event experience", "Discord VC", "Good builds", "Bad builds", "Technical aspects", "Other"};
|
||||||
|
String[] values = {username, email, discord, String.valueOf(age), pronoun, String.valueOf(avg_time), event_experience, discord_vc, good_builds, bad_builds, technical_aspects, other};
|
||||||
|
|
||||||
|
return toHtml(fields, values);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -8,7 +8,7 @@ import java.sql.SQLException;
|
||||||
|
|
||||||
public class Database {
|
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() {
|
public static void createTables() {
|
||||||
String[] createTables = {
|
String[] createTables = {
|
||||||
|
|
@ -28,6 +28,8 @@ public class Database {
|
||||||
creation_date BIGINT NOT NULL,
|
creation_date BIGINT NOT NULL,
|
||||||
form_json TEXT NOT NULL,
|
form_json TEXT NOT NULL,
|
||||||
form_class VARCHAR(64) NOT NULL,
|
form_class VARCHAR(64) NOT NULL,
|
||||||
|
ip VARCHAR(45) not null,
|
||||||
|
time TIMESTAMP default current_timestamp() not null,
|
||||||
PRIMARY KEY(formId)
|
PRIMARY KEY(formId)
|
||||||
)
|
)
|
||||||
""",
|
""",
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,9 @@ import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public abstract class Form {
|
public abstract class Form {
|
||||||
|
|
||||||
|
|
@ -18,25 +20,19 @@ public abstract class Form {
|
||||||
|
|
||||||
public String toHtml(String[] fields, String[] values) {
|
public String toHtml(String[] fields, String[] values) {
|
||||||
StringBuilder htmlOutput = new StringBuilder();
|
StringBuilder htmlOutput = new StringBuilder();
|
||||||
//language=HTML
|
|
||||||
htmlOutput.append("<table style='border-collapse: collapse; width: 100%;'>");
|
|
||||||
for (int i = 0; i < fields.length; i++) {
|
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(
|
htmlOutput.append(
|
||||||
String.format(
|
String.format(
|
||||||
//language=HTML
|
//language=HTML
|
||||||
"""
|
"""
|
||||||
<tr style='border: 1px solid #ddd;'>
|
<p><strong>%s</strong></p>
|
||||||
<td style='border: 1px solid #ddd; padding: 10px; font-weight: bold;'>
|
<p>%s</p>
|
||||||
%s
|
""", fields[i], paragraphs));
|
||||||
</td>
|
|
||||||
<td style='border: 1px solid #ddd; padding: 10px;'>
|
|
||||||
%s
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
""", fields[i], values[i]));
|
|
||||||
}
|
}
|
||||||
//language=HTML
|
|
||||||
htmlOutput.append("</table>");
|
|
||||||
return htmlOutput.toString();
|
return htmlOutput.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -45,7 +41,5 @@ public abstract class Form {
|
||||||
|
|
||||||
public abstract Optional<String> getDiscordBotUrl();
|
public abstract Optional<String> getDiscordBotUrl();
|
||||||
|
|
||||||
public abstract String getReceiver();
|
|
||||||
|
|
||||||
public abstract String getSender();
|
public abstract String getSender();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,29 +21,30 @@ public class StoreFormQuery {
|
||||||
return 100000 + random.nextInt(900000);
|
return 100000 + random.nextInt(900000);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Optional<Long> insertForm(Connection connection, Form form) {
|
private Optional<Long> insertForm(Connection connection, Form form, String ip) {
|
||||||
String insertForm = "INSERT INTO form (creation_date, form_json, form_class) VALUES (?, ?, ?)";
|
String insertForm = "INSERT INTO form (creation_date, form_json, form_class, ip) VALUES (?, ?, ?, ?)";
|
||||||
try (PreparedStatement stmt = connection.prepareStatement(insertForm, Statement.RETURN_GENERATED_KEYS)) {
|
try (PreparedStatement stmt = connection.prepareStatement(insertForm, Statement.RETURN_GENERATED_KEYS)) {
|
||||||
stmt.setLong(1, Instant.now().toEpochMilli());
|
stmt.setLong(1, Instant.now().toEpochMilli());
|
||||||
stmt.setString(2, form.toJsonString());
|
stmt.setString(2, form.toJsonString());
|
||||||
stmt.setString(3, form.getClass().getSimpleName());
|
stmt.setString(3, form.getClass().getSimpleName());
|
||||||
|
stmt.setString(4, ip);
|
||||||
int affectedRows = stmt.executeUpdate();
|
int affectedRows = stmt.executeUpdate();
|
||||||
if (affectedRows == 0) {
|
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();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
ResultSet generatedKeys = stmt.getGeneratedKeys();
|
ResultSet generatedKeys = stmt.getGeneratedKeys();
|
||||||
if (generatedKeys.next()) {
|
if (generatedKeys.next()) {
|
||||||
return Optional.of(generatedKeys.getLong(1));
|
return Optional.of(generatedKeys.getLong(1));
|
||||||
} else {
|
} else {
|
||||||
logger.error("No primary key generated when inserting form " + form);
|
logger.error("No primary key generated when inserting form {}", form);
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
logger.error("Failed insert form query for: " + form, e);
|
logger.error("Failed insert form query for: {}", form, e);
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
} catch (JsonProcessingException e) {
|
} 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();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -58,17 +59,17 @@ public class StoreFormQuery {
|
||||||
stmt.executeUpdate();
|
stmt.executeUpdate();
|
||||||
return Optional.of(verificationCode);
|
return Optional.of(verificationCode);
|
||||||
} catch (SQLException e) {
|
} 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();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public CompletableFuture<Integer> storeFormForVerificationCode(String eMail, Form form) {
|
public CompletableFuture<Integer> storeFormForVerificationCode(String eMail, Form form, String ip) {
|
||||||
logger.debug("storeFormForVerificationCode");
|
logger.debug("storeFormForVerificationCode");
|
||||||
Connection connection = DatabaseConnection.getConnection();
|
Connection connection = DatabaseConnection.getConnection();
|
||||||
logger.trace("Connection: {}", connection);
|
logger.trace("Connection: {}", connection);
|
||||||
return CompletableFuture.supplyAsync(() -> {
|
return CompletableFuture.supplyAsync(() -> {
|
||||||
Optional<Long> optionalFormId = insertForm(connection, form);
|
Optional<Long> optionalFormId = insertForm(connection, form, ip);
|
||||||
logger.trace("Form id: {}", optionalFormId);
|
logger.trace("Form id: {}", optionalFormId);
|
||||||
if (optionalFormId.isEmpty()) {
|
if (optionalFormId.isEmpty()) {
|
||||||
throw new RuntimeException("Failed to store form");
|
throw new RuntimeException("Failed to store form");
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,8 @@ public class MailForm {
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(MailForm.class);
|
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();
|
Properties mailProperties = MailSettings.getMailProperties();
|
||||||
Optional<PasswordAuthentication> accountDetails = MailSettings.getAccountDetails();
|
Optional<PasswordAuthentication> accountDetails = MailSettings.getAccountDetails();
|
||||||
if (accountDetails.isEmpty()) {
|
if (accountDetails.isEmpty()) {
|
||||||
|
|
@ -32,8 +33,7 @@ public class MailForm {
|
||||||
Message.RecipientType.TO,
|
Message.RecipientType.TO,
|
||||||
InternetAddress.parse(receiver)
|
InternetAddress.parse(receiver)
|
||||||
);
|
);
|
||||||
message.setSubject("Altitude Form");
|
message.setSubject(mailable.getSubject());
|
||||||
//TODO add something above the html form probably
|
|
||||||
message.setContent(form.toHtml(), "text/html");
|
message.setContent(form.toHtml(), "text/html");
|
||||||
try {
|
try {
|
||||||
Transport.send(message);
|
Transport.send(message);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
package com.alttd.forms.mail.mail_forms;
|
||||||
|
|
||||||
|
public interface Mailable {
|
||||||
|
|
||||||
|
String getReceiver();
|
||||||
|
|
||||||
|
String getSubject();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -2,6 +2,7 @@ package com.alttd.forms.verify_mail;
|
||||||
|
|
||||||
import com.alttd.forms.controlers.apply.StaffAppFormData;
|
import com.alttd.forms.controlers.apply.StaffAppFormData;
|
||||||
import com.alttd.forms.controlers.contact.ContactFormData;
|
import com.alttd.forms.controlers.contact.ContactFormData;
|
||||||
|
import com.alttd.forms.controlers.event_apply.EventAppFormData;
|
||||||
import com.alttd.forms.database.DatabaseConnection;
|
import com.alttd.forms.database.DatabaseConnection;
|
||||||
import com.alttd.forms.form.Form;
|
import com.alttd.forms.form.Form;
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
|
@ -76,6 +77,9 @@ public class FormQuery {
|
||||||
case "StaffAppFormData" -> {
|
case "StaffAppFormData" -> {
|
||||||
return objectMapper.readValue(json, StaffAppFormData.class);
|
return objectMapper.readValue(json, StaffAppFormData.class);
|
||||||
}
|
}
|
||||||
|
case "EventAppFormData" -> {
|
||||||
|
return objectMapper.readValue(json, EventAppFormData.class);
|
||||||
|
}
|
||||||
default -> throw new IllegalArgumentException("Invalid form class name: " + className);
|
default -> throw new IllegalArgumentException("Invalid form class name: " + className);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package com.alttd.forms.verify_mail;
|
||||||
|
|
||||||
import com.alttd.forms.form.Form;
|
import com.alttd.forms.form.Form;
|
||||||
import com.alttd.forms.mail.mail_forms.MailForm;
|
import com.alttd.forms.mail.mail_forms.MailForm;
|
||||||
|
import com.alttd.forms.mail.mail_forms.Mailable;
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
import jakarta.validation.Valid;
|
import jakarta.validation.Valid;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
|
@ -41,7 +42,8 @@ public class VerifyController {
|
||||||
return stringResponseEntity.get();
|
return stringResponseEntity.get();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
MailForm.sendForm(form.getReceiver(), form);
|
if (form instanceof Mailable mailable)
|
||||||
|
MailForm.sendForm(form, mailable);
|
||||||
try {
|
try {
|
||||||
return ResponseEntity.ok(form.toJsonString());
|
return ResponseEntity.ok(form.toJsonString());
|
||||||
} catch (JsonProcessingException e) {
|
} catch (JsonProcessingException e) {
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ public class TestForm {
|
||||||
Assertions.assertDoesNotThrow(() -> DatabaseConnection.initialize());
|
Assertions.assertDoesNotThrow(() -> DatabaseConnection.initialize());
|
||||||
StoreFormQuery storeFormQuery = new StoreFormQuery();
|
StoreFormQuery storeFormQuery = new StoreFormQuery();
|
||||||
ContactFormData contactFormData = new ContactFormData("akastijn", "akastijn@alttd.com", "This is a test question.");
|
ContactFormData contactFormData = new ContactFormData("akastijn", "akastijn@alttd.com", "This is a test question.");
|
||||||
storeFormQuery.storeFormForVerificationCode("akastijn@alttd.com", contactFormData).
|
storeFormQuery.storeFormForVerificationCode("akastijn@alttd.com", contactFormData, "0.0.0.0").
|
||||||
thenAccept(code -> {
|
thenAccept(code -> {
|
||||||
TestForm.code = code;
|
TestForm.code = code;
|
||||||
Assertions.assertTrue(code > 999 && code < 10000);
|
Assertions.assertTrue(code > 999 && code < 10000);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user