@drax/identity-back 0.5.2 → 0.5.4

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.
Files changed (60) hide show
  1. package/dist/controllers/RoleController.js +84 -0
  2. package/dist/controllers/TenantController.js +1 -2
  3. package/dist/controllers/UserApiKeyController.js +127 -0
  4. package/dist/controllers/UserController.js +295 -0
  5. package/dist/index.js +1 -2
  6. package/dist/repository/mongo/RoleMongoRepository.js +12 -3
  7. package/dist/repository/mongo/TenantMongoRepository.js +11 -0
  8. package/dist/routes/RoleRoutes.js +11 -207
  9. package/dist/routes/TenantRoutes.js +1 -0
  10. package/dist/routes/UserApiKeyRoutes.js +6 -114
  11. package/dist/routes/UserRoutes.js +12 -218
  12. package/dist/services/RoleService.js +42 -2
  13. package/dist/services/TenantService.js +5 -0
  14. package/dist/services/UserApiKeyService.js +9 -1
  15. package/dist/services/UserService.js +14 -4
  16. package/dist/setup/CreateOrUpdateRole.js +1 -1
  17. package/package.json +5 -5
  18. package/src/controllers/RoleController.ts +94 -0
  19. package/src/controllers/TenantController.ts +1 -2
  20. package/src/controllers/UserApiKeyController.ts +144 -0
  21. package/src/controllers/UserController.ts +300 -0
  22. package/src/index.ts +0 -2
  23. package/src/repository/mongo/RoleMongoRepository.ts +12 -3
  24. package/src/repository/mongo/TenantMongoRepository.ts +11 -0
  25. package/src/routes/RoleRoutes.ts +11 -186
  26. package/src/routes/TenantRoutes.ts +2 -0
  27. package/src/routes/UserApiKeyRoutes.ts +6 -113
  28. package/src/routes/UserRoutes.ts +12 -202
  29. package/src/services/RoleService.ts +45 -4
  30. package/src/services/TenantService.ts +7 -1
  31. package/src/services/UserApiKeyService.ts +11 -1
  32. package/src/services/UserService.ts +16 -4
  33. package/src/setup/CreateOrUpdateRole.ts +1 -1
  34. package/tsconfig.tsbuildinfo +1 -1
  35. package/types/controllers/RoleController.d.ts +14 -0
  36. package/types/controllers/RoleController.d.ts.map +1 -0
  37. package/types/controllers/TenantController.d.ts.map +1 -1
  38. package/types/controllers/UserApiKeyController.d.ts +14 -0
  39. package/types/controllers/UserApiKeyController.d.ts.map +1 -0
  40. package/types/controllers/UserController.d.ts +27 -0
  41. package/types/controllers/UserController.d.ts.map +1 -0
  42. package/types/index.d.ts +1 -2
  43. package/types/index.d.ts.map +1 -1
  44. package/types/repository/mongo/RoleMongoRepository.d.ts +2 -0
  45. package/types/repository/mongo/RoleMongoRepository.d.ts.map +1 -1
  46. package/types/repository/mongo/TenantMongoRepository.d.ts +2 -0
  47. package/types/repository/mongo/TenantMongoRepository.d.ts.map +1 -1
  48. package/types/routes/RoleRoutes.d.ts.map +1 -1
  49. package/types/routes/TenantRoutes.d.ts.map +1 -1
  50. package/types/routes/UserApiKeyRoutes.d.ts.map +1 -1
  51. package/types/routes/UserRoutes.d.ts.map +1 -1
  52. package/types/services/RoleService.d.ts +5 -1
  53. package/types/services/RoleService.d.ts.map +1 -1
  54. package/types/services/TenantService.d.ts +1 -0
  55. package/types/services/TenantService.d.ts.map +1 -1
  56. package/types/services/UserApiKeyService.d.ts +2 -1
  57. package/types/services/UserApiKeyService.d.ts.map +1 -1
  58. package/types/services/UserService.d.ts +3 -1
  59. package/types/services/UserService.d.ts.map +1 -1
  60. package/src/routes/UserAvatarRoutes.ts +0 -82
@@ -4,8 +4,10 @@ import { ZodError } from "zod";
4
4
  import crypto from "node:crypto";
5
5
  import AuthUtils from "../utils/AuthUtils.js";
6
6
  import IdentityConfig from "../config/IdentityConfig.js";
7
- class UserApiKeyService {
7
+ import { AbstractService } from "@drax/crud-back";
8
+ class UserApiKeyService extends AbstractService {
8
9
  constructor(userApiKeyRepostitory) {
10
+ super(userApiKeyRepostitory, userApiKeySchema);
9
11
  this._repository = userApiKeyRepostitory;
10
12
  console.log("UserApiKeyService constructor");
11
13
  }
@@ -14,6 +16,9 @@ class UserApiKeyService {
14
16
  userApiKeyData.name = userApiKeyData?.name?.trim();
15
17
  const secret = crypto.randomUUID();
16
18
  const APIKEY_SECRET = DraxConfig.getOrLoad(IdentityConfig.ApiKeySecret);
19
+ if (!APIKEY_SECRET) {
20
+ throw new Error('ApiKey miss configuration');
21
+ }
17
22
  userApiKeyData.secret = AuthUtils.generateHMAC(APIKEY_SECRET, secret);
18
23
  await userApiKeySchema.parseAsync(userApiKeyData);
19
24
  const userApiKey = await this._repository.create(userApiKeyData);
@@ -67,6 +72,9 @@ class UserApiKeyService {
67
72
  async findBySecret(secret) {
68
73
  try {
69
74
  const APIKEY_SECRET = DraxConfig.getOrLoad(IdentityConfig.ApiKeySecret);
75
+ if (!APIKEY_SECRET) {
76
+ throw new Error('ApiKey miss configuration');
77
+ }
70
78
  const hashedSecret = AuthUtils.generateHMAC(APIKEY_SECRET, secret);
71
79
  const userApiKey = await this._repository.findBySecret(hashedSecret);
72
80
  return userApiKey;
@@ -1,10 +1,12 @@
1
1
  import { ZodError } from "zod";
2
2
  import { ValidationError, ZodErrorToValidationError } from "@drax/common-back";
3
3
  import AuthUtils from "../utils/AuthUtils.js";
4
- import { createUserSchema, editUserSchema, } from "../zod/UserZod.js";
4
+ import { createUserSchema, editUserSchema, userBaseSchema } from "../zod/UserZod.js";
5
5
  import BadCredentialsError from "../errors/BadCredentialsError.js";
6
- class UserService {
6
+ import { AbstractService } from "@drax/crud-back";
7
+ class UserService extends AbstractService {
7
8
  constructor(userRepository) {
9
+ super(userRepository, userBaseSchema);
8
10
  this._repository = userRepository;
9
11
  console.log("UserService constructor");
10
12
  }
@@ -101,8 +103,11 @@ class UserService {
101
103
  }
102
104
  async delete(id) {
103
105
  try {
104
- const deletedRole = await this._repository.delete(id);
105
- return deletedRole;
106
+ const result = await this._repository.delete(id);
107
+ if (!result) {
108
+ throw new Error("error.deletionFailed");
109
+ }
110
+ return result;
106
111
  }
107
112
  catch (e) {
108
113
  console.error("Error deleting user", e);
@@ -139,5 +144,10 @@ class UserService {
139
144
  throw e;
140
145
  }
141
146
  }
147
+ async search(value) {
148
+ const limit = 100;
149
+ const users = await this._repository.search(value, limit);
150
+ return users;
151
+ }
142
152
  }
143
153
  export default UserService;
@@ -15,7 +15,7 @@ async function CreateOrUpdateRole(roleData) {
15
15
  }));
16
16
  }
17
17
  if (role) {
18
- const r = await roleService.update(role.id, roleData);
18
+ const r = await roleService.systemUpdate(role.id, roleData);
19
19
  console.log("Role Updated. Name: " + roleData.name);
20
20
  }
21
21
  else {
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "0.5.2",
6
+ "version": "0.5.4",
7
7
  "description": "Identity module for user management, authentication and authorization.",
8
8
  "main": "dist/index.js",
9
9
  "types": "dist/types/index.d.ts",
@@ -28,9 +28,9 @@
28
28
  "author": "Cristian Incarnato & Drax Team",
29
29
  "license": "ISC",
30
30
  "dependencies": {
31
- "@drax/common-back": "^0.5.2",
32
- "@drax/crud-back": "^0.5.2",
33
- "@drax/crud-share": "^0.5.2",
31
+ "@drax/common-back": "^0.5.3",
32
+ "@drax/crud-back": "^0.5.4",
33
+ "@drax/crud-share": "^0.5.4",
34
34
  "@drax/identity-share": "^0.5.1",
35
35
  "bcryptjs": "^2.4.3",
36
36
  "express-jwt": "^8.4.1",
@@ -62,5 +62,5 @@
62
62
  "debug": "0"
63
63
  }
64
64
  },
65
- "gitHead": "6f854dbeb2af7bca32ed35bcec2f8e48790a73b9"
65
+ "gitHead": "6db0bebb2df9edecd2c3caa7288fb5c7001c4243"
66
66
  }
@@ -0,0 +1,94 @@
1
+ import type {IRole, IRoleBase} from "@drax/identity-share";
2
+ import {AbstractFastifyController} from "@drax/crud-back";
3
+ import {ValidationError, UnauthorizedError} from "@drax/common-back";
4
+
5
+ import RoleServiceFactory from "../factory/RoleServiceFactory.js";
6
+ import RoleService from "../services/RoleService.js";
7
+ import RolePermissions from "../permissions/RolePermissions.js";
8
+ import PermissionService from "../services/PermissionService.js";
9
+
10
+ class RoleController extends AbstractFastifyController<IRole, IRoleBase, IRoleBase> {
11
+
12
+ protected service: RoleService
13
+
14
+ constructor() {
15
+ super(RoleServiceFactory(), RolePermissions)
16
+ }
17
+
18
+ async findByName(request, reply) {
19
+ try {
20
+ request.rbac.assertPermission(RolePermissions.View)
21
+ const name = request.params.name
22
+ const roleService = RoleServiceFactory()
23
+ let role = await roleService.findByName(name)
24
+ return role
25
+ } catch (e) {
26
+ console.error(e)
27
+ if (e instanceof ValidationError) {
28
+ reply.statusCode = e.statusCode
29
+ reply.send({error: e.message, inputErrors: e.errors})
30
+ } else if (e instanceof UnauthorizedError) {
31
+ reply.statusCode = e.statusCode
32
+ reply.send({error: e.message})
33
+ } else {
34
+ reply.statusCode = 500
35
+ reply.send({error: 'INTERNAL_SERVER_ERROR'})
36
+ }
37
+ }
38
+ }
39
+
40
+ async all(request, reply) {
41
+ try {
42
+ request.rbac.assertPermission(RolePermissions.View)
43
+ const roleService = RoleServiceFactory()
44
+ let roles = await roleService.fetchAll()
45
+ if(request.rbac.getRole?.childRoles?.length > 0) {
46
+ return roles.filter(role => request.rbac.getRole.childRoles.some(childRole => childRole.id === role.id));
47
+ }else{
48
+ return roles
49
+ }
50
+ } catch (e) {
51
+ console.error(e)
52
+ if (e instanceof ValidationError) {
53
+ reply.statusCode = e.statusCode
54
+ reply.send({error: e.message, inputErrors: e.errors})
55
+ } else if (e instanceof UnauthorizedError) {
56
+ reply.statusCode = e.statusCode
57
+ reply.send({error: e.message})
58
+ } else {
59
+ reply.statusCode = 500
60
+ reply.send({error: 'INTERNAL_SERVER_ERROR'})
61
+ }
62
+ }
63
+ }
64
+
65
+ async permissions(request, reply) {
66
+ try {
67
+ request.rbac.assertPermission(RolePermissions.Permissions)
68
+ let permissions = PermissionService.getPermissions()
69
+ return permissions
70
+ }catch (e){
71
+ console.error(e)
72
+ if (e instanceof UnauthorizedError) {
73
+ reply.statusCode = e.statusCode
74
+ reply.send({error: e.message})
75
+ } else {
76
+ reply.statusCode = 500
77
+ reply.send({error: 'INTERNAL_SERVER_ERROR'})
78
+ }
79
+ }
80
+ }
81
+
82
+
83
+
84
+ async xxxx(request, reply) {
85
+
86
+ }
87
+
88
+ }
89
+
90
+ export default RoleController;
91
+ export {
92
+ RoleController
93
+ }
94
+
@@ -1,11 +1,10 @@
1
1
  import type {ITenant, ITenantBase} from "@drax/identity-share";
2
2
  import {AbstractFastifyController} from "@drax/crud-back";
3
- import {ValidationError} from "@drax/common-back";
3
+ import {ValidationError, UnauthorizedError} from "@drax/common-back";
4
4
 
5
5
  import TenantServiceFactory from "../factory/TenantServiceFactory.js";
6
6
  import TenantService from "../services/TenantService.js";
7
7
  import TenantPermissions from "../permissions/TenantPermissions.js";
8
- import {UnauthorizedError} from "@drax/common-back";
9
8
 
10
9
  class TenantController extends AbstractFastifyController<ITenant, ITenantBase, ITenantBase> {
11
10
 
@@ -0,0 +1,144 @@
1
+ import type {IUserApiKey, IUserApiKeyBase} from "@drax/identity-share";
2
+ import {AbstractFastifyController} from "@drax/crud-back";
3
+ import {ValidationError, UnauthorizedError} from "@drax/common-back";
4
+
5
+ import UserApiKeyServiceFactory from "../factory/UserApiKeyServiceFactory.js";
6
+ import UserApiKeyService from "../services/UserApiKeyService.js";
7
+ import UserApiKeyPermissions from "../permissions/UserApiKeyPermissions.js";
8
+
9
+ class UserApiKeyController extends AbstractFastifyController<IUserApiKey, IUserApiKeyBase, IUserApiKeyBase> {
10
+
11
+ protected service: UserApiKeyService
12
+
13
+ constructor() {
14
+ super(UserApiKeyServiceFactory(), UserApiKeyPermissions)
15
+ }
16
+
17
+
18
+ async paginate(request, reply) {
19
+ try {
20
+ request.rbac.assertAuthenticated()
21
+
22
+ request.rbac.assertOrPermissions([
23
+ UserApiKeyPermissions.View,
24
+ UserApiKeyPermissions.ViewMy
25
+ ])
26
+
27
+ const filters = []
28
+
29
+ if(!request.rbac.hasPermission(UserApiKeyPermissions.View)){
30
+ filters.push({field: "user", operator: "eq", value: request.rbac.authUser.id})
31
+ }
32
+
33
+ const page = request.query.page
34
+ const limit = request.query.limit
35
+ const orderBy = request.query.orderBy
36
+ const order = request.query.order
37
+ const search = request.query.search
38
+ const userApiKeyService = UserApiKeyServiceFactory()
39
+
40
+
41
+ let paginateResult = await userApiKeyService.paginate({page, limit, orderBy, order, search, filters})
42
+ return paginateResult
43
+ } catch (e) {
44
+ console.log("/api/user-api-keys",e)
45
+ if (e instanceof ValidationError) {
46
+ reply.statusCode = e.statusCode
47
+ reply.send({error: e.message, inputErrors: e.errors})
48
+ } else if (e instanceof UnauthorizedError) {
49
+ reply.statusCode = e.statusCode
50
+ reply.send({error: e.message})
51
+ } else {
52
+ reply.statusCode = 500
53
+ reply.send({error: 'error.server'})
54
+ }
55
+ }
56
+
57
+ }
58
+
59
+ async create(request, reply) {
60
+ try {
61
+ request.rbac.assertPermission(UserApiKeyPermissions.Create)
62
+ const payload = request.body
63
+ payload.user = request.rbac.authUser.id
64
+
65
+ const userApiKeyService = UserApiKeyServiceFactory()
66
+
67
+ let userApiKey = await userApiKeyService.create(payload)
68
+ return userApiKey
69
+ } catch (e) {
70
+ if (e instanceof ValidationError) {
71
+ reply.statusCode = e.statusCode
72
+ reply.send({error: e.message, inputErrors: e.errors})
73
+ } else if (e instanceof UnauthorizedError) {
74
+ reply.statusCode = e.statusCode
75
+ reply.send({error: e.message})
76
+ } else {
77
+ reply.statusCode = 500
78
+ reply.send({error: 'error.server'})
79
+ }
80
+ }
81
+
82
+ }
83
+
84
+
85
+ async update(request, reply) {
86
+ try {
87
+ request.rbac.assertPermission(UserApiKeyPermissions.Update)
88
+ const id = request.params.id
89
+ const payload = request.body
90
+ const userApiKeyService = UserApiKeyServiceFactory()
91
+ let userApiKey = await userApiKeyService.update(id, payload)
92
+ return userApiKey
93
+ } catch (e) {
94
+ if (e instanceof ValidationError) {
95
+ reply.statusCode = e.statusCode
96
+ reply.send({error: e.message, inputErrors: e.errors})
97
+ }
98
+ if (e instanceof UnauthorizedError) {
99
+ reply.statusCode = e.statusCode
100
+ reply.send({error: e.message})
101
+ } else if (e instanceof UnauthorizedError) {
102
+ reply.statusCode = e.statusCode
103
+ reply.send({error: e.message})
104
+ } else {
105
+ reply.statusCode = 500
106
+ reply.send({error: 'error.server'})
107
+ }
108
+ }
109
+
110
+ }
111
+
112
+ async delete(request, reply) : Promise<void> {
113
+ try {
114
+ request.rbac.assertPermission(UserApiKeyPermissions.Delete)
115
+ const id = request.params.id
116
+ const userApiKeyService = UserApiKeyServiceFactory()
117
+ let r = await userApiKeyService.delete(id)
118
+ if(r){
119
+ reply.send({message: 'Deleted successfully'})
120
+ }else{
121
+ reply.statusCode(400).send({message: 'Not deleted'})
122
+ }
123
+ } catch (e) {
124
+ if (e instanceof ValidationError) {
125
+ reply.statusCode = e.statusCode
126
+ reply.send({error: e.message, inputErrors: e.errors})
127
+ } else if (e instanceof UnauthorizedError) {
128
+ reply.statusCode = e.statusCode
129
+ reply.send({error: e.message})
130
+ } else {
131
+ reply.statusCode = 500
132
+ reply.send({error: 'error.server'})
133
+ }
134
+ }
135
+
136
+ }
137
+
138
+ }
139
+
140
+ export default UserApiKeyController;
141
+ export {
142
+ UserApiKeyController
143
+ }
144
+
@@ -0,0 +1,300 @@
1
+ import type {IUser, IUserUpdate, IUserCreate} from "@drax/identity-share";
2
+ import {AbstractFastifyController} from "@drax/crud-back";
3
+ import {CommonConfig, DraxConfig, StoreManager, UploadFileError, ValidationError, UnauthorizedError} from "@drax/common-back";
4
+
5
+ import UserServiceFactory from "../factory/UserServiceFactory.js";
6
+ import UserService from "../services/UserService.js";
7
+ import UserPermissions from "../permissions/UserPermissions.js";
8
+ import BadCredentialsError from "../errors/BadCredentialsError.js";
9
+ import {join} from "path";
10
+ import {IdentityConfig} from "../config/IdentityConfig.js";
11
+
12
+ const BASE_FILE_DIR = DraxConfig.getOrLoad(CommonConfig.FileDir) || 'files';
13
+ const AVATAR_DIR = DraxConfig.getOrLoad(IdentityConfig.AvatarDir) || 'avatar';
14
+ const BASE_URL = DraxConfig.getOrLoad(CommonConfig.BaseUrl) ? DraxConfig.get(CommonConfig.BaseUrl).replace(/\/$/, '') : ''
15
+
16
+
17
+ class UserController extends AbstractFastifyController<IUser, IUserCreate, IUserUpdate> {
18
+
19
+ protected service: UserService
20
+
21
+ constructor() {
22
+ super(UserServiceFactory(), UserPermissions)
23
+ }
24
+
25
+ async auth(request, reply) {
26
+ try {
27
+ const username = request.body.username
28
+ const password = request.body.password
29
+ const userService = UserServiceFactory()
30
+ return await userService.auth(username, password)
31
+ } catch (e) {
32
+ console.error('/api/auth error', e)
33
+ if (e instanceof BadCredentialsError) {
34
+ reply.code(401)
35
+ reply.send({error: e.message})
36
+ }
37
+ reply.code(500)
38
+ reply.send({error: 'error.server'})
39
+ }
40
+ }
41
+
42
+ async me(request, reply) {
43
+ try {
44
+ if (request.authUser) {
45
+ const userService = UserServiceFactory()
46
+ let user = await userService.findById(request.authUser.id)
47
+ user.password = undefined
48
+ delete user.password
49
+ return user
50
+ } else {
51
+ throw new UnauthorizedError()
52
+
53
+ }
54
+ } catch (e) {
55
+ if (e instanceof UnauthorizedError) {
56
+ reply.code(401)
57
+ reply.send({error: "Unauthorized"})
58
+ } else if (e instanceof UnauthorizedError) {
59
+ reply.statusCode = e.statusCode
60
+ reply.send({error: e.message})
61
+ } else {
62
+ reply.statusCode = 500
63
+ reply.send({error: 'error.server'})
64
+ }
65
+ }
66
+ }
67
+
68
+ async paginate(request, reply) {
69
+ try {
70
+ request.rbac.assertPermission(UserPermissions.View)
71
+ const page = request.query.page
72
+ const limit = request.query.limit
73
+ const orderBy = request.query.orderBy
74
+ const order = request.query.order
75
+ const search = request.query.search
76
+ const userService = UserServiceFactory()
77
+ const filters = []
78
+ if(request.rbac.getAuthUser.tenantId){
79
+ filters.push({field: 'tenant', operator: 'eq', value: request.rbac.getAuthUser.tenantId})
80
+ }
81
+ let paginateResult = await userService.paginate({page, limit, orderBy, order, search, filters})
82
+ for(let item of paginateResult.items){
83
+ item.password = undefined
84
+ delete item.password
85
+ }
86
+ return paginateResult
87
+ } catch (e) {
88
+ if (e instanceof ValidationError) {
89
+ reply.statusCode = e.statusCode
90
+ reply.send({error: e.message, inputErrors: e.errors})
91
+ } else if (e instanceof UnauthorizedError) {
92
+ reply.statusCode = e.statusCode
93
+ reply.send({error: e.message})
94
+ } else {
95
+ reply.statusCode = 500
96
+ reply.send({error: 'error.server'})
97
+ }
98
+ }
99
+ }
100
+
101
+ async create(request, reply) {
102
+ try {
103
+ request.rbac.assertPermission(UserPermissions.Create)
104
+ const payload = request.body
105
+ const userService = UserServiceFactory()
106
+ if(request.rbac.getAuthUser.tenantId){
107
+ payload.tenant = request.rbac.getAuthUser.tenantId
108
+ }
109
+ let user = await userService.create(payload)
110
+ return user
111
+ } catch (e) {
112
+ if (e instanceof ValidationError) {
113
+ reply.statusCode = e.statusCode
114
+ reply.send({error: e.message, inputErrors: e.errors})
115
+ } else if (e instanceof UnauthorizedError) {
116
+ reply.statusCode = e.statusCode
117
+ reply.send({error: e.message})
118
+ } else {
119
+ reply.statusCode = 500
120
+ reply.send({error: 'error.server'})
121
+ }
122
+ }
123
+ }
124
+
125
+ async update(request, reply) {
126
+ try {
127
+ request.rbac.assertPermission(UserPermissions.Update)
128
+ const id = request.params.id
129
+ const payload = request.body
130
+ const userService = UserServiceFactory()
131
+ if(request.rbac.getAuthUser.tenantId){
132
+ payload.tenant = request.rbac.getAuthUser.tenantId
133
+ }
134
+ let user = await userService.update(id, payload)
135
+ return user
136
+ } catch (e) {
137
+ if (e instanceof ValidationError) {
138
+ reply.statusCode = e.statusCode
139
+ reply.send({error: e.message, inputErrors: e.errors})
140
+ }
141
+ if (e instanceof UnauthorizedError) {
142
+ reply.statusCode = e.statusCode
143
+ reply.send({error: e.message})
144
+ } else if (e instanceof UnauthorizedError) {
145
+ reply.statusCode = e.statusCode
146
+ reply.send({error: e.message})
147
+ } else {
148
+ reply.statusCode = 500
149
+ reply.send({error: 'error.server'})
150
+ }
151
+ }
152
+ }
153
+
154
+ async delete(request, reply) {
155
+ try {
156
+ request.rbac.assertPermission(UserPermissions.Delete)
157
+ const id = request.params.id
158
+ const userService = UserServiceFactory()
159
+ let r : boolean = await userService.delete(id)
160
+ if(r){
161
+ reply.send({message: 'Deleted successfully'})
162
+ }else{
163
+ reply.statusCode(400).send({message: 'Not deleted'})
164
+ }
165
+ } catch (e) {
166
+ if (e instanceof ValidationError) {
167
+ reply.statusCode = e.statusCode
168
+ reply.send({error: e.message, inputErrors: e.errors})
169
+ } else if (e instanceof UnauthorizedError) {
170
+ reply.statusCode = e.statusCode
171
+ reply.send({error: e.message})
172
+ } else {
173
+ reply.statusCode = 500
174
+ reply.send({error: 'error.server'})
175
+ }
176
+ }
177
+ }
178
+
179
+ async myPassword(request, reply) {
180
+ try {
181
+ if(!request.authUser){
182
+ throw new UnauthorizedError()
183
+ }
184
+ const userId = request.authUser.id
185
+ const currentPassword = request.body.currentPassword
186
+ const newPassword = request.body.newPassword
187
+ const userService = UserServiceFactory()
188
+ return await userService.changeOwnPassword(userId, currentPassword, newPassword)
189
+ } catch (e) {
190
+ console.error('/api/password error', e)
191
+ if (e instanceof ValidationError) {
192
+ reply.statusCode = e.statusCode
193
+ reply.send({error: e.message, inputErrors: e.errors})
194
+ } else if (e instanceof UnauthorizedError) {
195
+ reply.statusCode = e.statusCode
196
+ reply.send({error: e.message})
197
+ } else {
198
+ reply.statusCode = 500
199
+ reply.send({error: 'error.server'})
200
+ }
201
+ }
202
+ }
203
+
204
+ async password(request, reply) {
205
+ try {
206
+ request.rbac.assertPermission(UserPermissions.Update)
207
+ const userId = request.params.id
208
+ if(!userId){
209
+ throw new UnauthorizedError()
210
+ }
211
+ const newPassword = request.body.newPassword
212
+ const userService = UserServiceFactory()
213
+ return await userService.changeUserPassword(userId, newPassword)
214
+ } catch (e) {
215
+ console.error('/api/password error', e)
216
+ if (e instanceof ValidationError) {
217
+ reply.statusCode = e.statusCode
218
+ reply.send({error: e.message, inputErrors: e.errors})
219
+ } else if (e instanceof UnauthorizedError) {
220
+ reply.statusCode = e.statusCode
221
+ reply.send({error: e.message})
222
+ } else {
223
+ reply.statusCode = 500
224
+ reply.send({error: 'error.server'})
225
+ }
226
+ }
227
+ }
228
+
229
+
230
+ async updateAvatar(request, reply) {
231
+ try {
232
+ request.rbac.assertAuthenticated()
233
+ const userId = request.rbac.getAuthUser.id
234
+
235
+ const data = await request.file()
236
+
237
+ const file = {
238
+ filename: data.filename,
239
+ fileStream: data.file,
240
+ mimetype: data.mimetype
241
+ }
242
+
243
+ const destinationPath = join(BASE_FILE_DIR, AVATAR_DIR)
244
+ const storedFile = await StoreManager.saveFile(file, destinationPath)
245
+ const urlFile = BASE_URL + '/api/user/avatar/' + storedFile.filename
246
+
247
+ //Save into DB
248
+ const userService = UserServiceFactory()
249
+ await userService.changeAvatar(userId, urlFile)
250
+
251
+ return {
252
+ filename: storedFile.filename,
253
+ size: storedFile.size,
254
+ mimetype: storedFile.mimetype,
255
+ url: urlFile,
256
+ }
257
+ } catch (e) {
258
+ console.error(e)
259
+ if (e instanceof UploadFileError) {
260
+ reply.statusCode = e.statusCode
261
+ reply.send({error: e.message})
262
+ } else if (e instanceof UnauthorizedError) {
263
+ reply.statusCode = e.statusCode
264
+ reply.send({error: e.message})
265
+ } else {
266
+ reply.statusCode = 500
267
+ reply.send({error: 'INTERNAL_SERVER_ERROR'})
268
+ }
269
+ }
270
+
271
+ }
272
+
273
+ async getAvatar(request, reply) {
274
+ try {
275
+ const filename = request.params.filename
276
+ const subPath = 'avatar'
277
+ const fileDir = join(BASE_FILE_DIR, subPath)
278
+ //console.log("FILE_DIR: ",fileDir, " FILENAME:", filename)
279
+ return reply.sendFile(filename, fileDir)
280
+ } catch (e) {
281
+ console.error(e)
282
+ if (e instanceof UnauthorizedError) {
283
+ reply.statusCode = e.statusCode
284
+ reply.send({error: e.message})
285
+ } else {
286
+ reply.statusCode = 500
287
+ reply.send({error: 'INTERNAL_SERVER_ERROR'})
288
+ }
289
+ }
290
+
291
+ }
292
+
293
+
294
+ }
295
+
296
+ export default UserController;
297
+ export {
298
+ UserController
299
+ }
300
+
package/src/index.ts CHANGED
@@ -11,7 +11,6 @@ import PermissionService from "./services/PermissionService.js";
11
11
  import Rbac from "./rbac/Rbac.js";
12
12
 
13
13
  import {UserRoutes} from "./routes/UserRoutes.js";
14
- import {UserAvatarRoutes} from "./routes/UserAvatarRoutes.js";
15
14
  import {RoleRoutes} from "./routes/RoleRoutes.js";
16
15
  import {TenantRoutes} from "./routes/TenantRoutes.js";
17
16
  import {UserApiKeyRoutes} from "./routes/UserApiKeyRoutes.js";
@@ -77,7 +76,6 @@ export {
77
76
  UserRoutes,
78
77
  RoleRoutes,
79
78
  TenantRoutes,
80
- UserAvatarRoutes,
81
79
  UserApiKeyRoutes,
82
80
 
83
81
  AuthUtils,