@lenne.tech/nest-server 8.0.2 → 8.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/config.env.js +3 -2
- package/dist/config.env.js.map +1 -1
- package/dist/core/common/args/pagination.args.js +1 -1
- package/dist/core/common/args/pagination.args.js.map +1 -1
- package/dist/core/common/decorators/restricted.decorator.d.ts +3 -0
- package/dist/core/common/decorators/restricted.decorator.js +14 -8
- package/dist/core/common/decorators/restricted.decorator.js.map +1 -1
- package/dist/core/common/enums/role.enum.d.ts +3 -2
- package/dist/core/common/enums/role.enum.js +3 -2
- package/dist/core/common/enums/role.enum.js.map +1 -1
- package/dist/core/common/helpers/config.helper.d.ts +2 -1
- package/dist/core/common/helpers/config.helper.js +11 -7
- package/dist/core/common/helpers/config.helper.js.map +1 -1
- package/dist/core/common/helpers/context.helper.d.ts +7 -1
- package/dist/core/common/helpers/context.helper.js +33 -29
- package/dist/core/common/helpers/context.helper.js.map +1 -1
- package/dist/core/common/helpers/db.helper.d.ts +37 -0
- package/dist/core/common/helpers/db.helper.js +356 -0
- package/dist/core/common/helpers/db.helper.js.map +1 -0
- package/dist/core/common/helpers/file.helper.d.ts +8 -1
- package/dist/core/common/helpers/file.helper.js +43 -31
- package/dist/core/common/helpers/file.helper.js.map +1 -1
- package/dist/core/common/helpers/filter.helper.d.ts +3 -0
- package/dist/core/common/helpers/filter.helper.js +93 -81
- package/dist/core/common/helpers/filter.helper.js.map +1 -1
- package/dist/core/common/helpers/graphql.helper.d.ts +24 -1
- package/dist/core/common/helpers/graphql.helper.js +144 -96
- package/dist/core/common/helpers/graphql.helper.js.map +1 -1
- package/dist/core/common/helpers/input.helper.d.ts +42 -4
- package/dist/core/common/helpers/input.helper.js +256 -97
- package/dist/core/common/helpers/input.helper.js.map +1 -1
- package/dist/core/common/helpers/model.helper.d.ts +11 -0
- package/dist/core/common/helpers/model.helper.js +41 -29
- package/dist/core/common/helpers/model.helper.js.map +1 -1
- package/dist/core/common/helpers/service.helper.d.ts +21 -1
- package/dist/core/common/helpers/service.helper.js +80 -72
- package/dist/core/common/helpers/service.helper.js.map +1 -1
- package/dist/core/common/inputs/combined-filter.input.js +1 -1
- package/dist/core/common/inputs/combined-filter.input.js.map +1 -1
- package/dist/core/common/inputs/core-input.input.js +1 -1
- package/dist/core/common/inputs/core-input.input.js.map +1 -1
- package/dist/core/common/interceptors/check-response.interceptor.js +1 -1
- package/dist/core/common/interceptors/check-response.interceptor.js.map +1 -1
- package/dist/core/common/interfaces/resolve-selector.interface.d.ts +5 -0
- package/dist/core/common/interfaces/resolve-selector.interface.js +3 -0
- package/dist/core/common/interfaces/resolve-selector.interface.js.map +1 -0
- package/dist/core/common/interfaces/service-options.interface.d.ts +36 -0
- package/dist/core/common/interfaces/service-options.interface.js +3 -0
- package/dist/core/common/interfaces/service-options.interface.js.map +1 -0
- package/dist/core/common/models/core-model.model.d.ts +5 -1
- package/dist/core/common/models/core-model.model.js +1 -1
- package/dist/core/common/models/core-model.model.js.map +1 -1
- package/dist/core/common/pipes/check-input.pipe.js +2 -2
- package/dist/core/common/pipes/check-input.pipe.js.map +1 -1
- package/dist/core/common/pipes/map-and-validate.pipe.js +1 -1
- package/dist/core/common/pipes/map-and-validate.pipe.js.map +1 -1
- package/dist/core/common/services/crud.service.d.ts +13 -0
- package/dist/core/common/services/crud.service.js +57 -0
- package/dist/core/common/services/crud.service.js.map +1 -0
- package/dist/core/common/services/email.service.js +8 -8
- package/dist/core/common/services/email.service.js.map +1 -1
- package/dist/core/common/services/module.service.d.ts +40 -0
- package/dist/core/common/services/module.service.js +80 -0
- package/dist/core/common/services/module.service.js.map +1 -0
- package/dist/core/common/types/core-model-constructor.type.d.ts +21 -0
- package/dist/core/common/types/core-model-constructor.type.js +3 -0
- package/dist/core/common/types/core-model-constructor.type.js.map +1 -0
- package/dist/core/common/types/field-selection.type.d.ts +4 -0
- package/dist/core/common/types/field-selection.type.js +3 -0
- package/dist/core/common/types/field-selection.type.js.map +1 -0
- package/dist/core/common/types/ids.type.d.ts +8 -0
- package/dist/core/common/types/ids.type.js +3 -0
- package/dist/core/common/types/ids.type.js.map +1 -0
- package/dist/core/common/types/string-or-object-id.type.d.ts +2 -0
- package/dist/core/common/types/string-or-object-id.type.js +3 -0
- package/dist/core/common/types/string-or-object-id.type.js.map +1 -0
- package/dist/core/modules/auth/core-auth.resolver.d.ts +2 -1
- package/dist/core/modules/auth/core-auth.resolver.js +4 -3
- package/dist/core/modules/auth/core-auth.resolver.js.map +1 -1
- package/dist/core/modules/auth/guards/roles.guard.js +1 -2
- package/dist/core/modules/auth/guards/roles.guard.js.map +1 -1
- package/dist/core/modules/auth/services/core-auth-user.service.d.ts +3 -1
- package/dist/core/modules/auth/services/core-auth-user.service.js.map +1 -1
- package/dist/core/modules/auth/services/core-auth.service.d.ts +2 -1
- package/dist/core/modules/auth/services/core-auth.service.js +6 -4
- package/dist/core/modules/auth/services/core-auth.service.js.map +1 -1
- package/dist/core/modules/user/core-user.model.js +1 -1
- package/dist/core/modules/user/core-user.model.js.map +1 -1
- package/dist/core/modules/user/core-user.service.d.ts +16 -25
- package/dist/core/modules/user/core-user.service.js +69 -90
- package/dist/core/modules/user/core-user.service.js.map +1 -1
- package/dist/core.module.js +1 -1
- package/dist/core.module.js.map +1 -1
- package/dist/index.d.ts +9 -1
- package/dist/index.js +9 -1
- package/dist/index.js.map +1 -1
- package/dist/server/modules/auth/auth.resolver.d.ts +2 -1
- package/dist/server/modules/auth/auth.resolver.js +4 -3
- package/dist/server/modules/auth/auth.resolver.js.map +1 -1
- package/dist/server/modules/file/file.controller.js +1 -1
- package/dist/server/modules/file/file.controller.js.map +1 -1
- package/dist/server/modules/user/avatar.controller.js +2 -2
- package/dist/server/modules/user/avatar.controller.js.map +1 -1
- package/dist/server/modules/user/user.model.d.ts +2 -1
- package/dist/server/modules/user/user.module.js +7 -3
- package/dist/server/modules/user/user.module.js.map +1 -1
- package/dist/server/modules/user/user.resolver.d.ts +8 -7
- package/dist/server/modules/user/user.resolver.js +85 -49
- package/dist/server/modules/user/user.resolver.js.map +1 -1
- package/dist/server/modules/user/user.service.d.ts +9 -18
- package/dist/server/modules/user/user.service.js +23 -30
- package/dist/server/modules/user/user.service.js.map +1 -1
- package/dist/test/test.helper.d.ts +1 -2
- package/dist/test/test.helper.js +1 -16
- package/dist/test/test.helper.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +58 -59
- package/src/config.env.ts +3 -2
- package/src/core/common/args/pagination.args.ts +2 -2
- package/src/core/common/decorators/restricted.decorator.ts +24 -12
- package/src/core/common/enums/role.enum.ts +23 -5
- package/src/core/common/helpers/config.helper.ts +26 -6
- package/src/core/common/helpers/context.helper.ts +42 -33
- package/src/core/common/helpers/db.helper.ts +595 -0
- package/src/core/common/helpers/file.helper.ts +76 -49
- package/src/core/common/helpers/filter.helper.ts +119 -96
- package/src/core/common/helpers/graphql.helper.ts +219 -117
- package/src/core/common/helpers/input.helper.ts +349 -108
- package/src/core/common/helpers/model.helper.ts +102 -57
- package/src/core/common/helpers/service.helper.ts +149 -117
- package/src/core/common/inputs/combined-filter.input.ts +2 -2
- package/src/core/common/inputs/core-input.input.ts +2 -2
- package/src/core/common/interceptors/check-response.interceptor.ts +2 -2
- package/src/core/common/interfaces/resolve-selector.interface.ts +9 -0
- package/src/core/common/interfaces/service-options.interface.ts +71 -0
- package/src/core/common/models/core-model.model.ts +7 -3
- package/src/core/common/pipes/check-input.pipe.ts +4 -4
- package/src/core/common/pipes/map-and-validate.pipe.ts +2 -2
- package/src/core/common/services/crud.service.ts +100 -0
- package/src/core/common/services/email.service.ts +9 -9
- package/src/core/common/services/module.service.ts +188 -0
- package/src/core/common/types/core-model-constructor.type.ts +30 -0
- package/src/core/common/types/field-selection.type.ts +8 -0
- package/src/core/common/types/ids.type.ts +7 -0
- package/src/core/common/types/string-or-object-id.type.ts +3 -0
- package/src/core/modules/auth/core-auth.module.ts +1 -1
- package/src/core/modules/auth/core-auth.resolver.ts +8 -3
- package/src/core/modules/auth/guards/roles.guard.ts +5 -7
- package/src/core/modules/auth/services/core-auth-user.service.ts +7 -1
- package/src/core/modules/auth/services/core-auth.service.ts +14 -4
- package/src/core/modules/user/core-user.model.ts +2 -1
- package/src/core/modules/user/core-user.service.ts +115 -185
- package/src/core.module.ts +2 -2
- package/src/index.ts +9 -1
- package/src/main.ts +1 -1
- package/src/server/modules/auth/auth.resolver.ts +8 -3
- package/src/server/modules/file/file.controller.ts +2 -2
- package/src/server/modules/user/avatar.controller.ts +3 -3
- package/src/server/modules/user/user.module.ts +7 -3
- package/src/server/modules/user/user.resolver.ts +74 -43
- package/src/server/modules/user/user.service.ts +30 -53
- package/src/test/test.helper.ts +31 -30
- package/dist/core/modules/user/core-basic-user.service.d.ts +0 -17
- package/dist/core/modules/user/core-basic-user.service.js +0 -73
- package/dist/core/modules/user/core-basic-user.service.js.map +0 -1
- package/src/core/modules/user/core-basic-user.service.ts +0 -138
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Inject } from '@nestjs/common';
|
|
1
2
|
import { Args, Info, Mutation, Query, Resolver, Subscription } from '@nestjs/graphql';
|
|
2
3
|
import { GraphQLResolveInfo } from 'graphql';
|
|
3
4
|
import { PubSub } from 'graphql-subscriptions';
|
|
@@ -5,12 +6,10 @@ import { FilterArgs } from '../../../core/common/args/filter.args';
|
|
|
5
6
|
import { GraphQLUser } from '../../../core/common/decorators/graphql-user.decorator';
|
|
6
7
|
import { Roles } from '../../../core/common/decorators/roles.decorator';
|
|
7
8
|
import { RoleEnum } from '../../../core/common/enums/role.enum';
|
|
8
|
-
import { InputHelper } from '../../../core/common/helpers/input.helper';
|
|
9
9
|
import { UserCreateInput } from './inputs/user-create.input';
|
|
10
10
|
import { UserInput } from './inputs/user.input';
|
|
11
11
|
import { User } from './user.model';
|
|
12
12
|
import { UserService } from './user.service';
|
|
13
|
-
import { Inject } from '@nestjs/common';
|
|
14
13
|
|
|
15
14
|
/**
|
|
16
15
|
* Resolver to process with user data
|
|
@@ -20,27 +19,43 @@ export class UserResolver {
|
|
|
20
19
|
/**
|
|
21
20
|
* Import services
|
|
22
21
|
*/
|
|
23
|
-
constructor(protected readonly
|
|
22
|
+
constructor(protected readonly userService: UserService, @Inject('PUB_SUB') protected readonly pubSub: PubSub) {}
|
|
24
23
|
|
|
25
24
|
// ===========================================================================
|
|
26
25
|
// Queries
|
|
27
26
|
// ===========================================================================
|
|
28
27
|
|
|
28
|
+
/**
|
|
29
|
+
* Get users (via filter)
|
|
30
|
+
*/
|
|
31
|
+
@Roles(RoleEnum.ADMIN)
|
|
32
|
+
@Query((returns) => [User], { description: 'Find users (via filter)' })
|
|
33
|
+
async findUsers(@Info() info: GraphQLResolveInfo, @Args() args?: FilterArgs) {
|
|
34
|
+
return await this.userService.find(args, {
|
|
35
|
+
fieldSelection: { info, select: 'findUsers' },
|
|
36
|
+
inputType: FilterArgs,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
|
|
29
40
|
/**
|
|
30
41
|
* Get user via ID
|
|
31
42
|
*/
|
|
43
|
+
@Roles(RoleEnum.S_USER)
|
|
32
44
|
@Query((returns) => User, { description: 'Get user with specified ID' })
|
|
33
|
-
async getUser(@Args('id') id: string, @Info() info: GraphQLResolveInfo): Promise<User> {
|
|
34
|
-
return await this.
|
|
45
|
+
async getUser(@Args('id') id: string, @Info() info: GraphQLResolveInfo, @GraphQLUser() user: User): Promise<User> {
|
|
46
|
+
return await this.userService.get(id, {
|
|
47
|
+
currentUser: user,
|
|
48
|
+
fieldSelection: { info, select: 'getUser' },
|
|
49
|
+
roles: [RoleEnum.ADMIN, RoleEnum.S_CREATOR],
|
|
50
|
+
});
|
|
35
51
|
}
|
|
36
52
|
|
|
37
53
|
/**
|
|
38
|
-
* Get
|
|
54
|
+
* Get verified state of user with token
|
|
39
55
|
*/
|
|
40
|
-
@
|
|
41
|
-
@
|
|
42
|
-
|
|
43
|
-
return await this.usersService.find(args, info);
|
|
56
|
+
@Query((returns) => Boolean, { description: 'Get verified state of user with token' })
|
|
57
|
+
async getVerifiedState(@Args('token') token: string) {
|
|
58
|
+
return await this.userService.getVerifiedState(token);
|
|
44
59
|
}
|
|
45
60
|
|
|
46
61
|
/**
|
|
@@ -48,63 +63,76 @@ export class UserResolver {
|
|
|
48
63
|
*/
|
|
49
64
|
@Query((returns) => Boolean, { description: 'Request new password for user with email' })
|
|
50
65
|
async requestPasswordResetMail(@Args('email') email: string): Promise<boolean> {
|
|
51
|
-
return !!(await this.
|
|
66
|
+
return !!(await this.userService.sendPasswordResetMail(email));
|
|
52
67
|
}
|
|
53
68
|
|
|
54
69
|
// ===========================================================================
|
|
55
70
|
// Mutations
|
|
56
71
|
// ===========================================================================
|
|
72
|
+
|
|
57
73
|
/**
|
|
58
|
-
*
|
|
74
|
+
* Create new user
|
|
59
75
|
*/
|
|
60
|
-
@Mutation((returns) =>
|
|
61
|
-
async
|
|
62
|
-
|
|
76
|
+
@Mutation((returns) => User, { description: 'Create a new user' })
|
|
77
|
+
async createUser(
|
|
78
|
+
@Args('input') input: UserCreateInput,
|
|
79
|
+
@GraphQLUser() user: User,
|
|
80
|
+
@Info() info: GraphQLResolveInfo
|
|
81
|
+
): Promise<User> {
|
|
82
|
+
return await this.userService.create(input, {
|
|
83
|
+
currentUser: user,
|
|
84
|
+
fieldSelection: { info, select: 'createUser' },
|
|
85
|
+
inputType: UserCreateInput,
|
|
86
|
+
});
|
|
63
87
|
}
|
|
64
88
|
|
|
65
89
|
/**
|
|
66
|
-
*
|
|
90
|
+
* Delete existing user
|
|
67
91
|
*/
|
|
68
|
-
@
|
|
69
|
-
|
|
70
|
-
|
|
92
|
+
@Roles(RoleEnum.S_USER)
|
|
93
|
+
@Mutation((returns) => User, { description: 'Delete existing user' })
|
|
94
|
+
async deleteUser(@Args('id') id: string, @Info() info: GraphQLResolveInfo, @GraphQLUser() user: User): Promise<User> {
|
|
95
|
+
return await this.userService.delete(id, {
|
|
96
|
+
currentUser: user,
|
|
97
|
+
fieldSelection: { info, select: 'deleteUser' },
|
|
98
|
+
roles: [RoleEnum.ADMIN, RoleEnum.S_CREATOR],
|
|
99
|
+
});
|
|
71
100
|
}
|
|
72
101
|
|
|
73
102
|
/**
|
|
74
|
-
*
|
|
103
|
+
* Set new password for user with token
|
|
75
104
|
*/
|
|
76
|
-
@Mutation((returns) =>
|
|
77
|
-
async
|
|
78
|
-
|
|
79
|
-
// Hint: necessary as long as global CheckInputPipe can't access context for current user
|
|
80
|
-
// (see https://github.com/nestjs/graphql/issues/325)
|
|
81
|
-
input = await InputHelper.check(input, user, UserCreateInput);
|
|
82
|
-
|
|
83
|
-
return await this.usersService.create(input, user);
|
|
105
|
+
@Mutation((returns) => Boolean, { description: 'Set new password for user with token' })
|
|
106
|
+
async resetPassword(@Args('token') token: string, @Args('password') password: string): Promise<boolean> {
|
|
107
|
+
return !!(await this.userService.resetPassword(token, password));
|
|
84
108
|
}
|
|
85
109
|
|
|
86
110
|
/**
|
|
87
111
|
* Update existing user
|
|
88
112
|
*/
|
|
89
|
-
@Roles(RoleEnum.
|
|
113
|
+
@Roles(RoleEnum.S_USER)
|
|
90
114
|
@Mutation((returns) => User, { description: 'Update existing user' })
|
|
91
|
-
async updateUser(
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
115
|
+
async updateUser(
|
|
116
|
+
@Args('input') input: UserInput,
|
|
117
|
+
@Args('id') id: string,
|
|
118
|
+
@GraphQLUser() user: User,
|
|
119
|
+
@Info() info: GraphQLResolveInfo
|
|
120
|
+
): Promise<User> {
|
|
97
121
|
// Update user
|
|
98
|
-
return await this.
|
|
122
|
+
return await this.userService.update(id, input, {
|
|
123
|
+
currentUser: user,
|
|
124
|
+
fieldSelection: { info, select: 'updateUser' },
|
|
125
|
+
inputType: UserInput,
|
|
126
|
+
roles: [RoleEnum.ADMIN, RoleEnum.S_CREATOR],
|
|
127
|
+
});
|
|
99
128
|
}
|
|
100
129
|
|
|
101
130
|
/**
|
|
102
|
-
*
|
|
131
|
+
* Verify user with email
|
|
103
132
|
*/
|
|
104
|
-
@
|
|
105
|
-
@
|
|
106
|
-
|
|
107
|
-
return await this.usersService.delete(id, info);
|
|
133
|
+
@Mutation((returns) => Boolean, { description: 'Verify user with email' })
|
|
134
|
+
async verifyUser(@Args('token') token: string): Promise<boolean> {
|
|
135
|
+
return !!(await this.userService.verify(token));
|
|
108
136
|
}
|
|
109
137
|
|
|
110
138
|
// ===========================================================================
|
|
@@ -112,10 +140,13 @@ export class UserResolver {
|
|
|
112
140
|
// ===========================================================================
|
|
113
141
|
|
|
114
142
|
/**
|
|
115
|
-
*
|
|
143
|
+
* Subscription for created user
|
|
116
144
|
*/
|
|
117
145
|
@Subscription((returns) => User, {
|
|
118
|
-
|
|
146
|
+
filter(this: UserResolver, payload, variables, context) {
|
|
147
|
+
return context.user.roles.include(RoleEnum.ADMIN);
|
|
148
|
+
},
|
|
149
|
+
resolve: (user) => user,
|
|
119
150
|
})
|
|
120
151
|
async userCreated() {
|
|
121
152
|
return this.pubSub.asyncIterator('userCreated');
|
|
@@ -1,33 +1,23 @@
|
|
|
1
1
|
import { Inject, Injectable, UnauthorizedException, UnprocessableEntityException } from '@nestjs/common';
|
|
2
|
+
import { InjectModel } from '@nestjs/mongoose';
|
|
2
3
|
import * as fs from 'fs';
|
|
4
|
+
import { PubSub } from 'graphql-subscriptions';
|
|
5
|
+
import { Model } from 'mongoose';
|
|
3
6
|
import envConfig from '../../../config.env';
|
|
4
|
-
import {
|
|
5
|
-
import { Filter } from '../../../core/common/helpers/filter.helper';
|
|
6
|
-
import { ServiceHelper } from '../../../core/common/helpers/service.helper';
|
|
7
|
+
import { ServiceOptions } from '../../../core/common/interfaces/service-options.interface';
|
|
7
8
|
import { ConfigService } from '../../../core/common/services/config.service';
|
|
8
9
|
import { EmailService } from '../../../core/common/services/email.service';
|
|
10
|
+
import { CoreModelConstructor } from '../../../core/common/types/core-model-constructor.type';
|
|
9
11
|
import { CoreUserService } from '../../../core/modules/user/core-user.service';
|
|
10
12
|
import { UserCreateInput } from './inputs/user-create.input';
|
|
11
13
|
import { UserInput } from './inputs/user.input';
|
|
12
14
|
import { User, UserDocument } from './user.model';
|
|
13
|
-
import { InjectModel } from '@nestjs/mongoose';
|
|
14
|
-
import { Model } from 'mongoose';
|
|
15
|
-
import { ICorePersistenceModel } from '../../../core/common/interfaces/core-persistence-model.interface';
|
|
16
|
-
import { PubSub } from 'graphql-subscriptions';
|
|
17
15
|
|
|
18
16
|
/**
|
|
19
17
|
* User service
|
|
20
18
|
*/
|
|
21
19
|
@Injectable()
|
|
22
20
|
export class UserService extends CoreUserService<User, UserInput, UserCreateInput> {
|
|
23
|
-
// ===================================================================================================================
|
|
24
|
-
// Properties
|
|
25
|
-
// ===================================================================================================================
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* User model
|
|
29
|
-
*/
|
|
30
|
-
protected readonly model: ICorePersistenceModel;
|
|
31
21
|
// ===================================================================================================================
|
|
32
22
|
// Injections
|
|
33
23
|
// ===================================================================================================================
|
|
@@ -38,11 +28,11 @@ export class UserService extends CoreUserService<User, UserInput, UserCreateInpu
|
|
|
38
28
|
constructor(
|
|
39
29
|
protected readonly configService: ConfigService,
|
|
40
30
|
protected readonly emailService: EmailService,
|
|
41
|
-
@
|
|
31
|
+
@Inject('USER_CLASS') protected readonly mainModelConstructor: CoreModelConstructor<User>,
|
|
32
|
+
@InjectModel('User') protected readonly mainDbModel: Model<UserDocument>,
|
|
42
33
|
@Inject('PUB_SUB') protected readonly pubSub: PubSub
|
|
43
34
|
) {
|
|
44
|
-
super(
|
|
45
|
-
this.model = User;
|
|
35
|
+
super(emailService, mainDbModel, mainModelConstructor);
|
|
46
36
|
}
|
|
47
37
|
|
|
48
38
|
// ===================================================================================================================
|
|
@@ -52,43 +42,48 @@ export class UserService extends CoreUserService<User, UserInput, UserCreateInpu
|
|
|
52
42
|
/**
|
|
53
43
|
* Create new user and send welcome email
|
|
54
44
|
*/
|
|
55
|
-
async create(input: UserCreateInput,
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
45
|
+
async create(input: UserCreateInput, serviceOptions?: ServiceOptions): Promise<User> {
|
|
46
|
+
// Get prepared user
|
|
47
|
+
let user = await super.create(input, serviceOptions);
|
|
48
|
+
|
|
49
|
+
// Add the createdBy information in an additional step if it was not set by the system,
|
|
50
|
+
// because the user created himself and could not exist as currentUser before
|
|
51
|
+
if (!user.createdBy) {
|
|
52
|
+
await this.mainDbModel.findByIdAndUpdate(user.id, { createdBy: user.id });
|
|
53
|
+
user = await this.get(user.id, serviceOptions);
|
|
54
|
+
}
|
|
59
55
|
|
|
60
|
-
|
|
56
|
+
// Publish action
|
|
57
|
+
if (serviceOptions?.pubSub === undefined || serviceOptions.pubSub) {
|
|
58
|
+
await this.pubSub.publish('userCreated', User.map(user));
|
|
59
|
+
}
|
|
61
60
|
|
|
61
|
+
// Send email
|
|
62
62
|
await this.emailService.sendMail(user.email, 'Welcome', {
|
|
63
63
|
htmlTemplate: 'welcome',
|
|
64
64
|
templateData: { name: user.username, link: envConfig.email.verificationLink + '/' + user.verificationToken },
|
|
65
65
|
});
|
|
66
66
|
|
|
67
|
+
// Return created user
|
|
67
68
|
return user;
|
|
68
69
|
}
|
|
69
70
|
|
|
70
|
-
/**
|
|
71
|
-
* Get users via filter
|
|
72
|
-
*/
|
|
73
|
-
find(filterArgs?: FilterArgs, ...args: any[]): Promise<User[]> {
|
|
74
|
-
const filterQuery = Filter.convertFilterArgsToQuery(filterArgs);
|
|
75
|
-
// Return found users
|
|
76
|
-
return this.userModel.find(filterQuery[0], null, filterQuery[1]).exec();
|
|
77
|
-
}
|
|
78
|
-
|
|
79
71
|
/**
|
|
80
72
|
* Request password reset mail
|
|
81
73
|
*
|
|
82
74
|
* @param email
|
|
83
75
|
*/
|
|
84
|
-
async sendPasswordResetMail(email: string): Promise<User> {
|
|
85
|
-
|
|
76
|
+
async sendPasswordResetMail(email: string, serviceOptions?: ServiceOptions): Promise<User> {
|
|
77
|
+
// Set password reset token
|
|
78
|
+
const user = await super.setPasswordResetTokenForEmail(email, serviceOptions);
|
|
86
79
|
|
|
80
|
+
// Send email
|
|
87
81
|
await this.emailService.sendMail(user.email, 'Password reset', {
|
|
88
82
|
htmlTemplate: 'password-reset',
|
|
89
83
|
templateData: { name: user.username, link: envConfig.email.passwordResetLink + '/' + user.passwordResetToken },
|
|
90
84
|
});
|
|
91
85
|
|
|
86
|
+
// Return user
|
|
92
87
|
return user;
|
|
93
88
|
}
|
|
94
89
|
|
|
@@ -96,7 +91,7 @@ export class UserService extends CoreUserService<User, UserInput, UserCreateInpu
|
|
|
96
91
|
* Set avatar image
|
|
97
92
|
*/
|
|
98
93
|
async setAvatar(file: Express.Multer.File, user: User): Promise<string> {
|
|
99
|
-
const dbUser = await this.
|
|
94
|
+
const dbUser = await this.mainDbModel.findOne({ id: user.id }).exec();
|
|
100
95
|
// Check user
|
|
101
96
|
if (!dbUser) {
|
|
102
97
|
throw new UnauthorizedException();
|
|
@@ -124,22 +119,4 @@ export class UserService extends CoreUserService<User, UserInput, UserCreateInpu
|
|
|
124
119
|
// Return user
|
|
125
120
|
return file.filename;
|
|
126
121
|
}
|
|
127
|
-
|
|
128
|
-
// ===================================================================================================================
|
|
129
|
-
// Helper methods
|
|
130
|
-
// ===================================================================================================================
|
|
131
|
-
|
|
132
|
-
/**
|
|
133
|
-
* Prepare input before save
|
|
134
|
-
*/
|
|
135
|
-
protected async prepareInput(input: { [key: string]: any }, currentUser: User, options: { create?: boolean } = {}) {
|
|
136
|
-
return ServiceHelper.prepareInput(input, currentUser, options);
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
/**
|
|
140
|
-
* Prepare output before return
|
|
141
|
-
*/
|
|
142
|
-
protected async prepareOutput(user: User): Promise<User> {
|
|
143
|
-
return ServiceHelper.prepareOutput(user);
|
|
144
|
-
}
|
|
145
122
|
}
|
package/src/test/test.helper.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { INestApplication } from '@nestjs/common';
|
|
2
|
-
import { FastifyInstance } from 'fastify';
|
|
2
|
+
// import { FastifyInstance } from 'fastify';
|
|
3
3
|
import { jsonToGraphQLQuery } from 'json-to-graphql-query';
|
|
4
4
|
import * as LightMyRequest from 'light-my-request';
|
|
5
5
|
import * as supertest from 'supertest';
|
|
@@ -101,7 +101,8 @@ export interface TestRestOptions {
|
|
|
101
101
|
* Test helper
|
|
102
102
|
*/
|
|
103
103
|
export class TestHelper {
|
|
104
|
-
app: FastifyInstance | INestApplication;
|
|
104
|
+
// app: FastifyInstance | INestApplication;
|
|
105
|
+
app: INestApplication;
|
|
105
106
|
|
|
106
107
|
/**
|
|
107
108
|
* Constructor
|
|
@@ -202,15 +203,15 @@ export class TestHelper {
|
|
|
202
203
|
const response = await this.getResponse(token, requestConfig, statusCode, log, logError);
|
|
203
204
|
|
|
204
205
|
// Response of fastify
|
|
205
|
-
if ((this.app as FastifyInstance).inject) {
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
}
|
|
206
|
+
// if ((this.app as FastifyInstance).inject) {
|
|
207
|
+
// // Check data
|
|
208
|
+
// expect(response.headers['content-type']).toBe('application/json');
|
|
209
|
+
//
|
|
210
|
+
// // return data
|
|
211
|
+
// return JSON.parse(response.payload).data
|
|
212
|
+
// ? JSON.parse(response.payload).data[(graphql as TestGraphQLConfig).name]
|
|
213
|
+
// : JSON.parse(response.payload);
|
|
214
|
+
// }
|
|
214
215
|
|
|
215
216
|
// Check data
|
|
216
217
|
expect(response.headers['content-type']).toMatch('application/json');
|
|
@@ -322,24 +323,24 @@ export class TestHelper {
|
|
|
322
323
|
}
|
|
323
324
|
|
|
324
325
|
// Init response
|
|
325
|
-
let response: any;
|
|
326
|
-
|
|
327
|
-
// Response of fastify
|
|
328
|
-
if ((this.app as FastifyInstance).inject) {
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
}
|
|
326
|
+
// let response: any;
|
|
327
|
+
|
|
328
|
+
// // Response of fastify
|
|
329
|
+
// if ((this.app as FastifyInstance).inject) {
|
|
330
|
+
// // Get response
|
|
331
|
+
// response = await (this.app as FastifyInstance).inject(requestConfig);
|
|
332
|
+
//
|
|
333
|
+
// // Log response
|
|
334
|
+
// if (log) {
|
|
335
|
+
// console.log(response);
|
|
336
|
+
// }
|
|
337
|
+
//
|
|
338
|
+
// // Check data
|
|
339
|
+
// expect(response.statusCode).toBe(statusCode);
|
|
340
|
+
//
|
|
341
|
+
// // Return response
|
|
342
|
+
// return response;
|
|
343
|
+
// }
|
|
343
344
|
|
|
344
345
|
// Express request
|
|
345
346
|
const method: string = requestConfig.method.toLowerCase();
|
|
@@ -349,7 +350,7 @@ export class TestHelper {
|
|
|
349
350
|
}
|
|
350
351
|
|
|
351
352
|
// Response
|
|
352
|
-
response = await request.send(requestConfig.payload);
|
|
353
|
+
const response = await request.send(requestConfig.payload);
|
|
353
354
|
|
|
354
355
|
// Log response
|
|
355
356
|
if (log) {
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { FilterArgs } from '../../common/args/filter.args';
|
|
2
|
-
import { CoreUserModel } from './core-user.model';
|
|
3
|
-
import { CoreUserCreateInput } from './inputs/core-user-create.input';
|
|
4
|
-
import { CoreUserInput } from './inputs/core-user.input';
|
|
5
|
-
import { Model } from 'mongoose';
|
|
6
|
-
import { ICorePersistenceModel } from '../../common/interfaces/core-persistence-model.interface';
|
|
7
|
-
export declare abstract class CoreBasicUserService<TUser extends CoreUserModel, TUserInput extends CoreUserInput, TUserCreateInput extends CoreUserCreateInput> {
|
|
8
|
-
protected readonly userModel: Model<any>;
|
|
9
|
-
protected readonly model: ICorePersistenceModel;
|
|
10
|
-
constructor(userModel: Model<any>);
|
|
11
|
-
create(input: TUserCreateInput, ...args: any[]): Promise<TUser>;
|
|
12
|
-
get(id: string, ...args: any[]): Promise<TUser>;
|
|
13
|
-
getViaEmail(email: string, ...args: any[]): Promise<TUser>;
|
|
14
|
-
find(filterArgs?: FilterArgs, ...args: any[]): Promise<TUser[]>;
|
|
15
|
-
update(id: string, input: TUserInput, ...args: any[]): Promise<TUser>;
|
|
16
|
-
delete(id: string, ...args: any[]): Promise<TUser>;
|
|
17
|
-
}
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.CoreBasicUserService = void 0;
|
|
4
|
-
const common_1 = require("@nestjs/common");
|
|
5
|
-
const bcrypt = require("bcrypt");
|
|
6
|
-
const graphql_subscriptions_1 = require("graphql-subscriptions");
|
|
7
|
-
const filter_helper_1 = require("../../common/helpers/filter.helper");
|
|
8
|
-
const pubSub = new graphql_subscriptions_1.PubSub();
|
|
9
|
-
class CoreBasicUserService {
|
|
10
|
-
constructor(userModel) {
|
|
11
|
-
this.userModel = userModel;
|
|
12
|
-
}
|
|
13
|
-
async create(input, ...args) {
|
|
14
|
-
if (input.password) {
|
|
15
|
-
input.password = await bcrypt.hash(input.password, 10);
|
|
16
|
-
}
|
|
17
|
-
const createdUser = new this.userModel(this.model.map(input));
|
|
18
|
-
try {
|
|
19
|
-
await createdUser.save();
|
|
20
|
-
}
|
|
21
|
-
catch (error) {
|
|
22
|
-
if (error.code === 11000) {
|
|
23
|
-
throw new common_1.UnprocessableEntityException(`User with email address "${input.email}" already exists`);
|
|
24
|
-
}
|
|
25
|
-
else {
|
|
26
|
-
throw new common_1.UnprocessableEntityException();
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
pubSub.publish('userCreated', { userCreated: createdUser });
|
|
30
|
-
return createdUser;
|
|
31
|
-
}
|
|
32
|
-
async get(id, ...args) {
|
|
33
|
-
const user = await this.userModel.findOne({ id: id }).exec();
|
|
34
|
-
if (!user) {
|
|
35
|
-
throw new common_1.NotFoundException();
|
|
36
|
-
}
|
|
37
|
-
return user;
|
|
38
|
-
}
|
|
39
|
-
async getViaEmail(email, ...args) {
|
|
40
|
-
let user = await this.userModel.findOne({ email }).exec();
|
|
41
|
-
if (!user) {
|
|
42
|
-
throw new common_1.NotFoundException();
|
|
43
|
-
}
|
|
44
|
-
user = this.model.map(user);
|
|
45
|
-
return user;
|
|
46
|
-
}
|
|
47
|
-
find(filterArgs, ...args) {
|
|
48
|
-
return this.userModel.find(...filter_helper_1.Filter.convertFilterArgsToQuery(filterArgs)).exec();
|
|
49
|
-
}
|
|
50
|
-
async update(id, input, ...args) {
|
|
51
|
-
let user = await this.userModel.findOne({ id });
|
|
52
|
-
if (!user) {
|
|
53
|
-
throw new common_1.NotFoundException(`User not found with ID: ${id}`);
|
|
54
|
-
}
|
|
55
|
-
if (input.password) {
|
|
56
|
-
input.password = await bcrypt.hash(input.password, 10);
|
|
57
|
-
}
|
|
58
|
-
user.set(input);
|
|
59
|
-
await user.save();
|
|
60
|
-
user = this.model.map(user);
|
|
61
|
-
return user;
|
|
62
|
-
}
|
|
63
|
-
async delete(id, ...args) {
|
|
64
|
-
const user = await this.userModel.findOne({ id }).exec();
|
|
65
|
-
if (!user) {
|
|
66
|
-
throw new common_1.NotFoundException();
|
|
67
|
-
}
|
|
68
|
-
await this.userModel.deleteOne({ id: user.id });
|
|
69
|
-
return user;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
exports.CoreBasicUserService = CoreBasicUserService;
|
|
73
|
-
//# sourceMappingURL=core-basic-user.service.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"core-basic-user.service.js","sourceRoot":"","sources":["../../../../src/core/modules/user/core-basic-user.service.ts"],"names":[],"mappings":";;;AAAA,2CAAiF;AACjF,iCAAiC;AACjC,iEAA+C;AAE/C,sEAA4D;AAQ5D,MAAM,MAAM,GAAG,IAAI,8BAAM,EAAE,CAAC;AAK5B,MAAsB,oBAAoB;IAOxC,YAA+B,SAAqB;QAArB,cAAS,GAAT,SAAS,CAAY;IAAG,CAAC;IAKxD,KAAK,CAAC,MAAM,CAAC,KAAuB,EAAE,GAAG,IAAW;QAElD,IAAK,KAAa,CAAC,QAAQ,EAAE;YAC1B,KAAa,CAAC,QAAQ,GAAG,MAAM,MAAM,CAAC,IAAI,CAAE,KAAa,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;SAC1E;QAGD,MAAM,WAAW,GAAG,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;QAE9D,IAAI;YAEF,MAAM,WAAW,CAAC,IAAI,EAAE,CAAC;SAC1B;QAAC,OAAO,KAAK,EAAE;YACd,IAAI,KAAK,CAAC,IAAI,KAAK,KAAK,EAAE;gBACxB,MAAM,IAAI,qCAA4B,CAAC,4BAA6B,KAAa,CAAC,KAAK,kBAAkB,CAAC,CAAC;aAC5G;iBAAM;gBACL,MAAM,IAAI,qCAA4B,EAAE,CAAC;aAC1C;SACF;QAGD,MAAM,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,WAAW,EAAE,WAAW,EAAE,CAAC,CAAC;QAG5D,OAAO,WAAW,CAAC;IACrB,CAAC;IAKD,KAAK,CAAC,GAAG,CAAC,EAAU,EAAE,GAAG,IAAW;QAClC,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QAC7D,IAAI,CAAC,IAAI,EAAE;YACT,MAAM,IAAI,0BAAiB,EAAE,CAAC;SAC/B;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAKD,KAAK,CAAC,WAAW,CAAC,KAAa,EAAE,GAAG,IAAW;QAC7C,IAAI,IAAI,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QAE1D,IAAI,CAAC,IAAI,EAAE;YACT,MAAM,IAAI,0BAAiB,EAAE,CAAC;SAC/B;QAED,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAE5B,OAAO,IAAI,CAAC;IACd,CAAC;IAKD,IAAI,CAAC,UAAuB,EAAE,GAAG,IAAW;QAE1C,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,sBAAM,CAAC,wBAAwB,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IACpF,CAAC;IAKD,KAAK,CAAC,MAAM,CAAC,EAAU,EAAE,KAAiB,EAAE,GAAG,IAAW;QAExD,IAAI,IAAI,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;QAEhD,IAAI,CAAC,IAAI,EAAE;YACT,MAAM,IAAI,0BAAiB,CAAC,2BAA2B,EAAE,EAAE,CAAC,CAAC;SAC9D;QAGD,IAAK,KAAa,CAAC,QAAQ,EAAE;YAC1B,KAAa,CAAC,QAAQ,GAAG,MAAM,MAAM,CAAC,IAAI,CAAE,KAAa,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;SAC1E;QAGD,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAGhB,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QAGlB,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAG5B,OAAO,IAAI,CAAC;IACd,CAAC;IAKD,KAAK,CAAC,MAAM,CAAC,EAAU,EAAE,GAAG,IAAW;QAErC,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QAGzD,IAAI,CAAC,IAAI,EAAE;YACT,MAAM,IAAI,0BAAiB,EAAE,CAAC;SAC/B;QAGD,MAAM,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;QAGhD,OAAO,IAAI,CAAC;IACd,CAAC;CACF;AAxHD,oDAwHC"}
|
|
@@ -1,138 +0,0 @@
|
|
|
1
|
-
import { NotFoundException, UnprocessableEntityException } from '@nestjs/common';
|
|
2
|
-
import * as bcrypt from 'bcrypt';
|
|
3
|
-
import { PubSub } from 'graphql-subscriptions';
|
|
4
|
-
import { FilterArgs } from '../../common/args/filter.args';
|
|
5
|
-
import { Filter } from '../../common/helpers/filter.helper';
|
|
6
|
-
import { CoreUserModel } from './core-user.model';
|
|
7
|
-
import { CoreUserCreateInput } from './inputs/core-user-create.input';
|
|
8
|
-
import { CoreUserInput } from './inputs/core-user.input';
|
|
9
|
-
import { Model } from 'mongoose';
|
|
10
|
-
import { ICorePersistenceModel } from '../../common/interfaces/core-persistence-model.interface';
|
|
11
|
-
|
|
12
|
-
// Subscription
|
|
13
|
-
const pubSub = new PubSub();
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* User service
|
|
17
|
-
*/
|
|
18
|
-
export abstract class CoreBasicUserService<
|
|
19
|
-
TUser extends CoreUserModel,
|
|
20
|
-
TUserInput extends CoreUserInput,
|
|
21
|
-
TUserCreateInput extends CoreUserCreateInput
|
|
22
|
-
> {
|
|
23
|
-
protected readonly model: ICorePersistenceModel;
|
|
24
|
-
|
|
25
|
-
constructor(protected readonly userModel: Model<any>) {}
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Create user
|
|
29
|
-
*/
|
|
30
|
-
async create(input: TUserCreateInput, ...args: any[]): Promise<TUser> {
|
|
31
|
-
// Prepare input
|
|
32
|
-
if ((input as any).password) {
|
|
33
|
-
(input as any).password = await bcrypt.hash((input as any).password, 10);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
// Create new user
|
|
37
|
-
const createdUser = new this.userModel(this.model.map(input));
|
|
38
|
-
|
|
39
|
-
try {
|
|
40
|
-
// Save created user
|
|
41
|
-
await createdUser.save();
|
|
42
|
-
} catch (error) {
|
|
43
|
-
if (error.code === 11000) {
|
|
44
|
-
throw new UnprocessableEntityException(`User with email address "${(input as any).email}" already exists`);
|
|
45
|
-
} else {
|
|
46
|
-
throw new UnprocessableEntityException();
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
// Inform subscriber
|
|
51
|
-
pubSub.publish('userCreated', { userCreated: createdUser });
|
|
52
|
-
|
|
53
|
-
// Return created user
|
|
54
|
-
return createdUser;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Get user via ID
|
|
59
|
-
*/
|
|
60
|
-
async get(id: string, ...args: any[]): Promise<TUser> {
|
|
61
|
-
const user = await this.userModel.findOne({ id: id }).exec();
|
|
62
|
-
if (!user) {
|
|
63
|
-
throw new NotFoundException();
|
|
64
|
-
}
|
|
65
|
-
return user;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* Get user via email
|
|
70
|
-
*/
|
|
71
|
-
async getViaEmail(email: string, ...args: any[]): Promise<TUser> {
|
|
72
|
-
let user = await this.userModel.findOne({ email }).exec();
|
|
73
|
-
|
|
74
|
-
if (!user) {
|
|
75
|
-
throw new NotFoundException();
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
user = this.model.map(user);
|
|
79
|
-
|
|
80
|
-
return user;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* Get users via filter
|
|
85
|
-
*/
|
|
86
|
-
find(filterArgs?: FilterArgs, ...args: any[]): Promise<TUser[]> {
|
|
87
|
-
// Return found users
|
|
88
|
-
return this.userModel.find(...Filter.convertFilterArgsToQuery(filterArgs)).exec();
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* Get user via ID
|
|
93
|
-
*/
|
|
94
|
-
async update(id: string, input: TUserInput, ...args: any[]): Promise<TUser> {
|
|
95
|
-
// Check if user exists
|
|
96
|
-
let user = await this.userModel.findOne({ id });
|
|
97
|
-
|
|
98
|
-
if (!user) {
|
|
99
|
-
throw new NotFoundException(`User not found with ID: ${id}`);
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
// Prepare input
|
|
103
|
-
if ((input as any).password) {
|
|
104
|
-
(input as any).password = await bcrypt.hash((input as any).password, 10);
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
// Update
|
|
108
|
-
user.set(input);
|
|
109
|
-
|
|
110
|
-
// Save
|
|
111
|
-
await user.save();
|
|
112
|
-
|
|
113
|
-
// Map for response
|
|
114
|
-
user = this.model.map(user);
|
|
115
|
-
|
|
116
|
-
// Return user
|
|
117
|
-
return user;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
/**
|
|
121
|
-
* Delete user via ID
|
|
122
|
-
*/
|
|
123
|
-
async delete(id: string, ...args: any[]): Promise<TUser> {
|
|
124
|
-
// Search user
|
|
125
|
-
const user = await this.userModel.findOne({ id }).exec();
|
|
126
|
-
|
|
127
|
-
// Check user
|
|
128
|
-
if (!user) {
|
|
129
|
-
throw new NotFoundException();
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
// Delete user
|
|
133
|
-
await this.userModel.deleteOne({ id: user.id });
|
|
134
|
-
|
|
135
|
-
// Return deleted user
|
|
136
|
-
return user;
|
|
137
|
-
}
|
|
138
|
-
}
|