Skip to content

Commit

Permalink
Get transaction group by id (#591)
Browse files Browse the repository at this point in the history
Signed-off-by: John Bair <[email protected]>
  • Loading branch information
jbair06 authored Jun 28, 2024
1 parent e3f7d98 commit dca8814
Show file tree
Hide file tree
Showing 8 changed files with 102 additions and 41 deletions.
2 changes: 1 addition & 1 deletion back-end/apps/api/src/auth/auth-requests.http
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ POST http://localhost:3001/auth/login
content-type: application/json

{
"email": "[email protected]",
"email": "john.bair+16@swirldslabs.com",
"password": "1234567890"
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Expose } from 'class-transformer';
import { Expose, Type } from 'class-transformer';
import { TransactionDto } from './transaction.dto';

export class TransactionGroupItemDto {
@Expose()
Expand All @@ -9,4 +10,8 @@ export class TransactionGroupItemDto {

@Expose()
seq: number;

@Expose()
@Type(() => TransactionDto)
transaction: TransactionDto;
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Expose } from 'class-transformer';
import { Expose, Type } from 'class-transformer';
import { TransactionGroupItemDto } from './transaction-group-item.dto';

export class TransactionGroupDto {
@Expose()
Expand All @@ -12,4 +13,8 @@ export class TransactionGroupDto {

@Expose()
createdAt: Date;

@Expose()
@Type(() => TransactionGroupItemDto)
groupItems: TransactionGroupItemDto[];
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,29 @@ POST http://localhost:3001/transaction-groups
content-type: application/json

{
"description":"transaction - [email protected]",
"atomic":false,
"groupItems":
[
{"seq":0,
"transaction":
{
"name":"New Account Create Transaction",
"type":"ACCOUNT CREATE",
"description":"first account create transaction",
"body":"0a88012a85010a80010a170a0808f085a7c406100012090800100018ac98a30118001206080010001803188084af5f220308b40132005a510a221220d3ef6b5fcf45025d011c18bea660cc0add0d35d4f6c9d4a24e70c4ceba49224b108084af5f30ffffffffffffffff7f38ffffffffffffffff7f40004a050880ceda036a0668656c6c6f218801011200",
"status":"WAITING FOR SIGNATURES",
"network":"testnet",
"creatorKeyId":2,
"signature":"8d5e5b31cc3ee2c1b1e8443422ca13a8b211ffed4a9c0eea590835835aab15ae88204b1f6fb60b3cb7198b46a08a121a820e4c65a5a350f565e6b92ae035e405",
"validStart":"2024-06-27T16:02:00.000Z"
"description": "Create Account",
"atomic": true,
"groupItems": [
{
"seq": 0,
"transaction": {
"name": "Create Account",
"type": "ACCOUNT CREATE",
"transactionId": "[email protected]",
"description": "Create Account",
"body": "0a7f2a7d0a790a170a080880edf6cb06100012090800100018ac98a30118001206080010001803188084af5f2202087832005a4b0a221220d3ef6b5fcf45025d011c18bea660cc0add0d35d4f6c9d4a24e70c4ceba49224b1080d0dbc3f40230ffffffffffffffff7f38ffffffffffffffff7f40004a050880ceda038801001200",
"status": "WAITING FOR SIGNATURES",
"signature": "8dc8820f28e6f55322666453398f40f21dc788d680be8d6c61c0ee9cedbbe7359d8cb318c8955b4a6cfb763cda5bfa2d57dcede0b3903e68c865d36a347d5801",
"validStart": "2026-01-31T08:00:00.000Z",
"creatorKeyId": 2,
"network": "testnet"
}
}
]
}

### Get a transaction group
GET http://localhost:3001/transaction-groups/45

### Delete a transaction group
DELETE http://localhost:3000/transaction-groups/13
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,19 @@ export class TransactionGroupsController {
return this.transactionGroupsService.getTransactionGroups();
}

@ApiOperation({
summary: 'Get a transaction group',
description: 'Get a transaction group and its transactions by its id.',
})
@ApiResponse({
status: 200,
type: TransactionGroupDto,
})
@Get('/:id')
getTransactionGroup(@GetUser() user: User, @Param('id', ParseIntPipe) groupId: number): Promise<TransactionGroup> {
return this.transactionGroupsService.getTransactionGroup(user, groupId);
}

/* Delete a transaction group */
@ApiOperation({
summary: 'Remove a transaction group',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import { Inject, Injectable } from '@nestjs/common';
import { Inject, Injectable, NotFoundException, UnauthorizedException } from '@nestjs/common';
import { ClientProxy } from '@nestjs/microservices';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';

import {
asyncFilter,
NOTIFICATIONS_SERVICE,
NOTIFY_CLIENT,
NotifyClientDto,
TRANSACTION_ACTION,
} from '@app/common';
import { TransactionGroup, TransactionGroupItem } from '@entities';
import { TransactionGroup, TransactionGroupItem, User } from '@entities';

import { TransactionsService } from '../transactions.service';

Expand Down Expand Up @@ -59,6 +60,33 @@ export class TransactionGroupsService {
return group;
}

async getTransactionGroup(user: User, id: number): Promise<TransactionGroup> {
const group = await this.repo.findOne({
where: { id },
relations: [
'groupItems',
'groupItems.transaction',
'groupItems.transaction.creatorKey',
'groupItems.transaction.creatorKey.user',
'groupItems.transaction.observers',
],
});

if (!(group?.groupItems.length > 0)) {
throw new NotFoundException('Transaction not found');
}

group.groupItems = await asyncFilter(group.groupItems, async (groupItem) => {
return this.transactionsService.verifyAccess(groupItem.transaction, user);
});

if (group.groupItems.length === 0) {
throw new UnauthorizedException("You don't have permission to view this group.");
}

return group;
}

async removeTransactionGroup(user: UserDto, id: number): Promise<TransactionGroup> {
const group = await this.repo.findOneBy({ id });
if (!group) {
Expand Down
42 changes: 22 additions & 20 deletions back-end/apps/api/src/transactions/transactions.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -454,8 +454,25 @@ export class TransactionsService {
relations: ['creatorKey', 'creatorKey.user', 'observers', 'groupItem'],
});

if (!(await this.verifyAccess(transaction, user))) {
throw new UnauthorizedException("You don't have permission to view this transaction");
}
return transaction;
}

async verifyAccess(transaction: Transaction, user: User): Promise<boolean> {
if (!transaction) throw new NotFoundException('Transaction not found');

if (
[
TransactionStatus.EXECUTED,
TransactionStatus.EXPIRED,
TransactionStatus.FAILED,
TransactionStatus.CANCELED,
].includes(transaction.status)
)
return true;

transaction.signers = await this.entityManager.find(TransactionSigner, {
where: {
transaction: {
Expand All @@ -472,26 +489,11 @@ export class TransactionsService {

transaction.approvers = this.approversService.getTreeStructure(approvers);

if (
[
TransactionStatus.EXECUTED,
TransactionStatus.EXPIRED,
TransactionStatus.FAILED,
TransactionStatus.CANCELED,
].includes(transaction.status)
)
return transaction;

if (
userKeysToSign.length === 0 &&
transaction.creatorKey?.user?.id !== user.id &&
!transaction.observers.some(o => o.userId === user.id) &&
!transaction.signers.some(s => s.userKey.user.id === user.id) &&
!approvers.some(a => a.userId === user.id)
)
throw new UnauthorizedException("You don't have permission to view this transaction");

return transaction;
return userKeysToSign.length !== 0 ||
transaction.creatorKey?.user?.id === user.id ||
transaction.observers.some(o => o.userId === user.id) ||
transaction.signers.some(s => s.userKey.user.id === user.id) ||
approvers.some(a => a.userId === user.id);
}

/* Get the user keys that are required for a given transaction */
Expand Down
5 changes: 5 additions & 0 deletions back-end/libs/common/src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,8 @@ export * from './sdk';
export * from './mirrorNode';
export * from './model';
export * from './typeORM';

export const asyncFilter = async <T>(list: T[], predicate: (t: T) => Promise<boolean>) => {
const resolvedPredicates = await Promise.all(list.map(predicate));
return list.filter((item, idx) => resolvedPredicates[idx]);
};

0 comments on commit dca8814

Please sign in to comment.