@drax/identity-back 0.13.0 → 0.13.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/middleware/apiKeyMiddleware.js +7 -3
- package/dist/rbac/Rbac.js +20 -3
- package/dist/repository/mongo/UserApiKeyMongoRepository.js +1 -1
- package/dist/repository/mongo/UserMongoRepository.js +1 -1
- package/package.json +4 -4
- package/src/middleware/apiKeyMiddleware.ts +8 -4
- package/src/rbac/Rbac.ts +33 -8
- package/src/repository/mongo/UserApiKeyMongoRepository.ts +1 -1
- package/src/repository/mongo/UserMongoRepository.ts +1 -1
- package/test/repository/mongo/user-apikey-mongo-repository.test.ts +3 -4
- package/test/repository/mongo/user-mongo-repository.test.ts +4 -1
- package/test/routes/helpers/FastifyTestServerFactory.ts +0 -8
- package/test/routes/user-route.test.ts +3 -4
- package/tsconfig.tsbuildinfo +1 -1
- package/types/middleware/apiKeyMiddleware.d.ts.map +1 -1
- package/types/rbac/Rbac.d.ts +5 -2
- package/types/rbac/Rbac.d.ts.map +1 -1
- package/types/repository/mongo/UserApiKeyMongoRepository.d.ts.map +1 -1
- package/types/repository/mongo/UserMongoRepository.d.ts.map +1 -1
|
@@ -21,9 +21,13 @@ async function apiKeyMiddleware(request, reply) {
|
|
|
21
21
|
if (apiKey) {
|
|
22
22
|
const userApiKey = await draxCache.getOrLoad(apiKey, userApiKeyLoader);
|
|
23
23
|
if (userApiKey && userApiKey.user) {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
const authUser = {
|
|
25
|
+
id: userApiKey.user._id.toString(),
|
|
26
|
+
username: userApiKey.user.username,
|
|
27
|
+
roleId: userApiKey.user.role?._id?.toString(),
|
|
28
|
+
tenantId: userApiKey.user?.tenant?._id?.toString(),
|
|
29
|
+
};
|
|
30
|
+
request.authUser = authUser;
|
|
27
31
|
}
|
|
28
32
|
}
|
|
29
33
|
return;
|
package/dist/rbac/Rbac.js
CHANGED
|
@@ -8,13 +8,24 @@ class Rbac {
|
|
|
8
8
|
return this.role;
|
|
9
9
|
}
|
|
10
10
|
get getAuthUser() {
|
|
11
|
-
return
|
|
11
|
+
return {
|
|
12
|
+
id: this.userId,
|
|
13
|
+
username: this.username,
|
|
14
|
+
roleId: this.roleId,
|
|
15
|
+
tenantId: this.tenantId
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
get username() {
|
|
19
|
+
return this.authUser.username;
|
|
12
20
|
}
|
|
13
21
|
get userId() {
|
|
14
|
-
return this.authUser.
|
|
22
|
+
return this.authUser?.id.toString();
|
|
23
|
+
}
|
|
24
|
+
get roleId() {
|
|
25
|
+
return this.authUser?.roleId.toString();
|
|
15
26
|
}
|
|
16
27
|
get tenantId() {
|
|
17
|
-
return this.authUser
|
|
28
|
+
return this.authUser?.tenantId?.toString();
|
|
18
29
|
}
|
|
19
30
|
assertAuthenticated() {
|
|
20
31
|
if (!this.authUser) {
|
|
@@ -43,11 +54,17 @@ class Rbac {
|
|
|
43
54
|
throw new ForbiddenError();
|
|
44
55
|
}
|
|
45
56
|
assertUserId(userId) {
|
|
57
|
+
if (userId && typeof userId != 'string') {
|
|
58
|
+
throw new Error('Rbac Error: userId must be a string');
|
|
59
|
+
}
|
|
46
60
|
if (this.userId != userId) {
|
|
47
61
|
throw new UnauthorizedError();
|
|
48
62
|
}
|
|
49
63
|
}
|
|
50
64
|
assertTenantId(tenantId) {
|
|
65
|
+
if (tenantId && typeof tenantId != 'string') {
|
|
66
|
+
throw new Error('Rbac Error: tenantId must be a string or null|undefined');
|
|
67
|
+
}
|
|
51
68
|
if (this.tenantId && this.tenantId != tenantId) {
|
|
52
69
|
throw new UnauthorizedError();
|
|
53
70
|
}
|
|
@@ -10,7 +10,7 @@ class UserApiKeyMongoRepository extends AbstractMongoRepository {
|
|
|
10
10
|
{ path: 'createdBy', populate: { path: 'tenant role' } },
|
|
11
11
|
];
|
|
12
12
|
this._model = UserApiKeyModel;
|
|
13
|
-
this._lean =
|
|
13
|
+
this._lean = true;
|
|
14
14
|
}
|
|
15
15
|
async delete(id) {
|
|
16
16
|
const userApiKey = await UserApiKeyModel
|
|
@@ -8,7 +8,7 @@ class UserMongoRepository extends AbstractMongoRepository {
|
|
|
8
8
|
this._searchFields = ['name', 'username', 'email', 'phone'];
|
|
9
9
|
this._populateFields = ['role', 'tenant'];
|
|
10
10
|
this._model = UserModel;
|
|
11
|
-
this._lean =
|
|
11
|
+
this._lean = true;
|
|
12
12
|
this.roleRepository = new RoleMongoRepository();
|
|
13
13
|
}
|
|
14
14
|
async create(userData) {
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "0.13.
|
|
6
|
+
"version": "0.13.1",
|
|
7
7
|
"description": "Identity module for user management, authentication and authorization.",
|
|
8
8
|
"main": "dist/index.js",
|
|
9
9
|
"types": "types/index.d.ts",
|
|
@@ -29,10 +29,10 @@
|
|
|
29
29
|
"license": "ISC",
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"@drax/common-back": "^0.13.0",
|
|
32
|
-
"@drax/crud-back": "^0.13.
|
|
32
|
+
"@drax/crud-back": "^0.13.1",
|
|
33
33
|
"@drax/crud-share": "^0.13.0",
|
|
34
34
|
"@drax/email-back": "^0.13.0",
|
|
35
|
-
"@drax/identity-share": "^0.13.
|
|
35
|
+
"@drax/identity-share": "^0.13.1",
|
|
36
36
|
"bcryptjs": "^2.4.3",
|
|
37
37
|
"express-jwt": "^8.4.1",
|
|
38
38
|
"graphql": "^16.8.2",
|
|
@@ -64,5 +64,5 @@
|
|
|
64
64
|
"debug": "0"
|
|
65
65
|
}
|
|
66
66
|
},
|
|
67
|
-
"gitHead": "
|
|
67
|
+
"gitHead": "240696be4da58de762018927cda04f6c2446a473"
|
|
68
68
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {IUserApiKey} from "@drax/identity-share";
|
|
1
|
+
import {IAuthUser, IUserApiKey} from "@drax/identity-share";
|
|
2
2
|
import {DraxCache, DraxConfig} from "@drax/common-back";
|
|
3
3
|
import UserApiKeyServiceFactory from "../factory/UserApiKeyServiceFactory.js";
|
|
4
4
|
import IdentityConfig from "../config/IdentityConfig.js";
|
|
@@ -29,9 +29,13 @@ async function apiKeyMiddleware (request, reply) {
|
|
|
29
29
|
if(apiKey){
|
|
30
30
|
const userApiKey = await draxCache.getOrLoad(apiKey, userApiKeyLoader)
|
|
31
31
|
if(userApiKey && userApiKey.user){
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
const authUser: IAuthUser = {
|
|
33
|
+
id: userApiKey.user._id.toString(),
|
|
34
|
+
username: userApiKey.user.username,
|
|
35
|
+
roleId: userApiKey.user.role?._id?.toString(),
|
|
36
|
+
tenantId: userApiKey.user?.tenant?._id?.toString(),
|
|
37
|
+
}
|
|
38
|
+
request.authUser = authUser
|
|
35
39
|
}
|
|
36
40
|
}
|
|
37
41
|
return
|
package/src/rbac/Rbac.ts
CHANGED
|
@@ -1,29 +1,43 @@
|
|
|
1
1
|
import type {IJwtUser, IRole, IRbac} from "@drax/identity-share";
|
|
2
2
|
import {UnauthorizedError, ForbiddenError} from "@drax/common-back";
|
|
3
|
+
import {IAuthUser} from "@drax/identity-share/dist";
|
|
3
4
|
|
|
4
5
|
class Rbac implements IRbac{
|
|
5
6
|
private role: IRole;
|
|
6
|
-
private authUser:
|
|
7
|
+
private authUser: IAuthUser;
|
|
7
8
|
|
|
8
9
|
constructor(authUser: IJwtUser, role: IRole) {
|
|
9
10
|
this.authUser = authUser;
|
|
10
11
|
this.role = role;
|
|
11
12
|
}
|
|
12
13
|
|
|
13
|
-
get getRole() {
|
|
14
|
+
get getRole(): IRole {
|
|
14
15
|
return this.role
|
|
15
16
|
}
|
|
16
17
|
|
|
17
|
-
get getAuthUser() {
|
|
18
|
-
return
|
|
18
|
+
get getAuthUser():IAuthUser {
|
|
19
|
+
return {
|
|
20
|
+
id: this.userId,
|
|
21
|
+
username: this.username,
|
|
22
|
+
roleId: this.roleId,
|
|
23
|
+
tenantId: this.tenantId
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
get username(): string{
|
|
28
|
+
return this.authUser.username
|
|
19
29
|
}
|
|
20
30
|
|
|
21
|
-
get userId(){
|
|
22
|
-
return this.authUser.
|
|
31
|
+
get userId(): string {
|
|
32
|
+
return this.authUser?.id.toString()
|
|
23
33
|
}
|
|
24
34
|
|
|
25
|
-
get
|
|
26
|
-
return this.authUser.
|
|
35
|
+
get roleId(): string {
|
|
36
|
+
return this.authUser?.roleId.toString()
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
get tenantId(): string | undefined {
|
|
40
|
+
return this.authUser?.tenantId?.toString();
|
|
27
41
|
}
|
|
28
42
|
|
|
29
43
|
assertAuthenticated() {
|
|
@@ -61,15 +75,26 @@ class Rbac implements IRbac{
|
|
|
61
75
|
|
|
62
76
|
|
|
63
77
|
assertUserId(userId: string) {
|
|
78
|
+
|
|
79
|
+
if(userId && typeof userId != 'string'){
|
|
80
|
+
throw new Error('Rbac Error: userId must be a string')
|
|
81
|
+
}
|
|
82
|
+
|
|
64
83
|
if (this.userId != userId) {
|
|
65
84
|
throw new UnauthorizedError()
|
|
66
85
|
}
|
|
67
86
|
}
|
|
68
87
|
|
|
69
88
|
assertTenantId(tenantId: string) {
|
|
89
|
+
|
|
90
|
+
if(tenantId && typeof tenantId != 'string'){
|
|
91
|
+
throw new Error('Rbac Error: tenantId must be a string or null|undefined')
|
|
92
|
+
}
|
|
93
|
+
|
|
70
94
|
if (this.tenantId && this.tenantId != tenantId) {
|
|
71
95
|
throw new UnauthorizedError()
|
|
72
96
|
}
|
|
97
|
+
|
|
73
98
|
}
|
|
74
99
|
|
|
75
100
|
}
|
|
@@ -18,7 +18,7 @@ class UserApiKeyMongoRepository extends AbstractMongoRepository<IUserApiKey,IUse
|
|
|
18
18
|
{path: 'createdBy', populate: {path: 'tenant role'} },
|
|
19
19
|
]
|
|
20
20
|
protected _model = UserApiKeyModel
|
|
21
|
-
protected _lean =
|
|
21
|
+
protected _lean = true
|
|
22
22
|
|
|
23
23
|
|
|
24
24
|
async delete(id: string): Promise<boolean> {
|
|
@@ -19,7 +19,7 @@ class UserMongoRepository extends AbstractMongoRepository<IUser,IUserCreate,IUse
|
|
|
19
19
|
protected _searchFields = ['name','username','email','phone']
|
|
20
20
|
protected _populateFields = ['role','tenant']
|
|
21
21
|
protected _model = UserModel
|
|
22
|
-
protected _lean =
|
|
22
|
+
protected _lean = true
|
|
23
23
|
|
|
24
24
|
constructor() {
|
|
25
25
|
super()
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {beforeAll, afterAll, describe,
|
|
1
|
+
import {beforeAll, afterAll, describe, test, expect} from "vitest"
|
|
2
2
|
import assert, {equal} from "assert";
|
|
3
3
|
import UserApiKeyMongoRepository from "../../../src/repository/mongo/UserApiKeyMongoRepository";
|
|
4
4
|
import MongoInMemory from "../../db/MongoInMemory";
|
|
@@ -35,14 +35,13 @@ describe("UserApiKeyRepositoryTest", function () {
|
|
|
35
35
|
data = (await import("../../data-obj/apikey/root-mongo-user-apikey")).default
|
|
36
36
|
console.log("Data:",data)
|
|
37
37
|
let userApiKeyCreated = await userApiKeyRepository.create(data)
|
|
38
|
-
|
|
38
|
+
expect(userApiKeyCreated.name).toBe(data.name)
|
|
39
39
|
})
|
|
40
40
|
|
|
41
41
|
test("Find mongo user by ID successfully", async function () {
|
|
42
42
|
data = (await import("../../data-obj/apikey/root-mongo-user-apikey")).default
|
|
43
43
|
let userApiKeyFound = await userApiKeyRepository.findById(data._id)
|
|
44
|
-
|
|
45
|
-
equal(userApiKeyFound.name, data.name)
|
|
44
|
+
expect(userApiKeyFound.name).toBe(data.name)
|
|
46
45
|
})
|
|
47
46
|
|
|
48
47
|
test("Find mongo user by secret successfully", async function () {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {beforeAll, afterAll, describe, test} from "vitest"
|
|
1
|
+
import {beforeAll, afterAll, describe, test, expect} from "vitest"
|
|
2
2
|
import assert, {equal} from "assert";
|
|
3
3
|
import UserMongoRepository from "../../../src/repository/mongo/UserMongoRepository";
|
|
4
4
|
import MongoInMemory from "../../db/MongoInMemory";
|
|
@@ -6,6 +6,7 @@ import RoleMongoInitializer from "../../initializers/RoleMongoInitializer";
|
|
|
6
6
|
import {IUser} from "../../../../identity-share/src/interfaces/IUser";
|
|
7
7
|
import type {IDraxPaginateResult} from "@drax/crud-share";
|
|
8
8
|
import {mongoose, ValidationError} from "@drax/common-back";
|
|
9
|
+
import {object} from "zod";
|
|
9
10
|
|
|
10
11
|
|
|
11
12
|
describe("UserRepositoryTest", function () {
|
|
@@ -102,7 +103,9 @@ describe("UserRepositoryTest", function () {
|
|
|
102
103
|
test("Find mongo user by ID successfully", async function () {
|
|
103
104
|
let adminData = (await import("../../data-obj/users/root-mongo-user")).default
|
|
104
105
|
let userFound = await userRepository.findById(adminData._id)
|
|
106
|
+
console.log("userFound",userFound)
|
|
105
107
|
equal(userFound.username, userAdminData.username)
|
|
108
|
+
expect(userFound).toBeInstanceOf(Object)
|
|
106
109
|
})
|
|
107
110
|
|
|
108
111
|
test("Find mongo user by username successfully", async function () {
|
|
@@ -19,14 +19,6 @@ const FastifyTestServerFactory = () => {
|
|
|
19
19
|
fastify.addHook('onRequest', rbacMiddleware)
|
|
20
20
|
fastify.addHook('onRequest', apiKeyMiddleware)
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
// fastify.addHook('preHandler', async (request, reply) => {
|
|
24
|
-
// //@ts-ignore
|
|
25
|
-
// request.rbac = {assertPermission: () => true, getAuthUser: {username: 'admin', tenantId: ''}};
|
|
26
|
-
// //@ts-ignore
|
|
27
|
-
// request.authUser = {id:USER._id, username: USER.username, tenantId: '', roleId: USER.role};
|
|
28
|
-
// });
|
|
29
|
-
|
|
30
22
|
return fastify
|
|
31
23
|
}
|
|
32
24
|
|
|
@@ -4,12 +4,11 @@ import MongoInMemory from "../db/MongoInMemory";
|
|
|
4
4
|
process.env.DRAX_DB_ENGINE = "mongo"
|
|
5
5
|
process.env.DRAX_JWT_SECRET = "asdasdasd"
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
// import {CreateRootUserAndAdminRole} from "./helpers/CreateRootUserAndAdminRole.js"
|
|
7
|
+
|
|
9
8
|
import {SetupIdentityDrax} from "./helpers/SetupIdentityDrax.js"
|
|
10
9
|
import {FastifyTestServerFactory} from './helpers/FastifyTestServerFactory.js'
|
|
11
|
-
import {
|
|
12
|
-
import {UserRoutes
|
|
10
|
+
import {IUserCreate} from "@drax/identity-share";
|
|
11
|
+
import {UserRoutes} from "../../src/index.js"
|
|
13
12
|
|
|
14
13
|
|
|
15
14
|
const USER1: IUserCreate = {
|