@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.
Files changed (106) hide show
  1. package/dist/factory/TenantServiceFactory.js +24 -0
  2. package/dist/factory/UserServiceFactory.js +1 -1
  3. package/dist/graphql/resolvers/role.resolvers.js +19 -2
  4. package/dist/graphql/resolvers/tenant.resolvers.js +121 -0
  5. package/dist/graphql/resolvers/user.resolvers.js +14 -3
  6. package/dist/graphql/types/tenant.graphql +28 -0
  7. package/dist/graphql/types/user.graphql +3 -0
  8. package/dist/index.js +6 -3
  9. package/dist/interfaces/ITenant.js +1 -0
  10. package/dist/interfaces/ITenantRepository.js +1 -0
  11. package/dist/middleware/rbacMiddleware.js +2 -5
  12. package/dist/models/TenantModel.js +18 -0
  13. package/dist/models/UserModel.js +5 -0
  14. package/dist/permissions/IdentityPermissions.js +5 -0
  15. package/dist/rbac/Rbac.js +6 -0
  16. package/dist/repository/mongo/RoleMongoRepository.js +7 -6
  17. package/dist/repository/mongo/TenantMongoRepository.js +45 -0
  18. package/dist/repository/mongo/UserMongoRepository.js +19 -6
  19. package/dist/repository/sqlite/RoleSqliteRepository.js +24 -5
  20. package/dist/repository/sqlite/TenantSqliteRepository.js +106 -0
  21. package/dist/repository/sqlite/UserSqliteRepository.js +43 -37
  22. package/dist/routes/RoleRoutes.js +17 -2
  23. package/dist/routes/TenantRoutes.js +183 -0
  24. package/dist/routes/UserRoutes.js +14 -2
  25. package/dist/services/RoleService.js +0 -5
  26. package/dist/services/TenantService.js +59 -0
  27. package/dist/services/UserService.js +1 -1
  28. package/dist/utils/AuthUtils.js +4 -3
  29. package/dist/zod/TenantZod.js +8 -0
  30. package/package.json +2 -2
  31. package/src/factory/TenantServiceFactory.ts +33 -0
  32. package/src/factory/UserServiceFactory.ts +1 -1
  33. package/src/graphql/resolvers/role.resolvers.ts +21 -3
  34. package/src/graphql/resolvers/tenant.resolvers.ts +119 -0
  35. package/src/graphql/resolvers/user.resolvers.ts +14 -6
  36. package/src/graphql/types/tenant.graphql +28 -0
  37. package/src/graphql/types/user.graphql +3 -0
  38. package/src/index.ts +6 -0
  39. package/src/interfaces/ITenant.ts +9 -0
  40. package/src/interfaces/ITenantRepository.ts +15 -0
  41. package/src/interfaces/IUser.ts +4 -1
  42. package/src/middleware/rbacMiddleware.ts +6 -8
  43. package/src/models/TenantModel.ts +32 -0
  44. package/src/models/UserModel.ts +5 -0
  45. package/src/permissions/IdentityPermissions.ts +7 -0
  46. package/src/rbac/Rbac.ts +11 -3
  47. package/src/repository/mongo/RoleMongoRepository.ts +7 -6
  48. package/src/repository/mongo/TenantMongoRepository.ts +62 -0
  49. package/src/repository/mongo/UserMongoRepository.ts +20 -6
  50. package/src/repository/sqlite/RoleSqliteRepository.ts +27 -6
  51. package/src/repository/sqlite/TenantSqliteRepository.ts +139 -0
  52. package/src/repository/sqlite/UserSqliteRepository.ts +52 -40
  53. package/src/routes/RoleRoutes.ts +17 -3
  54. package/src/routes/TenantRoutes.ts +178 -0
  55. package/src/routes/UserRoutes.ts +14 -4
  56. package/src/services/RoleService.ts +1 -4
  57. package/src/services/TenantService.ts +74 -0
  58. package/src/services/UserService.ts +1 -1
  59. package/src/utils/AuthUtils.ts +4 -3
  60. package/src/zod/TenantZod.ts +14 -0
  61. package/tsconfig.tsbuildinfo +1 -1
  62. package/types/factory/TenantServiceFactory.d.ts +4 -0
  63. package/types/factory/TenantServiceFactory.d.ts.map +1 -0
  64. package/types/graphql/resolvers/role.resolvers.d.ts.map +1 -1
  65. package/types/graphql/resolvers/tenant.resolvers.d.ts +44 -0
  66. package/types/graphql/resolvers/tenant.resolvers.d.ts.map +1 -0
  67. package/types/graphql/resolvers/user.resolvers.d.ts +2 -1
  68. package/types/graphql/resolvers/user.resolvers.d.ts.map +1 -1
  69. package/types/index.d.ts +4 -1
  70. package/types/index.d.ts.map +1 -1
  71. package/types/interfaces/ITenant.d.ts +7 -0
  72. package/types/interfaces/ITenant.d.ts.map +1 -0
  73. package/types/interfaces/ITenantRepository.d.ts +15 -0
  74. package/types/interfaces/ITenantRepository.d.ts.map +1 -0
  75. package/types/interfaces/IUser.d.ts +4 -0
  76. package/types/interfaces/IUser.d.ts.map +1 -1
  77. package/types/middleware/rbacMiddleware.d.ts.map +1 -1
  78. package/types/models/TenantModel.d.ts +16 -0
  79. package/types/models/TenantModel.d.ts.map +1 -0
  80. package/types/models/UserModel.d.ts.map +1 -1
  81. package/types/permissions/IdentityPermissions.d.ts +6 -1
  82. package/types/permissions/IdentityPermissions.d.ts.map +1 -1
  83. package/types/rbac/Rbac.d.ts +4 -2
  84. package/types/rbac/Rbac.d.ts.map +1 -1
  85. package/types/repository/mongo/RoleMongoRepository.d.ts.map +1 -1
  86. package/types/repository/mongo/TenantMongoRepository.d.ts +15 -0
  87. package/types/repository/mongo/TenantMongoRepository.d.ts.map +1 -0
  88. package/types/repository/mongo/UserMongoRepository.d.ts +2 -2
  89. package/types/repository/mongo/UserMongoRepository.d.ts.map +1 -1
  90. package/types/repository/sqlite/RoleSqliteRepository.d.ts +2 -0
  91. package/types/repository/sqlite/RoleSqliteRepository.d.ts.map +1 -1
  92. package/types/repository/sqlite/TenantSqliteRepository.d.ts +19 -0
  93. package/types/repository/sqlite/TenantSqliteRepository.d.ts.map +1 -0
  94. package/types/repository/sqlite/UserSqliteRepository.d.ts +4 -2
  95. package/types/repository/sqlite/UserSqliteRepository.d.ts.map +1 -1
  96. package/types/routes/RoleRoutes.d.ts.map +1 -1
  97. package/types/routes/TenantRoutes.d.ts +4 -0
  98. package/types/routes/TenantRoutes.d.ts.map +1 -0
  99. package/types/routes/UserRoutes.d.ts.map +1 -1
  100. package/types/services/RoleService.d.ts.map +1 -1
  101. package/types/services/TenantService.d.ts +16 -0
  102. package/types/services/TenantService.d.ts.map +1 -0
  103. package/types/utils/AuthUtils.d.ts +3 -2
  104. package/types/utils/AuthUtils.d.ts.map +1 -1
  105. package/types/zod/TenantZod.d.ts +10 -0
  106. package/types/zod/TenantZod.d.ts.map +1 -0
@@ -15,6 +15,7 @@ const roleTableSQL = `
15
15
  class RoleSqliteRepository {
16
16
  constructor(DATABASE, verbose = false) {
17
17
  this.db = new sqlite(DATABASE, { verbose: verbose ? console.log : null });
18
+ this.table();
18
19
  }
19
20
  table() {
20
21
  this.db.exec(roleTableSQL);
@@ -55,7 +56,7 @@ class RoleSqliteRepository {
55
56
  async findById(id) {
56
57
  const role = this.db.prepare('SELECT * FROM roles WHERE id = ?').get(id);
57
58
  if (role) {
58
- role.permissions = role.permissions ? role.permissions.split(",") : [];
59
+ await this.populateRole(role);
59
60
  return role;
60
61
  }
61
62
  return undefined;
@@ -63,7 +64,7 @@ class RoleSqliteRepository {
63
64
  async findByName(name) {
64
65
  const role = this.db.prepare('SELECT * FROM roles WHERE name = ?').get(name);
65
66
  if (role) {
66
- role.permissions = role.permissions ? role.permissions.split(",") : [];
67
+ await this.populateRole(role);
67
68
  return role;
68
69
  }
69
70
  return undefined;
@@ -97,20 +98,20 @@ class RoleSqliteRepository {
97
98
  async fetchAll() {
98
99
  const roles = this.db.prepare('SELECT * FROM roles').all();
99
100
  for (const role of roles) {
100
- role.permissions = role.permissions ? role.permissions.split(",") : [];
101
+ await this.populateRole(role);
101
102
  }
102
103
  return roles;
103
104
  }
104
105
  async paginate(page = 1, limit = 5, search = "") {
105
106
  const offset = page > 1 ? (page - 1) * limit : 0;
106
- let where;
107
+ let where = "";
107
108
  if (search) {
108
109
  where = ` WHERE name LIKE '%${search}%'`;
109
110
  }
110
111
  const rCount = this.db.prepare('SELECT COUNT(*) as count FROM roles' + where).get();
111
112
  const roles = this.db.prepare('SELECT * FROM roles LIMIT ? OFFSET ?' + where).all([limit, offset]);
112
113
  for (const role of roles) {
113
- role.permissions = role.permissions ? role.permissions.split(",") : [];
114
+ await this.populateRole(role);
114
115
  }
115
116
  return {
116
117
  page: page,
@@ -119,5 +120,23 @@ class RoleSqliteRepository {
119
120
  items: roles
120
121
  };
121
122
  }
123
+ async findWithoutPopulateById(id) {
124
+ const role = this.db.prepare('SELECT * FROM roles WHERE id = ?').get(id);
125
+ if (role) {
126
+ return role;
127
+ }
128
+ return undefined;
129
+ }
130
+ async populateRole(role) {
131
+ role.permissions = role.permissions ? role.permissions.split(",") : [];
132
+ role.childRoles = role.childRoles ? role.childRoles.split(",") : [];
133
+ const childRoles = [];
134
+ for (const childRoleId of role.childRoles) {
135
+ const childRole = await this.findWithoutPopulateById(childRoleId);
136
+ childRoles.push(childRole);
137
+ }
138
+ role.childRoles = childRoles;
139
+ return role;
140
+ }
122
141
  }
123
142
  export default RoleSqliteRepository;
@@ -0,0 +1,106 @@
1
+ import sqlite from "better-sqlite3";
2
+ import { randomUUID } from "node:crypto";
3
+ import { SqliteErrorToValidationError } from "@drax/common-back";
4
+ const tenantTableSQL = `
5
+ CREATE TABLE IF NOT EXISTS tenants
6
+ (
7
+ id TEXT PRIMARY KEY,
8
+ name TEXT
9
+ );
10
+ `;
11
+ class TenantSqliteRepository {
12
+ constructor(DATABASE, verbose = false) {
13
+ this.db = new sqlite(DATABASE, { verbose: verbose ? console.log : null });
14
+ this.table();
15
+ }
16
+ table() {
17
+ this.db.exec(tenantTableSQL);
18
+ }
19
+ async create(tenantData) {
20
+ try {
21
+ if (!tenantData.id) {
22
+ tenantData.id = randomUUID();
23
+ }
24
+ const fields = Object.keys(tenantData)
25
+ .map(field => `${field}`)
26
+ .join(', ');
27
+ const values = Object.keys(tenantData)
28
+ .map(field => `@${field}`)
29
+ .join(', ');
30
+ const stmt = this.db.prepare(`INSERT INTO tenants (${fields}) VALUES (${values})`);
31
+ stmt.run(tenantData);
32
+ return this.findById(tenantData.id);
33
+ }
34
+ catch (e) {
35
+ console.log(e);
36
+ throw SqliteErrorToValidationError(e, tenantData);
37
+ }
38
+ }
39
+ async findById(id) {
40
+ const tenant = this.db.prepare('SELECT * FROM tenants WHERE id = ?').get(id);
41
+ if (tenant) {
42
+ tenant.permissions = tenant.permissions ? tenant.permissions.split(",") : [];
43
+ return tenant;
44
+ }
45
+ return undefined;
46
+ }
47
+ async findByName(name) {
48
+ const tenant = this.db.prepare('SELECT * FROM tenants WHERE name = ?').get(name);
49
+ if (tenant) {
50
+ tenant.permissions = tenant.permissions ? tenant.permissions.split(",") : [];
51
+ return tenant;
52
+ }
53
+ return undefined;
54
+ }
55
+ async update(id, tenantData) {
56
+ try {
57
+ const setClauses = Object.keys(tenantData)
58
+ .map(field => `${field} = @${field}`)
59
+ .join(', ');
60
+ tenantData.id = id;
61
+ const stmt = this.db.prepare(`UPDATE tenants SET ${setClauses} WHERE id = @id `);
62
+ stmt.run(tenantData);
63
+ return this.findById(id);
64
+ }
65
+ catch (e) {
66
+ console.log(e);
67
+ throw SqliteErrorToValidationError(e, tenantData);
68
+ }
69
+ }
70
+ async delete(id) {
71
+ const stmt = this.db.prepare('DELETE FROM tenants WHERE id = ?');
72
+ stmt.run(id);
73
+ return true;
74
+ }
75
+ async deleteAll() {
76
+ const stmt = this.db.prepare('DELETE FROM tenants');
77
+ stmt.run();
78
+ return true;
79
+ }
80
+ async fetchAll() {
81
+ const tenants = this.db.prepare('SELECT * FROM tenants').all();
82
+ for (const tenant of tenants) {
83
+ tenant.permissions = tenant.permissions ? tenant.permissions.split(",") : [];
84
+ }
85
+ return tenants;
86
+ }
87
+ async paginate(page = 1, limit = 5, search = "") {
88
+ const offset = page > 1 ? (page - 1) * limit : 0;
89
+ let where = "";
90
+ if (search) {
91
+ where = ` WHERE name LIKE '%${search}%'`;
92
+ }
93
+ const rCount = this.db.prepare('SELECT COUNT(*) as count FROM tenants' + where).get();
94
+ const tenants = this.db.prepare('SELECT * FROM tenants LIMIT ? OFFSET ?' + where).all([limit, offset]);
95
+ for (const tenant of tenants) {
96
+ tenant.permissions = tenant.permissions ? tenant.permissions.split(",") : [];
97
+ }
98
+ return {
99
+ page: page,
100
+ limit: limit,
101
+ total: rCount.count,
102
+ items: tenants
103
+ };
104
+ }
105
+ }
106
+ export default TenantSqliteRepository;
@@ -2,39 +2,29 @@ import sqlite from "better-sqlite3";
2
2
  import { randomUUID } from "node:crypto";
3
3
  import { SqliteErrorToValidationError, ValidationError } from "@drax/common-back";
4
4
  import RoleSqliteRepository from "./RoleSqliteRepository.js";
5
+ import TenantSqliteRepository from "./TenantSqliteRepository.js";
5
6
  const userTableSQL = `
6
7
  CREATE TABLE IF NOT EXISTS users
7
8
  (
8
- id
9
- TEXT
10
- PRIMARY
11
- KEY,
12
- name
13
- TEXT,
14
- username
15
- TEXT
16
- UNIQUE,
17
- active
18
- INTEGER,
19
- password
20
- TEXT,
21
- email
22
- TEXT
23
- UNIQUE,
24
- phone
25
- TEXT,
26
- role
27
- TEXT,
28
- groups
29
- TEXT,
30
- avatar
31
- TEXT
9
+ id TEXT PRIMARY KEY,
10
+ name TEXT,
11
+ username TEXT UNIQUE,
12
+ active INTEGER,
13
+ password TEXT,
14
+ email TEXT UNIQUE,
15
+ phone TEXT,
16
+ role TEXT,
17
+ tenant TEXT,
18
+ groups TEXT,
19
+ avatar TEXT
32
20
  );
33
21
  `;
34
22
  class UserSqliteRepository {
35
23
  constructor(DATABASE, verbose = false) {
36
24
  this.db = new sqlite(DATABASE, { verbose: verbose ? console.log : null });
37
25
  this.roleRepository = new RoleSqliteRepository(DATABASE, verbose);
26
+ this.tenantRepository = new TenantSqliteRepository(DATABASE, verbose);
27
+ this.table();
38
28
  }
39
29
  table() {
40
30
  this.db.exec(userTableSQL);
@@ -60,9 +50,6 @@ class UserSqliteRepository {
60
50
  const values = Object.keys(userData)
61
51
  .map(field => `@${field}`)
62
52
  .join(', ');
63
- /*console.log("fields", fields)
64
- console.log("values",values)
65
- console.log("userData",userData)*/
66
53
  const stmt = this.db.prepare(`INSERT INTO users (${fields})
67
54
  VALUES (${values})`);
68
55
  stmt.run(userData);
@@ -108,6 +95,7 @@ class UserSqliteRepository {
108
95
  return null;
109
96
  }
110
97
  user.role = await this.findRoleById(user.role);
98
+ user.tenant = await this.findTenantById(user.tenant);
111
99
  return user;
112
100
  }
113
101
  async findByUsername(username) {
@@ -116,24 +104,39 @@ class UserSqliteRepository {
116
104
  return null;
117
105
  }
118
106
  user.role = await this.findRoleById(user.role);
107
+ user.tenant = await this.findTenantById(user.tenant);
119
108
  return user;
120
109
  }
121
- async paginate(page = 1, limit = 5, search) {
110
+ async paginate(page = 1, limit = 5, search = "", filters = []) {
122
111
  const offset = page > 1 ? (page - 1) * limit : 0;
123
- let where;
112
+ let where = "";
124
113
  if (search) {
125
- where = ` WHERE name LIKE '%${search}%' OR username LIKE '%${search}%'`;
114
+ where = ` WHERE (name LIKE '%${search}%' OR username LIKE '%${search}%') `;
126
115
  }
116
+ let whereFilters = [];
117
+ if (filters && filters.length > 0) {
118
+ where = where ? ` AND ` : ` WHERE `;
119
+ for (const filter of filters) {
120
+ if (filter.operator === '$eq') {
121
+ whereFilters.push(` ${filter.field} = '${filter.value}' `);
122
+ }
123
+ if (filter.operator === '$ne') {
124
+ whereFilters.push(` ${filter.field} != '${filter.value}' `);
125
+ }
126
+ if (filter.operator === '$in') {
127
+ whereFilters.push(` ${filter.field} LIKE '%${filter.value}%' `);
128
+ }
129
+ }
130
+ where += whereFilters.join(" AND ");
131
+ }
132
+ // console.log("paginate where ", where, "search", search, "filters", filters, "whereFilters", whereFilters)
127
133
  const rCount = this.db.prepare('SELECT COUNT(*) as count FROM users' + where).get();
128
- const users = this.db.prepare('SELECT * FROM users LIMIT ? OFFSET ?' + where).all([limit, offset]);
134
+ const users = this.db.prepare('SELECT * FROM users' + where + ' LIMIT ? OFFSET ?').all([limit, offset]);
129
135
  for (const user of users) {
130
136
  let role = await this.findRoleById(user.role);
131
- if (role) {
132
- user.role = role;
133
- }
134
- else {
135
- user.role = null;
136
- }
137
+ user.role = role ? role : null;
138
+ let tenant = await this.findTenantById(user.tenant);
139
+ user.tenant = tenant ? tenant : null;
137
140
  user.active = user.active === 1;
138
141
  }
139
142
  return {
@@ -146,6 +149,9 @@ class UserSqliteRepository {
146
149
  async findRoleById(id) {
147
150
  return await this.roleRepository.findById(id);
148
151
  }
152
+ async findTenantById(id) {
153
+ return await this.tenantRepository.findById(id);
154
+ }
149
155
  async changePassword(id, password) {
150
156
  const stmt = this.db.prepare(`UPDATE users
151
157
  SET password = @password
@@ -3,7 +3,6 @@ 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();
7
6
  async function RoleRoutes(fastify, options) {
8
7
  fastify.get('/api/permissions', async (request, reply) => {
9
8
  try {
@@ -27,6 +26,7 @@ async function RoleRoutes(fastify, options) {
27
26
  try {
28
27
  request.rbac.assertPermission(IdentityPermissions.ViewRole);
29
28
  const id = request.params.id;
29
+ const roleService = RoleServiceFactory();
30
30
  let role = await roleService.findById(id);
31
31
  return role;
32
32
  }
@@ -50,6 +50,7 @@ async function RoleRoutes(fastify, options) {
50
50
  try {
51
51
  request.rbac.assertPermission(IdentityPermissions.ViewRole);
52
52
  const name = request.params.name;
53
+ const roleService = RoleServiceFactory();
53
54
  let role = await roleService.findByName(name);
54
55
  return role;
55
56
  }
@@ -72,8 +73,14 @@ async function RoleRoutes(fastify, options) {
72
73
  fastify.get('/api/roles/all', async (request, reply) => {
73
74
  try {
74
75
  request.rbac.assertPermission(IdentityPermissions.ViewRole);
76
+ const roleService = RoleServiceFactory();
75
77
  let roles = await roleService.fetchAll();
76
- return roles;
78
+ if (request.rbac.getRole?.childRoles?.length > 0) {
79
+ return roles.filter(role => request.rbac.getRole.childRoles.some(childRole => childRole.id === role.id));
80
+ }
81
+ else {
82
+ return roles;
83
+ }
77
84
  }
78
85
  catch (e) {
79
86
  console.error(e);
@@ -97,6 +104,7 @@ async function RoleRoutes(fastify, options) {
97
104
  const page = request.query.page;
98
105
  const limit = request.query.limit;
99
106
  const search = request.query.search;
107
+ const roleService = RoleServiceFactory();
100
108
  let paginateResult = await roleService.paginate(page, limit, search);
101
109
  return paginateResult;
102
110
  }
@@ -120,6 +128,7 @@ async function RoleRoutes(fastify, options) {
120
128
  try {
121
129
  request.rbac.assertPermission(IdentityPermissions.CreateRole);
122
130
  const payload = request.body;
131
+ const roleService = RoleServiceFactory();
123
132
  let role = await roleService.create(payload);
124
133
  return role;
125
134
  }
@@ -144,6 +153,7 @@ async function RoleRoutes(fastify, options) {
144
153
  request.rbac.assertPermission(IdentityPermissions.UpdateRole);
145
154
  const id = request.params.id;
146
155
  const payload = request.body;
156
+ const roleService = RoleServiceFactory();
147
157
  const currentRole = await roleService.findById(id);
148
158
  if (currentRole.readonly) {
149
159
  throw new ValidationError([{ field: 'name', reason: "role.readonly", value: payload.name }]);
@@ -171,6 +181,11 @@ async function RoleRoutes(fastify, options) {
171
181
  try {
172
182
  request.rbac.assertPermission(IdentityPermissions.DeleteRole);
173
183
  const id = request.params.id;
184
+ const roleService = RoleServiceFactory();
185
+ const currentRole = await roleService.findById(id);
186
+ if (currentRole.readonly) {
187
+ throw new UnauthorizedError();
188
+ }
174
189
  let r = await roleService.delete(id);
175
190
  return r;
176
191
  }
@@ -0,0 +1,183 @@
1
+ import { ValidationError } from "@drax/common-back";
2
+ import TenantServiceFactory from "../factory/TenantServiceFactory.js";
3
+ import { IdentityPermissions } from "../permissions/IdentityPermissions.js";
4
+ import UnauthorizedError from "../errors/UnauthorizedError.js";
5
+ async function TenantRoutes(fastify, options) {
6
+ fastify.get('/api/tenants/:id', async (request, reply) => {
7
+ try {
8
+ request.rbac.assertPermission(IdentityPermissions.ViewTenant);
9
+ const id = request.params.id;
10
+ const tenantService = TenantServiceFactory();
11
+ let tenant = await tenantService.findById(id);
12
+ return tenant;
13
+ }
14
+ catch (e) {
15
+ console.error(e);
16
+ if (e instanceof ValidationError) {
17
+ reply.statusCode = e.statusCode;
18
+ reply.send({ error: e.message, inputErrors: e.errors });
19
+ }
20
+ else if (e instanceof UnauthorizedError) {
21
+ reply.statusCode = e.statusCode;
22
+ reply.send({ error: e.message });
23
+ }
24
+ else {
25
+ reply.statusCode = 500;
26
+ reply.send({ error: 'INTERNAL_SERVER_ERROR' });
27
+ }
28
+ }
29
+ });
30
+ fastify.get('/api/tenants/name/:name', async (request, reply) => {
31
+ try {
32
+ request.rbac.assertPermission(IdentityPermissions.ViewTenant);
33
+ const name = request.params.name;
34
+ const tenantService = TenantServiceFactory();
35
+ let tenant = await tenantService.findByName(name);
36
+ return tenant;
37
+ }
38
+ catch (e) {
39
+ console.error(e);
40
+ if (e instanceof ValidationError) {
41
+ reply.statusCode = e.statusCode;
42
+ reply.send({ error: e.message, inputErrors: e.errors });
43
+ }
44
+ else if (e instanceof UnauthorizedError) {
45
+ reply.statusCode = e.statusCode;
46
+ reply.send({ error: e.message });
47
+ }
48
+ else {
49
+ reply.statusCode = 500;
50
+ reply.send({ error: 'INTERNAL_SERVER_ERROR' });
51
+ }
52
+ }
53
+ });
54
+ fastify.get('/api/tenants/all', async (request, reply) => {
55
+ try {
56
+ request.rbac.assertPermission(IdentityPermissions.ViewTenant);
57
+ const tenantService = TenantServiceFactory();
58
+ let tenants = await tenantService.fetchAll();
59
+ if (request.rbac.getAuthUser.tenantId) {
60
+ return tenants.filter(t => t.id === request.rbac.getAuthUser.tenantId);
61
+ }
62
+ else {
63
+ return tenants;
64
+ }
65
+ }
66
+ catch (e) {
67
+ console.error(e);
68
+ if (e instanceof ValidationError) {
69
+ reply.statusCode = e.statusCode;
70
+ reply.send({ error: e.message, inputErrors: e.errors });
71
+ }
72
+ else if (e instanceof UnauthorizedError) {
73
+ reply.statusCode = e.statusCode;
74
+ reply.send({ error: e.message });
75
+ }
76
+ else {
77
+ reply.statusCode = 500;
78
+ reply.send({ error: 'INTERNAL_SERVER_ERROR' });
79
+ }
80
+ }
81
+ });
82
+ fastify.get('/api/tenants', async (request, reply) => {
83
+ try {
84
+ request.rbac.assertPermission(IdentityPermissions.ViewTenant);
85
+ const page = request.query.page;
86
+ const limit = request.query.limit;
87
+ const search = request.query.search;
88
+ const tenantService = TenantServiceFactory();
89
+ let paginateResult = await tenantService.paginate(page, limit, search);
90
+ return paginateResult;
91
+ }
92
+ catch (e) {
93
+ console.error(e);
94
+ if (e instanceof ValidationError) {
95
+ reply.statusCode = e.statusCode;
96
+ reply.send({ error: e.message, inputErrors: e.errors });
97
+ }
98
+ else if (e instanceof UnauthorizedError) {
99
+ reply.statusCode = e.statusCode;
100
+ reply.send({ error: e.message });
101
+ }
102
+ else {
103
+ reply.statusCode = 500;
104
+ reply.send({ error: 'INTERNAL_SERVER_ERROR' });
105
+ }
106
+ }
107
+ });
108
+ fastify.post('/api/tenants', async (request, reply) => {
109
+ try {
110
+ request.rbac.assertPermission(IdentityPermissions.CreateTenant);
111
+ const payload = request.body;
112
+ const tenantService = TenantServiceFactory();
113
+ let tenant = await tenantService.create(payload);
114
+ return tenant;
115
+ }
116
+ catch (e) {
117
+ console.error(e);
118
+ if (e instanceof ValidationError) {
119
+ reply.statusCode = e.statusCode;
120
+ reply.send({ error: e.message, inputErrors: e.errors });
121
+ }
122
+ else if (e instanceof UnauthorizedError) {
123
+ reply.statusCode = e.statusCode;
124
+ reply.send({ error: e.message });
125
+ }
126
+ else {
127
+ reply.statusCode = 500;
128
+ reply.send({ error: 'INTERNAL_SERVER_ERROR' });
129
+ }
130
+ }
131
+ });
132
+ fastify.put('/api/tenants/:id', async (request, reply) => {
133
+ try {
134
+ request.rbac.assertPermission(IdentityPermissions.UpdateTenant);
135
+ const id = request.params.id;
136
+ const payload = request.body;
137
+ const tenantService = TenantServiceFactory();
138
+ let tenant = await tenantService.update(id, payload);
139
+ return tenant;
140
+ }
141
+ catch (e) {
142
+ console.error(e);
143
+ if (e instanceof ValidationError) {
144
+ reply.statusCode = e.statusCode;
145
+ reply.send({ error: e.message, inputErrors: e.errors });
146
+ }
147
+ else if (e instanceof UnauthorizedError) {
148
+ reply.statusCode = e.statusCode;
149
+ reply.send({ error: e.message });
150
+ }
151
+ else {
152
+ reply.statusCode = 500;
153
+ reply.send({ error: 'INTERNAL_SERVER_ERROR' });
154
+ }
155
+ }
156
+ });
157
+ fastify.delete('/api/tenants/:id', async (request, reply) => {
158
+ try {
159
+ request.rbac.assertPermission(IdentityPermissions.DeleteTenant);
160
+ const id = request.params.id;
161
+ const tenantService = TenantServiceFactory();
162
+ let r = await tenantService.delete(id);
163
+ return r;
164
+ }
165
+ catch (e) {
166
+ console.error(e);
167
+ if (e instanceof ValidationError) {
168
+ reply.statusCode = e.statusCode;
169
+ reply.send({ error: e.message, inputErrors: e.errors });
170
+ }
171
+ else if (e instanceof UnauthorizedError) {
172
+ reply.statusCode = e.statusCode;
173
+ reply.send({ error: e.message });
174
+ }
175
+ else {
176
+ reply.statusCode = 500;
177
+ reply.send({ error: 'INTERNAL_SERVER_ERROR' });
178
+ }
179
+ }
180
+ });
181
+ }
182
+ export default TenantRoutes;
183
+ export { TenantRoutes };
@@ -3,12 +3,12 @@ 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();
7
6
  async function UserRoutes(fastify, options) {
8
7
  fastify.post('/api/auth', async (request, reply) => {
9
8
  try {
10
9
  const username = request.body.username;
11
10
  const password = request.body.password;
11
+ const userService = UserServiceFactory();
12
12
  return await userService.auth(username, password);
13
13
  }
14
14
  catch (e) {
@@ -24,6 +24,7 @@ async function UserRoutes(fastify, options) {
24
24
  fastify.get('/api/me', async (request, reply) => {
25
25
  try {
26
26
  if (request.authUser) {
27
+ const userService = UserServiceFactory();
27
28
  let user = await userService.findById(request.authUser.id);
28
29
  delete user.password;
29
30
  return user;
@@ -53,10 +54,16 @@ async function UserRoutes(fastify, options) {
53
54
  const page = request.query.page;
54
55
  const limit = request.query.limit;
55
56
  const search = request.query.search;
56
- let paginateResult = await userService.paginate(page, limit, search);
57
+ const userService = UserServiceFactory();
58
+ const filters = [];
59
+ if (request.rbac.getAuthUser.tenantId) {
60
+ filters.push({ field: 'tenant', operator: '$eq', value: request.rbac.getAuthUser.tenantId });
61
+ }
62
+ let paginateResult = await userService.paginate(page, limit, search, filters);
57
63
  return paginateResult;
58
64
  }
59
65
  catch (e) {
66
+ console.log("/api/users", e);
60
67
  if (e instanceof ValidationError) {
61
68
  reply.statusCode = e.statusCode;
62
69
  reply.send({ error: e.message, inputErrors: e.errors });
@@ -75,6 +82,7 @@ async function UserRoutes(fastify, options) {
75
82
  try {
76
83
  request.rbac.assertPermission(IdentityPermissions.CreateUser);
77
84
  const payload = request.body;
85
+ const userService = UserServiceFactory();
78
86
  let user = await userService.create(payload);
79
87
  return user;
80
88
  }
@@ -98,6 +106,7 @@ async function UserRoutes(fastify, options) {
98
106
  request.rbac.assertPermission(IdentityPermissions.UpdateUser);
99
107
  const id = request.params.id;
100
108
  const payload = request.body;
109
+ const userService = UserServiceFactory();
101
110
  let user = await userService.update(id, payload);
102
111
  return user;
103
112
  }
@@ -124,6 +133,7 @@ async function UserRoutes(fastify, options) {
124
133
  try {
125
134
  request.rbac.assertPermission(IdentityPermissions.DeleteUser);
126
135
  const id = request.params.id;
136
+ const userService = UserServiceFactory();
127
137
  let r = await userService.delete(id);
128
138
  return r;
129
139
  }
@@ -150,6 +160,7 @@ async function UserRoutes(fastify, options) {
150
160
  const userId = request.authUser.id;
151
161
  const currentPassword = request.body.currentPassword;
152
162
  const newPassword = request.body.newPassword;
163
+ const userService = UserServiceFactory();
153
164
  return await userService.changeOwnPassword(userId, currentPassword, newPassword);
154
165
  }
155
166
  catch (e) {
@@ -176,6 +187,7 @@ async function UserRoutes(fastify, options) {
176
187
  throw new UnauthorizedError();
177
188
  }
178
189
  const newPassword = request.body.newPassword;
190
+ const userService = UserServiceFactory();
179
191
  return await userService.changeUserPassword(userId, newPassword);
180
192
  }
181
193
  catch (e) {
@@ -1,7 +1,6 @@
1
1
  import { ZodErrorToValidationError } from "@drax/common-back";
2
2
  import { roleSchema } from "../zod/RoleZod.js";
3
3
  import { ZodError } from "zod";
4
- import UnauthorizedError from "../errors/UnauthorizedError.js";
5
4
  class RoleService {
6
5
  constructor(roleRepostitory) {
7
6
  this._repository = roleRepostitory;
@@ -36,10 +35,6 @@ class RoleService {
36
35
  }
37
36
  }
38
37
  async delete(id) {
39
- const currentRole = await this.findById(id);
40
- if (currentRole.readonly) {
41
- throw new UnauthorizedError();
42
- }
43
38
  const deletedRole = await this._repository.delete(id);
44
39
  return deletedRole;
45
40
  }