UNPKG

@gleif-it/vlei-verifier-workflows

Version:

Workflows for vLEI users and vLEI credentials for the vLEI-verifier service

789 lines (788 loc) 51 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.VleiIssuance = void 0; const assert_1 = require("assert"); const mathjs_1 = require("mathjs"); const signify_ts_1 = require("signify-ts"); const test_util_js_1 = require("./utils/test-util.js"); const multisig_utils_js_1 = require("./utils/multisig-utils.js"); const retry_js_1 = require("./utils/retry.js"); const constants_js_1 = require("./constants.js"); const generate_test_data_js_1 = require("./utils/generate-test-data.js"); const workflow_state_js_1 = require("./workflow-state.js"); exports.VleiIssuance = { // Create client for given AID createClient: (secret, agentName) => __awaiter(void 0, void 0, void 0, function* () { const workflow_state = workflow_state_js_1.WorkflowState.getInstance(); console.log(`Creating client for secret: ${secret}`); const client = yield (0, test_util_js_1.getOrCreateClients)(1, [secret], false); workflow_state.clients.set(agentName, client[0]); return true; }), // Create AID createAid: (identifierData) => __awaiter(void 0, void 0, void 0, function* () { console.log('Creating AID'); const workflow_state = workflow_state_js_1.WorkflowState.getInstance(); let aid; if (identifierData.type == 'singlesig') { workflow_state.aidsInfo.set(identifierData.name, identifierData); aid = yield exports.VleiIssuance.createAidSinglesig(identifierData); yield exports.VleiIssuance.fetchOobi(identifierData); yield exports.VleiIssuance.createContacts(identifierData); yield exports.VleiIssuance.resolveOobi(identifierData); workflow_state.aids.set(identifierData.name, aid); } else { workflow_state.aidsInfo.set(identifierData.name, identifierData); aid = yield exports.VleiIssuance.createAidMultisig(identifierData); yield exports.VleiIssuance.fetchOobi(identifierData); workflow_state.aids.set(identifierData.name, aid); } }), // Fetch OOBIs for each client! fetchOobis: () => __awaiter(void 0, void 0, void 0, function* () { console.log('Fetching OOBIs'); const workflow_state = workflow_state_js_1.WorkflowState.getInstance(); for (const [, aidInfo] of workflow_state.aidsInfo) { yield exports.VleiIssuance.fetchOobi(aidInfo); } }), fetchOobi: (identifierData) => __awaiter(void 0, void 0, void 0, function* () { let client; let oobi; const workflow_state = workflow_state_js_1.WorkflowState.getInstance(); if (identifierData.type === 'singlesig') { const singlesigIdentifierData = identifierData; client = workflow_state.clients.get(singlesigIdentifierData.agent.name); oobi = yield client.oobis().get(identifierData.name, 'agent'); if (oobi) { workflow_state.oobis.set(singlesigIdentifierData.name, [oobi]); } } else { const multisigIdentifierData = identifierData; const oobis = []; for (const _ of multisigIdentifierData.identifiers) { const identifier = workflow_state.aidsInfo.get(multisigIdentifierData.identifiers[0]); client = workflow_state.clients.get(identifier.agent.name); oobi = yield client.oobis().get(identifier.name, 'agent'); oobis.push(oobi); } if (oobi) { workflow_state.oobis.set(identifierData.name, oobis); } } }), // Create contacts between clients createContacts: (identifierData) => __awaiter(void 0, void 0, void 0, function* () { console.log('Creating Contacts'); const workflow_state = workflow_state_js_1.WorkflowState.getInstance(); for (const [, contactIdentifierData] of workflow_state.aidsInfo) { if (contactIdentifierData.type === 'multisig' || identifierData.type === 'multisig') continue; if (identifierData.name != contactIdentifierData.name) { yield exports.VleiIssuance.createContact(identifierData, contactIdentifierData); } } }), createContact: (aidInfoA, aidInfoB) => __awaiter(void 0, void 0, void 0, function* () { var _a, _b; const workflow_state = workflow_state_js_1.WorkflowState.getInstance(); if (aidInfoA.type == 'singlesig') { const singlesigIdentifierDataA = aidInfoA; const singlesigIdentifierDataB = aidInfoB; const clientA = workflow_state.clients.get(singlesigIdentifierDataA.agent.name); const clientB = workflow_state.clients.get(singlesigIdentifierDataB.agent.name); const oobiA = (_a = workflow_state.oobis.get(singlesigIdentifierDataA.name)) === null || _a === void 0 ? void 0 : _a[0].oobis[0]; const oobiB = (_b = workflow_state.oobis.get(singlesigIdentifierDataB.name)) === null || _b === void 0 ? void 0 : _b[0].oobis[0]; yield (0, test_util_js_1.getOrCreateContact)(clientA, singlesigIdentifierDataB.name, oobiB); yield (0, test_util_js_1.getOrCreateContact)(clientB, singlesigIdentifierDataA.name, oobiA); } }), // Resolve OOBIs for each client! and schema resolveOobis: () => { const schemaUrls = [ constants_js_1.QVI_SCHEMA_URL, constants_js_1.LE_SCHEMA_URL, constants_js_1.ECR_AUTH_SCHEMA_URL, constants_js_1.ECR_SCHEMA_URL, constants_js_1.OOR_AUTH_SCHEMA_URL, constants_js_1.OOR_SCHEMA_URL, ]; console.log('Resolving OOBIs'); const workflow_state = workflow_state_js_1.WorkflowState.getInstance(); for (const [, client] of workflow_state.clients) { schemaUrls.forEach((schemaUrl) => __awaiter(void 0, void 0, void 0, function* () { yield (0, test_util_js_1.resolveOobi)(client, schemaUrl); })); } }, resolveOobi: (identifierData) => { const schemaUrls = [ constants_js_1.QVI_SCHEMA_URL, constants_js_1.LE_SCHEMA_URL, constants_js_1.ECR_AUTH_SCHEMA_URL, constants_js_1.ECR_SCHEMA_URL, constants_js_1.OOR_AUTH_SCHEMA_URL, constants_js_1.OOR_SCHEMA_URL, ]; if (identifierData.type === 'singlesig') { console.log('Resolving OOBIs for client'); const workflow_state = workflow_state_js_1.WorkflowState.getInstance(); const singlesigIdentifierData = identifierData; const client = workflow_state.clients.get(singlesigIdentifierData.agent.name); schemaUrls.forEach((schemaUrl) => __awaiter(void 0, void 0, void 0, function* () { yield (0, test_util_js_1.resolveOobi)(client, schemaUrl); })); } }, createRegistry: (identifierData) => __awaiter(void 0, void 0, void 0, function* () { console.log('Creating Registries'); const workflow_state = workflow_state_js_1.WorkflowState.getInstance(); let registry; if (identifierData.type == 'multisig') { registry = yield exports.VleiIssuance.createRegistryMultisig(identifierData); } else { const singlesigIdentifierData = identifierData; const client = workflow_state.clients.get(singlesigIdentifierData.agent.name); registry = yield (0, test_util_js_1.getOrCreateRegistry)(client, workflow_state.aids.get(identifierData.name), `${identifierData.name}Registry`); } workflow_state.registries.set(identifierData.name, registry); }), createAidSinglesig: (identifierData) => __awaiter(void 0, void 0, void 0, function* () { const workflow_state = workflow_state_js_1.WorkflowState.getInstance(); const delegator = identifierData.delegator; const kargsSinglesigAID = { toad: workflow_state.kargsAID.toad, wits: workflow_state.kargsAID.wits, }; const singlesigIdentifierData = identifierData; const client = workflow_state.clients.get(singlesigIdentifierData.agent.name); if (delegator != null) { try { const aid = yield client.identifiers().get(identifierData.name); return aid; } catch (_c) { console.log(`Creating delegated AID for: ${identifierData.name}`); } kargsSinglesigAID.delpre = workflow_state.aids.get(delegator).prefix; const delegatorIdentifierData = workflow_state.aidsInfo.get(delegator); const delegatorclient = workflow_state.clients.get(delegatorIdentifierData.agent.name); const delegatorAid = workflow_state.aids.get(delegator); // Resolve delegator's oobi const oobi1 = yield delegatorclient.oobis().get(delegator, 'agent'); yield (0, test_util_js_1.resolveOobi)(client, oobi1.oobis[0], delegator); // Delegate client! creates delegate AID const icpResult2 = yield client .identifiers() .create(identifierData.name, { delpre: delegatorAid.prefix }); const op2 = yield icpResult2.op(); const delegateAidPrefix = op2.name.split('.')[1]; console.log("Delegate's prefix:", delegateAidPrefix); // client! 1 approves delegation const anchor = { i: delegateAidPrefix, s: '0', d: delegateAidPrefix, }; const result = yield (0, retry_js_1.retry)(() => __awaiter(void 0, void 0, void 0, function* () { const apprDelRes = yield delegatorclient .delegations() .approve(delegator, anchor); yield (0, test_util_js_1.waitOperation)(delegatorclient, yield apprDelRes.op()); console.log('Delegator approve delegation submitted'); return apprDelRes; })); assert_1.strict.equal(JSON.stringify(result.serder.ked.a[0]), JSON.stringify(anchor)); const op3 = yield client.keyStates().query(delegatorAid.prefix, '1'); yield (0, test_util_js_1.waitOperation)(client, op3); // Delegate client! checks approval yield (0, test_util_js_1.waitOperation)(client, op2); const aid2 = yield client.identifiers().get(identifierData.name); assert_1.strict.equal(aid2.prefix, delegateAidPrefix); console.log('Delegation approved for aid:', aid2.prefix); yield (0, test_util_js_1.assertOperations)(delegatorclient, client); const rpyResult2 = yield client .identifiers() .addEndRole(identifierData.name, 'agent', client.agent.pre); yield (0, test_util_js_1.waitOperation)(client, yield rpyResult2.op()); return aid2; } else { const aid = yield (0, test_util_js_1.getOrCreateAID)(client, identifierData.name, kargsSinglesigAID); return aid; } }), createAidMultisig: (identifierData) => __awaiter(void 0, void 0, void 0, function* () { const workflow_state = workflow_state_js_1.WorkflowState.getInstance(); const multisigIdentifierData = identifierData; let multisigAids = []; const aidIdentifierNames = multisigIdentifierData.identifiers; const issuerAids = aidIdentifierNames.map((aidIdentifierName) => workflow_state.aids.get(aidIdentifierName)) || []; try { for (const aidIdentifierName of aidIdentifierNames) { const singlesigIdentifierData = workflow_state.aidsInfo.get(aidIdentifierName); const client = workflow_state.clients.get(singlesigIdentifierData.agent.name); multisigAids.push(yield client.identifiers().get(identifierData.name)); } const multisigAid = multisigAids[0]; console.log(`${identifierData.name} AID: ${multisigAid.prefix}`); return multisigAid; } catch (_d) { multisigAids = []; } if (multisigAids.length == 0) { const rstates = issuerAids.map((aid) => aid.state); const states = rstates; const kargsMultisigAID = { algo: signify_ts_1.default.Algos.group, isith: multisigIdentifierData.isith, nsith: multisigIdentifierData.nsith, toad: workflow_state.kargsAID.toad, wits: workflow_state.kargsAID.wits, states: states, rstates: rstates, }; if (identifierData.delegator != null) { kargsMultisigAID.delpre = workflow_state.aids.get(multisigIdentifierData.delegator).prefix; } const multisigOps = []; for (let index = 0; index < issuerAids.length; index++) { const aid = issuerAids[index]; const singlesigIdentifierData = workflow_state.aidsInfo.get(aid.name); const kargsMultisigAIDClone = Object.assign(Object.assign({}, kargsMultisigAID), { mhab: aid }); const otherAids = issuerAids.filter((aidTmp) => aid !== aidTmp); const client = workflow_state.clients.get(singlesigIdentifierData.agent.name); const op = yield (0, multisig_utils_js_1.createAIDMultisig)(client, aid, otherAids, identifierData.name, kargsMultisigAIDClone, index === 0 // Set true for the first operation ); multisigOps.push([client, op]); } if (multisigIdentifierData.delegator) { // Approve delegation const delegatoridentifierData = workflow_state.aidsInfo.get(multisigIdentifierData.delegator); const delegatorAidIdentifierNames = delegatoridentifierData.identifiers; const delegatorAids = delegatorAidIdentifierNames.map((aidIdentifierName) => workflow_state.aids.get(aidIdentifierName)) || []; const teepre = multisigOps[0][1].name.split('.')[1]; const anchor = { i: teepre, s: '0', d: teepre, }; let delegatorClientInitiator; const delegatorMultisigAid = workflow_state.aids.get(delegatoridentifierData.name); const delegateOps = []; for (let index = 0; index < delegatoridentifierData.identifiers.length; index++) { const curAidName = delegatoridentifierData.identifiers[index]; const curidentifierData = workflow_state.aidsInfo.get(curAidName); const aid = workflow_state.aids.get(curAidName); const otherAids = delegatorAids.filter((aidTmp) => aid.prefix !== aidTmp.prefix); const delegatorclient = workflow_state.clients.get(curidentifierData.agent.name); const delApprOp = yield (0, multisig_utils_js_1.delegateMultisig)(delegatorclient, aid, otherAids, delegatorMultisigAid, anchor, index === 0); delegateOps.push([delegatorclient, delApprOp]); if (index === 0) { delegatorClientInitiator = delegatorclient; } else { yield (0, test_util_js_1.waitAndMarkNotification)(delegatorClientInitiator, '/multisig/ixn'); } } for (const [client, op] of delegateOps) { yield (0, test_util_js_1.waitOperation)(client, op); } for (const identifier of delegatoridentifierData.identifiers) { const curidentifierData = workflow_state.aidsInfo.get(identifier); const delegatorclient = workflow_state.clients.get(curidentifierData.agent.name); const queryOp1 = yield delegatorclient .keyStates() .query(delegatorMultisigAid.prefix, '1'); yield (0, test_util_js_1.waitOperation)(delegatorclient, queryOp1); } for (const identifier of multisigIdentifierData.identifiers) { const curidentifierData = workflow_state.aidsInfo.get(identifier); const delegateeclient = workflow_state.clients.get(curidentifierData.agent.name); const ksteetor1 = yield delegateeclient .keyStates() .query(delegatorMultisigAid.prefix, '1'); yield (0, test_util_js_1.waitOperation)(delegateeclient, ksteetor1); } } // Wait for all multisig operations to complete for (const [client, op] of multisigOps) { yield (0, test_util_js_1.waitOperation)(client, op); } // Wait for multisig inception notifications for all clients const tmpAidData = workflow_state.aidsInfo.get(issuerAids[0].name); yield (0, test_util_js_1.waitAndMarkNotification)(workflow_state.clients.get(tmpAidData.agent.name), '/multisig/icp'); // Retrieve the newly created AIDs for all clients multisigAids = yield Promise.all(issuerAids.map((aid) => __awaiter(void 0, void 0, void 0, function* () { const tmpAidData = workflow_state.aidsInfo.get(aid.name); const client = workflow_state.clients.get(tmpAidData.agent.name); return yield client.identifiers().get(identifierData.name); }))); (0, assert_1.strict)(multisigAids.every((aid) => aid.prefix === multisigAids[0].prefix)); (0, assert_1.strict)(multisigAids.every((aid) => aid.name === multisigAids[0].name)); const multisigAid = multisigAids[0]; // Skip if they have already been authorized. let oobis = yield Promise.all(issuerAids.map((aid) => __awaiter(void 0, void 0, void 0, function* () { const tmpAidData = workflow_state.aidsInfo.get(aid.name); const client = workflow_state.clients.get(tmpAidData.agent.name); return yield client.oobis().get(multisigAid.name, 'agent'); }))); if (oobis.some((oobi) => oobi.oobis.length == 0)) { const timestamp = (0, test_util_js_1.createTimestamp)(); // Add endpoint role for all clients const roleOps = yield Promise.all(issuerAids.map((aid, index) => __awaiter(void 0, void 0, void 0, function* () { const otherAids = issuerAids.filter((_, i) => i !== index); const tmpAidData = workflow_state.aidsInfo.get(aid.name); const client = workflow_state.clients.get(tmpAidData.agent.name); return yield (0, multisig_utils_js_1.addEndRoleMultisig)(client, multisigAid.name, aid, otherAids, multisigAid, timestamp, index === 0); }))); // Wait for all role operations to complete for each client! for (const [i, roleOpGroup] of roleOps.entries()) { for (const roleOp of roleOpGroup) { const tmpAidData = workflow_state.aidsInfo.get(issuerAids[i].name); const client = workflow_state.clients.get(tmpAidData.agent.name); yield (0, test_util_js_1.waitOperation)(client, roleOp); } } // Wait for role resolution notifications for all clients // await waitAndMarkNotification(workflow_state.clients.get(workflow_state.aidsInfo.get(issuerAids[0].name).agent.name), "/multisig/rpy"); yield Promise.all(issuerAids.map((aid) => { const tmpAidData = workflow_state.aidsInfo.get(aid.name); const client = workflow_state.clients.get(tmpAidData.agent.name); return (0, test_util_js_1.waitAndMarkNotification)(client, '/multisig/rpy'); })); // Retrieve the OOBI again after the operation for all clients oobis = yield Promise.all(issuerAids.map((aid) => __awaiter(void 0, void 0, void 0, function* () { const tmpAidData = workflow_state.aidsInfo.get(aid.name); const client = workflow_state.clients.get(tmpAidData.agent.name); return yield client.oobis().get(multisigAid.name, 'agent'); }))); } // Ensure that all OOBIs are consistent across all clients (0, assert_1.strict)(oobis.every((oobi) => oobi.role === oobis[0].role)); (0, assert_1.strict)(oobis.every((oobi) => oobi.oobis[0] === oobis[0].oobis[0])); const oobi = oobis[0].oobis[0].split('/agent/')[0]; const clients = Array.from(workflow_state.clients.values()).flat(); yield Promise.all(clients.map((client) => __awaiter(void 0, void 0, void 0, function* () { return yield (0, test_util_js_1.getOrCreateContact)(client, multisigAid.name, oobi); }))); console.log(`${identifierData.name} AID: ${multisigAid.prefix}`); return multisigAid; } }), createRegistryMultisig: (identifierData) => __awaiter(void 0, void 0, void 0, function* () { const multisigIdentifierData = identifierData; const workflow_state = workflow_state_js_1.WorkflowState.getInstance(); const multisigAid = workflow_state.aids.get(identifierData.name); const registryIdentifierName = `${identifierData.name}Registry`; const aidIdentifierNames = multisigIdentifierData.identifiers; const registries = new Array(); const issuerAids = aidIdentifierNames.map((aidIdentifierName) => workflow_state.aids.get(aidIdentifierName)) || []; // Check if the registries already exist for (const aidIdentifierName of aidIdentifierNames) { const singlesigIdentifierData = workflow_state.aidsInfo.get(aidIdentifierName); const client = workflow_state.clients.get(singlesigIdentifierData.agent.name); let tmpRegistry = yield client.registries().list(multisigAid.name); tmpRegistry = tmpRegistry.filter((reg) => reg.name == `${identifierData.name}Registry`); registries.push(tmpRegistry); } // Check if registries exist const allEmpty = registries.every((registry) => registry.length === 0); if (allEmpty) { const nonce = signify_ts_1.default.randomNonce(); const registryOps = issuerAids.map((aid, index) => { const tmpAidData = workflow_state.aidsInfo.get(aid.name); const otherAids = issuerAids.filter((_, i) => i !== index); const client = workflow_state.clients.get(tmpAidData.agent.name); return (0, multisig_utils_js_1.createRegistryMultisig)(client, aid, otherAids, multisigAid, registryIdentifierName, nonce, index === 0 // Use true for the first operation, false for others ); }); // Await all registry creation operations const createdOps = yield Promise.all(registryOps); // Wait for all operations to complete across multiple clients yield Promise.all(createdOps.map((op, index) => __awaiter(void 0, void 0, void 0, function* () { const tmpAidData = workflow_state.aidsInfo.get(issuerAids[index].name); const client = workflow_state.clients.get(tmpAidData.agent.name); return yield (0, test_util_js_1.waitOperation)(client, op); }))); // Wait for multisig inception notification for each client! const tmpAidData = workflow_state.aidsInfo.get(issuerAids[0].name); yield (0, test_util_js_1.waitAndMarkNotification)(workflow_state.clients.get(tmpAidData.agent.name), '/multisig/vcp'); // Recheck the registries for each client! const updatedRegistries = yield Promise.all(issuerAids.map((aid) => { const tmpAidData = workflow_state.aidsInfo.get(aid.name); const client = workflow_state.clients.get(tmpAidData.agent.name); return client.registries().list(multisigAid.name); })); // Update the `registries` array with the new values registries.splice(0, registries.length, ...updatedRegistries); // Ensure that all registries match the first one const firstRegistry = registries[0][0]; registries.forEach((registry) => { assert_1.strict.equal(registry[0].regk, firstRegistry.regk); assert_1.strict.equal(registry[0].name, firstRegistry.name); }); // Save the first registry and return it workflow_state.registries.set(multisigAid.name, firstRegistry); console.log(`${multisigAid.name} Registry created`); return firstRegistry; } else { return registries[0][0]; } }), getOrIssueCredential: (credId_1, credName_1, attributes_1, issuerAidKey_1, issueeAidKey_1, credSourceId_1, ...args_1) => __awaiter(void 0, [credId_1, credName_1, attributes_1, issuerAidKey_1, issueeAidKey_1, credSourceId_1, ...args_1], void 0, function* (credId, credName, attributes, issuerAidKey, issueeAidKey, credSourceId, generateTestData = false, testName = 'default_test') { return workflow_state_js_1.WorkflowState.getInstance().aidsInfo.get(issuerAidKey).type === 'multisig' ? yield exports.VleiIssuance.getOrIssueCredentialMultiSig(credId, credName, attributes, issuerAidKey, issueeAidKey, credSourceId, generateTestData, testName) : yield exports.VleiIssuance.getOrIssueCredentialSingleSig(credId, credName, attributes, issuerAidKey, issueeAidKey, credSourceId, generateTestData, testName); }), revokeCredential: (credId_2, issuerAidKey_2, issueeAidKey_2, ...args_2) => __awaiter(void 0, [credId_2, issuerAidKey_2, issueeAidKey_2, ...args_2], void 0, function* (credId, issuerAidKey, issueeAidKey, generateTestData = false, testName = 'default_test') { const workflow_state = workflow_state_js_1.WorkflowState.getInstance(); const issuerAidInfo = workflow_state.aidsInfo.get(issuerAidKey); if (issuerAidInfo.type === 'multisig') { return yield exports.VleiIssuance.revokeCredentialMultiSig(credId, issuerAidKey, issueeAidKey, generateTestData, testName); } else { return yield exports.VleiIssuance.revokeCredentialSingleSig(credId, issuerAidKey, issueeAidKey, generateTestData, testName); } }), getOrIssueCredentialSingleSig: (credId_3, credName_2, attributes_2, issuerAidKey_3, issueeAidKey_3, credSourceId_2, ...args_3) => __awaiter(void 0, [credId_3, credName_2, attributes_2, issuerAidKey_3, issueeAidKey_3, credSourceId_2, ...args_3], void 0, function* (credId, credName, attributes, issuerAidKey, issueeAidKey, credSourceId, generateTestData = false, testName = 'default_test') { const workflow_state = workflow_state_js_1.WorkflowState.getInstance(); const credInfo = workflow_state.credentialsInfo.get(credName); const issuerAID = workflow_state.aids.get(issuerAidKey); const recipientAID = workflow_state.aids.get(issueeAidKey); const issuerAIDInfo = workflow_state.aidsInfo.get(issuerAidKey); const recipientAIDInfo = workflow_state.aidsInfo.get(issueeAidKey); const issuerclient = workflow_state.clients.get(issuerAIDInfo.agent.name); const recipientclient = workflow_state.clients.get(recipientAIDInfo.agent.name); const issuerRegistry = workflow_state.registries.get(issuerAIDInfo.name); const schema = workflow_state.schemas[credInfo.schema]; const rules = workflow_state.rules[credInfo.rules]; const privacy = credInfo.privacy; let credSource = null; if (credSourceId != null) { const credType = credInfo.credSource['type']; const issuerCred = workflow_state.credentials.get(credSourceId); const credO = credInfo.credSource['o'] || null; credSource = exports.VleiIssuance.buildCredSource(credType, issuerCred, credO); } if (attributes['AID'] != null) { attributes.AID = workflow_state.aids.get(attributes['AID']).prefix; } const credData = Object.assign(Object.assign({}, credInfo.attributes), attributes); const cred = yield (0, test_util_js_1.getOrIssueCredential)(issuerclient, issuerAID, recipientAID, issuerRegistry, credData, schema, rules || undefined, credSource || undefined, (0, mathjs_1.boolean)(privacy || false)); let credHolder = yield (0, test_util_js_1.getReceivedCredential)(recipientclient, cred.sad.d); if (!credHolder) { yield (0, test_util_js_1.sendGrantMessage)(issuerclient, issuerAID, recipientAID, cred); yield (0, test_util_js_1.sendAdmitMessage)(recipientclient, recipientAID, issuerAID); credHolder = yield (0, retry_js_1.retry)(() => __awaiter(void 0, void 0, void 0, function* () { const cCred = yield (0, test_util_js_1.getReceivedCredential)(recipientclient, cred.sad.d); (0, assert_1.strict)(cCred !== undefined); return cCred; }), constants_js_1.CRED_RETRY_DEFAULTS); } assert_1.strict.equal(credHolder.sad.d, cred.sad.d); assert_1.strict.equal(credHolder.sad.s, schema); assert_1.strict.equal(credHolder.sad.i, issuerAID.prefix); assert_1.strict.equal(credHolder.sad.a.i, recipientAID.prefix); assert_1.strict.equal(credHolder.status.s, '0'); (0, assert_1.strict)(credHolder.atc !== undefined); workflow_state.credentials.set(credId, cred); const credCesr = yield recipientclient.credentials().get(cred.sad.d, true); if (generateTestData) { const tmpCred = cred; const testData = { aid: recipientAID.prefix, lei: credData.LEI, credential: { raw: tmpCred, cesr: credCesr }, engagementContextRole: credData.engagementContextRole || credData.officialRole, }; yield (0, generate_test_data_js_1.buildTestData)(testData, testName, issueeAidKey); } const response = { roleClient: recipientclient, ecrAid: recipientAID, creds: { [credId]: { cred: cred, credCesr: credCesr } }, idAlias: issueeAidKey, }; return [response, credData.engagementContextRole]; }), getOrIssueCredentialMultiSig: (credId_4, credName_3, attributes_3, issuerAidKey_4, issueeAidKey_4, credSourceId_3, ...args_4) => __awaiter(void 0, [credId_4, credName_3, attributes_3, issuerAidKey_4, issueeAidKey_4, credSourceId_3, ...args_4], void 0, function* (credId, credName, attributes, issuerAidKey, issueeAidKey, credSourceId, _generateTestData = false, _testName = 'default_test') { const workflow_state = workflow_state_js_1.WorkflowState.getInstance(); const credInfo = workflow_state.credentialsInfo.get(credName); const issuerAidInfo = workflow_state.aidsInfo.get(issuerAidKey); const recipientAidInfo = workflow_state.aidsInfo.get(issueeAidKey); const issuerAIDMultisig = workflow_state.aids.get(issuerAidKey); const recipientAID = workflow_state.aids.get(issueeAidKey); const schema = workflow_state.schemas[credInfo.schema]; let rules = workflow_state.rules[credInfo.rules]; const privacy = credInfo.privacy; const registryName = issuerAidInfo.name; const issuerRegistry = workflow_state.registries.get(registryName); const issuerAids = issuerAidInfo.identifiers.map((identifier) => workflow_state.aids.get(identifier)) || []; let recepientAids = []; if (recipientAidInfo.type === 'multisig') { const multisigIdentifierData = recipientAidInfo; recepientAids = multisigIdentifierData.identifiers.map((identifier) => workflow_state.aids.get(identifier)) || []; } else { recepientAids = [workflow_state.aids.get(recipientAidInfo.name)]; } let credSource = null; if (credSourceId != null) { const credType = credInfo.credSource['type']; const issuerCred = workflow_state.credentials.get(credSourceId); const credO = credInfo.credSource['o'] || null; credSource = exports.VleiIssuance.buildCredSource(credType, issuerCred, credO); credSource = credSource ? { e: credSource } : undefined; } rules = rules ? { r: rules } : undefined; // Issuing a credential let creds = yield Promise.all(issuerAids.map((aid) => { const identifierData = workflow_state.aidsInfo.get(aid.name); const singlesigData = identifierData; const client = workflow_state.clients.get(singlesigData.agent.name); return (0, test_util_js_1.getIssuedCredential)(client, issuerAIDMultisig, recipientAID, schema); })); if (creds.every((cred) => !cred)) { if (attributes['AID'] != null) { attributes.AID = workflow_state.aids.get(attributes['AID']).prefix; } const credData = Object.assign(Object.assign({}, credInfo.attributes), attributes); const kargsSub = Object.assign({ i: recipientAID.prefix, dt: (0, test_util_js_1.createTimestamp)(), u: privacy ? new signify_ts_1.default.Salter({}).qb64 : undefined }, credData); const kargsIss = Object.assign(Object.assign({ i: issuerAIDMultisig.prefix, ri: issuerRegistry.regk, s: schema, a: kargsSub, u: privacy ? new signify_ts_1.default.Salter({}).qb64 : undefined }, credSource), rules); const IssOps = yield Promise.all(issuerAids.map((aid, index) => { const identifierData = workflow_state.aidsInfo.get(aid.name); const singlesigData = identifierData; const client = workflow_state.clients.get(singlesigData.agent.name); return (0, multisig_utils_js_1.issueCredentialMultisig)(client, aid, issuerAids.filter((_, i) => i !== index), issuerAIDMultisig.name, kargsIss, index === 0); })); yield Promise.all(issuerAids.map((aid, index) => { const singlesigData = workflow_state.aidsInfo.get(aid.name); const client = workflow_state.clients.get(singlesigData.agent.name); return (0, test_util_js_1.waitOperation)(client, IssOps[index]); })); let tmpAidData = workflow_state.aidsInfo.get(issuerAids[0].name); yield (0, test_util_js_1.waitAndMarkNotification)(workflow_state.clients.get(tmpAidData.agent.name), '/multisig/iss'); creds = yield Promise.all(issuerAids.map((aid) => { const singlesigData = workflow_state.aidsInfo.get(aid.name); const client = workflow_state.clients.get(singlesigData.agent.name); return (0, test_util_js_1.getIssuedCredential)(client, issuerAIDMultisig, recipientAID, schema); })); (0, test_util_js_1.sleep)(1000); const grantTime = (0, test_util_js_1.createTimestamp)(); yield Promise.all(creds.map((cred, index) => { const singlesigData = workflow_state.aidsInfo.get(issuerAids[index].name); const client = workflow_state.clients.get(singlesigData.agent.name); return (0, multisig_utils_js_1.grantMultisig)(client, issuerAids[index], issuerAids.filter((_, i) => i !== index), issuerAIDMultisig, recipientAID, cred, grantTime, index === 0); })); (0, test_util_js_1.sleep)(1000); tmpAidData = workflow_state.aidsInfo.get(issuerAids[0].name); yield (0, test_util_js_1.waitAndMarkNotification)(workflow_state.clients.get(tmpAidData.agent.name), '/multisig/exn'); } const cred = creds[0]; // Exchange grant and admit messages. // Check if the recipient is a singlesig AID if (recipientAidInfo.type === 'multisig') { let credsReceived = yield Promise.all(recepientAids.map((aid) => { const singlesigData = workflow_state.aidsInfo.get(aid.name); const client = workflow_state.clients.get(singlesigData.agent.name); return (0, test_util_js_1.getReceivedCredential)(client, cred.sad.d); })); if (credsReceived.every((cred) => cred === undefined)) { const admitTime = (0, test_util_js_1.createTimestamp)(); yield Promise.all(recepientAids.map((aid, index) => { const singlesigData = workflow_state.aidsInfo.get(aid.name); const client = workflow_state.clients.get(singlesigData.agent.name); return (0, multisig_utils_js_1.admitMultisig)(client, aid, recepientAids.filter((_, i) => i !== index), recipientAID, issuerAIDMultisig, admitTime); })); (0, test_util_js_1.sleep)(2000); for (const aid of issuerAids) { const singlesigData = workflow_state.aidsInfo.get(aid.name); yield (0, test_util_js_1.waitAndMarkNotification)(workflow_state.clients.get(singlesigData.agent.name), '/exn/ipex/admit'); } for (const aid of recepientAids) { const singlesigData = workflow_state.aidsInfo.get(aid.name); yield (0, test_util_js_1.waitAndMarkNotification)(workflow_state.clients.get(singlesigData.agent.name), '/multisig/exn'); } for (const aid of recepientAids) { const singlesigData = workflow_state.aidsInfo.get(aid.name); yield (0, test_util_js_1.waitAndMarkNotification)(workflow_state.clients.get(singlesigData.agent.name), '/exn/ipex/admit'); } (0, test_util_js_1.sleep)(1000); credsReceived = yield Promise.all(recepientAids.map((aid) => { const singlesigData = workflow_state.aidsInfo.get(aid.name); const client = workflow_state.clients.get(singlesigData.agent.name); return (0, test_util_js_1.waitForCredential)(client, cred.sad.d); })); // Assert received credential details for (const credReceived of credsReceived) { assert_1.strict.equal(cred.sad.d, credReceived.sad.d); } } } else { const singlesigData = workflow_state.aidsInfo.get(recepientAids[0].name); let credReceived = yield (0, test_util_js_1.getReceivedCredential)(workflow_state.clients.get(singlesigData.agent.name), cred.sad.d); if (!credReceived) { yield (0, test_util_js_1.admitSinglesig)(workflow_state.clients.get(singlesigData.agent.name), workflow_state.aids.get(recepientAids[0].name).name, issuerAIDMultisig); (0, test_util_js_1.sleep)(2000); for (const aid of issuerAids) { const singlesigData = workflow_state.aidsInfo.get(aid.name); yield (0, test_util_js_1.waitAndMarkNotification)(workflow_state.clients.get(singlesigData.agent.name), '/exn/ipex/admit'); } credReceived = yield (0, test_util_js_1.waitForCredential)(workflow_state.clients.get(singlesigData.agent.name), cred.sad.d); } assert_1.strict.equal(cred.sad.d, credReceived.sad.d); } console.log(`${issuerAIDMultisig.name} has issued a ${recipientAID.name} vLEI credential with SAID:`, cred.sad.d); workflow_state.credentials.set(credId, cred); return [cred, null]; }), revokeCredentialSingleSig: (credId_5, issuerAidKey_5, issueeAidKey_5, ...args_5) => __awaiter(void 0, [credId_5, issuerAidKey_5, issueeAidKey_5, ...args_5], void 0, function* (credId, issuerAidKey, issueeAidKey, generateTestData = false, testName = 'default_test') { const workflow_state = workflow_state_js_1.WorkflowState.getInstance(); const cred = workflow_state.credentials.get(credId); const issuerAID = workflow_state.aids.get(issuerAidKey); const recipientAID = workflow_state.aids.get(issueeAidKey); const issuerAIDInfo = workflow_state.aidsInfo.get(issuerAidKey); const recipientAIDInfo = workflow_state.aidsInfo.get(issueeAidKey); const recipientclient = workflow_state.clients.get(recipientAIDInfo.agent.name); const issuerclient = workflow_state.clients.get(issuerAIDInfo.agent.name); const revCred = yield (0, test_util_js_1.revokeCredential)(issuerclient, issuerAID, cred.sad.d); workflow_state.credentials.set(credId, revCred); const credCesr = yield issuerclient.credentials().get(revCred.sad.d, true); if (generateTestData) { const tmpCred = revCred; const testData = { aid: recipientAID.prefix, lei: revCred.sad.a.LEI, credential: { raw: tmpCred, cesr: credCesr }, engagementContextRole: revCred.sad.a.engagementContextRole || revCred.sad.a.officialRole, }; yield (0, generate_test_data_js_1.buildTestData)(testData, testName, issueeAidKey, 'revoked_'); } const response = { roleClient: recipientclient, ecrAid: recipientAID, creds: { credId: { cred: cred, credCesr: credCesr } }, idAlias: issueeAidKey, }; return [response, revCred.sad.a.engagementContextRole]; }), revokeCredentialMultiSig: (credId_6, issuerAidKey_6, issueeAidKey_6, ...args_6) => __awaiter(void 0, [credId_6, issuerAidKey_6, issueeAidKey_6, ...args_6], void 0, function* (credId, issuerAidKey, issueeAidKey, generateTestData = false, testName = 'default_test') { const workflow_state = workflow_state_js_1.WorkflowState.getInstance(); const recipientAID = workflow_state.aids.get(issueeAidKey); const cred = workflow_state.credentials.get(credId); const issuerAidInfo = workflow_state.aidsInfo.get(issuerAidKey); const issuerAIDMultisig = workflow_state.aids.get(issuerAidKey); const issuerAids = issuerAidInfo.identifiers.map((identifier) => workflow_state.aids.get(identifier)) || []; let issuerclient; const revOps = []; let i = 0; const REVTIME = new Date().toISOString().replace('Z', '000+00:00'); for (const issuerAid of issuerAids) { const aidInfo = workflow_state.aidsInfo.get(issuerAid.name); issuerclient = workflow_state.clients.get(aidInfo.agent.name); if (i != 0) { const msgSaid = yield (0, test_util_js_1.waitAndMarkNotification)(issuerclient, '/multisig/rev'); console.log(`Multisig AID ${issuerAid.name} received exchange message to join the credential revocation event`); yield issuerclient.groups().getRequest(msgSaid); } const revResult = yield issuerclient .credentials() .revoke(issuerAIDMultisig.name, cred.sad.d, REVTIME); revOps.push([issuerclient, revResult.op]); yield (0, multisig_utils_js_1.multisigRevoke)(issuerclient, issuerAid.name, issuerAIDMultisig.name, revResult.rev, revResult.anc); i += 1; } for (const [client, op] of revOps) { yield (0, test_util_js_1.waitOperation)(client, op); } const revCred = yield issuerclient.credentials().get(cred.sad.d); workflow_state.credentials.set(credId, revCred); if (generateTestData) { const tmpCred = revCred; const credCesr = yield issuerclient .credentials() .get(revCred.sad.d, true); const testData = { aid: recipientAID.prefix, lei: revCred.sad.a.LEI, credential: { raw: tmpCred, cesr: credCesr }, engagementContextRole: revCred.sad.a.engagementContextRole || revCred.sad.a.officialRole, }; yield (0, generate_test_data_js_1.buildTestData)(testData, testName, issueeAidKey, 'revoked_'); } return [revCred, null]; }), notifyCredentialIssuee: (credId, issuerAidKey, issueeAidKey) => __awaiter(void 0, void 0, void 0, function* () { const workflow_state = workflow_state_js_1.WorkflowState.getInstance(); const cred = workflow_state.credentials.get(credId); if (!cred) { console.log(`notifyCredential: credential with credId=${credId} was not found`); throw new Error(`notifyCredential: credential with credId=${credId} was not found`); } const issuerAID = workflow_state.aids.get(issuerAidKey); const recipientAID = workflow_state.aids.get(issueeAidKey); const issuerAIDInfo = workflow_state.aidsInfo.get(issuerAidKey); const recipientAIDInfo = workflow_state.aidsInfo.get(issueeAidKey); if (issuerAIDInfo.type === 'multisig') { const multisigIdentifierData = issuerAIDInfo; const schema = workflow_state.schemas[cred.schema]; const issuerAids = multisigIdentifierData.identifiers.map((identifier) => workflow_state.aids.get(identifier)) || []; const creds = yield Promise.all(issuerAids.map((aid) => { const singlesigIdentifierData = workflow_state.aidsInfo.get(aid.name); const client = workflow_state.clients.get(singlesigIdentifierData.agent.name); return (0, test_util_js_1.getIssuedCredential)(client, issuerAID, recipientAID, schema); })); (0, test_util_js_1.sleep)(1000); const grantTime = (0, test_util_js_1.createTimestamp)(); yield Promise.all(creds.map((cred, index) => { const singlesigIdentifierData = workflow_state.aidsInfo.get(issuerAids[index].name); const client = workflow_state.clients.get(singlesigIdentifierData.agent.name); return (0, multisig_utils_js_1.grantMultisig)(client, issuerAids[index], issuerAids.filter((_, i) => i !== index), issuerAID, recipientAID, cred, grantTime, index === 0); })); } else { const singlesigIdentifierData = issuerAIDInfo; const issuerclient = workflow_state.clients.get(singlesigIdentifierData.agent.name); yield (0, test_util_js_1.sendGrantMessage)(issuerclient, issuerAID, recipientAID, cred); } if (recipientAIDInfo.type === 'multisig') { const multisigRecipientIdentifierData = recipientAIDInfo; const multisigIssuerIdentifierData = issuerAIDInfo; const admitTime = (0, test_util_js_1.createTimestamp)(); const issuerAids = multisigIssuerIdentifierData.identifiers.map((identifier) => workflow_state.aids.get(identifier)) || []; const recepientAids = multisigRecipientIdentifierData.identifiers.map((identifier) => workflow_state.aids.get(identifier)) || []; yield Promise.all(recepientAids.map((aid, index) => { const singlesigIdentifierData = workflow_state.aidsInfo.get(aid.name); const client = workflow_state.clients.get(singlesigIdentifierData.agent.name); return (0, multisig_utils_js_1.admitMultisig)(client, aid, recepientAids.filter((_, i) => i !== index), recipientAID, issuerAID, admitTime); })); (0, test_util_js_1.sleep)(2000); for (const aid of issuerAids) { const singlesigIdentifierData = workflow_state.aidsInfo.get(aid.name); yield (0, test_util_js_1.waitAndMarkNotification)(workflow_state.clients.get(singlesigIdentifierData.agent.name), '/exn/ipex/admit'); } for (const aid of recepientAids) { const singlesigIdentifierData = workflow_state.aidsInfo.get(aid.name); yield (0, test_util_js_1.waitAndMarkNotification)(workflow_state.clients.get(singlesigIdentifierData.agent.name), '/multisig/exn'); } for (const aid of recepientAids) { const singlesigIdentifierData = workflow_state.aidsInfo.get(aid.name); yield (0, test_util_js_1.waitAndMarkNotification)(workflow_state.clients.get(singlesigIdentifierData.agent.name), '/exn/ipex/admit'); } (0, test_util_js_1.sleep)(1000);