diff --git a/.github/workflows/docs_enforcement.yml b/.github/workflows/docs_enforcement.yml
new file mode 100644
index 00000000..213c85c7
--- /dev/null
+++ b/.github/workflows/docs_enforcement.yml
@@ -0,0 +1,57 @@
+name: Documentation Enforcement
+
+env:
+ PLATFORM: java-sdk
+
+on:
+ pull_request:
+ branches:
+ - 'master'
+
+jobs:
+ extract_version:
+ runs-on: ubuntu-latest
+ name: Extract release version
+ outputs:
+ version: ${{ steps.version.outputs.value }}
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v4
+
+ - name: Setup Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version: '22'
+
+ - name: Get package version
+ id: version
+ run: echo "value=$(node -p -e "require('./px_metadata.json').version")" >> "$GITHUB_OUTPUT"
+
+ check_open_docs_pr:
+ runs-on: ubuntu-latest
+ name: Check for Open Docs PR
+ needs: extract_version
+ steps:
+ - name: Construct expected branch name
+ id: branch_details
+ run: |
+ VERSION=${{ needs.extract_version.outputs.version }}
+ BRANCH_NAME="${{ env.PLATFORM }}-${VERSION}-doc-update"
+ echo "Expected branch name is: $BRANCH_NAME"
+ echo "branch_name=$BRANCH_NAME" >> "$GITHUB_OUTPUT"
+
+ - name: Check for open PR from docs branch
+ env:
+ GH_TOKEN: ${{ secrets.CONNECT_PULL_TOKEN }}
+ DOCS_REPO: ${{ github.repository_owner }}/public-docs
+ EXPECTED_BRANCH_NAME: ${{ steps.branch_details.outputs.branch_name }}
+ run: |
+ echo "Searching for an open PR from branch '$EXPECTED_BRANCH_NAME' in repo '$DOCS_REPO'..."
+
+ if gh pr list --repo "$DOCS_REPO" --state open --base main --limit 100 --json headRefName --jq '.[].headRefName' | grep -qFx "$EXPECTED_BRANCH_NAME"; then
+ echo "✅ Success! Found an open PR from branch: '$EXPECTED_BRANCH_NAME'"
+ else
+ echo "❌ Failure! Could not find an open PR in '$DOCS_REPO' from a branch with the exact name: '$EXPECTED_BRANCH_NAME'"
+ echo "Please ensure a documentation PR has been opened against the 'main' branch before merging this release."
+ exit 1
+ fi
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5b502004..8d702f34 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,9 @@
# Change Log
+## [v6.15.0](https://github.com/PerimeterX/perimeterx-java-sdk/compare/6.15.0...HEAD) (2025-09-03)
+- Added Documentation enforcement workflow - verify that the documentation is up to date with the latest changes in the codebase
+- Added Telemetry by Risk support
+
## [v6.14.2](https://github.com/PerimeterX/perimeterx-java-sdk/compare/6.14.2...HEAD) (2025-06-15)
- Added Cross Tab Session cookie support on risk_api and async activities
diff --git a/README.md b/README.md
index edd35c1e..431e3c02 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,7 @@
# [PerimeterX](http://www.perimeterx.com) Java SDK
-> Latest stable version: [v6.14.2](https://search.maven.org/#artifactdetails%7Ccom.perimeterx%7Cperimeterx-sdk%7C6.15.0%7Cjar)
+> Latest stable version: [v6.15.0](https://search.maven.org/#artifactdetails%7Ccom.perimeterx%7Cperimeterx-sdk%7C6.15.0%7Cjar)
## Table of Contents
diff --git a/pom.xml b/pom.xml
index 8cfc7cd6..1df8cf3a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -7,7 +7,7 @@
PerimeterX JAVA SDK
com.perimeterx
perimeterx-sdk
- 6.14.2
+ 6.15.0
jar
PerimeterX Java SDK
diff --git a/px_metadata.json b/px_metadata.json
index 62d6972b..6b821421 100644
--- a/px_metadata.json
+++ b/px_metadata.json
@@ -1,5 +1,5 @@
{
- "version": "6.14.2",
+ "version": "6.15.0",
"supported_features": [
"advanced_blocking_response",
"bypass_monitor_header",
diff --git a/src/main/java/com/perimeterx/api/PerimeterX.java b/src/main/java/com/perimeterx/api/PerimeterX.java
index 5409ab0e..22a92084 100644
--- a/src/main/java/com/perimeterx/api/PerimeterX.java
+++ b/src/main/java/com/perimeterx/api/PerimeterX.java
@@ -266,11 +266,21 @@ public void pxPostVerify(ResponseWrapper response, PXContext context) throws PXE
if (response != null && !configuration.isAdditionalS2SActivityHeaderEnabled() && context.isContainCredentialsIntelligence()) {
handleAdditionalS2SActivityWithCI(response, context);
}
+
context.logger.sendMemoryLogs(this.configuration, context);
}
} catch (Exception e) {
context.logger.error("Failed to post verify response. Error :: ", e.getMessage());
}
+
+ // Handle telemetry separately with more specific error handling
+ if (context != null && context.isShouldSendTelemetry()) {
+ try {
+ activityHandler.handleEnforcerTelemetryActivity(this.configuration, UpdateReason.COMMAND, context);
+ } catch (Exception e) {
+ context.logger.error("Failed to send telemetry activity: " + e.getMessage());
+ }
+ }
}
private void handleAdditionalS2SActivityWithCI(ResponseWrapper response, PXContext context) throws PXException {
diff --git a/src/main/java/com/perimeterx/http/mock/MockPXClientFactory.java b/src/main/java/com/perimeterx/http/mock/MockPXClientFactory.java
index f6863636..5b61a3c4 100644
--- a/src/main/java/com/perimeterx/http/mock/MockPXClientFactory.java
+++ b/src/main/java/com/perimeterx/http/mock/MockPXClientFactory.java
@@ -9,13 +9,13 @@ private MockPXClientFactory() {
public static PXClient createPassAllPXClient() {
return MockPXClient.builder()
- .riskResponse(new RiskResponse("uuid", 0, 0, "c", null, null, "", "", "", ""))
+ .riskResponse(new RiskResponse("uuid", 0, 0, "c", null, null, "", "", "", "", null))
.build();
}
public static PXClient createBlockAllPXClient() {
return MockPXClient.builder()
- .riskResponse(new RiskResponse("uuid", 0, 100, "c", null, null, "", "", "", ""))
+ .riskResponse(new RiskResponse("uuid", 0, 100, "c", null, null, "", "", "", "", null))
.build();
}
}
diff --git a/src/main/java/com/perimeterx/internals/PXS2SValidator.java b/src/main/java/com/perimeterx/internals/PXS2SValidator.java
index 95ce5d8c..967c0a10 100644
--- a/src/main/java/com/perimeterx/internals/PXS2SValidator.java
+++ b/src/main/java/com/perimeterx/internals/PXS2SValidator.java
@@ -113,6 +113,9 @@ private void updateContextFromResponse(PXContext pxContext, RiskResponse respons
if (response.getAdditionalRiskInfo() != null) {
pxContext.setAdditionalRiskInfo(response.getAdditionalRiskInfo());
}
+ if (response.getTelemetryRequested() != null && response.getTelemetryRequested()) {
+ pxContext.setShouldSendTelemetry(true);
+ }
}
private boolean isResponseValid(RiskResponse response) {
diff --git a/src/main/java/com/perimeterx/models/PXContext.java b/src/main/java/com/perimeterx/models/PXContext.java
index f8c8cc41..68d30304 100644
--- a/src/main/java/com/perimeterx/models/PXContext.java
+++ b/src/main/java/com/perimeterx/models/PXContext.java
@@ -222,6 +222,7 @@ public class PXContext {
private String pxhd;
private PXHDSource pxhdSource;
private boolean isMonitoredRequest;
+ private boolean shouldSendTelemetry = false;
private LoginData loginData;
private UUID requestId;
private Set sensitiveHeaders;
diff --git a/src/main/java/com/perimeterx/models/httpmodels/RiskResponse.java b/src/main/java/com/perimeterx/models/httpmodels/RiskResponse.java
index 2bee458a..a26ec5f8 100644
--- a/src/main/java/com/perimeterx/models/httpmodels/RiskResponse.java
+++ b/src/main/java/com/perimeterx/models/httpmodels/RiskResponse.java
@@ -36,6 +36,9 @@ public class RiskResponse {
@JsonProperty("additional_risk_info")
private String additionalRiskInfo;
+ @JsonProperty("telemetry_requested")
+ private Boolean telemetryRequested;
+
@JsonCreator
public RiskResponse(@JsonProperty(value = "uuid", required = true) String uuid) {
this.uuid = uuid;
diff --git a/src/test/java/testutils/PXClientMock.java b/src/test/java/testutils/PXClientMock.java
index 6b76801d..b7e17a83 100644
--- a/src/test/java/testutils/PXClientMock.java
+++ b/src/test/java/testutils/PXClientMock.java
@@ -51,7 +51,7 @@ public RiskResponse riskApiCall(PXContext pxContext) {
ObjectMapper mapper = new ObjectMapper();
ObjectNode dataEnrichment = mapper.createObjectNode();
dataEnrichment.put("cookieMonster", "ilai");
- RiskResponse riskResponse = new RiskResponse("uuid", 0, this.score, "c", null, dataEnrichment, "", "", "", "");
+ RiskResponse riskResponse = new RiskResponse("uuid", 0, this.score, "c", null, dataEnrichment, "", "", "", "", null);
if (forceChallenge) {
riskResponse.setAction("j");
riskResponse.setActionData(new RiskResponseBody());
diff --git a/web/pom.xml b/web/pom.xml
index 0a228be3..f064b74d 100644
--- a/web/pom.xml
+++ b/web/pom.xml
@@ -65,7 +65,7 @@
8
8
- 6.14.2
+ 6.15.0