@reclaimprotocol/inapp-rn-sdk 0.1.3
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/InappRnSdk.podspec +43 -0
- package/LICENSE +20 -0
- package/README.md +292 -0
- package/android/build.gradle +130 -0
- package/android/generated/java/com/reclaimprotocol/inapp_rn_sdk/NativeInappRnSdkSpec.java +71 -0
- package/android/generated/jni/CMakeLists.txt +36 -0
- package/android/generated/jni/RNInappRnSdkSpec-generated.cpp +61 -0
- package/android/generated/jni/RNInappRnSdkSpec.h +31 -0
- package/android/generated/jni/react/renderer/components/RNInappRnSdkSpec/RNInappRnSdkSpecJSI-generated.cpp +56 -0
- package/android/generated/jni/react/renderer/components/RNInappRnSdkSpec/RNInappRnSdkSpecJSI.h +930 -0
- package/android/gradle.properties +5 -0
- package/android/src/main/AndroidManifest.xml +3 -0
- package/android/src/main/AndroidManifestNew.xml +2 -0
- package/android/src/main/java/com/reclaimprotocol/inapp_rn_sdk/InappRnSdkModule.kt +327 -0
- package/android/src/main/java/com/reclaimprotocol/inapp_rn_sdk/InappRnSdkPackage.kt +33 -0
- package/ios/InappRnSdk-Bridging-Header.h +1 -0
- package/ios/InappRnSdk.h +17 -0
- package/ios/InappRnSdk.mm +215 -0
- package/ios/generated/RNInappRnSdkSpec/RNInappRnSdkSpec-generated.mm +136 -0
- package/ios/generated/RNInappRnSdkSpec/RNInappRnSdkSpec.h +391 -0
- package/ios/generated/RNInappRnSdkSpecJSI-generated.cpp +56 -0
- package/ios/generated/RNInappRnSdkSpecJSI.h +930 -0
- package/ios/inapp_rn_sdk/Api.swift +405 -0
- package/lib/commonjs/ReclaimVerificationPlatformChannel.js +177 -0
- package/lib/commonjs/ReclaimVerificationPlatformChannel.js.map +1 -0
- package/lib/commonjs/index.js +43 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/specs/NativeInappRnSdk.js +23 -0
- package/lib/commonjs/specs/NativeInappRnSdk.js.map +1 -0
- package/lib/module/ReclaimVerificationPlatformChannel.js +171 -0
- package/lib/module/ReclaimVerificationPlatformChannel.js.map +1 -0
- package/lib/module/index.js +27 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/specs/NativeInappRnSdk.js +24 -0
- package/lib/module/specs/NativeInappRnSdk.js.map +1 -0
- package/lib/typescript/commonjs/package.json +1 -0
- package/lib/typescript/commonjs/src/ReclaimVerificationPlatformChannel.d.ts +80 -0
- package/lib/typescript/commonjs/src/ReclaimVerificationPlatformChannel.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/index.d.ts +12 -0
- package/lib/typescript/commonjs/src/index.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/specs/NativeInappRnSdk.d.ts +281 -0
- package/lib/typescript/commonjs/src/specs/NativeInappRnSdk.d.ts.map +1 -0
- package/lib/typescript/module/package.json +1 -0
- package/lib/typescript/module/src/ReclaimVerificationPlatformChannel.d.ts +80 -0
- package/lib/typescript/module/src/ReclaimVerificationPlatformChannel.d.ts.map +1 -0
- package/lib/typescript/module/src/index.d.ts +12 -0
- package/lib/typescript/module/src/index.d.ts.map +1 -0
- package/lib/typescript/module/src/specs/NativeInappRnSdk.d.ts +281 -0
- package/lib/typescript/module/src/specs/NativeInappRnSdk.d.ts.map +1 -0
- package/package.json +204 -0
- package/react-native.config.js +12 -0
- package/src/ReclaimVerificationPlatformChannel.ts +245 -0
- package/src/index.tsx +32 -0
- package/src/specs/NativeInappRnSdk.ts +313 -0
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
package com.reclaimprotocol.inapp_rn_sdk
|
|
2
|
+
|
|
3
|
+
import java.util.UUID
|
|
4
|
+
import android.util.Log
|
|
5
|
+
import com.facebook.react.bridge.Arguments
|
|
6
|
+
import com.facebook.react.bridge.Promise
|
|
7
|
+
import com.facebook.react.bridge.ReactApplicationContext
|
|
8
|
+
import com.facebook.react.bridge.ReadableMap
|
|
9
|
+
import com.facebook.react.bridge.WritableArray
|
|
10
|
+
import com.facebook.react.bridge.WritableMap
|
|
11
|
+
import com.facebook.react.module.annotations.ReactModule
|
|
12
|
+
import org.reclaimprotocol.inapp_sdk.ReclaimOverrides
|
|
13
|
+
import org.reclaimprotocol.inapp_sdk.ReclaimSessionStatus
|
|
14
|
+
import org.reclaimprotocol.inapp_sdk.ReclaimVerification
|
|
15
|
+
|
|
16
|
+
@ReactModule(name = InappRnSdkModule.NAME)
|
|
17
|
+
class InappRnSdkModule(private val reactContext: ReactApplicationContext) :
|
|
18
|
+
NativeInappRnSdkSpec(reactContext) {
|
|
19
|
+
|
|
20
|
+
override fun getName(): String {
|
|
21
|
+
return NAME
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
companion object {
|
|
25
|
+
const val NAME = "InappRnSdk"
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
class ReclaimVerificationResultHandlerImpl(val promise: Promise?) :
|
|
29
|
+
ReclaimVerification.ResultHandler {
|
|
30
|
+
override fun onException(exception: ReclaimVerification.ReclaimVerificationException) {
|
|
31
|
+
Log.e(NAME, "reclaim exception", exception)
|
|
32
|
+
val userInfoMap = Arguments.createMap()
|
|
33
|
+
val errorType = when (exception) {
|
|
34
|
+
is ReclaimVerification.ReclaimVerificationException.Cancelled -> "cancelled"
|
|
35
|
+
is ReclaimVerification.ReclaimVerificationException.Dismissed -> "dismissed"
|
|
36
|
+
is ReclaimVerification.ReclaimVerificationException.Failed -> "failed"
|
|
37
|
+
is ReclaimVerification.ReclaimVerificationException.SessionExpired -> "sessionExpired"
|
|
38
|
+
}
|
|
39
|
+
userInfoMap.putString("errorType", errorType)
|
|
40
|
+
userInfoMap.putString("sessionId", exception.sessionId)
|
|
41
|
+
userInfoMap.putBoolean("didSubmitManualVerification", exception.didSubmitManualVerification)
|
|
42
|
+
userInfoMap.putString("reason", if (exception is ReclaimVerification.ReclaimVerificationException.Failed) exception.reason else null)
|
|
43
|
+
promise?.reject("VERIFICATION_ERROR", "Verification Error", exception, userInfoMap)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
override fun onResponse(response: ReclaimVerification.Response) {
|
|
47
|
+
Log.d(NAME, "reclaim response")
|
|
48
|
+
val returnResponse: WritableMap = Arguments.createMap()
|
|
49
|
+
returnResponse.putString("sessionId", response.sessionId)
|
|
50
|
+
returnResponse.putBoolean("didSubmitManualVerification", response.didSubmitManualVerification)
|
|
51
|
+
val returnProofs: WritableArray = Arguments.createArray()
|
|
52
|
+
for (proof in response.proofs) {
|
|
53
|
+
val returnProof = Arguments.makeNativeMap(proof)
|
|
54
|
+
returnProofs.pushMap(returnProof)
|
|
55
|
+
}
|
|
56
|
+
returnResponse.putArray("proofs", returnProofs)
|
|
57
|
+
promise?.resolve(returnResponse)
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
override fun startVerification(request: ReadableMap?, promise: Promise?) {
|
|
62
|
+
Log.d(NAME, "startVerification")
|
|
63
|
+
if (request == null) {
|
|
64
|
+
Log.d(NAME, "no request. rejecting.")
|
|
65
|
+
|
|
66
|
+
promise?.reject(IllegalArgumentException("Request is null"))
|
|
67
|
+
return
|
|
68
|
+
}
|
|
69
|
+
val handler = ReclaimVerificationResultHandlerImpl(promise)
|
|
70
|
+
reactContext.runOnUiQueueThread {
|
|
71
|
+
val appId =getString(request,"appId")
|
|
72
|
+
val secret = getString(request,"secret")
|
|
73
|
+
val verificationRequest: ReclaimVerification.Request
|
|
74
|
+
val session = request.getMap("session")
|
|
75
|
+
val parametersRN = request.getMap("parameters")?.toHashMap()
|
|
76
|
+
val parameters = mutableMapOf<String, String>()
|
|
77
|
+
if (parametersRN != null) {
|
|
78
|
+
for (key in parametersRN.keys) {
|
|
79
|
+
val value = parametersRN[key]
|
|
80
|
+
if (value is String) {
|
|
81
|
+
parameters[key] = value
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
val hideLanding = getBoolean(request, "hideLanding")
|
|
86
|
+
val autoSubmit = getBoolean(request, "autoSubmit")
|
|
87
|
+
val acceptAiProviders = getBoolean(request, "acceptAiProviders")
|
|
88
|
+
val webhookUrl = getString(request, "webhookUrl")
|
|
89
|
+
if (appId.isNullOrBlank() && secret.isNullOrBlank()) {
|
|
90
|
+
verificationRequest = ReclaimVerification.Request.fromManifestMetaData(
|
|
91
|
+
context = reactContext.applicationContext,
|
|
92
|
+
providerId = getString(request, "providerId")!!,
|
|
93
|
+
contextString = getString(request, "contextString") ?: "",
|
|
94
|
+
session = if (session == null) null else ReclaimVerification.ReclaimSessionInformation(
|
|
95
|
+
timestamp = getString(session, "timestamp") ?: "",
|
|
96
|
+
sessionId = getString(session, "sessionId") ?: "",
|
|
97
|
+
signature = getString(session, "signature") ?: "",
|
|
98
|
+
),
|
|
99
|
+
parameters = parameters,
|
|
100
|
+
hideLanding = hideLanding ?: true,
|
|
101
|
+
autoSubmit = autoSubmit ?: false,
|
|
102
|
+
acceptAiProviders = acceptAiProviders ?: false,
|
|
103
|
+
webhookUrl = webhookUrl,
|
|
104
|
+
)
|
|
105
|
+
} else {
|
|
106
|
+
verificationRequest = ReclaimVerification.Request(
|
|
107
|
+
appId = appId!!,
|
|
108
|
+
secret = secret!!,
|
|
109
|
+
providerId = getString(request, "providerId")!!,
|
|
110
|
+
contextString = getString(request, "contextString") ?: "",
|
|
111
|
+
session = if (session == null) null else ReclaimVerification.ReclaimSessionInformation(
|
|
112
|
+
timestamp = getString(session, "timestamp") ?: "",
|
|
113
|
+
sessionId = getString(session, "sessionId") ?: "",
|
|
114
|
+
signature = getString(session, "signature") ?: "",
|
|
115
|
+
),
|
|
116
|
+
parameters = parameters,
|
|
117
|
+
hideLanding = hideLanding ?: true,
|
|
118
|
+
autoSubmit = autoSubmit ?: false,
|
|
119
|
+
acceptAiProviders = acceptAiProviders ?: false,
|
|
120
|
+
webhookUrl = webhookUrl,
|
|
121
|
+
)
|
|
122
|
+
}
|
|
123
|
+
ReclaimVerification.startVerification(
|
|
124
|
+
context = reactContext.applicationContext,
|
|
125
|
+
request = verificationRequest,
|
|
126
|
+
handler = handler
|
|
127
|
+
)
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
override fun startVerificationFromUrl(requestUrl: String?, promise: Promise?) {
|
|
132
|
+
Log.d(NAME, "startVerificationFromUrl")
|
|
133
|
+
if (requestUrl == null) {
|
|
134
|
+
Log.d(NAME, "no request url. rejecting.")
|
|
135
|
+
|
|
136
|
+
promise?.reject(IllegalArgumentException("Request url is null"))
|
|
137
|
+
return
|
|
138
|
+
}
|
|
139
|
+
val handler = ReclaimVerificationResultHandlerImpl(promise)
|
|
140
|
+
reactContext.runOnUiQueueThread {
|
|
141
|
+
ReclaimVerification.startVerificationFromUrl(
|
|
142
|
+
context = reactContext.applicationContext, requestUrl = requestUrl, handler = handler
|
|
143
|
+
)
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
override fun setOverrides(overrides: ReadableMap?, promise: Promise?) {
|
|
148
|
+
return setOverrides(
|
|
149
|
+
provider = getMap(overrides, "provider"),
|
|
150
|
+
featureOptions = getMap(overrides, "featureOptions"),
|
|
151
|
+
logConsumer = getMap(overrides, "logConsumer"),
|
|
152
|
+
sessionManagement = getMap(overrides, "sessionManagement"),
|
|
153
|
+
appInfo = getMap(overrides, "appInfo"),
|
|
154
|
+
promise,
|
|
155
|
+
)
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
private val replyHandlers: MutableMap<String, (Result<Boolean>) -> Unit> = mutableMapOf()
|
|
159
|
+
|
|
160
|
+
private fun setOverrides(
|
|
161
|
+
provider: ReadableMap?,
|
|
162
|
+
featureOptions: ReadableMap?,
|
|
163
|
+
logConsumer: ReadableMap?,
|
|
164
|
+
sessionManagement: ReadableMap?,
|
|
165
|
+
appInfo: ReadableMap?,
|
|
166
|
+
promise: Promise?
|
|
167
|
+
) {
|
|
168
|
+
reactContext.runOnUiQueueThread {
|
|
169
|
+
ReclaimVerification.setOverrides(
|
|
170
|
+
context = reactContext.applicationContext,
|
|
171
|
+
provider = if (provider == null) null else (if (provider.isNull("url")) ReclaimOverrides.ProviderInformation.FromJsonString(
|
|
172
|
+
requireString(
|
|
173
|
+
provider, "jsonString"
|
|
174
|
+
)
|
|
175
|
+
)
|
|
176
|
+
else ReclaimOverrides.ProviderInformation.FromUrl(requireString(provider, "url"))),
|
|
177
|
+
featureOptions = if (featureOptions == null) null else ReclaimOverrides.FeatureOptions(
|
|
178
|
+
cookiePersist = getBoolean(featureOptions, "cookiePersist"),
|
|
179
|
+
singleReclaimRequest = getBoolean(featureOptions, "singleReclaimRequest"),
|
|
180
|
+
idleTimeThresholdForManualVerificationTrigger = getLong(
|
|
181
|
+
featureOptions, "idleTimeThresholdForManualVerificationTrigger"
|
|
182
|
+
),
|
|
183
|
+
sessionTimeoutForManualVerificationTrigger = getLong(
|
|
184
|
+
featureOptions, "sessionTimeoutForManualVerificationTrigger"
|
|
185
|
+
),
|
|
186
|
+
attestorBrowserRpcUrl = getString(featureOptions, "attestorBrowserRpcUrl"),
|
|
187
|
+
isResponseRedactionRegexEscapingEnabled = getBoolean(
|
|
188
|
+
featureOptions, "isResponseRedactionRegexEscapingEnabled"
|
|
189
|
+
),
|
|
190
|
+
isAIFlowEnabled = getBoolean(featureOptions, "isAIFlowEnabled")
|
|
191
|
+
),
|
|
192
|
+
logConsumer = if (logConsumer == null) null else ReclaimOverrides.LogConsumer(
|
|
193
|
+
logHandler = if (getBoolean(logConsumer, "enableLogHandler") != true) null else object :
|
|
194
|
+
ReclaimOverrides.LogConsumer.LogHandler {
|
|
195
|
+
override fun onLogs(logJsonString: String) {
|
|
196
|
+
emitOnLogs(logJsonString)
|
|
197
|
+
}
|
|
198
|
+
},
|
|
199
|
+
canSdkCollectTelemetry = getBoolean(logConsumer, "canSdkCollectTelemetry") ?: true,
|
|
200
|
+
canSdkPrintLogs = getBoolean(logConsumer, "canSdkPrintLogs")
|
|
201
|
+
),
|
|
202
|
+
sessionManagement = if (sessionManagement == null || getBoolean(
|
|
203
|
+
sessionManagement, "enableSdkSessionManagement"
|
|
204
|
+
) != false
|
|
205
|
+
) null else ReclaimOverrides.SessionManagement(handler = object :
|
|
206
|
+
ReclaimOverrides.SessionManagement.SessionHandler {
|
|
207
|
+
override fun createSession(
|
|
208
|
+
appId: String,
|
|
209
|
+
providerId: String,
|
|
210
|
+
sessionId: String,
|
|
211
|
+
callback: (Result<Boolean>) -> Unit
|
|
212
|
+
) {
|
|
213
|
+
val args = Arguments.createMap()
|
|
214
|
+
args.putString("appId", appId)
|
|
215
|
+
args.putString("providerId", providerId)
|
|
216
|
+
args.putString("sessionId", sessionId)
|
|
217
|
+
val replyId = UUID.randomUUID().toString()
|
|
218
|
+
args.putString("replyId", replyId)
|
|
219
|
+
replyHandlers[replyId] = callback
|
|
220
|
+
emitOnSessionCreateRequest(args)
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
override fun logSession(
|
|
224
|
+
appId: String, providerId: String, sessionId: String, logType: String
|
|
225
|
+
) {
|
|
226
|
+
val args = Arguments.createMap()
|
|
227
|
+
args.putString("appId", appId)
|
|
228
|
+
args.putString("providerId", providerId)
|
|
229
|
+
args.putString("sessionId", sessionId)
|
|
230
|
+
args.putString("logType", logType)
|
|
231
|
+
emitOnSessionLogs(args)
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
override fun updateSession(
|
|
235
|
+
sessionId: String, status: ReclaimSessionStatus, callback: (Result<Boolean>) -> Unit
|
|
236
|
+
) {
|
|
237
|
+
status.name
|
|
238
|
+
val args = Arguments.createMap()
|
|
239
|
+
args.putString("sessionId", sessionId)
|
|
240
|
+
args.putString("status", status.name)
|
|
241
|
+
val replyId = UUID.randomUUID().toString()
|
|
242
|
+
args.putString("replyId", replyId)
|
|
243
|
+
replyHandlers[replyId] = callback
|
|
244
|
+
emitOnSessionUpdateRequest(args)
|
|
245
|
+
}
|
|
246
|
+
}),
|
|
247
|
+
appInfo = if (appInfo == null) null else ReclaimOverrides.ReclaimAppInfo(
|
|
248
|
+
appName = requireString(appInfo, "appName"),
|
|
249
|
+
appImageUrl = requireString(appInfo, "appImageUrl"),
|
|
250
|
+
isRecurring = getBoolean(appInfo, "isRecurring") ?: false,
|
|
251
|
+
),
|
|
252
|
+
) { result ->
|
|
253
|
+
result.onSuccess {
|
|
254
|
+
promise?.resolve(true)
|
|
255
|
+
}.onFailure { error ->
|
|
256
|
+
promise?.reject(error)
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
override fun reply(replyId: String?, reply: Boolean) {
|
|
263
|
+
if (replyId == null) {
|
|
264
|
+
Log.w(NAME, "Missing arg replyId")
|
|
265
|
+
return
|
|
266
|
+
}
|
|
267
|
+
reactContext.runOnUiQueueThread {
|
|
268
|
+
val callback = replyHandlers[replyId]
|
|
269
|
+
if (callback != null) {
|
|
270
|
+
callback(Result.success(reply))
|
|
271
|
+
} else {
|
|
272
|
+
Log.w(NAME, "Missing reply handler for id: $replyId")
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
private fun requireString(map: ReadableMap, key: String): String {
|
|
278
|
+
val value = getString(map, key)
|
|
279
|
+
if (value == null) {
|
|
280
|
+
Log.w(NAME, "Missing value for key: $key")
|
|
281
|
+
return ""
|
|
282
|
+
}
|
|
283
|
+
return value
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
private fun getMap(map: ReadableMap?, key: String): ReadableMap? {
|
|
287
|
+
return if (map == null || !map.hasKey(key) || map.isNull(key)) {
|
|
288
|
+
null
|
|
289
|
+
} else {
|
|
290
|
+
map.getMap(key)
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
private fun getLong(map: ReadableMap, key: String): Long? {
|
|
295
|
+
return if (!map.hasKey(key) || map.isNull(key)) {
|
|
296
|
+
null
|
|
297
|
+
} else {
|
|
298
|
+
map.getLong(key)
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
private fun getString(map: ReadableMap, key: String): String? {
|
|
303
|
+
return if (!map.hasKey(key) || map.isNull(key)) {
|
|
304
|
+
null
|
|
305
|
+
} else {
|
|
306
|
+
map.getString(key)
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
private fun getBoolean(map: ReadableMap, key: String): Boolean? {
|
|
311
|
+
return if (!map.hasKey(key) || map.isNull(key)) {
|
|
312
|
+
null
|
|
313
|
+
} else {
|
|
314
|
+
map.getBoolean(key)
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
override fun ping(promise: Promise?) {
|
|
319
|
+
Log.d(NAME, "startVerification")
|
|
320
|
+
fun submitPing() {
|
|
321
|
+
promise?.resolve(true)
|
|
322
|
+
}
|
|
323
|
+
reactContext.runOnUiQueueThread {
|
|
324
|
+
submitPing()
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
package com.reclaimprotocol.inapp_rn_sdk
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.BaseReactPackage
|
|
4
|
+
import com.facebook.react.bridge.NativeModule
|
|
5
|
+
import com.facebook.react.bridge.ReactApplicationContext
|
|
6
|
+
import com.facebook.react.module.model.ReactModuleInfo
|
|
7
|
+
import com.facebook.react.module.model.ReactModuleInfoProvider
|
|
8
|
+
import java.util.HashMap
|
|
9
|
+
|
|
10
|
+
class InappRnSdkPackage : BaseReactPackage() {
|
|
11
|
+
override fun getModule(name: String, reactContext: ReactApplicationContext): NativeModule? {
|
|
12
|
+
return if (name == InappRnSdkModule.NAME) {
|
|
13
|
+
InappRnSdkModule(reactContext)
|
|
14
|
+
} else {
|
|
15
|
+
null
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
override fun getReactModuleInfoProvider(): ReactModuleInfoProvider {
|
|
20
|
+
return ReactModuleInfoProvider {
|
|
21
|
+
val moduleInfos: MutableMap<String, ReactModuleInfo> = HashMap()
|
|
22
|
+
moduleInfos[InappRnSdkModule.NAME] = ReactModuleInfo(
|
|
23
|
+
InappRnSdkModule.NAME,
|
|
24
|
+
InappRnSdkModule.NAME,
|
|
25
|
+
false, // canOverrideExistingModule
|
|
26
|
+
false, // needsEagerInit
|
|
27
|
+
false, // isCxxModule
|
|
28
|
+
true // isTurboModule
|
|
29
|
+
)
|
|
30
|
+
moduleInfos
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
package/ios/InappRnSdk.h
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
|
2
|
+
#import "generated/RNInappRnSdkSpec/RNInappRnSdkSpec.h"
|
|
3
|
+
|
|
4
|
+
NS_ASSUME_NONNULL_BEGIN
|
|
5
|
+
|
|
6
|
+
@interface InappRnSdk : NativeInappRnSdkSpecBase <NativeInappRnSdkSpec>
|
|
7
|
+
|
|
8
|
+
NS_ASSUME_NONNULL_END
|
|
9
|
+
|
|
10
|
+
#else
|
|
11
|
+
#import <React/RCTBridgeModule.h>
|
|
12
|
+
|
|
13
|
+
@interface InappRnSdk : NSObject <RCTBridgeModule>
|
|
14
|
+
#endif
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@end
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
#import "InappRnSdk.h"
|
|
2
|
+
|
|
3
|
+
/*
|
|
4
|
+
This condition is needed to support use_frameworks.
|
|
5
|
+
https://github.com/callstack/react-native-builder-bob/discussions/412#discussioncomment-6352402
|
|
6
|
+
*/
|
|
7
|
+
#if __has_include("InappRnSdk-Swift.h")
|
|
8
|
+
#import "InappRnSdk-Swift.h"
|
|
9
|
+
#else
|
|
10
|
+
#import "InappRnSdk/InappRnSdk-Swift.h"
|
|
11
|
+
#endif
|
|
12
|
+
|
|
13
|
+
@implementation InappRnSdk
|
|
14
|
+
RCT_EXPORT_MODULE()
|
|
15
|
+
|
|
16
|
+
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
|
|
17
|
+
(const facebook::react::ObjCTurboModule::InitParams &)params
|
|
18
|
+
{
|
|
19
|
+
return std::make_shared<facebook::react::NativeInappRnSdkSpecJSI>(params);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
Api *api = [[Api alloc] init];
|
|
23
|
+
|
|
24
|
+
- (void)ping:(nonnull RCTPromiseResolveBlock)resolve reject:(nonnull RCTPromiseRejectBlock)reject {
|
|
25
|
+
|
|
26
|
+
BOOL pingResult = [api ping];
|
|
27
|
+
if (pingResult) {
|
|
28
|
+
resolve(@true);
|
|
29
|
+
} else {
|
|
30
|
+
resolve(@false);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
- (void)reply:(nonnull NSString *)replyId reply:(BOOL)reply {
|
|
35
|
+
[api replyWithReplyId:replyId reply:reply];
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
- (void)startVerification:(JS::NativeInappRnSdk::Request &)request resolve:(nonnull RCTPromiseResolveBlock)resolve reject:(nonnull RCTPromiseRejectBlock)reject {
|
|
39
|
+
NSLog(@"[InappRnSdk] starting verification");
|
|
40
|
+
|
|
41
|
+
bool hideLanding = true;
|
|
42
|
+
if (request.hideLanding().has_value()) {
|
|
43
|
+
hideLanding = request.hideLanding().value();
|
|
44
|
+
}
|
|
45
|
+
bool autoSubmit = false;
|
|
46
|
+
if (request.autoSubmit().has_value()) {
|
|
47
|
+
autoSubmit = request.autoSubmit().value();
|
|
48
|
+
}
|
|
49
|
+
bool acceptAiProviders = false;
|
|
50
|
+
if (request.acceptAiProviders().has_value()) {
|
|
51
|
+
acceptAiProviders = request.acceptAiProviders().value();
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
NSString *sessionId = nil;
|
|
55
|
+
NSString *timestamp = nil;
|
|
56
|
+
NSString *signature = nil;
|
|
57
|
+
if (request.session().has_value()) {
|
|
58
|
+
sessionId = request.session().value().sessionId();
|
|
59
|
+
timestamp = request.session().value().timestamp();
|
|
60
|
+
signature = request.session().value().signature();
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
NSDictionary<NSString *, NSString *> *parameters = @{};
|
|
64
|
+
if (request.parameters() != nil) {
|
|
65
|
+
id potentialParameters = request.parameters();
|
|
66
|
+
if ([potentialParameters isKindOfClass:[NSDictionary class]]) {
|
|
67
|
+
// just verifying because cannot trust JS
|
|
68
|
+
NSDictionary *tempDictionary = (NSDictionary *)potentialParameters;
|
|
69
|
+
BOOL allStrings = YES;
|
|
70
|
+
for (id key in tempDictionary) {
|
|
71
|
+
if (![key isKindOfClass:[NSString class]] || ![tempDictionary[key] isKindOfClass:[NSString class]]) {
|
|
72
|
+
allStrings = NO;
|
|
73
|
+
break;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
if (allStrings){
|
|
77
|
+
// should always be the case
|
|
78
|
+
parameters = (NSDictionary<NSString *, NSString *> *)potentialParameters;
|
|
79
|
+
} else {
|
|
80
|
+
NSLog(@"[InappRnSdk] request.parameters() contains non string key or value");
|
|
81
|
+
}
|
|
82
|
+
} else {
|
|
83
|
+
NSLog(@"[InappRnSdk] request.parameters() is not a dictionary.");
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
NSLog(@"[InappRnSdk] starting verification now");
|
|
88
|
+
[api startVerificationWithAppId:request.appId() secret:request.secret() providerId:request.providerId() sessionTimestamp:timestamp sessionSessionId:sessionId sessionSignature:signature context:request.contextString() parameters:parameters hideLanding:hideLanding autoSubmit:autoSubmit acceptAiProviders:acceptAiProviders webhookUrl:request.webhookUrl() completionHandler:^(NSDictionary<NSString *,id> * _Nullable result, NSError * _Nullable error) {
|
|
89
|
+
if (error != nil) {
|
|
90
|
+
NSLog(@"[InappRnSdk] Api Error: %@", error);
|
|
91
|
+
reject(@"VERIFICATION_ERROR", @"Verification Error", error);
|
|
92
|
+
} else {
|
|
93
|
+
resolve(result);
|
|
94
|
+
}
|
|
95
|
+
}];
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
- (void)startVerificationFromUrl:(nonnull NSString *)requestUrl resolve:(nonnull RCTPromiseResolveBlock)resolve reject:(nonnull RCTPromiseRejectBlock)reject {
|
|
99
|
+
NSLog(@"[InappRnSdk] starting verification");
|
|
100
|
+
|
|
101
|
+
NSLog(@"[InappRnSdk] starting verification now");
|
|
102
|
+
[api startVerificationFromUrlWithUrl:requestUrl completionHandler:^(NSDictionary<NSString *,id> * _Nullable result, NSError * _Nullable error) {
|
|
103
|
+
if (error != nil) {
|
|
104
|
+
NSLog(@"[InappRnSdk] Api Error: %@", error);
|
|
105
|
+
reject(@"VERIFICATION_ERROR", @"Verification Error", error);
|
|
106
|
+
} else {
|
|
107
|
+
resolve(result);
|
|
108
|
+
}
|
|
109
|
+
}];
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
- (void)setOverrides:(JS::NativeInappRnSdk::Overrides &)overrides resolve:(nonnull RCTPromiseResolveBlock)resolve reject:(nonnull RCTPromiseRejectBlock)reject {
|
|
113
|
+
|
|
114
|
+
OverridenProviderInformation * _Nullable overridenProvider = nil;
|
|
115
|
+
if (overrides.provider().has_value()) {
|
|
116
|
+
JS::NativeInappRnSdk::ProviderInformation provider = overrides.provider().value();
|
|
117
|
+
if (provider.url() != nil && provider.url().length > 0) {
|
|
118
|
+
overridenProvider = [[OverridenProviderInformation alloc] initWithUrl:provider.url() jsonString:nil];
|
|
119
|
+
} else if (provider.jsonString() != nil && provider.jsonString().length > 0) {
|
|
120
|
+
overridenProvider = [[OverridenProviderInformation alloc] initWithUrl:nil jsonString:provider.jsonString()];
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
OverridenFeatureOptions * _Nullable overridenFeatureOptions = nil;
|
|
125
|
+
if (overrides.featureOptions().has_value()) {
|
|
126
|
+
JS::NativeInappRnSdk::FeatureOptions featureOptions = overrides.featureOptions().value();
|
|
127
|
+
overridenFeatureOptions = [[OverridenFeatureOptions alloc] initWithCookiePersist:nil singleReclaimRequest:nil idleTimeThresholdForManualVerificationTrigger:nil sessionTimeoutForManualVerificationTrigger:nil attestorBrowserRpcUrl:nil isResponseRedactionRegexEscapingEnabled:nil isAIFlowEnabled:nil];
|
|
128
|
+
|
|
129
|
+
if (featureOptions.cookiePersist().has_value()) {
|
|
130
|
+
overridenFeatureOptions.cookiePersist = [NSNumber numberWithBool:featureOptions.cookiePersist().value()];
|
|
131
|
+
}
|
|
132
|
+
if (featureOptions.singleReclaimRequest().has_value()) {
|
|
133
|
+
overridenFeatureOptions.singleReclaimRequest = [NSNumber numberWithBool:featureOptions.singleReclaimRequest().value()];
|
|
134
|
+
}
|
|
135
|
+
if (featureOptions.idleTimeThresholdForManualVerificationTrigger().has_value()) {
|
|
136
|
+
overridenFeatureOptions.idleTimeThresholdForManualVerificationTrigger = [NSNumber numberWithDouble:featureOptions.idleTimeThresholdForManualVerificationTrigger().value()];
|
|
137
|
+
}
|
|
138
|
+
if (featureOptions.sessionTimeoutForManualVerificationTrigger().has_value()) {
|
|
139
|
+
overridenFeatureOptions.sessionTimeoutForManualVerificationTrigger = [NSNumber numberWithDouble:featureOptions.sessionTimeoutForManualVerificationTrigger().value()];
|
|
140
|
+
}
|
|
141
|
+
if (featureOptions.attestorBrowserRpcUrl() != nil && featureOptions.attestorBrowserRpcUrl().length > 0) {
|
|
142
|
+
overridenFeatureOptions.attestorBrowserRpcUrl = featureOptions.attestorBrowserRpcUrl();
|
|
143
|
+
}
|
|
144
|
+
if (featureOptions.isResponseRedactionRegexEscapingEnabled().has_value()) {
|
|
145
|
+
overridenFeatureOptions.isResponseRedactionRegexEscapingEnabled = [NSNumber numberWithBool:featureOptions.isResponseRedactionRegexEscapingEnabled().value()];
|
|
146
|
+
}
|
|
147
|
+
if (featureOptions.isAIFlowEnabled().has_value()) {
|
|
148
|
+
overridenFeatureOptions.isAIFlowEnabled = [NSNumber numberWithBool:featureOptions.isAIFlowEnabled().value()];
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
OverridenLogConsumer * _Nullable overridenLogConsumer = nil;
|
|
153
|
+
if (overrides.logConsumer().has_value()) {
|
|
154
|
+
BOOL canSDKCollectTelemetry = true;
|
|
155
|
+
if (overrides.logConsumer().value().canSdkCollectTelemetry().has_value()) {
|
|
156
|
+
canSDKCollectTelemetry =overrides.logConsumer().value().canSdkCollectTelemetry().value();
|
|
157
|
+
}
|
|
158
|
+
NSNumber * _Nullable canSdkPrintLogs = nil;
|
|
159
|
+
if (overrides.logConsumer().value().canSdkPrintLogs().has_value()) {
|
|
160
|
+
canSdkPrintLogs = [NSNumber numberWithBool:overrides.logConsumer().value().canSdkPrintLogs().value()];
|
|
161
|
+
}
|
|
162
|
+
OverridenLogHandler * _Nullable logHandler;
|
|
163
|
+
if (overrides.logConsumer().value().enableLogHandler()) {
|
|
164
|
+
logHandler = [[OverridenLogHandler alloc] initOnLogs:^(NSString * _Nonnull logJsonString) {
|
|
165
|
+
[self emitOnLogs:logJsonString];
|
|
166
|
+
}];
|
|
167
|
+
}
|
|
168
|
+
overridenLogConsumer = [[OverridenLogConsumer alloc] initWithLogHandler: logHandler canSdkCollectTelemetry: canSDKCollectTelemetry canSdkPrintLogs: canSdkPrintLogs];
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
OverridenSessionManagement * _Nullable sessionManagement;
|
|
172
|
+
if (overrides.sessionManagement().has_value()) {
|
|
173
|
+
sessionManagement = [[OverridenSessionManagement alloc] initWithHandler:[[OverridenSessionHandler alloc] initWith_createSession:^(NSString * _Nonnull appId, NSString * _Nonnull providerId, NSString * _Nonnull sessionId, NSString * _Nonnull replyId) {
|
|
174
|
+
[self emitOnSessionCreateRequest:@{
|
|
175
|
+
@"appId": appId,
|
|
176
|
+
@"providerId": providerId,
|
|
177
|
+
@"sessionId": sessionId,
|
|
178
|
+
@"replyId": replyId
|
|
179
|
+
}];
|
|
180
|
+
} _updateSession:^(NSString * _Nonnull sessionId, NSString * _Nonnull status, NSString * _Nonnull replyId) {
|
|
181
|
+
[self emitOnSessionUpdateRequest:@{
|
|
182
|
+
@"sessionId": sessionId,
|
|
183
|
+
@"status": status,
|
|
184
|
+
@"replyId": replyId
|
|
185
|
+
}];
|
|
186
|
+
} _logSession:^(NSString * _Nonnull appId, NSString * _Nonnull providerId, NSString * _Nonnull sessionId, NSString * _Nonnull replyId) {
|
|
187
|
+
[self emitOnSessionLogs:@{
|
|
188
|
+
@"appId": appId,
|
|
189
|
+
@"providerId": providerId,
|
|
190
|
+
@"sessionId": sessionId,
|
|
191
|
+
@"replyId": replyId
|
|
192
|
+
}];
|
|
193
|
+
}]];
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
OverridenReclaimAppInfo * _Nullable overridenAppInfo = nil;
|
|
197
|
+
if (overrides.appInfo().has_value()) {
|
|
198
|
+
JS::NativeInappRnSdk::ReclaimAppInfo appInfo = overrides.appInfo().value();
|
|
199
|
+
NSNumber * _Nullable isRecurring = nil;
|
|
200
|
+
if (appInfo.isRecurring().has_value()) {
|
|
201
|
+
isRecurring = [NSNumber numberWithBool:appInfo.isRecurring().value()];
|
|
202
|
+
}
|
|
203
|
+
overridenAppInfo = [[OverridenReclaimAppInfo alloc] initWithAppName:appInfo.appName() appImageUrl:appInfo.appImageUrl() isRecurring:isRecurring];
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
[api setOverridesWithProvider:overridenProvider featureOptions:overridenFeatureOptions logConsumer:overridenLogConsumer sessionManagement: sessionManagement appInfo:overridenAppInfo completionHandler:^(NSError * _Nullable error) {
|
|
207
|
+
if (error != nil) {
|
|
208
|
+
reject(@"OVERRIDE_ERROR", @"Error on override", error);
|
|
209
|
+
} else {
|
|
210
|
+
resolve(nil);
|
|
211
|
+
}
|
|
212
|
+
}];
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
@end
|