@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
|
@@ -0,0 +1,508 @@
|
|
|
1
|
+
package com.ioreactnativeiso18013
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.bridge.JavaOnlyArray
|
|
4
|
+
import com.facebook.react.bridge.JavaOnlyMap
|
|
5
|
+
import it.pagopa.io.wallet.proximity.request.DocRequested
|
|
6
|
+
import java.util.UUID
|
|
7
|
+
import kotlin.io.encoding.Base64
|
|
8
|
+
import kotlin.io.encoding.ExperimentalEncodingApi
|
|
9
|
+
import kotlin.random.Random
|
|
10
|
+
import org.junit.Assert.assertThrows
|
|
11
|
+
import org.junit.Test
|
|
12
|
+
import kotlin.collections.emptyList
|
|
13
|
+
|
|
14
|
+
class IoReactNativeIso18013Test {
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Checks if two parsed certificates lists are equal.
|
|
18
|
+
* This is required because ByteArray are compared by reference.
|
|
19
|
+
* @param a - The first list to be compared
|
|
20
|
+
* @param b - The second list to be compared
|
|
21
|
+
* @returns true if they are equal, false otherwise
|
|
22
|
+
*/
|
|
23
|
+
private fun areCertificatesListsEqual(
|
|
24
|
+
a: List<List<ByteArray>>,
|
|
25
|
+
b: List<List<ByteArray>>
|
|
26
|
+
): Boolean {
|
|
27
|
+
if (a.size != b.size) return false
|
|
28
|
+
return a.indices.all { i ->
|
|
29
|
+
val innerA = a[i]
|
|
30
|
+
val innerB = b[i]
|
|
31
|
+
if (innerA.size != innerB.size) return false
|
|
32
|
+
innerA.indices.all { j ->
|
|
33
|
+
innerA[j].contentEquals(innerB[j])
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Checks if two array of documents equal.
|
|
40
|
+
* TThis is needed because DocRequest contains a ByteArray which is compared by reference
|
|
41
|
+
* @param a - The first array to be compared
|
|
42
|
+
* @param b - The second array to be compared
|
|
43
|
+
* @returns true if they are equal, false otherwise
|
|
44
|
+
*/
|
|
45
|
+
private fun areDocumentsArrayEqual(
|
|
46
|
+
a: Array<DocRequested>,
|
|
47
|
+
b: Array<DocRequested>
|
|
48
|
+
): Boolean {
|
|
49
|
+
if (a.size != b.size) return false
|
|
50
|
+
return a.indices.all { i ->
|
|
51
|
+
val innerA = a[i]
|
|
52
|
+
val innerB = b[i]
|
|
53
|
+
innerA.alias == innerB.alias &&
|
|
54
|
+
innerA.docType == innerB.docType &&
|
|
55
|
+
innerA.issuerSignedContent.contentEquals(innerB.issuerSignedContent)
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Tests for parseCertificates
|
|
61
|
+
*/
|
|
62
|
+
|
|
63
|
+
@Test
|
|
64
|
+
fun `should parse multiple certificates from the bridge with an empty inner array into a 2 dimensional byte array`() {
|
|
65
|
+
val certificatesBase64 = listOf(
|
|
66
|
+
JavaOnlyArray.from(listOf("dGVzdA==", "dGVzdDEyMw==", "cmFuZG9tU3RyaW5nMTIz")),
|
|
67
|
+
JavaOnlyArray(),
|
|
68
|
+
)
|
|
69
|
+
val certificatesByteArray = listOf(
|
|
70
|
+
listOf(
|
|
71
|
+
byteArrayOf(116, 101, 115, 116),
|
|
72
|
+
byteArrayOf(116, 101, 115, 116, 49, 50, 51),
|
|
73
|
+
byteArrayOf(114, 97, 110, 100, 111, 109, 83, 116, 114, 105, 110, 103, 49, 50, 51)
|
|
74
|
+
),
|
|
75
|
+
emptyList<ByteArray>()
|
|
76
|
+
)
|
|
77
|
+
val nativeArray = JavaOnlyArray.from(certificatesBase64)
|
|
78
|
+
val parsedCertificates = IoReactNativeIso18013Module.parseCertificates(nativeArray)
|
|
79
|
+
print(parsedCertificates.toString())
|
|
80
|
+
assert(areCertificatesListsEqual(certificatesByteArray, parsedCertificates))
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
@Test
|
|
84
|
+
fun `should parse multiple certificates from the bridge into a 2 dimensional byte array`() {
|
|
85
|
+
val certificatesBase64 = listOf(
|
|
86
|
+
JavaOnlyArray.from(listOf("dGVzdA==", "dGVzdDEyMw==", "cmFuZG9tU3RyaW5nMTIz")),
|
|
87
|
+
JavaOnlyArray.from(listOf("aWVybnF3aWRuczEyNA==", "MTIzeHhxcWVy")),
|
|
88
|
+
)
|
|
89
|
+
val certificatesByteArray = listOf(
|
|
90
|
+
listOf(
|
|
91
|
+
byteArrayOf(116, 101, 115, 116),
|
|
92
|
+
byteArrayOf(116, 101, 115, 116, 49, 50, 51),
|
|
93
|
+
byteArrayOf(114, 97, 110, 100, 111, 109, 83, 116, 114, 105, 110, 103, 49, 50, 51)
|
|
94
|
+
),
|
|
95
|
+
listOf(
|
|
96
|
+
byteArrayOf(105, 101, 114, 110, 113, 119, 105, 100, 110, 115, 49, 50, 52),
|
|
97
|
+
byteArrayOf(49, 50, 51, 120, 120, 113, 113, 101, 114)
|
|
98
|
+
)
|
|
99
|
+
)
|
|
100
|
+
val nativeArray = JavaOnlyArray.from(certificatesBase64)
|
|
101
|
+
val parsedCertificates = IoReactNativeIso18013Module.parseCertificates(nativeArray)
|
|
102
|
+
assert(areCertificatesListsEqual(certificatesByteArray, parsedCertificates))
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
@Test
|
|
106
|
+
fun `should parse a single certificates array from the bridge into a 2 dimensional byte array`() {
|
|
107
|
+
val certificatesBase64 = listOf(
|
|
108
|
+
JavaOnlyArray.from(listOf("dGVzdA==")),
|
|
109
|
+
)
|
|
110
|
+
val certificatesByteArray = listOf(listOf(byteArrayOf(116, 101, 115, 116)))
|
|
111
|
+
val nativeArray = JavaOnlyArray.from(certificatesBase64)
|
|
112
|
+
val parsedCertificates = IoReactNativeIso18013Module.parseCertificates(nativeArray)
|
|
113
|
+
assert(areCertificatesListsEqual(certificatesByteArray, parsedCertificates))
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
@Test
|
|
118
|
+
fun `should return an empty list if the array of certificates is empty`() {
|
|
119
|
+
val nativeArray = JavaOnlyArray()
|
|
120
|
+
val parsedCertificates = IoReactNativeIso18013Module.parseCertificates(nativeArray)
|
|
121
|
+
assert(parsedCertificates.isEmpty())
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
@Test
|
|
125
|
+
fun `should throw an IllegalArgumentException if the provided certificate is not a valid base64 string`() {
|
|
126
|
+
val certificatesBase64 = listOf(
|
|
127
|
+
JavaOnlyArray.from(listOf("123~")),
|
|
128
|
+
)
|
|
129
|
+
val nativeArray = JavaOnlyArray.from(certificatesBase64)
|
|
130
|
+
assertThrows(
|
|
131
|
+
IllegalArgumentException::class.java
|
|
132
|
+
) {
|
|
133
|
+
IoReactNativeIso18013Module.parseCertificates(nativeArray)
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
@Test
|
|
138
|
+
fun `should throw an IllegalArgumentException if the provided certificate is not a string`() {
|
|
139
|
+
val certificatesBase64 = listOf(
|
|
140
|
+
JavaOnlyArray.from(listOf("dGVzdA==", 123)),
|
|
141
|
+
)
|
|
142
|
+
val nativeArray = JavaOnlyArray.from(certificatesBase64)
|
|
143
|
+
assertThrows(
|
|
144
|
+
IllegalArgumentException::class.java
|
|
145
|
+
) {
|
|
146
|
+
IoReactNativeIso18013Module.parseCertificates(nativeArray)
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
@Test
|
|
151
|
+
fun `should throw an IllegalArgumentException if an array of array of certificates is not provided`() {
|
|
152
|
+
val nativeArray = JavaOnlyArray.from("dGVzdA==".toList())
|
|
153
|
+
assertThrows(
|
|
154
|
+
IllegalArgumentException::class.java
|
|
155
|
+
) {
|
|
156
|
+
IoReactNativeIso18013Module.parseCertificates(nativeArray)
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Tests for parseDocRequested
|
|
162
|
+
*/
|
|
163
|
+
|
|
164
|
+
@OptIn(ExperimentalEncodingApi::class)
|
|
165
|
+
@Test
|
|
166
|
+
fun `should parse a valid set of documents with issuerSignedContent as base64`() {
|
|
167
|
+
val randomDocs = List(2) {
|
|
168
|
+
val randomBytes = ByteArray(10).apply { Random.nextBytes(this) }
|
|
169
|
+
val alias = UUID.randomUUID().toString()
|
|
170
|
+
val docType = UUID.randomUUID().toString()
|
|
171
|
+
DocRequested(randomBytes, alias, docType)
|
|
172
|
+
}
|
|
173
|
+
val nativeArray = JavaOnlyArray.from(
|
|
174
|
+
randomDocs.map { doc ->
|
|
175
|
+
JavaOnlyMap.of(
|
|
176
|
+
"alias", doc.alias,
|
|
177
|
+
"docType", doc.docType,
|
|
178
|
+
"issuerSignedContent", Base64.encode(doc.issuerSignedContent)
|
|
179
|
+
)
|
|
180
|
+
}
|
|
181
|
+
)
|
|
182
|
+
val result = IoReactNativeIso18013Module.parseDocRequested(nativeArray)
|
|
183
|
+
assert(areDocumentsArrayEqual(result, randomDocs.toTypedArray()))
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
@OptIn(ExperimentalEncodingApi::class)
|
|
187
|
+
@Test
|
|
188
|
+
fun `should parse a valid set of documents with issuerSignedContent as base64url`() {
|
|
189
|
+
val randomDocs = List(2) {
|
|
190
|
+
val randomBytes = ByteArray(10).apply { Random.nextBytes(this) }
|
|
191
|
+
val alias = UUID.randomUUID().toString()
|
|
192
|
+
val docType = UUID.randomUUID().toString()
|
|
193
|
+
DocRequested(randomBytes, alias, docType)
|
|
194
|
+
}
|
|
195
|
+
val nativeArray = JavaOnlyArray.from(
|
|
196
|
+
randomDocs.map { doc ->
|
|
197
|
+
JavaOnlyMap.of(
|
|
198
|
+
"alias", doc.alias,
|
|
199
|
+
"docType", doc.docType,
|
|
200
|
+
"issuerSignedContent", Base64.UrlSafe.encode(doc.issuerSignedContent)
|
|
201
|
+
)
|
|
202
|
+
}
|
|
203
|
+
)
|
|
204
|
+
val result = IoReactNativeIso18013Module.parseDocRequested(nativeArray)
|
|
205
|
+
assert(areDocumentsArrayEqual(result, randomDocs.toTypedArray()))
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
@Test
|
|
209
|
+
fun `should parse an empty set of documents`() {
|
|
210
|
+
val nativeArray = JavaOnlyArray()
|
|
211
|
+
val result = IoReactNativeIso18013Module.parseDocRequested(nativeArray)
|
|
212
|
+
assert(result.isEmpty())
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
@Test
|
|
216
|
+
fun `should throw an IllegalArgumentException if the document is missing the issuerSignedContent field`() {
|
|
217
|
+
val nativeArray = JavaOnlyArray.from(
|
|
218
|
+
listOf(
|
|
219
|
+
JavaOnlyMap.of("alias", "test", "docType", "test", "somethingElse", "test")
|
|
220
|
+
)
|
|
221
|
+
)
|
|
222
|
+
assertThrows(
|
|
223
|
+
IllegalArgumentException::class.java
|
|
224
|
+
) {
|
|
225
|
+
IoReactNativeIso18013Module.parseDocRequested(nativeArray)
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
@Test
|
|
230
|
+
fun `should throw an IllegalArgumentException if the document issuerSignedContent field is null`() {
|
|
231
|
+
val nativeArray = JavaOnlyArray.from(
|
|
232
|
+
listOf(
|
|
233
|
+
JavaOnlyMap.of("alias", "test", "docType", "test", "issuerSignedContent", null)
|
|
234
|
+
)
|
|
235
|
+
)
|
|
236
|
+
assertThrows(
|
|
237
|
+
IllegalArgumentException::class.java
|
|
238
|
+
) {
|
|
239
|
+
IoReactNativeIso18013Module.parseDocRequested(nativeArray)
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
@Test
|
|
244
|
+
fun `should throw an IllegalArgumentException if the document issuerSignedContent field is not a string`() {
|
|
245
|
+
val nativeArray = JavaOnlyArray.from(
|
|
246
|
+
listOf(
|
|
247
|
+
JavaOnlyMap.of("alias", "test", "docType", "test", "issuerSignedContent", 123)
|
|
248
|
+
)
|
|
249
|
+
)
|
|
250
|
+
assertThrows(
|
|
251
|
+
IllegalArgumentException::class.java
|
|
252
|
+
) {
|
|
253
|
+
IoReactNativeIso18013Module.parseDocRequested(nativeArray)
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
@Test
|
|
258
|
+
fun `should throw an IllegalArgumentException if the document issuerSignedContent is not a valid base64 or base64url string`() {
|
|
259
|
+
val nativeArray = JavaOnlyArray.from(
|
|
260
|
+
listOf(
|
|
261
|
+
JavaOnlyMap.of(
|
|
262
|
+
"alias", "test", "docType", "test", "issuerSignedContent", "123~"
|
|
263
|
+
)
|
|
264
|
+
)
|
|
265
|
+
)
|
|
266
|
+
assertThrows(
|
|
267
|
+
IllegalArgumentException::class.java
|
|
268
|
+
) {
|
|
269
|
+
IoReactNativeIso18013Module.parseDocRequested(nativeArray)
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
@Test
|
|
274
|
+
fun `should throw an IllegalArgumentException if the document is missing the alias field`() {
|
|
275
|
+
val nativeArray = JavaOnlyArray.from(
|
|
276
|
+
listOf(
|
|
277
|
+
JavaOnlyMap.of(
|
|
278
|
+
"somethingElse", "test", "docType", "test", "issuerSignedContent", "test"
|
|
279
|
+
)
|
|
280
|
+
)
|
|
281
|
+
)
|
|
282
|
+
assertThrows(
|
|
283
|
+
IllegalArgumentException::class.java
|
|
284
|
+
) {
|
|
285
|
+
IoReactNativeIso18013Module.parseDocRequested(nativeArray)
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
@Test
|
|
290
|
+
fun `should throw an IllegalArgumentException if the document alias field is null`() {
|
|
291
|
+
val nativeArray = JavaOnlyArray.from(
|
|
292
|
+
listOf(
|
|
293
|
+
JavaOnlyMap.of(
|
|
294
|
+
"alias", null, "docType", "test", "issuerSignedContent", "test"
|
|
295
|
+
)
|
|
296
|
+
)
|
|
297
|
+
)
|
|
298
|
+
assertThrows(
|
|
299
|
+
IllegalArgumentException::class.java
|
|
300
|
+
) {
|
|
301
|
+
IoReactNativeIso18013Module.parseDocRequested(nativeArray)
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
@Test
|
|
306
|
+
fun `should throw an IllegalArgumentException if the document alias field not a string`() {
|
|
307
|
+
val nativeArray = JavaOnlyArray.from(
|
|
308
|
+
listOf(
|
|
309
|
+
JavaOnlyMap.of(
|
|
310
|
+
"alias", 123, "docType", "test", "issuerSignedContent", "test"
|
|
311
|
+
)
|
|
312
|
+
)
|
|
313
|
+
)
|
|
314
|
+
assertThrows(
|
|
315
|
+
IllegalArgumentException::class.java
|
|
316
|
+
) {
|
|
317
|
+
IoReactNativeIso18013Module.parseDocRequested(nativeArray)
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
@Test
|
|
322
|
+
fun `should throw an IllegalArgumentException if the document is missing the docType field`() {
|
|
323
|
+
val nativeArray = JavaOnlyArray.from(
|
|
324
|
+
listOf(
|
|
325
|
+
JavaOnlyMap.of(
|
|
326
|
+
"alias", "test", "somethingElse", "test", "issuerSignedContent", "test"
|
|
327
|
+
)
|
|
328
|
+
)
|
|
329
|
+
)
|
|
330
|
+
assertThrows(
|
|
331
|
+
IllegalArgumentException::class.java
|
|
332
|
+
) {
|
|
333
|
+
IoReactNativeIso18013Module.parseDocRequested(nativeArray)
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
@Test
|
|
338
|
+
fun `should throw an IllegalArgumentException if the document docType field is null`() {
|
|
339
|
+
val nativeArray = JavaOnlyArray.from(
|
|
340
|
+
listOf(
|
|
341
|
+
JavaOnlyMap.of(
|
|
342
|
+
"alias", "test", "docType", null, "issuerSignedContent", "test"
|
|
343
|
+
)
|
|
344
|
+
)
|
|
345
|
+
)
|
|
346
|
+
assertThrows(
|
|
347
|
+
IllegalArgumentException::class.java
|
|
348
|
+
) {
|
|
349
|
+
IoReactNativeIso18013Module.parseDocRequested(nativeArray)
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
@Test
|
|
354
|
+
fun `should throw an IllegalArgumentException if the document docType field is not a string`() {
|
|
355
|
+
val nativeArray = JavaOnlyArray.from(
|
|
356
|
+
listOf(
|
|
357
|
+
JavaOnlyMap.of(
|
|
358
|
+
"alias", "test", "docType", 123, "issuerSignedContent", "test"
|
|
359
|
+
)
|
|
360
|
+
)
|
|
361
|
+
)
|
|
362
|
+
assertThrows(
|
|
363
|
+
IllegalArgumentException::class.java
|
|
364
|
+
) {
|
|
365
|
+
IoReactNativeIso18013Module.parseDocRequested(nativeArray)
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
@Test
|
|
370
|
+
fun `should throw an IllegalArgumentException if the elements in the array are not map of documents`() {
|
|
371
|
+
val nativeArray = JavaOnlyArray.from(
|
|
372
|
+
listOf(123, 123)
|
|
373
|
+
)
|
|
374
|
+
assertThrows(
|
|
375
|
+
IllegalArgumentException::class.java
|
|
376
|
+
) {
|
|
377
|
+
IoReactNativeIso18013Module.parseDocRequested(nativeArray)
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
/**
|
|
382
|
+
* Tests for parseAcceptedFields
|
|
383
|
+
*/
|
|
384
|
+
|
|
385
|
+
@Test
|
|
386
|
+
fun `should parse a valid map of accepted fields`() {
|
|
387
|
+
val nativeMap = JavaOnlyMap.of(
|
|
388
|
+
"org.iso.18013.5.1.mDL",
|
|
389
|
+
JavaOnlyMap.of(
|
|
390
|
+
"org.iso.18013.5.1",
|
|
391
|
+
JavaOnlyMap.of(
|
|
392
|
+
"hair_colour",
|
|
393
|
+
true,
|
|
394
|
+
"given_name_national_character",
|
|
395
|
+
true,
|
|
396
|
+
"family_name_national_character",
|
|
397
|
+
false
|
|
398
|
+
),
|
|
399
|
+
"org.iso.18013.5.1_ext",
|
|
400
|
+
JavaOnlyMap.of(
|
|
401
|
+
"name", true, "surname", false
|
|
402
|
+
)
|
|
403
|
+
)
|
|
404
|
+
)
|
|
405
|
+
val result = IoReactNativeIso18013Module.parseAcceptedFields(nativeMap)
|
|
406
|
+
assert(result.contentEquals(nativeMap.toString()))
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
@Test
|
|
410
|
+
fun `should parse an empty map of accepted fields`() {
|
|
411
|
+
val nativeMap = JavaOnlyMap()
|
|
412
|
+
val result = IoReactNativeIso18013Module.parseAcceptedFields(nativeMap)
|
|
413
|
+
print(result)
|
|
414
|
+
assert(result == "{}")
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
@Test
|
|
418
|
+
fun `should throw an IllegalArgumentException if the credential type is not a map`() {
|
|
419
|
+
val nativeMap = JavaOnlyMap.of(
|
|
420
|
+
"org.iso.18013.5.1.mDL", 123
|
|
421
|
+
)
|
|
422
|
+
assertThrows(
|
|
423
|
+
IllegalArgumentException::class.java
|
|
424
|
+
) {
|
|
425
|
+
IoReactNativeIso18013Module.parseAcceptedFields(nativeMap)
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
@Test
|
|
430
|
+
fun `should throw an IllegalArgumentException if the namespace type is not a map`() {
|
|
431
|
+
val nativeMap = JavaOnlyMap.of(
|
|
432
|
+
"org.iso.18013.5.1.mDL",
|
|
433
|
+
JavaOnlyMap.of(
|
|
434
|
+
"org.iso.18013.5.1",
|
|
435
|
+
JavaOnlyMap.of(
|
|
436
|
+
"hair_colour",
|
|
437
|
+
true,
|
|
438
|
+
"given_name_national_character",
|
|
439
|
+
true,
|
|
440
|
+
"family_name_national_character",
|
|
441
|
+
false
|
|
442
|
+
),
|
|
443
|
+
"org.iso.18013.5.1_ext", 123
|
|
444
|
+
)
|
|
445
|
+
)
|
|
446
|
+
assertThrows(
|
|
447
|
+
IllegalArgumentException::class.java
|
|
448
|
+
) {
|
|
449
|
+
IoReactNativeIso18013Module.parseAcceptedFields(nativeMap)
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
@Test
|
|
454
|
+
fun `should throw an IllegalArgumentException if no namespace are provided for the credential`() {
|
|
455
|
+
val nativeMap = JavaOnlyMap.of(
|
|
456
|
+
"org.iso.18013.5.1.mDL",
|
|
457
|
+
JavaOnlyMap()
|
|
458
|
+
)
|
|
459
|
+
assertThrows(
|
|
460
|
+
IllegalArgumentException::class.java
|
|
461
|
+
) {
|
|
462
|
+
IoReactNativeIso18013Module.parseAcceptedFields(nativeMap)
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
@Test
|
|
467
|
+
fun `should throw an IllegalArgumentException if no fields are provided for the namespace`() {
|
|
468
|
+
val nativeMap = JavaOnlyMap.of(
|
|
469
|
+
"org.iso.18013.5.1.mDL",
|
|
470
|
+
JavaOnlyMap.of(
|
|
471
|
+
"org.iso.18013.5.1",
|
|
472
|
+
JavaOnlyMap()
|
|
473
|
+
)
|
|
474
|
+
)
|
|
475
|
+
assertThrows(
|
|
476
|
+
IllegalArgumentException::class.java
|
|
477
|
+
) {
|
|
478
|
+
IoReactNativeIso18013Module.parseAcceptedFields(nativeMap)
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
@Test
|
|
483
|
+
fun `should throw an IllegalArgumentException if the field type is not a boolean`() {
|
|
484
|
+
val nativeMap = JavaOnlyMap.of(
|
|
485
|
+
"org.iso.18013.5.1.mDL",
|
|
486
|
+
JavaOnlyMap.of(
|
|
487
|
+
"org.iso.18013.5.1",
|
|
488
|
+
JavaOnlyMap.of(
|
|
489
|
+
"hair_colour",
|
|
490
|
+
true,
|
|
491
|
+
"given_name_national_character",
|
|
492
|
+
true,
|
|
493
|
+
"family_name_national_character",
|
|
494
|
+
false
|
|
495
|
+
),
|
|
496
|
+
"org.iso.18013.5.1_ext",
|
|
497
|
+
JavaOnlyMap.of(
|
|
498
|
+
"name", true, "surname", 123
|
|
499
|
+
)
|
|
500
|
+
)
|
|
501
|
+
)
|
|
502
|
+
assertThrows(
|
|
503
|
+
IllegalArgumentException::class.java
|
|
504
|
+
) {
|
|
505
|
+
IoReactNativeIso18013Module.parseAcceptedFields(nativeMap)
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
}
|
package/ios/Base64Utils.swift
CHANGED
|
@@ -4,8 +4,15 @@ import Foundation
|
|
|
4
4
|
* This class contains a set of utilities for encoding and decoding base64 and base64url strings.
|
|
5
5
|
*/
|
|
6
6
|
class Base64Utils {
|
|
7
|
-
enum Base64DecodingError:
|
|
8
|
-
|
|
7
|
+
enum Base64DecodingError: LocalizedError {
|
|
8
|
+
case invalidBase64
|
|
9
|
+
|
|
10
|
+
var errorDescription: String? {
|
|
11
|
+
switch self {
|
|
12
|
+
case .invalidBase64:
|
|
13
|
+
return "Input is not a valid Base64 or Base64URL string"
|
|
14
|
+
}
|
|
15
|
+
}
|
|
9
16
|
}
|
|
10
17
|
|
|
11
18
|
/**
|
|
@@ -24,7 +31,7 @@ class Base64Utils {
|
|
|
24
31
|
} else if let data = Data(base64Encoded: base) {
|
|
25
32
|
return data
|
|
26
33
|
} else {
|
|
27
|
-
throw Base64DecodingError.invalidBase64
|
|
34
|
+
throw Base64DecodingError.invalidBase64
|
|
28
35
|
}
|
|
29
36
|
}
|
|
30
37
|
|
package/ios/IoReactNativeCbor.mm
CHANGED
|
@@ -2,27 +2,27 @@
|
|
|
2
2
|
|
|
3
3
|
@interface RCT_EXTERN_MODULE(IoReactNativeCbor, NSObject)
|
|
4
4
|
|
|
5
|
-
RCT_EXTERN_METHOD(decode: (NSString)
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
RCT_EXTERN_METHOD(decodeDocuments: (NSString)
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
RCT_EXTERN_METHOD(decodeIssuerSigned: (NSString)
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
RCT_EXTERN_METHOD(sign: (NSString)
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
RCT_EXTERN_METHOD(verify: (NSString)
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
5
|
+
RCT_EXTERN_METHOD(decode: (NSString *)data
|
|
6
|
+
withResolver: (RCTPromiseResolveBlock)resolve
|
|
7
|
+
withRejecter: (RCTPromiseRejectBlock)reject)
|
|
8
|
+
|
|
9
|
+
RCT_EXTERN_METHOD(decodeDocuments: (NSString *)data
|
|
10
|
+
withResolver: (RCTPromiseResolveBlock)resolve
|
|
11
|
+
withRejecter: (RCTPromiseRejectBlock)reject)
|
|
12
|
+
|
|
13
|
+
RCT_EXTERN_METHOD(decodeIssuerSigned: (NSString *)data
|
|
14
|
+
withResolver: (RCTPromiseResolveBlock)resolve
|
|
15
|
+
withRejecter: (RCTPromiseRejectBlock)reject)
|
|
16
|
+
|
|
17
|
+
RCT_EXTERN_METHOD(sign: (NSString *)data
|
|
18
|
+
withKeyTag: (NSString *)keyTag
|
|
19
|
+
withResolver: (RCTPromiseResolveBlock)resolve
|
|
20
|
+
withRejecter: (RCTPromiseRejectBlock)reject)
|
|
21
|
+
|
|
22
|
+
RCT_EXTERN_METHOD(verify: (NSString *)data
|
|
23
|
+
withJwk: (NSDictionary *)jwk
|
|
24
|
+
withResolver: (RCTPromiseResolveBlock)resolve
|
|
25
|
+
withRejecter: (RCTPromiseRejectBlock)reject)
|
|
26
26
|
|
|
27
27
|
+ (BOOL)requiresMainQueueSetup
|
|
28
28
|
{
|