diff --git a/.circleci/config.yml b/.circleci/config.yml
deleted file mode 100644
index 1675c39f..00000000
--- a/.circleci/config.yml
+++ /dev/null
@@ -1,61 +0,0 @@
-version: 2.1
-orbs:
- codecov: codecov/codecov@3
-
-commands:
- checkout-and-build:
- steps:
- - checkout
- - run: chmod +x gradlew
- # Download and cache dependencies
- - restore_cache:
- keys:
- - v1-dependencies-{{ checksum "build.gradle" }}
- # fallback to using the latest cache if no exact match is found
- - v1-dependencies-
- - run: ./gradlew clean build
- - save_cache:
- paths:
- - ~/.m2
- key: v1-dependencies-{{ checksum "build.gradle" }}
- run-tests:
- steps:
- - run: ./gradlew check jacocoTestReport --continue --console=plain
- - codecov/upload
- run-api-diff:
- steps:
- # run apiDiff task
- - run: ./gradlew apiDiff
- - store_artifacts:
- path: lib/build/reports/apiDiff/apiDiff.txt
- - store_artifacts:
- path: lib/build/reports/apiDiff/apiDiff.html
-jobs:
- build:
- docker:
- - image: openjdk:11.0-jdk
- steps:
- - checkout-and-build
- - run-tests
- environment:
- GRADLE_OPTS: '-Dorg.gradle.jvmargs="-Xmx2048m -XX:+HeapDumpOnOutOfMemoryError"'
- _JAVA_OPTIONS: "-Xms512m -Xmx1024m"
- TERM: dumb
- api-diff:
- docker:
- - image: openjdk:11.0-jdk
- steps:
- - checkout-and-build
- - run-api-diff
- environment:
- GRADLE_OPTS: '-Dorg.gradle.jvmargs="-Xmx2048m -XX:+HeapDumpOnOutOfMemoryError"'
- _JAVA_OPTIONS: "-Xms512m -Xmx1024m"
- TERM: dumb
-
-workflows:
- build-and-test:
- jobs:
- - build
- api-diff:
- jobs:
- - api-diff
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 60f116c0..7958e8bd 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -1 +1 @@
-* @auth0/dx-sdks-engineer
+* @auth0/project-dx-sdks-engineer-codeowner
diff --git a/.github/ISSUE_TEMPLATE/Bug Report.yml b/.github/ISSUE_TEMPLATE/Bug Report.yml
new file mode 100644
index 00000000..d5d861e0
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/Bug Report.yml
@@ -0,0 +1,67 @@
+name: 🐞 Report a bug
+description: Have you found a bug or issue? Create a bug report for this library
+labels: ["bug"]
+
+body:
+ - type: markdown
+ attributes:
+ value: |
+ **Please do not report security vulnerabilities here**. The [Responsible Disclosure Program](https://auth0.com/responsible-disclosure-policy) details the procedure for disclosing security issues.
+
+ - type: checkboxes
+ id: checklist
+ attributes:
+ label: Checklist
+ options:
+ - label: I have looked into the [Readme](https://github.com/auth0/java-jwt#readme) and [Examples](https://github.com/auth0/java-jwt/blob/master/EXAMPLES.md), and have not found a suitable solution or answer.
+ required: true
+ - label: I have looked into the [API documentation](https://javadoc.io/doc/com.auth0/java-jwt/latest/index.html) and have not found a suitable solution or answer.
+ required: true
+ - label: I have searched the [issues](https://github.com/auth0/java-jwt/issues) and have not found a suitable solution or answer.
+ required: true
+ - label: I have searched the [Auth0 Community](https://community.auth0.com) forums and have not found a suitable solution or answer.
+ required: true
+ - label: I agree to the terms within the [Auth0 Code of Conduct](https://github.com/auth0/open-source-template/blob/master/CODE-OF-CONDUCT.md).
+ required: true
+
+ - type: textarea
+ id: description
+ attributes:
+ label: Description
+ description: Provide a clear and concise description of the issue, including what you expected to happen.
+ validations:
+ required: true
+
+ - type: textarea
+ id: reproduction
+ attributes:
+ label: Reproduction
+ description: Detail the steps taken to reproduce this error, and whether this issue can be reproduced consistently or if it is intermittent.
+ placeholder: |
+ 1. Step 1...
+ 2. Step 2...
+ 3. ...
+ validations:
+ required: true
+
+ - type: textarea
+ id: additional-context
+ attributes:
+ label: Additional context
+ description: Other libraries that might be involved, or any other relevant information you think would be useful.
+ validations:
+ required: false
+
+ - type: input
+ id: environment-version
+ attributes:
+ label: java-jwt version
+ validations:
+ required: true
+
+ - type: input
+ id: environment-java-version
+ attributes:
+ label: Java version
+ validations:
+ required: true
diff --git a/.github/ISSUE_TEMPLATE/Feature Request.yml b/.github/ISSUE_TEMPLATE/Feature Request.yml
new file mode 100644
index 00000000..38fee433
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/Feature Request.yml
@@ -0,0 +1,53 @@
+name: 🧩 Feature request
+description: Suggest an idea or a feature for this library
+labels: ["feature request"]
+
+body:
+ - type: checkboxes
+ id: checklist
+ attributes:
+ label: Checklist
+ options:
+ - label: I have looked into the [Readme](https://github.com/auth0/java-jwt#readme) and [Examples](https://github.com/auth0/java-jwt/blob/master/EXAMPLES.md), and have not found a suitable solution or answer.
+ required: true
+ - label: I have looked into the [API documentation](https://javadoc.io/doc/com.auth0/java-jwt/latest/index.html) and have not found a suitable solution or answer.
+ required: true
+ - label: I have searched the [issues](https://github.com/auth0/java-jwt/issues) and have not found a suitable solution or answer.
+ required: true
+ - label: I have searched the [Auth0 Community](https://community.auth0.com) forums and have not found a suitable solution or answer.
+ required: true
+ - label: I agree to the terms within the [Auth0 Code of Conduct](https://github.com/auth0/open-source-template/blob/master/CODE-OF-CONDUCT.md).
+ required: true
+
+ - type: textarea
+ id: description
+ attributes:
+ label: Describe the problem you'd like to have solved
+ description: A clear and concise description of what the problem is.
+ placeholder: I'm always frustrated when...
+ validations:
+ required: true
+
+ - type: textarea
+ id: ideal-solution
+ attributes:
+ label: Describe the ideal solution
+ description: A clear and concise description of what you want to happen.
+ validations:
+ required: true
+
+ - type: textarea
+ id: alternatives-and-workarounds
+ attributes:
+ label: Alternatives and current workarounds
+ description: A clear and concise description of any alternatives you've considered or any workarounds that are currently in place.
+ validations:
+ required: false
+
+ - type: textarea
+ id: additional-context
+ attributes:
+ label: Additional context
+ description: Add any other context or screenshots about the feature request here.
+ validations:
+ required: false
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
index 3cd7aa53..f58e0249 100644
--- a/.github/ISSUE_TEMPLATE/config.yml
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -1,8 +1,5 @@
blank_issues_enabled: false
contact_links:
- name: Auth0 Community
- url: https://community.auth0.com/c/sdks/5
- about: Discuss this SDK in the Auth0 Community forums
- - name: Library Documentation
- url: https://github.com/auth0/java-jwt/blob/master/README.md
- about: Read the library documentation
+ url: https://community.auth0.com
+ about: Discuss this library in the Auth0 Community forums
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
deleted file mode 100644
index 68352ba2..00000000
--- a/.github/ISSUE_TEMPLATE/feature_request.md
+++ /dev/null
@@ -1,39 +0,0 @@
----
-name: Feature request
-about: Suggest an idea or a feature for this project
-title: ''
-labels: feature request
-assignees: ''
----
-
-
-
-### Describe the problem you'd like to have solved
-
-
-
-### Describe the ideal solution
-
-
-
-## Alternatives and current work-arounds
-
-
-
-### Additional information, if any
-
-
\ No newline at end of file
diff --git a/.github/ISSUE_TEMPLATE/report-a-bug.md b/.github/ISSUE_TEMPLATE/report-a-bug.md
deleted file mode 100644
index e5cf8c46..00000000
--- a/.github/ISSUE_TEMPLATE/report-a-bug.md
+++ /dev/null
@@ -1,55 +0,0 @@
----
-name: Report a bug
-about: Have you found a bug or issue? Create a bug report for this SDK
-title: ''
-labels: bug report
-assignees: ''
----
-
-
-
-### Describe the problem
-
-
-
-### What was the expected behavior?
-
-
-
-### Reproduction
-
-
-- Step 1..
-- Step 2..
-- ...
-
-### Environment
-
-
-
-- **Version of this library used:**
-- **Version of Java used:**
-- **Other modules/plugins/libraries that might be involved:**
-- **Any other relevant information you think would be useful:**
diff --git a/.github/actions/get-prerelease/action.yml b/.github/actions/get-prerelease/action.yml
new file mode 100644
index 00000000..ce7acdc3
--- /dev/null
+++ b/.github/actions/get-prerelease/action.yml
@@ -0,0 +1,30 @@
+name: Return a boolean indicating if the version contains prerelease identifiers
+
+#
+# Returns a simple true/false boolean indicating whether the version indicates it's a prerelease or not.
+#
+# TODO: Remove once the common repo is public.
+#
+
+inputs:
+ version:
+ required: true
+
+outputs:
+ prerelease:
+ value: ${{ steps.get_prerelease.outputs.PRERELEASE }}
+
+runs:
+ using: composite
+
+ steps:
+ - id: get_prerelease
+ shell: bash
+ run: |
+ if [[ "${VERSION}" == *"beta"* || "${VERSION}" == *"alpha"* ]]; then
+ echo "PRERELEASE=true" >> $GITHUB_OUTPUT
+ else
+ echo "PRERELEASE=false" >> $GITHUB_OUTPUT
+ fi
+ env:
+ VERSION: ${{ inputs.version }}
diff --git a/.github/actions/get-release-notes/action.yml b/.github/actions/get-release-notes/action.yml
new file mode 100644
index 00000000..287d2066
--- /dev/null
+++ b/.github/actions/get-release-notes/action.yml
@@ -0,0 +1,42 @@
+name: Return the release notes extracted from the body of the PR associated with the release.
+
+#
+# Returns the release notes from the content of a pull request linked to a release branch. It expects the branch name to be in the format release/vX.Y.Z, release/X.Y.Z, release/vX.Y.Z-beta.N. etc.
+#
+# TODO: Remove once the common repo is public.
+#
+inputs:
+ version:
+ required: true
+ repo_name:
+ required: false
+ repo_owner:
+ required: true
+ token:
+ required: true
+
+outputs:
+ release-notes:
+ value: ${{ steps.get_release_notes.outputs.RELEASE_NOTES }}
+
+runs:
+ using: composite
+
+ steps:
+ - uses: actions/github-script@v7
+ id: get_release_notes
+ with:
+ result-encoding: string
+ script: |
+ const { data: pulls } = await github.rest.pulls.list({
+ owner: process.env.REPO_OWNER,
+ repo: process.env.REPO_NAME,
+ state: 'all',
+ head: `${process.env.REPO_OWNER}:release/${process.env.VERSION}`,
+ });
+ core.setOutput('RELEASE_NOTES', pulls[0].body);
+ env:
+ GITHUB_TOKEN: ${{ inputs.token }}
+ REPO_OWNER: ${{ inputs.repo_owner }}
+ REPO_NAME: ${{ inputs.repo_name }}
+ VERSION: ${{ inputs.version }}
diff --git a/.github/actions/get-version/action.yml b/.github/actions/get-version/action.yml
new file mode 100644
index 00000000..9440ec92
--- /dev/null
+++ b/.github/actions/get-version/action.yml
@@ -0,0 +1,21 @@
+name: Return the version extracted from the branch name
+
+#
+# Returns the version from the .version file.
+#
+# TODO: Remove once the common repo is public.
+#
+
+outputs:
+ version:
+ value: ${{ steps.get_version.outputs.VERSION }}
+
+runs:
+ using: composite
+
+ steps:
+ - id: get_version
+ shell: bash
+ run: |
+ VERSION=$(head -1 .version)
+ echo "VERSION=${VERSION}" >> $GITHUB_OUTPUT
diff --git a/.github/actions/maven-publish/action.yml b/.github/actions/maven-publish/action.yml
new file mode 100644
index 00000000..01e3a621
--- /dev/null
+++ b/.github/actions/maven-publish/action.yml
@@ -0,0 +1,44 @@
+name: Publish release to Java
+
+inputs:
+ java-version:
+ required: true
+ ossr-username:
+ required: true
+ ossr-token:
+ required: true
+ signing-key:
+ required: true
+ signing-password:
+ required: true
+
+runs:
+ using: composite
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v4
+
+ - name: Setup Java
+ shell: bash
+ run: |
+ curl -s "https://get.sdkman.io" | bash
+ source "/home/runner/.sdkman/bin/sdkman-init.sh"
+ sdk list java
+ sdk install java ${{ inputs.java-version }} && sdk default java ${{ inputs.java-version }}
+ export JAVA_HOME=${SDKMAN_DIR}/candidates/java/current
+ echo "JAVA_HOME is set to $JAVA_HOME"
+
+ - uses: gradle/wrapper-validation-action@56b90f209b02bf6d1deae490e9ef18b21a389cd4 # pin@1.1.0
+ env:
+ JAVA_HOME: ${{ env.JAVA_HOME }}
+
+ - name: Publish Android/Java Packages to Maven
+ shell: bash
+ run: ./gradlew publish -PisSnapshot=false --stacktrace
+ env:
+ JAVA_HOME: ${{ env.JAVA_HOME }}
+ MAVEN_USERNAME: ${{ inputs.ossr-username }}
+ MAVEN_PASSWORD: ${{ inputs.ossr-token }}
+ SIGNING_KEY: ${{ inputs.signing-key}}
+ SIGNING_PASSWORD: ${{ inputs.signing-password}}
\ No newline at end of file
diff --git a/.github/actions/release-create/action.yml b/.github/actions/release-create/action.yml
new file mode 100644
index 00000000..6a2bf804
--- /dev/null
+++ b/.github/actions/release-create/action.yml
@@ -0,0 +1,47 @@
+name: Create a GitHub release
+
+#
+# Creates a GitHub release with the given version.
+#
+# TODO: Remove once the common repo is public.
+#
+
+inputs:
+ token:
+ required: true
+ files:
+ required: false
+ name:
+ required: true
+ body:
+ required: true
+ tag:
+ required: true
+ commit:
+ required: true
+ draft:
+ default: false
+ required: false
+ prerelease:
+ default: false
+ required: false
+ fail_on_unmatched_files:
+ default: true
+ required: false
+
+runs:
+ using: composite
+
+ steps:
+ - uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844
+ with:
+ body: ${{ inputs.body }}
+ name: ${{ inputs.name }}
+ tag_name: ${{ inputs.tag }}
+ target_commitish: ${{ inputs.commit }}
+ draft: ${{ inputs.draft }}
+ prerelease: ${{ inputs.prerelease }}
+ fail_on_unmatched_files: ${{ inputs.fail_on_unmatched_files }}
+ files: ${{ inputs.files }}
+ env:
+ GITHUB_TOKEN: ${{ inputs.token }}
diff --git a/.github/actions/rl-scanner/action.yml b/.github/actions/rl-scanner/action.yml
new file mode 100644
index 00000000..fbf81217
--- /dev/null
+++ b/.github/actions/rl-scanner/action.yml
@@ -0,0 +1,66 @@
+name: 'Reversing Labs Scanner'
+description: 'Runs the Reversing Labs scanner on a specified artifact.'
+inputs:
+ artifact-path:
+ description: 'Path to the artifact to be scanned.'
+ required: true
+ version:
+ description: 'Version of the artifact.'
+ required: true
+
+runs:
+ using: 'composite'
+ steps:
+ - name: Set up Python
+ uses: actions/setup-python@v4
+ with:
+ python-version: '3.10'
+
+ - name: Install Python dependencies
+ shell: bash
+ run: |
+ pip install boto3 requests
+ - name: Configure AWS credentials
+ uses: aws-actions/configure-aws-credentials@v1
+ with:
+ role-to-assume: ${{ env.PRODSEC_TOOLS_ARN }}
+ aws-region: us-east-1
+ mask-aws-account-id: true
+
+ - name: Install RL Wrapper
+ shell: bash
+ run: |
+ pip install rl-wrapper>=1.0.0 --index-url "https://${{ env.PRODSEC_TOOLS_USER }}:${{ env.PRODSEC_TOOLS_TOKEN }}@a0us.jfrog.io/artifactory/api/pypi/python-local/simple"
+ - name: Run RL Scanner
+ shell: bash
+ env:
+ RLSECURE_LICENSE: ${{ env.RLSECURE_LICENSE }}
+ RLSECURE_SITE_KEY: ${{ env.RLSECURE_SITE_KEY }}
+ SIGNAL_HANDLER_TOKEN: ${{ env.SIGNAL_HANDLER_TOKEN }}
+ PYTHONUNBUFFERED: 1
+ run: |
+ if [ ! -f "${{ inputs.artifact-path }}" ]; then
+ echo "Artifact not found: ${{ inputs.artifact-path }}"
+ exit 1
+ fi
+ rl-wrapper \
+ --artifact "${{ inputs.artifact-path }}" \
+ --name "${{ github.event.repository.name }}" \
+ --version "${{ inputs.version }}" \
+ --repository "${{ github.repository }}" \
+ --commit "${{ github.sha }}" \
+ --build-env "github_actions" \
+ --suppress_output
+ # Check the outcome of the scanner
+ if [ $? -ne 0 ]; then
+ echo "RL Scanner failed."
+ echo "scan-status=failed" >> $GITHUB_ENV
+ exit 1
+ else
+ echo "RL Scanner passed."
+ echo "scan-status=success" >> $GITHUB_ENV
+ fi
+outputs:
+ scan-status:
+ description: 'The outcome of the scan process.'
+ value: ${{ env.scan-status }}
\ No newline at end of file
diff --git a/.github/actions/tag-exists/action.yml b/.github/actions/tag-exists/action.yml
new file mode 100644
index 00000000..b5fbdb73
--- /dev/null
+++ b/.github/actions/tag-exists/action.yml
@@ -0,0 +1,36 @@
+name: Return a boolean indicating if a tag already exists for the repository
+
+#
+# Returns a simple true/false boolean indicating whether the tag exists or not.
+#
+# TODO: Remove once the common repo is public.
+#
+
+inputs:
+ token:
+ required: true
+ tag:
+ required: true
+
+outputs:
+ exists:
+ description: 'Whether the tag exists or not'
+ value: ${{ steps.tag-exists.outputs.EXISTS }}
+
+runs:
+ using: composite
+
+ steps:
+ - id: tag-exists
+ shell: bash
+ run: |
+ GET_API_URL="https://api.github.com/repos/${GITHUB_REPOSITORY}/git/ref/tags/${TAG_NAME}"
+ http_status_code=$(curl -LI $GET_API_URL -o /dev/null -w '%{http_code}\n' -s -H "Authorization: token ${GITHUB_TOKEN}")
+ if [ "$http_status_code" -ne "404" ] ; then
+ echo "EXISTS=true" >> $GITHUB_OUTPUT
+ else
+ echo "EXISTS=false" >> $GITHUB_OUTPUT
+ fi
+ env:
+ TAG_NAME: ${{ inputs.tag }}
+ GITHUB_TOKEN: ${{ inputs.token }}
diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml
new file mode 100644
index 00000000..f86ed60e
--- /dev/null
+++ b/.github/workflows/build-and-test.yml
@@ -0,0 +1,27 @@
+name: auth0/java-jwt/build-and-test
+
+on:
+ pull_request:
+ merge_group:
+ push:
+ branches: ["master", "main", "v1"]
+
+jobs:
+ gradle:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ - uses: actions/setup-java@v3
+ with:
+ distribution: temurin
+ java-version: 11
+ - uses: gradle/gradle-build-action@a4cf152f482c7ca97ef56ead29bf08bcd953284c
+ with:
+ arguments: assemble apiDiff check jacocoTestReport --continue --console=plain
+ - uses: codecov/codecov-action@eaaf4bedf32dbdc6b720b63067d99c4d77d6047d
+ with:
+ flags: unittests
+ - uses: actions/upload-artifact@v3
+ with:
+ name: Reports
+ path: lib/build/reports
diff --git a/.github/workflows/dependabot.yml b/.github/workflows/dependabot.yml
new file mode 100644
index 00000000..f2839f50
--- /dev/null
+++ b/.github/workflows/dependabot.yml
@@ -0,0 +1,14 @@
+version: 2
+updates:
+ - package-ecosystem: "github-actions"
+ directory: "/"
+ schedule:
+ interval: "daily"
+
+ - package-ecosystem: "gradle"
+ directory: "lib"
+ schedule:
+ interval: "daily"
+ ignore:
+ - dependency-name: "*"
+ update-types: ["version-update:semver-major"]
\ No newline at end of file
diff --git a/.github/workflows/gradle-wrapper-validation.yml b/.github/workflows/gradle-wrapper-validation.yml
index a015578a..ce302cb4 100644
--- a/.github/workflows/gradle-wrapper-validation.yml
+++ b/.github/workflows/gradle-wrapper-validation.yml
@@ -6,5 +6,5 @@ jobs:
name: "validation/gradlew"
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v2
- - uses: gradle/wrapper-validation-action@v1
+ - uses: actions/checkout@v3
+ - uses: gradle/wrapper-validation-action@8d49e559aae34d3e0eb16cde532684bc9702762b # pin@v1.0.6
diff --git a/.github/workflows/java-release.yml b/.github/workflows/java-release.yml
new file mode 100644
index 00000000..00771307
--- /dev/null
+++ b/.github/workflows/java-release.yml
@@ -0,0 +1,91 @@
+name: Create Java and GitHub Release
+
+on:
+ workflow_call:
+ inputs:
+ java-version:
+ required: true
+ type: string
+ secrets:
+ ossr-username:
+ required: true
+ ossr-token:
+ required: true
+ signing-key:
+ required: true
+ signing-password:
+ required: true
+ github-token:
+ required: true
+
+### TODO: Replace instances of './.github/actions/' w/ `auth0/dx-sdk-actions/` and append `@latest` after the common `dx-sdk-actions` repo is made public.
+### TODO: Also remove `get-prerelease`, `get-version`, `release-create`, `tag-create` and `tag-exists` actions from this repo's .github/actions folder once the repo is public.
+
+jobs:
+ release:
+ if: github.event_name == 'workflow_dispatch' || (github.event_name == 'pull_request' && github.event.pull_request.merged && startsWith(github.event.pull_request.head.ref, 'release/'))
+ runs-on: ubuntu-latest
+ environment: release
+
+ steps:
+ # Checkout the code
+ - uses: actions/checkout@v4
+ with:
+ fetch-depth: 0
+
+ # Get the version from the branch name
+ - id: get_version
+ uses: ./.github/actions/get-version
+
+ # Get the prerelease flag from the branch name
+ - id: get_prerelease
+ uses: ./.github/actions/get-prerelease
+ with:
+ version: ${{ steps.get_version.outputs.version }}
+
+ # Get the release notes
+ - id: get_release_notes
+ uses: ./.github/actions/get-release-notes
+ with:
+ token: ${{ secrets.github-token }}
+ version: ${{ steps.get_version.outputs.version }}
+ repo_owner: ${{ github.repository_owner }}
+ repo_name: ${{ github.event.repository.name }}
+
+ # Check if the tag already exists
+ - id: tag_exists
+ uses: ./.github/actions/tag-exists
+ with:
+ tag: ${{ steps.get_version.outputs.version }}
+ token: ${{ secrets.github-token }}
+
+ # If the tag already exists, exit with an error
+ - if: steps.tag_exists.outputs.exists == 'true'
+ run: exit 1
+
+ # Set JAVA_HOME here and pass it to subsequent steps
+ - name: Set JAVA_HOME for Gradle
+ run: echo "JAVA_HOME=/home/runner/.sdkman/candidates/java/current" >> $GITHUB_ENV # This ensures JAVA_HOME is set globally
+ env:
+ SDKMAN_DIR: /home/runner/.sdkman
+
+ # Publish the release to Maven
+ - uses: ./.github/actions/maven-publish
+ with:
+ java-version: ${{ inputs.java-version }}
+ ossr-username: ${{ secrets.ossr-username }}
+ ossr-token: ${{ secrets.ossr-token }}
+ signing-key: ${{ secrets.signing-key }}
+ signing-password: ${{ secrets.signing-password }}
+ env:
+ JAVA_HOME: ${{ env.JAVA_HOME }}
+
+ # Create a release for the tag
+ - uses: ./.github/actions/release-create
+ with:
+ token: ${{ secrets.github-token }}
+ name: ${{ steps.get_version.outputs.version }}
+ body: ${{ steps.get_release_notes.outputs.release-notes }}
+ tag: ${{ steps.get_version.outputs.version }}
+ commit: ${{ github.sha }}
+ prerelease: ${{ steps.get_prerelease.outputs.prerelease }}
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
new file mode 100644
index 00000000..2b00e426
--- /dev/null
+++ b/.github/workflows/release.yml
@@ -0,0 +1,40 @@
+name: Create GitHub Release
+
+on:
+ pull_request:
+ types:
+ - closed
+ workflow_dispatch:
+
+permissions:
+ contents: write
+ id-token: write # This is required for requesting the JWT
+
+### TODO: Replace instances of './.github/workflows/' w/ `auth0/dx-sdk-actions/workflows/` and append `@latest` after the common `dx-sdk-actions` repo is made public.
+### TODO: Also remove `get-prerelease`, `get-release-notes`, `get-version`, `maven-publish`, `release-create`, and `tag-exists` actions from this repo's .github/actions folder once the repo is public.
+### TODO: Also remove `java-release` workflow from this repo's .github/workflows folder once the repo is public.
+
+jobs:
+ rl-scanner:
+ uses: ./.github/workflows/rl-secure.yml
+ with:
+ java-version: 11
+ artifact-name: 'java-jwt.tgz'
+ secrets:
+ RLSECURE_LICENSE: ${{ secrets.RLSECURE_LICENSE }}
+ RLSECURE_SITE_KEY: ${{ secrets.RLSECURE_SITE_KEY }}
+ SIGNAL_HANDLER_TOKEN: ${{ secrets.SIGNAL_HANDLER_TOKEN }}
+ PRODSEC_TOOLS_USER: ${{ secrets.PRODSEC_TOOLS_USER }}
+ PRODSEC_TOOLS_TOKEN: ${{ secrets.PRODSEC_TOOLS_TOKEN }}
+ PRODSEC_TOOLS_ARN: ${{ secrets.PRODSEC_TOOLS_ARN }}
+ release:
+ uses: ./.github/workflows/java-release.yml
+ needs: rl-scanner
+ with:
+ java-version: 11.0.21-tem
+ secrets:
+ ossr-username: ${{ secrets.OSSR_USERNAME }}
+ ossr-token: ${{ secrets.OSSR_TOKEN }}
+ signing-key: ${{ secrets.SIGNING_KEY }}
+ signing-password: ${{ secrets.SIGNING_PASSWORD }}
+ github-token: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/rl-secure.yml b/.github/workflows/rl-secure.yml
new file mode 100644
index 00000000..ef329594
--- /dev/null
+++ b/.github/workflows/rl-secure.yml
@@ -0,0 +1,73 @@
+name: RL-Secure Workflow
+
+on:
+ workflow_call:
+ inputs:
+ java-version:
+ required: true
+ type: string
+ artifact-name:
+ required: true
+ type: string
+ secrets:
+ RLSECURE_LICENSE:
+ required: true
+ RLSECURE_SITE_KEY:
+ required: true
+ SIGNAL_HANDLER_TOKEN:
+ required: true
+ PRODSEC_TOOLS_USER:
+ required: true
+ PRODSEC_TOOLS_TOKEN:
+ required: true
+ PRODSEC_TOOLS_ARN:
+ required: true
+
+jobs:
+ checkout-build-scan-only:
+ if: github.event_name == 'workflow_dispatch' || (github.event_name == 'pull_request' && github.event.pull_request.merged && startsWith(github.event.pull_request.head.ref, 'release/'))
+ runs-on: ubuntu-latest
+ outputs:
+ scan-status: ${{ steps.rl-scan-conclusion.outcome }}
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v4
+ with:
+ fetch-depth: 0
+
+ - name: Set up Java
+ uses: actions/setup-java@v4
+ with:
+ distribution: temurin
+ java-version: ${{ inputs.java-version }}
+
+ - name: Build with Gradle
+ uses: gradle/gradle-build-action@a4cf152f482c7ca97ef56ead29bf08bcd953284c
+ with:
+ arguments: assemble apiDiff check jacocoTestReport --continue --console=plain
+
+ - name: Get Artifact Version
+ id: get_version
+ uses: ./.github/actions/get-version
+
+ - name: Create tgz build artifact
+ run: |
+ tar -czvf ${{ inputs.artifact-name }} *
+
+ - name: Run RL Scanner
+ id: rl-scan-conclusion
+ uses: ./.github/actions/rl-scanner
+ with:
+ artifact-path: "$(pwd)/${{ inputs.artifact-name }}"
+ version: "${{ steps.get_version.outputs.version }}"
+ env:
+ RLSECURE_LICENSE: ${{ secrets.RLSECURE_LICENSE }}
+ RLSECURE_SITE_KEY: ${{ secrets.RLSECURE_SITE_KEY }}
+ SIGNAL_HANDLER_TOKEN: ${{ secrets.SIGNAL_HANDLER_TOKEN }}
+ PRODSEC_TOOLS_USER: ${{ secrets.PRODSEC_TOOLS_USER }}
+ PRODSEC_TOOLS_TOKEN: ${{ secrets.PRODSEC_TOOLS_TOKEN }}
+ PRODSEC_TOOLS_ARN: ${{ secrets.PRODSEC_TOOLS_ARN }}
+
+ - name: Output scan result
+ run: echo "scan-status=${{ steps.rl-scan-conclusion.outcome }}" >> $GITHUB_ENV
\ No newline at end of file
diff --git a/.github/workflows/snyk.yml b/.github/workflows/snyk.yml
new file mode 100644
index 00000000..457b6afa
--- /dev/null
+++ b/.github/workflows/snyk.yml
@@ -0,0 +1,39 @@
+name: Snyk
+
+on:
+ merge_group:
+ workflow_dispatch:
+ pull_request:
+ types:
+ - opened
+ - synchronize
+ push:
+ branches:
+ - master
+ schedule:
+ - cron: '30 0 1,15 * *'
+
+permissions:
+ contents: read
+
+concurrency:
+ group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
+ cancel-in-progress: ${{ github.ref != 'refs/heads/master' }}
+
+jobs:
+
+ check:
+ name: Check for Vulnerabilities
+ runs-on: ubuntu-latest
+
+ steps:
+ - if: github.actor == 'dependabot[bot]' || github.event_name == 'merge_group'
+ run: exit 0 # Skip unnecessary test runs for dependabot and merge queues. Artifically flag as successful, as this is a required check for branch protection.
+
+ - uses: actions/checkout@v4
+ with:
+ ref: ${{ github.event.pull_request.head.sha || github.ref }}
+
+ - uses: snyk/actions/gradle-jdk11@b98d498629f1c368650224d6d212bf7dfa89e4bf # pin@0.4.0
+ env:
+ SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
\ No newline at end of file
diff --git a/.shiprc b/.shiprc
index fe59345e..1b83cc62 100644
--- a/.shiprc
+++ b/.shiprc
@@ -1,6 +1,7 @@
{
"files": {
"README.md": [],
+ ".version": [],
"lib/build.gradle": ["version = \"{MAJOR}.{MINOR}.{PATCH}\""]
},
"prefixVersion": false
diff --git a/.version b/.version
new file mode 100644
index 00000000..ae153944
--- /dev/null
+++ b/.version
@@ -0,0 +1 @@
+4.5.0
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1b1e75bd..b97fab71 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,49 @@
# Change Log
+## [4.5.0](https://github.com/auth0/java-jwt/tree/4.5.0) (2025-01-29)
+[Full Changelog](https://github.com/auth0/java-jwt/compare/4.4.0...4.5.0)
+
+**Added**
+- Upgraded Plugin [\#711](https://github.com/auth0/java-jwt/pull/711) ([tanya732](https://github.com/tanya732))
+- Fix jackson vuln [\#705](https://github.com/auth0/java-jwt/pull/705) ([tanya732](https://github.com/tanya732))
+- Fix typo in example code [\#682](https://github.com/auth0/java-jwt/pull/682) ([kasperkarlsson](https://github.com/kasperkarlsson))
+- Remove dead README links [\#676](https://github.com/auth0/java-jwt/pull/676) ([jimmyjames](https://github.com/jimmyjames))
+- Fix typo on a comment in JWTCreator.java [\#672](https://github.com/auth0/java-jwt/pull/672) ([sgc109](https://github.com/sgc109))
+- Remove CircleCI [\#670](https://github.com/auth0/java-jwt/pull/670) ([jimmyjames](https://github.com/jimmyjames))
+- Empty string audience claim should be deserialized as empty string [\#663](https://github.com/auth0/java-jwt/pull/663) ([jimmyjames](https://github.com/jimmyjames))
+
+**Fixed**
+- empty expected audience array should throw InvalidClaimException [\#679](https://github.com/auth0/java-jwt/pull/679) ([jimmyjames](https://github.com/jimmyjames))
+
+## [4.5.0](https://github.com/auth0/java-jwt/tree/4.5.0) (2025-01-28)
+[Full Changelog](https://github.com/auth0/java-jwt/compare/4.4.0...4.5.0)
+
+**Added**
+- Upgraded Plugin [\#711](https://github.com/auth0/java-jwt/pull/711) ([tanya732](https://github.com/tanya732))
+- Fix jackson vuln [\#705](https://github.com/auth0/java-jwt/pull/705) ([tanya732](https://github.com/tanya732))
+- Fix typo in example code [\#682](https://github.com/auth0/java-jwt/pull/682) ([kasperkarlsson](https://github.com/kasperkarlsson))
+- Remove dead README links [\#676](https://github.com/auth0/java-jwt/pull/676) ([jimmyjames](https://github.com/jimmyjames))
+- Fix typo on a comment in JWTCreator.java [\#672](https://github.com/auth0/java-jwt/pull/672) ([sgc109](https://github.com/sgc109))
+- Remove CircleCI [\#670](https://github.com/auth0/java-jwt/pull/670) ([jimmyjames](https://github.com/jimmyjames))
+- Empty string audience claim should be deserialized as empty string [\#663](https://github.com/auth0/java-jwt/pull/663) ([jimmyjames](https://github.com/jimmyjames))
+
+**Fixed**
+- empty expected audience array should throw InvalidClaimException [\#679](https://github.com/auth0/java-jwt/pull/679) ([jimmyjames](https://github.com/jimmyjames))
+
+## [4.5.0](https://github.com/auth0/java-jwt/tree/4.5.0) (2025-01-22)
+[Full Changelog](https://github.com/auth0/java-jwt/compare/4.4.0...4.5.0)
+
+**Added**
+- Fix jackson vuln [\#705](https://github.com/auth0/java-jwt/pull/705) ([tanya732](https://github.com/tanya732))
+- Fix typo in example code [\#682](https://github.com/auth0/java-jwt/pull/682) ([kasperkarlsson](https://github.com/kasperkarlsson))
+- Remove dead README links [\#676](https://github.com/auth0/java-jwt/pull/676) ([jimmyjames](https://github.com/jimmyjames))
+- Fix typo on a comment in JWTCreator.java [\#672](https://github.com/auth0/java-jwt/pull/672) ([sgc109](https://github.com/sgc109))
+- Remove CircleCI [\#670](https://github.com/auth0/java-jwt/pull/670) ([jimmyjames](https://github.com/jimmyjames))
+- Empty string audience claim should be deserialized as empty string [\#663](https://github.com/auth0/java-jwt/pull/663) ([jimmyjames](https://github.com/jimmyjames))
+
+**Fixed**
+- empty expected audience array should throw InvalidClaimException [\#679](https://github.com/auth0/java-jwt/pull/679) ([jimmyjames](https://github.com/jimmyjames))
+
## [4.4.0](https://github.com/auth0/java-jwt/tree/4.4.0) (2023-03-31)
[Full Changelog](https://github.com/auth0/java-jwt/compare/4.3.0...4.4.0)
diff --git a/README.md b/README.md
index 9f425898..9d0ae41c 100644
--- a/README.md
+++ b/README.md
@@ -5,7 +5,7 @@

-[](https://circleci.com/gh/auth0/java-jwt/tree/master)
+
[](https://codecov.io/github/auth0/java-jwt)
[](https://doge.mit-license.org/)
[](https://mvnrepository.com/artifact/com.auth0/java-jwt)
@@ -50,14 +50,14 @@ Add the dependency via Maven:
com.auth0
java-jwt
- 4.4.0
+ 4.5.0
```
or Gradle:
```gradle
-implementation 'com.auth0:java-jwt:4.4.0'
+implementation 'com.auth0:java-jwt:4.5.0'
```
### Create a JWT
@@ -89,7 +89,7 @@ DecodedJWT decodedJWT;
try {
Algorithm algorithm = Algorithm.RSA256(rsaPublicKey, rsaPrivateKey);
JWTVerifier verifier = JWT.require(algorithm)
- // specify an specific claim validations
+ // specify any specific claim validations
.withIssuer("auth0")
// reusable verifier instance
.build();
diff --git a/gradle.properties b/gradle.properties
index aac7c9b4..74a5a049 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -15,3 +15,24 @@ org.gradle.jvmargs=-Xmx1536m
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
+
+GROUP=com.auth0
+POM_ARTIFACT_ID=java-jwt
+
+POM_NAME=java jwt
+POM_DESCRIPTION=Java client library for the Auth0 platform
+POM_PACKAGING=jar
+
+POM_URL=https://github.com/auth0/java-jwt
+POM_SCM_URL=https://github.com/auth0/java-jwt
+
+POM_SCM_CONNECTION=scm:git:https://github.com/auth0/java-jwt.git
+POM_SCM_DEV_CONNECTION=scm:git:https://github.com/auth0/java-jwt.git
+
+POM_LICENCE_NAME=The MIT License (MIT)
+POM_LICENCE_URL=https://raw.githubusercontent.com/auth0/java-jwt/master/LICENSE
+POM_LICENCE_DIST=repo
+
+POM_DEVELOPER_ID=auth0
+POM_DEVELOPER_NAME=Auth0
+POM_DEVELOPER_EMAIL=oss@auth0.com
\ No newline at end of file
diff --git a/gradle/maven-publish.gradle b/gradle/maven-publish.gradle
new file mode 100644
index 00000000..a9ad38d3
--- /dev/null
+++ b/gradle/maven-publish.gradle
@@ -0,0 +1,113 @@
+apply plugin: 'maven-publish'
+apply plugin: 'signing'
+
+task('sourcesJar', type: Jar, dependsOn: classes) {
+ archiveClassifier = 'sources'
+ from sourceSets.main.allSource
+}
+
+task('javadocJar', type: Jar, dependsOn: javadoc) {
+ archiveClassifier = 'javadoc'
+ from javadoc.getDestinationDir()
+}
+tasks.withType(Javadoc).configureEach {
+ javadocTool = javaToolchains.javadocToolFor {
+ // Use latest JDK for javadoc generation
+ languageVersion = JavaLanguageVersion.of(17)
+ }
+}
+
+javadoc {
+ // Specify the Java version that the project will use
+ options.addStringOption('-release', "11")
+}
+artifacts {
+ archives sourcesJar, javadocJar
+}
+
+
+final releaseRepositoryUrl = "https://oss.sonatype.org/service/local/staging/deploy/maven2/"
+final snapshotRepositoryUrl = "https://oss.sonatype.org/content/repositories/snapshots/"
+
+publishing {
+ publications {
+ mavenJava(MavenPublication) {
+
+ groupId = GROUP
+ artifactId = POM_ARTIFACT_ID
+ version = getVersionName()
+
+ artifact("$buildDir/libs/${project.name}-${version}.jar")
+ artifact sourcesJar
+ artifact javadocJar
+
+ pom {
+ name = POM_NAME
+ packaging = POM_PACKAGING
+ description = POM_DESCRIPTION
+ url = POM_URL
+
+ licenses {
+ license {
+ name = POM_LICENCE_NAME
+ url = POM_LICENCE_URL
+ distribution = POM_LICENCE_DIST
+ }
+ }
+
+ developers {
+ developer {
+ id = POM_DEVELOPER_ID
+ name = POM_DEVELOPER_NAME
+ email = POM_DEVELOPER_EMAIL
+ }
+ }
+
+ scm {
+ url = POM_SCM_URL
+ connection = POM_SCM_CONNECTION
+ developerConnection = POM_SCM_DEV_CONNECTION
+ }
+
+ pom.withXml {
+ def dependenciesNode = asNode().appendNode('dependencies')
+
+ project.configurations.implementation.allDependencies.each {
+ def dependencyNode = dependenciesNode.appendNode('dependency')
+ dependencyNode.appendNode('groupId', it.group)
+ dependencyNode.appendNode('artifactId', it.name)
+ dependencyNode.appendNode('version', it.version)
+ }
+ }
+ }
+ }
+ }
+ repositories {
+ maven {
+ name = "sonatype"
+ url = version.endsWith('SNAPSHOT') ? snapshotRepositoryUrl : releaseRepositoryUrl
+ credentials {
+ username = System.getenv("MAVEN_USERNAME")
+ password = System.getenv("MAVEN_PASSWORD")
+ }
+ }
+ }
+}
+
+signing {
+ def signingKey = System.getenv("SIGNING_KEY")
+ def signingPassword = System.getenv("SIGNING_PASSWORD")
+ useInMemoryPgpKeys(signingKey, signingPassword)
+
+ sign publishing.publications.mavenJava
+}
+
+javadoc {
+ if(JavaVersion.current().isJava9Compatible()) {
+ options.addBooleanOption('html5', true)
+ }
+}
+
+tasks.named('publish').configure {
+ dependsOn tasks.named('assemble')
+}
\ No newline at end of file
diff --git a/gradle/versioning.gradle b/gradle/versioning.gradle
new file mode 100644
index 00000000..3441ae11
--- /dev/null
+++ b/gradle/versioning.gradle
@@ -0,0 +1,17 @@
+def getVersionFromFile() {
+ def versionFile = rootProject.file('.version')
+ return versionFile.text.readLines().first().trim()
+}
+
+def isSnapshot() {
+ return hasProperty('isSnapshot') ? isSnapshot.toBoolean() : true
+}
+
+def getVersionName() {
+ return isSnapshot() ? project.version+"-SNAPSHOT" : project.version
+}
+
+ext {
+ getVersionName = this.&getVersionName
+ getVersionFromFile = this.&getVersionFromFile
+}
\ No newline at end of file
diff --git a/lib/build.gradle b/lib/build.gradle
index c4e11764..83093fc1 100644
--- a/lib/build.gradle
+++ b/lib/build.gradle
@@ -1,9 +1,19 @@
+buildscript {
+ repositories {
+ jcenter()
+ }
+
+ dependencies {
+ // https://github.com/melix/japicmp-gradle-plugin/issues/36
+ classpath 'com.google.guava:guava:31.1-jre'
+ }
+}
plugins {
id 'java'
id 'jacoco'
- id 'com.auth0.gradle.oss-library.java'
id 'checkstyle'
+ id 'me.champeau.gradle.japicmp' version '0.4.1'
}
sourceSets {
@@ -29,31 +39,71 @@ tasks.named("checkstyleJmh").configure({
enabled = false
})
-logger.lifecycle("Using version ${version} for ${group}.${name}")
+apply from: rootProject.file('gradle/versioning.gradle')
-oss {
- name "java jwt"
- repository "java-jwt"
- organization "auth0"
- description "Java implementation of JSON Web Token (JWT)"
- baselineCompareVersion "4.1.0"
+version = getVersionFromFile()
+group = GROUP
+logger.lifecycle("Using version ${version} for ${name} group $group")
- developers {
- auth0 {
- displayName = "Auth0"
- email = "oss@auth0.com"
+import me.champeau.gradle.japicmp.JapicmpTask
+
+project.afterEvaluate {
+
+ def versions = project.ext.testInJavaVersions
+ for (pluginJavaTestVersion in versions) {
+ def taskName = "testInJava-${pluginJavaTestVersion}"
+ tasks.register(taskName, Test) {
+ def versionToUse = taskName.split("-").getAt(1) as Integer
+ description = "Runs unit tests on Java version ${versionToUse}."
+ project.logger.quiet("Test will be running in ${versionToUse}")
+ group = 'verification'
+ javaLauncher.set(javaToolchains.launcherFor {
+ languageVersion = JavaLanguageVersion.of(versionToUse)
+ })
+ shouldRunAfter(tasks.named('test'))
}
- lbalmaceda {
- displayName = "Luciano Balmaceda"
- email = "luciano.balmaceda@auth0.com"
+ tasks.named('check') {
+ dependsOn(taskName)
}
- hzalaz {
- displayName = "Hernan Zalazar"
- email = "hernan@auth0.com"
+ }
+
+ project.configure(project) {
+ def baselineVersion = project.ext.baselineCompareVersion
+ task('apiDiff', type: JapicmpTask, dependsOn: 'jar') {
+ oldClasspath.from(files(getBaselineJar(project, baselineVersion)))
+ newClasspath.from(files(jar.archiveFile))
+ onlyModified = true
+ failOnModification = true
+ ignoreMissingClasses = true
+ htmlOutputFile = file("$buildDir/reports/apiDiff/apiDiff.html")
+ txtOutputFile = file("$buildDir/reports/apiDiff/apiDiff.txt")
+ doLast {
+ project.logger.quiet("Comparing against baseline version ${baselineVersion}")
+ }
+ }
+ }
+}
+
+private static File getBaselineJar(Project project, String baselineVersion) {
+ // Use detached configuration: https://github.com/square/okhttp/blob/master/build.gradle#L270
+ def group = project.group
+ try {
+ def baseline = "${project.group}:${project.name}:$baselineVersion"
+ project.group = 'virtual_group_for_japicmp'
+ def dependency = project.dependencies.create(baseline + "@jar")
+ return project.configurations.detachedConfiguration(dependency).files.find {
+ it.name == "${project.name}-${baselineVersion}.jar"
}
+ } finally {
+ project.group = group
}
}
+ext {
+ baselineCompareVersion = '4.1.0'
+ testInJavaVersions = [8, 11, 17, 21]
+}
+
java {
toolchain {
languageVersion = JavaLanguageVersion.of(11)
@@ -72,7 +122,8 @@ javadoc {
}
dependencies {
- implementation 'com.fasterxml.jackson.core:jackson-databind:2.14.2'
+ implementation 'com.fasterxml.jackson.core:jackson-core:2.15.4'
+ implementation 'com.fasterxml.jackson.core:jackson-databind:2.15.4'
testImplementation 'org.bouncycastle:bcprov-jdk15on:1.70'
testImplementation 'junit:junit:4.13.2'
@@ -86,7 +137,7 @@ dependencies {
}
jacoco {
- toolVersion = "0.8.7"
+ toolVersion = "0.8.10"
}
jacocoTestReport {
@@ -146,9 +197,20 @@ def testJava17 = tasks.register('testJava17', Test) {
shouldRunAfter(tasks.named('test'))
}
+def testJava21 = tasks.register('testJava21', Test) {
+ description = 'Runs unit tests on Java 21.'
+ group = 'verification'
+
+ javaLauncher.set(javaToolchains.launcherFor {
+ languageVersion = JavaLanguageVersion.of(21)
+ })
+ shouldRunAfter(tasks.named('test'))
+}
+
tasks.named('check') {
dependsOn(testJava8)
dependsOn(testJava17)
+ dependsOn(testJava21)
}
jar {
@@ -158,14 +220,6 @@ jar {
compileModuleInfoJava.dependsOn compileJava
classes.dependsOn compileModuleInfoJava
-// Creates a version.txt file containing the current version of the SDK.
-// This file is picked up and parsed by our Ship Orb to determine the version.
-task exportVersion() {
- doLast {
- new File(rootDir, "version.txt").text = "$version"
- }
-}
-
// you can pass any arguments JMH accepts via Gradle args.
// Example: ./gradlew runJMH --args="-lrf"
tasks.register('runJMH', JavaExec) {
@@ -187,3 +241,4 @@ tasks.register('jmhHelp', JavaExec) {
args '-h'
}
+apply from: rootProject.file('gradle/maven-publish.gradle')
diff --git a/lib/src/main/java/com/auth0/jwt/JWTCreator.java b/lib/src/main/java/com/auth0/jwt/JWTCreator.java
index 0b0d21e4..bfcb9147 100644
--- a/lib/src/main/java/com/auth0/jwt/JWTCreator.java
+++ b/lib/src/main/java/com/auth0/jwt/JWTCreator.java
@@ -582,7 +582,7 @@ private static boolean isBasicType(Object value) {
}
/**
- * Creates a new JWT and signs is with the given algorithm.
+ * Creates a new JWT and signs it with the given algorithm.
*
* @param algorithm used to sign the JWT
* @return a new JWT token
diff --git a/lib/src/main/java/com/auth0/jwt/JWTVerifier.java b/lib/src/main/java/com/auth0/jwt/JWTVerifier.java
index 6cec2026..bf180300 100644
--- a/lib/src/main/java/com/auth0/jwt/JWTVerifier.java
+++ b/lib/src/main/java/com/auth0/jwt/JWTVerifier.java
@@ -364,12 +364,19 @@ private boolean assertInstantIsLessThanOrEqualToNow(Instant claimVal, long leewa
}
private boolean assertValidAudienceClaim(
- List audience,
- List values,
+ List actualAudience,
+ List expectedAudience,
boolean shouldContainAll
) {
- return !(audience == null || (shouldContainAll && !audience.containsAll(values))
- || (!shouldContainAll && Collections.disjoint(audience, values)));
+ if (actualAudience == null || expectedAudience == null) {
+ return false;
+ }
+
+ if (shouldContainAll) {
+ return actualAudience.containsAll(expectedAudience);
+ } else {
+ return !Collections.disjoint(actualAudience, expectedAudience);
+ }
}
private void assertPositive(long leeway) {
diff --git a/lib/src/main/java/com/auth0/jwt/algorithms/Algorithm.java b/lib/src/main/java/com/auth0/jwt/algorithms/Algorithm.java
index 27d79909..248af7c5 100644
--- a/lib/src/main/java/com/auth0/jwt/algorithms/Algorithm.java
+++ b/lib/src/main/java/com/auth0/jwt/algorithms/Algorithm.java
@@ -132,7 +132,6 @@ public static Algorithm RSA512(RSAKey key) throws IllegalArgumentException {
*
* @param secret the secret bytes to use in the verify or signing instance.
* Ensure the length of the secret is at least 256 bit long
- * See HMAC Key Length and Security in README
* @return a valid HMAC256 Algorithm.
* @throws IllegalArgumentException if the provided Secret is null.
*/
@@ -145,7 +144,6 @@ public static Algorithm HMAC256(String secret) throws IllegalArgumentException {
*
* @param secret the secret bytes to use in the verify or signing instance.
* Ensure the length of the secret is at least 256 bit long
- * See HMAC Key Length and Security in README
* @return a valid HMAC256 Algorithm.
* @throws IllegalArgumentException if the provided Secret is null.
*/
@@ -158,7 +156,6 @@ public static Algorithm HMAC256(byte[] secret) throws IllegalArgumentException {
*
* @param secret the secret bytes to use in the verify or signing instance.
* Ensure the length of the secret is at least 384 bit long
- * See HMAC Key Length and Security in README
* @return a valid HMAC384 Algorithm.
* @throws IllegalArgumentException if the provided Secret is null.
*/
@@ -171,7 +168,6 @@ public static Algorithm HMAC384(String secret) throws IllegalArgumentException {
*
* @param secret the secret bytes to use in the verify or signing instance.
* Ensure the length of the secret is at least 384 bit long
- * See HMAC Key Length and Security in README
* @return a valid HMAC384 Algorithm.
* @throws IllegalArgumentException if the provided Secret is null.
*/
@@ -184,7 +180,6 @@ public static Algorithm HMAC384(byte[] secret) throws IllegalArgumentException {
*
* @param secret the secret bytes to use in the verify or signing instance.
* Ensure the length of the secret is at least 512 bit long
- * See HMAC Key Length and Security in README
* @return a valid HMAC512 Algorithm.
* @throws IllegalArgumentException if the provided Secret is null.
*/
@@ -197,7 +192,6 @@ public static Algorithm HMAC512(String secret) throws IllegalArgumentException {
*
* @param secret the secret bytes to use in the verify or signing instance.
* Ensure the length of the secret is at least 512 bit long
- * See HMAC Key Length and Security in README
* @return a valid HMAC512 Algorithm.
* @throws IllegalArgumentException if the provided Secret is null.
*/
diff --git a/lib/src/main/java/com/auth0/jwt/impl/PayloadDeserializer.java b/lib/src/main/java/com/auth0/jwt/impl/PayloadDeserializer.java
index 65fba3ac..b1d32a12 100644
--- a/lib/src/main/java/com/auth0/jwt/impl/PayloadDeserializer.java
+++ b/lib/src/main/java/com/auth0/jwt/impl/PayloadDeserializer.java
@@ -54,7 +54,7 @@ List getStringOrArray(ObjectCodec codec, Map tree, Str
if (node == null || node.isNull() || !(node.isArray() || node.isTextual())) {
return null;
}
- if (node.isTextual() && !node.asText().isEmpty()) {
+ if (node.isTextual()) {
return Collections.singletonList(node.asText());
}
diff --git a/lib/src/test/java/com/auth0/jwt/JWTVerifierTest.java b/lib/src/test/java/com/auth0/jwt/JWTVerifierTest.java
index 5a784b87..732d6365 100644
--- a/lib/src/test/java/com/auth0/jwt/JWTVerifierTest.java
+++ b/lib/src/test/java/com/auth0/jwt/JWTVerifierTest.java
@@ -310,6 +310,21 @@ public void shouldThrowWhenAudienceClaimIsNullWithAnAudience() {
assertThat(e.getClaimValue().asArray(String.class), is(new String[] {null}));
}
+ @Test
+ public void shouldThrowWhenExpectedEmptyList() {
+ IncorrectClaimException e = assertThrows(null, IncorrectClaimException.class, () -> {
+ // Token 'aud': 'wide audience'
+ String token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJ3aWRlIGF1ZGllbmNlIn0.c9anq03XepcuEKWEVsPk9cck0sIIfrT6hHbBsCar49o";
+ JWTVerifier.init(Algorithm.HMAC256("secret"))
+ .withAnyOfAudience(new String[0])
+ .build()
+ .verify(token);
+ });
+ assertThat(e.getMessage(), is("The Claim 'aud' value doesn't contain the required audience."));
+ assertThat(e.getClaimName(), is(RegisteredClaims.AUDIENCE));
+ assertThat(e.getClaimValue().asString(), is("wide audience"));
+ }
+
@Test
public void shouldNotReplaceWhenMultipleChecksAreAdded() {
JWTVerifier verifier = JWTVerifier.init(Algorithm.HMAC256("secret"))
diff --git a/lib/src/test/java/com/auth0/jwt/impl/PayloadDeserializerTest.java b/lib/src/test/java/com/auth0/jwt/impl/PayloadDeserializerTest.java
index 86c4f10f..c3e04013 100644
--- a/lib/src/test/java/com/auth0/jwt/impl/PayloadDeserializerTest.java
+++ b/lib/src/test/java/com/auth0/jwt/impl/PayloadDeserializerTest.java
@@ -145,14 +145,14 @@ public void shouldGetStringArrayWhenParsingTextNode() {
}
@Test
- public void shouldGetEmptyStringArrayWhenParsingEmptyTextNode() {
+ public void shouldGetEmptyStringInArrayWhenParsingEmptyTextNode() {
Map tree = new HashMap<>();
TextNode textNode = new TextNode("");
tree.put("key", textNode);
List values = deserializer.getStringOrArray(objectMapper, tree, "key");
assertThat(values, is(notNullValue()));
- assertThat(values, is(IsEmptyCollection.empty()));
+ assertThat(values, is(IsIterableContaining.hasItem("")));
}
@Test
diff --git a/settings.gradle b/settings.gradle
index 8d5f112c..d3c4c85b 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -2,9 +2,6 @@ pluginManagement {
repositories {
gradlePluginPortal()
}
- plugins {
- id 'com.auth0.gradle.oss-library.java' version '0.17.2'
- }
}
include ':java-jwt'