Skip to content

Commit 92e4d3f

Browse files
committed
Merge branch '1-schematics' of https://github.com/Libertech-FR/teaket into 1-schematics
2 parents facdd2c + d9cc7b9 commit 92e4d3f

File tree

12 files changed

+354
-57
lines changed

12 files changed

+354
-57
lines changed
Lines changed: 63 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,68 @@
1-
import { PartialType } from '@nestjs/swagger'
1+
import { ApiProperty, PartialType } from '@nestjs/swagger'
2+
import { IsString, IsNotEmpty, ValidateNested, IsEmail, IsBoolean, IsArray, IsMongoId } from 'class-validator'
3+
import { Type } from 'class-transformer'
4+
import { StatePartDTO } from './parts/state.part.dto'
5+
import { SecurityPartDTO } from './parts/security.part.dto'
6+
import { AbstractCustomFieldsDto } from '~/_common/abstracts/dto/abstract.custom-fields.dto'
27

3-
export class IdentitiesCreateDto {
8+
export class IdentitiesCreateDto extends AbstractCustomFieldsDto {
9+
@IsMongoId()
10+
@IsNotEmpty()
11+
@ApiProperty()
12+
public entityId: string
413

14+
@IsString()
15+
@IsNotEmpty()
16+
@ApiProperty()
17+
public username: string
18+
19+
@IsString()
20+
@ApiProperty()
21+
public displayName?: string
22+
23+
@IsEmail()
24+
@IsNotEmpty()
25+
@ApiProperty()
26+
public email: string
27+
28+
@IsString()
29+
@IsNotEmpty()
30+
@ApiProperty()
31+
public password: string
32+
33+
@IsString()
34+
@ApiProperty()
35+
public thirdPartyAuth?: string
36+
37+
@ValidateNested()
38+
@Type(() => StatePartDTO)
39+
@IsNotEmpty()
40+
@ApiProperty()
41+
public state: StatePartDTO
42+
43+
@IsString()
44+
@ApiProperty()
45+
public baseURL: string
46+
47+
@IsArray()
48+
@IsString({ each: true })
49+
@ApiProperty()
50+
public roles: string[]
51+
52+
@ValidateNested()
53+
@Type(() => SecurityPartDTO)
54+
@ApiProperty()
55+
public security: SecurityPartDTO
56+
57+
@IsBoolean()
58+
@ApiProperty()
59+
public hidden: boolean
560
}
661

7-
export class IdentitiesUpdateDto extends PartialType(IdentitiesCreateDto) {
62+
export class IdentitiesDto extends IdentitiesCreateDto {
63+
@IsMongoId()
64+
@ApiProperty()
65+
public _id: string
866
}
67+
68+
export class IdentitiesUpdateDto extends PartialType(IdentitiesCreateDto) {}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { ApiProperty } from '@nestjs/swagger'
2+
import { IsString, IsArray, IsBoolean } from 'class-validator'
3+
4+
export class SecurityPartDTO {
5+
@IsArray()
6+
@IsString({ each: true })
7+
@ApiProperty()
8+
public oldPasswords?: string[]
9+
10+
@IsString()
11+
@ApiProperty()
12+
public otpKey?: string
13+
14+
@IsArray()
15+
@IsString({ each: true })
16+
@ApiProperty()
17+
public u2fKey?: string[]
18+
19+
@IsArray()
20+
@IsString({ each: true })
21+
@ApiProperty()
22+
public allowedNetworks?: string[]
23+
24+
@IsBoolean()
25+
@ApiProperty()
26+
public changePwdAtNextLogin: boolean
27+
28+
@IsBoolean()
29+
@ApiProperty()
30+
public secretKey?: string
31+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { ApiProperty } from '@nestjs/swagger'
2+
import { IsString, IsNotEmpty, IsNumber, IsDate } from 'class-validator'
3+
4+
export class StatePartDTO {
5+
@IsNumber()
6+
@IsNotEmpty()
7+
@ApiProperty()
8+
public current: number
9+
10+
@IsDate()
11+
@ApiProperty()
12+
public lastChangedAt?: Date
13+
14+
@IsDate()
15+
@ApiProperty()
16+
public suspendedAt?: Date
17+
18+
@IsDate()
19+
@ApiProperty()
20+
public suspendedUntil?: Date
21+
22+
@IsString()
23+
@ApiProperty()
24+
public suspendedReason?: string
25+
}

service/src/core/identities/_schemas/identities.schema.ts

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -83,10 +83,9 @@ export class Identities extends AbstractSchema {
8383
public customFields?: { [key: string]: any }
8484
}
8585

86-
export const IdentitiesSchema = SchemaFactory.createForClass(Identities)
87-
.pre('save', function (this: Identities, next: () => void): void {
88-
if (this.isNew) {
89-
this.displayName = this.displayName || this.username
90-
}
91-
next()
92-
})
86+
export const IdentitiesSchema = SchemaFactory.createForClass(Identities).pre('save', function (this: Identities, next: () => void): void {
87+
if (this.isNew) {
88+
this.displayName = this.displayName || this.username
89+
}
90+
next()
91+
})
Lines changed: 73 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,82 @@
1-
import { Controller } from '@nestjs/common'
1+
import { Body, Controller, Delete, Get, HttpStatus, Param, Patch, Post, Res } from '@nestjs/common'
22
import { IdentitiesService } from './identities.service'
33
import { AbstractController } from '~/_common/abstracts/abstract.controller'
4-
import { ApiTags } from '@nestjs/swagger'
4+
import { ApiParam, ApiTags } from '@nestjs/swagger'
5+
import { PartialProjectionType } from '~/_common/types/partial-projection.type'
6+
import { SearchFilterSchema, FilterSchema, SearchFilterOptions, FilterOptions, ObjectIdValidationPipe } from '@streamkits/nestjs_module_scrud'
7+
import { Types } from 'mongoose'
8+
import { ApiCreateDecorator } from '~/_common/decorators/api-create.decorator'
9+
import { ApiDeletedResponseDecorator } from '~/_common/decorators/api-deleted-response.decorator'
10+
import { ApiPaginatedDecorator } from '~/_common/decorators/api-paginated.decorator'
11+
import { ApiReadResponseDecorator } from '~/_common/decorators/api-read-response.decorator'
12+
import { ApiUpdateDecorator } from '~/_common/decorators/api-update.decorator'
13+
import { PickProjectionHelper } from '~/_common/helpers/pick-projection.helper'
14+
import { IdentitiesCreateDto, IdentitiesDto, IdentitiesUpdateDto } from '../identities/_dto/identities.dto'
15+
import { Response } from 'express'
516

617
@ApiTags('core')
718
@Controller('identities')
819
export class IdentitiesController extends AbstractController {
9-
constructor(private readonly service: IdentitiesService) {
20+
protected static readonly projection: PartialProjectionType<IdentitiesDto> = {
21+
username: 1,
22+
}
23+
24+
constructor(private readonly _service: IdentitiesService) {
1025
super()
1126
}
27+
28+
@Post()
29+
@ApiCreateDecorator(IdentitiesCreateDto, IdentitiesDto)
30+
public async create(@Res() res: Response, @Body() body: IdentitiesCreateDto): Promise<Response> {
31+
const data = await this._service.create(body)
32+
return res.status(HttpStatus.CREATED).json({
33+
statusCode: HttpStatus.CREATED,
34+
data,
35+
})
36+
}
37+
38+
@Get()
39+
@ApiPaginatedDecorator(PickProjectionHelper(IdentitiesDto, IdentitiesController.projection))
40+
public async search(@Res() res: Response, @SearchFilterSchema() searchFilterSchema: FilterSchema, @SearchFilterOptions() searchFilterOptions: FilterOptions): Promise<Response> {
41+
//TODO: search tree by parentId
42+
const [data, total] = await this._service.findAndCount(searchFilterSchema, IdentitiesController.projection, searchFilterOptions)
43+
return res.status(HttpStatus.OK).json({
44+
statusCode: HttpStatus.OK,
45+
total,
46+
data,
47+
})
48+
}
49+
50+
@Get(':_id([0-9a-fA-F]{24})')
51+
@ApiParam({ name: '_id', type: String })
52+
@ApiReadResponseDecorator(IdentitiesDto)
53+
public async read(@Param('_id', ObjectIdValidationPipe) _id: Types.ObjectId, @Res() res: Response): Promise<Response> {
54+
const data = await this._service.findById(_id)
55+
return res.status(HttpStatus.OK).json({
56+
statusCode: HttpStatus.OK,
57+
data,
58+
})
59+
}
60+
61+
@Patch(':_id([0-9a-fA-F]{24})')
62+
@ApiParam({ name: '_id', type: String })
63+
@ApiUpdateDecorator(IdentitiesUpdateDto, IdentitiesDto)
64+
public async update(@Param('_id', ObjectIdValidationPipe) _id: Types.ObjectId, @Body() body: IdentitiesUpdateDto, @Res() res: Response): Promise<Response> {
65+
const data = await this._service.update(_id, body)
66+
return res.status(HttpStatus.OK).json({
67+
statusCode: HttpStatus.OK,
68+
data,
69+
})
70+
}
71+
72+
@Delete(':_id([0-9a-fA-F]{24})')
73+
@ApiParam({ name: '_id', type: String })
74+
@ApiDeletedResponseDecorator(IdentitiesDto)
75+
public async remove(@Param('_id', ObjectIdValidationPipe) _id: Types.ObjectId, @Res() res: Response): Promise<Response> {
76+
const data = await this._service.delete(_id)
77+
return res.status(HttpStatus.OK).json({
78+
statusCode: HttpStatus.OK,
79+
data,
80+
})
81+
}
1282
}

service/src/core/identities/identities.service.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,11 @@ import { Injectable } from '@nestjs/common'
22
import { InjectModel } from '@nestjs/mongoose'
33
import { Identities } from '~/core/identities/_schemas/identities.schema'
44
import { Model } from 'mongoose'
5-
import { AbstractService } from '~/_common/abstracts/abstract.service'
5+
import { AbstractServiceSchema } from '~/_common/abstracts/abstract.service.schema'
66

77
@Injectable()
8-
export class IdentitiesService extends AbstractService {
9-
constructor(@InjectModel(Identities.name) protected model: Model<Identities>,
10-
) {
8+
export class IdentitiesService extends AbstractServiceSchema {
9+
constructor(@InjectModel(Identities.name) protected _model: Model<Identities>) {
1110
super()
1211
}
1312
}
Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,28 @@
1-
import { PartialType } from "@nestjs/swagger"
1+
import { ApiProperty, PartialType } from '@nestjs/swagger'
2+
import { IsString, IsNotEmpty, IsObject, IsOptional, ValidateNested, IsMongoId } from 'class-validator'
23

34
export class PreferencesCreateDto {
5+
@IsString()
6+
@IsNotEmpty()
7+
@ApiProperty()
8+
public name: string
49

10+
@IsMongoId()
11+
@IsOptional()
12+
@ApiProperty()
13+
public entityId?: string
14+
15+
@IsObject()
16+
@IsOptional()
17+
@ValidateNested({ each: true })
18+
@ApiProperty()
19+
public data?: { [key: string]: any }
20+
}
21+
22+
export class PreferencesDto extends PreferencesCreateDto {
23+
@IsMongoId()
24+
@ApiProperty()
25+
public _id: string
526
}
627

7-
export class PreferencesUpdateDto extends PartialType(PreferencesCreateDto) {}
28+
export class PreferencesUpdateDto extends PartialType(PreferencesCreateDto) {}

service/src/core/preferences/preferences.controller.ts

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,35 @@
11
import { Body, Controller, Delete, Get, HttpStatus, Param, Patch, Post, Req, Res } from '@nestjs/common'
2-
import { PreferencesCreateDto, PreferencesUpdateDto } from './_dto/preferences.dto'
2+
import { PreferencesCreateDto, PreferencesDto, PreferencesUpdateDto } from './_dto/preferences.dto'
33
import { PreferencesService } from './preferences.service'
44
import { AbstractController } from '~/_common/abstracts/abstract.controller'
55
import { ApiParam, ApiTags } from '@nestjs/swagger'
66
import { SearchFilterSchema, FilterSchema, SearchFilterOptions, FilterOptions, ObjectIdValidationPipe } from '@streamkits/nestjs_module_scrud'
77
import { Types } from 'mongoose'
88
import { Request, Response } from 'express'
9+
import { PartialProjectionType } from '~/_common/types/partial-projection.type'
10+
import { ApiCreateDecorator } from '~/_common/decorators/api-create.decorator'
11+
import { ApiPaginatedDecorator } from '~/_common/decorators/api-paginated.decorator'
12+
import { PickProjectionHelper } from '~/_common/helpers/pick-projection.helper'
13+
import { ApiReadResponseDecorator } from '~/_common/decorators/api-read-response.decorator'
14+
import { ApiUpdateDecorator } from '~/_common/decorators/api-update.decorator'
15+
import { ApiDeletedResponseDecorator } from '~/_common/decorators/api-deleted-response.decorator'
916

1017
@ApiTags('core')
1118
@Controller('preferences')
1219
export class PreferencesController extends AbstractController {
13-
public readonly projection = {
20+
public static readonly projection: PartialProjectionType<PreferencesDto> = {
1421
name: 1,
1522
data: 1,
16-
personId: 1,
23+
entityId: 1,
1724
}
1825

1926
constructor(private readonly _service: PreferencesService) {
2027
super()
2128
}
2229

2330
@Post()
24-
public async create(@Req() req: Request, @Res() res: Response, @Body() body: PreferencesCreateDto) {
31+
@ApiCreateDecorator(PreferencesCreateDto, PreferencesDto)
32+
public async create(@Req() req: Request, @Res() res: Response, @Body() body: PreferencesCreateDto): Promise<Response> {
2533
const data = await this._service.create(body)
2634
return res.status(HttpStatus.CREATED).json({
2735
statusCode: HttpStatus.CREATED,
@@ -30,8 +38,9 @@ export class PreferencesController extends AbstractController {
3038
}
3139

3240
@Get()
33-
public async search(@Res() res: Response, @SearchFilterSchema() searchFilterSchema: FilterSchema, @SearchFilterOptions() searchFilterOptions: FilterOptions) {
34-
const [data, total] = await this._service.findAndCount(searchFilterSchema, this.projection, searchFilterOptions)
41+
@ApiPaginatedDecorator(PickProjectionHelper(PreferencesDto, PreferencesController.projection))
42+
public async search(@Res() res: Response, @SearchFilterSchema() searchFilterSchema: FilterSchema, @SearchFilterOptions() searchFilterOptions: FilterOptions): Promise<Response> {
43+
const [data, total] = await this._service.findAndCount(searchFilterSchema, PreferencesController.projection, searchFilterOptions)
3544
return res.status(HttpStatus.OK).json({
3645
statusCode: HttpStatus.OK,
3746
total,
@@ -41,7 +50,8 @@ export class PreferencesController extends AbstractController {
4150

4251
@Get(':_id([0-9a-fA-F]{24})')
4352
@ApiParam({ name: '_id', type: String })
44-
public async read(@Param('_id', ObjectIdValidationPipe) _id: Types.ObjectId, @Res() res: Response) {
53+
@ApiReadResponseDecorator(PreferencesDto)
54+
public async read(@Param('_id', ObjectIdValidationPipe) _id: Types.ObjectId, @Res() res: Response): Promise<Response> {
4555
const data = await this._service.findById(_id)
4656
return res.status(HttpStatus.OK).json({
4757
statusCode: HttpStatus.OK,
@@ -51,7 +61,8 @@ export class PreferencesController extends AbstractController {
5161

5262
@Patch(':_id([0-9a-fA-F]{24})')
5363
@ApiParam({ name: '_id', type: String })
54-
public async update(@Param('_id', ObjectIdValidationPipe) _id: Types.ObjectId, @Body() body: PreferencesUpdateDto, @Res() res: Response) {
64+
@ApiUpdateDecorator(PreferencesUpdateDto, PreferencesDto)
65+
public async update(@Param('_id', ObjectIdValidationPipe) _id: Types.ObjectId, @Body() body: PreferencesUpdateDto, @Res() res: Response): Promise<Response> {
5566
const data = await this._service.update(_id, body)
5667
return res.status(HttpStatus.OK).json({
5768
statusCode: HttpStatus.OK,
@@ -61,7 +72,8 @@ export class PreferencesController extends AbstractController {
6172

6273
@Delete(':_id([0-9a-fA-F]{24})')
6374
@ApiParam({ name: '_id', type: String })
64-
public async remove(@Param('_id', ObjectIdValidationPipe) _id: Types.ObjectId, @Res() res: Response) {
75+
@ApiDeletedResponseDecorator(PreferencesDto)
76+
public async remove(@Param('_id', ObjectIdValidationPipe) _id: Types.ObjectId, @Res() res: Response): Promise<Response> {
6577
const data = await this._service.delete(_id)
6678
return res.status(HttpStatus.OK).json({
6779
statusCode: HttpStatus.OK,

0 commit comments

Comments
 (0)