@pagopa/io-react-native-iso18013 0.3.0 → 0.5.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/README.md +10 -5
- package/android/build.gradle +7 -1
- package/android/src/main/java/com/ioreactnativeiso18013/IoReactNativeCborModule.kt +69 -134
- package/android/src/main/java/com/ioreactnativeiso18013/IoReactNativeIso18013Module.kt +254 -183
- package/android/src/test/java/com/ioreactnativeiso18013/Base64UtilsTest.kt +66 -0
- package/android/src/test/java/com/ioreactnativeiso18013/IoReactNativeIso18013Test.kt +508 -0
- package/ios/Base64Utils.swift +10 -3
- package/ios/IoReactNativeCbor.mm +21 -21
- package/ios/IoReactNativeCbor.swift +116 -138
- package/ios/IoReactNativeIso18013.mm +10 -10
- package/ios/IoReactNativeIso18013.swift +172 -193
- package/lib/module/cbor/cbor/README.md +39 -59
- package/lib/module/cbor/cbor/decoder.js +13 -23
- package/lib/module/cbor/cbor/decoder.js.map +1 -1
- package/lib/module/cbor/cbor/error.js +15 -0
- package/lib/module/cbor/cbor/error.js.map +1 -0
- package/lib/module/cbor/cbor/index.js +1 -0
- package/lib/module/cbor/cbor/index.js.map +1 -1
- package/lib/module/cbor/cose/README.md +39 -9
- package/lib/module/cbor/cose/error.js +17 -0
- package/lib/module/cbor/cose/error.js.map +1 -0
- package/lib/module/cbor/cose/index.js +1 -0
- package/lib/module/cbor/cose/index.js.map +1 -1
- package/lib/module/cbor/cose/sign.js +4 -3
- package/lib/module/cbor/cose/sign.js.map +1 -1
- package/lib/module/iso18013/index.js +0 -1
- package/lib/module/iso18013/index.js.map +1 -1
- package/lib/module/iso18013/iso18013-5/README.md +120 -44
- package/lib/module/iso18013/iso18013-5/error.js +25 -0
- package/lib/module/iso18013/iso18013-5/error.js.map +1 -0
- package/lib/module/iso18013/iso18013-5/index.js +3 -2
- package/lib/module/iso18013/iso18013-5/index.js.map +1 -1
- package/lib/module/iso18013/iso18013-5/proximity.js +20 -15
- package/lib/module/iso18013/iso18013-5/proximity.js.map +1 -1
- package/lib/module/iso18013/iso18013-5/{schema.js → request.js} +1 -37
- package/lib/module/iso18013/iso18013-5/request.js.map +1 -0
- package/lib/module/iso18013/iso18013-7/README.md +66 -41
- package/lib/module/iso18013/iso18013-7/error.js +15 -0
- package/lib/module/iso18013/iso18013-7/error.js.map +1 -0
- package/lib/module/iso18013/iso18013-7/index.js +1 -0
- package/lib/module/iso18013/iso18013-7/index.js.map +1 -1
- package/lib/module/iso18013/iso18013-7/remote.js +11 -24
- package/lib/module/iso18013/iso18013-7/remote.js.map +1 -1
- package/lib/module/schema.js +46 -0
- package/lib/module/schema.js.map +1 -0
- package/lib/typescript/src/cbor/cbor/decoder.d.ts +12 -22
- package/lib/typescript/src/cbor/cbor/decoder.d.ts.map +1 -1
- package/lib/typescript/src/cbor/cbor/error.d.ts +68 -0
- package/lib/typescript/src/cbor/cbor/error.d.ts.map +1 -0
- package/lib/typescript/src/cbor/cbor/index.d.ts +1 -1
- package/lib/typescript/src/cbor/cbor/index.d.ts.map +1 -1
- package/lib/typescript/src/cbor/cose/error.d.ts +68 -0
- package/lib/typescript/src/cbor/cose/error.d.ts.map +1 -0
- package/lib/typescript/src/cbor/cose/index.d.ts +1 -1
- package/lib/typescript/src/cbor/cose/index.d.ts.map +1 -1
- package/lib/typescript/src/cbor/cose/sign.d.ts +4 -3
- package/lib/typescript/src/cbor/cose/sign.d.ts.map +1 -1
- package/lib/typescript/src/iso18013/index.d.ts +0 -1
- package/lib/typescript/src/iso18013/index.d.ts.map +1 -1
- package/lib/typescript/src/iso18013/iso18013-5/error.d.ts +73 -0
- package/lib/typescript/src/iso18013/iso18013-5/error.d.ts.map +1 -0
- package/lib/typescript/src/iso18013/iso18013-5/index.d.ts +4 -3
- package/lib/typescript/src/iso18013/iso18013-5/index.d.ts.map +1 -1
- package/lib/typescript/src/iso18013/iso18013-5/proximity.d.ts +21 -14
- package/lib/typescript/src/iso18013/iso18013-5/proximity.d.ts.map +1 -1
- package/lib/typescript/src/iso18013/iso18013-5/{schema.d.ts → request.d.ts} +1 -39
- package/lib/typescript/src/iso18013/iso18013-5/request.d.ts.map +1 -0
- package/lib/typescript/src/iso18013/iso18013-7/error.d.ts +68 -0
- package/lib/typescript/src/iso18013/iso18013-7/error.d.ts.map +1 -0
- package/lib/typescript/src/iso18013/iso18013-7/index.d.ts +3 -2
- package/lib/typescript/src/iso18013/iso18013-7/index.d.ts.map +1 -1
- package/lib/typescript/src/iso18013/iso18013-7/remote.d.ts +11 -25
- package/lib/typescript/src/iso18013/iso18013-7/remote.d.ts.map +1 -1
- package/lib/typescript/src/iso18013/types.d.ts +25 -0
- package/lib/typescript/src/iso18013/types.d.ts.map +1 -1
- package/lib/typescript/src/schema.d.ts +76 -0
- package/lib/typescript/src/schema.d.ts.map +1 -0
- package/package.json +1 -1
- package/src/cbor/cbor/README.md +39 -59
- package/src/cbor/cbor/decoder.ts +13 -23
- package/src/cbor/cbor/error.ts +23 -0
- package/src/cbor/cbor/index.ts +5 -1
- package/src/cbor/cose/README.md +39 -9
- package/src/cbor/cose/error.ts +23 -0
- package/src/cbor/cose/index.ts +5 -1
- package/src/cbor/cose/sign.ts +5 -4
- package/src/iso18013/index.ts +0 -7
- package/src/iso18013/iso18013-5/README.md +120 -44
- package/src/iso18013/iso18013-5/error.ts +35 -0
- package/src/iso18013/iso18013-5/index.ts +9 -8
- package/src/iso18013/iso18013-5/proximity.ts +21 -17
- package/src/iso18013/iso18013-5/{schema.ts → request.ts} +0 -42
- package/src/iso18013/iso18013-7/README.md +66 -41
- package/src/iso18013/iso18013-7/error.ts +21 -0
- package/src/iso18013/iso18013-7/index.ts +6 -5
- package/src/iso18013/iso18013-7/remote.ts +12 -34
- package/src/iso18013/types.ts +24 -0
- package/src/schema.ts +55 -0
- package/lib/module/cbor/cbor/failure.js +0 -2
- package/lib/module/cbor/cbor/failure.js.map +0 -1
- package/lib/module/cbor/cose/failure.js +0 -2
- package/lib/module/cbor/cose/failure.js.map +0 -1
- package/lib/module/iso18013/iso18013-5/schema.js.map +0 -1
- package/lib/typescript/src/cbor/cbor/failure.d.ts +0 -15
- package/lib/typescript/src/cbor/cbor/failure.d.ts.map +0 -1
- package/lib/typescript/src/cbor/cose/failure.d.ts +0 -15
- package/lib/typescript/src/cbor/cose/failure.d.ts.map +0 -1
- package/lib/typescript/src/iso18013/iso18013-5/schema.d.ts.map +0 -1
- package/src/cbor/cbor/failure.ts +0 -18
- package/src/cbor/cose/failure.ts +0 -20
package/src/cbor/cbor/README.md
CHANGED
|
@@ -1,95 +1,75 @@
|
|
|
1
|
-
|
|
1
|
+
# CBOR
|
|
2
2
|
|
|
3
3
|
This module provides methods to decode CBOR data into readable objects.
|
|
4
4
|
|
|
5
5
|
```typescript
|
|
6
|
-
import { CBOR } from '@pagopa/io-react-native-
|
|
6
|
+
import { CBOR } from '@pagopa/io-react-native-iso18013';
|
|
7
7
|
```
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
## Methods
|
|
10
10
|
|
|
11
11
|
#### `decode`
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
Returns a `Promise` which resolves to a JSON object, or rejects with an instance of `CborFailure` in case of failure.
|
|
13
|
+
Decodes CBOR data into readable JSON objects.
|
|
15
14
|
|
|
16
15
|
**Note**: this method does not decode nested CBOR objects and therefore complex objects needs additional manual decoding
|
|
17
16
|
|
|
18
17
|
```typescript
|
|
19
|
-
|
|
20
|
-
const decoded = await CBOR.decode('...');
|
|
21
|
-
} catch (e) {
|
|
22
|
-
const { message, userInfo } = e as CborFailure;
|
|
23
|
-
}
|
|
18
|
+
const decoded = await CBOR.decode('...');
|
|
24
19
|
```
|
|
25
20
|
|
|
26
21
|
#### `decodeDocuments`
|
|
27
22
|
|
|
28
|
-
|
|
29
|
-
Returns a promise wich resolves to a [Documents](#documents) object, or rejects with an instance of `CborFailure` in case of failure.
|
|
23
|
+
Decodes CBOR data containing MDOC objects.
|
|
30
24
|
|
|
31
25
|
```typescript
|
|
32
|
-
|
|
33
|
-
const decoded = await CBOR.decodeDocuments('...');
|
|
34
|
-
} catch (e) {
|
|
35
|
-
const { message, userInfo } = e as CborFailure;
|
|
36
|
-
}
|
|
26
|
+
const decoded = await CBOR.decodeDocuments('...');
|
|
37
27
|
```
|
|
38
28
|
|
|
39
|
-
|
|
29
|
+
#### `decodeIssuerSigned`
|
|
40
30
|
|
|
41
|
-
|
|
31
|
+
Decodes CBOR data containing an Issuer Signed object.
|
|
42
32
|
|
|
43
33
|
```typescript
|
|
44
|
-
|
|
45
|
-
status?: number;
|
|
46
|
-
version?: string;
|
|
47
|
-
documents?: Array<MDOC>;
|
|
48
|
-
};
|
|
34
|
+
const decoded = await CBOR.decodeIssuerSigned('...');
|
|
49
35
|
```
|
|
50
36
|
|
|
51
|
-
|
|
37
|
+
## Errors
|
|
52
38
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
39
|
+
This table contains the list of error codes that can be thrown by the `CBOR` module which are mapped via the `ModuleErrorCodes` type:
|
|
40
|
+
| Type | Platform | Description |
|
|
41
|
+
| -------------------------- | ----------- | ------------------------------------------------------------ |
|
|
42
|
+
| DECODE_ERROR | Android/iOS | An error occurred while decoding the CBOR |
|
|
43
|
+
| DECODE_DOCUMENTS_ERROR | Android/iOS | An error occurred while decoding a CBOR mDOC |
|
|
44
|
+
| DECODE_ISSUER_SIGNED_ERROR | Android/iOS | An error occurred while decoding a CBOR Issuer Signed object |
|
|
59
45
|
|
|
60
|
-
|
|
46
|
+
An error can be parsed using the `ModuleErrorSchema` with type `ModuleErrorCodes` exposed by the `ISO18013_5` module. The error can be parsed as follows:
|
|
61
47
|
|
|
62
48
|
```typescript
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
}
|
|
49
|
+
import { CBOR } from '@pagopa/io-react-native-iso18013';
|
|
50
|
+
try {
|
|
51
|
+
await CBOR.func();
|
|
52
|
+
} catch (error) {
|
|
53
|
+
const parsedError = CBOR.ModuleErrorSchema.parse(error); // Or ModuleErrorSchema.safeParse(error) for safe parsing
|
|
54
|
+
console.log(JSON.stringify(parsedError, null, 2));
|
|
55
|
+
}
|
|
67
56
|
```
|
|
68
57
|
|
|
69
|
-
|
|
58
|
+
The parsed object will contain properties from both iOS and Android platforms:
|
|
70
59
|
|
|
71
60
|
```typescript
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
61
|
+
{
|
|
62
|
+
code: string; // Defined in ModuleErrorCodes
|
|
63
|
+
message: string;
|
|
64
|
+
name: string;
|
|
65
|
+
userInfo?: Record<string, any> | null;
|
|
66
|
+
nativeStackAndroid?: Array<{
|
|
67
|
+
lineNumber: number;
|
|
68
|
+
file: string;
|
|
69
|
+
methodName: string;
|
|
70
|
+
class: string;
|
|
71
|
+
}>;
|
|
72
|
+
domain?: string;
|
|
73
|
+
nativeStackIOS?: Array<string>;
|
|
77
74
|
};
|
|
78
75
|
```
|
|
79
|
-
|
|
80
|
-
#### `DocumentType`
|
|
81
|
-
|
|
82
|
-
```typescript
|
|
83
|
-
enum DocumentTypeEnum {
|
|
84
|
-
MDL = 'org.iso.18013.5.1.mDL',
|
|
85
|
-
EU_PID = 'eu.europa.ec.eudi.pid.1',
|
|
86
|
-
}
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
### Error Codes
|
|
90
|
-
|
|
91
|
-
| Type | Platform | Description |
|
|
92
|
-
| ----------------- | ----------- | --------------------------------------------- |
|
|
93
|
-
| INVALID_ENCODING | Android/iOS | Provided payload has incorrect encoding |
|
|
94
|
-
| UNABLE_TO_DECODE | Android/iOS | The data does not contain a valid CBOR object |
|
|
95
|
-
| UNKNOWN_EXCEPTION | Android/iOS | Unexpected failure |
|
package/src/cbor/cbor/decoder.ts
CHANGED
|
@@ -8,15 +8,11 @@ import {
|
|
|
8
8
|
import { coerceToJSON } from './schema.utils';
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
|
-
* Decode base64 encoded CBOR data to JSON object.
|
|
11
|
+
* Decode base64 or base64url encoded CBOR data to JSON object.
|
|
12
|
+
* This method does not handle nested CBOR data, which will need additional parsing.
|
|
12
13
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* **NOTE**: this method does not handle nested CBOR data, which will need additional
|
|
17
|
-
* parsing.
|
|
18
|
-
*
|
|
19
|
-
* @param data - The base64 or base64url encoded CBOR data
|
|
14
|
+
* @param data - The base64 or base64url encoded CBOR string
|
|
15
|
+
* @throws {ModuleError} in case of failure which can be parsed with {@link ModuleErrorSchema}
|
|
20
16
|
* @returns The decoded data as JSON object
|
|
21
17
|
*/
|
|
22
18
|
export const decode = async (data: string): Promise<any> => {
|
|
@@ -25,12 +21,9 @@ export const decode = async (data: string): Promise<any> => {
|
|
|
25
21
|
};
|
|
26
22
|
|
|
27
23
|
/**
|
|
28
|
-
* Decode base64 or base64url encoded CBOR data to
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
* an instance of {@link CborFailure}.
|
|
32
|
-
*
|
|
33
|
-
* @param data - The base64 encoded MDOC data
|
|
24
|
+
* Decode base64 or base64url encoded mDOC-CBOR data to a JSON object
|
|
25
|
+
* @param data - The base64 or base64url encoded mDOC-CBOR string
|
|
26
|
+
* @throws {ModuleError} in case of failure which can be parsed with {@link ModuleErrorSchema}
|
|
34
27
|
* @returns The decoded data as mDOC object
|
|
35
28
|
*/
|
|
36
29
|
export const decodeDocuments = async (data: string): Promise<Documents> => {
|
|
@@ -39,18 +32,15 @@ export const decodeDocuments = async (data: string): Promise<Documents> => {
|
|
|
39
32
|
};
|
|
40
33
|
|
|
41
34
|
/**
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
* @param issuerSigned - The base64 or base64url encoded MDOC data
|
|
48
|
-
* @returns The decoded {@link IssuerSigned} contained in the mDOC object
|
|
35
|
+
* Decode base64 or base64url encoded issuerSigned attribute part of an mDOC-CBOR.
|
|
36
|
+
* @param data - The base64 or base64url encoded mDOC-CBOR containing the issuerSigned
|
|
37
|
+
* @throws {ModuleError} in case of failure which can be parsed with {@link ModuleErrorSchema}
|
|
38
|
+
* @returns The decoded {@link IssuerSigned}
|
|
49
39
|
*/
|
|
50
40
|
export const decodeIssuerSigned = async (
|
|
51
|
-
|
|
41
|
+
data: string
|
|
52
42
|
): Promise<IssuerSigned> => {
|
|
53
43
|
const decodedIssuerSignedString =
|
|
54
|
-
await IoReactNativeCbor.decodeIssuerSigned(
|
|
44
|
+
await IoReactNativeCbor.decodeIssuerSigned(data);
|
|
55
45
|
return await IssuerSignedFromString.parseAsync(decodedIssuerSignedString);
|
|
56
46
|
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import z from 'zod';
|
|
2
|
+
import { GenericModuleErrorSchema } from '../../schema';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Error codes which the CBOR module uses to reject a promise.
|
|
6
|
+
*/
|
|
7
|
+
const ModuleErrorCodesSchema = z.enum([
|
|
8
|
+
'DECODE_ERROR',
|
|
9
|
+
'DECODE_DOCUMENTS_ERROR',
|
|
10
|
+
'DECODE_ISSUER_SIGNED_ERROR',
|
|
11
|
+
'EUNSPECIFIED', // Android only default when no other error is specified
|
|
12
|
+
]);
|
|
13
|
+
|
|
14
|
+
export type ModuleErrorCodes = z.infer<typeof ModuleErrorCodesSchema>;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Schema which can be used to parse a rejected promise error by the CBOR module.
|
|
18
|
+
*/
|
|
19
|
+
export const ModuleErrorSchema = GenericModuleErrorSchema(
|
|
20
|
+
ModuleErrorCodesSchema
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
export type ModuleError = z.infer<typeof ModuleErrorSchema>;
|
package/src/cbor/cbor/index.ts
CHANGED
package/src/cbor/cose/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
This module provides methods to sign and verify data with COSE.
|
|
4
4
|
|
|
5
5
|
```typescript
|
|
6
|
-
import { COSE } from '@pagopa/io-react-native-
|
|
6
|
+
import { COSE } from '@pagopa/io-react-native-iso18013';
|
|
7
7
|
```
|
|
8
8
|
|
|
9
9
|
### Methods
|
|
@@ -42,12 +42,42 @@ try {
|
|
|
42
42
|
}
|
|
43
43
|
```
|
|
44
44
|
|
|
45
|
-
### Error
|
|
45
|
+
### Error
|
|
46
46
|
|
|
47
|
-
|
|
48
|
-
|
|
|
49
|
-
|
|
|
50
|
-
|
|
|
51
|
-
|
|
|
52
|
-
| THREADING_ERROR
|
|
53
|
-
|
|
47
|
+
This table contains the list of error codes that can be thrown by the `COSE` module which are mapped via the `ModuleErrorCodes` type:
|
|
48
|
+
| Type | Platform | Description |
|
|
49
|
+
| -------------------------- | ----------- | ------------------------------------------------------------ |
|
|
50
|
+
| SIGN_ERROR | Android/iOS | An error occurred while signing the data |
|
|
51
|
+
| VERIFY_ERROR | Android/iOS | An error occurred while verifying the signature |
|
|
52
|
+
| THREADING_ERROR | iOS | An error occurred while performing the sign operation in background |
|
|
53
|
+
|
|
54
|
+
An error can be parsed using the `ModuleErrorSchema` with type `ModuleErrorCodes` exposed by the `COSE` module. The error can be parsed as follows:
|
|
55
|
+
|
|
56
|
+
```typescript
|
|
57
|
+
import { COSE } from '@pagopa/io-react-native-iso18013';
|
|
58
|
+
try {
|
|
59
|
+
await COSE.func();
|
|
60
|
+
} catch (error) {
|
|
61
|
+
const parsedError = COSE.ModuleErrorSchema.parse(error); // Or ModuleErrorSchema.safeParse(error) for safe parsing
|
|
62
|
+
console.log(JSON.stringify(parsedError, null, 2));
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
The parsed object will contain properties from both iOS and Android platforms:
|
|
67
|
+
|
|
68
|
+
```typescript
|
|
69
|
+
{
|
|
70
|
+
code: string; // Defined in ModuleErrorCodes
|
|
71
|
+
message: string;
|
|
72
|
+
name: string;
|
|
73
|
+
userInfo?: Record<string, any> | null;
|
|
74
|
+
nativeStackAndroid?: Array<{
|
|
75
|
+
lineNumber: number;
|
|
76
|
+
file: string;
|
|
77
|
+
methodName: string;
|
|
78
|
+
class: string;
|
|
79
|
+
}>;
|
|
80
|
+
domain?: string;
|
|
81
|
+
nativeStackIOS?: Array<string>;
|
|
82
|
+
};
|
|
83
|
+
```
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import z from 'zod';
|
|
2
|
+
import { GenericModuleErrorSchema } from '../../schema';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Error codes which the COSE module uses to reject a promise.
|
|
6
|
+
*/
|
|
7
|
+
const ModuleErrorCodesSchema = z.enum([
|
|
8
|
+
'SIGN_ERROR',
|
|
9
|
+
'VERIFY_ERROR',
|
|
10
|
+
'THREADING_ERROR', // iOS only
|
|
11
|
+
'EUNSPECIFIED', // Android only default when no other error is specified
|
|
12
|
+
]);
|
|
13
|
+
|
|
14
|
+
export type ModuleErrorCodes = z.infer<typeof ModuleErrorCodesSchema>;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Schema which can be used to parse a rejected promise error by the COSE module.
|
|
18
|
+
*/
|
|
19
|
+
export const ModuleErrorSchema = GenericModuleErrorSchema(
|
|
20
|
+
ModuleErrorCodesSchema
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
export type ModuleError = z.infer<typeof ModuleErrorSchema>;
|
package/src/cbor/cose/index.ts
CHANGED
package/src/cbor/cose/sign.ts
CHANGED
|
@@ -4,19 +4,20 @@ import { IoReactNativeCbor } from '..';
|
|
|
4
4
|
/**
|
|
5
5
|
* Sign base64 encoded data with COSE and return the COSE-Sign1 object in base64 encoding
|
|
6
6
|
*
|
|
7
|
-
* @param
|
|
7
|
+
* @param data - The base64 or base64url encoded payload to sign
|
|
8
8
|
* @param keyTag - The alias of the key to use for signing.
|
|
9
|
-
* @throws {
|
|
9
|
+
* @throws {ModuleError} in case of failure which can be parsed with {@link ModuleErrorSchema}
|
|
10
10
|
* @returns The COSE-Sign1 object in base64 encoding
|
|
11
11
|
*/
|
|
12
|
-
export const sign = async (
|
|
13
|
-
await IoReactNativeCbor.sign(
|
|
12
|
+
export const sign = async (data: string, keyTag: string): Promise<string> =>
|
|
13
|
+
await IoReactNativeCbor.sign(data, keyTag);
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
16
|
* Verifies a COSE-Sign1 object with the provided public key
|
|
17
17
|
*
|
|
18
18
|
* @param data - The COSE-Sign1 object in base64 or base64url encoding
|
|
19
19
|
* @param publicKey - The public key in JWK format
|
|
20
|
+
* @throws {ModuleError} in case of failure which can be parsed with {@link ModuleErrorSchema}
|
|
20
21
|
* @returns true if the signature is valid, false otherwise
|
|
21
22
|
*/
|
|
22
23
|
export const verify = async (
|
package/src/iso18013/index.ts
CHANGED
|
@@ -1,11 +1,4 @@
|
|
|
1
1
|
import { NativeModules, Platform } from 'react-native';
|
|
2
|
-
export {
|
|
3
|
-
type AcceptedFields,
|
|
4
|
-
type EventError,
|
|
5
|
-
type VerifierRequest,
|
|
6
|
-
parseEventError,
|
|
7
|
-
parseVerifierRequest,
|
|
8
|
-
} from './iso18013-5/schema';
|
|
9
2
|
|
|
10
3
|
const LINKING_ERROR =
|
|
11
4
|
`The package '@pagopa/io-react-native-iso18013' (IoReactNativeIso18013) doesn't seem to be linked. Make sure: \n\n` +
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
# ISO18013-5
|
|
2
2
|
|
|
3
|
-
This library provides a React Native module based on [iso18013-android](https://github.com/pagopa/iso18013-android) and [iso18013-ios](https://github.com/pagopa/iso18013-ios) which allows mDL proximity presentation according to the
|
|
4
|
-
ISO 18013-5 standard and remote presentation according to the ISO 18013-7 standard.
|
|
3
|
+
This library provides a React Native module based on [iso18013-android](https://github.com/pagopa/iso18013-android) and [iso18013-ios](https://github.com/pagopa/iso18013-ios) which allows mDL proximity presentation according to the ISO 18013-5 standard.
|
|
5
4
|
|
|
6
5
|
## Installation
|
|
7
6
|
|
|
8
|
-
|
|
7
|
+
```
|
|
8
|
+
yarn add @pagopa/io-react-native-iso18013
|
|
9
|
+
cd ios && bundle exec pod install && cd ..
|
|
10
|
+
```
|
|
9
11
|
|
|
10
|
-
|
|
12
|
+
## Events
|
|
11
13
|
|
|
12
14
|
This library emits the following events:
|
|
13
15
|
| Event | Payload | Description |
|
|
@@ -15,17 +17,39 @@ This library emits the following events:
|
|
|
15
17
|
| onDeviceConnecting (iOS only) | `undefined` | Event dispatched when the verifier app is connecting |
|
|
16
18
|
| onDeviceConnected | `undefined` | Event dispatched when the verifier app is connected. |
|
|
17
19
|
| onDocumentRequestReceived | `{ data: string } \| undefined` | Event dispatched when the consumer app receives a new request, contained in the data payload. It can be parsed via the `parseVerifierRequest` provided [here](src/schema.ts). |
|
|
18
|
-
| onDeviceDisconnected | `undefined` | Event dispatched when the verifier app disconnects. |
|
|
20
|
+
| onDeviceDisconnected | `undefined` | Event dispatched when the verifier app disconnects by sending the END (0x02) flag. |
|
|
19
21
|
| onError | `{ error: string } \| undefined` | Event dispatched when an error occurs which is contained in the error payload. It can be parsed via the `parseError` provided [here](src/schema.ts). |
|
|
20
22
|
|
|
21
|
-
|
|
23
|
+
The events flow is described in the following diagram:
|
|
24
|
+
|
|
25
|
+
```mermaid
|
|
26
|
+
flowchart LR
|
|
27
|
+
onDeviceConnecting["onDeviceConnecting *(iOS only)*"]
|
|
28
|
+
onDeviceConnected["onDeviceConnected"]
|
|
29
|
+
onDocumentRequestReceived["onDocumentRequestReceived"]
|
|
30
|
+
onDeviceDisconnected["onDeviceDisconnected"]
|
|
31
|
+
onError["onError"]
|
|
32
|
+
|
|
33
|
+
onDeviceConnecting -- "Verifier app connects" --> onDeviceConnected
|
|
34
|
+
|
|
35
|
+
onDeviceConnected -- "Verifier app sends request" --> onDocumentRequestReceived
|
|
36
|
+
onDeviceConnected -- "Verifier sends END (0x02)" --> onDeviceDisconnected
|
|
37
|
+
onDeviceConnected -- "Error status or abrupt disconnection" --> onError
|
|
38
|
+
|
|
39
|
+
onDocumentRequestReceived -- "Verifier sends END (0x02)" --> onDeviceDisconnected
|
|
40
|
+
onDocumentRequestReceived -- "Error status or abrupt disconnection" --> onError
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Listeners can be added using the `addListener` method and removed by using the returned reference by calling the `remove` method.
|
|
22
44
|
|
|
23
45
|
```typescript
|
|
24
46
|
import { ISO18013_5 } from '@pagopa/io-react-native-iso18013';
|
|
25
47
|
|
|
26
|
-
ISO18013_5.addListener('event', () =>
|
|
48
|
+
const listener = ISO18013_5.addListener('event', () =>
|
|
49
|
+
console.log('event occurred')
|
|
50
|
+
);
|
|
27
51
|
|
|
28
|
-
|
|
52
|
+
listener.remove();
|
|
29
53
|
```
|
|
30
54
|
|
|
31
55
|
#### `onDeviceConnecting`
|
|
@@ -105,7 +129,9 @@ ISO18013_5.addListener(
|
|
|
105
129
|
);
|
|
106
130
|
```
|
|
107
131
|
|
|
108
|
-
|
|
132
|
+
## Methods
|
|
133
|
+
|
|
134
|
+
#### `start`
|
|
109
135
|
|
|
110
136
|
Starts the proximity flow and starts the bluetooth service. This method also accepts optional parameters to configure the initialization on Android, along with the possibility
|
|
111
137
|
to specify a certificates of array to verify the reader app.
|
|
@@ -116,7 +142,7 @@ import { ISO18013_5 } from '@pagopa/io-react-native-iso18013';
|
|
|
116
142
|
await ISO18013_5.start();
|
|
117
143
|
```
|
|
118
144
|
|
|
119
|
-
|
|
145
|
+
#### `getQrCodeString`
|
|
120
146
|
|
|
121
147
|
Returns the QR code string which contains a base64url encoded CBOR object which encodes the bluetooth engagement data.
|
|
122
148
|
It can be used to display the QR code in the UI which will be scanned by the verifier app.
|
|
@@ -128,25 +154,37 @@ const qrCodeString = await ISO18013_5.getQrCodeString();
|
|
|
128
154
|
console.log(qrCodeString);
|
|
129
155
|
```
|
|
130
156
|
|
|
131
|
-
|
|
157
|
+
#### `generateResponse`
|
|
132
158
|
|
|
133
159
|
Generates a response that will be sent to the verifier app containing the requested documents.
|
|
134
160
|
|
|
135
161
|
```typescript
|
|
136
162
|
import { ISO18013_5 } from '@pagopa/io-react-native-iso18013';
|
|
137
163
|
|
|
138
|
-
const
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
164
|
+
const documents = [
|
|
165
|
+
{
|
|
166
|
+
issuerSignedContent: 'base64url-or-base64-encoded-content',
|
|
167
|
+
alias: 'key-alias',
|
|
168
|
+
docType: 'docType',
|
|
169
|
+
},
|
|
170
|
+
];
|
|
171
|
+
|
|
172
|
+
const acceptedFields = {
|
|
173
|
+
'org.iso.18013.5.1.mDL': {
|
|
174
|
+
'org.iso.18013.5.1': {
|
|
175
|
+
hair_colour: true,
|
|
176
|
+
given_name_national_character: true,
|
|
177
|
+
family_name_national_character: true,
|
|
178
|
+
given_name: true,
|
|
143
179
|
},
|
|
144
|
-
|
|
145
|
-
}
|
|
180
|
+
},
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
const response = await ISO18013_5.generateResponse(documents, acceptedFields);
|
|
146
184
|
console.log(response);
|
|
147
185
|
```
|
|
148
186
|
|
|
149
|
-
|
|
187
|
+
#### `sendResponse`
|
|
150
188
|
|
|
151
189
|
Sends the response generate by `generateResponse` to the verifier app.
|
|
152
190
|
|
|
@@ -156,24 +194,21 @@ import { ISO18013_5 } from '@pagopa/io-react-native-iso18013';
|
|
|
156
194
|
await ISO18013_5.sendResponse(response);
|
|
157
195
|
```
|
|
158
196
|
|
|
159
|
-
|
|
197
|
+
#### `sendErrorResponse`
|
|
160
198
|
|
|
161
199
|
Sends an error response to the verifier app. The supported error codes are defined in the Table 20 of the ISO 18013-5 standard and are coded in the `ErrorCode` enum.
|
|
162
200
|
|
|
163
201
|
```typescript
|
|
164
202
|
import { ISO18013_5, ErrorCode } from '@pagopa/io-react-native-iso18013';
|
|
165
203
|
|
|
166
|
-
await ISO18013_5.sendErrorResponse(
|
|
167
|
-
errorCode: ErrorCode.SESSION_ENCRYPTION,
|
|
168
|
-
errorMessage: 'An error occurred while encrypting the session',
|
|
169
|
-
});
|
|
204
|
+
await ISO18013_5.sendErrorResponse(ErrorCode.SESSION_ENCRYPTION);
|
|
170
205
|
```
|
|
171
206
|
|
|
172
|
-
|
|
207
|
+
#### `close`
|
|
173
208
|
|
|
174
209
|
Closes the QR engagement by releasing the resources allocated during the `start` method.
|
|
175
210
|
Before starting a new flow, it is necessary to call this method to ensure that the previous flow is properly closed.
|
|
176
|
-
|
|
211
|
+
Listeners can be added using the `addListener` method and removed using the `removeListener` method.
|
|
177
212
|
|
|
178
213
|
```typescript
|
|
179
214
|
import { ISO18013_5 } from '@pagopa/io-react-native-iso18013';
|
|
@@ -181,9 +216,9 @@ import { ISO18013_5 } from '@pagopa/io-react-native-iso18013';
|
|
|
181
216
|
await ISO18013_5.close();
|
|
182
217
|
```
|
|
183
218
|
|
|
184
|
-
## Proximity
|
|
219
|
+
## Proximity Sequence Diagram
|
|
185
220
|
|
|
186
|
-
This section describes a high level overview of the interactions between an app implementing the `io-react-native-proximity` library and a verifier app.
|
|
221
|
+
This section describes a high level overview of the happy flow interactions between an app implementing the `io-react-native-proximity` library and a verifier app.
|
|
187
222
|
|
|
188
223
|
```mermaid
|
|
189
224
|
sequenceDiagram
|
|
@@ -216,19 +251,60 @@ sequenceDiagram
|
|
|
216
251
|
proximity->>+verifier: Sends the error response code
|
|
217
252
|
verifier->>+verifier: Shows the received error response code
|
|
218
253
|
end
|
|
219
|
-
verifier
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
|
254
|
+
alt The verifier sends the END (0x02) termination flag
|
|
255
|
+
verifier->>+app: Closes the connection
|
|
256
|
+
proximity->>+app: Calls the onDeviceDisconnected callback
|
|
257
|
+
app->>+proximity: Calls close()
|
|
258
|
+
else The verifier app closes the connection without the END (0x02) termination flag
|
|
259
|
+
verifier->>+app: Closes the connection
|
|
260
|
+
proximity->>+app: Calls the onError callback
|
|
261
|
+
app->>+proximity: Calls close()
|
|
262
|
+
end
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
## Errors
|
|
266
|
+
|
|
267
|
+
This table contains the list of error codes that can be thrown by the `ISO18013_5` module which are mapped via the `ModuleErrorCodes` type:
|
|
268
|
+
|
|
269
|
+
| Type | Platform | Description |
|
|
270
|
+
| ------------------------- | ----------- | ---------------------------------------------------------------------------- |
|
|
271
|
+
| DRH_NOT_DEFINED | Android | The device retrieval helper hasn't been initialized, call the `start` method |
|
|
272
|
+
| QR_ENGAGEMENT_NOT_DEFINED | Android | The QR engagement hasn't been initialized, call the `start` method |
|
|
273
|
+
| START_ERROR | Android/iOS | An error occurred while initializing the required resources |
|
|
274
|
+
| GET_QR_CODE_ERROR | Android/iOS | An error occurred while generating the engagement QR code |
|
|
275
|
+
| SEND_RESPONSE_ERROR | Android/iOS | An error occurred while sending the response for the verifier app |
|
|
276
|
+
| SEND_ERROR_RESPONSE_ERROR | Android/iOS | An error occurred while sending the error response to the verifier app |
|
|
277
|
+
| GENERATE_RESPONSE_ERROR | Android/iOS | An error occurred while generating the response for the verifier app |
|
|
278
|
+
| CLOSE_ERROR | Android | An error occured while closing the required resources |
|
|
279
|
+
| EUNSPECIFIED | Android | Default error when no other error is specified |
|
|
280
|
+
|
|
281
|
+
An error can be parsed using the `ModuleErrorSchema` with type `ModuleErrorCodes` exposed by the `ISO18013_5` module. The error can be parsed as follows:
|
|
282
|
+
|
|
283
|
+
```typescript
|
|
284
|
+
import { ISO18013_5 } from '@pagopa/io-react-native-iso18013';
|
|
285
|
+
try {
|
|
286
|
+
await ISO18013_5.func();
|
|
287
|
+
} catch (error) {
|
|
288
|
+
const parsedError = ISO18013_5.ModuleErrorSchema.parse(error); // Or ModuleErrorSchema.safeParse(error) for safe parsing
|
|
289
|
+
console.log(JSON.stringify(parsedError, null, 2));
|
|
290
|
+
}
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
The parsed object will contain properties from both iOS and Android platforms:
|
|
294
|
+
|
|
295
|
+
```typescript
|
|
296
|
+
{
|
|
297
|
+
code: string; // Defined in ModuleErrorCodes
|
|
298
|
+
message: string;
|
|
299
|
+
name: string;
|
|
300
|
+
userInfo?: Record<string, any> | null;
|
|
301
|
+
nativeStackAndroid?: Array<{
|
|
302
|
+
lineNumber: number;
|
|
303
|
+
file: string;
|
|
304
|
+
methodName: string;
|
|
305
|
+
class: string;
|
|
306
|
+
}>;
|
|
307
|
+
domain?: string;
|
|
308
|
+
nativeStackIOS?: Array<string>;
|
|
309
|
+
};
|
|
310
|
+
```
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import z from 'zod';
|
|
2
|
+
import { GenericModuleErrorSchema } from '../../schema';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Schema for parsing the payload returned by the `onError` event in Proximity `Events`, along with its type definition.
|
|
6
|
+
*/
|
|
7
|
+
export const OnErrorPayloadSchema = z.string().catch('Unknown error');
|
|
8
|
+
|
|
9
|
+
export type OnErrorPayload = z.infer<typeof OnErrorPayloadSchema>;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Error codes which the ISO18013_5 module uses to reject a promise.
|
|
13
|
+
*/
|
|
14
|
+
const ModuleErrorCodesSchema = z.enum([
|
|
15
|
+
'DRH_NOT_DEFINED', // Android only
|
|
16
|
+
'QR_ENGAGEMENT_NOT_DEFINED', // Android only
|
|
17
|
+
'START_ERROR',
|
|
18
|
+
'GET_QR_CODE_ERROR',
|
|
19
|
+
'SEND_RESPONSE_ERROR',
|
|
20
|
+
'SEND_ERROR_RESPONSE_ERROR',
|
|
21
|
+
'GENERATE_RESPONSE_ERROR',
|
|
22
|
+
'CLOSE_ERROR', // Android only
|
|
23
|
+
'EUNSPECIFIED', // Android only default when no other error is specified
|
|
24
|
+
]);
|
|
25
|
+
|
|
26
|
+
export type ModuleErrorCodes = z.infer<typeof ModuleErrorCodesSchema>;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Schema which can be used to parse a rejected promise error by the ISO18013_5 module.
|
|
30
|
+
*/
|
|
31
|
+
export const ModuleErrorSchema = GenericModuleErrorSchema(
|
|
32
|
+
ModuleErrorCodesSchema
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
export type ModuleError = z.infer<typeof ModuleErrorSchema>;
|