Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import { AutoMap } from '@automapper/classes';
import { ApiProperty } from '@nestjs/swagger';
import { Type } from 'class-transformer';
import { IsEthereumAddress, IsNumber } from 'class-validator';
import {
IsEthereumAddress,
IsNotEmpty,
IsNumber,
IsString,
} from 'class-validator';

export class ReportAbuseDto {
@AutoMap()
Expand All @@ -13,14 +18,22 @@ export class ReportAbuseDto {
@Type(() => Number)
@ApiProperty()
chain_id: number;
@AutoMap()
@IsString()
@IsNotEmpty()
@ApiProperty({ required: true, description: 'Reason for the abuse report' })
reason: string;
}

export class ReportAbuseParams {
@AutoMap()
chainId: number;
@AutoMap()
escrowAddress: string;
@AutoMap()
reason: string;
}

export class ReportAbuseCommand {
@AutoMap()
data: ReportAbuseParams;
Expand All @@ -33,13 +46,16 @@ export class ReportAbuseData {
escrow_address: string;
@AutoMap()
chain_id: number;
@AutoMap()
reason: string;
}

export class ReportedAbuseItem {
id: number;
escrowAddress: string;
chainId: number;
status: string;
reason: string;
}

export class ReportedAbuseResponse {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,19 @@ const ESCROW_ADDRESS = 'test_address';
const CHAIN_ID = 1;
const STATUS = 'reported';
const ABUSE_ID = 1;
const REASON = 'Test abuse reason';
export const TOKEN = 'test_user_token';

export const reportAbuseDtoFixture: ReportAbuseDto = {
chain_id: CHAIN_ID,
escrow_address: ESCROW_ADDRESS,
reason: REASON,
};

export const reportAbuseParamsFixture: ReportAbuseParams = {
chainId: CHAIN_ID,
escrowAddress: ESCROW_ADDRESS,
reason: REASON,
};

export const reportAbuseCommandFixture: ReportAbuseCommand = {
Expand All @@ -32,6 +35,7 @@ export const reportedAbuseItemFixture: ReportedAbuseItem = {
escrowAddress: ESCROW_ADDRESS,
chainId: CHAIN_ID,
status: STATUS,
reason: REASON,
};

export const reportedAbuseResponseFixture: ReportedAbuseResponse = {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { MigrationInterface, QueryRunner } from 'typeorm';

export class AddReasonToAbuse1750766313641 implements MigrationInterface {
name = 'AddReasonToAbuse1750766313641';

public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "hmt"."abuses" ADD "reason" text NOT NULL`);
}

public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "hmt"."abuses" DROP COLUMN "reason"`);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ export class AbuseController {
escrowAddress: data.escrowAddress,
chainId: data.chainId,
userId: request.user.id,
reason: data.reason,
});
}

Expand Down Expand Up @@ -82,6 +83,7 @@ export class AbuseController {
escrowAddress: abuseEntity.escrowAddress,
chainId: abuseEntity.chainId,
status: abuseEntity.status,
reason: abuseEntity.reason,
};
});
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ChainId } from '@human-protocol/sdk';
import { ApiProperty } from '@nestjs/swagger';
import { IsEthereumAddress, IsString } from 'class-validator';
import { IsEthereumAddress, IsString, MaxLength } from 'class-validator';

import { IsChainId } from '../../common/validators';
import { AbuseStatus } from './constants';
Expand All @@ -13,6 +13,15 @@ export class ReportAbuseDto {
@ApiProperty({ name: 'escrow_address' })
@IsEthereumAddress()
escrowAddress: string;

@ApiProperty({
name: 'reason',
required: true,
description: 'Reason for the abuse report',
})
@IsString()
@MaxLength(1000)
reason: string;
}

export class AbuseResponseDto {
Expand All @@ -27,6 +36,9 @@ export class AbuseResponseDto {

@ApiProperty({ description: 'Current status of the abuse report' })
status: AbuseStatus;

@ApiProperty({ description: 'Reason for the abuse report', required: true })
reason: string;
}

export class SlackInteractionDto {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ export class AbuseEntity extends BaseEntity {
@Column({ type: 'decimal', precision: 30, scale: 18, nullable: true })
amount: number | null;

@Column({ type: 'text' })
reason: string;

@JoinColumn()
@ManyToOne('UserEntity', { nullable: false, onDelete: 'CASCADE' })
user?: UserEntity;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,17 +73,20 @@ describe('AbuseService', () => {
describe('reportAbuse', () => {
it('should create a new abuse entity', async () => {
const userId = faker.number.int();
const reason = faker.lorem.sentence();

await abuseService.reportAbuse({
escrowAddress,
chainId,
userId,
reason,
});

expect(mockAbuseRepository.createUnique).toHaveBeenCalledWith({
escrowAddress: escrowAddress,
chainId: chainId,
userId: userId,
reason: reason,
retriesCount: 0,
status: AbuseStatus.PENDING,
waitUntil: expect.any(Date),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export class AbuseService {
abuseEntity.escrowAddress = data.escrowAddress;
abuseEntity.chainId = data.chainId;
abuseEntity.userId = data.userId;
abuseEntity.reason = data.reason;
abuseEntity.status = AbuseStatus.PENDING;
abuseEntity.retriesCount = 0;
abuseEntity.waitUntil = new Date();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export function generateAbuseEntity(
status: AbuseStatus.PENDING,
decision: null,
amount: null,
reason: faker.lorem.sentence(),
waitUntil: faker.date.future(),
createdAt: faker.date.recent(),
updatedAt: new Date(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export type ReportAbuseInput = {
userId: number;
chainId: ChainId;
escrowAddress: string;
reason: string;
};

export type SlackInteractionBase = {
Expand Down
Loading