Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgraded to PowerAuth 1.9.x #165

Merged
merged 6 commits into from
Oct 9, 2024
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
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ __Wultra Mobile Token SDK__ is a high-level SDK for operation approval.
<!-- begin remove -->
<img align="right" src="docs/images/il-mobile-token.svg" width="40%" />
<!-- end -->
With Wultra Mobile Token (WMT) SDK, you can integrate an out-of-band operation approval into an existing mobile app, instead of using a standalone mobile token application. WMT is built on top of [PowerAuth Mobile SDK](https://github.com/wultra/powerauth-mobile-sdk). It communicates with the "Mobile Token REST API" and "Mobile Push Registration API". Individual endpoints are described in the [PowerAuth Webflow documentation](https://github.com/wultra/powerauth-webflow/).

With Wultra Mobile Token (WMT) SDK, you can integrate an out-of-band operation approval into an existing mobile app, instead of using a standalone mobile token application. WMT is built on top of [PowerAuth Mobile SDK](https://github.com/wultra/powerauth-mobile-sdk). It communicates with the [Mobile Token API](https://developers.wultra.com/components/enrollment-server/develop/documentation/Mobile-Token-API).

To understand the Wultra Mobile Token SDK purpose on a business level better, you can visit our own [Mobile Token application](https://www.wultra.com/mobile-token). We use Wultra Mobile Token SDK in our mobile token application as well.

Expand Down
7 changes: 6 additions & 1 deletion docs/Changelog.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
# Changelog

## 1.12.0 (Aug, 2024)
## 1.12.0 (Oct, 2024)

- Upgraded to PowerAuth 1.9.x [(#165)](https://github.com/wultra/mtoken-sdk-ios/pull/165)
- Document fixes and improvements

## 1.11.1 (Aug, 2024)

- Added resultTexts to UserOperation [(#152)](https://github.com/wultra/mtoken-sdk-ios/pull/152)
- Extended PushParser to support parsing of inbox notifications [(#150)](https://github.com/wultra/mtoken-sdk-android/pull/150)
Expand Down
4 changes: 2 additions & 2 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Wultra Mobile Token SDK for Android
With Wultra Mobile Token (WMT) SDK, you can integrate an out-of-band operation approval into an existing mobile app, instead of using a standalone mobile token application. WMT is built on top of [PowerAuth Mobile SDK](https://github.com/wultra/powerauth-mobile-sdk). It communicates with the "Mobile Token REST API" and "Mobile Push Registration API". Individual endpoints are described in the [PowerAuth Webflow documentation](https://github.com/wultra/powerauth-webflow/).

With Wultra Mobile Token (WMT) SDK, you can integrate an out-of-band operation approval into an existing mobile app, instead of using a standalone mobile token application. WMT is built on top of [PowerAuth Mobile SDK](https://github.com/wultra/powerauth-mobile-sdk). It communicates with the [Mobile Token API](https://developers.wultra.com/components/enrollment-server/develop/documentation/Mobile-Token-API).

To understand the Wultra Mobile Token SDK purpose on a business level better, you can visit our own [Mobile Token application](https://www.wultra.com/mobile-token). We use Wultra Mobile Token SDK in our mobile token application as well.

Expand Down
2 changes: 2 additions & 0 deletions docs/Using-Inbox-Service.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ Inbox Service is responsible for managing messages in the Inbox. The inbox is a
Note: Before using Inbox Service, you need to have a `PowerAuthSDK` object available and initialized with a valid activation. Without a valid PowerAuth activation, the service will return an error.
<!-- end -->

Inbox Service communicates with the [Mobile Token API](https://developers.wultra.com/components/enrollment-server/develop/documentation/Mobile-Token-API).

## Creating an Instance

### Factory Extension With SSL Validation Strategy
Expand Down
55 changes: 26 additions & 29 deletions docs/Using-Operations-Service.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ An operation can be anything you need to be approved or rejected by the user. It
Note: Before using Operations Service, you need to have a `PowerAuthSDK` object available and initialized with a valid activation. Without a valid PowerAuth activation, all endpoints will return an error.
<!-- end -->

Operations Service communicates with a backend via [Mobile Token API endpoints](https://github.com/wultra/powerauth-webflow/blob/develop/docs/Mobile-Token-API.md).
Operations Service communicates with the [Mobile Token API](https://developers.wultra.com/components/enrollment-server/develop/documentation/Mobile-Token-API).

## Creating an Instance

Expand Down Expand Up @@ -149,26 +149,26 @@ fun approve(operation: IOperation, password: String) {
}
```

To approve offline operations with biometry, your PowerAuth instance [needs to be configured with biometry factor](https://github.com/wultra/powerauth-mobile-sdk/blob/develop/docs/PowerAuth-SDK-for-Android.md#biometric-authentication-setup).
To approve offline operations with biometrics, your PowerAuth instance [needs to be configured with biometric factor](https://github.com/wultra/powerauth-mobile-sdk/blob/develop/docs/PowerAuth-SDK-for-Android.md#biometric-authentication-setup).

```kotlin
// Approve operation with biometry
fun approveWithBiometry(operation: IOperation) {
// Approve operation with biometrics
fun approveWithBiometrics(operation: IOperation) {

// UserOperation contains information if biometry can be used
// UserOperation contains information if biometrics can be used
if (operation is UserOperation) {
if (!operation.allowedSignatureType.factors.contains(AllowedSignatureType.Factor.POSSESSION_BIOMETRY)) {
return
}
}

this.powerAuthSDK.authenticateUsingBiometry(appContext, fragmentManager,
this.powerAuthSDK.authenticateUsingBiometrics(appContext, fragmentManager,
"Operation approval",
"Use biometry to approve the operation",
"Use biometrics to approve the operation",
object : IBiometricAuthenticationCallback {

override fun onBiometricDialogSuccess(biometricKeyData: BiometricKeyData) {
val auth = PowerAuthAuthentication.possessionWithBiometry(biometricKeyData.derivedData)
val auth = PowerAuthAuthentication.possessionWithBiometrics(biometricKeyData.derivedData)
this.operationsService.authorizeOperation(operation, auth) {
it.onSuccess {
// show success UI
Expand All @@ -179,11 +179,11 @@ fun approveWithBiometry(operation: IOperation) {
}

override fun onBiometricDialogCancelled(userCancel: Boolean) {
// the biometry dialog was canceled
// the biometrics dialog was canceled
}

override fun onBiometricDialogFailed(error: PowerAuthErrorException) {
// biometry authentication failed
// biometrics authentication failed
}
}
)
Expand Down Expand Up @@ -270,7 +270,7 @@ Note that the operation history availability depends on the backend implementati

## Off-line Authorization

In case the user is not online, you can use off-line authorizations. In this operation mode, the user needs to scan a QR code, enter a PIN code, or use biometry, and rewrite the resulting code. Wultra provides a special format for [the operation QR codes](https://github.com/wultra/powerauth-webflow/blob/develop/docs/Off-line-Signatures-QR-Code.md), which are automatically processed with the SDK.
In case the user is not online, you can use off-line authorizations. In this operation mode, the user needs to scan a QR code, enter a PIN code, or use biometrics, and rewrite the resulting code. Wultra provides a special format for [the operation QR codes](https://github.com/wultra/enrollment-server/blob/develop/docs/Offline-Signatures-QR-Code.md), which are automatically processed with the SDK.

### Processing Scanned QR Operation

Expand All @@ -291,7 +291,7 @@ fun onQROperationScanned(scannedCode: String): QROperation {
### Authorizing Scanned QR Operation

<!-- begin box info -->
An offline operation needs to be __always__ approved with __a 2-factor scheme__ (password or biometry).
An offline operation needs to be __always__ approved with __a 2-factor scheme__ (password or biometrics).
<!-- end -->

<!-- begin box info -->
Expand Down Expand Up @@ -334,28 +334,28 @@ fun approveQROperation(operation: QROperation, password: String) {
}
```

#### With Biometry
#### With Biometrics

To approve offline operations with biometry, your PowerAuth instance [needs to be configured with biometry factor](https://github.com/wultra/powerauth-mobile-sdk/blob/develop/docs/PowerAuth-SDK-for-Android.md#biometric-authentication-setup).
To approve offline operations with biometrics, your PowerAuth instance [needs to be configured with biometric factor](https://github.com/wultra/powerauth-mobile-sdk/blob/develop/docs/PowerAuth-SDK-for-Android.md#biometric-authentication-setup).

To determine if biometry can be used for offline operation authorization, use `QROperation.flags.biometryAllowed`.
To determine if biometrics can be used for offline operation authorization, use `QROperation.flags.biometricsAllowed`.

```kotlin
// Approves QR operation with biometry
fun approveQROperationWithBiometry(operation: QROperation, appContext: Context, fragmentManager: FragmentManager) {
// Approves QR operation with biometrics
fun approveQROperationWithBiometrics(operation: QROperation, appContext: Context, fragmentManager: FragmentManager) {

if (!operation.flags.biometryAllowed) {
// biometry usage is not allowed on this operation
if (!operation.flags.biometricsAllowed) {
// biometrics usage is not allowed on this operation
return
}

this.powerAuthSDK.authenticateUsingBiometry(appContext, fragmentManager,
this.powerAuthSDK.authenticateUsingBiometrics(appContext, fragmentManager,
"Operation approval",
"Use biometry to approve the operation",
"Use biometrics to approve the operation",
object : IBiometricAuthenticationCallback {

override fun onBiometricDialogSuccess(biometricKeyData: BiometricKeyData) {
val auth = PowerAuthAuthentication.possessionWithBiometry(biometricKeyData.derivedData)
val auth = PowerAuthAuthentication.possessionWithBiometrics(biometricKeyData.derivedData)
try {
val offlineSignature = operationsService.authorizeOfflineOperation(operation, auth)
// Display the signature to the user so it can be manually rewritten.
Expand All @@ -365,11 +365,11 @@ fun approveQROperationWithBiometry(operation: QROperation, appContext: Context,
}

override fun onBiometricDialogCancelled(userCancel: Boolean) {
// the biometry dialog was canceled
// the biometrics dialog was canceled
}

override fun onBiometricDialogFailed(error: PowerAuthErrorException) {
// biometry authentication failed
// biometrics authentication failed
}
}
)
Expand Down Expand Up @@ -408,9 +408,6 @@ All available methods and attributes of `IOperationsService` API are:
- `operation` - Offline operation retrieved via `QROperationParser.parse` method.
- `authentication` - PowerAuth authentication object for operation signing.
- `uriId` - Custom signature URI ID of the operation. Use the URI ID under which the operation was created on the server. The default value is `/operation/authorize/offline`.
- `signOfflineOperationWithBiometry(biometry: ByteArray, offlineOperation: QROperation)` - Sign offline (QR) operation with biometry data.
- `biometry` - Biometry data retrieved from the `powerAuthSDK.authenticateUsingBiometry` call.
- `offlineOperation` - Offline operation retrieved via `processOfflineQrPayload` method.

## UserOperation

Expand Down Expand Up @@ -455,7 +452,7 @@ class UserOperation: IOperation {
*
* This hints if the operation needs a 2nd factor or can be approved simply by
* tapping an approve button. If the operation requires 2FA, this value also hints if
* the user may use the biometry, or if a password is required.
* the user may use the biometrics, or if a password is required.
*/
val allowedSignatureType: AllowedSignatureType

Expand Down Expand Up @@ -661,7 +658,7 @@ data class PACData(
- two methods are provided:
- `parseDeeplink(uri: Uri): PACData?` - URI is expected to be in the format `scheme://code=$JWT` or `scheme://operation?oid=5b753d0d-d59a-49b7-bec4-eae258566dbb&potp=12345678`
- `parseQRCode(code: String): PACData?` - code is to be expected in the same format as deeplink formats or as a plain JWT
- mentioned JWT should be in the format `{“typ”:”JWT”, “alg”:”none}.{oid”:”5b753d0d-d59a-49b7-bec4-eae258566dbb”, “potp”:”12345678”} `
- mentioned JWT should be in the format `{"type":"JWT", "alg":"none"}.{"oid":"5b753d0d-d59a-49b7-bec4-eae258566dbb", "potp":"12345678"}`

- Accepted formats:
- notice that the totp key in JWT and in query shall be `potp`!
2 changes: 1 addition & 1 deletion docs/Using-Push-Service.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Push Service is responsible for registering the device for the push notification
Note: Before using Push Service, you need to have a `PowerAuthSDK` object available and initialized with a valid activation. Without a valid PowerAuth activation, the service will return an error.
<!-- end -->

Push Service communicates with [Mobile Push Registration API](https://github.com/wultra/powerauth-webflow/blob/develop/docs/Mobile-Push-Registration-API.md).
Push Service communicates with the [Mobile Token API](https://developers.wultra.com/components/enrollment-server/develop/documentation/Mobile-Token-API).

## Creating an Instance

Expand Down
22 changes: 10 additions & 12 deletions library/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -78,28 +78,26 @@ android {
dependencies {
// Bundled
implementation("org.jetbrains.kotlin:kotlin-stdlib:${Constants.BuildScript.kotlinVersion}")
implementation("androidx.annotation:annotation:1.7.0")
implementation("com.google.code.gson:gson:2.10.1")
implementation("androidx.annotation:annotation:1.8.2")
implementation("com.google.code.gson:gson:2.11.0")
implementation("com.jakewharton.threetenabp:threetenabp:1.1.1")
// DO NOT UPGRADE ABOVE 3.12.X! Version 3.12 is the last version supporting TLS 1 and 1.1
// If upgraded, the app will crash on android 4.4
implementation("com.squareup.okhttp3:okhttp:3.12.13")
implementation("com.wultra.android.powerauth:powerauth-networking:1.4.0")
implementation("com.squareup.okhttp3:okhttp:4.9.3")
implementation("com.wultra.android.powerauth:powerauth-networking:1.5.0")

// Dependencies
compileOnly("com.wultra.android.powerauth:powerauth-sdk:1.8.0")
compileOnly("io.getlime.core:rest-model-base:1.2.0")
compileOnly("com.wultra.android.powerauth:powerauth-sdk:1.9.2")
compileOnly("io.getlime.core:rest-model-base:1.9.0")

// TestDependencies
testImplementation("junit:junit:4.13.2")

// Android tests
androidTestImplementation("com.jakewharton.threetenabp:threetenabp:1.1.1")
androidTestImplementation("com.wultra.android.powerauth:powerauth-sdk:1.8.0")
androidTestImplementation("com.wultra.android.powerauth:powerauth-networking:1.4.0")
androidTestImplementation("androidx.test:runner:1.5.2")
androidTestImplementation("com.wultra.android.powerauth:powerauth-sdk:1.9.2")
androidTestImplementation("com.wultra.android.powerauth:powerauth-networking:1.5.0")
androidTestImplementation("androidx.test:runner:1.6.2")
androidTestImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test:core:1.5.0")
androidTestImplementation("androidx.test:core:1.6.1")
androidTestImplementation(platform("org.jetbrains.kotlin:kotlin-bom:${Constants.BuildScript.kotlinVersion}"))
}

Expand Down
2 changes: 1 addition & 1 deletion library/gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@
# and limitations under the License.
#

VERSION_NAME=1.11.0-SNAPSHOT
VERSION_NAME=1.12.0-SNAPSHOT
GROUP_ID=com.wultra.android.mtokensdk
ARTIFACT_ID=wultra-mtoken-sdk
24 changes: 11 additions & 13 deletions library/src/androidTest/java/IntegrationUtils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ import android.content.Context
import android.util.Log
import androidx.test.core.app.ApplicationProvider
import androidx.test.platform.app.InstrumentationRegistry
import com.google.gson.*
import com.google.gson.Gson
import com.google.gson.TypeAdapter
import com.google.gson.annotations.JsonAdapter
import com.google.gson.reflect.TypeToken
import com.google.gson.stream.JsonReader
Expand All @@ -37,12 +38,13 @@ import io.getlime.security.powerauth.networking.response.ICreateActivationListen
import io.getlime.security.powerauth.sdk.PowerAuthClientConfiguration
import io.getlime.security.powerauth.sdk.PowerAuthConfiguration
import io.getlime.security.powerauth.sdk.PowerAuthSDK
import okhttp3.MediaType
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody
import java.util.*
import okhttp3.RequestBody.Companion.toRequestBody
import java.util.Base64.getEncoder
import java.util.Date
import java.util.UUID
import java.util.concurrent.CompletableFuture
import java.util.concurrent.TimeUnit

Expand Down Expand Up @@ -70,7 +72,7 @@ class IntegrationUtils {
val context: Context = ApplicationProvider.getApplicationContext()
private val client = OkHttpClient.Builder().build()
private val gson = Gson()
private val jsonMediaType = MediaType.parse("application/json; charset=UTF-8")!!
private val jsonMediaType = "application/json; charset=UTF-8".toMediaType()

private val cloudServerUrl = getInstrumentationParameter("cloudServerUrl")
private val cloudServerLogin = getInstrumentationParameter("cloudServerLogin")
Expand Down Expand Up @@ -150,8 +152,8 @@ class IntegrationUtils {

return Triple(
pa,
pa.createOperationsService(context, operationsUrl, SSLValidationStrategy.default()),
pa.createInboxService(context, inboxUrl, SSLValidationStrategy.default())
pa.createOperationsService(context, operationsUrl, SSLValidationStrategy.system()),
pa.createInboxService(context, inboxUrl, SSLValidationStrategy.system())
)
}

Expand Down Expand Up @@ -263,18 +265,14 @@ class IntegrationUtils {
Log.d("make call payload", payload ?: "")
Log.d("make call url", url)
val creds = getEncoder().encodeToString("$cloudServerLogin:$cloudServerPassword".toByteArray())
val body = if (payload != null) {
RequestBody.create(jsonMediaType, payload.toByteArray())
} else {
null
}
val body = payload?.toByteArray()?.toRequestBody(jsonMediaType)
val request = Request.Builder()
.header("authorization", "Basic $creds")
.url(url)
.method(method, body)
.build()
val resp = client.newCall(request).execute()
val stringResp = resp.body()!!.string()
val stringResp = resp.body!!.string()
Log.d("make call response", stringResp)
return gson.fromJson(stringResp, object: TypeToken<T>() {}.type)
}
Expand Down
Loading
Loading