@drax/identity-back 0.0.14 → 0.0.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/factory/TenantServiceFactory.js +24 -0
- package/dist/factory/UserServiceFactory.js +1 -1
- package/dist/graphql/resolvers/role.resolvers.js +19 -2
- package/dist/graphql/resolvers/tenant.resolvers.js +121 -0
- package/dist/graphql/resolvers/user.resolvers.js +14 -3
- package/dist/graphql/types/tenant.graphql +28 -0
- package/dist/graphql/types/user.graphql +3 -0
- package/dist/index.js +6 -3
- package/dist/interfaces/ITenant.js +1 -0
- package/dist/interfaces/ITenantRepository.js +1 -0
- package/dist/middleware/rbacMiddleware.js +2 -5
- package/dist/models/TenantModel.js +18 -0
- package/dist/models/UserModel.js +5 -0
- package/dist/permissions/IdentityPermissions.js +5 -0
- package/dist/rbac/Rbac.js +6 -0
- package/dist/repository/mongo/RoleMongoRepository.js +7 -6
- package/dist/repository/mongo/TenantMongoRepository.js +45 -0
- package/dist/repository/mongo/UserMongoRepository.js +19 -6
- package/dist/repository/sqlite/RoleSqliteRepository.js +24 -5
- package/dist/repository/sqlite/TenantSqliteRepository.js +106 -0
- package/dist/repository/sqlite/UserSqliteRepository.js +43 -37
- package/dist/routes/RoleRoutes.js +17 -2
- package/dist/routes/TenantRoutes.js +183 -0
- package/dist/routes/UserRoutes.js +14 -2
- package/dist/services/RoleService.js +0 -5
- package/dist/services/TenantService.js +59 -0
- package/dist/services/UserService.js +1 -1
- package/dist/utils/AuthUtils.js +4 -3
- package/dist/zod/TenantZod.js +8 -0
- package/package.json +2 -2
- package/src/factory/TenantServiceFactory.ts +33 -0
- package/src/factory/UserServiceFactory.ts +1 -1
- package/src/graphql/resolvers/role.resolvers.ts +21 -3
- package/src/graphql/resolvers/tenant.resolvers.ts +119 -0
- package/src/graphql/resolvers/user.resolvers.ts +14 -6
- package/src/graphql/types/tenant.graphql +28 -0
- package/src/graphql/types/user.graphql +3 -0
- package/src/index.ts +6 -0
- package/src/interfaces/ITenant.ts +9 -0
- package/src/interfaces/ITenantRepository.ts +15 -0
- package/src/interfaces/IUser.ts +4 -1
- package/src/middleware/rbacMiddleware.ts +6 -8
- package/src/models/TenantModel.ts +32 -0
- package/src/models/UserModel.ts +5 -0
- package/src/permissions/IdentityPermissions.ts +7 -0
- package/src/rbac/Rbac.ts +11 -3
- package/src/repository/mongo/RoleMongoRepository.ts +7 -6
- package/src/repository/mongo/TenantMongoRepository.ts +62 -0
- package/src/repository/mongo/UserMongoRepository.ts +20 -6
- package/src/repository/sqlite/RoleSqliteRepository.ts +27 -6
- package/src/repository/sqlite/TenantSqliteRepository.ts +139 -0
- package/src/repository/sqlite/UserSqliteRepository.ts +52 -40
- package/src/routes/RoleRoutes.ts +17 -3
- package/src/routes/TenantRoutes.ts +178 -0
- package/src/routes/UserRoutes.ts +14 -4
- package/src/services/RoleService.ts +1 -4
- package/src/services/TenantService.ts +74 -0
- package/src/services/UserService.ts +1 -1
- package/src/utils/AuthUtils.ts +4 -3
- package/src/zod/TenantZod.ts +14 -0
- package/tsconfig.tsbuildinfo +1 -1
- package/types/factory/TenantServiceFactory.d.ts +4 -0
- package/types/factory/TenantServiceFactory.d.ts.map +1 -0
- package/types/graphql/resolvers/role.resolvers.d.ts.map +1 -1
- package/types/graphql/resolvers/tenant.resolvers.d.ts +44 -0
- package/types/graphql/resolvers/tenant.resolvers.d.ts.map +1 -0
- package/types/graphql/resolvers/user.resolvers.d.ts +2 -1
- package/types/graphql/resolvers/user.resolvers.d.ts.map +1 -1
- package/types/index.d.ts +4 -1
- package/types/index.d.ts.map +1 -1
- package/types/interfaces/ITenant.d.ts +7 -0
- package/types/interfaces/ITenant.d.ts.map +1 -0
- package/types/interfaces/ITenantRepository.d.ts +15 -0
- package/types/interfaces/ITenantRepository.d.ts.map +1 -0
- package/types/interfaces/IUser.d.ts +4 -0
- package/types/interfaces/IUser.d.ts.map +1 -1
- package/types/middleware/rbacMiddleware.d.ts.map +1 -1
- package/types/models/TenantModel.d.ts +16 -0
- package/types/models/TenantModel.d.ts.map +1 -0
- package/types/models/UserModel.d.ts.map +1 -1
- package/types/permissions/IdentityPermissions.d.ts +6 -1
- package/types/permissions/IdentityPermissions.d.ts.map +1 -1
- package/types/rbac/Rbac.d.ts +4 -2
- package/types/rbac/Rbac.d.ts.map +1 -1
- package/types/repository/mongo/RoleMongoRepository.d.ts.map +1 -1
- package/types/repository/mongo/TenantMongoRepository.d.ts +15 -0
- package/types/repository/mongo/TenantMongoRepository.d.ts.map +1 -0
- package/types/repository/mongo/UserMongoRepository.d.ts +2 -2
- package/types/repository/mongo/UserMongoRepository.d.ts.map +1 -1
- package/types/repository/sqlite/RoleSqliteRepository.d.ts +2 -0
- package/types/repository/sqlite/RoleSqliteRepository.d.ts.map +1 -1
- package/types/repository/sqlite/TenantSqliteRepository.d.ts +19 -0
- package/types/repository/sqlite/TenantSqliteRepository.d.ts.map +1 -0
- package/types/repository/sqlite/UserSqliteRepository.d.ts +4 -2
- 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 +4 -0
- package/types/routes/TenantRoutes.d.ts.map +1 -0
- package/types/routes/UserRoutes.d.ts.map +1 -1
- package/types/services/RoleService.d.ts.map +1 -1
- package/types/services/TenantService.d.ts +16 -0
- package/types/services/TenantService.d.ts.map +1 -0
- package/types/utils/AuthUtils.d.ts +3 -2
- package/types/utils/AuthUtils.d.ts.map +1 -1
- package/types/zod/TenantZod.d.ts +10 -0
- package/types/zod/TenantZod.d.ts.map +1 -0
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import TenantService from "../services/TenantService.js";
|
|
2
|
+
import TenantMongoRepository from "../repository/mongo/TenantMongoRepository.js";
|
|
3
|
+
import TenantSqliteRepository from "../repository/sqlite/TenantSqliteRepository.js";
|
|
4
|
+
import { DbSetupUtils, DbEngine } from "../utils/DbSetupUtils.js";
|
|
5
|
+
let tenantService;
|
|
6
|
+
const TenantServiceFactory = () => {
|
|
7
|
+
if (!tenantService) {
|
|
8
|
+
let tenantRepository;
|
|
9
|
+
switch (DbSetupUtils.getDbEngine()) {
|
|
10
|
+
case DbEngine.Mongo:
|
|
11
|
+
console.log("TenantServiceFactory DB ENGINE MONGODB");
|
|
12
|
+
tenantRepository = new TenantMongoRepository();
|
|
13
|
+
break;
|
|
14
|
+
case DbEngine.Sqlite:
|
|
15
|
+
console.log("TenantServiceFactory DB ENGINE SQLITE");
|
|
16
|
+
tenantRepository = new TenantSqliteRepository(DbSetupUtils.getDbConfig(), false);
|
|
17
|
+
tenantRepository.table();
|
|
18
|
+
break;
|
|
19
|
+
}
|
|
20
|
+
tenantService = new TenantService(tenantRepository);
|
|
21
|
+
}
|
|
22
|
+
return tenantService;
|
|
23
|
+
};
|
|
24
|
+
export default TenantServiceFactory;
|
|
@@ -13,7 +13,7 @@ const UserServiceFactory = () => {
|
|
|
13
13
|
break;
|
|
14
14
|
case DbEngine.Sqlite:
|
|
15
15
|
console.log("UserServiceFactory DB ENGINE SQLITE");
|
|
16
|
-
userRepository = new UserSqliteRepository(DbSetupUtils.getDbConfig(),
|
|
16
|
+
userRepository = new UserSqliteRepository(DbSetupUtils.getDbConfig(), true);
|
|
17
17
|
userRepository.table();
|
|
18
18
|
break;
|
|
19
19
|
}
|
|
@@ -4,12 +4,12 @@ import { ValidationError, ValidationErrorToGraphQLError } from "@drax/common-bac
|
|
|
4
4
|
import { GraphQLError } from "graphql";
|
|
5
5
|
import { PermissionService } from "../../services/PermissionService.js";
|
|
6
6
|
import UnauthorizedError from "../../errors/UnauthorizedError.js";
|
|
7
|
-
const roleService = RoleServiceFactory();
|
|
8
7
|
export default {
|
|
9
8
|
Query: {
|
|
10
9
|
findRoleById: async (_, { id }, { rbac }) => {
|
|
11
10
|
try {
|
|
12
11
|
rbac.assertPermission(IdentityPermissions.ViewRole);
|
|
12
|
+
const roleService = RoleServiceFactory();
|
|
13
13
|
return await roleService.findById(id);
|
|
14
14
|
}
|
|
15
15
|
catch (e) {
|
|
@@ -22,6 +22,7 @@ export default {
|
|
|
22
22
|
findRoleByName: async (_, { name }, { rbac }) => {
|
|
23
23
|
try {
|
|
24
24
|
rbac.assertPermission(IdentityPermissions.ViewRole);
|
|
25
|
+
const roleService = RoleServiceFactory();
|
|
25
26
|
return await roleService.findByName(name);
|
|
26
27
|
}
|
|
27
28
|
catch (e) {
|
|
@@ -34,9 +35,17 @@ export default {
|
|
|
34
35
|
fetchRole: async (_, {}, { rbac }) => {
|
|
35
36
|
try {
|
|
36
37
|
rbac.assertPermission(IdentityPermissions.ViewRole);
|
|
37
|
-
|
|
38
|
+
const roleService = RoleServiceFactory();
|
|
39
|
+
const roles = await roleService.fetchAll();
|
|
40
|
+
if (rbac.getRole?.childRoles?.length > 0) {
|
|
41
|
+
return roles.filter(role => rbac.getRole.childRoles.some(childRole => childRole.id === role.id));
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
return roles;
|
|
45
|
+
}
|
|
38
46
|
}
|
|
39
47
|
catch (e) {
|
|
48
|
+
console.error("fetchRole", e);
|
|
40
49
|
if (e instanceof UnauthorizedError) {
|
|
41
50
|
throw new GraphQLError(e.message);
|
|
42
51
|
}
|
|
@@ -58,6 +67,7 @@ export default {
|
|
|
58
67
|
paginateRole: async (_, { page, limit, seach }, { rbac }) => {
|
|
59
68
|
try {
|
|
60
69
|
rbac.assertPermission(IdentityPermissions.ViewRole);
|
|
70
|
+
const roleService = RoleServiceFactory();
|
|
61
71
|
return await roleService.paginate(page, limit, seach);
|
|
62
72
|
}
|
|
63
73
|
catch (e) {
|
|
@@ -73,6 +83,7 @@ export default {
|
|
|
73
83
|
createRole: async (_, { input }, { rbac }) => {
|
|
74
84
|
try {
|
|
75
85
|
rbac.assertPermission(IdentityPermissions.CreateRole);
|
|
86
|
+
const roleService = RoleServiceFactory();
|
|
76
87
|
return await roleService.create(input);
|
|
77
88
|
}
|
|
78
89
|
catch (e) {
|
|
@@ -89,6 +100,7 @@ export default {
|
|
|
89
100
|
updateRole: async (_, { id, input }, { rbac }) => {
|
|
90
101
|
try {
|
|
91
102
|
rbac.assertPermission(IdentityPermissions.UpdateRole);
|
|
103
|
+
const roleService = RoleServiceFactory();
|
|
92
104
|
const currentRole = await roleService.findById(id);
|
|
93
105
|
if (currentRole.readonly) {
|
|
94
106
|
throw new ValidationError([{ field: 'name', reason: "role.readonly", value: input.name }]);
|
|
@@ -109,6 +121,11 @@ export default {
|
|
|
109
121
|
deleteRole: async (_, { id }, { rbac }) => {
|
|
110
122
|
try {
|
|
111
123
|
rbac.assertPermission(IdentityPermissions.DeleteRole);
|
|
124
|
+
const roleService = RoleServiceFactory();
|
|
125
|
+
const currentRole = await roleService.findById(id);
|
|
126
|
+
if (currentRole.readonly) {
|
|
127
|
+
throw new UnauthorizedError();
|
|
128
|
+
}
|
|
112
129
|
return await roleService.delete(id);
|
|
113
130
|
}
|
|
114
131
|
catch (e) {
|
|
@@ -0,0 +1,121 @@
|
|
|
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 UnauthorizedError from "../../errors/UnauthorizedError.js";
|
|
6
|
+
export default {
|
|
7
|
+
Query: {
|
|
8
|
+
findTenantById: async (_, { id }, { rbac }) => {
|
|
9
|
+
try {
|
|
10
|
+
rbac.assertPermission(IdentityPermissions.ViewTenant);
|
|
11
|
+
const tenantService = TenantServiceFactory();
|
|
12
|
+
return await tenantService.findById(id);
|
|
13
|
+
}
|
|
14
|
+
catch (e) {
|
|
15
|
+
if (e instanceof UnauthorizedError) {
|
|
16
|
+
throw new GraphQLError(e.message);
|
|
17
|
+
}
|
|
18
|
+
throw new GraphQLError('error.server');
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
findTenantByName: async (_, { name }, { rbac }) => {
|
|
22
|
+
try {
|
|
23
|
+
rbac.assertPermission(IdentityPermissions.ViewTenant);
|
|
24
|
+
const tenantService = TenantServiceFactory();
|
|
25
|
+
return await tenantService.findByName(name);
|
|
26
|
+
}
|
|
27
|
+
catch (e) {
|
|
28
|
+
if (e instanceof UnauthorizedError) {
|
|
29
|
+
throw new GraphQLError(e.message);
|
|
30
|
+
}
|
|
31
|
+
throw new GraphQLError('error.server');
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
fetchTenant: async (_, {}, { rbac }) => {
|
|
35
|
+
try {
|
|
36
|
+
rbac.assertPermission(IdentityPermissions.ViewTenant);
|
|
37
|
+
const tenantService = TenantServiceFactory();
|
|
38
|
+
const tenants = await tenantService.fetchAll();
|
|
39
|
+
if (rbac.getAuthUser.tenantId) {
|
|
40
|
+
return tenants.filter(t => t.id === rbac.getAuthUser.tenantId);
|
|
41
|
+
}
|
|
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
|
+
}
|
|
59
|
+
catch (e) {
|
|
60
|
+
console.error("paginateTenant", e);
|
|
61
|
+
if (e instanceof UnauthorizedError) {
|
|
62
|
+
throw new GraphQLError(e.message);
|
|
63
|
+
}
|
|
64
|
+
throw new GraphQLError('error.server');
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
Mutation: {
|
|
69
|
+
createTenant: async (_, { input }, { rbac }) => {
|
|
70
|
+
try {
|
|
71
|
+
rbac.assertPermission(IdentityPermissions.CreateTenant);
|
|
72
|
+
const tenantService = TenantServiceFactory();
|
|
73
|
+
return await tenantService.create(input);
|
|
74
|
+
}
|
|
75
|
+
catch (e) {
|
|
76
|
+
console.error("createTenant", e);
|
|
77
|
+
if (e instanceof ValidationError) {
|
|
78
|
+
throw ValidationErrorToGraphQLError(e);
|
|
79
|
+
}
|
|
80
|
+
if (e instanceof UnauthorizedError) {
|
|
81
|
+
throw new GraphQLError(e.message);
|
|
82
|
+
}
|
|
83
|
+
throw new GraphQLError('error.server');
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
updateTenant: async (_, { id, input }, { rbac }) => {
|
|
87
|
+
try {
|
|
88
|
+
rbac.assertPermission(IdentityPermissions.UpdateTenant);
|
|
89
|
+
const tenantService = TenantServiceFactory();
|
|
90
|
+
return await tenantService.update(id, input);
|
|
91
|
+
}
|
|
92
|
+
catch (e) {
|
|
93
|
+
console.error("updateTenant", e);
|
|
94
|
+
if (e instanceof ValidationError) {
|
|
95
|
+
throw ValidationErrorToGraphQLError(e);
|
|
96
|
+
}
|
|
97
|
+
if (e instanceof UnauthorizedError) {
|
|
98
|
+
throw new GraphQLError(e.message);
|
|
99
|
+
}
|
|
100
|
+
throw new GraphQLError('error.server');
|
|
101
|
+
}
|
|
102
|
+
},
|
|
103
|
+
deleteTenant: async (_, { id }, { rbac }) => {
|
|
104
|
+
try {
|
|
105
|
+
rbac.assertPermission(IdentityPermissions.DeleteTenant);
|
|
106
|
+
const tenantService = TenantServiceFactory();
|
|
107
|
+
return await tenantService.delete(id);
|
|
108
|
+
}
|
|
109
|
+
catch (e) {
|
|
110
|
+
console.error("deleteTenant", e);
|
|
111
|
+
if (e instanceof ValidationError) {
|
|
112
|
+
throw ValidationErrorToGraphQLError(e);
|
|
113
|
+
}
|
|
114
|
+
if (e instanceof UnauthorizedError) {
|
|
115
|
+
throw new GraphQLError(e.message);
|
|
116
|
+
}
|
|
117
|
+
throw new GraphQLError('error.server');
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
};
|
|
@@ -4,12 +4,12 @@ import { ValidationErrorToGraphQLError, ValidationError } from "@drax/common-bac
|
|
|
4
4
|
import { IdentityPermissions } from "../../permissions/IdentityPermissions.js";
|
|
5
5
|
import UnauthorizedError from "../../errors/UnauthorizedError.js";
|
|
6
6
|
import BadCredentialsError from "../../errors/BadCredentialsError.js";
|
|
7
|
-
const userService = UserServiceFactory();
|
|
8
7
|
export default {
|
|
9
8
|
Query: {
|
|
10
9
|
me: async (_, {}, { authUser }) => {
|
|
11
10
|
try {
|
|
12
11
|
if (authUser) {
|
|
12
|
+
let userService = UserServiceFactory();
|
|
13
13
|
let user = await userService.findById(authUser.id);
|
|
14
14
|
delete user.password;
|
|
15
15
|
return user;
|
|
@@ -24,6 +24,7 @@ export default {
|
|
|
24
24
|
findUserById: async (_, { id }, { rbac }) => {
|
|
25
25
|
try {
|
|
26
26
|
rbac.assertPermission(IdentityPermissions.ViewUser);
|
|
27
|
+
let userService = UserServiceFactory();
|
|
27
28
|
return await userService.findById(id);
|
|
28
29
|
}
|
|
29
30
|
catch (e) {
|
|
@@ -33,10 +34,14 @@ export default {
|
|
|
33
34
|
throw new GraphQLError('error.server');
|
|
34
35
|
}
|
|
35
36
|
},
|
|
36
|
-
paginateUser: async (_, { page, limit, search }, { rbac }) => {
|
|
37
|
+
paginateUser: async (_, { page, limit, search, filters = [] }, { rbac }) => {
|
|
37
38
|
try {
|
|
38
39
|
rbac.assertPermission(IdentityPermissions.ViewUser);
|
|
39
|
-
|
|
40
|
+
let userService = UserServiceFactory();
|
|
41
|
+
if (rbac.getAuthUser.tenantId) {
|
|
42
|
+
filters.push({ field: 'tenant', operator: '$eq', value: rbac.getAuthUser.tenantId });
|
|
43
|
+
}
|
|
44
|
+
return await userService.paginate(page, limit, search, filters);
|
|
40
45
|
}
|
|
41
46
|
catch (e) {
|
|
42
47
|
if (e instanceof UnauthorizedError) {
|
|
@@ -49,6 +54,7 @@ export default {
|
|
|
49
54
|
Mutation: {
|
|
50
55
|
auth: async (_, { input }) => {
|
|
51
56
|
try {
|
|
57
|
+
let userService = UserServiceFactory();
|
|
52
58
|
return await userService.auth(input.username, input.password);
|
|
53
59
|
}
|
|
54
60
|
catch (e) {
|
|
@@ -62,6 +68,7 @@ export default {
|
|
|
62
68
|
createUser: async (_, { input }, { rbac }) => {
|
|
63
69
|
try {
|
|
64
70
|
rbac.assertPermission(IdentityPermissions.CreateUser);
|
|
71
|
+
let userService = UserServiceFactory();
|
|
65
72
|
const user = await userService.create(input);
|
|
66
73
|
return user;
|
|
67
74
|
}
|
|
@@ -79,6 +86,7 @@ export default {
|
|
|
79
86
|
updateUser: async (_, { id, input }, { rbac }) => {
|
|
80
87
|
try {
|
|
81
88
|
rbac.assertPermission(IdentityPermissions.UpdateUser);
|
|
89
|
+
let userService = UserServiceFactory();
|
|
82
90
|
const user = await userService.update(id, input);
|
|
83
91
|
return user;
|
|
84
92
|
}
|
|
@@ -95,6 +103,7 @@ export default {
|
|
|
95
103
|
deleteUser: async (_, { id }, { rbac }) => {
|
|
96
104
|
try {
|
|
97
105
|
rbac.assertPermission(IdentityPermissions.DeleteUser);
|
|
106
|
+
let userService = UserServiceFactory();
|
|
98
107
|
return await userService.delete(id);
|
|
99
108
|
}
|
|
100
109
|
catch (e) {
|
|
@@ -114,6 +123,7 @@ export default {
|
|
|
114
123
|
throw new UnauthorizedError();
|
|
115
124
|
}
|
|
116
125
|
let userId = authUser.id;
|
|
126
|
+
let userService = UserServiceFactory();
|
|
117
127
|
return await userService.changeOwnPassword(userId, currentPassword, newPassword);
|
|
118
128
|
}
|
|
119
129
|
catch (e) {
|
|
@@ -129,6 +139,7 @@ export default {
|
|
|
129
139
|
changeUserPassword: async (_, { userId, newPassword }, { rbac }) => {
|
|
130
140
|
try {
|
|
131
141
|
rbac.assertPermission(IdentityPermissions.UpdateUser);
|
|
142
|
+
let userService = UserServiceFactory();
|
|
132
143
|
return await userService.changeUserPassword(userId, newPassword);
|
|
133
144
|
}
|
|
134
145
|
catch (e) {
|
|
@@ -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/dist/index.js
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";
|
|
@@ -24,13 +27,13 @@ const identityTypeDefs = await graphqlMergeResult.typeDefs;
|
|
|
24
27
|
const identityResolvers = await graphqlMergeResult.resolvers;
|
|
25
28
|
export {
|
|
26
29
|
//Service
|
|
27
|
-
UserService, RoleService, PermissionService, Rbac,
|
|
30
|
+
UserService, RoleService, TenantService, PermissionService, Rbac,
|
|
28
31
|
//Factories
|
|
29
|
-
UserServiceFactory, RoleServiceFactory,
|
|
32
|
+
UserServiceFactory, RoleServiceFactory, TenantServiceFactory,
|
|
30
33
|
//GQL
|
|
31
34
|
identityTypeDefs, identityResolvers,
|
|
32
35
|
//API REST
|
|
33
|
-
UserRoutes, RoleRoutes, AuthUtils,
|
|
36
|
+
UserRoutes, RoleRoutes, TenantRoutes, AuthUtils,
|
|
34
37
|
//API MIDDLEWARE
|
|
35
38
|
jwtMiddleware, rbacMiddleware,
|
|
36
39
|
//Permissions
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -4,13 +4,10 @@ import Rbac from "../rbac/Rbac.js";
|
|
|
4
4
|
import IdentityConfig from "../config/IdentityConfig.js";
|
|
5
5
|
const cacheTTL = DraxConfig.getOrLoad(IdentityConfig.RbacCacheTTL) ? parseInt(DraxConfig.getOrLoad(IdentityConfig.RbacCacheTTL)) : 10000;
|
|
6
6
|
const draxCache = new DraxCache(cacheTTL);
|
|
7
|
-
const roleService = RoleServiceFactory();
|
|
8
7
|
async function roleLoader(k) {
|
|
8
|
+
const roleService = RoleServiceFactory();
|
|
9
9
|
const role = await roleService.findById(k);
|
|
10
|
-
|
|
11
|
-
return { id: role.id, name: role.name, permissions: role.permissions };
|
|
12
|
-
}
|
|
13
|
-
return null;
|
|
10
|
+
return role;
|
|
14
11
|
}
|
|
15
12
|
async function rbacMiddleware(request, reply) {
|
|
16
13
|
try {
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { mongoose, MongooseSoftDelete } from '@drax/common-back';
|
|
2
|
+
import uniqueValidator from 'mongoose-unique-validator';
|
|
3
|
+
import mongoosePaginate from 'mongoose-paginate-v2';
|
|
4
|
+
const Schema = mongoose.Schema;
|
|
5
|
+
const TenantSchema = new Schema({
|
|
6
|
+
name: {
|
|
7
|
+
type: String, unique: true, required: true, index: true,
|
|
8
|
+
},
|
|
9
|
+
});
|
|
10
|
+
TenantSchema.plugin(uniqueValidator, { message: 'validation.unique' });
|
|
11
|
+
TenantSchema.plugin(MongooseSoftDelete);
|
|
12
|
+
TenantSchema.plugin(mongoosePaginate);
|
|
13
|
+
TenantSchema.set('toJSON', { getters: true });
|
|
14
|
+
const TENANT_MODEL_NAME = 'Tenant';
|
|
15
|
+
const TENANT_COLLECTION_NAME = 'tenants';
|
|
16
|
+
const TenantModel = mongoose.model(TENANT_MODEL_NAME, TenantSchema, TENANT_COLLECTION_NAME);
|
|
17
|
+
export { TenantSchema, TenantModel };
|
|
18
|
+
export default TenantModel;
|
package/dist/models/UserModel.js
CHANGED
|
@@ -11,6 +11,11 @@ var IdentityPermissions;
|
|
|
11
11
|
IdentityPermissions["ViewRole"] = "role:view";
|
|
12
12
|
IdentityPermissions["ManageRole"] = "role:manage";
|
|
13
13
|
IdentityPermissions["PermissionsRole"] = "role:permissions";
|
|
14
|
+
IdentityPermissions["CreateTenant"] = "tenant:create";
|
|
15
|
+
IdentityPermissions["UpdateTenant"] = "tenant:update";
|
|
16
|
+
IdentityPermissions["DeleteTenant"] = "tenant:delete";
|
|
17
|
+
IdentityPermissions["ViewTenant"] = "tenant:view";
|
|
18
|
+
IdentityPermissions["ManageTenant"] = "tenant:manage";
|
|
14
19
|
})(IdentityPermissions || (IdentityPermissions = {}));
|
|
15
20
|
export default IdentityPermissions;
|
|
16
21
|
export { IdentityPermissions };
|
package/dist/rbac/Rbac.js
CHANGED
|
@@ -4,6 +4,12 @@ class Rbac {
|
|
|
4
4
|
this.authUser = authUser;
|
|
5
5
|
this.role = role;
|
|
6
6
|
}
|
|
7
|
+
get getRole() {
|
|
8
|
+
return this.role;
|
|
9
|
+
}
|
|
10
|
+
get getAuthUser() {
|
|
11
|
+
return this.authUser;
|
|
12
|
+
}
|
|
7
13
|
hasPermission(requiredPermission) {
|
|
8
14
|
if (!this.authUser || !this.role || !this.role.permissions || this.role.permissions.length === 0) {
|
|
9
15
|
return false;
|
|
@@ -3,26 +3,27 @@ class RoleMongoRepository {
|
|
|
3
3
|
async create(roleData) {
|
|
4
4
|
const role = new RoleModel(roleData);
|
|
5
5
|
await role.save();
|
|
6
|
+
await role.populate('childRoles');
|
|
6
7
|
return role;
|
|
7
8
|
}
|
|
8
9
|
async update(id, roleData) {
|
|
9
|
-
const role = await RoleModel.findOneAndUpdate({ _id: id }, roleData, { new: true }).exec();
|
|
10
|
+
const role = await RoleModel.findOneAndUpdate({ _id: id }, roleData, { new: true }).populate('childRoles').exec();
|
|
10
11
|
return role;
|
|
11
12
|
}
|
|
12
13
|
async delete(id) {
|
|
13
|
-
const result = await RoleModel.deleteOne(id).exec();
|
|
14
|
+
const result = await RoleModel.deleteOne({ _id: id }).exec();
|
|
14
15
|
return result.deletedCount == 1;
|
|
15
16
|
}
|
|
16
17
|
async findById(id) {
|
|
17
|
-
const role = await RoleModel.findById(id).exec();
|
|
18
|
+
const role = await RoleModel.findById(id).populate('childRoles').exec();
|
|
18
19
|
return role;
|
|
19
20
|
}
|
|
20
21
|
async findByName(name) {
|
|
21
|
-
const role = await RoleModel.findOne({ name }).exec();
|
|
22
|
+
const role = await RoleModel.findOne({ name }).populate('childRoles').exec();
|
|
22
23
|
return role;
|
|
23
24
|
}
|
|
24
25
|
async fetchAll() {
|
|
25
|
-
const roles = await RoleModel.find().exec();
|
|
26
|
+
const roles = await RoleModel.find().populate('childRoles').exec();
|
|
26
27
|
return roles;
|
|
27
28
|
}
|
|
28
29
|
async paginate(page = 1, limit = 5, search) {
|
|
@@ -32,7 +33,7 @@ class RoleMongoRepository {
|
|
|
32
33
|
{ name: new RegExp(search, 'i') },
|
|
33
34
|
];
|
|
34
35
|
}
|
|
35
|
-
const options = { page, limit };
|
|
36
|
+
const options = { populate: ['childRoles'], page, limit };
|
|
36
37
|
const roles = await RoleModel.paginate(query, options);
|
|
37
38
|
return {
|
|
38
39
|
page: page,
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { TenantModel } from "../../models/TenantModel.js";
|
|
2
|
+
class TenantMongoRepository {
|
|
3
|
+
async create(tenantData) {
|
|
4
|
+
const tenant = new TenantModel(tenantData);
|
|
5
|
+
await tenant.save();
|
|
6
|
+
return tenant;
|
|
7
|
+
}
|
|
8
|
+
async update(id, tenantData) {
|
|
9
|
+
const tenant = await TenantModel.findOneAndUpdate({ _id: id }, tenantData, { new: true }).exec();
|
|
10
|
+
return tenant;
|
|
11
|
+
}
|
|
12
|
+
async delete(id) {
|
|
13
|
+
const result = await TenantModel.deleteOne({ _id: id }).exec();
|
|
14
|
+
return result.deletedCount == 1;
|
|
15
|
+
}
|
|
16
|
+
async findById(id) {
|
|
17
|
+
const tenant = await TenantModel.findById(id).exec();
|
|
18
|
+
return tenant;
|
|
19
|
+
}
|
|
20
|
+
async findByName(name) {
|
|
21
|
+
const tenant = await TenantModel.findOne({ name }).exec();
|
|
22
|
+
return tenant;
|
|
23
|
+
}
|
|
24
|
+
async fetchAll() {
|
|
25
|
+
const tenants = await TenantModel.find().exec();
|
|
26
|
+
return tenants;
|
|
27
|
+
}
|
|
28
|
+
async paginate(page = 1, limit = 5, search) {
|
|
29
|
+
const query = {};
|
|
30
|
+
if (search) {
|
|
31
|
+
query['$or'] = [
|
|
32
|
+
{ name: new RegExp(search, 'i') },
|
|
33
|
+
];
|
|
34
|
+
}
|
|
35
|
+
const options = { page, limit };
|
|
36
|
+
const tenants = await TenantModel.paginate(query, options);
|
|
37
|
+
return {
|
|
38
|
+
page: page,
|
|
39
|
+
limit: limit,
|
|
40
|
+
total: tenants.totalDocs,
|
|
41
|
+
items: tenants.docs
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
export default TenantMongoRepository;
|
|
@@ -13,7 +13,7 @@ class UserMongoRepository {
|
|
|
13
13
|
}
|
|
14
14
|
const user = new UserModel(userData);
|
|
15
15
|
await user.save();
|
|
16
|
-
await user.populate('role');
|
|
16
|
+
await user.populate(['role', 'tenant']);
|
|
17
17
|
return user;
|
|
18
18
|
}
|
|
19
19
|
catch (e) {
|
|
@@ -25,7 +25,7 @@ class UserMongoRepository {
|
|
|
25
25
|
}
|
|
26
26
|
async update(id, userData) {
|
|
27
27
|
try {
|
|
28
|
-
const user = await UserModel.findOneAndUpdate({ _id: id }, userData, { new: true }).populate('role').exec();
|
|
28
|
+
const user = await UserModel.findOneAndUpdate({ _id: id }, userData, { new: true }).populate(['role', 'tenant']).exec();
|
|
29
29
|
return user;
|
|
30
30
|
}
|
|
31
31
|
catch (e) {
|
|
@@ -43,14 +43,14 @@ class UserMongoRepository {
|
|
|
43
43
|
return result.deletedCount == 1;
|
|
44
44
|
}
|
|
45
45
|
async findById(id) {
|
|
46
|
-
const user = await UserModel.findById(id).populate('role').exec();
|
|
46
|
+
const user = await UserModel.findById(id).populate(['role', 'tenant']).exec();
|
|
47
47
|
return user;
|
|
48
48
|
}
|
|
49
49
|
async findByUsername(username) {
|
|
50
|
-
const user = await UserModel.findOne({ username: username }).populate('role').exec();
|
|
50
|
+
const user = await UserModel.findOne({ username: username }).populate(['role', 'tenant']).exec();
|
|
51
51
|
return user;
|
|
52
52
|
}
|
|
53
|
-
async paginate(page = 1, limit = 5, search) {
|
|
53
|
+
async paginate(page = 1, limit = 5, search, filters) {
|
|
54
54
|
const query = {};
|
|
55
55
|
if (search) {
|
|
56
56
|
query['$or'] = [
|
|
@@ -59,7 +59,20 @@ class UserMongoRepository {
|
|
|
59
59
|
{ name: new RegExp(search, 'i') },
|
|
60
60
|
];
|
|
61
61
|
}
|
|
62
|
-
|
|
62
|
+
if (filters) {
|
|
63
|
+
for (const filter of filters) {
|
|
64
|
+
if (filter.operator === '$eq') {
|
|
65
|
+
query[filter.field] = { $eq: filter.value };
|
|
66
|
+
}
|
|
67
|
+
if (filter.operator === '$ne') {
|
|
68
|
+
query[filter.field] = { $ne: filter.value };
|
|
69
|
+
}
|
|
70
|
+
if (filter.operator === '$in') {
|
|
71
|
+
query[filter.field] = { $in: filter.value };
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
const options = { populate: ['role', 'tenant'], page: page, limit: limit };
|
|
63
76
|
const userPaginated = await UserModel.paginate(query, options);
|
|
64
77
|
return {
|
|
65
78
|
page: page,
|