Skip to content

Commit

Permalink
docs(api): Add swagger docs of API key controller (#167)
Browse files Browse the repository at this point in the history
  • Loading branch information
rajdip-b authored Mar 11, 2024
1 parent fd59522 commit 2910476
Show file tree
Hide file tree
Showing 5 changed files with 172 additions and 43 deletions.
2 changes: 1 addition & 1 deletion apps/api/src/api-key/api-key.e2e.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ describe('Api Key Role Controller Tests', () => {
}
})

expect(response.statusCode).toBe(200)
expect(response.statusCode).toBe(204)
})

afterAll(async () => {
Expand Down
147 changes: 146 additions & 1 deletion apps/api/src/api-key/controller/api-key.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
Controller,
Delete,
Get,
HttpCode,
Param,
Post,
Put,
Expand All @@ -14,19 +15,81 @@ import { CreateApiKey } from '../dto/create.api-key/create.api-key'
import { UpdateApiKey } from '../dto/update.api-key/update.api-key'
import { Authority, User } from '@prisma/client'
import { RequiredApiKeyAuthorities } from '../../decorators/required-api-key-authorities.decorator'
import {
ApiBearerAuth,
ApiCreatedResponse,
ApiForbiddenResponse,
ApiNoContentResponse,
ApiOkResponse,
ApiOperation,
ApiParam,
ApiQuery,
ApiSecurity,
ApiTags
} from '@nestjs/swagger'
import { invalidAuthenticationResponse } from '../../common/static'

const baseProperties = {
id: { type: 'string' },
name: { type: 'string' },
expiresAt: { type: 'string' },
authorities: { type: 'array', items: { type: 'string' } },
createdAt: { type: 'string' },
updatedAt: { type: 'string' }
}

const apiKeySchemaWithValue = {
type: 'object',
properties: {
...baseProperties,
value: { type: 'string' }
}
}

const apiKeySchema = {
type: 'object',
properties: baseProperties
}

@Controller('api-key')
@ApiBearerAuth()
@ApiSecurity('api_key')
@ApiTags('API Key Controller')
export class ApiKeyController {
constructor(private readonly apiKeyService: ApiKeyService) {}

@Post()
@RequiredApiKeyAuthorities(Authority.CREATE_API_KEY)
@ApiOperation({
summary: 'Create API key',
description: 'This endpoint creates a new API key'
})
@ApiCreatedResponse({
schema: apiKeySchemaWithValue,
description: 'API key created successfully'
})
@ApiForbiddenResponse(invalidAuthenticationResponse)
async createApiKey(@CurrentUser() user: User, @Body() dto: CreateApiKey) {
return this.apiKeyService.createApiKey(user, dto)
}

@Put(':id')
@RequiredApiKeyAuthorities(Authority.UPDATE_API_KEY)
@ApiOperation({
summary: 'Update API key',
description: 'This endpoint updates an existing API key'
})
@ApiParam({
name: 'id',
description: 'API key ID',
required: true,
schema: { type: 'string' }
})
@ApiOkResponse({
schema: apiKeySchema,
description: 'API key updated successfully'
})
@ApiForbiddenResponse(invalidAuthenticationResponse)
async updateApiKey(
@CurrentUser() user: User,
@Body() dto: UpdateApiKey,
Expand All @@ -37,21 +100,103 @@ export class ApiKeyController {

@Delete(':id')
@RequiredApiKeyAuthorities(Authority.DELETE_API_KEY)
@HttpCode(204)
@ApiOperation({
summary: 'Delete API key',
description: 'This endpoint deletes an existing API key'
})
@ApiParam({
name: 'id',
description: 'API key ID',
required: true,
schema: { type: 'string' }
})
@ApiNoContentResponse({
description: 'API key deleted successfully'
})
@ApiForbiddenResponse(invalidAuthenticationResponse)
async deleteApiKey(@CurrentUser() user: User, @Param('id') id: string) {
return this.apiKeyService.deleteApiKey(user, id)
}

@Get(':id')
@RequiredApiKeyAuthorities(Authority.READ_API_KEY)
@ApiOperation({
summary: 'Get API key',
description: 'This endpoint returns the details of an API key'
})
@ApiParam({
name: 'id',
description: 'API key ID',
required: true,
schema: { type: 'string' }
})
@ApiOkResponse({
schema: apiKeySchemaWithValue,
description: 'API key details'
})
@ApiForbiddenResponse(invalidAuthenticationResponse)
async getApiKey(@CurrentUser() user: User, @Param('id') id: string) {
return this.apiKeyService.getApiKeyById(user, id)
}

@Get('all')
@RequiredApiKeyAuthorities(Authority.READ_API_KEY)
@ApiOperation({
summary: 'Get all API keys',
description: 'This endpoint returns all API keys of the user'
})
@ApiQuery({
name: 'page',
description: 'Page number',
required: false,
type: Number,
example: 1,
allowEmptyValue: false
})
@ApiQuery({
name: 'limit',
description: 'Number of items per page',
required: false,
type: Number,
example: 10,
allowEmptyValue: false
})
@ApiQuery({
name: 'sort',
description: 'Sort by field',
required: false,
type: String,
example: 'name',
allowEmptyValue: false
})
@ApiQuery({
name: 'order',
description: 'Sort order',
required: false,
type: String,
example: 'asc',
allowEmptyValue: false
})
@ApiQuery({
name: 'search',
description: 'Search by name',
required: false,
type: String,
example: 'My API Key',
allowEmptyValue: false
})
@ApiOkResponse({
schema: {
type: 'array',
items: apiKeySchema
},
description: 'API keys'
})
@ApiForbiddenResponse(invalidAuthenticationResponse)
async getApiKeysOfUser(
@CurrentUser() user: User,
@Query('page') page: number = 1,
@Query('page') page: number = 0,
@Query('limit') limit: number = 10,
@Query('sort') sort: string = 'name',
@Query('order') order: string = 'asc',
Expand Down
24 changes: 24 additions & 0 deletions apps/api/src/api-key/dto/create.api-key/create.api-key.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,39 @@
import { ApiProperty } from '@nestjs/swagger'
import { ApiKey, Authority } from '@prisma/client'
import { IsArray, IsOptional, IsString } from 'class-validator'

export class CreateApiKey {
@IsString()
@ApiProperty({
name: 'name',
description: 'Name of the API key',
required: true,
type: String,
example: 'My API Key'
})
name: ApiKey['name']

@IsString()
@IsOptional()
@ApiProperty({
name: 'expiresAfter',
description: 'API key expiration time in hours',
required: false,
type: String,
example: '24',
default: 'never'
})
expiresAfter?: '24' | '168' | '720' | '8760' | 'never' = 'never'

@IsArray()
@IsOptional()
@ApiProperty({
name: 'authorities',
description: 'API key authorities',
required: false,
type: [String],
example: ['READ_SELF', 'UPDATE_SELF'],
default: []
})
authorities?: Authority[] = []
}
2 changes: 1 addition & 1 deletion apps/api/src/api-key/service/api-key.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ export class ApiKeyService {
contains: search
}
},
skip: (page - 1) * limit,
skip: page * limit,
take: limit,
orderBy: {
[sort]: order
Expand Down
40 changes: 0 additions & 40 deletions apps/api/src/common/mock-data/users.ts

This file was deleted.

0 comments on commit 2910476

Please sign in to comment.