body = new HashMap<>();
- body.put("key", key);
+ body.put("key", encrypt(key));
body.put("product", product);
- body.put("hwid", hardwareId);
+ body.put("hwid", encrypt(hardwareId));
String bodyJson = GSON.toJson(body); // The json body
- OkHttpClient client = new OkHttpClient(); // Create a new http client
MediaType mediaType = MediaType.parse("application/json"); // Ensure the media type is json
- RequestBody requestBody = RequestBody.create(bodyJson, mediaType); // Build the request body
+ RequestBody requestBody = RequestBody.create(mediaType, bodyJson); // Build the request body
Request request = new Request.Builder()
- .url(CHECK_ENDPOINT)
+ .url(appUrl + CHECK_ENDPOINT)
.post(requestBody)
.build(); // Build the POST request
Response response = null; // The response of the request
int responseCode = -1; // The response code of the request
try { // Attempt to execute the request
- response = client.newCall(request).execute();
+ response = httpClient.newCall(request).execute();
responseCode = response.code();
// If the response is successful, we can parse the response
@@ -127,6 +180,43 @@ public final class LicenseExample {
return new LicenseResponse(responseCode, "An unknown error occurred");
}
+ /**
+ * Fetch the public key.
+ *
+ * If the public key is not already present, we
+ * fetch it from the server. Otherwise, the public
+ * key is loaded from the file.
+ *
+ *
+ * @param publicKeyFile the public key file
+ * @return the public key
+ * @see PublicKey for public key
+ */
+ @SneakyThrows
+ private PublicKey fetchPublicKey(@NonNull File publicKeyFile) {
+ byte[] publicKey;
+ if (publicKeyFile.exists()) { // Public key exists, use it
+ publicKey = Files.readAllBytes(publicKeyFile.toPath());
+ } else {
+ Request request = new Request.Builder()
+ .url(appUrl + PUBLIC_KEY_ENDPOINT)
+ .build(); // Build the GET request
+ @Cleanup Response response = httpClient.newCall(request).execute(); // Make the request
+ if (!response.isSuccessful()) { // Response wasn't successful
+ throw new IOException("Failed to download the public key, got response " + response.code());
+ }
+ ResponseBody body = response.body(); // Get the response body
+ assert body != null; // We need a response body
+ publicKey = body.bytes(); // Read our public key
+
+ // Write the response to the public key file
+ try (FileOutputStream outputStream = new FileOutputStream(publicKeyFile)) {
+ outputStream.write(publicKey);
+ }
+ }
+ return readPublicKey(publicKey);
+ }
+
/**
* Get the unique hardware
* identifier of this machine.
@@ -134,7 +224,7 @@ public final class LicenseExample {
* @return the hardware id
*/
@NonNull
- private static String getHardwareId() {
+ private String getHardwareId() {
SystemInfo systemInfo = new SystemInfo();
OperatingSystem operatingSystem = systemInfo.getOperatingSystem();
HardwareAbstractionLayer hardwareAbstractionLayer = systemInfo.getHardware();
@@ -155,9 +245,25 @@ public final class LicenseExample {
+ String.format("%08x", processorIdentifier.hashCode()) + "-" + processors;
}
- @AllArgsConstructor
- @Getter
- @ToString
+ /**
+ * Encrypt the given input.
+ *
+ * @param input the encrypted input
+ * @return the encrypted result
+ */
+ @SneakyThrows @NonNull
+ private String encrypt(@NonNull String input) {
+ Cipher cipher = Cipher.getInstance(ALGORITHM); // Create our cipher
+ cipher.init(Cipher.ENCRYPT_MODE, publicKey); // Set our mode and public key
+ return Base64.getEncoder().encodeToString(cipher.doFinal(input.getBytes())); // Return our encrypted result
+ }
+
+ /**
+ * The response of a license check.
+ *
+ * @see #check(String)
+ */
+ @AllArgsConstructor @Getter @ToString
public static class LicenseResponse {
/**
* The status code of the response.
diff --git a/Example/src/main/java/me/braydon/example/Main.java b/Example/src/main/java/me/braydon/example/Main.java
index 2454f11..bcf52b4 100644
--- a/Example/src/main/java/me/braydon/example/Main.java
+++ b/Example/src/main/java/me/braydon/example/Main.java
@@ -1,11 +1,19 @@
+/*
+ * Copyright (c) 2023 Braydon (Rainnny). All rights reserved.
+ *
+ * For inquiries, please contact braydonrainnny@gmail.com
+ */
package me.braydon.example;
+import java.io.File;
+
/**
* @author Braydon
*/
public final class Main {
public static void main(String[] args) {
- LicenseExample.LicenseResponse response = LicenseExample.check("XXXX-XXXX-XXXX-XXXX", "Example");
+ LicenseClient client = new LicenseClient("http://localhost:7500", "Example", new File("public.key")); // Create the client
+ LicenseClient.LicenseResponse response = client.check("XXXX-XXXX-XXXX-XXXX"); // Check our license
if (!response.isValid()) { // License isn't valid
System.err.println("Invalid license: " + response.getError());
return;
diff --git a/src/main/java/me/braydon/license/LicenseServer.java b/src/main/java/me/braydon/license/LicenseServer.java
index de974cb..81025f2 100644
--- a/src/main/java/me/braydon/license/LicenseServer.java
+++ b/src/main/java/me/braydon/license/LicenseServer.java
@@ -1,3 +1,8 @@
+/*
+ * Copyright (c) 2023 Braydon (Rainnny). All rights reserved.
+ *
+ * For inquiries, please contact braydonrainnny@gmail.com
+ */
package me.braydon.license;
import com.google.gson.Gson;
diff --git a/src/main/java/me/braydon/license/common/CryptographyUtils.java b/src/main/java/me/braydon/license/common/CryptographyUtils.java
new file mode 100644
index 0000000..bd1cd61
--- /dev/null
+++ b/src/main/java/me/braydon/license/common/CryptographyUtils.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2023 Braydon (Rainnny). All rights reserved.
+ *
+ * For inquiries, please contact braydonrainnny@gmail.com
+ */
+package me.braydon.license.common;
+
+import lombok.NonNull;
+import lombok.SneakyThrows;
+import lombok.experimental.UtilityClass;
+
+import javax.crypto.Cipher;
+import java.io.File;
+import java.nio.file.Files;
+import java.security.*;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+import java.util.Base64;
+
+/**
+ * @author Braydon
+ */
+@UtilityClass
+public final class CryptographyUtils {
+ private static final String ALGORITHM = "RSA"; // The algorithm to use
+
+ /**
+ * Generate a new key pair.
+ *
+ * @return the key pair
+ * @see KeyPair for key pair
+ */
+ @NonNull @SneakyThrows
+ public static KeyPair generateKeyPair() {
+ KeyPairGenerator generator = KeyPairGenerator.getInstance(ALGORITHM); // Create a generator
+ generator.initialize(2048); // Set the key size
+ return generator.generateKeyPair(); // Return our generated key pair
+ }
+
+ /**
+ * Read the public key from the given file.
+ *
+ * @param keyFile the key file to read
+ * @return the public key
+ * @see PrivateKey for public key
+ */
+ @SneakyThrows
+ public static PublicKey readPublicKey(@NonNull File keyFile) {
+ X509EncodedKeySpec keySpec = new X509EncodedKeySpec(Files.readAllBytes(keyFile.toPath())); // Get the key spec
+ return KeyFactory.getInstance(ALGORITHM).generatePublic(keySpec); // Return the public key from the key spec
+ }
+
+ /**
+ * Read the private key from the given file.
+ *
+ * @param keyFile the key file to read
+ * @return the private key
+ * @see PrivateKey for private key
+ */
+ @SneakyThrows
+ public static PrivateKey readPrivateKey(@NonNull File keyFile) {
+ PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(Files.readAllBytes(keyFile.toPath())); // Get the key spec
+ return KeyFactory.getInstance(ALGORITHM).generatePrivate(keySpec); // Return the private key from the key spec
+ }
+
+ /**
+ * Decrypt the given input with
+ * the provided private key.
+ *
+ * @param input the encrypted input
+ * @param privateKey the private key
+ * @return the decrypted result
+ * @see PrivateKey for private key
+ */
+ @SneakyThrows @NonNull
+ public static String decryptMessage(@NonNull String input, @NonNull PrivateKey privateKey) {
+ Cipher cipher = Cipher.getInstance(ALGORITHM); // Create the cipher
+ cipher.init(Cipher.DECRYPT_MODE, privateKey); // Set our mode and private key
+ return new String(cipher.doFinal(Base64.getDecoder().decode(input))); // Return our decrypted result
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/me/braydon/license/common/IPUtils.java b/src/main/java/me/braydon/license/common/IPUtils.java
index e8990b6..610d7f7 100644
--- a/src/main/java/me/braydon/license/common/IPUtils.java
+++ b/src/main/java/me/braydon/license/common/IPUtils.java
@@ -1,3 +1,8 @@
+/*
+ * Copyright (c) 2023 Braydon (Rainnny). All rights reserved.
+ *
+ * For inquiries, please contact braydonrainnny@gmail.com
+ */
package me.braydon.license.common;
import jakarta.servlet.http.HttpServletRequest;
diff --git a/src/main/java/me/braydon/license/common/MiscUtils.java b/src/main/java/me/braydon/license/common/MiscUtils.java
index 26e6569..bfd71b5 100644
--- a/src/main/java/me/braydon/license/common/MiscUtils.java
+++ b/src/main/java/me/braydon/license/common/MiscUtils.java
@@ -1,3 +1,8 @@
+/*
+ * Copyright (c) 2023 Braydon (Rainnny). All rights reserved.
+ *
+ * For inquiries, please contact braydonrainnny@gmail.com
+ */
package me.braydon.license.common;
import lombok.NonNull;
diff --git a/src/main/java/me/braydon/license/common/RandomUtils.java b/src/main/java/me/braydon/license/common/RandomUtils.java
index 9fca53a..807d9b6 100644
--- a/src/main/java/me/braydon/license/common/RandomUtils.java
+++ b/src/main/java/me/braydon/license/common/RandomUtils.java
@@ -1,3 +1,8 @@
+/*
+ * Copyright (c) 2023 Braydon (Rainnny). All rights reserved.
+ *
+ * For inquiries, please contact braydonrainnny@gmail.com
+ */
package me.braydon.license.common;
import lombok.NonNull;
diff --git a/src/main/java/me/braydon/license/common/TimeUtils.java b/src/main/java/me/braydon/license/common/TimeUtils.java
index 4908469..684bb00 100644
--- a/src/main/java/me/braydon/license/common/TimeUtils.java
+++ b/src/main/java/me/braydon/license/common/TimeUtils.java
@@ -1,3 +1,8 @@
+/*
+ * Copyright (c) 2023 Braydon (Rainnny). All rights reserved.
+ *
+ * For inquiries, please contact braydonrainnny@gmail.com
+ */
package me.braydon.license.common;
import lombok.NonNull;
diff --git a/src/main/java/me/braydon/license/controller/CryptographyController.java b/src/main/java/me/braydon/license/controller/CryptographyController.java
new file mode 100644
index 0000000..092a91e
--- /dev/null
+++ b/src/main/java/me/braydon/license/controller/CryptographyController.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2023 Braydon (Rainnny). All rights reserved.
+ *
+ * For inquiries, please contact braydonrainnny@gmail.com
+ */
+package me.braydon.license.controller;
+
+import lombok.NonNull;
+import me.braydon.license.model.License;
+import me.braydon.license.service.CryptographyService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.io.ByteArrayResource;
+import org.springframework.core.io.Resource;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.security.PublicKey;
+
+/**
+ * @author Braydon
+ */
+@RestController
+@RequestMapping(value = "/crypto", produces = MediaType.APPLICATION_JSON_VALUE)
+public final class CryptographyController {
+ /**
+ * The {@link CryptographyService} to use.
+ */
+ @NonNull private final CryptographyService service;
+
+ @Autowired
+ public CryptographyController(@NonNull CryptographyService service) {
+ this.service = service;
+ }
+
+ /**
+ * Downloads the public key file.
+ *
+ * @return the response entity
+ * @see PublicKey for public key
+ * @see License for license
+ * @see ResponseEntity for response entity
+ */
+ @GetMapping("/pub")
+ @ResponseBody
+ public ResponseEntity publicKey() {
+ byte[] publicKey = service.getKeyPair().getPublic().getEncoded(); // Get the public key
+ String fileName = "public.key"; // The name of the file to download
+ return ResponseEntity.ok()
+ .contentType(MediaType.APPLICATION_OCTET_STREAM)
+ .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + fileName + "\"")
+ .contentLength(publicKey.length)
+ .body(new ByteArrayResource(publicKey));
+ }
+}
diff --git a/src/main/java/me/braydon/license/controller/LicenseController.java b/src/main/java/me/braydon/license/controller/LicenseController.java
index bdd0837..3066237 100644
--- a/src/main/java/me/braydon/license/controller/LicenseController.java
+++ b/src/main/java/me/braydon/license/controller/LicenseController.java
@@ -1,12 +1,19 @@
+/*
+ * Copyright (c) 2023 Braydon (Rainnny). All rights reserved.
+ *
+ * For inquiries, please contact braydonrainnny@gmail.com
+ */
package me.braydon.license.controller;
import jakarta.servlet.http.HttpServletRequest;
import lombok.NonNull;
+import me.braydon.license.common.CryptographyUtils;
import me.braydon.license.common.IPUtils;
import me.braydon.license.dto.LicenseCheckBodyDTO;
import me.braydon.license.dto.LicenseDTO;
import me.braydon.license.exception.APIException;
import me.braydon.license.model.License;
+import me.braydon.license.service.CryptographyService;
import me.braydon.license.service.LicenseService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
@@ -14,6 +21,7 @@ import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
+import java.security.PrivateKey;
import java.util.Map;
/**
@@ -22,14 +30,20 @@ import java.util.Map;
@RestController
@RequestMapping(value = "/", produces = MediaType.APPLICATION_JSON_VALUE)
public final class LicenseController {
+ /**
+ * The {@link CryptographyService} to use.
+ */
+ @NonNull private final CryptographyService cryptographyService;
+
/**
* The {@link LicenseService} to use.
*/
- @NonNull private final LicenseService service;
+ @NonNull private final LicenseService licenseService;
@Autowired
- public LicenseController(@NonNull LicenseService service) {
- this.service = service;
+ public LicenseController(@NonNull CryptographyService cryptographyService, @NonNull LicenseService licenseService) {
+ this.cryptographyService = cryptographyService;
+ this.licenseService = licenseService;
}
/**
@@ -53,24 +67,34 @@ public final class LicenseController {
if (IPUtils.getIpType(ip) == -1) {
throw new APIException(HttpStatus.BAD_REQUEST, "Invalid IP address");
}
- // Ensure the HWID is valid
- String hwidString = body.getHwid();
+ String key;
+ String hwid;
+ try {
+ PrivateKey privateKey = cryptographyService.getKeyPair().getPrivate(); // Get our private key
+ key = CryptographyUtils.decryptMessage(body.getKey(), privateKey); // Decrypt our license key
+ hwid = CryptographyUtils.decryptMessage(body.getHwid(), privateKey); // Decrypt our hwid
+ } catch (IllegalArgumentException ex) {
+ throw new APIException(HttpStatus.BAD_REQUEST, "Signature Error");
+ }
+
+ // Validating that the UUID is in the correct format
boolean invalidHwid = true;
- if (hwidString.contains("-")) {
- int segments = hwidString.substring(0, hwidString.lastIndexOf("-")).split("-").length;
+ if (hwid.contains("-")) {
+ int segments = hwid.substring(0, hwid.lastIndexOf("-")).split("-").length;
if (segments == 4) {
invalidHwid = false;
}
}
- if (invalidHwid) {
+ if (invalidHwid) { // Invalid HWID
throw new APIException(HttpStatus.BAD_REQUEST, "Invalid HWID");
}
+
// Check the license
- License license = service.check(
- body.getKey(),
+ License license = licenseService.check(
+ key,
body.getProduct(),
ip,
- hwidString
+ hwid
);
// Return OK with the license DTO
return ResponseEntity.ok(new LicenseDTO(
diff --git a/src/main/java/me/braydon/license/dto/LicenseCheckBodyDTO.java b/src/main/java/me/braydon/license/dto/LicenseCheckBodyDTO.java
index d5f8d90..40f0845 100644
--- a/src/main/java/me/braydon/license/dto/LicenseCheckBodyDTO.java
+++ b/src/main/java/me/braydon/license/dto/LicenseCheckBodyDTO.java
@@ -1,3 +1,8 @@
+/*
+ * Copyright (c) 2023 Braydon (Rainnny). All rights reserved.
+ *
+ * For inquiries, please contact braydonrainnny@gmail.com
+ */
package me.braydon.license.dto;
import lombok.AllArgsConstructor;
diff --git a/src/main/java/me/braydon/license/dto/LicenseDTO.java b/src/main/java/me/braydon/license/dto/LicenseDTO.java
index bc079f5..cf5014a 100644
--- a/src/main/java/me/braydon/license/dto/LicenseDTO.java
+++ b/src/main/java/me/braydon/license/dto/LicenseDTO.java
@@ -1,3 +1,8 @@
+/*
+ * Copyright (c) 2023 Braydon (Rainnny). All rights reserved.
+ *
+ * For inquiries, please contact braydonrainnny@gmail.com
+ */
package me.braydon.license.dto;
import lombok.AllArgsConstructor;
diff --git a/src/main/java/me/braydon/license/exception/APIException.java b/src/main/java/me/braydon/license/exception/APIException.java
index d35fb30..dc351f3 100644
--- a/src/main/java/me/braydon/license/exception/APIException.java
+++ b/src/main/java/me/braydon/license/exception/APIException.java
@@ -1,3 +1,8 @@
+/*
+ * Copyright (c) 2023 Braydon (Rainnny). All rights reserved.
+ *
+ * For inquiries, please contact braydonrainnny@gmail.com
+ */
package me.braydon.license.exception;
import lombok.Getter;
diff --git a/src/main/java/me/braydon/license/exception/LicenseExpiredException.java b/src/main/java/me/braydon/license/exception/LicenseExpiredException.java
index 03268bd..57297ff 100644
--- a/src/main/java/me/braydon/license/exception/LicenseExpiredException.java
+++ b/src/main/java/me/braydon/license/exception/LicenseExpiredException.java
@@ -1,3 +1,8 @@
+/*
+ * Copyright (c) 2023 Braydon (Rainnny). All rights reserved.
+ *
+ * For inquiries, please contact braydonrainnny@gmail.com
+ */
package me.braydon.license.exception;
import me.braydon.license.model.License;
diff --git a/src/main/java/me/braydon/license/exception/LicenseHwidLimitExceededException.java b/src/main/java/me/braydon/license/exception/LicenseHwidLimitExceededException.java
index b22df78..7e3a136 100644
--- a/src/main/java/me/braydon/license/exception/LicenseHwidLimitExceededException.java
+++ b/src/main/java/me/braydon/license/exception/LicenseHwidLimitExceededException.java
@@ -1,3 +1,8 @@
+/*
+ * Copyright (c) 2023 Braydon (Rainnny). All rights reserved.
+ *
+ * For inquiries, please contact braydonrainnny@gmail.com
+ */
package me.braydon.license.exception;
import me.braydon.license.model.License;
diff --git a/src/main/java/me/braydon/license/exception/LicenseIpLimitExceededException.java b/src/main/java/me/braydon/license/exception/LicenseIpLimitExceededException.java
index 0dddf54..246a8b5 100644
--- a/src/main/java/me/braydon/license/exception/LicenseIpLimitExceededException.java
+++ b/src/main/java/me/braydon/license/exception/LicenseIpLimitExceededException.java
@@ -1,3 +1,8 @@
+/*
+ * Copyright (c) 2023 Braydon (Rainnny). All rights reserved.
+ *
+ * For inquiries, please contact braydonrainnny@gmail.com
+ */
package me.braydon.license.exception;
import me.braydon.license.model.License;
diff --git a/src/main/java/me/braydon/license/exception/LicenseNotFoundException.java b/src/main/java/me/braydon/license/exception/LicenseNotFoundException.java
index c25d77f..33699d8 100644
--- a/src/main/java/me/braydon/license/exception/LicenseNotFoundException.java
+++ b/src/main/java/me/braydon/license/exception/LicenseNotFoundException.java
@@ -1,3 +1,8 @@
+/*
+ * Copyright (c) 2023 Braydon (Rainnny). All rights reserved.
+ *
+ * For inquiries, please contact braydonrainnny@gmail.com
+ */
package me.braydon.license.exception;
import me.braydon.license.model.License;
diff --git a/src/main/java/me/braydon/license/model/License.java b/src/main/java/me/braydon/license/model/License.java
index 0bf6d85..dda6ad8 100644
--- a/src/main/java/me/braydon/license/model/License.java
+++ b/src/main/java/me/braydon/license/model/License.java
@@ -1,3 +1,8 @@
+/*
+ * Copyright (c) 2023 Braydon (Rainnny). All rights reserved.
+ *
+ * For inquiries, please contact braydonrainnny@gmail.com
+ */
package me.braydon.license.model;
import lombok.Getter;
diff --git a/src/main/java/me/braydon/license/repository/LicenseRepository.java b/src/main/java/me/braydon/license/repository/LicenseRepository.java
index 40890fc..712057f 100644
--- a/src/main/java/me/braydon/license/repository/LicenseRepository.java
+++ b/src/main/java/me/braydon/license/repository/LicenseRepository.java
@@ -1,3 +1,8 @@
+/*
+ * Copyright (c) 2023 Braydon (Rainnny). All rights reserved.
+ *
+ * For inquiries, please contact braydonrainnny@gmail.com
+ */
package me.braydon.license.repository;
import lombok.NonNull;
diff --git a/src/main/java/me/braydon/license/service/CryptographyService.java b/src/main/java/me/braydon/license/service/CryptographyService.java
new file mode 100644
index 0000000..eb7b85f
--- /dev/null
+++ b/src/main/java/me/braydon/license/service/CryptographyService.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2023 Braydon (Rainnny). All rights reserved.
+ *
+ * For inquiries, please contact braydonrainnny@gmail.com
+ */
+package me.braydon.license.service;
+
+import lombok.Getter;
+import lombok.NonNull;
+import lombok.SneakyThrows;
+import lombok.extern.slf4j.Slf4j;
+import me.braydon.license.common.CryptographyUtils;
+import org.springframework.stereotype.Service;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.security.KeyPair;
+import java.util.Base64;
+
+/**
+ * @author Braydon
+ */
+@Service
+@Slf4j(topic = "Cryptography")
+@Getter
+public final class CryptographyService {
+ /**
+ * Our {@link KeyPair}.
+ */
+ @NonNull private final KeyPair keyPair;
+
+ @SneakyThrows
+ public CryptographyService() {
+ File publicKeyFile = new File("public.key"); // The private key
+ File privateKeyFile = new File("private.key"); // The private key
+ if (!publicKeyFile.exists() || !privateKeyFile.exists()) { // Missing private key, generate new key pair.
+ keyPair = CryptographyUtils.generateKeyPair(); // Generate new key pair
+ writeKey(keyPair.getPublic().getEncoded(), publicKeyFile); // Write our public key
+ writeKey(keyPair.getPrivate().getEncoded(), privateKeyFile); // Write our private key
+ log.info("New key pair has been generated");
+ log.info(Base64.getEncoder().encodeToString(keyPair.getPublic().getEncoded()));
+ return;
+ }
+ // Load our private key from the file
+ keyPair = new KeyPair(CryptographyUtils.readPublicKey(publicKeyFile), CryptographyUtils.readPrivateKey(privateKeyFile));
+ log.info("Loaded private key from file " + privateKeyFile.getPath());
+ }
+
+ /**
+ * Write the given contents to the provided file.
+ *
+ * @param contents the content bytes to write
+ * @param file the file to write to
+ */
+ private void writeKey(byte[] contents, @NonNull File file) {
+ try (FileOutputStream outputStream = new FileOutputStream(file)) {
+ outputStream.write(contents);
+ } catch (IOException ex) {
+ ex.printStackTrace();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/me/braydon/license/service/DiscordService.java b/src/main/java/me/braydon/license/service/DiscordService.java
index b7f7f35..9c69e61 100644
--- a/src/main/java/me/braydon/license/service/DiscordService.java
+++ b/src/main/java/me/braydon/license/service/DiscordService.java
@@ -1,3 +1,8 @@
+/*
+ * Copyright (c) 2023 Braydon (Rainnny). All rights reserved.
+ *
+ * For inquiries, please contact braydonrainnny@gmail.com
+ */
package me.braydon.license.service;
import com.google.common.cache.Cache;
@@ -33,7 +38,6 @@ import net.dv8tion.jda.api.requests.GatewayIntent;
import org.mindrot.jbcrypt.BCrypt;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
-import org.springframework.boot.info.BuildProperties;
import org.springframework.stereotype.Service;
import java.awt.*;
@@ -59,7 +63,7 @@ public final class DiscordService {
/**
* The version of this Springboot application.
*/
- @NonNull private final String applicationVersion;
+ @NonNull private String applicationVersion = "n/a";
/**
* The salt to use for hashing license keys.
@@ -140,9 +144,9 @@ public final class DiscordService {
.build();
@Autowired
- public DiscordService(@NonNull LicenseRepository licenseRepository, @NonNull BuildProperties buildProperties) {
+ public DiscordService(@NonNull LicenseRepository licenseRepository/*, @NonNull BuildProperties buildProperties*/) {
this.licenseRepository = licenseRepository;
- this.applicationVersion = buildProperties.getVersion();
+ // this.applicationVersion = buildProperties.getVersion();
}
@PostConstruct @SneakyThrows
diff --git a/src/main/java/me/braydon/license/service/LicenseService.java b/src/main/java/me/braydon/license/service/LicenseService.java
index 45fb026..a11c5c1 100644
--- a/src/main/java/me/braydon/license/service/LicenseService.java
+++ b/src/main/java/me/braydon/license/service/LicenseService.java
@@ -1,3 +1,8 @@
+/*
+ * Copyright (c) 2023 Braydon (Rainnny). All rights reserved.
+ *
+ * For inquiries, please contact braydonrainnny@gmail.com
+ */
package me.braydon.license.service;
import jakarta.annotation.PostConstruct;