@drax/identity-back 0.11.4 → 0.12.1
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.
- package/dist/controllers/RoleController.js +8 -39
- package/dist/controllers/TenantController.js +1 -28
- package/dist/controllers/UserApiKeyController.js +6 -3
- package/dist/controllers/UserController.js +48 -209
- package/dist/errors/BadCredentialsError.js +12 -0
- package/dist/factory/RoleServiceFactory.js +1 -0
- package/dist/factory/TenantServiceFactory.js +1 -0
- package/dist/factory/UserApiKeyServiceFactory.js +5 -4
- package/dist/factory/UserServiceFactory.js +1 -0
- package/dist/graphql/resolvers/role.resolvers.js +2 -2
- package/dist/graphql/resolvers/tenant.resolvers.js +2 -2
- package/dist/graphql/resolvers/user-api-key.resolvers.js +2 -2
- package/dist/graphql/resolvers/user.resolvers.js +1 -1
- package/dist/graphql/types/userApiKey.graphql +1 -0
- package/dist/index.js +6 -0
- package/dist/middleware/apiKeyMiddleware.js +2 -2
- package/dist/models/RoleModel.js +10 -7
- package/dist/models/TenantModel.js +11 -8
- package/dist/models/UserApiKeyModel.js +15 -7
- package/dist/models/UserGroupModel.js +7 -7
- package/dist/models/UserModel.js +10 -8
- package/dist/permissions/UserApiKeyPermissions.js +2 -1
- package/dist/rbac/Rbac.js +10 -8
- package/dist/repository/mongo/RoleMongoRepository.js +20 -65
- package/dist/repository/mongo/TenantMongoRepository.js +18 -66
- package/dist/repository/mongo/UserApiKeyMongoRepository.js +29 -44
- package/dist/repository/mongo/UserMongoRepository.js +56 -85
- package/dist/repository/sqlite/RoleSqliteRepository.js +30 -115
- package/dist/repository/sqlite/TenantSqliteRepository.js +15 -105
- package/dist/repository/sqlite/UserApiKeySqliteRepository.js +42 -115
- package/dist/repository/sqlite/UserSqliteRepository.js +49 -130
- package/dist/routes/RoleRoutes.js +35 -10
- package/dist/routes/TenantRoutes.js +18 -9
- package/dist/routes/UserApiKeyRoutes.js +20 -4
- package/dist/routes/UserRoutes.js +92 -17
- package/dist/schemas/LoginSchema.js +9 -0
- package/dist/schemas/PasswordSchema.js +12 -0
- package/dist/schemas/RegisterSchema.js +19 -0
- package/dist/schemas/RoleSchema.js +23 -0
- package/dist/schemas/TenantSchema.js +13 -0
- package/dist/schemas/UserApiKeySchema.js +14 -0
- package/dist/schemas/UserSchema.js +39 -0
- package/dist/services/PermissionService.js +5 -5
- package/dist/services/RoleService.js +6 -6
- package/dist/services/TenantService.js +6 -6
- package/dist/services/UserApiKeyService.js +5 -5
- package/dist/services/UserService.js +14 -14
- package/dist/setup/CreateOrUpdateRole.js +5 -2
- package/dist/setup/CreateUserIfNotExist.js +3 -1
- package/dist/setup/RecoveryUserPassword.js +1 -1
- package/dist/zod/EndpointZod.js +9 -0
- package/dist/zod/TenantSchema.js +12 -0
- package/dist/zod/TenantZod.js +5 -3
- package/dist/zod/UserApiKeyZod.js +7 -3
- package/package.json +10 -9
- package/src/controllers/RoleController.ts +8 -36
- package/src/controllers/TenantController.ts +2 -25
- package/src/controllers/UserApiKeyController.ts +8 -3
- package/src/controllers/UserController.ts +50 -183
- package/src/errors/BadCredentialsError.ts +18 -1
- package/src/factory/RoleServiceFactory.ts +1 -0
- package/src/factory/TenantServiceFactory.ts +1 -0
- package/src/factory/UserApiKeyServiceFactory.ts +5 -4
- package/src/factory/UserServiceFactory.ts +1 -0
- package/src/graphql/resolvers/role.resolvers.ts +3 -2
- package/src/graphql/resolvers/tenant.resolvers.ts +3 -2
- package/src/graphql/resolvers/user-api-key.resolvers.ts +3 -2
- package/src/graphql/resolvers/user.resolvers.ts +2 -1
- package/src/graphql/types/userApiKey.graphql +1 -0
- package/src/index.ts +16 -0
- package/src/interfaces/ITenantRepository.ts +2 -2
- package/src/interfaces/IUserApiKeyRepository.ts +2 -2
- package/src/interfaces/IUserRepository.ts +3 -2
- package/src/middleware/apiKeyMiddleware.ts +2 -2
- package/src/models/RoleModel.ts +12 -7
- package/src/models/TenantModel.ts +13 -8
- package/src/models/UserApiKeyModel.ts +17 -7
- package/src/models/UserGroupModel.ts +7 -7
- package/src/models/UserModel.ts +10 -8
- package/src/permissions/UserApiKeyPermissions.ts +2 -1
- package/src/rbac/Rbac.ts +12 -9
- package/src/repository/mongo/RoleMongoRepository.ts +23 -94
- package/src/repository/mongo/TenantMongoRepository.ts +19 -98
- package/src/repository/mongo/UserApiKeyMongoRepository.ts +31 -53
- package/src/repository/mongo/UserMongoRepository.ts +71 -130
- package/src/repository/sqlite/RoleSqliteRepository.ts +37 -146
- package/src/repository/sqlite/TenantSqliteRepository.ts +16 -156
- package/src/repository/sqlite/UserApiKeySqliteRepository.ts +46 -149
- package/src/repository/sqlite/UserSqliteRepository.ts +59 -173
- package/src/routes/RoleRoutes.ts +35 -12
- package/src/routes/TenantRoutes.ts +25 -9
- package/src/routes/UserApiKeyRoutes.ts +23 -7
- package/src/routes/UserRoutes.ts +117 -34
- package/src/schemas/LoginSchema.ts +12 -0
- package/src/schemas/PasswordSchema.ts +16 -0
- package/src/{zod/UserZod.ts → schemas/RegisterSchema.ts} +7 -10
- package/src/schemas/RoleSchema.ts +29 -0
- package/src/schemas/TenantSchema.ts +22 -0
- package/src/{zod/UserApiKeyZod.ts → schemas/UserApiKeySchema.ts} +8 -3
- package/src/schemas/UserSchema.ts +57 -0
- package/src/services/PermissionService.ts +6 -5
- package/src/services/RoleService.ts +6 -6
- package/src/services/TenantService.ts +10 -10
- package/src/services/UserApiKeyService.ts +5 -5
- package/src/services/UserService.ts +15 -16
- package/src/setup/CreateOrUpdateRole.ts +7 -4
- package/src/setup/CreateUserIfNotExist.ts +5 -3
- package/src/setup/RecoveryUserPassword.ts +1 -1
- package/test/data-obj/apikey/root-mongo-user-apikey.ts +2 -1
- package/test/data-obj/roles/admin-sqlite-role.ts +2 -2
- package/test/data-obj/roles/operator-sqlite-role.ts +1 -1
- package/test/data-obj/tenants/company-sqlite-tenant.ts +6 -0
- package/test/data-obj/users/root-sqlite-user.ts +2 -2
- package/test/initializers/RoleSqliteInitializer.ts +1 -1
- package/test/repository/mongo/role-mongo-repository.test.ts +3 -3
- package/test/repository/mongo/user-apikey-mongo-repository.test.ts +5 -4
- package/test/repository/mongo/user-mongo-repository.test.ts +4 -4
- package/test/repository/sqlite/role-sqlite-repository.test.ts +21 -9
- package/test/repository/sqlite/tenant-sqlite-repository.test.ts +74 -0
- package/test/repository/sqlite/user-sqlite-repository.test.ts +15 -9
- package/test/routes/data/admin-role.ts +10 -0
- package/test/routes/data/root-user.ts +13 -0
- package/test/routes/helpers/CreateRootUserAndAdminRole.ts +17 -0
- package/test/routes/helpers/FastifyTestServerFactory.ts +34 -0
- package/test/routes/helpers/InitializePermissions.ts +23 -0
- package/test/routes/helpers/SetupIdentityDrax.ts +22 -0
- package/test/routes/tenant-route.test.ts +336 -0
- package/test/routes/user-route.test.ts +186 -0
- package/test/schemas/lab-schema.test.ts +110 -0
- package/test/service/mock-service.test.ts +3 -3
- package/test/service/role-service.test.ts +3 -3
- package/test/service/user-service.test.ts +16 -25
- package/test.db +0 -0
- package/tsconfig.tsbuildinfo +1 -1
- package/types/controllers/RoleController.d.ts +0 -1
- package/types/controllers/RoleController.d.ts.map +1 -1
- package/types/controllers/TenantController.d.ts +0 -1
- package/types/controllers/TenantController.d.ts.map +1 -1
- package/types/controllers/UserApiKeyController.d.ts.map +1 -1
- package/types/controllers/UserController.d.ts +11 -4
- package/types/controllers/UserController.d.ts.map +1 -1
- package/types/errors/BadCredentialsError.d.ts +9 -1
- package/types/errors/BadCredentialsError.d.ts.map +1 -1
- package/types/factory/RoleServiceFactory.d.ts.map +1 -1
- package/types/factory/TenantServiceFactory.d.ts.map +1 -1
- package/types/factory/UserApiKeyServiceFactory.d.ts.map +1 -1
- package/types/factory/UserServiceFactory.d.ts.map +1 -1
- package/types/graphql/resolvers/role.resolvers.d.ts +3 -9
- package/types/graphql/resolvers/role.resolvers.d.ts.map +1 -1
- package/types/graphql/resolvers/tenant.resolvers.d.ts +3 -9
- package/types/graphql/resolvers/tenant.resolvers.d.ts.map +1 -1
- package/types/graphql/resolvers/user-api-key.resolvers.d.ts +3 -9
- package/types/graphql/resolvers/user-api-key.resolvers.d.ts.map +1 -1
- package/types/graphql/resolvers/user.resolvers.d.ts +3 -9
- package/types/graphql/resolvers/user.resolvers.d.ts.map +1 -1
- package/types/index.d.ts +5 -1
- package/types/index.d.ts.map +1 -1
- package/types/interfaces/ITenantRepository.d.ts +2 -2
- package/types/interfaces/ITenantRepository.d.ts.map +1 -1
- package/types/interfaces/IUserApiKeyRepository.d.ts +2 -2
- package/types/interfaces/IUserApiKeyRepository.d.ts.map +1 -1
- package/types/interfaces/IUserRepository.d.ts +3 -2
- package/types/interfaces/IUserRepository.d.ts.map +1 -1
- package/types/models/RoleModel.d.ts +7 -7
- package/types/models/RoleModel.d.ts.map +1 -1
- package/types/models/TenantModel.d.ts +7 -7
- package/types/models/TenantModel.d.ts.map +1 -1
- package/types/models/UserApiKeyModel.d.ts +7 -7
- package/types/models/UserApiKeyModel.d.ts.map +1 -1
- package/types/models/UserGroupModel.d.ts +2 -2
- package/types/models/UserGroupModel.d.ts.map +1 -1
- package/types/models/UserModel.d.ts +7 -7
- package/types/models/UserModel.d.ts.map +1 -1
- package/types/permissions/UserApiKeyPermissions.d.ts +2 -1
- package/types/permissions/UserApiKeyPermissions.d.ts.map +1 -1
- package/types/permissions/index.d.ts +1 -0
- package/types/permissions/index.d.ts.map +1 -1
- package/types/rbac/Rbac.d.ts +1 -1
- package/types/rbac/Rbac.d.ts.map +1 -1
- package/types/repository/mongo/RoleMongoRepository.d.ts +9 -11
- package/types/repository/mongo/RoleMongoRepository.d.ts.map +1 -1
- package/types/repository/mongo/TenantMongoRepository.d.ts +8 -11
- package/types/repository/mongo/TenantMongoRepository.d.ts.map +1 -1
- package/types/repository/mongo/UserApiKeyMongoRepository.d.ts +12 -5
- package/types/repository/mongo/UserApiKeyMongoRepository.d.ts.map +1 -1
- package/types/repository/mongo/UserMongoRepository.d.ts +11 -12
- package/types/repository/mongo/UserMongoRepository.d.ts.map +1 -1
- package/types/repository/sqlite/RoleSqliteRepository.d.ts +14 -14
- package/types/repository/sqlite/RoleSqliteRepository.d.ts.map +1 -1
- package/types/repository/sqlite/TenantSqliteRepository.d.ts +12 -14
- package/types/repository/sqlite/TenantSqliteRepository.d.ts.map +1 -1
- package/types/repository/sqlite/UserApiKeySqliteRepository.d.ts +15 -11
- package/types/repository/sqlite/UserApiKeySqliteRepository.d.ts.map +1 -1
- package/types/repository/sqlite/UserSqliteRepository.d.ts +15 -12
- package/types/repository/sqlite/UserSqliteRepository.d.ts.map +1 -1
- package/types/routes/RoleRoutes.d.ts.map +1 -1
- package/types/routes/TenantRoutes.d.ts.map +1 -1
- package/types/routes/UserApiKeyRoutes.d.ts.map +1 -1
- package/types/routes/UserRoutes.d.ts.map +1 -1
- package/types/schemas/LoginSchema.d.ts +20 -0
- package/types/schemas/LoginSchema.d.ts.map +1 -0
- package/types/schemas/PasswordSchema.d.ts +27 -0
- package/types/schemas/PasswordSchema.d.ts.map +1 -0
- package/types/schemas/RegisterSchema.d.ts +32 -0
- package/types/schemas/RegisterSchema.d.ts.map +1 -0
- package/types/schemas/RoleSchema.d.ts +67 -0
- package/types/schemas/RoleSchema.d.ts.map +1 -0
- package/types/schemas/TenantSchema.d.ts +29 -0
- package/types/schemas/TenantSchema.d.ts.map +1 -0
- package/types/schemas/UserApiKeySchema.d.ts +39 -0
- package/types/schemas/UserApiKeySchema.d.ts.map +1 -0
- package/types/schemas/UserSchema.d.ts +161 -0
- package/types/schemas/UserSchema.d.ts.map +1 -0
- package/types/services/PermissionService.d.ts +1 -0
- package/types/services/PermissionService.d.ts.map +1 -1
- package/types/services/TenantService.d.ts +3 -3
- package/types/services/TenantService.d.ts.map +1 -1
- package/types/services/UserService.d.ts.map +1 -1
- package/types/setup/CreateOrUpdateRole.d.ts +2 -2
- package/types/setup/CreateOrUpdateRole.d.ts.map +1 -1
- package/types/setup/CreateUserIfNotExist.d.ts +2 -2
- package/types/setup/CreateUserIfNotExist.d.ts.map +1 -1
- package/types/zod/EndpointZod.d.ts +20 -0
- package/types/zod/EndpointZod.d.ts.map +1 -0
- package/types/zod/TenantSchema.d.ts +26 -0
- package/types/zod/TenantSchema.d.ts.map +1 -0
- package/types/zod/TenantZod.d.ts +13 -3
- package/types/zod/TenantZod.d.ts.map +1 -1
- package/types/zod/UserApiKeyZod.d.ts +23 -3
- package/types/zod/UserApiKeyZod.d.ts.map +1 -1
- package/types/zod/UserZod.d.ts +6 -6
- package/src/zod/RoleZod.ts +0 -14
- package/src/zod/TenantZod.ts +0 -14
|
@@ -1,75 +1,48 @@
|
|
|
1
1
|
import {UserApiKeyModel} from "../../models/UserApiKeyModel.js";
|
|
2
2
|
import {
|
|
3
3
|
mongoose,
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
ValidationError
|
|
4
|
+
MongooseQueryFilter,
|
|
5
|
+
MongooseSort,
|
|
7
6
|
} from "@drax/common-back"
|
|
8
7
|
import type {IUserApiKey, IUserApiKeyBase, IUserApiKeySoftDelete} from "@drax/identity-share";
|
|
9
|
-
import {DeleteResult, MongoServerError} from "mongodb";
|
|
10
8
|
import {PaginateResult} from "mongoose";
|
|
11
9
|
import {IDraxPaginateOptions, IDraxPaginateResult} from "@drax/crud-share";
|
|
12
10
|
import {IUserApiKeyRepository} from "../../interfaces/IUserApiKeyRepository";
|
|
11
|
+
import {AbstractMongoRepository} from "@drax/crud-back";
|
|
13
12
|
|
|
14
|
-
class UserApiKeyMongoRepository implements IUserApiKeyRepository {
|
|
13
|
+
class UserApiKeyMongoRepository extends AbstractMongoRepository<IUserApiKey,IUserApiKeyBase,IUserApiKeyBase> implements IUserApiKeyRepository {
|
|
15
14
|
|
|
15
|
+
protected _searchFields=['name']
|
|
16
|
+
protected _populateFields = [
|
|
17
|
+
{path: 'user', populate: {path: 'tenant role'} },
|
|
18
|
+
{path: 'createdBy', populate: {path: 'tenant role'} },
|
|
19
|
+
]
|
|
20
|
+
protected _model = UserApiKeyModel
|
|
21
|
+
protected _lean = false
|
|
16
22
|
|
|
17
|
-
constructor() {
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
async create(data: IUserApiKeyBase): Promise<IUserApiKey> {
|
|
21
|
-
try {
|
|
22
|
-
|
|
23
|
-
const userApiKey: mongoose.HydratedDocument<IUserApiKey> = new UserApiKeyModel(data)
|
|
24
|
-
await userApiKey.save()
|
|
25
|
-
await userApiKey.populate({path: 'user', populate: {path: 'tenant role'} })
|
|
26
|
-
return userApiKey
|
|
27
|
-
} catch (e) {
|
|
28
|
-
if (e instanceof mongoose.Error.ValidationError) {
|
|
29
|
-
throw MongooseErrorToValidationError(e)
|
|
30
|
-
}
|
|
31
|
-
throw e
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
async update(id: string, data: IUserApiKeyBase): Promise<IUserApiKey> {
|
|
37
|
-
try {
|
|
38
|
-
delete data.secret
|
|
39
|
-
const userApiKey: mongoose.HydratedDocument<IUserApiKey> = await UserApiKeyModel.findOneAndUpdate({_id: id}, data, {new: true}).populate({path: 'user', populate: {path: 'tenant role'} }).exec()
|
|
40
|
-
return userApiKey
|
|
41
|
-
} catch (e) {
|
|
42
|
-
if (e instanceof mongoose.Error.ValidationError) {
|
|
43
|
-
throw MongooseErrorToValidationError(e)
|
|
44
|
-
}
|
|
45
|
-
if (e instanceof MongoServerError || e.name === 'MongoServerError') {
|
|
46
|
-
throw MongoServerErrorToValidationError(e)
|
|
47
|
-
}
|
|
48
|
-
throw e
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
23
|
|
|
52
24
|
async delete(id: string): Promise<boolean> {
|
|
53
|
-
const userApiKey: mongoose.HydratedDocument<IUserApiKeySoftDelete> = await UserApiKeyModel
|
|
25
|
+
const userApiKey: mongoose.HydratedDocument<IUserApiKeySoftDelete> = await UserApiKeyModel
|
|
26
|
+
.findById(id)
|
|
54
27
|
userApiKey.softDelete()
|
|
55
28
|
return true
|
|
56
29
|
}
|
|
57
30
|
|
|
58
|
-
|
|
59
|
-
const userApiKey: mongoose.HydratedDocument<IUserApiKey> = await UserApiKeyModel.findById(id).populate({path: 'user', populate: {path: 'tenant role'} }).exec()
|
|
60
|
-
return userApiKey
|
|
61
|
-
}
|
|
31
|
+
|
|
62
32
|
|
|
63
33
|
async findBySecret(secret: string): Promise<IUserApiKey> {
|
|
64
|
-
const userApiKey
|
|
65
|
-
|
|
34
|
+
const userApiKey = await UserApiKeyModel
|
|
35
|
+
.findOne({secret: {$eq: secret}, deleted: {$ne: true} })
|
|
36
|
+
.populate(this._populateFields)
|
|
37
|
+
.exec()
|
|
38
|
+
return userApiKey as IUserApiKey
|
|
66
39
|
}
|
|
67
40
|
|
|
68
41
|
async paginate({
|
|
69
42
|
page = 1,
|
|
70
43
|
limit = 5,
|
|
71
44
|
orderBy = '',
|
|
72
|
-
order =
|
|
45
|
+
order = "asc",
|
|
73
46
|
search = '',
|
|
74
47
|
filters = []
|
|
75
48
|
}: IDraxPaginateOptions): Promise<IDraxPaginateResult<IUserApiKey>> {
|
|
@@ -78,17 +51,22 @@ class UserApiKeyMongoRepository implements IUserApiKeyRepository {
|
|
|
78
51
|
deleted: false
|
|
79
52
|
}
|
|
80
53
|
|
|
81
|
-
if
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
54
|
+
if(search){
|
|
55
|
+
if(mongoose.Types.ObjectId.isValid(search)) {
|
|
56
|
+
query['_id'] = new mongoose.Types.ObjectId(search)
|
|
57
|
+
}else{
|
|
58
|
+
query['$or'] = this._searchFields.map(field => ({[field]: new RegExp(search.toString(), 'i')}))
|
|
59
|
+
}
|
|
85
60
|
}
|
|
86
61
|
|
|
87
62
|
MongooseQueryFilter.applyFilters(query, filters)
|
|
88
63
|
|
|
89
64
|
const sort = MongooseSort.applySort(orderBy, order)
|
|
90
|
-
|
|
91
|
-
const
|
|
65
|
+
const populate = ['user', 'user.tenant', 'user.role', 'createdBy']
|
|
66
|
+
const lean = this._lean
|
|
67
|
+
const leanWithId = this._lean
|
|
68
|
+
const leanWithVirtuals = this._lean
|
|
69
|
+
const options = {populate , page, limit, sort, lean, leanWithId, leanWithVirtuals}
|
|
92
70
|
|
|
93
71
|
const userApiKeyPaginated: PaginateResult<IUserApiKey> = await UserApiKeyModel.paginate(query, options)
|
|
94
72
|
return {
|
|
@@ -1,24 +1,28 @@
|
|
|
1
1
|
import {UserModel} from "../../models/UserModel.js";
|
|
2
2
|
import {
|
|
3
3
|
mongoose,
|
|
4
|
-
|
|
5
|
-
MongooseQueryFilter,
|
|
6
|
-
|
|
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
|
|
11
|
+
import {Cursor} from "mongoose";
|
|
13
12
|
import RoleMongoRepository from "./RoleMongoRepository.js";
|
|
14
|
-
import {IDraxFindOptions
|
|
15
|
-
import
|
|
13
|
+
import {IDraxFindOptions} from "@drax/crud-share";
|
|
14
|
+
import {AbstractMongoRepository} from "@drax/crud-back";
|
|
16
15
|
|
|
17
|
-
class UserMongoRepository implements IUserRepository {
|
|
18
|
-
|
|
19
|
-
|
|
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(
|
|
38
|
+
await user.populate(this._populateFields)
|
|
35
39
|
return user
|
|
36
40
|
}catch (e){
|
|
37
41
|
if(e instanceof mongoose.Error.ValidationError){
|
|
38
|
-
throw
|
|
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
|
|
54
|
-
throw
|
|
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
|
|
85
|
-
|
|
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
|
|
90
|
-
|
|
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
|
|
95
|
-
|
|
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
|
|
100
|
-
|
|
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
|
|
105
|
-
|
|
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
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
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
|
|
207
|
-
|
|
208
|
-
|
|
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
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
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
|
-
|
|
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
|
|
59
|
-
|
|
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
|
-
|
|
126
|
-
const sort = SqlSort.applySort(orderBy, order)
|
|
58
|
+
role.permissions = role && role.permissions ? role.permissions.split(",") : []
|
|
127
59
|
|
|
128
|
-
|
|
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
|
-
|
|
133
|
-
|
|
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.
|
|
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(
|
|
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
|
}
|