@drax/identity-back 0.5.6 → 0.5.12
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/UserController.js +27 -0
- package/dist/repository/mongo/UserMongoRepository.js +11 -5
- package/dist/routes/UserRoutes.js +1 -0
- package/dist/services/RoleService.js +2 -3
- package/dist/services/TenantService.js +2 -3
- package/dist/services/UserService.js +2 -3
- package/package.json +4 -4
- package/src/controllers/UserController.ts +27 -0
- package/src/interfaces/IUserRepository.ts +1 -1
- package/src/repository/mongo/UserMongoRepository.ts +15 -7
- package/src/routes/UserRoutes.ts +2 -0
- package/src/services/RoleService.ts +2 -3
- package/src/services/TenantService.ts +2 -3
- package/src/services/UserService.ts +2 -3
- package/tsconfig.tsbuildinfo +1 -1
- package/types/controllers/UserController.d.ts +1 -0
- package/types/controllers/UserController.d.ts.map +1 -1
- package/types/interfaces/IUserRepository.d.ts.map +1 -1
- package/types/models/RoleModel.d.ts +4 -0
- package/types/models/RoleModel.d.ts.map +1 -1
- package/types/models/TenantModel.d.ts +4 -0
- package/types/models/TenantModel.d.ts.map +1 -1
- package/types/models/UserApiKeyModel.d.ts +4 -0
- package/types/models/UserApiKeyModel.d.ts.map +1 -1
- package/types/models/UserGroupModel.d.ts +4 -0
- package/types/models/UserGroupModel.d.ts.map +1 -1
- package/types/models/UserModel.d.ts +4 -0
- package/types/models/UserModel.d.ts.map +1 -1
- package/types/repository/mongo/UserMongoRepository.d.ts +3 -0
- package/types/repository/mongo/UserMongoRepository.d.ts.map +1 -1
- package/types/routes/UserRoutes.d.ts.map +1 -1
- package/types/services/RoleService.d.ts +1 -1
- package/types/services/RoleService.d.ts.map +1 -1
- package/types/services/TenantService.d.ts +1 -1
- package/types/services/TenantService.d.ts.map +1 -1
- package/types/services/UserService.d.ts +1 -1
- package/types/services/UserService.d.ts.map +1 -1
- package/types/zod/UserZod.d.ts +6 -6
|
@@ -92,6 +92,33 @@ class UserController extends AbstractFastifyController {
|
|
|
92
92
|
}
|
|
93
93
|
}
|
|
94
94
|
}
|
|
95
|
+
async search(request, reply) {
|
|
96
|
+
try {
|
|
97
|
+
request.rbac.assertPermission(UserPermissions.View);
|
|
98
|
+
const filters = [];
|
|
99
|
+
if (request.rbac.getAuthUser.tenantId) {
|
|
100
|
+
filters.push({ field: 'tenant', operator: 'eq', value: request.rbac.getAuthUser.tenantId });
|
|
101
|
+
}
|
|
102
|
+
const search = request.query.search;
|
|
103
|
+
let item = await this.service.search(search, 1000, filters);
|
|
104
|
+
return item;
|
|
105
|
+
}
|
|
106
|
+
catch (e) {
|
|
107
|
+
console.error(e);
|
|
108
|
+
if (e instanceof ValidationError) {
|
|
109
|
+
reply.statusCode = e.statusCode;
|
|
110
|
+
reply.send({ error: e.message, inputErrors: e.errors });
|
|
111
|
+
}
|
|
112
|
+
else if (e instanceof UnauthorizedError) {
|
|
113
|
+
reply.statusCode = e.statusCode;
|
|
114
|
+
reply.send({ error: e.message });
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
reply.statusCode = 500;
|
|
118
|
+
reply.send({ error: 'INTERNAL_SERVER_ERROR' });
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
95
122
|
async create(request, reply) {
|
|
96
123
|
try {
|
|
97
124
|
request.rbac.assertPermission(UserPermissions.Create);
|
|
@@ -4,6 +4,7 @@ import { MongoServerError } from "mongodb";
|
|
|
4
4
|
import RoleMongoRepository from "./RoleMongoRepository.js";
|
|
5
5
|
class UserMongoRepository {
|
|
6
6
|
constructor() {
|
|
7
|
+
this._searchFields = ['name', 'username', 'email', 'phone'];
|
|
7
8
|
this.roleRepository = new RoleMongoRepository();
|
|
8
9
|
}
|
|
9
10
|
async create(userData) {
|
|
@@ -53,11 +54,7 @@ class UserMongoRepository {
|
|
|
53
54
|
async paginate({ page = 1, limit = 5, orderBy = '', order = false, search = '', filters = [] }) {
|
|
54
55
|
const query = {};
|
|
55
56
|
if (search) {
|
|
56
|
-
query['$or'] = [
|
|
57
|
-
{ username: new RegExp(search, 'i') },
|
|
58
|
-
{ email: new RegExp(search, 'i') },
|
|
59
|
-
{ name: new RegExp(search, 'i') },
|
|
60
|
-
];
|
|
57
|
+
query['$or'] = this._searchFields.map(field => ({ [field]: new RegExp(search.toString(), 'i') }));
|
|
61
58
|
}
|
|
62
59
|
MongooseQueryFilter.applyFilters(query, filters);
|
|
63
60
|
const sort = MongooseSort.applySort(orderBy, order);
|
|
@@ -70,6 +67,15 @@ class UserMongoRepository {
|
|
|
70
67
|
items: userPaginated.docs
|
|
71
68
|
};
|
|
72
69
|
}
|
|
70
|
+
async search(value, limit = 1000, filters = []) {
|
|
71
|
+
const query = {};
|
|
72
|
+
if (value) {
|
|
73
|
+
query['$or'] = this._searchFields.map(field => ({ [field]: new RegExp(value.toString(), 'i') }));
|
|
74
|
+
}
|
|
75
|
+
MongooseQueryFilter.applyFilters(query, filters);
|
|
76
|
+
const items = await UserModel.find(query).limit(limit).exec();
|
|
77
|
+
return items;
|
|
78
|
+
}
|
|
73
79
|
async changePassword(id, password) {
|
|
74
80
|
try {
|
|
75
81
|
await UserModel.findOneAndUpdate({ _id: id }, { password }).exec();
|
|
@@ -3,6 +3,7 @@ async function UserRoutes(fastify, options) {
|
|
|
3
3
|
const controller = new UserController();
|
|
4
4
|
fastify.post('/api/auth', (req, rep) => controller.auth(req, rep));
|
|
5
5
|
fastify.get('/api/me', (req, rep) => controller.me(req, rep));
|
|
6
|
+
fastify.get('/api/users/search', (req, rep) => controller.search(req, rep));
|
|
6
7
|
fastify.get('/api/users/export', (req, rep) => controller.export(req, rep));
|
|
7
8
|
fastify.get('/api/users', (req, rep) => controller.paginate(req, rep));
|
|
8
9
|
fastify.post('/api/users', (req, rep) => controller.create(req, rep));
|
|
@@ -105,9 +105,8 @@ class RoleService extends AbstractService {
|
|
|
105
105
|
const roles = await this._repository.fetchAll();
|
|
106
106
|
return roles;
|
|
107
107
|
}
|
|
108
|
-
async search(value) {
|
|
109
|
-
const
|
|
110
|
-
const roles = await this._repository.search(value, limit);
|
|
108
|
+
async search(value, limit = 1000, filters = []) {
|
|
109
|
+
const roles = await this._repository.search(value, limit, filters);
|
|
111
110
|
return roles;
|
|
112
111
|
}
|
|
113
112
|
async paginate({ page = 1, limit = 5, orderBy = '', order = false, search = '', filters = [] }) {
|
|
@@ -78,9 +78,8 @@ class TenantService extends AbstractService {
|
|
|
78
78
|
throw e;
|
|
79
79
|
}
|
|
80
80
|
}
|
|
81
|
-
async search(value) {
|
|
82
|
-
const
|
|
83
|
-
const tenants = await this._repository.search(value, limit);
|
|
81
|
+
async search(value, limit = 1000, filters = []) {
|
|
82
|
+
const tenants = await this._repository.search(value, limit, filters);
|
|
84
83
|
return tenants;
|
|
85
84
|
}
|
|
86
85
|
async paginate({ page = 1, limit = 5, orderBy = '', order = false, search = '', filters = [] }) {
|
|
@@ -144,9 +144,8 @@ class UserService extends AbstractService {
|
|
|
144
144
|
throw e;
|
|
145
145
|
}
|
|
146
146
|
}
|
|
147
|
-
async search(value) {
|
|
148
|
-
const
|
|
149
|
-
const users = await this._repository.search(value, limit);
|
|
147
|
+
async search(value, limit = 1000, filters = []) {
|
|
148
|
+
const users = await this._repository.search(value, limit, filters);
|
|
150
149
|
return users;
|
|
151
150
|
}
|
|
152
151
|
}
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "0.5.
|
|
6
|
+
"version": "0.5.12",
|
|
7
7
|
"description": "Identity module for user management, authentication and authorization.",
|
|
8
8
|
"main": "dist/index.js",
|
|
9
9
|
"types": "dist/types/index.d.ts",
|
|
@@ -29,8 +29,8 @@
|
|
|
29
29
|
"license": "ISC",
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"@drax/common-back": "^0.5.6",
|
|
32
|
-
"@drax/crud-back": "^0.5.
|
|
33
|
-
"@drax/crud-share": "^0.5.
|
|
32
|
+
"@drax/crud-back": "^0.5.12",
|
|
33
|
+
"@drax/crud-share": "^0.5.12",
|
|
34
34
|
"@drax/identity-share": "^0.5.1",
|
|
35
35
|
"bcryptjs": "^2.4.3",
|
|
36
36
|
"express-jwt": "^8.4.1",
|
|
@@ -62,5 +62,5 @@
|
|
|
62
62
|
"debug": "0"
|
|
63
63
|
}
|
|
64
64
|
},
|
|
65
|
-
"gitHead": "
|
|
65
|
+
"gitHead": "440be142d8877498814d5c4914e645004fd60f90"
|
|
66
66
|
}
|
|
@@ -8,6 +8,7 @@ import UserPermissions from "../permissions/UserPermissions.js";
|
|
|
8
8
|
import BadCredentialsError from "../errors/BadCredentialsError.js";
|
|
9
9
|
import {join} from "path";
|
|
10
10
|
import {IdentityConfig} from "../config/IdentityConfig.js";
|
|
11
|
+
import type {FastifyReply} from "fastify";
|
|
11
12
|
|
|
12
13
|
const BASE_FILE_DIR = DraxConfig.getOrLoad(CommonConfig.FileDir) || 'files';
|
|
13
14
|
const AVATAR_DIR = DraxConfig.getOrLoad(IdentityConfig.AvatarDir) || 'avatar';
|
|
@@ -98,6 +99,32 @@ class UserController extends AbstractFastifyController<IUser, IUserCreate, IUser
|
|
|
98
99
|
}
|
|
99
100
|
}
|
|
100
101
|
|
|
102
|
+
|
|
103
|
+
async search(request, reply) {
|
|
104
|
+
try {
|
|
105
|
+
request.rbac.assertPermission(UserPermissions.View)
|
|
106
|
+
const filters = []
|
|
107
|
+
if(request.rbac.getAuthUser.tenantId){
|
|
108
|
+
filters.push({field: 'tenant', operator: 'eq', value: request.rbac.getAuthUser.tenantId})
|
|
109
|
+
}
|
|
110
|
+
const search = request.query.search
|
|
111
|
+
let item = await this.service.search(search,1000,filters)
|
|
112
|
+
return item
|
|
113
|
+
} catch (e) {
|
|
114
|
+
console.error(e)
|
|
115
|
+
if (e instanceof ValidationError) {
|
|
116
|
+
reply.statusCode = e.statusCode
|
|
117
|
+
reply.send({error: e.message, inputErrors: e.errors})
|
|
118
|
+
} else if (e instanceof UnauthorizedError) {
|
|
119
|
+
reply.statusCode = e.statusCode
|
|
120
|
+
reply.send({error: e.message})
|
|
121
|
+
} else {
|
|
122
|
+
reply.statusCode = 500
|
|
123
|
+
reply.send({error: 'INTERNAL_SERVER_ERROR'})
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
101
128
|
async create(request, reply) {
|
|
102
129
|
try {
|
|
103
130
|
request.rbac.assertPermission(UserPermissions.Create)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {IUser, IUserCreate, IUserUpdate} from '@drax/identity-share'
|
|
2
|
-
import {IDraxCrud} from "@drax/crud-share";
|
|
2
|
+
import {IDraxCrud, IDraxFieldFilter} from "@drax/crud-share";
|
|
3
3
|
|
|
4
4
|
interface IUserRepository extends IDraxCrud<IUser, IUserCreate, IUserUpdate>{
|
|
5
5
|
findById(id: string): Promise<IUser | null>;
|
|
@@ -12,11 +12,12 @@ import type {IUserRepository} from "../../interfaces/IUserRepository";
|
|
|
12
12
|
import {Cursor, PaginateResult} from "mongoose";
|
|
13
13
|
import RoleMongoRepository from "./RoleMongoRepository.js";
|
|
14
14
|
import {IDraxFindOptions, IDraxPaginateOptions, IDraxPaginateResult} from "@drax/crud-share";
|
|
15
|
-
import {IRole} from "@drax/identity-share";
|
|
15
|
+
import {IRole, ITenant} from "@drax/identity-share";
|
|
16
|
+
import type {IDraxFieldFilter} from "@drax/crud-share/dist";
|
|
16
17
|
|
|
17
18
|
class UserMongoRepository implements IUserRepository {
|
|
18
19
|
private roleRepository: RoleMongoRepository;
|
|
19
|
-
|
|
20
|
+
_searchFields = ['name','username','email','phone']
|
|
20
21
|
|
|
21
22
|
constructor() {
|
|
22
23
|
this.roleRepository = new RoleMongoRepository()
|
|
@@ -84,11 +85,7 @@ class UserMongoRepository implements IUserRepository {
|
|
|
84
85
|
const query = {}
|
|
85
86
|
|
|
86
87
|
if(search){
|
|
87
|
-
query['$or'] = [
|
|
88
|
-
{username: new RegExp(search, 'i')},
|
|
89
|
-
{email: new RegExp(search, 'i')},
|
|
90
|
-
{name: new RegExp(search, 'i')},
|
|
91
|
-
]
|
|
88
|
+
query['$or'] = this._searchFields.map(field => ({[field]: new RegExp(search.toString(), 'i')}))
|
|
92
89
|
}
|
|
93
90
|
|
|
94
91
|
MongooseQueryFilter.applyFilters(query, filters)
|
|
@@ -106,6 +103,17 @@ class UserMongoRepository implements IUserRepository {
|
|
|
106
103
|
}
|
|
107
104
|
}
|
|
108
105
|
|
|
106
|
+
|
|
107
|
+
async search(value: string, limit: number = 1000, filters: IDraxFieldFilter[] = []): Promise<IUser[]> {
|
|
108
|
+
const query = {}
|
|
109
|
+
if(value){
|
|
110
|
+
query['$or'] = this._searchFields.map(field => ({[field]: new RegExp(value.toString(), 'i')}))
|
|
111
|
+
}
|
|
112
|
+
MongooseQueryFilter.applyFilters(query, filters)
|
|
113
|
+
const items: mongoose.HydratedDocument<IUser>[] = await UserModel.find(query).limit(limit).exec()
|
|
114
|
+
return items
|
|
115
|
+
}
|
|
116
|
+
|
|
109
117
|
async changePassword(id: string, password: string):Promise<boolean> {
|
|
110
118
|
try{
|
|
111
119
|
await UserModel.findOneAndUpdate({_id: id}, {password}).exec()
|
package/src/routes/UserRoutes.ts
CHANGED
|
@@ -8,6 +8,8 @@ async function UserRoutes(fastify, options) {
|
|
|
8
8
|
|
|
9
9
|
fastify.get('/api/me', (req,rep) => controller.me(req,rep))
|
|
10
10
|
|
|
11
|
+
fastify.get('/api/users/search', (req,rep) => controller.search(req,rep) )
|
|
12
|
+
|
|
11
13
|
fastify.get('/api/users/export', (req,rep) => controller.export(req,rep) )
|
|
12
14
|
|
|
13
15
|
fastify.get('/api/users', (req,rep) => controller.paginate(req,rep))
|
|
@@ -116,9 +116,8 @@ class RoleService extends AbstractService<IRole, IRoleBase, IRoleBase> {
|
|
|
116
116
|
return roles
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
-
async search(value: any): Promise<IRole[]> {
|
|
120
|
-
const
|
|
121
|
-
const roles: IRole[] = await this._repository.search(value, limit);
|
|
119
|
+
async search(value: any, limit=1000, filters=[]): Promise<IRole[]> {
|
|
120
|
+
const roles: IRole[] = await this._repository.search(value, limit, filters);
|
|
122
121
|
return roles;
|
|
123
122
|
}
|
|
124
123
|
|
|
@@ -90,9 +90,8 @@ class TenantService extends AbstractService<ITenant,ITenantBase,ITenantBase> {
|
|
|
90
90
|
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
-
async search(value: any): Promise<ITenant[]> {
|
|
94
|
-
const
|
|
95
|
-
const tenants: ITenant[] = await this._repository.search(value, limit);
|
|
93
|
+
async search(value: any, limit=1000, filters=[]): Promise<ITenant[]> {
|
|
94
|
+
const tenants: ITenant[] = await this._repository.search(value, limit,filters);
|
|
96
95
|
return tenants;
|
|
97
96
|
}
|
|
98
97
|
|
|
@@ -178,9 +178,8 @@ class UserService extends AbstractService<IUser, IUserCreate, IUserUpdate>{
|
|
|
178
178
|
|
|
179
179
|
}
|
|
180
180
|
|
|
181
|
-
async search(value: any): Promise<IUser[]> {
|
|
182
|
-
const
|
|
183
|
-
const users: IUser[] = await this._repository.search(value, limit);
|
|
181
|
+
async search(value: any, limit: number = 1000, filters = []): Promise<IUser[]> {
|
|
182
|
+
const users: IUser[] = await this._repository.search(value, limit, filters);
|
|
184
183
|
return users;
|
|
185
184
|
}
|
|
186
185
|
}
|