@veriff/react-native-sdk 5.2.0 → 6.1.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/babel.config.js +1 -1
- package/catalog-info.yaml +1 -1
- package/ios/Podfile +2 -4
- package/ios/VeriffSdk.swift +4 -2
- package/package.json +15 -54
- 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 -489
- 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/babel.config.js
CHANGED
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
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
platform :ios, '
|
|
1
|
+
platform :ios, '13.4'
|
|
2
2
|
|
|
3
3
|
# Resolve react_native_pods.rb with node to allow for hoisting
|
|
4
4
|
require Pod::Executable.execute_command('node', ['-p',
|
|
@@ -9,12 +9,10 @@ require Pod::Executable.execute_command('node', ['-p',
|
|
|
9
9
|
|
|
10
10
|
target 'VeriffSdk' do
|
|
11
11
|
# Pods for VeriffSdk
|
|
12
|
-
pod 'VeriffSDK', '6.
|
|
12
|
+
pod 'VeriffSDK', '6.31.0'
|
|
13
13
|
|
|
14
14
|
config = use_native_modules!
|
|
15
15
|
|
|
16
|
-
# Flags change depending on the env values.
|
|
17
|
-
flags = get_default_flags()
|
|
18
16
|
use_react_native!(
|
|
19
17
|
:path => config[:reactNativePath]
|
|
20
18
|
)
|
package/ios/VeriffSdk.swift
CHANGED
|
@@ -29,6 +29,7 @@ class VeriffSdk: NSObject {
|
|
|
29
29
|
private static let LOCALE = "locale"
|
|
30
30
|
private static let LOGO = "logo"
|
|
31
31
|
private static let USE_CUSTOM_INTRO_SCREEN = "customIntroScreen"
|
|
32
|
+
private static let VENDOR_DATA = "vendorData"
|
|
32
33
|
|
|
33
34
|
private static let STATUS = "status"
|
|
34
35
|
private static let ERROR = "error"
|
|
@@ -118,7 +119,6 @@ class VeriffSdk: NSObject {
|
|
|
118
119
|
}
|
|
119
120
|
|
|
120
121
|
veriffConfiguration = Veriff.VeriffSdk.Configuration(branding: veriffBranding, languageLocale: locale)
|
|
121
|
-
veriffConfiguration?.customIntroScreen = VeriffSdk.checkCustomIntro(configuration: configuration)
|
|
122
122
|
} else if let sessionToken = configuration[VeriffSdk.SESSION_TOKEN] as? String {
|
|
123
123
|
// Using deprecated API
|
|
124
124
|
let baseURLString = configuration[VeriffSdk.BASE_URL] as? String ?? VeriffSdk.DEFAULT_BASE_URL
|
|
@@ -128,13 +128,15 @@ class VeriffSdk: NSObject {
|
|
|
128
128
|
sessionURL = baseURL.appendingPathComponent(sessionToken)
|
|
129
129
|
|
|
130
130
|
veriffConfiguration = Veriff.VeriffSdk.Configuration(branding: veriffBranding)
|
|
131
|
-
veriffConfiguration?.customIntroScreen = VeriffSdk.checkCustomIntro(configuration: configuration)
|
|
132
131
|
} else {
|
|
133
132
|
// Failed to configure
|
|
134
133
|
reject(VeriffSdk.ERROR_INVALID_ARGS, "No sessionUrl or sessionToken in Veriff SDK configuration", nil)
|
|
135
134
|
return
|
|
136
135
|
}
|
|
137
136
|
|
|
137
|
+
veriffConfiguration?.customIntroScreen = VeriffSdk.checkCustomIntro(configuration: configuration)
|
|
138
|
+
veriffConfiguration?.vendorData = configuration[VeriffSdk.VENDOR_DATA] as? String
|
|
139
|
+
|
|
138
140
|
DispatchQueue.main.async {
|
|
139
141
|
self.resolve = resolve
|
|
140
142
|
self.reject = reject
|
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": "
|
|
4
|
+
"version": "6.1.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": [
|
|
@@ -28,59 +26,22 @@
|
|
|
28
26
|
"readmeFilename": "README.md",
|
|
29
27
|
"peerDependencies": {
|
|
30
28
|
"react": "18.2.0",
|
|
31
|
-
"react-native": "^0.
|
|
29
|
+
"react-native": "^0.73.0"
|
|
32
30
|
},
|
|
33
31
|
"devDependencies": {
|
|
34
|
-
"@
|
|
35
|
-
"@
|
|
36
|
-
"@
|
|
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",
|
|
36
|
+
"@react-native/eslint-config": "^0.73.1",
|
|
37
|
+
"@react-native/metro-config": "^0.73.2",
|
|
38
|
+
"@react-native/typescript-config": "^0.73.1",
|
|
39
|
+
"@types/react": "^18.2.6",
|
|
37
40
|
"eslint": "^8.19.0",
|
|
38
|
-
"prettier": "
|
|
39
|
-
"
|
|
40
|
-
"react-native": "0.72.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.71"
|
|
70
|
-
],
|
|
71
|
-
"production": [
|
|
72
|
-
"react-native@0.71"
|
|
73
|
-
]
|
|
74
|
-
},
|
|
75
|
-
"capabilities": [
|
|
76
|
-
"core",
|
|
77
|
-
"core-android",
|
|
78
|
-
"core-ios",
|
|
79
|
-
"react"
|
|
80
|
-
]
|
|
81
|
-
}
|
|
41
|
+
"prettier": "2.8.8",
|
|
42
|
+
"typescript": "5.0.4"
|
|
82
43
|
},
|
|
83
|
-
"
|
|
84
|
-
"
|
|
44
|
+
"engines": {
|
|
45
|
+
"node": ">=18"
|
|
85
46
|
}
|
|
86
47
|
}
|
package/react-native-sdk.podspec
CHANGED