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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
getConfigService,
ProjectController,
SubscriptionController,
TenderlyController,
UserController,
} from './modules';

Expand Down Expand Up @@ -81,6 +82,7 @@ useExpressServer(app, {
ProjectController,
SubscriptionController,
ContractController,
TenderlyController,
],
middlewares: [AppErrorHandler, AuthMiddleware],
});
Expand Down
10 changes: 10 additions & 0 deletions src/middleware/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import { Service } from 'typedi';

import { getGlobalLogger } from '@bonadocs/di';

import { ApplicationError } from '../modules/errors';

@Service()
@Middleware({ type: 'after' })
export default class AppErrorHandler implements ExpressErrorMiddlewareInterface {
Expand All @@ -15,6 +17,14 @@ export default class AppErrorHandler implements ExpressErrorMiddlewareInterface
return;
}

if (error instanceof ApplicationError) {
response.status(error.statusCode).json({
status: error.errorCode,
message: error.userFriendlyMessage,
});
return;
}

if ((<Error>error).name === 'PayloadTooLargeError') {
response.status(StatusCodes.REQUEST_TOO_LONG).json({
status: 'failed',
Expand Down
2 changes: 1 addition & 1 deletion src/modules/auth/auth.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export class AuthService {
userFriendlyMessage: 'Please check your credentials and try again',
});
}
const user = await this.userRepository.findUserByAuth(request.authSource, authUserId, null);
const user = await this.userRepository.findUserByAuth(request.authSource, authUserId);
if (!user) {
throw new ApplicationError({
logger: this.logger,
Expand Down
5 changes: 2 additions & 3 deletions src/modules/auth/firebase/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import crypto, { createHash } from 'crypto';

import { Inject, Service } from 'typedi';

import { ServiceConfiguration } from '../../configuration/config.interface';
import { GCP } from '../../configuration/config.interface';
import { ConfigService } from '../../configuration/config.service';

let keysCache: { keys: Record<string, string>; expiry: number } | null = null;
Expand Down Expand Up @@ -60,8 +60,7 @@ export class FirebaseJWTProvider {
return false;
}

const gcpProjectId =
this.configService.getTransformed<ServiceConfiguration>('gcp').gcp.projectId;
const gcpProjectId = this.configService.getTransformed<GCP>('gcp').projectId;

const nowSeconds = Date.now() / 1000;
if (
Expand Down
27 changes: 27 additions & 0 deletions src/modules/configuration/config.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,30 @@ export type ServiceConfiguration = {
metaBucket: string;
};
};

export type GCP = {
projectId: string;
collectionsBucket: string;
abisBucket: string;
automergeBucket: string;
metaBucket: string;
};

export type MailGun = {
apiKey: string;
domain: string;
defaultSender: {
name: string;
email: string;
};
};

export type Blockscan = {
etherscan: Record<string, string>;
};

export type Tenderly = {
accessKey: string;
username: string;
project: string;
};
9 changes: 6 additions & 3 deletions src/modules/connection/dbcontext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,13 @@ export function withDbContext<T extends (...args: any[]) => Promise<any>>(
descriptor: TypedPropertyDescriptor<T>,
): TypedPropertyDescriptor<T> {
const originalMethod = descriptor.value!;
return async function wrappedFunction(this: object, ...args: any[]) {

descriptor.value = async function wrappedFunction(this: object, ...args: any[]) {
const lastArg = args[args.length - 1] as DbContext | undefined | null;
const dbContext =
args.length > 0 && lastArg?.isDbContext === true ? (lastArg as DbContext) : undefined;

// if the last argument is a DbContext, we don't need to create a new one
// If the last argument is a DbContext, we don't need to create a new one
if (dbContext) {
return originalMethod.apply(this, args);
}
Expand Down Expand Up @@ -104,5 +105,7 @@ export function withDbContext<T extends (...args: any[]) => Promise<any>>(
}
poolClient.release();
}
} as TypedPropertyDescriptor<T>;
} as T;

return descriptor;
}
4 changes: 2 additions & 2 deletions src/modules/contract/contract.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { diConstants } from '@bonadocs/di';
import { BonadocsLogger } from '@bonadocs/logger';

import { getVerifiedContractABI } from '../blockscan/index';
import { ServiceConfiguration } from '../configuration/config.interface';
import { GCP } from '../configuration/config.interface';
import { ConfigService } from '../configuration/config.service';
import { ApplicationError, applicationErrorCodes } from '../errors';
import { EvmContractRepository } from '../repositories/evm-contracts/evm-contracts.repository';
Expand All @@ -31,7 +31,7 @@ export class ContractService {
request.chainId,
request.address,
);
const gcpConfig = this.configService.getTransformed<ServiceConfiguration>('gcp').gcp;
const gcpConfig = this.configService.getTransformed<GCP>('gcp');
if (abiHash) {
const abi = await this.storage.downloadFile(gcpConfig.abisBucket, `${abiHash}.json`);

Expand Down
2 changes: 1 addition & 1 deletion src/modules/errors/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export { ApplicationError, applicationErrorCodes } from './ApplicationError';
export * from './ApplicationError';
1 change: 1 addition & 0 deletions src/modules/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ export * from './project';
export * from './user';
export * from './contract';
export * from './subscription';
export * from './tenderly';
13 changes: 5 additions & 8 deletions src/modules/mailing/mailgun.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { Inject, Service } from 'typedi';
import { diConstants } from '@bonadocs/di';
import { BonadocsLogger } from '@bonadocs/logger';

import { ServiceConfiguration } from '../configuration/config.interface';
import { MailGun } from '../configuration/config.interface';
import { ConfigService } from '../configuration/config.service';

import { MailError, MailSender, SenderConfig, SendOptions } from './types';
Expand Down Expand Up @@ -45,14 +45,11 @@ export class MailgunSender implements MailSender {

private loadConfig(): MailgunOptions {
return {
domain: this.configService.getTransformed<ServiceConfiguration>('mail').mailgun.domain,
apiKey: this.configService.getTransformed<ServiceConfiguration>('mail').mailgun.apiKey,
domain: this.configService.getTransformed<MailGun>('mail').domain,
apiKey: this.configService.getTransformed<MailGun>('mail').apiKey,
defaultSender: {
email:
this.configService.getTransformed<ServiceConfiguration>('mail').mailgun.defaultSender
.email,
name: this.configService.getTransformed<ServiceConfiguration>('mail').mailgun.defaultSender
.name,
email: this.configService.getTransformed<MailGun>('mail').defaultSender.email,
name: this.configService.getTransformed<MailGun>('mail').defaultSender.name,
},
};
}
Expand Down
17 changes: 6 additions & 11 deletions src/modules/project/project.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { BonadocsLogger } from '@bonadocs/logger';

import { AuthService } from '../auth/auth.service';
import { FirebaseJWTProvider } from '../auth/firebase/index';
import { ServiceConfiguration } from '../configuration/config.interface';
import { GCP } from '../configuration/config.interface';
import { ConfigService } from '../configuration/config.service';
import { ApplicationError, applicationErrorCodes } from '../errors/ApplicationError';
import { MailgunSender } from '../mailing/mailgun';
Expand Down Expand Up @@ -263,8 +263,7 @@ export class ProjectService {
}

const fileId = randomBytes(16).toString('hex');
const bucketName =
this.configService.getTransformed<ServiceConfiguration>('gcp').gcp.collectionsBucket;
const bucketName = this.configService.getTransformed<GCP>('gcp').collectionsBucket;
const fileName = `project-${projectId}/${fileId}.json`;
await this.storage.uploadFile(
bucketName,
Expand Down Expand Up @@ -343,8 +342,7 @@ export class ProjectService {
logger: this.logger,
});
}
const bucketName =
this.configService.getTransformed<ServiceConfiguration>('gcp').gcp.collectionsBucket;
const bucketName = this.configService.getTransformed<GCP>('gcp').collectionsBucket;
const publicUrl = this.storage.getFilePublicUrl(bucketName, collection.uri);

return {
Expand Down Expand Up @@ -373,8 +371,7 @@ export class ProjectService {
});
}

const bucketName =
this.configService.getTransformed<ServiceConfiguration>('gcp').gcp.collectionsBucket;
const bucketName = this.configService.getTransformed<GCP>('gcp').collectionsBucket;

const fileName = collection?.uri;
const savedCollectionData = await this.storage.downloadFile(bucketName, fileName);
Expand Down Expand Up @@ -410,8 +407,7 @@ export class ProjectService {
});
}

const bucketName =
this.configService.getTransformed<ServiceConfiguration>('gcp').gcp.collectionsBucket;
const bucketName = this.configService.getTransformed<GCP>('gcp').collectionsBucket;
const group = FirebaseJWTProvider.getFcmGroupId(projectId, collectionId);
const fileName = `firebase-device-ids/${group}.json`;
const existingFile = await this.storage.downloadFile(bucketName, fileName);
Expand Down Expand Up @@ -471,8 +467,7 @@ export class ProjectService {
});
}

const bucketName =
this.configService.getTransformed<ServiceConfiguration>('gcp').gcp.collectionsBucket;
const bucketName = this.configService.getTransformed<GCP>('gcp').collectionsBucket;
const fileName = collection!.uri;
await this.storage.configureFileAccess(bucketName, fileName, request.isPublic);
await this.projectRepository.updateProjectCollection(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ import { DbContext } from '../../connection/dbcontext';
import { EvmContractRepository } from './evm-contracts.repository';
import { queries } from './queries';

jest.mock('../../connection/dbcontext');
jest.mock('@bonadocs/logger');

describe('EvmContractRepository', () => {
let evmContractsRepository: EvmContractRepository;
let context: jest.Mocked<DbContext>;
Expand Down
2 changes: 2 additions & 0 deletions src/modules/repositories/projects/project.repository.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import { queries } from './queries';
import { CreateProjectDto, GenerateApiKeyDto, InviteUserToProjectDto, PlanDto } from './types';
import { flagsToPermissions, PermissionNames } from './util';

jest.mock('../../connection/dbcontext');
jest.mock('@bonadocs/logger');
describe('ProjectRepository', () => {
let projectRepository: ProjectRepository;
let context: jest.Mocked<DbContext>;
Expand Down
4 changes: 1 addition & 3 deletions src/modules/repositories/projects/project.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,10 @@ export class ProjectRepository {
@withDbContext
async createProject(
data: CreateProjectDto,
context?: DbContext | null,
context: DbContext | null,
): Promise<number | undefined> {
try {
context?.beginTransaction();
// begin and rollback transaction should happen in the service

const createProjectResult = await context?.query({
text: queries.createProject,
values: [data.slug, data.name],
Expand Down
2 changes: 1 addition & 1 deletion src/modules/repositories/users/user.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ export class UserRepository {
async findUserByAuth(
authSource: string,
authId: string,
context: DbContext | null = null,
context?: DbContext,
): Promise<UserData | null> {
const result = await context?.query({
text: queries.findUserByAuth,
Expand Down
5 changes: 2 additions & 3 deletions src/modules/storage/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Inject, Service } from 'typedi';
import { diConstants } from '@bonadocs/di';
import { BonadocsLogger } from '@bonadocs/logger';

import { ServiceConfiguration } from '../configuration/config.interface';
import { GCP } from '../configuration/config.interface';
import { ConfigService } from '../configuration/config.service';

let storageClient: GCloudStorage | undefined;
Expand All @@ -20,8 +20,7 @@ export class Storage {
@Inject(diConstants.logger) private readonly logger: BonadocsLogger,
@Inject() private readonly configService: ConfigService,
) {
this.gcpProjectId =
this.configService.getTransformed<ServiceConfiguration>('gcp').gcp.projectId;
this.gcpProjectId = this.configService.getTransformed<GCP>('gcp').projectId;
}

async uploadFile(
Expand Down
1 change: 1 addition & 0 deletions src/modules/tenderly/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { TenderlyController } from './tenderly.controller';
2 changes: 1 addition & 1 deletion src/modules/tenderly/tenderly.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { TenderlyService } from './tenderly.service';
@Service()
@JsonController('/tenderly')
@Authorized()
export class ProjectController {
export class TenderlyController {
constructor(@Inject() private readonly tenderlyService: TenderlyService) {}

@Get('/stimulate')
Expand Down
Loading