From 78b6f561656cd218453dd25253ee3bd77ffd4c35 Mon Sep 17 00:00:00 2001 From: Dmitry Nechay Date: Tue, 11 Feb 2025 16:55:22 +0300 Subject: [PATCH 01/14] fix: use dev env for compose to align with env usage --- scripts/cvat/docker-compose.local.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/cvat/docker-compose.local.yml b/scripts/cvat/docker-compose.local.yml index 14ccd6e9bd..8ccb37b78d 100644 --- a/scripts/cvat/docker-compose.local.yml +++ b/scripts/cvat/docker-compose.local.yml @@ -16,7 +16,7 @@ x-hardcoded-vars: redis_host: &redis_host redis redis_port: &redis_port 6379 minio_host: &minio_host minio - node_env: &node_env local + node_env: &node_env development cvat_lb_url: &cvat_lb_url 'http://cvat-lb:8080' cvat_oracle_storage_provider: &cvat_oracle_storage_provider aws From f39b14d2b71fe8ae3116eb3b8bea7ba29b52860b Mon Sep 17 00:00:00 2001 From: Dmitry Nechay Date: Wed, 12 Feb 2025 17:31:44 +0300 Subject: [PATCH 02/14] refactor: remove unused code --- .../server/src/common/constants/index.ts | 453 ------------------ .../server/src/common/helpers/utils.ts | 7 - 2 files changed, 460 deletions(-) delete mode 100644 packages/apps/reputation-oracle/server/src/common/helpers/utils.ts diff --git a/packages/apps/reputation-oracle/server/src/common/constants/index.ts b/packages/apps/reputation-oracle/server/src/common/constants/index.ts index 8b71b9b341..983b97cbd4 100644 --- a/packages/apps/reputation-oracle/server/src/common/constants/index.ts +++ b/packages/apps/reputation-oracle/server/src/common/constants/index.ts @@ -31,456 +31,3 @@ export const RESEND_EMAIL_VERIFICATION_PATH = export const LOGOUT_PATH = '/auth/logout'; export const BACKOFF_INTERVAL_SECONDS = 120; - -export const CURSE_WORDS = [ - '4r5e', - '5h1t', - '5hit', - 'a55', - 'anal', - 'anus', - 'ar5e', - 'arrse', - 'arse', - 'ass', - 'ass-fucker', - 'asses', - 'assfucker', - 'assfukka', - 'asshole', - 'assholes', - 'asswhole', - 'a_s_s', - 'b!tch', - 'b00bs', - 'b17ch', - 'b1tch', - 'ballbag', - 'balls', - 'ballsack', - 'bastard', - 'beastial', - 'beastiality', - 'bellend', - 'bestial', - 'bestiality', - 'bi+ch', - 'biatch', - 'bitch', - 'bitcher', - 'bitchers', - 'bitches', - 'bitchin', - 'bitching', - 'bloody', - 'blow job', - 'blowjob', - 'blowjobs', - 'boiolas', - 'bollock', - 'bollok', - 'boner', - 'boob', - 'boobs', - 'booobs', - 'boooobs', - 'booooobs', - 'booooooobs', - 'breasts', - 'buceta', - 'bugger', - 'bum', - 'bunny fucker', - 'butt', - 'butthole', - 'buttmuch', - 'buttplug', - 'c0ck', - 'c0cksucker', - 'carpet muncher', - 'cawk', - 'chink', - 'cipa', - 'cl1t', - 'clit', - 'clitoris', - 'clits', - 'cnut', - 'cock', - 'cock-sucker', - 'cockface', - 'cockhead', - 'cockmunch', - 'cockmuncher', - 'cocks', - 'cocksuck', - 'cocksucked', - 'cocksucker', - 'cocksucking', - 'cocksucks', - 'cocksuka', - 'cocksukka', - 'cok', - 'cokmuncher', - 'coksucka', - 'coon', - 'cox', - 'crap', - 'cum', - 'cummer', - 'cumming', - 'cums', - 'cumshot', - 'cunilingus', - 'cunillingus', - 'cunnilingus', - 'cunt', - 'cuntlick', - 'cuntlicker', - 'cuntlicking', - 'cunts', - 'cyalis', - 'cyberfuc', - 'cyberfuck', - 'cyberfucked', - 'cyberfucker', - 'cyberfuckers', - 'cyberfucking', - 'd1ck', - 'damn', - 'dick', - 'dickhead', - 'dildo', - 'dildos', - 'dink', - 'dinks', - 'dirsa', - 'dlck', - 'dog-fucker', - 'doggin', - 'dogging', - 'donkeyribber', - 'doosh', - 'duche', - 'dyke', - 'ejaculate', - 'ejaculated', - 'ejaculates', - 'ejaculating', - 'ejaculatings', - 'ejaculation', - 'ejakulate', - 'f u c k', - 'f u c k e r', - 'f4nny', - 'fag', - 'fagging', - 'faggitt', - 'faggot', - 'faggs', - 'fagot', - 'fagots', - 'fags', - 'fanny', - 'fannyflaps', - 'fannyfucker', - 'fanyy', - 'fatass', - 'fcuk', - 'fcuker', - 'fcuking', - 'feck', - 'fecker', - 'felching', - 'fellate', - 'fellatio', - 'fingerfuck', - 'fingerfucked', - 'fingerfucker', - 'fingerfuckers', - 'fingerfucking', - 'fingerfucks', - 'fistfuck', - 'fistfucked', - 'fistfucker', - 'fistfuckers', - 'fistfucking', - 'fistfuckings', - 'fistfucks', - 'flange', - 'fook', - 'fooker', - 'fuck', - 'fucka', - 'fucked', - 'fucker', - 'fuckers', - 'fuckhead', - 'fuckheads', - 'fuckin', - 'fucking', - 'fuckings', - 'fuckingshitmotherfucker', - 'fuckme', - 'fucks', - 'fuckwhit', - 'fuckwit', - 'fudge packer', - 'fudgepacker', - 'fuk', - 'fuker', - 'fukker', - 'fukkin', - 'fuks', - 'fukwhit', - 'fukwit', - 'fux', - 'fux0r', - 'f_u_c_k', - 'gangbang', - 'gangbanged', - 'gangbangs', - 'gaylord', - 'gaysex', - 'goatse', - 'God', - 'god-dam', - 'god-damned', - 'goddamn', - 'goddamned', - 'hardcoresex', - 'hell', - 'heshe', - 'hoar', - 'hoare', - 'hoer', - 'homo', - 'hore', - 'horniest', - 'horny', - 'hotsex', - 'jack-off', - 'jackoff', - 'jap', - 'jerk-off', - 'jism', - 'jiz', - 'jizm', - 'jizz', - 'kawk', - 'knob', - 'knobead', - 'knobed', - 'knobend', - 'knobhead', - 'knobjocky', - 'knobjokey', - 'kock', - 'kondum', - 'kondums', - 'kum', - 'kummer', - 'kumming', - 'kums', - 'kunilingus', - 'l3i+ch', - 'l3itch', - 'labia', - 'lust', - 'lusting', - 'm0f0', - 'm0fo', - 'm45terbate', - 'ma5terb8', - 'ma5terbate', - 'masochist', - 'master-bate', - 'masterb8', - 'masterbat*', - 'masterbat3', - 'masterbate', - 'masterbation', - 'masterbations', - 'masturbate', - 'mo-fo', - 'mof0', - 'mofo', - 'mothafuck', - 'mothafucka', - 'mothafuckas', - 'mothafuckaz', - 'mothafucked', - 'mothafucker', - 'mothafuckers', - 'mothafuckin', - 'mothafucking', - 'mothafuckings', - 'mothafucks', - 'mother fucker', - 'motherfuck', - 'motherfucked', - 'motherfucker', - 'motherfuckers', - 'motherfuckin', - 'motherfucking', - 'motherfuckings', - 'motherfuckka', - 'motherfucks', - 'muff', - 'mutha', - 'muthafecker', - 'muthafuckker', - 'muther', - 'mutherfucker', - 'n1gga', - 'n1gger', - 'nazi', - 'nigg3r', - 'nigg4h', - 'nigga', - 'niggah', - 'niggas', - 'niggaz', - 'nigger', - 'niggers', - 'nob', - 'nob jokey', - 'nobhead', - 'nobjocky', - 'nobjokey', - 'numbnuts', - 'nutsack', - 'orgasim', - 'orgasims', - 'orgasm', - 'orgasms', - 'p0rn', - 'pawn', - 'pecker', - 'penis', - 'penisfucker', - 'phonesex', - 'phuck', - 'phuk', - 'phuked', - 'phuking', - 'phukked', - 'phukking', - 'phuks', - 'phuq', - 'pigfucker', - 'pimpis', - 'piss', - 'pissed', - 'pisser', - 'pissers', - 'pisses', - 'pissflaps', - 'pissin', - 'pissing', - 'pissoff', - 'poop', - 'porn', - 'porno', - 'pornography', - 'pornos', - 'prick', - 'pricks', - 'pron', - 'pube', - 'pusse', - 'pussi', - 'pussies', - 'pussy', - 'pussys', - 'rectum', - 'retard', - 'rimjaw', - 'rimming', - 's hit', - 's.o.b.', - 'sadist', - 'schlong', - 'screwing', - 'scroat', - 'scrote', - 'scrotum', - 'semen', - 'sex', - 'sh!+', - 'sh!t', - 'sh1t', - 'shag', - 'shagger', - 'shaggin', - 'shagging', - 'shemale', - 'shi+', - 'shit', - 'shitdick', - 'shite', - 'shited', - 'shitey', - 'shitfuck', - 'shitfull', - 'shithead', - 'shiting', - 'shitings', - 'shits', - 'shitted', - 'shitter', - 'shitters', - 'shitting', - 'shittings', - 'shitty', - 'skank', - 'slut', - 'sluts', - 'smegma', - 'smut', - 'snatch', - 'son-of-a-bitch', - 'spac', - 'spunk', - 's_h_i_t', - 't1tt1e5', - 't1tties', - 'teets', - 'teez', - 'testical', - 'testicle', - 'tit', - 'titfuck', - 'tits', - 'titt', - 'tittie5', - 'tittiefucker', - 'titties', - 'tittyfuck', - 'tittywank', - 'titwank', - 'tosser', - 'turd', - 'tw4t', - 'twat', - 'twathead', - 'twatty', - 'twunt', - 'twunter', - 'v14gra', - 'v1gra', - 'vagina', - 'viagra', - 'vulva', - 'w00se', - 'wang', - 'wank', - 'wanker', - 'wanky', - 'whoar', - 'whore', - 'willies', - 'willy', - 'xrated', - 'xxx', -]; diff --git a/packages/apps/reputation-oracle/server/src/common/helpers/utils.ts b/packages/apps/reputation-oracle/server/src/common/helpers/utils.ts deleted file mode 100644 index 84568024a3..0000000000 --- a/packages/apps/reputation-oracle/server/src/common/helpers/utils.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { CURSE_WORDS } from '../constants'; - -export const checkCurseWords = (text: string): boolean => { - const words = text.replace(/[^a-zA-Z0-9 ]/g, '').split(' '); - const res = CURSE_WORDS.some((w) => words.includes(w)); - return res; -}; From 76d3b0a61d2f79c5a878f034dd001d6ac6a51916 Mon Sep 17 00:00:00 2001 From: Dmitry Nechay Date: Wed, 12 Feb 2025 17:31:18 +0300 Subject: [PATCH 03/14] refactor: case interceptor --- .../server/src/app.module.ts | 4 +- .../src/common/interceptors/snake-case.ts | 28 -- .../transform.interceptor.spec.ts | 259 ++++++++++++++++++ .../interceptors/transform.interceptor.ts | 74 +++++ .../server/src/common/utils/environment.ts | 5 +- .../server/src/utils/case-converters.ts | 15 + .../server/src/utils/type-guards.ts | 3 + .../server/test/mock-creators/nest.ts | 38 +++ 8 files changed, 393 insertions(+), 33 deletions(-) delete mode 100644 packages/apps/reputation-oracle/server/src/common/interceptors/snake-case.ts create mode 100644 packages/apps/reputation-oracle/server/src/common/interceptors/transform.interceptor.spec.ts create mode 100644 packages/apps/reputation-oracle/server/src/common/interceptors/transform.interceptor.ts create mode 100644 packages/apps/reputation-oracle/server/src/utils/case-converters.ts create mode 100644 packages/apps/reputation-oracle/server/src/utils/type-guards.ts create mode 100644 packages/apps/reputation-oracle/server/test/mock-creators/nest.ts diff --git a/packages/apps/reputation-oracle/server/src/app.module.ts b/packages/apps/reputation-oracle/server/src/app.module.ts index 5b841bf230..b03e81fdef 100644 --- a/packages/apps/reputation-oracle/server/src/app.module.ts +++ b/packages/apps/reputation-oracle/server/src/app.module.ts @@ -12,7 +12,7 @@ import { envValidator } from './common/config'; import { AuthModule } from './modules/auth/auth.module'; import { ServeStaticModule } from '@nestjs/serve-static'; import { join } from 'path'; -import { SnakeCaseInterceptor } from './common/interceptors/snake-case'; +import { TransformInterceptor } from './common/interceptors/transform.interceptor'; import { KycModule } from './modules/kyc/kyc.module'; import { CronJobModule } from './modules/cron-job/cron-job.module'; import { PayoutModule } from './modules/payout/payout.module'; @@ -33,7 +33,7 @@ import { EmailModule } from './modules/email/module'; }, { provide: APP_INTERCEPTOR, - useClass: SnakeCaseInterceptor, + useClass: TransformInterceptor, }, { provide: APP_FILTER, diff --git a/packages/apps/reputation-oracle/server/src/common/interceptors/snake-case.ts b/packages/apps/reputation-oracle/server/src/common/interceptors/snake-case.ts deleted file mode 100644 index 0d62e5f222..0000000000 --- a/packages/apps/reputation-oracle/server/src/common/interceptors/snake-case.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { - CallHandler, - ExecutionContext, - Injectable, - NestInterceptor, -} from '@nestjs/common'; -import { Observable } from 'rxjs'; -import { map } from 'rxjs/operators'; -import { CaseConverter } from '../utils/case-converter'; - -@Injectable() -export class SnakeCaseInterceptor implements NestInterceptor { - intercept(context: ExecutionContext, next: CallHandler): Observable { - const request = context.switchToHttp().getRequest(); - - if (request.body) { - request.body = CaseConverter.transformToCamelCase(request.body); - } - - if (request.query) { - request.query = CaseConverter.transformToCamelCase(request.query); - } - - return next - .handle() - .pipe(map((data) => CaseConverter.transformToSnakeCase(data))); - } -} diff --git a/packages/apps/reputation-oracle/server/src/common/interceptors/transform.interceptor.spec.ts b/packages/apps/reputation-oracle/server/src/common/interceptors/transform.interceptor.spec.ts new file mode 100644 index 0000000000..609b603c0f --- /dev/null +++ b/packages/apps/reputation-oracle/server/src/common/interceptors/transform.interceptor.spec.ts @@ -0,0 +1,259 @@ +import { faker } from '@faker-js/faker'; +import { ExecutionContext, StreamableFile } from '@nestjs/common'; +import { firstValueFrom, of } from 'rxjs'; +import { TransformInterceptor } from './transform.interceptor'; +import { + CallHandlerMock, + createCallHandlerMock, + createExecutionContextMock, + ExecutionContextMock, +} from '../../../test/mock-creators/nest'; + +describe('TransformInterceptor', () => { + describe('transformRequestData', () => { + it.each(['string', 42, BigInt(0), Symbol('test'), true, null, undefined])( + 'should not transform primitive [%#]', + (value: unknown) => { + expect(TransformInterceptor.transformRequestData(value)).toEqual(value); + }, + ); + + it('should not transform simple array', () => { + const input = faker.helpers.multiple(() => faker.string.sample()); + + const output = TransformInterceptor.transformRequestData(input); + + expect(output).toEqual(input); + }); + + it('should transform array of objects', () => { + const input = faker.helpers.multiple(() => ({ + test_case: faker.string.sample(), + })); + const expectedOutput = input.map((v) => ({ + testCase: v.test_case, + })); + + const output = TransformInterceptor.transformRequestData(input); + + expect(output).toEqual(expectedOutput); + }); + + it('should transform plain object to camelCase', () => { + const input = { + random_string: faker.string.sample(), + random_number: faker.number.float(), + random_boolean: faker.datatype.boolean(), + always_null: null, + }; + + const output = TransformInterceptor.transformRequestData(input); + + expect(output).toEqual({ + randomString: input.random_string, + randomNumber: input.random_number, + randomBoolean: input.random_boolean, + alwaysNull: null, + }); + }); + + it('should transform input with nested data', () => { + const randomString = faker.string.sample(); + + const input = { + nested_object: { + with_array: [ + { + of_objects: { + with_random_string: randomString, + }, + }, + ], + }, + }; + + const output = TransformInterceptor.transformRequestData(input); + + expect(output).toEqual({ + nestedObject: { + withArray: [ + { + ofObjects: { + withRandomString: randomString, + }, + }, + ], + }, + }); + }); + }); + + describe('transformResponseData', () => { + it.each(['string', 42, BigInt(0), Symbol('test'), true, null, undefined])( + 'should not transform primitive [%#]', + (value: unknown) => { + expect(TransformInterceptor.transformResponseData(value)).toEqual( + value, + ); + }, + ); + + it('should not transfrom file response', () => { + const input = new StreamableFile(Buffer.from('file-contents')); + + const output = TransformInterceptor.transformResponseData(input); + + expect(output).toEqual(input); + }); + + it('should not transform simple array', () => { + const input = faker.helpers.multiple(() => faker.string.sample()); + + const output = TransformInterceptor.transformResponseData(input); + + expect(output).toEqual(input); + }); + + it('should transform array of objects', () => { + const input = faker.helpers.multiple(() => ({ + testCase: faker.string.sample(), + })); + const expectedOutput = input.map((v) => ({ + test_case: v.testCase, + })); + + const output = TransformInterceptor.transformResponseData(input); + + expect(output).toEqual(expectedOutput); + }); + + it('should transform plain object to camelCase', () => { + const input = { + randomString: faker.string.sample(), + randomNumber: faker.number.float(), + randomBoolean: faker.datatype.boolean(), + alwaysNull: null, + }; + + const output = TransformInterceptor.transformResponseData(input); + + expect(output).toEqual({ + random_string: input.randomString, + random_number: input.randomNumber, + random_boolean: input.randomBoolean, + always_null: null, + }); + }); + + it('should transform date in response to ISO string', () => { + const input = { + date: faker.date.anytime(), + nested: { + date: faker.date.anytime(), + }, + array: [faker.date.anytime()], + }; + + const output = TransformInterceptor.transformResponseData(input); + + expect(output).toEqual({ + date: input.date.toISOString(), + nested: { + date: input.nested.date.toISOString(), + }, + array: input.array.map((v) => v.toISOString()), + }); + }); + + it('should transform input with nested data', () => { + const randomString = faker.string.sample(); + + const input = { + nestedObject: { + withArray: [ + { + ofObjects: { + withRandomString: randomString, + }, + }, + ], + }, + }; + + const output = TransformInterceptor.transformResponseData(input); + + expect(output).toEqual({ + nested_object: { + with_array: [ + { + of_objects: { + with_random_string: randomString, + }, + }, + ], + }, + }); + }); + }); + + describe('intercept', () => { + const interceptor = new TransformInterceptor(); + let executionContextMock: ExecutionContextMock; + let callHandlerMock: CallHandlerMock; + + beforeEach(() => { + executionContextMock = createExecutionContextMock(); + callHandlerMock = createCallHandlerMock(); + }); + + it('should transform request', async () => { + const randomValueForBody = faker.string.sample(); + const randomValueForQuery = faker.string.sample(); + + const request = { + body: { + some_body_key: randomValueForBody, + }, + query: { + some_query_key: randomValueForQuery, + }, + }; + executionContextMock.__getRequest.mockReturnValueOnce(request); + + await firstValueFrom( + interceptor.intercept( + executionContextMock as unknown as ExecutionContext, + callHandlerMock, + ), + ); + + expect(request.body).toEqual({ + someBodyKey: randomValueForBody, + }); + + expect(request.query).toEqual({ + someQueryKey: randomValueForQuery, + }); + }); + + it('should transform response', async () => { + const originalResponseBody = { + someResponseValue: faker.string.sample(), + someResponseDate: faker.date.anytime(), + }; + callHandlerMock.handle.mockReturnValueOnce(of(originalResponseBody)); + + const interceptedResponseBody = await firstValueFrom( + interceptor.intercept( + executionContextMock as unknown as ExecutionContext, + callHandlerMock, + ), + ); + + expect(interceptedResponseBody).toEqual({ + some_response_value: originalResponseBody.someResponseValue, + some_response_date: originalResponseBody.someResponseDate.toISOString(), + }); + }); + }); +}); diff --git a/packages/apps/reputation-oracle/server/src/common/interceptors/transform.interceptor.ts b/packages/apps/reputation-oracle/server/src/common/interceptors/transform.interceptor.ts new file mode 100644 index 0000000000..6e7e06d5b4 --- /dev/null +++ b/packages/apps/reputation-oracle/server/src/common/interceptors/transform.interceptor.ts @@ -0,0 +1,74 @@ +import { + CallHandler, + ExecutionContext, + Injectable, + NestInterceptor, + StreamableFile, +} from '@nestjs/common'; +import { Observable } from 'rxjs'; +import { map } from 'rxjs/operators'; +import * as CaseConverter from '../../utils/case-converters'; +import { isObject } from '../../utils/type-guards'; + +@Injectable() +export class TransformInterceptor implements NestInterceptor { + intercept(context: ExecutionContext, next: CallHandler): Observable { + const request = context.switchToHttp().getRequest(); + + if (request.body) { + request.body = TransformInterceptor.transformRequestData(request.body); + } + + if (request.query) { + request.query = TransformInterceptor.transformRequestData(request.query); + } + + return next + .handle() + .pipe(map((data) => TransformInterceptor.transformResponseData(data))); + } + + static transformRequestData(input: unknown): unknown { + /** + * If primitive value - no need to transform + */ + if (!isObject(input)) { + return input; + } + + if (Array.isArray(input)) { + return input.map(TransformInterceptor.transformRequestData); + } + + const transformedObject: Record = {}; + for (const [key, value] of Object.entries(input)) { + transformedObject[CaseConverter.snakeToCamel(key)] = + TransformInterceptor.transformRequestData(value); + } + return transformedObject; + } + + static transformResponseData(input: unknown): unknown { + /** + * If primitive value or file - return as is + */ + if (!isObject(input) || input instanceof StreamableFile) { + return input; + } + + if (input instanceof Date) { + return input.toISOString(); + } + + if (Array.isArray(input)) { + return input.map(TransformInterceptor.transformResponseData); + } + + const transformedObject: Record = {}; + for (const [key, value] of Object.entries(input)) { + transformedObject[CaseConverter.camelToSnake(key)] = + TransformInterceptor.transformResponseData(value); + } + return transformedObject; + } +} diff --git a/packages/apps/reputation-oracle/server/src/common/utils/environment.ts b/packages/apps/reputation-oracle/server/src/common/utils/environment.ts index f9ec4c4c59..d7470880cb 100644 --- a/packages/apps/reputation-oracle/server/src/common/utils/environment.ts +++ b/packages/apps/reputation-oracle/server/src/common/utils/environment.ts @@ -1,8 +1,7 @@ import { Environment } from '../constants'; export function isDevelopmentEnv(): boolean { - return ( - process.env.NODE_ENV === Environment.DEVELOPMENT || - process.env.NODE_ENV === Environment.TEST + return [Environment.DEVELOPMENT, Environment.TEST].includes( + process.env.NODE_ENV as Environment, ); } diff --git a/packages/apps/reputation-oracle/server/src/utils/case-converters.ts b/packages/apps/reputation-oracle/server/src/utils/case-converters.ts new file mode 100644 index 0000000000..66db69c6bc --- /dev/null +++ b/packages/apps/reputation-oracle/server/src/utils/case-converters.ts @@ -0,0 +1,15 @@ +/** + * TODO: check if replacing it with lodash.camelCase + * won't break anything + */ +export function snakeToCamel(input: string): string { + return input.replace(/_([a-z])/g, (_match, letter) => letter.toUpperCase()); +} + +/** + * TODO: check if replacing it with lodash.snakeCase + * won't break anything + */ +export function camelToSnake(input: string): string { + return input.replace(/([A-Z])/g, '_$1').toLowerCase(); +} diff --git a/packages/apps/reputation-oracle/server/src/utils/type-guards.ts b/packages/apps/reputation-oracle/server/src/utils/type-guards.ts new file mode 100644 index 0000000000..5dedf4fb34 --- /dev/null +++ b/packages/apps/reputation-oracle/server/src/utils/type-guards.ts @@ -0,0 +1,3 @@ +export function isObject(value: unknown): value is object { + return typeof value === 'object' && value !== null; +} diff --git a/packages/apps/reputation-oracle/server/test/mock-creators/nest.ts b/packages/apps/reputation-oracle/server/test/mock-creators/nest.ts new file mode 100644 index 0000000000..af49bedf8b --- /dev/null +++ b/packages/apps/reputation-oracle/server/test/mock-creators/nest.ts @@ -0,0 +1,38 @@ +import { CallHandler, ExecutionContext } from '@nestjs/common'; +import { of } from 'rxjs'; + +class MockClassOfExecutionContext {} + +export type ExecutionContextMock = jest.Mocked< + Pick +> & { + __getRequest: jest.Mock; +}; +export function createExecutionContextMock(): ExecutionContextMock { + /** + * Intentionally do not implement everything now, + * so we provide only things that are actually used + * with correct mock implementation. + */ + const getRequest = jest.fn().mockReturnValue({ + body: {}, + query: {}, + }); + return { + getClass: jest.fn().mockReturnValue(MockClassOfExecutionContext), + getHandler: jest.fn().mockReturnValue({ + name: 'getHandlerMock', + }), + switchToHttp: jest.fn().mockReturnValue({ + getRequest, + }), + __getRequest: getRequest, + }; +} + +export type CallHandlerMock = jest.Mocked; +export function createCallHandlerMock(): CallHandlerMock { + return { + handle: jest.fn().mockReturnValue(of({})), + }; +} From 4ae48001fc8c901004a1a3a7b1a4745d0da0ce0b Mon Sep 17 00:00:00 2001 From: Dmitry Nechay Date: Thu, 13 Feb 2025 02:44:34 +0300 Subject: [PATCH 04/14] chore: remove unused setup & tests --- .../reputation-oracle/server/package.json | 1 - .../server/test/app.e2e-spec.ts | 24 ------ .../server/test/jest-e2e.json | 9 -- .../reputation-oracle/server/test/setup.ts | 82 ------------------- 4 files changed, 116 deletions(-) delete mode 100644 packages/apps/reputation-oracle/server/test/app.e2e-spec.ts delete mode 100644 packages/apps/reputation-oracle/server/test/jest-e2e.json delete mode 100644 packages/apps/reputation-oracle/server/test/setup.ts diff --git a/packages/apps/reputation-oracle/server/package.json b/packages/apps/reputation-oracle/server/package.json index 85c39c17e1..dfa28d58d2 100644 --- a/packages/apps/reputation-oracle/server/package.json +++ b/packages/apps/reputation-oracle/server/package.json @@ -25,7 +25,6 @@ "test:watch": "jest --watch", "test:cov": "jest --coverage", "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand", - "test:e2e": "jest --config ./test/jest-e2e.json", "vercel-build": "yarn workspace @human-protocol/sdk build", "generate-env-doc": "ts-node scripts/generate-env-doc.ts" }, diff --git a/packages/apps/reputation-oracle/server/test/app.e2e-spec.ts b/packages/apps/reputation-oracle/server/test/app.e2e-spec.ts deleted file mode 100644 index 9ceebc4bec..0000000000 --- a/packages/apps/reputation-oracle/server/test/app.e2e-spec.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { INestApplication } from '@nestjs/common'; -import request from 'supertest'; -import { AppModule } from './../src/app.module'; - -describe('AppController (e2e)', () => { - let app: INestApplication; - - beforeEach(async () => { - const moduleFixture: TestingModule = await Test.createTestingModule({ - imports: [AppModule], - }).compile(); - - app = moduleFixture.createNestApplication(); - await app.init(); - }); - - it('/ (GET)', () => { - return request(app.getHttpServer()) - .get('/') - .expect(200) - .expect('Hello World!'); - }); -}); diff --git a/packages/apps/reputation-oracle/server/test/jest-e2e.json b/packages/apps/reputation-oracle/server/test/jest-e2e.json deleted file mode 100644 index e9d912f3e3..0000000000 --- a/packages/apps/reputation-oracle/server/test/jest-e2e.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "moduleFileExtensions": ["js", "json", "ts"], - "rootDir": ".", - "testEnvironment": "node", - "testRegex": ".e2e-spec.ts$", - "transform": { - "^.+\\.(t|j)s$": "ts-jest" - } -} diff --git a/packages/apps/reputation-oracle/server/test/setup.ts b/packages/apps/reputation-oracle/server/test/setup.ts deleted file mode 100644 index 1e54185ca9..0000000000 --- a/packages/apps/reputation-oracle/server/test/setup.ts +++ /dev/null @@ -1,82 +0,0 @@ -import { KVStoreClient, KVStoreKeys, Role } from '@human-protocol/sdk'; -import { Wallet, ethers } from 'ethers'; -import * as Minio from 'minio'; -import * as dotenv from 'dotenv'; -dotenv.config({ path: '.env.local' }); - -export async function setup(): Promise { - const privateKey = process.env.WEB3_PRIVATE_KEY; - if (!privateKey) { - throw new Error('Private key is empty'); - } - const jwtPublicKey = process.env.JWT_PUBLIC_KEY; - if (!jwtPublicKey) { - throw new Error('JWT public key is empty'); - } - - const minioClient = new Minio.Client({ - endPoint: process.env.S3_ENDPOINT || 'localhost', - port: parseInt(process.env.S3_PORT || '9000', 10), - useSSL: process.env.S3_USE_SSL === 'true', - accessKey: process.env.S3_ACCESS_KEY || 'access-key', - secretKey: process.env.S3_SECRET_KEY || 'secret-key', - }); - const bucket = process.env.S3_BUCKET || 'bucket'; - const fileName = 'repo-jwt-public-key.txt'; - const exists = await minioClient.bucketExists(bucket); - if (!exists) { - throw new Error('Bucket does not exists'); - } - try { - await minioClient.putObject(bucket, fileName, jwtPublicKey, { - 'Content-Type': 'application/json', - 'Cache-Control': 'no-store', - }); - } catch (e) { - console.log(e); - } - - const provider = new ethers.JsonRpcProvider('http://0.0.0.0:8545'); - const wallet = new Wallet(privateKey, provider); - - const kvStoreClient = await KVStoreClient.build(wallet); - await kvStoreClient.setBulk( - [ - KVStoreKeys.role, - KVStoreKeys.fee, - KVStoreKeys.webhookUrl, - KVStoreKeys.url, - ], - [ - Role.ReputationOracle, - '1', - 'http://localhost:5003/webhook', - 'http://localhost:5003', - ], - { nonce: 0 }, - ); - await kvStoreClient.setFileUrlAndHash( - `http://localhost:9000/bucket/${fileName}`, - 'jwt_public_key', - { nonce: 1 }, - ); - - if (process.env.PGP_ENCRYPT && process.env.PGP_ENCRYPT === 'true') { - if (!process.env.PGP_PUBLIC_KEY) { - throw new Error('PGP public key is empty'); - } - const fileName = 'repo-pgp-public-key.txt'; - - await minioClient.putObject(bucket, fileName, process.env.PGP_PUBLIC_KEY, { - 'Content-Type': 'application/json', - 'Cache-Control': 'no-store', - }); - await kvStoreClient.setFileUrlAndHash( - `http://localhost:9000/bucket/${fileName}`, - KVStoreKeys.publicKey, - { nonce: 2 }, - ); - } -} - -setup(); From 7f5a45340920422a09b7728e506396908c8de4d9 Mon Sep 17 00:00:00 2001 From: Dmitry Nechay Date: Thu, 13 Feb 2025 03:02:31 +0300 Subject: [PATCH 05/14] chore: remove unused module --- .../server/src/app.controller.spec.ts | 15 --------------- .../server/src/app.controller.ts | 14 -------------- .../reputation-oracle/server/src/app.module.ts | 2 -- 3 files changed, 31 deletions(-) delete mode 100644 packages/apps/reputation-oracle/server/src/app.controller.spec.ts delete mode 100644 packages/apps/reputation-oracle/server/src/app.controller.ts diff --git a/packages/apps/reputation-oracle/server/src/app.controller.spec.ts b/packages/apps/reputation-oracle/server/src/app.controller.spec.ts deleted file mode 100644 index 741a42c324..0000000000 --- a/packages/apps/reputation-oracle/server/src/app.controller.spec.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { AppController } from './app.controller'; - -describe('AppController', () => { - let appController: AppController; - - beforeEach(() => { - appController = new AppController(); - }); - - describe('Health Check', () => { - it('should return OK', async () => { - expect(await appController.health()).toBe('OK'); - }); - }); -}); diff --git a/packages/apps/reputation-oracle/server/src/app.controller.ts b/packages/apps/reputation-oracle/server/src/app.controller.ts deleted file mode 100644 index f82b076b7e..0000000000 --- a/packages/apps/reputation-oracle/server/src/app.controller.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { Controller, Get, Redirect } from '@nestjs/common'; -import { Public } from './common/decorators'; -import { ApiExcludeController } from '@nestjs/swagger'; - -@Controller('/') -@ApiExcludeController() -export class AppController { - @Public() - @Get('/') - @Redirect('/swagger', 301) - public health(): string { - return 'OK'; - } -} diff --git a/packages/apps/reputation-oracle/server/src/app.module.ts b/packages/apps/reputation-oracle/server/src/app.module.ts index b03e81fdef..4ecbdc07f5 100644 --- a/packages/apps/reputation-oracle/server/src/app.module.ts +++ b/packages/apps/reputation-oracle/server/src/app.module.ts @@ -2,7 +2,6 @@ import { Module } from '@nestjs/common'; import { APP_FILTER, APP_INTERCEPTOR, APP_PIPE } from '@nestjs/core'; import { ConfigModule } from '@nestjs/config'; import { ScheduleModule } from '@nestjs/schedule'; -import { AppController } from './app.controller'; import { DatabaseModule } from './database/database.module'; import { HttpValidationPipe } from './common/pipes'; import { HealthModule } from './modules/health/health.module'; @@ -71,6 +70,5 @@ import { EmailModule } from './modules/email/module'; EscrowCompletionModule, EmailModule, ], - controllers: [AppController], }) export class AppModule {} From e96680c4b252183fbfdf7b2bb741bb0cb7a1104c Mon Sep 17 00:00:00 2001 From: Dmitry Nechay Date: Thu, 13 Feb 2025 05:58:09 +0300 Subject: [PATCH 06/14] refactor: cleanup validators and transformers --- .../server/src/common/decorators/index.ts | 11 +- .../server/src/common/decorators/public.ts | 4 - .../server/src/common/decorators/roles.ts | 5 - .../src/common/decorators/validation.ts | 87 ------- .../server/src/common/dto/manifest.ts | 12 - .../transform-enum.interceptor.spec.ts | 237 ------------------ .../transform-enum.interceptor.ts | 121 --------- .../server/src/common/validators/index.ts | 32 +++ .../server/src/common/validators/web3.ts | 44 ++++ .../auth/dto/email-verification.dto.ts | 4 +- .../src/modules/auth/dto/password.dto.ts | 4 +- .../src/modules/auth/dto/sign-in.dto.ts | 8 +- .../src/modules/auth/dto/sign-up.dto.ts | 12 +- .../server/src/modules/kyc/kyc.dto.ts | 12 +- .../src/modules/payout/payout.interface.ts | 16 +- .../src/modules/payout/payout.service.ts | 21 +- .../reputation/reputation.controller.ts | 6 - .../src/modules/reputation/reputation.dto.ts | 46 ++-- .../server/src/modules/user/user.dto.ts | 4 +- .../server/src/modules/webhook/webhook.dto.ts | 8 +- 20 files changed, 155 insertions(+), 539 deletions(-) delete mode 100644 packages/apps/reputation-oracle/server/src/common/decorators/public.ts delete mode 100644 packages/apps/reputation-oracle/server/src/common/decorators/roles.ts delete mode 100644 packages/apps/reputation-oracle/server/src/common/decorators/validation.ts delete mode 100644 packages/apps/reputation-oracle/server/src/common/interceptors/transform-enum.interceptor.spec.ts delete mode 100644 packages/apps/reputation-oracle/server/src/common/interceptors/transform-enum.interceptor.ts create mode 100644 packages/apps/reputation-oracle/server/src/common/validators/web3.ts diff --git a/packages/apps/reputation-oracle/server/src/common/decorators/index.ts b/packages/apps/reputation-oracle/server/src/common/decorators/index.ts index 00df47fd20..4000eaa20b 100644 --- a/packages/apps/reputation-oracle/server/src/common/decorators/index.ts +++ b/packages/apps/reputation-oracle/server/src/common/decorators/index.ts @@ -1,3 +1,8 @@ -export * from './public'; -export * from './roles'; -export * from './validation'; +import { SetMetadata } from '@nestjs/common'; +import { Role } from '../enums/user'; + +export const Public = (): ((target: any, key?: any, descriptor?: any) => any) => + SetMetadata('isPublic', true); + +export const ROLES_KEY = 'roles'; +export const Roles = (...roles: Role[]) => SetMetadata(ROLES_KEY, roles); diff --git a/packages/apps/reputation-oracle/server/src/common/decorators/public.ts b/packages/apps/reputation-oracle/server/src/common/decorators/public.ts deleted file mode 100644 index a12eaafa09..0000000000 --- a/packages/apps/reputation-oracle/server/src/common/decorators/public.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { SetMetadata } from '@nestjs/common'; - -export const Public = (): ((target: any, key?: any, descriptor?: any) => any) => - SetMetadata('isPublic', true); diff --git a/packages/apps/reputation-oracle/server/src/common/decorators/roles.ts b/packages/apps/reputation-oracle/server/src/common/decorators/roles.ts deleted file mode 100644 index 85ff6a817d..0000000000 --- a/packages/apps/reputation-oracle/server/src/common/decorators/roles.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { SetMetadata } from '@nestjs/common'; -import { Role } from '../enums/user'; - -export const ROLES_KEY = 'roles'; -export const Roles = (...roles: Role[]) => SetMetadata(ROLES_KEY, roles); diff --git a/packages/apps/reputation-oracle/server/src/common/decorators/validation.ts b/packages/apps/reputation-oracle/server/src/common/decorators/validation.ts deleted file mode 100644 index a6cd51f277..0000000000 --- a/packages/apps/reputation-oracle/server/src/common/decorators/validation.ts +++ /dev/null @@ -1,87 +0,0 @@ -/* eslint-disable prettier/prettier */ -import { applyDecorators } from '@nestjs/common'; -import { Transform } from 'class-transformer'; -import { - registerDecorator, - ValidationOptions, - ValidationArguments, - IsEmail, -} from 'class-validator'; -import 'reflect-metadata'; - -export function IsEnumCaseInsensitive( - enumType: any, - validationOptions?: ValidationOptions, -) { - // eslint-disable-next-line @typescript-eslint/ban-types - return function (object: Object, propertyName: string) { - // Attach enum metadata to the property - Reflect.defineMetadata('custom:enum', enumType, object, propertyName); - - // Register the validation logic using class-validator - registerDecorator({ - name: 'isEnumWithMetadata', - target: object.constructor, - propertyName: propertyName, - options: validationOptions, - validator: { - validate(value: any, args: ValidationArguments) { - // Retrieve enum type from metadata - const enumType = Reflect.getMetadata( - 'custom:enum', - args.object, - args.property, - ); - if (!enumType) { - return false; // If no enum metadata is found, validation fails - } - - // Validate value is part of the enum - const enumValues = Object.values(enumType); - return enumValues.includes(value); - }, - defaultMessage(args: ValidationArguments) { - // Default message if validation fails - const enumType = Reflect.getMetadata( - 'custom:enum', - args.object, - args.property, - ); - const enumValues = Object.values(enumType).join(', '); - return `${args.property} must be a valid enum value. Valid values: [${enumValues}]`; - }, - }, - }); - }; -} - -export function LowercasedEmail() { - return applyDecorators( - IsEmail(), - Transform(({ value }: { value: string }) => value.toLowerCase()), - ); -} - -export function IsValidWeb3Signature(validationOptions?: ValidationOptions) { - return function (object: object, propertyName: string) { - registerDecorator({ - name: 'isValidWeb3Signature', - target: object.constructor, - propertyName: propertyName, - options: validationOptions, - validator: { - validate(value: any) { - if (typeof value !== 'string') { - return false; - } - - const regex = /^0x[a-fA-F0-9]{130}$/; - return regex.test(value); - }, - defaultMessage(args: ValidationArguments) { - return `${args.property} must be a valid Ethereum Web3 signature in hex format starting with "0x"`; - }, - }, - }); - }; -} diff --git a/packages/apps/reputation-oracle/server/src/common/dto/manifest.ts b/packages/apps/reputation-oracle/server/src/common/dto/manifest.ts index 20ec538816..6e66187f2b 100644 --- a/packages/apps/reputation-oracle/server/src/common/dto/manifest.ts +++ b/packages/apps/reputation-oracle/server/src/common/dto/manifest.ts @@ -7,7 +7,6 @@ import { IsString, } from 'class-validator'; import { JobRequestType } from '../enums'; -import { ChainId } from '@human-protocol/sdk'; export class CvatData { @IsString() @@ -83,14 +82,3 @@ export class FortuneManifestDto { @IsEnum(JobRequestType) requestType: JobRequestType; } - -export class CalculatePayoutsDto { - @IsEnum(ChainId) - chainId: ChainId; - - @IsString() - escrowAddress: string; - - @IsString() - finalResultsUrl: string; -} diff --git a/packages/apps/reputation-oracle/server/src/common/interceptors/transform-enum.interceptor.spec.ts b/packages/apps/reputation-oracle/server/src/common/interceptors/transform-enum.interceptor.spec.ts deleted file mode 100644 index fd3ae360a1..0000000000 --- a/packages/apps/reputation-oracle/server/src/common/interceptors/transform-enum.interceptor.spec.ts +++ /dev/null @@ -1,237 +0,0 @@ -import { TransformEnumInterceptor } from './transform-enum.interceptor'; -import { - ExecutionContext, - CallHandler, - BadRequestException, -} from '@nestjs/common'; -import { of } from 'rxjs'; -import { IsNumber, IsString, Min } from 'class-validator'; -import { JobRequestType } from '../../common/enums/job'; -import { ApiProperty } from '@nestjs/swagger'; -import { IsEnumCaseInsensitive } from '../decorators'; - -export class MockDto { - @ApiProperty({ - enum: JobRequestType, - }) - @IsEnumCaseInsensitive(JobRequestType) - public jobType: JobRequestType; - - @ApiProperty() - @IsNumber() - @Min(0.5) - public amount: number; - - @ApiProperty() - @IsString() - public address: string; -} - -describe('TransformEnumInterceptor', () => { - let interceptor: TransformEnumInterceptor; - let executionContext: ExecutionContext; - let callHandler: CallHandler; - - beforeEach(() => { - interceptor = new TransformEnumInterceptor(); - - // Mocking ExecutionContext and CallHandler - executionContext = { - switchToHttp: jest.fn().mockReturnValue({ - getRequest: jest.fn().mockReturnValue({ - body: { - jobType: 'FORTUNE', - amount: 5, - address: '0xCf88b3f1992458C2f5a229573c768D0E9F70C44e', - }, - query: { - jobType: 'FORTUNE', - }, - }), - }), - getHandler: jest.fn().mockReturnValue({ - name: 'create', // Assume the handler is named 'create' - }), - getClass: jest.fn().mockReturnValue({ - prototype: {}, - }), - } as unknown as ExecutionContext; - - callHandler = { - handle: jest.fn().mockReturnValue(of({})), - }; - - // Mock Reflect.getMetadata to return DTO and Enum types - Reflect.getMetadata = jest.fn((metadataKey, _target, propertyKey) => { - // Mock design:paramtypes to return MockDto as the parameter type - if (metadataKey === 'design:paramtypes') { - return [MockDto]; - } - - // Mock custom:enum to return the corresponding enum for each property - if (metadataKey === 'custom:enum' && propertyKey === 'jobType') { - return JobRequestType; - } - return undefined; // For non-enum properties, return undefined - }) as any; - }); - - it('should transform enum values in query params to lowercase', async () => { - // Run the interceptor - await interceptor.intercept(executionContext, callHandler).toPromise(); - - // Access the modified request query - const request = executionContext.switchToHttp().getRequest(); - - // Expectations - expect(request.query.jobType).toBe('fortune'); - expect(request.query).toEqual({ - jobType: 'fortune', - }); - expect(callHandler.handle).toBeCalled(); // Ensure the handler is called - }); - - it('should throw an error if the query value is not a valid enum', async () => { - // Modify the request query to have an invalid enum value for jobType - executionContext.switchToHttp = jest.fn().mockReturnValue({ - getRequest: jest.fn().mockReturnValue({ - query: { - jobType: 'invalidEnum', // Invalid enum value for jobType - }, - }), - }); - - try { - // Run the interceptor - await interceptor.intercept(executionContext, callHandler).toPromise(); - } catch (err) { - // Expect an error to be thrown - expect(err).toBeInstanceOf(BadRequestException); - expect(err.response.statusCode).toBe(400); - expect(err.response.message).toContain('Validation failed'); - } - }); - - it('should transform enum values to lowercase', async () => { - // Run the interceptor - await interceptor.intercept(executionContext, callHandler).toPromise(); - - // Access the modified request body - const request = executionContext.switchToHttp().getRequest(); - - // Expectations - expect(request.body.jobType).toBe('fortune'); // Should be transformed to lowercase - expect(request.body).toEqual({ - jobType: 'fortune', - amount: 5, - address: '0xCf88b3f1992458C2f5a229573c768D0E9F70C44e', - }); - expect(callHandler.handle).toBeCalled(); // Ensure the handler is called - }); - - it('should throw an error if the value is not a valid enum', async () => { - // Modify the request body to have an invalid enum value for jobType - executionContext.switchToHttp = jest.fn().mockReturnValue({ - getRequest: jest.fn().mockReturnValue({ - body: { - jobType: 'invalidEnum', // Invalid enum value for jobType - amount: 5, - address: '0xCf88b3f1992458C2f5a229573c768D0E9F70C44e', - }, - }), - }); - - try { - // Run the interceptor - await interceptor.intercept(executionContext, callHandler).toPromise(); - } catch (err) { - // Expect an error to be thrown - expect(err).toBeInstanceOf(BadRequestException); - expect(err.response.statusCode).toBe(400); - expect(err.response.message).toContain('Validation failed'); - } - }); - - it('should not transform non-enum properties', async () => { - // Run the interceptor with a non-enum property (amount and address) - await interceptor.intercept(executionContext, callHandler).toPromise(); - - // Access the modified request body - const request = executionContext.switchToHttp().getRequest(); - - // Expectations - expect(request.body.amount).toBe(5); // Non-enum property should remain unchanged - expect(request.body.address).toBe( - '0xCf88b3f1992458C2f5a229573c768D0E9F70C44e', - ); // Non-enum string should remain unchanged - expect(callHandler.handle).toBeCalled(); - }); - - it('should handle nested objects with enums', async () => { - // Modify the request body to have a nested object with enum value - executionContext.switchToHttp = jest.fn().mockReturnValue({ - getRequest: jest.fn().mockReturnValue({ - body: { - transaction: { - jobType: 'FORTUNE', - address: '0xCf88b3f1992458C2f5a229573c768D0E9F70C44e', - }, - amount: 5, - address: '0xCf88b3f1992458C2f5a229573c768D0E9F70C44e', - }, - }), - }); - - // Run the interceptor - await interceptor.intercept(executionContext, callHandler).toPromise(); - - // Access the modified request body - const request = executionContext.switchToHttp().getRequest(); - - // Expectations - expect(request.body.transaction.jobType).toBe('fortune'); - expect(request.body).toEqual({ - transaction: { - jobType: 'fortune', - address: '0xCf88b3f1992458C2f5a229573c768D0E9F70C44e', - }, - amount: 5, - address: '0xCf88b3f1992458C2f5a229573c768D0E9F70C44e', - }); - expect(callHandler.handle).toHaveBeenCalled(); - }); - - it('should return bodyOrQuery if instance is not an object', () => { - // Test with `null` as the instance - let result = interceptor['lowercaseEnumProperties']( - { status: 'PENDING' }, - null, - MockDto, - ); - expect(result).toEqual({ status: 'PENDING' }); - - // Test with `undefined` as the instance - result = interceptor['lowercaseEnumProperties']( - { status: 'PENDING' }, - undefined, - MockDto, - ); - expect(result).toEqual({ status: 'PENDING' }); - - // Test with a primitive value (string) as the instance - result = interceptor['lowercaseEnumProperties']( - { status: 'PENDING' }, - 'some string', - MockDto, - ); - expect(result).toEqual({ status: 'PENDING' }); - - // Test with a primitive value (number) as the instance - result = interceptor['lowercaseEnumProperties']( - { status: 'PENDING' }, - 123, - MockDto, - ); - expect(result).toEqual({ status: 'PENDING' }); - }); -}); diff --git a/packages/apps/reputation-oracle/server/src/common/interceptors/transform-enum.interceptor.ts b/packages/apps/reputation-oracle/server/src/common/interceptors/transform-enum.interceptor.ts deleted file mode 100644 index d24d146f34..0000000000 --- a/packages/apps/reputation-oracle/server/src/common/interceptors/transform-enum.interceptor.ts +++ /dev/null @@ -1,121 +0,0 @@ -import { - Injectable, - NestInterceptor, - ExecutionContext, - CallHandler, - BadRequestException, -} from '@nestjs/common'; -import { Observable } from 'rxjs'; -import { map } from 'rxjs/operators'; -import { plainToInstance, ClassConstructor } from 'class-transformer'; -import { validateSync } from 'class-validator'; -import 'reflect-metadata'; - -@Injectable() -export class TransformEnumInterceptor implements NestInterceptor { - intercept(context: ExecutionContext, next: CallHandler): Observable { - const request = context.switchToHttp().getRequest(); - const body = request.body; - const query = request.query; - - // Retrieve the class of the controller's DTO (if applicable) - const targetClass = this.getTargetClass(context); - - if (targetClass) { - // Transform and validate enums in the body (for POST requests) - if (body) { - request.body = this.transformEnums(body, targetClass); - } - - // Transform and validate enums in the query (for GET requests) - if (query) { - request.query = this.transformEnums(query, targetClass); - } - } - - return next.handle().pipe(map((data) => data)); - } - - private getTargetClass( - context: ExecutionContext, - ): ClassConstructor | null { - const handler = context.getHandler(); - const controller = context.getClass(); - - // Get the parameter types of the route handler - const routeArgs = Reflect.getMetadata( - 'design:paramtypes', - controller.prototype, - handler.name, - ); - - // Return the first parameter's constructor if the handler has a class (DTO) - return routeArgs && routeArgs.length > 0 - ? (routeArgs[0] as ClassConstructor) - : null; - } - - private transformEnums( - bodyOrQuery: any, - targetClass: ClassConstructor, - ): any { - // Convert the body or query to an instance of the target class - let transformedInstance = plainToInstance(targetClass, bodyOrQuery); - - // Transform the enums before validation - transformedInstance = this.lowercaseEnumProperties( - bodyOrQuery, - transformedInstance, - targetClass, - ); - - // Validate the transformed data - const validationErrors = validateSync(transformedInstance); - if (validationErrors.length > 0) { - throw new BadRequestException('Validation failed'); - } - - return bodyOrQuery; - } - - private lowercaseEnumProperties( - bodyOrQuery: any, - instance: any, - targetClass: ClassConstructor, - ): any { - if (!instance || typeof instance !== 'object') { - return bodyOrQuery; - } - - for (const property in bodyOrQuery) { - if (bodyOrQuery.hasOwnProperty(property)) { - const instanceValue = instance[property]; - - // Retrieve enum metadata if available - const enumType = Reflect.getMetadata( - 'custom:enum', - targetClass.prototype, - property, - ); - - if (enumType && typeof instanceValue === 'string') { - // Check if it's an enum and convert to lowercase - if (Object.values(enumType).includes(instanceValue.toLowerCase())) { - bodyOrQuery[property] = instanceValue.toLowerCase(); - } - } else if ( - typeof bodyOrQuery[property] === 'object' && - !Array.isArray(bodyOrQuery[property]) - ) { - // Recursively handle nested objects - this.lowercaseEnumProperties( - bodyOrQuery[property], - instance[property], - targetClass, - ); - } - } - } - return bodyOrQuery; - } -} diff --git a/packages/apps/reputation-oracle/server/src/common/validators/index.ts b/packages/apps/reputation-oracle/server/src/common/validators/index.ts index 47b7e7a263..459430a8bb 100644 --- a/packages/apps/reputation-oracle/server/src/common/validators/index.ts +++ b/packages/apps/reputation-oracle/server/src/common/validators/index.ts @@ -1 +1,33 @@ +import { applyDecorators } from '@nestjs/common'; +import { Transform } from 'class-transformer'; +import { IsEmail, IsEnum, ValidationOptions } from 'class-validator'; + export * from './password'; +export * from './web3'; + +/** + * TODO: if we want to use lowercased emails in the system, + * then it should be done somewhere in the business logic, + * not in HTTP validation layer + */ +export function IsLowercasedEmail() { + return applyDecorators( + IsEmail(), + Transform(({ value }: { value: string }) => value.toLowerCase()), + ); +} + +export function IsLowercasedEnum( + entity: object, + validationOptions?: ValidationOptions, +) { + return applyDecorators( + IsEnum(entity, validationOptions), + Transform(({ value }) => { + if (validationOptions?.each) { + return value.map((v: string) => v.toLowerCase()); + } + return value.toLowerCase(); + }), + ); +} diff --git a/packages/apps/reputation-oracle/server/src/common/validators/web3.ts b/packages/apps/reputation-oracle/server/src/common/validators/web3.ts new file mode 100644 index 0000000000..eed8b2be5b --- /dev/null +++ b/packages/apps/reputation-oracle/server/src/common/validators/web3.ts @@ -0,0 +1,44 @@ +import { ChainId } from '@human-protocol/sdk'; +import { applyDecorators } from '@nestjs/common'; +import { Transform } from 'class-transformer'; +import { + registerDecorator, + ValidationOptions, + ValidationArguments, + IsEnum, +} from 'class-validator'; + +export function IsValidWeb3Signature(validationOptions?: ValidationOptions) { + return function (object: object, propertyName: string) { + registerDecorator({ + name: 'isValidWeb3Signature', + target: object.constructor, + propertyName: propertyName, + options: validationOptions, + validator: { + validate(value: any) { + if (typeof value !== 'string') { + return false; + } + + const regex = /^0x[a-fA-F0-9]{130}$/; + return regex.test(value); + }, + defaultMessage(args: ValidationArguments) { + return `${args.property} must be a valid Ethereum Web3 signature in hex format starting with "0x"`; + }, + }, + }); + }; +} + +/** + * TODO: Remove "ALL" value from ChainId enum in sdk + * to avoid selecting it as valid value in flows + */ +export function IsChainId() { + return applyDecorators( + IsEnum(ChainId), + Transform(({ value }) => Number(value)), + ); +} diff --git a/packages/apps/reputation-oracle/server/src/modules/auth/dto/email-verification.dto.ts b/packages/apps/reputation-oracle/server/src/modules/auth/dto/email-verification.dto.ts index 36a3f2da4b..9c8cf0be04 100644 --- a/packages/apps/reputation-oracle/server/src/modules/auth/dto/email-verification.dto.ts +++ b/packages/apps/reputation-oracle/server/src/modules/auth/dto/email-verification.dto.ts @@ -1,10 +1,10 @@ import { ApiProperty } from '@nestjs/swagger'; import { IsString, IsUUID } from 'class-validator'; -import { LowercasedEmail } from '../../../common/decorators'; +import { IsLowercasedEmail } from '../../../common/validators'; export class ResendVerificationEmailDto { @ApiProperty() - @LowercasedEmail() + @IsLowercasedEmail() public email: string; @ApiProperty({ name: 'h_captcha_token' }) diff --git a/packages/apps/reputation-oracle/server/src/modules/auth/dto/password.dto.ts b/packages/apps/reputation-oracle/server/src/modules/auth/dto/password.dto.ts index 1d20033074..3c0fee33ba 100644 --- a/packages/apps/reputation-oracle/server/src/modules/auth/dto/password.dto.ts +++ b/packages/apps/reputation-oracle/server/src/modules/auth/dto/password.dto.ts @@ -1,7 +1,7 @@ import { applyDecorators } from '@nestjs/common'; import { ApiProperty } from '@nestjs/swagger'; import { IsString, MinLength } from 'class-validator'; -import { LowercasedEmail } from '../../../common/decorators'; +import { IsLowercasedEmail } from '../../../common/validators'; export function ValidPassword() { return applyDecorators( @@ -14,7 +14,7 @@ export function ValidPassword() { export class ForgotPasswordDto { @ApiProperty() - @LowercasedEmail() + @IsLowercasedEmail() public email: string; @ApiProperty({ name: 'h_captcha_token' }) diff --git a/packages/apps/reputation-oracle/server/src/modules/auth/dto/sign-in.dto.ts b/packages/apps/reputation-oracle/server/src/modules/auth/dto/sign-in.dto.ts index 759e1cbe51..08f92af916 100644 --- a/packages/apps/reputation-oracle/server/src/modules/auth/dto/sign-in.dto.ts +++ b/packages/apps/reputation-oracle/server/src/modules/auth/dto/sign-in.dto.ts @@ -1,13 +1,13 @@ import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; +import { IsEthereumAddress, IsOptional, IsString } from 'class-validator'; import { + IsLowercasedEmail, IsValidWeb3Signature, - LowercasedEmail, -} from '../../../common/decorators'; -import { IsEthereumAddress, IsOptional, IsString } from 'class-validator'; +} from '../../../common/validators'; export class Web2SignInDto { @ApiProperty() - @LowercasedEmail() + @IsLowercasedEmail() public email: string; @ApiProperty() diff --git a/packages/apps/reputation-oracle/server/src/modules/auth/dto/sign-up.dto.ts b/packages/apps/reputation-oracle/server/src/modules/auth/dto/sign-up.dto.ts index b9ae0a7321..4ffdfc60a3 100644 --- a/packages/apps/reputation-oracle/server/src/modules/auth/dto/sign-up.dto.ts +++ b/packages/apps/reputation-oracle/server/src/modules/auth/dto/sign-up.dto.ts @@ -1,16 +1,16 @@ import { ApiProperty } from '@nestjs/swagger'; import { IsEthereumAddress, IsString } from 'class-validator'; +import { ValidPassword } from './password.dto'; import { - IsEnumCaseInsensitive, + IsLowercasedEmail, + IsLowercasedEnum, IsValidWeb3Signature, - LowercasedEmail, -} from '../../../common/decorators'; +} from '../../../common/validators'; import { Role } from '../../../common/enums/user'; -import { ValidPassword } from './password.dto'; export class Web2SignUpDto { @ApiProperty() - @LowercasedEmail() + @IsLowercasedEmail() public email: string; @ApiProperty() @@ -30,7 +30,7 @@ export class Web3SignUpDto { @ApiProperty({ enum: Role, }) - @IsEnumCaseInsensitive(Role) + @IsLowercasedEnum(Role) public type: Role; @ApiProperty() diff --git a/packages/apps/reputation-oracle/server/src/modules/kyc/kyc.dto.ts b/packages/apps/reputation-oracle/server/src/modules/kyc/kyc.dto.ts index c516d7b3a6..5d7c794c57 100644 --- a/packages/apps/reputation-oracle/server/src/modules/kyc/kyc.dto.ts +++ b/packages/apps/reputation-oracle/server/src/modules/kyc/kyc.dto.ts @@ -1,7 +1,13 @@ import { ApiProperty } from '@nestjs/swagger'; -import { IsObject, IsOptional, IsString, IsUrl, IsUUID } from 'class-validator'; +import { + IsEnum, + IsObject, + IsOptional, + IsString, + IsUrl, + IsUUID, +} from 'class-validator'; import { KycStatus } from '../../common/enums/user'; -import { IsEnumCaseInsensitive } from '../../common/decorators'; export class KycSessionDto { @ApiProperty({ name: 'url' }) @@ -25,7 +31,7 @@ export class KycVerificationDto { public vendorData: string; @ApiProperty() - @IsEnumCaseInsensitive(KycStatus) + @IsEnum(KycStatus) public status: KycStatus; @ApiProperty({ nullable: true }) diff --git a/packages/apps/reputation-oracle/server/src/modules/payout/payout.interface.ts b/packages/apps/reputation-oracle/server/src/modules/payout/payout.interface.ts index 096afbe53f..c2629bff4f 100644 --- a/packages/apps/reputation-oracle/server/src/modules/payout/payout.interface.ts +++ b/packages/apps/reputation-oracle/server/src/modules/payout/payout.interface.ts @@ -1,9 +1,13 @@ import { ChainId } from '@human-protocol/sdk'; -import { - CalculatePayoutsDto, - CvatManifestDto, - FortuneManifestDto, -} from '../../common/dto/manifest'; +import { CvatManifestDto, FortuneManifestDto } from '../../common/dto/manifest'; + +export class CalculatePayoutsInput { + chainId: ChainId; + + escrowAddress: string; + + finalResultsUrl: string; +} export class SaveResultDto { /** @@ -25,7 +29,7 @@ export type CalculatedPayout = { export interface RequestAction { calculatePayouts: ( manifest: FortuneManifestDto | CvatManifestDto, - data: CalculatePayoutsDto, + data: CalculatePayoutsInput, ) => Promise; saveResults: ( chainId: ChainId, diff --git a/packages/apps/reputation-oracle/server/src/modules/payout/payout.service.ts b/packages/apps/reputation-oracle/server/src/modules/payout/payout.service.ts index 2b5bbdc03e..7b23af5e0a 100644 --- a/packages/apps/reputation-oracle/server/src/modules/payout/payout.service.ts +++ b/packages/apps/reputation-oracle/server/src/modules/payout/payout.service.ts @@ -10,17 +10,14 @@ import { ethers } from 'ethers'; import { Web3Service } from '../web3/web3.service'; import { JobRequestType } from '../../common/enums'; import { StorageService } from '../storage/storage.service'; -import { - CalculatePayoutsDto, - CvatManifestDto, - FortuneManifestDto, -} from '../../common/dto/manifest'; +import { CvatManifestDto, FortuneManifestDto } from '../../common/dto/manifest'; import { CvatAnnotationMeta, FortuneFinalResult, } from '../../common/dto/result'; import { CalculatedPayout, + CalculatePayoutsInput, RequestAction, SaveResultDto, } from './payout.interface'; @@ -101,7 +98,7 @@ export class PayoutService { const { calculatePayouts } = this.createPayoutSpecificActions[requestType]; - const data: CalculatePayoutsDto = { + const data: CalculatePayoutsInput = { chainId, escrowAddress, finalResultsUrl, @@ -114,7 +111,7 @@ export class PayoutService { [JobRequestType.FORTUNE]: { calculatePayouts: async ( manifest: FortuneManifestDto, - data: CalculatePayoutsDto, + data: CalculatePayoutsInput, ): Promise => this.calculatePayoutsFortune(manifest, data.finalResultsUrl), saveResults: async ( @@ -127,7 +124,7 @@ export class PayoutService { [JobRequestType.IMAGE_BOXES]: { calculatePayouts: async ( manifest: CvatManifestDto, - data: CalculatePayoutsDto, + data: CalculatePayoutsInput, ): Promise => this.calculatePayoutsCvat(manifest, data.chainId, data.escrowAddress), saveResults: async ( @@ -138,7 +135,7 @@ export class PayoutService { [JobRequestType.IMAGE_POINTS]: { calculatePayouts: async ( manifest: CvatManifestDto, - data: CalculatePayoutsDto, + data: CalculatePayoutsInput, ): Promise => this.calculatePayoutsCvat(manifest, data.chainId, data.escrowAddress), saveResults: async ( @@ -149,7 +146,7 @@ export class PayoutService { [JobRequestType.IMAGE_BOXES_FROM_POINTS]: { calculatePayouts: async ( manifest: CvatManifestDto, - data: CalculatePayoutsDto, + data: CalculatePayoutsInput, ): Promise => this.calculatePayoutsCvat(manifest, data.chainId, data.escrowAddress), saveResults: async ( @@ -160,7 +157,7 @@ export class PayoutService { [JobRequestType.IMAGE_SKELETONS_FROM_BOXES]: { calculatePayouts: async ( manifest: CvatManifestDto, - data: CalculatePayoutsDto, + data: CalculatePayoutsInput, ): Promise => this.calculatePayoutsCvat(manifest, data.chainId, data.escrowAddress), saveResults: async ( @@ -171,7 +168,7 @@ export class PayoutService { [JobRequestType.IMAGE_POLYGONS]: { calculatePayouts: async ( manifest: CvatManifestDto, - data: CalculatePayoutsDto, + data: CalculatePayoutsInput, ): Promise => this.calculatePayoutsCvat(manifest, data.chainId, data.escrowAddress), saveResults: async ( diff --git a/packages/apps/reputation-oracle/server/src/modules/reputation/reputation.controller.ts b/packages/apps/reputation-oracle/server/src/modules/reputation/reputation.controller.ts index a05a17d8ff..1238d19588 100644 --- a/packages/apps/reputation-oracle/server/src/modules/reputation/reputation.controller.ts +++ b/packages/apps/reputation-oracle/server/src/modules/reputation/reputation.controller.ts @@ -27,12 +27,6 @@ export class ReputationController { summary: 'Get All Reputations', description: 'Endpoint to get all reputations.', }) - @ApiQuery({ - name: 'chain_id', - description: 'Chain ID for filtering reputations.', - type: Number, - required: true, - }) @ApiResponse({ status: 200, description: 'Reputations retrieved successfully', diff --git a/packages/apps/reputation-oracle/server/src/modules/reputation/reputation.dto.ts b/packages/apps/reputation-oracle/server/src/modules/reputation/reputation.dto.ts index c1a74c07e7..48ad11d0de 100644 --- a/packages/apps/reputation-oracle/server/src/modules/reputation/reputation.dto.ts +++ b/packages/apps/reputation-oracle/server/src/modules/reputation/reputation.dto.ts @@ -1,26 +1,24 @@ +import { ChainId } from '@human-protocol/sdk'; import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; import { - IsEnum, IsEthereumAddress, - IsIn, IsNumber, IsOptional, IsString, Min, } from 'class-validator'; -import { ChainId } from '@human-protocol/sdk'; +import { Transform } from 'class-transformer'; import { ReputationEntityType, ReputationLevel, ReputationOrderBy, SortDirection, } from '../../common/enums'; -import { Transform } from 'class-transformer'; -import { IsEnumCaseInsensitive } from '../../common/decorators'; +import { IsChainId, IsLowercasedEnum } from '../../common/validators'; export class ReputationCreateDto { @ApiProperty({ name: 'chain_id' }) - @IsEnumCaseInsensitive(ChainId) + @IsChainId() public chainId: ChainId; @ApiProperty() @@ -32,7 +30,7 @@ export class ReputationCreateDto { public reputationPoints: number; @ApiProperty() - @IsEnumCaseInsensitive(ReputationEntityType) + @IsLowercasedEnum(ReputationEntityType) public type: ReputationEntityType; } @@ -43,10 +41,12 @@ export class ReputationUpdateDto { } export class ReputationGetAllQueryDto { - @ApiPropertyOptional({ enum: ChainId, name: 'chain_id' }) - @IsEnumCaseInsensitive(ChainId) + @ApiPropertyOptional({ + enum: ChainId, + name: 'chain_id', + }) + @IsChainId() @IsOptional() - @Transform(({ value }) => Number(value)) public chainId?: ChainId; @ApiPropertyOptional({ @@ -54,17 +54,21 @@ export class ReputationGetAllQueryDto { enum: ReputationEntityType, name: 'roles', }) - @IsEnumCaseInsensitive(ReputationEntityType, { each: true }) - @IsOptional() + /** + * NOTE: Order here matters + * + * Query param is string if single value and array if multiple + */ @Transform(({ value }) => (Array.isArray(value) ? value : [value])) + @IsLowercasedEnum(ReputationEntityType, { each: true }) + @IsOptional() public roles?: ReputationEntityType[]; @ApiPropertyOptional({ enum: ReputationOrderBy, default: ReputationOrderBy.CREATED_AT, }) - @IsEnum(ReputationOrderBy) - @IsIn(Object.values(ReputationOrderBy)) + @IsLowercasedEnum(ReputationOrderBy) @IsOptional() public orderBy?: ReputationOrderBy; @@ -72,8 +76,7 @@ export class ReputationGetAllQueryDto { enum: SortDirection, default: SortDirection.DESC, }) - @IsEnum(SortDirection) - @IsIn(Object.values(SortDirection)) + @IsLowercasedEnum(SortDirection) @IsOptional() public orderDirection?: SortDirection; @@ -99,15 +102,13 @@ export class ReputationGetParamsDto { export class ReputationGetQueryDto { @ApiProperty({ enum: ChainId, name: 'chain_id' }) - @IsEnumCaseInsensitive(ChainId) - @Transform(({ value }) => Number(value)) + @IsChainId() public chainId: ChainId; } export class ReputationDto { @ApiProperty({ enum: ChainId, name: 'chain_id' }) - @IsEnumCaseInsensitive(ChainId) - @Transform(({ value }) => Number(value)) + @IsChainId() chainId: ChainId; @ApiProperty() @@ -116,11 +117,10 @@ export class ReputationDto { address: string; @ApiProperty({ enum: ReputationLevel }) - @IsEnumCaseInsensitive(ReputationLevel) - @Transform(({ value }) => Number(value)) + @IsLowercasedEnum(ReputationLevel) reputation: ReputationLevel; @ApiProperty({ enum: ReputationEntityType }) - @IsEnumCaseInsensitive(ReputationEntityType) + @IsLowercasedEnum(ReputationEntityType) role: ReputationEntityType; } diff --git a/packages/apps/reputation-oracle/server/src/modules/user/user.dto.ts b/packages/apps/reputation-oracle/server/src/modules/user/user.dto.ts index ee2e2cd2e6..44f4a12be4 100644 --- a/packages/apps/reputation-oracle/server/src/modules/user/user.dto.ts +++ b/packages/apps/reputation-oracle/server/src/modules/user/user.dto.ts @@ -1,7 +1,7 @@ import { ApiProperty } from '@nestjs/swagger'; import { IsEthereumAddress, IsOptional, IsString } from 'class-validator'; import { SignatureType } from '../../common/enums/web3'; -import { IsEnumCaseInsensitive } from '../../common/decorators'; +import { IsLowercasedEnum } from '../../common/validators'; export class RegisterLabelerResponseDto { @ApiProperty({ name: 'site_key' }) @@ -61,7 +61,7 @@ export class PrepareSignatureDto { @ApiProperty({ enum: SignatureType, }) - @IsEnumCaseInsensitive(SignatureType) + @IsLowercasedEnum(SignatureType) public type: SignatureType; } diff --git a/packages/apps/reputation-oracle/server/src/modules/webhook/webhook.dto.ts b/packages/apps/reputation-oracle/server/src/modules/webhook/webhook.dto.ts index 56816ee0fb..31c563318c 100644 --- a/packages/apps/reputation-oracle/server/src/modules/webhook/webhook.dto.ts +++ b/packages/apps/reputation-oracle/server/src/modules/webhook/webhook.dto.ts @@ -1,16 +1,16 @@ +import { ChainId } from '@human-protocol/sdk'; import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; import { IsEthereumAddress, IsObject, IsOptional } from 'class-validator'; import { EventType } from '../../common/enums'; -import { ChainId } from '@human-protocol/sdk'; -import { IsEnumCaseInsensitive } from '../../common/decorators'; +import { IsChainId, IsLowercasedEnum } from '../../common/validators'; export class IncomingWebhookDto { @ApiProperty({ name: 'chain_id' }) - @IsEnumCaseInsensitive(ChainId) + @IsChainId() public chainId: ChainId; @ApiProperty({ name: 'event_type' }) - @IsEnumCaseInsensitive(EventType) + @IsLowercasedEnum(EventType) public eventType: EventType; @ApiProperty({ name: 'escrow_address' }) From 3a56d5d3762053818579daac11bf94d32ec553e9 Mon Sep 17 00:00:00 2001 From: Dmitry Nechay Date: Thu, 13 Feb 2025 13:48:49 +0300 Subject: [PATCH 07/14] refactor: wrap up case converting --- .../transform.interceptor.spec.ts | 247 +++++------------- .../interceptors/transform.interceptor.ts | 51 +--- .../server/src/common/utils/case-converter.ts | 40 --- .../webhook/webhook-outgoing.service.ts | 6 +- .../server/src/utils/case-converters.spec.ts | 172 ++++++++++++ .../server/src/utils/case-converters.ts | 41 ++- 6 files changed, 281 insertions(+), 276 deletions(-) delete mode 100644 packages/apps/reputation-oracle/server/src/common/utils/case-converter.ts create mode 100644 packages/apps/reputation-oracle/server/src/utils/case-converters.spec.ts diff --git a/packages/apps/reputation-oracle/server/src/common/interceptors/transform.interceptor.spec.ts b/packages/apps/reputation-oracle/server/src/common/interceptors/transform.interceptor.spec.ts index 609b603c0f..7c111923b6 100644 --- a/packages/apps/reputation-oracle/server/src/common/interceptors/transform.interceptor.spec.ts +++ b/packages/apps/reputation-oracle/server/src/common/interceptors/transform.interceptor.spec.ts @@ -10,213 +10,71 @@ import { } from '../../../test/mock-creators/nest'; describe('TransformInterceptor', () => { - describe('transformRequestData', () => { - it.each(['string', 42, BigInt(0), Symbol('test'), true, null, undefined])( - 'should not transform primitive [%#]', - (value: unknown) => { - expect(TransformInterceptor.transformRequestData(value)).toEqual(value); - }, - ); - - it('should not transform simple array', () => { - const input = faker.helpers.multiple(() => faker.string.sample()); - - const output = TransformInterceptor.transformRequestData(input); - - expect(output).toEqual(input); - }); - - it('should transform array of objects', () => { - const input = faker.helpers.multiple(() => ({ - test_case: faker.string.sample(), - })); - const expectedOutput = input.map((v) => ({ - testCase: v.test_case, - })); - - const output = TransformInterceptor.transformRequestData(input); + describe('intercept', () => { + const interceptor = new TransformInterceptor(); + let executionContextMock: ExecutionContextMock; + let callHandlerMock: CallHandlerMock; - expect(output).toEqual(expectedOutput); + beforeEach(() => { + executionContextMock = createExecutionContextMock(); + callHandlerMock = createCallHandlerMock(); }); - it('should transform plain object to camelCase', () => { - const input = { - random_string: faker.string.sample(), - random_number: faker.number.float(), - random_boolean: faker.datatype.boolean(), + it('should transform request body', async () => { + const originalInput = { + some_string: faker.string.sample(), + some_number: faker.number.float(), + some_boolean: faker.datatype.boolean(), always_null: null, - }; - - const output = TransformInterceptor.transformRequestData(input); - - expect(output).toEqual({ - randomString: input.random_string, - randomNumber: input.random_number, - randomBoolean: input.random_boolean, - alwaysNull: null, - }); - }); - - it('should transform input with nested data', () => { - const randomString = faker.string.sample(); - - const input = { nested_object: { with_array: [ { - of_objects: { - with_random_string: randomString, - }, + of_objects: faker.string.sample(), }, ], }, }; - const output = TransformInterceptor.transformRequestData(input); - - expect(output).toEqual({ - nestedObject: { - withArray: [ - { - ofObjects: { - withRandomString: randomString, - }, - }, - ], - }, - }); - }); - }); - - describe('transformResponseData', () => { - it.each(['string', 42, BigInt(0), Symbol('test'), true, null, undefined])( - 'should not transform primitive [%#]', - (value: unknown) => { - expect(TransformInterceptor.transformResponseData(value)).toEqual( - value, - ); - }, - ); - - it('should not transfrom file response', () => { - const input = new StreamableFile(Buffer.from('file-contents')); - - const output = TransformInterceptor.transformResponseData(input); - - expect(output).toEqual(input); - }); - - it('should not transform simple array', () => { - const input = faker.helpers.multiple(() => faker.string.sample()); - - const output = TransformInterceptor.transformResponseData(input); - - expect(output).toEqual(input); - }); - - it('should transform array of objects', () => { - const input = faker.helpers.multiple(() => ({ - testCase: faker.string.sample(), - })); - const expectedOutput = input.map((v) => ({ - test_case: v.testCase, - })); - - const output = TransformInterceptor.transformResponseData(input); + const request = { body: originalInput }; + executionContextMock.__getRequest.mockReturnValueOnce(request); - expect(output).toEqual(expectedOutput); - }); + await firstValueFrom( + interceptor.intercept( + executionContextMock as unknown as ExecutionContext, + callHandlerMock, + ), + ); - it('should transform plain object to camelCase', () => { - const input = { - randomString: faker.string.sample(), - randomNumber: faker.number.float(), - randomBoolean: faker.datatype.boolean(), + expect(request.body).toEqual({ + someString: originalInput.some_string, + someNumber: originalInput.some_number, + someBoolean: originalInput.some_boolean, alwaysNull: null, - }; - - const output = TransformInterceptor.transformResponseData(input); - - expect(output).toEqual({ - random_string: input.randomString, - random_number: input.randomNumber, - random_boolean: input.randomBoolean, - always_null: null, - }); - }); - - it('should transform date in response to ISO string', () => { - const input = { - date: faker.date.anytime(), - nested: { - date: faker.date.anytime(), - }, - array: [faker.date.anytime()], - }; - - const output = TransformInterceptor.transformResponseData(input); - - expect(output).toEqual({ - date: input.date.toISOString(), - nested: { - date: input.nested.date.toISOString(), - }, - array: input.array.map((v) => v.toISOString()), - }); - }); - - it('should transform input with nested data', () => { - const randomString = faker.string.sample(); - - const input = { nestedObject: { withArray: [ { - ofObjects: { - withRandomString: randomString, - }, - }, - ], - }, - }; - - const output = TransformInterceptor.transformResponseData(input); - - expect(output).toEqual({ - nested_object: { - with_array: [ - { - of_objects: { - with_random_string: randomString, - }, + ofObjects: originalInput.nested_object.with_array[0].of_objects, }, ], }, }); }); - }); - describe('intercept', () => { - const interceptor = new TransformInterceptor(); - let executionContextMock: ExecutionContextMock; - let callHandlerMock: CallHandlerMock; - - beforeEach(() => { - executionContextMock = createExecutionContextMock(); - callHandlerMock = createCallHandlerMock(); - }); - - it('should transform request', async () => { - const randomValueForBody = faker.string.sample(); - const randomValueForQuery = faker.string.sample(); + it('should transform request query', async () => { + /** + * Interceptors called before pipes, so we can get + * only those types that Nest automatically parses + */ + const originalInput = { + some_string: faker.string.sample(), + some_number: faker.number.float(), + some_boolean: faker.datatype.boolean(), + some_date: faker.date.anytime(), + some_array: faker.helpers.multiple(() => faker.string.sample()), + }; const request = { - body: { - some_body_key: randomValueForBody, - }, - query: { - some_query_key: randomValueForQuery, - }, + query: originalInput, }; executionContextMock.__getRequest.mockReturnValueOnce(request); @@ -227,15 +85,30 @@ describe('TransformInterceptor', () => { ), ); - expect(request.body).toEqual({ - someBodyKey: randomValueForBody, - }); - expect(request.query).toEqual({ - someQueryKey: randomValueForQuery, + someString: originalInput.some_string, + someNumber: originalInput.some_number, + someBoolean: originalInput.some_boolean, + someDate: originalInput.some_date, + someArray: originalInput.some_array, }); }); + it('should not transform response if it is a file', async () => { + const testFile = new StreamableFile(Buffer.from('test-contents')); + + callHandlerMock.handle.mockReturnValueOnce(of(testFile)); + + const responseBody = await firstValueFrom( + interceptor.intercept( + executionContextMock as unknown as ExecutionContext, + callHandlerMock, + ), + ); + + expect(responseBody).toEqual(testFile); + }); + it('should transform response', async () => { const originalResponseBody = { someResponseValue: faker.string.sample(), @@ -252,7 +125,7 @@ describe('TransformInterceptor', () => { expect(interceptedResponseBody).toEqual({ some_response_value: originalResponseBody.someResponseValue, - some_response_date: originalResponseBody.someResponseDate.toISOString(), + some_response_date: originalResponseBody.someResponseDate, }); }); }); diff --git a/packages/apps/reputation-oracle/server/src/common/interceptors/transform.interceptor.ts b/packages/apps/reputation-oracle/server/src/common/interceptors/transform.interceptor.ts index 6e7e06d5b4..49c8070a7e 100644 --- a/packages/apps/reputation-oracle/server/src/common/interceptors/transform.interceptor.ts +++ b/packages/apps/reputation-oracle/server/src/common/interceptors/transform.interceptor.ts @@ -8,7 +8,6 @@ import { import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; import * as CaseConverter from '../../utils/case-converters'; -import { isObject } from '../../utils/type-guards'; @Injectable() export class TransformInterceptor implements NestInterceptor { @@ -16,59 +15,25 @@ export class TransformInterceptor implements NestInterceptor { const request = context.switchToHttp().getRequest(); if (request.body) { - request.body = TransformInterceptor.transformRequestData(request.body); + request.body = this.transformRequestData(request.body); } if (request.query) { - request.query = TransformInterceptor.transformRequestData(request.query); + request.query = this.transformRequestData(request.query); } - return next - .handle() - .pipe(map((data) => TransformInterceptor.transformResponseData(data))); + return next.handle().pipe(map((data) => this.transformResponseData(data))); } - static transformRequestData(input: unknown): unknown { - /** - * If primitive value - no need to transform - */ - if (!isObject(input)) { - return input; - } - - if (Array.isArray(input)) { - return input.map(TransformInterceptor.transformRequestData); - } - - const transformedObject: Record = {}; - for (const [key, value] of Object.entries(input)) { - transformedObject[CaseConverter.snakeToCamel(key)] = - TransformInterceptor.transformRequestData(value); - } - return transformedObject; + private transformRequestData(input: unknown): unknown { + return CaseConverter.transformKeysFromSnakeToCamel(input); } - static transformResponseData(input: unknown): unknown { - /** - * If primitive value or file - return as is - */ - if (!isObject(input) || input instanceof StreamableFile) { + private transformResponseData(input: unknown): unknown { + if (input instanceof StreamableFile) { return input; } - if (input instanceof Date) { - return input.toISOString(); - } - - if (Array.isArray(input)) { - return input.map(TransformInterceptor.transformResponseData); - } - - const transformedObject: Record = {}; - for (const [key, value] of Object.entries(input)) { - transformedObject[CaseConverter.camelToSnake(key)] = - TransformInterceptor.transformResponseData(value); - } - return transformedObject; + return CaseConverter.transformKeysFromCamelToSnake(input); } } diff --git a/packages/apps/reputation-oracle/server/src/common/utils/case-converter.ts b/packages/apps/reputation-oracle/server/src/common/utils/case-converter.ts deleted file mode 100644 index 6c52276739..0000000000 --- a/packages/apps/reputation-oracle/server/src/common/utils/case-converter.ts +++ /dev/null @@ -1,40 +0,0 @@ -export class CaseConverter { - static transformToCamelCase(obj: any): any { - if (Array.isArray(obj)) { - return obj.map((item) => CaseConverter.transformToCamelCase(item)); - } else if (typeof obj === 'object' && obj !== null) { - return Object.keys(obj).reduce( - (acc: Record, key: string) => { - const camelCaseKey = key.replace(/_([a-z])/g, (g) => - g[1].toUpperCase(), - ); - acc[camelCaseKey] = CaseConverter.transformToCamelCase(obj[key]); - return acc; - }, - {}, - ); - } else { - return obj; - } - } - - static transformToSnakeCase(obj: any): any { - if (Array.isArray(obj)) { - return obj.map((item) => CaseConverter.transformToSnakeCase(item)); - } else if (typeof obj === 'object' && obj !== null) { - if (obj instanceof Date) { - return obj.toISOString(); // Convert Date object to ISO string format - } - return Object.keys(obj).reduce( - (acc: Record, key: string) => { - const snakeCaseKey = key.replace(/([A-Z])/g, '_$1').toLowerCase(); - acc[snakeCaseKey] = CaseConverter.transformToSnakeCase(obj[key]); - return acc; - }, - {}, - ); - } else { - return obj; - } - } -} diff --git a/packages/apps/reputation-oracle/server/src/modules/webhook/webhook-outgoing.service.ts b/packages/apps/reputation-oracle/server/src/modules/webhook/webhook-outgoing.service.ts index 726c0af585..099b27ba0a 100644 --- a/packages/apps/reputation-oracle/server/src/modules/webhook/webhook-outgoing.service.ts +++ b/packages/apps/reputation-oracle/server/src/modules/webhook/webhook-outgoing.service.ts @@ -10,7 +10,7 @@ import { HEADER_SIGNATURE_KEY, } from '../../common/constants'; import { HttpService } from '@nestjs/axios'; -import { CaseConverter } from '../../common/utils/case-converter'; +import { transformKeysFromCamelToSnake } from '../../utils/case-converters'; import { ServerConfigService } from '../../common/config/server-config.service'; import { Web3ConfigService } from '../../common/config/web3-config.service'; import { WebhookOutgoingEntity } from './webhook-outgoing.entity'; @@ -94,9 +94,9 @@ export class WebhookOutgoingService { public async sendWebhook( outgoingWebhook: WebhookOutgoingEntity, ): Promise { - const snake_case_body = CaseConverter.transformToSnakeCase( + const snake_case_body = transformKeysFromCamelToSnake( outgoingWebhook.payload, - ); + ) as object; const signedBody = await signMessage( snake_case_body, this.web3ConfigService.privateKey, diff --git a/packages/apps/reputation-oracle/server/src/utils/case-converters.spec.ts b/packages/apps/reputation-oracle/server/src/utils/case-converters.spec.ts new file mode 100644 index 0000000000..529797dbcc --- /dev/null +++ b/packages/apps/reputation-oracle/server/src/utils/case-converters.spec.ts @@ -0,0 +1,172 @@ +import { faker } from '@faker-js/faker'; +import * as CaseConverter from './case-converters'; + +describe('case-converters', () => { + describe('transformKeysFromSnakeToCamel', () => { + it.each([ + 'string', + 42, + BigInt(0), + new Date(), + Symbol('test'), + true, + null, + undefined, + ])('should not transform basic value [%#]', (value: unknown) => { + expect(CaseConverter.transformKeysFromSnakeToCamel(value)).toEqual(value); + }); + + it('should not transform simple array', () => { + const input = faker.helpers.multiple(() => faker.string.sample()); + + const output = CaseConverter.transformKeysFromSnakeToCamel(input); + + expect(output).toEqual(input); + }); + + it('should transform array of objects', () => { + const input = faker.helpers.multiple(() => ({ + test_case: faker.string.sample(), + })); + const expectedOutput = input.map((v) => ({ + testCase: v.test_case, + })); + + const output = CaseConverter.transformKeysFromSnakeToCamel(input); + + expect(output).toEqual(expectedOutput); + }); + + it('should transform plain object to camelCase', () => { + const input = { + random_string: faker.string.sample(), + random_number: faker.number.float(), + random_boolean: faker.datatype.boolean(), + always_null: null, + }; + + const output = CaseConverter.transformKeysFromSnakeToCamel(input); + + expect(output).toEqual({ + randomString: input.random_string, + randomNumber: input.random_number, + randomBoolean: input.random_boolean, + alwaysNull: null, + }); + }); + + it('should transform input with nested data', () => { + const randomString = faker.string.sample(); + + const input = { + nested_object: { + with_array: [ + { + of_objects: { + with_random_string: randomString, + }, + }, + ], + }, + }; + + const output = CaseConverter.transformKeysFromSnakeToCamel(input); + + expect(output).toEqual({ + nestedObject: { + withArray: [ + { + ofObjects: { + withRandomString: randomString, + }, + }, + ], + }, + }); + }); + }); + + describe('transformKeysFromCamelToSnake', () => { + it.each([ + 'string', + 42, + BigInt(0), + new Date(), + Symbol('test'), + true, + null, + undefined, + ])('should not transform primitive [%#]', (value: unknown) => { + expect(CaseConverter.transformKeysFromCamelToSnake(value)).toEqual(value); + }); + + it('should not transform simple array', () => { + const input = faker.helpers.multiple(() => faker.string.sample()); + + const output = CaseConverter.transformKeysFromCamelToSnake(input); + + expect(output).toEqual(input); + }); + + it('should transform array of objects', () => { + const input = faker.helpers.multiple(() => ({ + testCase: faker.string.sample(), + })); + const expectedOutput = input.map((v) => ({ + test_case: v.testCase, + })); + + const output = CaseConverter.transformKeysFromCamelToSnake(input); + + expect(output).toEqual(expectedOutput); + }); + + it('should transform plain object to camelCase', () => { + const input = { + randomString: faker.string.sample(), + randomNumber: faker.number.float(), + randomBoolean: faker.datatype.boolean(), + alwaysNull: null, + }; + + const output = CaseConverter.transformKeysFromCamelToSnake(input); + + expect(output).toEqual({ + random_string: input.randomString, + random_number: input.randomNumber, + random_boolean: input.randomBoolean, + always_null: null, + }); + }); + + it('should transform input with nested data', () => { + const randomString = faker.string.sample(); + + const input = { + nestedObject: { + withArray: [ + { + ofObjects: { + withRandomString: randomString, + }, + }, + ], + }, + }; + + const output = CaseConverter.transformKeysFromCamelToSnake(input); + + expect(output).toEqual({ + nested_object: { + with_array: [ + { + of_objects: { + with_random_string: randomString, + }, + }, + ], + }, + }); + }); + }); +}); diff --git a/packages/apps/reputation-oracle/server/src/utils/case-converters.ts b/packages/apps/reputation-oracle/server/src/utils/case-converters.ts index 66db69c6bc..7a1eeed4d4 100644 --- a/packages/apps/reputation-oracle/server/src/utils/case-converters.ts +++ b/packages/apps/reputation-oracle/server/src/utils/case-converters.ts @@ -1,15 +1,50 @@ +import { isObject } from './type-guards'; + +type CaseTransformer = (input: string) => string; + /** * TODO: check if replacing it with lodash.camelCase * won't break anything */ -export function snakeToCamel(input: string): string { +export const snakeToCamel: CaseTransformer = (input) => { return input.replace(/_([a-z])/g, (_match, letter) => letter.toUpperCase()); -} +}; /** * TODO: check if replacing it with lodash.snakeCase * won't break anything */ -export function camelToSnake(input: string): string { +export const camelToSnake: CaseTransformer = (input) => { return input.replace(/([A-Z])/g, '_$1').toLowerCase(); +}; + +function transformKeysCase( + input: unknown, + transformer: CaseTransformer, +): unknown { + /** + * Primitives and Date objects returned as is + * to keep their original value for later use + */ + if (!isObject(input) || input instanceof Date) { + return input; + } + + if (Array.isArray(input)) { + return input.map((value) => transformKeysCase(value, transformer)); + } + + const transformedObject: Record = {}; + for (const [key, value] of Object.entries(input)) { + transformedObject[transformer(key)] = transformKeysCase(value, transformer); + } + return transformedObject; +} + +export function transformKeysFromSnakeToCamel(input: unknown): unknown { + return transformKeysCase(input, snakeToCamel); +} + +export function transformKeysFromCamelToSnake(input: unknown): unknown { + return transformKeysCase(input, camelToSnake); } From 07b37ad0cba0488d2a4ab2c6d489c71c13c999bf Mon Sep 17 00:00:00 2001 From: Dmitry Nechay Date: Thu, 13 Feb 2025 14:29:08 +0300 Subject: [PATCH 08/14] refactor: regroup some utils --- .../src/common/guards/signature.auth.spec.ts | 2 +- .../src/common/guards/signature.auth.ts | 2 +- .../server/src/common/utils/backoff.spec.ts | 28 ------- .../server/src/common/utils/index.ts | 50 ------------- .../server/src/common/utils/signature.ts | 66 ---------------- .../src/modules/auth/auth.service.spec.ts | 2 +- .../server/src/modules/auth/auth.service.ts | 4 +- .../src/modules/payout/payout.service.ts | 3 +- .../modules/reputation/reputation.service.ts | 2 +- .../src/modules/user/user.controller.ts | 2 +- .../src/modules/user/user.service.spec.ts | 5 +- .../server/src/modules/user/user.service.ts | 4 +- .../webhook/webhook-outgoing.service.spec.ts | 2 +- .../webhook/webhook-outgoing.service.ts | 2 +- .../server/src/utils/backoff.spec.ts | 44 +++++++++++ .../server/src/{common => }/utils/backoff.ts | 2 +- .../server/src/utils/case-converters.spec.ts | 2 +- .../server/src/utils/case-converters.ts | 4 +- .../server/src/utils/manifest.ts | 18 +++++ .../server/src/utils/type-guards.ts | 14 ++++ .../signature.spec.ts => utils/web3.spec.ts} | 18 ++--- .../server/src/utils/web3.ts | 75 +++++++++++++++++++ 22 files changed, 178 insertions(+), 173 deletions(-) delete mode 100644 packages/apps/reputation-oracle/server/src/common/utils/backoff.spec.ts delete mode 100644 packages/apps/reputation-oracle/server/src/common/utils/index.ts delete mode 100644 packages/apps/reputation-oracle/server/src/common/utils/signature.ts create mode 100644 packages/apps/reputation-oracle/server/src/utils/backoff.spec.ts rename packages/apps/reputation-oracle/server/src/{common => }/utils/backoff.ts (74%) create mode 100644 packages/apps/reputation-oracle/server/src/utils/manifest.ts rename packages/apps/reputation-oracle/server/src/{common/utils/signature.spec.ts => utils/web3.spec.ts} (83%) create mode 100644 packages/apps/reputation-oracle/server/src/utils/web3.ts diff --git a/packages/apps/reputation-oracle/server/src/common/guards/signature.auth.spec.ts b/packages/apps/reputation-oracle/server/src/common/guards/signature.auth.spec.ts index f9e9380fb3..d25e3c257c 100644 --- a/packages/apps/reputation-oracle/server/src/common/guards/signature.auth.spec.ts +++ b/packages/apps/reputation-oracle/server/src/common/guards/signature.auth.spec.ts @@ -1,7 +1,7 @@ import { Test, TestingModule } from '@nestjs/testing'; import { ExecutionContext, HttpException, HttpStatus } from '@nestjs/common'; import { SignatureAuthGuard } from './signature.auth'; -import { signMessage } from '../utils/signature'; +import { signMessage } from '../../utils/web3'; import { ChainId, EscrowUtils } from '@human-protocol/sdk'; import { MOCK_ADDRESS, MOCK_PRIVATE_KEY } from '../../../test/constants'; import { AuthSignatureRole } from '../enums/role'; diff --git a/packages/apps/reputation-oracle/server/src/common/guards/signature.auth.ts b/packages/apps/reputation-oracle/server/src/common/guards/signature.auth.ts index 9ec08e5d6e..314e3660ff 100644 --- a/packages/apps/reputation-oracle/server/src/common/guards/signature.auth.ts +++ b/packages/apps/reputation-oracle/server/src/common/guards/signature.auth.ts @@ -5,7 +5,7 @@ import { HttpStatus, Injectable, } from '@nestjs/common'; -import { verifySignature } from '../utils/signature'; +import { verifySignature } from '../../utils/web3'; import { HEADER_SIGNATURE_KEY } from '../constants'; import { EscrowUtils } from '@human-protocol/sdk'; import { AuthSignatureRole } from '../enums/role'; diff --git a/packages/apps/reputation-oracle/server/src/common/utils/backoff.spec.ts b/packages/apps/reputation-oracle/server/src/common/utils/backoff.spec.ts deleted file mode 100644 index 1b1d545c76..0000000000 --- a/packages/apps/reputation-oracle/server/src/common/utils/backoff.spec.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { MOCK_BACKOFF_INTERVAL_SECONDS } from '../../../test/constants'; -import { calculateExponentialBackoffMs } from './backoff'; - -describe('calculateExponentialBackoffMs', () => { - it('should return 2 minutes backoff for the first retry (retriesCount = 0)', () => { - const retriesCount = 0; - const result = calculateExponentialBackoffMs(retriesCount); - expect(result).toBe(MOCK_BACKOFF_INTERVAL_SECONDS * 1000); // 2 minutes in milliseconds - }); - - it('should return 4 minutes backoff for the second retry (retriesCount = 1)', () => { - const retriesCount = 1; - const result = calculateExponentialBackoffMs(retriesCount); - expect(result).toBe(2 * MOCK_BACKOFF_INTERVAL_SECONDS * 1000); // 4 minutes in milliseconds - }); - - it('should return 8 minutes backoff for the third retry (retriesCount = 2)', () => { - const retriesCount = 2; - const result = calculateExponentialBackoffMs(retriesCount); - expect(result).toBe(4 * MOCK_BACKOFF_INTERVAL_SECONDS * 1000); // 8 minutes in milliseconds - }); - - it('should return 64 minutes backoff for the sixth retry (retriesCount = 5)', () => { - const retriesCount = 5; - const result = calculateExponentialBackoffMs(retriesCount); - expect(result).toBe(32 * MOCK_BACKOFF_INTERVAL_SECONDS * 1000); // 64 minutes in milliseconds - }); -}); diff --git a/packages/apps/reputation-oracle/server/src/common/utils/index.ts b/packages/apps/reputation-oracle/server/src/common/utils/index.ts deleted file mode 100644 index 0178818dac..0000000000 --- a/packages/apps/reputation-oracle/server/src/common/utils/index.ts +++ /dev/null @@ -1,50 +0,0 @@ -import * as crypto from 'crypto'; -import { Readable } from 'stream'; -import { CvatManifestDto, FortuneManifestDto } from '../dto/manifest'; -import { JobRequestType } from '../enums'; -import { UnsupportedManifestTypeError } from '../errors/manifest'; - -export function hashStream(stream: Readable): Promise { - return new Promise((resolve, reject) => { - const hash = crypto.createHash('sha1'); - - stream.on('data', (chunk) => { - hash.update(chunk); - }); - - stream.on('end', () => { - resolve(hash.digest('hex')); - }); - - stream.on('error', (error) => { - reject(error); - }); - }); -} - -export function getRequestType( - manifest: FortuneManifestDto | CvatManifestDto, -): JobRequestType { - const requestType = - (manifest as FortuneManifestDto).requestType || - ((manifest as CvatManifestDto).annotation && - (manifest as CvatManifestDto).annotation.type); - - if (!requestType) { - throw new UnsupportedManifestTypeError(requestType); - } - - return requestType; -} - -export function assertValidJobRequestType( - value: string, -): asserts value is JobRequestType { - const validValues = Object.values(JobRequestType); - - if (validValues.includes(value)) { - return; - } - - throw new Error(`Unsupported request type: ${value}`); -} diff --git a/packages/apps/reputation-oracle/server/src/common/utils/signature.ts b/packages/apps/reputation-oracle/server/src/common/utils/signature.ts deleted file mode 100644 index 7e76a417b0..0000000000 --- a/packages/apps/reputation-oracle/server/src/common/utils/signature.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { ethers } from 'ethers'; - -export function verifySignature( - message: object | string, - signature: string, - addresses: string[], -): boolean { - const signer = recoverSigner(message, signature); - - return addresses.some( - (address) => address.toLowerCase() === signer.toLowerCase(), - ); -} - -export async function signMessage( - message: object | string, - privateKey: string, -): Promise { - if (typeof message !== 'string') { - message = JSON.stringify(message); - } - - const wallet = new ethers.Wallet(privateKey); - const signature = await wallet.signMessage(message); - - return signature; -} - -export function recoverSigner( - message: object | string, - signature: string, -): string { - if (typeof message !== 'string') { - message = JSON.stringify(message); - } - - try { - return ethers.verifyMessage(message, signature); - } catch (noop) { - return ''; - } -} - -export function generateNonce(): string { - return Buffer.from(ethers.randomBytes(16)).toString('hex'); -} - -type SignatureBody = { - from: string; - to: string; - contents: string; - nonce?: string; -}; -export function prepareSignatureBody({ - from, - to, - contents, - nonce, -}: SignatureBody): SignatureBody { - return { - from: from.toLowerCase(), - to: to.toLowerCase(), - contents, - nonce: nonce ?? undefined, - }; -} diff --git a/packages/apps/reputation-oracle/server/src/modules/auth/auth.service.spec.ts b/packages/apps/reputation-oracle/server/src/modules/auth/auth.service.spec.ts index ec02abe317..de955fe045 100644 --- a/packages/apps/reputation-oracle/server/src/modules/auth/auth.service.spec.ts +++ b/packages/apps/reputation-oracle/server/src/modules/auth/auth.service.spec.ts @@ -35,7 +35,7 @@ import { generateNonce, prepareSignatureBody, signMessage, -} from '../../common/utils/signature'; +} from '../../utils/web3'; import { HCaptchaService } from '../../integrations/hcaptcha/hcaptcha.service'; import { SiteKeyRepository } from '../user/site-key.repository'; import { PrepareSignatureDto } from '../user/user.dto'; diff --git a/packages/apps/reputation-oracle/server/src/modules/auth/auth.service.ts b/packages/apps/reputation-oracle/server/src/modules/auth/auth.service.ts index 94ad08285f..054d3372d8 100644 --- a/packages/apps/reputation-oracle/server/src/modules/auth/auth.service.ts +++ b/packages/apps/reputation-oracle/server/src/modules/auth/auth.service.ts @@ -10,7 +10,7 @@ import { UserEntity } from '../user/user.entity'; import { UserService } from '../user/user.service'; import { TokenEntity, TokenType } from './token.entity'; import { TokenRepository } from './token.repository'; -import { verifySignature } from '../../common/utils/signature'; +import { verifySignature } from '../../utils/web3'; import { Web3Service } from '../web3/web3.service'; import { ChainId, @@ -20,7 +20,7 @@ import { Role, } from '@human-protocol/sdk'; import { SignatureType, Web3Env } from '../../common/enums/web3'; -import { prepareSignatureBody } from '../../common/utils/signature'; +import { prepareSignatureBody } from '../../utils/web3'; import { UserRepository } from '../user/user.repository'; import { AuthConfigService } from '../../common/config/auth-config.service'; import { ServerConfigService } from '../../common/config/server-config.service'; diff --git a/packages/apps/reputation-oracle/server/src/modules/payout/payout.service.ts b/packages/apps/reputation-oracle/server/src/modules/payout/payout.service.ts index 7b23af5e0a..1d96873dd5 100644 --- a/packages/apps/reputation-oracle/server/src/modules/payout/payout.service.ts +++ b/packages/apps/reputation-oracle/server/src/modules/payout/payout.service.ts @@ -21,7 +21,8 @@ import { RequestAction, SaveResultDto, } from './payout.interface'; -import { assertValidJobRequestType, getRequestType } from '../../common/utils'; +import { getRequestType } from '../../utils/manifest'; +import { assertValidJobRequestType } from '../../utils/type-guards'; import { MissingManifestUrlError } from '../../common/errors/manifest'; @Injectable() diff --git a/packages/apps/reputation-oracle/server/src/modules/reputation/reputation.service.ts b/packages/apps/reputation-oracle/server/src/modules/reputation/reputation.service.ts index cd98e6b179..738455f4ae 100644 --- a/packages/apps/reputation-oracle/server/src/modules/reputation/reputation.service.ts +++ b/packages/apps/reputation-oracle/server/src/modules/reputation/reputation.service.ts @@ -23,7 +23,7 @@ import { FortuneFinalResult, } from '../../common/dto/result'; import { RequestAction } from './reputation.interface'; -import { getRequestType } from '../../common/utils'; +import { getRequestType } from '../../utils/manifest'; import { CvatManifestDto } from '../../common/dto/manifest'; import { ReputationConfigService } from '../../common/config/reputation-config.service'; import { ReputationEntity } from './reputation.entity'; diff --git a/packages/apps/reputation-oracle/server/src/modules/user/user.controller.ts b/packages/apps/reputation-oracle/server/src/modules/user/user.controller.ts index a968f52109..ddacd763d2 100644 --- a/packages/apps/reputation-oracle/server/src/modules/user/user.controller.ts +++ b/packages/apps/reputation-oracle/server/src/modules/user/user.controller.ts @@ -30,7 +30,7 @@ import { import { JwtAuthGuard } from '../../common/guards'; import { HCaptchaGuard } from '../../common/guards/hcaptcha'; import { RequestWithUser } from '../../common/types'; -import { prepareSignatureBody } from '../../common/utils/signature'; +import { prepareSignatureBody } from '../../utils/web3'; import { UserService } from './user.service'; import { Public } from '../../common/decorators'; import { KycSignedAddressDto } from '../kyc/kyc.dto'; diff --git a/packages/apps/reputation-oracle/server/src/modules/user/user.service.spec.ts b/packages/apps/reputation-oracle/server/src/modules/user/user.service.spec.ts index 5ec3c87c13..096824ec18 100644 --- a/packages/apps/reputation-oracle/server/src/modules/user/user.service.spec.ts +++ b/packages/apps/reputation-oracle/server/src/modules/user/user.service.spec.ts @@ -10,10 +10,7 @@ import { UserStatus, Role, } from '../../common/enums/user'; -import { - signMessage, - prepareSignatureBody, -} from '../../common/utils/signature'; +import { signMessage, prepareSignatureBody } from '../../utils/web3'; import { MOCK_ADDRESS, MOCK_EMAIL, diff --git a/packages/apps/reputation-oracle/server/src/modules/user/user.service.ts b/packages/apps/reputation-oracle/server/src/modules/user/user.service.ts index 44014fd3ae..4a74beb4fa 100644 --- a/packages/apps/reputation-oracle/server/src/modules/user/user.service.ts +++ b/packages/apps/reputation-oracle/server/src/modules/user/user.service.ts @@ -6,7 +6,7 @@ import { UserStatus, Role, } from '../../common/enums/user'; -import { generateNonce, verifySignature } from '../../common/utils/signature'; +import { generateNonce, verifySignature } from '../../utils/web3'; import { UserEntity } from './user.entity'; import { RegisterAddressRequestDto } from './user.dto'; import { UserRepository } from './user.repository'; @@ -20,7 +20,7 @@ import { SiteKeyType } from '../../common/enums'; import { HCaptchaService } from '../../integrations/hcaptcha/hcaptcha.service'; import { HCaptchaConfigService } from '../../common/config/hcaptcha-config.service'; import { NetworkConfigService } from '../../common/config/network-config.service'; -import { prepareSignatureBody } from '../../common/utils/signature'; +import { prepareSignatureBody } from '../../utils/web3'; import { KycSignedAddressDto } from '../kyc/kyc.dto'; import { ethers } from 'ethers'; import { diff --git a/packages/apps/reputation-oracle/server/src/modules/webhook/webhook-outgoing.service.spec.ts b/packages/apps/reputation-oracle/server/src/modules/webhook/webhook-outgoing.service.spec.ts index 66d129a8ab..c2372ba300 100644 --- a/packages/apps/reputation-oracle/server/src/modules/webhook/webhook-outgoing.service.spec.ts +++ b/packages/apps/reputation-oracle/server/src/modules/webhook/webhook-outgoing.service.spec.ts @@ -21,7 +21,7 @@ import { WebhookOutgoingService } from './webhook-outgoing.service'; import { WebhookOutgoingEntity } from './webhook-outgoing.entity'; import { of } from 'rxjs'; import { HEADER_SIGNATURE_KEY } from '../../common/constants'; -import { signMessage } from '../../common/utils/signature'; +import { signMessage } from '../../utils/web3'; import { HttpStatus } from '@nestjs/common'; import { Web3ConfigService } from '../../common/config/web3-config.service'; import { ServerConfigService } from '../../common/config/server-config.service'; diff --git a/packages/apps/reputation-oracle/server/src/modules/webhook/webhook-outgoing.service.ts b/packages/apps/reputation-oracle/server/src/modules/webhook/webhook-outgoing.service.ts index 099b27ba0a..6fe5fe4574 100644 --- a/packages/apps/reputation-oracle/server/src/modules/webhook/webhook-outgoing.service.ts +++ b/packages/apps/reputation-oracle/server/src/modules/webhook/webhook-outgoing.service.ts @@ -4,7 +4,7 @@ import stringify from 'json-stable-stringify'; import { HttpStatus, Injectable } from '@nestjs/common'; import { WebhookOutgoingStatus } from '../../common/enums'; import { firstValueFrom } from 'rxjs'; -import { signMessage } from '../../common/utils/signature'; +import { signMessage } from '../../utils/web3'; import { BACKOFF_INTERVAL_SECONDS, HEADER_SIGNATURE_KEY, diff --git a/packages/apps/reputation-oracle/server/src/utils/backoff.spec.ts b/packages/apps/reputation-oracle/server/src/utils/backoff.spec.ts new file mode 100644 index 0000000000..9b177c72b8 --- /dev/null +++ b/packages/apps/reputation-oracle/server/src/utils/backoff.spec.ts @@ -0,0 +1,44 @@ +import { faker } from '@faker-js/faker/.'; +import { calculateExponentialBackoffMs } from './backoff'; + +describe('Backoff utilities', () => { + describe('calculateExponentialBackoffMs', () => { + const testBackoffIntervalSeconds = faker.number.int({ max: 42 }); + + it('should return correct backoff for the first retry', () => { + const retriesCount = 0; + const result = calculateExponentialBackoffMs( + retriesCount, + testBackoffIntervalSeconds, + ); + expect(result).toBe(testBackoffIntervalSeconds * 1000); + }); + + it('should return correct backoff for the second retry', () => { + const retriesCount = 1; + const result = calculateExponentialBackoffMs( + retriesCount, + testBackoffIntervalSeconds, + ); + expect(result).toBe(2 * testBackoffIntervalSeconds * 1000); + }); + + it('should return correct backoff for the third retry ', () => { + const retriesCount = 2; + const result = calculateExponentialBackoffMs( + retriesCount, + testBackoffIntervalSeconds, + ); + expect(result).toBe(4 * testBackoffIntervalSeconds * 1000); + }); + + it('should return correct backoff for the sixth retry', () => { + const retriesCount = 5; + const result = calculateExponentialBackoffMs( + retriesCount, + testBackoffIntervalSeconds, + ); + expect(result).toBe(32 * testBackoffIntervalSeconds * 1000); + }); + }); +}); diff --git a/packages/apps/reputation-oracle/server/src/common/utils/backoff.ts b/packages/apps/reputation-oracle/server/src/utils/backoff.ts similarity index 74% rename from packages/apps/reputation-oracle/server/src/common/utils/backoff.ts rename to packages/apps/reputation-oracle/server/src/utils/backoff.ts index ecd7c9263d..42fdad0760 100644 --- a/packages/apps/reputation-oracle/server/src/common/utils/backoff.ts +++ b/packages/apps/reputation-oracle/server/src/utils/backoff.ts @@ -1,4 +1,4 @@ -import { BACKOFF_INTERVAL_SECONDS } from '../constants'; +import { BACKOFF_INTERVAL_SECONDS } from '../common/constants'; export function calculateExponentialBackoffMs( retriesCount: number, diff --git a/packages/apps/reputation-oracle/server/src/utils/case-converters.spec.ts b/packages/apps/reputation-oracle/server/src/utils/case-converters.spec.ts index 529797dbcc..d837423205 100644 --- a/packages/apps/reputation-oracle/server/src/utils/case-converters.spec.ts +++ b/packages/apps/reputation-oracle/server/src/utils/case-converters.spec.ts @@ -1,7 +1,7 @@ import { faker } from '@faker-js/faker'; import * as CaseConverter from './case-converters'; -describe('case-converters', () => { +describe('Case converting utilities', () => { describe('transformKeysFromSnakeToCamel', () => { it.each([ 'string', diff --git a/packages/apps/reputation-oracle/server/src/utils/case-converters.ts b/packages/apps/reputation-oracle/server/src/utils/case-converters.ts index 7a1eeed4d4..ce3d3f09a6 100644 --- a/packages/apps/reputation-oracle/server/src/utils/case-converters.ts +++ b/packages/apps/reputation-oracle/server/src/utils/case-converters.ts @@ -6,7 +6,7 @@ type CaseTransformer = (input: string) => string; * TODO: check if replacing it with lodash.camelCase * won't break anything */ -export const snakeToCamel: CaseTransformer = (input) => { +const snakeToCamel: CaseTransformer = (input) => { return input.replace(/_([a-z])/g, (_match, letter) => letter.toUpperCase()); }; @@ -14,7 +14,7 @@ export const snakeToCamel: CaseTransformer = (input) => { * TODO: check if replacing it with lodash.snakeCase * won't break anything */ -export const camelToSnake: CaseTransformer = (input) => { +const camelToSnake: CaseTransformer = (input) => { return input.replace(/([A-Z])/g, '_$1').toLowerCase(); }; diff --git a/packages/apps/reputation-oracle/server/src/utils/manifest.ts b/packages/apps/reputation-oracle/server/src/utils/manifest.ts new file mode 100644 index 0000000000..569e380a91 --- /dev/null +++ b/packages/apps/reputation-oracle/server/src/utils/manifest.ts @@ -0,0 +1,18 @@ +import { CvatManifestDto, FortuneManifestDto } from '../common/dto/manifest'; +import { JobRequestType } from '../common/enums'; +import { UnsupportedManifestTypeError } from '../common/errors/manifest'; + +export function getRequestType( + manifest: FortuneManifestDto | CvatManifestDto, +): JobRequestType { + const requestType = + (manifest as FortuneManifestDto).requestType || + ((manifest as CvatManifestDto).annotation && + (manifest as CvatManifestDto).annotation.type); + + if (!requestType) { + throw new UnsupportedManifestTypeError(requestType); + } + + return requestType; +} diff --git a/packages/apps/reputation-oracle/server/src/utils/type-guards.ts b/packages/apps/reputation-oracle/server/src/utils/type-guards.ts index 5dedf4fb34..4b1f7e062b 100644 --- a/packages/apps/reputation-oracle/server/src/utils/type-guards.ts +++ b/packages/apps/reputation-oracle/server/src/utils/type-guards.ts @@ -1,3 +1,17 @@ +import { JobRequestType } from '../common/enums'; + export function isObject(value: unknown): value is object { return typeof value === 'object' && value !== null; } + +export function assertValidJobRequestType( + value: string, +): asserts value is JobRequestType { + const validValues = Object.values(JobRequestType); + + if (validValues.includes(value)) { + return; + } + + throw new Error(`Unsupported request type: ${value}`); +} diff --git a/packages/apps/reputation-oracle/server/src/common/utils/signature.spec.ts b/packages/apps/reputation-oracle/server/src/utils/web3.spec.ts similarity index 83% rename from packages/apps/reputation-oracle/server/src/common/utils/signature.spec.ts rename to packages/apps/reputation-oracle/server/src/utils/web3.spec.ts index 8f51eb4974..3eca6770f1 100644 --- a/packages/apps/reputation-oracle/server/src/common/utils/signature.spec.ts +++ b/packages/apps/reputation-oracle/server/src/utils/web3.spec.ts @@ -1,7 +1,7 @@ -import { verifySignature, recoverSigner, signMessage } from './signature'; -import { MOCK_ADDRESS, MOCK_PRIVATE_KEY } from '../../../test/constants'; +import { verifySignature, recoverSignerAddress, signMessage } from './web3'; +import { MOCK_ADDRESS, MOCK_PRIVATE_KEY } from '../../test/constants'; -describe('Signature utility', () => { +describe('Web3 utilities', () => { describe('verifySignature', () => { it('should return true for valid signature', async () => { const message = 'Hello, this is a signed message!'; @@ -33,12 +33,12 @@ describe('Signature utility', () => { }); }); - describe('recoverSigner', () => { + describe('recoverSignerAddress', () => { it('should recover the correct signer', async () => { const message = 'value'; const signature = await signMessage(message, MOCK_PRIVATE_KEY); - const result = recoverSigner(message, signature); + const result = recoverSignerAddress(message, signature); expect(result).toBe(MOCK_ADDRESS); }); @@ -47,15 +47,15 @@ describe('Signature utility', () => { const message = 'Hello, this is a signed message!'; const invalidSignature = '0xInvalidSignature'; - const signer = recoverSigner(message, invalidSignature); - expect(signer).toBe(''); + const signer = recoverSignerAddress(message, invalidSignature); + expect(signer).toBe(null); }); it('should stringify message object if it is not already a string', async () => { const message = { key: 'value' }; const signature = await signMessage(message, MOCK_PRIVATE_KEY); - const recoveredAddress = recoverSigner(message, signature); + const recoveredAddress = recoverSignerAddress(message, signature); expect(recoveredAddress).toBe(MOCK_ADDRESS); }); @@ -64,7 +64,7 @@ describe('Signature utility', () => { const message = 'valid message'; const signature = await signMessage(message, MOCK_PRIVATE_KEY); - const recoveredAddress = recoverSigner(message, signature); + const recoveredAddress = recoverSignerAddress(message, signature); expect(recoveredAddress).toBe(MOCK_ADDRESS); }); diff --git a/packages/apps/reputation-oracle/server/src/utils/web3.ts b/packages/apps/reputation-oracle/server/src/utils/web3.ts new file mode 100644 index 0000000000..e6eabf0416 --- /dev/null +++ b/packages/apps/reputation-oracle/server/src/utils/web3.ts @@ -0,0 +1,75 @@ +import { ethers } from 'ethers'; + +type SignatureMessage = object | string; + +function prepareSignatureMessage(message: SignatureMessage): string { + if (typeof message === 'string') { + return message; + } else { + return JSON.stringify(message); + } +} + +export async function signMessage( + message: SignatureMessage, + privateKey: string, +): Promise { + const _message = prepareSignatureMessage(message); + + const wallet = new ethers.Wallet(privateKey); + const signature = await wallet.signMessage(_message); + + return signature; +} + +export function verifySignature( + message: SignatureMessage, + signature: string, + addresses: string[], +): boolean { + let signerAddress = recoverSignerAddress(message, signature); + if (!signerAddress) { + return false; + } + + signerAddress = signerAddress.toLowerCase(); + + return addresses.some((address) => address.toLowerCase() === signerAddress); +} + +export function recoverSignerAddress( + message: SignatureMessage, + signature: string, +): string | null { + const _message = prepareSignatureMessage(message); + + try { + return ethers.verifyMessage(_message, signature); + } catch (noop) { + return null; + } +} + +export function generateNonce(): string { + return Buffer.from(ethers.randomBytes(16)).toString('hex'); +} + +type SignatureBody = { + from: string; + to: string; + contents: string; + nonce?: string; +}; +export function prepareSignatureBody({ + from, + to, + contents, + nonce, +}: SignatureBody): SignatureBody { + return { + from: from.toLowerCase(), + to: to.toLowerCase(), + contents, + nonce: nonce ?? undefined, + }; +} From 0b627a2a2dc05c28d2ab582abece63dada62adb8 Mon Sep 17 00:00:00 2001 From: Dmitry Nechay Date: Thu, 13 Feb 2025 15:34:11 +0300 Subject: [PATCH 09/14] fix: backoff --- .../escrow-completion/escrow-completion.service.spec.ts | 4 ++-- .../modules/escrow-completion/escrow-completion.service.ts | 2 +- .../server/src/modules/webhook/webhook-incoming.service.ts | 2 +- .../server/src/modules/webhook/webhook-outgoing.service.ts | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/apps/reputation-oracle/server/src/modules/escrow-completion/escrow-completion.service.spec.ts b/packages/apps/reputation-oracle/server/src/modules/escrow-completion/escrow-completion.service.spec.ts index e8a9d4ff00..62293fd6e0 100644 --- a/packages/apps/reputation-oracle/server/src/modules/escrow-completion/escrow-completion.service.spec.ts +++ b/packages/apps/reputation-oracle/server/src/modules/escrow-completion/escrow-completion.service.spec.ts @@ -46,8 +46,8 @@ jest.mock('@human-protocol/sdk', () => ({ }, })); -jest.mock('../../common/utils/backoff', () => ({ - ...jest.requireActual('../../common/utils/backoff'), +jest.mock('../../utils/backoff', () => ({ + ...jest.requireActual('../../utils/backoff'), calculateExponentialBackoffMs: jest .fn() .mockReturnValue(MOCK_BACKOFF_INTERVAL_SECONDS * 1000), diff --git a/packages/apps/reputation-oracle/server/src/modules/escrow-completion/escrow-completion.service.ts b/packages/apps/reputation-oracle/server/src/modules/escrow-completion/escrow-completion.service.ts index 756d8aa95f..1c60a7d672 100644 --- a/packages/apps/reputation-oracle/server/src/modules/escrow-completion/escrow-completion.service.ts +++ b/packages/apps/reputation-oracle/server/src/modules/escrow-completion/escrow-completion.service.ts @@ -15,7 +15,7 @@ import { EscrowStatus, OperatorUtils, } from '@human-protocol/sdk'; -import { calculateExponentialBackoffMs } from '../../common/utils/backoff'; +import { calculateExponentialBackoffMs } from '../../utils/backoff'; import { BACKOFF_INTERVAL_SECONDS, DEFAULT_BULK_PAYOUT_TX_ID, diff --git a/packages/apps/reputation-oracle/server/src/modules/webhook/webhook-incoming.service.ts b/packages/apps/reputation-oracle/server/src/modules/webhook/webhook-incoming.service.ts index b879827394..01c4c9b86f 100644 --- a/packages/apps/reputation-oracle/server/src/modules/webhook/webhook-incoming.service.ts +++ b/packages/apps/reputation-oracle/server/src/modules/webhook/webhook-incoming.service.ts @@ -4,7 +4,7 @@ import { ServerConfigService } from '../../common/config/server-config.service'; import { Web3ConfigService } from '../../common/config/web3-config.service'; import { BACKOFF_INTERVAL_SECONDS } from '../../common/constants'; import { EventType, WebhookIncomingStatus } from '../../common/enums'; -import { calculateExponentialBackoffMs } from '../../common/utils/backoff'; +import { calculateExponentialBackoffMs } from '../../utils/backoff'; import { isDuplicatedError } from '../../common/utils/database'; import { EscrowCompletionService } from '../escrow-completion/escrow-completion.service'; import { WebhookIncomingEntity } from './webhook-incoming.entity'; diff --git a/packages/apps/reputation-oracle/server/src/modules/webhook/webhook-outgoing.service.ts b/packages/apps/reputation-oracle/server/src/modules/webhook/webhook-outgoing.service.ts index 6fe5fe4574..3f2c8204db 100644 --- a/packages/apps/reputation-oracle/server/src/modules/webhook/webhook-outgoing.service.ts +++ b/packages/apps/reputation-oracle/server/src/modules/webhook/webhook-outgoing.service.ts @@ -15,7 +15,7 @@ import { ServerConfigService } from '../../common/config/server-config.service'; import { Web3ConfigService } from '../../common/config/web3-config.service'; import { WebhookOutgoingEntity } from './webhook-outgoing.entity'; import { WebhookOutgoingRepository } from './webhook-outgoing.repository'; -import { calculateExponentialBackoffMs } from '../../common/utils/backoff'; +import { calculateExponentialBackoffMs } from '../../utils/backoff'; import { OutgoingWebhookError, WebhookErrorMessage } from './webhook.error'; import logger from '../../logger'; From 28ad0f2fb45596ba0283185e2a4e1eda222960fc Mon Sep 17 00:00:00 2001 From: Dmitry Nechay Date: Thu, 13 Feb 2025 15:32:22 +0300 Subject: [PATCH 10/14] refactor: NODE_ENV usage --- .../reputation-oracle/server/.env.example | 1 - .../server/src/app.module.ts | 12 ++++++---- .../server/src/common/config/env-schema.ts | 1 - .../common/config/server-config.service.ts | 8 ------- .../server/src/common/constants/index.ts | 6 ----- .../server/src/common/utils/environment.ts | 7 ------ .../server/src/database/database.module.ts | 11 +++------ .../server/src/logger/index.ts | 12 +++++----- .../modules/email/sendgrid.service.spec.ts | 4 ++-- .../src/modules/email/sendgrid.service.ts | 6 ++--- .../modules/health/dto/ping-response.dto.ts | 3 +++ .../src/modules/health/health.controller.ts | 2 ++ .../server/src/utils/environment.ts | 23 +++++++++++++++++++ .../server/typeorm.config.ts | 8 ++++--- 14 files changed, 54 insertions(+), 50 deletions(-) delete mode 100644 packages/apps/reputation-oracle/server/src/common/utils/environment.ts create mode 100644 packages/apps/reputation-oracle/server/src/utils/environment.ts diff --git a/packages/apps/reputation-oracle/server/.env.example b/packages/apps/reputation-oracle/server/.env.example index f2b20e3467..790d265d0b 100644 --- a/packages/apps/reputation-oracle/server/.env.example +++ b/packages/apps/reputation-oracle/server/.env.example @@ -1,5 +1,4 @@ # General -NODE_ENV=development HOST=localhost PORT=3008 FE_URL=http://localhost:3009 diff --git a/packages/apps/reputation-oracle/server/src/app.module.ts b/packages/apps/reputation-oracle/server/src/app.module.ts index 4ecbdc07f5..5d2e52c904 100644 --- a/packages/apps/reputation-oracle/server/src/app.module.ts +++ b/packages/apps/reputation-oracle/server/src/app.module.ts @@ -2,6 +2,8 @@ import { Module } from '@nestjs/common'; import { APP_FILTER, APP_INTERCEPTOR, APP_PIPE } from '@nestjs/core'; import { ConfigModule } from '@nestjs/config'; import { ScheduleModule } from '@nestjs/schedule'; +import { ServeStaticModule } from '@nestjs/serve-static'; +import { join } from 'path'; import { DatabaseModule } from './database/database.module'; import { HttpValidationPipe } from './common/pipes'; import { HealthModule } from './modules/health/health.module'; @@ -9,8 +11,6 @@ import { ReputationModule } from './modules/reputation/reputation.module'; import { Web3Module } from './modules/web3/web3.module'; import { envValidator } from './common/config'; import { AuthModule } from './modules/auth/auth.module'; -import { ServeStaticModule } from '@nestjs/serve-static'; -import { join } from 'path'; import { TransformInterceptor } from './common/interceptors/transform.interceptor'; import { KycModule } from './modules/kyc/kyc.module'; import { CronJobModule } from './modules/cron-job/cron-job.module'; @@ -23,6 +23,7 @@ import { EscrowCompletionModule } from './modules/escrow-completion/escrow-compl import { WebhookIncomingModule } from './modules/webhook/webhook-incoming.module'; import { WebhookOutgoingModule } from './modules/webhook/webhook-outgoing.module'; import { EmailModule } from './modules/email/module'; +import Environment from './utils/environment'; @Module({ providers: [ @@ -42,9 +43,10 @@ import { EmailModule } from './modules/email/module'; imports: [ ScheduleModule.forRoot(), ConfigModule.forRoot({ - envFilePath: process.env.NODE_ENV - ? `.env.${process.env.NODE_ENV as string}` - : '.env', + /** + * First value found takes precendece + */ + envFilePath: [`.env.${Environment.name}`, '.env'], validationSchema: envValidator, }), DatabaseModule, diff --git a/packages/apps/reputation-oracle/server/src/common/config/env-schema.ts b/packages/apps/reputation-oracle/server/src/common/config/env-schema.ts index 11142ebb4d..763c16b5ca 100644 --- a/packages/apps/reputation-oracle/server/src/common/config/env-schema.ts +++ b/packages/apps/reputation-oracle/server/src/common/config/env-schema.ts @@ -2,7 +2,6 @@ import * as Joi from 'joi'; export const envValidator = Joi.object({ // General - NODE_ENV: Joi.string(), HOST: Joi.string(), PORT: Joi.string(), FE_URL: Joi.string(), diff --git a/packages/apps/reputation-oracle/server/src/common/config/server-config.service.ts b/packages/apps/reputation-oracle/server/src/common/config/server-config.service.ts index 7ee50bbc58..016e6d54fe 100644 --- a/packages/apps/reputation-oracle/server/src/common/config/server-config.service.ts +++ b/packages/apps/reputation-oracle/server/src/common/config/server-config.service.ts @@ -5,14 +5,6 @@ import { ConfigService } from '@nestjs/config'; export class ServerConfigService { constructor(private configService: ConfigService) {} - /** - * The environment in which the server is running (e.g., 'development', 'production'). - * Default: 'development' - */ - get nodeEnv(): string { - return this.configService.get('NODE_ENV', 'development'); - } - get gitHash(): string { return this.configService.get('GIT_HASH', ''); } diff --git a/packages/apps/reputation-oracle/server/src/common/constants/index.ts b/packages/apps/reputation-oracle/server/src/common/constants/index.ts index 983b97cbd4..e66196ba93 100644 --- a/packages/apps/reputation-oracle/server/src/common/constants/index.ts +++ b/packages/apps/reputation-oracle/server/src/common/constants/index.ts @@ -1,11 +1,5 @@ import { JobRequestType } from '../enums'; -export enum Environment { - DEVELOPMENT = 'development', - TEST = 'test', - STAGING = 'staging', - PRODUCTION = 'production', -} export const NS = 'hmt'; export const RETRIES_COUNT_THRESHOLD = 3; export const INITIAL_REPUTATION = 0; diff --git a/packages/apps/reputation-oracle/server/src/common/utils/environment.ts b/packages/apps/reputation-oracle/server/src/common/utils/environment.ts deleted file mode 100644 index d7470880cb..0000000000 --- a/packages/apps/reputation-oracle/server/src/common/utils/environment.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { Environment } from '../constants'; - -export function isDevelopmentEnv(): boolean { - return [Environment.DEVELOPMENT, Environment.TEST].includes( - process.env.NODE_ENV as Environment, - ); -} diff --git a/packages/apps/reputation-oracle/server/src/database/database.module.ts b/packages/apps/reputation-oracle/server/src/database/database.module.ts index 88d7fd3d19..d6d85dac29 100644 --- a/packages/apps/reputation-oracle/server/src/database/database.module.ts +++ b/packages/apps/reputation-oracle/server/src/database/database.module.ts @@ -13,7 +13,6 @@ import { KycEntity } from '../modules/kyc/kyc.entity'; import { CronJobEntity } from '../modules/cron-job/cron-job.entity'; import { LoggerOptions } from 'typeorm'; import { DatabaseConfigService } from '../common/config/database-config.service'; -import { ServerConfigService } from '../common/config/server-config.service'; import { SiteKeyEntity } from '../modules/user/site-key.entity'; import { QualificationEntity } from '../modules/qualification/qualification.entity'; import { UserQualificationEntity } from '../modules/qualification/user-qualification.entity'; @@ -21,20 +20,16 @@ import { WebhookIncomingEntity } from '../modules/webhook/webhook-incoming.entit import { WebhookOutgoingEntity } from '../modules/webhook/webhook-outgoing.entity'; import { EscrowCompletionEntity } from '../modules/escrow-completion/escrow-completion.entity'; import { EscrowPayoutsBatchEntity } from '../modules/escrow-completion/escrow-payouts-batch.entity'; +import Environment from '../utils/environment'; @Module({ imports: [ TypeOrmModule.forRootAsync({ imports: [TypeOrmLoggerModule, ConfigModule], - inject: [ - TypeOrmLoggerService, - DatabaseConfigService, - ServerConfigService, - ], + inject: [TypeOrmLoggerService, DatabaseConfigService], useFactory: ( typeOrmLoggerService: TypeOrmLoggerService, databaseConfigService: DatabaseConfigService, - serverConfigService: ServerConfigService, ) => { const loggerOptions = databaseConfigService.logging?.split(', '); typeOrmLoggerService.setOptions( @@ -79,7 +74,7 @@ import { EscrowPayoutsBatchEntity } from '../modules/escrow-completion/escrow-pa username: databaseConfigService.user, password: databaseConfigService.password, database: databaseConfigService.database, - keepConnectionAlive: serverConfigService.nodeEnv === 'test', + keepConnectionAlive: Environment.isTest(), migrationsRun: false, ssl: databaseConfigService.ssl, }; diff --git a/packages/apps/reputation-oracle/server/src/logger/index.ts b/packages/apps/reputation-oracle/server/src/logger/index.ts index c3e6ee3e20..4509f80573 100644 --- a/packages/apps/reputation-oracle/server/src/logger/index.ts +++ b/packages/apps/reputation-oracle/server/src/logger/index.ts @@ -1,19 +1,19 @@ import { createLogger } from './pino-logger'; import NestLogger from './nest-logger'; import { LogLevel } from './types'; +import Environment from '../utils/environment'; -const environment = process.env.NODE_ENV || 'local'; -const isDevEnvironment = ['development', 'local'].includes(environment); +const isDevelopment = Environment.isDevelopment(); const defaultLogger = createLogger( { name: 'DefaultLogger', - level: isDevEnvironment ? LogLevel.DEBUG : LogLevel.INFO, - pretty: isDevEnvironment, - disabled: environment === 'test', + level: isDevelopment ? LogLevel.DEBUG : LogLevel.INFO, + pretty: isDevelopment, + disabled: Environment.isTest(), }, { - environment, + environment: Environment.name, service: 'reputation-oracle', }, ); diff --git a/packages/apps/reputation-oracle/server/src/modules/email/sendgrid.service.spec.ts b/packages/apps/reputation-oracle/server/src/modules/email/sendgrid.service.spec.ts index 5cf2fe2ae0..f1ccfdd04a 100644 --- a/packages/apps/reputation-oracle/server/src/modules/email/sendgrid.service.spec.ts +++ b/packages/apps/reputation-oracle/server/src/modules/email/sendgrid.service.spec.ts @@ -4,7 +4,7 @@ import { faker } from '@faker-js/faker'; import { Test, TestingModule } from '@nestjs/testing'; import { MailService } from '@sendgrid/mail'; -import * as environmentUtils from '../../common/utils/environment'; +import Environment from '../../utils/environment'; import { SENDGRID_TEMPLATES, SERVICE_NAME } from './sendgrid.service'; import logger from '../../logger'; import { getTemplateId } from './sendgrid.service'; @@ -24,7 +24,7 @@ const mockEmailConfigService = { }; const spyOnIsDevelopmentEnv = jest - .spyOn(environmentUtils, 'isDevelopmentEnv') + .spyOn(Environment, 'isDevelopment') .mockReturnValue(false); describe('SendgridEmailService', () => { diff --git a/packages/apps/reputation-oracle/server/src/modules/email/sendgrid.service.ts b/packages/apps/reputation-oracle/server/src/modules/email/sendgrid.service.ts index bf3d81adf9..251a5d4c2f 100644 --- a/packages/apps/reputation-oracle/server/src/modules/email/sendgrid.service.ts +++ b/packages/apps/reputation-oracle/server/src/modules/email/sendgrid.service.ts @@ -5,7 +5,7 @@ import { EmailService } from './email.service'; import { EmailAction, SENDGRID_API_KEY_REGEX } from './constants'; import logger from '../../logger'; import { EmailConfigService } from '../../common/config/email-config.service'; -import { isDevelopmentEnv } from '../../common/utils/environment'; +import Environment from '../../utils/environment'; export const SENDGRID_TEMPLATES = { signup: 'd-ca99cc7410aa4e6dab3e6042d5ecb9a3', @@ -35,7 +35,7 @@ export class SendgridEmailService extends EmailService { private readonly emailConfigService: EmailConfigService, ) { super(); - if (!isDevelopmentEnv()) { + if (!Environment.isDevelopment()) { if (!SENDGRID_API_KEY_REGEX.test(this.emailConfigService.apiKey)) { throw new Error('Invalid SendGrid API key'); } @@ -48,7 +48,7 @@ export class SendgridEmailService extends EmailService { action: EmailAction, payload?: Record, ): Promise { - if (isDevelopmentEnv()) { + if (Environment.isDevelopment()) { /** * Logging email data upon local development */ diff --git a/packages/apps/reputation-oracle/server/src/modules/health/dto/ping-response.dto.ts b/packages/apps/reputation-oracle/server/src/modules/health/dto/ping-response.dto.ts index cd190171ab..95427cddb5 100644 --- a/packages/apps/reputation-oracle/server/src/modules/health/dto/ping-response.dto.ts +++ b/packages/apps/reputation-oracle/server/src/modules/health/dto/ping-response.dto.ts @@ -4,6 +4,9 @@ export class PingResponseDto { @ApiProperty({ name: 'app_name' }) public appName: string; + @ApiProperty({ name: 'node_env' }) + public nodeEnv: string; + @ApiProperty({ name: 'git_hash' }) public gitHash: string; } diff --git a/packages/apps/reputation-oracle/server/src/modules/health/health.controller.ts b/packages/apps/reputation-oracle/server/src/modules/health/health.controller.ts index 252594e62f..16f4342f73 100644 --- a/packages/apps/reputation-oracle/server/src/modules/health/health.controller.ts +++ b/packages/apps/reputation-oracle/server/src/modules/health/health.controller.ts @@ -11,6 +11,7 @@ import packageJson from '../../../package.json'; import { Public } from '../../common/decorators'; import { ServerConfigService } from '../../common/config/server-config.service'; import { PingResponseDto } from './dto/ping-response.dto'; +import Environment from '../../utils/environment'; @Public() @ApiTags('Health') @@ -40,6 +41,7 @@ export class HealthController { async ping(): Promise { return { appName: packageJson.name, + nodeEnv: Environment.name, gitHash: this.serverConfigService.gitHash, }; } diff --git a/packages/apps/reputation-oracle/server/src/utils/environment.ts b/packages/apps/reputation-oracle/server/src/utils/environment.ts new file mode 100644 index 0000000000..b28db18424 --- /dev/null +++ b/packages/apps/reputation-oracle/server/src/utils/environment.ts @@ -0,0 +1,23 @@ +enum EnvironmentName { + DEVELOPMENT = 'development', + TEST = 'test', + STAGING = 'staging', + PRODUCTION = 'production', +} + +class Environment { + static readonly name: string = + process.env.NODE_ENV || EnvironmentName.DEVELOPMENT; + + static isDevelopment(): boolean { + return [EnvironmentName.DEVELOPMENT, EnvironmentName.TEST].includes( + Environment.name as EnvironmentName, + ); + } + + static isTest(): boolean { + return Environment.name === EnvironmentName.TEST; + } +} + +export default Environment; diff --git a/packages/apps/reputation-oracle/server/typeorm.config.ts b/packages/apps/reputation-oracle/server/typeorm.config.ts index d636d85e2f..d63d544043 100644 --- a/packages/apps/reputation-oracle/server/typeorm.config.ts +++ b/packages/apps/reputation-oracle/server/typeorm.config.ts @@ -1,11 +1,13 @@ import { DataSource } from 'typeorm'; import { SnakeNamingStrategy } from 'typeorm-naming-strategies'; import * as dotenv from 'dotenv'; +import Environment from './src/utils/environment'; dotenv.config({ - path: process.env.NODE_ENV - ? `.env.${process.env.NODE_ENV as string}` - : '.env', + /** + * First value wins if "override" option is not set + */ + path: [`.env.${Environment.name}`, '.env'], }); export default new DataSource({ From 100fdbfccc6b3deea46089fff8e2da88590a160e Mon Sep 17 00:00:00 2001 From: Dmitry Nechay Date: Thu, 13 Feb 2025 15:55:16 +0300 Subject: [PATCH 11/14] refactor: manifest dto --- .../server/src/common/dto/manifest.ts | 84 ------------------- .../server/src/common/interfaces/manifest.ts | 45 ++++++---- .../src/modules/payout/payout.interface.ts | 9 +- .../src/modules/payout/payout.service.spec.ts | 6 +- .../src/modules/payout/payout.service.ts | 25 +++--- .../reputation/reputation.interface.ts | 7 +- .../modules/reputation/reputation.service.ts | 14 ++-- .../server/src/utils/manifest.ts | 10 +-- .../server/test/constants.ts | 10 --- 9 files changed, 70 insertions(+), 140 deletions(-) delete mode 100644 packages/apps/reputation-oracle/server/src/common/dto/manifest.ts diff --git a/packages/apps/reputation-oracle/server/src/common/dto/manifest.ts b/packages/apps/reputation-oracle/server/src/common/dto/manifest.ts deleted file mode 100644 index 6e66187f2b..0000000000 --- a/packages/apps/reputation-oracle/server/src/common/dto/manifest.ts +++ /dev/null @@ -1,84 +0,0 @@ -import { - IsArray, - IsEnum, - IsNumber, - IsObject, - IsPositive, - IsString, -} from 'class-validator'; -import { JobRequestType } from '../enums'; - -export class CvatData { - @IsString() - data_url: string; -} - -export class Label { - @IsString() - name: string; -} - -export class Annotation { - @IsArray() - labels: Label[]; - - @IsString() - description: string; - - @IsEnum(JobRequestType) - type: JobRequestType; - - @IsNumber() - @IsPositive() - job_size: number; - - @IsNumber() - @IsPositive() - max_time: number; -} - -export class Validation { - @IsNumber() - @IsPositive() - min_quality: number; - - @IsNumber() - @IsPositive() - val_size: number; - - @IsString() - gt_url: string; -} - -export class CvatManifestDto { - @IsObject() - data: CvatData; - - @IsObject() - annotation: Annotation; - - @IsObject() - validation: Validation; - - @IsString() - job_bounty: string; -} - -export class FortuneManifestDto { - @IsNumber() - @IsPositive() - submissionsRequired: number; - - @IsString() - requesterTitle: string; - - @IsString() - requesterDescription: string; - - @IsNumber() - @IsPositive() - fundAmount: number; - - @IsEnum(JobRequestType) - requestType: JobRequestType; -} diff --git a/packages/apps/reputation-oracle/server/src/common/interfaces/manifest.ts b/packages/apps/reputation-oracle/server/src/common/interfaces/manifest.ts index 27010be092..ddd0ad6b4a 100644 --- a/packages/apps/reputation-oracle/server/src/common/interfaces/manifest.ts +++ b/packages/apps/reputation-oracle/server/src/common/interfaces/manifest.ts @@ -1,23 +1,38 @@ import { JobRequestType } from '../enums'; -export interface IFortuneManifest { - submissionsRequired: number; - requesterTitle: string; - requesterDescription: string; - fee: string; - fundAmount: string; - requestType: JobRequestType; +interface CvatData { + data_url: string; +} + +interface Label { + name: string; +} + +interface Annotation { + labels: Label[]; + description: string; + type: JobRequestType; + job_size: number; + max_time: number; +} + +interface Validation { + min_quality: number; + val_size: number; + gt_url: string; } -export interface ICvatManifest { - dataUrl: string; - labels: string[]; +export interface CvatManifest { + data: CvatData; + annotation: Annotation; + validation: Validation; + job_bounty: string; +} + +export interface FortuneManifest { submissionsRequired: number; + requesterTitle: string; requesterDescription: string; - requesterAccuracyTarget: number; - fee: string; - fundAmount: string; + fundAmount: number; requestType: JobRequestType; } - -export type Manifest = IFortuneManifest | ICvatManifest; diff --git a/packages/apps/reputation-oracle/server/src/modules/payout/payout.interface.ts b/packages/apps/reputation-oracle/server/src/modules/payout/payout.interface.ts index c2629bff4f..ff0d14b8c3 100644 --- a/packages/apps/reputation-oracle/server/src/modules/payout/payout.interface.ts +++ b/packages/apps/reputation-oracle/server/src/modules/payout/payout.interface.ts @@ -1,5 +1,8 @@ import { ChainId } from '@human-protocol/sdk'; -import { CvatManifestDto, FortuneManifestDto } from '../../common/dto/manifest'; +import { + CvatManifest, + FortuneManifest, +} from '../../common/interfaces/manifest'; export class CalculatePayoutsInput { chainId: ChainId; @@ -28,12 +31,12 @@ export type CalculatedPayout = { export interface RequestAction { calculatePayouts: ( - manifest: FortuneManifestDto | CvatManifestDto, + manifest: FortuneManifest | CvatManifest, data: CalculatePayoutsInput, ) => Promise; saveResults: ( chainId: ChainId, escrowAddress: string, - manifest?: FortuneManifestDto, + manifest?: FortuneManifest, ) => Promise; } diff --git a/packages/apps/reputation-oracle/server/src/modules/payout/payout.service.spec.ts b/packages/apps/reputation-oracle/server/src/modules/payout/payout.service.spec.ts index 8199f5a97f..63a46b2450 100644 --- a/packages/apps/reputation-oracle/server/src/modules/payout/payout.service.spec.ts +++ b/packages/apps/reputation-oracle/server/src/modules/payout/payout.service.spec.ts @@ -19,7 +19,7 @@ import { JobRequestType } from '../../common/enums'; import { Web3Service } from '../web3/web3.service'; import { StorageService } from '../storage/storage.service'; import { PayoutService } from './payout.service'; -import { CvatManifestDto } from '../../common/dto/manifest'; +import { CvatManifest } from '../../common/interfaces/manifest'; import { CvatAnnotationMeta } from '../../common/dto/result'; import { CalculatedPayout, SaveResultDto } from './payout.interface'; import { MissingManifestUrlError } from '../../common/errors/manifest'; @@ -120,7 +120,7 @@ describe('PayoutService', () => { }); it('should successfully save results for CVAT', async () => { - const manifest: CvatManifestDto = { + const manifest: CvatManifest = { data: { data_url: MOCK_FILE_URL, }, @@ -232,7 +232,7 @@ describe('PayoutService', () => { }); it('should successfully calculate payouts for CVAT', async () => { - const manifest: CvatManifestDto = { + const manifest: CvatManifest = { data: { data_url: MOCK_FILE_URL, }, diff --git a/packages/apps/reputation-oracle/server/src/modules/payout/payout.service.ts b/packages/apps/reputation-oracle/server/src/modules/payout/payout.service.ts index 1d96873dd5..70983d28dc 100644 --- a/packages/apps/reputation-oracle/server/src/modules/payout/payout.service.ts +++ b/packages/apps/reputation-oracle/server/src/modules/payout/payout.service.ts @@ -10,7 +10,10 @@ import { ethers } from 'ethers'; import { Web3Service } from '../web3/web3.service'; import { JobRequestType } from '../../common/enums'; import { StorageService } from '../storage/storage.service'; -import { CvatManifestDto, FortuneManifestDto } from '../../common/dto/manifest'; +import { + CvatManifest, + FortuneManifest, +} from '../../common/interfaces/manifest'; import { CvatAnnotationMeta, FortuneFinalResult, @@ -111,20 +114,20 @@ export class PayoutService { public createPayoutSpecificActions: Record = { [JobRequestType.FORTUNE]: { calculatePayouts: async ( - manifest: FortuneManifestDto, + manifest: FortuneManifest, data: CalculatePayoutsInput, ): Promise => this.calculatePayoutsFortune(manifest, data.finalResultsUrl), saveResults: async ( chainId: ChainId, escrowAddress: string, - manifest: FortuneManifestDto, + manifest: FortuneManifest, ): Promise => this.saveResultsFortune(manifest, chainId, escrowAddress), }, [JobRequestType.IMAGE_BOXES]: { calculatePayouts: async ( - manifest: CvatManifestDto, + manifest: CvatManifest, data: CalculatePayoutsInput, ): Promise => this.calculatePayoutsCvat(manifest, data.chainId, data.escrowAddress), @@ -135,7 +138,7 @@ export class PayoutService { }, [JobRequestType.IMAGE_POINTS]: { calculatePayouts: async ( - manifest: CvatManifestDto, + manifest: CvatManifest, data: CalculatePayoutsInput, ): Promise => this.calculatePayoutsCvat(manifest, data.chainId, data.escrowAddress), @@ -146,7 +149,7 @@ export class PayoutService { }, [JobRequestType.IMAGE_BOXES_FROM_POINTS]: { calculatePayouts: async ( - manifest: CvatManifestDto, + manifest: CvatManifest, data: CalculatePayoutsInput, ): Promise => this.calculatePayoutsCvat(manifest, data.chainId, data.escrowAddress), @@ -157,7 +160,7 @@ export class PayoutService { }, [JobRequestType.IMAGE_SKELETONS_FROM_BOXES]: { calculatePayouts: async ( - manifest: CvatManifestDto, + manifest: CvatManifest, data: CalculatePayoutsInput, ): Promise => this.calculatePayoutsCvat(manifest, data.chainId, data.escrowAddress), @@ -168,7 +171,7 @@ export class PayoutService { }, [JobRequestType.IMAGE_POLYGONS]: { calculatePayouts: async ( - manifest: CvatManifestDto, + manifest: CvatManifest, data: CalculatePayoutsInput, ): Promise => this.calculatePayoutsCvat(manifest, data.chainId, data.escrowAddress), @@ -188,7 +191,7 @@ export class PayoutService { * @returns {Promise} The URL and hash for the saved results. */ public async saveResultsFortune( - manifest: FortuneManifestDto, + manifest: FortuneManifest, chainId: ChainId, escrowAddress: string, ): Promise { @@ -256,7 +259,7 @@ export class PayoutService { * @returns {Promise} Recipients, amounts, and relevant storage data. */ public async calculatePayoutsFortune( - manifest: FortuneManifestDto, + manifest: FortuneManifest, finalResultsUrl: string, ): Promise { const finalResults = (await this.storageService.downloadJsonLikeData( @@ -286,7 +289,7 @@ export class PayoutService { * @returns {Promise} Recipients, amounts, and relevant storage data. */ public async calculatePayoutsCvat( - manifest: CvatManifestDto, + manifest: CvatManifest, chainId: ChainId, escrowAddress: string, ): Promise { diff --git a/packages/apps/reputation-oracle/server/src/modules/reputation/reputation.interface.ts b/packages/apps/reputation-oracle/server/src/modules/reputation/reputation.interface.ts index 1f72f7991e..bc5509c4a9 100644 --- a/packages/apps/reputation-oracle/server/src/modules/reputation/reputation.interface.ts +++ b/packages/apps/reputation-oracle/server/src/modules/reputation/reputation.interface.ts @@ -1,10 +1,13 @@ import { ChainId } from '@human-protocol/sdk'; -import { CvatManifestDto, FortuneManifestDto } from '../../common/dto/manifest'; +import { + CvatManifest, + FortuneManifest, +} from '../../common/interfaces/manifest'; export interface RequestAction { assessWorkerReputationScores: ( chainId: ChainId, escrowAddress: string, - manifest?: FortuneManifestDto | CvatManifestDto, + manifest?: FortuneManifest | CvatManifest, ) => Promise; } diff --git a/packages/apps/reputation-oracle/server/src/modules/reputation/reputation.service.ts b/packages/apps/reputation-oracle/server/src/modules/reputation/reputation.service.ts index 738455f4ae..d63399f7ab 100644 --- a/packages/apps/reputation-oracle/server/src/modules/reputation/reputation.service.ts +++ b/packages/apps/reputation-oracle/server/src/modules/reputation/reputation.service.ts @@ -24,7 +24,7 @@ import { } from '../../common/dto/result'; import { RequestAction } from './reputation.interface'; import { getRequestType } from '../../utils/manifest'; -import { CvatManifestDto } from '../../common/dto/manifest'; +import { CvatManifest } from '../../common/interfaces/manifest'; import { ReputationConfigService } from '../../common/config/reputation-config.service'; import { ReputationEntity } from './reputation.entity'; import { ReputationError, ReputationErrorMessage } from './reputation.error'; @@ -118,35 +118,35 @@ export class ReputationService { assessWorkerReputationScores: async ( chainId: ChainId, escrowAddress: string, - manifest: CvatManifestDto, + manifest: CvatManifest, ): Promise => this.processCvat(chainId, escrowAddress, manifest), }, [JobRequestType.IMAGE_POINTS]: { assessWorkerReputationScores: async ( chainId: ChainId, escrowAddress: string, - manifest: CvatManifestDto, + manifest: CvatManifest, ): Promise => this.processCvat(chainId, escrowAddress, manifest), }, [JobRequestType.IMAGE_BOXES_FROM_POINTS]: { assessWorkerReputationScores: async ( chainId: ChainId, escrowAddress: string, - manifest: CvatManifestDto, + manifest: CvatManifest, ): Promise => this.processCvat(chainId, escrowAddress, manifest), }, [JobRequestType.IMAGE_SKELETONS_FROM_BOXES]: { assessWorkerReputationScores: async ( chainId: ChainId, escrowAddress: string, - manifest: CvatManifestDto, + manifest: CvatManifest, ): Promise => this.processCvat(chainId, escrowAddress, manifest), }, [JobRequestType.IMAGE_POLYGONS]: { assessWorkerReputationScores: async ( chainId: ChainId, escrowAddress: string, - manifest: CvatManifestDto, + manifest: CvatManifest, ): Promise => this.processCvat(chainId, escrowAddress, manifest), }, }; @@ -187,7 +187,7 @@ export class ReputationService { private async processCvat( chainId: ChainId, escrowAddress: string, - manifest: CvatManifestDto, + manifest: CvatManifest, ): Promise { const signer = this.web3Service.getSigner(chainId); const escrowClient = await EscrowClient.build(signer); diff --git a/packages/apps/reputation-oracle/server/src/utils/manifest.ts b/packages/apps/reputation-oracle/server/src/utils/manifest.ts index 569e380a91..ff7691d7b2 100644 --- a/packages/apps/reputation-oracle/server/src/utils/manifest.ts +++ b/packages/apps/reputation-oracle/server/src/utils/manifest.ts @@ -1,14 +1,14 @@ -import { CvatManifestDto, FortuneManifestDto } from '../common/dto/manifest'; +import { CvatManifest, FortuneManifest } from '../common/interfaces/manifest'; import { JobRequestType } from '../common/enums'; import { UnsupportedManifestTypeError } from '../common/errors/manifest'; export function getRequestType( - manifest: FortuneManifestDto | CvatManifestDto, + manifest: FortuneManifest | CvatManifest, ): JobRequestType { const requestType = - (manifest as FortuneManifestDto).requestType || - ((manifest as CvatManifestDto).annotation && - (manifest as CvatManifestDto).annotation.type); + (manifest as FortuneManifest).requestType || + ((manifest as CvatManifest).annotation && + (manifest as CvatManifest).annotation.type); if (!requestType) { throw new UnsupportedManifestTypeError(requestType); diff --git a/packages/apps/reputation-oracle/server/test/constants.ts b/packages/apps/reputation-oracle/server/test/constants.ts index a2106b5c86..92dee80fdf 100644 --- a/packages/apps/reputation-oracle/server/test/constants.ts +++ b/packages/apps/reputation-oracle/server/test/constants.ts @@ -1,7 +1,5 @@ import { Web3Env } from '../src/common/enums/web3'; import { ImageLabelBinaryJobResults } from '../src/common/dto/result'; -import { JobRequestType } from '../src/common/enums'; -import { IFortuneManifest } from '../src/common/interfaces/manifest'; export const MOCK_REQUESTER_TITLE = 'Mock job title'; export const MOCK_REQUESTER_DESCRIPTION = 'Mock job description'; @@ -22,14 +20,6 @@ export const MOCK_RECORDING_ORACLE_ADDRESS = '0xCf88b3f1992458C2f5a229573c768D0E9F70C442'; export const MOCK_REPUTATION_ORACLE_ADDRESS = '0xCf88b3f1992458C2f5a229573c768D0E9F70C443'; -export const MOCK_MANIFEST: IFortuneManifest = { - submissionsRequired: 2, - requesterTitle: 'Fortune', - requesterDescription: 'Some desc', - fee: '20', - fundAmount: '8', - requestType: JobRequestType.FORTUNE, -}; export const MOCK_IMAGE_BINARY_LABEL_JOB_RESULTS: ImageLabelBinaryJobResults = { dataset: { dataset_scores: { From 8a73df9512381a12b9f1ef0cd7ad859a32a560c0 Mon Sep 17 00:00:00 2001 From: Dmitry Nechay Date: Thu, 13 Feb 2025 16:12:16 +0300 Subject: [PATCH 12/14] refactor: cleanup types and consts --- .../server/src/common/constants/index.ts | 12 -- .../server/src/common/dto/result.ts | 53 ------ .../server/src/common/interfaces/index.ts | 2 - .../src/common/interfaces/job-result.ts | 24 +++ .../common/{types => interfaces}/request.ts | 0 .../server/src/common/types/index.ts | 1 - .../src/modules/auth/auth.controller.ts | 2 +- .../server/src/modules/kyc/kyc.controller.ts | 2 +- .../src/modules/payout/payout.service.spec.ts | 2 +- .../src/modules/payout/payout.service.ts | 2 +- .../modules/reputation/reputation.service.ts | 2 +- .../src/modules/storage/storage.service.ts | 2 +- .../src/modules/user/user.controller.ts | 2 +- .../server/src/modules/user/user.entity.ts | 2 +- .../server/test/constants.ts | 151 ------------------ 15 files changed, 32 insertions(+), 227 deletions(-) delete mode 100644 packages/apps/reputation-oracle/server/src/common/dto/result.ts delete mode 100644 packages/apps/reputation-oracle/server/src/common/interfaces/index.ts create mode 100644 packages/apps/reputation-oracle/server/src/common/interfaces/job-result.ts rename packages/apps/reputation-oracle/server/src/common/{types => interfaces}/request.ts (100%) delete mode 100644 packages/apps/reputation-oracle/server/src/common/types/index.ts diff --git a/packages/apps/reputation-oracle/server/src/common/constants/index.ts b/packages/apps/reputation-oracle/server/src/common/constants/index.ts index e66196ba93..969a25dc71 100644 --- a/packages/apps/reputation-oracle/server/src/common/constants/index.ts +++ b/packages/apps/reputation-oracle/server/src/common/constants/index.ts @@ -1,23 +1,11 @@ -import { JobRequestType } from '../enums'; - export const NS = 'hmt'; -export const RETRIES_COUNT_THRESHOLD = 3; export const INITIAL_REPUTATION = 0; -export const JWT_PREFIX = 'bearer '; export const JWT_STRATEGY_NAME = 'jwt-http'; export const CVAT_RESULTS_ANNOTATIONS_FILENAME = 'resulting_annotations.zip'; export const CVAT_VALIDATION_META_FILENAME = 'validation_meta.json'; export const DEFAULT_BULK_PAYOUT_TX_ID = 1; -export const CVAT_JOB_TYPES = [ - JobRequestType.IMAGE_BOXES, - JobRequestType.IMAGE_POINTS, - JobRequestType.IMAGE_BOXES_FROM_POINTS, - JobRequestType.IMAGE_SKELETONS_FROM_BOXES, - JobRequestType.IMAGE_POLYGONS, -]; - export const HEADER_SIGNATURE_KEY = 'human-signature'; export const RESEND_EMAIL_VERIFICATION_PATH = diff --git a/packages/apps/reputation-oracle/server/src/common/dto/result.ts b/packages/apps/reputation-oracle/server/src/common/dto/result.ts deleted file mode 100644 index ba39232cf9..0000000000 --- a/packages/apps/reputation-oracle/server/src/common/dto/result.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { SolutionError } from '../../common/enums'; - -export class FortuneFinalResult { - workerAddress: string; - solution: string; - error?: SolutionError; -} - -export class ImageLabelBinaryJobResults { - dataset: Dataset; - worker_performance: WorkerPerformanceResult[]; -} -export class CvatAnnotationMetaJobs { - job_id: number; - final_result_id: number; -} - -export class CvatAnnotationMetaResults { - id: number; - job_id: number; - annotator_wallet_address: string; - annotation_quality: number; -} - -export class CvatAnnotationMeta { - jobs: CvatAnnotationMetaJobs[]; - results: CvatAnnotationMetaResults[]; -} - -class Dataset { - dataset_scores: { [score_name: string]: AgreementEstimate }; - data_points: T[]; -} - -class AgreementEstimate { - score: number; - interval?: [number, number]; - alpha?: number; -} - -class ImageLabelBinaryResult { - url: string; - label: string; - label_counts: { [label: string]: number }; - score: number; -} - -class WorkerPerformanceResult { - worker_id: string; - consensus_annotations: number; - total_annotations: number; - score: number; -} diff --git a/packages/apps/reputation-oracle/server/src/common/interfaces/index.ts b/packages/apps/reputation-oracle/server/src/common/interfaces/index.ts deleted file mode 100644 index 93a2fd5c55..0000000000 --- a/packages/apps/reputation-oracle/server/src/common/interfaces/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './base'; -export * from './user'; diff --git a/packages/apps/reputation-oracle/server/src/common/interfaces/job-result.ts b/packages/apps/reputation-oracle/server/src/common/interfaces/job-result.ts new file mode 100644 index 0000000000..a02680c699 --- /dev/null +++ b/packages/apps/reputation-oracle/server/src/common/interfaces/job-result.ts @@ -0,0 +1,24 @@ +import { SolutionError } from '../../common/enums'; + +export interface FortuneFinalResult { + workerAddress: string; + solution: string; + error?: SolutionError; +} + +interface CvatAnnotationMetaJobs { + job_id: number; + final_result_id: number; +} + +export interface CvatAnnotationMetaResults { + id: number; + job_id: number; + annotator_wallet_address: string; + annotation_quality: number; +} + +export interface CvatAnnotationMeta { + jobs: CvatAnnotationMetaJobs[]; + results: CvatAnnotationMetaResults[]; +} diff --git a/packages/apps/reputation-oracle/server/src/common/types/request.ts b/packages/apps/reputation-oracle/server/src/common/interfaces/request.ts similarity index 100% rename from packages/apps/reputation-oracle/server/src/common/types/request.ts rename to packages/apps/reputation-oracle/server/src/common/interfaces/request.ts diff --git a/packages/apps/reputation-oracle/server/src/common/types/index.ts b/packages/apps/reputation-oracle/server/src/common/types/index.ts deleted file mode 100644 index 56e4b0555f..0000000000 --- a/packages/apps/reputation-oracle/server/src/common/types/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './request'; diff --git a/packages/apps/reputation-oracle/server/src/modules/auth/auth.controller.ts b/packages/apps/reputation-oracle/server/src/modules/auth/auth.controller.ts index 9de46ac4a6..e836375a8b 100644 --- a/packages/apps/reputation-oracle/server/src/modules/auth/auth.controller.ts +++ b/packages/apps/reputation-oracle/server/src/modules/auth/auth.controller.ts @@ -20,7 +20,7 @@ import { Public } from '../../common/decorators'; import { AuthService } from './auth.service'; import { JwtAuthGuard } from '../../common/guards'; import { HCaptchaGuard } from '../../common/guards/hcaptcha'; -import { RequestWithUser } from '../../common/types'; +import { RequestWithUser } from '../../common/interfaces/request'; import { TokenRepository } from './token.repository'; import { TokenType } from './token.entity'; import { AuthControllerErrorsFilter } from './auth.error.filter'; diff --git a/packages/apps/reputation-oracle/server/src/modules/kyc/kyc.controller.ts b/packages/apps/reputation-oracle/server/src/modules/kyc/kyc.controller.ts index 6993861245..c03c992296 100644 --- a/packages/apps/reputation-oracle/server/src/modules/kyc/kyc.controller.ts +++ b/packages/apps/reputation-oracle/server/src/modules/kyc/kyc.controller.ts @@ -17,7 +17,7 @@ import { UseGuards, } from '@nestjs/common'; import { JwtAuthGuard } from '../../common/guards'; -import { RequestWithUser } from '../../common/types'; +import { RequestWithUser } from '../../common/interfaces/request'; import { KycSessionDto, KycSignedAddressDto, KycStatusDto } from './kyc.dto'; import { KycService } from './kyc.service'; import { KycWebhookAuthGuard } from '../../common/guards/kyc-webhook.auth'; diff --git a/packages/apps/reputation-oracle/server/src/modules/payout/payout.service.spec.ts b/packages/apps/reputation-oracle/server/src/modules/payout/payout.service.spec.ts index 63a46b2450..2bc2436b9a 100644 --- a/packages/apps/reputation-oracle/server/src/modules/payout/payout.service.spec.ts +++ b/packages/apps/reputation-oracle/server/src/modules/payout/payout.service.spec.ts @@ -20,7 +20,7 @@ import { Web3Service } from '../web3/web3.service'; import { StorageService } from '../storage/storage.service'; import { PayoutService } from './payout.service'; import { CvatManifest } from '../../common/interfaces/manifest'; -import { CvatAnnotationMeta } from '../../common/dto/result'; +import { CvatAnnotationMeta } from '../../common/interfaces/job-result'; import { CalculatedPayout, SaveResultDto } from './payout.interface'; import { MissingManifestUrlError } from '../../common/errors/manifest'; diff --git a/packages/apps/reputation-oracle/server/src/modules/payout/payout.service.ts b/packages/apps/reputation-oracle/server/src/modules/payout/payout.service.ts index 70983d28dc..e4df068d77 100644 --- a/packages/apps/reputation-oracle/server/src/modules/payout/payout.service.ts +++ b/packages/apps/reputation-oracle/server/src/modules/payout/payout.service.ts @@ -17,7 +17,7 @@ import { import { CvatAnnotationMeta, FortuneFinalResult, -} from '../../common/dto/result'; +} from '../../common/interfaces/job-result'; import { CalculatedPayout, CalculatePayoutsInput, diff --git a/packages/apps/reputation-oracle/server/src/modules/reputation/reputation.service.ts b/packages/apps/reputation-oracle/server/src/modules/reputation/reputation.service.ts index d63399f7ab..54ab5d61ba 100644 --- a/packages/apps/reputation-oracle/server/src/modules/reputation/reputation.service.ts +++ b/packages/apps/reputation-oracle/server/src/modules/reputation/reputation.service.ts @@ -21,7 +21,7 @@ import { CvatAnnotationMeta, CvatAnnotationMetaResults, FortuneFinalResult, -} from '../../common/dto/result'; +} from '../../common/interfaces/job-result'; import { RequestAction } from './reputation.interface'; import { getRequestType } from '../../utils/manifest'; import { CvatManifest } from '../../common/interfaces/manifest'; diff --git a/packages/apps/reputation-oracle/server/src/modules/storage/storage.service.ts b/packages/apps/reputation-oracle/server/src/modules/storage/storage.service.ts index f866f181f7..dee3f069c8 100644 --- a/packages/apps/reputation-oracle/server/src/modules/storage/storage.service.ts +++ b/packages/apps/reputation-oracle/server/src/modules/storage/storage.service.ts @@ -11,7 +11,7 @@ import * as Minio from 'minio'; import crypto from 'crypto'; import { UploadedFile } from '../../common/interfaces/s3'; import { Web3Service } from '../web3/web3.service'; -import { FortuneFinalResult } from '../../common/dto/result'; +import { FortuneFinalResult } from '../../common/interfaces/job-result'; import { S3ConfigService } from '../../common/config/s3-config.service'; import { PGPConfigService } from '../../common/config/pgp-config.service'; import { isNotFoundError } from '../../common/utils/minio'; diff --git a/packages/apps/reputation-oracle/server/src/modules/user/user.controller.ts b/packages/apps/reputation-oracle/server/src/modules/user/user.controller.ts index ddacd763d2..df199b95d0 100644 --- a/packages/apps/reputation-oracle/server/src/modules/user/user.controller.ts +++ b/packages/apps/reputation-oracle/server/src/modules/user/user.controller.ts @@ -29,7 +29,7 @@ import { } from './user.dto'; import { JwtAuthGuard } from '../../common/guards'; import { HCaptchaGuard } from '../../common/guards/hcaptcha'; -import { RequestWithUser } from '../../common/types'; +import { RequestWithUser } from '../../common/interfaces/request'; import { prepareSignatureBody } from '../../utils/web3'; import { UserService } from './user.service'; import { Public } from '../../common/decorators'; diff --git a/packages/apps/reputation-oracle/server/src/modules/user/user.entity.ts b/packages/apps/reputation-oracle/server/src/modules/user/user.entity.ts index 30cc009251..285d3b3df8 100644 --- a/packages/apps/reputation-oracle/server/src/modules/user/user.entity.ts +++ b/packages/apps/reputation-oracle/server/src/modules/user/user.entity.ts @@ -3,7 +3,7 @@ import { Column, Entity, OneToMany, OneToOne } from 'typeorm'; import { NS } from '../../common/constants'; import { UserStatus, Role } from '../../common/enums/user'; -import { IUser } from '../../common/interfaces'; +import { IUser } from '../../common/interfaces/user'; import { BaseEntity } from '../../database/base.entity'; import { TokenEntity } from '../auth/token.entity'; import { KycEntity } from '../kyc/kyc.entity'; diff --git a/packages/apps/reputation-oracle/server/test/constants.ts b/packages/apps/reputation-oracle/server/test/constants.ts index 92dee80fdf..552af71a55 100644 --- a/packages/apps/reputation-oracle/server/test/constants.ts +++ b/packages/apps/reputation-oracle/server/test/constants.ts @@ -1,5 +1,4 @@ import { Web3Env } from '../src/common/enums/web3'; -import { ImageLabelBinaryJobResults } from '../src/common/dto/result'; export const MOCK_REQUESTER_TITLE = 'Mock job title'; export const MOCK_REQUESTER_DESCRIPTION = 'Mock job description'; @@ -20,156 +19,6 @@ export const MOCK_RECORDING_ORACLE_ADDRESS = '0xCf88b3f1992458C2f5a229573c768D0E9F70C442'; export const MOCK_REPUTATION_ORACLE_ADDRESS = '0xCf88b3f1992458C2f5a229573c768D0E9F70C443'; -export const MOCK_IMAGE_BINARY_LABEL_JOB_RESULTS: ImageLabelBinaryJobResults = { - dataset: { - dataset_scores: { - fleiss_kappa: { - score: 0.6375655872223378, - interval: [0.2390581389740375, 0.8568940200253629], - alpha: 0.05, - }, - avg_percent_agreement_across_labels: { - score: 0.8245614035087719, - }, - }, - data_points: [ - { - url: 'https://test.storage.googleapis.com/1.png', - label: MOCK_LABEL_NEGATIVE, - label_counts: { MOCK_LABEL_NEGATIVE: 3, MOCK_LABEL: 0 }, - score: 1.0, - }, - { - url: 'https://test.storage.googleapis.com/10.png', - label: MOCK_LABEL_NEGATIVE, - label_counts: { MOCK_LABEL_NEGATIVE: 3, MOCK_LABEL: 0 }, - score: 1.0, - }, - { - url: 'https://test.storage.googleapis.com/11.png', - label: MOCK_LABEL_NEGATIVE, - label_counts: { MOCK_LABEL_NEGATIVE: 2, MOCK_LABEL: 1 }, - score: 0.6666666666666666, - }, - { - url: 'https://test.storage.googleapis.com/12.png', - label: MOCK_LABEL, - label_counts: { MOCK_LABEL_NEGATIVE: 0, MOCK_LABEL: 2 }, - score: 1.0, - }, - { - url: 'https://test.storage.googleapis.com/13.png', - label: MOCK_LABEL, - label_counts: { MOCK_LABEL_NEGATIVE: 0, MOCK_LABEL: 3 }, - score: 1.0, - }, - { - url: 'https://test.storage.googleapis.com/14.png', - label: MOCK_LABEL, - label_counts: { MOCK_LABEL_NEGATIVE: 0, MOCK_LABEL: 3 }, - score: 1.0, - }, - { - url: 'https://test.storage.googleapis.com/15.png', - label: MOCK_LABEL_NEGATIVE, - label_counts: { MOCK_LABEL_NEGATIVE: 3, MOCK_LABEL: 0 }, - score: 1.0, - }, - { - url: 'https://test.storage.googleapis.com/16.png', - label: MOCK_LABEL_NEGATIVE, - label_counts: { MOCK_LABEL_NEGATIVE: 3, MOCK_LABEL: 0 }, - score: 1.0, - }, - { - url: 'https://test.storage.googleapis.com/17.png', - label: MOCK_LABEL_NEGATIVE, - label_counts: { MOCK_LABEL_NEGATIVE: 3, MOCK_LABEL: 0 }, - score: 1.0, - }, - { - url: 'https://test.storage.googleapis.com/18.png', - label: MOCK_LABEL_NEGATIVE, - label_counts: { MOCK_LABEL_NEGATIVE: 2, MOCK_LABEL: 1 }, - score: 0.6666666666666666, - }, - { - url: 'https://test.storage.googleapis.com/19.png', - label: MOCK_LABEL_NEGATIVE, - label_counts: { MOCK_LABEL_NEGATIVE: 2, MOCK_LABEL: 1 }, - score: 0.6666666666666666, - }, - { - url: 'https://test.storage.googleapis.com/2.png', - label: MOCK_LABEL_NEGATIVE, - label_counts: { MOCK_LABEL_NEGATIVE: 2, MOCK_LABEL: 1 }, - score: 0.6666666666666666, - }, - { - url: 'https://test.storage.googleapis.com/3.png', - label: MOCK_LABEL, - label_counts: { MOCK_LABEL_NEGATIVE: 1, MOCK_LABEL: 2 }, - score: 0.6666666666666666, - }, - { - url: 'https://test.storage.googleapis.com/4.png', - label: MOCK_LABEL_NEGATIVE, - label_counts: { MOCK_LABEL_NEGATIVE: 3, MOCK_LABEL: 0 }, - score: 1.0, - }, - { - url: 'https://test.storage.googleapis.com/5.png', - label: MOCK_LABEL, - label_counts: { MOCK_LABEL_NEGATIVE: 0, MOCK_LABEL: 3 }, - score: 1.0, - }, - { - url: 'https://test.storage.googleapis.com/6.png', - label: MOCK_LABEL, - label_counts: { MOCK_LABEL_NEGATIVE: 0, MOCK_LABEL: 3 }, - score: 1.0, - }, - { - url: 'https://test.storage.googleapis.com/7.png', - label: MOCK_LABEL, - label_counts: { MOCK_LABEL_NEGATIVE: 0, MOCK_LABEL: 3 }, - score: 1.0, - }, - { - url: 'https://test.storage.googleapis.com/8.png', - label: MOCK_LABEL_NEGATIVE, - label_counts: { MOCK_LABEL_NEGATIVE: 3, MOCK_LABEL: 0 }, - score: 1.0, - }, - { - url: 'https://test.storage.googleapis.com/9.png', - label: MOCK_LABEL_NEGATIVE, - label_counts: { MOCK_LABEL_NEGATIVE: 3, MOCK_LABEL: 0 }, - score: 1.0, - }, - ], - }, - worker_performance: [ - { - worker_id: '0x0755D4d722a4a201c1C5A4B5E614D913e7747b36', - consensus_annotations: 18, - total_annotations: 19, - score: 0.8901734104046242, - }, - { - worker_id: '0x0755D4d722a4a201c1C5A4B5E614D913e7747b37', - consensus_annotations: 16, - total_annotations: 19, - score: 0.6705202312138727, - }, - { - worker_id: '0x0755D4d722a4a201c1C5A4B5E614D913e7747b38', - consensus_annotations: 17, - total_annotations: 18, - score: 0.8799999999999999, - }, - ], -}; export const MOCK_PRIVATE_KEY = 'd334daf65a631f40549cc7de126d5a0016f32a2d00c49f94563f9737f7135e55'; export const MOCK_PGP_PRIVATE_KEY = ` From ce4d6b811e3775b11784887c0d60d785ed0a0297 Mon Sep 17 00:00:00 2001 From: Dmitry Nechay Date: Thu, 13 Feb 2025 16:20:50 +0300 Subject: [PATCH 13/14] refactor: error utils --- .../server/src/app.module.ts | 2 +- .../server/src/common/enums/minio.ts | 3 --- .../server/src/common/errors/database.ts | 22 +++++++++++-------- .../src/common/{utils => errors}/minio.ts | 4 +++- .../exception.filter.ts | 0 .../server/src/common/utils/database.ts | 9 -------- .../escrow-completion.service.ts | 2 +- .../src/modules/storage/storage.service.ts | 2 +- .../webhook/webhook-incoming.service.ts | 2 +- 9 files changed, 20 insertions(+), 26 deletions(-) delete mode 100644 packages/apps/reputation-oracle/server/src/common/enums/minio.ts rename packages/apps/reputation-oracle/server/src/common/{utils => errors}/minio.ts (68%) rename packages/apps/reputation-oracle/server/src/common/{exceptions => filters}/exception.filter.ts (100%) delete mode 100644 packages/apps/reputation-oracle/server/src/common/utils/database.ts diff --git a/packages/apps/reputation-oracle/server/src/app.module.ts b/packages/apps/reputation-oracle/server/src/app.module.ts index 5d2e52c904..74aada9e5e 100644 --- a/packages/apps/reputation-oracle/server/src/app.module.ts +++ b/packages/apps/reputation-oracle/server/src/app.module.ts @@ -17,7 +17,7 @@ import { CronJobModule } from './modules/cron-job/cron-job.module'; import { PayoutModule } from './modules/payout/payout.module'; import { EnvConfigModule } from './common/config/config.module'; import { HCaptchaModule } from './integrations/hcaptcha/hcaptcha.module'; -import { ExceptionFilter } from './common/exceptions/exception.filter'; +import { ExceptionFilter } from './common/filters/exception.filter'; import { QualificationModule } from './modules/qualification/qualification.module'; import { EscrowCompletionModule } from './modules/escrow-completion/escrow-completion.module'; import { WebhookIncomingModule } from './modules/webhook/webhook-incoming.module'; diff --git a/packages/apps/reputation-oracle/server/src/common/enums/minio.ts b/packages/apps/reputation-oracle/server/src/common/enums/minio.ts deleted file mode 100644 index 745299d7b1..0000000000 --- a/packages/apps/reputation-oracle/server/src/common/enums/minio.ts +++ /dev/null @@ -1,3 +0,0 @@ -export enum MinioErrorCodes { - NotFound = 'NotFound', -} diff --git a/packages/apps/reputation-oracle/server/src/common/errors/database.ts b/packages/apps/reputation-oracle/server/src/common/errors/database.ts index c369f38558..d7e4a0701e 100644 --- a/packages/apps/reputation-oracle/server/src/common/errors/database.ts +++ b/packages/apps/reputation-oracle/server/src/common/errors/database.ts @@ -1,16 +1,11 @@ import { QueryFailedError } from 'typeorm'; import { PostgresErrorCodes } from '../enums/database'; +import { BaseError } from './base'; -export class DatabaseError extends Error { - constructor(message: string, stack: string) { - super(message); - this.stack = stack; - } -} +export class DatabaseError extends BaseError {} export function handleQueryFailedError(error: QueryFailedError): DatabaseError { - const stack = error.stack || ''; - let message = error.message; + let message: string; switch ((error.driverError as any).code) { case PostgresErrorCodes.Duplicated: @@ -20,7 +15,16 @@ export function handleQueryFailedError(error: QueryFailedError): DatabaseError { message = 'Incorrect amount'; break; default: + message = error.message; break; } - return new DatabaseError(message, stack); + + return new DatabaseError(message, error); +} + +export function isDuplicatedError(error: unknown): boolean { + return ( + error instanceof DatabaseError && + error.message.includes(PostgresErrorCodes.Duplicated) + ); } diff --git a/packages/apps/reputation-oracle/server/src/common/utils/minio.ts b/packages/apps/reputation-oracle/server/src/common/errors/minio.ts similarity index 68% rename from packages/apps/reputation-oracle/server/src/common/utils/minio.ts rename to packages/apps/reputation-oracle/server/src/common/errors/minio.ts index e1537e3291..5d2eb82833 100644 --- a/packages/apps/reputation-oracle/server/src/common/utils/minio.ts +++ b/packages/apps/reputation-oracle/server/src/common/errors/minio.ts @@ -1,4 +1,6 @@ -import { MinioErrorCodes } from '../enums/minio'; +enum MinioErrorCodes { + NotFound = 'NotFound', +} export function isNotFoundError(error: any): boolean { return error?.code === MinioErrorCodes.NotFound; diff --git a/packages/apps/reputation-oracle/server/src/common/exceptions/exception.filter.ts b/packages/apps/reputation-oracle/server/src/common/filters/exception.filter.ts similarity index 100% rename from packages/apps/reputation-oracle/server/src/common/exceptions/exception.filter.ts rename to packages/apps/reputation-oracle/server/src/common/filters/exception.filter.ts diff --git a/packages/apps/reputation-oracle/server/src/common/utils/database.ts b/packages/apps/reputation-oracle/server/src/common/utils/database.ts deleted file mode 100644 index f921c305d0..0000000000 --- a/packages/apps/reputation-oracle/server/src/common/utils/database.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { PostgresErrorCodes } from '../enums/database'; -import { DatabaseError } from '../errors/database'; - -export function isDuplicatedError(error: any): boolean { - return ( - error instanceof DatabaseError && - error.message.includes(PostgresErrorCodes.Duplicated) - ); -} diff --git a/packages/apps/reputation-oracle/server/src/modules/escrow-completion/escrow-completion.service.ts b/packages/apps/reputation-oracle/server/src/modules/escrow-completion/escrow-completion.service.ts index 1c60a7d672..a426cca014 100644 --- a/packages/apps/reputation-oracle/server/src/modules/escrow-completion/escrow-completion.service.ts +++ b/packages/apps/reputation-oracle/server/src/modules/escrow-completion/escrow-completion.service.ts @@ -25,7 +25,7 @@ import { PayoutService } from '../payout/payout.service'; import { ReputationService } from '../reputation/reputation.service'; import { Web3Service } from '../web3/web3.service'; import { WebhookOutgoingService } from '../webhook/webhook-outgoing.service'; -import { isDuplicatedError } from '../../common/utils/database'; +import { isDuplicatedError } from '../../common/errors/database'; import { CalculatedPayout } from '../payout/payout.interface'; import { EscrowPayoutsBatchEntity } from './escrow-payouts-batch.entity'; import { EscrowPayoutsBatchRepository } from './escrow-payouts-batch.repository'; diff --git a/packages/apps/reputation-oracle/server/src/modules/storage/storage.service.ts b/packages/apps/reputation-oracle/server/src/modules/storage/storage.service.ts index dee3f069c8..2ad1949c20 100644 --- a/packages/apps/reputation-oracle/server/src/modules/storage/storage.service.ts +++ b/packages/apps/reputation-oracle/server/src/modules/storage/storage.service.ts @@ -14,7 +14,7 @@ import { Web3Service } from '../web3/web3.service'; import { FortuneFinalResult } from '../../common/interfaces/job-result'; import { S3ConfigService } from '../../common/config/s3-config.service'; import { PGPConfigService } from '../../common/config/pgp-config.service'; -import { isNotFoundError } from '../../common/utils/minio'; +import { isNotFoundError } from '../../common/errors/minio'; import { FileDownloadError, FileNotFoundError, diff --git a/packages/apps/reputation-oracle/server/src/modules/webhook/webhook-incoming.service.ts b/packages/apps/reputation-oracle/server/src/modules/webhook/webhook-incoming.service.ts index 01c4c9b86f..5267e12e08 100644 --- a/packages/apps/reputation-oracle/server/src/modules/webhook/webhook-incoming.service.ts +++ b/packages/apps/reputation-oracle/server/src/modules/webhook/webhook-incoming.service.ts @@ -5,7 +5,7 @@ import { Web3ConfigService } from '../../common/config/web3-config.service'; import { BACKOFF_INTERVAL_SECONDS } from '../../common/constants'; import { EventType, WebhookIncomingStatus } from '../../common/enums'; import { calculateExponentialBackoffMs } from '../../utils/backoff'; -import { isDuplicatedError } from '../../common/utils/database'; +import { isDuplicatedError } from '../../common/errors/database'; import { EscrowCompletionService } from '../escrow-completion/escrow-completion.service'; import { WebhookIncomingEntity } from './webhook-incoming.entity'; import { WebhookIncomingRepository } from './webhook-incoming.repository'; From 4a3a77dfe38c382aea35f87ca450f07fbf752b9e Mon Sep 17 00:00:00 2001 From: Dmitry Nechay Date: Thu, 13 Feb 2025 16:31:44 +0300 Subject: [PATCH 14/14] refactor: move config module up --- .../server/scripts/generate-env-doc.ts | 2 +- .../apps/reputation-oracle/server/src/app.module.ts | 4 ++-- .../server/src/common/guards/hcaptcha.ts | 2 +- .../server/src/common/guards/kyc-webhook.auth.ts | 2 +- .../src/{common => }/config/auth-config.service.ts | 0 .../server/src/{common => }/config/config.module.ts | 0 .../src/{common => }/config/database-config.service.ts | 0 .../src/{common => }/config/email-config.service.ts | 0 .../server/src/{common => }/config/env-schema.ts | 0 .../src/{common => }/config/hcaptcha-config.service.ts | 0 .../server/src/{common => }/config/index.ts | 0 .../src/{common => }/config/kyc-config.service.ts | 0 .../src/{common => }/config/network-config.service.ts | 4 ++-- .../src/{common => }/config/pgp-config.service.ts | 0 .../{common => }/config/reputation-config.service.ts | 0 .../src/{common => }/config/s3-config.service.ts | 0 .../src/{common => }/config/server-config.service.ts | 0 .../src/{common => }/config/web3-config.service.ts | 0 .../server/src/database/database.module.ts | 2 +- .../src/integrations/hcaptcha/hcaptcha.service.spec.ts | 2 +- .../src/integrations/hcaptcha/hcaptcha.service.ts | 2 +- packages/apps/reputation-oracle/server/src/main.ts | 2 +- .../server/src/modules/auth/auth.module.ts | 2 +- .../server/src/modules/auth/auth.service.spec.ts | 10 +++++----- .../server/src/modules/auth/auth.service.ts | 6 +++--- .../server/src/modules/auth/strategy/jwt.http.ts | 2 +- .../server/src/modules/email/sendgrid.service.spec.ts | 2 +- .../server/src/modules/email/sendgrid.service.ts | 2 +- .../escrow-completion/escrow-completion.repository.ts | 2 +- .../escrow-completion.service.spec.ts | 10 +++++----- .../escrow-completion/escrow-completion.service.ts | 2 +- .../server/src/modules/health/health.controller.ts | 2 +- .../server/src/modules/kyc/kyc.controller.spec.ts | 2 +- .../server/src/modules/kyc/kyc.service.spec.ts | 6 +++--- .../server/src/modules/kyc/kyc.service.ts | 4 ++-- .../qualification/qualification.service.spec.ts | 2 +- .../src/modules/qualification/qualification.service.ts | 2 +- .../modules/reputation/reputation.controller.spec.ts | 6 +++--- .../src/modules/reputation/reputation.service.spec.ts | 2 +- .../src/modules/reputation/reputation.service.ts | 2 +- .../server/src/modules/storage/storage.service.spec.ts | 4 ++-- .../server/src/modules/storage/storage.service.ts | 4 ++-- .../server/src/modules/user/user.service.spec.ts | 6 +++--- .../server/src/modules/user/user.service.ts | 6 +++--- .../server/src/modules/web3/web3.service.spec.ts | 4 ++-- .../server/src/modules/web3/web3.service.ts | 4 ++-- .../src/modules/webhook/webhook-incoming.repository.ts | 2 +- .../modules/webhook/webhook-incoming.service.spec.ts | 10 +++++----- .../src/modules/webhook/webhook-incoming.service.ts | 4 ++-- .../src/modules/webhook/webhook-outgoing.repository.ts | 2 +- .../modules/webhook/webhook-outgoing.service.spec.ts | 4 ++-- .../src/modules/webhook/webhook-outgoing.service.ts | 4 ++-- 52 files changed, 71 insertions(+), 71 deletions(-) rename packages/apps/reputation-oracle/server/src/{common => }/config/auth-config.service.ts (100%) rename packages/apps/reputation-oracle/server/src/{common => }/config/config.module.ts (100%) rename packages/apps/reputation-oracle/server/src/{common => }/config/database-config.service.ts (100%) rename packages/apps/reputation-oracle/server/src/{common => }/config/email-config.service.ts (100%) rename packages/apps/reputation-oracle/server/src/{common => }/config/env-schema.ts (100%) rename packages/apps/reputation-oracle/server/src/{common => }/config/hcaptcha-config.service.ts (100%) rename packages/apps/reputation-oracle/server/src/{common => }/config/index.ts (100%) rename packages/apps/reputation-oracle/server/src/{common => }/config/kyc-config.service.ts (100%) rename packages/apps/reputation-oracle/server/src/{common => }/config/network-config.service.ts (97%) rename packages/apps/reputation-oracle/server/src/{common => }/config/pgp-config.service.ts (100%) rename packages/apps/reputation-oracle/server/src/{common => }/config/reputation-config.service.ts (100%) rename packages/apps/reputation-oracle/server/src/{common => }/config/s3-config.service.ts (100%) rename packages/apps/reputation-oracle/server/src/{common => }/config/server-config.service.ts (100%) rename packages/apps/reputation-oracle/server/src/{common => }/config/web3-config.service.ts (100%) diff --git a/packages/apps/reputation-oracle/server/scripts/generate-env-doc.ts b/packages/apps/reputation-oracle/server/scripts/generate-env-doc.ts index 2b1817c9ce..5c56a8f1ca 100644 --- a/packages/apps/reputation-oracle/server/scripts/generate-env-doc.ts +++ b/packages/apps/reputation-oracle/server/scripts/generate-env-doc.ts @@ -1,7 +1,7 @@ import * as fs from 'fs'; import * as path from 'path'; -const CONFIG_FOLDER_PATH = path.join(__dirname, '../src/common/config'); +const CONFIG_FOLDER_PATH = path.join(__dirname, '../src/config'); const OUTPUT_FILE_PATH = path.join(__dirname, '../ENV.md'); const envVarRegex = diff --git a/packages/apps/reputation-oracle/server/src/app.module.ts b/packages/apps/reputation-oracle/server/src/app.module.ts index 74aada9e5e..64f1d360cd 100644 --- a/packages/apps/reputation-oracle/server/src/app.module.ts +++ b/packages/apps/reputation-oracle/server/src/app.module.ts @@ -9,13 +9,13 @@ import { HttpValidationPipe } from './common/pipes'; import { HealthModule } from './modules/health/health.module'; import { ReputationModule } from './modules/reputation/reputation.module'; import { Web3Module } from './modules/web3/web3.module'; -import { envValidator } from './common/config'; +import { envValidator } from './config'; import { AuthModule } from './modules/auth/auth.module'; import { TransformInterceptor } from './common/interceptors/transform.interceptor'; import { KycModule } from './modules/kyc/kyc.module'; import { CronJobModule } from './modules/cron-job/cron-job.module'; import { PayoutModule } from './modules/payout/payout.module'; -import { EnvConfigModule } from './common/config/config.module'; +import { EnvConfigModule } from './config/config.module'; import { HCaptchaModule } from './integrations/hcaptcha/hcaptcha.module'; import { ExceptionFilter } from './common/filters/exception.filter'; import { QualificationModule } from './modules/qualification/qualification.module'; diff --git a/packages/apps/reputation-oracle/server/src/common/guards/hcaptcha.ts b/packages/apps/reputation-oracle/server/src/common/guards/hcaptcha.ts index 5b9a169ed3..ad58229bfd 100644 --- a/packages/apps/reputation-oracle/server/src/common/guards/hcaptcha.ts +++ b/packages/apps/reputation-oracle/server/src/common/guards/hcaptcha.ts @@ -7,7 +7,7 @@ import { } from '@nestjs/common'; import { Request } from 'express'; import { HCaptchaService } from '../../integrations/hcaptcha/hcaptcha.service'; -import { AuthConfigService } from '../config/auth-config.service'; +import { AuthConfigService } from '../../config/auth-config.service'; @Injectable() export class HCaptchaGuard implements CanActivate { diff --git a/packages/apps/reputation-oracle/server/src/common/guards/kyc-webhook.auth.ts b/packages/apps/reputation-oracle/server/src/common/guards/kyc-webhook.auth.ts index c590bf20ce..259acf1a0d 100644 --- a/packages/apps/reputation-oracle/server/src/common/guards/kyc-webhook.auth.ts +++ b/packages/apps/reputation-oracle/server/src/common/guards/kyc-webhook.auth.ts @@ -7,7 +7,7 @@ import { } from '@nestjs/common'; import { Request } from 'express'; import { createHmac } from 'crypto'; -import { KycConfigService } from '../config/kyc-config.service'; +import { KycConfigService } from '../../config/kyc-config.service'; @Injectable() export class KycWebhookAuthGuard implements CanActivate { diff --git a/packages/apps/reputation-oracle/server/src/common/config/auth-config.service.ts b/packages/apps/reputation-oracle/server/src/config/auth-config.service.ts similarity index 100% rename from packages/apps/reputation-oracle/server/src/common/config/auth-config.service.ts rename to packages/apps/reputation-oracle/server/src/config/auth-config.service.ts diff --git a/packages/apps/reputation-oracle/server/src/common/config/config.module.ts b/packages/apps/reputation-oracle/server/src/config/config.module.ts similarity index 100% rename from packages/apps/reputation-oracle/server/src/common/config/config.module.ts rename to packages/apps/reputation-oracle/server/src/config/config.module.ts diff --git a/packages/apps/reputation-oracle/server/src/common/config/database-config.service.ts b/packages/apps/reputation-oracle/server/src/config/database-config.service.ts similarity index 100% rename from packages/apps/reputation-oracle/server/src/common/config/database-config.service.ts rename to packages/apps/reputation-oracle/server/src/config/database-config.service.ts diff --git a/packages/apps/reputation-oracle/server/src/common/config/email-config.service.ts b/packages/apps/reputation-oracle/server/src/config/email-config.service.ts similarity index 100% rename from packages/apps/reputation-oracle/server/src/common/config/email-config.service.ts rename to packages/apps/reputation-oracle/server/src/config/email-config.service.ts diff --git a/packages/apps/reputation-oracle/server/src/common/config/env-schema.ts b/packages/apps/reputation-oracle/server/src/config/env-schema.ts similarity index 100% rename from packages/apps/reputation-oracle/server/src/common/config/env-schema.ts rename to packages/apps/reputation-oracle/server/src/config/env-schema.ts diff --git a/packages/apps/reputation-oracle/server/src/common/config/hcaptcha-config.service.ts b/packages/apps/reputation-oracle/server/src/config/hcaptcha-config.service.ts similarity index 100% rename from packages/apps/reputation-oracle/server/src/common/config/hcaptcha-config.service.ts rename to packages/apps/reputation-oracle/server/src/config/hcaptcha-config.service.ts diff --git a/packages/apps/reputation-oracle/server/src/common/config/index.ts b/packages/apps/reputation-oracle/server/src/config/index.ts similarity index 100% rename from packages/apps/reputation-oracle/server/src/common/config/index.ts rename to packages/apps/reputation-oracle/server/src/config/index.ts diff --git a/packages/apps/reputation-oracle/server/src/common/config/kyc-config.service.ts b/packages/apps/reputation-oracle/server/src/config/kyc-config.service.ts similarity index 100% rename from packages/apps/reputation-oracle/server/src/common/config/kyc-config.service.ts rename to packages/apps/reputation-oracle/server/src/config/kyc-config.service.ts diff --git a/packages/apps/reputation-oracle/server/src/common/config/network-config.service.ts b/packages/apps/reputation-oracle/server/src/config/network-config.service.ts similarity index 97% rename from packages/apps/reputation-oracle/server/src/common/config/network-config.service.ts rename to packages/apps/reputation-oracle/server/src/config/network-config.service.ts index 15079cbd64..c318e548ee 100644 --- a/packages/apps/reputation-oracle/server/src/common/config/network-config.service.ts +++ b/packages/apps/reputation-oracle/server/src/config/network-config.service.ts @@ -1,12 +1,12 @@ import { ChainId } from '@human-protocol/sdk'; import { Injectable } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; -import { Web3Env } from '../enums/web3'; +import { Web3Env } from '../common/enums/web3'; import { LOCALHOST_CHAIN_IDS, MAINNET_CHAIN_IDS, TESTNET_CHAIN_IDS, -} from '../constants/networks'; +} from '../common/constants/networks'; export interface TokensList { [key: string]: string | undefined; diff --git a/packages/apps/reputation-oracle/server/src/common/config/pgp-config.service.ts b/packages/apps/reputation-oracle/server/src/config/pgp-config.service.ts similarity index 100% rename from packages/apps/reputation-oracle/server/src/common/config/pgp-config.service.ts rename to packages/apps/reputation-oracle/server/src/config/pgp-config.service.ts diff --git a/packages/apps/reputation-oracle/server/src/common/config/reputation-config.service.ts b/packages/apps/reputation-oracle/server/src/config/reputation-config.service.ts similarity index 100% rename from packages/apps/reputation-oracle/server/src/common/config/reputation-config.service.ts rename to packages/apps/reputation-oracle/server/src/config/reputation-config.service.ts diff --git a/packages/apps/reputation-oracle/server/src/common/config/s3-config.service.ts b/packages/apps/reputation-oracle/server/src/config/s3-config.service.ts similarity index 100% rename from packages/apps/reputation-oracle/server/src/common/config/s3-config.service.ts rename to packages/apps/reputation-oracle/server/src/config/s3-config.service.ts diff --git a/packages/apps/reputation-oracle/server/src/common/config/server-config.service.ts b/packages/apps/reputation-oracle/server/src/config/server-config.service.ts similarity index 100% rename from packages/apps/reputation-oracle/server/src/common/config/server-config.service.ts rename to packages/apps/reputation-oracle/server/src/config/server-config.service.ts diff --git a/packages/apps/reputation-oracle/server/src/common/config/web3-config.service.ts b/packages/apps/reputation-oracle/server/src/config/web3-config.service.ts similarity index 100% rename from packages/apps/reputation-oracle/server/src/common/config/web3-config.service.ts rename to packages/apps/reputation-oracle/server/src/config/web3-config.service.ts diff --git a/packages/apps/reputation-oracle/server/src/database/database.module.ts b/packages/apps/reputation-oracle/server/src/database/database.module.ts index d6d85dac29..c298adee78 100644 --- a/packages/apps/reputation-oracle/server/src/database/database.module.ts +++ b/packages/apps/reputation-oracle/server/src/database/database.module.ts @@ -12,7 +12,7 @@ import { UserEntity } from '../modules/user/user.entity'; import { KycEntity } from '../modules/kyc/kyc.entity'; import { CronJobEntity } from '../modules/cron-job/cron-job.entity'; import { LoggerOptions } from 'typeorm'; -import { DatabaseConfigService } from '../common/config/database-config.service'; +import { DatabaseConfigService } from '../config/database-config.service'; import { SiteKeyEntity } from '../modules/user/site-key.entity'; import { QualificationEntity } from '../modules/qualification/qualification.entity'; import { UserQualificationEntity } from '../modules/qualification/user-qualification.entity'; diff --git a/packages/apps/reputation-oracle/server/src/integrations/hcaptcha/hcaptcha.service.spec.ts b/packages/apps/reputation-oracle/server/src/integrations/hcaptcha/hcaptcha.service.spec.ts index b941f914e6..16591a5349 100644 --- a/packages/apps/reputation-oracle/server/src/integrations/hcaptcha/hcaptcha.service.spec.ts +++ b/packages/apps/reputation-oracle/server/src/integrations/hcaptcha/hcaptcha.service.spec.ts @@ -1,7 +1,7 @@ import { HCaptchaService } from './hcaptcha.service'; import { Test } from '@nestjs/testing'; import { ConfigService } from '@nestjs/config'; -import { HCaptchaConfigService } from '../../common/config/hcaptcha-config.service'; +import { HCaptchaConfigService } from '../../config/hcaptcha-config.service'; import { DeepPartial } from 'typeorm'; import { HttpService } from '@nestjs/axios'; import { of, firstValueFrom } from 'rxjs'; diff --git a/packages/apps/reputation-oracle/server/src/integrations/hcaptcha/hcaptcha.service.ts b/packages/apps/reputation-oracle/server/src/integrations/hcaptcha/hcaptcha.service.ts index 9d349ec7ff..a2072f291f 100644 --- a/packages/apps/reputation-oracle/server/src/integrations/hcaptcha/hcaptcha.service.ts +++ b/packages/apps/reputation-oracle/server/src/integrations/hcaptcha/hcaptcha.service.ts @@ -6,7 +6,7 @@ import { hCaptchaRegisterLabeler, hCaptchaVerifyToken, } from './hcaptcha.dto'; -import { HCaptchaConfigService } from '../../common/config/hcaptcha-config.service'; +import { HCaptchaConfigService } from '../../config/hcaptcha-config.service'; import logger from '../../logger'; @Injectable() diff --git a/packages/apps/reputation-oracle/server/src/main.ts b/packages/apps/reputation-oracle/server/src/main.ts index 6ec2f8e331..cf2416f074 100644 --- a/packages/apps/reputation-oracle/server/src/main.ts +++ b/packages/apps/reputation-oracle/server/src/main.ts @@ -6,7 +6,7 @@ import { json, urlencoded } from 'body-parser'; import helmet from 'helmet'; import { AppModule } from './app.module'; import { useContainer } from 'class-validator'; -import { ServerConfigService } from './common/config/server-config.service'; +import { ServerConfigService } from './config/server-config.service'; import { nestLoggerOverride } from './logger'; async function bootstrap() { diff --git a/packages/apps/reputation-oracle/server/src/modules/auth/auth.module.ts b/packages/apps/reputation-oracle/server/src/modules/auth/auth.module.ts index 82d222df16..c98a82c4c7 100644 --- a/packages/apps/reputation-oracle/server/src/modules/auth/auth.module.ts +++ b/packages/apps/reputation-oracle/server/src/modules/auth/auth.module.ts @@ -8,7 +8,7 @@ import { AuthJwtController } from './auth.controller'; import { TokenRepository } from './token.repository'; import { UserRepository } from '../user/user.repository'; import { Web3Module } from '../web3/web3.module'; -import { AuthConfigService } from '../../common/config/auth-config.service'; +import { AuthConfigService } from '../../config/auth-config.service'; import { HCaptchaModule } from '../../integrations/hcaptcha/hcaptcha.module'; import { EmailModule } from '../email/module'; diff --git a/packages/apps/reputation-oracle/server/src/modules/auth/auth.service.spec.ts b/packages/apps/reputation-oracle/server/src/modules/auth/auth.service.spec.ts index de955fe045..1fe447ed0d 100644 --- a/packages/apps/reputation-oracle/server/src/modules/auth/auth.service.spec.ts +++ b/packages/apps/reputation-oracle/server/src/modules/auth/auth.service.spec.ts @@ -23,11 +23,11 @@ import { MOCK_REFRESH_TOKEN, mockConfig, } from '../../../test/constants'; -import { AuthConfigService } from '../../common/config/auth-config.service'; -import { HCaptchaConfigService } from '../../common/config/hcaptcha-config.service'; -import { NetworkConfigService } from '../../common/config/network-config.service'; -import { ServerConfigService } from '../../common/config/server-config.service'; -import { Web3ConfigService } from '../../common/config/web3-config.service'; +import { AuthConfigService } from '../../config/auth-config.service'; +import { HCaptchaConfigService } from '../../config/hcaptcha-config.service'; +import { NetworkConfigService } from '../../config/network-config.service'; +import { ServerConfigService } from '../../config/server-config.service'; +import { Web3ConfigService } from '../../config/web3-config.service'; import { JobRequestType } from '../../common/enums'; import { Role, UserStatus } from '../../common/enums/user'; import { SignatureType } from '../../common/enums/web3'; diff --git a/packages/apps/reputation-oracle/server/src/modules/auth/auth.service.ts b/packages/apps/reputation-oracle/server/src/modules/auth/auth.service.ts index 054d3372d8..822f3491e6 100644 --- a/packages/apps/reputation-oracle/server/src/modules/auth/auth.service.ts +++ b/packages/apps/reputation-oracle/server/src/modules/auth/auth.service.ts @@ -22,9 +22,9 @@ import { import { SignatureType, Web3Env } from '../../common/enums/web3'; import { prepareSignatureBody } from '../../utils/web3'; import { UserRepository } from '../user/user.repository'; -import { AuthConfigService } from '../../common/config/auth-config.service'; -import { ServerConfigService } from '../../common/config/server-config.service'; -import { Web3ConfigService } from '../../common/config/web3-config.service'; +import { AuthConfigService } from '../../config/auth-config.service'; +import { ServerConfigService } from '../../config/server-config.service'; +import { Web3ConfigService } from '../../config/web3-config.service'; import { SiteKeyType } from '../../common/enums'; import { AuthError, diff --git a/packages/apps/reputation-oracle/server/src/modules/auth/strategy/jwt.http.ts b/packages/apps/reputation-oracle/server/src/modules/auth/strategy/jwt.http.ts index bba6c08e44..3d494d2ea5 100644 --- a/packages/apps/reputation-oracle/server/src/modules/auth/strategy/jwt.http.ts +++ b/packages/apps/reputation-oracle/server/src/modules/auth/strategy/jwt.http.ts @@ -10,7 +10,7 @@ import { } from '../../../common/constants'; import { UserStatus } from '../../../common/enums/user'; import { UserRepository } from '../../user/user.repository'; -import { AuthConfigService } from '../../../common/config/auth-config.service'; +import { AuthConfigService } from '../../../config/auth-config.service'; import { TokenRepository } from '../token.repository'; import { TokenType } from '../token.entity'; diff --git a/packages/apps/reputation-oracle/server/src/modules/email/sendgrid.service.spec.ts b/packages/apps/reputation-oracle/server/src/modules/email/sendgrid.service.spec.ts index f1ccfdd04a..a225eccdb6 100644 --- a/packages/apps/reputation-oracle/server/src/modules/email/sendgrid.service.spec.ts +++ b/packages/apps/reputation-oracle/server/src/modules/email/sendgrid.service.spec.ts @@ -9,7 +9,7 @@ import { SENDGRID_TEMPLATES, SERVICE_NAME } from './sendgrid.service'; import logger from '../../logger'; import { getTemplateId } from './sendgrid.service'; import { EmailAction } from './constants'; -import { EmailConfigService } from '../../common/config/email-config.service'; +import { EmailConfigService } from '../../config/email-config.service'; import { SendgridEmailService } from './sendgrid.service'; const mockMailService = { diff --git a/packages/apps/reputation-oracle/server/src/modules/email/sendgrid.service.ts b/packages/apps/reputation-oracle/server/src/modules/email/sendgrid.service.ts index 251a5d4c2f..cdd3b37848 100644 --- a/packages/apps/reputation-oracle/server/src/modules/email/sendgrid.service.ts +++ b/packages/apps/reputation-oracle/server/src/modules/email/sendgrid.service.ts @@ -4,7 +4,7 @@ import { MailService } from '@sendgrid/mail'; import { EmailService } from './email.service'; import { EmailAction, SENDGRID_API_KEY_REGEX } from './constants'; import logger from '../../logger'; -import { EmailConfigService } from '../../common/config/email-config.service'; +import { EmailConfigService } from '../../config/email-config.service'; import Environment from '../../utils/environment'; export const SENDGRID_TEMPLATES = { diff --git a/packages/apps/reputation-oracle/server/src/modules/escrow-completion/escrow-completion.repository.ts b/packages/apps/reputation-oracle/server/src/modules/escrow-completion/escrow-completion.repository.ts index ea511e65b1..2454e455d4 100644 --- a/packages/apps/reputation-oracle/server/src/modules/escrow-completion/escrow-completion.repository.ts +++ b/packages/apps/reputation-oracle/server/src/modules/escrow-completion/escrow-completion.repository.ts @@ -1,7 +1,7 @@ import { Injectable } from '@nestjs/common'; import { BaseRepository } from '../../database/base.repository'; import { DataSource, LessThanOrEqual } from 'typeorm'; -import { ServerConfigService } from '../../common/config/server-config.service'; +import { ServerConfigService } from '../../config/server-config.service'; import { EscrowCompletionEntity } from './escrow-completion.entity'; import { EscrowCompletionStatus } from '../../common/enums'; diff --git a/packages/apps/reputation-oracle/server/src/modules/escrow-completion/escrow-completion.service.spec.ts b/packages/apps/reputation-oracle/server/src/modules/escrow-completion/escrow-completion.service.spec.ts index 62293fd6e0..c6405d2ab8 100644 --- a/packages/apps/reputation-oracle/server/src/modules/escrow-completion/escrow-completion.service.spec.ts +++ b/packages/apps/reputation-oracle/server/src/modules/escrow-completion/escrow-completion.service.spec.ts @@ -18,8 +18,8 @@ import { EscrowCompletionStatus } from '../../common/enums/webhook'; import { Web3Service } from '../web3/web3.service'; import { EscrowCompletionRepository } from './escrow-completion.repository'; import { EscrowCompletionEntity } from './escrow-completion.entity'; -import { Web3ConfigService } from '../../common/config/web3-config.service'; -import { ServerConfigService } from '../../common/config/server-config.service'; +import { Web3ConfigService } from '../../config/web3-config.service'; +import { ServerConfigService } from '../../config/server-config.service'; import { EscrowCompletionService } from './escrow-completion.service'; import { PostgresErrorCodes } from '../../common/enums/database'; import { WebhookOutgoingService } from '../webhook/webhook-outgoing.service'; @@ -29,9 +29,9 @@ import { DatabaseError } from '../../common/errors/database'; import { WebhookOutgoingRepository } from '../webhook/webhook-outgoing.repository'; import { StorageService } from '../storage/storage.service'; import { ReputationRepository } from '../reputation/reputation.repository'; -import { ReputationConfigService } from '../../common/config/reputation-config.service'; -import { PGPConfigService } from '../../common/config/pgp-config.service'; -import { S3ConfigService } from '../../common/config/s3-config.service'; +import { ReputationConfigService } from '../../config/reputation-config.service'; +import { PGPConfigService } from '../../config/pgp-config.service'; +import { S3ConfigService } from '../../config/s3-config.service'; import { EscrowPayoutsBatchRepository } from './escrow-payouts-batch.repository'; jest.mock('@human-protocol/sdk', () => ({ diff --git a/packages/apps/reputation-oracle/server/src/modules/escrow-completion/escrow-completion.service.ts b/packages/apps/reputation-oracle/server/src/modules/escrow-completion/escrow-completion.service.ts index a426cca014..26c6e7f197 100644 --- a/packages/apps/reputation-oracle/server/src/modules/escrow-completion/escrow-completion.service.ts +++ b/packages/apps/reputation-oracle/server/src/modules/escrow-completion/escrow-completion.service.ts @@ -5,7 +5,7 @@ import stringify from 'json-stable-stringify'; import _ from 'lodash'; import { Injectable } from '@nestjs/common'; import { EscrowCompletionStatus, EventType } from '../../common/enums'; -import { ServerConfigService } from '../../common/config/server-config.service'; +import { ServerConfigService } from '../../config/server-config.service'; import { EscrowCompletionRepository } from './escrow-completion.repository'; import { EscrowCompletionEntity } from './escrow-completion.entity'; import { diff --git a/packages/apps/reputation-oracle/server/src/modules/health/health.controller.ts b/packages/apps/reputation-oracle/server/src/modules/health/health.controller.ts index 16f4342f73..9cd1e04358 100644 --- a/packages/apps/reputation-oracle/server/src/modules/health/health.controller.ts +++ b/packages/apps/reputation-oracle/server/src/modules/health/health.controller.ts @@ -9,7 +9,7 @@ import { } from '@nestjs/terminus'; import packageJson from '../../../package.json'; import { Public } from '../../common/decorators'; -import { ServerConfigService } from '../../common/config/server-config.service'; +import { ServerConfigService } from '../../config/server-config.service'; import { PingResponseDto } from './dto/ping-response.dto'; import Environment from '../../utils/environment'; diff --git a/packages/apps/reputation-oracle/server/src/modules/kyc/kyc.controller.spec.ts b/packages/apps/reputation-oracle/server/src/modules/kyc/kyc.controller.spec.ts index 8fefe5ced8..9799d287a1 100644 --- a/packages/apps/reputation-oracle/server/src/modules/kyc/kyc.controller.spec.ts +++ b/packages/apps/reputation-oracle/server/src/modules/kyc/kyc.controller.spec.ts @@ -3,7 +3,7 @@ import { Test } from '@nestjs/testing'; import { KycController } from './kyc.controller'; import { KycSessionDto } from './kyc.dto'; import { KycService } from './kyc.service'; -import { EnvConfigModule } from '../../common/config/config.module'; +import { EnvConfigModule } from '../../config/config.module'; describe('KycController', () => { let kycController: KycController; diff --git a/packages/apps/reputation-oracle/server/src/modules/kyc/kyc.service.spec.ts b/packages/apps/reputation-oracle/server/src/modules/kyc/kyc.service.spec.ts index 2109ac4095..207dfe8f2e 100644 --- a/packages/apps/reputation-oracle/server/src/modules/kyc/kyc.service.spec.ts +++ b/packages/apps/reputation-oracle/server/src/modules/kyc/kyc.service.spec.ts @@ -6,9 +6,9 @@ import { Test } from '@nestjs/testing'; import { of } from 'rxjs'; import { DeepPartial } from 'typeorm'; import { MOCK_ADDRESS, mockConfig } from '../../../test/constants'; -import { HCaptchaConfigService } from '../../common/config/hcaptcha-config.service'; -import { NetworkConfigService } from '../../common/config/network-config.service'; -import { KycConfigService } from '../../common/config/kyc-config.service'; +import { HCaptchaConfigService } from '../../config/hcaptcha-config.service'; +import { NetworkConfigService } from '../../config/network-config.service'; +import { KycConfigService } from '../../config/kyc-config.service'; import { KycStatus } from '../../common/enums/user'; import { Web3Service } from '../web3/web3.service'; import { KycEntity } from './kyc.entity'; diff --git a/packages/apps/reputation-oracle/server/src/modules/kyc/kyc.service.ts b/packages/apps/reputation-oracle/server/src/modules/kyc/kyc.service.ts index 7504c9dc30..ee77a6b9a5 100644 --- a/packages/apps/reputation-oracle/server/src/modules/kyc/kyc.service.ts +++ b/packages/apps/reputation-oracle/server/src/modules/kyc/kyc.service.ts @@ -6,10 +6,10 @@ import { KycSessionDto, KycSignedAddressDto, KycStatusDto } from './kyc.dto'; import { KycRepository } from './kyc.repository'; import { KycStatus } from '../../common/enums/user'; import { firstValueFrom } from 'rxjs'; -import { KycConfigService } from '../../common/config/kyc-config.service'; +import { KycConfigService } from '../../config/kyc-config.service'; import { KycEntity } from './kyc.entity'; import { Web3Service } from '../web3/web3.service'; -import { NetworkConfigService } from '../../common/config/network-config.service'; +import { NetworkConfigService } from '../../config/network-config.service'; import { KycErrorMessage, KycError } from './kyc.error'; diff --git a/packages/apps/reputation-oracle/server/src/modules/qualification/qualification.service.spec.ts b/packages/apps/reputation-oracle/server/src/modules/qualification/qualification.service.spec.ts index becbafe035..36597690fc 100644 --- a/packages/apps/reputation-oracle/server/src/modules/qualification/qualification.service.spec.ts +++ b/packages/apps/reputation-oracle/server/src/modules/qualification/qualification.service.spec.ts @@ -11,7 +11,7 @@ import { CreateQualificationDto } from './qualification.dto'; import { QualificationEntity } from './qualification.entity'; import { UserEntity } from '../user/user.entity'; import { UserQualificationEntity } from './user-qualification.entity'; -import { ServerConfigService } from '../../common/config/server-config.service'; +import { ServerConfigService } from '../../config/server-config.service'; import { ConfigService } from '@nestjs/config'; import { mockConfig } from '../../../test/constants'; diff --git a/packages/apps/reputation-oracle/server/src/modules/qualification/qualification.service.ts b/packages/apps/reputation-oracle/server/src/modules/qualification/qualification.service.ts index 4dd55aa189..d717b520da 100644 --- a/packages/apps/reputation-oracle/server/src/modules/qualification/qualification.service.ts +++ b/packages/apps/reputation-oracle/server/src/modules/qualification/qualification.service.ts @@ -6,7 +6,7 @@ import { UserEntity } from '../user/user.entity'; import { UserRepository } from '../user/user.repository'; import { UserStatus, Role } from '../../common/enums/user'; import { UserQualificationEntity } from './user-qualification.entity'; -import { ServerConfigService } from '../../common/config/server-config.service'; +import { ServerConfigService } from '../../config/server-config.service'; import { QualificationError, QualificationErrorMessage, diff --git a/packages/apps/reputation-oracle/server/src/modules/reputation/reputation.controller.spec.ts b/packages/apps/reputation-oracle/server/src/modules/reputation/reputation.controller.spec.ts index 14f63c265d..f9f1e0a1f2 100644 --- a/packages/apps/reputation-oracle/server/src/modules/reputation/reputation.controller.spec.ts +++ b/packages/apps/reputation-oracle/server/src/modules/reputation/reputation.controller.spec.ts @@ -9,9 +9,9 @@ import { ReputationDto } from './reputation.dto'; import { StorageService } from '../storage/storage.service'; import { Web3Service } from '../web3/web3.service'; import { MOCK_ADDRESS, mockConfig } from '../../../test/constants'; -import { ReputationConfigService } from '../../common/config/reputation-config.service'; -import { S3ConfigService } from '../../common/config/s3-config.service'; -import { PGPConfigService } from '../../common/config/pgp-config.service'; +import { ReputationConfigService } from '../../config/reputation-config.service'; +import { S3ConfigService } from '../../config/s3-config.service'; +import { PGPConfigService } from '../../config/pgp-config.service'; const OPERATOR_ADDRESS = 'TEST_OPERATOR_ADDRESS'; const CHAIN_ID = 1; diff --git a/packages/apps/reputation-oracle/server/src/modules/reputation/reputation.service.spec.ts b/packages/apps/reputation-oracle/server/src/modules/reputation/reputation.service.spec.ts index 6dae0f8508..67d371f720 100644 --- a/packages/apps/reputation-oracle/server/src/modules/reputation/reputation.service.spec.ts +++ b/packages/apps/reputation-oracle/server/src/modules/reputation/reputation.service.spec.ts @@ -25,7 +25,7 @@ import { ConfigModule, ConfigService, registerAs } from '@nestjs/config'; import { Web3Service } from '../web3/web3.service'; import { StorageService } from '../storage/storage.service'; import { EscrowClient } from '@human-protocol/sdk'; -import { ReputationConfigService } from '../../common/config/reputation-config.service'; +import { ReputationConfigService } from '../../config/reputation-config.service'; import { ReputationError, ReputationErrorMessage } from './reputation.error'; jest.mock('@human-protocol/sdk', () => ({ diff --git a/packages/apps/reputation-oracle/server/src/modules/reputation/reputation.service.ts b/packages/apps/reputation-oracle/server/src/modules/reputation/reputation.service.ts index 54ab5d61ba..58b3fb0916 100644 --- a/packages/apps/reputation-oracle/server/src/modules/reputation/reputation.service.ts +++ b/packages/apps/reputation-oracle/server/src/modules/reputation/reputation.service.ts @@ -25,7 +25,7 @@ import { import { RequestAction } from './reputation.interface'; import { getRequestType } from '../../utils/manifest'; import { CvatManifest } from '../../common/interfaces/manifest'; -import { ReputationConfigService } from '../../common/config/reputation-config.service'; +import { ReputationConfigService } from '../../config/reputation-config.service'; import { ReputationEntity } from './reputation.entity'; import { ReputationError, ReputationErrorMessage } from './reputation.error'; diff --git a/packages/apps/reputation-oracle/server/src/modules/storage/storage.service.spec.ts b/packages/apps/reputation-oracle/server/src/modules/storage/storage.service.spec.ts index 1dac0a7270..605660b6f3 100644 --- a/packages/apps/reputation-oracle/server/src/modules/storage/storage.service.spec.ts +++ b/packages/apps/reputation-oracle/server/src/modules/storage/storage.service.spec.ts @@ -16,8 +16,8 @@ import { import { StorageService } from './storage.service'; import crypto from 'crypto'; import { Web3Service } from '../web3/web3.service'; -import { PGPConfigService } from '../../common/config/pgp-config.service'; -import { S3ConfigService } from '../../common/config/s3-config.service'; +import { PGPConfigService } from '../../config/pgp-config.service'; +import { S3ConfigService } from '../../config/s3-config.service'; jest.mock('@human-protocol/sdk', () => ({ ...jest.requireActual('@human-protocol/sdk'), diff --git a/packages/apps/reputation-oracle/server/src/modules/storage/storage.service.ts b/packages/apps/reputation-oracle/server/src/modules/storage/storage.service.ts index 2ad1949c20..46f58d7c49 100644 --- a/packages/apps/reputation-oracle/server/src/modules/storage/storage.service.ts +++ b/packages/apps/reputation-oracle/server/src/modules/storage/storage.service.ts @@ -12,8 +12,8 @@ import crypto from 'crypto'; import { UploadedFile } from '../../common/interfaces/s3'; import { Web3Service } from '../web3/web3.service'; import { FortuneFinalResult } from '../../common/interfaces/job-result'; -import { S3ConfigService } from '../../common/config/s3-config.service'; -import { PGPConfigService } from '../../common/config/pgp-config.service'; +import { S3ConfigService } from '../../config/s3-config.service'; +import { PGPConfigService } from '../../config/pgp-config.service'; import { isNotFoundError } from '../../common/errors/minio'; import { FileDownloadError, diff --git a/packages/apps/reputation-oracle/server/src/modules/user/user.service.spec.ts b/packages/apps/reputation-oracle/server/src/modules/user/user.service.spec.ts index 096824ec18..96914926c0 100644 --- a/packages/apps/reputation-oracle/server/src/modules/user/user.service.spec.ts +++ b/packages/apps/reputation-oracle/server/src/modules/user/user.service.spec.ts @@ -22,11 +22,11 @@ import { ChainId, KVStoreClient, KVStoreUtils } from '@human-protocol/sdk'; import { ConfigService } from '@nestjs/config'; import { SignatureBodyDto } from '../user/user.dto'; import { SignatureType } from '../../common/enums/web3'; -import { Web3ConfigService } from '../../common/config/web3-config.service'; +import { Web3ConfigService } from '../../config/web3-config.service'; import { SiteKeyRepository } from './site-key.repository'; import { SiteKeyEntity } from './site-key.entity'; import { HCaptchaService } from '../../integrations/hcaptcha/hcaptcha.service'; -import { HCaptchaConfigService } from '../../common/config/hcaptcha-config.service'; +import { HCaptchaConfigService } from '../../config/hcaptcha-config.service'; import { HttpService } from '@nestjs/axios'; import { UserError, @@ -34,7 +34,7 @@ import { DuplicatedWalletAddressError, InvalidWeb3SignatureError, } from '../../modules/user/user.error'; -import { NetworkConfigService } from '../../common/config/network-config.service'; +import { NetworkConfigService } from '../../config/network-config.service'; import { SiteKeyType } from '../../common/enums'; jest.mock('@human-protocol/sdk', () => ({ diff --git a/packages/apps/reputation-oracle/server/src/modules/user/user.service.ts b/packages/apps/reputation-oracle/server/src/modules/user/user.service.ts index 4a74beb4fa..8266453c5f 100644 --- a/packages/apps/reputation-oracle/server/src/modules/user/user.service.ts +++ b/packages/apps/reputation-oracle/server/src/modules/user/user.service.ts @@ -13,13 +13,13 @@ import { UserRepository } from './user.repository'; import { Web3Service } from '../web3/web3.service'; import { SignatureType, Web3Env } from '../../common/enums/web3'; import { ChainId, KVStoreClient, KVStoreUtils } from '@human-protocol/sdk'; -import { Web3ConfigService } from '../../common/config/web3-config.service'; +import { Web3ConfigService } from '../../config/web3-config.service'; import { SiteKeyEntity } from './site-key.entity'; import { SiteKeyRepository } from './site-key.repository'; import { SiteKeyType } from '../../common/enums'; import { HCaptchaService } from '../../integrations/hcaptcha/hcaptcha.service'; -import { HCaptchaConfigService } from '../../common/config/hcaptcha-config.service'; -import { NetworkConfigService } from '../../common/config/network-config.service'; +import { HCaptchaConfigService } from '../../config/hcaptcha-config.service'; +import { NetworkConfigService } from '../../config/network-config.service'; import { prepareSignatureBody } from '../../utils/web3'; import { KycSignedAddressDto } from '../kyc/kyc.dto'; import { ethers } from 'ethers'; diff --git a/packages/apps/reputation-oracle/server/src/modules/web3/web3.service.spec.ts b/packages/apps/reputation-oracle/server/src/modules/web3/web3.service.spec.ts index 54ccdadd13..b712a5416a 100644 --- a/packages/apps/reputation-oracle/server/src/modules/web3/web3.service.spec.ts +++ b/packages/apps/reputation-oracle/server/src/modules/web3/web3.service.spec.ts @@ -7,8 +7,8 @@ import { mockConfig, } from '../../../test/constants'; import { Web3Service } from './web3.service'; -import { Web3ConfigService } from '../../common/config/web3-config.service'; -import { NetworkConfigService } from '../../common/config/network-config.service'; +import { Web3ConfigService } from '../../config/web3-config.service'; +import { NetworkConfigService } from '../../config/network-config.service'; describe('Web3Service', () => { let web3Service: Web3Service; diff --git a/packages/apps/reputation-oracle/server/src/modules/web3/web3.service.ts b/packages/apps/reputation-oracle/server/src/modules/web3/web3.service.ts index 423e09327b..9a9b30bcca 100644 --- a/packages/apps/reputation-oracle/server/src/modules/web3/web3.service.ts +++ b/packages/apps/reputation-oracle/server/src/modules/web3/web3.service.ts @@ -1,7 +1,7 @@ import { Injectable } from '@nestjs/common'; import { Provider, Wallet, ethers } from 'ethers'; -import { Web3ConfigService } from '../../common/config/web3-config.service'; -import { NetworkConfigService } from '../../common/config/network-config.service'; +import { Web3ConfigService } from '../../config/web3-config.service'; +import { NetworkConfigService } from '../../config/network-config.service'; type WalletWithProvider = Wallet & { provider: Provider }; diff --git a/packages/apps/reputation-oracle/server/src/modules/webhook/webhook-incoming.repository.ts b/packages/apps/reputation-oracle/server/src/modules/webhook/webhook-incoming.repository.ts index 11eb2322ee..2ccb1dad39 100644 --- a/packages/apps/reputation-oracle/server/src/modules/webhook/webhook-incoming.repository.ts +++ b/packages/apps/reputation-oracle/server/src/modules/webhook/webhook-incoming.repository.ts @@ -3,7 +3,7 @@ import { BaseRepository } from '../../database/base.repository'; import { DataSource, LessThanOrEqual } from 'typeorm'; import { WebhookIncomingStatus } from '../../common/enums/webhook'; import { WebhookIncomingEntity } from './webhook-incoming.entity'; -import { ServerConfigService } from '../../common/config/server-config.service'; +import { ServerConfigService } from '../../config/server-config.service'; @Injectable() export class WebhookIncomingRepository extends BaseRepository { diff --git a/packages/apps/reputation-oracle/server/src/modules/webhook/webhook-incoming.service.spec.ts b/packages/apps/reputation-oracle/server/src/modules/webhook/webhook-incoming.service.spec.ts index 99eacefafc..146a8faea2 100644 --- a/packages/apps/reputation-oracle/server/src/modules/webhook/webhook-incoming.service.spec.ts +++ b/packages/apps/reputation-oracle/server/src/modules/webhook/webhook-incoming.service.spec.ts @@ -16,8 +16,8 @@ import { WebhookOutgoingRepository } from './webhook-outgoing.repository'; import { WebhookIncomingService } from './webhook-incoming.service'; import { WebhookIncomingEntity } from './webhook-incoming.entity'; import { IncomingWebhookDto } from './webhook.dto'; -import { Web3ConfigService } from '../../common/config/web3-config.service'; -import { ServerConfigService } from '../../common/config/server-config.service'; +import { Web3ConfigService } from '../../config/web3-config.service'; +import { ServerConfigService } from '../../config/server-config.service'; import { ReputationService } from '../reputation/reputation.service'; import { EscrowCompletionRepository } from '../escrow-completion/escrow-completion.repository'; import { EscrowCompletionService } from '../escrow-completion/escrow-completion.service'; @@ -27,9 +27,9 @@ import { WebhookOutgoingService } from './webhook-outgoing.service'; import { PayoutService } from '../payout/payout.service'; import { StorageService } from '../storage/storage.service'; import { ReputationRepository } from '../reputation/reputation.repository'; -import { ReputationConfigService } from '../../common/config/reputation-config.service'; -import { S3ConfigService } from '../../common/config/s3-config.service'; -import { PGPConfigService } from '../../common/config/pgp-config.service'; +import { ReputationConfigService } from '../../config/reputation-config.service'; +import { S3ConfigService } from '../../config/s3-config.service'; +import { PGPConfigService } from '../../config/pgp-config.service'; import { IncomingWebhookError, WebhookErrorMessage } from './webhook.error'; import { EscrowPayoutsBatchRepository } from '../escrow-completion/escrow-payouts-batch.repository'; diff --git a/packages/apps/reputation-oracle/server/src/modules/webhook/webhook-incoming.service.ts b/packages/apps/reputation-oracle/server/src/modules/webhook/webhook-incoming.service.ts index 5267e12e08..b02ccab0aa 100644 --- a/packages/apps/reputation-oracle/server/src/modules/webhook/webhook-incoming.service.ts +++ b/packages/apps/reputation-oracle/server/src/modules/webhook/webhook-incoming.service.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/no-non-null-assertion */ import { Injectable } from '@nestjs/common'; -import { ServerConfigService } from '../../common/config/server-config.service'; -import { Web3ConfigService } from '../../common/config/web3-config.service'; +import { ServerConfigService } from '../../config/server-config.service'; +import { Web3ConfigService } from '../../config/web3-config.service'; import { BACKOFF_INTERVAL_SECONDS } from '../../common/constants'; import { EventType, WebhookIncomingStatus } from '../../common/enums'; import { calculateExponentialBackoffMs } from '../../utils/backoff'; diff --git a/packages/apps/reputation-oracle/server/src/modules/webhook/webhook-outgoing.repository.ts b/packages/apps/reputation-oracle/server/src/modules/webhook/webhook-outgoing.repository.ts index 68ff98f576..a2b99adb3d 100644 --- a/packages/apps/reputation-oracle/server/src/modules/webhook/webhook-outgoing.repository.ts +++ b/packages/apps/reputation-oracle/server/src/modules/webhook/webhook-outgoing.repository.ts @@ -3,7 +3,7 @@ import { BaseRepository } from '../../database/base.repository'; import { DataSource, LessThanOrEqual } from 'typeorm'; import { WebhookOutgoingStatus } from '../../common/enums/webhook'; import { WebhookOutgoingEntity } from './webhook-outgoing.entity'; -import { ServerConfigService } from '../../common/config/server-config.service'; +import { ServerConfigService } from '../../config/server-config.service'; @Injectable() export class WebhookOutgoingRepository extends BaseRepository { diff --git a/packages/apps/reputation-oracle/server/src/modules/webhook/webhook-outgoing.service.spec.ts b/packages/apps/reputation-oracle/server/src/modules/webhook/webhook-outgoing.service.spec.ts index c2372ba300..e7eeb5a512 100644 --- a/packages/apps/reputation-oracle/server/src/modules/webhook/webhook-outgoing.service.spec.ts +++ b/packages/apps/reputation-oracle/server/src/modules/webhook/webhook-outgoing.service.spec.ts @@ -23,8 +23,8 @@ import { of } from 'rxjs'; import { HEADER_SIGNATURE_KEY } from '../../common/constants'; import { signMessage } from '../../utils/web3'; import { HttpStatus } from '@nestjs/common'; -import { Web3ConfigService } from '../../common/config/web3-config.service'; -import { ServerConfigService } from '../../common/config/server-config.service'; +import { Web3ConfigService } from '../../config/web3-config.service'; +import { ServerConfigService } from '../../config/server-config.service'; import { OutgoingWebhookError, WebhookErrorMessage } from './webhook.error'; describe('WebhookOutgoingService', () => { diff --git a/packages/apps/reputation-oracle/server/src/modules/webhook/webhook-outgoing.service.ts b/packages/apps/reputation-oracle/server/src/modules/webhook/webhook-outgoing.service.ts index 3f2c8204db..453827a4ee 100644 --- a/packages/apps/reputation-oracle/server/src/modules/webhook/webhook-outgoing.service.ts +++ b/packages/apps/reputation-oracle/server/src/modules/webhook/webhook-outgoing.service.ts @@ -11,8 +11,8 @@ import { } from '../../common/constants'; import { HttpService } from '@nestjs/axios'; import { transformKeysFromCamelToSnake } from '../../utils/case-converters'; -import { ServerConfigService } from '../../common/config/server-config.service'; -import { Web3ConfigService } from '../../common/config/web3-config.service'; +import { ServerConfigService } from '../../config/server-config.service'; +import { Web3ConfigService } from '../../config/web3-config.service'; import { WebhookOutgoingEntity } from './webhook-outgoing.entity'; import { WebhookOutgoingRepository } from './webhook-outgoing.repository'; import { calculateExponentialBackoffMs } from '../../utils/backoff';