@drax/identity-back 0.0.12 → 0.0.14
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/config/IdentityConfig.js +12 -0
- package/dist/factory/RoleServiceFactory.js +16 -13
- package/dist/factory/UserServiceFactory.js +16 -14
- package/dist/graphql/resolvers/role.resolvers.js +5 -1
- package/dist/graphql/resolvers/user.resolvers.js +1 -1
- package/dist/index.js +11 -1
- package/dist/middleware/rbacMiddleware.js +4 -3
- package/dist/routes/RoleRoutes.js +5 -1
- package/dist/routes/UserRoutes.js +1 -1
- package/dist/services/RoleService.js +1 -5
- package/dist/setup/CreateOrUpdateRole.js +15 -0
- package/dist/setup/CreateUserIfNotExist.js +17 -0
- package/dist/setup/LoadConfigFromEnv.js +12 -0
- package/dist/setup/LoadPermissions.js +8 -0
- package/dist/setup/RecoveryUserPassword.js +9 -0
- package/dist/utils/AuthUtils.js +9 -5
- package/dist/utils/DbSetupUtils.js +10 -8
- package/package.json +2 -2
- package/src/config/IdentityConfig.ts +17 -0
- package/src/factory/RoleServiceFactory.ts +19 -13
- package/src/factory/UserServiceFactory.ts +18 -14
- package/src/graphql/resolvers/role.resolvers.ts +7 -1
- package/src/graphql/resolvers/user.resolvers.ts +1 -1
- package/src/index.ts +18 -1
- package/src/middleware/rbacMiddleware.ts +4 -3
- package/src/routes/RoleRoutes.ts +7 -1
- package/src/routes/UserRoutes.ts +1 -1
- package/src/services/RoleService.ts +0 -4
- package/src/setup/CreateOrUpdateRole.ts +19 -0
- package/src/setup/CreateUserIfNotExist.ts +21 -0
- package/src/setup/LoadConfigFromEnv.ts +16 -0
- package/src/setup/LoadPermissions.ts +12 -0
- package/src/setup/RecoveryUserPassword.ts +13 -0
- package/src/utils/AuthUtils.ts +10 -5
- package/src/utils/DbSetupUtils.ts +10 -8
- package/tsconfig.tsbuildinfo +1 -1
- package/types/config/IdentityConfig.d.ts +12 -0
- package/types/config/IdentityConfig.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.map +1 -1
- package/types/index.d.ts +7 -1
- package/types/index.d.ts.map +1 -1
- package/types/interfaces/IID.d.ts +1 -1
- package/types/middleware/rbacMiddleware.d.ts.map +1 -1
- package/types/routes/RoleRoutes.d.ts.map +1 -1
- package/types/routes/UserRoutes.d.ts +1 -1
- package/types/services/RoleService.d.ts.map +1 -1
- package/types/setup/CreateOrUpdateRole.d.ts +5 -0
- package/types/setup/CreateOrUpdateRole.d.ts.map +1 -0
- package/types/setup/CreateUserIfNotExist.d.ts +5 -0
- package/types/setup/CreateUserIfNotExist.d.ts.map +1 -0
- package/types/setup/LoadConfigFromEnv.d.ts +4 -0
- package/types/setup/LoadConfigFromEnv.d.ts.map +1 -0
- package/types/setup/LoadPermissions.d.ts +4 -0
- package/types/setup/LoadPermissions.d.ts.map +1 -0
- package/types/setup/RecoveryUserPassword.d.ts +4 -0
- package/types/setup/RecoveryUserPassword.d.ts.map +1 -0
- package/types/utils/AuthUtils.d.ts.map +1 -1
- package/types/utils/DbSetupUtils.d.ts +1 -1
- package/types/utils/DbSetupUtils.d.ts.map +1 -1
- package/types/zod/UserZod.d.ts +6 -6
- package/dist/i18n/messages/validation-i18n.js +0 -21
- package/dist/routes/authRoutes.js +0 -29
- package/dist/services/AuthService.js +0 -6
- package/types/i18n/messages/validation-i18n.d.ts +0 -4
- package/types/i18n/messages/validation-i18n.d.ts.map +0 -1
- package/types/routes/authRoutes.d.ts +0 -4
- package/types/routes/authRoutes.d.ts.map +0 -1
- package/types/services/AuthService.d.ts +0 -7
- package/types/services/AuthService.d.ts.map +0 -1
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
var IdentityConfig;
|
|
2
|
+
(function (IdentityConfig) {
|
|
3
|
+
IdentityConfig["DbEngine"] = "DB_ENGINE";
|
|
4
|
+
IdentityConfig["SqliteDbFile"] = "SQLITE_FILE";
|
|
5
|
+
IdentityConfig["MongoDbUri"] = "MONGO_URI";
|
|
6
|
+
IdentityConfig["JwtSecret"] = "JWT_SECRET";
|
|
7
|
+
IdentityConfig["JwtExpiration"] = "JWT_EXPIRATION";
|
|
8
|
+
IdentityConfig["JwtIssuer"] = "JWT_ISSUER";
|
|
9
|
+
IdentityConfig["RbacCacheTTL"] = "RBAC_CACHE_TTL";
|
|
10
|
+
})(IdentityConfig || (IdentityConfig = {}));
|
|
11
|
+
export default IdentityConfig;
|
|
12
|
+
export { IdentityConfig };
|
|
@@ -2,20 +2,23 @@ import RoleService from "../services/RoleService.js";
|
|
|
2
2
|
import RoleMongoRepository from "../repository/mongo/RoleMongoRepository.js";
|
|
3
3
|
import RoleSqliteRepository from "../repository/sqlite/RoleSqliteRepository.js";
|
|
4
4
|
import { DbSetupUtils, DbEngine } from "../utils/DbSetupUtils.js";
|
|
5
|
+
let roleService;
|
|
5
6
|
const RoleServiceFactory = () => {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
7
|
+
if (!roleService) {
|
|
8
|
+
let roleRepository;
|
|
9
|
+
switch (DbSetupUtils.getDbEngine()) {
|
|
10
|
+
case DbEngine.Mongo:
|
|
11
|
+
console.log("RoleServiceFactory DB ENGINE MONGODB");
|
|
12
|
+
roleRepository = new RoleMongoRepository();
|
|
13
|
+
break;
|
|
14
|
+
case DbEngine.Sqlite:
|
|
15
|
+
console.log("RoleServiceFactory DB ENGINE SQLITE");
|
|
16
|
+
roleRepository = new RoleSqliteRepository(DbSetupUtils.getDbConfig(), false);
|
|
17
|
+
roleRepository.table();
|
|
18
|
+
break;
|
|
19
|
+
}
|
|
20
|
+
roleService = new RoleService(roleRepository);
|
|
17
21
|
}
|
|
18
|
-
const roleService = new RoleService(roleRepository);
|
|
19
22
|
return roleService;
|
|
20
23
|
};
|
|
21
|
-
export default RoleServiceFactory
|
|
24
|
+
export default RoleServiceFactory;
|
|
@@ -1,22 +1,24 @@
|
|
|
1
1
|
import UserMongoRepository from "../repository/mongo/UserMongoRepository.js";
|
|
2
2
|
import UserService from "../services/UserService.js";
|
|
3
3
|
import UserSqliteRepository from "../repository/sqlite/UserSqliteRepository.js";
|
|
4
|
-
import process from "node:process";
|
|
5
4
|
import { DbEngine, DbSetupUtils } from "../utils/DbSetupUtils.js";
|
|
5
|
+
let userService;
|
|
6
6
|
const UserServiceFactory = () => {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
7
|
+
if (!userService) {
|
|
8
|
+
let userRepository;
|
|
9
|
+
switch (DbSetupUtils.getDbEngine()) {
|
|
10
|
+
case DbEngine.Mongo:
|
|
11
|
+
console.log("UserServiceFactory DB ENGINE MONGODB");
|
|
12
|
+
userRepository = new UserMongoRepository();
|
|
13
|
+
break;
|
|
14
|
+
case DbEngine.Sqlite:
|
|
15
|
+
console.log("UserServiceFactory DB ENGINE SQLITE");
|
|
16
|
+
userRepository = new UserSqliteRepository(DbSetupUtils.getDbConfig(), false);
|
|
17
|
+
userRepository.table();
|
|
18
|
+
break;
|
|
19
|
+
}
|
|
20
|
+
userService = new UserService(userRepository);
|
|
18
21
|
}
|
|
19
|
-
const userService = new UserService(userRepository);
|
|
20
22
|
return userService;
|
|
21
23
|
};
|
|
22
|
-
export default UserServiceFactory
|
|
24
|
+
export default UserServiceFactory;
|
|
@@ -4,7 +4,7 @@ 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;
|
|
7
|
+
const roleService = RoleServiceFactory();
|
|
8
8
|
export default {
|
|
9
9
|
Query: {
|
|
10
10
|
findRoleById: async (_, { id }, { rbac }) => {
|
|
@@ -89,6 +89,10 @@ export default {
|
|
|
89
89
|
updateRole: async (_, { id, input }, { rbac }) => {
|
|
90
90
|
try {
|
|
91
91
|
rbac.assertPermission(IdentityPermissions.UpdateRole);
|
|
92
|
+
const currentRole = await roleService.findById(id);
|
|
93
|
+
if (currentRole.readonly) {
|
|
94
|
+
throw new ValidationError([{ field: 'name', reason: "role.readonly", value: input.name }]);
|
|
95
|
+
}
|
|
92
96
|
return await roleService.update(id, input);
|
|
93
97
|
}
|
|
94
98
|
catch (e) {
|
|
@@ -4,7 +4,7 @@ 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;
|
|
7
|
+
const userService = UserServiceFactory();
|
|
8
8
|
export default {
|
|
9
9
|
Query: {
|
|
10
10
|
me: async (_, {}, { authUser }) => {
|
package/dist/index.js
CHANGED
|
@@ -11,8 +11,14 @@ import AuthUtils from "./utils/AuthUtils.js";
|
|
|
11
11
|
import { jwtMiddleware } from "./middleware/jwtMiddleware.js";
|
|
12
12
|
import { rbacMiddleware } from "./middleware/rbacMiddleware.js";
|
|
13
13
|
import IdentityPermissions from "./permissions/IdentityPermissions.js";
|
|
14
|
+
import IdentityConfig from "./config/IdentityConfig.js";
|
|
14
15
|
import UnauthorizedError from "./errors/UnauthorizedError.js";
|
|
15
16
|
import BadCredentialsError from "./errors/BadCredentialsError.js";
|
|
17
|
+
import CreateUserIfNotExist from "./setup/CreateUserIfNotExist.js";
|
|
18
|
+
import CreateOrUpdateRole from "./setup/CreateOrUpdateRole.js";
|
|
19
|
+
import LoadPermissions from "./setup/LoadPermissions.js";
|
|
20
|
+
import LoadConfigFromEnv from "./setup/LoadConfigFromEnv.js";
|
|
21
|
+
import RecoveryUserPassword from "./setup/RecoveryUserPassword.js";
|
|
16
22
|
const graphqlMergeResult = await GraphqlMerge();
|
|
17
23
|
const identityTypeDefs = await graphqlMergeResult.typeDefs;
|
|
18
24
|
const identityResolvers = await graphqlMergeResult.resolvers;
|
|
@@ -29,6 +35,10 @@ UserRoutes, RoleRoutes, AuthUtils,
|
|
|
29
35
|
jwtMiddleware, rbacMiddleware,
|
|
30
36
|
//Permissions
|
|
31
37
|
IdentityPermissions,
|
|
38
|
+
//Config
|
|
39
|
+
IdentityConfig,
|
|
32
40
|
//Errors
|
|
33
|
-
UnauthorizedError, BadCredentialsError
|
|
41
|
+
UnauthorizedError, BadCredentialsError,
|
|
42
|
+
//Setup
|
|
43
|
+
LoadConfigFromEnv, LoadPermissions, CreateOrUpdateRole, CreateUserIfNotExist, RecoveryUserPassword };
|
|
34
44
|
/// <reference types="index.d.ts" />
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { DraxCache } from "@drax/common-back";
|
|
1
|
+
import { DraxCache, DraxConfig } from "@drax/common-back";
|
|
2
2
|
import RoleServiceFactory from "../factory/RoleServiceFactory.js";
|
|
3
3
|
import Rbac from "../rbac/Rbac.js";
|
|
4
|
-
|
|
4
|
+
import IdentityConfig from "../config/IdentityConfig.js";
|
|
5
|
+
const cacheTTL = DraxConfig.getOrLoad(IdentityConfig.RbacCacheTTL) ? parseInt(DraxConfig.getOrLoad(IdentityConfig.RbacCacheTTL)) : 10000;
|
|
5
6
|
const draxCache = new DraxCache(cacheTTL);
|
|
6
|
-
const roleService = RoleServiceFactory;
|
|
7
|
+
const roleService = RoleServiceFactory();
|
|
7
8
|
async function roleLoader(k) {
|
|
8
9
|
const role = await roleService.findById(k);
|
|
9
10
|
if (role) {
|
|
@@ -3,7 +3,7 @@ import RoleServiceFactory from "../factory/RoleServiceFactory.js";
|
|
|
3
3
|
import { IdentityPermissions } from "../permissions/IdentityPermissions.js";
|
|
4
4
|
import { PermissionService } from "../services/PermissionService.js";
|
|
5
5
|
import UnauthorizedError from "../errors/UnauthorizedError.js";
|
|
6
|
-
const roleService = RoleServiceFactory;
|
|
6
|
+
const roleService = RoleServiceFactory();
|
|
7
7
|
async function RoleRoutes(fastify, options) {
|
|
8
8
|
fastify.get('/api/permissions', async (request, reply) => {
|
|
9
9
|
try {
|
|
@@ -144,6 +144,10 @@ async function RoleRoutes(fastify, options) {
|
|
|
144
144
|
request.rbac.assertPermission(IdentityPermissions.UpdateRole);
|
|
145
145
|
const id = request.params.id;
|
|
146
146
|
const payload = request.body;
|
|
147
|
+
const currentRole = await roleService.findById(id);
|
|
148
|
+
if (currentRole.readonly) {
|
|
149
|
+
throw new ValidationError([{ field: 'name', reason: "role.readonly", value: payload.name }]);
|
|
150
|
+
}
|
|
147
151
|
let role = await roleService.update(id, payload);
|
|
148
152
|
return role;
|
|
149
153
|
}
|
|
@@ -3,7 +3,7 @@ import { ValidationError } from "@drax/common-back";
|
|
|
3
3
|
import { IdentityPermissions } from "../permissions/IdentityPermissions.js";
|
|
4
4
|
import UnauthorizedError from "../errors/UnauthorizedError.js";
|
|
5
5
|
import BadCredentialsError from "../errors/BadCredentialsError.js";
|
|
6
|
-
const userService = UserServiceFactory;
|
|
6
|
+
const userService = UserServiceFactory();
|
|
7
7
|
async function UserRoutes(fastify, options) {
|
|
8
8
|
fastify.post('/api/auth', async (request, reply) => {
|
|
9
9
|
try {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ZodErrorToValidationError } from "@drax/common-back";
|
|
2
2
|
import { roleSchema } from "../zod/RoleZod.js";
|
|
3
3
|
import { ZodError } from "zod";
|
|
4
4
|
import UnauthorizedError from "../errors/UnauthorizedError.js";
|
|
@@ -25,10 +25,6 @@ class RoleService {
|
|
|
25
25
|
try {
|
|
26
26
|
roleData.name = roleData?.name?.trim();
|
|
27
27
|
await roleSchema.parseAsync(roleData);
|
|
28
|
-
const currentRole = await this.findById(id);
|
|
29
|
-
if (currentRole.readonly) {
|
|
30
|
-
throw new ValidationError([{ field: 'name', reason: "role.readonly", value: roleData.name }]);
|
|
31
|
-
}
|
|
32
28
|
const role = await this._repository.update(id, roleData);
|
|
33
29
|
return role;
|
|
34
30
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import RoleServiceFactory from "../factory/RoleServiceFactory.js";
|
|
2
|
+
async function CreateOrUpdateRole(roleData) {
|
|
3
|
+
const roleService = RoleServiceFactory();
|
|
4
|
+
const role = await roleService.findByName(roleData.name);
|
|
5
|
+
if (role) {
|
|
6
|
+
const r = await roleService.update(role.id, roleData);
|
|
7
|
+
console.log("Role Updated. Name: " + roleData.name);
|
|
8
|
+
}
|
|
9
|
+
else {
|
|
10
|
+
const r = await roleService.create(roleData);
|
|
11
|
+
console.log("Role Created. Name: " + roleData.name);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
export default CreateOrUpdateRole;
|
|
15
|
+
export { CreateOrUpdateRole };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import RoleServiceFactory from "../factory/RoleServiceFactory.js";
|
|
2
|
+
import UserServiceFactory from "../factory/UserServiceFactory.js";
|
|
3
|
+
async function CreateUserIfNotExist(userData) {
|
|
4
|
+
const userService = UserServiceFactory();
|
|
5
|
+
const roleService = RoleServiceFactory();
|
|
6
|
+
const user = await userService.findByUsername(userData.username);
|
|
7
|
+
if (user) {
|
|
8
|
+
}
|
|
9
|
+
else {
|
|
10
|
+
const role = await roleService.findByName(userData.role);
|
|
11
|
+
userData.role = role.id;
|
|
12
|
+
const r = await userService.create(userData);
|
|
13
|
+
console.log("User Created. Username: " + userData.username);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
export default CreateUserIfNotExist;
|
|
17
|
+
export { CreateUserIfNotExist };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { DraxConfig } from "@drax/common-back";
|
|
2
|
+
import IdentityConfig from "../config/IdentityConfig.js";
|
|
3
|
+
function LoadConfigFromEnv() {
|
|
4
|
+
DraxConfig.set(IdentityConfig.DbEngine, process.env[IdentityConfig.DbEngine]);
|
|
5
|
+
DraxConfig.set(IdentityConfig.SqliteDbFile, process.env[IdentityConfig.SqliteDbFile]);
|
|
6
|
+
DraxConfig.set(IdentityConfig.MongoDbUri, process.env[IdentityConfig.MongoDbUri]);
|
|
7
|
+
DraxConfig.set(IdentityConfig.JwtSecret, process.env[IdentityConfig.JwtSecret]);
|
|
8
|
+
DraxConfig.set(IdentityConfig.JwtExpiration, process.env[IdentityConfig.JwtExpiration]);
|
|
9
|
+
DraxConfig.set(IdentityConfig.JwtIssuer, process.env[IdentityConfig.JwtIssuer]);
|
|
10
|
+
}
|
|
11
|
+
export default LoadConfigFromEnv;
|
|
12
|
+
export { LoadConfigFromEnv };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { PermissionService } from "../services/PermissionService.js";
|
|
2
|
+
function LoadPermissions(permissions) {
|
|
3
|
+
for (const permission of permissions) {
|
|
4
|
+
PermissionService.addPermission(permission);
|
|
5
|
+
}
|
|
6
|
+
}
|
|
7
|
+
export default LoadPermissions;
|
|
8
|
+
export { LoadPermissions };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import UserServiceFactory from "../factory/UserServiceFactory.js";
|
|
2
|
+
async function RecoveryUserPassword(username, password) {
|
|
3
|
+
const userService = UserServiceFactory();
|
|
4
|
+
const user = await userService.findByUsername(username);
|
|
5
|
+
const r = await userService.changeUserPassword(user.id, password);
|
|
6
|
+
console.log("User password recovered. Username: " + username);
|
|
7
|
+
}
|
|
8
|
+
export default RecoveryUserPassword;
|
|
9
|
+
export { RecoveryUserPassword };
|
package/dist/utils/AuthUtils.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import bcryptjs from "bcryptjs";
|
|
2
2
|
import jsonwebtoken from "jsonwebtoken";
|
|
3
|
+
import { DraxConfig } from "@drax/common-back";
|
|
4
|
+
import IdentityConfig from "../config/IdentityConfig.js";
|
|
3
5
|
class AuthUtils {
|
|
4
6
|
static verifyToken(token) {
|
|
5
|
-
const JWT_SECRET =
|
|
7
|
+
const JWT_SECRET = DraxConfig.getOrLoad(IdentityConfig.JwtSecret);
|
|
6
8
|
if (!JWT_SECRET) {
|
|
7
|
-
throw new Error("JWT_SECRET
|
|
9
|
+
throw new Error("DraxConfig.JWT_SECRET must be provided");
|
|
8
10
|
}
|
|
9
11
|
const options = {
|
|
10
12
|
algorithms: ['HS256'],
|
|
@@ -32,16 +34,18 @@ class AuthUtils {
|
|
|
32
34
|
}
|
|
33
35
|
static generateToken(userId, username, roleId, session) {
|
|
34
36
|
const payload = AuthUtils.tokenSignPayload(userId, username, roleId, session);
|
|
35
|
-
const JWT_SECRET =
|
|
37
|
+
const JWT_SECRET = DraxConfig.getOrLoad(IdentityConfig.JwtSecret);
|
|
36
38
|
if (!JWT_SECRET) {
|
|
37
39
|
throw new Error("JWT_SECRET ENV must be provided");
|
|
38
40
|
}
|
|
41
|
+
const JWT_EXPIRATION = DraxConfig.getOrLoad(IdentityConfig.JwtExpiration) || '1h';
|
|
42
|
+
const JWT_ISSUER = DraxConfig.getOrLoad(IdentityConfig.JwtIssuer) || 'DRAX';
|
|
39
43
|
const options = {
|
|
40
|
-
expiresIn:
|
|
44
|
+
expiresIn: JWT_EXPIRATION,
|
|
41
45
|
jwtid: userId,
|
|
42
46
|
algorithm: 'HS256',
|
|
43
47
|
audience: username,
|
|
44
|
-
issuer:
|
|
48
|
+
issuer: JWT_ISSUER
|
|
45
49
|
};
|
|
46
50
|
let token = jsonwebtoken.sign(payload, JWT_SECRET, options);
|
|
47
51
|
return token;
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import IdentityConfig from "../config/IdentityConfig.js";
|
|
2
|
+
import { DraxConfig } from "@drax/common-back";
|
|
1
3
|
var DbEngine;
|
|
2
4
|
(function (DbEngine) {
|
|
3
5
|
DbEngine["Sqlite"] = "sqlite";
|
|
@@ -5,23 +7,23 @@ var DbEngine;
|
|
|
5
7
|
})(DbEngine || (DbEngine = {}));
|
|
6
8
|
class DbSetupUtils {
|
|
7
9
|
static getDbEngine() {
|
|
8
|
-
if (!
|
|
9
|
-
throw new Error("
|
|
10
|
+
if (!DraxConfig.getOrLoad(IdentityConfig.DbEngine)) {
|
|
11
|
+
throw new Error("DraxConfig.DB_ENGINE is not defined");
|
|
10
12
|
}
|
|
11
|
-
const dbEngine =
|
|
13
|
+
const dbEngine = DraxConfig.getOrLoad(IdentityConfig.DbEngine);
|
|
12
14
|
if (!Object.values(DbEngine).includes(dbEngine)) {
|
|
13
|
-
throw new Error("
|
|
15
|
+
throw new Error("DraxConfig.DB_ENGINE must be one of " + Object.values(DbEngine).join(", "));
|
|
14
16
|
}
|
|
15
17
|
return dbEngine;
|
|
16
18
|
}
|
|
17
|
-
static
|
|
19
|
+
static getDbConfig() {
|
|
18
20
|
switch (DbSetupUtils.getDbEngine()) {
|
|
19
21
|
case DbEngine.Mongo:
|
|
20
|
-
return
|
|
22
|
+
return DraxConfig.getOrLoad(IdentityConfig.MongoDbUri);
|
|
21
23
|
case DbEngine.Sqlite:
|
|
22
|
-
return
|
|
24
|
+
return DraxConfig.getOrLoad(IdentityConfig.SqliteDbFile);
|
|
23
25
|
default:
|
|
24
|
-
throw new Error("
|
|
26
|
+
throw new Error("DraxConfig.DB_ENGINE must be one of " + Object.values(DbEngine).join(", "));
|
|
25
27
|
}
|
|
26
28
|
}
|
|
27
29
|
}
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "0.0.
|
|
6
|
+
"version": "0.0.14",
|
|
7
7
|
"description": "Identity module for user management, authentication and authorization.",
|
|
8
8
|
"main": "dist/index.js",
|
|
9
9
|
"types": "types/index.d.ts",
|
|
@@ -56,5 +56,5 @@
|
|
|
56
56
|
"debug": "0"
|
|
57
57
|
}
|
|
58
58
|
},
|
|
59
|
-
"gitHead": "
|
|
59
|
+
"gitHead": "ef0b07b3396f6eeb1f045ef430b4ec3856896f7e"
|
|
60
60
|
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
enum IdentityConfig {
|
|
2
|
+
|
|
3
|
+
DbEngine = "DB_ENGINE",
|
|
4
|
+
SqliteDbFile = "SQLITE_FILE",
|
|
5
|
+
MongoDbUri = "MONGO_URI",
|
|
6
|
+
|
|
7
|
+
JwtSecret = "JWT_SECRET",
|
|
8
|
+
JwtExpiration = "JWT_EXPIRATION",
|
|
9
|
+
JwtIssuer = "JWT_ISSUER",
|
|
10
|
+
|
|
11
|
+
RbacCacheTTL = "RBAC_CACHE_TTL",
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export default IdentityConfig;
|
|
17
|
+
export {IdentityConfig};
|
|
@@ -1,27 +1,33 @@
|
|
|
1
|
+
import {DraxConfig} from "@drax/common-back"
|
|
1
2
|
import RoleService from "../services/RoleService.js";
|
|
2
3
|
import RoleMongoRepository from "../repository/mongo/RoleMongoRepository.js";
|
|
3
4
|
import RoleSqliteRepository from "../repository/sqlite/RoleSqliteRepository.js";
|
|
4
5
|
import {DbSetupUtils, DbEngine} from "../utils/DbSetupUtils.js";
|
|
5
6
|
import type {IRoleRepository} from "../interfaces/IRoleRepository";
|
|
6
7
|
|
|
8
|
+
let roleService: RoleService
|
|
9
|
+
|
|
7
10
|
const RoleServiceFactory = () : RoleService => {
|
|
8
11
|
|
|
9
|
-
|
|
12
|
+
if(!roleService){
|
|
13
|
+
let roleRepository: IRoleRepository
|
|
14
|
+
|
|
15
|
+
switch (DbSetupUtils.getDbEngine()) {
|
|
16
|
+
case DbEngine.Mongo:
|
|
17
|
+
console.log("RoleServiceFactory DB ENGINE MONGODB")
|
|
18
|
+
roleRepository = new RoleMongoRepository()
|
|
19
|
+
break;
|
|
20
|
+
case DbEngine.Sqlite:
|
|
21
|
+
console.log("RoleServiceFactory DB ENGINE SQLITE")
|
|
22
|
+
roleRepository = new RoleSqliteRepository(DbSetupUtils.getDbConfig(), false)
|
|
23
|
+
roleRepository.table()
|
|
24
|
+
break;
|
|
25
|
+
}
|
|
10
26
|
|
|
11
|
-
|
|
12
|
-
case DbEngine.Mongo:
|
|
13
|
-
console.log("RoleServiceFactory DB ENGINE MONGODB")
|
|
14
|
-
roleRepository = new RoleMongoRepository()
|
|
15
|
-
break;
|
|
16
|
-
case DbEngine.Sqlite:
|
|
17
|
-
console.log("RoleServiceFactory DB ENGINE SQLITE")
|
|
18
|
-
roleRepository = new RoleSqliteRepository(process.env.SQLITE_DATABASE, false)
|
|
19
|
-
roleRepository.table()
|
|
20
|
-
break;
|
|
27
|
+
roleService = new RoleService(roleRepository)
|
|
21
28
|
}
|
|
22
29
|
|
|
23
|
-
const roleService = new RoleService(roleRepository)
|
|
24
30
|
return roleService
|
|
25
31
|
}
|
|
26
32
|
|
|
27
|
-
export default RoleServiceFactory
|
|
33
|
+
export default RoleServiceFactory
|
|
@@ -1,27 +1,31 @@
|
|
|
1
1
|
import UserMongoRepository from "../repository/mongo/UserMongoRepository.js";
|
|
2
2
|
import UserService from "../services/UserService.js";
|
|
3
3
|
import UserSqliteRepository from "../repository/sqlite/UserSqliteRepository.js";
|
|
4
|
-
import process from "node:process";
|
|
5
4
|
import {DbEngine, DbSetupUtils} from "../utils/DbSetupUtils.js";
|
|
6
5
|
import {IUserRepository} from "../interfaces/IUserRepository";
|
|
7
6
|
|
|
7
|
+
let userService: UserService
|
|
8
|
+
|
|
8
9
|
const UserServiceFactory = () : UserService => {
|
|
9
10
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
11
|
+
if(!userService){
|
|
12
|
+
let userRepository: IUserRepository
|
|
13
|
+
switch (DbSetupUtils.getDbEngine()) {
|
|
14
|
+
case DbEngine.Mongo:
|
|
15
|
+
console.log("UserServiceFactory DB ENGINE MONGODB")
|
|
16
|
+
userRepository = new UserMongoRepository()
|
|
17
|
+
break;
|
|
18
|
+
case DbEngine.Sqlite:
|
|
19
|
+
console.log("UserServiceFactory DB ENGINE SQLITE")
|
|
20
|
+
userRepository = new UserSqliteRepository(DbSetupUtils.getDbConfig(),false)
|
|
21
|
+
userRepository.table()
|
|
22
|
+
break;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
userService = new UserService(userRepository)
|
|
21
26
|
}
|
|
22
27
|
|
|
23
|
-
const userService = new UserService(userRepository)
|
|
24
28
|
return userService
|
|
25
29
|
}
|
|
26
30
|
|
|
27
|
-
export default UserServiceFactory
|
|
31
|
+
export default UserServiceFactory
|
|
@@ -5,7 +5,7 @@ import {GraphQLError} from "graphql";
|
|
|
5
5
|
import {PermissionService} from "../../services/PermissionService.js";
|
|
6
6
|
import UnauthorizedError from "../../errors/UnauthorizedError.js";
|
|
7
7
|
|
|
8
|
-
const roleService = RoleServiceFactory
|
|
8
|
+
const roleService = RoleServiceFactory()
|
|
9
9
|
export default {
|
|
10
10
|
Query: {
|
|
11
11
|
findRoleById: async (_, {id}, {rbac}) => {
|
|
@@ -85,6 +85,12 @@ export default {
|
|
|
85
85
|
updateRole: async (_, {id, input}, {rbac}) => {
|
|
86
86
|
try {
|
|
87
87
|
rbac.assertPermission(IdentityPermissions.UpdateRole)
|
|
88
|
+
|
|
89
|
+
const currentRole = await roleService.findById(id)
|
|
90
|
+
if(currentRole.readonly){
|
|
91
|
+
throw new ValidationError([{field:'name', reason:"role.readonly", value:input.name}])
|
|
92
|
+
}
|
|
93
|
+
|
|
88
94
|
return await roleService.update(id, input)
|
|
89
95
|
} catch (e) {
|
|
90
96
|
console.error("updateRole",e)
|
|
@@ -5,7 +5,7 @@ import {IdentityPermissions} from "../../permissions/IdentityPermissions.js";
|
|
|
5
5
|
import UnauthorizedError from "../../errors/UnauthorizedError.js";
|
|
6
6
|
import BadCredentialsError from "../../errors/BadCredentialsError.js";
|
|
7
7
|
|
|
8
|
-
const userService = UserServiceFactory
|
|
8
|
+
const userService = UserServiceFactory()
|
|
9
9
|
|
|
10
10
|
export default {
|
|
11
11
|
Query: {
|
package/src/index.ts
CHANGED
|
@@ -12,9 +12,16 @@ import {jwtMiddleware} from "./middleware/jwtMiddleware.js";
|
|
|
12
12
|
import {rbacMiddleware} from "./middleware/rbacMiddleware.js";
|
|
13
13
|
|
|
14
14
|
import IdentityPermissions from "./permissions/IdentityPermissions.js";
|
|
15
|
+
import IdentityConfig from "./config/IdentityConfig.js";
|
|
15
16
|
import UnauthorizedError from "./errors/UnauthorizedError.js";
|
|
16
17
|
import BadCredentialsError from "./errors/BadCredentialsError.js";
|
|
17
18
|
|
|
19
|
+
import CreateUserIfNotExist from "./setup/CreateUserIfNotExist.js";
|
|
20
|
+
import CreateOrUpdateRole from "./setup/CreateOrUpdateRole.js";
|
|
21
|
+
import LoadPermissions from "./setup/LoadPermissions.js";
|
|
22
|
+
import LoadConfigFromEnv from "./setup/LoadConfigFromEnv.js";
|
|
23
|
+
import RecoveryUserPassword from "./setup/RecoveryUserPassword.js";
|
|
24
|
+
|
|
18
25
|
import type {IJwtUser} from "./interfaces/IJwtUser";
|
|
19
26
|
import type {IRole, IRoleBase} from "./interfaces/IRole";
|
|
20
27
|
import type {IUser, IUserCreate, IUserUpdate} from "./interfaces/IUser";
|
|
@@ -62,9 +69,19 @@ export {
|
|
|
62
69
|
//Permissions
|
|
63
70
|
IdentityPermissions,
|
|
64
71
|
|
|
72
|
+
//Config
|
|
73
|
+
IdentityConfig,
|
|
74
|
+
|
|
65
75
|
//Errors
|
|
66
76
|
UnauthorizedError,
|
|
67
|
-
BadCredentialsError
|
|
77
|
+
BadCredentialsError,
|
|
78
|
+
|
|
79
|
+
//Setup
|
|
80
|
+
LoadConfigFromEnv,
|
|
81
|
+
LoadPermissions,
|
|
82
|
+
CreateOrUpdateRole,
|
|
83
|
+
CreateUserIfNotExist,
|
|
84
|
+
RecoveryUserPassword
|
|
68
85
|
}
|
|
69
86
|
|
|
70
87
|
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import type {IJwtUser} from "../interfaces/IJwtUser";
|
|
2
2
|
import type {IRole, IRoleBase} from "../interfaces/IRole";
|
|
3
|
-
import {DraxCache} from "@drax/common-back";
|
|
3
|
+
import {DraxCache, DraxConfig} from "@drax/common-back";
|
|
4
4
|
import RoleServiceFactory from "../factory/RoleServiceFactory.js";
|
|
5
5
|
import Rbac from "../rbac/Rbac.js";
|
|
6
|
+
import IdentityConfig from "../config/IdentityConfig.js";
|
|
6
7
|
|
|
7
|
-
const cacheTTL =
|
|
8
|
+
const cacheTTL = DraxConfig.getOrLoad(IdentityConfig.RbacCacheTTL) ? parseInt(DraxConfig.getOrLoad(IdentityConfig.RbacCacheTTL)) : 10000;
|
|
8
9
|
const draxCache = new DraxCache<IRoleBase>(cacheTTL);
|
|
9
|
-
const roleService = RoleServiceFactory
|
|
10
|
+
const roleService = RoleServiceFactory()
|
|
10
11
|
|
|
11
12
|
async function roleLoader(k):Promise<IRoleBase | null> {
|
|
12
13
|
const role: IRole = await roleService.findById(k)
|
package/src/routes/RoleRoutes.ts
CHANGED
|
@@ -5,7 +5,7 @@ import {IdentityPermissions} from "../permissions/IdentityPermissions.js";
|
|
|
5
5
|
import {PermissionService} from "../services/PermissionService.js";
|
|
6
6
|
import UnauthorizedError from "../errors/UnauthorizedError.js";
|
|
7
7
|
|
|
8
|
-
const roleService = RoleServiceFactory
|
|
8
|
+
const roleService = RoleServiceFactory()
|
|
9
9
|
|
|
10
10
|
async function RoleRoutes(fastify, options) {
|
|
11
11
|
|
|
@@ -138,6 +138,12 @@ async function RoleRoutes(fastify, options) {
|
|
|
138
138
|
request.rbac.assertPermission(IdentityPermissions.UpdateRole)
|
|
139
139
|
const id = request.params.id
|
|
140
140
|
const payload = request.body
|
|
141
|
+
|
|
142
|
+
const currentRole = await roleService.findById(id)
|
|
143
|
+
if(currentRole.readonly){
|
|
144
|
+
throw new ValidationError([{field:'name', reason:"role.readonly", value:payload.name}])
|
|
145
|
+
}
|
|
146
|
+
|
|
141
147
|
let role = await roleService.update(id, payload)
|
|
142
148
|
return role
|
|
143
149
|
} catch (e) {
|
package/src/routes/UserRoutes.ts
CHANGED
|
@@ -5,7 +5,7 @@ import {IdentityPermissions} from "../permissions/IdentityPermissions.js";
|
|
|
5
5
|
import UnauthorizedError from "../errors/UnauthorizedError.js";
|
|
6
6
|
import BadCredentialsError from "../errors/BadCredentialsError.js";
|
|
7
7
|
|
|
8
|
-
const userService = UserServiceFactory
|
|
8
|
+
const userService = UserServiceFactory()
|
|
9
9
|
|
|
10
10
|
async function UserRoutes(fastify, options) {
|
|
11
11
|
fastify.post('/api/auth', async (request, reply) => {
|
|
@@ -32,10 +32,6 @@ class RoleService {
|
|
|
32
32
|
try {
|
|
33
33
|
roleData.name = roleData?.name?.trim()
|
|
34
34
|
await roleSchema.parseAsync(roleData)
|
|
35
|
-
const currentRole = await this.findById(id)
|
|
36
|
-
if(currentRole.readonly){
|
|
37
|
-
throw new ValidationError([{field:'name', reason:"role.readonly", value:roleData.name}])
|
|
38
|
-
}
|
|
39
35
|
const role = await this._repository.update(id, roleData)
|
|
40
36
|
return role
|
|
41
37
|
} catch (e) {
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type {IRole} from "../interfaces/IRole"
|
|
2
|
+
import RoleServiceFactory from "../factory/RoleServiceFactory.js"
|
|
3
|
+
|
|
4
|
+
async function CreateOrUpdateRole(roleData: IRole) {
|
|
5
|
+
const roleService = RoleServiceFactory()
|
|
6
|
+
const role = await roleService.findByName(roleData.name)
|
|
7
|
+
if(role){
|
|
8
|
+
const r = await roleService.update(role.id, roleData)
|
|
9
|
+
console.log("Role Updated. Name: "+ roleData.name)
|
|
10
|
+
}else{
|
|
11
|
+
const r = await roleService.create(roleData)
|
|
12
|
+
console.log("Role Created. Name: "+ roleData.name)
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export default CreateOrUpdateRole
|
|
17
|
+
export {
|
|
18
|
+
CreateOrUpdateRole
|
|
19
|
+
}
|