@pagopa/io-react-native-cie 1.0.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/IoReactNativeCie.podspec +28 -0
- package/LICENSE +201 -0
- package/README.md +406 -0
- package/android/build.gradle +83 -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/pagopa/ioreactnativecie/IoReactNativeCieModule.kt +302 -0
- package/android/src/main/java/com/pagopa/ioreactnativecie/IoReactNativeCiePackage.kt +17 -0
- package/android/src/main/java/com/pagopa/ioreactnativecie/cie/Atr.kt +39 -0
- package/android/src/main/java/com/pagopa/ioreactnativecie/cie/CieType.kt +157 -0
- package/ios/CIEType.swift +81 -0
- package/ios/IoReactNativeCie-Bridging-Header.h +2 -0
- package/ios/IoReactNativeCie.mm +43 -0
- package/ios/IoReactNativeCie.swift +227 -0
- package/lib/module/errors.js +2 -0
- package/lib/module/errors.js.map +1 -0
- package/lib/module/index.js +6 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/manager/index.js +149 -0
- package/lib/module/manager/index.js.map +1 -0
- package/lib/module/manager/types.js +50 -0
- package/lib/module/manager/types.js.map +1 -0
- package/lib/module/native.js +13 -0
- package/lib/module/native.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/module/utils/index.js +45 -0
- package/lib/module/utils/index.js.map +1 -0
- package/lib/typescript/package.json +1 -0
- package/lib/typescript/src/errors.d.ts +24 -0
- package/lib/typescript/src/errors.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +6 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/lib/typescript/src/manager/index.d.ts +113 -0
- package/lib/typescript/src/manager/index.d.ts.map +1 -0
- package/lib/typescript/src/manager/types.d.ts +83 -0
- package/lib/typescript/src/manager/types.d.ts.map +1 -0
- package/lib/typescript/src/native.d.ts +2 -0
- package/lib/typescript/src/native.d.ts.map +1 -0
- package/lib/typescript/src/utils/index.d.ts +30 -0
- package/lib/typescript/src/utils/index.d.ts.map +1 -0
- package/package.json +158 -0
- package/src/errors.ts +32 -0
- package/src/index.ts +14 -0
- package/src/manager/index.ts +167 -0
- package/src/manager/types.ts +94 -0
- package/src/native.ts +18 -0
- package/src/utils/index.ts +42 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
#import <React/RCTBridgeModule.h>
|
|
2
|
+
|
|
3
|
+
@interface RCT_EXTERN_MODULE(IoReactNativeCie, NSObject)
|
|
4
|
+
|
|
5
|
+
RCT_EXTERN_METHOD(addListener: (NSString)type)
|
|
6
|
+
|
|
7
|
+
RCT_EXTERN_METHOD(removeListeners: (NSString)type)
|
|
8
|
+
|
|
9
|
+
RCT_EXTERN_METHOD(hasNfcFeature: (RCTPromiseResolveBlock)resolve
|
|
10
|
+
withRejecter: (RCTPromiseRejectBlock)reject)
|
|
11
|
+
|
|
12
|
+
RCT_EXTERN_METHOD(isNfcEnabled: (RCTPromiseResolveBlock)resolve
|
|
13
|
+
withRejecter: (RCTPromiseRejectBlock)reject)
|
|
14
|
+
|
|
15
|
+
RCT_EXTERN_METHOD(isCieAuthenticationSupported: (RCTPromiseResolveBlock)resolve
|
|
16
|
+
withRejecter: (RCTPromiseRejectBlock)reject)
|
|
17
|
+
|
|
18
|
+
RCT_EXTERN_METHOD(openNfcSettings: (RCTPromiseResolveBlock)resolve
|
|
19
|
+
withRejecter: (RCTPromiseRejectBlock)reject)
|
|
20
|
+
|
|
21
|
+
RCT_EXTERN_METHOD(setAlertMessage: (NSString)key
|
|
22
|
+
withValue: (NSString)value)
|
|
23
|
+
|
|
24
|
+
RCT_EXTERN_METHOD(setCurrentAlertMessage: (NSString)value)
|
|
25
|
+
|
|
26
|
+
RCT_EXTERN_METHOD(setCustomIdpUrl: (NSString)url)
|
|
27
|
+
|
|
28
|
+
RCT_EXTERN_METHOD(startReadingAttributes: (NSNumber)timeout
|
|
29
|
+
withResolver: (RCTPromiseResolveBlock)resolve
|
|
30
|
+
withRejecter: (RCTPromiseRejectBlock)reject)
|
|
31
|
+
|
|
32
|
+
RCT_EXTERN_METHOD(startReading: (NSString)pin
|
|
33
|
+
withAuthUrl: (NSString)authUrl
|
|
34
|
+
withTimeout: (NSNumber)timeout
|
|
35
|
+
withResolver: (RCTPromiseResolveBlock)resolve
|
|
36
|
+
withRejecter: (RCTPromiseRejectBlock)reject)
|
|
37
|
+
|
|
38
|
+
+ (BOOL)requiresMainQueueSetup
|
|
39
|
+
{
|
|
40
|
+
return NO;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
@end
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
import CieSDK
|
|
2
|
+
import React
|
|
3
|
+
|
|
4
|
+
@objc(IoReactNativeCie)
|
|
5
|
+
class IoReactNativeCie: RCTEventEmitter {
|
|
6
|
+
private typealias ME = ModuleException
|
|
7
|
+
|
|
8
|
+
private let cieSdk: CieDigitalId
|
|
9
|
+
|
|
10
|
+
override init() {
|
|
11
|
+
#if DEBUG
|
|
12
|
+
self.cieSdk = CieDigitalId.init(.console)
|
|
13
|
+
#else
|
|
14
|
+
self.cieSdk = CieDigitalId.init()
|
|
15
|
+
#endif
|
|
16
|
+
super.init()
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
@objc override func supportedEvents() -> [String]! {
|
|
20
|
+
return EventType.allCases.map { $0.rawValue }
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
@objc func hasNfcFeature(
|
|
24
|
+
_ resolve: RCTPromiseResolveBlock,
|
|
25
|
+
withRejecter reject: RCTPromiseRejectBlock
|
|
26
|
+
) {
|
|
27
|
+
resolve(true) // iOS devices always have NFC functionality
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
@objc func isNfcEnabled(
|
|
31
|
+
_ resolve: RCTPromiseResolveBlock,
|
|
32
|
+
withRejecter reject: RCTPromiseRejectBlock
|
|
33
|
+
) {
|
|
34
|
+
resolve(CieDigitalId.isNFCEnabled())
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
@objc func isCieAuthenticationSupported(
|
|
38
|
+
_ resolve: RCTPromiseResolveBlock,
|
|
39
|
+
withRejecter reject: RCTPromiseRejectBlock
|
|
40
|
+
) {
|
|
41
|
+
resolve(CieDigitalId.isNFCEnabled())
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
@objc func openNfcSettings(
|
|
45
|
+
_ resolve: RCTPromiseResolveBlock,
|
|
46
|
+
withRejecter reject: RCTPromiseRejectBlock
|
|
47
|
+
) {
|
|
48
|
+
resolve(false) // iOS does not have NFC settings
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
@objc func setAlertMessage(
|
|
52
|
+
_ key: String,
|
|
53
|
+
withValue value: String
|
|
54
|
+
) {
|
|
55
|
+
cieSdk.setAlertMessage(key: key, value: value)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
@objc func setCurrentAlertMessage(
|
|
59
|
+
_ value: String
|
|
60
|
+
) {
|
|
61
|
+
cieSdk.alertMessage = value
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
@objc func setCustomIdpUrl(
|
|
65
|
+
_ url: String
|
|
66
|
+
) {
|
|
67
|
+
cieSdk.idpUrl = url
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
@objc func startReadingAttributes(
|
|
71
|
+
_ timeout: Int,
|
|
72
|
+
withResolver resolve: @escaping RCTPromiseResolveBlock,
|
|
73
|
+
withRejecter reject: @escaping RCTPromiseRejectBlock
|
|
74
|
+
) {
|
|
75
|
+
Task { [weak self] in
|
|
76
|
+
guard let self = self else {
|
|
77
|
+
ME.threadingError.reject(reject: reject)
|
|
78
|
+
return
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
do {
|
|
82
|
+
let atr = try await self.cieSdk.performReadAtr(handleReadEvent)
|
|
83
|
+
let cieType = CIEType.fromATR(atr)
|
|
84
|
+
let payload: NSDictionary = [
|
|
85
|
+
"type": cieType.rawValue,
|
|
86
|
+
"atr": Data(atr).base64EncodedString(),
|
|
87
|
+
]
|
|
88
|
+
self.sendEvent(
|
|
89
|
+
withName: EventType.onAttributesSuccess.rawValue, body: payload)
|
|
90
|
+
} catch {
|
|
91
|
+
guard let nfcDigitalIdError = error as? NfcDigitalIdError else {
|
|
92
|
+
ME.unexpected.reject(
|
|
93
|
+
reject: reject, ("error", error.localizedDescription))
|
|
94
|
+
return
|
|
95
|
+
}
|
|
96
|
+
handleReadError(nfcDigitalIdError)
|
|
97
|
+
resolve(nil)
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
@objc func startReading(
|
|
103
|
+
_ pin: String,
|
|
104
|
+
withAuthUrl authUrl: String,
|
|
105
|
+
withTimeout timeout: Int,
|
|
106
|
+
withResolver resolve: @escaping RCTPromiseResolveBlock,
|
|
107
|
+
withRejecter reject: @escaping RCTPromiseRejectBlock
|
|
108
|
+
) {
|
|
109
|
+
Task { [weak self] in
|
|
110
|
+
guard let self = self else {
|
|
111
|
+
ME.threadingError.reject(reject: reject)
|
|
112
|
+
return
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
guard pin.count == 8, pin.allSatisfy(\.isNumber) else {
|
|
116
|
+
ME.invalidPin.reject(reject: reject)
|
|
117
|
+
return
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
guard let url = URL(string: authUrl) else {
|
|
121
|
+
ME.invalidAuthUrl.reject(reject: reject)
|
|
122
|
+
return
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
do {
|
|
126
|
+
let authenticatedUrl = try await self.cieSdk.performAuthentication(
|
|
127
|
+
forUrl: url.absoluteString, withPin: pin, handleReadEvent)
|
|
128
|
+
self.sendEvent(
|
|
129
|
+
withName: EventType.onSuccess.rawValue, body: authenticatedUrl)
|
|
130
|
+
} catch {
|
|
131
|
+
guard let nfcDigitalIdError = error as? NfcDigitalIdError else {
|
|
132
|
+
ME.unexpected.reject(
|
|
133
|
+
reject: reject, ("error", error.localizedDescription))
|
|
134
|
+
return
|
|
135
|
+
}
|
|
136
|
+
handleReadError(nfcDigitalIdError)
|
|
137
|
+
resolve(nil)
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
func handleReadEvent(event: CieSDK.CieDigitalIdEvent, progress: Float) {
|
|
143
|
+
let payload: NSDictionary = ["name": "\(event)", "progress": progress]
|
|
144
|
+
self.sendEvent(withName: EventType.onEvent.rawValue, body: payload)
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
func handleReadError(_ error: NfcDigitalIdError) {
|
|
148
|
+
var payload: [String: Any] = [:]
|
|
149
|
+
|
|
150
|
+
switch error {
|
|
151
|
+
case .invalidTag:
|
|
152
|
+
payload = [ "name": ErrorType.NOT_A_CIE.rawValue, "message": error.description ]
|
|
153
|
+
case .nfcError(let nfcError):
|
|
154
|
+
switch nfcError.code {
|
|
155
|
+
case .readerTransceiveErrorTagConnectionLost, .readerTransceiveErrorTagResponseError:
|
|
156
|
+
payload = [ "name": ErrorType.TAG_LOST.rawValue, "message": error.description ]
|
|
157
|
+
case .readerSessionInvalidationErrorUserCanceled:
|
|
158
|
+
payload = [ "name": ErrorType.CANCELLED_BY_USER.rawValue, "message": error.description ]
|
|
159
|
+
default:
|
|
160
|
+
payload = [ "name": ErrorType.GENERIC_ERROR.rawValue, "message": error.description ]
|
|
161
|
+
}
|
|
162
|
+
case .errorBuildingApdu, .responseError:
|
|
163
|
+
payload = [ "name": ErrorType.APDU_ERROR.rawValue, "message": error.description ]
|
|
164
|
+
case .wrongPin(let attempts):
|
|
165
|
+
payload = [ "name":ErrorType.WRONG_PIN.rawValue, "message": error.description, "attempts": attempts ]
|
|
166
|
+
case .cardBlocked:
|
|
167
|
+
payload = [ "name": ErrorType.CARD_BLOCKED.rawValue, "message": error.description ]
|
|
168
|
+
case .sslError:
|
|
169
|
+
payload = [ "name": ErrorType.CERTIFICATE_EXPIRED.rawValue, "message": error.description ]
|
|
170
|
+
default:
|
|
171
|
+
payload = [ "name": ErrorType.GENERIC_ERROR.rawValue, "message": error.description ]
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
self.sendEvent(withName: EventType.onError.rawValue, body: payload)
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
private enum EventType: String, CaseIterable {
|
|
178
|
+
case onEvent
|
|
179
|
+
case onError
|
|
180
|
+
case onAttributesSuccess
|
|
181
|
+
case onSuccess
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
private enum ErrorType: String, CaseIterable {
|
|
185
|
+
case NOT_A_CIE
|
|
186
|
+
case TAG_LOST
|
|
187
|
+
case CANCELLED_BY_USER
|
|
188
|
+
case APDU_ERROR
|
|
189
|
+
case WRONG_PIN
|
|
190
|
+
case CARD_BLOCKED
|
|
191
|
+
case NO_INTERNET_CONNECTION
|
|
192
|
+
case CERTIFICATE_EXPIRED
|
|
193
|
+
case CERTIFICATE_REVOKED
|
|
194
|
+
case AUTHENTICATION_ERROR
|
|
195
|
+
case GENERIC_ERROR
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
private enum ModuleException: String, CaseIterable {
|
|
199
|
+
case invalidPin = "PIN_REGEX_NOT_VALID"
|
|
200
|
+
case invalidAuthUrl = "INVALID_AUTH_URL"
|
|
201
|
+
case threadingError = "THREADING_ERROR"
|
|
202
|
+
case unexpected = "UNEXPECTED_ERROR"
|
|
203
|
+
|
|
204
|
+
func error(userInfo: [String: Any]? = nil) -> NSError {
|
|
205
|
+
switch self {
|
|
206
|
+
case .invalidPin:
|
|
207
|
+
return NSError(domain: self.rawValue, code: -1, userInfo: userInfo)
|
|
208
|
+
case .invalidAuthUrl:
|
|
209
|
+
return NSError(domain: self.rawValue, code: -1, userInfo: userInfo)
|
|
210
|
+
case .threadingError:
|
|
211
|
+
return NSError(domain: self.rawValue, code: -1, userInfo: userInfo)
|
|
212
|
+
case .unexpected:
|
|
213
|
+
return NSError(domain: self.rawValue, code: -1, userInfo: userInfo)
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
func reject(reject: RCTPromiseRejectBlock, _ moreUserInfo: (String, Any)...)
|
|
218
|
+
{
|
|
219
|
+
var userInfo = [String: Any]()
|
|
220
|
+
moreUserInfo.forEach { userInfo[$0.0] = $0.1 }
|
|
221
|
+
let error = error(userInfo: userInfo)
|
|
222
|
+
reject("\(error.code)", error.domain, error)
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
}
|
|
227
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":[],"sourceRoot":"../../src","sources":["errors.ts"],"mappings":"","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["CieUtils","CieManager"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":";;AAAA,OAAO,KAAKA,QAAQ,MAAM,kBAAS;AACnC,OAAO,KAAKC,UAAU,MAAM,oBAAW;AAEvC,SAASD,QAAQ,EAAEC,UAAU","ignoreList":[]}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { NativeEventEmitter, NativeModules } from 'react-native';
|
|
4
|
+
import { IoReactNativeCie } from "../native.js";
|
|
5
|
+
const DEFAULT_TIMEOUT = 10000;
|
|
6
|
+
const eventEmitter = new NativeEventEmitter(NativeModules.IoReactNativeCie);
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Adds a listener for a specific CIE event.
|
|
10
|
+
*
|
|
11
|
+
* @param event - The event to listen to {@see CieEvent}
|
|
12
|
+
* @param listener - The listener to add {@see CieEventHandler}
|
|
13
|
+
* @returns Function to remove the listener
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* const removeListener = CieManager.addListener('onEvent', event => {
|
|
17
|
+
* console.log(event.name, event.progress);
|
|
18
|
+
* });
|
|
19
|
+
* // ...
|
|
20
|
+
* removeListener();
|
|
21
|
+
*/
|
|
22
|
+
const addListener = (event, listener) => {
|
|
23
|
+
const subscription = eventEmitter.addListener(event, listener);
|
|
24
|
+
return subscription.remove;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Removes a listener for a specific CIE event.
|
|
29
|
+
*
|
|
30
|
+
* @param event - The event to remove the listener from {@see CieEvent}
|
|
31
|
+
*/
|
|
32
|
+
const removeListener = event => {
|
|
33
|
+
eventEmitter.removeAllListeners(event);
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Removes all registered event, error, and success listeners for CIE operations.
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```typescript
|
|
41
|
+
* CieManager.removeAllListeners();
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
const removeAllListeners = () => {
|
|
45
|
+
eventEmitter.removeAllListeners('onEvent');
|
|
46
|
+
eventEmitter.removeAllListeners('onError');
|
|
47
|
+
eventEmitter.removeAllListeners('onAttributesSuccess');
|
|
48
|
+
eventEmitter.removeAllListeners('onSuccess');
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Sets a custom Identity Provider (IDP) URL for authentication.
|
|
53
|
+
* If not set, will be used the default IDP URL:
|
|
54
|
+
* https://idserver.servizicie.interno.gov.it/idp/
|
|
55
|
+
*
|
|
56
|
+
* @param url - The custom IDP URL to use
|
|
57
|
+
* @example
|
|
58
|
+
* ```typescript
|
|
59
|
+
* CieManager.setCustomIdpUrl('https://custom.idp.com/auth');
|
|
60
|
+
* ```
|
|
61
|
+
*/
|
|
62
|
+
const setCustomIdpUrl = url => {
|
|
63
|
+
return IoReactNativeCie.setCustomIdpUrl(url);
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Sets an alert message for the CIE reading process.
|
|
68
|
+
*
|
|
69
|
+
* **Note**: Alert messages are only available on iOS
|
|
70
|
+
*
|
|
71
|
+
* @param key - The key of the alert message to set
|
|
72
|
+
* @param value - The value of the alert message to set
|
|
73
|
+
* @example
|
|
74
|
+
* ```typescript
|
|
75
|
+
* CieManager.setAlertMessage('readingInstructions', 'Please scan your CIE card');
|
|
76
|
+
* ```
|
|
77
|
+
*/
|
|
78
|
+
export const setAlertMessage = (key, value) => {
|
|
79
|
+
return IoReactNativeCie.setAlertMessage(key, value);
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Updates the current displayed alert message for the CIE reading process.
|
|
84
|
+
*
|
|
85
|
+
* **Note**: Alert messages are only available on iOS
|
|
86
|
+
*
|
|
87
|
+
* @param value - The value of the alert message to set
|
|
88
|
+
* @example
|
|
89
|
+
* ```typescript
|
|
90
|
+
* CieManager.setCurrentAlertMessage('Please scan your CIE card');
|
|
91
|
+
* ```
|
|
92
|
+
*/
|
|
93
|
+
export const setCurrentAlertMessage = value => {
|
|
94
|
+
return IoReactNativeCie.setCurrentAlertMessage(value);
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Starts the process of reading attributes from the CIE card.
|
|
99
|
+
*
|
|
100
|
+
* @param timeout - Optional timeout in milliseconds (default: 10000) (**Note**: Android only)
|
|
101
|
+
* @returns Promise<void>
|
|
102
|
+
* @throws {CieError} If reading attributes fails
|
|
103
|
+
* @example
|
|
104
|
+
* ```typescript
|
|
105
|
+
* await CieManager.startReadingAttributes();
|
|
106
|
+
* // or with custom timeout
|
|
107
|
+
* await CieManager.startReadingAttributes(15000);
|
|
108
|
+
* ```
|
|
109
|
+
*/
|
|
110
|
+
const startReadingAttributes = async (timeout = DEFAULT_TIMEOUT) => {
|
|
111
|
+
return IoReactNativeCie.startReadingAttributes(timeout);
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Starts the CIE reading and authentication process.
|
|
116
|
+
*
|
|
117
|
+
* @param pin - The CIE card PIN code
|
|
118
|
+
* @param authenticationUrl - The authentication service URL
|
|
119
|
+
* @param timeout - Optional timeout in milliseconds (default: 10000) (**Note**: Android only)
|
|
120
|
+
* @returns Promise<void>
|
|
121
|
+
* @throws {CieError} If could not start reading for authentication
|
|
122
|
+
* @example
|
|
123
|
+
* ```typescript
|
|
124
|
+
* await CieManager.startReading('12345678', 'https://idserver.example.com/auth');
|
|
125
|
+
* // or with custom timeout
|
|
126
|
+
* await CieManager.startReading('12345678', 'https://idserver.example.com/auth', 20000);
|
|
127
|
+
* ```
|
|
128
|
+
*/
|
|
129
|
+
const startReading = async (pin, authenticationUrl, timeout = DEFAULT_TIMEOUT) => {
|
|
130
|
+
return IoReactNativeCie.startReading(pin, authenticationUrl, timeout);
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Stops any ongoing CIE reading process.
|
|
135
|
+
*
|
|
136
|
+
* **Note:** Android only. On iOS the reading process is stopped by closing
|
|
137
|
+
* the system NFC overlay
|
|
138
|
+
*
|
|
139
|
+
* @returns Promise<void>
|
|
140
|
+
* @example
|
|
141
|
+
* ```typescript
|
|
142
|
+
* await CieManager.stopReading();
|
|
143
|
+
* ```
|
|
144
|
+
*/
|
|
145
|
+
const stopReading = async () => {
|
|
146
|
+
return IoReactNativeCie.stopReading();
|
|
147
|
+
};
|
|
148
|
+
export { addListener, removeListener, removeAllListeners, setCustomIdpUrl, startReadingAttributes, startReading, stopReading };
|
|
149
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["NativeEventEmitter","NativeModules","IoReactNativeCie","DEFAULT_TIMEOUT","eventEmitter","addListener","event","listener","subscription","remove","removeListener","removeAllListeners","setCustomIdpUrl","url","setAlertMessage","key","value","setCurrentAlertMessage","startReadingAttributes","timeout","startReading","pin","authenticationUrl","stopReading"],"sourceRoot":"../../../src","sources":["manager/index.ts"],"mappings":";;AAAA,SAASA,kBAAkB,EAAEC,aAAa,QAAQ,cAAc;AAChE,SAASC,gBAAgB,QAAQ,cAAW;AAG5C,MAAMC,eAAe,GAAG,KAAK;AAE7B,MAAMC,YAAY,GAAG,IAAIJ,kBAAkB,CAACC,aAAa,CAACC,gBAAgB,CAAC;;AAE3E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAMG,WAAW,GAAGA,CAClBC,KAAQ,EACRC,QAA6B,KAC1B;EACH,MAAMC,YAAY,GAAGJ,YAAY,CAACC,WAAW,CAACC,KAAK,EAAEC,QAAQ,CAAC;EAC9D,OAAOC,YAAY,CAACC,MAAM;AAC5B,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA,MAAMC,cAAc,GAAIJ,KAAe,IAAK;EAC1CF,YAAY,CAACO,kBAAkB,CAACL,KAAK,CAAC;AACxC,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAMK,kBAAkB,GAAGA,CAAA,KAAM;EAC/BP,YAAY,CAACO,kBAAkB,CAAC,SAAS,CAAC;EAC1CP,YAAY,CAACO,kBAAkB,CAAC,SAAS,CAAC;EAC1CP,YAAY,CAACO,kBAAkB,CAAC,qBAAqB,CAAC;EACtDP,YAAY,CAACO,kBAAkB,CAAC,WAAW,CAAC;AAC9C,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAMC,eAAe,GAAIC,GAAW,IAAK;EACvC,OAAOX,gBAAgB,CAACU,eAAe,CAACC,GAAG,CAAC;AAC9C,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,eAAe,GAAGA,CAACC,GAAoB,EAAEC,KAAa,KAAK;EACtE,OAAOd,gBAAgB,CAACY,eAAe,CAACC,GAAG,EAAEC,KAAK,CAAC;AACrD,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,sBAAsB,GAAID,KAAa,IAAK;EACvD,OAAOd,gBAAgB,CAACe,sBAAsB,CAACD,KAAK,CAAC;AACvD,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAME,sBAAsB,GAAG,MAAAA,CAC7BC,OAAe,GAAGhB,eAAe,KACf;EAClB,OAAOD,gBAAgB,CAACgB,sBAAsB,CAACC,OAAO,CAAC;AACzD,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAMC,YAAY,GAAG,MAAAA,CACnBC,GAAW,EACXC,iBAAyB,EACzBH,OAAe,GAAGhB,eAAe,KACf;EAClB,OAAOD,gBAAgB,CAACkB,YAAY,CAACC,GAAG,EAAEC,iBAAiB,EAAEH,OAAO,CAAC;AACvE,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAMI,WAAW,GAAG,MAAAA,CAAA,KAA2B;EAC7C,OAAOrB,gBAAgB,CAACqB,WAAW,CAAC,CAAC;AACvC,CAAC;AAED,SACElB,WAAW,EACXK,cAAc,EACdC,kBAAkB,EAClBC,eAAe,EACfM,sBAAsB,EACtBE,YAAY,EACZG,WAAW","ignoreList":[]}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Represent the key of the alert message that can be set during the CIE reading process
|
|
7
|
+
*
|
|
8
|
+
* **Note**: Alert messages are only available on iOS
|
|
9
|
+
*/
|
|
10
|
+
export const AlertMessageKey = z.enum(['readingInstructions', 'moreTags', 'readingInProgress', 'readingSuccess', 'invalidCard', 'tagLost', 'cardLocked', 'wrongPin1AttemptLeft', 'wrongPin2AttemptLeft', 'genericError']);
|
|
11
|
+
/**
|
|
12
|
+
* Event emitted during the CIE reading process with the name of the event and the progress of the reading up to that point.
|
|
13
|
+
* Event names may differ based on the platform.
|
|
14
|
+
*/
|
|
15
|
+
export const NfcEvent = z.object({
|
|
16
|
+
name: z.string(),
|
|
17
|
+
progress: z.coerce.number()
|
|
18
|
+
});
|
|
19
|
+
/**
|
|
20
|
+
* Name of the error emitted during the CIE reading process
|
|
21
|
+
*/
|
|
22
|
+
export const NfcErrorName = z.enum(['NOT_A_CIE', 'TAG_LOST', 'CANCELLED_BY_USER', 'APDU_ERROR', 'WRONG_PIN', 'CARD_BLOCKED', 'NO_INTERNET_CONNECTION', 'CERTIFICATE_EXPIRED', 'CERTIFICATE_REVOKED', 'AUTHENTICATION_ERROR', 'GENERIC_ERROR']);
|
|
23
|
+
/**
|
|
24
|
+
* Represent an NFC error emitted during the CIE reading process
|
|
25
|
+
* It contains the name of the error, the message and the number of attempts
|
|
26
|
+
*/
|
|
27
|
+
export const NfcError = z.union([z.object({
|
|
28
|
+
name: NfcErrorName,
|
|
29
|
+
message: z.string().optional()
|
|
30
|
+
}), z.object({
|
|
31
|
+
name: z.literal(NfcErrorName.enum.WRONG_PIN),
|
|
32
|
+
message: z.string().optional(),
|
|
33
|
+
attempts: z.number()
|
|
34
|
+
})]);
|
|
35
|
+
/**
|
|
36
|
+
* Represent the CIE attributes containing the CIE type
|
|
37
|
+
*/
|
|
38
|
+
export const CieAttributes = z.object({
|
|
39
|
+
type: z.string(),
|
|
40
|
+
base64: z.string()
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Event handler that can be used to handle the CIE events during the reading process
|
|
45
|
+
*/
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Possible events that can be listened to
|
|
49
|
+
*/
|
|
50
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["z","AlertMessageKey","enum","NfcEvent","object","name","string","progress","coerce","number","NfcErrorName","NfcError","union","message","optional","literal","WRONG_PIN","attempts","CieAttributes","type","base64"],"sourceRoot":"../../../src","sources":["manager/types.ts"],"mappings":";;AAAA,SAASA,CAAC,QAAQ,KAAK;;AAEvB;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,eAAe,GAAGD,CAAC,CAACE,IAAI,CAAC,CACpC,qBAAqB,EACrB,UAAU,EACV,mBAAmB,EACnB,gBAAgB,EAChB,aAAa,EACb,SAAS,EACT,YAAY,EACZ,sBAAsB,EACtB,sBAAsB,EACtB,cAAc,CACf,CAAC;AAIF;AACA;AACA;AACA;AACA,OAAO,MAAMC,QAAQ,GAAGH,CAAC,CAACI,MAAM,CAAC;EAC/BC,IAAI,EAAEL,CAAC,CAACM,MAAM,CAAC,CAAC;EAChBC,QAAQ,EAAEP,CAAC,CAACQ,MAAM,CAACC,MAAM,CAAC;AAC5B,CAAC,CAAC;AAIF;AACA;AACA;AACA,OAAO,MAAMC,YAAY,GAAGV,CAAC,CAACE,IAAI,CAAC,CACjC,WAAW,EACX,UAAU,EACV,mBAAmB,EACnB,YAAY,EACZ,WAAW,EACX,cAAc,EACd,wBAAwB,EACxB,qBAAqB,EACrB,qBAAqB,EACrB,sBAAsB,EACtB,eAAe,CAChB,CAAC;AAIF;AACA;AACA;AACA;AACA,OAAO,MAAMS,QAAQ,GAAGX,CAAC,CAACY,KAAK,CAAC,CAC9BZ,CAAC,CAACI,MAAM,CAAC;EACPC,IAAI,EAAEK,YAAY;EAClBG,OAAO,EAAEb,CAAC,CAACM,MAAM,CAAC,CAAC,CAACQ,QAAQ,CAAC;AAC/B,CAAC,CAAC,EACFd,CAAC,CAACI,MAAM,CAAC;EACPC,IAAI,EAAEL,CAAC,CAACe,OAAO,CAACL,YAAY,CAACR,IAAI,CAACc,SAAS,CAAC;EAC5CH,OAAO,EAAEb,CAAC,CAACM,MAAM,CAAC,CAAC,CAACQ,QAAQ,CAAC,CAAC;EAC9BG,QAAQ,EAAEjB,CAAC,CAACS,MAAM,CAAC;AACrB,CAAC,CAAC,CACH,CAAC;AAIF;AACA;AACA;AACA,OAAO,MAAMS,aAAa,GAAGlB,CAAC,CAACI,MAAM,CAAC;EACpCe,IAAI,EAAEnB,CAAC,CAACM,MAAM,CAAC,CAAC;EAChBc,MAAM,EAAEpB,CAAC,CAACM,MAAM,CAAC;AACnB,CAAC,CAAC;;AAIF;AACA;AACA;;AAQA;AACA;AACA","ignoreList":[]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { NativeModules, Platform } from 'react-native';
|
|
4
|
+
const LINKING_ERROR = `The package '@pagopa/io-react-native-cie' doesn't seem to be linked. Make sure: \n\n` + Platform.select({
|
|
5
|
+
ios: "- You have run 'pod install'\n",
|
|
6
|
+
default: ''
|
|
7
|
+
}) + '- You rebuilt the app after installing the package\n' + '- You are not using Expo Go\n';
|
|
8
|
+
export const IoReactNativeCie = NativeModules.IoReactNativeCie ? NativeModules.IoReactNativeCie : new Proxy({}, {
|
|
9
|
+
get() {
|
|
10
|
+
throw new Error(LINKING_ERROR);
|
|
11
|
+
}
|
|
12
|
+
});
|
|
13
|
+
//# sourceMappingURL=native.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["NativeModules","Platform","LINKING_ERROR","select","ios","default","IoReactNativeCie","Proxy","get","Error"],"sourceRoot":"../../src","sources":["native.ts"],"mappings":";;AAAA,SAASA,aAAa,EAAEC,QAAQ,QAAQ,cAAc;AAEtD,MAAMC,aAAa,GACjB,sFAAsF,GACtFD,QAAQ,CAACE,MAAM,CAAC;EAAEC,GAAG,EAAE,gCAAgC;EAAEC,OAAO,EAAE;AAAG,CAAC,CAAC,GACvE,sDAAsD,GACtD,+BAA+B;AAEjC,OAAO,MAAMC,gBAAgB,GAAGN,aAAa,CAACM,gBAAgB,GAC1DN,aAAa,CAACM,gBAAgB,GAC9B,IAAIC,KAAK,CACP,CAAC,CAAC,EACF;EACEC,GAAGA,CAAA,EAAG;IACJ,MAAM,IAAIC,KAAK,CAACP,aAAa,CAAC;EAChC;AACF,CACF,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"type":"module"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { IoReactNativeCie } from "../native.js";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Checks if the device has NFC hardware capabilities.
|
|
7
|
+
*
|
|
8
|
+
* On iOS the NFC features is always available.
|
|
9
|
+
*
|
|
10
|
+
* @returns A promise that resolves to true if the device supports NFC, false otherwise.
|
|
11
|
+
* @throws {CieError} If cannot check if NFC is available.
|
|
12
|
+
*/
|
|
13
|
+
export const hasNfcFeature = async () => {
|
|
14
|
+
return IoReactNativeCie.hasNfcFeature();
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Checks if NFC is currently enabled on the device.
|
|
19
|
+
*
|
|
20
|
+
* On iOS the NFC features is always enabled.
|
|
21
|
+
*
|
|
22
|
+
* @returns A promise that resolves to true if NFC is enabled, false otherwise.
|
|
23
|
+
* @throws {CieError} If cannot check if NFC is enabled.
|
|
24
|
+
*/
|
|
25
|
+
export const isNfcEnabled = async () => {
|
|
26
|
+
return IoReactNativeCie.isNfcEnabled();
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Verifies if the device supports CIE (Electronic Identity Card) authentication.
|
|
31
|
+
* @returns A promise that resolves to true if CIE authentication is supported, false otherwise.
|
|
32
|
+
*/
|
|
33
|
+
export const isCieAuthenticationSupported = async () => {
|
|
34
|
+
return IoReactNativeCie.isCieAuthenticationSupported();
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Opens the device's NFC settings page, allowing users to enable or disable NFC.
|
|
39
|
+
* @returns A promise that resolves when the settings page is opened.
|
|
40
|
+
* @throws {CieError} If cannot open the settings page.
|
|
41
|
+
*/
|
|
42
|
+
export const openNfcSettings = async () => {
|
|
43
|
+
return IoReactNativeCie.openNfcSettings();
|
|
44
|
+
};
|
|
45
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["IoReactNativeCie","hasNfcFeature","isNfcEnabled","isCieAuthenticationSupported","openNfcSettings"],"sourceRoot":"../../../src","sources":["utils/index.ts"],"mappings":";;AAAA,SAASA,gBAAgB,QAAQ,cAAW;;AAE5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,aAAa,GAAG,MAAAA,CAAA,KAAY;EACvC,OAAOD,gBAAgB,CAACC,aAAa,CAAC,CAAC;AACzC,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,YAAY,GAAG,MAAAA,CAAA,KAAY;EACtC,OAAOF,gBAAgB,CAACE,YAAY,CAAC,CAAC;AACxC,CAAC;;AAED;AACA;AACA;AACA;AACA,OAAO,MAAMC,4BAA4B,GAAG,MAAAA,CAAA,KAAY;EACtD,OAAOH,gBAAgB,CAACG,4BAA4B,CAAC,CAAC;AACxD,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,eAAe,GAAG,MAAAA,CAAA,KAAY;EACzC,OAAOJ,gBAAgB,CAACI,eAAe,CAAC,CAAC;AAC3C,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"type":"module"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error codes returned by the iOS module.
|
|
3
|
+
*/
|
|
4
|
+
type CieErrorCodesIOS = 'PIN_REGEX_NOT_VALID' | 'INVALID_AUTH_URL' | 'THREADING_ERROR' | 'UNKNOWN_EXCEPTION';
|
|
5
|
+
/**
|
|
6
|
+
* Error codes returned by the Android side.
|
|
7
|
+
*/
|
|
8
|
+
type CieErrorCodesAndroid = 'PIN_REGEX_NOT_VALID' | 'INVALID_AUTH_URL' | 'UNKNOWN_EXCEPTION';
|
|
9
|
+
/**
|
|
10
|
+
* All error codes that the module could return.
|
|
11
|
+
*/
|
|
12
|
+
export type CieErrorCodes = CieErrorCodesAndroid | CieErrorCodesIOS;
|
|
13
|
+
/**
|
|
14
|
+
* Error type returned by a rejected promise.
|
|
15
|
+
*
|
|
16
|
+
* If additional error information are available,
|
|
17
|
+
* they are stored in the {@link CieError["userInfo"]} field.
|
|
18
|
+
*/
|
|
19
|
+
export type CieError = {
|
|
20
|
+
message: CieErrorCodes;
|
|
21
|
+
userInfo: Record<string, string>;
|
|
22
|
+
};
|
|
23
|
+
export {};
|
|
24
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../src/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,KAAK,gBAAgB,GACjB,qBAAqB,GACrB,kBAAkB,GAClB,iBAAiB,GACjB,mBAAmB,CAAC;AAExB;;GAEG;AACH,KAAK,oBAAoB,GACrB,qBAAqB,GACrB,kBAAkB,GAClB,mBAAmB,CAAC;AAExB;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,oBAAoB,GAAG,gBAAgB,CAAC;AAEpE;;;;;GAKG;AACH,MAAM,MAAM,QAAQ,GAAG;IACrB,OAAO,EAAE,aAAa,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import * as CieUtils from './utils';
|
|
2
|
+
import * as CieManager from './manager';
|
|
3
|
+
export { CieUtils, CieManager };
|
|
4
|
+
export type { NfcEvent, NfcError, CieAttributes, CieEventHandlers, CieEvent, } from './manager/types';
|
|
5
|
+
export type { CieError, CieErrorCodes } from './errors';
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,SAAS,CAAC;AACpC,OAAO,KAAK,UAAU,MAAM,WAAW,CAAC;AAExC,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC;AAEhC,YAAY,EACV,QAAQ,EACR,QAAQ,EACR,aAAa,EACb,gBAAgB,EAChB,QAAQ,GACT,MAAM,iBAAiB,CAAC;AAEzB,YAAY,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC"}
|