@drax/identity-back 0.0.8 → 0.0.10

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 (188) hide show
  1. package/dist/errors/BadCredentialsError.js +10 -0
  2. package/dist/errors/UnauthorizedError.js +10 -0
  3. package/dist/factory/RoleServiceFactory.js +16 -3
  4. package/dist/factory/UserServiceFactory.js +17 -3
  5. package/dist/graphql/resolvers/role.resolvers.js +98 -11
  6. package/dist/graphql/resolvers/user.resolvers.js +134 -15
  7. package/dist/graphql/types/role.graphql +6 -4
  8. package/dist/graphql/types/user.graphql +36 -9
  9. package/dist/i18n/messages/validation-i18n.js +21 -0
  10. package/dist/index.js +22 -7
  11. package/dist/interfaces/IID.js +1 -0
  12. package/dist/interfaces/IJwtUser.js +1 -0
  13. package/dist/middleware/jwtMiddleware.js +19 -0
  14. package/dist/middleware/rbacMiddleware.js +36 -0
  15. package/dist/models/RoleModel.js +0 -8
  16. package/dist/models/UserModel.js +1 -2
  17. package/dist/permissions/IdentityPermissions.js +16 -0
  18. package/dist/rbac/Rbac.js +20 -0
  19. package/dist/repository/mongo/RoleMongoRepository.js +41 -0
  20. package/dist/repository/mongo/UserMongoRepository.js +82 -0
  21. package/dist/repository/sqlite/RoleSqliteRepository.js +115 -0
  22. package/dist/repository/sqlite/UserSqliteRepository.js +157 -0
  23. package/dist/routes/RoleRoutes.js +145 -0
  24. package/dist/routes/UserRoutes.js +199 -0
  25. package/dist/routes/authRoutes.js +12 -4
  26. package/dist/services/AuthService.js +0 -15
  27. package/dist/services/PermissionService.js +19 -0
  28. package/dist/services/RoleService.js +48 -16
  29. package/dist/services/UserService.js +82 -23
  30. package/dist/utils/AuthUtils.js +20 -6
  31. package/dist/utils/DbSetupUtils.js +28 -0
  32. package/dist/zod/RoleZod.js +8 -0
  33. package/dist/zod/UserZod.js +18 -0
  34. package/package.json +17 -10
  35. package/src/errors/BadCredentialsError.ts +13 -0
  36. package/src/errors/UnauthorizedError.ts +13 -0
  37. package/src/factory/RoleServiceFactory.ts +20 -3
  38. package/src/factory/UserServiceFactory.ts +20 -3
  39. package/src/graphql/resolvers/role.resolvers.ts +92 -11
  40. package/src/graphql/resolvers/user.resolvers.ts +128 -15
  41. package/src/graphql/types/role.graphql +6 -4
  42. package/src/graphql/types/user.graphql +36 -9
  43. package/src/index.ts +50 -10
  44. package/src/interfaces/IID.ts +5 -0
  45. package/src/interfaces/IJwtUser.ts +7 -0
  46. package/src/interfaces/IRole.ts +15 -5
  47. package/src/interfaces/IRoleRepository.ts +8 -5
  48. package/src/interfaces/IUser.ts +30 -6
  49. package/src/interfaces/IUserGroup.ts +2 -1
  50. package/src/interfaces/IUserRepository.ts +11 -6
  51. package/src/middleware/jwtMiddleware.ts +22 -0
  52. package/src/middleware/rbacMiddleware.ts +40 -0
  53. package/src/models/RoleModel.ts +0 -9
  54. package/src/models/UserModel.ts +1 -2
  55. package/src/permissions/IdentityPermissions.ts +20 -0
  56. package/src/rbac/Rbac.ts +31 -0
  57. package/src/repository/mongo/RoleMongoRepository.ts +57 -0
  58. package/src/repository/mongo/UserMongoRepository.ts +104 -0
  59. package/src/repository/sqlite/RoleSqliteRepository.ts +151 -0
  60. package/src/repository/sqlite/UserSqliteRepository.ts +194 -0
  61. package/src/routes/RoleRoutes.ts +141 -0
  62. package/src/routes/UserRoutes.ts +198 -0
  63. package/src/services/PermissionService.ts +26 -0
  64. package/src/services/RoleService.ts +46 -21
  65. package/src/services/UserService.ts +86 -28
  66. package/src/utils/AuthUtils.ts +22 -7
  67. package/src/utils/DbSetupUtils.ts +39 -0
  68. package/src/zod/RoleZod.ts +14 -0
  69. package/src/zod/UserZod.ts +26 -0
  70. package/test/data-json/roles/admin-role.json +1 -1
  71. package/test/data-obj/roles/{admin-role.ts → admin-mongo-role.ts} +2 -1
  72. package/test/data-obj/roles/admin-sqlite-role.ts +9 -0
  73. package/test/data-obj/roles/operator-sqlite-role.ts +9 -0
  74. package/test/data-obj/users/root-mongo-user.ts +15 -0
  75. package/test/data-obj/users/root-sqlite-user.ts +16 -0
  76. package/test/{initializers → db}/MongoInMemory.ts +2 -1
  77. package/test/initializers/RoleMongoInitializer.ts +15 -0
  78. package/test/initializers/RoleSqliteInitializer.ts +18 -0
  79. package/test/repository/{role-repository.test.ts → mongo/role-mongo-repository.test.ts} +14 -24
  80. package/test/repository/mongo/user-mongo-repository.test.ts +121 -0
  81. package/test/repository/sqlite/role-sqlite-repository.test.ts +70 -0
  82. package/test/repository/sqlite/user-sqlite-repository.test.ts +126 -0
  83. package/test/service/mock-service.test.ts +3 -3
  84. package/test/service/role-service.test.ts +5 -5
  85. package/test/service/user-service.test.ts +42 -15
  86. package/test.db +0 -0
  87. package/tsconfig.json +16 -3
  88. package/tsconfig.tsbuildinfo +1 -1
  89. package/types/errors/BadCredentialsError.d.ts +6 -0
  90. package/types/errors/BadCredentialsError.d.ts.map +1 -0
  91. package/types/errors/UnauthorizedError.d.ts +6 -0
  92. package/types/errors/UnauthorizedError.d.ts.map +1 -0
  93. package/types/factory/RoleServiceFactory.d.ts +2 -2
  94. package/types/factory/RoleServiceFactory.d.ts.map +1 -1
  95. package/types/factory/UserServiceFactory.d.ts +2 -2
  96. package/types/factory/UserServiceFactory.d.ts.map +1 -1
  97. package/types/graphql/resolvers/role.resolvers.d.ts +24 -7
  98. package/types/graphql/resolvers/role.resolvers.d.ts.map +1 -1
  99. package/types/graphql/resolvers/user.resolvers.d.ts +38 -7
  100. package/types/graphql/resolvers/user.resolvers.d.ts.map +1 -1
  101. package/types/i18n/messages/validation-i18n.d.ts +4 -0
  102. package/types/i18n/messages/validation-i18n.d.ts.map +1 -0
  103. package/types/index.d.ts +21 -5
  104. package/types/index.d.ts.map +1 -1
  105. package/types/interfaces/IID.d.ts +6 -0
  106. package/types/interfaces/IID.d.ts.map +1 -0
  107. package/types/interfaces/IJwtUser.d.ts +7 -0
  108. package/types/interfaces/IJwtUser.d.ts.map +1 -0
  109. package/types/interfaces/IRole.d.ts +13 -6
  110. package/types/interfaces/IRole.d.ts.map +1 -1
  111. package/types/interfaces/IRoleRepository.d.ts +8 -4
  112. package/types/interfaces/IRoleRepository.d.ts.map +1 -1
  113. package/types/interfaces/IUser.d.ts +29 -8
  114. package/types/interfaces/IUser.d.ts.map +1 -1
  115. package/types/interfaces/IUserGroup.d.ts +3 -2
  116. package/types/interfaces/IUserGroup.d.ts.map +1 -1
  117. package/types/interfaces/IUserRepository.d.ts +10 -6
  118. package/types/interfaces/IUserRepository.d.ts.map +1 -1
  119. package/types/middleware/jwtMiddleware.d.ts +4 -0
  120. package/types/middleware/jwtMiddleware.d.ts.map +1 -0
  121. package/types/middleware/rbacMiddleware.d.ts +4 -0
  122. package/types/middleware/rbacMiddleware.d.ts.map +1 -0
  123. package/types/models/RoleModel.d.ts +8 -8
  124. package/types/models/RoleModel.d.ts.map +1 -1
  125. package/types/models/UserGroupModel.d.ts +8 -8
  126. package/types/models/UserGroupModel.d.ts.map +1 -1
  127. package/types/models/UserModel.d.ts +8 -8
  128. package/types/models/UserModel.d.ts.map +1 -1
  129. package/types/permissions/IdentityPermissions.d.ts +16 -0
  130. package/types/permissions/IdentityPermissions.d.ts.map +1 -0
  131. package/types/rbac/Rbac.d.ts +12 -0
  132. package/types/rbac/Rbac.d.ts.map +1 -0
  133. package/types/repository/mongo/RoleMongoRepository.d.ts +14 -0
  134. package/types/repository/mongo/RoleMongoRepository.d.ts.map +1 -0
  135. package/types/repository/mongo/UserMongoRepository.d.ts +18 -0
  136. package/types/repository/mongo/UserMongoRepository.d.ts.map +1 -0
  137. package/types/repository/sqlite/RoleSqliteRepository.d.ts +19 -0
  138. package/types/repository/sqlite/RoleSqliteRepository.d.ts.map +1 -0
  139. package/types/repository/sqlite/UserSqliteRepository.d.ts +24 -0
  140. package/types/repository/sqlite/UserSqliteRepository.d.ts.map +1 -0
  141. package/types/routes/RoleRoutes.d.ts +4 -0
  142. package/types/routes/RoleRoutes.d.ts.map +1 -0
  143. package/types/routes/UserRoutes.d.ts +4 -0
  144. package/types/routes/UserRoutes.d.ts.map +1 -0
  145. package/types/routes/authRoutes.d.ts.map +1 -1
  146. package/types/services/AuthService.d.ts +0 -3
  147. package/types/services/AuthService.d.ts.map +1 -1
  148. package/types/services/PermissionService.d.ts +9 -0
  149. package/types/services/PermissionService.d.ts.map +1 -0
  150. package/types/services/RoleService.d.ts +6 -8
  151. package/types/services/RoleService.d.ts.map +1 -1
  152. package/types/services/UserService.d.ts +13 -11
  153. package/types/services/UserService.d.ts.map +1 -1
  154. package/types/utils/AuthUtils.d.ts +5 -2
  155. package/types/utils/AuthUtils.d.ts.map +1 -1
  156. package/types/utils/DbSetupUtils.d.ts +10 -0
  157. package/types/utils/DbSetupUtils.d.ts.map +1 -0
  158. package/types/zod/RoleZod.d.ts +10 -0
  159. package/types/zod/RoleZod.d.ts.map +1 -0
  160. package/types/zod/UserZod.d.ts +53 -0
  161. package/types/zod/UserZod.d.ts.map +1 -0
  162. package/dist/factory/AuthServiceFactory.js +0 -8
  163. package/dist/graphql/resolvers/auth.resolvers.js +0 -16
  164. package/dist/graphql/types/auth.graphql +0 -12
  165. package/dist/repository/RoleRepository.js +0 -29
  166. package/dist/repository/UserRepository.js +0 -33
  167. package/src/factory/AuthServiceFactory.ts +0 -10
  168. package/src/graphql/resolvers/auth.resolvers.ts +0 -20
  169. package/src/graphql/types/auth.graphql +0 -12
  170. package/src/repository/RoleRepository.ts +0 -42
  171. package/src/repository/UserRepository.ts +0 -47
  172. package/src/routes/authRoutes.ts +0 -22
  173. package/src/services/AuthService.ts +0 -29
  174. package/test/data-obj/users/root-user.ts +0 -15
  175. package/test/initializers/MongoInMemory.mjs +0 -34
  176. package/test/initializers/RoleInitializer.mjs +0 -11
  177. package/test/initializers/RoleInitializer.ts +0 -15
  178. package/test/repository/user-repository.test.ts +0 -54
  179. package/types/factory/AuthServiceFactory.d.ts +0 -4
  180. package/types/factory/AuthServiceFactory.d.ts.map +0 -1
  181. package/types/graphql/resolvers/auth.resolvers.d.ts +0 -12
  182. package/types/graphql/resolvers/auth.resolvers.d.ts.map +0 -1
  183. package/types/repository/RoleRepository.d.ts +0 -41
  184. package/types/repository/RoleRepository.d.ts.map +0 -1
  185. package/types/repository/UserRepository.d.ts +0 -40
  186. package/types/repository/UserRepository.d.ts.map +0 -1
  187. package/types/routes/AuthRoutes.d.ts +0 -3
  188. package/types/routes/AuthRoutes.d.ts.map +0 -1
@@ -0,0 +1,141 @@
1
+ import {IPaginateResult, ValidationError} from "@drax/common-back";
2
+ import RoleServiceFactory from "../factory/RoleServiceFactory.js";
3
+ import {IRole} from "../interfaces/IRole";
4
+ import {IdentityPermissions} from "../permissions/IdentityPermissions.js";
5
+ import {PermissionService} from "../services/PermissionService.js";
6
+ import UnauthorizedError from "../errors/UnauthorizedError.js";
7
+
8
+ const roleService = RoleServiceFactory
9
+
10
+ async function RoleRoutes(fastify, options) {
11
+
12
+ fastify.get('/api/permissions', async (request, reply): Promise<string[]> => {
13
+ try {
14
+ request.rbac.assertPermission(IdentityPermissions.PermissionsRole)
15
+ let permissions = PermissionService.getPermissions()
16
+ return permissions
17
+ }catch (e){
18
+ console.error(e)
19
+ if (e instanceof UnauthorizedError) {
20
+ reply.statusCode = e.statusCode
21
+ reply.send({error: e.message})
22
+ } else {
23
+ reply.statusCode = 500
24
+ reply.send({error: 'INTERNAL_SERVER_ERROR'})
25
+ }
26
+ }
27
+ })
28
+
29
+ fastify.get('/api/roles/all', async (request, reply): Promise<IRole[]> => {
30
+ try {
31
+ request.rbac.assertPermission(IdentityPermissions.ViewRole)
32
+ let roles = await roleService.fetchAll()
33
+ return roles
34
+ } catch (e) {
35
+ console.error(e)
36
+ if (e instanceof ValidationError) {
37
+ reply.statusCode = e.statusCode
38
+ reply.send({error: e.message, inputErrors: e.errors})
39
+ } else if (e instanceof UnauthorizedError) {
40
+ reply.statusCode = e.statusCode
41
+ reply.send({error: e.message})
42
+ } else {
43
+ reply.statusCode = 500
44
+ reply.send({error: 'INTERNAL_SERVER_ERROR'})
45
+ }
46
+ }
47
+ })
48
+
49
+ fastify.get('/api/roles', async (request, reply): Promise<IPaginateResult> => {
50
+ try {
51
+ request.rbac.assertPermission(IdentityPermissions.ViewRole)
52
+ const page = request.query.page
53
+ const limit = request.query.limit
54
+ const search = request.query.search
55
+ let paginateResult = await roleService.paginate(page, limit, search)
56
+ return paginateResult
57
+ } catch (e) {
58
+ console.error(e)
59
+ if (e instanceof ValidationError) {
60
+ reply.statusCode = e.statusCode
61
+ reply.send({error: e.message, inputErrors: e.errors})
62
+ } else if (e instanceof UnauthorizedError) {
63
+ reply.statusCode = e.statusCode
64
+ reply.send({error: e.message})
65
+ } else {
66
+ reply.statusCode = 500
67
+ reply.send({error: 'INTERNAL_SERVER_ERROR'})
68
+ }
69
+ }
70
+ })
71
+
72
+ fastify.post('/api/roles', async (request, reply): Promise<IRole> => {
73
+ try {
74
+ request.rbac.assertPermission(IdentityPermissions.CreateRole)
75
+ const payload = request.body
76
+ let role = await roleService.create(payload)
77
+ return role
78
+ } catch (e) {
79
+ console.error(e)
80
+ if (e instanceof ValidationError) {
81
+ reply.statusCode = e.statusCode
82
+ reply.send({error: e.message, inputErrors: e.errors})
83
+ } else if (e instanceof UnauthorizedError) {
84
+ reply.statusCode = e.statusCode
85
+ reply.send({error: e.message})
86
+ } else {
87
+ reply.statusCode = 500
88
+ reply.send({error: 'INTERNAL_SERVER_ERROR'})
89
+ }
90
+ }
91
+
92
+ })
93
+
94
+ fastify.put('/api/roles/:id', async (request, reply): Promise<IRole> => {
95
+ try {
96
+ request.rbac.assertPermission(IdentityPermissions.UpdateRole)
97
+ const id = request.params.id
98
+ const payload = request.body
99
+ let role = await roleService.update(id, payload)
100
+ return role
101
+ } catch (e) {
102
+ console.error(e)
103
+ if (e instanceof ValidationError) {
104
+ reply.statusCode = e.statusCode
105
+ reply.send({error: e.message, inputErrors: e.errors})
106
+ } else if (e instanceof UnauthorizedError) {
107
+ reply.statusCode = e.statusCode
108
+ reply.send({error: e.message})
109
+ } else {
110
+ reply.statusCode = 500
111
+ reply.send({error: 'INTERNAL_SERVER_ERROR'})
112
+ }
113
+ }
114
+
115
+ })
116
+
117
+ fastify.delete('/api/roles/:id', async (request, reply): Promise<any> => {
118
+ try {
119
+ request.rbac.assertPermission(IdentityPermissions.DeleteRole)
120
+ const id = request.params.id
121
+ let r = await roleService.delete(id)
122
+ return r
123
+ } catch (e) {
124
+ console.error(e)
125
+ if (e instanceof ValidationError) {
126
+ reply.statusCode = e.statusCode
127
+ reply.send({error: e.message, inputErrors: e.errors})
128
+ } else if (e instanceof UnauthorizedError) {
129
+ reply.statusCode = e.statusCode
130
+ reply.send({error: e.message})
131
+ } else {
132
+ reply.statusCode = 500
133
+ reply.send({error: 'INTERNAL_SERVER_ERROR'})
134
+ }
135
+ }
136
+ })
137
+
138
+ }
139
+
140
+ export default RoleRoutes;
141
+ export {RoleRoutes}
@@ -0,0 +1,198 @@
1
+ import UserServiceFactory from "../factory/UserServiceFactory.js";
2
+ import {IUser} from "../interfaces/IUser";
3
+ import {IPaginateResult, ValidationError} from "@drax/common-back";
4
+ import {IdentityPermissions} from "../permissions/IdentityPermissions.js";
5
+ import UnauthorizedError from "../errors/UnauthorizedError.js";
6
+ import BadCredentialsError from "../errors/BadCredentialsError.js";
7
+
8
+ const userService = UserServiceFactory
9
+
10
+ async function UserRoutes(fastify, options) {
11
+ fastify.post('/api/auth', async (request, reply) => {
12
+ try {
13
+ const username = request.body.username
14
+ const password = request.body.password
15
+ return await userService.auth(username, password)
16
+ } catch (e) {
17
+ console.error('/api/auth error', e)
18
+ if (e instanceof BadCredentialsError) {
19
+ reply.code(401)
20
+ reply.send({error: e.message})
21
+ }
22
+ reply.code(500)
23
+ reply.send({error: 'error.server'})
24
+ }
25
+ })
26
+
27
+
28
+
29
+
30
+ fastify.get('/api/me', async (request, reply): Promise<IUser | null> => {
31
+ try {
32
+ if (request.authUser) {
33
+ let user = await userService.findById(request.authUser.id)
34
+ delete user.password
35
+ return user
36
+ } else {
37
+ throw new UnauthorizedError()
38
+
39
+ }
40
+ } catch (e) {
41
+ if (e instanceof UnauthorizedError) {
42
+ reply.code(401)
43
+ reply.send({error: "Unauthorized"})
44
+ } else if (e instanceof UnauthorizedError) {
45
+ reply.statusCode = e.statusCode
46
+ reply.send({error: e.message})
47
+ } else {
48
+ reply.statusCode = 500
49
+ reply.send({error: 'error.server'})
50
+ }
51
+ }
52
+
53
+
54
+ })
55
+
56
+ fastify.get('/api/users', async (request, reply): Promise<IPaginateResult> => {
57
+
58
+ try {
59
+ request.rbac.assertPermission(IdentityPermissions.ViewUser)
60
+ const page = request.query.page
61
+ const limit = request.query.limit
62
+ const search = request.query.search
63
+ let paginateResult = await userService.paginate(page, limit, search)
64
+ return paginateResult
65
+ } catch (e) {
66
+ if (e instanceof ValidationError) {
67
+ reply.statusCode = e.statusCode
68
+ reply.send({error: e.message, inputErrors: e.errors})
69
+ } else if (e instanceof UnauthorizedError) {
70
+ reply.statusCode = e.statusCode
71
+ reply.send({error: e.message})
72
+ } else {
73
+ reply.statusCode = 500
74
+ reply.send({error: 'error.server'})
75
+ }
76
+ }
77
+ })
78
+
79
+ fastify.post('/api/users', async (request, reply): Promise<IUser> => {
80
+ try {
81
+ request.rbac.assertPermission(IdentityPermissions.CreateUser)
82
+ const payload = request.body
83
+ let user = await userService.create(payload)
84
+ return user
85
+ } catch (e) {
86
+ if (e instanceof ValidationError) {
87
+ reply.statusCode = e.statusCode
88
+ reply.send({error: e.message, inputErrors: e.errors})
89
+ } else if (e instanceof UnauthorizedError) {
90
+ reply.statusCode = e.statusCode
91
+ reply.send({error: e.message})
92
+ } else {
93
+ reply.statusCode = 500
94
+ reply.send({error: 'error.server'})
95
+ }
96
+ }
97
+
98
+ })
99
+
100
+ fastify.put('/api/users/:id', async (request, reply): Promise<IUser> => {
101
+ try {
102
+ request.rbac.assertPermission(IdentityPermissions.UpdateUser)
103
+ const id = request.params.id
104
+ const payload = request.body
105
+ let user = await userService.update(id, payload)
106
+ return user
107
+ } catch (e) {
108
+ if (e instanceof ValidationError) {
109
+ reply.statusCode = e.statusCode
110
+ reply.send({error: e.message, inputErrors: e.errors})
111
+ }
112
+ if (e instanceof UnauthorizedError) {
113
+ reply.statusCode = e.statusCode
114
+ reply.send({error: e.message})
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
+ fastify.delete('/api/users/:id', async (request, reply): Promise<any> => {
126
+ try {
127
+ request.rbac.assertPermission(IdentityPermissions.DeleteUser)
128
+ const id = request.params.id
129
+ let r = await userService.delete(id)
130
+ return r
131
+ } catch (e) {
132
+ if (e instanceof ValidationError) {
133
+ reply.statusCode = e.statusCode
134
+ reply.send({error: e.message, inputErrors: e.errors})
135
+ } else if (e instanceof UnauthorizedError) {
136
+ reply.statusCode = e.statusCode
137
+ reply.send({error: e.message})
138
+ } else {
139
+ reply.statusCode = 500
140
+ reply.send({error: 'error.server'})
141
+ }
142
+ }
143
+ })
144
+
145
+ fastify.post('/api/password', async (request, reply) => {
146
+ try {
147
+ if(!request.authUser){
148
+ throw new UnauthorizedError()
149
+ }
150
+ const userId = request.authUser.id
151
+ const currentPassword = request.body.currentPassword
152
+ const newPassword = request.body.newPassword
153
+ return await userService.changeOwnPassword(userId, currentPassword, newPassword)
154
+ } catch (e) {
155
+ console.error('/api/password error', e)
156
+ if (e instanceof ValidationError) {
157
+ reply.statusCode = e.statusCode
158
+ reply.send({error: e.message, inputErrors: e.errors})
159
+ } else if (e instanceof UnauthorizedError) {
160
+ reply.statusCode = e.statusCode
161
+ reply.send({error: e.message})
162
+ } else {
163
+ reply.statusCode = 500
164
+ reply.send({error: 'error.server'})
165
+ }
166
+ }
167
+ })
168
+
169
+
170
+ fastify.post('/api/password/:id', async (request, reply) => {
171
+ try {
172
+ request.rbac.assertPermission(IdentityPermissions.UpdateUser)
173
+ const userId = request.params.id
174
+ if(!userId){
175
+ throw new UnauthorizedError()
176
+ }
177
+ const newPassword = request.body.newPassword
178
+
179
+ return await userService.changeUserPassword(userId, newPassword)
180
+ } catch (e) {
181
+ console.error('/api/password error', e)
182
+ if (e instanceof ValidationError) {
183
+ reply.statusCode = e.statusCode
184
+ reply.send({error: e.message, inputErrors: e.errors})
185
+ } else if (e instanceof UnauthorizedError) {
186
+ reply.statusCode = e.statusCode
187
+ reply.send({error: e.message})
188
+ } else {
189
+ reply.statusCode = 500
190
+ reply.send({error: 'error.server'})
191
+ }
192
+ }
193
+ })
194
+
195
+ }
196
+
197
+ export default UserRoutes;
198
+ export {UserRoutes}
@@ -0,0 +1,26 @@
1
+ const permissions: string[] = []
2
+
3
+ class PermissionService{
4
+
5
+ static addPermission(permission: string){
6
+ if(PermissionService.hasPermission(permission)) return;
7
+ permissions.push(permission)
8
+ }
9
+
10
+ static removePermission(permission: string){
11
+ permissions.splice(permissions.indexOf(permission), 1)
12
+ }
13
+
14
+ static hasPermission(permission: string): boolean{
15
+ return permissions.includes(permission)
16
+ }
17
+
18
+ static getPermissions(): string[]{
19
+ return permissions
20
+ }
21
+
22
+ }
23
+
24
+
25
+ export default PermissionService
26
+ export {PermissionService}
@@ -1,6 +1,9 @@
1
1
  import {IRole} from "../interfaces/IRole";
2
2
  import {IRoleRepository} from "../interfaces/IRoleRepository";
3
- import { IPaginateFilter} from "@drax/common-back"
3
+ import {IPaginateFilter, IPaginateResult, ValidationError, ZodErrorToValidationError} from "@drax/common-back"
4
+ import {roleSchema} from "../zod/RoleZod.js";
5
+ import {ZodError} from "zod";
6
+ import UnauthorizedError from "../errors/UnauthorizedError.js";
4
7
 
5
8
  class RoleService {
6
9
 
@@ -8,40 +11,62 @@ class RoleService {
8
11
 
9
12
  constructor(roleRepostitory: IRoleRepository) {
10
13
  this._repository = roleRepostitory
14
+ console.log("RoleService constructor")
11
15
  }
12
16
 
13
17
  async create(roleData: IRole): Promise<IRole> {
14
- const role = await this._repository.create(roleData)
15
- return role
18
+ try {
19
+ roleData.name = roleData?.name?.trim()
20
+ await roleSchema.parseAsync(roleData)
21
+ const role = await this._repository.create(roleData)
22
+ return role
23
+ } catch (e) {
24
+ if (e instanceof ZodError) {
25
+ throw ZodErrorToValidationError(e, roleData)
26
+ }
27
+ throw e
28
+ }
16
29
  }
17
30
 
18
- async update(_id: any, roleData: IRole) {
19
- const role = await this._repository.update(_id, roleData)
20
- return role
31
+ async update(id: any, roleData: IRole) {
32
+ try {
33
+ roleData.name = roleData?.name?.trim()
34
+ await roleSchema.parseAsync(roleData)
35
+ const currentRole = await this.findById(id)
36
+ if(currentRole.readonly){
37
+ throw new ValidationError([{field:'name', reason:"role.readonly", value:roleData.name}])
38
+ }
39
+ const role = await this._repository.update(id, roleData)
40
+ return role
41
+ } catch (e) {
42
+ if (e instanceof ZodError) {
43
+ throw ZodErrorToValidationError(e, roleData)
44
+ }
45
+ throw e
46
+ }
21
47
  }
22
48
 
23
- async delete(_id: any): Promise<boolean> {
24
- const deletedRole = await this._repository.delete(_id);
49
+ async delete(id: any): Promise<boolean> {
50
+ const currentRole = await this.findById(id)
51
+ if(currentRole.readonly){
52
+ throw new UnauthorizedError()
53
+ }
54
+ const deletedRole = await this._repository.delete(id);
25
55
  return deletedRole;
26
56
  }
27
57
 
28
- async findById(_id: any): Promise<IRole | null> {
29
- const role : IRole = await this._repository.findById(_id);
58
+ async findById(id: any): Promise<IRole | null> {
59
+ const role: IRole = await this._repository.findById(id);
30
60
  return role
31
61
  }
32
62
 
33
- async paginate(filters ?: IPaginateFilter, page: number = 1, limit: number = 10): Promise<{ roles: IRole[], totalCount: number }> {
34
-
35
- const query = {
36
-
37
- }
38
-
39
- const options = {
40
- page: page,
41
- limit: limit
42
- }
63
+ async fetchAll(): Promise<IRole[]> {
64
+ const roles: IRole[] = await this._repository.fetchAll();
65
+ return roles
66
+ }
43
67
 
44
- const pagination = await this._repository.paginate(query, options);
68
+ async paginate(page: number = 1, limit: number = 5, search?:string, filters ?: IPaginateFilter[]): Promise<IPaginateResult> {
69
+ const pagination = await this._repository.paginate(page, limit, search, filters);
45
70
  return pagination;
46
71
  }
47
72
 
@@ -1,7 +1,11 @@
1
- import {IPaginateFilter} from "@drax/common-back"
2
- import {IUser} from "../interfaces/IUser";
3
- import {IUserRepository} from "../interfaces/IUserRepository";
1
+ import type {IUser, IUserCreate, IUserUpdate} from "../interfaces/IUser";
2
+ import type {IUserRepository} from "../interfaces/IUserRepository";
3
+ import type {IPaginateFilter, IPaginateResult} from "@drax/common-back"
4
+ import {ZodError} from "zod";
5
+ import {ValidationError, ZodErrorToValidationError} from "@drax/common-back";
4
6
  import AuthUtils from "../utils/AuthUtils.js";
7
+ import {createUserSchema, editUserSchema,} from "../zod/UserZod.js";
8
+ import BadCredentialsError from "../errors/BadCredentialsError.js";
5
9
 
6
10
  class UserService {
7
11
 
@@ -9,35 +13,100 @@ class UserService {
9
13
 
10
14
  constructor(userRepository: IUserRepository) {
11
15
  this._repository = userRepository;
16
+ console.log("UserService constructor")
12
17
  }
13
18
 
14
- async create(userData: IUser): Promise<IUser> {
19
+ async auth(username : string, password : string){
20
+ let user = null
21
+ console.log("auth username",username)
22
+ user = await this.findByUsername(username)
23
+ if (user && user.active && AuthUtils.checkPassword(password, user.password)) {
24
+ //TODO: Generar Sesion
25
+ const session = '123'
26
+ const accessToken = AuthUtils.generateToken(user.id.toString(), user.username, user.role.id, session)
27
+ return {accessToken: accessToken}
28
+ }else{
29
+ throw new BadCredentialsError()
30
+ }
31
+ }
15
32
 
16
- userData.name = userData?.name?.trim()
17
- userData.username = userData.username.trim()
18
- userData.password = AuthUtils.hashPassword(userData.password.trim())
33
+ async changeUserPassword(userId : string, newPassword : string){
34
+ const user = await this.findById(userId)
35
+ if(user){
36
+ newPassword = AuthUtils.hashPassword(newPassword)
37
+ await this._repository.changePassword(userId, newPassword)
38
+ return true
39
+ }else{
40
+ throw new ValidationError([{field: 'userId', reason: 'validation.notFound'}])
41
+ }
42
+ }
19
43
 
20
- const user: IUser = await this._repository.create(userData)
21
- return user
44
+
45
+ async changeOwnPassword(userId : string, currentPassword : string, newPassword : string){
46
+ const user = await this.findById(userId)
47
+ if(user && user.active){
48
+ if (AuthUtils.checkPassword(currentPassword, user.password)) {
49
+ newPassword = AuthUtils.hashPassword(newPassword)
50
+ await this._repository.changePassword(userId, newPassword)
51
+ return true
52
+ }else{
53
+ throw new ValidationError([{field: 'currentPassword', reason: 'validation.notMatch'}])
54
+ }
55
+
56
+ }else{
57
+ throw new BadCredentialsError()
58
+ }
22
59
  }
23
60
 
24
- async update(_id: any, userData: IUser) {
25
61
 
62
+ async create(userData: IUserCreate): Promise<IUser> {
63
+ try{
64
+ userData.name = userData?.name?.trim()
65
+ userData.username = userData.username.trim()
66
+ userData.password = userData.password.trim()
67
+
68
+ await createUserSchema.parseAsync(userData)
69
+
70
+ userData.password = AuthUtils.hashPassword(userData.password.trim())
71
+
72
+ const user: IUser = await this._repository.create(userData)
73
+ return user
74
+ }catch (e){
75
+ if(e instanceof ZodError){
76
+ throw ZodErrorToValidationError(e,userData)
77
+ }
78
+ throw e
79
+ }
80
+
81
+
82
+ }
83
+
84
+ async update(id: any, userData: IUserUpdate) {
85
+ try{
26
86
  userData.name = userData.name.trim()
27
87
  userData.username = userData.username.trim()
28
88
  delete userData.password
29
89
 
30
- const user: IUser = await this._repository.update(_id, userData)
90
+ await editUserSchema.parseAsync(userData)
91
+
92
+
93
+ const user: IUser = await this._repository.update(id, userData)
31
94
  return user
95
+ }catch (e){
96
+ if(e instanceof ZodError){
97
+ throw ZodErrorToValidationError(e,userData)
98
+ }
99
+ throw e
100
+ }
32
101
  }
33
102
 
34
- async delete(_id: any): Promise<boolean> {
35
- const deletedRole: boolean = await this._repository.delete(_id);
103
+ async delete(id: any): Promise<boolean> {
104
+ const deletedRole: boolean = await this._repository.delete(id);
36
105
  return deletedRole;
37
106
  }
38
107
 
39
- async findById(_id: any): Promise<IUser | null> {
40
- const user: IUser = await this._repository.findById(_id);
108
+ async findById(id: any): Promise<IUser> {
109
+ const user: IUser = await this._repository.findById(id);
41
110
  return user
42
111
  }
43
112
 
@@ -46,20 +115,9 @@ class UserService {
46
115
  return user
47
116
  }
48
117
 
49
- async paginate(filters ?: IPaginateFilter, page : number = 1, limit : number = 10): Promise<{
50
- roles: IUser[],
51
- totalCount: number
52
- }> {
53
-
54
- const query = {}
55
-
56
- const options = {
57
- page: page,
58
- limit: limit
59
- }
118
+ async paginate( page : number = 1, limit : number = 10, search?: string, filters ?: IPaginateFilter[]): Promise<IPaginateResult> {
60
119
 
61
- const pagination = await this._repository.paginate(query, options);
62
- console.log("pagination",pagination)
120
+ const pagination = await this._repository.paginate( page, limit, search, filters);
63
121
  return pagination;
64
122
  }
65
123
  }
@@ -1,8 +1,19 @@
1
1
  import bcryptjs from "bcryptjs";
2
- import jsonwebtoken, {SignOptions} from "jsonwebtoken";
2
+ import jsonwebtoken, {SignOptions, VerifyOptions} from "jsonwebtoken";
3
3
 
4
4
  class AuthUtils{
5
5
 
6
+ static verifyToken(token : string) {
7
+ const JWT_SECRET = process.env.JWT_SECRET
8
+ if(!JWT_SECRET){
9
+ throw new Error("JWT_SECRET ENV must be provided")
10
+ }
11
+ const options : VerifyOptions = {
12
+ algorithms: ['HS256'],
13
+ }
14
+ return jsonwebtoken.verify(token, JWT_SECRET, options)
15
+ }
16
+
6
17
  static hashPassword(password : string) :string {
7
18
  if (!password) {
8
19
  throw new Error("password must be provided")
@@ -17,25 +28,29 @@ class AuthUtils{
17
28
  return bcryptjs.compareSync(password, hashPassword);
18
29
  }
19
30
 
20
- static tokenSignPayload(userId : string, username: string, session : string) {
31
+ static tokenSignPayload(userId : string, username: string, roleId: string, session : string) {
21
32
  return {
22
33
  id: userId,
23
34
  username: username,
35
+ roleId: roleId,
24
36
  session: session
25
37
  };
26
38
  }
27
39
 
28
- static generateToken(userId : string, username: string, session : string) {
29
- const payload = AuthUtils.tokenSignPayload(userId, username, session)
40
+ static generateToken(userId : string, username: string, roleId: string, session : string) {
41
+ const payload = AuthUtils.tokenSignPayload(userId, username, roleId, session)
30
42
 
31
- const JWT_SECRET = process.env.JWT_SECRET ? process.env.JWT_SECRET :'KRgDV3CeR5lVhsFF'
43
+ const JWT_SECRET = process.env.JWT_SECRET
44
+ if(!JWT_SECRET){
45
+ throw new Error("JWT_SECRET ENV must be provided")
46
+ }
32
47
 
33
48
  const options : SignOptions = {
34
- expiresIn: process.env.JWT_LOGIN_EXPIRED_IN || '1h',
49
+ expiresIn: process.env.JWT_EXPIRATION || '1h',
35
50
  jwtid: userId,
36
51
  algorithm: 'HS256',
37
52
  audience: username,
38
- issuer: process.env.ISSUER? process.env.ISSUER : 'drax'
53
+ issuer: process.env.JWT_ISSUER? process.env.JWT_ISSUER : 'drax'
39
54
  }
40
55
 
41
56
  let token = jsonwebtoken.sign(