UNPKG

@sphereon/ssi-sdk.data-store

Version:

165 lines • 8.42 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()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.DigitalCredentialStore = void 0; const AbstractDigitalCredentialStore_1 = require("./AbstractDigitalCredentialStore"); const types_1 = require("../types"); const debug_1 = __importDefault(require("debug")); const DigitalCredentialEntity_1 = require("../entities/digitalCredential/DigitalCredentialEntity"); const MappingUtils_1 = require("../utils/digitalCredential/MappingUtils"); const SortingUtils_1 = require("../utils/SortingUtils"); const debug = (0, debug_1.default)('sphereon:ssi-sdk:credential-store'); class DigitalCredentialStore extends AbstractDigitalCredentialStore_1.AbstractDigitalCredentialStore { constructor(dbConnection) { super(); this.addCredential = (args) => __awaiter(this, void 0, void 0, function* () { debug('Adding credential', args); const credentialEntity = (0, MappingUtils_1.nonPersistedDigitalCredentialEntityFromAddArgs)(args); const validationError = this.assertValidDigitalCredential(credentialEntity); if (validationError) { return Promise.reject(validationError); } const dcRepo = yield this.getRepository(); const createdResult = yield dcRepo.save(credentialEntity); return Promise.resolve((0, MappingUtils_1.digitalCredentialFrom)(createdResult)); }); this.getCredential = (args) => __awaiter(this, void 0, void 0, function* () { const dcRepo = yield this.getRepository(); const result = yield dcRepo.findOne({ where: args, }); if (!result) { return Promise.reject(Error(`No credential found for arg: ${JSON.stringify(args)}`)); } return (0, MappingUtils_1.digitalCredentialFrom)(result); }); this.getCredentials = (args) => __awaiter(this, void 0, void 0, function* () { const { filter = {}, offset, limit, order = 'createdAt.asc' } = args !== null && args !== void 0 ? args : {}; const sortOptions = order && typeof order === 'string' ? (0, SortingUtils_1.parseAndValidateOrderOptions)(order) : order; const dcRepo = yield this.getRepository(); const [result, total] = yield dcRepo.findAndCount({ where: filter, skip: offset, take: limit, order: sortOptions, }); return { data: (0, MappingUtils_1.digitalCredentialsFrom)(result), total, }; }); this.removeCredential = (args) => __awaiter(this, void 0, void 0, function* () { if (!args) { return false; } let query = {}; if ('id' in args) { query.id = args.id; } else if ('hash' in args) { query.hash = args.hash; } else { return false; } try { const dcRepo = yield this.getRepository(); // TODO create a flag whether we want to delete recursively or return an error when there are child credentials? const affected = yield this.deleteTree(dcRepo, query); return affected > 0; } catch (error) { console.error('Error removing digital credential:', error); return false; } }); this.updateCredentialState = (args) => __awaiter(this, void 0, void 0, function* () { const credentialRepository = (yield this.dbConnection).getRepository(DigitalCredentialEntity_1.DigitalCredentialEntity); const whereClause = {}; if ('id' in args) { whereClause.id = args.id; } else if ('hash' in args) { whereClause.hash = args.hash; } else { throw new Error('No id or hash param is provided.'); } if (!args.verifiedState) { throw new Error('No verifiedState param is provided.'); } if (args.verifiedState === types_1.CredentialStateType.REVOKED && !args.revokedAt) { throw new Error('No revokedAt param is provided.'); } if (args.verifiedState !== types_1.CredentialStateType.REVOKED && !args.verifiedAt) { throw new Error('No verifiedAt param is provided.'); } const credential = yield credentialRepository.findOne({ where: whereClause, }); if (!credential) { return Promise.reject(Error(`No credential found for args: ${JSON.stringify(whereClause)}`)); } const updatedCredential = Object.assign(Object.assign(Object.assign(Object.assign({}, credential), (args.verifiedState !== types_1.CredentialStateType.REVOKED && { verifiedAt: args.verifiedAt })), (args.verifiedState === types_1.CredentialStateType.REVOKED && { revokedAt: args.revokedAt })), { identifierMethod: credential.identifierMethod, lastUpdatedAt: new Date(), verifiedState: args.verifiedState }); debug('Updating credential', credential); const updatedResult = yield credentialRepository.save(updatedCredential, { transaction: true }); return (0, MappingUtils_1.digitalCredentialFrom)(updatedResult); }); this.dbConnection = dbConnection; } deleteTree(dcRepo, query) { return __awaiter(this, void 0, void 0, function* () { let affected = 0; const findResult = yield dcRepo.findBy(query); for (const dc of findResult) { affected += yield this.deleteTree(dcRepo, { parentId: dc.id }); const result = yield dcRepo.delete(dc.id); if (result.affected) { affected += result.affected; } } return affected; }); } getRepository() { return __awaiter(this, void 0, void 0, function* () { if (this.dcRepo !== undefined) { return Promise.resolve(this.dcRepo); } this.dcRepo = (yield this.dbConnection).getRepository(DigitalCredentialEntity_1.DigitalCredentialEntity); if (this.dcRepo === undefined) { return Promise.reject(Error('Could not get DigitalCredentialEntity repository')); } return this.dcRepo; }); } assertValidDigitalCredential(credentialEntity) { const { kmsKeyRef, identifierMethod, credentialRole, isIssuerSigned } = credentialEntity; const isRoleInvalid = credentialRole === types_1.CredentialRole.ISSUER || (credentialRole === types_1.CredentialRole.HOLDER && !isIssuerSigned); if (isRoleInvalid && (!kmsKeyRef || !identifierMethod)) { const missingFields = []; if (!kmsKeyRef) missingFields.push('kmsKeyRef'); if (!identifierMethod) missingFields.push('identifierMethod'); const fields = missingFields.join(' and '); return new Error(`DigitalCredential field(s) ${fields} is/are required for credential role ${credentialRole} with isIssuerSigned=${isIssuerSigned}.`); } return undefined; } } exports.DigitalCredentialStore = DigitalCredentialStore; //# sourceMappingURL=DigitalCredentialStore.js.map