@pagopa/io-react-native-cie 1.1.2 → 1.2.1
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/IoReactNativeCie.podspec +1 -1
- package/README.md +30 -15
- package/android/build.gradle +1 -1
- package/android/src/main/java/com/pagopa/ioreactnativecie/IoReactNativeCieModule.kt +235 -45
- package/ios/Data/Data+StringRepresentations.swift +48 -0
- package/ios/Data/DataEncoding.swift +15 -0
- package/ios/IoReactNativeCie.mm +19 -0
- package/ios/IoReactNativeCie.swift +134 -32
- package/lib/module/errors.js +50 -0
- package/lib/module/errors.js.map +1 -1
- package/lib/module/manager/index.js +110 -1
- package/lib/module/manager/index.js.map +1 -1
- package/lib/module/manager/types.js +37 -0
- package/lib/module/manager/types.js.map +1 -1
- package/lib/typescript/src/errors.d.ts +66 -18
- package/lib/typescript/src/errors.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +2 -2
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/manager/index.d.ts +101 -1
- package/lib/typescript/src/manager/index.d.ts.map +1 -1
- package/lib/typescript/src/manager/types.d.ts +103 -0
- package/lib/typescript/src/manager/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/errors.ts +53 -21
- package/src/index.ts +4 -1
- package/src/manager/index.ts +134 -0
- package/src/manager/types.ts +55 -0
package/IoReactNativeCie.podspec
CHANGED
|
@@ -16,7 +16,7 @@ Pod::Spec.new do |s|
|
|
|
16
16
|
s.source_files = "ios/**/*.{h,m,mm,swift}"
|
|
17
17
|
|
|
18
18
|
# CieSDK dependency
|
|
19
|
-
s.dependency "CieSDK", "~> 0.1.
|
|
19
|
+
s.dependency "CieSDK", "~> 0.1.13"
|
|
20
20
|
|
|
21
21
|
# Use install_modules_dependencies helper to install the dependencies if React Native version >=0.71.0.
|
|
22
22
|
# See https://github.com/facebook/react-native/blob/febf6b7f33fdb4904669f99d795eba4c0f95d7bf/scripts/cocoapods/new_architecture.rb#L79.
|
package/README.md
CHANGED
|
@@ -97,21 +97,24 @@ To run the example app, follow the instructions in [example/README.md](./example
|
|
|
97
97
|
|
|
98
98
|
List of available functions
|
|
99
99
|
|
|
100
|
-
| Function
|
|
101
|
-
|
|
|
102
|
-
| `hasNFCFeature()`
|
|
103
|
-
| `isNfcEnabled()`
|
|
104
|
-
| `isCieAuthenticationSupported()`
|
|
105
|
-
| `openNfcSettings()`
|
|
106
|
-
| `addListener(event: CieEvent, listener: CieEventHandlers)`
|
|
107
|
-
| `removeListener(event: CieEvent)`
|
|
108
|
-
| `removeAllListeners()`
|
|
109
|
-
| `setCustomIdpUrl(url?: string)`
|
|
110
|
-
| `setAlertMessage(key: AlertMessageKey, value: string)`
|
|
111
|
-
| `setCurrentAlertMessage(value: string)`
|
|
112
|
-
| `
|
|
113
|
-
| `
|
|
114
|
-
| `
|
|
100
|
+
| Function | Return | Description |
|
|
101
|
+
| :---------------------------------------------------------------------------------------------------------------------- | :----------------- | :----------------------------------------------------------------------------- |
|
|
102
|
+
| `hasNFCFeature()` | `Promise<boolean>` | (Android) Checks if the device supports NFC feature |
|
|
103
|
+
| `isNfcEnabled()` | `Promise<boolean>` | (Android) Checks if the NFC is currently enabled |
|
|
104
|
+
| `isCieAuthenticationSupported()` | `Promise<boolean>` | (Android) Checks if the device supports CIE autentication |
|
|
105
|
+
| `openNfcSettings()` | `Promise<void>` | (Android) Opens NFC system settings page |
|
|
106
|
+
| `addListener(event: CieEvent, listener: CieEventHandlers)` | `() => void` | Adds a NFC event listener and returns a function to unsubscribe from the event |
|
|
107
|
+
| `removeListener(event: CieEvent)` | `void` | Removes all listeners for the specified event |
|
|
108
|
+
| `removeAllListeners()` | `void` | Removes all registered listeners |
|
|
109
|
+
| `setCustomIdpUrl(url?: string)` | `void` | Updates IDP url, if `undefined` will use the default IDP url |
|
|
110
|
+
| `setAlertMessage(key: AlertMessageKey, value: string)` | `void` | (iOS) Updates iOS NFC modal alert message |
|
|
111
|
+
| `setCurrentAlertMessage(value: string)` | `void` | (iOS) Updates currently displayed iOS NFC modal alert message |
|
|
112
|
+
| `startInternalAuthentication(challenge: string, resultEncoding?: 'hex' \| 'base64', timeout?: number)` | `Promise<void>` | Start the CIE IAS/NIS Internal Authentication |
|
|
113
|
+
| `startMRTDReading(can: string, resultEncoding?: 'hex' \| 'base64', timeout?: number)` | `Promise<void>` | Start PACE MRTD reading (reads MRTD data using CAN) |
|
|
114
|
+
| `startInternalAuthAndMRTDReading(can: string, challenge: string, resultEncoding?: 'hex' \| 'base64', timeout?: number)` | `Promise<void>` | Start combined Internal Authentication + PACE MRTD reading |
|
|
115
|
+
| `startReadingAttributes(timeout: number)` | `Promise<void>` | Start the CIE attributes reading process |
|
|
116
|
+
| `startReading(pin: string, authenticationUrl: string, timeout: number)` | `Promise<void>` | Start the CIE reading process fro authentication |
|
|
117
|
+
| `stopReading()` | `Promise<void>` | (Android) Stops all reading process |
|
|
115
118
|
|
|
116
119
|
## Usage
|
|
117
120
|
|
|
@@ -137,6 +140,18 @@ await CieUtils.isCieAuthenticationSupported();
|
|
|
137
140
|
|
|
138
141
|
### Reading CIE Data
|
|
139
142
|
|
|
143
|
+
#### Internal Authentication
|
|
144
|
+
|
|
145
|
+
Start the CIE Internal Authentication
|
|
146
|
+
|
|
147
|
+
```typescript
|
|
148
|
+
import { CieManager } from '@pagopa/io-react-native-cie';
|
|
149
|
+
|
|
150
|
+
CieManager.startInternalAuthentication('challenge')
|
|
151
|
+
.then(() => console.log('Reading started'))
|
|
152
|
+
.catch((error) => console.error('Error:', error));
|
|
153
|
+
```
|
|
154
|
+
|
|
140
155
|
#### Reading Attributes
|
|
141
156
|
|
|
142
157
|
Read CIE attributes (card type and base64-encoded data) with optional timeout (Android only)
|
package/android/build.gradle
CHANGED
|
@@ -5,22 +5,26 @@ import com.facebook.react.bridge.Promise
|
|
|
5
5
|
import com.facebook.react.bridge.ReactApplicationContext
|
|
6
6
|
import com.facebook.react.bridge.ReactContextBaseJavaModule
|
|
7
7
|
import com.facebook.react.bridge.ReactMethod
|
|
8
|
-
import com.facebook.react.bridge.WritableMap
|
|
9
8
|
import com.facebook.react.bridge.WritableNativeMap
|
|
10
9
|
import com.facebook.react.modules.core.DeviceEventManagerModule
|
|
11
10
|
import com.pagopa.ioreactnativecie.cie.Atr
|
|
12
11
|
import it.pagopa.io.app.cie.CieLogger
|
|
13
12
|
import it.pagopa.io.app.cie.CieSDK
|
|
13
|
+
import it.pagopa.io.app.cie.IntAuthMRTDResponse
|
|
14
|
+
import it.pagopa.io.app.cie.NisAndPaceCallback
|
|
14
15
|
import it.pagopa.io.app.cie.cie.CieAtrCallback
|
|
15
16
|
import it.pagopa.io.app.cie.cie.NfcError
|
|
16
17
|
import it.pagopa.io.app.cie.cie.NfcEvent
|
|
17
18
|
import it.pagopa.io.app.cie.network.NetworkCallback
|
|
18
19
|
import it.pagopa.io.app.cie.network.NetworkError
|
|
19
20
|
import it.pagopa.io.app.cie.nfc.NfcEvents
|
|
21
|
+
import it.pagopa.io.app.cie.nis.InternalAuthenticationResponse
|
|
22
|
+
import it.pagopa.io.app.cie.nis.NisCallback
|
|
23
|
+
import it.pagopa.io.app.cie.pace.MRTDResponse
|
|
24
|
+
import it.pagopa.io.app.cie.pace.PaceCallback
|
|
25
|
+
import it.pagopa.io.app.cie.toHex
|
|
20
26
|
import java.net.URL
|
|
21
27
|
|
|
22
|
-
typealias ME = IoReactNativeCieModule.Companion.ModuleException
|
|
23
|
-
|
|
24
28
|
class IoReactNativeCieModule(reactContext: ReactApplicationContext) :
|
|
25
29
|
ReactContextBaseJavaModule(reactContext) {
|
|
26
30
|
|
|
@@ -37,16 +41,19 @@ class IoReactNativeCieModule(reactContext: ReactApplicationContext) :
|
|
|
37
41
|
*/
|
|
38
42
|
val cieSdk: CieSDK by lazy {
|
|
39
43
|
CieSDK.withContext(currentActivity)
|
|
40
|
-
}
|
|
44
|
+
}
|
|
41
45
|
|
|
46
|
+
@Suppress("unused")
|
|
42
47
|
@ReactMethod
|
|
43
48
|
fun addListener(eventName: String) {
|
|
44
49
|
}
|
|
45
50
|
|
|
51
|
+
@Suppress("unused")
|
|
46
52
|
@ReactMethod
|
|
47
53
|
fun removeListeners(count: Int) {
|
|
48
54
|
}
|
|
49
55
|
|
|
56
|
+
@Suppress("unused")
|
|
50
57
|
@ReactMethod
|
|
51
58
|
fun hasNfcFeature(promise: Promise) {
|
|
52
59
|
try {
|
|
@@ -54,12 +61,11 @@ class IoReactNativeCieModule(reactContext: ReactApplicationContext) :
|
|
|
54
61
|
promise.resolve(it)
|
|
55
62
|
}
|
|
56
63
|
} catch (e: Exception) {
|
|
57
|
-
|
|
58
|
-
promise, Pair(ERROR_USER_INFO_KEY, e.message.orEmpty())
|
|
59
|
-
)
|
|
64
|
+
promise.reject(ModuleException.UNKNOWN_EXCEPTION, e.message, e)
|
|
60
65
|
}
|
|
61
66
|
}
|
|
62
67
|
|
|
68
|
+
@Suppress("unused")
|
|
63
69
|
@ReactMethod
|
|
64
70
|
fun isNfcEnabled(promise: Promise) {
|
|
65
71
|
try {
|
|
@@ -67,12 +73,11 @@ class IoReactNativeCieModule(reactContext: ReactApplicationContext) :
|
|
|
67
73
|
promise.resolve(it)
|
|
68
74
|
}
|
|
69
75
|
} catch (e: Exception) {
|
|
70
|
-
|
|
71
|
-
promise, Pair(ERROR_USER_INFO_KEY, e.message.orEmpty())
|
|
72
|
-
)
|
|
76
|
+
promise.reject(ModuleException.UNKNOWN_EXCEPTION, e.message, e)
|
|
73
77
|
}
|
|
74
78
|
}
|
|
75
79
|
|
|
80
|
+
@Suppress("unused")
|
|
76
81
|
@ReactMethod
|
|
77
82
|
fun isCieAuthenticationSupported(promise: Promise) {
|
|
78
83
|
cieSdk.isCieAuthenticationSupported().apply {
|
|
@@ -80,33 +85,216 @@ class IoReactNativeCieModule(reactContext: ReactApplicationContext) :
|
|
|
80
85
|
}
|
|
81
86
|
}
|
|
82
87
|
|
|
88
|
+
@Suppress("unused")
|
|
83
89
|
@ReactMethod
|
|
84
90
|
fun openNfcSettings(promise: Promise) {
|
|
85
91
|
try {
|
|
86
92
|
cieSdk.openNfcSettings()
|
|
87
93
|
promise.resolve(null)
|
|
88
94
|
} catch (e: Exception) {
|
|
89
|
-
|
|
90
|
-
promise, Pair(ERROR_USER_INFO_KEY, e.message.orEmpty())
|
|
91
|
-
)
|
|
95
|
+
promise.reject(ModuleException.UNKNOWN_EXCEPTION, e.message, e)
|
|
92
96
|
}
|
|
93
97
|
}
|
|
94
98
|
|
|
99
|
+
@Suppress("unused")
|
|
95
100
|
@ReactMethod
|
|
96
101
|
fun setAlertMessage(key: String, value: String) {
|
|
97
102
|
// Android does not support alert messages for NFC reading
|
|
98
103
|
}
|
|
99
104
|
|
|
105
|
+
@Suppress("unused")
|
|
100
106
|
@ReactMethod
|
|
101
107
|
fun setCurrentAlertMessage(value: String) {
|
|
102
108
|
// Android does not support alert messages for NFC reading
|
|
103
109
|
}
|
|
104
110
|
|
|
111
|
+
@Suppress("unused")
|
|
105
112
|
@ReactMethod
|
|
106
113
|
fun setCustomIdpUrl(url: String) {
|
|
107
114
|
cieSdk.withCustomIdpUrl(url)
|
|
108
115
|
}
|
|
109
116
|
|
|
117
|
+
@Suppress("unused")
|
|
118
|
+
@ReactMethod
|
|
119
|
+
fun startInternalAuthentication(
|
|
120
|
+
challenge: String,
|
|
121
|
+
resultEncoding: String,
|
|
122
|
+
timeout: Int = 10000,
|
|
123
|
+
promise: Promise,
|
|
124
|
+
) {
|
|
125
|
+
val encoding: ResultEncoding = ResultEncoding.fromString(resultEncoding)
|
|
126
|
+
try {
|
|
127
|
+
cieSdk.startReadingNis(challenge, timeout, object : NfcEvents {
|
|
128
|
+
override fun event(event: NfcEvent) {
|
|
129
|
+
this@IoReactNativeCieModule.reactApplicationContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
|
130
|
+
.emit(EventType.EVENT.value, WritableNativeMap().apply {
|
|
131
|
+
putString("name", event.name)
|
|
132
|
+
putDouble(
|
|
133
|
+
"progress",
|
|
134
|
+
(event.numeratorForNis.toDouble() / NfcEvent.totalNisOfNumeratorEvent.toDouble())
|
|
135
|
+
)
|
|
136
|
+
})
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
override fun error(error: NfcError) {
|
|
140
|
+
this@IoReactNativeCieModule.reactApplicationContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
|
141
|
+
.emit(EventType.ERROR.value, WritableNativeMap().apply {
|
|
142
|
+
putString("name", mapNfcError(error).name)
|
|
143
|
+
error.msg?.let { putString("message", it) }
|
|
144
|
+
})
|
|
145
|
+
|
|
146
|
+
}
|
|
147
|
+
}, object : NisCallback {
|
|
148
|
+
override fun onSuccess(nisAuth: InternalAuthenticationResponse) {
|
|
149
|
+
this@IoReactNativeCieModule.reactApplicationContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
|
150
|
+
.emit(EventType.INTERNAL_AUTHENTICATION_SUCCESS.value, WritableNativeMap().apply {
|
|
151
|
+
putString("nis", encoding.encode(nisAuth.nis))
|
|
152
|
+
putString("publicKey", encoding.encode(nisAuth.kpubIntServ))
|
|
153
|
+
putString("sod", encoding.encode(nisAuth.sod))
|
|
154
|
+
putString("signedChallenge", encoding.encode(nisAuth.challengeSigned))
|
|
155
|
+
})
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
override fun onError(error: NfcError) {
|
|
159
|
+
this@IoReactNativeCieModule.reactApplicationContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
|
160
|
+
.emit(EventType.ERROR.value, WritableNativeMap().apply {
|
|
161
|
+
putString("name", mapNfcError(error).name)
|
|
162
|
+
error.msg?.let { putString("message", it) }
|
|
163
|
+
})
|
|
164
|
+
}
|
|
165
|
+
})
|
|
166
|
+
promise.resolve(null)
|
|
167
|
+
} catch (e: Exception) {
|
|
168
|
+
promise.reject(ModuleException.UNKNOWN_EXCEPTION, e.message, e)
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
@Suppress("unused")
|
|
173
|
+
@ReactMethod
|
|
174
|
+
fun startMRTDReading(
|
|
175
|
+
can: String,
|
|
176
|
+
resultEncoding: String,
|
|
177
|
+
timeout: Int = 10000,
|
|
178
|
+
promise: Promise,
|
|
179
|
+
) {
|
|
180
|
+
val encoding: ResultEncoding = ResultEncoding.fromString(resultEncoding)
|
|
181
|
+
try {
|
|
182
|
+
cieSdk.startDoPace(can, timeout, object : NfcEvents {
|
|
183
|
+
override fun event(event: NfcEvent) {
|
|
184
|
+
this@IoReactNativeCieModule.reactApplicationContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
|
185
|
+
.emit(EventType.EVENT.value, WritableNativeMap().apply {
|
|
186
|
+
putString("name", event.name)
|
|
187
|
+
putDouble(
|
|
188
|
+
"progress",
|
|
189
|
+
(event.numeratorForPace.toDouble() / NfcEvent.totalPaceOfNumeratorEvent.toDouble())
|
|
190
|
+
)
|
|
191
|
+
})
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
override fun error(error: NfcError) {
|
|
195
|
+
this@IoReactNativeCieModule.reactApplicationContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
|
196
|
+
.emit(EventType.ERROR.value, WritableNativeMap().apply {
|
|
197
|
+
putString("name", mapNfcError(error).name)
|
|
198
|
+
error.msg?.let { putString("message", it) }
|
|
199
|
+
})
|
|
200
|
+
|
|
201
|
+
}
|
|
202
|
+
}, object : PaceCallback {
|
|
203
|
+
override fun onSuccess(eMRTDResponse: MRTDResponse) {
|
|
204
|
+
this@IoReactNativeCieModule.reactApplicationContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
|
205
|
+
.emit(EventType.MRTD_WITH_PACE_SUCCESS.value, WritableNativeMap().apply {
|
|
206
|
+
putString("dg1", encoding.encode(eMRTDResponse.dg1))
|
|
207
|
+
putString("dg11", encoding.encode(eMRTDResponse.dg11))
|
|
208
|
+
putString("sod", encoding.encode(eMRTDResponse.sod))
|
|
209
|
+
})
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
override fun onError(error: NfcError) {
|
|
213
|
+
this@IoReactNativeCieModule.reactApplicationContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
|
214
|
+
.emit(EventType.ERROR.value, WritableNativeMap().apply {
|
|
215
|
+
putString("name", mapNfcError(error).name)
|
|
216
|
+
error.msg?.let { putString("message", it) }
|
|
217
|
+
})
|
|
218
|
+
}
|
|
219
|
+
})
|
|
220
|
+
promise.resolve(null)
|
|
221
|
+
} catch (e: Exception) {
|
|
222
|
+
promise.reject(ModuleException.UNKNOWN_EXCEPTION, e.message, e)
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
@Suppress("unused")
|
|
227
|
+
@ReactMethod
|
|
228
|
+
fun startInternalAuthAndMRTDReading(
|
|
229
|
+
can: String,
|
|
230
|
+
challenge: String,
|
|
231
|
+
resultEncoding: String,
|
|
232
|
+
timeout: Int = 10000,
|
|
233
|
+
promise: Promise,
|
|
234
|
+
) {
|
|
235
|
+
val encoding: ResultEncoding = ResultEncoding.fromString(resultEncoding)
|
|
236
|
+
try {
|
|
237
|
+
cieSdk.startNisAndPace(challenge, can, timeout, object : NfcEvents {
|
|
238
|
+
override fun event(event: NfcEvent) {
|
|
239
|
+
this@IoReactNativeCieModule.reactApplicationContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
|
240
|
+
.emit(EventType.EVENT.value, WritableNativeMap().apply {
|
|
241
|
+
putString("name", event.name)
|
|
242
|
+
putDouble(
|
|
243
|
+
"progress",
|
|
244
|
+
(event.numeratorForNisAndPace.toDouble() / NfcEvent.totalNisAndPaceOfNumeratorEvent.toDouble())
|
|
245
|
+
)
|
|
246
|
+
})
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
override fun error(error: NfcError) {
|
|
250
|
+
this@IoReactNativeCieModule.reactApplicationContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
|
251
|
+
.emit(EventType.ERROR.value, WritableNativeMap().apply {
|
|
252
|
+
putString("name", mapNfcError(error).name)
|
|
253
|
+
error.msg?.let { putString("message", it) }
|
|
254
|
+
})
|
|
255
|
+
|
|
256
|
+
}
|
|
257
|
+
}, object : NisAndPaceCallback {
|
|
258
|
+
override fun onSuccess(intAuthMRTDResponse: IntAuthMRTDResponse) {
|
|
259
|
+
this@IoReactNativeCieModule.reactApplicationContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
|
260
|
+
.emit(
|
|
261
|
+
EventType.INTERNAL_AUTH_AND_MRTD_WITH_PACE_SUCCESS.value,
|
|
262
|
+
WritableNativeMap().apply {
|
|
263
|
+
putMap("nis_data", WritableNativeMap().apply {
|
|
264
|
+
putString("nis", encoding.encode(intAuthMRTDResponse.internalAuthentication.nis))
|
|
265
|
+
putString(
|
|
266
|
+
"publicKey",
|
|
267
|
+
encoding.encode(intAuthMRTDResponse.internalAuthentication.kpubIntServ)
|
|
268
|
+
)
|
|
269
|
+
putString("sod", encoding.encode(intAuthMRTDResponse.internalAuthentication.sod))
|
|
270
|
+
putString(
|
|
271
|
+
"signedChallenge",
|
|
272
|
+
encoding.encode(intAuthMRTDResponse.internalAuthentication.challengeSigned)
|
|
273
|
+
)
|
|
274
|
+
})
|
|
275
|
+
putMap("mrtd_data", WritableNativeMap().apply {
|
|
276
|
+
putString("dg1", encoding.encode(intAuthMRTDResponse.mrtd.dg1))
|
|
277
|
+
putString("dg11", encoding.encode(intAuthMRTDResponse.mrtd.dg11))
|
|
278
|
+
putString("sod", encoding.encode(intAuthMRTDResponse.mrtd.sod))
|
|
279
|
+
})
|
|
280
|
+
})
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
override fun onError(error: NfcError) {
|
|
284
|
+
this@IoReactNativeCieModule.reactApplicationContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
|
285
|
+
.emit(EventType.ERROR.value, WritableNativeMap().apply {
|
|
286
|
+
putString("name", mapNfcError(error).name)
|
|
287
|
+
error.msg?.let { putString("message", it) }
|
|
288
|
+
})
|
|
289
|
+
}
|
|
290
|
+
})
|
|
291
|
+
promise.resolve(null)
|
|
292
|
+
} catch (e: Exception) {
|
|
293
|
+
promise.reject(ModuleException.UNKNOWN_EXCEPTION, e.message, e)
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
@Suppress("unused")
|
|
110
298
|
@ReactMethod
|
|
111
299
|
fun startReadingAttributes(
|
|
112
300
|
timeout: Int = 10000,
|
|
@@ -152,12 +340,11 @@ class IoReactNativeCieModule(reactContext: ReactApplicationContext) :
|
|
|
152
340
|
})
|
|
153
341
|
promise.resolve(null)
|
|
154
342
|
} catch (e: Exception) {
|
|
155
|
-
|
|
156
|
-
promise, Pair(ERROR_USER_INFO_KEY, e.message.orEmpty())
|
|
157
|
-
)
|
|
343
|
+
promise.reject(ModuleException.UNKNOWN_EXCEPTION, e.message, e)
|
|
158
344
|
}
|
|
159
345
|
}
|
|
160
346
|
|
|
347
|
+
@Suppress("unused")
|
|
161
348
|
@ReactMethod
|
|
162
349
|
fun startReading(
|
|
163
350
|
pin: String,
|
|
@@ -168,16 +355,14 @@ class IoReactNativeCieModule(reactContext: ReactApplicationContext) :
|
|
|
168
355
|
try {
|
|
169
356
|
cieSdk.setPin(pin)
|
|
170
357
|
} catch (e: Exception) {
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
)
|
|
174
|
-
return;
|
|
358
|
+
promise.reject(ModuleException.PIN_REGEX_NOT_VALID, e.message, e)
|
|
359
|
+
return
|
|
175
360
|
}
|
|
176
361
|
|
|
177
362
|
try {
|
|
178
363
|
cieSdk.withUrl(URL(authenticationUrl).toString())
|
|
179
364
|
} catch (e: Exception) {
|
|
180
|
-
|
|
365
|
+
promise.reject(ModuleException.INVALID_AUTH_URL, e.message, e)
|
|
181
366
|
return
|
|
182
367
|
}
|
|
183
368
|
|
|
@@ -218,12 +403,11 @@ class IoReactNativeCieModule(reactContext: ReactApplicationContext) :
|
|
|
218
403
|
})
|
|
219
404
|
promise.resolve(null)
|
|
220
405
|
} catch (e: Exception) {
|
|
221
|
-
|
|
222
|
-
promise, Pair(ERROR_USER_INFO_KEY, e.message.orEmpty())
|
|
223
|
-
)
|
|
406
|
+
promise.reject(ModuleException.UNKNOWN_EXCEPTION, e.message, e)
|
|
224
407
|
}
|
|
225
408
|
}
|
|
226
409
|
|
|
410
|
+
@Suppress("unused")
|
|
227
411
|
@ReactMethod
|
|
228
412
|
fun stopReading() {
|
|
229
413
|
cieSdk.stopNFCListening()
|
|
@@ -253,12 +437,34 @@ class IoReactNativeCieModule(reactContext: ReactApplicationContext) :
|
|
|
253
437
|
|
|
254
438
|
companion object {
|
|
255
439
|
const val NAME = "IoReactNativeCie"
|
|
256
|
-
|
|
440
|
+
|
|
441
|
+
enum class ResultEncoding(val value: String) {
|
|
442
|
+
BASE64("base64"),
|
|
443
|
+
HEX("hex");
|
|
444
|
+
|
|
445
|
+
fun encode(data: ByteArray): String = when (this) {
|
|
446
|
+
BASE64 -> Base64.encodeToString(data, Base64.URL_SAFE or Base64.NO_WRAP)
|
|
447
|
+
HEX -> data.toHex().uppercase()
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
companion object {
|
|
451
|
+
fun fromString(value: String?): ResultEncoding {
|
|
452
|
+
return when (value) {
|
|
453
|
+
"hex" -> HEX
|
|
454
|
+
"base64" -> BASE64
|
|
455
|
+
else -> BASE64 // Default
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
}
|
|
257
460
|
|
|
258
461
|
enum class EventType(val value: String) {
|
|
259
462
|
EVENT("onEvent"),
|
|
260
463
|
ERROR("onError"),
|
|
261
464
|
ATTRIBUTES_SUCCESS("onAttributesSuccess"),
|
|
465
|
+
INTERNAL_AUTHENTICATION_SUCCESS("onInternalAuthenticationSuccess"),
|
|
466
|
+
MRTD_WITH_PACE_SUCCESS("onMRTDWithPaceSuccess"),
|
|
467
|
+
INTERNAL_AUTH_AND_MRTD_WITH_PACE_SUCCESS("onInternalAuthAndMRTDWithPaceSuccess"),
|
|
262
468
|
SUCCESS("onSuccess")
|
|
263
469
|
}
|
|
264
470
|
|
|
@@ -275,26 +481,10 @@ class IoReactNativeCieModule(reactContext: ReactApplicationContext) :
|
|
|
275
481
|
GENERIC_ERROR,
|
|
276
482
|
}
|
|
277
483
|
|
|
278
|
-
|
|
279
|
-
val
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
INVALID_AUTH_URL(Exception("INVALID_AUTH_URL")),
|
|
283
|
-
UNKNOWN_EXCEPTION(Exception("UNKNOWN_EXCEPTION"));
|
|
284
|
-
|
|
285
|
-
fun reject(
|
|
286
|
-
promise: Promise, vararg args: Pair<String, String>
|
|
287
|
-
) {
|
|
288
|
-
exMap(*args).let {
|
|
289
|
-
promise.reject(it.first, ex.message, it.second)
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
private fun exMap(vararg args: Pair<String, String>): Pair<String, WritableMap> {
|
|
294
|
-
val writableMap = WritableNativeMap()
|
|
295
|
-
args.forEach { writableMap.putString(it.first, it.second) }
|
|
296
|
-
return Pair(this.ex.message ?: "UNKNOWN", writableMap)
|
|
297
|
-
}
|
|
484
|
+
private object ModuleException {
|
|
485
|
+
const val PIN_REGEX_NOT_VALID = "PIN_REGEX_NOT_VALID"
|
|
486
|
+
const val INVALID_AUTH_URL = "INVALID_AUTH_URL"
|
|
487
|
+
const val UNKNOWN_EXCEPTION = "UNKNOWN_EXCEPTION"
|
|
298
488
|
}
|
|
299
489
|
}
|
|
300
490
|
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Data+StringRepresentations.swift
|
|
3
|
+
// Pods
|
|
4
|
+
//
|
|
5
|
+
// Created by Fabio Bombardi on 02/10/25.
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
import Foundation
|
|
9
|
+
|
|
10
|
+
extension Data {
|
|
11
|
+
|
|
12
|
+
/// Converts the data to an uppercase hexadecimal string.
|
|
13
|
+
func toHexString() -> String {
|
|
14
|
+
return self.map { String(format: "%02X", $0) }.joined()
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/// Converts the data to a base64url encoded string (RFC 7515), without padding.
|
|
18
|
+
/// - Replaces + with -, / with _, and removes trailing =
|
|
19
|
+
func base64UrlEncodedString() -> String {
|
|
20
|
+
return self.base64EncodedString()
|
|
21
|
+
.replacingOccurrences(of: "+", with: "-")
|
|
22
|
+
.replacingOccurrences(of: "/", with: "_")
|
|
23
|
+
.replacingOccurrences(of: "=", with: "")
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Convenience extension for an array of bytes ([UInt8]).
|
|
28
|
+
extension Array where Element == UInt8 {
|
|
29
|
+
|
|
30
|
+
/// Converts the byte array to a lowercase hexadecimal string.
|
|
31
|
+
func toHexString() -> String {
|
|
32
|
+
return Data(self).toHexString()
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/// Converts the byte array to a base64url encoded string.
|
|
36
|
+
func base64UrlEncodedString() -> String {
|
|
37
|
+
return Data(self).base64UrlEncodedString()
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
func encodedDataString(encoding: DataEncoding) -> String {
|
|
41
|
+
switch encoding {
|
|
42
|
+
case .HEX:
|
|
43
|
+
return Data(self).toHexString()
|
|
44
|
+
case .BASE64:
|
|
45
|
+
return Data(self).base64UrlEncodedString()
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
//
|
|
2
|
+
// DataEncoding.swift
|
|
3
|
+
// Pods
|
|
4
|
+
//
|
|
5
|
+
// Created by Fabio Bombardi on 02/10/25.
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
enum DataEncoding: String, Sendable {
|
|
9
|
+
case HEX = "HEX"
|
|
10
|
+
case BASE64 = "BASE64"
|
|
11
|
+
|
|
12
|
+
static func from(string: String?) -> DataEncoding {
|
|
13
|
+
return DataEncoding(rawValue: string?.uppercased() ?? "") ?? .BASE64
|
|
14
|
+
}
|
|
15
|
+
}
|
package/ios/IoReactNativeCie.mm
CHANGED
|
@@ -25,6 +25,25 @@ RCT_EXTERN_METHOD(setCurrentAlertMessage: (NSString)value)
|
|
|
25
25
|
|
|
26
26
|
RCT_EXTERN_METHOD(setCustomIdpUrl: (NSString)url)
|
|
27
27
|
|
|
28
|
+
RCT_EXTERN_METHOD(startInternalAuthentication: (NSString)challenge
|
|
29
|
+
withResultEncoding: (NSString)encodingString
|
|
30
|
+
withTimeout: (NSNumber)timeout
|
|
31
|
+
withResolver: (RCTPromiseResolveBlock)resolve
|
|
32
|
+
withRejecter: (RCTPromiseRejectBlock)reject)
|
|
33
|
+
|
|
34
|
+
RCT_EXTERN_METHOD(startMRTDReading: (NSString)can
|
|
35
|
+
withResultEncoding: (NSString)encodingString
|
|
36
|
+
withTimeout: (NSNumber)timeout
|
|
37
|
+
withResolver: (RCTPromiseResolveBlock)resolve
|
|
38
|
+
withRejecter: (RCTPromiseRejectBlock)reject)
|
|
39
|
+
|
|
40
|
+
RCT_EXTERN_METHOD(startInternalAuthAndMRTDReading: (NSString)can
|
|
41
|
+
withChallenge: (NSString)challenge
|
|
42
|
+
withResultEncoding: (NSString)encodingString
|
|
43
|
+
withTimeout: (NSNumber)timeout
|
|
44
|
+
withResolver: (RCTPromiseResolveBlock)resolve
|
|
45
|
+
withRejecter: (RCTPromiseRejectBlock)reject)
|
|
46
|
+
|
|
28
47
|
RCT_EXTERN_METHOD(startReadingAttributes: (NSNumber)timeout
|
|
29
48
|
withResolver: (RCTPromiseResolveBlock)resolve
|
|
30
49
|
withRejecter: (RCTPromiseRejectBlock)reject)
|