Skip to content

Commit 26923f9

Browse files
authored
Feat/swtich credentials in default presentation (#471)
* create default presentation in verification controller * Restore credential switching helpers lost during rebase * fix presentation submission by ensuring descriptor_map is populated * enable presentation submission for templates 1, 2, 3 and 4 * fix range proof presentations by revealing attributes from PEX template * patch pex to bounds * fix MAX_NUMBER overflow in range proof bounds for browser environments * update pex-helpers tests for MAX_NUMBER constant change * skip cheqd integration tests temporarily * remove unnecesary patch file * use MAX_NUMBER constant in pex-helpers tests
1 parent 62ae91b commit 26923f9

6 files changed

Lines changed: 544 additions & 73 deletions

File tree

integration-tests/cheqd-credentials.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { CheqdCredentialNonZKP, CheqdCredentialZKP } from './data/credentials/ch
44
import { addCredentialIfNotExists, closeWallet, createNewWallet, getCredentialProvider, getWallet } from './helpers';
55
import { ProofTemplateIds, createProofRequest } from './helpers/certs-helpers';
66

7-
describe('Cheq integration tests', () => {
7+
describe.skip('Cheq integration tests', () => {
88
beforeAll(async () => {
99
await createNewWallet();
1010
});

integration-tests/verification-flow/default-presentation.test.ts

Lines changed: 235 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@ describe('Default presentation', () => {
6262

6363
expect(result.isValid).toBe(true);
6464
expect(result.errors).toHaveLength(0);
65+
66+
const submitResult = await controller.submitPresentation(presentation);
67+
68+
expect(submitResult.verified).toBe(true);
6569
});
6670

6771
it('should create a default presentation with range proof', async () => {
@@ -83,6 +87,8 @@ describe('Default presentation', () => {
8387
expect(presentation.verifiableCredential).toBeDefined();
8488
expect(presentation.verifiableCredential.length).toBe(1);
8589

90+
const submitResult = await controller.submitPresentation(presentation);
91+
expect(submitResult.verified).toBe(true);
8692
});
8793

8894
it('should create a default presentation for any credential with dateOfBirth', async () => {
@@ -104,6 +110,9 @@ describe('Default presentation', () => {
104110
expect(presentation.verifiableCredential).toBeDefined();
105111
expect(presentation.verifiableCredential.length).toBe(1);
106112

113+
const submitResult = await controller.submitPresentation(presentation);
114+
115+
expect(submitResult.verified).toBe(true);
107116
});
108117

109118
it('should create a default presentation with 2 range proofs', async () => {
@@ -125,5 +134,231 @@ describe('Default presentation', () => {
125134
expect(presentation.verifiableCredential).toBeDefined();
126135
expect(presentation.verifiableCredential.length).toBeGreaterThanOrEqual(1);
127136

137+
const submitResult = await controller.submitPresentation(presentation);
138+
expect(submitResult.verified).toBe(true);
139+
});
140+
141+
it('should return selected credentials by descriptor with alternatives', async () => {
142+
const proofRequest = await createProofRequest(template1);
143+
144+
const controller = createVerificationController({
145+
wallet,
146+
didProvider,
147+
});
148+
149+
await controller.start({
150+
template: proofRequest,
151+
});
152+
153+
await controller.createDefaultPresentation();
154+
155+
const descriptors = controller.getSelectedCredentialsByDescriptor();
156+
157+
expect(descriptors.length).toBeGreaterThanOrEqual(1);
158+
159+
const descriptor = descriptors[0];
160+
expect(descriptor.selected).toBeDefined();
161+
expect(descriptor.selected.id).toBeDefined();
162+
expect(descriptor.descriptorName).toBeDefined();
163+
// Template1 requires university degree, and we have 2 university degrees in the wallet
164+
expect(descriptor.alternatives.length).toBeGreaterThanOrEqual(1);
165+
});
166+
167+
it('should return credential options for a selected credential', async () => {
168+
const proofRequest = await createProofRequest(template1);
169+
170+
const controller = createVerificationController({
171+
wallet,
172+
didProvider,
173+
});
174+
175+
await controller.start({
176+
template: proofRequest,
177+
});
178+
179+
await controller.createDefaultPresentation();
180+
181+
const descriptors = controller.getSelectedCredentialsByDescriptor();
182+
const selectedCredentialId = descriptors[0].selected.id;
183+
184+
const options = controller.getCredentialOptionsForDescriptor(selectedCredentialId);
185+
186+
expect(options.selected.id).toBe(selectedCredentialId);
187+
expect(options.alternatives.length).toBeGreaterThanOrEqual(1);
188+
// The alternative should not be the same as the selected credential
189+
expect(options.alternatives.every(alt => alt.id !== selectedCredentialId)).toBe(true);
190+
});
191+
192+
it('should switch a credential and generate a valid presentation', async () => {
193+
const proofRequest = await createProofRequest(template1);
194+
195+
const controller = createVerificationController({
196+
wallet,
197+
didProvider,
198+
});
199+
200+
await controller.start({
201+
template: proofRequest,
202+
});
203+
204+
await controller.createDefaultPresentation();
205+
206+
const descriptors = controller.getSelectedCredentialsByDescriptor();
207+
const originalCredentialId = descriptors[0].selected.id;
208+
const replacementCredentialId = descriptors[0].alternatives[0].id;
209+
210+
const newPresentation = await controller.switchCredential(
211+
originalCredentialId,
212+
replacementCredentialId,
213+
);
214+
215+
expect(newPresentation).toBeDefined();
216+
expect(newPresentation.type).toEqual(['VerifiablePresentation']);
217+
218+
// Verify the selected credentials were actually swapped
219+
const updatedDescriptors = controller.getSelectedCredentialsByDescriptor();
220+
expect(updatedDescriptors[0].selected.id).toBe(replacementCredentialId);
221+
222+
const result = controller.evaluatePresentation(newPresentation);
223+
expect(result.isValid).toBe(true);
224+
});
225+
226+
it('should throw when switching with a non-selected credential', async () => {
227+
const proofRequest = await createProofRequest(template1);
228+
229+
const controller = createVerificationController({
230+
wallet,
231+
didProvider,
232+
});
233+
234+
await controller.start({
235+
template: proofRequest,
236+
});
237+
238+
await controller.createDefaultPresentation();
239+
240+
await expect(
241+
controller.switchCredential('non-existent-id', universityDegree2.id),
242+
).rejects.toThrow('is not currently selected');
243+
});
244+
245+
it('should throw when switching with an ineligible replacement', async () => {
246+
const proofRequest = await createProofRequest(template1);
247+
248+
const controller = createVerificationController({
249+
wallet,
250+
didProvider,
251+
});
252+
253+
await controller.start({
254+
template: proofRequest,
255+
});
256+
257+
await controller.createDefaultPresentation();
258+
259+
const descriptors = controller.getSelectedCredentialsByDescriptor();
260+
const selectedCredentialId = descriptors[0].selected.id;
261+
262+
await expect(
263+
controller.switchCredential(selectedCredentialId, 'non-existent-credential'),
264+
).rejects.toThrow('is not a valid replacement');
265+
});
266+
267+
it('should return requested attributes for a credential', async () => {
268+
const proofRequest = await createProofRequest(template1);
269+
270+
const controller = createVerificationController({
271+
wallet,
272+
didProvider,
273+
});
274+
275+
await controller.start({
276+
template: proofRequest,
277+
});
278+
279+
await controller.createDefaultPresentation();
280+
281+
const descriptors = controller.getSelectedCredentialsByDescriptor();
282+
const selectedCredentialId = descriptors[0].selected.id;
283+
284+
const attributes = controller.getRequestedAttributes(selectedCredentialId);
285+
286+
expect(attributes.length).toBeGreaterThanOrEqual(1);
287+
// Template1 requests dateOfBirth
288+
const dateOfBirth = attributes.find(a => a.name === 'credentialSubject.dateOfBirth');
289+
expect(dateOfBirth).toBeDefined();
290+
expect(dateOfBirth.isRangeProof).toBe(false);
291+
expect(dateOfBirth.value).toBeDefined();
292+
});
293+
294+
it('should identify range proof attributes', async () => {
295+
const proofRequest = await createProofRequest(template2);
296+
297+
const controller = createVerificationController({
298+
wallet,
299+
didProvider,
300+
});
301+
302+
await controller.start({
303+
template: proofRequest,
304+
});
305+
306+
await controller.createDefaultPresentation();
307+
308+
const descriptors = controller.getSelectedCredentialsByDescriptor();
309+
const selectedCredentialId = descriptors[0].selected.id;
310+
311+
const attributes = controller.getRequestedAttributes(selectedCredentialId);
312+
313+
const rangeProofAttr = attributes.find(a => a.isRangeProof);
314+
expect(rangeProofAttr).toBeDefined();
315+
expect(rangeProofAttr.value).toBeNull();
316+
expect(rangeProofAttr.min !== undefined || rangeProofAttr.max !== undefined).toBe(true);
317+
});
318+
319+
it('should return credential status for a valid credential', async () => {
320+
const proofRequest = await createProofRequest(template1);
321+
322+
const controller = createVerificationController({
323+
wallet,
324+
didProvider,
325+
});
326+
327+
await controller.start({
328+
template: proofRequest,
329+
});
330+
331+
await controller.createDefaultPresentation();
332+
333+
const descriptors = controller.getSelectedCredentialsByDescriptor();
334+
const selectedCredentialId = descriptors[0].selected.id;
335+
336+
const status = await controller.getCredentialStatus(selectedCredentialId);
337+
338+
expect(status).toBeDefined();
339+
expect(status.status).toBe('verified');
340+
});
341+
342+
it('should check if a credential can be switched', async () => {
343+
const proofRequest = await createProofRequest(template1);
344+
345+
const controller = createVerificationController({
346+
wallet,
347+
didProvider,
348+
});
349+
350+
await controller.start({
351+
template: proofRequest,
352+
});
353+
354+
await controller.createDefaultPresentation();
355+
356+
const descriptors = controller.getSelectedCredentialsByDescriptor();
357+
const selectedCredentialId = descriptors[0].selected.id;
358+
359+
// Template1 has 2 matching university degrees, so switching should be possible
360+
expect(controller.canSwitchCredential(selectedCredentialId)).toBe(true);
361+
// Non-existent credential should return false
362+
expect(controller.canSwitchCredential('non-existent-id')).toBe(false);
128363
});
129364
});

0 commit comments

Comments
 (0)