@idos-network/credentials 1.5.0 → 2.2.2
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 +289 -85
- package/assets/idos-credential-subject-edd-v1.json +10 -0
- package/assets/idos-credential-subject-v1.json +1 -1
- package/assets/idos-credential-subject-v2.json +1 -1
- package/assets/idos-credential-subject-v3.json +83 -0
- package/assets/idos-credentials-v1.json +2 -2
- package/assets/idos-credentials-v2.json +10 -0
- package/dist/index-0NqXMjNk.d.mts +395 -0
- package/dist/index-0NqXMjNk.d.mts.map +1 -0
- package/dist/index-WW372Tf5.d.mts +57 -0
- package/dist/index-WW372Tf5.d.mts.map +1 -0
- package/dist/index.mjs +1 -1
- package/dist/loader-Cg6hs1-P.mjs +2 -0
- package/dist/loader-Cg6hs1-P.mjs.map +1 -0
- package/dist/parser/index.d.mts +19 -0
- package/dist/parser/index.d.mts.map +1 -0
- package/dist/parser/index.mjs +2 -0
- package/dist/parser/index.mjs.map +1 -0
- package/dist/schemas/index.d.mts +2 -0
- package/dist/schemas/index.mjs +1 -0
- package/dist/schemas-BVGuUlPe.mjs +2 -0
- package/dist/schemas-BVGuUlPe.mjs.map +1 -0
- package/dist/types/index.d.mts +2 -134
- package/dist/types/index.mjs +1 -63
- package/dist/utils/index.d.mts +37 -15
- package/dist/utils/index.d.mts.map +1 -1
- package/dist/utils/index.mjs +1 -116
- package/dist/utils/index.mjs.map +1 -1
- package/dist/verifier/index.d.mts +8 -0
- package/dist/verifier/index.d.mts.map +1 -0
- package/dist/verifier/index.mjs +2 -0
- package/dist/verifier/index.mjs.map +1 -0
- package/package.json +23 -10
- package/src/parser/index.test.ts +266 -0
- package/src/parser/index.ts +69 -0
- package/src/schemas/EddV1/index.test.ts +40 -0
- package/src/schemas/EddV1/index.ts +53 -0
- package/src/schemas/Envelope.ts +37 -0
- package/src/schemas/FaceIdV1/index.test.ts +26 -0
- package/src/schemas/FaceIdV1/index.ts +33 -0
- package/src/schemas/KycV1/IdDocument.ts +41 -0
- package/src/schemas/KycV1/ResidentialAddress.ts +56 -0
- package/src/schemas/KycV1/Subject.ts +86 -0
- package/src/schemas/KycV1/index.test.ts +156 -0
- package/src/schemas/KycV1/index.ts +40 -0
- package/src/schemas/KycV2/Subject.ts +67 -0
- package/src/schemas/KycV2/index.test.ts +162 -0
- package/src/schemas/KycV2/index.ts +45 -0
- package/src/schemas/KycV3/Biometric.ts +14 -0
- package/src/schemas/KycV3/Contact.ts +13 -0
- package/src/schemas/KycV3/EDD.ts +32 -0
- package/src/schemas/KycV3/IdDocument.ts +92 -0
- package/src/schemas/KycV3/Onboarding.ts +36 -0
- package/src/schemas/KycV3/Person.ts +105 -0
- package/src/schemas/KycV3/ResidentialAddress.ts +73 -0
- package/src/schemas/KycV3/Screening.ts +27 -0
- package/src/schemas/KycV3/SourceOfWealth.ts +44 -0
- package/src/schemas/KycV3/Subject.ts +54 -0
- package/src/schemas/KycV3/index.test.ts +682 -0
- package/src/schemas/KycV3/index.ts +108 -0
- package/src/schemas/VerifiableCredential.ts +232 -0
- package/src/schemas/enums.ts +126 -0
- package/src/schemas/index.ts +14 -0
- package/src/schemas/integration.test.ts +251 -0
- package/src/schemas/types.ts +11 -0
- package/src/schemas/utils.ts +274 -0
- package/src/types/credentials.ts +18 -249
- package/src/utils/{utils.test.ts → index.test.ts} +59 -67
- package/src/utils/index.ts +129 -134
- package/src/utils/issuer.ts +42 -0
- package/src/{builder → utils}/loader.ts +22 -17
- package/src/verifier/index.test.ts +149 -0
- package/src/{builder/verifier.ts → verifier/index.ts} +4 -8
- package/types/internals.d.ts +11 -6
- package/dist/builder/index.d.mts +0 -19
- package/dist/builder/index.d.mts.map +0 -1
- package/dist/builder/index.mjs +0 -619
- package/dist/builder/index.mjs.map +0 -1
- package/dist/types/index.d.mts.map +0 -1
- package/dist/types/index.mjs.map +0 -1
- package/src/builder/builder.test.ts +0 -407
- package/src/builder/index.ts +0 -122
package/src/types/credentials.ts
CHANGED
|
@@ -1,255 +1,33 @@
|
|
|
1
|
-
import * as z from "zod";
|
|
2
|
-
|
|
3
1
|
export type idOSCredential = {
|
|
4
2
|
id: string;
|
|
5
3
|
user_id: string;
|
|
6
4
|
public_notes: string;
|
|
7
|
-
|
|
5
|
+
content_uri: string;
|
|
6
|
+
content_size: number;
|
|
8
7
|
encryptor_public_key: string;
|
|
9
8
|
issuer_auth_public_key: string;
|
|
10
9
|
original_id?: string | null;
|
|
10
|
+
inserter_type?: string | null;
|
|
11
|
+
inserter_id?: string | null;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export type idOSCredentialRecord = Omit<idOSCredential, "content_uri" | "content_size"> & {
|
|
15
|
+
content: string | null;
|
|
16
|
+
content_uri?: string | null;
|
|
17
|
+
content_size?: number | null;
|
|
11
18
|
};
|
|
12
19
|
|
|
13
|
-
export type
|
|
14
|
-
|
|
15
|
-
content_hash?: string;
|
|
20
|
+
export type SignedCredentialContentReference = {
|
|
21
|
+
public_notes: string;
|
|
16
22
|
public_notes_signature: string;
|
|
17
23
|
broader_signature: string;
|
|
24
|
+
issuer_auth_public_key: string;
|
|
18
25
|
};
|
|
19
26
|
|
|
20
|
-
// https://github.com/colinhacks/zod/issues/3751
|
|
21
|
-
export const CredentialFieldsSchema: z.ZodObject<{
|
|
22
|
-
id: z.ZodString;
|
|
23
|
-
level: z.ZodString;
|
|
24
|
-
issued: z.ZodOptional<z.ZodDate>;
|
|
25
|
-
approvedAt: z.ZodOptional<z.ZodDate>;
|
|
26
|
-
expirationDate: z.ZodOptional<z.ZodDate>;
|
|
27
|
-
}> = z.object({
|
|
28
|
-
id: z.string(),
|
|
29
|
-
|
|
30
|
-
/* Level of KYC verification performed (e.g., basic, intermediate, advanced). */
|
|
31
|
-
level: z.string(),
|
|
32
|
-
|
|
33
|
-
/* @default Date.now() */
|
|
34
|
-
issued: z.date().optional(),
|
|
35
|
-
|
|
36
|
-
/* Date the credential was approved. */
|
|
37
|
-
approvedAt: z.date().optional(),
|
|
38
|
-
|
|
39
|
-
/* Date the credential was revoked. */
|
|
40
|
-
expirationDate: z.date().optional(),
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
export type CredentialFields = z.infer<typeof CredentialFieldsSchema>;
|
|
44
|
-
|
|
45
|
-
// https://github.com/colinhacks/zod/issues/3751
|
|
46
|
-
export const CredentialResidentialAddressSchema: z.ZodObject<{
|
|
47
|
-
street: z.ZodString;
|
|
48
|
-
houseNumber: z.ZodOptional<z.ZodString>;
|
|
49
|
-
additionalAddressInfo: z.ZodOptional<z.ZodString>;
|
|
50
|
-
region: z.ZodOptional<z.ZodString>;
|
|
51
|
-
city: z.ZodString;
|
|
52
|
-
postalCode: z.ZodOptional<z.ZodString>;
|
|
53
|
-
country: z.ZodString;
|
|
54
|
-
proofCategory: z.ZodString;
|
|
55
|
-
proofDateOfIssue: z.ZodOptional<z.ZodDate>;
|
|
56
|
-
proofFile: z.ZodType<Buffer<ArrayBufferLike>>;
|
|
57
|
-
}> = z.object({
|
|
58
|
-
/* Street address. */
|
|
59
|
-
street: z.string(),
|
|
60
|
-
|
|
61
|
-
/* House number. */
|
|
62
|
-
houseNumber: z.string().optional(),
|
|
63
|
-
|
|
64
|
-
/* Additional address information (e.g., apartment number). */
|
|
65
|
-
additionalAddressInfo: z.string().optional(),
|
|
66
|
-
|
|
67
|
-
/* Region (e.g., state, province). */
|
|
68
|
-
region: z.string().optional(),
|
|
69
|
-
|
|
70
|
-
/* Locality (e.g., city, town). */
|
|
71
|
-
city: z.string(),
|
|
72
|
-
|
|
73
|
-
/* Postal code. */
|
|
74
|
-
postalCode: z.string().optional(),
|
|
75
|
-
|
|
76
|
-
/* Country (ISO 3166-1 alpha-2). */
|
|
77
|
-
country: z.string().min(2).max(2),
|
|
78
|
-
|
|
79
|
-
/* Residential Address Proof Category Type of document provided to verify the address(e.g., utility bill, bank statement). */
|
|
80
|
-
proofCategory: z.string(),
|
|
81
|
-
|
|
82
|
-
/* Residential Address Proof Date Of Issue Date the address proof document was issued. */
|
|
83
|
-
proofDateOfIssue: z.date().optional(),
|
|
84
|
-
|
|
85
|
-
/* Residential Address Proof File or URL of the document provided as address proof. */
|
|
86
|
-
proofFile: z.instanceof(Buffer),
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
export type CredentialResidentialAddress = z.infer<typeof CredentialResidentialAddressSchema>;
|
|
90
|
-
|
|
91
|
-
export const IDDocumentTypeSchema: z.ZodEnum<{
|
|
92
|
-
PASSPORT: "PASSPORT";
|
|
93
|
-
DRIVERS: "DRIVERS";
|
|
94
|
-
ID_CARD: "ID_CARD";
|
|
95
|
-
VOTING_CARD: "VOTING_CARD";
|
|
96
|
-
PAN_CARD: "PAN_CARD";
|
|
97
|
-
INTERNAL_PASSPORT: "INTERNAL_PASSPORT";
|
|
98
|
-
RESIDENCE_PERMIT: "RESIDENCE_PERMIT";
|
|
99
|
-
}> = z.enum([
|
|
100
|
-
"PASSPORT",
|
|
101
|
-
"DRIVERS",
|
|
102
|
-
"ID_CARD",
|
|
103
|
-
"VOTING_CARD",
|
|
104
|
-
"PAN_CARD",
|
|
105
|
-
"INTERNAL_PASSPORT",
|
|
106
|
-
"RESIDENCE_PERMIT",
|
|
107
|
-
]);
|
|
108
|
-
export type IDDocumentType = z.infer<typeof IDDocumentTypeSchema>;
|
|
109
|
-
|
|
110
|
-
export const GenderSchema: z.ZodEnum<{
|
|
111
|
-
M: "M";
|
|
112
|
-
F: "F";
|
|
113
|
-
OTHER: "OTHER";
|
|
114
|
-
}> = z.enum(["M", "F", "OTHER"]);
|
|
115
|
-
export type Gender = z.infer<typeof GenderSchema>;
|
|
116
|
-
|
|
117
|
-
// https://github.com/colinhacks/zod/issues/3751
|
|
118
|
-
export const CredentialSubjectSchema: z.ZodObject<{
|
|
119
|
-
id: z.ZodString;
|
|
120
|
-
// Indonesian and Indian did not always have first name
|
|
121
|
-
firstName: z.ZodOptional<z.ZodString>;
|
|
122
|
-
middleName: z.ZodOptional<z.ZodString>;
|
|
123
|
-
ssn: z.ZodOptional<z.ZodString>;
|
|
124
|
-
gender: z.ZodOptional<typeof GenderSchema>;
|
|
125
|
-
nationality: z.ZodOptional<z.ZodString>;
|
|
126
|
-
// Indonesian and Indian did not always have family name
|
|
127
|
-
familyName: z.ZodOptional<z.ZodString>;
|
|
128
|
-
maidenName: z.ZodOptional<z.ZodString>;
|
|
129
|
-
email: z.ZodOptional<z.ZodEmail>;
|
|
130
|
-
phoneNumber: z.ZodOptional<z.ZodString>;
|
|
131
|
-
dateOfBirth: z.ZodDate;
|
|
132
|
-
placeOfBirth: z.ZodOptional<z.ZodString>;
|
|
133
|
-
idDocumentCountry: z.ZodString;
|
|
134
|
-
idDocumentNumber: z.ZodString;
|
|
135
|
-
idDocumentType: typeof IDDocumentTypeSchema;
|
|
136
|
-
idDocumentDateOfIssue: z.ZodOptional<z.ZodDate>;
|
|
137
|
-
idDocumentDateOfExpiry: z.ZodOptional<z.ZodDate>;
|
|
138
|
-
idDocumentFrontFile: z.ZodType<Buffer<ArrayBufferLike>>;
|
|
139
|
-
idDocumentBackFile: z.ZodOptional<z.ZodType<Buffer<ArrayBufferLike>>>;
|
|
140
|
-
selfieFile: z.ZodType<Buffer<ArrayBufferLike>>;
|
|
141
|
-
residentialAddress: z.ZodOptional<typeof CredentialResidentialAddressSchema>;
|
|
142
|
-
}> = z
|
|
143
|
-
.object({
|
|
144
|
-
/* ID(unique credential) Unique identifier for the credential itself. */
|
|
145
|
-
id: z.string(),
|
|
146
|
-
|
|
147
|
-
/* First name. */
|
|
148
|
-
firstName: z.string().optional(),
|
|
149
|
-
|
|
150
|
-
/* Middle name. */
|
|
151
|
-
middleName: z.string().optional(),
|
|
152
|
-
|
|
153
|
-
/* Social-security-number (without dashes) */
|
|
154
|
-
ssn: z.string().min(9).max(9).optional(),
|
|
155
|
-
|
|
156
|
-
/* Nationality (ISO 3166-1 alpha-2). */
|
|
157
|
-
nationality: z.string().min(2).max(2).optional(),
|
|
158
|
-
|
|
159
|
-
/* Gender (M or F, empty if not provided). */
|
|
160
|
-
gender: GenderSchema.optional(),
|
|
161
|
-
|
|
162
|
-
/* Family name. */
|
|
163
|
-
familyName: z.string().optional(),
|
|
164
|
-
|
|
165
|
-
/* Maiden name. */
|
|
166
|
-
maidenName: z.string().optional(),
|
|
167
|
-
|
|
168
|
-
/* Date of birth. */
|
|
169
|
-
dateOfBirth: z.date(),
|
|
170
|
-
|
|
171
|
-
/* Place of birth. */
|
|
172
|
-
placeOfBirth: z.string().optional(),
|
|
173
|
-
|
|
174
|
-
/* Email. */
|
|
175
|
-
email: z.email().optional(),
|
|
176
|
-
|
|
177
|
-
/* Phone number. */
|
|
178
|
-
phoneNumber: z.string().optional(),
|
|
179
|
-
|
|
180
|
-
/* Country that issued the identity document (ISO 3166-1 alpha-2). */
|
|
181
|
-
idDocumentCountry: z.string().min(2).max(2),
|
|
182
|
-
|
|
183
|
-
/* ID Document Number Unique number on the identity document. */
|
|
184
|
-
idDocumentNumber: z.string(),
|
|
185
|
-
|
|
186
|
-
/* ID Document Type Type of identity document(e.g., Passport, Driver's License, National ID). */
|
|
187
|
-
idDocumentType: IDDocumentTypeSchema,
|
|
188
|
-
|
|
189
|
-
/* ID Document Date of Issue Date the identity document was issued. */
|
|
190
|
-
idDocumentDateOfIssue: z.date().optional(),
|
|
191
|
-
|
|
192
|
-
/* ID Document Date of Expiry Expiration date of the identity document - if applicable. */
|
|
193
|
-
idDocumentDateOfExpiry: z.date().optional(),
|
|
194
|
-
|
|
195
|
-
/* ID Document Front File Buffer with file representing the front of the identity document. */
|
|
196
|
-
idDocumentFrontFile: z.instanceof(Buffer),
|
|
197
|
-
|
|
198
|
-
/* ID Document Back File Buffer with file representing the back of the identity document - if applicable. */
|
|
199
|
-
idDocumentBackFile: z.instanceof(Buffer).optional(),
|
|
200
|
-
|
|
201
|
-
/* (ID Document) Selfie File Buffer with selfie with the identity document for verification purposes. */
|
|
202
|
-
selfieFile: z.instanceof(Buffer),
|
|
203
|
-
|
|
204
|
-
/* Residential Address Full residential address of the individual - if applicable. */
|
|
205
|
-
residentialAddress: CredentialResidentialAddressSchema.optional(),
|
|
206
|
-
})
|
|
207
|
-
.refine(
|
|
208
|
-
// At least one of firstName or familyName must be present,
|
|
209
|
-
(data) => data.firstName || data.familyName,
|
|
210
|
-
{ message: "At least one of firstName or familyName must be provided" },
|
|
211
|
-
);
|
|
212
|
-
|
|
213
|
-
export type CredentialSubject = z.infer<typeof CredentialSubjectSchema>;
|
|
214
|
-
|
|
215
|
-
export interface VerifiableCredentialSubject extends Omit<
|
|
216
|
-
CredentialSubject,
|
|
217
|
-
| "residentialAddress"
|
|
218
|
-
| "idDocumentBackFile"
|
|
219
|
-
| "idDocumentFrontFile"
|
|
220
|
-
| "selfieFile"
|
|
221
|
-
| "idDocumentDateOfIssue"
|
|
222
|
-
| "idDocumentDateOfExpiry"
|
|
223
|
-
| "dateOfBirth"
|
|
224
|
-
> {
|
|
225
|
-
"@context": string;
|
|
226
|
-
// Files are strings in verifiable credentials, but as an input they should be buffers
|
|
227
|
-
idDocumentFrontFile?: string;
|
|
228
|
-
idDocumentBackFile?: string;
|
|
229
|
-
selfieFile?: string;
|
|
230
|
-
// Dates are strings in verifiable credentials
|
|
231
|
-
dateOfBirth?: string;
|
|
232
|
-
idDocumentDateOfIssue?: string;
|
|
233
|
-
idDocumentDateOfExpiry?: string;
|
|
234
|
-
// This is the residential address flattened fields
|
|
235
|
-
residentialAddressStreet?: string;
|
|
236
|
-
residentialAddressHouseNumber?: string;
|
|
237
|
-
residentialAddressAdditionalAddressInfo?: string;
|
|
238
|
-
residentialAddressRegion?: string;
|
|
239
|
-
residentialAddressCity?: string;
|
|
240
|
-
residentialAddressPostalCode?: string;
|
|
241
|
-
residentialAddressCountry?: string;
|
|
242
|
-
residentialAddressProofCategory?: string;
|
|
243
|
-
// Dates are strings in verifiable credentials
|
|
244
|
-
residentialAddressProofDateOfIssue?: string;
|
|
245
|
-
// Files are strings in verifiable credentials, but as an input they should be buffers
|
|
246
|
-
residentialAddressProofFile?: string;
|
|
247
|
-
}
|
|
248
|
-
|
|
249
27
|
// TODO: This is a stub of the types for @digitalbazaar/vc
|
|
250
28
|
// when they introduce TypeScript support we should remove this
|
|
251
29
|
// The copy is here because `types.d.ts` file is not bundled.
|
|
252
|
-
export interface
|
|
30
|
+
export interface VerifiableCredentialProof {
|
|
253
31
|
type: string;
|
|
254
32
|
created: string;
|
|
255
33
|
verificationMethod: string;
|
|
@@ -257,26 +35,17 @@ export interface VerifiedCredentialsProof {
|
|
|
257
35
|
proofPurpose: string;
|
|
258
36
|
}
|
|
259
37
|
|
|
260
|
-
export
|
|
261
|
-
faceSignUserId: z.ZodString;
|
|
262
|
-
}> = z.object({
|
|
263
|
-
faceSignUserId: z.string(),
|
|
264
|
-
});
|
|
265
|
-
|
|
266
|
-
export type CredentialSubjectFaceId = z.infer<typeof CredentialSubjectFaceIdSchema>;
|
|
267
|
-
|
|
268
|
-
export interface VerifiedCredentials<K> {
|
|
38
|
+
export interface VerifiableCredential<K> {
|
|
269
39
|
"@context": string[];
|
|
270
40
|
type: string[];
|
|
271
41
|
issuer: string;
|
|
272
42
|
id: string;
|
|
273
43
|
level: string;
|
|
44
|
+
kycLevel?: number;
|
|
274
45
|
issued: string;
|
|
275
46
|
approvedAt: string;
|
|
276
|
-
expirationDate
|
|
47
|
+
expirationDate?: string;
|
|
277
48
|
credentialSubject: K;
|
|
278
49
|
issuanceDate: string;
|
|
279
|
-
proof:
|
|
50
|
+
proof: VerifiableCredentialProof;
|
|
280
51
|
}
|
|
281
|
-
|
|
282
|
-
export type VerifiableCredential<K> = VerifiedCredentials<K>;
|
|
@@ -1,26 +1,18 @@
|
|
|
1
|
+
import { hexEncode, utf8Encode } from "@idos-network/utils/codecs";
|
|
2
|
+
import nacl from "tweetnacl";
|
|
1
3
|
import { describe, expect, it } from "vitest";
|
|
2
4
|
|
|
3
|
-
import type { CredentialSubject } from "../types";
|
|
4
|
-
|
|
5
5
|
import {
|
|
6
|
-
|
|
6
|
+
buildEphemeralSignedCredentialContentReference,
|
|
7
|
+
buildPreliminaryIDOSCredential,
|
|
8
|
+
buildSignedCredentialContentReference,
|
|
7
9
|
highestMatchingCredential,
|
|
8
10
|
matchLevelOrHigher,
|
|
9
11
|
pickHighestMatchingLevel,
|
|
10
12
|
recordFilter,
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
id: "uuid:1234",
|
|
15
|
-
firstName: "John",
|
|
16
|
-
familyName: "Doe",
|
|
17
|
-
idDocumentType: "PASSPORT",
|
|
18
|
-
dateOfBirth: new Date("1990-01-01"),
|
|
19
|
-
idDocumentCountry: "US",
|
|
20
|
-
idDocumentNumber: "123456789",
|
|
21
|
-
idDocumentFrontFile: Buffer.from("ID Document Front"),
|
|
22
|
-
selfieFile: Buffer.alloc(0),
|
|
23
|
-
};
|
|
13
|
+
type Addon,
|
|
14
|
+
type BaseLevel,
|
|
15
|
+
} from ".";
|
|
24
16
|
|
|
25
17
|
describe("recordFilter", () => {
|
|
26
18
|
[
|
|
@@ -76,6 +68,9 @@ describe("recordFilter", () => {
|
|
|
76
68
|
|
|
77
69
|
describe("matchLevelOrHigher", () => {
|
|
78
70
|
[
|
|
71
|
+
["unverified", [], "unverified", true],
|
|
72
|
+
["unverified", [], "basic", true],
|
|
73
|
+
["basic", [], "unverified", false],
|
|
79
74
|
["basic", [], "basic+liveness", true],
|
|
80
75
|
["plus", [], "plus+liveness", true],
|
|
81
76
|
["plus", [], "basic", false],
|
|
@@ -86,11 +81,7 @@ describe("matchLevelOrHigher", () => {
|
|
|
86
81
|
].forEach(([level, requiredAddons, testLevel, expected]) => {
|
|
87
82
|
it(`level=${level} requiredAddons=[${(requiredAddons as string[]).join(",")}] testLevel=${testLevel} => ${expected}`, () => {
|
|
88
83
|
expect(
|
|
89
|
-
matchLevelOrHigher(
|
|
90
|
-
level as "basic" | "plus",
|
|
91
|
-
requiredAddons as ("liveness" | "email" | "phoneNumber")[],
|
|
92
|
-
testLevel as string,
|
|
93
|
-
),
|
|
84
|
+
matchLevelOrHigher(level as BaseLevel, requiredAddons as Addon[], testLevel as string),
|
|
94
85
|
).toBe(expected as boolean);
|
|
95
86
|
});
|
|
96
87
|
});
|
|
@@ -116,6 +107,12 @@ describe("pickHighestMatchingLevel", () => {
|
|
|
116
107
|
["email", "phoneNumber"],
|
|
117
108
|
null,
|
|
118
109
|
],
|
|
110
|
+
[
|
|
111
|
+
["unverified+phoneNumber", "basic+phoneNumber", "plus+phoneNumber"],
|
|
112
|
+
"unverified",
|
|
113
|
+
["phoneNumber"],
|
|
114
|
+
"plus+phoneNumber",
|
|
115
|
+
],
|
|
119
116
|
[["basic+liveness", "plus+liveness"], "basic", ["liveness"], "plus+liveness"],
|
|
120
117
|
].forEach(([levels, requiredLevel, requiredAddons, expected]) => {
|
|
121
118
|
it(`levels=${levels} requiredLevel=${requiredLevel} requiredAddons=[${(requiredAddons as string[]).join(",")}] => ${expected}`, () => {
|
|
@@ -247,57 +244,52 @@ describe("highestMatchingCredential", () => {
|
|
|
247
244
|
});
|
|
248
245
|
});
|
|
249
246
|
|
|
250
|
-
describe("
|
|
251
|
-
it("
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
).toBe(
|
|
247
|
+
describe("buildSignedCredentialContentReference", () => {
|
|
248
|
+
it("derives issuer_auth_public_key from the signing secret key", () => {
|
|
249
|
+
const keyPair = nacl.sign.keyPair();
|
|
250
|
+
const result = buildSignedCredentialContentReference("", "ipfs://cid", keyPair.secretKey);
|
|
251
|
+
|
|
252
|
+
expect(result.public_notes).toBe("");
|
|
253
|
+
expect(result.public_notes_signature).toBeTruthy();
|
|
254
|
+
expect(result.broader_signature).toBeTruthy();
|
|
255
|
+
expect(result.issuer_auth_public_key).toBe(hexEncode(keyPair.publicKey, true));
|
|
259
256
|
});
|
|
257
|
+
});
|
|
260
258
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
).
|
|
259
|
+
describe("buildEphemeralSignedCredentialContentReference", () => {
|
|
260
|
+
it("returns a signed reference with a public key", () => {
|
|
261
|
+
const result = buildEphemeralSignedCredentialContentReference("", "ipfs://cid");
|
|
262
|
+
|
|
263
|
+
expect(result.public_notes).toBe("");
|
|
264
|
+
expect(result.public_notes_signature).toBeTruthy();
|
|
265
|
+
expect(result.broader_signature).toBeTruthy();
|
|
266
|
+
expect(result.issuer_auth_public_key).toMatch(/^(0x)?[0-9a-f]+$/i);
|
|
267
267
|
});
|
|
268
|
+
});
|
|
268
269
|
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
}),
|
|
282
|
-
).toBe("plus+liveness");
|
|
270
|
+
describe("buildPreliminaryIDOSCredential", () => {
|
|
271
|
+
const recipient = nacl.box.keyPair();
|
|
272
|
+
|
|
273
|
+
it("hashes encrypted content to an ipfs:// uri by default", async () => {
|
|
274
|
+
const result = await buildPreliminaryIDOSCredential({
|
|
275
|
+
publicNotes: "{}",
|
|
276
|
+
plaintextContent: utf8Encode("secret"),
|
|
277
|
+
recipientEncryptionPublicKey: recipient.publicKey,
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
expect(result.contentUri).toMatch(/^ipfs:\/\//);
|
|
281
|
+
expect(result.contentSize).toBe(result.encryptedContent.byteLength);
|
|
283
282
|
});
|
|
284
283
|
|
|
285
|
-
it("
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
postalCode: "12345",
|
|
296
|
-
country: "US",
|
|
297
|
-
proofCategory: "UTILITY_BILL",
|
|
298
|
-
proofFile: Buffer.from("Utility Bill"),
|
|
299
|
-
},
|
|
300
|
-
}),
|
|
301
|
-
).toBe("plus+liveness+email+phoneNumber");
|
|
284
|
+
it("uses a provided contentUri instead of hashing to ipfs", async () => {
|
|
285
|
+
const result = await buildPreliminaryIDOSCredential({
|
|
286
|
+
publicNotes: "{}",
|
|
287
|
+
plaintextContent: utf8Encode("secret"),
|
|
288
|
+
recipientEncryptionPublicKey: recipient.publicKey,
|
|
289
|
+
contentUri: "ukyc://storage-abc/blobs/blob-1",
|
|
290
|
+
});
|
|
291
|
+
|
|
292
|
+
expect(result.contentUri).toBe("ukyc://storage-abc/blobs/blob-1");
|
|
293
|
+
expect(result.contentSize).toBe(result.encryptedContent.byteLength);
|
|
302
294
|
});
|
|
303
295
|
});
|