Skip to content

Commit cf9371e

Browse files
author
RN SDK Release User
committed
v15.1.0 release
1 parent 4acea9d commit cf9371e

File tree

14 files changed

+472
-54
lines changed

14 files changed

+472
-54
lines changed

.editorconfig

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
[*]
2+
indent_size = 2
3+
4+
[*.java]
5+
indent_size = 4

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
66
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
77

8+
## Future version
9+
10+
### Fixed:
11+
12+
- Fixed Kosovo XKX country code support
13+
814
## [15.0.0] - 2025-08-06
915

1016
### Changed:

README.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -667,6 +667,27 @@ For example:
667667
}
668668
```
669669
670+
### User analytics
671+
672+
#### Implementation
673+
1. Provide a custom callback using `Onfido.addAnalyticsCallback`
674+
675+
```typescript
676+
677+
type Event = {
678+
type: string
679+
properties: Record<string, string>
680+
} | {
681+
name: string
682+
properties: Record<string, string>
683+
}
684+
685+
Onfido.addAnalyticsCallback((event:Event) => {});
686+
```
687+
688+
Please see the documentation for the [ios](https://documentation.onfido.com/sdk/ios/#user-analytics) and
689+
[android](https://documentation.onfido.com/sdk/android/#kotlin-15) event structure.
690+
670691
### Custom biometric token storage
671692
672693
When using the authentication with local storage solution, by default the SDK manages biometric token storage. The SDK also allows the clients to take control of the token lifecycle and exposes an API to override the default implementation to read and write the token, so it can be stored on device, in cloud, in a keystore or on your premises.

android/src/main/AndroidManifest.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@
88

99
<meta-data
1010
android:name="onfido_integration_version"
11-
android:value="15.0.0" />
11+
android:value="15.1.0" />
1212
</application>
1313
</manifest>
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package com.onfido.reactnative.sdk;
2+
3+
import androidx.annotation.NonNull;
4+
5+
import com.facebook.react.bridge.Arguments;
6+
import com.facebook.react.bridge.ReactApplicationContext;
7+
import com.facebook.react.modules.core.DeviceEventManagerModule;
8+
import com.onfido.android.sdk.capture.analytics.OnfidoAnalyticsEvent;
9+
import com.onfido.android.sdk.capture.analytics.OnfidoAnalyticsEventListener;
10+
11+
public class AnalyticsCallbackBridge implements OnfidoAnalyticsEventListener {
12+
13+
public static final String CALLBACK_NAME = "onfidoAnalyticsCallback";
14+
private final ReactApplicationContext reactContext;
15+
16+
public AnalyticsCallbackBridge(ReactApplicationContext reactContext) {
17+
this.reactContext = reactContext;
18+
}
19+
20+
@Override
21+
public void onEvent(@NonNull OnfidoAnalyticsEvent event) {
22+
23+
var properties = Arguments.createMap();
24+
for (var entry : event.getProperties().entrySet()) {
25+
properties.putString(entry.getKey().toString(), entry.getValue());
26+
}
27+
28+
var params = Arguments.createMap();
29+
params.putString("type", event.getType().toString());
30+
params.putMap("properties", properties);
31+
32+
reactContext
33+
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
34+
.emit(CALLBACK_NAME, params);
35+
}
36+
}

android/src/main/java/com/onfido/reactnative/sdk/OnfidoSdkModule.java

Lines changed: 35 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
import android.annotation.SuppressLint;
44
import android.app.Activity;
55

6+
import androidx.annotation.NonNull;
7+
68
import com.facebook.react.bridge.Promise;
79
import com.facebook.react.bridge.ReactApplicationContext;
810
import com.facebook.react.bridge.ReactContextBaseJavaModule;
@@ -17,6 +19,8 @@
1719
import com.onfido.android.sdk.capture.OnfidoConfig;
1820
import com.onfido.android.sdk.capture.OnfidoFactory;
1921
import com.onfido.android.sdk.capture.OnfidoTheme;
22+
import com.onfido.android.sdk.capture.analytics.OnfidoAnalyticsEvent;
23+
import com.onfido.android.sdk.capture.analytics.OnfidoAnalyticsEventListener;
2024
import com.onfido.android.sdk.capture.config.BiometricTokenCallback;
2125
import com.onfido.android.sdk.capture.config.MediaCallback;
2226
import com.onfido.android.sdk.capture.errors.EnterpriseFeatureNotEnabledException;
@@ -38,7 +42,8 @@
3842
// Analytics to be re-added once payloads are harmonised across platforms
3943
enum CallbackType {
4044
MEDIA,
41-
BIOMETRIC_TOKEN
45+
BIOMETRIC_TOKEN,
46+
ANALYTICS
4247
}
4348

4449
public class OnfidoSdkModule extends ReactContextBaseJavaModule {
@@ -89,16 +94,14 @@ public void start(final ReadableMap config, final Promise promise) {
8994
try {
9095
sdkToken = getSdkTokenFromConfig(config);
9196
} catch (Exception e) {
92-
currentPromise.reject("config_error", e);
93-
currentPromise = null;
94-
return;
97+
reject("config_error", e);
98+
return;
9599
}
96100

97101
Activity currentActivity = getCurrentActivityInParentClass();
98102
if (currentActivity == null) {
99-
currentPromise.reject("error", new Exception("Android activity does not exist"));
100-
currentPromise = null;
101-
return;
103+
reject("error", new Exception("Android activity does not exist"));
104+
return;
102105
}
103106

104107
try {
@@ -110,25 +113,26 @@ public void start(final ReadableMap config, final Promise promise) {
110113
defaultSDKConfiguration(config, currentActivity, sdkToken);
111114
}
112115
} catch (final EnterpriseFeaturesInvalidLogoCobrandingException e) {
113-
currentPromise.reject("error", new EnterpriseFeaturesInvalidLogoCobrandingException());
114-
currentPromise = null;
116+
reject("error", new EnterpriseFeaturesInvalidLogoCobrandingException());
115117
} catch (final EnterpriseFeatureNotEnabledException e) {
116-
currentPromise.reject("error", e);
117-
currentPromise = null;
118+
reject("error", e);
118119
} catch (final Exception e) {
119-
currentPromise.reject("error", new Exception(e.getMessage(), e));
120-
currentPromise = null;
120+
reject("error", new Exception(e.getMessage(), e));
121121
}
122122

123123
} catch (final Exception e) {
124124
e.printStackTrace();
125125
// Wrap all unexpected exceptions.
126-
currentPromise.reject("error", new Exception("Unexpected error starting Onfido page", e));
127-
currentPromise = null;
126+
reject("error", new Exception("Unexpected error starting Onfido page", e));
128127
}
129128
}
130129

131-
@SuppressLint("UnsafeOptInUsageError")
130+
private void reject(String config_error, Exception e) {
131+
currentPromise.reject(config_error, e);
132+
currentPromise = null;
133+
}
134+
135+
@SuppressLint("UnsafeOptInUsageError")
132136
private void workflowSDKConfiguration(final ReadableMap config, Activity currentActivity, String sdkToken) throws Exception {
133137
final String workflowRunId = getWorkflowRunIdFromConfig(config);
134138

@@ -149,6 +153,10 @@ private void workflowSDKConfiguration(final ReadableMap config, Activity current
149153
onfidoConfigBuilder.withBiometricTokenCallback(addBiometricTokenCallback());
150154
}
151155

156+
if (callbackTypeList.contains(CallbackType.ANALYTICS)) {
157+
onfidoConfigBuilder.withAnalyticsEventListener(new AnalyticsCallbackBridge(getReactApplicationContext()));
158+
}
159+
152160
OnfidoTheme onfidoTheme = getThemeFromConfig(config);
153161
if (onfidoTheme != null) {
154162
onfidoConfigBuilder.withTheme(onfidoTheme);
@@ -182,6 +190,10 @@ private void defaultSDKConfiguration(final ReadableMap config, Activity currentA
182190
onfidoConfigBuilder.withMediaCallback(addMediaCallback());
183191
}
184192

193+
if (callbackTypeList.contains(CallbackType.ANALYTICS)) {
194+
onfidoConfigBuilder.withAnalyticsEventListener(new AnalyticsCallbackBridge(getReactApplicationContext()));
195+
}
196+
185197
NFCOptions nfcOption = getNFCOptionFromConfig(config);
186198
onfidoConfigBuilder.withNFC(nfcOption);
187199

@@ -215,9 +227,8 @@ private EnterpriseFeatures.Builder getEnterpriseFeatures(final ReadableMap confi
215227
currentActivity.getApplicationContext().getPackageName()
216228
);
217229
if (cobrandLogoLight == 0 || cobrandLogoDark == 0) {
218-
currentPromise.reject("error", new Exception("Cobrand logos were not found"));
219-
currentPromise = null;
220-
return null;
230+
reject("error", new Exception("Cobrand logos were not found"));
231+
return null;
221232
}
222233
enterpriseFeaturesBuilder.withCobrandingLogo(cobrandLogoLight, cobrandLogoDark);
223234
hasSetEnterpriseFeatures = true;
@@ -532,6 +543,11 @@ public void withBiometricTokenCallback() {
532543
callbackTypeList.add(CallbackType.BIOMETRIC_TOKEN);
533544
}
534545

546+
@ReactMethod
547+
public void withAnalyticsCallback() {
548+
callbackTypeList.add(CallbackType.ANALYTICS);
549+
}
550+
535551
@ReactMethod
536552
public void provideBiometricToken(String biometricToken) {
537553
biometricTokenCallback.provideToken(biometricToken);

0 commit comments

Comments
 (0)