@veriff/react-native-sdk 6.0.0 → 6.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/android/build.gradle +34 -25
- package/android/gradle/wrapper/gradle-wrapper.jar +0 -0
- package/android/gradle/wrapper/gradle-wrapper.properties +5 -0
- package/android/gradlew +234 -0
- package/android/gradlew.bat +89 -0
- package/android/src/main/java/com/veriff/sdk/reactnative/ReactNativeImageProvider.kt +126 -0
- package/android/src/main/java/com/veriff/sdk/reactnative/VeriffSdkModule.kt +449 -0
- package/android/src/main/java/com/veriff/sdk/reactnative/VeriffSdkPackage.kt +18 -0
- package/catalog-info.yaml +1 -1
- package/ios/Podfile +1 -1
- package/package.json +11 -50
- package/react-native-sdk.podspec +1 -1
- package/android/src/main/java/com/veriff/sdk/reactnative/ImageLoader.java +0 -119
- package/android/src/main/java/com/veriff/sdk/reactnative/ReactNativeImageProvider.java +0 -130
- package/android/src/main/java/com/veriff/sdk/reactnative/VeriffSdkModule.java +0 -494
- package/android/src/main/java/com/veriff/sdk/reactnative/VeriffSdkPackage.java +0 -23
|
@@ -0,0 +1,449 @@
|
|
|
1
|
+
package com.veriff.sdk.reactnative
|
|
2
|
+
|
|
3
|
+
import android.app.Activity
|
|
4
|
+
import android.content.Context
|
|
5
|
+
import android.content.Intent
|
|
6
|
+
import android.graphics.Color
|
|
7
|
+
import android.util.Log
|
|
8
|
+
import com.facebook.react.bridge.Arguments
|
|
9
|
+
import com.facebook.react.bridge.BaseActivityEventListener
|
|
10
|
+
import com.facebook.react.bridge.Promise
|
|
11
|
+
import com.facebook.react.bridge.ReactApplicationContext
|
|
12
|
+
import com.facebook.react.bridge.ReactContextBaseJavaModule
|
|
13
|
+
import com.facebook.react.bridge.ReactMethod
|
|
14
|
+
import com.facebook.react.bridge.ReadableMap
|
|
15
|
+
import com.facebook.react.bridge.ReadableType
|
|
16
|
+
import com.veriff.Branding
|
|
17
|
+
import com.veriff.Configuration
|
|
18
|
+
import com.veriff.Font
|
|
19
|
+
import com.veriff.GeneralConfig
|
|
20
|
+
import com.veriff.Result
|
|
21
|
+
import com.veriff.Sdk.createLaunchIntent
|
|
22
|
+
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
|
23
|
+
import java.util.Locale
|
|
24
|
+
|
|
25
|
+
class VeriffSdkModule(private val reactContext: ReactApplicationContext) :
|
|
26
|
+
ReactContextBaseJavaModule(reactContext) {
|
|
27
|
+
|
|
28
|
+
private var lastResult: Result? = null
|
|
29
|
+
private var sessionToken: String? = null
|
|
30
|
+
private var status: String? = null
|
|
31
|
+
|
|
32
|
+
@ReactMethod
|
|
33
|
+
fun recoverLastResult(promise: Promise) {
|
|
34
|
+
if (lastResult != null && status != null && sessionToken != null) {
|
|
35
|
+
sendResult(lastResult, status, sessionToken, promise)
|
|
36
|
+
lastResult = null
|
|
37
|
+
sessionToken = null
|
|
38
|
+
status = null
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
override fun getName(): String {
|
|
43
|
+
return JS_NAME
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
override fun getConstants(): Map<String, Any> {
|
|
47
|
+
return EXPORTED_CONSTANTS
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
@ReactMethod
|
|
51
|
+
fun launchVeriff(configuration: ReadableMap, promise: Promise) {
|
|
52
|
+
try {
|
|
53
|
+
val sessionToken: String?
|
|
54
|
+
val startUrl: String?
|
|
55
|
+
if (configuration.hasKey(KEY_SESSION_URL) &&
|
|
56
|
+
!configuration.getString(KEY_SESSION_URL).isNullOrEmpty()
|
|
57
|
+
) {
|
|
58
|
+
startUrl = configuration.getString(KEY_SESSION_URL)
|
|
59
|
+
sessionToken = if (startUrl != null) extractToken(startUrl) else null
|
|
60
|
+
if (startUrl.isNullOrEmpty() || sessionToken.isNullOrEmpty()) {
|
|
61
|
+
promise.reject(ERROR_INVALID_ARGS, "Invalid session url $startUrl")
|
|
62
|
+
return
|
|
63
|
+
}
|
|
64
|
+
} else {
|
|
65
|
+
sessionToken =
|
|
66
|
+
if (configuration.hasKey(KEY_TOKEN)) configuration.getString(KEY_TOKEN) else null
|
|
67
|
+
if (sessionToken.isNullOrEmpty()) {
|
|
68
|
+
promise.reject(
|
|
69
|
+
ERROR_INVALID_ARGS,
|
|
70
|
+
"No sessionToken in Veriff SDK configuration"
|
|
71
|
+
)
|
|
72
|
+
return
|
|
73
|
+
}
|
|
74
|
+
var baseUrl: String? = null
|
|
75
|
+
if (configuration.hasKey(KEY_BASE_URL)) {
|
|
76
|
+
baseUrl = configuration.getString(KEY_BASE_URL)
|
|
77
|
+
}
|
|
78
|
+
if (baseUrl.isNullOrEmpty()) {
|
|
79
|
+
baseUrl = DEFAULT_BASE_URL
|
|
80
|
+
}
|
|
81
|
+
if (baseUrl.endsWith("/")) {
|
|
82
|
+
baseUrl = baseUrl.substring(0, baseUrl.length - 1)
|
|
83
|
+
}
|
|
84
|
+
startUrl = "$baseUrl/v/$sessionToken"
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
this.sessionToken = sessionToken
|
|
88
|
+
lastResult = null
|
|
89
|
+
status = null
|
|
90
|
+
|
|
91
|
+
val activity = currentActivity
|
|
92
|
+
if (activity == null) {
|
|
93
|
+
promise.reject(ERROR_ACTIVITY_NOT_ATTACHED, "No activity attached while launching Veriff")
|
|
94
|
+
return
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
val listener = object : BaseActivityEventListener() {
|
|
98
|
+
override fun onActivityResult(
|
|
99
|
+
activity: Activity,
|
|
100
|
+
requestCode: Int,
|
|
101
|
+
resultCode: Int,
|
|
102
|
+
data: Intent?
|
|
103
|
+
) {
|
|
104
|
+
if (requestCode == VERIFF_REQUEST_CODE) {
|
|
105
|
+
if (data == null) {
|
|
106
|
+
return
|
|
107
|
+
}
|
|
108
|
+
val token = data.getStringExtra(GeneralConfig.INTENT_EXTRA_SESSION_URL)
|
|
109
|
+
if (sessionToken != token && startUrl != token) {
|
|
110
|
+
return
|
|
111
|
+
}
|
|
112
|
+
reactContext.removeActivityEventListener(this)
|
|
113
|
+
val veriffResult = Result.fromResultIntent(data)
|
|
114
|
+
lastResult = veriffResult
|
|
115
|
+
status = statusToString(getVeriffStatus(resultCode, veriffResult))
|
|
116
|
+
sendResult(veriffResult, status, sessionToken, promise)
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
reactContext.addActivityEventListener(listener)
|
|
121
|
+
val configBuilder = Configuration.Builder()
|
|
122
|
+
if (configuration.hasKey(KEY_CUSTOM_INTRO_SCREEN)) {
|
|
123
|
+
configBuilder.customIntroScreen(configuration.getBoolean(KEY_CUSTOM_INTRO_SCREEN))
|
|
124
|
+
}
|
|
125
|
+
if (configuration.hasKey(KEY_BRANDING)) {
|
|
126
|
+
val brandConfig = configuration.getMap(KEY_BRANDING)
|
|
127
|
+
if (brandConfig != null) {
|
|
128
|
+
val branding = Branding.Builder()
|
|
129
|
+
if (brandConfig.hasKey(KEY_LOGO)) {
|
|
130
|
+
handleLogo(activity, KEY_LOGO, branding, brandConfig)
|
|
131
|
+
}
|
|
132
|
+
if (brandConfig.hasKey(KEY_BACKGROUND)) {
|
|
133
|
+
branding.background(parseColor(brandConfig.getString(KEY_BACKGROUND)))
|
|
134
|
+
}
|
|
135
|
+
if (brandConfig.hasKey(KEY_ON_BACKGROUND)) {
|
|
136
|
+
branding.onBackground(parseColor(brandConfig.getString(KEY_ON_BACKGROUND)))
|
|
137
|
+
}
|
|
138
|
+
if (brandConfig.hasKey(KEY_ON_BACKGROUND_SECONDARY)) {
|
|
139
|
+
branding.onBackgroundSecondary(
|
|
140
|
+
parseColor(brandConfig.getString(KEY_ON_BACKGROUND_SECONDARY))
|
|
141
|
+
)
|
|
142
|
+
}
|
|
143
|
+
if (brandConfig.hasKey(KEY_ON_BACKGROUND_TERTIARY)) {
|
|
144
|
+
branding.onBackgroundTertiary(
|
|
145
|
+
parseColor(brandConfig.getString(KEY_ON_BACKGROUND_TERTIARY))
|
|
146
|
+
)
|
|
147
|
+
}
|
|
148
|
+
if (brandConfig.hasKey(KEY_PRIMARY)) {
|
|
149
|
+
branding.primary(parseColor(brandConfig.getString(KEY_PRIMARY)))
|
|
150
|
+
}
|
|
151
|
+
if (brandConfig.hasKey(KEY_ON_PRIMARY)) {
|
|
152
|
+
branding.onPrimary(parseColor(brandConfig.getString(KEY_ON_PRIMARY)))
|
|
153
|
+
}
|
|
154
|
+
if (brandConfig.hasKey(KEY_SECONDARY)) {
|
|
155
|
+
branding.secondary(parseColor(brandConfig.getString(KEY_SECONDARY)))
|
|
156
|
+
}
|
|
157
|
+
if (brandConfig.hasKey(KEY_ON_SECONDARY)) {
|
|
158
|
+
branding.onSecondary(parseColor(brandConfig.getString(KEY_ON_SECONDARY)))
|
|
159
|
+
}
|
|
160
|
+
if (brandConfig.hasKey(KEY_CAMERA_OVERLAY)) {
|
|
161
|
+
branding.cameraOverlay(parseColor(brandConfig.getString(KEY_CAMERA_OVERLAY)))
|
|
162
|
+
}
|
|
163
|
+
if (brandConfig.hasKey(KEY_ON_CAMERA_OVERLAY)) {
|
|
164
|
+
branding.onCameraOverlay(
|
|
165
|
+
parseColor(brandConfig.getString(KEY_ON_CAMERA_OVERLAY))
|
|
166
|
+
)
|
|
167
|
+
}
|
|
168
|
+
if (brandConfig.hasKey(KEY_OUTLINE)) {
|
|
169
|
+
branding.outline(parseColor(brandConfig.getString(KEY_OUTLINE)))
|
|
170
|
+
}
|
|
171
|
+
if (brandConfig.hasKey(KEY_SUCCESS)) {
|
|
172
|
+
branding.success(parseColor(brandConfig.getString(KEY_SUCCESS)))
|
|
173
|
+
}
|
|
174
|
+
if (brandConfig.hasKey(KEY_ERROR)) {
|
|
175
|
+
branding.error(parseColor(brandConfig.getString(KEY_ERROR)))
|
|
176
|
+
}
|
|
177
|
+
if (brandConfig.hasKey(KEY_BUTTON_RADIUS)) {
|
|
178
|
+
branding.buttonRadius(brandConfig.getDouble(KEY_BUTTON_RADIUS).toFloat())
|
|
179
|
+
}
|
|
180
|
+
if (brandConfig.hasKey(KEY_FONT)) {
|
|
181
|
+
brandConfig.getMap(KEY_FONT)?.let { srcFont ->
|
|
182
|
+
val font = buildFont(activity, srcFont)
|
|
183
|
+
branding.font(font)
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
configBuilder.branding(branding.build())
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
if (configuration.hasKey(KEY_LOCALE)) {
|
|
191
|
+
configuration.getString(KEY_LOCALE)?.let { locale ->
|
|
192
|
+
configBuilder.locale(Locale.forLanguageTag(locale))
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
if (configuration.hasKey(KEY_RN_VENDOR_DATA)) {
|
|
197
|
+
configuration.getString(KEY_RN_VENDOR_DATA)?.let { vendorData ->
|
|
198
|
+
configBuilder.vendorData(vendorData)
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
val intent = createLaunchIntent(activity, startUrl, configBuilder.build())
|
|
203
|
+
activity.startActivityForResult(intent, VERIFF_REQUEST_CODE)
|
|
204
|
+
} catch (t: Throwable) {
|
|
205
|
+
Log.e(TAG, "starting verification failed", t)
|
|
206
|
+
promise.reject(t)
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
private fun sendResult(
|
|
211
|
+
veriffResult: Result?,
|
|
212
|
+
status: String?,
|
|
213
|
+
sessionToken: String?,
|
|
214
|
+
promise: Promise
|
|
215
|
+
) {
|
|
216
|
+
val result = Arguments.createMap()
|
|
217
|
+
result.putString(KEY_TOKEN, sessionToken)
|
|
218
|
+
result.putString(KEY_STATUS, status)
|
|
219
|
+
if (veriffResult != null && veriffResult.error != null) {
|
|
220
|
+
result.putString(KEY_RESULT_ERROR, codeToError(veriffResult.error))
|
|
221
|
+
}
|
|
222
|
+
promise.resolve(result)
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
private fun buildFont(context: Context, src: ReadableMap): Font {
|
|
226
|
+
val regularFont = getFontId(context, src.getString(KEY_FONT_REGULAR))
|
|
227
|
+
val mediumFont = getFontId(context, src.getString(KEY_FONT_MEDIUM))
|
|
228
|
+
val boldFont = getFontId(context, src.getString(KEY_FONT_BOLD))
|
|
229
|
+
Log.v(
|
|
230
|
+
TAG, String.format(
|
|
231
|
+
"Regular font: [%s], value [%s]",
|
|
232
|
+
src.getString(KEY_FONT_REGULAR), regularFont
|
|
233
|
+
)
|
|
234
|
+
)
|
|
235
|
+
Log.v(
|
|
236
|
+
TAG, String.format(
|
|
237
|
+
"Medium font: [%s], value [%s]",
|
|
238
|
+
src.getString(KEY_FONT_MEDIUM), mediumFont
|
|
239
|
+
)
|
|
240
|
+
)
|
|
241
|
+
Log.v(
|
|
242
|
+
TAG, String.format(
|
|
243
|
+
"Bold font: [%s], value [%s]",
|
|
244
|
+
src.getString(KEY_FONT_BOLD), boldFont
|
|
245
|
+
)
|
|
246
|
+
)
|
|
247
|
+
return Font.Builder()
|
|
248
|
+
.setRegular(regularFont)
|
|
249
|
+
.setMedium(mediumFont)
|
|
250
|
+
.setBold(boldFont)
|
|
251
|
+
.build()
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
private fun handleLogo(
|
|
255
|
+
context: Context,
|
|
256
|
+
key: String,
|
|
257
|
+
branding: Branding.Builder,
|
|
258
|
+
brandConfig: ReadableMap
|
|
259
|
+
) {
|
|
260
|
+
val type = brandConfig.getType(key)
|
|
261
|
+
Log.d(TAG, "Logo type$type")
|
|
262
|
+
if (ReadableType.String == type) {
|
|
263
|
+
branding.logo(getDrawableId(context, brandConfig.getString(key)))
|
|
264
|
+
} else if (ReadableType.Map == type) {
|
|
265
|
+
// check if it's a native RN image
|
|
266
|
+
val image = brandConfig.getMap(key)
|
|
267
|
+
if (image != null) {
|
|
268
|
+
if (image.hasKey(KEY_RN_IMAGE_URI)) {
|
|
269
|
+
val url = image.getString(KEY_RN_IMAGE_URI)
|
|
270
|
+
if (!url.isNullOrEmpty()) {
|
|
271
|
+
// check if url has an async scheme
|
|
272
|
+
if (isAsyncLogoUrl(url)) {
|
|
273
|
+
Log.d(TAG, "Async logo$url")
|
|
274
|
+
branding.logo(ReactNativeImageProvider(url))
|
|
275
|
+
} else {
|
|
276
|
+
Log.d(TAG, "Logo from resource$url")
|
|
277
|
+
branding.logo(getDrawableId(context, url))
|
|
278
|
+
}
|
|
279
|
+
} else {
|
|
280
|
+
Log.w(TAG, "Image url is empty: $url")
|
|
281
|
+
}
|
|
282
|
+
} else {
|
|
283
|
+
for (imageKey in image.toHashMap().keys) {
|
|
284
|
+
Log.w(TAG, imageKey)
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
} else {
|
|
288
|
+
Log.w(TAG, "Provided image is null")
|
|
289
|
+
}
|
|
290
|
+
} else {
|
|
291
|
+
Log.w(TAG, "Unexpected image type: $type")
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
private fun extractToken(startUrl: String): String? {
|
|
296
|
+
// this is suboptimal but it is what it is.. the SDK returns us a token in the
|
|
297
|
+
// INTENT_EXTRA_SESSION_URL for matching :(
|
|
298
|
+
val url = startUrl.toHttpUrlOrNull() ?: return null
|
|
299
|
+
return if (url.encodedPathSegments.size < 2) {
|
|
300
|
+
null
|
|
301
|
+
} else url.encodedPathSegments[1]
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
private fun isAsyncLogoUrl(url: String): Boolean {
|
|
305
|
+
return url.startsWith("https://") || url.startsWith("http://") || url.startsWith("file://")
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
private fun parseColor(hexcolor: String?): Int {
|
|
309
|
+
if (hexcolor == null) {
|
|
310
|
+
return 0
|
|
311
|
+
}
|
|
312
|
+
if (hexcolor.startsWith("#")) {
|
|
313
|
+
return parseColor(hexcolor.substring(1))
|
|
314
|
+
}
|
|
315
|
+
var color = hexcolor.toLong(16)
|
|
316
|
+
var a = 255
|
|
317
|
+
if (hexcolor.length > 6) {
|
|
318
|
+
a = color.toInt() and 0xff
|
|
319
|
+
color = color ushr 8
|
|
320
|
+
}
|
|
321
|
+
val r = (color ushr 16).toInt() and 0xff
|
|
322
|
+
val g = (color ushr 8).toInt() and 0xff
|
|
323
|
+
val b = (color ushr 0).toInt() and 0xff
|
|
324
|
+
return Color.argb(a, r, g, b)
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
companion object {
|
|
328
|
+
/**
|
|
329
|
+
* Indicates that the parameters passed to [.launchVeriff] were invalid.
|
|
330
|
+
*/
|
|
331
|
+
private const val ERROR_INVALID_ARGS = "E_VERIFF_INVALID_ARGUMENTS"
|
|
332
|
+
|
|
333
|
+
/**
|
|
334
|
+
* Indicates that the activity is no longer attached when the
|
|
335
|
+
* [.launchVeriff] method was invoked.
|
|
336
|
+
*/
|
|
337
|
+
private const val ERROR_ACTIVITY_NOT_ATTACHED = "E_VERIFF_ACTIVITY_NOT_ATTACHED"
|
|
338
|
+
|
|
339
|
+
/**
|
|
340
|
+
* The user canceled left the flow before completing it.
|
|
341
|
+
*/
|
|
342
|
+
private const val STATUS_CANCELED = "STATUS_CANCELED"
|
|
343
|
+
|
|
344
|
+
/**
|
|
345
|
+
* The flow was completed, note that this doesn't mean there's a decision yet.
|
|
346
|
+
*/
|
|
347
|
+
private const val STATUS_DONE = "STATUS_DONE"
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* The flow did not complete successfully.
|
|
351
|
+
*/
|
|
352
|
+
private const val STATUS_ERROR = "STATUS_ERROR"
|
|
353
|
+
private const val DEFAULT_BASE_URL = "https://magic.veriff.me"
|
|
354
|
+
const val TAG = "@veriff/RN-SDK"
|
|
355
|
+
private const val JS_NAME = "VeriffSdk"
|
|
356
|
+
private const val VERIFF_REQUEST_CODE = 47239
|
|
357
|
+
private const val KEY_TOKEN = "sessionToken"
|
|
358
|
+
private const val KEY_BASE_URL = "baseUrl"
|
|
359
|
+
private const val KEY_SESSION_URL = "sessionUrl"
|
|
360
|
+
private const val KEY_BRANDING = "branding"
|
|
361
|
+
private const val KEY_LOCALE = "locale"
|
|
362
|
+
private const val KEY_STATUS = "status"
|
|
363
|
+
private const val KEY_RESULT_ERROR = "result_error"
|
|
364
|
+
private const val KEY_LOGO = "logo"
|
|
365
|
+
private const val KEY_BACKGROUND = "background"
|
|
366
|
+
private const val KEY_ON_BACKGROUND = "onBackground"
|
|
367
|
+
private const val KEY_ON_BACKGROUND_SECONDARY = "onBackgroundSecondary"
|
|
368
|
+
private const val KEY_ON_BACKGROUND_TERTIARY = "onBackgroundTertiary"
|
|
369
|
+
private const val KEY_PRIMARY = "primary"
|
|
370
|
+
private const val KEY_ON_PRIMARY = "onPrimary"
|
|
371
|
+
private const val KEY_SECONDARY = "secondary"
|
|
372
|
+
private const val KEY_ON_SECONDARY = "onSecondary"
|
|
373
|
+
private const val KEY_CAMERA_OVERLAY = "cameraOverlay"
|
|
374
|
+
private const val KEY_ON_CAMERA_OVERLAY = "onCameraOverlay"
|
|
375
|
+
private const val KEY_OUTLINE = "outline"
|
|
376
|
+
private const val KEY_SUCCESS = "success"
|
|
377
|
+
private const val KEY_ERROR = "error"
|
|
378
|
+
const val KEY_BUTTON_RADIUS = "buttonRadius"
|
|
379
|
+
private const val KEY_CUSTOM_INTRO_SCREEN = "customIntroScreen"
|
|
380
|
+
private const val KEY_RN_IMAGE_URI = "uri"
|
|
381
|
+
private const val KEY_RN_VENDOR_DATA = "vendorData"
|
|
382
|
+
private const val KEY_FONT = "androidFont"
|
|
383
|
+
private const val KEY_FONT_REGULAR = "regular"
|
|
384
|
+
private const val KEY_FONT_MEDIUM = "medium"
|
|
385
|
+
private const val KEY_FONT_BOLD = "bold"
|
|
386
|
+
private const val ERROR_UNABLE_TO_ACCESS_CAMERA = "UNABLE_TO_ACCESS_CAMERA"
|
|
387
|
+
private const val ERROR_UNABLE_TO_RECORD_AUDIO = "UNABLE_TO_RECORD_AUDIO"
|
|
388
|
+
private const val ERROR_UNABLE_TO_START_CAMERA = "UNABLE_TO_START_CAMERA"
|
|
389
|
+
private const val ERROR_NO_IDENTIFICATION_METHODS_AVAILABLE =
|
|
390
|
+
"NO_IDENTIFICATION_METHODS_AVAILABLE"
|
|
391
|
+
private const val ERROR_UNSUPPORTED_SDK_VERSION = "UNSUPPORTED_SDK_VERSION"
|
|
392
|
+
private const val ERROR_SESSION = "SESSION_ERROR"
|
|
393
|
+
private const val ERROR_SETUP = "SETUP_ERROR"
|
|
394
|
+
private const val ERROR_NETWORK = "NETWORK_ERROR"
|
|
395
|
+
private const val ERROR_UNKNOWN = "UNKNOWN_ERROR"
|
|
396
|
+
private const val ERROR_NFC_DISABLED = "NFC_DISABLED"
|
|
397
|
+
private const val ERROR_DEVICE_HAS_NO_NFC = "DEVICE_HAS_NO_NFC"
|
|
398
|
+
private val EXPORTED_CONSTANTS: MutableMap<String, Any> = HashMap()
|
|
399
|
+
|
|
400
|
+
init {
|
|
401
|
+
// promise reject errors
|
|
402
|
+
EXPORTED_CONSTANTS["errorInvalidArgs"] = ERROR_INVALID_ARGS
|
|
403
|
+
EXPORTED_CONSTANTS["errorActivityNotAttached"] =
|
|
404
|
+
ERROR_ACTIVITY_NOT_ATTACHED
|
|
405
|
+
|
|
406
|
+
// promise resolve statuses
|
|
407
|
+
EXPORTED_CONSTANTS["statusCanceled"] = STATUS_CANCELED
|
|
408
|
+
EXPORTED_CONSTANTS["statusDone"] = STATUS_DONE
|
|
409
|
+
EXPORTED_CONSTANTS["statusError"] = STATUS_ERROR
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
private fun getVeriffStatus(resultCode: Int, veriffResult: Result?): Result.Status {
|
|
413
|
+
return veriffResult?.status
|
|
414
|
+
?: if (resultCode == Activity.RESULT_CANCELED) Result.Status.CANCELED else Result.Status.ERROR
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
private fun getDrawableId(context: Context, name: String?): Int {
|
|
418
|
+
return context.resources.getIdentifier(name, "drawable", context.packageName)
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
private fun getFontId(context: Context, name: String?): Int {
|
|
422
|
+
return context.resources.getIdentifier(name, "font", context.packageName)
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
private fun codeToError(error: Result.Error?): String {
|
|
426
|
+
return when (error) {
|
|
427
|
+
Result.Error.UNABLE_TO_ACCESS_CAMERA -> ERROR_UNABLE_TO_ACCESS_CAMERA
|
|
428
|
+
Result.Error.UNABLE_TO_RECORD_AUDIO -> ERROR_UNABLE_TO_RECORD_AUDIO
|
|
429
|
+
Result.Error.UNABLE_TO_START_CAMERA -> ERROR_UNABLE_TO_START_CAMERA
|
|
430
|
+
Result.Error.UNSUPPORTED_SDK_VERSION -> ERROR_UNSUPPORTED_SDK_VERSION
|
|
431
|
+
Result.Error.SESSION_ERROR -> ERROR_SESSION
|
|
432
|
+
Result.Error.NETWORK_ERROR -> ERROR_NETWORK
|
|
433
|
+
Result.Error.SETUP_ERROR -> ERROR_SETUP
|
|
434
|
+
Result.Error.NFC_DISABLED -> ERROR_NFC_DISABLED
|
|
435
|
+
Result.Error.DEVICE_HAS_NO_NFC -> ERROR_DEVICE_HAS_NO_NFC
|
|
436
|
+
Result.Error.UNKNOWN_ERROR -> ERROR_UNKNOWN
|
|
437
|
+
else -> ERROR_UNKNOWN
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
private fun statusToString(status: Result.Status): String {
|
|
442
|
+
return when (status) {
|
|
443
|
+
Result.Status.DONE -> STATUS_DONE
|
|
444
|
+
Result.Status.CANCELED -> STATUS_CANCELED
|
|
445
|
+
else -> STATUS_ERROR
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
package com.veriff.sdk.reactnative
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.ReactPackage
|
|
4
|
+
import com.facebook.react.bridge.NativeModule
|
|
5
|
+
import com.facebook.react.bridge.ReactApplicationContext
|
|
6
|
+
import com.facebook.react.uimanager.ViewManager
|
|
7
|
+
import java.util.Arrays
|
|
8
|
+
|
|
9
|
+
@Suppress("unused")
|
|
10
|
+
class VeriffSdkPackage : ReactPackage {
|
|
11
|
+
override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> {
|
|
12
|
+
return listOf<NativeModule>(VeriffSdkModule(reactContext))
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> {
|
|
16
|
+
return emptyList()
|
|
17
|
+
}
|
|
18
|
+
}
|
package/catalog-info.yaml
CHANGED
|
@@ -4,7 +4,7 @@ metadata:
|
|
|
4
4
|
name: react-native-sdk
|
|
5
5
|
description: React Native wrapper around our native Android & iOS SDKs
|
|
6
6
|
annotations:
|
|
7
|
-
veriff.com/criticality:
|
|
7
|
+
veriff.com/criticality: disaster
|
|
8
8
|
github.com/project-slug: Veriff/react-native-sdk
|
|
9
9
|
circleci.com/project-slug: github/Veriff/react-native-sdk
|
|
10
10
|
sonarqube.org/project-key: Veriff_react-native-sdk
|
package/ios/Podfile
CHANGED
package/package.json
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@veriff/react-native-sdk",
|
|
3
3
|
"title": "React Native Veriff SDK",
|
|
4
|
-
"version": "6.
|
|
4
|
+
"version": "6.2.0",
|
|
5
5
|
"description": "React Native SDK for Veriff identity verification",
|
|
6
6
|
"main": "index.js",
|
|
7
7
|
"scripts": {
|
|
8
|
-
"lint": "eslint ."
|
|
9
|
-
"check-dependencies": "rnx-align-deps",
|
|
10
|
-
"fix-dependencies": "rnx-align-deps --write"
|
|
8
|
+
"lint": "eslint ."
|
|
11
9
|
},
|
|
12
10
|
"homepage": "https://developers.veriff.com/#react-native-sdk-integration",
|
|
13
11
|
"keywords": [
|
|
@@ -31,56 +29,19 @@
|
|
|
31
29
|
"react-native": "^0.73.0"
|
|
32
30
|
},
|
|
33
31
|
"devDependencies": {
|
|
32
|
+
"@babel/core": "^7.20.0",
|
|
33
|
+
"@babel/preset-env": "^7.20.0",
|
|
34
|
+
"@babel/runtime": "^7.20.0",
|
|
35
|
+
"@react-native/babel-preset": "^0.73.18",
|
|
34
36
|
"@react-native/eslint-config": "^0.73.1",
|
|
35
37
|
"@react-native/metro-config": "^0.73.2",
|
|
36
|
-
"@
|
|
38
|
+
"@react-native/typescript-config": "^0.73.1",
|
|
39
|
+
"@types/react": "^18.2.6",
|
|
37
40
|
"eslint": "^8.19.0",
|
|
38
41
|
"prettier": "2.8.8",
|
|
39
|
-
"
|
|
40
|
-
"react-native": "0.73.0"
|
|
41
|
-
},
|
|
42
|
-
"resolutions": {
|
|
43
|
-
"ansi-regex": "^5.0.1",
|
|
44
|
-
"minimist": "^0.2.1",
|
|
45
|
-
"lodash": "^4.17.21",
|
|
46
|
-
"ua-parser-js": "^0.7.24",
|
|
47
|
-
"path-parse": "^1.0.7",
|
|
48
|
-
"tmpl": "^1.0.5",
|
|
49
|
-
"node-fetch": "^2.6.7",
|
|
50
|
-
"plist": "^3.0.4",
|
|
51
|
-
"ajv": "^6.12.3"
|
|
52
|
-
},
|
|
53
|
-
"resolutionComments": {
|
|
54
|
-
"ansi-regex": "Resolving to 5.0.1 to fix vulnerability (https://github.com/advisories/GHSA-93q8-gq69-wqmw)",
|
|
55
|
-
"minimist": "Resolving to 0.2.1 to fix vulnerability (https://www.npmjs.com/advisories/1066649)",
|
|
56
|
-
"lodash": "Resolving to 4.17.21 to fix vulnerability (https://www.npmjs.com/advisories/1065397)",
|
|
57
|
-
"ua-parser-js": "Resolving to 0.7.24 to fix vulnerability (https://www.npmjs.com/advisories/1065393)",
|
|
58
|
-
"path-parse": "Resolving to 1.0.7 to fix vulnerability (https://www.npmjs.com/advisories/1064972)",
|
|
59
|
-
"tmpl": "Resolving to 1.0.5 to fix vulnerability (https://www.npmjs.com/advisories/1064907)",
|
|
60
|
-
"node-fetch": "Resolving to 2.6.7 to fix vulnerability (https://www.npmjs.com/advisories/1064646)",
|
|
61
|
-
"plist": "Resolving to 3.0.4 to fix vulnerability (https://www.npmjs.com/advisories/1064605)",
|
|
62
|
-
"ajv": "Resolving to 6.12.3 to fix vulnerability (https://www.npmjs.com/advisories/1065159)"
|
|
63
|
-
},
|
|
64
|
-
"rnx-kit": {
|
|
65
|
-
"kitType": "library",
|
|
66
|
-
"alignDeps": {
|
|
67
|
-
"requirements": {
|
|
68
|
-
"development": [
|
|
69
|
-
"react-native@0.73"
|
|
70
|
-
],
|
|
71
|
-
"production": [
|
|
72
|
-
"react-native@0.73"
|
|
73
|
-
]
|
|
74
|
-
},
|
|
75
|
-
"capabilities": [
|
|
76
|
-
"core",
|
|
77
|
-
"core-android",
|
|
78
|
-
"core-ios",
|
|
79
|
-
"react"
|
|
80
|
-
]
|
|
81
|
-
}
|
|
42
|
+
"typescript": "5.0.4"
|
|
82
43
|
},
|
|
83
|
-
"
|
|
84
|
-
"
|
|
44
|
+
"engines": {
|
|
45
|
+
"node": ">=18"
|
|
85
46
|
}
|
|
86
47
|
}
|
package/react-native-sdk.podspec
CHANGED