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
8 changes: 4 additions & 4 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ jobs:

- name: Run tests
if: matrix.android != true
run: ./gradlew ${{ matrix.tasks }} --continue
run: ./gradlew ${{ matrix.tasks }} checkKotlinAbi --continue

- name: Run tests (Android emulator)
if: matrix.android == true
Expand All @@ -96,7 +96,7 @@ jobs:
api-level: ${{ matrix.api-level }}
target: ${{ matrix.target }}
arch: x86_64
script: ./gradlew connectedAndroidDeviceTest --continue
script: ./gradlew connectedAndroidDeviceTest checkKotlinAbi --continue

- name: Publish Test Report
uses: mikepenz/action-junit-report@v6
Expand Down Expand Up @@ -137,8 +137,8 @@ jobs:
run: |
set -o pipefail && xcodebuild test \
-project Subprojects/KJWT-HardwareTesting/iosApp/iosApp.xcodeproj \
-scheme iosApp \
-destination 'platform=iOS Simulator,OS=latest,name=iPhone 16' \
-scheme KJWT-HardwareTestingTests \
-destination 'platform=iOS Simulator,OS=latest,name=iPhone 17' \
2>&1 | xcpretty --report junit --output build/test-results/ios/TEST-ios-hardware.xml

- name: Publish Test Report
Expand Down
6 changes: 6 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ RFC 7515), and JWE (RFC 7516) tokens across JVM, JavaScript, WebAssembly, and Na

# Run all checks
./gradlew check

# Check ABI Compatibility
./gradlew checkKotlinAbi

# Update ABI dumps
./gradlew updateKotlinAbi
```

Tests live in `lib/src/commonTest/kotlin/` and run on all platforms.
Expand Down
23 changes: 23 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,29 @@ The CI pipeline also runs detekt automatically on pull requests and posts inline

The detekt configuration lives in `config/detekt/detekt.yml`. Zero violations are allowed (`maxIssues: 0`).

### ABI Compatibility

The project uses the Kotlin ABI validator to track the public API of every published module. Each module keeps its
ABI dumps in an `api/` directory (`<module>.api` for JVM/Android and `<module>.klib.api` for the other targets).
Declarations annotated with `@InternalKJWTApi` are excluded from the dumps.

Before submitting a PR, run:

```bash
./gradlew checkKotlinAbi
```

This fails if the public API differs from the committed dumps. If your change intentionally modifies the public API
(adding, removing, or changing a public declaration), regenerate the dumps and commit them alongside your change:

```bash
./gradlew updateKotlinAbi
```

Review the resulting diff in the `api/` files carefully: it is the source of truth for what changed in the public
API, and reviewers use it to spot unintended or breaking changes. The CI pipeline runs `checkKotlinAbi` on every pull
request.

### Writing Tests

Tests live in `lib/src/commonTest/kotlin/` and run on all platforms.
Expand Down
Empty file.
13 changes: 13 additions & 0 deletions build-logic/src/main/kotlin/kjwt.multiplatform-library.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import kjwt.configureTests
import org.jetbrains.kotlin.gradle.dsl.abi.BinariesSource
import org.jetbrains.kotlin.gradle.dsl.abi.ExperimentalAbiValidation

plugins {
kotlin("multiplatform")
Expand All @@ -13,6 +15,17 @@ plugins {
kotlin {
explicitApi()

@OptIn(ExperimentalAbiValidation::class)
abiValidation {
binariesSource.set(BinariesSource.MAVEN_PUBLICATIONS)

filters {
exclude {
annotatedWith.add("co.touchlab.kjwt.annotations.InternalKJWTApi")
}
}
}

compilerOptions {
freeCompilerArgs.add("-Xexpect-actual-classes")
}
Expand Down
1,099 changes: 1,099 additions & 0 deletions core/api/kjwt-core.api

Large diffs are not rendered by default.

1,203 changes: 1,203 additions & 0 deletions core/api/kjwt-core.klib.api

Large diffs are not rendered by default.

178 changes: 178 additions & 0 deletions cryptography-kotlin/ext/api/kjwt-cryptography-kotlin-processor-ext.api

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
public final class co/touchlab/kjwt/cryptography/CryptographyExtensionsKt {
public static final fun toCryptographyKotlin (Lco/touchlab/kjwt/model/algorithm/JwtCurve;)Ljava/lang/String;
public static final fun toCryptographyKotlin (Lco/touchlab/kjwt/model/algorithm/JwtEdCurve;)Ldev/whyoleg/cryptography/algorithms/EdDSA$Curve;
}

public abstract class co/touchlab/kjwt/cryptography/EncryptionKey : co/touchlab/kjwt/processor/BaseJweProcessor {
public fun getAlgorithm ()Lco/touchlab/kjwt/model/algorithm/EncryptionAlgorithm;
public abstract fun getIdentifier ()Lco/touchlab/kjwt/cryptography/EncryptionKey$Identifier;
public fun getKeyId ()Ljava/lang/String;
public abstract fun getPrivateKey ()Ljava/lang/Object;
public abstract fun getPublicKey ()Ljava/lang/Object;
public final fun mergeWith (Lco/touchlab/kjwt/cryptography/EncryptionKey;)Lco/touchlab/kjwt/cryptography/EncryptionKey;
}

public final class co/touchlab/kjwt/cryptography/EncryptionKey$DecryptionOnlyKey : co/touchlab/kjwt/cryptography/EncryptionKey, co/touchlab/kjwt/processor/JweDecryptor {
public fun <init> (Lco/touchlab/kjwt/cryptography/EncryptionKey$Identifier;Ljava/lang/Object;)V
public fun decrypt ([B[B[B[B[BLco/touchlab/kjwt/model/algorithm/EncryptionContentAlgorithm;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public fun equals (Ljava/lang/Object;)Z
public fun getIdentifier ()Lco/touchlab/kjwt/cryptography/EncryptionKey$Identifier;
public fun getPrivateKey ()Ljava/lang/Object;
public fun getPublicKey ()Ljava/lang/Object;
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
}

public final class co/touchlab/kjwt/cryptography/EncryptionKey$EncryptionKeyPair : co/touchlab/kjwt/cryptography/EncryptionKey, co/touchlab/kjwt/processor/JweProcessor {
public fun <init> (Lco/touchlab/kjwt/cryptography/EncryptionKey$Identifier;Ljava/lang/Object;Ljava/lang/Object;)V
public fun decrypt ([B[B[B[B[BLco/touchlab/kjwt/model/algorithm/EncryptionContentAlgorithm;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public fun encrypt ([B[BLco/touchlab/kjwt/model/algorithm/EncryptionContentAlgorithm;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public fun equals (Ljava/lang/Object;)Z
public fun getIdentifier ()Lco/touchlab/kjwt/cryptography/EncryptionKey$Identifier;
public fun getPrivateKey ()Ljava/lang/Object;
public fun getPublicKey ()Ljava/lang/Object;
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
}

public final class co/touchlab/kjwt/cryptography/EncryptionKey$EncryptionOnlyKey : co/touchlab/kjwt/cryptography/EncryptionKey, co/touchlab/kjwt/processor/JweEncryptor {
public fun <init> (Lco/touchlab/kjwt/cryptography/EncryptionKey$Identifier;Ljava/lang/Object;)V
public fun encrypt ([B[BLco/touchlab/kjwt/model/algorithm/EncryptionContentAlgorithm;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public fun equals (Ljava/lang/Object;)Z
public fun getIdentifier ()Lco/touchlab/kjwt/cryptography/EncryptionKey$Identifier;
public fun getPrivateKey ()Ljava/lang/Object;
public fun getPublicKey ()Ljava/lang/Object;
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
}

public final class co/touchlab/kjwt/cryptography/EncryptionKey$Identifier {
public static final field Companion Lco/touchlab/kjwt/cryptography/EncryptionKey$Identifier$Companion;
public fun <init> (Lco/touchlab/kjwt/model/algorithm/EncryptionAlgorithm;Ljava/lang/String;)V
public final fun component1 ()Lco/touchlab/kjwt/model/algorithm/EncryptionAlgorithm;
public final fun component2 ()Ljava/lang/String;
public final fun copy (Lco/touchlab/kjwt/model/algorithm/EncryptionAlgorithm;Ljava/lang/String;)Lco/touchlab/kjwt/cryptography/EncryptionKey$Identifier;
public static synthetic fun copy$default (Lco/touchlab/kjwt/cryptography/EncryptionKey$Identifier;Lco/touchlab/kjwt/model/algorithm/EncryptionAlgorithm;Ljava/lang/String;ILjava/lang/Object;)Lco/touchlab/kjwt/cryptography/EncryptionKey$Identifier;
public fun equals (Ljava/lang/Object;)Z
public final fun getAlgorithm ()Lco/touchlab/kjwt/model/algorithm/EncryptionAlgorithm;
public final fun getKeyId ()Ljava/lang/String;
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
}

public final class co/touchlab/kjwt/cryptography/EncryptionKey$Identifier$Companion {
}

public abstract class co/touchlab/kjwt/cryptography/SigningKey : co/touchlab/kjwt/processor/BaseJwsProcessor {
public fun getAlgorithm ()Lco/touchlab/kjwt/model/algorithm/SigningAlgorithm;
public abstract fun getIdentifier ()Lco/touchlab/kjwt/cryptography/SigningKey$Identifier;
public fun getKeyId ()Ljava/lang/String;
public abstract fun getPrivateKey ()Ljava/lang/Object;
public abstract fun getPublicKey ()Ljava/lang/Object;
}

public final class co/touchlab/kjwt/cryptography/SigningKey$Identifier {
public static final field Companion Lco/touchlab/kjwt/cryptography/SigningKey$Identifier$Companion;
public fun <init> (Lco/touchlab/kjwt/model/algorithm/SigningAlgorithm;Ljava/lang/String;)V
public final fun component1 ()Lco/touchlab/kjwt/model/algorithm/SigningAlgorithm;
public final fun component2 ()Ljava/lang/String;
public final fun copy (Lco/touchlab/kjwt/model/algorithm/SigningAlgorithm;Ljava/lang/String;)Lco/touchlab/kjwt/cryptography/SigningKey$Identifier;
public static synthetic fun copy$default (Lco/touchlab/kjwt/cryptography/SigningKey$Identifier;Lco/touchlab/kjwt/model/algorithm/SigningAlgorithm;Ljava/lang/String;ILjava/lang/Object;)Lco/touchlab/kjwt/cryptography/SigningKey$Identifier;
public fun equals (Ljava/lang/Object;)Z
public final fun getAlgorithm ()Lco/touchlab/kjwt/model/algorithm/SigningAlgorithm;
public final fun getKeyId ()Ljava/lang/String;
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
}

public final class co/touchlab/kjwt/cryptography/SigningKey$Identifier$Companion {
public final fun getNone ()Lco/touchlab/kjwt/cryptography/SigningKey$Identifier;
}

public final class co/touchlab/kjwt/cryptography/SigningKey$SigningKeyPair : co/touchlab/kjwt/cryptography/SigningKey, co/touchlab/kjwt/processor/JwsProcessor {
public fun <init> (Lco/touchlab/kjwt/cryptography/SigningKey$Identifier;Ljava/lang/Object;Ljava/lang/Object;)V
public fun equals (Ljava/lang/Object;)Z
public fun getIdentifier ()Lco/touchlab/kjwt/cryptography/SigningKey$Identifier;
public fun getPrivateKey ()Ljava/lang/Object;
public fun getPublicKey ()Ljava/lang/Object;
public fun hashCode ()I
public fun sign ([BLkotlin/coroutines/Continuation;)Ljava/lang/Object;
public fun toString ()Ljava/lang/String;
public fun verify ([B[BLkotlin/coroutines/Continuation;)Ljava/lang/Object;
}

public final class co/touchlab/kjwt/cryptography/SigningKey$SigningOnlyKey : co/touchlab/kjwt/cryptography/SigningKey, co/touchlab/kjwt/processor/JwsSigner {
public fun <init> (Lco/touchlab/kjwt/cryptography/SigningKey$Identifier;Ljava/lang/Object;)V
public fun equals (Ljava/lang/Object;)Z
public fun getIdentifier ()Lco/touchlab/kjwt/cryptography/SigningKey$Identifier;
public fun getPrivateKey ()Ljava/lang/Object;
public fun getPublicKey ()Ljava/lang/Object;
public fun hashCode ()I
public fun sign ([BLkotlin/coroutines/Continuation;)Ljava/lang/Object;
public fun toString ()Ljava/lang/String;
}

public final class co/touchlab/kjwt/cryptography/SigningKey$VerifyOnlyKey : co/touchlab/kjwt/cryptography/SigningKey, co/touchlab/kjwt/processor/JwsVerifier {
public fun <init> (Lco/touchlab/kjwt/cryptography/SigningKey$Identifier;Ljava/lang/Object;)V
public fun equals (Ljava/lang/Object;)Z
public fun getIdentifier ()Lco/touchlab/kjwt/cryptography/SigningKey$Identifier;
public fun getPrivateKey ()Ljava/lang/Object;
public fun getPublicKey ()Ljava/lang/Object;
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
public fun verify ([B[BLkotlin/coroutines/Continuation;)Ljava/lang/Object;
}

Loading
Loading