import { v4 as uuidv4 } from 'uuid'; import User from 'src/sdk/User'; import AbstractService from './AbstractService'; import RuleService from './RuleService'; export default class RoleService extends AbstractService { private constructor() { super(); } public static createRole(roleData: any, validatorId: string): Promise { const ownerId = User.getInstance().getPairingId()!; const processData: any = { uid: uuidv4(), utype: 'role', isDeleted: 'false', created_at: new Date().toISOString(), updated_at: new Date().toISOString(), ...roleData, }; const privateFields: string[] = Object.keys(processData); privateFields.splice(privateFields.indexOf('uid'), 1); privateFields.splice(privateFields.indexOf('utype'), 1); privateFields.splice(privateFields.indexOf('isDeleted'), 1); const roles: any = { demiurge: { members: [...[ownerId], validatorId], validation_rules: [], storages: [] }, owner: { members: [ownerId], validation_rules: [ { quorum: 0.5, fields: [...privateFields, 'roles', 'uid', 'utype'], min_sig_member: 1, }, ], storages: [] }, validator: { members: [validatorId], validation_rules: [ { quorum: 0.5, fields: ['idCertified', 'roles'], min_sig_member: 1, }, { quorum: 0.0, fields: [...privateFields], min_sig_member: 0, }, ], storages: [] }, apophis: { members: [ownerId], validation_rules: [], storages: [] } }; return new Promise((resolve: (processCreated: any) => void, reject: (error: string) => void) => { this.messageBus.createProcess(processData, privateFields, roles).then((processCreated: any) => { this.messageBus.notifyUpdate(processCreated.processId, processCreated.process.states[0].state_id).then(() => { this.messageBus.validateState(processCreated.processId, processCreated.process.states[0].state_id).then((_stateValidated: any) => { this.getRoleByUid(processCreated.processData.uid).then(resolve).catch(reject); }).catch(reject); }).catch(reject); }).catch(reject); }); } public static getRoles(): Promise { // Check if we have valid cache const items: any[] = this.getItems('_roles_'); return this.messageBus.getProcessesDecoded((publicValues: any) => publicValues['uid'] && publicValues['utype'] && publicValues['utype'] === 'role' && publicValues['isDeleted'] && publicValues['isDeleted'] === 'false' && !items.map((item: any) => item.processData.uid).includes(publicValues['uid']) ).then(async (processes: any[]) => { if (processes.length === 0) { return items; } else { for (let process of processes) { process = await this.completeRole(process); // Update cache this.setItem('_roles_', process); items.push(process); } return items; } }); } public static getRoleByUid(uid: string): Promise { // Check if we have valid cache const item: any = this.getItem('_roles_', uid); if (item) { return Promise.resolve(item); } return new Promise((resolve: (process: any) => void, reject: (error: string) => void) => { this.messageBus.getProcessesDecoded((publicValues: any) => publicValues['uid'] && publicValues['uid'] === uid && publicValues['utype'] && publicValues['utype'] === 'role' && publicValues['isDeleted'] && publicValues['isDeleted'] === 'false' ).then(async (processes: any[]) => { if (processes.length === 0) { resolve(null); } else { let process: any = processes[0]; process = await this.completeRole(process); // Update cache this.setItem('_roles_', process); resolve(process); } }).catch(reject); }); } public static updateRole(process: any, newData: any): Promise { return new Promise((resolve: () => void, reject: (error: string) => void) => { this.messageBus.updateProcess(process.processId, { updated_at: new Date().toISOString(), ...newData }, [], null).then((processUpdated: any) => { const newStateId: string = processUpdated.diffs[0]?.state_id; this.messageBus.notifyUpdate(process.processId, newStateId).then(() => { this.messageBus.validateState(process.processId, newStateId).then((_stateValidated) => { const roleUid: string = process.processData.uid; this.removeItem('_roles_', roleUid); this.getRoleByUid(roleUid).then(resolve).catch(reject); }).catch(reject); }).catch(reject); }).catch(reject); }); } private static async completeRole(process: any): Promise { /* if (process.processData.rules && process.processData.rules.length > 0) { process.processData.rules = await new Promise(async (resolve: (rules: any[]) => void) => { const rules: any[] = []; for (const rule of process.processData.rules) { rules.push((await RuleService.getRuleByUid(rule.uid)).processData); } resolve(rules); }); } */ return process; } }