@sphereon/ssi-sdk.data-store
Version:
165 lines • 8.42 kB
JavaScript
;
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