Skip to content

Commit

Permalink
feat: send email on transaction cancel (#1470)
Browse files Browse the repository at this point in the history
Signed-off-by: Svetoslav Borislavov <[email protected]>
  • Loading branch information
SvetBorislavov authored Jan 22, 2025
1 parent 10475ed commit fbf3987
Show file tree
Hide file tree
Showing 9 changed files with 86 additions and 3 deletions.
26 changes: 26 additions & 0 deletions back-end/apps/api/src/transactions/transactions.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,10 @@ import {
MirrorNetworkGRPC,
isTransactionBodyOverMaxSize,
emitExecuteTranasction,
notifyGeneral,
} from '@app/common/utils';
import {
NotificationType,
Transaction,
TransactionApprover,
TransactionSigner,
Expand Down Expand Up @@ -672,6 +674,30 @@ describe('TransactionsService', () => {
);
expect(notifyTransactionAction).toHaveBeenCalledWith(notificationsService);
});

it('should emit notification to the notifiaction service', async () => {
const transaction = {
id: 123,
creatorKey: { userId: 1 },
observers: [{ userId: 2 }],
signers: [{ userId: 3 }],
status: TransactionStatus.WAITING_FOR_SIGNATURES,
};

jest
.spyOn(service, 'getTransactionForCreator')
.mockResolvedValueOnce(transaction as Transaction);

await service.cancelTransaction(123, { id: 1 } as User);

expect(notifyGeneral).toHaveBeenCalledWith(
notificationsService,
NotificationType.TRANSACTION_CANCELLED,
expect.arrayContaining([2, 3]),
expect.any(String),
123,
);
});
});

describe('archiveTransaction', () => {
Expand Down
24 changes: 23 additions & 1 deletion back-end/apps/api/src/transactions/transactions.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,13 @@ import {
FindOperator,
} from 'typeorm';

import { Transaction, TransactionSigner, TransactionStatus, User } from '@entities';
import {
NotificationType,
Transaction,
TransactionSigner,
TransactionStatus,
User,
} from '@entities';

import {
CHAIN_SERVICE,
Expand All @@ -39,6 +45,7 @@ import {
ErrorCodes,
isTransactionBodyOverMaxSize,
emitExecuteTranasction,
notifyGeneral,
} from '@app/common';

import { CreateTransactionDto } from './dto';
Expand Down Expand Up @@ -428,6 +435,21 @@ export class TransactionsService {
notifySyncIndicators(this.notificationsService, transaction.id, TransactionStatus.CANCELED);
notifyTransactionAction(this.notificationsService);

/* Send email notification to all the participants */
await this.attachTransactionApprovers(transaction);
const userIds = new Set<number>();
transaction.approvers?.forEach(a => userIds.add(a.userId));
transaction.signers?.forEach(s => userIds.add(s.userId));
transaction.observers?.forEach(o => userIds.add(o.userId));

notifyGeneral(
this.notificationsService,
NotificationType.TRANSACTION_CANCELLED,
[...userIds],
`A transaction ${transaction.name} has been cancelled.\nTransaction ID: ${transaction.transactionId}\n Netowork: ${transaction.mirrorNetwork}`,
transaction.id,
);

return true;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ export enum NotificationTypeEmailSubjects {
TRANSACTION_WAITING_FOR_SIGNATURES = 'Hedera Transaction Tool | Action Required | Review and Sign Transaction',
TRANSACTION_READY_FOR_EXECUTION = 'Hedera Transaction Tool | Transaction ready for execution',
TRANSACTION_EXECUTED = 'Hedera Transaction Tool | Transaction has been executed',
TRANSACTION_CANCELLED = 'Hedera Transaction Tool | Transaction has been cancelled',
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export enum NotificationType {
TRANSACTION_READY_FOR_EXECUTION = 'TRANSACTION_READY_FOR_EXECUTION',
TRANSACTION_EXECUTED = 'TRANSACTION_EXECUTED',
TRANSACTION_EXPIRED = 'TRANSACTION_EXPIRED',
TRANSACTION_CANCELLED = 'TRANSACTION_CANCELLED',
TRANSACTION_INDICATOR_APPROVE = 'TRANSACTION_INDICATOR_APPROVE',
TRANSACTION_INDICATOR_SIGN = 'TRANSACTION_INDICATOR_SIGN',
TRANSACTION_INDICATOR_EXECUTABLE = 'TRANSACTION_INDICATOR_EXECUTABLE',
Expand Down
19 changes: 18 additions & 1 deletion back-end/libs/common/src/utils/client/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@ import {
SYNC_INDICATORS,
NotifyClientDto,
NotifyForTransactionDto,
NotifyGeneralDto,
UpdateTransactionStatusDto,
SyncIndicatorsDto,
ExecuteTransactionDto,
NOTIFY_GENERAL,
} from '@app/common';
import { TransactionStatus } from '@entities';
import { NotificationType, TransactionStatus } from '@entities';

/* Chain */
export const emitUpdateTransactionStatus = (client: ClientProxy, id: number) => {
Expand Down Expand Up @@ -50,3 +52,18 @@ export const notifySyncIndicators = (
transactionStatus,
});
};

export const notifyGeneral = (
client: ClientProxy,
type: NotificationType,
userIds: number[],
content: string,
entityId?: number,
) => {
client.emit<undefined, NotifyGeneralDto>(NOTIFY_GENERAL, {
type,
userIds,
content,
entityId,
});
};
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ export enum NotificationType {
TRANSACTION_WAITING_FOR_SIGNATURES = 'TRANSACTION_WAITING_FOR_SIGNATURES',
TRANSACTION_READY_FOR_EXECUTION = 'TRANSACTION_READY_FOR_EXECUTION',
TRANSACTION_EXECUTED = 'TRANSACTION_EXECUTED',
TRANSACTION_CANCELLED = 'TRANSACTION_CANCELLED',
TRANSACTION_EXPIRED = 'TRANSACTION_EXPIRED',
TRANSACTION_INDICATOR_APPROVE = 'TRANSACTION_INDICATOR_APPROVE',
TRANSACTION_INDICATOR_SIGN = 'TRANSACTION_INDICATOR_SIGN',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ export default function useAfterOrganizationSelection() {

if (previousPath && currentRoute.path !== previousPath) {
await router.push(previousPath);
} else if (currentRoute.name === 'login') {
await router.push({ name: 'transactions' });
}
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,22 @@ const handlePreferenceChange = (type: NotificationType, email: boolean) => {
label="Required Signature"
/>
<p class="text-small text-secondary mt-2">
You will be notified whenever a transaction, which requires your signature has been
You will be notified whenever a transaction, which requires your signature, has been
created.
</p>
</div>
<div class="mt-6">
<AppSwitch
:checked="notifications.notificationsPreferences[NotificationType.TRANSACTION_CANCELLED]"
@update:checked="handlePreferenceChange(NotificationType.TRANSACTION_CANCELLED, $event)"
name="transaction-cancelled"
label="Transaction Cancelled"
/>
<p class="text-small text-secondary mt-2">
You will be notified whenever a transaction, which you have signed, approved or observe,
has been cancelled.
</p>
</div>
</div>
</div>
</template>
1 change: 1 addition & 0 deletions front-end/src/renderer/stores/storeNotifications.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ const useNotificationsStore = defineStore('notifications', () => {
const notificationsPreferences = ref({
[NotificationType.TRANSACTION_READY_FOR_EXECUTION]: true,
[NotificationType.TRANSACTION_WAITING_FOR_SIGNATURES]: true,
[NotificationType.TRANSACTION_CANCELLED]: true,
});
const notifications = ref<{ [serverUrl: string]: INotificationReceiver[] }>({});

Expand Down

0 comments on commit fbf3987

Please sign in to comment.