response = Unirest.post("https://challenges.cloudflare.com/turnstile/v0/siteverify").body(body).asJson();
+ if (!response.getBody().getObject().getBoolean("success")) {
+ throw new BadRequestException(Error.CAPTCHA_INVALID);
+ }
+ }
+
+ public enum Error implements IGenericResponse {
+ CAPTCHA_INVALID
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/cc/pulseapp/api/service/SnowflakeService.java b/src/main/java/cc/pulseapp/api/service/SnowflakeService.java
new file mode 100644
index 0000000..5273f6b
--- /dev/null
+++ b/src/main/java/cc/pulseapp/api/service/SnowflakeService.java
@@ -0,0 +1,48 @@
+package cc.pulseapp.api.service;
+
+import com.relops.snowflake.Snowflake;
+import lombok.NonNull;
+import org.springframework.stereotype.Service;
+
+/**
+ * The service responsible for generating snowflakes!
+ *
+ * @author Braydon
+ */
+@Service
+public final class SnowflakeService {
+ private static final long TIMESTAMP_SHIFT = Snowflake.NODE_SHIFT + Snowflake.SEQ_SHIFT;
+
+ /**
+ * The snowflake instance to use.
+ */
+ @NonNull private final Snowflake snowflake;
+
+ private SnowflakeService() {
+ snowflake = new Snowflake(7);
+ }
+
+ /**
+ * Generate a new snowflake.
+ *
+ * @return the generated snowflake
+ */
+ public long generateSnowflake() {
+ return snowflake.next();
+ }
+
+ /**
+ * Extract the creation time of the given
+ * snowflake by reversing the snowflake algorithm.
+ *
+ * The snowflake is right-shifted by 22
+ * bits to get the original timestamp.
+ *
+ *
+ * @param snowflake the snowflake
+ * @return the snowflake unix creation time
+ */
+ public long extractCreationTime(long snowflake) {
+ return snowflake >>> TIMESTAMP_SHIFT;
+ }
+}
\ No newline at end of file
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index 978cd76..a99e5b0 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -8,19 +8,33 @@ logging:
file:
path: "./logs"
-# Sentry Configuration
-sentry:
- dsn: "CHANGE_ME"
- tracesSampleRate: 1.0
- environment: "development"
+# Cloudflare Captcha Configuration
+captcha:
+ secret: "CHANGE_ME"
# QuestDB Configuration (Metrics)
questdb:
enabled: false
uri: "http::addr=localhost:9000;username=tether;password=p4$$w0rd;auto_flush_interval=5000;"
+# Sentry Configuration
+sentry:
+ dsn: "" # Leave blank for no sentry
+ tracesSampleRate: 1.0
+ environment: "development"
+
# Spring Configuration
spring:
+ data:
+ # MongoDB Configuration
+ mongodb:
+ uri: "mongodb://pulseapp:p4$$w0rd@localhost:27017/pulseapp?authSource=admin"
+ auto-index-creation: true # Automatically create collection indexes
+
+ # Don't serialize null values by default with Jackson
+ jackson:
+ default-property-inclusion: non_null
+
# Ignore
banner:
location: "classpath:banner.txt"
\ No newline at end of file