@drax/identity-back 0.0.14 → 0.0.16

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 (106) hide show
  1. package/dist/factory/TenantServiceFactory.js +24 -0
  2. package/dist/factory/UserServiceFactory.js +1 -1
  3. package/dist/graphql/resolvers/role.resolvers.js +19 -2
  4. package/dist/graphql/resolvers/tenant.resolvers.js +121 -0
  5. package/dist/graphql/resolvers/user.resolvers.js +14 -3
  6. package/dist/graphql/types/tenant.graphql +28 -0
  7. package/dist/graphql/types/user.graphql +3 -0
  8. package/dist/index.js +6 -3
  9. package/dist/interfaces/ITenant.js +1 -0
  10. package/dist/interfaces/ITenantRepository.js +1 -0
  11. package/dist/middleware/rbacMiddleware.js +2 -5
  12. package/dist/models/TenantModel.js +18 -0
  13. package/dist/models/UserModel.js +5 -0
  14. package/dist/permissions/IdentityPermissions.js +5 -0
  15. package/dist/rbac/Rbac.js +6 -0
  16. package/dist/repository/mongo/RoleMongoRepository.js +7 -6
  17. package/dist/repository/mongo/TenantMongoRepository.js +45 -0
  18. package/dist/repository/mongo/UserMongoRepository.js +19 -6
  19. package/dist/repository/sqlite/RoleSqliteRepository.js +24 -5
  20. package/dist/repository/sqlite/TenantSqliteRepository.js +106 -0
  21. package/dist/repository/sqlite/UserSqliteRepository.js +43 -37
  22. package/dist/routes/RoleRoutes.js +17 -2
  23. package/dist/routes/TenantRoutes.js +183 -0
  24. package/dist/routes/UserRoutes.js +14 -2
  25. package/dist/services/RoleService.js +0 -5
  26. package/dist/services/TenantService.js +59 -0
  27. package/dist/services/UserService.js +1 -1
  28. package/dist/utils/AuthUtils.js +4 -3
  29. package/dist/zod/TenantZod.js +8 -0
  30. package/package.json +2 -2
  31. package/src/factory/TenantServiceFactory.ts +33 -0
  32. package/src/factory/UserServiceFactory.ts +1 -1
  33. package/src/graphql/resolvers/role.resolvers.ts +21 -3
  34. package/src/graphql/resolvers/tenant.resolvers.ts +119 -0
  35. package/src/graphql/resolvers/user.resolvers.ts +14 -6
  36. package/src/graphql/types/tenant.graphql +28 -0
  37. package/src/graphql/types/user.graphql +3 -0
  38. package/src/index.ts +6 -0
  39. package/src/interfaces/ITenant.ts +9 -0
  40. package/src/interfaces/ITenantRepository.ts +15 -0
  41. package/src/interfaces/IUser.ts +4 -1
  42. package/src/middleware/rbacMiddleware.ts +6 -8
  43. package/src/models/TenantModel.ts +32 -0
  44. package/src/models/UserModel.ts +5 -0
  45. package/src/permissions/IdentityPermissions.ts +7 -0
  46. package/src/rbac/Rbac.ts +11 -3
  47. package/src/repository/mongo/RoleMongoRepository.ts +7 -6
  48. package/src/repository/mongo/TenantMongoRepository.ts +62 -0
  49. package/src/repository/mongo/UserMongoRepository.ts +20 -6
  50. package/src/repository/sqlite/RoleSqliteRepository.ts +27 -6
  51. package/src/repository/sqlite/TenantSqliteRepository.ts +139 -0
  52. package/src/repository/sqlite/UserSqliteRepository.ts +52 -40
  53. package/src/routes/RoleRoutes.ts +17 -3
  54. package/src/routes/TenantRoutes.ts +178 -0
  55. package/src/routes/UserRoutes.ts +14 -4
  56. package/src/services/RoleService.ts +1 -4
  57. package/src/services/TenantService.ts +74 -0
  58. package/src/services/UserService.ts +1 -1
  59. package/src/utils/AuthUtils.ts +4 -3
  60. package/src/zod/TenantZod.ts +14 -0
  61. package/tsconfig.tsbuildinfo +1 -1
  62. package/types/factory/TenantServiceFactory.d.ts +4 -0
  63. package/types/factory/TenantServiceFactory.d.ts.map +1 -0
  64. package/types/graphql/resolvers/role.resolvers.d.ts.map +1 -1
  65. package/types/graphql/resolvers/tenant.resolvers.d.ts +44 -0
  66. package/types/graphql/resolvers/tenant.resolvers.d.ts.map +1 -0
  67. package/types/graphql/resolvers/user.resolvers.d.ts +2 -1
  68. package/types/graphql/resolvers/user.resolvers.d.ts.map +1 -1
  69. package/types/index.d.ts +4 -1
  70. package/types/index.d.ts.map +1 -1
  71. package/types/interfaces/ITenant.d.ts +7 -0
  72. package/types/interfaces/ITenant.d.ts.map +1 -0
  73. package/types/interfaces/ITenantRepository.d.ts +15 -0
  74. package/types/interfaces/ITenantRepository.d.ts.map +1 -0
  75. package/types/interfaces/IUser.d.ts +4 -0
  76. package/types/interfaces/IUser.d.ts.map +1 -1
  77. package/types/middleware/rbacMiddleware.d.ts.map +1 -1
  78. package/types/models/TenantModel.d.ts +16 -0
  79. package/types/models/TenantModel.d.ts.map +1 -0
  80. package/types/models/UserModel.d.ts.map +1 -1
  81. package/types/permissions/IdentityPermissions.d.ts +6 -1
  82. package/types/permissions/IdentityPermissions.d.ts.map +1 -1
  83. package/types/rbac/Rbac.d.ts +4 -2
  84. package/types/rbac/Rbac.d.ts.map +1 -1
  85. package/types/repository/mongo/RoleMongoRepository.d.ts.map +1 -1
  86. package/types/repository/mongo/TenantMongoRepository.d.ts +15 -0
  87. package/types/repository/mongo/TenantMongoRepository.d.ts.map +1 -0
  88. package/types/repository/mongo/UserMongoRepository.d.ts +2 -2
  89. package/types/repository/mongo/UserMongoRepository.d.ts.map +1 -1
  90. package/types/repository/sqlite/RoleSqliteRepository.d.ts +2 -0
  91. package/types/repository/sqlite/RoleSqliteRepository.d.ts.map +1 -1
  92. package/types/repository/sqlite/TenantSqliteRepository.d.ts +19 -0
  93. package/types/repository/sqlite/TenantSqliteRepository.d.ts.map +1 -0
  94. package/types/repository/sqlite/UserSqliteRepository.d.ts +4 -2
  95. package/types/repository/sqlite/UserSqliteRepository.d.ts.map +1 -1
  96. package/types/routes/RoleRoutes.d.ts.map +1 -1
  97. package/types/routes/TenantRoutes.d.ts +4 -0
  98. package/types/routes/TenantRoutes.d.ts.map +1 -0
  99. package/types/routes/UserRoutes.d.ts.map +1 -1
  100. package/types/services/RoleService.d.ts.map +1 -1
  101. package/types/services/TenantService.d.ts +16 -0
  102. package/types/services/TenantService.d.ts.map +1 -0
  103. package/types/utils/AuthUtils.d.ts +3 -2
  104. package/types/utils/AuthUtils.d.ts.map +1 -1
  105. package/types/zod/TenantZod.d.ts +10 -0
  106. package/types/zod/TenantZod.d.ts.map +1 -0
@@ -0,0 +1,178 @@
1
+ import {IPaginateResult, ValidationError} from "@drax/common-back";
2
+ import TenantServiceFactory from "../factory/TenantServiceFactory.js";
3
+ import {ITenant} from "../interfaces/ITenant";
4
+ import {IdentityPermissions} from "../permissions/IdentityPermissions.js";
5
+ import {PermissionService} from "../services/PermissionService.js";
6
+ import UnauthorizedError from "../errors/UnauthorizedError.js";
7
+
8
+
9
+
10
+ async function TenantRoutes(fastify, options) {
11
+
12
+ fastify.get('/api/tenants/:id', async (request, reply): Promise<ITenant> => {
13
+ try {
14
+ request.rbac.assertPermission(IdentityPermissions.ViewTenant)
15
+ const id = request.params.id
16
+ const tenantService = TenantServiceFactory()
17
+ let tenant = await tenantService.findById(id)
18
+ return tenant
19
+ } catch (e) {
20
+ console.error(e)
21
+ if (e instanceof ValidationError) {
22
+ reply.statusCode = e.statusCode
23
+ reply.send({error: e.message, inputErrors: e.errors})
24
+ } else if (e instanceof UnauthorizedError) {
25
+ reply.statusCode = e.statusCode
26
+ reply.send({error: e.message})
27
+ } else {
28
+ reply.statusCode = 500
29
+ reply.send({error: 'INTERNAL_SERVER_ERROR'})
30
+ }
31
+ }
32
+ })
33
+
34
+ fastify.get('/api/tenants/name/:name', async (request, reply): Promise<ITenant> => {
35
+ try {
36
+ request.rbac.assertPermission(IdentityPermissions.ViewTenant)
37
+ const name = request.params.name
38
+ const tenantService = TenantServiceFactory()
39
+ let tenant = await tenantService.findByName(name)
40
+ return tenant
41
+ } catch (e) {
42
+ console.error(e)
43
+ if (e instanceof ValidationError) {
44
+ reply.statusCode = e.statusCode
45
+ reply.send({error: e.message, inputErrors: e.errors})
46
+ } else if (e instanceof UnauthorizedError) {
47
+ reply.statusCode = e.statusCode
48
+ reply.send({error: e.message})
49
+ } else {
50
+ reply.statusCode = 500
51
+ reply.send({error: 'INTERNAL_SERVER_ERROR'})
52
+ }
53
+ }
54
+ })
55
+
56
+ fastify.get('/api/tenants/all', async (request, reply): Promise<ITenant[]> => {
57
+ try {
58
+ request.rbac.assertPermission(IdentityPermissions.ViewTenant)
59
+ const tenantService = TenantServiceFactory()
60
+ let tenants = await tenantService.fetchAll()
61
+ if(request.rbac.getAuthUser.tenantId){
62
+ return tenants.filter(t => t.id === request.rbac.getAuthUser.tenantId)
63
+ }else{
64
+ return tenants
65
+ }
66
+ } catch (e) {
67
+ console.error(e)
68
+ if (e instanceof ValidationError) {
69
+ reply.statusCode = e.statusCode
70
+ reply.send({error: e.message, inputErrors: e.errors})
71
+ } else if (e instanceof UnauthorizedError) {
72
+ reply.statusCode = e.statusCode
73
+ reply.send({error: e.message})
74
+ } else {
75
+ reply.statusCode = 500
76
+ reply.send({error: 'INTERNAL_SERVER_ERROR'})
77
+ }
78
+ }
79
+ })
80
+
81
+ fastify.get('/api/tenants', async (request, reply): Promise<IPaginateResult> => {
82
+ try {
83
+ request.rbac.assertPermission(IdentityPermissions.ViewTenant)
84
+ const page = request.query.page
85
+ const limit = request.query.limit
86
+ const search = request.query.search
87
+ const tenantService = TenantServiceFactory()
88
+ let paginateResult = await tenantService.paginate(page, limit, search)
89
+ return paginateResult
90
+ } catch (e) {
91
+ console.error(e)
92
+ if (e instanceof ValidationError) {
93
+ reply.statusCode = e.statusCode
94
+ reply.send({error: e.message, inputErrors: e.errors})
95
+ } else if (e instanceof UnauthorizedError) {
96
+ reply.statusCode = e.statusCode
97
+ reply.send({error: e.message})
98
+ } else {
99
+ reply.statusCode = 500
100
+ reply.send({error: 'INTERNAL_SERVER_ERROR'})
101
+ }
102
+ }
103
+ })
104
+
105
+ fastify.post('/api/tenants', async (request, reply): Promise<ITenant> => {
106
+ try {
107
+ request.rbac.assertPermission(IdentityPermissions.CreateTenant)
108
+ const payload = request.body
109
+ const tenantService = TenantServiceFactory()
110
+ let tenant = await tenantService.create(payload)
111
+ return tenant
112
+ } catch (e) {
113
+ console.error(e)
114
+ if (e instanceof ValidationError) {
115
+ reply.statusCode = e.statusCode
116
+ reply.send({error: e.message, inputErrors: e.errors})
117
+ } else if (e instanceof UnauthorizedError) {
118
+ reply.statusCode = e.statusCode
119
+ reply.send({error: e.message})
120
+ } else {
121
+ reply.statusCode = 500
122
+ reply.send({error: 'INTERNAL_SERVER_ERROR'})
123
+ }
124
+ }
125
+
126
+ })
127
+
128
+ fastify.put('/api/tenants/:id', async (request, reply): Promise<ITenant> => {
129
+ try {
130
+ request.rbac.assertPermission(IdentityPermissions.UpdateTenant)
131
+ const id = request.params.id
132
+ const payload = request.body
133
+ const tenantService = TenantServiceFactory()
134
+
135
+ let tenant = await tenantService.update(id, payload)
136
+ return tenant
137
+ } catch (e) {
138
+ console.error(e)
139
+ if (e instanceof ValidationError) {
140
+ reply.statusCode = e.statusCode
141
+ reply.send({error: e.message, inputErrors: e.errors})
142
+ } else if (e instanceof UnauthorizedError) {
143
+ reply.statusCode = e.statusCode
144
+ reply.send({error: e.message})
145
+ } else {
146
+ reply.statusCode = 500
147
+ reply.send({error: 'INTERNAL_SERVER_ERROR'})
148
+ }
149
+ }
150
+
151
+ })
152
+
153
+ fastify.delete('/api/tenants/:id', async (request, reply): Promise<any> => {
154
+ try {
155
+ request.rbac.assertPermission(IdentityPermissions.DeleteTenant)
156
+ const id = request.params.id
157
+ const tenantService = TenantServiceFactory()
158
+ let r = await tenantService.delete(id)
159
+ return r
160
+ } catch (e) {
161
+ console.error(e)
162
+ if (e instanceof ValidationError) {
163
+ reply.statusCode = e.statusCode
164
+ reply.send({error: e.message, inputErrors: e.errors})
165
+ } else if (e instanceof UnauthorizedError) {
166
+ reply.statusCode = e.statusCode
167
+ reply.send({error: e.message})
168
+ } else {
169
+ reply.statusCode = 500
170
+ reply.send({error: 'INTERNAL_SERVER_ERROR'})
171
+ }
172
+ }
173
+ })
174
+
175
+ }
176
+
177
+ export default TenantRoutes;
178
+ export {TenantRoutes}
@@ -5,13 +5,12 @@ import {IdentityPermissions} from "../permissions/IdentityPermissions.js";
5
5
  import UnauthorizedError from "../errors/UnauthorizedError.js";
6
6
  import BadCredentialsError from "../errors/BadCredentialsError.js";
7
7
 
8
- const userService = UserServiceFactory()
9
-
10
8
  async function UserRoutes(fastify, options) {
11
9
  fastify.post('/api/auth', async (request, reply) => {
12
10
  try {
13
11
  const username = request.body.username
14
12
  const password = request.body.password
13
+ const userService = UserServiceFactory()
15
14
  return await userService.auth(username, password)
16
15
  } catch (e) {
17
16
  console.error('/api/auth error', e)
@@ -30,6 +29,7 @@ async function UserRoutes(fastify, options) {
30
29
  fastify.get('/api/me', async (request, reply): Promise<IUser | null> => {
31
30
  try {
32
31
  if (request.authUser) {
32
+ const userService = UserServiceFactory()
33
33
  let user = await userService.findById(request.authUser.id)
34
34
  delete user.password
35
35
  return user
@@ -60,9 +60,15 @@ async function UserRoutes(fastify, options) {
60
60
  const page = request.query.page
61
61
  const limit = request.query.limit
62
62
  const search = request.query.search
63
- let paginateResult = await userService.paginate(page, limit, search)
63
+ const userService = UserServiceFactory()
64
+ const filters = []
65
+ if(request.rbac.getAuthUser.tenantId){
66
+ filters.push({field: 'tenant', operator: '$eq', value: request.rbac.getAuthUser.tenantId})
67
+ }
68
+ let paginateResult = await userService.paginate(page, limit, search, filters)
64
69
  return paginateResult
65
70
  } catch (e) {
71
+ console.log("/api/users",e)
66
72
  if (e instanceof ValidationError) {
67
73
  reply.statusCode = e.statusCode
68
74
  reply.send({error: e.message, inputErrors: e.errors})
@@ -80,6 +86,7 @@ async function UserRoutes(fastify, options) {
80
86
  try {
81
87
  request.rbac.assertPermission(IdentityPermissions.CreateUser)
82
88
  const payload = request.body
89
+ const userService = UserServiceFactory()
83
90
  let user = await userService.create(payload)
84
91
  return user
85
92
  } catch (e) {
@@ -102,6 +109,7 @@ async function UserRoutes(fastify, options) {
102
109
  request.rbac.assertPermission(IdentityPermissions.UpdateUser)
103
110
  const id = request.params.id
104
111
  const payload = request.body
112
+ const userService = UserServiceFactory()
105
113
  let user = await userService.update(id, payload)
106
114
  return user
107
115
  } catch (e) {
@@ -126,6 +134,7 @@ async function UserRoutes(fastify, options) {
126
134
  try {
127
135
  request.rbac.assertPermission(IdentityPermissions.DeleteUser)
128
136
  const id = request.params.id
137
+ const userService = UserServiceFactory()
129
138
  let r = await userService.delete(id)
130
139
  return r
131
140
  } catch (e) {
@@ -150,6 +159,7 @@ async function UserRoutes(fastify, options) {
150
159
  const userId = request.authUser.id
151
160
  const currentPassword = request.body.currentPassword
152
161
  const newPassword = request.body.newPassword
162
+ const userService = UserServiceFactory()
153
163
  return await userService.changeOwnPassword(userId, currentPassword, newPassword)
154
164
  } catch (e) {
155
165
  console.error('/api/password error', e)
@@ -175,7 +185,7 @@ async function UserRoutes(fastify, options) {
175
185
  throw new UnauthorizedError()
176
186
  }
177
187
  const newPassword = request.body.newPassword
178
-
188
+ const userService = UserServiceFactory()
179
189
  return await userService.changeUserPassword(userId, newPassword)
180
190
  } catch (e) {
181
191
  console.error('/api/password error', e)
@@ -43,10 +43,7 @@ class RoleService {
43
43
  }
44
44
 
45
45
  async delete(id: any): Promise<boolean> {
46
- const currentRole = await this.findById(id)
47
- if(currentRole.readonly){
48
- throw new UnauthorizedError()
49
- }
46
+
50
47
  const deletedRole = await this._repository.delete(id);
51
48
  return deletedRole;
52
49
  }
@@ -0,0 +1,74 @@
1
+ import {ITenant} from "../interfaces/ITenant";
2
+ import {ITenantRepository} from "../interfaces/ITenantRepository";
3
+ import {IPaginateFilter, IPaginateResult, ValidationError, ZodErrorToValidationError} from "@drax/common-back"
4
+ import {tenantSchema} from "../zod/TenantZod.js";
5
+ import {ZodError} from "zod";
6
+ import UnauthorizedError from "../errors/UnauthorizedError.js";
7
+
8
+ class TenantService {
9
+
10
+ _repository: ITenantRepository
11
+
12
+ constructor(tenantRepostitory: ITenantRepository) {
13
+ this._repository = tenantRepostitory
14
+ console.log("TenantService constructor")
15
+ }
16
+
17
+ async create(tenantData: ITenant): Promise<ITenant> {
18
+ try {
19
+ tenantData.name = tenantData?.name?.trim()
20
+ await tenantSchema.parseAsync(tenantData)
21
+ const tenant = await this._repository.create(tenantData)
22
+ return tenant
23
+ } catch (e) {
24
+ if (e instanceof ZodError) {
25
+ throw ZodErrorToValidationError(e, tenantData)
26
+ }
27
+ throw e
28
+ }
29
+ }
30
+
31
+ async update(id: any, tenantData: ITenant) {
32
+ try {
33
+ tenantData.name = tenantData?.name?.trim()
34
+ await tenantSchema.parseAsync(tenantData)
35
+ const tenant = await this._repository.update(id, tenantData)
36
+ return tenant
37
+ } catch (e) {
38
+ if (e instanceof ZodError) {
39
+ throw ZodErrorToValidationError(e, tenantData)
40
+ }
41
+ throw e
42
+ }
43
+ }
44
+
45
+ async delete(id: any): Promise<boolean> {
46
+ const currentTenant = await this.findById(id)
47
+ const deletedTenant = await this._repository.delete(id);
48
+ return deletedTenant;
49
+ }
50
+
51
+ async findById(id: any): Promise<ITenant | null> {
52
+ const tenant: ITenant = await this._repository.findById(id);
53
+ return tenant
54
+ }
55
+
56
+ async findByName(name: string): Promise<ITenant | null> {
57
+ const tenant: ITenant = await this._repository.findByName(name);
58
+ return tenant
59
+ }
60
+
61
+ async fetchAll(): Promise<ITenant[]> {
62
+ const tenants: ITenant[] = await this._repository.fetchAll();
63
+ return tenants
64
+ }
65
+
66
+ async paginate(page: number = 1, limit: number = 5, search?:string, filters ?: IPaginateFilter[]): Promise<IPaginateResult> {
67
+ const pagination = await this._repository.paginate(page, limit, search, filters);
68
+ return pagination;
69
+ }
70
+
71
+
72
+ }
73
+
74
+ export default TenantService
@@ -23,7 +23,7 @@ class UserService {
23
23
  if (user && user.active && AuthUtils.checkPassword(password, user.password)) {
24
24
  //TODO: Generar Sesion
25
25
  const session = '123'
26
- const accessToken = AuthUtils.generateToken(user.id.toString(), user.username, user.role.id, session)
26
+ const accessToken = AuthUtils.generateToken(user.id.toString(), user.username, user.role.id, user.tenant?.id, session)
27
27
  return {accessToken: accessToken}
28
28
  }else{
29
29
  throw new BadCredentialsError()
@@ -30,17 +30,18 @@ class AuthUtils{
30
30
  return bcryptjs.compareSync(password, hashPassword);
31
31
  }
32
32
 
33
- static tokenSignPayload(userId : string, username: string, roleId: string, session : string) {
33
+ static tokenSignPayload(userId : string, username: string, roleId: string, tenantId: string, session : string) {
34
34
  return {
35
35
  id: userId,
36
36
  username: username,
37
37
  roleId: roleId,
38
+ tenantId: tenantId,
38
39
  session: session
39
40
  };
40
41
  }
41
42
 
42
- static generateToken(userId : string, username: string, roleId: string, session : string) {
43
- const payload = AuthUtils.tokenSignPayload(userId, username, roleId, session)
43
+ static generateToken(userId : string, username: string, roleId: string, tenantId: string, session : string) {
44
+ const payload = AuthUtils.tokenSignPayload(userId, username, roleId, tenantId, session)
44
45
 
45
46
  const JWT_SECRET = DraxConfig.getOrLoad(IdentityConfig.JwtSecret)
46
47
  if(!JWT_SECRET){
@@ -0,0 +1,14 @@
1
+ import { object, string } from "zod"
2
+
3
+ const tenantSchema = object({
4
+ name: string({ required_error: "validation.required" })
5
+ .min(1, "validation.required")
6
+ .regex(/^[A-Z]/, "validation.startWithUpperCase"),
7
+
8
+
9
+ })
10
+
11
+
12
+ export default tenantSchema
13
+
14
+ export {tenantSchema}