Skip to content

Commit 81440a1

Browse files
api key controller, dto, and readme update
1 parent 4cc43ba commit 81440a1

File tree

10 files changed

+80
-71
lines changed

10 files changed

+80
-71
lines changed

README.md

Lines changed: 37 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,17 @@
1515

1616
# ACK NestJs Boilerplate 🔥 🚀
1717

18-
> Amazon web service will be the cloud provider. This is why this project is focused on AWS features.
18+
> This repo will representative of authentication service and authorization service
1919
2020
[ACK NestJs][ack] is a [Http NestJs v9.x][ref-nestjs] boilerplate. Best uses for backend service.
2121

2222
*You can [request feature][ack-issues] or [report bug][ack-issues] with following this link*
2323

2424
## Other Repo
2525

26-
* [Mongoose Mini Version][ack-mongoose] : Mini version
27-
* [Typeorm Integration][ack-typeorm] : Typeorm integration
28-
* [Kafka Integration][ack-kafka] : Apache Kafka integration
26+
* [Mini Version][ack-mongoose] : Mini version
27+
* [Typeorm Integration][ack-typeorm] : Typeorm integration `(Outdated)`
28+
* [Kafka Integration][ack-kafka] : Hybrid Between HTTP and Microservice (Apache Kafka Integration)
2929

3030
## Table of contents
3131

@@ -56,40 +56,17 @@
5656

5757
## Important
5858

59-
> If you want to implement `database transactions`, you must run MongoDB as a `replication set`.
60-
61-
If you change the environment value of `APP_ENV` to `production`, that will trigger.
62-
63-
1. CorsMiddleware will implement `src/configs/middleware.config.ts`.Otherwise is `*`.
64-
2. Documentation will `disable`.
59+
* The features will replated with AWS Features
60+
* If you want to implement `database transactions`, you must run MongoDB as a `replication set`.
61+
* If you change the environment value of `APP_ENV` to `production`, that will trigger.
62+
1. CorsMiddleware will implement `src/configs/middleware.config.ts`.
63+
2. Documentation will `disable`.
6564

6665
## Next Todo
6766

6867
Next development
6968

70-
* [x] Implement Repository Design Pattern / Data Access Object Design Pattern
71-
* [x] Swagger for API Documentation
72-
* [x] Mongo Repository soft delete
73-
* [x] Make it simple
74-
* [x] Encrypt jwt payload
75-
* [x] Optimize Unit Testing
76-
* [x] Make serverless separate repo
77-
* [x] Optimize Swagger
78-
* [x] Remove enum endpoint
79-
* [x] Permission group fixed
80-
* [x] Reduce the payload of access token
81-
* [x] Update authorization mechanism, permission token on `x-permission-token`
82-
* [x] Update package, cors setting, check all interfaces, husky trigger switch to on and check test
83-
* [x] AuthApiKey mechanism
84-
* [x] AuthApi Controller
85-
* [x] AuthApi Get, Active, Inactive Endpoint
86-
* [x] AuthApi Create (Random Key), and Reset Secret Endpoint
87-
* [x] AuthApi Controller Test E2E
88-
* [x] Fix automation testing
89-
* [x] Pagination move from decorator to service pagination -> make pipe transformer -> wrap into group decorator ResponsePaging
90-
* [x] Check Swagger for pagination
91-
* [x] ApiKey add startDate and endDate
92-
* [x] Make docker port expose be difference with port app
69+
* Validation guard change to pipe
9370
* [ ] SSO
9471
* [ ] Google
9572
* [ ] Apple
@@ -122,28 +99,29 @@ Describes which version.
12299
* Component based folder structure
123100
* Repository Design Pattern or Data Access Layer Design Pattern
124101
* Support Microservice Architecture, Serverless Architecture, Clean Architecture, and/or Hexagonal Architecture
102+
* Follow Community Guide Line
125103
* Follow The Twelve-Factor App
126104
* Adopt SOLID and KISS principle
127105

128106
## Features
129107

108+
### Main Features
109+
130110
* NestJs v9.x 🥳
131111
* Typescript 🚀
132112
* Production ready 🔥
133113
* Repository Design Pattern
134114
* Swagger included
135-
* Authentication and authorization (`JWT`, `API Key`) 💪
136-
* Role management system
137-
* Storage integration with `AwsS3`
138-
* Upload file `single` and `multipart` to AwsS3
115+
* Authentication (`Access Token`, `Refresh Token`, `API Key`)
116+
* Authorization, Role and Permission Management (`PermissionToken`)
139117
* Support multi-language `i18n` 🗣
140118
* Request validation with `class-validation`
141119
* Serialization with `class-transformer`
142120
* Url Versioning
143121
* Server Side Pagination, there have 3 of types
144122
* Import and export data with excel by using `decorator`
145123

146-
## Database
124+
### Database
147125

148126
* MongoDB integrate by using [mongoose][ref-mongoose] 🎉
149127
* Multi Database
@@ -171,6 +149,11 @@ Describes which version.
171149
* Setting from database 🗿
172150
* Maintenance mode on / off from database 🐤
173151

152+
### Third Party Integration
153+
154+
* Storage integration with `AwsS3`
155+
* Upload file `single` and `multipart` to AwsS3
156+
174157
### Others
175158

176159
* Support Docker Installation
@@ -215,7 +198,8 @@ Full structure of module
215198
├── pipes
216199
├── repository
217200
├── entities // database entities
218-
└── repositories // database repositories
201+
├── repositories // database repositories
202+
└── module1.repository.module.ts
219203
├── serializations // response serialization
220204
├── services
221205
├── tasks // task for cron job
@@ -252,9 +236,11 @@ export interface IResponseMetadata {
252236
Default response for the response
253237

254238
```ts
255-
export interface IResponse {
239+
export class ResponseDefaultSerialization {
240+
statusCode: number;
241+
message: string;
256242
metadata?: IResponseMetadata;
257-
[key: string]: any;
243+
data?: Record<string, any>;
258244
}
259245
```
260246

@@ -263,7 +249,9 @@ export interface IResponse {
263249
Default response for pagination.
264250

265251
```ts
266-
export interface IResponsePaging {
252+
export class ResponsePagingSerialization {
253+
statusCode: number;
254+
message: string;
267255
totalData: number;
268256
totalPage?: number;
269257
currentPage?: number;
@@ -301,8 +289,6 @@ The recommended version is the LTS version for every tool and package.
301289
2. [MongoDB][ref-mongodb]
302290
3. [Yarn][ref-yarn]
303291
4. [Git][ref-git]
304-
5. [Docker][ref-docker]
305-
6. [Docker-Compose][ref-dockercompose]
306292

307293
### Clone Repo
308294

@@ -390,6 +376,13 @@ yarn start:dev
390376

391377
### Run Project with Docker
392378

379+
For docker installation, we need more tools to be installed in our instance.
380+
381+
1. [Docker][ref-docker]
382+
2. [Docker-Compose][ref-dockercompose]
383+
384+
Then run
385+
393386
```bash
394387
docker-compose up -d
395388
```

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "ack-nestjs-boilerplate",
3-
"version": "4.1.2",
3+
"version": "4.1.3",
44
"description": "Ack NestJs Boilerplate",
55
"repository": {
66
"type": "git",

src/common/api-key/controllers/api-key.admin.controller.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ import {
3535
import { ApiKeyCreateDto } from 'src/common/api-key/dtos/api-key.create.dto';
3636
import { ApiKeyRequestDto } from 'src/common/api-key/dtos/api-key.request.dto';
3737
import { ApiKeyUpdateDateDto } from 'src/common/api-key/dtos/api-key.update-date.dto';
38-
import { ApiKeyUpdateNameDto } from 'src/common/api-key/dtos/api-key.update-name.dto';
38+
import { ApiKeyUpdateDto } from 'src/common/api-key/dtos/api-key.update.dto';
3939
import { IApiKeyEntity } from 'src/common/api-key/interfaces/api-key.interface';
4040
import { ApiKeyEntity } from 'src/common/api-key/repository/entities/api-key.entity';
4141
import { ApiKeyCreateSerialization } from 'src/common/api-key/serializations/api-key.create.serialization';
@@ -262,11 +262,11 @@ export class ApiKeyAdminController {
262262
@AuthJwtAdminAccessProtected()
263263
@Put('/update/:apiKey')
264264
async updateName(
265-
@Body() body: ApiKeyUpdateNameDto,
265+
@Body() body: ApiKeyUpdateDto,
266266
@GetApiKey() apiKey: ApiKeyEntity
267267
): Promise<IResponse> {
268268
try {
269-
await this.apiKeyService.updateName(apiKey._id, body);
269+
await this.apiKeyService.update(apiKey._id, body);
270270
} catch (err: any) {
271271
throw new InternalServerErrorException({
272272
statusCode: ENUM_ERROR_STATUS_CODE_ERROR.ERROR_UNKNOWN,

src/common/api-key/dtos/api-key.create.dto.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@ import {
77
IsOptional,
88
IsString,
99
MaxLength,
10+
MinLength,
1011
} from 'class-validator';
12+
import { MinGreaterThanEqual } from 'src/common/request/validations/request.min-greater-than-equal.validation';
13+
import { MinDateToday } from 'src/common/request/validations/request.min-date-today.validation';
1114

1215
export class ApiKeyCreateDto {
1316
@ApiProperty({
@@ -29,6 +32,7 @@ export class ApiKeyCreateDto {
2932
@IsOptional()
3033
@Type(() => Date)
3134
@IsDate()
35+
@MinDateToday()
3236
startDate?: Date;
3337

3438
@ApiProperty({
@@ -40,6 +44,7 @@ export class ApiKeyCreateDto {
4044
@IsOptional()
4145
@Type(() => Date)
4246
@IsDate()
47+
@MinGreaterThanEqual('startDate')
4348
endDate?: Date;
4449

4550
@ApiProperty({
@@ -49,6 +54,7 @@ export class ApiKeyCreateDto {
4954
})
5055
@IsOptional()
5156
@IsString()
57+
@MinLength(1)
5258
@MaxLength(100)
5359
description?: string;
5460
}

src/common/api-key/dtos/api-key.update-date.dto.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,31 @@ import { ApiProperty } from '@nestjs/swagger';
22
import { faker } from '@faker-js/faker';
33
import { IsDate, IsNotEmpty } from 'class-validator';
44
import { Type } from 'class-transformer';
5+
import { MinGreaterThanEqual } from 'src/common/request/validations/request.min-greater-than-equal.validation';
6+
import { MinDateToday } from 'src/common/request/validations/request.min-date-today.validation';
57

68
export class ApiKeyUpdateDateDto {
79
@ApiProperty({
810
description: 'Api Key start date',
911
example: faker.date.recent(),
10-
required: true,
11-
nullable: false,
12+
required: false,
13+
nullable: true,
1214
})
1315
@IsNotEmpty()
1416
@Type(() => Date)
1517
@IsDate()
18+
@MinDateToday()
1619
startDate: Date;
1720

1821
@ApiProperty({
1922
description: 'Api Key end date',
2023
example: faker.date.recent(),
21-
required: true,
22-
nullable: false,
24+
required: false,
25+
nullable: true,
2326
})
2427
@IsNotEmpty()
2528
@Type(() => Date)
2629
@IsDate()
30+
@MinGreaterThanEqual('startDate')
2731
endDate: Date;
2832
}

src/common/api-key/dtos/api-key.update-name.dto.ts

Lines changed: 0 additions & 4 deletions
This file was deleted.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { PickType } from '@nestjs/swagger';
2+
import { ApiKeyCreateDto } from './api-key.create.dto';
3+
4+
export class ApiKeyUpdateDto extends PickType(ApiKeyCreateDto, [
5+
'name',
6+
'description',
7+
] as const) {}

src/common/api-key/interfaces/api-key.service.interface.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import {
33
ApiKeyCreateRawDto,
44
} from 'src/common/api-key/dtos/api-key.create.dto';
55
import { ApiKeyUpdateDateDto } from 'src/common/api-key/dtos/api-key.update-date.dto';
6-
import { ApiKeyUpdateNameDto } from 'src/common/api-key/dtos/api-key.update-name.dto';
6+
import { ApiKeyUpdateDto } from 'src/common/api-key/dtos/api-key.update.dto';
77
import { IApiKeyEntity } from 'src/common/api-key/interfaces/api-key.interface';
88
import { ApiKeyEntity } from 'src/common/api-key/repository/entities/api-key.entity';
99
import {
@@ -60,9 +60,9 @@ export interface IApiKeyService {
6060
options?: IDatabaseCreateOptions
6161
): Promise<IApiKeyEntity>;
6262

63-
updateName(
63+
update(
6464
_id: string,
65-
data: ApiKeyUpdateNameDto,
65+
data: ApiKeyUpdateDto,
6666
options?: IDatabaseOptions
6767
): Promise<ApiKeyEntity>;
6868

src/common/api-key/services/api-key.service.ts

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import {
2020
ApiKeyCreateDto,
2121
ApiKeyCreateRawDto,
2222
} from 'src/common/api-key/dtos/api-key.create.dto';
23-
import { ApiKeyUpdateNameDto } from 'src/common/api-key/dtos/api-key.update-name.dto';
23+
import { ApiKeyUpdateDto } from 'src/common/api-key/dtos/api-key.update.dto';
2424
import { ApiKeyUpdateDateDto } from 'src/common/api-key/dtos/api-key.update-date.dto';
2525
import { HelperDateService } from 'src/common/helper/services/helper.date.service';
2626

@@ -161,8 +161,8 @@ export class ApiKeyService implements IApiKeyService {
161161
dto.isActive = true;
162162

163163
if (startDate && endDate) {
164-
dto.startDate = startDate;
165-
dto.endDate = endDate;
164+
dto.startDate = this.helperDateService.startOfDay(startDate);
165+
dto.endDate = this.helperDateService.endOfDay(endDate);
166166
}
167167

168168
const created: ApiKeyEntity =
@@ -171,12 +171,12 @@ export class ApiKeyService implements IApiKeyService {
171171
return { ...created, secret };
172172
}
173173

174-
async updateName(
174+
async update(
175175
_id: string,
176-
data: ApiKeyUpdateNameDto,
176+
data: ApiKeyUpdateDto,
177177
options?: IDatabaseOptions
178178
): Promise<ApiKeyEntity> {
179-
return this.apiKeyRepository.updateOneById<ApiKeyUpdateNameDto>(
179+
return this.apiKeyRepository.updateOneById<ApiKeyUpdateDto>(
180180
_id,
181181
data,
182182
options
@@ -185,12 +185,15 @@ export class ApiKeyService implements IApiKeyService {
185185

186186
async updateDate(
187187
_id: string,
188-
data: ApiKeyUpdateDateDto,
188+
{ startDate, endDate }: ApiKeyUpdateDateDto,
189189
options?: IDatabaseOptions
190190
): Promise<ApiKeyEntity> {
191191
return this.apiKeyRepository.updateOneById<ApiKeyUpdateDateDto>(
192192
_id,
193-
data,
193+
{
194+
startDate: this.helperDateService.startOfDay(startDate),
195+
endDate: this.helperDateService.endOfDay(endDate),
196+
},
194197
options
195198
);
196199
}

test/unit/api-key/api-key.service.spec.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -331,17 +331,17 @@ describe('ApiKeyService', () => {
331331
});
332332
});
333333

334-
describe('updateName', () => {
334+
describe('update', () => {
335335
it('should return a updated apikey', async () => {
336336
const nameUpdate = faker.random.alphaNumeric(10);
337-
const result: ApiKeyEntity = await apiKeyService.updateName(
337+
const result: ApiKeyEntity = await apiKeyService.update(
338338
apiKey._id,
339339
{
340340
name: nameUpdate,
341341
description: faker.random.alphaNumeric(20),
342342
}
343343
);
344-
jest.spyOn(apiKeyService, 'updateName').mockReturnValueOnce(
344+
jest.spyOn(apiKeyService, 'update').mockReturnValueOnce(
345345
result as any
346346
);
347347

@@ -360,7 +360,7 @@ describe('ApiKeyService', () => {
360360
endDate,
361361
}
362362
);
363-
jest.spyOn(apiKeyService, 'updateName').mockReturnValueOnce(
363+
jest.spyOn(apiKeyService, 'updateDate').mockReturnValueOnce(
364364
result as any
365365
);
366366

0 commit comments

Comments
 (0)