diff --git a/frontend/src/app/modules/analytics/compare-policy/compare-policy.component.ts b/frontend/src/app/modules/analytics/compare-policy/compare-policy.component.ts
index d370144a32..382064f0d2 100644
--- a/frontend/src/app/modules/analytics/compare-policy/compare-policy.component.ts
+++ b/frontend/src/app/modules/analytics/compare-policy/compare-policy.component.ts
@@ -48,6 +48,7 @@ export class ComparePolicyComponent implements OnInit {
"aggregateDocumentBlock": "calendar_month",
"reassigningBlock": "content_copy",
"revokeBlock": "restart_alt",
+ "revocationBlock": "restart_alt",
"setRelationshipsBlock": "settings",
"splitBlock": "content_cut",
"filtersAddon": "filter_alt",
diff --git a/frontend/src/app/modules/policy-engine/policy-configuration/common-properties/common-properties.component.html b/frontend/src/app/modules/policy-engine/policy-configuration/common-properties/common-properties.component.html
index 628e80d74c..00ca665b31 100644
--- a/frontend/src/app/modules/policy-engine/policy-configuration/common-properties/common-properties.component.html
+++ b/frontend/src/app/modules/policy-engine/policy-configuration/common-properties/common-properties.component.html
@@ -63,6 +63,13 @@
{{about.children}}
+
+ |
+ Deprecated |
+
+ {{about.deprecated?'Yes':'No'}}
+ |
+
diff --git a/frontend/src/app/modules/policy-engine/policy-configuration/policy-configuration/policy-configuration.component.ts b/frontend/src/app/modules/policy-engine/policy-configuration/policy-configuration/policy-configuration.component.ts
index bc53b11756..f7060a6ce5 100644
--- a/frontend/src/app/modules/policy-engine/policy-configuration/policy-configuration/policy-configuration.component.ts
+++ b/frontend/src/app/modules/policy-engine/policy-configuration/policy-configuration/policy-configuration.component.ts
@@ -479,7 +479,10 @@ export class PolicyConfigurationComponent implements OnInit {
this.componentsList.unGrouped = [];
const search = this.search ? this.search.toLowerCase() : null;
for (const block of all) {
- if (search && block.search.indexOf(search) === -1) {
+ if (
+ (search && block.search.indexOf(search) === -1) ||
+ block?.deprecated
+ ) {
continue;
}
if (block.header === 'UI Components') {
diff --git a/frontend/src/app/modules/policy-engine/policy-configuration/policy-tree/policy-tree.component.css b/frontend/src/app/modules/policy-engine/policy-configuration/policy-tree/policy-tree.component.css
index 98e8e80568..0917757c0a 100644
--- a/frontend/src/app/modules/policy-engine/policy-configuration/policy-tree/policy-tree.component.css
+++ b/frontend/src/app/modules/policy-engine/policy-configuration/policy-tree/policy-tree.component.css
@@ -455,6 +455,23 @@
grid-template-columns: auto 1px !important;
}
+.block-container[deprecated="true"] .block-item {
+ background-color: lightgray !important;
+ border-color: lightgray !important;
+}
+
+.block-container[deprecated="true"] .block-item::after {
+ content: "";
+ width: 110%;
+ height: 3px;
+ background-color: black;
+ position: absolute;
+ left: -5%;
+}
+
+.block-container[selected="true"][deprecated="true"] .block-item {
+ border-color: #5161e1 !important;
+}
.cdk-drag-animating {
transition: transform 50ms cubic-bezier(0, 0, 0.2, 1);
diff --git a/frontend/src/app/modules/policy-engine/policy-configuration/policy-tree/policy-tree.component.html b/frontend/src/app/modules/policy-engine/policy-configuration/policy-tree/policy-tree.component.html
index d15020c441..6c4730d866 100644
--- a/frontend/src/app/modules/policy-engine/policy-configuration/policy-tree/policy-tree.component.html
+++ b/frontend/src/app/modules/policy-engine/policy-configuration/policy-tree/policy-tree.component.html
@@ -15,7 +15,7 @@
[attr.collapsed]="item.collapsed" [attr.selected]="isSelect(item)" [attr.error]="item.error"
[attr.root]="item.root" [attr.block-id]="item.id" [attr.block-instance]="item.node.tag"
[attr.block-type]="item.type" [style.paddingLeft]="item.offset" cdkDrag [cdkDragData]="item.level"
- [cdkDragDisabled]="item.root">
+ [cdkDragDisabled]="item.root" [attr.deprecated]="item.deprecated">
arrow_drop_down
diff --git a/frontend/src/app/modules/policy-engine/policy-configuration/policy-tree/policy-tree.component.ts b/frontend/src/app/modules/policy-engine/policy-configuration/policy-tree/policy-tree.component.ts
index c8af82de9f..543c260282 100644
--- a/frontend/src/app/modules/policy-engine/policy-configuration/policy-tree/policy-tree.component.ts
+++ b/frontend/src/app/modules/policy-engine/policy-configuration/policy-tree/policy-tree.component.ts
@@ -220,6 +220,7 @@ export class PolicyTreeComponent implements OnInit {
node.level = level;
node.root = block === this.root;
node.expandable = block.expandable && !node.root;
+ node.deprecated = this.registeredService.getDeprecated(block.blockType);
node.about = this.registeredService.getAbout(block, this.module);
node.icon = this.registeredService.getIcon(block.blockType);
node.type = this.registeredService.getHeader(block.blockType);
diff --git a/frontend/src/app/modules/policy-engine/services/blocks-information.ts b/frontend/src/app/modules/policy-engine/services/blocks-information.ts
index 0f09a517ec..ad2ae8a9ec 100644
--- a/frontend/src/app/modules/policy-engine/services/blocks-information.ts
+++ b/frontend/src/app/modules/policy-engine/services/blocks-information.ts
@@ -82,6 +82,7 @@ const Container: IBlockSetting = {
{ type: BlockType.CustomLogicBlock },
{ type: BlockType.Report },
{ type: BlockType.RevokeBlock },
+ { type: BlockType.RevocationBlock },
{ type: BlockType.SetRelationshipsBlock },
{ type: BlockType.ButtonBlock },
{ type: BlockType.TokenActionBlock },
@@ -124,6 +125,7 @@ const Step: IBlockSetting = {
{ type: BlockType.CustomLogicBlock },
{ type: BlockType.Report },
{ type: BlockType.RevokeBlock },
+ { type: BlockType.RevocationBlock },
{ type: BlockType.SetRelationshipsBlock },
{ type: BlockType.ButtonBlock },
{ type: BlockType.TokenActionBlock },
@@ -378,6 +380,15 @@ const RevokeBlock: IBlockSetting = {
property: RevokeConfigComponent,
}
+const RevocationBlock: IBlockSetting = {
+ type: BlockType.RevocationBlock,
+ icon: 'restart_alt',
+ group: BlockGroup.Documents,
+ header: BlockHeaders.ServerBlocks,
+ factory: null,
+ property: null,
+}
+
const SetRelationshipsBlock: IBlockSetting = {
type: BlockType.SetRelationshipsBlock,
icon: 'settings',
@@ -625,6 +636,7 @@ export default [
AggregateDocument,
ReassigningBlock,
RevokeBlock,
+ RevocationBlock,
SetRelationshipsBlock,
SplitBlock,
FiltersAddon,
diff --git a/frontend/src/app/modules/policy-engine/services/module-information.ts b/frontend/src/app/modules/policy-engine/services/module-information.ts
index c39f5dd42b..39a9e5ec61 100644
--- a/frontend/src/app/modules/policy-engine/services/module-information.ts
+++ b/frontend/src/app/modules/policy-engine/services/module-information.ts
@@ -43,6 +43,7 @@ const Module: IBlockSetting = {
{ type: BlockType.CustomLogicBlock },
{ type: BlockType.Report },
{ type: BlockType.RevokeBlock },
+ { type: BlockType.RevocationBlock },
{ type: BlockType.SetRelationshipsBlock },
{ type: BlockType.ButtonBlock },
{ type: BlockType.TokenActionBlock },
diff --git a/frontend/src/app/modules/policy-engine/services/registered.service.ts b/frontend/src/app/modules/policy-engine/services/registered.service.ts
index 2fbbafa5f4..657e414a77 100644
--- a/frontend/src/app/modules/policy-engine/services/registered.service.ts
+++ b/frontend/src/app/modules/policy-engine/services/registered.service.ts
@@ -19,6 +19,7 @@ export class RegisteredService {
private blockName: { [type: string]: string };
private blockTitle: { [type: string]: string };
+ private blockDeprecation: { [type: string]: boolean };
private blockAbout: { [type: string]: BlockAbout };
private blockProperties: { [type: string]: BlockAbout };
@@ -38,6 +39,7 @@ export class RegisteredService {
this.blockTitle = {};
this.blockAbout = {};
this.blockProperties = {};
+ this.blockDeprecation = {};
this.defaultAbout = new BlockAbout({
post: false,
get: false,
@@ -45,7 +47,8 @@ export class RegisteredService {
output: null,
children: ChildrenType.None,
control: ControlType.None,
- defaultEvent: false
+ defaultEvent: false,
+ deprecated: false,
})
for (const config of blocks) {
@@ -103,6 +106,7 @@ export class RegisteredService {
this.blockTitle[type] = setting.title;
this.blockAbout[type] = new BlockAbout(setting, this.about[type]);
this.blockProperties[type] = setting.properties;
+ this.blockDeprecation[type] = !!setting.deprecated;
}
this.update();
}
@@ -119,7 +123,8 @@ export class RegisteredService {
group: this.group[type],
header: this.header[type],
title: this.blockTitle[type],
- data: `new:${type}`
+ data: `new:${type}`,
+ deprecated: this.blockDeprecation[type],
});
}
this.list = this.list.sort((a, b) => a.name > b.name ? 1 : -1);
@@ -181,4 +186,8 @@ export class RegisteredService {
public getHeader(blockType: string): string {
return this.header[blockType] || '';
}
-}
+
+ public getDeprecated(blockType: string): boolean {
+ return this.blockDeprecation[blockType];
+ }
+ }
diff --git a/frontend/src/app/modules/policy-engine/structures/interfaces/block-about-config.interface.ts b/frontend/src/app/modules/policy-engine/structures/interfaces/block-about-config.interface.ts
index 6972e856fd..7425d0aa5c 100644
--- a/frontend/src/app/modules/policy-engine/structures/interfaces/block-about-config.interface.ts
+++ b/frontend/src/app/modules/policy-engine/structures/interfaces/block-about-config.interface.ts
@@ -9,4 +9,5 @@ export interface IBlockAboutConfig {
children: ChildrenType;
control: ControlType;
defaultEvent: boolean;
+ deprecated?: boolean;
}
diff --git a/frontend/src/app/modules/policy-engine/structures/interfaces/block-about.interface.ts b/frontend/src/app/modules/policy-engine/structures/interfaces/block-about.interface.ts
index 603bd52ef8..d6447ace7d 100644
--- a/frontend/src/app/modules/policy-engine/structures/interfaces/block-about.interface.ts
+++ b/frontend/src/app/modules/policy-engine/structures/interfaces/block-about.interface.ts
@@ -11,4 +11,5 @@ export interface IBlockAbout {
defaultEvent: boolean;
prev?: IBlockAbout;
next?: boolean;
+ deprecated?: boolean;
}
diff --git a/frontend/src/app/modules/policy-engine/structures/interfaces/block-dynamic-about-config.interface.ts b/frontend/src/app/modules/policy-engine/structures/interfaces/block-dynamic-about-config.interface.ts
index d17bd066ac..0898109522 100644
--- a/frontend/src/app/modules/policy-engine/structures/interfaces/block-dynamic-about-config.interface.ts
+++ b/frontend/src/app/modules/policy-engine/structures/interfaces/block-dynamic-about-config.interface.ts
@@ -14,4 +14,5 @@ export interface IBlockDynamicAboutConfig {
children?: ConfigFunction;
control?: ConfigFunction;
defaultEvent?: ConfigFunction;
+ deprecated?: ConfigFunction;
}
diff --git a/frontend/src/app/modules/policy-engine/structures/policy-models/block-about.ts b/frontend/src/app/modules/policy-engine/structures/policy-models/block-about.ts
index fabc5ebdbb..9d14971731 100644
--- a/frontend/src/app/modules/policy-engine/structures/policy-models/block-about.ts
+++ b/frontend/src/app/modules/policy-engine/structures/policy-models/block-about.ts
@@ -34,6 +34,7 @@ export class BlockAbout {
this._setProp(about, dynamic, 'children');
this._setProp(about, dynamic, 'control');
this._setProp(about, dynamic, 'defaultEvent');
+ this._setProp(about, dynamic, 'deprecated');
}
public getAbout(
@@ -48,6 +49,7 @@ export class BlockAbout {
children: this._propFunc.children(this._propVal.children, block, module),
control: this._propFunc.control(this._propVal.control, block, module),
defaultEvent: this._propFunc.defaultEvent(this._propVal.defaultEvent, block, module),
+ deprecated: this._propFunc.deprecated(this._propVal.deprecated, block, module),
};
}
@@ -81,6 +83,9 @@ export class BlockAbout {
get defaultEvent() {
return this._func.defaultEvent(this._val.defaultEvent, this._block, this._module);
},
+ get deprecated() {
+ return this._func.defaultEvent(this._val.deprecated, this._block, this._module);
+ },
set module(value: PolicyModel | PolicyModuleModel) {
this._module = value;
},
diff --git a/frontend/src/app/modules/policy-engine/structures/tree-model/block-node.ts b/frontend/src/app/modules/policy-engine/structures/tree-model/block-node.ts
index 77759a5626..711763b09f 100644
--- a/frontend/src/app/modules/policy-engine/structures/tree-model/block-node.ts
+++ b/frontend/src/app/modules/policy-engine/structures/tree-model/block-node.ts
@@ -18,6 +18,7 @@ export class FlatBlockNode {
public parentNode!: FlatBlockNode;
public data!: any;
public error!: boolean;
+ public deprecated!: boolean;
constructor(node: PolicyBlockModel) {
this.node = node;
diff --git a/frontend/src/app/modules/policy-engine/themes/default.ts b/frontend/src/app/modules/policy-engine/themes/default.ts
index 281b32be67..5e0a787faf 100644
--- a/frontend/src/app/modules/policy-engine/themes/default.ts
+++ b/frontend/src/app/modules/policy-engine/themes/default.ts
@@ -48,6 +48,7 @@ export const defaultTheme = {
'reassigningBlock',
'httpRequestBlock',
'revokeBlock',
+ 'revocationBlock',
'sendToGuardianBlock',
'setRelationshipsBlock',
'splitBlock',
diff --git a/guardian-service/src/policy-engine/block-about.ts b/guardian-service/src/policy-engine/block-about.ts
index 893b7ebbf8..63e2890945 100644
--- a/guardian-service/src/policy-engine/block-about.ts
+++ b/guardian-service/src/policy-engine/block-about.ts
@@ -494,6 +494,23 @@ export const BlockAbout = {
'revokeBlock': {
'label': 'Revoke Document',
'title': 'Add \'Revoke\' Block',
+ 'post': true,
+ 'get': true,
+ 'children': 'None',
+ 'control': 'Server',
+ 'input': [
+ 'RunEvent'
+ ],
+ 'output': [
+ 'RunEvent',
+ 'ErrorEvent'
+ ],
+ 'defaultEvent': true,
+ 'deprecated': true,
+ },
+ 'revocationBlock': {
+ 'label': 'Revocation',
+ 'title': 'Add \'Revocation\' Block',
'post': false,
'get': false,
'children': 'None',
@@ -505,7 +522,23 @@ export const BlockAbout = {
'RunEvent',
'ErrorEvent'
],
- 'defaultEvent': true
+ 'defaultEvent': true,
+ 'properties': [
+ {
+ 'name': 'updatePrevDoc',
+ 'label': 'Update previous document status',
+ 'title': 'Update previous document status',
+ 'type': 'Checkbox',
+ 'default': false
+ },
+ {
+ 'name': 'prevDocStatus',
+ 'label': 'Status value',
+ 'title': 'Status value',
+ 'type': 'Input',
+ 'default': ''
+ },
+ ],
},
'setRelationshipsBlock': {
'label': 'Set Relationships',
diff --git a/guardian-service/src/policy-engine/block-validators/block-validator.ts b/guardian-service/src/policy-engine/block-validators/block-validator.ts
index d019ff5db1..a418bfaa28 100644
--- a/guardian-service/src/policy-engine/block-validators/block-validator.ts
+++ b/guardian-service/src/policy-engine/block-validators/block-validator.ts
@@ -31,6 +31,7 @@ import { ReportItemBlock } from './blocks/report-item-block';
import { RequestVcDocumentBlock } from './blocks/request-vc-document-block';
import { RetirementBlock } from './blocks/retirement-block';
import { RevokeBlock } from './blocks/revoke-block';
+import { RevocationBlock } from './blocks/revocation-block';
import { SelectiveAttributes } from './blocks/selective-attributes-addon';
import { SendToGuardianBlock } from './blocks/send-to-guardian-block';
import { SetRelationshipsBlock } from './blocks/set-relationships-block';
@@ -75,6 +76,7 @@ export const validators = [
RequestVcDocumentBlock,
RetirementBlock,
RevokeBlock,
+ RevocationBlock,
SelectiveAttributes,
SendToGuardianBlock,
SetRelationshipsBlock,
diff --git a/guardian-service/src/policy-engine/block-validators/blocks/revocation-block.ts b/guardian-service/src/policy-engine/block-validators/blocks/revocation-block.ts
new file mode 100644
index 0000000000..28a0cefb94
--- /dev/null
+++ b/guardian-service/src/policy-engine/block-validators/blocks/revocation-block.ts
@@ -0,0 +1,31 @@
+import { BlockValidator, IBlockProp } from '@policy-engine/block-validators';
+
+/**
+ * Revoke document action with UI
+ */
+export class RevocationBlock {
+ /**
+ * Block type
+ */
+ public static readonly blockType: string = 'revocationBlock';
+
+ /**
+ * Validate block options
+ * @param validator
+ * @param config
+ */
+ public static async validate(
+ validator: BlockValidator,
+ ref: IBlockProp
+ ): Promise {
+ try {
+ if (ref.options.updatePrevDoc && !ref.options.prevDocStatus) {
+ validator.addError('Option "Status Value" is not set');
+ }
+ } catch (error) {
+ validator.addError(
+ `Unhandled exception ${validator.getErrorMessage(error)}`
+ );
+ }
+ }
+}
diff --git a/guardian-service/src/policy-engine/policy-converter-utils.ts b/guardian-service/src/policy-engine/policy-converter-utils.ts
index 9b4dcb35de..cff57e20c9 100644
--- a/guardian-service/src/policy-engine/policy-converter-utils.ts
+++ b/guardian-service/src/policy-engine/policy-converter-utils.ts
@@ -1,6 +1,6 @@
import { Policy } from '@guardian/common';
-import { GenerateUUIDv4, UserType } from '@guardian/interfaces';
-import { EventActor, EventConfig, PolicyInputEventType, PolicyOutputEventType } from './interfaces';
+import { BlockType, GenerateUUIDv4, UserType } from '@guardian/interfaces';
+import { EventConfig, PolicyInputEventType, PolicyOutputEventType, EventActor } from './interfaces';
/**
* Policy converter utils
@@ -390,7 +390,7 @@ export class PolicyConverterUtils {
const currentBlock = stack.pop();
if (
currentBlock?.blockType ===
- 'interfaceDocumentsSourceBlock' &&
+ BlockType.DocumentsViewer &&
Array.isArray(currentBlock.uiMetaData?.fields)
) {
currentBlock.uiMetaData.fields =
@@ -404,6 +404,10 @@ export class PolicyConverterUtils {
}
};
clearOldRevokeColumns(root, block.tag);
+ block.blockType = BlockType.RevocationBlock;
+ block.updatePrevDoc = block.uiMetaData.updatePrevDoc;
+ block.prevDocStatus = block.uiMetaData.prevDocStatus;
+ delete block.uiMetaData;
return block;
}
}
diff --git a/interfaces/src/type/block.type.ts b/interfaces/src/type/block.type.ts
index 2f3aff3394..dbc005e50f 100644
--- a/interfaces/src/type/block.type.ts
+++ b/interfaces/src/type/block.type.ts
@@ -27,6 +27,7 @@ export enum BlockType {
CustomLogicBlock = 'customLogicBlock',
Switch = 'switchBlock',
RevokeBlock = 'revokeBlock',
+ RevocationBlock = 'revocationBlock',
SetRelationshipsBlock = 'setRelationshipsBlock',
ButtonBlock = 'buttonBlock',
TokenActionBlock = 'tokenActionBlock',
diff --git a/policy-service/src/policy-engine/block-tree-generator.ts b/policy-service/src/policy-engine/block-tree-generator.ts
index fb6aae33a1..b16699fc20 100644
--- a/policy-service/src/policy-engine/block-tree-generator.ts
+++ b/policy-service/src/policy-engine/block-tree-generator.ts
@@ -179,6 +179,11 @@ export class BlockTreeGenerator extends NatsService {
const block = PolicyComponentsUtils.GetBlockByTag(policyId, tag);
if (block && (await block.isAvailable(userFull))) {
+ if (typeof block.getData !== 'function') {
+ throw new Error(
+ 'Block is not supporting get data functions'
+ );
+ }
const data = await block.getData(userFull, block.uuid, null);
return new MessageResponse(data);
} else {
@@ -194,6 +199,11 @@ export class BlockTreeGenerator extends NatsService {
const block = PolicyComponentsUtils.GetBlockByUUID(blockId);
if (block && (await block.isAvailable(userFull))) {
+ if (typeof block.setData !== 'function') {
+ throw new Error(
+ 'Block is not supporting set data functions'
+ );
+ }
const result = await block.setData(userFull, data);
return new MessageResponse(result);
} else {
diff --git a/policy-service/src/policy-engine/block-validators/block-validator.ts b/policy-service/src/policy-engine/block-validators/block-validator.ts
index d019ff5db1..a418bfaa28 100644
--- a/policy-service/src/policy-engine/block-validators/block-validator.ts
+++ b/policy-service/src/policy-engine/block-validators/block-validator.ts
@@ -31,6 +31,7 @@ import { ReportItemBlock } from './blocks/report-item-block';
import { RequestVcDocumentBlock } from './blocks/request-vc-document-block';
import { RetirementBlock } from './blocks/retirement-block';
import { RevokeBlock } from './blocks/revoke-block';
+import { RevocationBlock } from './blocks/revocation-block';
import { SelectiveAttributes } from './blocks/selective-attributes-addon';
import { SendToGuardianBlock } from './blocks/send-to-guardian-block';
import { SetRelationshipsBlock } from './blocks/set-relationships-block';
@@ -75,6 +76,7 @@ export const validators = [
RequestVcDocumentBlock,
RetirementBlock,
RevokeBlock,
+ RevocationBlock,
SelectiveAttributes,
SendToGuardianBlock,
SetRelationshipsBlock,
diff --git a/policy-service/src/policy-engine/block-validators/blocks/revocation-block.ts b/policy-service/src/policy-engine/block-validators/blocks/revocation-block.ts
new file mode 100644
index 0000000000..28a0cefb94
--- /dev/null
+++ b/policy-service/src/policy-engine/block-validators/blocks/revocation-block.ts
@@ -0,0 +1,31 @@
+import { BlockValidator, IBlockProp } from '@policy-engine/block-validators';
+
+/**
+ * Revoke document action with UI
+ */
+export class RevocationBlock {
+ /**
+ * Block type
+ */
+ public static readonly blockType: string = 'revocationBlock';
+
+ /**
+ * Validate block options
+ * @param validator
+ * @param config
+ */
+ public static async validate(
+ validator: BlockValidator,
+ ref: IBlockProp
+ ): Promise {
+ try {
+ if (ref.options.updatePrevDoc && !ref.options.prevDocStatus) {
+ validator.addError('Option "Status Value" is not set');
+ }
+ } catch (error) {
+ validator.addError(
+ `Unhandled exception ${validator.getErrorMessage(error)}`
+ );
+ }
+ }
+}
diff --git a/policy-service/src/policy-engine/blocks/index.ts b/policy-service/src/policy-engine/blocks/index.ts
index 3c37a8f89d..7f723692f4 100644
--- a/policy-service/src/policy-engine/blocks/index.ts
+++ b/policy-service/src/policy-engine/blocks/index.ts
@@ -24,6 +24,7 @@ export { SendToGuardianBlock } from './send-to-guardian-block';
export { SwitchBlock } from './switch-block';
export { TimerBlock } from './timer-block';
export { RevokeBlock } from './revoke-block';
+export { RevocationBlock } from './revocation-block';
export { SetRelationshipsBlock } from './set-relationships-block';
export { ButtonBlock } from './button-block';
export { TokenActionBlock } from './token-action-block';
diff --git a/policy-service/src/policy-engine/blocks/revocation-block.ts b/policy-service/src/policy-engine/blocks/revocation-block.ts
new file mode 100644
index 0000000000..ff5dd4bbd6
--- /dev/null
+++ b/policy-service/src/policy-engine/blocks/revocation-block.ts
@@ -0,0 +1,272 @@
+import { ActionCallback, BasicBlock } from '@policy-engine/helpers/decorators';
+import { PolicyComponentsUtils } from '@policy-engine/policy-components-utils';
+import {
+ AnyBlockType,
+ IPolicyEventState,
+ IPolicyInterfaceBlock,
+} from '@policy-engine/policy-engine.interface';
+import { Message, MessageServer } from '@guardian/common';
+import { PolicyUtils } from '@policy-engine/helpers/utils';
+import {
+ IPolicyEvent,
+ PolicyInputEventType,
+ PolicyOutputEventType,
+} from '@policy-engine/interfaces';
+import {
+ ChildrenType,
+ ControlType,
+ PropertyType,
+} from '@policy-engine/interfaces/block-about';
+import { CatchErrors } from '@policy-engine/helpers/decorators/catch-errors';
+import {
+ ExternalDocuments,
+ ExternalEvent,
+ ExternalEventType,
+} from '@policy-engine/interfaces/external-event';
+
+export const RevokedStatus = 'Revoked';
+
+/**
+ * Revocation block
+ */
+@BasicBlock({
+ blockType: 'revocationBlock',
+ about: {
+ label: 'Revocation',
+ title: `Add 'Revocation' Block`,
+ post: false,
+ get: false,
+ children: ChildrenType.None,
+ control: ControlType.Server,
+ input: [PolicyInputEventType.RunEvent],
+ output: [
+ PolicyOutputEventType.RunEvent,
+ PolicyOutputEventType.ErrorEvent,
+ ],
+ defaultEvent: true,
+ properties: [
+ {
+ name: 'updatePrevDoc',
+ label: 'Update previous document status',
+ title: 'Update previous document status',
+ type: PropertyType.Checkbox,
+ default: false,
+ },
+ {
+ name: 'prevDocStatus',
+ label: 'Status value',
+ title: 'Status value',
+ type: PropertyType.Input,
+ default: '',
+ },
+ ],
+ },
+})
+export class RevocationBlock {
+ /**
+ * Send to hedera
+ * @param message
+ * @param messageServer
+ * @param ref
+ * @param revokeMessage
+ * @param parentId
+ */
+ async sendToHedera(
+ message: Message,
+ messageServer: MessageServer,
+ ref: AnyBlockType,
+ revokeMessage: string,
+ parentId?: string[]
+ ) {
+ const topic = await PolicyUtils.getPolicyTopic(ref, message.topicId);
+ message.revoke(revokeMessage, parentId);
+ await messageServer.setTopicObject(topic).sendMessage(message, false);
+ }
+
+ /**
+ * Find related message Ids
+ * @param topicMessage
+ * @param topicMessages
+ * @param relatedMessageIds
+ * @param parentId
+ */
+ async findRelatedMessageIds(
+ topicMessage: any,
+ topicMessages: any[],
+ relatedMessageIds: any[] = [],
+ parentId?: string
+ ): Promise {
+ if (!topicMessage) {
+ throw new Error('Topic message to find related messages is empty');
+ }
+ const relatedMessages = topicMessages.filter(
+ (message: any) =>
+ message.relationships &&
+ message.relationships.includes(topicMessage.id)
+ );
+ for (const relatedMessage of relatedMessages) {
+ await this.findRelatedMessageIds(
+ relatedMessage,
+ topicMessages,
+ relatedMessageIds,
+ topicMessage.id
+ );
+ }
+ const relatedMessageId = relatedMessageIds.find(
+ (item) => item.id === topicMessage.id
+ );
+ if (!relatedMessageId) {
+ relatedMessageIds.push({
+ parentIds: parentId ? [parentId] : undefined,
+ id: topicMessage.id,
+ });
+ } else if (
+ relatedMessageId.parentIds &&
+ !relatedMessageId.parentIds.includes(parentId)
+ ) {
+ relatedMessageId.parentIds.push(parentId);
+ }
+ return relatedMessageIds;
+ }
+
+ /**
+ * Find document by message ids
+ * @param messageIds
+ */
+ async findDocumentByMessageIds(messageIds: string[]): Promise {
+ const ref =
+ PolicyComponentsUtils.GetBlockRef(this);
+ const filters: any = {
+ messageId: { $in: messageIds },
+ };
+ const otherOptions = {
+ orderBy: {
+ messageId: 'ASC',
+ },
+ };
+ const vcDocuments: any[] = (await ref.databaseServer.getVcDocuments(
+ filters,
+ otherOptions
+ )) as any[];
+ const vpDocuments: any[] = (await ref.databaseServer.getVpDocuments(
+ filters,
+ otherOptions
+ )) as any[];
+ const didDocuments: any[] = (await ref.databaseServer.getDidDocuments(
+ filters,
+ otherOptions
+ )) as any[];
+ return vcDocuments.concat(vpDocuments).concat(didDocuments);
+ }
+
+ /**
+ * Run block action
+ * @param event
+ */
+ @ActionCallback({
+ output: [
+ PolicyOutputEventType.RunEvent,
+ PolicyOutputEventType.ErrorEvent,
+ ],
+ })
+ @CatchErrors()
+ async runAction(event: IPolicyEvent): Promise {
+ const ref =
+ PolicyComponentsUtils.GetBlockRef(this);
+ const data = event.data.data;
+ const doc = Array.isArray(data) ? data[0] : data;
+
+ const hederaAccount = await PolicyUtils.getHederaAccount(
+ ref,
+ event.user.did
+ );
+ const messageServer = new MessageServer(
+ hederaAccount.hederaAccountId,
+ hederaAccount.hederaAccountKey,
+ ref.dryRun
+ );
+ const policyTopics = await ref.databaseServer.getTopics({
+ policyId: ref.policyId,
+ });
+
+ const policyTopicsMessages = [];
+ for (const topic of policyTopics) {
+ const topicMessages = await messageServer.getMessages(
+ topic.topicId
+ );
+ policyTopicsMessages.push(...topicMessages);
+ }
+ const messagesToFind = policyTopicsMessages.filter(
+ (item) => !item.isRevoked()
+ );
+
+ const topicMessage = policyTopicsMessages.find(
+ (item) => item.id === doc.messageId
+ );
+
+ const relatedMessages = await this.findRelatedMessageIds(
+ topicMessage,
+ messagesToFind
+ );
+ for (const policyTopicMessage of policyTopicsMessages) {
+ const relatedMessage = relatedMessages.find(
+ (item) => item.id === policyTopicMessage.id
+ );
+ if (relatedMessage) {
+ await this.sendToHedera(
+ policyTopicMessage,
+ messageServer,
+ ref,
+ doc.comment,
+ relatedMessage.parentIds
+ );
+ }
+ }
+
+ const documents = await this.findDocumentByMessageIds(
+ relatedMessages.map((item) => item.id)
+ );
+ for (const item of documents) {
+ item.option = item.option || {};
+ item.option.status = RevokedStatus;
+ item.comment = doc.option.comment;
+ if (Array.isArray(item.comment)) {
+ item.comment = item.comment[item.comment.length - 1];
+ }
+ if (item.option.comment) {
+ if (Array.isArray(item.option.comment)) {
+ item.option.comment.push(item.comment);
+ }
+ } else {
+ item.option.comment = [item.comment];
+ }
+ }
+
+ if (ref.options.updatePrevDoc && doc.relationships) {
+ const prevDocs = await this.findDocumentByMessageIds(
+ doc.relationships
+ );
+ const prevDocument = prevDocs[prevDocs.length - 1];
+ if (prevDocument) {
+ prevDocument.option.status = ref.options.prevDocStatus;
+ await ref.databaseServer.updateVC(prevDocument);
+ await ref.databaseServer.saveDocumentState({
+ documentId: prevDocument.id,
+ document: prevDocument,
+ });
+ }
+ }
+
+ const state: IPolicyEventState = {
+ data: documents,
+ };
+ ref.triggerEvents(PolicyOutputEventType.RunEvent, event.user, state);
+ ref.triggerEvents(PolicyOutputEventType.ReleaseEvent, event.user, null);
+
+ PolicyComponentsUtils.ExternalEventFn(
+ new ExternalEvent(ExternalEventType.Run, ref, event?.user, {
+ documents: ExternalDocuments(documents),
+ })
+ );
+ }
+}
diff --git a/policy-service/src/policy-engine/blocks/revoke-block.ts b/policy-service/src/policy-engine/blocks/revoke-block.ts
index 68bb031ff6..b89f6b24b5 100644
--- a/policy-service/src/policy-engine/blocks/revoke-block.ts
+++ b/policy-service/src/policy-engine/blocks/revoke-block.ts
@@ -1,4 +1,4 @@
-import { ActionCallback, BasicBlock } from '@policy-engine/helpers/decorators';
+import { ActionCallback, EventBlock } from '@policy-engine/helpers/decorators';
import { PolicyComponentsUtils } from '@policy-engine/policy-components-utils';
import { AnyBlockType, IPolicyEventState, IPolicyInterfaceBlock } from '@policy-engine/policy-engine.interface';
import { Message, MessageServer } from '@guardian/common';
@@ -13,13 +13,13 @@ export const RevokedStatus = 'Revoked';
/**
* Revoke document action with UI
*/
-@BasicBlock({
+@EventBlock({
blockType: 'revokeBlock',
about: {
label: 'Revoke Document',
title: `Add 'Revoke' Block`,
- post: false,
- get: false,
+ post: true,
+ get: true,
children: ChildrenType.None,
control: ControlType.Server,
input: [
diff --git a/policy-service/src/policy-engine/helpers/decorators/basic-block.ts b/policy-service/src/policy-engine/helpers/decorators/basic-block.ts
index 9ebb7dcdfb..40a6e26cb1 100644
--- a/policy-service/src/policy-engine/helpers/decorators/basic-block.ts
+++ b/policy-service/src/policy-engine/helpers/decorators/basic-block.ts
@@ -248,28 +248,6 @@ export function BasicBlock(options: Partial) {
}
}
- /**
- * Get block data
- * @param args
- */
- async getData(...args) {
- if (typeof super.getData === 'function') {
- return await super.getData(...args);
- }
- return {};
- }
-
- /**
- * Set block data
- * @param args
- */
- async setData(...args) {
- if (typeof super.getData === 'function') {
- return await super.setData(...args);
- }
- return {};
- }
-
/**
* Get child by UUID
* @param uuid