git » subscription-tool.git » commit 233b134

ready for deployment

author Thorsten Ortlepp
2025-12-10 22:05:41 UTC
committer Thorsten Ortlepp
2025-12-10 22:05:41 UTC
parent b94f50c57438dc4d820618eb651e1c0e9056d12c

ready for deployment

LICENSE.md +20 -0
README.md +3 -3
pom.xml +20 -16
src/main/java/dev/rubidium/subscriptiontool/SubscriptionToolApplication.java +1 -1
src/main/java/dev/rubidium/subscriptiontool/configuration/SecurityConfiguration.java +0 -2
src/main/java/dev/rubidium/subscriptiontool/controller/SubscriptionController.java +0 -6
src/main/java/dev/rubidium/subscriptiontool/service/impl/PersistenceServiceImpl.java +11 -7
src/main/resources/application.properties +2 -0

diff --git a/LICENSE.md b/LICENSE.md
new file mode 100644
index 0000000..b87f10e
--- /dev/null
+++ b/LICENSE.md
@@ -0,0 +1,20 @@
+# MIT License
+
+Copyright 2025 Thorsten Ortlepp
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ and associated documentation files (the “Software”), to deal in the Software without restriction,
+ including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or
+ substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
+ NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+[https://opensource.org/license/mit](https://opensource.org/license/mit)
diff --git a/README.md b/README.md
index 2d643d3..21144e7 100644
--- a/README.md
+++ b/README.md
@@ -18,10 +18,10 @@ CREATE DATABASE subscriptiontool;
 ### Configuration
 
 Basic authentication protects private endpoints (e.g., `/actuator`). The username and password can
- be configured by passing the following JVM parameters:
+ be configured by using the following properties:
 
-- `-Dsubscriptiontool.web.username=USERNAME`
-- `-Dsubscriptiontool.web.password=PASSWORD`
+- `subscriptiontool.web.username=USERNAME`
+- `subscriptiontool.web.password=PASSWORD`
 
 The password is hashed using Bcrypt. To create a password hash, use the following command:
  `mkpasswd -m bcrypt` (on Debian GNU/Linux `mkpasswd` is part of the *whois* package).
diff --git a/pom.xml b/pom.xml
index 525209a..862bb95 100644
--- a/pom.xml
+++ b/pom.xml
@@ -9,27 +9,19 @@
     <version>4.0.0</version>
     <relativePath/> <!-- lookup parent from repository -->
   </parent>
+
   <groupId>dev.rubidium</groupId>
   <artifactId>subscription-tool</artifactId>
-  <version>0.0.1-SNAPSHOT</version>
+  <version>0.1</version>
+  <packaging>jar</packaging>
   <name>subscription-tool</name>
-  <description>subscription-tool</description>
-  <url/>
-  <licenses>
-    <license/>
-  </licenses>
-  <developers>
-    <developer/>
-  </developers>
-  <scm>
-    <connection/>
-    <developerConnection/>
-    <tag/>
-    <url/>
-  </scm>
+  <description>a tool to manage subscriptions (e.g., to a newsletter)</description>
+  <url>https://git.ortlepp.ms/web/r/subscription-tool.git/</url>
+
   <properties>
     <java.version>25</java.version>
   </properties>
+
   <dependencies>
     <dependency>
       <groupId>org.springframework.boot</groupId>
@@ -67,7 +59,6 @@
       <groupId>org.thymeleaf.extras</groupId>
       <artifactId>thymeleaf-extras-springsecurity6</artifactId>
     </dependency>
-
     <dependency>
       <groupId>org.postgresql</groupId>
       <artifactId>postgresql</artifactId>
@@ -115,6 +106,19 @@
       <plugin>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-maven-plugin</artifactId>
+        <executions>
+          <execution>
+            <goals>
+              <goal>repackage</goal>
+            </goals>
+            <configuration>
+              <classifier>spring-boot</classifier>
+              <mainClass>
+                dev.rubidium.subscriptiontool.SubscriptionToolApplication
+              </mainClass>
+            </configuration>
+          </execution>
+        </executions>
       </plugin>
     </plugins>
   </build>
diff --git a/src/main/java/dev/rubidium/subscriptiontool/SubscriptionToolApplication.java b/src/main/java/dev/rubidium/subscriptiontool/SubscriptionToolApplication.java
index a61eab7..2720e0b 100644
--- a/src/main/java/dev/rubidium/subscriptiontool/SubscriptionToolApplication.java
+++ b/src/main/java/dev/rubidium/subscriptiontool/SubscriptionToolApplication.java
@@ -12,7 +12,7 @@ import org.springframework.scheduling.annotation.EnableScheduling;
 @EnableScheduling
 public class SubscriptionToolApplication {
 
-  public static void main(String[] args) {
+  static void main(String[] args) {
     SpringApplication.run(SubscriptionToolApplication.class, args);
   }
 
diff --git a/src/main/java/dev/rubidium/subscriptiontool/configuration/SecurityConfiguration.java b/src/main/java/dev/rubidium/subscriptiontool/configuration/SecurityConfiguration.java
index 6238d78..624f73c 100644
--- a/src/main/java/dev/rubidium/subscriptiontool/configuration/SecurityConfiguration.java
+++ b/src/main/java/dev/rubidium/subscriptiontool/configuration/SecurityConfiguration.java
@@ -24,7 +24,6 @@ public class SecurityConfiguration {
   @Value("${subscriptiontool.web.password}")
   private String password;
 
-
   @Bean
   public SecurityFilterChain defaultHttpSecurity(HttpSecurity httpSecurity) {
     httpSecurity
@@ -37,7 +36,6 @@ public class SecurityConfiguration {
     return httpSecurity.build();
   }
 
-
   @Bean
   public UserDetailsService users() {
     UserDetails user = User.builder()
diff --git a/src/main/java/dev/rubidium/subscriptiontool/controller/SubscriptionController.java b/src/main/java/dev/rubidium/subscriptiontool/controller/SubscriptionController.java
index 31697e2..92d68f3 100644
--- a/src/main/java/dev/rubidium/subscriptiontool/controller/SubscriptionController.java
+++ b/src/main/java/dev/rubidium/subscriptiontool/controller/SubscriptionController.java
@@ -27,14 +27,12 @@ public class SubscriptionController {
     this.translation = translation;
   }
 
-
   @GetMapping("/")
   public String index(Model model) {
     model.addAttribute(ATTRIBUTE_NAME_TRANSLATION, translation);
     return "Index";
   }
 
-
   @GetMapping("/subscribe")
   public String subscribeForm(Model model) {
     model.addAttribute(ATTRIBUTE_NAME_SUBSCRIPTION, new Subscription());
@@ -42,7 +40,6 @@ public class SubscriptionController {
     return "SubscribeForm";
   }
 
-
   @PostMapping("/subscribe")
   public String subscribeSave(@ModelAttribute Subscription subscription, Model model) {
     boolean saved = false;
@@ -56,7 +53,6 @@ public class SubscriptionController {
     return "SubscribeSave";
   }
 
-
   @GetMapping("/unsubscribe")
   public String unsubscribeForm(Model model) {
     model.addAttribute(ATTRIBUTE_NAME_SUBSCRIPTION, new Subscription());
@@ -64,7 +60,6 @@ public class SubscriptionController {
     return "UnsubscribeForm";
   }
 
-
   @PostMapping("/unsubscribe")
   public String unsubscribeDelete(@ModelAttribute Subscription subscription, Model model) {
     boolean deleted = false;
@@ -78,7 +73,6 @@ public class SubscriptionController {
     return "UnsubscribeDelete";
   }
 
-
   @GetMapping("/confirm")
   public String confirm(@RequestParam(name = "code") String code, Model model) {
     boolean confirmed = false;
diff --git a/src/main/java/dev/rubidium/subscriptiontool/service/impl/PersistenceServiceImpl.java b/src/main/java/dev/rubidium/subscriptiontool/service/impl/PersistenceServiceImpl.java
index 845c82c..d3f7e9d 100644
--- a/src/main/java/dev/rubidium/subscriptiontool/service/impl/PersistenceServiceImpl.java
+++ b/src/main/java/dev/rubidium/subscriptiontool/service/impl/PersistenceServiceImpl.java
@@ -72,9 +72,13 @@ public class PersistenceServiceImpl implements PersistenceService {
   public boolean updateSubscription(String code) {
     Subscription subscription = subscriptionRepository.findByCode(code);
     if (subscription != null) {
-      subscription.setConfirmed(Boolean.TRUE);
-      subscription.setConfirmation(Timestamp.valueOf(LocalDateTime.now()));
-      subscriptionRepository.saveAndFlush(subscription);
+      if (subscription.getConfirmed()) {
+        logger.warn("Subscription {} already confirmed", subscription.getId());
+      } else {
+        subscription.setConfirmed(Boolean.TRUE);
+        subscription.setConfirmation(Timestamp.valueOf(LocalDateTime.now()));
+        subscriptionRepository.saveAndFlush(subscription);
+      }
       return true;
     }
     logger.warn("No subscription found for code {}", code);
@@ -84,10 +88,10 @@ public class PersistenceServiceImpl implements PersistenceService {
   @Override
   public List<UnsentMail> getUnsentMails() {
     var mails = new ArrayList<UnsentMail>();
-    mailRepository.findUnsentMails().forEach(mail -> {
-      subscriptionRepository.findById(mail.getSubscription()).ifPresent(subscription ->
-          mails.add(new UnsentMail(mail.getId(), subscription.getMail(), subscription.getCode())));
-    });
+    mailRepository.findUnsentMails().forEach(mail ->
+        subscriptionRepository.findById(mail.getSubscription()).ifPresent(subscription ->
+            mails.add(new UnsentMail(mail.getId(), subscription.getMail(),
+                subscription.getCode()))));
     return mails;
   }
 
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index 778e402..b875956 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -30,5 +30,7 @@ subscriptiontool.mail.from=hello@example.com
 subscriptiontool.mail.url=https://example.com/confirm?code=
 subscriptiontool.scheduler.cron=0 * * * * *
 subscriptiontool.scheduler.zone=Europe/Berlin
+subscriptiontool.web.username=USERNAME
+subscriptiontool.web.password=PASSWORD
 
 spring.config.import=translation.properties