@drax/identity-back 0.0.15 → 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 +12 -1
  4. package/dist/graphql/resolvers/tenant.resolvers.js +121 -0
  5. package/dist/graphql/resolvers/user.resolvers.js +5 -2
  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 +1 -4
  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 +10 -1
  23. package/dist/routes/TenantRoutes.js +183 -0
  24. package/dist/routes/UserRoutes.js +6 -1
  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 +13 -1
  34. package/src/graphql/resolvers/tenant.resolvers.ts +119 -0
  35. package/src/graphql/resolvers/user.resolvers.ts +5 -2
  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 +4 -7
  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 +9 -1
  54. package/src/routes/TenantRoutes.ts +178 -0
  55. package/src/routes/UserRoutes.ts +6 -1
  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,119 @@
1
+ import TenantServiceFactory from "../../factory/TenantServiceFactory.js";
2
+ import {IdentityPermissions} from "../../permissions/IdentityPermissions.js";
3
+ import {ValidationError, ValidationErrorToGraphQLError} from "@drax/common-back";
4
+ import {GraphQLError} from "graphql";
5
+ import {PermissionService} from "../../services/PermissionService.js";
6
+ import UnauthorizedError from "../../errors/UnauthorizedError.js";
7
+
8
+
9
+ export default {
10
+ Query: {
11
+ findTenantById: async (_, {id}, {rbac}) => {
12
+ try {
13
+ rbac.assertPermission(IdentityPermissions.ViewTenant)
14
+ const tenantService = TenantServiceFactory()
15
+ return await tenantService.findById(id)
16
+ } catch (e) {
17
+ if (e instanceof UnauthorizedError) {
18
+ throw new GraphQLError(e.message)
19
+ }
20
+ throw new GraphQLError('error.server')
21
+ }
22
+ },
23
+ findTenantByName: async (_, {name}, {rbac}) => {
24
+ try {
25
+ rbac.assertPermission(IdentityPermissions.ViewTenant)
26
+ const tenantService = TenantServiceFactory()
27
+ return await tenantService.findByName(name)
28
+ } catch (e) {
29
+ if (e instanceof UnauthorizedError) {
30
+ throw new GraphQLError(e.message)
31
+ }
32
+ throw new GraphQLError('error.server')
33
+ }
34
+ },
35
+ fetchTenant: async (_, {}, {rbac}) => {
36
+ try {
37
+ rbac.assertPermission(IdentityPermissions.ViewTenant)
38
+ const tenantService = TenantServiceFactory()
39
+ const tenants = await tenantService.fetchAll()
40
+ if(rbac.getAuthUser.tenantId){
41
+ return tenants.filter(t => t.id === rbac.getAuthUser.tenantId)
42
+ }else{
43
+ return tenants
44
+ }
45
+
46
+ } catch (e) {
47
+ if (e instanceof UnauthorizedError) {
48
+ throw new GraphQLError(e.message)
49
+ }
50
+ throw new GraphQLError('error.server')
51
+ }
52
+ },
53
+ paginateTenant: async (_, {page, limit, seach}, {rbac}) => {
54
+ try {
55
+ rbac.assertPermission(IdentityPermissions.ViewTenant)
56
+ const tenantService = TenantServiceFactory()
57
+ return await tenantService.paginate(page, limit, seach)
58
+ } catch (e) {
59
+ console.error("paginateTenant",e)
60
+ if (e instanceof UnauthorizedError) {
61
+ throw new GraphQLError(e.message)
62
+ }
63
+ throw new GraphQLError('error.server')
64
+ }
65
+ }
66
+ },
67
+ Mutation: {
68
+ createTenant: async (_, {input}, {rbac}) => {
69
+ try {
70
+ rbac.assertPermission(IdentityPermissions.CreateTenant)
71
+ const tenantService = TenantServiceFactory()
72
+ return await tenantService.create(input)
73
+ } catch (e) {
74
+ console.error("createTenant",e)
75
+ if (e instanceof ValidationError) {
76
+ throw ValidationErrorToGraphQLError(e)
77
+ }
78
+ if (e instanceof UnauthorizedError) {
79
+ throw new GraphQLError(e.message)
80
+ }
81
+ throw new GraphQLError('error.server')
82
+ }
83
+
84
+ },
85
+ updateTenant: async (_, {id, input}, {rbac}) => {
86
+ try {
87
+ rbac.assertPermission(IdentityPermissions.UpdateTenant)
88
+ const tenantService = TenantServiceFactory()
89
+ return await tenantService.update(id, input)
90
+ } catch (e) {
91
+ console.error("updateTenant",e)
92
+ if (e instanceof ValidationError) {
93
+ throw ValidationErrorToGraphQLError(e)
94
+ }
95
+ if (e instanceof UnauthorizedError) {
96
+ throw new GraphQLError(e.message)
97
+ }
98
+ throw new GraphQLError('error.server')
99
+ }
100
+ },
101
+ deleteTenant: async (_, {id}, {rbac}) => {
102
+ try {
103
+ rbac.assertPermission(IdentityPermissions.DeleteTenant)
104
+ const tenantService = TenantServiceFactory()
105
+ return await tenantService.delete(id)
106
+ } catch (e) {
107
+ console.error("deleteTenant",e)
108
+ if (e instanceof ValidationError) {
109
+ throw ValidationErrorToGraphQLError(e)
110
+ }
111
+ if (e instanceof UnauthorizedError) {
112
+ throw new GraphQLError(e.message)
113
+ }
114
+ throw new GraphQLError('error.server')
115
+ }
116
+
117
+ }
118
+ }
119
+ }
@@ -35,11 +35,14 @@ export default {
35
35
  }
36
36
 
37
37
  },
38
- paginateUser: async (_, {page, limit, search}, {rbac}) => {
38
+ paginateUser: async (_, {page, limit, search, filters = []}, {rbac}) => {
39
39
  try {
40
40
  rbac.assertPermission(IdentityPermissions.ViewUser)
41
41
  let userService= UserServiceFactory()
42
- return await userService.paginate(page, limit, search)
42
+ if(rbac.getAuthUser.tenantId){
43
+ filters.push({field: 'tenant', operator: '$eq', value: rbac.getAuthUser.tenantId})
44
+ }
45
+ return await userService.paginate(page, limit, search, filters)
43
46
  } catch (e) {
44
47
  if (e instanceof UnauthorizedError) {
45
48
  throw new GraphQLError(e.message)
@@ -0,0 +1,28 @@
1
+ type Tenant {
2
+ id: ID!
3
+ name: String
4
+ }
5
+
6
+ type TenantPaginated{
7
+ total: Int
8
+ page: Int
9
+ limit: Int
10
+ items: [Tenant]
11
+ }
12
+
13
+ type Query{
14
+ paginateTenant(page:Int, limit:Int, search:String): TenantPaginated
15
+ fetchTenant: [Tenant]
16
+ findTenantById(id: ID): Tenant
17
+ findTenantByName(name: String!): Tenant
18
+ }
19
+
20
+ input TenantInput{
21
+ name: String
22
+ }
23
+
24
+ type Mutation{
25
+ createTenant(input: TenantInput): Tenant
26
+ updateTenant(id: ID!, input: TenantInput): Tenant
27
+ deleteTenant(id: ID!): Boolean
28
+ }
@@ -4,6 +4,7 @@ type User {
4
4
  name: String
5
5
  email: String
6
6
  role: Role
7
+ tenant: Tenant
7
8
  phone: String
8
9
  avatar: String
9
10
  active: Boolean
@@ -28,6 +29,7 @@ input UserCreateInput{
28
29
  username: String!
29
30
  password: String!
30
31
  role: ID
32
+ tenant: ID
31
33
  email: String!
32
34
  phone: String
33
35
  active: Boolean
@@ -37,6 +39,7 @@ input UserUpdateInput{
37
39
  name: String
38
40
  username: String!
39
41
  role: ID
42
+ tenant: ID
40
43
  email: String!
41
44
  phone: String
42
45
  active: Boolean
package/src/index.ts CHANGED
@@ -1,12 +1,15 @@
1
1
  import GraphqlMerge from "./graphql/index.js"
2
2
  import UserServiceFactory from "./factory/UserServiceFactory.js";
3
3
  import RoleServiceFactory from "./factory/RoleServiceFactory.js";
4
+ import TenantServiceFactory from "./factory/TenantServiceFactory.js";
4
5
  import RoleService from "./services/RoleService.js";
5
6
  import UserService from "./services/UserService.js";
7
+ import TenantService from "./services/TenantService.js";
6
8
  import PermissionService from "./services/PermissionService.js";
7
9
  import Rbac from "./rbac/Rbac.js";
8
10
  import {UserRoutes} from "./routes/UserRoutes.js";
9
11
  import {RoleRoutes} from "./routes/RoleRoutes.js";
12
+ import {TenantRoutes} from "./routes/TenantRoutes.js";
10
13
  import AuthUtils from "./utils/AuthUtils.js";
11
14
  import {jwtMiddleware} from "./middleware/jwtMiddleware.js";
12
15
  import {rbacMiddleware} from "./middleware/rbacMiddleware.js";
@@ -45,12 +48,14 @@ export {
45
48
  //Service
46
49
  UserService,
47
50
  RoleService,
51
+ TenantService,
48
52
  PermissionService,
49
53
  Rbac,
50
54
 
51
55
  //Factories
52
56
  UserServiceFactory,
53
57
  RoleServiceFactory,
58
+ TenantServiceFactory,
54
59
 
55
60
  //GQL
56
61
  identityTypeDefs,
@@ -59,6 +64,7 @@ export {
59
64
  //API REST
60
65
  UserRoutes,
61
66
  RoleRoutes,
67
+ TenantRoutes,
62
68
 
63
69
  AuthUtils,
64
70
 
@@ -0,0 +1,9 @@
1
+ import {IID} from "./IID";
2
+
3
+ interface ITenant{
4
+ id: IID
5
+ name: string
6
+ }
7
+
8
+
9
+ export {ITenant}
@@ -0,0 +1,15 @@
1
+ import {ITenant} from './ITenant'
2
+ import {IPaginateFilter, IPaginateResult} from "@drax/common-back";
3
+ import {IID} from "./IID";
4
+ interface ITenantRepository{
5
+ create(role: ITenant): Promise<ITenant>;
6
+ update(id: IID, updatedRole: ITenant): Promise<ITenant | null>;
7
+ delete(id: IID): Promise<boolean>;
8
+ findById(id: IID): Promise<ITenant | null>;
9
+ findByName(name: string): Promise<ITenant | null>;
10
+ fetchAll(): Promise<ITenant[]>;
11
+ paginate(page?: number, limit?: number, search?:string, filters?: IPaginateFilter[]): Promise<IPaginateResult>;
12
+ table?():void
13
+ }
14
+
15
+ export {ITenantRepository}
@@ -1,7 +1,7 @@
1
- import {mongoose} from "@drax/common-back";
2
1
  import {IRole} from "./IRole";
3
2
  import {IUserGroup} from "./IUserGroup";
4
3
  import {IID} from "./IID";
4
+ import {ITenant} from "./ITenant";
5
5
 
6
6
  interface IUser {
7
7
  id?: IID
@@ -14,6 +14,7 @@ interface IUser {
14
14
  avatar?: string
15
15
  code?: string
16
16
  role: IRole | IID
17
+ tenant?: ITenant | IID
17
18
  groups: IID[] | IUserGroup[] | string[] | string
18
19
  toObject(): IUser;
19
20
  }
@@ -27,6 +28,7 @@ interface IUserCreate {
27
28
  active: boolean | number
28
29
  phone: string
29
30
  role: IID
31
+ tenant?: IID
30
32
  groups: IID[] | string
31
33
  }
32
34
 
@@ -38,6 +40,7 @@ interface IUserUpdate {
38
40
  active: boolean
39
41
  phone: string
40
42
  role: IID
43
+ tenant?: IID
41
44
  groups: IID[]
42
45
  password?: string
43
46
  }
@@ -1,21 +1,18 @@
1
1
  import type {IJwtUser} from "../interfaces/IJwtUser";
2
- import type {IRole, IRoleBase} from "../interfaces/IRole";
2
+ import type {IRole} from "../interfaces/IRole";
3
3
  import {DraxCache, DraxConfig} from "@drax/common-back";
4
4
  import RoleServiceFactory from "../factory/RoleServiceFactory.js";
5
5
  import Rbac from "../rbac/Rbac.js";
6
6
  import IdentityConfig from "../config/IdentityConfig.js";
7
7
 
8
8
  const cacheTTL = DraxConfig.getOrLoad(IdentityConfig.RbacCacheTTL) ? parseInt(DraxConfig.getOrLoad(IdentityConfig.RbacCacheTTL)) : 10000;
9
- const draxCache = new DraxCache<IRoleBase>(cacheTTL);
9
+ const draxCache = new DraxCache<IRole>(cacheTTL);
10
10
 
11
11
 
12
- async function roleLoader(k):Promise<IRoleBase | null> {
12
+ async function roleLoader(k):Promise<IRole | null> {
13
13
  const roleService = RoleServiceFactory()
14
14
  const role: IRole = await roleService.findById(k)
15
- if(role){
16
- return {id: role.id, name: role.name, permissions: role.permissions} as IRoleBase
17
- }
18
- return null
15
+ return role
19
16
  }
20
17
 
21
18
  async function rbacMiddleware (request, reply) {
@@ -0,0 +1,32 @@
1
+ import {mongoose, MongooseSoftDelete} from '@drax/common-back';
2
+ import uniqueValidator from 'mongoose-unique-validator';
3
+ import mongoosePaginate from 'mongoose-paginate-v2'
4
+ import {ITenant} from '../interfaces/ITenant'
5
+ const Schema = mongoose.Schema
6
+ import {PaginateModel} from "mongoose";
7
+
8
+
9
+ const TenantSchema = new Schema<ITenant>({
10
+ name: {
11
+ type: String, unique: true, required: true, index: true,
12
+ },
13
+ });
14
+
15
+ TenantSchema.plugin(uniqueValidator, {message: 'validation.unique'});
16
+ TenantSchema.plugin(MongooseSoftDelete);
17
+ TenantSchema.plugin(mongoosePaginate);
18
+
19
+
20
+ TenantSchema.set('toJSON', {getters: true});
21
+
22
+ const TENANT_MODEL_NAME = 'Tenant';
23
+ const TENANT_COLLECTION_NAME = 'tenants';
24
+ const TenantModel = mongoose.model<ITenant, PaginateModel<ITenant>>(TENANT_MODEL_NAME, TenantSchema,TENANT_COLLECTION_NAME);
25
+
26
+ export {
27
+ TenantSchema,
28
+ TenantModel
29
+ }
30
+
31
+ export default TenantModel
32
+
@@ -54,6 +54,11 @@ const UserSchema = new mongoose.Schema<IUser>({
54
54
  ref: 'Role',
55
55
  required: true,
56
56
  },
57
+ tenant: {
58
+ type: mongoose.Schema.Types.ObjectId,
59
+ ref: 'Tenant',
60
+ required: false,
61
+ },
57
62
  groups: [{
58
63
  type: mongoose.Schema.Types.ObjectId,
59
64
  ref: 'Group',
@@ -14,6 +14,13 @@ enum IdentityPermissions {
14
14
  ManageRole = "role:manage",
15
15
  PermissionsRole = "role:permissions",
16
16
 
17
+
18
+ CreateTenant = "tenant:create",
19
+ UpdateTenant = "tenant:update",
20
+ DeleteTenant = "tenant:delete",
21
+ ViewTenant = "tenant:view",
22
+ ManageTenant = "tenant:manage",
23
+
17
24
  }
18
25
 
19
26
  export default IdentityPermissions;
package/src/rbac/Rbac.ts CHANGED
@@ -1,16 +1,24 @@
1
- import {IRoleBase} from "../interfaces/IRole";
1
+ import {IRole} from "../interfaces/IRole";
2
2
  import {IJwtUser} from "../interfaces/IJwtUser";
3
3
  import UnauthorizedError from "../errors/UnauthorizedError.js";
4
4
 
5
5
  class Rbac{
6
- private role: IRoleBase;
6
+ private role: IRole;
7
7
  private authUser: IJwtUser;
8
8
 
9
- constructor(authUser: IJwtUser, role: IRoleBase) {
9
+ constructor(authUser: IJwtUser, role: IRole) {
10
10
  this.authUser = authUser;
11
11
  this.role = role;
12
12
  }
13
13
 
14
+ get getRole() {
15
+ return this.role
16
+ }
17
+
18
+ get getAuthUser() {
19
+ return this.authUser
20
+ }
21
+
14
22
  hasPermission(requiredPermission: string): boolean {
15
23
  if (!this.authUser || !this.role || !this.role.permissions || this.role.permissions.length === 0) {
16
24
  return false;
@@ -10,31 +10,32 @@ class RoleMongoRepository implements IRoleRepository{
10
10
  async create(roleData: IRole): Promise<IRole> {
11
11
  const role : mongoose.HydratedDocument<IRole> = new RoleModel(roleData)
12
12
  await role.save()
13
+ await role.populate('childRoles')
13
14
  return role
14
15
  }
15
16
 
16
17
  async update(id: mongoose.Types.ObjectId | string, roleData: IRole): Promise<IRole> {
17
- const role : mongoose.HydratedDocument<IRole> = await RoleModel.findOneAndUpdate({_id: id}, roleData, {new: true}).exec()
18
+ const role : mongoose.HydratedDocument<IRole> = await RoleModel.findOneAndUpdate({_id: id}, roleData, {new: true}).populate('childRoles').exec()
18
19
  return role
19
20
  }
20
21
 
21
22
  async delete(id: mongoose.Types.ObjectId): Promise<boolean> {
22
- const result : DeleteResult = await RoleModel.deleteOne(id).exec()
23
+ const result : DeleteResult = await RoleModel.deleteOne({_id: id}).exec()
23
24
  return result.deletedCount == 1
24
25
  }
25
26
 
26
27
  async findById(id: mongoose.Types.ObjectId): Promise<IRole | null>{
27
- const role: mongoose.HydratedDocument<IRole> | null = await RoleModel.findById(id).exec()
28
+ const role: mongoose.HydratedDocument<IRole> | null = await RoleModel.findById(id).populate('childRoles').exec()
28
29
  return role
29
30
  }
30
31
 
31
32
  async findByName(name: string): Promise<IRole | null>{
32
- const role: mongoose.HydratedDocument<IRole> | null = await RoleModel.findOne({name}).exec()
33
+ const role: mongoose.HydratedDocument<IRole> | null = await RoleModel.findOne({name}).populate('childRoles').exec()
33
34
  return role
34
35
  }
35
36
 
36
37
  async fetchAll(): Promise<IRole[]>{
37
- const roles: mongoose.HydratedDocument<IRole>[] = await RoleModel.find().exec()
38
+ const roles: mongoose.HydratedDocument<IRole>[] = await RoleModel.find().populate('childRoles').exec()
38
39
  return roles
39
40
  }
40
41
 
@@ -48,7 +49,7 @@ class RoleMongoRepository implements IRoleRepository{
48
49
  ]
49
50
  }
50
51
 
51
- const options = {page, limit} as PaginateOptions
52
+ const options = {populate: ['childRoles'], page, limit} as PaginateOptions
52
53
  const roles: PaginateResult<IRole> = await RoleModel.paginate(query, options)
53
54
  return {
54
55
  page: page,
@@ -0,0 +1,62 @@
1
+ import {TenantModel} from "../../models/TenantModel.js";
2
+ import {ITenant} from '../../interfaces/ITenant'
3
+ import {ITenantRepository} from '../../interfaces/ITenantRepository'
4
+ import {IPaginateFilter, IPaginateResult, mongoose} from "@drax/common-back";
5
+ import {FilterQuery, PaginateOptions, PaginateResult} from "mongoose";
6
+ import {DeleteResult} from "mongodb";
7
+
8
+ class TenantMongoRepository implements ITenantRepository{
9
+
10
+ async create(tenantData: ITenant): Promise<ITenant> {
11
+ const tenant : mongoose.HydratedDocument<ITenant> = new TenantModel(tenantData)
12
+ await tenant.save()
13
+ return tenant
14
+ }
15
+
16
+ async update(id: mongoose.Types.ObjectId | string, tenantData: ITenant): Promise<ITenant> {
17
+ const tenant : mongoose.HydratedDocument<ITenant> = await TenantModel.findOneAndUpdate({_id: id}, tenantData, {new: true}).exec()
18
+ return tenant
19
+ }
20
+
21
+ async delete(id: mongoose.Types.ObjectId): Promise<boolean> {
22
+ const result : DeleteResult = await TenantModel.deleteOne({_id:id}).exec()
23
+ return result.deletedCount == 1
24
+ }
25
+
26
+ async findById(id: mongoose.Types.ObjectId): Promise<ITenant | null>{
27
+ const tenant: mongoose.HydratedDocument<ITenant> | null = await TenantModel.findById(id).exec()
28
+ return tenant
29
+ }
30
+
31
+ async findByName(name: string): Promise<ITenant | null>{
32
+ const tenant: mongoose.HydratedDocument<ITenant> | null = await TenantModel.findOne({name}).exec()
33
+ return tenant
34
+ }
35
+
36
+ async fetchAll(): Promise<ITenant[]>{
37
+ const tenants: mongoose.HydratedDocument<ITenant>[] = await TenantModel.find().exec()
38
+ return tenants
39
+ }
40
+
41
+ async paginate(page:number = 1, limit:number = 5, search:string): Promise<IPaginateResult>{
42
+
43
+ const query = {}
44
+
45
+ if(search){
46
+ query['$or'] = [
47
+ {name: new RegExp(search, 'i')},
48
+ ]
49
+ }
50
+
51
+ const options = {page, limit} as PaginateOptions
52
+ const tenants: PaginateResult<ITenant> = await TenantModel.paginate(query, options)
53
+ return {
54
+ page: page,
55
+ limit: limit,
56
+ total: tenants.totalDocs,
57
+ items: tenants.docs
58
+ }
59
+ }
60
+ }
61
+
62
+ export default TenantMongoRepository
@@ -24,7 +24,7 @@ class UserMongoRepository implements IUserRepository {
24
24
 
25
25
  const user: mongoose.HydratedDocument<IUser> = new UserModel(userData)
26
26
  await user.save()
27
- await user.populate('role')
27
+ await user.populate(['role','tenant'])
28
28
  return user
29
29
  }catch (e){
30
30
  if(e instanceof mongoose.Error.ValidationError){
@@ -37,7 +37,7 @@ class UserMongoRepository implements IUserRepository {
37
37
 
38
38
  async update(id: mongoose.Types.ObjectId, userData: IUserUpdate): Promise<IUser> {
39
39
  try{
40
- const user: mongoose.HydratedDocument<IUser> = await UserModel.findOneAndUpdate({_id: id}, userData, {new: true}).populate('role').exec()
40
+ const user: mongoose.HydratedDocument<IUser> = await UserModel.findOneAndUpdate({_id: id}, userData, {new: true}).populate(['role','tenant']).exec()
41
41
  return user
42
42
  }catch (e){
43
43
  if(e instanceof mongoose.Error.ValidationError){
@@ -57,16 +57,16 @@ class UserMongoRepository implements IUserRepository {
57
57
 
58
58
 
59
59
  async findById(id: mongoose.Types.ObjectId): Promise<IUser> {
60
- const user: mongoose.HydratedDocument<IUser> = await UserModel.findById(id).populate('role').exec()
60
+ const user: mongoose.HydratedDocument<IUser> = await UserModel.findById(id).populate(['role','tenant']).exec()
61
61
  return user
62
62
  }
63
63
 
64
64
  async findByUsername(username: string): Promise<IUser> {
65
- const user: mongoose.HydratedDocument<IUser> = await UserModel.findOne({username: username}).populate('role').exec()
65
+ const user: mongoose.HydratedDocument<IUser> = await UserModel.findOne({username: username}).populate(['role','tenant']).exec()
66
66
  return user
67
67
  }
68
68
 
69
- async paginate(page: number = 1, limit: number = 5, search?:string): Promise<IPaginateResult> {
69
+ async paginate(page: number = 1, limit: number = 5, search?:string, filters?:IPaginateFilter[]): Promise<IPaginateResult> {
70
70
 
71
71
 
72
72
  const query = {}
@@ -79,7 +79,21 @@ class UserMongoRepository implements IUserRepository {
79
79
  ]
80
80
  }
81
81
 
82
- const options = {populate: ['role'], page: page, limit: limit }
82
+ if(filters){
83
+ for(const filter of filters){
84
+ if(filter.operator === '$eq'){
85
+ query[filter.field] = {$eq: filter.value}
86
+ }
87
+ if(filter.operator === '$ne'){
88
+ query[filter.field] = {$ne: filter.value}
89
+ }
90
+ if(filter.operator === '$in'){
91
+ query[filter.field] = {$in: filter.value}
92
+ }
93
+ }
94
+ }
95
+
96
+ const options = {populate: ['role','tenant'], page: page, limit: limit }
83
97
 
84
98
  const userPaginated: PaginateResult<IUser> = await UserModel.paginate(query, options)
85
99
  return {
@@ -25,6 +25,7 @@ class RoleSqliteRepository implements IRoleRepository{
25
25
 
26
26
  constructor(DATABASE:string, verbose:boolean = false) {
27
27
  this.db = new sqlite(DATABASE, {verbose: verbose ? console.log : null});
28
+ this.table()
28
29
  }
29
30
 
30
31
  table() {
@@ -78,7 +79,7 @@ class RoleSqliteRepository implements IRoleRepository{
78
79
  async findById(id: IID): Promise<IRole | null>{
79
80
  const role = this.db.prepare('SELECT * FROM roles WHERE id = ?').get(id);
80
81
  if(role){
81
- role.permissions = role.permissions ? role.permissions.split(",") : []
82
+ await this.populateRole(role)
82
83
  return role
83
84
  }
84
85
  return undefined
@@ -87,7 +88,7 @@ class RoleSqliteRepository implements IRoleRepository{
87
88
  async findByName(name: string): Promise<IRole | null>{
88
89
  const role = this.db.prepare('SELECT * FROM roles WHERE name = ?').get(name);
89
90
  if(role){
90
- role.permissions = role.permissions ? role.permissions.split(",") : []
91
+ await this.populateRole(role)
91
92
  return role
92
93
  }
93
94
  return undefined
@@ -125,7 +126,7 @@ class RoleSqliteRepository implements IRoleRepository{
125
126
  async fetchAll(): Promise<IRole[]>{
126
127
  const roles = this.db.prepare('SELECT * FROM roles').all();
127
128
  for (const role of roles) {
128
- role.permissions = role.permissions? role.permissions.split(",") : []
129
+ await this.populateRole(role)
129
130
  }
130
131
  return roles
131
132
  }
@@ -133,7 +134,7 @@ class RoleSqliteRepository implements IRoleRepository{
133
134
  async paginate(page = 1, limit = 5, search=""): Promise<IPaginateResult>{
134
135
  const offset = page > 1 ? (page - 1) * limit : 0
135
136
 
136
- let where
137
+ let where=""
137
138
  if (search) {
138
139
  where = ` WHERE name LIKE '%${search}%'`
139
140
  }
@@ -142,10 +143,9 @@ class RoleSqliteRepository implements IRoleRepository{
142
143
  const roles = this.db.prepare('SELECT * FROM roles LIMIT ? OFFSET ?'+where).all([limit, offset]);
143
144
 
144
145
  for (const role of roles) {
145
- role.permissions = role.permissions? role.permissions.split(",") : []
146
+ await this.populateRole(role)
146
147
  }
147
148
 
148
-
149
149
  return {
150
150
  page: page,
151
151
  limit: limit,
@@ -154,6 +154,27 @@ class RoleSqliteRepository implements IRoleRepository{
154
154
  }
155
155
  }
156
156
 
157
+ async findWithoutPopulateById(id: IID): Promise<IRole | null>{
158
+ const role = this.db.prepare('SELECT * FROM roles WHERE id = ?').get(id);
159
+ if(role){
160
+ return role
161
+ }
162
+ return undefined
163
+ }
164
+
165
+ async populateRole(role){
166
+ role.permissions = role.permissions? role.permissions.split(",") : []
167
+ role.childRoles = role.childRoles? role.childRoles.split(",") : []
168
+
169
+ const childRoles = []
170
+ for(const childRoleId of role.childRoles){
171
+ const childRole:IRole = await this.findWithoutPopulateById(childRoleId)
172
+ childRoles.push(childRole)
173
+ }
174
+ role.childRoles = childRoles
175
+ return role
176
+ }
177
+
157
178
 
158
179
  }
159
180