Refactor backend and add exception handlers (#189)
This commit is contained in:
@@ -11,10 +11,12 @@ import { AffectedRows } from '../@generated/prisma/affected-rows.output';
|
||||
import { DeleteManyCompanyArgs } from '../@generated/company/delete-many-company.args';
|
||||
import { Workspace } from '@prisma/client';
|
||||
import { ArgsService } from './services/args.service';
|
||||
import { CheckWorkspaceOwnership } from 'src/auth/guards/check-workspace-ownership.guard';
|
||||
import { Prisma } from '@prisma/client';
|
||||
import { UpdateOneGuard } from './guards/update-one.guard';
|
||||
import { DeleteManyGuard } from './guards/delete-many.guard';
|
||||
import { CreateOneGuard } from './guards/create-one.guard';
|
||||
|
||||
@UseGuards(JwtAuthGuard, CheckWorkspaceOwnership)
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@Resolver(() => Company)
|
||||
export class CompanyResolver {
|
||||
constructor(
|
||||
@@ -35,6 +37,7 @@ export class CompanyResolver {
|
||||
return this.prismaService.company.findMany(preparedArgs);
|
||||
}
|
||||
|
||||
@UseGuards(UpdateOneGuard)
|
||||
@Mutation(() => Company, {
|
||||
nullable: true,
|
||||
})
|
||||
@@ -50,6 +53,7 @@ export class CompanyResolver {
|
||||
} satisfies UpdateOneCompanyArgs as Prisma.CompanyUpdateArgs);
|
||||
}
|
||||
|
||||
@UseGuards(DeleteManyGuard)
|
||||
@Mutation(() => AffectedRows, {
|
||||
nullable: false,
|
||||
})
|
||||
@@ -61,6 +65,7 @@ export class CompanyResolver {
|
||||
});
|
||||
}
|
||||
|
||||
@UseGuards(CreateOneGuard)
|
||||
@Mutation(() => Company, {
|
||||
nullable: false,
|
||||
})
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
import { Catch, HttpException } from '@nestjs/common';
|
||||
import { GqlExceptionFilter } from '@nestjs/graphql';
|
||||
import { Prisma } from '@prisma/client';
|
||||
import { GraphQLError } from 'graphql';
|
||||
|
||||
@Catch()
|
||||
export class ExceptionFilter implements GqlExceptionFilter {
|
||||
catch(exception: HttpException) {
|
||||
if (exception instanceof Prisma.PrismaClientValidationError) {
|
||||
throw new GraphQLError('Invalid request', {
|
||||
extensions: {
|
||||
code: 'INVALID_REQUEST',
|
||||
},
|
||||
});
|
||||
}
|
||||
return exception;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import { CanActivate, Injectable } from '@nestjs/common';
|
||||
import { PrismaService } from 'src/database/prisma.service';
|
||||
|
||||
@Injectable()
|
||||
export class CreateOneGuard implements CanActivate {
|
||||
constructor(private prismaService: PrismaService) {}
|
||||
|
||||
async canActivate(): Promise<boolean> {
|
||||
// TODO
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import { CanActivate, Injectable } from '@nestjs/common';
|
||||
import { PrismaService } from 'src/database/prisma.service';
|
||||
|
||||
@Injectable()
|
||||
export class DeleteManyGuard implements CanActivate {
|
||||
constructor(private prismaService: PrismaService) {}
|
||||
|
||||
async canActivate(): Promise<boolean> {
|
||||
// TODO
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
import {
|
||||
CanActivate,
|
||||
ExecutionContext,
|
||||
HttpException,
|
||||
HttpStatus,
|
||||
Injectable,
|
||||
} from '@nestjs/common';
|
||||
import { GqlExecutionContext } from '@nestjs/graphql';
|
||||
import { PrismaService } from 'src/database/prisma.service';
|
||||
|
||||
@Injectable()
|
||||
export class UpdateOneGuard implements CanActivate {
|
||||
constructor(private prismaService: PrismaService) {}
|
||||
|
||||
async canActivate(context: ExecutionContext): Promise<boolean> {
|
||||
const gqlContext = GqlExecutionContext.create(context);
|
||||
const request = gqlContext.getContext().req;
|
||||
const entity = gqlContext.getArgByIndex(3).returnType?.name;
|
||||
const args = gqlContext.getArgs();
|
||||
|
||||
console.log(args.data);
|
||||
if (!entity || !args.where?.id) {
|
||||
throw new HttpException(
|
||||
{ reason: 'Invalid Request' },
|
||||
HttpStatus.BAD_REQUEST,
|
||||
);
|
||||
}
|
||||
|
||||
const object = await this.prismaService[entity].findUniqueOrThrow({
|
||||
where: { id: args.where.id },
|
||||
});
|
||||
|
||||
if (!object) {
|
||||
throw new HttpException(
|
||||
{ reason: 'Record not found' },
|
||||
HttpStatus.NOT_FOUND,
|
||||
);
|
||||
}
|
||||
|
||||
const workspace = await request.workspace;
|
||||
|
||||
if (object.workspaceId !== workspace.id) {
|
||||
throw new HttpException(
|
||||
{ reason: 'Record not found' },
|
||||
HttpStatus.NOT_FOUND,
|
||||
);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -11,10 +11,12 @@ import { DeleteManyPersonArgs } from '../@generated/person/delete-many-person.ar
|
||||
import { Workspace } from '../@generated/workspace/workspace.model';
|
||||
import { AuthWorkspace } from './decorators/auth-workspace.decorator';
|
||||
import { ArgsService } from './services/args.service';
|
||||
import { CheckWorkspaceOwnership } from 'src/auth/guards/check-workspace-ownership.guard';
|
||||
import { Prisma } from '@prisma/client';
|
||||
import { UpdateOneGuard } from './guards/update-one.guard';
|
||||
import { DeleteManyGuard } from './guards/delete-many.guard';
|
||||
import { CreateOneGuard } from './guards/create-one.guard';
|
||||
|
||||
@UseGuards(JwtAuthGuard, CheckWorkspaceOwnership)
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@Resolver(() => Person)
|
||||
export class PersonResolver {
|
||||
constructor(
|
||||
@@ -39,6 +41,7 @@ export class PersonResolver {
|
||||
});
|
||||
}
|
||||
|
||||
@UseGuards(UpdateOneGuard)
|
||||
@Mutation(() => Person, {
|
||||
nullable: true,
|
||||
})
|
||||
@@ -54,6 +57,7 @@ export class PersonResolver {
|
||||
} satisfies UpdateOnePersonArgs as Prisma.PersonUpdateArgs);
|
||||
}
|
||||
|
||||
@UseGuards(DeleteManyGuard)
|
||||
@Mutation(() => AffectedRows, {
|
||||
nullable: false,
|
||||
})
|
||||
@@ -65,6 +69,7 @@ export class PersonResolver {
|
||||
});
|
||||
}
|
||||
|
||||
@UseGuards(CreateOneGuard)
|
||||
@Mutation(() => Person, {
|
||||
nullable: false,
|
||||
})
|
||||
|
||||
@@ -1,23 +1,20 @@
|
||||
import { Resolver, Query, Args } from '@nestjs/graphql';
|
||||
import { PrismaService } from 'src/database/prisma.service';
|
||||
import { UseGuards } from '@nestjs/common';
|
||||
import { JwtAuthGuard } from 'src/auth/guards/jwt.auth.guard';
|
||||
import { UseFilters, UseGuards } from '@nestjs/common';
|
||||
|
||||
import { User } from '../@generated/user/user.model';
|
||||
import { FindManyUserArgs } from '../@generated/user/find-many-user.args';
|
||||
import { Workspace } from '@prisma/client';
|
||||
import { AuthWorkspace } from './decorators/auth-workspace.decorator';
|
||||
import { ArgsService } from './services/args.service';
|
||||
import { CheckWorkspaceOwnership } from 'src/auth/guards/check-workspace-ownership.guard';
|
||||
import { ExceptionFilter } from './exception-filters/exception.filter';
|
||||
import { JwtAuthGuard } from 'src/auth/guards/jwt.auth.guard';
|
||||
|
||||
@UseGuards(JwtAuthGuard, CheckWorkspaceOwnership)
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@Resolver(() => User)
|
||||
export class UserResolver {
|
||||
constructor(
|
||||
private readonly prismaService: PrismaService,
|
||||
private readonly argsService: ArgsService,
|
||||
) {}
|
||||
constructor(private readonly prismaService: PrismaService) {}
|
||||
|
||||
@UseFilters(ExceptionFilter)
|
||||
@Query(() => [User], {
|
||||
nullable: false,
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user