@drax/identity-back 0.11.4 → 0.12.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/controllers/RoleController.js +8 -39
- package/dist/controllers/TenantController.js +1 -28
- package/dist/controllers/UserApiKeyController.js +6 -3
- package/dist/controllers/UserController.js +48 -209
- package/dist/errors/BadCredentialsError.js +12 -0
- package/dist/factory/RoleServiceFactory.js +1 -0
- package/dist/factory/TenantServiceFactory.js +1 -0
- package/dist/factory/UserApiKeyServiceFactory.js +5 -4
- package/dist/factory/UserServiceFactory.js +1 -0
- package/dist/graphql/resolvers/role.resolvers.js +2 -2
- package/dist/graphql/resolvers/tenant.resolvers.js +2 -2
- package/dist/graphql/resolvers/user-api-key.resolvers.js +2 -2
- package/dist/graphql/resolvers/user.resolvers.js +1 -1
- package/dist/graphql/types/userApiKey.graphql +1 -0
- package/dist/index.js +6 -0
- package/dist/middleware/apiKeyMiddleware.js +2 -2
- package/dist/models/RoleModel.js +10 -7
- package/dist/models/TenantModel.js +11 -8
- package/dist/models/UserApiKeyModel.js +15 -7
- package/dist/models/UserGroupModel.js +7 -7
- package/dist/models/UserModel.js +10 -8
- package/dist/permissions/UserApiKeyPermissions.js +2 -1
- package/dist/rbac/Rbac.js +10 -8
- package/dist/repository/mongo/RoleMongoRepository.js +20 -65
- package/dist/repository/mongo/TenantMongoRepository.js +18 -66
- package/dist/repository/mongo/UserApiKeyMongoRepository.js +29 -44
- package/dist/repository/mongo/UserMongoRepository.js +56 -85
- package/dist/repository/sqlite/RoleSqliteRepository.js +30 -115
- package/dist/repository/sqlite/TenantSqliteRepository.js +15 -105
- package/dist/repository/sqlite/UserApiKeySqliteRepository.js +42 -115
- package/dist/repository/sqlite/UserSqliteRepository.js +49 -130
- package/dist/routes/RoleRoutes.js +35 -10
- package/dist/routes/TenantRoutes.js +18 -9
- package/dist/routes/UserApiKeyRoutes.js +20 -4
- package/dist/routes/UserRoutes.js +92 -17
- package/dist/schemas/LoginSchema.js +9 -0
- package/dist/schemas/PasswordSchema.js +12 -0
- package/dist/schemas/RegisterSchema.js +19 -0
- package/dist/schemas/RoleSchema.js +23 -0
- package/dist/schemas/TenantSchema.js +13 -0
- package/dist/schemas/UserApiKeySchema.js +14 -0
- package/dist/schemas/UserSchema.js +39 -0
- package/dist/services/PermissionService.js +5 -5
- package/dist/services/RoleService.js +6 -6
- package/dist/services/TenantService.js +6 -6
- package/dist/services/UserApiKeyService.js +5 -5
- package/dist/services/UserService.js +14 -14
- package/dist/setup/CreateOrUpdateRole.js +5 -2
- package/dist/setup/CreateUserIfNotExist.js +3 -1
- package/dist/setup/RecoveryUserPassword.js +1 -1
- package/dist/zod/EndpointZod.js +9 -0
- package/dist/zod/TenantSchema.js +12 -0
- package/dist/zod/TenantZod.js +5 -3
- package/dist/zod/UserApiKeyZod.js +7 -3
- package/package.json +10 -9
- package/src/controllers/RoleController.ts +8 -36
- package/src/controllers/TenantController.ts +2 -25
- package/src/controllers/UserApiKeyController.ts +8 -3
- package/src/controllers/UserController.ts +50 -183
- package/src/errors/BadCredentialsError.ts +18 -1
- package/src/factory/RoleServiceFactory.ts +1 -0
- package/src/factory/TenantServiceFactory.ts +1 -0
- package/src/factory/UserApiKeyServiceFactory.ts +5 -4
- package/src/factory/UserServiceFactory.ts +1 -0
- package/src/graphql/resolvers/role.resolvers.ts +3 -2
- package/src/graphql/resolvers/tenant.resolvers.ts +3 -2
- package/src/graphql/resolvers/user-api-key.resolvers.ts +3 -2
- package/src/graphql/resolvers/user.resolvers.ts +2 -1
- package/src/graphql/types/userApiKey.graphql +1 -0
- package/src/index.ts +16 -0
- package/src/interfaces/ITenantRepository.ts +2 -2
- package/src/interfaces/IUserApiKeyRepository.ts +2 -2
- package/src/interfaces/IUserRepository.ts +3 -2
- package/src/middleware/apiKeyMiddleware.ts +2 -2
- package/src/models/RoleModel.ts +12 -7
- package/src/models/TenantModel.ts +13 -8
- package/src/models/UserApiKeyModel.ts +17 -7
- package/src/models/UserGroupModel.ts +7 -7
- package/src/models/UserModel.ts +10 -8
- package/src/permissions/UserApiKeyPermissions.ts +2 -1
- package/src/rbac/Rbac.ts +12 -9
- package/src/repository/mongo/RoleMongoRepository.ts +23 -94
- package/src/repository/mongo/TenantMongoRepository.ts +19 -98
- package/src/repository/mongo/UserApiKeyMongoRepository.ts +31 -53
- package/src/repository/mongo/UserMongoRepository.ts +71 -130
- package/src/repository/sqlite/RoleSqliteRepository.ts +37 -146
- package/src/repository/sqlite/TenantSqliteRepository.ts +16 -156
- package/src/repository/sqlite/UserApiKeySqliteRepository.ts +46 -149
- package/src/repository/sqlite/UserSqliteRepository.ts +59 -173
- package/src/routes/RoleRoutes.ts +35 -12
- package/src/routes/TenantRoutes.ts +25 -9
- package/src/routes/UserApiKeyRoutes.ts +23 -7
- package/src/routes/UserRoutes.ts +117 -34
- package/src/schemas/LoginSchema.ts +12 -0
- package/src/schemas/PasswordSchema.ts +16 -0
- package/src/{zod/UserZod.ts → schemas/RegisterSchema.ts} +7 -10
- package/src/schemas/RoleSchema.ts +29 -0
- package/src/schemas/TenantSchema.ts +22 -0
- package/src/{zod/UserApiKeyZod.ts → schemas/UserApiKeySchema.ts} +8 -3
- package/src/schemas/UserSchema.ts +57 -0
- package/src/services/PermissionService.ts +6 -5
- package/src/services/RoleService.ts +6 -6
- package/src/services/TenantService.ts +10 -10
- package/src/services/UserApiKeyService.ts +5 -5
- package/src/services/UserService.ts +15 -16
- package/src/setup/CreateOrUpdateRole.ts +7 -4
- package/src/setup/CreateUserIfNotExist.ts +5 -3
- package/src/setup/RecoveryUserPassword.ts +1 -1
- package/test/data-obj/apikey/root-mongo-user-apikey.ts +2 -1
- package/test/data-obj/roles/admin-sqlite-role.ts +2 -2
- package/test/data-obj/roles/operator-sqlite-role.ts +1 -1
- package/test/data-obj/tenants/company-sqlite-tenant.ts +6 -0
- package/test/data-obj/users/root-sqlite-user.ts +2 -2
- package/test/initializers/RoleSqliteInitializer.ts +1 -1
- package/test/repository/mongo/role-mongo-repository.test.ts +3 -3
- package/test/repository/mongo/user-apikey-mongo-repository.test.ts +5 -4
- package/test/repository/mongo/user-mongo-repository.test.ts +4 -4
- package/test/repository/sqlite/role-sqlite-repository.test.ts +21 -9
- package/test/repository/sqlite/tenant-sqlite-repository.test.ts +74 -0
- package/test/repository/sqlite/user-sqlite-repository.test.ts +15 -9
- package/test/routes/data/admin-role.ts +10 -0
- package/test/routes/data/root-user.ts +13 -0
- package/test/routes/helpers/CreateRootUserAndAdminRole.ts +17 -0
- package/test/routes/helpers/FastifyTestServerFactory.ts +34 -0
- package/test/routes/helpers/InitializePermissions.ts +23 -0
- package/test/routes/helpers/SetupIdentityDrax.ts +22 -0
- package/test/routes/tenant-route.test.ts +336 -0
- package/test/routes/user-route.test.ts +186 -0
- package/test/schemas/lab-schema.test.ts +110 -0
- package/test/service/mock-service.test.ts +3 -3
- package/test/service/role-service.test.ts +3 -3
- package/test/service/user-service.test.ts +16 -25
- package/test.db +0 -0
- package/tsconfig.tsbuildinfo +1 -1
- package/types/controllers/RoleController.d.ts +0 -1
- package/types/controllers/RoleController.d.ts.map +1 -1
- package/types/controllers/TenantController.d.ts +0 -1
- package/types/controllers/TenantController.d.ts.map +1 -1
- package/types/controllers/UserApiKeyController.d.ts.map +1 -1
- package/types/controllers/UserController.d.ts +11 -4
- package/types/controllers/UserController.d.ts.map +1 -1
- package/types/errors/BadCredentialsError.d.ts +9 -1
- package/types/errors/BadCredentialsError.d.ts.map +1 -1
- package/types/factory/RoleServiceFactory.d.ts.map +1 -1
- package/types/factory/TenantServiceFactory.d.ts.map +1 -1
- package/types/factory/UserApiKeyServiceFactory.d.ts.map +1 -1
- package/types/factory/UserServiceFactory.d.ts.map +1 -1
- package/types/graphql/resolvers/role.resolvers.d.ts +3 -9
- package/types/graphql/resolvers/role.resolvers.d.ts.map +1 -1
- package/types/graphql/resolvers/tenant.resolvers.d.ts +3 -9
- package/types/graphql/resolvers/tenant.resolvers.d.ts.map +1 -1
- package/types/graphql/resolvers/user-api-key.resolvers.d.ts +3 -9
- package/types/graphql/resolvers/user-api-key.resolvers.d.ts.map +1 -1
- package/types/graphql/resolvers/user.resolvers.d.ts +3 -9
- package/types/graphql/resolvers/user.resolvers.d.ts.map +1 -1
- package/types/index.d.ts +5 -1
- package/types/index.d.ts.map +1 -1
- package/types/interfaces/ITenantRepository.d.ts +2 -2
- package/types/interfaces/ITenantRepository.d.ts.map +1 -1
- package/types/interfaces/IUserApiKeyRepository.d.ts +2 -2
- package/types/interfaces/IUserApiKeyRepository.d.ts.map +1 -1
- package/types/interfaces/IUserRepository.d.ts +3 -2
- package/types/interfaces/IUserRepository.d.ts.map +1 -1
- package/types/models/RoleModel.d.ts +7 -7
- package/types/models/RoleModel.d.ts.map +1 -1
- package/types/models/TenantModel.d.ts +7 -7
- package/types/models/TenantModel.d.ts.map +1 -1
- package/types/models/UserApiKeyModel.d.ts +7 -7
- package/types/models/UserApiKeyModel.d.ts.map +1 -1
- package/types/models/UserGroupModel.d.ts +2 -2
- package/types/models/UserGroupModel.d.ts.map +1 -1
- package/types/models/UserModel.d.ts +7 -7
- package/types/models/UserModel.d.ts.map +1 -1
- package/types/permissions/UserApiKeyPermissions.d.ts +2 -1
- package/types/permissions/UserApiKeyPermissions.d.ts.map +1 -1
- package/types/permissions/index.d.ts +1 -0
- package/types/permissions/index.d.ts.map +1 -1
- package/types/rbac/Rbac.d.ts +1 -1
- package/types/rbac/Rbac.d.ts.map +1 -1
- package/types/repository/mongo/RoleMongoRepository.d.ts +9 -11
- package/types/repository/mongo/RoleMongoRepository.d.ts.map +1 -1
- package/types/repository/mongo/TenantMongoRepository.d.ts +8 -11
- package/types/repository/mongo/TenantMongoRepository.d.ts.map +1 -1
- package/types/repository/mongo/UserApiKeyMongoRepository.d.ts +12 -5
- package/types/repository/mongo/UserApiKeyMongoRepository.d.ts.map +1 -1
- package/types/repository/mongo/UserMongoRepository.d.ts +11 -12
- package/types/repository/mongo/UserMongoRepository.d.ts.map +1 -1
- package/types/repository/sqlite/RoleSqliteRepository.d.ts +14 -14
- package/types/repository/sqlite/RoleSqliteRepository.d.ts.map +1 -1
- package/types/repository/sqlite/TenantSqliteRepository.d.ts +12 -14
- package/types/repository/sqlite/TenantSqliteRepository.d.ts.map +1 -1
- package/types/repository/sqlite/UserApiKeySqliteRepository.d.ts +15 -11
- package/types/repository/sqlite/UserApiKeySqliteRepository.d.ts.map +1 -1
- package/types/repository/sqlite/UserSqliteRepository.d.ts +15 -12
- package/types/repository/sqlite/UserSqliteRepository.d.ts.map +1 -1
- package/types/routes/RoleRoutes.d.ts.map +1 -1
- package/types/routes/TenantRoutes.d.ts.map +1 -1
- package/types/routes/UserApiKeyRoutes.d.ts.map +1 -1
- package/types/routes/UserRoutes.d.ts.map +1 -1
- package/types/schemas/LoginSchema.d.ts +20 -0
- package/types/schemas/LoginSchema.d.ts.map +1 -0
- package/types/schemas/PasswordSchema.d.ts +27 -0
- package/types/schemas/PasswordSchema.d.ts.map +1 -0
- package/types/schemas/RegisterSchema.d.ts +32 -0
- package/types/schemas/RegisterSchema.d.ts.map +1 -0
- package/types/schemas/RoleSchema.d.ts +67 -0
- package/types/schemas/RoleSchema.d.ts.map +1 -0
- package/types/schemas/TenantSchema.d.ts +29 -0
- package/types/schemas/TenantSchema.d.ts.map +1 -0
- package/types/schemas/UserApiKeySchema.d.ts +39 -0
- package/types/schemas/UserApiKeySchema.d.ts.map +1 -0
- package/types/schemas/UserSchema.d.ts +161 -0
- package/types/schemas/UserSchema.d.ts.map +1 -0
- package/types/services/PermissionService.d.ts +1 -0
- package/types/services/PermissionService.d.ts.map +1 -1
- package/types/services/TenantService.d.ts +3 -3
- package/types/services/TenantService.d.ts.map +1 -1
- package/types/services/UserService.d.ts.map +1 -1
- package/types/setup/CreateOrUpdateRole.d.ts +2 -2
- package/types/setup/CreateOrUpdateRole.d.ts.map +1 -1
- package/types/setup/CreateUserIfNotExist.d.ts +2 -2
- package/types/setup/CreateUserIfNotExist.d.ts.map +1 -1
- package/types/zod/EndpointZod.d.ts +20 -0
- package/types/zod/EndpointZod.d.ts.map +1 -0
- package/types/zod/TenantSchema.d.ts +26 -0
- package/types/zod/TenantSchema.d.ts.map +1 -0
- package/types/zod/TenantZod.d.ts +13 -3
- package/types/zod/TenantZod.d.ts.map +1 -1
- package/types/zod/UserApiKeyZod.d.ts +23 -3
- package/types/zod/UserApiKeyZod.d.ts.map +1 -1
- package/types/zod/UserZod.d.ts +6 -6
- package/src/zod/RoleZod.ts +0 -14
- package/src/zod/TenantZod.ts +0 -14
|
@@ -1,130 +1,79 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { randomUUID } from "node:crypto";
|
|
3
|
-
import { SqliteErrorToValidationError, SqliteTableBuilder, SqlQueryFilter, SqlSort, ValidationError } from "@drax/common-back";
|
|
1
|
+
import { ValidationError } from "@drax/common-back";
|
|
4
2
|
import RoleSqliteRepository from "./RoleSqliteRepository.js";
|
|
5
3
|
import TenantSqliteRepository from "./TenantSqliteRepository.js";
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
{ name: "username", type: "TEXT", unique: true, primary: false },
|
|
9
|
-
{ name: "active", type: "INTEGER", unique: false, primary: false },
|
|
10
|
-
{ name: "active", type: "INTEGER", unique: false, primary: false },
|
|
11
|
-
{ name: "password", type: "TEXT", unique: false, primary: false },
|
|
12
|
-
{ name: "email", type: "TEXT", unique: true, primary: false },
|
|
13
|
-
{ name: "phone", type: "TEXT", unique: false, primary: false },
|
|
14
|
-
{ name: "role", type: "TEXT", unique: false, primary: false },
|
|
15
|
-
{ name: "tenant", type: "TEXT", unique: false, primary: false },
|
|
16
|
-
{ name: "groups", type: "TEXT", unique: false, primary: false },
|
|
17
|
-
{ name: "avatar", type: "TEXT", unique: false, primary: false },
|
|
18
|
-
{ name: "origin", type: "TEXT", unique: false, primary: false },
|
|
19
|
-
{ name: "createdAt", type: "TEXT", unique: false, primary: false },
|
|
20
|
-
{ name: "updatedAt", type: "TEXT", unique: false, primary: false },
|
|
21
|
-
{ name: "emailVerified", type: "INTEGER", unique: false, primary: false },
|
|
22
|
-
{ name: "phoneVerified", type: "INTEGER", unique: false, primary: false },
|
|
23
|
-
{ name: "emailCode", type: "TEXT", unique: false, primary: false },
|
|
24
|
-
{ name: "phoneCode", type: "TEXT", unique: false, primary: false },
|
|
25
|
-
];
|
|
26
|
-
class UserSqliteRepository {
|
|
4
|
+
import { AbstractSqliteRepository } from "@drax/crud-back";
|
|
5
|
+
class UserSqliteRepository extends AbstractSqliteRepository {
|
|
27
6
|
constructor(dataBaseFile, verbose = false) {
|
|
28
|
-
|
|
29
|
-
this.
|
|
7
|
+
super(dataBaseFile, verbose);
|
|
8
|
+
this.tableName = 'users';
|
|
9
|
+
this.searchFields = [];
|
|
10
|
+
this.booleanFields = ['active'];
|
|
11
|
+
this.identifier = '_id';
|
|
12
|
+
this.populateFields = [];
|
|
13
|
+
this.tableFields = [
|
|
14
|
+
{ name: "name", type: "TEXT", unique: false, primary: false },
|
|
15
|
+
{ name: "username", type: "TEXT", unique: true, primary: false },
|
|
16
|
+
{ name: "active", type: "INTEGER", unique: false, primary: false },
|
|
17
|
+
{ name: "password", type: "TEXT", unique: false, primary: false },
|
|
18
|
+
{ name: "email", type: "TEXT", unique: true, primary: false },
|
|
19
|
+
{ name: "phone", type: "TEXT", unique: false, primary: false },
|
|
20
|
+
{ name: "role", type: "TEXT", unique: false, primary: false },
|
|
21
|
+
{ name: "tenant", type: "TEXT", unique: false, primary: false },
|
|
22
|
+
{ name: "groups", type: "TEXT", unique: false, primary: false },
|
|
23
|
+
{ name: "avatar", type: "TEXT", unique: false, primary: false },
|
|
24
|
+
{ name: "origin", type: "TEXT", unique: false, primary: false },
|
|
25
|
+
{ name: "createdAt", type: "TEXT", unique: false, primary: false },
|
|
26
|
+
{ name: "updatedAt", type: "TEXT", unique: false, primary: false },
|
|
27
|
+
{ name: "emailVerified", type: "INTEGER", unique: false, primary: false },
|
|
28
|
+
{ name: "phoneVerified", type: "INTEGER", unique: false, primary: false },
|
|
29
|
+
{ name: "emailCode", type: "TEXT", unique: false, primary: false },
|
|
30
|
+
{ name: "phoneCode", type: "TEXT", unique: false, primary: false },
|
|
31
|
+
];
|
|
30
32
|
this.roleRepository = new RoleSqliteRepository(dataBaseFile, verbose);
|
|
31
33
|
this.tenantRepository = new TenantSqliteRepository(dataBaseFile, verbose);
|
|
32
|
-
this.table();
|
|
33
34
|
}
|
|
34
|
-
|
|
35
|
-
const builder = new SqliteTableBuilder(this.dataBaseFile, 'users', tableFields, false);
|
|
36
|
-
builder.build('id');
|
|
37
|
-
}
|
|
38
|
-
normalizeData(userData) {
|
|
35
|
+
async prepareData(userData) {
|
|
39
36
|
if (userData.groups && Array.isArray(userData.groups)) {
|
|
40
37
|
userData.groups = userData.groups.join(",");
|
|
41
38
|
}
|
|
42
39
|
userData.active = userData.active ? 1 : 0;
|
|
43
|
-
}
|
|
44
|
-
async create(userData) {
|
|
45
|
-
if (!userData.id) {
|
|
46
|
-
userData.id = randomUUID();
|
|
47
|
-
}
|
|
48
40
|
if (!await this.findRoleById(userData.role)) {
|
|
49
41
|
throw new ValidationError([{ field: 'role', reason: 'validation.notfound', value: userData.role }]);
|
|
50
42
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
.map(field => `${field}`)
|
|
56
|
-
.join(', ');
|
|
57
|
-
const values = Object.keys(userData)
|
|
58
|
-
.map(field => `@${field}`)
|
|
59
|
-
.join(', ');
|
|
60
|
-
const stmt = this.db.prepare(`INSERT INTO users (${fields})
|
|
61
|
-
VALUES (${values})`);
|
|
62
|
-
stmt.run(userData);
|
|
63
|
-
return this.findById(userData.id);
|
|
43
|
+
}
|
|
44
|
+
async prepareItem(user) {
|
|
45
|
+
if (user && user.role) {
|
|
46
|
+
user.role = await this.findRoleById(user.role);
|
|
64
47
|
}
|
|
65
|
-
|
|
66
|
-
|
|
48
|
+
if (user && user.tenant) {
|
|
49
|
+
user.tenant = await this.findTenantById(user.tenant);
|
|
67
50
|
}
|
|
68
51
|
}
|
|
69
52
|
async updatePartial(id, userData) {
|
|
70
53
|
return this.update(id, userData);
|
|
71
54
|
}
|
|
72
|
-
async
|
|
73
|
-
|
|
74
|
-
if (!await this.findRoleById(userData.role)) {
|
|
75
|
-
throw new ValidationError([{ field: 'role', reason: 'validation.notfound', value: userData.role }]);
|
|
76
|
-
}
|
|
77
|
-
userData.updatedAt = (new Date().toISOString());
|
|
78
|
-
this.normalizeData(userData);
|
|
79
|
-
const setClauses = Object.keys(userData)
|
|
80
|
-
.map(field => `${field} = @${field}`)
|
|
81
|
-
.join(', ');
|
|
82
|
-
userData.id = id;
|
|
83
|
-
const stmt = this.db.prepare(`UPDATE users
|
|
84
|
-
SET ${setClauses}
|
|
85
|
-
WHERE id = @id `);
|
|
86
|
-
stmt.run(userData);
|
|
87
|
-
}
|
|
88
|
-
catch (e) {
|
|
89
|
-
throw SqliteErrorToValidationError(e, userData);
|
|
90
|
-
}
|
|
91
|
-
return this.findById(id);
|
|
92
|
-
}
|
|
93
|
-
async delete(id) {
|
|
94
|
-
const stmt = this.db.prepare('DELETE FROM users WHERE id = ?');
|
|
95
|
-
stmt.run(id);
|
|
96
|
-
return true;
|
|
97
|
-
}
|
|
98
|
-
async deleteAll() {
|
|
99
|
-
const stmt = this.db.prepare('DELETE FROM users');
|
|
100
|
-
stmt.run();
|
|
101
|
-
return true;
|
|
102
|
-
}
|
|
103
|
-
async findById(id) {
|
|
104
|
-
const user = this.db.prepare('SELECT * FROM users WHERE id = ?').get(id);
|
|
55
|
+
async findByUsername(username) {
|
|
56
|
+
const user = this.db.prepare('SELECT * FROM users WHERE username = ?').get(username);
|
|
105
57
|
if (!user) {
|
|
106
58
|
return null;
|
|
107
59
|
}
|
|
108
|
-
|
|
109
|
-
user.tenant = await this.findTenantById(user.tenant);
|
|
60
|
+
await this.decorate(user);
|
|
110
61
|
return user;
|
|
111
62
|
}
|
|
112
|
-
async
|
|
63
|
+
async findByUsernameWithPassword(username) {
|
|
113
64
|
const user = this.db.prepare('SELECT * FROM users WHERE username = ?').get(username);
|
|
114
65
|
if (!user) {
|
|
115
66
|
return null;
|
|
116
67
|
}
|
|
117
|
-
|
|
118
|
-
user.tenant = await this.findTenantById(user.tenant);
|
|
68
|
+
await this.decorate(user);
|
|
119
69
|
return user;
|
|
120
70
|
}
|
|
121
|
-
async
|
|
122
|
-
const user = this.db.prepare('SELECT * FROM users WHERE
|
|
71
|
+
async findByIdWithPassword(id) {
|
|
72
|
+
const user = this.db.prepare('SELECT * FROM users WHERE ${this.identifier} = ?').get(id);
|
|
123
73
|
if (!user) {
|
|
124
74
|
return null;
|
|
125
75
|
}
|
|
126
|
-
|
|
127
|
-
user.tenant = await this.findTenantById(user.tenant);
|
|
76
|
+
await this.decorate(user);
|
|
128
77
|
return user;
|
|
129
78
|
}
|
|
130
79
|
async findByEmail(email) {
|
|
@@ -132,8 +81,7 @@ class UserSqliteRepository {
|
|
|
132
81
|
if (!user) {
|
|
133
82
|
return null;
|
|
134
83
|
}
|
|
135
|
-
|
|
136
|
-
user.tenant = await this.findTenantById(user.tenant);
|
|
84
|
+
await this.decorate(user);
|
|
137
85
|
return user;
|
|
138
86
|
}
|
|
139
87
|
async findByEmailCode(code) {
|
|
@@ -141,8 +89,7 @@ class UserSqliteRepository {
|
|
|
141
89
|
if (!user) {
|
|
142
90
|
return null;
|
|
143
91
|
}
|
|
144
|
-
|
|
145
|
-
user.tenant = await this.findTenantById(user.tenant);
|
|
92
|
+
await this.decorate(user);
|
|
146
93
|
return user;
|
|
147
94
|
}
|
|
148
95
|
async findByRecoveryCode(code) {
|
|
@@ -150,8 +97,7 @@ class UserSqliteRepository {
|
|
|
150
97
|
if (!user) {
|
|
151
98
|
return null;
|
|
152
99
|
}
|
|
153
|
-
|
|
154
|
-
user.tenant = await this.findTenantById(user.tenant);
|
|
100
|
+
await this.decorate(user);
|
|
155
101
|
return user;
|
|
156
102
|
}
|
|
157
103
|
async findByPhoneCode(code) {
|
|
@@ -159,36 +105,9 @@ class UserSqliteRepository {
|
|
|
159
105
|
if (!user) {
|
|
160
106
|
return null;
|
|
161
107
|
}
|
|
162
|
-
|
|
163
|
-
user.tenant = await this.findTenantById(user.tenant);
|
|
108
|
+
await this.decorate(user);
|
|
164
109
|
return user;
|
|
165
110
|
}
|
|
166
|
-
async paginate({ page = 1, limit = 5, orderBy = '', order = false, search = '', filters = [] }) {
|
|
167
|
-
const offset = page > 1 ? (page - 1) * limit : 0;
|
|
168
|
-
let where = "";
|
|
169
|
-
if (search) {
|
|
170
|
-
where = ` WHERE (name LIKE '%${search}%' OR username LIKE '%${search}%') `;
|
|
171
|
-
}
|
|
172
|
-
where = SqlQueryFilter.applyFilters(where, filters);
|
|
173
|
-
const sort = SqlSort.applySort(orderBy, order);
|
|
174
|
-
console.log("paginate where ", where, "search", search, "filters", filters);
|
|
175
|
-
const rCount = this.db.prepare('SELECT COUNT(*) as count FROM users' + where).get();
|
|
176
|
-
where += sort;
|
|
177
|
-
const users = this.db.prepare('SELECT * FROM users' + where + ' LIMIT ? OFFSET ?').all([limit, offset]);
|
|
178
|
-
for (const user of users) {
|
|
179
|
-
let role = await this.findRoleById(user.role);
|
|
180
|
-
user.role = role ? role : null;
|
|
181
|
-
let tenant = await this.findTenantById(user.tenant);
|
|
182
|
-
user.tenant = tenant ? tenant : null;
|
|
183
|
-
user.active = user.active === 1;
|
|
184
|
-
}
|
|
185
|
-
return {
|
|
186
|
-
page: page,
|
|
187
|
-
limit: limit,
|
|
188
|
-
total: rCount.count,
|
|
189
|
-
items: users
|
|
190
|
-
};
|
|
191
|
-
}
|
|
192
111
|
async findRoleById(id) {
|
|
193
112
|
return await this.roleRepository.findById(id);
|
|
194
113
|
}
|
|
@@ -198,14 +117,14 @@ class UserSqliteRepository {
|
|
|
198
117
|
async changePassword(id, password) {
|
|
199
118
|
const stmt = this.db.prepare(`UPDATE users
|
|
200
119
|
SET password = @password
|
|
201
|
-
WHERE
|
|
120
|
+
WHERE ${this.identifier} = @id `);
|
|
202
121
|
stmt.run({ id: id, password: password });
|
|
203
122
|
return true;
|
|
204
123
|
}
|
|
205
124
|
async changeAvatar(id, avatar) {
|
|
206
125
|
const stmt = this.db.prepare(`UPDATE users
|
|
207
126
|
SET avatar = @avatar
|
|
208
|
-
WHERE
|
|
127
|
+
WHERE ${this.identifier} = @id `);
|
|
209
128
|
stmt.run({ id: id, avatar: avatar });
|
|
210
129
|
return true;
|
|
211
130
|
}
|
|
@@ -1,16 +1,41 @@
|
|
|
1
1
|
import RoleController from "../controllers/RoleController.js";
|
|
2
|
+
import { CrudSchemaBuilder } from "@drax/crud-back";
|
|
3
|
+
import { RoleBaseSchema, RoleSchema } from "../schemas/RoleSchema.js";
|
|
4
|
+
import { zodToJsonSchema } from "zod-to-json-schema";
|
|
5
|
+
import zod from "zod";
|
|
2
6
|
async function RoleRoutes(fastify, options) {
|
|
3
7
|
const controller = new RoleController();
|
|
4
|
-
|
|
5
|
-
fastify.get('/api/roles/
|
|
6
|
-
fastify.get('/api/roles
|
|
7
|
-
fastify.get('/api/roles
|
|
8
|
-
fastify.get('/api/roles
|
|
9
|
-
fastify.
|
|
10
|
-
fastify.
|
|
11
|
-
fastify.
|
|
12
|
-
fastify.
|
|
13
|
-
fastify.
|
|
8
|
+
const schemas = new CrudSchemaBuilder(RoleSchema, RoleBaseSchema, RoleBaseSchema, 'role', 'openApi3', ['Identity']);
|
|
9
|
+
fastify.get('/api/roles/search', { schema: schemas.searchSchema }, (req, rep) => controller.search(req, rep));
|
|
10
|
+
fastify.get('/api/roles/:id', { schema: schemas.findByIdSchema }, (req, rep) => controller.findById(req, rep));
|
|
11
|
+
fastify.get('/api/roles/all', { schema: schemas.allSchema }, (req, rep) => controller.all(req, rep));
|
|
12
|
+
fastify.get('/api/roles', { schema: schemas.paginateSchema }, (req, rep) => controller.paginate(req, rep));
|
|
13
|
+
fastify.post('/api/roles', { schema: schemas.createSchema }, (req, rep) => controller.create(req, rep));
|
|
14
|
+
fastify.put('/api/roles/:id', { schema: schemas.updateSchema }, (req, rep) => controller.update(req, rep));
|
|
15
|
+
fastify.delete('/api/roles/:id', { schema: schemas.deleteSchema }, (req, rep) => controller.delete(req, rep));
|
|
16
|
+
fastify.get('/api/roles/export', { schema: schemas.exportSchema }, (req, rep) => controller.export(req, rep));
|
|
17
|
+
fastify.get('/api/permissions', {
|
|
18
|
+
schema: {
|
|
19
|
+
tags: ['Identity'],
|
|
20
|
+
response: {
|
|
21
|
+
200: zodToJsonSchema(zod.array(zod.string())),
|
|
22
|
+
401: schemas.jsonErrorBodyResponse,
|
|
23
|
+
403: schemas.jsonErrorBodyResponse,
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}, (req, rep) => controller.permissions(req, rep));
|
|
27
|
+
fastify.get('/api/roles/name/:name', {
|
|
28
|
+
schema: {
|
|
29
|
+
tags: ['Identity'],
|
|
30
|
+
params: zodToJsonSchema(zod.object({ name: zod.string() })),
|
|
31
|
+
response: {
|
|
32
|
+
200: schemas.jsonEntitySchema,
|
|
33
|
+
401: schemas.jsonErrorBodyResponse,
|
|
34
|
+
403: schemas.jsonErrorBodyResponse,
|
|
35
|
+
404: schemas.jsonErrorBodyResponse,
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}, (req, rep) => controller.findByName(req, rep));
|
|
14
39
|
}
|
|
15
40
|
export default RoleRoutes;
|
|
16
41
|
export { RoleRoutes };
|
|
@@ -1,15 +1,24 @@
|
|
|
1
|
+
import { CrudSchemaBuilder } from "@drax/crud-back";
|
|
1
2
|
import TenantController from '../controllers/TenantController.js';
|
|
3
|
+
import { TenantSchema, TenantBaseSchema } from '../schemas/TenantSchema.js';
|
|
2
4
|
async function TenantRoutes(fastify, options) {
|
|
3
5
|
const controller = new TenantController();
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
fastify.get('/api/tenants
|
|
7
|
-
fastify.get('/api/tenants
|
|
8
|
-
fastify.get('/api/tenants/all', (req, rep) => controller.all(req, rep));
|
|
9
|
-
fastify.get('/api/tenants', (req, rep) => controller.
|
|
10
|
-
fastify.
|
|
11
|
-
fastify.
|
|
12
|
-
fastify.
|
|
6
|
+
const schemas = new CrudSchemaBuilder(TenantSchema, TenantBaseSchema, TenantBaseSchema, 'tenant', 'openApi3', ['Identity']);
|
|
7
|
+
//Getters
|
|
8
|
+
fastify.get('/api/tenants/search', { schema: schemas.searchSchema }, (req, rep) => controller.search(req, rep));
|
|
9
|
+
fastify.get('/api/tenants/:id', { schema: schemas.findByIdSchema }, (req, rep) => controller.findById(req, rep));
|
|
10
|
+
fastify.get('/api/tenants/all', { schema: schemas.allSchema }, (req, rep) => controller.all(req, rep));
|
|
11
|
+
fastify.get('/api/tenants/find', { schema: schemas.findSchema }, (req, rep) => controller.find(req, rep));
|
|
12
|
+
fastify.get('/api/tenants/find-one', { schema: schemas.findOneSchema }, (req, rep) => controller.findOne(req, rep));
|
|
13
|
+
fastify.get('/api/tenants/find-by/:field/:value', { schema: schemas.findBySchema }, (req, rep) => controller.findBy(req, rep));
|
|
14
|
+
fastify.get('/api/tenants/find-one-by/:field/:value', { schema: schemas.findOneBySchema }, (req, rep) => controller.findOneBy(req, rep));
|
|
15
|
+
fastify.get('/api/tenants', { schema: schemas.paginateSchema }, (req, rep) => controller.paginate(req, rep));
|
|
16
|
+
//Mutations
|
|
17
|
+
fastify.post('/api/tenants', { schema: schemas.createSchema }, (req, rep) => controller.create(req, rep));
|
|
18
|
+
fastify.put('/api/tenants/:id', { schema: schemas.updateSchema }, (req, rep) => controller.update(req, rep));
|
|
19
|
+
fastify.delete('/api/tenants/:id', { schema: schemas.deleteSchema }, (req, rep) => controller.delete(req, rep));
|
|
20
|
+
//Others
|
|
21
|
+
fastify.get('/api/tenants/export', { schema: schemas.exportSchema }, (req, rep) => controller.export(req, rep));
|
|
13
22
|
}
|
|
14
23
|
export default TenantRoutes;
|
|
15
24
|
export { TenantRoutes };
|
|
@@ -1,10 +1,26 @@
|
|
|
1
1
|
import UserApiKeyController from "../controllers/UserApiKeyController.js";
|
|
2
2
|
async function UserApiKeyRoutes(fastify, options) {
|
|
3
3
|
const controller = new UserApiKeyController();
|
|
4
|
-
fastify.get('/api/user-api-keys',
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
fastify.get('/api/user-api-keys', {
|
|
5
|
+
schema: {
|
|
6
|
+
tags: ['Identity'],
|
|
7
|
+
}
|
|
8
|
+
}, (req, rep) => controller.paginate(req, rep));
|
|
9
|
+
fastify.post('/api/user-api-keys', {
|
|
10
|
+
schema: {
|
|
11
|
+
tags: ['Identity'],
|
|
12
|
+
}
|
|
13
|
+
}, (req, rep) => controller.create(req, rep));
|
|
14
|
+
fastify.put('/api/user-api-keys/:id', {
|
|
15
|
+
schema: {
|
|
16
|
+
tags: ['Identity'],
|
|
17
|
+
}
|
|
18
|
+
}, (req, rep) => controller.update(req, rep));
|
|
19
|
+
fastify.delete('/api/user-api-keys/:id', {
|
|
20
|
+
schema: {
|
|
21
|
+
tags: ['Identity'],
|
|
22
|
+
}
|
|
23
|
+
}, (req, rep) => controller.delete(req, rep));
|
|
8
24
|
}
|
|
9
25
|
export default UserApiKeyRoutes;
|
|
10
26
|
export { UserApiKeyRoutes };
|
|
@@ -1,23 +1,98 @@
|
|
|
1
1
|
import UserController from "../controllers/UserController.js";
|
|
2
|
+
import { zodToJsonSchema } from "zod-to-json-schema";
|
|
3
|
+
import { CrudSchemaBuilder } from "@drax/crud-back";
|
|
4
|
+
import { LoginBodyRequestSchema, LoginBodyResponseSchema } from "../schemas/LoginSchema.js";
|
|
5
|
+
import { UserSchema, UserCreateSchema, UserUpdateSchema } from "../schemas/UserSchema.js";
|
|
6
|
+
import { RegisterBodyRequestSchema, RegisterBodyResponseSchema } from "../schemas/RegisterSchema.js";
|
|
7
|
+
import { MyPasswordBodyRequestSchema, PasswordBodyRequestSchema, PasswordBodyResponseSchema } from "../schemas/PasswordSchema.js";
|
|
2
8
|
async function UserRoutes(fastify, options) {
|
|
3
9
|
const controller = new UserController();
|
|
4
|
-
|
|
5
|
-
fastify.get('/api/
|
|
6
|
-
fastify.get('/api/users/
|
|
7
|
-
fastify.get('/api/users
|
|
8
|
-
fastify.
|
|
9
|
-
fastify.
|
|
10
|
-
fastify.
|
|
11
|
-
fastify.
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
10
|
+
const schemas = new CrudSchemaBuilder(UserSchema, UserCreateSchema, UserUpdateSchema, 'tenant', 'openApi3', ['Identity']);
|
|
11
|
+
fastify.get('/api/users/search', { schema: schemas.searchSchema }, async (req, rep) => await controller.search(req, rep));
|
|
12
|
+
fastify.get('/api/users/export', { schema: schemas.exportSchema }, (req, rep) => controller.export(req, rep));
|
|
13
|
+
fastify.get('/api/users', { schema: schemas.paginateSchema }, (req, rep) => controller.paginate(req, rep));
|
|
14
|
+
fastify.post('/api/users', { schema: schemas.createSchema }, (req, rep) => controller.create(req, rep));
|
|
15
|
+
fastify.put('/api/users/:id', { schema: schemas.updateSchema }, (req, rep) => controller.update(req, rep));
|
|
16
|
+
fastify.delete('/api/users/:id', { schema: schemas.deleteSchema }, (req, rep) => controller.delete(req, rep));
|
|
17
|
+
fastify.post('/api/auth/login', {
|
|
18
|
+
schema: {
|
|
19
|
+
tags: ['Auth'],
|
|
20
|
+
body: zodToJsonSchema(LoginBodyRequestSchema),
|
|
21
|
+
response: {
|
|
22
|
+
200: zodToJsonSchema(LoginBodyResponseSchema),
|
|
23
|
+
400: schemas.jsonErrorBodyResponse,
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
}, (req, rep) => controller.auth(req, rep));
|
|
27
|
+
fastify.get('/api/auth/me', {
|
|
28
|
+
schema: {
|
|
29
|
+
tags: ['Auth'],
|
|
30
|
+
response: {
|
|
31
|
+
200: schemas.jsonEntitySchema,
|
|
32
|
+
401: schemas.jsonErrorBodyResponse,
|
|
33
|
+
500: schemas.jsonErrorBodyResponse,
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
}, (req, rep) => controller.me(req, rep));
|
|
37
|
+
fastify.post('/api/users/register', {
|
|
38
|
+
schema: {
|
|
39
|
+
tags: ['Auth'],
|
|
40
|
+
body: zodToJsonSchema(RegisterBodyRequestSchema),
|
|
41
|
+
response: {
|
|
42
|
+
200: zodToJsonSchema(RegisterBodyResponseSchema),
|
|
43
|
+
400: schemas.jsonErrorBodyResponse,
|
|
44
|
+
500: schemas.jsonErrorBodyResponse,
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
}, (req, rep) => controller.register(req, rep));
|
|
48
|
+
fastify.get('/api/users/verify-email/:code', {
|
|
49
|
+
schema: {
|
|
50
|
+
tags: ['Auth'],
|
|
51
|
+
}
|
|
52
|
+
}, (req, rep) => controller.verifyEmail(req, rep));
|
|
53
|
+
fastify.get('/api/users/verify-phone/:code', {
|
|
54
|
+
schema: {
|
|
55
|
+
tags: ['Auth'],
|
|
56
|
+
}
|
|
57
|
+
}, (req, rep) => controller.verifyPhone(req, rep));
|
|
58
|
+
fastify.post('/api/users/password/change', {
|
|
59
|
+
schema: {
|
|
60
|
+
tags: ['Auth'],
|
|
61
|
+
body: zodToJsonSchema(MyPasswordBodyRequestSchema),
|
|
62
|
+
200: zodToJsonSchema(PasswordBodyResponseSchema),
|
|
63
|
+
400: schemas.jsonErrorBodyResponse,
|
|
64
|
+
500: schemas.jsonErrorBodyResponse,
|
|
65
|
+
}
|
|
66
|
+
}, (req, rep) => controller.changeMyPassword(req, rep));
|
|
67
|
+
fastify.post('/api/users/password/change/:id', {
|
|
68
|
+
schema: {
|
|
69
|
+
tags: ['Auth'],
|
|
70
|
+
body: zodToJsonSchema(PasswordBodyRequestSchema),
|
|
71
|
+
200: zodToJsonSchema(PasswordBodyResponseSchema),
|
|
72
|
+
400: schemas.jsonErrorBodyResponse,
|
|
73
|
+
500: schemas.jsonErrorBodyResponse,
|
|
74
|
+
}
|
|
75
|
+
}, (req, rep) => controller.changePassword(req, rep));
|
|
76
|
+
fastify.post('/api/users/password/recovery/request', {
|
|
77
|
+
schema: {
|
|
78
|
+
tags: ['Auth'],
|
|
79
|
+
}
|
|
80
|
+
}, (req, rep) => controller.passwordRecoveryRequest(req, rep));
|
|
81
|
+
fastify.post('/api/users/password/recovery/complete', {
|
|
82
|
+
schema: {
|
|
83
|
+
tags: ['Auth'],
|
|
84
|
+
}
|
|
85
|
+
}, (req, rep) => controller.recoveryPasswordComplete(req, rep));
|
|
86
|
+
fastify.post('/api/users/avatar', {
|
|
87
|
+
schema: {
|
|
88
|
+
tags: ['Auth'],
|
|
89
|
+
}
|
|
90
|
+
}, (req, rep) => controller.updateAvatar(req, rep));
|
|
91
|
+
fastify.get('/api/users/avatar/:filename', {
|
|
92
|
+
schema: {
|
|
93
|
+
tags: ['Auth'],
|
|
94
|
+
}
|
|
95
|
+
}, (req, rep) => controller.getAvatar(req, rep));
|
|
21
96
|
}
|
|
22
97
|
export default UserRoutes;
|
|
23
98
|
export { UserRoutes };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import z from "zod";
|
|
2
|
+
const MyPasswordBodyRequestSchema = z.object({
|
|
3
|
+
currentPassword: z.string(),
|
|
4
|
+
newPassword: z.string(),
|
|
5
|
+
});
|
|
6
|
+
const PasswordBodyRequestSchema = z.object({
|
|
7
|
+
newPassword: z.string()
|
|
8
|
+
});
|
|
9
|
+
const PasswordBodyResponseSchema = z.object({
|
|
10
|
+
message: z.string()
|
|
11
|
+
});
|
|
12
|
+
export { MyPasswordBodyRequestSchema, PasswordBodyRequestSchema, PasswordBodyResponseSchema };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import z, { string } from "zod";
|
|
2
|
+
const RegisterBodyRequestSchema = z.object({
|
|
3
|
+
name: string({ required_error: "validation.required" })
|
|
4
|
+
.min(1, "validation.required"),
|
|
5
|
+
username: string({ required_error: "validation.required" })
|
|
6
|
+
.min(1, "validation.required"),
|
|
7
|
+
email: string({ required_error: "validation.required" })
|
|
8
|
+
.email("validation.email.invalid"),
|
|
9
|
+
phone: string({ required_error: "validation.required" }).optional(),
|
|
10
|
+
password: string({ required_error: "validation.required" })
|
|
11
|
+
.min(1, "validation.required")
|
|
12
|
+
.min(8, "validation.password.min8")
|
|
13
|
+
.max(64, "validation.password.max64"),
|
|
14
|
+
});
|
|
15
|
+
const RegisterBodyResponseSchema = z.object({
|
|
16
|
+
success: z.boolean(),
|
|
17
|
+
message: z.string().optional(),
|
|
18
|
+
});
|
|
19
|
+
export { RegisterBodyRequestSchema, RegisterBodyResponseSchema };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { date, object, string, array, boolean } from "zod";
|
|
2
|
+
const RoleBaseSchema = object({
|
|
3
|
+
name: string({ required_error: "validation.required" })
|
|
4
|
+
.min(1, "validation.required")
|
|
5
|
+
.regex(/^[A-Z]/, "validation.startWithUpperCase"),
|
|
6
|
+
permissions: array(string()).optional(),
|
|
7
|
+
childRoles: array(string()).optional(),
|
|
8
|
+
});
|
|
9
|
+
const RoleSchema = RoleBaseSchema.extend({
|
|
10
|
+
_id: string(),
|
|
11
|
+
id: string().optional(),
|
|
12
|
+
permissions: array(string()).optional(),
|
|
13
|
+
readonly: boolean(),
|
|
14
|
+
childRoles: array(object({
|
|
15
|
+
_id: string(),
|
|
16
|
+
id: string().optional(),
|
|
17
|
+
name: string()
|
|
18
|
+
})).optional(),
|
|
19
|
+
createdAt: date().optional(),
|
|
20
|
+
updatedAt: date().optional()
|
|
21
|
+
});
|
|
22
|
+
export default RoleSchema;
|
|
23
|
+
export { RoleSchema, RoleBaseSchema };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { object, string, date } from "zod";
|
|
2
|
+
const TenantBaseSchema = object({
|
|
3
|
+
name: string({ required_error: "validation.required" })
|
|
4
|
+
.min(1, "validation.required")
|
|
5
|
+
.regex(/^[A-Z]/, "validation.startWithUpperCase"),
|
|
6
|
+
});
|
|
7
|
+
const TenantSchema = TenantBaseSchema.extend({
|
|
8
|
+
_id: string(),
|
|
9
|
+
id: string().optional(),
|
|
10
|
+
createdAt: date(),
|
|
11
|
+
updatedAt: date()
|
|
12
|
+
});
|
|
13
|
+
export { TenantSchema, TenantBaseSchema };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { array, object, string } from "zod";
|
|
2
|
+
const UserApiKeyBaseSchema = object({
|
|
3
|
+
name: string({ required_error: "validation.required" })
|
|
4
|
+
.min(1, "validation.required"),
|
|
5
|
+
ipv4: array(string().ip({ version: "v4", message: 'validation.invalidIpv4' })),
|
|
6
|
+
ipv6: array(string().ip({ version: "v6", message: 'validation.invalidIpv6' })),
|
|
7
|
+
});
|
|
8
|
+
const UserApiKeySchema = UserApiKeyBaseSchema.extend({
|
|
9
|
+
_id: string(),
|
|
10
|
+
id: string().optional(),
|
|
11
|
+
createdBy: string(),
|
|
12
|
+
});
|
|
13
|
+
export default UserApiKeyBaseSchema;
|
|
14
|
+
export { UserApiKeyBaseSchema, UserApiKeySchema };
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { date, object, string, boolean, array } from "zod";
|
|
2
|
+
const UserBaseSchema = object({
|
|
3
|
+
name: string({ required_error: "validation.required" })
|
|
4
|
+
.min(1, "validation.required"),
|
|
5
|
+
username: string({ required_error: "validation.required" })
|
|
6
|
+
.min(1, "validation.required"),
|
|
7
|
+
email: string({ required_error: "validation.required" })
|
|
8
|
+
.email("validation.email.invalid"),
|
|
9
|
+
phone: string({ required_error: "validation.required" }).optional(),
|
|
10
|
+
active: boolean().optional(),
|
|
11
|
+
role: string({ required_error: "validation.required" })
|
|
12
|
+
.min(1, "validation.required"),
|
|
13
|
+
tenant: string({ required_error: "validation.required" }).nullable().optional()
|
|
14
|
+
});
|
|
15
|
+
const UserCreateSchema = UserBaseSchema.extend({
|
|
16
|
+
password: string({ required_error: "validation.required" })
|
|
17
|
+
.min(1, "validation.required")
|
|
18
|
+
.min(8, "validation.password.min8")
|
|
19
|
+
.max(64, "validation.password.max64"),
|
|
20
|
+
});
|
|
21
|
+
const UserUpdateSchema = UserBaseSchema.extend({});
|
|
22
|
+
const UserSchema = UserBaseSchema
|
|
23
|
+
.extend({
|
|
24
|
+
_id: string(),
|
|
25
|
+
role: object({
|
|
26
|
+
_id: string(),
|
|
27
|
+
id: string().optional(),
|
|
28
|
+
name: string(),
|
|
29
|
+
permissions: array(string())
|
|
30
|
+
}).optional(),
|
|
31
|
+
active: boolean(),
|
|
32
|
+
tenant: object({
|
|
33
|
+
_id: string(),
|
|
34
|
+
id: string().optional(),
|
|
35
|
+
name: string(),
|
|
36
|
+
}).nullable().optional(),
|
|
37
|
+
createdAt: date().optional()
|
|
38
|
+
});
|
|
39
|
+
export { UserBaseSchema, UserSchema, UserCreateSchema, UserUpdateSchema, };
|