Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,17 @@ on:
- main

jobs:
format-check:
runs-on: ubuntu-latest
name: Check source code formatting
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
distribution: 'zulu'
java-version: 17
- run: ./gradlew :sdk:checkFormat :examples:checkFormat --continue

test:
runs-on: ubuntu-latest
name: Java ${{ matrix.Java }}
Expand Down
88 changes: 88 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,7 +1,95 @@
import java.net.URL
import java.nio.file.Files
import java.nio.file.StandardCopyOption

val projectVersion: String by project

allprojects {
group = "com.github.fingerprintjs"
version = projectVersion
}

plugins {
alias(libs.plugins.google.osdetector)
}

// Register formatting tasks for each subproject

val googleJavaFormatExeFile = layout.buildDirectory.file("google-java-format.exe")
val googleJavaFormatOsSuffixMap = mapOf(
"osx" to "darwin",
"linux" to "linux",
"windows" to "windows",
)
val googleJavaFormatArchSuffixMap = mapOf(
"x86_64" to "x86-64",
"aarch_64" to "arm64"
)
val googleJavaFormatBinarySuffixMap = mapOf(
"osx" to "",
"linux" to "",
"windows" to ".exe"
)

tasks.register("downloadGoogleJavaFormat") {
val osSuffix = googleJavaFormatOsSuffixMap[osdetector.os]
val archSuffix = googleJavaFormatArchSuffixMap[osdetector.arch]
val binarySuffix = googleJavaFormatBinarySuffixMap[osdetector.os]
val googleJavaFormatVersion = libs.versions.google.java.format.get()
val downloadUrl = "https://github.com/google/google-java-format/releases/download/v$googleJavaFormatVersion/google-java-format_${osSuffix}-${archSuffix}${binarySuffix}"
outputs.file(googleJavaFormatExeFile)

doLast {
val file = googleJavaFormatExeFile.get().asFile
if (!file.exists()) {
println("Downloading google-java-format for $osSuffix-$archSuffix")
URL(downloadUrl).openStream().use { input ->
Files.copy(input, file.toPath(), StandardCopyOption.REPLACE_EXISTING)
}
file.setExecutable(true)
} else {
println("google-java-format already downloaded")
}
}
}


fun Project.registerFormatTasks() {
val inputFiles = fileTree("src") {
include("**/*.java")
}.files.map { it.absolutePath }

tasks.register("format") {
dependsOn(rootProject.tasks.named("downloadGoogleJavaFormat"))

doLast {
// First, fix the imports
exec {
executable = googleJavaFormatExeFile.get().asFile.toPath().toString()
args = listOf("--replace", "--fix-imports-only") + inputFiles
}

// Second, format the code. This ensures that the removal of unused imports does not
// introduce the need to run another formatting pass to pass the formatting checks.
exec {
executable = googleJavaFormatExeFile.get().asFile.toPath().toString()
args = listOf("--replace", "--skip-javadoc-formatting", "--skip-reflowing-long-strings") + inputFiles
}
}
}

tasks.register<Exec>("checkFormat") {
dependsOn(rootProject.tasks.named("downloadGoogleJavaFormat"))

doFirst {
println("The following source files need to be formatted:")
}

executable = googleJavaFormatExeFile.get().asFile.toPath().toString()
args = listOf("--dry-run", "--set-exit-if-changed", "--skip-javadoc-formatting", "--skip-reflowing-long-strings") + inputFiles
}
}

subprojects {
registerFormatTasks()
}
204 changes: 105 additions & 99 deletions examples/src/main/java/com/fingerprint/example/FunctionalTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import com.fingerprint.v4.model.*;
import com.fingerprint.v4.sdk.ApiException;
import com.fingerprint.v4.sdk.Configuration;

import java.sql.Timestamp;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
Expand All @@ -14,108 +13,115 @@

public class FunctionalTests {

public static void main(String... args) {
final String apiSecret = System.getenv("FPJS_API_SECRET");
if (apiSecret == null || apiSecret.isBlank()) {
System.err.println("Missing required environment variable: FPJS_API_SECRET");
System.exit(1);
}

final String regionEnv = System.getenv("FPJS_API_REGION");
final String region = regionEnv != null ? regionEnv.toLowerCase(Locale.getDefault()).trim() : "us";

final FingerprintApi api = new FingerprintApi(Configuration.getDefaultApiClient(apiSecret, region));

long end = Instant.now().toEpochMilli();
long start = Instant.now().minus(90L, ChronoUnit.DAYS).toEpochMilli();

String eventId = "";

// Search events
try {
final EventSearch events = api.searchEvents(new FingerprintApi.SearchEventsOptionalParams()
.setLimit(2)
.setStart(start)
.setEnd(end));
assert events.getEvents() != null;
if (events.getEvents().isEmpty()) {
System.err.println("FingerprintApi.searchEvents: is empty");
System.exit(1);
}
final Event firstEvent = events.getEvents().get(0);
assert firstEvent != null;
eventId = firstEvent.getEventId();
System.out.println(events.getEvents());
} catch (ApiException e) {
System.err.println("Exception when calling FingerprintApi.searchEvents:" + e.getMessage());
System.exit(1);
}

// Get identification event
try {
final Event event = api.getEvent(eventId);
System.out.println(event);
} catch (ApiException e) {
System.err.println("Exception when calling FingerprintApi.getEvent:" + e.getMessage());
System.exit(1);
}

// Update identification event
final String requestIdToUpdate = System.getenv("FPJS_REQUEST_ID_TO_UPDATE");
if (requestIdToUpdate != null) {
try {
final HashMap<String, Object> tags = new HashMap<>() {
{
put("timestamp", new Timestamp(new Date().getTime()));
}
};
api.updateEvent(requestIdToUpdate, new EventUpdate().tags(tags));
} catch (ApiException e) {
System.err.println("Exception when calling FingerprintApi.updateEvent:" + e.getMessage());
System.exit(1);
}
}
public static void main(String... args) {
final String apiSecret = System.getenv("FPJS_API_SECRET");
if (apiSecret == null || apiSecret.isBlank()) {
System.err.println("Missing required environment variable: FPJS_API_SECRET");
System.exit(1);
}

// Delete visitor data
final String visitorIdToDelete = System.getenv("FPJS_VISITOR_ID_TO_DELETE");
if (visitorIdToDelete != null) {
try {
api.deleteVisitorData(visitorIdToDelete);
} catch (ApiException e) {
System.err.println("Exception when calling FingerprintApi.deleteVisitor:" + e.getMessage());
System.exit(1);
}
}
final String regionEnv = System.getenv("FPJS_API_REGION");
final String region =
regionEnv != null ? regionEnv.toLowerCase(Locale.getDefault()).trim() : "us";

final FingerprintApi api =
new FingerprintApi(Configuration.getDefaultApiClient(apiSecret, region));

long end = Instant.now().toEpochMilli();
long start = Instant.now().minus(90L, ChronoUnit.DAYS).toEpochMilli();

String eventId = "";

// Search events
try {
final EventSearch events =
api.searchEvents(
new FingerprintApi.SearchEventsOptionalParams()
.setLimit(2)
.setStart(start)
.setEnd(end));
assert events.getEvents() != null;
if (events.getEvents().isEmpty()) {
System.err.println("FingerprintApi.searchEvents: is empty");
System.exit(1);
}
final Event firstEvent = events.getEvents().get(0);
assert firstEvent != null;
eventId = firstEvent.getEventId();
System.out.println(events.getEvents());
} catch (ApiException e) {
System.err.println("Exception when calling FingerprintApi.searchEvents:" + e.getMessage());
System.exit(1);
}

// Check that old events are still match expected format
try {
final EventSearch oldEvents = api.searchEvents(new FingerprintApi.SearchEventsOptionalParams()
.setLimit(2)
.setStart(start)
.setEnd(end)
.setReverse(true));
assert oldEvents.getEvents() != null;
if (oldEvents.getEvents().isEmpty()) {
System.err.println("FingerprintApi.searchEvents: is empty for old events");
System.exit(1);
}
final Event oldEvent = oldEvents.getEvents().get(0);
assert oldEvent != null;
String oldRequestId = oldEvent.getEventId();
// Get identification event
try {
final Event event = api.getEvent(eventId);
System.out.println(event);
} catch (ApiException e) {
System.err.println("Exception when calling FingerprintApi.getEvent:" + e.getMessage());
System.exit(1);
}

if (eventId.equals(oldRequestId)) {
System.err.println("Old events are identical to new");
System.exit(1);
}
// Update identification event
final String requestIdToUpdate = System.getenv("FPJS_REQUEST_ID_TO_UPDATE");
if (requestIdToUpdate != null) {
try {
final HashMap<String, Object> tags =
new HashMap<>() {
{
put("timestamp", new Timestamp(new Date().getTime()));
}
};
api.updateEvent(requestIdToUpdate, new EventUpdate().tags(tags));
} catch (ApiException e) {
System.err.println("Exception when calling FingerprintApi.updateEvent:" + e.getMessage());
System.exit(1);
}
}

api.getEvent(oldRequestId);
System.out.println("Old events are good");
} catch (ApiException e) {
System.err.println("Exception when trying to read old data:" + e.getMessage());
System.exit(1);
}
// Delete visitor data
final String visitorIdToDelete = System.getenv("FPJS_VISITOR_ID_TO_DELETE");
if (visitorIdToDelete != null) {
try {
api.deleteVisitorData(visitorIdToDelete);
} catch (ApiException e) {
System.err.println("Exception when calling FingerprintApi.deleteVisitor:" + e.getMessage());
System.exit(1);
}
}

System.out.println("Checks Passed");
System.exit(0);
// Check that old events are still match expected format
try {
final EventSearch oldEvents =
api.searchEvents(
new FingerprintApi.SearchEventsOptionalParams()
.setLimit(2)
.setStart(start)
.setEnd(end)
.setReverse(true));
assert oldEvents.getEvents() != null;
if (oldEvents.getEvents().isEmpty()) {
System.err.println("FingerprintApi.searchEvents: is empty for old events");
System.exit(1);
}
final Event oldEvent = oldEvents.getEvents().get(0);
assert oldEvent != null;
String oldRequestId = oldEvent.getEventId();

if (eventId.equals(oldRequestId)) {
System.err.println("Old events are identical to new");
System.exit(1);
}

api.getEvent(oldRequestId);
System.out.println("Old events are good");
} catch (ApiException e) {
System.err.println("Exception when trying to read old data:" + e.getMessage());
System.exit(1);
}

System.out.println("Checks Passed");
System.exit(0);
}
}
31 changes: 14 additions & 17 deletions examples/src/main/java/com/fingerprint/example/SealedResults.java
Original file line number Diff line number Diff line change
@@ -1,26 +1,23 @@
package com.fingerprint.example;

import com.fingerprint.v4.model.Event;
import com.fingerprint.v4.Sealed;

import com.fingerprint.v4.model.Event;
import java.util.Base64;

public class SealedResults {
public static void main(String... args) throws Exception {
String SEALED_RESULT = System.getenv("BASE64_SEALED_RESULT");
String SEALED_KEY = System.getenv("BASE64_KEY");
public static void main(String... args) throws Exception {
String SEALED_RESULT = System.getenv("BASE64_SEALED_RESULT");
String SEALED_KEY = System.getenv("BASE64_KEY");

final Event event = Sealed.unsealEventResponse(
Base64.getDecoder().decode(SEALED_RESULT),
new Sealed.DecryptionKey[]{
new Sealed.DecryptionKey(
Base64.getDecoder().decode(SEALED_KEY),
Sealed.DecryptionAlgorithm.AES_256_GCM
)
}
);
final Event event =
Sealed.unsealEventResponse(
Base64.getDecoder().decode(SEALED_RESULT),
new Sealed.DecryptionKey[] {
new Sealed.DecryptionKey(
Base64.getDecoder().decode(SEALED_KEY), Sealed.DecryptionAlgorithm.AES_256_GCM)
});

System.out.println(event);
System.exit(0);
}
System.out.println(event);
System.exit(0);
}
}
Loading
Loading