@lenne.tech/nest-server 11.2.0 → 11.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/common/decorators/unified-field.decorator.d.ts +2 -0
- package/dist/core/common/decorators/unified-field.decorator.js +26 -9
- package/dist/core/common/decorators/unified-field.decorator.js.map +1 -1
- package/dist/core/common/models/core-persistence.model.js +2 -2
- package/dist/core/common/models/core-persistence.model.js.map +1 -1
- package/dist/core/modules/file/core-file-info.model.js +41 -23
- package/dist/core/modules/file/core-file-info.model.js.map +1 -1
- package/dist/core/modules/user/core-user.model.js +95 -54
- package/dist/core/modules/user/core-user.model.js.map +1 -1
- package/dist/main.js +22 -0
- package/dist/main.js.map +1 -1
- package/dist/server/common/models/persistence.model.js +13 -11
- package/dist/server/common/models/persistence.model.js.map +1 -1
- package/dist/server/modules/auth/auth.model.js +6 -2
- package/dist/server/modules/auth/auth.model.js.map +1 -1
- package/dist/server/modules/user/user.controller.d.ts +19 -0
- package/dist/server/modules/user/user.controller.js +256 -0
- package/dist/server/modules/user/user.controller.js.map +1 -0
- package/dist/server/modules/user/user.model.js +37 -24
- package/dist/server/modules/user/user.model.js.map +1 -1
- package/dist/server/modules/user/user.module.js +2 -1
- package/dist/server/modules/user/user.module.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +27 -28
- package/src/core/common/decorators/unified-field.decorator.ts +49 -10
- package/src/core/common/models/core-persistence.model.ts +3 -3
- package/src/core/modules/file/core-file-info.model.ts +40 -22
- package/src/core/modules/user/core-user.model.ts +120 -78
- package/src/main.ts +25 -0
- package/src/server/common/models/persistence.model.ts +15 -13
- package/src/server/modules/auth/auth.model.ts +7 -3
- package/src/server/modules/user/user.controller.ts +242 -0
- package/src/server/modules/user/user.model.ts +39 -26
- package/src/server/modules/user/user.module.ts +2 -1
package/src/main.ts
CHANGED
|
@@ -1,11 +1,19 @@
|
|
|
1
1
|
import { NestFactory } from '@nestjs/core';
|
|
2
2
|
import { NestExpressApplication } from '@nestjs/platform-express';
|
|
3
|
+
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
|
|
3
4
|
import { exec } from 'child_process';
|
|
4
5
|
import compression = require('compression');
|
|
5
6
|
import cookieParser = require('cookie-parser');
|
|
6
7
|
|
|
7
8
|
import envConfig from './config.env';
|
|
9
|
+
import { FilterArgs } from './core/common/args/filter.args';
|
|
8
10
|
import { HttpExceptionLogFilter } from './core/common/filters/http-exception-log.filter';
|
|
11
|
+
import { CorePersistenceModel } from './core/common/models/core-persistence.model';
|
|
12
|
+
import { CoreAuthModel } from './core/modules/auth/core-auth.model';
|
|
13
|
+
import { CoreUserModel } from './core/modules/user/core-user.model';
|
|
14
|
+
import { PersistenceModel } from './server/common/models/persistence.model';
|
|
15
|
+
import { Auth } from './server/modules/auth/auth.model';
|
|
16
|
+
import { User } from './server/modules/user/user.model';
|
|
9
17
|
import { ServerModule } from './server/server.module';
|
|
10
18
|
|
|
11
19
|
/**
|
|
@@ -54,6 +62,23 @@ async function bootstrap() {
|
|
|
54
62
|
// Enable cors to allow requests from other domains
|
|
55
63
|
server.enableCors();
|
|
56
64
|
|
|
65
|
+
// Swagger documentation
|
|
66
|
+
const config = new DocumentBuilder()
|
|
67
|
+
.setTitle('Nest Server API')
|
|
68
|
+
.setDescription('API lenne.Tech Nest Server')
|
|
69
|
+
.setVersion('1.0.0')
|
|
70
|
+
.addBearerAuth()
|
|
71
|
+
.build();
|
|
72
|
+
const documentFactory = () =>
|
|
73
|
+
SwaggerModule.createDocument(server, config, {
|
|
74
|
+
autoTagControllers: true,
|
|
75
|
+
deepScanRoutes: true,
|
|
76
|
+
extraModels: [CoreUserModel, CoreAuthModel, Auth, User, PersistenceModel, CorePersistenceModel, FilterArgs],
|
|
77
|
+
});
|
|
78
|
+
SwaggerModule.setup('swagger', server, documentFactory, {
|
|
79
|
+
jsonDocumentUrl: '/api-docs-json',
|
|
80
|
+
});
|
|
81
|
+
|
|
57
82
|
// Start server on configured port
|
|
58
83
|
await server.listen(envConfig.port, envConfig.hostname);
|
|
59
84
|
console.debug(`Server startet at ${await server.getUrl()}`);
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { ApiExtraModels, ApiProperty } from '@nestjs/swagger';
|
|
1
|
+
import { ObjectType } from '@nestjs/graphql';
|
|
2
|
+
import { ApiExtraModels } from '@nestjs/swagger';
|
|
4
3
|
import { Types } from 'mongoose';
|
|
5
4
|
import mongoose = require('mongoose');
|
|
6
5
|
|
|
7
6
|
import { Restricted } from '../../../core/common/decorators/restricted.decorator';
|
|
7
|
+
import { UnifiedField } from '../../../core/common/decorators/unified-field.decorator';
|
|
8
8
|
import { RoleEnum } from '../../../core/common/enums/role.enum';
|
|
9
9
|
import { CorePersistenceModel } from '../../../core/common/models/core-persistence.model';
|
|
10
10
|
import { User } from '../../modules/user/user.model';
|
|
@@ -30,13 +30,14 @@ export abstract class PersistenceModel extends CorePersistenceModel {
|
|
|
30
30
|
*
|
|
31
31
|
* Not set when created by system
|
|
32
32
|
*/
|
|
33
|
-
@
|
|
34
|
-
@Field(() => User, {
|
|
33
|
+
@UnifiedField({
|
|
35
34
|
description: 'ID of the user who created the object',
|
|
36
|
-
|
|
35
|
+
isOptional: true,
|
|
36
|
+
mongoose: { ref: 'User', type: mongoose.Schema.Types.ObjectId },
|
|
37
|
+
roles: RoleEnum.ADMIN,
|
|
38
|
+
swaggerApiOptions: { type: String },
|
|
39
|
+
type: () => User,
|
|
37
40
|
})
|
|
38
|
-
@Prop({ ref: 'User', type: mongoose.Schema.Types.ObjectId })
|
|
39
|
-
@Restricted(RoleEnum.ADMIN)
|
|
40
41
|
createdBy?: string | Types.ObjectId = undefined;
|
|
41
42
|
|
|
42
43
|
/**
|
|
@@ -44,13 +45,14 @@ export abstract class PersistenceModel extends CorePersistenceModel {
|
|
|
44
45
|
*
|
|
45
46
|
* Not set when updated by system
|
|
46
47
|
*/
|
|
47
|
-
@
|
|
48
|
-
@Field(() => User, {
|
|
48
|
+
@UnifiedField({
|
|
49
49
|
description: 'ID of the user who updated the object',
|
|
50
|
-
|
|
50
|
+
isOptional: true,
|
|
51
|
+
mongoose: { ref: 'User', type: mongoose.Schema.Types.ObjectId },
|
|
52
|
+
roles: RoleEnum.ADMIN,
|
|
53
|
+
swaggerApiOptions: { type: User },
|
|
54
|
+
type: () => User,
|
|
51
55
|
})
|
|
52
|
-
@Prop({ ref: 'User', type: mongoose.Schema.Types.ObjectId })
|
|
53
|
-
@Restricted(RoleEnum.ADMIN)
|
|
54
56
|
updatedBy?: string | Types.ObjectId = undefined;
|
|
55
57
|
|
|
56
58
|
// ===================================================================================================================
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ObjectType } from '@nestjs/graphql';
|
|
2
2
|
|
|
3
3
|
import { Restricted } from '../../../core/common/decorators/restricted.decorator';
|
|
4
|
+
import { UnifiedField } from '../../../core/common/decorators/unified-field.decorator';
|
|
4
5
|
import { RoleEnum } from '../../../core/common/enums/role.enum';
|
|
5
6
|
import { mapClasses } from '../../../core/common/helpers/model.helper';
|
|
6
7
|
import { CoreAuthModel } from '../../../core/modules/auth/core-auth.model';
|
|
@@ -19,8 +20,11 @@ export class Auth extends CoreAuthModel {
|
|
|
19
20
|
/**
|
|
20
21
|
* Signed-in user
|
|
21
22
|
*/
|
|
22
|
-
@
|
|
23
|
-
|
|
23
|
+
@UnifiedField({
|
|
24
|
+
description: 'User who signed in',
|
|
25
|
+
roles: RoleEnum.S_EVERYONE,
|
|
26
|
+
type: () => User,
|
|
27
|
+
})
|
|
24
28
|
override user: User = undefined;
|
|
25
29
|
|
|
26
30
|
// ===================================================================================================================
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
import { Body, Controller, Delete, Get, Param, Patch, Post, Query, UseGuards } from '@nestjs/common';
|
|
2
|
+
import {
|
|
3
|
+
ApiBearerAuth,
|
|
4
|
+
ApiBody,
|
|
5
|
+
ApiCreatedResponse,
|
|
6
|
+
ApiOkResponse,
|
|
7
|
+
ApiOperation,
|
|
8
|
+
ApiParam,
|
|
9
|
+
ApiQuery,
|
|
10
|
+
ApiTags,
|
|
11
|
+
} from '@nestjs/swagger';
|
|
12
|
+
|
|
13
|
+
import { ApiCommonErrorResponses } from '../../../core/common/decorators/common-error.decorator';
|
|
14
|
+
import { CurrentUser } from '../../../core/common/decorators/current-user.decorator';
|
|
15
|
+
import { Roles } from '../../../core/common/decorators/roles.decorator';
|
|
16
|
+
import { RoleEnum } from '../../../core/common/enums/role.enum';
|
|
17
|
+
import { ServiceOptions } from '../../../core/common/interfaces/service-options.interface';
|
|
18
|
+
import { AuthGuardStrategy } from '../../../core/modules/auth/auth-guard-strategy.enum';
|
|
19
|
+
import { AuthGuard } from '../../../core/modules/auth/guards/auth.guard';
|
|
20
|
+
import { UserCreateInput } from './inputs/user-create.input';
|
|
21
|
+
import { UserInput } from './inputs/user.input';
|
|
22
|
+
import { FindAndCountUsersResult } from './outputs/find-and-count-users-result.output';
|
|
23
|
+
import { User } from './user.model';
|
|
24
|
+
import { UserService } from './user.service';
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Controller to handle user REST API endpoints
|
|
28
|
+
*/
|
|
29
|
+
@ApiCommonErrorResponses()
|
|
30
|
+
@ApiTags('users')
|
|
31
|
+
@Controller('users')
|
|
32
|
+
@Roles(RoleEnum.ADMIN)
|
|
33
|
+
export class UserController {
|
|
34
|
+
/**
|
|
35
|
+
* Import services
|
|
36
|
+
*/
|
|
37
|
+
constructor(protected readonly userService: UserService) {}
|
|
38
|
+
|
|
39
|
+
// ===========================================================================
|
|
40
|
+
// GET Endpoints (Queries)
|
|
41
|
+
// ===========================================================================
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Get users (via filter)
|
|
45
|
+
*/
|
|
46
|
+
@ApiBearerAuth()
|
|
47
|
+
@ApiOkResponse({ description: 'Users found successfully', type: [User] })
|
|
48
|
+
@ApiOperation({ description: 'Find users (via filter)', summary: 'Get all users' })
|
|
49
|
+
@Get()
|
|
50
|
+
@Roles(RoleEnum.ADMIN)
|
|
51
|
+
@UseGuards(AuthGuard(AuthGuardStrategy.JWT))
|
|
52
|
+
async findUsers(@CurrentUser() currentUser: User): Promise<User[]> {
|
|
53
|
+
const serviceOptions: ServiceOptions = {
|
|
54
|
+
currentUser,
|
|
55
|
+
};
|
|
56
|
+
return await this.userService.find({}, serviceOptions);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Get users and total count (via filter)
|
|
61
|
+
*/
|
|
62
|
+
@ApiBearerAuth()
|
|
63
|
+
@ApiOkResponse({ description: 'Users and count found successfully', type: FindAndCountUsersResult })
|
|
64
|
+
@ApiOperation({
|
|
65
|
+
description: 'Find users and total count (via filter)',
|
|
66
|
+
summary: 'Get users with count',
|
|
67
|
+
})
|
|
68
|
+
@Get('count')
|
|
69
|
+
@Roles(RoleEnum.ADMIN)
|
|
70
|
+
@UseGuards(AuthGuard(AuthGuardStrategy.JWT))
|
|
71
|
+
async findAndCountUsers(@CurrentUser() currentUser: User): Promise<FindAndCountUsersResult> {
|
|
72
|
+
const serviceOptions: ServiceOptions = {
|
|
73
|
+
currentUser,
|
|
74
|
+
};
|
|
75
|
+
return await this.userService.findAndCount({}, serviceOptions);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Get verified state of user with token
|
|
80
|
+
*/
|
|
81
|
+
@ApiOkResponse({ description: 'Verified state retrieved successfully', type: Boolean })
|
|
82
|
+
@ApiOperation({
|
|
83
|
+
description: 'Get verified state of user with token',
|
|
84
|
+
summary: 'Check if user is verified',
|
|
85
|
+
})
|
|
86
|
+
@ApiQuery({ description: 'Verification token', name: 'token', type: String })
|
|
87
|
+
@Get('verified-state')
|
|
88
|
+
@Roles(RoleEnum.S_EVERYONE)
|
|
89
|
+
async getVerifiedState(@Query('token') token: string): Promise<boolean> {
|
|
90
|
+
return await this.userService.getVerifiedState(token);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Get user via ID
|
|
95
|
+
*/
|
|
96
|
+
@ApiBearerAuth()
|
|
97
|
+
@ApiOkResponse({ description: 'User found successfully', type: User })
|
|
98
|
+
@ApiOperation({ description: 'Get user with specified ID', summary: 'Get user by ID' })
|
|
99
|
+
@ApiParam({ description: 'User ID', name: 'id', type: String })
|
|
100
|
+
@Get(':id')
|
|
101
|
+
@Roles(RoleEnum.S_USER)
|
|
102
|
+
@UseGuards(AuthGuard(AuthGuardStrategy.JWT))
|
|
103
|
+
async getUser(@CurrentUser() currentUser: User, @Param('id') id: string): Promise<User> {
|
|
104
|
+
const serviceOptions: ServiceOptions = {
|
|
105
|
+
currentUser,
|
|
106
|
+
roles: [RoleEnum.ADMIN, RoleEnum.S_CREATOR, RoleEnum.S_SELF],
|
|
107
|
+
};
|
|
108
|
+
return await this.userService.get(id, serviceOptions);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// ===========================================================================
|
|
112
|
+
// POST Endpoints (Mutations)
|
|
113
|
+
// ===========================================================================
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Create new user
|
|
117
|
+
*/
|
|
118
|
+
@ApiBearerAuth()
|
|
119
|
+
@ApiBody({ type: UserCreateInput })
|
|
120
|
+
@ApiCreatedResponse({ description: 'User created successfully', type: User })
|
|
121
|
+
@ApiOperation({ description: 'Create a new user', summary: 'Create user' })
|
|
122
|
+
@Post()
|
|
123
|
+
@Roles(RoleEnum.ADMIN)
|
|
124
|
+
@UseGuards(AuthGuard(AuthGuardStrategy.JWT))
|
|
125
|
+
async createUser(@CurrentUser() currentUser: User, @Body() input: UserCreateInput): Promise<User> {
|
|
126
|
+
const serviceOptions: ServiceOptions = {
|
|
127
|
+
currentUser,
|
|
128
|
+
inputType: UserCreateInput,
|
|
129
|
+
};
|
|
130
|
+
return await this.userService.create(input, serviceOptions);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Request new password for user with email
|
|
135
|
+
*/
|
|
136
|
+
@ApiBody({
|
|
137
|
+
description: 'User email',
|
|
138
|
+
schema: {
|
|
139
|
+
properties: {
|
|
140
|
+
email: { type: 'string' },
|
|
141
|
+
},
|
|
142
|
+
type: 'object',
|
|
143
|
+
},
|
|
144
|
+
})
|
|
145
|
+
@ApiOkResponse({ description: 'Password reset email sent successfully', type: Boolean })
|
|
146
|
+
@ApiOperation({
|
|
147
|
+
description: 'Request new password for user with email',
|
|
148
|
+
summary: 'Request password reset',
|
|
149
|
+
})
|
|
150
|
+
@Post('password/reset-request')
|
|
151
|
+
@Roles(RoleEnum.S_EVERYONE)
|
|
152
|
+
async requestPasswordResetMail(@Body('email') email: string): Promise<boolean> {
|
|
153
|
+
return !!(await this.userService.sendPasswordResetMail(email));
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Set new password for user with token
|
|
158
|
+
*/
|
|
159
|
+
@ApiBody({
|
|
160
|
+
description: 'Password reset data',
|
|
161
|
+
schema: {
|
|
162
|
+
properties: {
|
|
163
|
+
password: { type: 'string' },
|
|
164
|
+
token: { type: 'string' },
|
|
165
|
+
},
|
|
166
|
+
type: 'object',
|
|
167
|
+
},
|
|
168
|
+
})
|
|
169
|
+
@ApiOkResponse({ description: 'Password reset successfully', type: Boolean })
|
|
170
|
+
@ApiOperation({ description: 'Set new password for user with token', summary: 'Reset password' })
|
|
171
|
+
@Post('password/reset')
|
|
172
|
+
@Roles(RoleEnum.S_EVERYONE)
|
|
173
|
+
async resetPassword(@Body('token') token: string, @Body('password') password: string): Promise<boolean> {
|
|
174
|
+
return !!(await this.userService.resetPassword(token, password));
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Verify user with email
|
|
179
|
+
*/
|
|
180
|
+
@ApiBody({
|
|
181
|
+
description: 'Verification token',
|
|
182
|
+
schema: {
|
|
183
|
+
properties: {
|
|
184
|
+
token: { type: 'string' },
|
|
185
|
+
},
|
|
186
|
+
type: 'object',
|
|
187
|
+
},
|
|
188
|
+
})
|
|
189
|
+
@ApiOkResponse({ description: 'User verified successfully', type: Boolean })
|
|
190
|
+
@ApiOperation({ description: 'Verify user with email', summary: 'Verify user' })
|
|
191
|
+
@Post('verify')
|
|
192
|
+
@Roles(RoleEnum.S_EVERYONE)
|
|
193
|
+
async verifyUser(@Body('token') token: string): Promise<boolean> {
|
|
194
|
+
return !!(await this.userService.verify(token));
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// ===========================================================================
|
|
198
|
+
// PATCH Endpoints (Updates)
|
|
199
|
+
// ===========================================================================
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Update existing user
|
|
203
|
+
*/
|
|
204
|
+
@ApiBearerAuth()
|
|
205
|
+
@ApiBody({ type: UserInput })
|
|
206
|
+
@ApiOkResponse({ description: 'User updated successfully', type: User })
|
|
207
|
+
@ApiOperation({ description: 'Update existing user', summary: 'Update user' })
|
|
208
|
+
@ApiParam({ description: 'User ID', name: 'id', type: String })
|
|
209
|
+
@Patch(':id')
|
|
210
|
+
@Roles(RoleEnum.S_USER)
|
|
211
|
+
@UseGuards(AuthGuard(AuthGuardStrategy.JWT))
|
|
212
|
+
async updateUser(@CurrentUser() currentUser: User, @Param('id') id: string, @Body() input: UserInput): Promise<User> {
|
|
213
|
+
const serviceOptions: ServiceOptions = {
|
|
214
|
+
currentUser,
|
|
215
|
+
inputType: UserInput,
|
|
216
|
+
roles: [RoleEnum.ADMIN, RoleEnum.S_CREATOR, RoleEnum.S_SELF],
|
|
217
|
+
};
|
|
218
|
+
return await this.userService.update(id, input, serviceOptions);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// ===========================================================================
|
|
222
|
+
// DELETE Endpoints
|
|
223
|
+
// ===========================================================================
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Delete existing user
|
|
227
|
+
*/
|
|
228
|
+
@ApiBearerAuth()
|
|
229
|
+
@ApiOkResponse({ description: 'User deleted successfully', type: User })
|
|
230
|
+
@ApiOperation({ description: 'Delete existing user', summary: 'Delete user' })
|
|
231
|
+
@ApiParam({ description: 'User ID', name: 'id', type: String })
|
|
232
|
+
@Delete(':id')
|
|
233
|
+
@Roles(RoleEnum.S_USER)
|
|
234
|
+
@UseGuards(AuthGuard(AuthGuardStrategy.JWT))
|
|
235
|
+
async deleteUser(@CurrentUser() currentUser: User, @Param('id') id: string): Promise<User> {
|
|
236
|
+
const serviceOptions: ServiceOptions = {
|
|
237
|
+
currentUser,
|
|
238
|
+
roles: [RoleEnum.ADMIN, RoleEnum.S_CREATOR, RoleEnum.S_SELF],
|
|
239
|
+
};
|
|
240
|
+
return await this.userService.delete(id, serviceOptions);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ObjectType } from '@nestjs/graphql';
|
|
2
2
|
import { Schema as MongooseSchema, Prop, SchemaFactory } from '@nestjs/mongoose';
|
|
3
|
-
import { IsEmail
|
|
3
|
+
import { IsEmail } from 'class-validator';
|
|
4
4
|
import { Document, Schema } from 'mongoose';
|
|
5
5
|
|
|
6
6
|
import { Restricted } from '../../../core/common/decorators/restricted.decorator';
|
|
7
7
|
import { Translatable } from '../../../core/common/decorators/translatable.decorator';
|
|
8
|
+
import { UnifiedField } from '../../../core/common/decorators/unified-field.decorator';
|
|
8
9
|
import { RoleEnum } from '../../../core/common/enums/role.enum';
|
|
9
10
|
import { CoreUserModel } from '../../../core/modules/user/core-user.model';
|
|
10
11
|
import { PersistenceModel } from '../../common/models/persistence.model';
|
|
@@ -25,9 +26,12 @@ export class User extends CoreUserModel implements PersistenceModel {
|
|
|
25
26
|
/**
|
|
26
27
|
* URL to avatar file of the user
|
|
27
28
|
*/
|
|
28
|
-
@
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
@UnifiedField({
|
|
30
|
+
description: 'URL to avatar file of the user',
|
|
31
|
+
isOptional: true,
|
|
32
|
+
mongoose: true,
|
|
33
|
+
roles: RoleEnum.S_EVERYONE,
|
|
34
|
+
})
|
|
31
35
|
avatar: string = undefined;
|
|
32
36
|
|
|
33
37
|
/**
|
|
@@ -35,39 +39,47 @@ export class User extends CoreUserModel implements PersistenceModel {
|
|
|
35
39
|
*
|
|
36
40
|
* Not set when created by system
|
|
37
41
|
*/
|
|
38
|
-
@
|
|
42
|
+
@UnifiedField({
|
|
39
43
|
description: 'ID of the user who created the object',
|
|
40
|
-
|
|
44
|
+
isOptional: true,
|
|
45
|
+
mongoose: { ref: 'User', type: Schema.Types.ObjectId },
|
|
46
|
+
roles: RoleEnum.S_EVERYONE,
|
|
47
|
+
type: () => String,
|
|
41
48
|
})
|
|
42
|
-
@Prop({ ref: 'User', type: Schema.Types.ObjectId })
|
|
43
|
-
@Restricted(RoleEnum.S_EVERYONE)
|
|
44
49
|
createdBy: string = undefined;
|
|
45
50
|
|
|
46
51
|
/**
|
|
47
52
|
* E-Mail address of the user
|
|
48
53
|
*/
|
|
49
|
-
@
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
54
|
+
@UnifiedField({
|
|
55
|
+
description: 'Email of the user',
|
|
56
|
+
isOptional: true,
|
|
57
|
+
mongoose: { lowercase: true, trim: true, unique: true },
|
|
58
|
+
roles: RoleEnum.S_EVERYONE,
|
|
59
|
+
validator: () => [IsEmail()],
|
|
60
|
+
})
|
|
53
61
|
override email: string = undefined;
|
|
54
62
|
|
|
55
63
|
/**
|
|
56
64
|
* Roles of the user
|
|
57
65
|
*/
|
|
58
|
-
@
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
66
|
+
@UnifiedField({
|
|
67
|
+
description: 'Roles of the user',
|
|
68
|
+
isArray: true,
|
|
69
|
+
isOptional: true,
|
|
70
|
+
mongoose: [String],
|
|
71
|
+
roles: RoleEnum.S_EVERYONE,
|
|
72
|
+
type: () => String,
|
|
73
|
+
})
|
|
62
74
|
override roles: string[] = undefined;
|
|
63
75
|
|
|
64
|
-
@
|
|
76
|
+
@Translatable()
|
|
77
|
+
@UnifiedField({
|
|
65
78
|
description: 'Job title of user',
|
|
66
|
-
|
|
79
|
+
isOptional: true,
|
|
80
|
+
mongoose: true,
|
|
81
|
+
roles: RoleEnum.S_EVERYONE,
|
|
67
82
|
})
|
|
68
|
-
@Prop()
|
|
69
|
-
@Restricted(RoleEnum.S_EVERYONE)
|
|
70
|
-
@Translatable()
|
|
71
83
|
jobTitle?: string = undefined;
|
|
72
84
|
|
|
73
85
|
/**
|
|
@@ -75,12 +87,13 @@ export class User extends CoreUserModel implements PersistenceModel {
|
|
|
75
87
|
*
|
|
76
88
|
* Not set when updated by system
|
|
77
89
|
*/
|
|
78
|
-
@
|
|
90
|
+
@UnifiedField({
|
|
79
91
|
description: 'ID of the user who last updated the object',
|
|
80
|
-
|
|
92
|
+
isOptional: true,
|
|
93
|
+
mongoose: { ref: 'User', type: Schema.Types.ObjectId },
|
|
94
|
+
roles: RoleEnum.S_USER,
|
|
95
|
+
type: () => String,
|
|
81
96
|
})
|
|
82
|
-
@Prop({ ref: 'User', type: Schema.Types.ObjectId })
|
|
83
|
-
@Restricted(RoleEnum.S_USER)
|
|
84
97
|
updatedBy: string = undefined;
|
|
85
98
|
|
|
86
99
|
@Prop({ default: {}, type: Schema.Types.Mixed })
|
|
@@ -4,6 +4,7 @@ import { PubSub } from 'graphql-subscriptions';
|
|
|
4
4
|
|
|
5
5
|
import { ConfigService } from '../../../core/common/services/config.service';
|
|
6
6
|
import { AvatarController } from './avatar.controller';
|
|
7
|
+
import { UserController } from './user.controller';
|
|
7
8
|
import { User, UserSchema } from './user.model';
|
|
8
9
|
import { UserResolver } from './user.resolver';
|
|
9
10
|
import { UserService } from './user.service';
|
|
@@ -12,7 +13,7 @@ import { UserService } from './user.service';
|
|
|
12
13
|
* User module
|
|
13
14
|
*/
|
|
14
15
|
@Module({
|
|
15
|
-
controllers: [AvatarController],
|
|
16
|
+
controllers: [AvatarController, UserController],
|
|
16
17
|
exports: [MongooseModule, UserResolver, UserService, 'USER_CLASS'],
|
|
17
18
|
imports: [MongooseModule.forFeature([{ name: User.name, schema: UserSchema }])],
|
|
18
19
|
providers: [
|