@drax/identity-back 0.0.8 → 0.0.10
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/errors/BadCredentialsError.js +10 -0
- package/dist/errors/UnauthorizedError.js +10 -0
- package/dist/factory/RoleServiceFactory.js +16 -3
- package/dist/factory/UserServiceFactory.js +17 -3
- package/dist/graphql/resolvers/role.resolvers.js +98 -11
- package/dist/graphql/resolvers/user.resolvers.js +134 -15
- package/dist/graphql/types/role.graphql +6 -4
- package/dist/graphql/types/user.graphql +36 -9
- package/dist/i18n/messages/validation-i18n.js +21 -0
- package/dist/index.js +22 -7
- package/dist/interfaces/IID.js +1 -0
- package/dist/interfaces/IJwtUser.js +1 -0
- package/dist/middleware/jwtMiddleware.js +19 -0
- package/dist/middleware/rbacMiddleware.js +36 -0
- package/dist/models/RoleModel.js +0 -8
- package/dist/models/UserModel.js +1 -2
- package/dist/permissions/IdentityPermissions.js +16 -0
- package/dist/rbac/Rbac.js +20 -0
- package/dist/repository/mongo/RoleMongoRepository.js +41 -0
- package/dist/repository/mongo/UserMongoRepository.js +82 -0
- package/dist/repository/sqlite/RoleSqliteRepository.js +115 -0
- package/dist/repository/sqlite/UserSqliteRepository.js +157 -0
- package/dist/routes/RoleRoutes.js +145 -0
- package/dist/routes/UserRoutes.js +199 -0
- package/dist/routes/authRoutes.js +12 -4
- package/dist/services/AuthService.js +0 -15
- package/dist/services/PermissionService.js +19 -0
- package/dist/services/RoleService.js +48 -16
- package/dist/services/UserService.js +82 -23
- package/dist/utils/AuthUtils.js +20 -6
- package/dist/utils/DbSetupUtils.js +28 -0
- package/dist/zod/RoleZod.js +8 -0
- package/dist/zod/UserZod.js +18 -0
- package/package.json +17 -10
- package/src/errors/BadCredentialsError.ts +13 -0
- package/src/errors/UnauthorizedError.ts +13 -0
- package/src/factory/RoleServiceFactory.ts +20 -3
- package/src/factory/UserServiceFactory.ts +20 -3
- package/src/graphql/resolvers/role.resolvers.ts +92 -11
- package/src/graphql/resolvers/user.resolvers.ts +128 -15
- package/src/graphql/types/role.graphql +6 -4
- package/src/graphql/types/user.graphql +36 -9
- package/src/index.ts +50 -10
- package/src/interfaces/IID.ts +5 -0
- package/src/interfaces/IJwtUser.ts +7 -0
- package/src/interfaces/IRole.ts +15 -5
- package/src/interfaces/IRoleRepository.ts +8 -5
- package/src/interfaces/IUser.ts +30 -6
- package/src/interfaces/IUserGroup.ts +2 -1
- package/src/interfaces/IUserRepository.ts +11 -6
- package/src/middleware/jwtMiddleware.ts +22 -0
- package/src/middleware/rbacMiddleware.ts +40 -0
- package/src/models/RoleModel.ts +0 -9
- package/src/models/UserModel.ts +1 -2
- package/src/permissions/IdentityPermissions.ts +20 -0
- package/src/rbac/Rbac.ts +31 -0
- package/src/repository/mongo/RoleMongoRepository.ts +57 -0
- package/src/repository/mongo/UserMongoRepository.ts +104 -0
- package/src/repository/sqlite/RoleSqliteRepository.ts +151 -0
- package/src/repository/sqlite/UserSqliteRepository.ts +194 -0
- package/src/routes/RoleRoutes.ts +141 -0
- package/src/routes/UserRoutes.ts +198 -0
- package/src/services/PermissionService.ts +26 -0
- package/src/services/RoleService.ts +46 -21
- package/src/services/UserService.ts +86 -28
- package/src/utils/AuthUtils.ts +22 -7
- package/src/utils/DbSetupUtils.ts +39 -0
- package/src/zod/RoleZod.ts +14 -0
- package/src/zod/UserZod.ts +26 -0
- package/test/data-json/roles/admin-role.json +1 -1
- package/test/data-obj/roles/{admin-role.ts → admin-mongo-role.ts} +2 -1
- package/test/data-obj/roles/admin-sqlite-role.ts +9 -0
- package/test/data-obj/roles/operator-sqlite-role.ts +9 -0
- package/test/data-obj/users/root-mongo-user.ts +15 -0
- package/test/data-obj/users/root-sqlite-user.ts +16 -0
- package/test/{initializers → db}/MongoInMemory.ts +2 -1
- package/test/initializers/RoleMongoInitializer.ts +15 -0
- package/test/initializers/RoleSqliteInitializer.ts +18 -0
- package/test/repository/{role-repository.test.ts → mongo/role-mongo-repository.test.ts} +14 -24
- package/test/repository/mongo/user-mongo-repository.test.ts +121 -0
- package/test/repository/sqlite/role-sqlite-repository.test.ts +70 -0
- package/test/repository/sqlite/user-sqlite-repository.test.ts +126 -0
- package/test/service/mock-service.test.ts +3 -3
- package/test/service/role-service.test.ts +5 -5
- package/test/service/user-service.test.ts +42 -15
- package/test.db +0 -0
- package/tsconfig.json +16 -3
- package/tsconfig.tsbuildinfo +1 -1
- package/types/errors/BadCredentialsError.d.ts +6 -0
- package/types/errors/BadCredentialsError.d.ts.map +1 -0
- package/types/errors/UnauthorizedError.d.ts +6 -0
- package/types/errors/UnauthorizedError.d.ts.map +1 -0
- package/types/factory/RoleServiceFactory.d.ts +2 -2
- package/types/factory/RoleServiceFactory.d.ts.map +1 -1
- package/types/factory/UserServiceFactory.d.ts +2 -2
- package/types/factory/UserServiceFactory.d.ts.map +1 -1
- package/types/graphql/resolvers/role.resolvers.d.ts +24 -7
- package/types/graphql/resolvers/role.resolvers.d.ts.map +1 -1
- package/types/graphql/resolvers/user.resolvers.d.ts +38 -7
- package/types/graphql/resolvers/user.resolvers.d.ts.map +1 -1
- package/types/i18n/messages/validation-i18n.d.ts +4 -0
- package/types/i18n/messages/validation-i18n.d.ts.map +1 -0
- package/types/index.d.ts +21 -5
- package/types/index.d.ts.map +1 -1
- package/types/interfaces/IID.d.ts +6 -0
- package/types/interfaces/IID.d.ts.map +1 -0
- package/types/interfaces/IJwtUser.d.ts +7 -0
- package/types/interfaces/IJwtUser.d.ts.map +1 -0
- package/types/interfaces/IRole.d.ts +13 -6
- package/types/interfaces/IRole.d.ts.map +1 -1
- package/types/interfaces/IRoleRepository.d.ts +8 -4
- package/types/interfaces/IRoleRepository.d.ts.map +1 -1
- package/types/interfaces/IUser.d.ts +29 -8
- package/types/interfaces/IUser.d.ts.map +1 -1
- package/types/interfaces/IUserGroup.d.ts +3 -2
- package/types/interfaces/IUserGroup.d.ts.map +1 -1
- package/types/interfaces/IUserRepository.d.ts +10 -6
- package/types/interfaces/IUserRepository.d.ts.map +1 -1
- package/types/middleware/jwtMiddleware.d.ts +4 -0
- package/types/middleware/jwtMiddleware.d.ts.map +1 -0
- package/types/middleware/rbacMiddleware.d.ts +4 -0
- package/types/middleware/rbacMiddleware.d.ts.map +1 -0
- package/types/models/RoleModel.d.ts +8 -8
- package/types/models/RoleModel.d.ts.map +1 -1
- package/types/models/UserGroupModel.d.ts +8 -8
- package/types/models/UserGroupModel.d.ts.map +1 -1
- package/types/models/UserModel.d.ts +8 -8
- package/types/models/UserModel.d.ts.map +1 -1
- package/types/permissions/IdentityPermissions.d.ts +16 -0
- package/types/permissions/IdentityPermissions.d.ts.map +1 -0
- package/types/rbac/Rbac.d.ts +12 -0
- package/types/rbac/Rbac.d.ts.map +1 -0
- package/types/repository/mongo/RoleMongoRepository.d.ts +14 -0
- package/types/repository/mongo/RoleMongoRepository.d.ts.map +1 -0
- package/types/repository/mongo/UserMongoRepository.d.ts +18 -0
- package/types/repository/mongo/UserMongoRepository.d.ts.map +1 -0
- package/types/repository/sqlite/RoleSqliteRepository.d.ts +19 -0
- package/types/repository/sqlite/RoleSqliteRepository.d.ts.map +1 -0
- package/types/repository/sqlite/UserSqliteRepository.d.ts +24 -0
- package/types/repository/sqlite/UserSqliteRepository.d.ts.map +1 -0
- package/types/routes/RoleRoutes.d.ts +4 -0
- package/types/routes/RoleRoutes.d.ts.map +1 -0
- package/types/routes/UserRoutes.d.ts +4 -0
- package/types/routes/UserRoutes.d.ts.map +1 -0
- package/types/routes/authRoutes.d.ts.map +1 -1
- package/types/services/AuthService.d.ts +0 -3
- package/types/services/AuthService.d.ts.map +1 -1
- package/types/services/PermissionService.d.ts +9 -0
- package/types/services/PermissionService.d.ts.map +1 -0
- package/types/services/RoleService.d.ts +6 -8
- package/types/services/RoleService.d.ts.map +1 -1
- package/types/services/UserService.d.ts +13 -11
- package/types/services/UserService.d.ts.map +1 -1
- package/types/utils/AuthUtils.d.ts +5 -2
- package/types/utils/AuthUtils.d.ts.map +1 -1
- package/types/utils/DbSetupUtils.d.ts +10 -0
- package/types/utils/DbSetupUtils.d.ts.map +1 -0
- package/types/zod/RoleZod.d.ts +10 -0
- package/types/zod/RoleZod.d.ts.map +1 -0
- package/types/zod/UserZod.d.ts +53 -0
- package/types/zod/UserZod.d.ts.map +1 -0
- package/dist/factory/AuthServiceFactory.js +0 -8
- package/dist/graphql/resolvers/auth.resolvers.js +0 -16
- package/dist/graphql/types/auth.graphql +0 -12
- package/dist/repository/RoleRepository.js +0 -29
- package/dist/repository/UserRepository.js +0 -33
- package/src/factory/AuthServiceFactory.ts +0 -10
- package/src/graphql/resolvers/auth.resolvers.ts +0 -20
- package/src/graphql/types/auth.graphql +0 -12
- package/src/repository/RoleRepository.ts +0 -42
- package/src/repository/UserRepository.ts +0 -47
- package/src/routes/authRoutes.ts +0 -22
- package/src/services/AuthService.ts +0 -29
- package/test/data-obj/users/root-user.ts +0 -15
- package/test/initializers/MongoInMemory.mjs +0 -34
- package/test/initializers/RoleInitializer.mjs +0 -11
- package/test/initializers/RoleInitializer.ts +0 -15
- package/test/repository/user-repository.test.ts +0 -54
- package/types/factory/AuthServiceFactory.d.ts +0 -4
- package/types/factory/AuthServiceFactory.d.ts.map +0 -1
- package/types/graphql/resolvers/auth.resolvers.d.ts +0 -12
- package/types/graphql/resolvers/auth.resolvers.d.ts.map +0 -1
- package/types/repository/RoleRepository.d.ts +0 -41
- package/types/repository/RoleRepository.d.ts.map +0 -1
- package/types/repository/UserRepository.d.ts +0 -40
- package/types/repository/UserRepository.d.ts.map +0 -1
- package/types/routes/AuthRoutes.d.ts +0 -3
- package/types/routes/AuthRoutes.d.ts.map +0 -1
|
@@ -1,8 +1,21 @@
|
|
|
1
1
|
import RoleService from "../services/RoleService.js";
|
|
2
|
-
import
|
|
2
|
+
import RoleMongoRepository from "../repository/mongo/RoleMongoRepository.js";
|
|
3
|
+
import RoleSqliteRepository from "../repository/sqlite/RoleSqliteRepository.js";
|
|
4
|
+
import { DbSetupUtils, DbEngine } from "../utils/DbSetupUtils.js";
|
|
3
5
|
const RoleServiceFactory = () => {
|
|
4
|
-
|
|
6
|
+
let roleRepository;
|
|
7
|
+
switch (DbSetupUtils.getDbEngine()) {
|
|
8
|
+
case DbEngine.Mongo:
|
|
9
|
+
console.log("RoleServiceFactory DB ENGINE MONGODB");
|
|
10
|
+
roleRepository = new RoleMongoRepository();
|
|
11
|
+
break;
|
|
12
|
+
case DbEngine.Sqlite:
|
|
13
|
+
console.log("RoleServiceFactory DB ENGINE SQLITE");
|
|
14
|
+
roleRepository = new RoleSqliteRepository(process.env.SQLITE_DATABASE, false);
|
|
15
|
+
roleRepository.table();
|
|
16
|
+
break;
|
|
17
|
+
}
|
|
5
18
|
const roleService = new RoleService(roleRepository);
|
|
6
19
|
return roleService;
|
|
7
20
|
};
|
|
8
|
-
export default RoleServiceFactory;
|
|
21
|
+
export default RoleServiceFactory();
|
|
@@ -1,8 +1,22 @@
|
|
|
1
|
-
import
|
|
1
|
+
import UserMongoRepository from "../repository/mongo/UserMongoRepository.js";
|
|
2
2
|
import UserService from "../services/UserService.js";
|
|
3
|
+
import UserSqliteRepository from "../repository/sqlite/UserSqliteRepository.js";
|
|
4
|
+
import process from "node:process";
|
|
5
|
+
import { DbEngine, DbSetupUtils } from "../utils/DbSetupUtils.js";
|
|
3
6
|
const UserServiceFactory = () => {
|
|
4
|
-
|
|
7
|
+
let userRepository;
|
|
8
|
+
switch (DbSetupUtils.getDbEngine()) {
|
|
9
|
+
case DbEngine.Mongo:
|
|
10
|
+
console.log("UserServiceFactory DB ENGINE MONGODB");
|
|
11
|
+
userRepository = new UserMongoRepository();
|
|
12
|
+
break;
|
|
13
|
+
case DbEngine.Sqlite:
|
|
14
|
+
console.log("UserServiceFactory DB ENGINE SQLITE");
|
|
15
|
+
userRepository = new UserSqliteRepository(process.env.SQLITE_DATABASE, false);
|
|
16
|
+
userRepository.table();
|
|
17
|
+
break;
|
|
18
|
+
}
|
|
5
19
|
const userService = new UserService(userRepository);
|
|
6
20
|
return userService;
|
|
7
21
|
};
|
|
8
|
-
export default UserServiceFactory;
|
|
22
|
+
export default UserServiceFactory();
|
|
@@ -1,23 +1,110 @@
|
|
|
1
1
|
import RoleServiceFactory from "../../factory/RoleServiceFactory.js";
|
|
2
|
-
|
|
2
|
+
import { IdentityPermissions } from "../../permissions/IdentityPermissions.js";
|
|
3
|
+
import { ValidationError, ValidationErrorToGraphQLError } from "@drax/common-back";
|
|
4
|
+
import { GraphQLError } from "graphql";
|
|
5
|
+
import { PermissionService } from "../../services/PermissionService.js";
|
|
6
|
+
import UnauthorizedError from "../../errors/UnauthorizedError.js";
|
|
7
|
+
const roleService = RoleServiceFactory;
|
|
3
8
|
export default {
|
|
4
9
|
Query: {
|
|
5
|
-
findRoleById: async (_, { id }) => {
|
|
6
|
-
|
|
10
|
+
findRoleById: async (_, { id }, { rbac }) => {
|
|
11
|
+
try {
|
|
12
|
+
rbac.assertPermission(IdentityPermissions.ViewRole);
|
|
13
|
+
return await roleService.findById(id);
|
|
14
|
+
}
|
|
15
|
+
catch (e) {
|
|
16
|
+
if (e instanceof UnauthorizedError) {
|
|
17
|
+
throw new GraphQLError(e.message);
|
|
18
|
+
}
|
|
19
|
+
throw new GraphQLError('error.server');
|
|
20
|
+
}
|
|
7
21
|
},
|
|
8
|
-
|
|
9
|
-
|
|
22
|
+
fetchRole: async (_, {}, { rbac }) => {
|
|
23
|
+
try {
|
|
24
|
+
rbac.assertPermission(IdentityPermissions.ViewRole);
|
|
25
|
+
return await roleService.fetchAll();
|
|
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
|
+
fetchPermissions: async (_, {}, { rbac }) => {
|
|
35
|
+
try {
|
|
36
|
+
rbac.assertPermission(IdentityPermissions.PermissionsRole);
|
|
37
|
+
return PermissionService.getPermissions();
|
|
38
|
+
}
|
|
39
|
+
catch (e) {
|
|
40
|
+
if (e instanceof UnauthorizedError) {
|
|
41
|
+
throw new GraphQLError(e.message);
|
|
42
|
+
}
|
|
43
|
+
throw new GraphQLError('error.server');
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
paginateRole: async (_, { page, limit, seach }, { rbac }) => {
|
|
47
|
+
try {
|
|
48
|
+
rbac.assertPermission(IdentityPermissions.ViewRole);
|
|
49
|
+
return await roleService.paginate(page, limit, seach);
|
|
50
|
+
}
|
|
51
|
+
catch (e) {
|
|
52
|
+
console.error("paginateRole", e);
|
|
53
|
+
if (e instanceof UnauthorizedError) {
|
|
54
|
+
throw new GraphQLError(e.message);
|
|
55
|
+
}
|
|
56
|
+
throw new GraphQLError('error.server');
|
|
57
|
+
}
|
|
10
58
|
}
|
|
11
59
|
},
|
|
12
60
|
Mutation: {
|
|
13
|
-
createRole: async (_, { input }) => {
|
|
14
|
-
|
|
61
|
+
createRole: async (_, { input }, { rbac }) => {
|
|
62
|
+
try {
|
|
63
|
+
rbac.assertPermission(IdentityPermissions.CreateRole);
|
|
64
|
+
return await roleService.create(input);
|
|
65
|
+
}
|
|
66
|
+
catch (e) {
|
|
67
|
+
console.error("createRole", e);
|
|
68
|
+
if (e instanceof ValidationError) {
|
|
69
|
+
throw ValidationErrorToGraphQLError(e);
|
|
70
|
+
}
|
|
71
|
+
if (e instanceof UnauthorizedError) {
|
|
72
|
+
throw new GraphQLError(e.message);
|
|
73
|
+
}
|
|
74
|
+
throw new GraphQLError('error.server');
|
|
75
|
+
}
|
|
15
76
|
},
|
|
16
|
-
updateRole: async (_, { id, input }) => {
|
|
17
|
-
|
|
77
|
+
updateRole: async (_, { id, input }, { rbac }) => {
|
|
78
|
+
try {
|
|
79
|
+
rbac.assertPermission(IdentityPermissions.UpdateRole);
|
|
80
|
+
return await roleService.update(id, input);
|
|
81
|
+
}
|
|
82
|
+
catch (e) {
|
|
83
|
+
console.error("updateRole", e);
|
|
84
|
+
if (e instanceof ValidationError) {
|
|
85
|
+
throw ValidationErrorToGraphQLError(e);
|
|
86
|
+
}
|
|
87
|
+
if (e instanceof UnauthorizedError) {
|
|
88
|
+
throw new GraphQLError(e.message);
|
|
89
|
+
}
|
|
90
|
+
throw new GraphQLError('error.server');
|
|
91
|
+
}
|
|
18
92
|
},
|
|
19
|
-
deleteRole: async (_, { id }) => {
|
|
20
|
-
|
|
93
|
+
deleteRole: async (_, { id }, { rbac }) => {
|
|
94
|
+
try {
|
|
95
|
+
rbac.assertPermission(IdentityPermissions.DeleteRole);
|
|
96
|
+
return await roleService.delete(id);
|
|
97
|
+
}
|
|
98
|
+
catch (e) {
|
|
99
|
+
console.error("deleteRole", e);
|
|
100
|
+
if (e instanceof ValidationError) {
|
|
101
|
+
throw ValidationErrorToGraphQLError(e);
|
|
102
|
+
}
|
|
103
|
+
if (e instanceof UnauthorizedError) {
|
|
104
|
+
throw new GraphQLError(e.message);
|
|
105
|
+
}
|
|
106
|
+
throw new GraphQLError('error.server');
|
|
107
|
+
}
|
|
21
108
|
}
|
|
22
109
|
}
|
|
23
110
|
};
|
|
@@ -1,26 +1,145 @@
|
|
|
1
1
|
import UserServiceFactory from "../../factory/UserServiceFactory.js";
|
|
2
|
-
|
|
2
|
+
import { GraphQLError } from "graphql";
|
|
3
|
+
import { ValidationErrorToGraphQLError, ValidationError } from "@drax/common-back";
|
|
4
|
+
import { IdentityPermissions } from "../../permissions/IdentityPermissions.js";
|
|
5
|
+
import UnauthorizedError from "../../errors/UnauthorizedError.js";
|
|
6
|
+
import BadCredentialsError from "../../errors/BadCredentialsError.js";
|
|
7
|
+
const userService = UserServiceFactory;
|
|
3
8
|
export default {
|
|
4
9
|
Query: {
|
|
5
|
-
|
|
6
|
-
|
|
10
|
+
me: async (_, {}, { authUser }) => {
|
|
11
|
+
try {
|
|
12
|
+
if (authUser) {
|
|
13
|
+
let user = await userService.findById(authUser.id);
|
|
14
|
+
delete user.password;
|
|
15
|
+
return user;
|
|
16
|
+
}
|
|
17
|
+
throw new UnauthorizedError();
|
|
18
|
+
}
|
|
19
|
+
catch (e) {
|
|
20
|
+
console.log(e);
|
|
21
|
+
throw new GraphQLError(e.message);
|
|
22
|
+
}
|
|
7
23
|
},
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
24
|
+
findUserById: async (_, { id }, { rbac }) => {
|
|
25
|
+
try {
|
|
26
|
+
rbac.assertPermission(IdentityPermissions.ViewUser);
|
|
27
|
+
return await userService.findById(id);
|
|
28
|
+
}
|
|
29
|
+
catch (e) {
|
|
30
|
+
if (e instanceof UnauthorizedError) {
|
|
31
|
+
throw new GraphQLError(e.message);
|
|
32
|
+
}
|
|
33
|
+
throw new GraphQLError('error.server');
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
paginateUser: async (_, { page, limit, search }, { rbac }) => {
|
|
37
|
+
try {
|
|
38
|
+
rbac.assertPermission(IdentityPermissions.ViewUser);
|
|
39
|
+
return await userService.paginate(page, limit, search);
|
|
40
|
+
}
|
|
41
|
+
catch (e) {
|
|
42
|
+
if (e instanceof UnauthorizedError) {
|
|
43
|
+
throw new GraphQLError(e.message);
|
|
44
|
+
}
|
|
45
|
+
throw new GraphQLError('error.server');
|
|
46
|
+
}
|
|
11
47
|
}
|
|
12
48
|
},
|
|
13
49
|
Mutation: {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
50
|
+
auth: async (_, { input }) => {
|
|
51
|
+
try {
|
|
52
|
+
return await userService.auth(input.username, input.password);
|
|
53
|
+
}
|
|
54
|
+
catch (e) {
|
|
55
|
+
console.error("auth", e);
|
|
56
|
+
if (e instanceof BadCredentialsError) {
|
|
57
|
+
throw new GraphQLError(e.message);
|
|
58
|
+
}
|
|
59
|
+
throw new GraphQLError('error.server');
|
|
60
|
+
}
|
|
18
61
|
},
|
|
19
|
-
|
|
20
|
-
|
|
62
|
+
createUser: async (_, { input }, { rbac }) => {
|
|
63
|
+
try {
|
|
64
|
+
rbac.assertPermission(IdentityPermissions.CreateUser);
|
|
65
|
+
const user = await userService.create(input);
|
|
66
|
+
return user;
|
|
67
|
+
}
|
|
68
|
+
catch (e) {
|
|
69
|
+
console.error("createUser", e);
|
|
70
|
+
if (e instanceof ValidationError) {
|
|
71
|
+
throw ValidationErrorToGraphQLError(e);
|
|
72
|
+
}
|
|
73
|
+
else if (e instanceof UnauthorizedError) {
|
|
74
|
+
throw new GraphQLError(e.message);
|
|
75
|
+
}
|
|
76
|
+
throw new GraphQLError('error.server');
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
updateUser: async (_, { id, input }, { rbac }) => {
|
|
80
|
+
try {
|
|
81
|
+
rbac.assertPermission(IdentityPermissions.UpdateUser);
|
|
82
|
+
const user = await userService.update(id, input);
|
|
83
|
+
return user;
|
|
84
|
+
}
|
|
85
|
+
catch (e) {
|
|
86
|
+
if (e instanceof ValidationError) {
|
|
87
|
+
throw ValidationErrorToGraphQLError(e);
|
|
88
|
+
}
|
|
89
|
+
else if (e instanceof UnauthorizedError) {
|
|
90
|
+
throw new GraphQLError(e.message);
|
|
91
|
+
}
|
|
92
|
+
throw new GraphQLError('error.server');
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
deleteUser: async (_, { id }, { rbac }) => {
|
|
96
|
+
try {
|
|
97
|
+
rbac.assertPermission(IdentityPermissions.DeleteUser);
|
|
98
|
+
return await userService.delete(id);
|
|
99
|
+
}
|
|
100
|
+
catch (e) {
|
|
101
|
+
console.error("deleteUser", e);
|
|
102
|
+
if (e instanceof ValidationError) {
|
|
103
|
+
throw ValidationErrorToGraphQLError(e);
|
|
104
|
+
}
|
|
105
|
+
else if (e instanceof UnauthorizedError) {
|
|
106
|
+
throw new GraphQLError(e.message);
|
|
107
|
+
}
|
|
108
|
+
throw new GraphQLError('error.server');
|
|
109
|
+
}
|
|
110
|
+
},
|
|
111
|
+
changeOwnPassword: async (_, { currentPassword, newPassword }, { authUser }) => {
|
|
112
|
+
try {
|
|
113
|
+
if (!authUser) {
|
|
114
|
+
throw new UnauthorizedError();
|
|
115
|
+
}
|
|
116
|
+
let userId = authUser.id;
|
|
117
|
+
return await userService.changeOwnPassword(userId, currentPassword, newPassword);
|
|
118
|
+
}
|
|
119
|
+
catch (e) {
|
|
120
|
+
if (e instanceof ValidationError) {
|
|
121
|
+
throw ValidationErrorToGraphQLError(e);
|
|
122
|
+
}
|
|
123
|
+
else if (e instanceof UnauthorizedError) {
|
|
124
|
+
throw new GraphQLError(e.message);
|
|
125
|
+
}
|
|
126
|
+
throw new GraphQLError('error.server');
|
|
127
|
+
}
|
|
128
|
+
},
|
|
129
|
+
changeUserPassword: async (_, { userId, newPassword }, { rbac }) => {
|
|
130
|
+
try {
|
|
131
|
+
rbac.assertPermission(IdentityPermissions.UpdateUser);
|
|
132
|
+
return await userService.changeUserPassword(userId, newPassword);
|
|
133
|
+
}
|
|
134
|
+
catch (e) {
|
|
135
|
+
if (e instanceof ValidationError) {
|
|
136
|
+
throw ValidationErrorToGraphQLError(e);
|
|
137
|
+
}
|
|
138
|
+
else if (e instanceof UnauthorizedError) {
|
|
139
|
+
throw new GraphQLError(e.message);
|
|
140
|
+
}
|
|
141
|
+
throw new GraphQLError('error.server');
|
|
142
|
+
}
|
|
21
143
|
},
|
|
22
|
-
deleteUser: async (_, { id }) => {
|
|
23
|
-
return await userService.delete(id);
|
|
24
|
-
}
|
|
25
144
|
}
|
|
26
145
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
type Role {
|
|
2
|
-
|
|
2
|
+
id: ID!
|
|
3
3
|
name: String
|
|
4
4
|
readonly: Boolean
|
|
5
5
|
childRoles: [Role]
|
|
@@ -7,14 +7,16 @@ type Role {
|
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
type RolePaginated{
|
|
10
|
-
|
|
10
|
+
total: Int
|
|
11
11
|
page: Int
|
|
12
12
|
limit: Int
|
|
13
|
-
|
|
13
|
+
items: [Role]
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
type Query{
|
|
17
|
-
paginateRole: RolePaginated
|
|
17
|
+
paginateRole(page:Int, limit:Int, search:String): RolePaginated
|
|
18
|
+
fetchRole: [Role]
|
|
19
|
+
fetchPermissions: [String]
|
|
18
20
|
findRoleById(id: ID): Role
|
|
19
21
|
}
|
|
20
22
|
|
|
@@ -1,34 +1,61 @@
|
|
|
1
1
|
type User {
|
|
2
|
-
|
|
2
|
+
id: ID!
|
|
3
3
|
username: String!
|
|
4
|
+
name: String
|
|
4
5
|
email: String
|
|
5
6
|
role: Role
|
|
6
7
|
phone: String
|
|
7
|
-
|
|
8
|
+
avatar: String
|
|
9
|
+
active: Boolean
|
|
8
10
|
}
|
|
9
11
|
|
|
10
12
|
type UserPaginated{
|
|
11
|
-
|
|
13
|
+
total: Int
|
|
12
14
|
page: Int
|
|
13
15
|
limit: Int
|
|
14
|
-
|
|
16
|
+
items: [User]
|
|
15
17
|
}
|
|
16
18
|
|
|
17
19
|
type Query{
|
|
20
|
+
me: User
|
|
18
21
|
findUserByUsername(username: String!): User
|
|
19
22
|
findUserById(id: ID!): User
|
|
20
|
-
paginateUser: UserPaginated
|
|
23
|
+
paginateUser(page: Int, limit: Int, search: String): UserPaginated
|
|
21
24
|
}
|
|
22
25
|
|
|
23
|
-
input
|
|
26
|
+
input UserCreateInput{
|
|
27
|
+
name: String
|
|
24
28
|
username: String!
|
|
25
|
-
email: String!
|
|
26
29
|
password: String!
|
|
27
30
|
role: ID
|
|
31
|
+
email: String!
|
|
32
|
+
phone: String
|
|
33
|
+
active: Boolean
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
input UserUpdateInput{
|
|
37
|
+
name: String
|
|
38
|
+
username: String!
|
|
39
|
+
role: ID
|
|
40
|
+
email: String!
|
|
41
|
+
phone: String
|
|
42
|
+
active: Boolean
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
type Auth{
|
|
46
|
+
accessToken: String
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
input AuthInput{
|
|
50
|
+
username: String!
|
|
51
|
+
password: String!
|
|
28
52
|
}
|
|
29
53
|
|
|
30
54
|
type Mutation{
|
|
31
|
-
|
|
32
|
-
|
|
55
|
+
auth(input: AuthInput): Auth
|
|
56
|
+
createUser(input: UserCreateInput): User
|
|
57
|
+
updateUser(id: ID!, input: UserUpdateInput): User
|
|
33
58
|
deleteUser(id: ID!): Boolean
|
|
59
|
+
changeOwnPassword(currentPassword:String!, newPassword: String!): Boolean
|
|
60
|
+
changeUserPassword(userId:ID!, newPassword:String!): Boolean
|
|
34
61
|
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
const messages = {
|
|
2
|
+
en: {
|
|
3
|
+
validation: {
|
|
4
|
+
required: "{field} is required",
|
|
5
|
+
minCharacteres: "{field} must be more than {min} characters",
|
|
6
|
+
maxCharacteres: "{field} must be less than {max} characters",
|
|
7
|
+
email: "{field} is not a valid email",
|
|
8
|
+
unique: "{field} must be unique",
|
|
9
|
+
}
|
|
10
|
+
},
|
|
11
|
+
es: {
|
|
12
|
+
validation: {
|
|
13
|
+
required: "{field} es requerido",
|
|
14
|
+
minCharacteres: "{field} debe tener mas de {min} caracteres",
|
|
15
|
+
maxCharacteres: "{field} debe tener menos de {max} caracteres",
|
|
16
|
+
email: "{field} no es un email valido",
|
|
17
|
+
unique: "{field} debe ser unico",
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
export default messages;
|
package/dist/index.js
CHANGED
|
@@ -1,19 +1,34 @@
|
|
|
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
|
|
5
|
-
import
|
|
4
|
+
import RoleService from "./services/RoleService.js";
|
|
5
|
+
import UserService from "./services/UserService.js";
|
|
6
|
+
import PermissionService from "./services/PermissionService.js";
|
|
7
|
+
import Rbac from "./rbac/Rbac.js";
|
|
8
|
+
import { UserRoutes } from "./routes/UserRoutes.js";
|
|
9
|
+
import { RoleRoutes } from "./routes/RoleRoutes.js";
|
|
10
|
+
import AuthUtils from "./utils/AuthUtils.js";
|
|
11
|
+
import { jwtMiddleware } from "./middleware/jwtMiddleware.js";
|
|
12
|
+
import { rbacMiddleware } from "./middleware/rbacMiddleware.js";
|
|
13
|
+
import IdentityPermissions from "./permissions/IdentityPermissions.js";
|
|
14
|
+
import UnauthorizedError from "./errors/UnauthorizedError.js";
|
|
15
|
+
import BadCredentialsError from "./errors/BadCredentialsError.js";
|
|
6
16
|
const graphqlMergeResult = await GraphqlMerge();
|
|
7
17
|
const identityTypeDefs = await graphqlMergeResult.typeDefs;
|
|
8
18
|
const identityResolvers = await graphqlMergeResult.resolvers;
|
|
9
|
-
const userService = UserServiceFactory();
|
|
10
|
-
const roleService = RoleServiceFactory();
|
|
11
|
-
const authService = AuthServiceFactory();
|
|
12
19
|
export {
|
|
13
20
|
//Service
|
|
14
|
-
|
|
21
|
+
UserService, RoleService, PermissionService, Rbac,
|
|
22
|
+
//Factories
|
|
23
|
+
UserServiceFactory, RoleServiceFactory,
|
|
15
24
|
//GQL
|
|
16
25
|
identityTypeDefs, identityResolvers,
|
|
17
26
|
//API REST
|
|
18
|
-
|
|
27
|
+
UserRoutes, RoleRoutes, AuthUtils,
|
|
28
|
+
//API MIDDLEWARE
|
|
29
|
+
jwtMiddleware, rbacMiddleware,
|
|
30
|
+
//Permissions
|
|
31
|
+
IdentityPermissions,
|
|
32
|
+
//Errors
|
|
33
|
+
UnauthorizedError, BadCredentialsError };
|
|
19
34
|
/// <reference types="index.d.ts" />
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import AuthUtils from "../utils/AuthUtils.js";
|
|
2
|
+
function jwtMiddleware(request, reply, done) {
|
|
3
|
+
try {
|
|
4
|
+
const token = request.headers?.authorization?.replace(/Bearer /i, "");
|
|
5
|
+
if (token) {
|
|
6
|
+
const authUser = AuthUtils.verifyToken(token);
|
|
7
|
+
if (authUser) {
|
|
8
|
+
request.authUser = authUser;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
done();
|
|
12
|
+
}
|
|
13
|
+
catch (e) {
|
|
14
|
+
console.error(e);
|
|
15
|
+
reply.code(401).send({ error: 'Token JWT inválido' });
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
export default jwtMiddleware;
|
|
19
|
+
export { jwtMiddleware };
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { DraxCache } from "@drax/common-back";
|
|
2
|
+
import RoleServiceFactory from "../factory/RoleServiceFactory.js";
|
|
3
|
+
import Rbac from "../rbac/Rbac.js";
|
|
4
|
+
const cacheTTL = process.env.RBAC_CACHE_TTL ? parseInt(process.env.RBAC_CACHE_TTL) : 10000;
|
|
5
|
+
const draxCache = new DraxCache(cacheTTL);
|
|
6
|
+
const roleService = RoleServiceFactory;
|
|
7
|
+
async function roleLoader(k) {
|
|
8
|
+
const role = await roleService.findById(k);
|
|
9
|
+
if (role) {
|
|
10
|
+
return { id: role.id, name: role.name, permissions: role.permissions };
|
|
11
|
+
}
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
async function rbacMiddleware(request, reply) {
|
|
15
|
+
try {
|
|
16
|
+
//console.log("rbacMiddleware authUser",request.authUser)
|
|
17
|
+
if (request.authUser) {
|
|
18
|
+
const authUser = request.authUser;
|
|
19
|
+
const cacheKey = authUser.roleId;
|
|
20
|
+
const role = await draxCache.getOrLoad(cacheKey, roleLoader);
|
|
21
|
+
const rbac = new Rbac(authUser, role);
|
|
22
|
+
request.rbac = rbac;
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
const rbac = new Rbac(null, null);
|
|
26
|
+
request.rbac = rbac;
|
|
27
|
+
}
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
catch (e) {
|
|
31
|
+
console.error(e);
|
|
32
|
+
reply.code(500).send({ error: 'RBAC ERROR' });
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
export default rbacMiddleware;
|
|
36
|
+
export { rbacMiddleware };
|
package/dist/models/RoleModel.js
CHANGED
|
@@ -5,14 +5,6 @@ const Schema = mongoose.Schema;
|
|
|
5
5
|
const RoleSchema = new Schema({
|
|
6
6
|
name: {
|
|
7
7
|
type: String, unique: true, required: true, index: true,
|
|
8
|
-
validate: [
|
|
9
|
-
{
|
|
10
|
-
validator: function (v) {
|
|
11
|
-
return !/(\s){2}/.test(v);
|
|
12
|
-
},
|
|
13
|
-
message: props => `Role name cant contain two spaces`
|
|
14
|
-
},
|
|
15
|
-
],
|
|
16
8
|
},
|
|
17
9
|
permissions: [{ type: String, required: true }],
|
|
18
10
|
childRoles: [{
|
package/dist/models/UserModel.js
CHANGED
|
@@ -45,7 +45,6 @@ const UserSchema = new mongoose.Schema({
|
|
|
45
45
|
}
|
|
46
46
|
},
|
|
47
47
|
avatar: { type: String, required: false },
|
|
48
|
-
avatarurl: { type: String, required: false },
|
|
49
48
|
role: {
|
|
50
49
|
type: mongoose.Schema.Types.ObjectId,
|
|
51
50
|
ref: 'Role',
|
|
@@ -65,7 +64,7 @@ const UserSchema = new mongoose.Schema({
|
|
|
65
64
|
}
|
|
66
65
|
],
|
|
67
66
|
default: [],
|
|
68
|
-
|
|
67
|
+
id: false
|
|
69
68
|
}*/
|
|
70
69
|
}, { timestamps: true });
|
|
71
70
|
UserSchema.set('toJSON', { getters: true });
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
var IdentityPermissions;
|
|
2
|
+
(function (IdentityPermissions) {
|
|
3
|
+
IdentityPermissions["CreateUser"] = "user:create";
|
|
4
|
+
IdentityPermissions["UpdateUser"] = "user:update";
|
|
5
|
+
IdentityPermissions["DeleteUser"] = "user:delete";
|
|
6
|
+
IdentityPermissions["ViewUser"] = "user:view";
|
|
7
|
+
IdentityPermissions["ManageUser"] = "user:manage";
|
|
8
|
+
IdentityPermissions["CreateRole"] = "role:create";
|
|
9
|
+
IdentityPermissions["UpdateRole"] = "role:update";
|
|
10
|
+
IdentityPermissions["DeleteRole"] = "role:delete";
|
|
11
|
+
IdentityPermissions["ViewRole"] = "role:view";
|
|
12
|
+
IdentityPermissions["ManageRole"] = "role:manage";
|
|
13
|
+
IdentityPermissions["PermissionsRole"] = "role:permissions";
|
|
14
|
+
})(IdentityPermissions || (IdentityPermissions = {}));
|
|
15
|
+
export default IdentityPermissions;
|
|
16
|
+
export { IdentityPermissions };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import UnauthorizedError from "../errors/UnauthorizedError.js";
|
|
2
|
+
class Rbac {
|
|
3
|
+
constructor(authUser, role) {
|
|
4
|
+
this.authUser = authUser;
|
|
5
|
+
this.role = role;
|
|
6
|
+
}
|
|
7
|
+
hasPermission(requiredPermission) {
|
|
8
|
+
if (!this.authUser || !this.role || !this.role.permissions || this.role.permissions.length === 0) {
|
|
9
|
+
return false;
|
|
10
|
+
}
|
|
11
|
+
return this.role.permissions.includes(requiredPermission);
|
|
12
|
+
}
|
|
13
|
+
assertPermission(requiredPermission) {
|
|
14
|
+
if (!this.hasPermission(requiredPermission)) {
|
|
15
|
+
throw new UnauthorizedError();
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
export default Rbac;
|
|
20
|
+
export { Rbac };
|