Skip to content
This repository has been archived by the owner on Apr 19, 2023. It is now read-only.

Commit

Permalink
✨ Add audit logs module
Browse files Browse the repository at this point in the history
  • Loading branch information
AnandChowdhary committed Nov 7, 2020
1 parent 5dfc1ca commit 049e3eb
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { RawBodyMiddleware } from './middleware/raw-body.middleware';
import { AccessTokensModule } from './modules/access-tokens/access-tokens.module';
import { ApiKeysModule } from './modules/api-keys/api-keys.module';
import { ApprovedSubnetsModule } from './modules/approved-subnets/approved-subnets.module';
import { AuditLogsModule } from './modules/audit-logs/audit-logs.module';
import { AuthModule } from './modules/auth/auth.module';
import { JwtAuthGuard } from './modules/auth/jwt-auth.guard';
import { ScopesGuard } from './modules/auth/scope.guard';
Expand Down Expand Up @@ -58,6 +59,7 @@ import { UsersModule } from './modules/users/users.module';
GeolocationModule,
MembershipsModule,
StripeModule,
AuditLogsModule,
],
providers: [
{
Expand Down
1 change: 1 addition & 0 deletions src/modules/api-keys/api-keys.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ export class ApiKeysService {
] = `Delete payment method: ${source.id}`;
}

scopes[`group-${groupId}:read-audit-log-*`] = 'Read audit logs';
return scopes;
}
}
42 changes: 42 additions & 0 deletions src/modules/audit-logs/audit-logs.controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { Controller, Get, Param, ParseIntPipe, Query } from '@nestjs/common';
import { auditLogs } from '@prisma/client';
import { CursorPipe } from '../../pipes/cursor.pipe';
import { OptionalIntPipe } from '../../pipes/optional-int.pipe';
import { OrderByPipe } from '../../pipes/order-by.pipe';
import { WherePipe } from '../../pipes/where.pipe';
import { Scopes } from '../auth/scope.decorator';
import { Expose } from '../prisma/prisma.interface';
import { AuditLogsService } from './audit-logs.service';

@Controller('groups/:groupId/audit-logs')
export class AuditLogController {
constructor(private auditLogsService: AuditLogsService) {}

@Get()
@Scopes('group-{groupId}:read-audit-log-*')
async getAll(
@Param('groupId', ParseIntPipe) groupId: number,
@Query('skip', OptionalIntPipe) skip?: number,
@Query('take', OptionalIntPipe) take?: number,
@Query('cursor', CursorPipe) cursor?: Record<string, number | string>,
@Query('where', WherePipe) where?: Record<string, number | string>,
@Query('orderBy', OrderByPipe) orderBy?: Record<string, 'asc' | 'desc'>,
): Promise<Expose<auditLogs>[]> {
return this.auditLogsService.getAuditLogs(groupId, {
skip,
take,
orderBy,
cursor,
where,
});
}

@Get(':id')
@Scopes('group-{groupId}:read-audit-log-{id}')
async get(
@Param('groupId', ParseIntPipe) groupId: number,
@Param('id', ParseIntPipe) id: number,
): Promise<Expose<auditLogs>> {
return this.auditLogsService.getAuditLog(groupId, Number(id));
}
}
11 changes: 11 additions & 0 deletions src/modules/audit-logs/audit-logs.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { Module } from '@nestjs/common';
import { PrismaModule } from '../prisma/prisma.module';
import { AuditLogController } from './audit-logs.controller';
import { AuditLogsService } from './audit-logs.service';

@Module({
imports: [PrismaModule],
controllers: [AuditLogController],
providers: [AuditLogsService],
})
export class AuditLogsModule {}
50 changes: 50 additions & 0 deletions src/modules/audit-logs/audit-logs.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import {
HttpException,
HttpStatus,
Injectable,
UnauthorizedException,
} from '@nestjs/common';
import {
auditLogs,
auditLogsOrderByInput,
auditLogsWhereInput,
auditLogsWhereUniqueInput,
} from '@prisma/client';
import { Expose } from '../prisma/prisma.interface';
import { PrismaService } from '../prisma/prisma.service';

@Injectable()
export class AuditLogsService {
constructor(private prisma: PrismaService) {}

async getAuditLogs(
groupId: number,
params: {
skip?: number;
take?: number;
cursor?: auditLogsWhereUniqueInput;
where?: auditLogsWhereInput;
orderBy?: auditLogsOrderByInput;
},
): Promise<Expose<auditLogs>[]> {
const { skip, take, cursor, where, orderBy } = params;
const auditLogs = await this.prisma.auditLogs.findMany({
skip,
take,
cursor,
where: { ...where, group: { id: groupId } },
orderBy,
});
return auditLogs.map((group) => this.prisma.expose<auditLogs>(group));
}

async getAuditLog(groupId: number, id: number): Promise<Expose<auditLogs>> {
const auditLog = await this.prisma.auditLogs.findOne({
where: { id },
});
if (!auditLog)
throw new HttpException('AuditLog not found', HttpStatus.NOT_FOUND);
if (auditLog.groupId !== groupId) throw new UnauthorizedException();
return this.prisma.expose<auditLogs>(auditLog);
}
}

0 comments on commit 049e3eb

Please sign in to comment.