@drax/identity-back 0.11.5 → 0.12.2

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 (224) hide show
  1. package/dist/controllers/RoleController.js +8 -39
  2. package/dist/controllers/TenantController.js +1 -28
  3. package/dist/controllers/UserApiKeyController.js +3 -3
  4. package/dist/controllers/UserController.js +48 -209
  5. package/dist/errors/BadCredentialsError.js +12 -0
  6. package/dist/factory/RoleServiceFactory.js +1 -0
  7. package/dist/factory/TenantServiceFactory.js +1 -0
  8. package/dist/factory/UserApiKeyServiceFactory.js +5 -4
  9. package/dist/factory/UserServiceFactory.js +1 -0
  10. package/dist/graphql/resolvers/role.resolvers.js +2 -2
  11. package/dist/graphql/resolvers/tenant.resolvers.js +2 -2
  12. package/dist/graphql/resolvers/user-api-key.resolvers.js +2 -2
  13. package/dist/graphql/resolvers/user.resolvers.js +1 -1
  14. package/dist/index.js +6 -0
  15. package/dist/middleware/apiKeyMiddleware.js +2 -2
  16. package/dist/models/RoleModel.js +10 -7
  17. package/dist/models/TenantModel.js +11 -8
  18. package/dist/models/UserApiKeyModel.js +10 -7
  19. package/dist/models/UserGroupModel.js +7 -7
  20. package/dist/models/UserModel.js +10 -8
  21. package/dist/rbac/Rbac.js +10 -8
  22. package/dist/repository/mongo/RoleMongoRepository.js +20 -65
  23. package/dist/repository/mongo/TenantMongoRepository.js +18 -66
  24. package/dist/repository/mongo/UserApiKeyMongoRepository.js +29 -47
  25. package/dist/repository/mongo/UserMongoRepository.js +56 -85
  26. package/dist/repository/sqlite/RoleSqliteRepository.js +30 -115
  27. package/dist/repository/sqlite/TenantSqliteRepository.js +15 -105
  28. package/dist/repository/sqlite/UserApiKeySqliteRepository.js +42 -117
  29. package/dist/repository/sqlite/UserSqliteRepository.js +49 -130
  30. package/dist/routes/RoleRoutes.js +35 -10
  31. package/dist/routes/TenantRoutes.js +18 -9
  32. package/dist/routes/UserApiKeyRoutes.js +20 -4
  33. package/dist/routes/UserRoutes.js +92 -17
  34. package/dist/schemas/LoginSchema.js +9 -0
  35. package/dist/schemas/PasswordSchema.js +12 -0
  36. package/dist/schemas/RegisterSchema.js +19 -0
  37. package/dist/schemas/RoleSchema.js +23 -0
  38. package/dist/schemas/TenantSchema.js +13 -0
  39. package/dist/schemas/UserApiKeySchema.js +14 -0
  40. package/dist/schemas/UserSchema.js +39 -0
  41. package/dist/services/PermissionService.js +5 -5
  42. package/dist/services/RoleService.js +6 -6
  43. package/dist/services/TenantService.js +6 -6
  44. package/dist/services/UserApiKeyService.js +5 -5
  45. package/dist/services/UserService.js +14 -14
  46. package/dist/setup/CreateOrUpdateRole.js +5 -2
  47. package/dist/setup/CreateUserIfNotExist.js +3 -1
  48. package/dist/setup/RecoveryUserPassword.js +1 -1
  49. package/dist/zod/EndpointZod.js +9 -0
  50. package/dist/zod/TenantSchema.js +12 -0
  51. package/dist/zod/TenantZod.js +5 -3
  52. package/dist/zod/UserApiKeyZod.js +7 -3
  53. package/package.json +10 -9
  54. package/src/controllers/RoleController.ts +8 -36
  55. package/src/controllers/TenantController.ts +2 -25
  56. package/src/controllers/UserApiKeyController.ts +3 -3
  57. package/src/controllers/UserController.ts +50 -183
  58. package/src/errors/BadCredentialsError.ts +18 -1
  59. package/src/factory/RoleServiceFactory.ts +1 -0
  60. package/src/factory/TenantServiceFactory.ts +1 -0
  61. package/src/factory/UserApiKeyServiceFactory.ts +5 -4
  62. package/src/factory/UserServiceFactory.ts +1 -0
  63. package/src/graphql/resolvers/role.resolvers.ts +3 -2
  64. package/src/graphql/resolvers/tenant.resolvers.ts +3 -2
  65. package/src/graphql/resolvers/user-api-key.resolvers.ts +3 -2
  66. package/src/graphql/resolvers/user.resolvers.ts +2 -1
  67. package/src/index.ts +16 -0
  68. package/src/interfaces/ITenantRepository.ts +2 -2
  69. package/src/interfaces/IUserApiKeyRepository.ts +2 -2
  70. package/src/interfaces/IUserRepository.ts +3 -2
  71. package/src/middleware/apiKeyMiddleware.ts +2 -2
  72. package/src/models/RoleModel.ts +12 -7
  73. package/src/models/TenantModel.ts +13 -8
  74. package/src/models/UserApiKeyModel.ts +12 -7
  75. package/src/models/UserGroupModel.ts +7 -7
  76. package/src/models/UserModel.ts +10 -8
  77. package/src/rbac/Rbac.ts +12 -9
  78. package/src/repository/mongo/RoleMongoRepository.ts +23 -94
  79. package/src/repository/mongo/TenantMongoRepository.ts +19 -98
  80. package/src/repository/mongo/UserApiKeyMongoRepository.ts +31 -56
  81. package/src/repository/mongo/UserMongoRepository.ts +71 -130
  82. package/src/repository/sqlite/RoleSqliteRepository.ts +37 -146
  83. package/src/repository/sqlite/TenantSqliteRepository.ts +16 -156
  84. package/src/repository/sqlite/UserApiKeySqliteRepository.ts +46 -151
  85. package/src/repository/sqlite/UserSqliteRepository.ts +59 -173
  86. package/src/routes/RoleRoutes.ts +35 -12
  87. package/src/routes/TenantRoutes.ts +25 -9
  88. package/src/routes/UserApiKeyRoutes.ts +23 -7
  89. package/src/routes/UserRoutes.ts +117 -34
  90. package/src/schemas/LoginSchema.ts +12 -0
  91. package/src/schemas/PasswordSchema.ts +16 -0
  92. package/src/{zod/UserZod.ts → schemas/RegisterSchema.ts} +7 -10
  93. package/src/schemas/RoleSchema.ts +29 -0
  94. package/src/schemas/TenantSchema.ts +22 -0
  95. package/src/{zod/UserApiKeyZod.ts → schemas/UserApiKeySchema.ts} +8 -3
  96. package/src/schemas/UserSchema.ts +57 -0
  97. package/src/services/PermissionService.ts +6 -5
  98. package/src/services/RoleService.ts +6 -6
  99. package/src/services/TenantService.ts +10 -10
  100. package/src/services/UserApiKeyService.ts +5 -5
  101. package/src/services/UserService.ts +15 -16
  102. package/src/setup/CreateOrUpdateRole.ts +7 -4
  103. package/src/setup/CreateUserIfNotExist.ts +5 -3
  104. package/src/setup/RecoveryUserPassword.ts +1 -1
  105. package/test/data-obj/apikey/root-mongo-user-apikey.ts +2 -1
  106. package/test/data-obj/roles/admin-sqlite-role.ts +2 -2
  107. package/test/data-obj/roles/operator-sqlite-role.ts +1 -1
  108. package/test/data-obj/tenants/company-sqlite-tenant.ts +6 -0
  109. package/test/data-obj/users/root-sqlite-user.ts +2 -2
  110. package/test/initializers/RoleSqliteInitializer.ts +1 -1
  111. package/test/repository/mongo/role-mongo-repository.test.ts +3 -3
  112. package/test/repository/mongo/user-apikey-mongo-repository.test.ts +5 -4
  113. package/test/repository/mongo/user-mongo-repository.test.ts +4 -4
  114. package/test/repository/sqlite/role-sqlite-repository.test.ts +21 -9
  115. package/test/repository/sqlite/tenant-sqlite-repository.test.ts +74 -0
  116. package/test/repository/sqlite/user-sqlite-repository.test.ts +15 -9
  117. package/test/routes/data/admin-role.ts +10 -0
  118. package/test/routes/data/root-user.ts +13 -0
  119. package/test/routes/helpers/CreateRootUserAndAdminRole.ts +17 -0
  120. package/test/routes/helpers/FastifyTestServerFactory.ts +34 -0
  121. package/test/routes/helpers/InitializePermissions.ts +23 -0
  122. package/test/routes/helpers/SetupIdentityDrax.ts +22 -0
  123. package/test/routes/tenant-route.test.ts +336 -0
  124. package/test/routes/user-route.test.ts +186 -0
  125. package/test/schemas/lab-schema.test.ts +110 -0
  126. package/test/service/mock-service.test.ts +3 -3
  127. package/test/service/role-service.test.ts +3 -3
  128. package/test/service/user-service.test.ts +16 -25
  129. package/test.db +0 -0
  130. package/tsconfig.tsbuildinfo +1 -1
  131. package/types/controllers/RoleController.d.ts +0 -1
  132. package/types/controllers/RoleController.d.ts.map +1 -1
  133. package/types/controllers/TenantController.d.ts +0 -1
  134. package/types/controllers/TenantController.d.ts.map +1 -1
  135. package/types/controllers/UserController.d.ts +11 -4
  136. package/types/controllers/UserController.d.ts.map +1 -1
  137. package/types/errors/BadCredentialsError.d.ts +9 -1
  138. package/types/errors/BadCredentialsError.d.ts.map +1 -1
  139. package/types/factory/RoleServiceFactory.d.ts.map +1 -1
  140. package/types/factory/TenantServiceFactory.d.ts.map +1 -1
  141. package/types/factory/UserApiKeyServiceFactory.d.ts.map +1 -1
  142. package/types/factory/UserServiceFactory.d.ts.map +1 -1
  143. package/types/graphql/resolvers/role.resolvers.d.ts +3 -9
  144. package/types/graphql/resolvers/role.resolvers.d.ts.map +1 -1
  145. package/types/graphql/resolvers/tenant.resolvers.d.ts +3 -9
  146. package/types/graphql/resolvers/tenant.resolvers.d.ts.map +1 -1
  147. package/types/graphql/resolvers/user-api-key.resolvers.d.ts +3 -9
  148. package/types/graphql/resolvers/user-api-key.resolvers.d.ts.map +1 -1
  149. package/types/graphql/resolvers/user.resolvers.d.ts +3 -9
  150. package/types/graphql/resolvers/user.resolvers.d.ts.map +1 -1
  151. package/types/index.d.ts +5 -1
  152. package/types/index.d.ts.map +1 -1
  153. package/types/interfaces/ITenantRepository.d.ts +2 -2
  154. package/types/interfaces/ITenantRepository.d.ts.map +1 -1
  155. package/types/interfaces/IUserApiKeyRepository.d.ts +2 -2
  156. package/types/interfaces/IUserApiKeyRepository.d.ts.map +1 -1
  157. package/types/interfaces/IUserRepository.d.ts +3 -2
  158. package/types/interfaces/IUserRepository.d.ts.map +1 -1
  159. package/types/models/RoleModel.d.ts +7 -7
  160. package/types/models/RoleModel.d.ts.map +1 -1
  161. package/types/models/TenantModel.d.ts +7 -7
  162. package/types/models/TenantModel.d.ts.map +1 -1
  163. package/types/models/UserApiKeyModel.d.ts +7 -7
  164. package/types/models/UserApiKeyModel.d.ts.map +1 -1
  165. package/types/models/UserGroupModel.d.ts +2 -2
  166. package/types/models/UserGroupModel.d.ts.map +1 -1
  167. package/types/models/UserModel.d.ts +7 -7
  168. package/types/models/UserModel.d.ts.map +1 -1
  169. package/types/rbac/Rbac.d.ts +1 -1
  170. package/types/rbac/Rbac.d.ts.map +1 -1
  171. package/types/repository/mongo/RoleMongoRepository.d.ts +9 -11
  172. package/types/repository/mongo/RoleMongoRepository.d.ts.map +1 -1
  173. package/types/repository/mongo/TenantMongoRepository.d.ts +8 -11
  174. package/types/repository/mongo/TenantMongoRepository.d.ts.map +1 -1
  175. package/types/repository/mongo/UserApiKeyMongoRepository.d.ts +12 -5
  176. package/types/repository/mongo/UserApiKeyMongoRepository.d.ts.map +1 -1
  177. package/types/repository/mongo/UserMongoRepository.d.ts +11 -12
  178. package/types/repository/mongo/UserMongoRepository.d.ts.map +1 -1
  179. package/types/repository/sqlite/RoleSqliteRepository.d.ts +14 -14
  180. package/types/repository/sqlite/RoleSqliteRepository.d.ts.map +1 -1
  181. package/types/repository/sqlite/TenantSqliteRepository.d.ts +12 -14
  182. package/types/repository/sqlite/TenantSqliteRepository.d.ts.map +1 -1
  183. package/types/repository/sqlite/UserApiKeySqliteRepository.d.ts +15 -11
  184. package/types/repository/sqlite/UserApiKeySqliteRepository.d.ts.map +1 -1
  185. package/types/repository/sqlite/UserSqliteRepository.d.ts +15 -12
  186. package/types/repository/sqlite/UserSqliteRepository.d.ts.map +1 -1
  187. package/types/routes/RoleRoutes.d.ts.map +1 -1
  188. package/types/routes/TenantRoutes.d.ts.map +1 -1
  189. package/types/routes/UserApiKeyRoutes.d.ts.map +1 -1
  190. package/types/routes/UserRoutes.d.ts.map +1 -1
  191. package/types/schemas/LoginSchema.d.ts +20 -0
  192. package/types/schemas/LoginSchema.d.ts.map +1 -0
  193. package/types/schemas/PasswordSchema.d.ts +27 -0
  194. package/types/schemas/PasswordSchema.d.ts.map +1 -0
  195. package/types/schemas/RegisterSchema.d.ts +32 -0
  196. package/types/schemas/RegisterSchema.d.ts.map +1 -0
  197. package/types/schemas/RoleSchema.d.ts +67 -0
  198. package/types/schemas/RoleSchema.d.ts.map +1 -0
  199. package/types/schemas/TenantSchema.d.ts +29 -0
  200. package/types/schemas/TenantSchema.d.ts.map +1 -0
  201. package/types/schemas/UserApiKeySchema.d.ts +39 -0
  202. package/types/schemas/UserApiKeySchema.d.ts.map +1 -0
  203. package/types/schemas/UserSchema.d.ts +161 -0
  204. package/types/schemas/UserSchema.d.ts.map +1 -0
  205. package/types/services/PermissionService.d.ts +1 -0
  206. package/types/services/PermissionService.d.ts.map +1 -1
  207. package/types/services/TenantService.d.ts +3 -3
  208. package/types/services/TenantService.d.ts.map +1 -1
  209. package/types/services/UserService.d.ts.map +1 -1
  210. package/types/setup/CreateOrUpdateRole.d.ts +2 -2
  211. package/types/setup/CreateOrUpdateRole.d.ts.map +1 -1
  212. package/types/setup/CreateUserIfNotExist.d.ts +2 -2
  213. package/types/setup/CreateUserIfNotExist.d.ts.map +1 -1
  214. package/types/zod/EndpointZod.d.ts +20 -0
  215. package/types/zod/EndpointZod.d.ts.map +1 -0
  216. package/types/zod/TenantSchema.d.ts +26 -0
  217. package/types/zod/TenantSchema.d.ts.map +1 -0
  218. package/types/zod/TenantZod.d.ts +13 -3
  219. package/types/zod/TenantZod.d.ts.map +1 -1
  220. package/types/zod/UserApiKeyZod.d.ts +23 -3
  221. package/types/zod/UserApiKeyZod.d.ts.map +1 -1
  222. package/types/zod/UserZod.d.ts +6 -6
  223. package/src/zod/RoleZod.ts +0 -14
  224. package/src/zod/TenantZod.ts +0 -14
@@ -1,24 +1,28 @@
1
1
  import {UserModel} from "../../models/UserModel.js";
2
2
  import {
3
3
  mongoose,
4
- MongooseErrorToValidationError,
5
- MongooseQueryFilter, MongooseSort,
6
- MongoServerErrorToValidationError,
7
- ValidationError
4
+ MongooseValidationErrorToValidationError,
5
+ MongooseQueryFilter,
6
+ MongooseSort,
7
+ ValidationError, MongooseCastErrorToValidationError
8
8
  } from "@drax/common-back"
9
9
  import type {IUser, IUserCreate, IUserUpdate} from "@drax/identity-share";
10
- import {DeleteResult, MongoServerError} from "mongodb";
11
10
  import type {IUserRepository} from "../../interfaces/IUserRepository";
12
- import {Cursor, PaginateResult} from "mongoose";
11
+ import {Cursor} from "mongoose";
13
12
  import RoleMongoRepository from "./RoleMongoRepository.js";
14
- import {IDraxFindOptions, IDraxPaginateOptions, IDraxPaginateResult} from "@drax/crud-share";
15
- import type {IDraxFieldFilter} from "@drax/crud-share/dist";
13
+ import {IDraxFindOptions} from "@drax/crud-share";
14
+ import {AbstractMongoRepository} from "@drax/crud-back";
16
15
 
17
- class UserMongoRepository implements IUserRepository {
18
- private roleRepository: RoleMongoRepository;
19
- _searchFields = ['name','username','email','phone']
16
+ class UserMongoRepository extends AbstractMongoRepository<IUser,IUserCreate,IUserUpdate> implements IUserRepository {
17
+ protected roleRepository: RoleMongoRepository;
18
+
19
+ protected _searchFields = ['name','username','email','phone']
20
+ protected _populateFields = ['role','tenant']
21
+ protected _model = UserModel
22
+ protected _lean = false
20
23
 
21
24
  constructor() {
25
+ super()
22
26
  this.roleRepository = new RoleMongoRepository()
23
27
  }
24
28
 
@@ -31,123 +35,82 @@ class UserMongoRepository implements IUserRepository {
31
35
 
32
36
  const user: mongoose.HydratedDocument<IUser> = new UserModel(userData)
33
37
  await user.save()
34
- await user.populate(['role','tenant'])
38
+ await user.populate(this._populateFields)
35
39
  return user
36
40
  }catch (e){
37
41
  if(e instanceof mongoose.Error.ValidationError){
38
- throw MongooseErrorToValidationError(e)
39
- }
40
- throw e
41
- }
42
-
43
- }
44
-
45
- async update(id: string, userData: IUserUpdate): Promise<IUser> {
46
- try{
47
- const user: mongoose.HydratedDocument<IUser> = await UserModel.findOneAndUpdate({_id: id}, userData, {new: true}).populate(['role','tenant']).exec()
48
- return user
49
- }catch (e){
50
- if(e instanceof mongoose.Error.ValidationError){
51
- throw MongooseErrorToValidationError(e)
42
+ throw MongooseValidationErrorToValidationError(e)
52
43
  }
53
- if(e instanceof MongoServerError || e.name === 'MongoServerError'){
54
- throw MongoServerErrorToValidationError(e)
44
+ if (e instanceof mongoose.Error.CastError) {
45
+ throw MongooseCastErrorToValidationError(e)
55
46
  }
56
47
  throw e
57
48
  }
58
- }
59
49
 
60
- async updatePartial(id: string, data: any): Promise<IUser> {
61
- try {
62
- const item: mongoose.HydratedDocument<IUser> = await UserModel.findOneAndUpdate({_id: id}, data, {new: true}).populate(['role','tenant']).exec()
63
- return item
64
- } catch (e) {
65
- if (e instanceof mongoose.Error.ValidationError) {
66
- throw MongooseErrorToValidationError(e)
67
- }
68
- throw e
69
- }
70
- }
71
-
72
- async delete(id: string): Promise<boolean> {
73
- const result: DeleteResult = await UserModel.deleteOne({_id: id}).exec()
74
- return result.deletedCount == 1
75
- }
76
-
77
-
78
- async findById(id:string): Promise<IUser> {
79
- const user: mongoose.HydratedDocument<IUser> = await UserModel.findById(id).populate(['role','tenant']).exec()
80
- return user
81
50
  }
82
51
 
83
52
  async findByUsername(username: string): Promise<IUser> {
84
- const user: mongoose.HydratedDocument<IUser> = await UserModel.findOne({username: username}).populate(['role','tenant']).exec()
85
- return user
53
+ const user = await UserModel
54
+ .findOne({username: username})
55
+ .populate(['role','tenant'])
56
+ .lean(this._lean)
57
+ .exec()
58
+ return user as IUser
86
59
  }
87
60
 
88
61
  async findByUsernameWithPassword(username: string): Promise<IUser> {
89
- const user: mongoose.HydratedDocument<IUser> = await UserModel.findOne({username: username}).select('+password').populate(['role','tenant']).exec()
90
- return user
62
+ const user = await UserModel
63
+ .findOne({username: username})
64
+ .select('+password')
65
+ .populate(['role','tenant'])
66
+ .lean(this._lean)
67
+ .exec()
68
+ return user as IUser
69
+ }
70
+
71
+ async findByIdWithPassword(id: string): Promise<IUser> {
72
+ const user = await UserModel.findById(id)
73
+ .select('+password')
74
+ .populate(['role','tenant'])
75
+ .lean(this._lean)
76
+ .exec()
77
+ return user as IUser
91
78
  }
92
79
 
93
80
  async findByEmail(email: string): Promise<IUser> {
94
- const user: mongoose.HydratedDocument<IUser> = await UserModel.findOne({email: email}).populate(['role','tenant']).exec()
95
- return user
81
+ const user = await UserModel
82
+ .findOne({email: email})
83
+ .populate(['role','tenant'])
84
+ .lean(this._lean)
85
+ .exec()
86
+ return user as IUser
96
87
  }
97
88
 
98
89
  async findByEmailCode(code: string): Promise<IUser> {
99
- const user: mongoose.HydratedDocument<IUser> = await UserModel.findOne({emailCode: {$eq: code}, emailVerified: {$eq: false} }).populate(['role','tenant']).exec()
100
- return user
90
+ const user = await UserModel
91
+ .findOne({emailCode: {$eq: code}, emailVerified: {$eq: false} })
92
+ .populate(['role','tenant'])
93
+ .lean(this._lean)
94
+ .exec()
95
+ return user as IUser
101
96
  }
102
97
 
103
98
  async findByPhoneCode(code: string): Promise<IUser> {
104
- const user: mongoose.HydratedDocument<IUser> = await UserModel.findOne({phoneCode: {$eq: code}, phoneVerified: {$eq: false} }).populate(['role','tenant']).exec()
105
- return user
99
+ const user = await UserModel
100
+ .findOne({phoneCode: {$eq: code}, phoneVerified: {$eq: false} })
101
+ .populate(['role','tenant'])
102
+ .lean(this._lean)
103
+ .exec()
104
+ return user as IUser
106
105
  }
107
106
 
108
107
  async findByRecoveryCode(code: string): Promise<IUser> {
109
- const user: mongoose.HydratedDocument<IUser> = await UserModel.findOne({recoveryCode: {$eq: code}, active: {$eq: true} }).populate(['role','tenant']).exec()
110
- return user
111
- }
112
-
113
- async paginate({
114
- page= 1,
115
- limit= 5,
116
- orderBy= '',
117
- order= false,
118
- search= '',
119
- filters= []} : IDraxPaginateOptions): Promise<IDraxPaginateResult<IUser>> {
120
-
121
- const query = {}
122
-
123
- if(search){
124
- query['$or'] = this._searchFields.map(field => ({[field]: new RegExp(search.toString(), 'i')}))
125
- }
126
-
127
- MongooseQueryFilter.applyFilters(query, filters)
128
-
129
- const sort = MongooseSort.applySort(orderBy, order)
130
-
131
- const options = {populate: ['role','tenant'], page, limit, sort }
132
-
133
- const userPaginated: PaginateResult<IUser> = await UserModel.paginate(query, options)
134
- return {
135
- page: page,
136
- limit: limit,
137
- total: userPaginated.totalDocs,
138
- items: userPaginated.docs
139
- }
140
- }
141
-
142
-
143
- async search(value: string, limit: number = 1000, filters: IDraxFieldFilter[] = []): Promise<IUser[]> {
144
- const query = {}
145
- if(value){
146
- query['$or'] = this._searchFields.map(field => ({[field]: new RegExp(value.toString(), 'i')}))
147
- }
148
- MongooseQueryFilter.applyFilters(query, filters)
149
- const items: mongoose.HydratedDocument<IUser>[] = await UserModel.find(query).limit(limit).exec()
150
- return items
108
+ const user = await UserModel
109
+ .findOne({recoveryCode: {$eq: code}, active: {$eq: true} })
110
+ .populate(['role','tenant'])
111
+ .lean(this._lean)
112
+ .exec()
113
+ return user as IUser
151
114
  }
152
115
 
153
116
  async changePassword(id: string, password: string):Promise<boolean> {
@@ -170,29 +133,6 @@ class UserMongoRepository implements IUserRepository {
170
133
  }
171
134
  }
172
135
 
173
- async find({
174
- limit = 0,
175
- orderBy = '',
176
- order = false,
177
- search = '',
178
- filters = []
179
- }: IDraxFindOptions): Promise<IUser[]> {
180
-
181
- const query = {}
182
-
183
- if (search) {
184
- query['$or'] = [
185
- {name: new RegExp(search, 'i')},
186
- ]
187
- }
188
-
189
- MongooseQueryFilter.applyFilters(query, filters)
190
-
191
- const sort = MongooseSort.applySort(orderBy, order)
192
-
193
- return await UserModel.find(query).populate(['role','tenant']).limit(limit).sort(sort)
194
- }
195
-
196
136
  async findCursor({
197
137
  limit = 0,
198
138
  orderBy = '',
@@ -200,13 +140,14 @@ class UserMongoRepository implements IUserRepository {
200
140
  search = '',
201
141
  filters = []
202
142
  }: IDraxFindOptions): Promise<Cursor> {
203
- console.log("RoleMongoRepository.findCursor called")
204
143
  const query = {}
205
144
 
206
- if (search) {
207
- query['$or'] = [
208
- {name: new RegExp(search, 'i')},
209
- ]
145
+ if(search){
146
+ if(mongoose.Types.ObjectId.isValid(search)) {
147
+ query['_id'] = new mongoose.Types.ObjectId(search)
148
+ }else{
149
+ query['$or'] = this._searchFields.map(field => ({[field]: new RegExp(search.toString(), 'i')}))
150
+ }
210
151
  }
211
152
 
212
153
  MongooseQueryFilter.applyFilters(query, filters)
@@ -4,45 +4,42 @@ import sqlite from "better-sqlite3";
4
4
  import {randomUUID} from "node:crypto";
5
5
  import {IDraxPaginateResult, IDraxPaginateOptions} from "@drax/crud-share";
6
6
  import {IRole, IRoleBase} from "@drax/identity-share";
7
+ import {AbstractSqliteRepository} from "@drax/crud-back";
7
8
  import {
8
9
  SqliteErrorToValidationError,
9
- SqliteTableBuilder,
10
10
  SqliteTableField,
11
11
  SqlQueryFilter,
12
12
  SqlSort
13
13
  } from "@drax/common-back";
14
14
 
15
- const tableFields: SqliteTableField[] = [
16
- {name: "name", type: "TEXT", unique: true, primary: false},
17
- {name: "permissions", type: "TEXT", unique: false, primary: false},
18
- {name: "childRoles", type: "TEXT", unique: false, primary: false},
19
- {name: "readonly", type: "INTEGER", unique: false, primary: false},
20
- {name: "createdAt", type: "TEXT", unique: false, primary: false},
21
- {name: "updatedAt", type: "TEXT", unique: false, primary: false},
22
- ]
23
15
 
24
16
 
25
- class RoleSqliteRepository implements IRoleRepository{
26
-
27
- private db: any;
28
- private dataBaseFile: string;
29
-
30
- constructor(dataBaseFile:string, verbose:boolean = false) {
31
- this.dataBaseFile = dataBaseFile;
32
- this.db = new sqlite(dataBaseFile, {verbose: verbose ? console.log : null});
33
- this.table()
17
+ class RoleSqliteRepository extends AbstractSqliteRepository<IRole, IRoleBase, IRoleBase> implements IRoleRepository{
18
+
19
+ protected db: any;
20
+ protected tableName: string = 'roles';
21
+ protected dataBaseFile: string;
22
+ protected searchFields: string[] = [];
23
+ protected booleanFields: string[] = [];
24
+ protected identifier: string = '_id';
25
+ protected populateFields = []
26
+ protected tableFields: SqliteTableField[] = [
27
+ {name: "name", type: "TEXT", unique: true, primary: false},
28
+ {name: "permissions", type: "TEXT", unique: false, primary: false},
29
+ {name: "childRoles", type: "TEXT", unique: false, primary: false},
30
+ {name: "readonly", type: "INTEGER", unique: false, primary: false},
31
+ {name: "createdAt", type: "TEXT", unique: false, primary: false},
32
+ {name: "updatedAt", type: "TEXT", unique: false, primary: false},
33
+ ]
34
+ protected verbose: boolean;
35
+
36
+ constructor(dataBaseFile: string, verbose: boolean = false) {
37
+ super(dataBaseFile, verbose);
38
+ this.tableName = 'roles'
34
39
  }
35
40
 
36
- table() {
37
- const builder = new SqliteTableBuilder(
38
- this.dataBaseFile,
39
- 'roles',
40
- tableFields,
41
- false);
42
- builder.build('id')
43
- }
44
41
 
45
- normalizeData(roleData: IRoleBase){
42
+ async prepareData(roleData: any){
46
43
 
47
44
  roleData.readonly = roleData.readonly ? 1 : 0
48
45
 
@@ -55,152 +52,46 @@ class RoleSqliteRepository implements IRoleRepository{
55
52
  }
56
53
  }
57
54
 
58
- async create(roleData: IRoleBase): Promise<IRole> {
59
- try{
60
-
61
- if(!roleData.id){
62
- roleData.id = randomUUID()
63
- }
64
-
65
- this.normalizeData(roleData)
66
- roleData.createdAt = (new Date().toISOString())
67
-
68
- const fields = Object.keys(roleData)
69
- .map(field => `${field}`)
70
- .join(', ');
71
-
72
- const values = Object.keys(roleData)
73
- .map(field => `@${field}`)
74
- .join(', ');
75
-
76
-
77
- const stmt = this.db.prepare(`INSERT INTO roles (${fields}) VALUES (${values})`);
78
- stmt.run(roleData)
79
- return this.findById(roleData.id as UUID)
80
- }catch (e){
81
- console.log(e)
82
- throw SqliteErrorToValidationError(e, roleData)
83
- }
84
- }
85
-
86
-
87
-
88
- async update(id: string, roleData: IRoleBase): Promise<IRole> {
89
- try{
90
- this.normalizeData(roleData)
91
- roleData.updatedAt = (new Date().toISOString())
92
-
93
- const setClauses = Object.keys(roleData)
94
- .map(field => `${field} = @${field}`)
95
- .join(', ');
96
-
97
- roleData.id = id
98
-
99
- const stmt = this.db.prepare( `UPDATE roles SET ${setClauses} WHERE id = @id `);
100
-
101
- stmt.run(roleData);
102
-
103
- return this.findById(id)
104
- }catch (e){
105
- console.log(e)
106
- throw SqliteErrorToValidationError(e, roleData)
107
- }
108
-
109
- }
110
-
111
- async paginate({
112
- page= 1,
113
- limit= 5,
114
- orderBy= '',
115
- order= false,
116
- search= '',
117
- filters= []} : IDraxPaginateOptions): Promise<IDraxPaginateResult<IRole>>{
118
- const offset = page > 1 ? (page - 1) * limit : 0
119
-
120
- let where=""
121
- if (search) {
122
- where = ` WHERE name LIKE '%${search}%'`
123
- }
55
+ async prepareItem(role: any): Promise<IRole>{
56
+ if(role){
124
57
 
125
- where = SqlQueryFilter.applyFilters(where, filters)
126
- const sort = SqlSort.applySort(orderBy, order)
58
+ role.permissions = role && role.permissions ? role.permissions.split(",") : []
127
59
 
128
- const rCount = this.db.prepare('SELECT COUNT(*) as count FROM roles'+where).get();
129
- where += sort
130
- const roles = this.db.prepare('SELECT * FROM roles ' + where + ' LIMIT ? OFFSET ?').all([limit, offset]);
60
+ role.childRoles = role && role.childRoles ? role.childRoles.split(",") : []
131
61
 
132
- for (const role of roles) {
133
- await this.populateRole(role)
62
+ const childRoles = []
63
+ for(const childRoleId of role.childRoles){
64
+ const childRole:IRole = await this.findWithoutPopulateById(childRoleId)
65
+ childRoles.push(childRole)
66
+ }
67
+ role.childRoles = childRoles
68
+ return role
134
69
  }
135
70
 
136
- return {
137
- page: page,
138
- limit: limit,
139
- total: rCount.count,
140
- items: roles
141
- }
142
71
  }
143
72
 
144
- async delete(id: string): Promise<boolean> {
145
- const stmt = this.db.prepare('DELETE FROM roles WHERE id = ?');
146
- stmt.run(id);
147
- return true
148
- }
149
73
 
150
- async deleteAll(): Promise<boolean> {
151
- const stmt = this.db.prepare('DELETE FROM roles');
152
- stmt.run();
153
- return true
154
- }
155
-
156
- async findById(id: string): Promise<IRole | null>{
157
- const role = this.db.prepare('SELECT * FROM roles WHERE id = ?').get(id);
158
- if(role){
159
- await this.populateRole(role)
160
- return role
161
- }
162
- return undefined
163
- }
164
74
 
165
75
  async findByName(name: string): Promise<IRole | null>{
166
76
  const role = this.db.prepare('SELECT * FROM roles WHERE name = ?').get(name);
167
77
  if(role){
168
- await this.populateRole(role)
78
+ await this.decorate(role)
169
79
  return role
170
80
  }
171
81
  return undefined
172
82
  }
173
83
 
174
- async fetchAll(): Promise<IRole[]>{
175
- const roles = this.db.prepare('SELECT * FROM roles').all();
176
- for (const role of roles) {
177
- await this.populateRole(role)
178
- }
179
- return roles
180
- }
181
-
182
84
 
183
85
 
184
86
  async findWithoutPopulateById(id: string): Promise<IRole | null>{
185
- const role = this.db.prepare('SELECT * FROM roles WHERE id = ?').get(id);
87
+ const role = this.db.prepare(`SELECT * FROM roles WHERE ${this.identifier} = ?`).get(id);
186
88
  if(role){
187
89
  return role
188
90
  }
189
91
  return undefined
190
92
  }
191
93
 
192
- async populateRole(role){
193
- role.permissions = role.permissions? role.permissions.split(",") : []
194
- role.childRoles = role.childRoles? role.childRoles.split(",") : []
195
94
 
196
- const childRoles = []
197
- for(const childRoleId of role.childRoles){
198
- const childRole:IRole = await this.findWithoutPopulateById(childRoleId)
199
- childRoles.push(childRole)
200
- }
201
- role.childRoles = childRoles
202
- return role
203
- }
204
95
 
205
96
 
206
97
  }
@@ -1,170 +1,30 @@
1
1
  import {ITenant, ITenantBase} from '@drax/identity-share'
2
2
  import {ITenantRepository} from '../../interfaces/ITenantRepository'
3
- import {UUID} from "crypto";
4
- import sqlite from "better-sqlite3";
5
- import {randomUUID} from "node:crypto";
6
- import {IDraxPaginateResult, IDraxPaginateOptions, IDraxFindOptions} from "@drax/crud-share";
7
- import {SqliteErrorToValidationError, SqliteTableBuilder, SqlQueryFilter, SqlSort} from "@drax/common-back";
8
3
  import type {SqliteTableField} from "@drax/common-back";
4
+ import {AbstractSqliteRepository} from "@drax/crud-back";
9
5
 
6
+ class TenantSqliteRepository extends AbstractSqliteRepository<ITenant,ITenantBase,ITenantBase> implements ITenantRepository{
10
7
 
11
- const tableFields: SqliteTableField[] = [
12
- {name: "name", type: "TEXT", unique: false, primary: false},
13
- {name: "createdAt", type: "TEXT", unique: false, primary: false},
14
- {name: "updatedAt", type: "TEXT", unique: false, primary: false},
15
- ]
8
+ protected db: any;
9
+ protected tableName: string = 'tenants';
10
+ protected dataBaseFile: string;
11
+ protected searchFields: string[] = [];
12
+ protected booleanFields: string[] = [];
13
+ protected identifier: string = '_id';
14
+ protected populateFields = []
15
+ protected tableFields: SqliteTableField[] = [
16
+ {name: "name", type: "TEXT", unique: false, primary: false},
17
+ {name: "createdAt", type: "TEXT", unique: false, primary: false},
18
+ {name: "updatedAt", type: "TEXT", unique: false, primary: false},
19
+ ]
20
+ protected verbose: boolean;
16
21
 
17
22
 
18
- class TenantSqliteRepository implements ITenantRepository{
19
-
20
- private db: any;
21
- private dataBaseFile: string;
22
-
23
- constructor(dataBaseFile:string, verbose:boolean = false) {
24
- this.dataBaseFile = dataBaseFile;
25
- this.db = new sqlite(this.dataBaseFile, {verbose: verbose ? console.log : null});
26
- this.table()
27
- }
28
-
29
- table() {
30
- const builder = new SqliteTableBuilder(
31
- this.dataBaseFile,
32
- 'tenants',
33
- tableFields,
34
- false);
35
- builder.build('id')
36
- }
37
-
38
-
39
-
40
- async create(tenantData: ITenantBase): Promise<ITenant> {
41
- try{
42
-
43
- if(!tenantData.id){
44
- tenantData.id = randomUUID()
45
- }
46
-
47
- tenantData.createdAt = (new Date().toISOString())
48
-
49
- const fields = Object.keys(tenantData)
50
- .map(field => `${field}`)
51
- .join(', ');
52
-
53
- const values = Object.keys(tenantData)
54
- .map(field => `@${field}`)
55
- .join(', ');
56
-
57
- const stmt = this.db.prepare(`INSERT INTO tenants (${fields}) VALUES (${values})`);
58
- stmt.run(tenantData)
59
- return this.findById(tenantData.id as UUID)
60
- }catch (e){
61
- console.log(e)
62
- throw SqliteErrorToValidationError(e, tenantData)
63
- }
64
- }
65
-
66
- async findById(id: string): Promise<ITenant | null>{
67
- const tenant = this.db.prepare('SELECT * FROM tenants WHERE id = ?').get(id);
68
- return tenant
69
- }
70
-
71
23
  async findByName(name: string): Promise<ITenant | null>{
72
- const tenant = this.db.prepare('SELECT * FROM tenants WHERE name = ?').get(name);
24
+ const tenant = this.db.prepare(`SELECT * FROM ${this.tableName} WHERE name = ?`).get(name);
73
25
  return tenant
74
26
  }
75
27
 
76
- async update(id: string, tenantData: ITenantBase): Promise<ITenant> {
77
- try{
78
-
79
- tenantData.updatedAt = (new Date().toISOString())
80
-
81
- const setClauses = Object.keys(tenantData)
82
- .map(field => `${field} = @${field}`)
83
- .join(', ');
84
-
85
- tenantData.id = id
86
-
87
- const stmt = this.db.prepare( `UPDATE tenants SET ${setClauses} WHERE id = @id `);
88
- stmt.run(tenantData);
89
- return this.findById(id)
90
- }catch (e){
91
- console.log(e)
92
- throw SqliteErrorToValidationError(e, tenantData)
93
- }
94
-
95
- }
96
-
97
- async delete(id: string): Promise<boolean> {
98
- const stmt = this.db.prepare('DELETE FROM tenants WHERE id = ?');
99
- stmt.run(id);
100
- return true
101
- }
102
-
103
- async deleteAll(): Promise<boolean> {
104
- const stmt = this.db.prepare('DELETE FROM tenants');
105
- stmt.run();
106
- return true
107
- }
108
-
109
- async fetchAll(): Promise<ITenant[]>{
110
- const tenants = this.db.prepare('SELECT * FROM tenants').all();
111
- for (const tenant of tenants) {
112
- tenant.permissions = tenant.permissions? tenant.permissions.split(",") : []
113
- }
114
- return tenants
115
- }
116
-
117
- async paginate({
118
- page= 1,
119
- limit= 5,
120
- orderBy= '',
121
- order= false,
122
- search= '',
123
- filters= []} : IDraxPaginateOptions): Promise<IDraxPaginateResult<ITenant>>{
124
- const offset = page > 1 ? (page - 1) * limit : 0
125
-
126
- let where=""
127
- if (search) {
128
- where = ` WHERE name LIKE '%${search}%'`
129
- }
130
-
131
- where = SqlQueryFilter.applyFilters(where, filters)
132
- const sort = SqlSort.applySort(orderBy, order)
133
-
134
- const rCount = this.db.prepare('SELECT COUNT(*) as count FROM tenants'+where).get();
135
- where += sort
136
- const tenants = this.db.prepare('SELECT * FROM tenants ' + where + ' LIMIT ? OFFSET ?').all([limit, offset]);
137
-
138
- return {
139
- page: page,
140
- limit: limit,
141
- total: rCount.count,
142
- items: tenants
143
- }
144
- }
145
-
146
- async find({
147
- limit = 0,
148
- orderBy = '',
149
- order = false,
150
- search = '',
151
- filters = []
152
- }: IDraxFindOptions): Promise<ITenant[]>{
153
-
154
- let where=""
155
- if (search) {
156
- where = ` WHERE name LIKE '%${search}%'`
157
- }
158
-
159
- where = SqlQueryFilter.applyFilters(where, filters)
160
- const sort = SqlSort.applySort(orderBy, order)
161
-
162
- where += sort
163
- const tenants = this.db.prepare('SELECT * FROM tenants ' + where).all();
164
-
165
- return tenants
166
- }
167
-
168
28
 
169
29
  }
170
30