Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release 230904 #864

Merged
merged 21 commits into from
Sep 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
6aac245
Using `json.dumps()` instead of `str()` to ensure compatability with …
Dzeranov Aug 24, 2023
57818b6
[CVAT][JOB LAUNCHER] Update CVAT manifest (#817)
flopez7 Aug 24, 2023
cb9414b
[AGREEMENT] Add bootstrapping capabilities to agreement package (#823)
simulacrum6 Aug 25, 2023
3eeb2b7
[JOB LAUNCHER] Get job lists (#831)
flopez7 Aug 28, 2023
4a133f2
[Job Launcher] Implemented signature verification mechanism (#800)
eugenvoronov Aug 28, 2023
0d36bba
Job Launcher - vercel config (#832)
portuu3 Aug 28, 2023
a1b21ab
Add an endpoint to retrieve all valid networks (#839)
flopez7 Aug 28, 2023
8615c14
add a constant hash secret to avoid 401 in vercel (#840)
portuu3 Aug 28, 2023
3039dfc
[SDK] Nullable credentials (#841)
flopez7 Aug 29, 2023
115e88f
[Job Launcher] Cancel job (#805)
eugenvoronov Aug 29, 2023
956a5ed
[Job Launcher] Job cancelation (#844)
eugenvoronov Aug 29, 2023
ac97979
fix build error of Job Launcher (#845)
portuu3 Aug 29, 2023
af1e50d
[Job Launcher] Calculate job bounties (#846)
flopez7 Aug 30, 2023
d90724c
[Job Launcher] Job bounties (#851)
flopez7 Aug 30, 2023
8e27a4b
feat: Getter functions of SDK (#833)
leric7 Aug 30, 2023
216c18e
Feat: Add JobRequesterId to createEscrow function (#853)
leric7 Aug 31, 2023
fab76cf
fix cron job route (#855)
portuu3 Aug 31, 2023
b21b382
[Job Launcher] Exchange Oracle webhook (#849)
eugenvoronov Sep 1, 2023
cf84bdb
Fixes after adding job requester to contract (#858)
portuu3 Sep 1, 2023
e0b105f
Make the constant path relative (#860)
flopez7 Sep 1, 2023
a4ad466
Add getManifestHash function for python/typescript sdk. Allow docker-…
alidzm Sep 4, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 0 additions & 57 deletions .github/workflows/cd-deploy-contracts.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -135,61 +135,4 @@ jobs:
run: npx hardhat verify --network ${{ github.event.inputs.network }} ${{ steps.networks.outputs.reward_pool }}
working-directory: ./packages/core

#Deploy subgraph
- run: yarn global add @graphprotocol/graph-cli
name: Install Graph CLI
- run: graph auth --product hosted-service ${API_KEY}
name: Authenticate Graph CLI
env:
API_KEY: ${{ secrets.HP_GRAPH_API_KEY }}
- run: yarn generate
name: Generate Subgraph
working-directory: ./packages/sdk/typescript/subgraph
env:
NETWORK: ${{ steps.networks.outputs.subgraph }}
- run: graph deploy --product hosted-service humanprotocol/${NETWORK}
name: Deploy Subgraph
working-directory: ./packages/sdk/typescript/subgraph
env:
NETWORK: ${{ steps.networks.outputs.subgraph }}
#Commit changes to develop
- name: Check for Changes
if: always()
id: check_changes
run: |
git fetch
if [[ -n "$(git diff --name-only)" ]]; then
echo "Changes detected."
echo "::set-output name=changes::true"
else
echo "No changes detected."
echo "::set-output name=changes::false"
fi

- name: stash
if: always() && steps.check_changes.outputs.changes == 'true'
run: |
git status
git stash --include-untracked
- name: Checkout develop
if: always() && steps.check_changes.outputs.changes == 'true'
uses: actions/checkout@v3
with:
ref: develop
token: ${{ secrets.GH_TOKEN_CD_CONTRACTS }}
- name: pop
if: always() && steps.check_changes.outputs.changes == 'true'
run: |
git stash pop
git status
- name: Commit changes
if: always() && steps.check_changes.outputs.changes == 'true'
uses: EndBug/add-and-commit@v9
with:
add: "['./packages/core/.openzeppelin', './packages/sdk/typescript/subgraph/config']"
message: 'Update grafting and upgrade file from CD'
default_author: github_actions
tag_push: '--force'
github_token: ${{ secrets.GH_TOKEN_CD_CONTRACTS }}


Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ export class JobService {
};

this.storageClient = new StorageClient(
storageCredentials,
this.storageParams,
storageCredentials,
);
}

Expand Down
1 change: 1 addition & 0 deletions packages/apps/job-launcher/server/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ RECORDING_ORACLE_ADDRESS=
REPUTATION_ORACLE_ADDRESS=

# Auth
HASH_SECRET=a328af3fc1dad15342cc3d68936008fa
JWT_SECRET=test-secret
JWT_ACCESS_TOKEN_EXPIRES_IN=1d
JWT_REFRESH_TOKEN_EXPIRES_IN=1d
Expand Down
6 changes: 4 additions & 2 deletions packages/apps/job-launcher/server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"start": "nest start",
"start:dev": "nest start --watch",
"start:debug": "nest start --debug --watch",
"start:prod": "node dist/main",
"start:prod": "node dist/src/main",
"migration:create": "typeorm-ts-node-commonjs migration:create",
"migration:generate": "yarn build && typeorm-ts-node-commonjs migration:generate -p -d typeorm.config.ts",
"migration:revert": "typeorm-ts-node-commonjs migration:revert -d typeorm.config.ts",
Expand All @@ -24,7 +24,8 @@
"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"
"test:e2e": "jest --config ./test/jest-e2e.json",
"vercel-build": "yarn workspace @human-protocol/sdk build"
},
"dependencies": {
"@human-protocol/sdk": "*",
Expand All @@ -36,6 +37,7 @@
"@nestjs/passport": "^10.0.0",
"@nestjs/platform-express": "^9.4.3",
"@nestjs/schedule": "^3.0.1",
"@nestjs/serve-static": "^4.0.0",
"@nestjs/swagger": "^7.0.6",
"@nestjs/terminus": "^10.0.1",
"@nestjs/typeorm": "^10.0.0",
Expand Down
6 changes: 6 additions & 0 deletions packages/apps/job-launcher/server/src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import { JobModule } from './modules/job/job.module';
import { PaymentModule } from './modules/payment/payment.module';
import { Web3Module } from './modules/web3/web3.module';
import { envValidator } from './common/config';
import { ServeStaticModule } from '@nestjs/serve-static';
import { join } from 'path';

@Module({
providers: [
Expand Down Expand Up @@ -40,6 +42,10 @@ import { envValidator } from './common/config';
JobModule,
PaymentModule,
Web3Module,
ServeStaticModule.forRoot({
rootPath: join(__dirname, '..', 'swagger-static'),
serveRoot: process.env.NODE_ENV === 'development' ? '/' : '/swagger',
}),
],
controllers: [AppController],
})
Expand Down
23 changes: 18 additions & 5 deletions packages/apps/job-launcher/server/src/common/config/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export const ConfigNames = {
PORT: 'PORT',
FE_URL: 'FE_URL',
SESSION_SECRET: 'SESSION_SECRET',
HASH_SECRET: 'HASH_SECRET',
JWT_SECRET: 'JWT_SECRET',
JWT_ACCESS_TOKEN_EXPIRES_IN: 'JWT_ACCESS_TOKEN_EXPIRES_IN',
JWT_REFRESH_TOKEN_EXPIRES_IN: 'JWT_REFRESH_TOKEN_EXPIRES_IN',
Expand All @@ -21,8 +22,10 @@ export const ConfigNames = {
JOB_LAUNCHER_FEE: 'JOB_LAUNCHER_FEE',
RECORDING_ORACLE_FEE: 'RECORDING_ORACLE_FEE',
REPUTATION_ORACLE_FEE: 'REPUTATION_ORACLE_FEE',
EXCHANGE_ORACLE_ADDRESS: 'EXCHANGE_ORACLE_ADDRESS',
EXCHANGE_ORACLE_WEBHOOK_URL: 'EXCHANGE_ORACLE_WEBHOOK_URL',
FORTUNE_EXCHANGE_ORACLE_ADDRESS: 'FORTUNE_EXCHANGE_ORACLE_ADDRESS',
CVAT_EXCHANGE_ORACLE_ADDRESS: 'CVAT_EXCHANGE_ORACLE_ADDRESS',
FORTUNE_EXCHANGE_ORACLE_WEBHOOK_URL: 'FORTUNE_EXCHANGE_ORACLE_WEBHOOK_URL',
CVAT_EXCHANGE_ORACLE_WEBHOOK_URL: 'CVAT_EXCHANGE_ORACLE_WEBHOOK_URL',
RECORDING_ORACLE_ADDRESS: 'RECORDING_ORACLE_ADDRESS',
REPUTATION_ORACLE_ADDRESS: 'REPUTATION_ORACLE_ADDRESS',
S3_ENDPOINT: 'S3_ENDPOINT',
Expand All @@ -39,6 +42,9 @@ export const ConfigNames = {
SENDGRID_API_KEY: 'SENDGRID_API_KEY',
SENDGRID_FROM_EMAIL: 'SENDGRID_FROM_EMAIL',
SENDGRID_FROM_NAME: 'SENDGRID_FROM_NAME',
CVAT_JOB_SIZE: 'CVAT_JOB_SIZE',
CVAT_MAX_TIME: 'CVAT_MAX_TIME',
CVAT_VAL_SIZE: 'CVAT_VAL_SIZE',
};

export const envValidator = Joi.object({
Expand All @@ -49,7 +55,8 @@ export const envValidator = Joi.object({
FE_URL: Joi.string().default('http://localhost:3005'),
SESSION_SECRET: Joi.string().default('session_key'),
// Auth
JWT_SECRET: Joi.string().default('secrete'),
HASH_SECRET: Joi.string().default('a328af3fc1dad15342cc3d68936008fa'),
JWT_SECRET: Joi.string().default('secret'),
JWT_ACCESS_TOKEN_EXPIRES_IN: Joi.string().default(1000000000),
JWT_REFRESH_TOKEN_EXPIRES_IN: Joi.string().default(1000000000),
// Database
Expand All @@ -67,8 +74,10 @@ export const envValidator = Joi.object({
JOB_LAUNCHER_FEE: Joi.string().default(10),
RECORDING_ORACLE_FEE: Joi.string().default(10),
REPUTATION_ORACLE_FEE: Joi.string().default(10),
EXCHANGE_ORACLE_ADDRESS: Joi.string().required(),
EXCHANGE_ORACLE_WEBHOOK_URL: Joi.string().default('http://localhost:3005'),
FORTUNE_EXCHANGE_ORACLE_ADDRESS: Joi.string().required(),
CVAT_EXCHANGE_ORACLE_ADDRESS: Joi.string().required(),
FORTUNE_EXCHANGE_ORACLE_WEBHOOK_URL: Joi.string().default('http://localhost:3004'),
CVAT_EXCHANGE_ORACLE_WEBHOOK_URL: Joi.string().default('http://localhost:3005'),
RECORDING_ORACLE_ADDRESS: Joi.string().required(),
REPUTATION_ORACLE_ADDRESS: Joi.string().required(),
// S3
Expand All @@ -88,4 +97,8 @@ export const envValidator = Joi.object({
SENDGRID_API_KEY: Joi.string().required(),
SENDGRID_FROM_EMAIL: Joi.string().default('[email protected]'),
SENDGRID_FROM_NAME: Joi.string().default('Human Protocol Job Launcher'),
// CVAT
CVAT_JOB_SIZE: Joi.string().default('10'),
CVAT_MAX_TIME: Joi.string().default('300'),
CVAT_VAL_SIZE: Joi.string().default('2'),
});
12 changes: 12 additions & 0 deletions packages/apps/job-launcher/server/src/common/constants/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ export enum ErrorJob {
ResultValidationFailed = 'Result validation failed',
InvalidRequestType = 'Invalid job type',
JobParamsValidationFailed = 'Job parameters validation failed',
InvalidEventType = 'Invalid event type',
NotLaunched = 'Not launched'
}

/**
Expand All @@ -21,6 +23,8 @@ export enum ErrorEscrow {
NotFound = 'Escrow not found',
NotCreated = 'Escrow has not been created',
NotLaunched = 'Escrow has not been launched',
InvalidStatusCancellation = 'Escrow has an invalid status for cancellation',
InvalidBalanceCancellation = 'Escrow has an invalid balance for cancellation'
}

/**
Expand Down Expand Up @@ -101,6 +105,14 @@ export enum ErrorSendGrid {
InvalidApiKey = 'Invalid SendGrid API key',
}

/**
* Represents error messages related to signature.
*/
export enum ErrorSignature {
SignatureNotVerified = 'Signature not verified',
InvalidSignature = 'Invalid signature',
}

/**
* Represents error messages related to postgres.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,5 @@ export const MAINNET_CHAIN_IDS = [

export const SENDGRID_API_KEY_REGEX =
/^SG\.[A-Za-z0-9-_]{22}\.[A-Za-z0-9-_]{43}$/;

export const HEADER_SIGNATURE_KEY = 'human-signature';
14 changes: 13 additions & 1 deletion packages/apps/job-launcher/server/src/common/enums/job.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,23 @@ export enum JobStatus {
PENDING = 'PENDING',
PAID = 'PAID',
LAUNCHED = 'LAUNCHED',
COMPLETED = 'COMPLETED',
FAILED = 'FAILED',
TO_CANCEL = 'TO_CANCEL',
CANCELED = 'CANCELED',
}

export enum JobStatusFilter {
PENDING = 'PENDING',
PAID = 'PAID',
LAUNCHED = 'LAUNCHED',
FAILED = 'FAILED',
TO_CANCEL = 'TO_CANCEL',
CANCELED = 'CANCELED',
}

export enum JobRequestType {
IMAGE_LABEL_BINARY = 'IMAGE_LABEL_BINARY',
IMAGE_POINTS = 'IMAGE_POINTS',
IMAGE_BOXES = 'IMAGE_BOXES',
FORTUNE = 'FORTUNE',
}
10 changes: 10 additions & 0 deletions packages/apps/job-launcher/server/src/common/enums/webhook.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export enum EventType {
ESCROW_CREATED = 'escrow_created',
ESCROW_CANCELED = 'escrow_canceled',
TASK_CREATION_FAILED = 'task_creation_failed',
}

export enum OracleType {
FORTUNE = 'fortune',
CVAT = 'cvat',
}
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from './jwt.auth';
export * from './signature.auth';
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import { Test, TestingModule } from '@nestjs/testing';
import { ExecutionContext, UnauthorizedException, BadRequestException } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { SignatureAuthGuard } from './signature.auth';
import { verifySignature } from '../utils/signature';
import { MOCK_ADDRESS } from '../../../test/constants';

jest.mock('../../common/utils/signature');

describe('SignatureAuthGuard', () => {
let guard: SignatureAuthGuard;
let mockConfigService: Partial<ConfigService>;

beforeEach(async () => {
mockConfigService = {
get: jest.fn(),
};

const module: TestingModule = await Test.createTestingModule({
providers: [
SignatureAuthGuard,
{ provide: ConfigService, useValue: mockConfigService }
],
}).compile();

guard = module.get<SignatureAuthGuard>(SignatureAuthGuard);
});

it('should be defined', () => {
expect(guard).toBeDefined();
});

describe('canActivate', () => {
let context: ExecutionContext;
let mockRequest: any;

beforeEach(() => {
mockRequest = {
switchToHttp: jest.fn().mockReturnThis(),
getRequest: jest.fn().mockReturnThis(),
headers: {},
body: {},
originalUrl: '',
};
context = {
switchToHttp: jest.fn().mockReturnThis(),
getRequest: jest.fn(() => mockRequest)
} as any as ExecutionContext;
});

it('should return true if signature is verified', async () => {
mockRequest.headers['header-signature-key'] = 'validSignature';
jest.spyOn(guard, 'determineAddress').mockReturnValue('someAddress');
(verifySignature as jest.Mock).mockReturnValue(true);

const result = await guard.canActivate(context as any);
expect(result).toBeTruthy();
});

it('should throw unauthorized exception if signature is not verified', async () => {
jest.spyOn(guard, 'determineAddress').mockReturnValue('someAddress');
(verifySignature as jest.Mock).mockReturnValue(false);

await expect(guard.canActivate(context as any)).rejects.toThrow(UnauthorizedException);
});

it('should throw unauthorized exception for unrecognized oracle type', async () => {
mockRequest.originalUrl = '/some/random/path';
await expect(guard.canActivate(context as any)).rejects.toThrow(UnauthorizedException);
});
});

describe('determineAddress', () => {
it('should return the correct address if originalUrl contains the fortune oracle type', () => {
const mockRequest = { originalUrl: '/somepath/fortune/anotherpath' };
const expectedAddress = MOCK_ADDRESS;
mockConfigService.get = jest.fn().mockReturnValue(expectedAddress);

const result = guard.determineAddress(mockRequest);

expect(result).toEqual(expectedAddress);
});

it('should return the correct address if originalUrl contains the cvat oracle type', () => {
const mockRequest = { originalUrl: '/somepath/cvat/anotherpath' };
const expectedAddress = MOCK_ADDRESS;
mockConfigService.get = jest.fn().mockReturnValue(expectedAddress);

const result = guard.determineAddress(mockRequest);

expect(result).toEqual(expectedAddress);
});

it('should throw BadRequestException for unrecognized oracle type', () => {
const mockRequest = { originalUrl: '/some/random/path' };

expect(() => {
guard.determineAddress(mockRequest);
}).toThrow(BadRequestException);
});

});
});
Loading
Loading