@quanticjs/iam-audit 5.10.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/iam-audit.controller.d.ts +12 -0
- package/dist/controllers/iam-audit.controller.js +125 -0
- package/dist/dtos/iam-audit.dtos.d.ts +74 -0
- package/dist/dtos/iam-audit.dtos.js +2 -0
- package/dist/dtos/keycloak-admin.types.d.ts +45 -0
- package/dist/dtos/keycloak-admin.types.js +2 -0
- package/dist/iam-audit.module.d.ts +5 -0
- package/dist/iam-audit.module.js +49 -0
- package/dist/iam-audit.options.d.ts +7 -0
- package/dist/iam-audit.options.js +4 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +21 -0
- package/dist/queries/get-iam-audit-events.handler.d.ts +12 -0
- package/dist/queries/get-iam-audit-events.handler.js +41 -0
- package/dist/queries/get-iam-audit-events.query.d.ts +5 -0
- package/dist/queries/get-iam-audit-events.query.js +12 -0
- package/dist/queries/get-iam-group-members.handler.d.ts +12 -0
- package/dist/queries/get-iam-group-members.handler.js +39 -0
- package/dist/queries/get-iam-group-members.query.d.ts +6 -0
- package/dist/queries/get-iam-group-members.query.js +14 -0
- package/dist/queries/get-iam-groups.handler.d.ts +14 -0
- package/dist/queries/get-iam-groups.handler.js +60 -0
- package/dist/queries/get-iam-groups.query.d.ts +2 -0
- package/dist/queries/get-iam-groups.query.js +6 -0
- package/dist/queries/get-iam-roles.handler.d.ts +14 -0
- package/dist/queries/get-iam-roles.handler.js +46 -0
- package/dist/queries/get-iam-roles.query.d.ts +2 -0
- package/dist/queries/get-iam-roles.query.js +6 -0
- package/dist/queries/get-iam-user-detail.handler.d.ts +12 -0
- package/dist/queries/get-iam-user-detail.handler.js +61 -0
- package/dist/queries/get-iam-user-detail.query.d.ts +4 -0
- package/dist/queries/get-iam-user-detail.query.js +10 -0
- package/dist/queries/get-iam-users.handler.d.ts +15 -0
- package/dist/queries/get-iam-users.handler.js +60 -0
- package/dist/queries/get-iam-users.query.d.ts +6 -0
- package/dist/queries/get-iam-users.query.js +14 -0
- package/dist/queries/get-permission-matrix.handler.d.ts +12 -0
- package/dist/queries/get-permission-matrix.handler.js +54 -0
- package/dist/queries/get-permission-matrix.query.d.ts +2 -0
- package/dist/queries/get-permission-matrix.query.js +6 -0
- package/dist/services/keycloak-admin.service.d.ts +28 -0
- package/dist/services/keycloak-admin.service.js +144 -0
- package/package.json +30 -0
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { QueryBus } from '@nestjs/cqrs';
|
|
2
|
+
export declare class IamAuditController {
|
|
3
|
+
private readonly queryBus;
|
|
4
|
+
constructor(queryBus: QueryBus);
|
|
5
|
+
listUsers(search: string | undefined, first: string | undefined, max: string | undefined): Promise<any>;
|
|
6
|
+
getUser(id: string): Promise<any>;
|
|
7
|
+
listGroups(): Promise<any>;
|
|
8
|
+
getGroupMembers(id: string, first: string | undefined, max: string | undefined): Promise<any>;
|
|
9
|
+
listRoles(): Promise<any>;
|
|
10
|
+
getPermissionMatrix(): Promise<any>;
|
|
11
|
+
getAuditEvents(first: string | undefined, max: string | undefined): Promise<any>;
|
|
12
|
+
}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.IamAuditController = void 0;
|
|
16
|
+
const common_1 = require("@nestjs/common");
|
|
17
|
+
const cqrs_1 = require("@nestjs/cqrs");
|
|
18
|
+
const swagger_1 = require("@nestjs/swagger");
|
|
19
|
+
const core_1 = require("@quanticjs/core");
|
|
20
|
+
const get_iam_users_query_1 = require("../queries/get-iam-users.query");
|
|
21
|
+
const get_iam_user_detail_query_1 = require("../queries/get-iam-user-detail.query");
|
|
22
|
+
const get_iam_groups_query_1 = require("../queries/get-iam-groups.query");
|
|
23
|
+
const get_iam_group_members_query_1 = require("../queries/get-iam-group-members.query");
|
|
24
|
+
const get_iam_roles_query_1 = require("../queries/get-iam-roles.query");
|
|
25
|
+
const get_permission_matrix_query_1 = require("../queries/get-permission-matrix.query");
|
|
26
|
+
const get_iam_audit_events_query_1 = require("../queries/get-iam-audit-events.query");
|
|
27
|
+
let IamAuditController = class IamAuditController {
|
|
28
|
+
queryBus;
|
|
29
|
+
constructor(queryBus) {
|
|
30
|
+
this.queryBus = queryBus;
|
|
31
|
+
}
|
|
32
|
+
async listUsers(search, first, max) {
|
|
33
|
+
return this.queryBus.execute(new get_iam_users_query_1.GetIamUsersQuery(search, first ? parseInt(first, 10) : undefined, max ? parseInt(max, 10) : undefined));
|
|
34
|
+
}
|
|
35
|
+
async getUser(id) {
|
|
36
|
+
return this.queryBus.execute(new get_iam_user_detail_query_1.GetIamUserDetailQuery(id));
|
|
37
|
+
}
|
|
38
|
+
async listGroups() {
|
|
39
|
+
return this.queryBus.execute(new get_iam_groups_query_1.GetIamGroupsQuery());
|
|
40
|
+
}
|
|
41
|
+
async getGroupMembers(id, first, max) {
|
|
42
|
+
return this.queryBus.execute(new get_iam_group_members_query_1.GetIamGroupMembersQuery(id, first ? parseInt(first, 10) : undefined, max ? parseInt(max, 10) : undefined));
|
|
43
|
+
}
|
|
44
|
+
async listRoles() {
|
|
45
|
+
return this.queryBus.execute(new get_iam_roles_query_1.GetIamRolesQuery());
|
|
46
|
+
}
|
|
47
|
+
async getPermissionMatrix() {
|
|
48
|
+
return this.queryBus.execute(new get_permission_matrix_query_1.GetPermissionMatrixQuery());
|
|
49
|
+
}
|
|
50
|
+
async getAuditEvents(first, max) {
|
|
51
|
+
return this.queryBus.execute(new get_iam_audit_events_query_1.GetIamAuditEventsQuery(first ? parseInt(first, 10) : undefined, max ? parseInt(max, 10) : undefined));
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
exports.IamAuditController = IamAuditController;
|
|
55
|
+
__decorate([
|
|
56
|
+
(0, common_1.Get)('users'),
|
|
57
|
+
(0, swagger_1.ApiOperation)({ summary: 'List users with group memberships and permission counts' }),
|
|
58
|
+
(0, swagger_1.ApiResponse)({ status: 200, description: 'Paginated user list' }),
|
|
59
|
+
__param(0, (0, common_1.Query)('search')),
|
|
60
|
+
__param(1, (0, common_1.Query)('first')),
|
|
61
|
+
__param(2, (0, common_1.Query)('max')),
|
|
62
|
+
__metadata("design:type", Function),
|
|
63
|
+
__metadata("design:paramtypes", [Object, Object, Object]),
|
|
64
|
+
__metadata("design:returntype", Promise)
|
|
65
|
+
], IamAuditController.prototype, "listUsers", null);
|
|
66
|
+
__decorate([
|
|
67
|
+
(0, common_1.Get)('users/:id'),
|
|
68
|
+
(0, swagger_1.ApiOperation)({ summary: 'Get user detail with groups and client roles per app' }),
|
|
69
|
+
(0, swagger_1.ApiResponse)({ status: 200, description: 'User detail' }),
|
|
70
|
+
__param(0, (0, common_1.Param)('id')),
|
|
71
|
+
__metadata("design:type", Function),
|
|
72
|
+
__metadata("design:paramtypes", [String]),
|
|
73
|
+
__metadata("design:returntype", Promise)
|
|
74
|
+
], IamAuditController.prototype, "getUser", null);
|
|
75
|
+
__decorate([
|
|
76
|
+
(0, common_1.Get)('groups'),
|
|
77
|
+
(0, swagger_1.ApiOperation)({ summary: 'List groups with member counts and role assignments' }),
|
|
78
|
+
(0, swagger_1.ApiResponse)({ status: 200, description: 'Group list' }),
|
|
79
|
+
__metadata("design:type", Function),
|
|
80
|
+
__metadata("design:paramtypes", []),
|
|
81
|
+
__metadata("design:returntype", Promise)
|
|
82
|
+
], IamAuditController.prototype, "listGroups", null);
|
|
83
|
+
__decorate([
|
|
84
|
+
(0, common_1.Get)('groups/:id/members'),
|
|
85
|
+
(0, swagger_1.ApiOperation)({ summary: 'List members of a group' }),
|
|
86
|
+
(0, swagger_1.ApiResponse)({ status: 200, description: 'Group member list' }),
|
|
87
|
+
__param(0, (0, common_1.Param)('id')),
|
|
88
|
+
__param(1, (0, common_1.Query)('first')),
|
|
89
|
+
__param(2, (0, common_1.Query)('max')),
|
|
90
|
+
__metadata("design:type", Function),
|
|
91
|
+
__metadata("design:paramtypes", [String, Object, Object]),
|
|
92
|
+
__metadata("design:returntype", Promise)
|
|
93
|
+
], IamAuditController.prototype, "getGroupMembers", null);
|
|
94
|
+
__decorate([
|
|
95
|
+
(0, common_1.Get)('roles'),
|
|
96
|
+
(0, swagger_1.ApiOperation)({ summary: 'List all client roles across all apps' }),
|
|
97
|
+
(0, swagger_1.ApiResponse)({ status: 200, description: 'Roles by client' }),
|
|
98
|
+
__metadata("design:type", Function),
|
|
99
|
+
__metadata("design:paramtypes", []),
|
|
100
|
+
__metadata("design:returntype", Promise)
|
|
101
|
+
], IamAuditController.prototype, "listRoles", null);
|
|
102
|
+
__decorate([
|
|
103
|
+
(0, common_1.Get)('permissions/matrix'),
|
|
104
|
+
(0, swagger_1.ApiOperation)({ summary: 'Permission matrix: users x permissions grid' }),
|
|
105
|
+
(0, swagger_1.ApiResponse)({ status: 200, description: 'Permission matrix' }),
|
|
106
|
+
__metadata("design:type", Function),
|
|
107
|
+
__metadata("design:paramtypes", []),
|
|
108
|
+
__metadata("design:returntype", Promise)
|
|
109
|
+
], IamAuditController.prototype, "getPermissionMatrix", null);
|
|
110
|
+
__decorate([
|
|
111
|
+
(0, common_1.Get)('audit/events'),
|
|
112
|
+
(0, swagger_1.ApiOperation)({ summary: 'Recent Keycloak admin events' }),
|
|
113
|
+
(0, swagger_1.ApiResponse)({ status: 200, description: 'Admin event list' }),
|
|
114
|
+
__param(0, (0, common_1.Query)('first')),
|
|
115
|
+
__param(1, (0, common_1.Query)('max')),
|
|
116
|
+
__metadata("design:type", Function),
|
|
117
|
+
__metadata("design:paramtypes", [Object, Object]),
|
|
118
|
+
__metadata("design:returntype", Promise)
|
|
119
|
+
], IamAuditController.prototype, "getAuditEvents", null);
|
|
120
|
+
exports.IamAuditController = IamAuditController = __decorate([
|
|
121
|
+
(0, swagger_1.ApiTags)('iam-audit'),
|
|
122
|
+
(0, core_1.Roles)('admin'),
|
|
123
|
+
(0, common_1.Controller)('iam'),
|
|
124
|
+
__metadata("design:paramtypes", [cqrs_1.QueryBus])
|
|
125
|
+
], IamAuditController);
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
export interface IamUserSummaryDto {
|
|
2
|
+
id: string;
|
|
3
|
+
username: string;
|
|
4
|
+
email: string | undefined;
|
|
5
|
+
firstName: string | undefined;
|
|
6
|
+
lastName: string | undefined;
|
|
7
|
+
enabled: boolean;
|
|
8
|
+
groups: string[];
|
|
9
|
+
permissionCount: number;
|
|
10
|
+
}
|
|
11
|
+
export interface IamUserDetailDto {
|
|
12
|
+
id: string;
|
|
13
|
+
username: string;
|
|
14
|
+
email: string | undefined;
|
|
15
|
+
firstName: string | undefined;
|
|
16
|
+
lastName: string | undefined;
|
|
17
|
+
enabled: boolean;
|
|
18
|
+
emailVerified: boolean;
|
|
19
|
+
createdTimestamp: number | undefined;
|
|
20
|
+
groups: {
|
|
21
|
+
id: string;
|
|
22
|
+
name: string;
|
|
23
|
+
path: string;
|
|
24
|
+
}[];
|
|
25
|
+
clientRoles: {
|
|
26
|
+
clientId: string;
|
|
27
|
+
roles: {
|
|
28
|
+
name: string;
|
|
29
|
+
description: string | undefined;
|
|
30
|
+
}[];
|
|
31
|
+
}[];
|
|
32
|
+
}
|
|
33
|
+
export interface IamGroupSummaryDto {
|
|
34
|
+
id: string;
|
|
35
|
+
name: string;
|
|
36
|
+
path: string;
|
|
37
|
+
memberCount: number;
|
|
38
|
+
clientRoles: {
|
|
39
|
+
clientId: string;
|
|
40
|
+
roles: string[];
|
|
41
|
+
}[];
|
|
42
|
+
}
|
|
43
|
+
export interface IamGroupMemberDto {
|
|
44
|
+
id: string;
|
|
45
|
+
username: string;
|
|
46
|
+
email: string | undefined;
|
|
47
|
+
firstName: string | undefined;
|
|
48
|
+
lastName: string | undefined;
|
|
49
|
+
}
|
|
50
|
+
export interface IamClientRolesDto {
|
|
51
|
+
clientId: string;
|
|
52
|
+
roles: {
|
|
53
|
+
name: string;
|
|
54
|
+
description: string | undefined;
|
|
55
|
+
}[];
|
|
56
|
+
}
|
|
57
|
+
export interface IamPermissionMatrixDto {
|
|
58
|
+
permissions: string[];
|
|
59
|
+
users: {
|
|
60
|
+
id: string;
|
|
61
|
+
username: string;
|
|
62
|
+
displayName: string;
|
|
63
|
+
grants: string[];
|
|
64
|
+
}[];
|
|
65
|
+
}
|
|
66
|
+
export interface IamAuditEventDto {
|
|
67
|
+
time: number;
|
|
68
|
+
operationType: string;
|
|
69
|
+
resourceType: string;
|
|
70
|
+
resourcePath: string;
|
|
71
|
+
userId: string;
|
|
72
|
+
ipAddress: string;
|
|
73
|
+
clientId: string;
|
|
74
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export interface KcUser {
|
|
2
|
+
id: string;
|
|
3
|
+
username: string;
|
|
4
|
+
email?: string;
|
|
5
|
+
firstName?: string;
|
|
6
|
+
lastName?: string;
|
|
7
|
+
enabled: boolean;
|
|
8
|
+
emailVerified: boolean;
|
|
9
|
+
createdTimestamp?: number;
|
|
10
|
+
}
|
|
11
|
+
export interface KcGroup {
|
|
12
|
+
id: string;
|
|
13
|
+
name: string;
|
|
14
|
+
path: string;
|
|
15
|
+
subGroups: KcGroup[];
|
|
16
|
+
}
|
|
17
|
+
export interface KcRole {
|
|
18
|
+
id: string;
|
|
19
|
+
name: string;
|
|
20
|
+
description?: string;
|
|
21
|
+
composite: boolean;
|
|
22
|
+
clientRole: boolean;
|
|
23
|
+
containerId: string;
|
|
24
|
+
}
|
|
25
|
+
export interface KcClient {
|
|
26
|
+
id: string;
|
|
27
|
+
clientId: string;
|
|
28
|
+
name?: string;
|
|
29
|
+
enabled: boolean;
|
|
30
|
+
}
|
|
31
|
+
export interface KcAdminEvent {
|
|
32
|
+
time: number;
|
|
33
|
+
type: string;
|
|
34
|
+
realmId: string;
|
|
35
|
+
operationType: string;
|
|
36
|
+
resourceType: string;
|
|
37
|
+
resourcePath: string;
|
|
38
|
+
representation?: string;
|
|
39
|
+
authDetails: {
|
|
40
|
+
realmId: string;
|
|
41
|
+
clientId: string;
|
|
42
|
+
userId: string;
|
|
43
|
+
ipAddress: string;
|
|
44
|
+
};
|
|
45
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var IamAuditModule_1;
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.IamAuditModule = void 0;
|
|
11
|
+
const common_1 = require("@nestjs/common");
|
|
12
|
+
const cqrs_1 = require("@nestjs/cqrs");
|
|
13
|
+
const iam_audit_options_1 = require("./iam-audit.options");
|
|
14
|
+
const keycloak_admin_service_1 = require("./services/keycloak-admin.service");
|
|
15
|
+
const iam_audit_controller_1 = require("./controllers/iam-audit.controller");
|
|
16
|
+
const get_iam_users_handler_1 = require("./queries/get-iam-users.handler");
|
|
17
|
+
const get_iam_user_detail_handler_1 = require("./queries/get-iam-user-detail.handler");
|
|
18
|
+
const get_iam_groups_handler_1 = require("./queries/get-iam-groups.handler");
|
|
19
|
+
const get_iam_group_members_handler_1 = require("./queries/get-iam-group-members.handler");
|
|
20
|
+
const get_iam_roles_handler_1 = require("./queries/get-iam-roles.handler");
|
|
21
|
+
const get_permission_matrix_handler_1 = require("./queries/get-permission-matrix.handler");
|
|
22
|
+
const get_iam_audit_events_handler_1 = require("./queries/get-iam-audit-events.handler");
|
|
23
|
+
const QueryHandlers = [
|
|
24
|
+
get_iam_users_handler_1.GetIamUsersHandler,
|
|
25
|
+
get_iam_user_detail_handler_1.GetIamUserDetailHandler,
|
|
26
|
+
get_iam_groups_handler_1.GetIamGroupsHandler,
|
|
27
|
+
get_iam_group_members_handler_1.GetIamGroupMembersHandler,
|
|
28
|
+
get_iam_roles_handler_1.GetIamRolesHandler,
|
|
29
|
+
get_permission_matrix_handler_1.GetPermissionMatrixHandler,
|
|
30
|
+
get_iam_audit_events_handler_1.GetIamAuditEventsHandler,
|
|
31
|
+
];
|
|
32
|
+
let IamAuditModule = IamAuditModule_1 = class IamAuditModule {
|
|
33
|
+
static forRoot(options) {
|
|
34
|
+
return {
|
|
35
|
+
module: IamAuditModule_1,
|
|
36
|
+
imports: [cqrs_1.CqrsModule],
|
|
37
|
+
controllers: [iam_audit_controller_1.IamAuditController],
|
|
38
|
+
providers: [
|
|
39
|
+
{ provide: iam_audit_options_1.IAM_AUDIT_OPTIONS, useValue: options },
|
|
40
|
+
keycloak_admin_service_1.KeycloakAdminService,
|
|
41
|
+
...QueryHandlers,
|
|
42
|
+
],
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
exports.IamAuditModule = IamAuditModule;
|
|
47
|
+
exports.IamAuditModule = IamAuditModule = IamAuditModule_1 = __decorate([
|
|
48
|
+
(0, common_1.Module)({})
|
|
49
|
+
], IamAuditModule);
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare const IAM_AUDIT_OPTIONS: unique symbol;
|
|
2
|
+
export interface IamAuditModuleOptions {
|
|
3
|
+
/** Keycloak client IDs to audit (e.g., ['delivery-hub-backend', 'quanticflow']) */
|
|
4
|
+
clients: string[];
|
|
5
|
+
/** Client used for the user list permission count and permission matrix. Defaults to clients[0]. */
|
|
6
|
+
primaryClient?: string;
|
|
7
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export { IamAuditModule } from './iam-audit.module';
|
|
2
|
+
export { IAM_AUDIT_OPTIONS, type IamAuditModuleOptions } from './iam-audit.options';
|
|
3
|
+
export type { IamUserSummaryDto, IamUserDetailDto, IamGroupSummaryDto, IamGroupMemberDto, IamClientRolesDto, IamPermissionMatrixDto, IamAuditEventDto, } from './dtos/iam-audit.dtos';
|
|
4
|
+
export { GetIamUsersQuery } from './queries/get-iam-users.query';
|
|
5
|
+
export { GetIamUserDetailQuery } from './queries/get-iam-user-detail.query';
|
|
6
|
+
export { GetIamGroupsQuery } from './queries/get-iam-groups.query';
|
|
7
|
+
export { GetIamGroupMembersQuery } from './queries/get-iam-group-members.query';
|
|
8
|
+
export { GetIamRolesQuery } from './queries/get-iam-roles.query';
|
|
9
|
+
export { GetPermissionMatrixQuery } from './queries/get-permission-matrix.query';
|
|
10
|
+
export { GetIamAuditEventsQuery } from './queries/get-iam-audit-events.query';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GetIamAuditEventsQuery = exports.GetPermissionMatrixQuery = exports.GetIamRolesQuery = exports.GetIamGroupMembersQuery = exports.GetIamGroupsQuery = exports.GetIamUserDetailQuery = exports.GetIamUsersQuery = exports.IAM_AUDIT_OPTIONS = exports.IamAuditModule = void 0;
|
|
4
|
+
var iam_audit_module_1 = require("./iam-audit.module");
|
|
5
|
+
Object.defineProperty(exports, "IamAuditModule", { enumerable: true, get: function () { return iam_audit_module_1.IamAuditModule; } });
|
|
6
|
+
var iam_audit_options_1 = require("./iam-audit.options");
|
|
7
|
+
Object.defineProperty(exports, "IAM_AUDIT_OPTIONS", { enumerable: true, get: function () { return iam_audit_options_1.IAM_AUDIT_OPTIONS; } });
|
|
8
|
+
var get_iam_users_query_1 = require("./queries/get-iam-users.query");
|
|
9
|
+
Object.defineProperty(exports, "GetIamUsersQuery", { enumerable: true, get: function () { return get_iam_users_query_1.GetIamUsersQuery; } });
|
|
10
|
+
var get_iam_user_detail_query_1 = require("./queries/get-iam-user-detail.query");
|
|
11
|
+
Object.defineProperty(exports, "GetIamUserDetailQuery", { enumerable: true, get: function () { return get_iam_user_detail_query_1.GetIamUserDetailQuery; } });
|
|
12
|
+
var get_iam_groups_query_1 = require("./queries/get-iam-groups.query");
|
|
13
|
+
Object.defineProperty(exports, "GetIamGroupsQuery", { enumerable: true, get: function () { return get_iam_groups_query_1.GetIamGroupsQuery; } });
|
|
14
|
+
var get_iam_group_members_query_1 = require("./queries/get-iam-group-members.query");
|
|
15
|
+
Object.defineProperty(exports, "GetIamGroupMembersQuery", { enumerable: true, get: function () { return get_iam_group_members_query_1.GetIamGroupMembersQuery; } });
|
|
16
|
+
var get_iam_roles_query_1 = require("./queries/get-iam-roles.query");
|
|
17
|
+
Object.defineProperty(exports, "GetIamRolesQuery", { enumerable: true, get: function () { return get_iam_roles_query_1.GetIamRolesQuery; } });
|
|
18
|
+
var get_permission_matrix_query_1 = require("./queries/get-permission-matrix.query");
|
|
19
|
+
Object.defineProperty(exports, "GetPermissionMatrixQuery", { enumerable: true, get: function () { return get_permission_matrix_query_1.GetPermissionMatrixQuery; } });
|
|
20
|
+
var get_iam_audit_events_query_1 = require("./queries/get-iam-audit-events.query");
|
|
21
|
+
Object.defineProperty(exports, "GetIamAuditEventsQuery", { enumerable: true, get: function () { return get_iam_audit_events_query_1.GetIamAuditEventsQuery; } });
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { IQueryHandler } from '@nestjs/cqrs';
|
|
2
|
+
import { Result } from '@quanticjs/core';
|
|
3
|
+
import { GetIamAuditEventsQuery } from './get-iam-audit-events.query';
|
|
4
|
+
import { KeycloakAdminService } from '../services/keycloak-admin.service';
|
|
5
|
+
import { IamAuditEventDto } from '../dtos/iam-audit.dtos';
|
|
6
|
+
export declare class GetIamAuditEventsHandler implements IQueryHandler<GetIamAuditEventsQuery> {
|
|
7
|
+
private readonly keycloakAdmin;
|
|
8
|
+
constructor(keycloakAdmin: KeycloakAdminService);
|
|
9
|
+
execute(query: GetIamAuditEventsQuery): Promise<Result<{
|
|
10
|
+
data: IamAuditEventDto[];
|
|
11
|
+
}>>;
|
|
12
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.GetIamAuditEventsHandler = void 0;
|
|
13
|
+
const cqrs_1 = require("@nestjs/cqrs");
|
|
14
|
+
const core_1 = require("@quanticjs/core");
|
|
15
|
+
const get_iam_audit_events_query_1 = require("./get-iam-audit-events.query");
|
|
16
|
+
const keycloak_admin_service_1 = require("../services/keycloak-admin.service");
|
|
17
|
+
let GetIamAuditEventsHandler = class GetIamAuditEventsHandler {
|
|
18
|
+
keycloakAdmin;
|
|
19
|
+
constructor(keycloakAdmin) {
|
|
20
|
+
this.keycloakAdmin = keycloakAdmin;
|
|
21
|
+
}
|
|
22
|
+
async execute(query) {
|
|
23
|
+
const events = await this.keycloakAdmin.getAdminEvents(undefined, query.first, query.max);
|
|
24
|
+
return core_1.Result.success({
|
|
25
|
+
data: events.map((e) => ({
|
|
26
|
+
time: e.time,
|
|
27
|
+
operationType: e.operationType,
|
|
28
|
+
resourceType: e.resourceType,
|
|
29
|
+
resourcePath: e.resourcePath,
|
|
30
|
+
userId: e.authDetails?.userId ?? '',
|
|
31
|
+
ipAddress: e.authDetails?.ipAddress ?? '',
|
|
32
|
+
clientId: e.authDetails?.clientId ?? '',
|
|
33
|
+
})),
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
exports.GetIamAuditEventsHandler = GetIamAuditEventsHandler;
|
|
38
|
+
exports.GetIamAuditEventsHandler = GetIamAuditEventsHandler = __decorate([
|
|
39
|
+
(0, cqrs_1.QueryHandler)(get_iam_audit_events_query_1.GetIamAuditEventsQuery),
|
|
40
|
+
__metadata("design:paramtypes", [keycloak_admin_service_1.KeycloakAdminService])
|
|
41
|
+
], GetIamAuditEventsHandler);
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GetIamAuditEventsQuery = void 0;
|
|
4
|
+
class GetIamAuditEventsQuery {
|
|
5
|
+
first;
|
|
6
|
+
max;
|
|
7
|
+
constructor(first = 0, max = 50) {
|
|
8
|
+
this.first = first;
|
|
9
|
+
this.max = max;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
exports.GetIamAuditEventsQuery = GetIamAuditEventsQuery;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { IQueryHandler } from '@nestjs/cqrs';
|
|
2
|
+
import { Result } from '@quanticjs/core';
|
|
3
|
+
import { GetIamGroupMembersQuery } from './get-iam-group-members.query';
|
|
4
|
+
import { KeycloakAdminService } from '../services/keycloak-admin.service';
|
|
5
|
+
import { IamGroupMemberDto } from '../dtos/iam-audit.dtos';
|
|
6
|
+
export declare class GetIamGroupMembersHandler implements IQueryHandler<GetIamGroupMembersQuery> {
|
|
7
|
+
private readonly keycloakAdmin;
|
|
8
|
+
constructor(keycloakAdmin: KeycloakAdminService);
|
|
9
|
+
execute(query: GetIamGroupMembersQuery): Promise<Result<{
|
|
10
|
+
data: IamGroupMemberDto[];
|
|
11
|
+
}>>;
|
|
12
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.GetIamGroupMembersHandler = void 0;
|
|
13
|
+
const cqrs_1 = require("@nestjs/cqrs");
|
|
14
|
+
const core_1 = require("@quanticjs/core");
|
|
15
|
+
const get_iam_group_members_query_1 = require("./get-iam-group-members.query");
|
|
16
|
+
const keycloak_admin_service_1 = require("../services/keycloak-admin.service");
|
|
17
|
+
let GetIamGroupMembersHandler = class GetIamGroupMembersHandler {
|
|
18
|
+
keycloakAdmin;
|
|
19
|
+
constructor(keycloakAdmin) {
|
|
20
|
+
this.keycloakAdmin = keycloakAdmin;
|
|
21
|
+
}
|
|
22
|
+
async execute(query) {
|
|
23
|
+
const members = await this.keycloakAdmin.getGroupMembers(query.groupId, query.first, query.max);
|
|
24
|
+
return core_1.Result.success({
|
|
25
|
+
data: members.map((m) => ({
|
|
26
|
+
id: m.id,
|
|
27
|
+
username: m.username,
|
|
28
|
+
email: m.email,
|
|
29
|
+
firstName: m.firstName,
|
|
30
|
+
lastName: m.lastName,
|
|
31
|
+
})),
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
exports.GetIamGroupMembersHandler = GetIamGroupMembersHandler;
|
|
36
|
+
exports.GetIamGroupMembersHandler = GetIamGroupMembersHandler = __decorate([
|
|
37
|
+
(0, cqrs_1.QueryHandler)(get_iam_group_members_query_1.GetIamGroupMembersQuery),
|
|
38
|
+
__metadata("design:paramtypes", [keycloak_admin_service_1.KeycloakAdminService])
|
|
39
|
+
], GetIamGroupMembersHandler);
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GetIamGroupMembersQuery = void 0;
|
|
4
|
+
class GetIamGroupMembersQuery {
|
|
5
|
+
groupId;
|
|
6
|
+
first;
|
|
7
|
+
max;
|
|
8
|
+
constructor(groupId, first = 0, max = 100) {
|
|
9
|
+
this.groupId = groupId;
|
|
10
|
+
this.first = first;
|
|
11
|
+
this.max = max;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
exports.GetIamGroupMembersQuery = GetIamGroupMembersQuery;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { IQueryHandler } from '@nestjs/cqrs';
|
|
2
|
+
import { Result } from '@quanticjs/core';
|
|
3
|
+
import { GetIamGroupsQuery } from './get-iam-groups.query';
|
|
4
|
+
import { KeycloakAdminService } from '../services/keycloak-admin.service';
|
|
5
|
+
import { IamAuditModuleOptions } from '../iam-audit.options';
|
|
6
|
+
import { IamGroupSummaryDto } from '../dtos/iam-audit.dtos';
|
|
7
|
+
export declare class GetIamGroupsHandler implements IQueryHandler<GetIamGroupsQuery> {
|
|
8
|
+
private readonly keycloakAdmin;
|
|
9
|
+
private readonly options;
|
|
10
|
+
constructor(keycloakAdmin: KeycloakAdminService, options: IamAuditModuleOptions);
|
|
11
|
+
execute(_query: GetIamGroupsQuery): Promise<Result<{
|
|
12
|
+
data: IamGroupSummaryDto[];
|
|
13
|
+
}>>;
|
|
14
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.GetIamGroupsHandler = void 0;
|
|
16
|
+
const common_1 = require("@nestjs/common");
|
|
17
|
+
const cqrs_1 = require("@nestjs/cqrs");
|
|
18
|
+
const core_1 = require("@quanticjs/core");
|
|
19
|
+
const get_iam_groups_query_1 = require("./get-iam-groups.query");
|
|
20
|
+
const keycloak_admin_service_1 = require("../services/keycloak-admin.service");
|
|
21
|
+
const iam_audit_options_1 = require("../iam-audit.options");
|
|
22
|
+
let GetIamGroupsHandler = class GetIamGroupsHandler {
|
|
23
|
+
keycloakAdmin;
|
|
24
|
+
options;
|
|
25
|
+
constructor(keycloakAdmin, options) {
|
|
26
|
+
this.keycloakAdmin = keycloakAdmin;
|
|
27
|
+
this.options = options;
|
|
28
|
+
}
|
|
29
|
+
async execute(_query) {
|
|
30
|
+
const [groups, clientUuids] = await Promise.all([
|
|
31
|
+
this.keycloakAdmin.getGroups(),
|
|
32
|
+
Promise.all(this.options.clients.map((c) => this.keycloakAdmin.resolveClientUuid(c))),
|
|
33
|
+
]);
|
|
34
|
+
const data = await Promise.all(groups.map(async (group) => {
|
|
35
|
+
const [members, ...rolesByClient] = await Promise.all([
|
|
36
|
+
this.keycloakAdmin.getGroupMembers(group.id, 0, 1000),
|
|
37
|
+
...clientUuids.map((uuid, i) => this.keycloakAdmin
|
|
38
|
+
.getGroupClientRoles(group.id, uuid)
|
|
39
|
+
.then((roles) => ({
|
|
40
|
+
clientId: this.options.clients[i],
|
|
41
|
+
roles: roles.map((r) => r.name),
|
|
42
|
+
}))),
|
|
43
|
+
]);
|
|
44
|
+
return {
|
|
45
|
+
id: group.id,
|
|
46
|
+
name: group.name,
|
|
47
|
+
path: group.path,
|
|
48
|
+
memberCount: members.length,
|
|
49
|
+
clientRoles: rolesByClient,
|
|
50
|
+
};
|
|
51
|
+
}));
|
|
52
|
+
return core_1.Result.success({ data });
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
exports.GetIamGroupsHandler = GetIamGroupsHandler;
|
|
56
|
+
exports.GetIamGroupsHandler = GetIamGroupsHandler = __decorate([
|
|
57
|
+
(0, cqrs_1.QueryHandler)(get_iam_groups_query_1.GetIamGroupsQuery),
|
|
58
|
+
__param(1, (0, common_1.Inject)(iam_audit_options_1.IAM_AUDIT_OPTIONS)),
|
|
59
|
+
__metadata("design:paramtypes", [keycloak_admin_service_1.KeycloakAdminService, Object])
|
|
60
|
+
], GetIamGroupsHandler);
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { IQueryHandler } from '@nestjs/cqrs';
|
|
2
|
+
import { Result } from '@quanticjs/core';
|
|
3
|
+
import { GetIamRolesQuery } from './get-iam-roles.query';
|
|
4
|
+
import { KeycloakAdminService } from '../services/keycloak-admin.service';
|
|
5
|
+
import { IamAuditModuleOptions } from '../iam-audit.options';
|
|
6
|
+
import { IamClientRolesDto } from '../dtos/iam-audit.dtos';
|
|
7
|
+
export declare class GetIamRolesHandler implements IQueryHandler<GetIamRolesQuery> {
|
|
8
|
+
private readonly keycloakAdmin;
|
|
9
|
+
private readonly options;
|
|
10
|
+
constructor(keycloakAdmin: KeycloakAdminService, options: IamAuditModuleOptions);
|
|
11
|
+
execute(_query: GetIamRolesQuery): Promise<Result<{
|
|
12
|
+
data: IamClientRolesDto[];
|
|
13
|
+
}>>;
|
|
14
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.GetIamRolesHandler = void 0;
|
|
16
|
+
const common_1 = require("@nestjs/common");
|
|
17
|
+
const cqrs_1 = require("@nestjs/cqrs");
|
|
18
|
+
const core_1 = require("@quanticjs/core");
|
|
19
|
+
const get_iam_roles_query_1 = require("./get-iam-roles.query");
|
|
20
|
+
const keycloak_admin_service_1 = require("../services/keycloak-admin.service");
|
|
21
|
+
const iam_audit_options_1 = require("../iam-audit.options");
|
|
22
|
+
let GetIamRolesHandler = class GetIamRolesHandler {
|
|
23
|
+
keycloakAdmin;
|
|
24
|
+
options;
|
|
25
|
+
constructor(keycloakAdmin, options) {
|
|
26
|
+
this.keycloakAdmin = keycloakAdmin;
|
|
27
|
+
this.options = options;
|
|
28
|
+
}
|
|
29
|
+
async execute(_query) {
|
|
30
|
+
const clientUuids = await Promise.all(this.options.clients.map((c) => this.keycloakAdmin.resolveClientUuid(c)));
|
|
31
|
+
const data = await Promise.all(this.options.clients.map(async (clientId, i) => {
|
|
32
|
+
const roles = await this.keycloakAdmin.getClientRoles(clientUuids[i]);
|
|
33
|
+
return {
|
|
34
|
+
clientId,
|
|
35
|
+
roles: roles.map((r) => ({ name: r.name, description: r.description })),
|
|
36
|
+
};
|
|
37
|
+
}));
|
|
38
|
+
return core_1.Result.success({ data });
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
exports.GetIamRolesHandler = GetIamRolesHandler;
|
|
42
|
+
exports.GetIamRolesHandler = GetIamRolesHandler = __decorate([
|
|
43
|
+
(0, cqrs_1.QueryHandler)(get_iam_roles_query_1.GetIamRolesQuery),
|
|
44
|
+
__param(1, (0, common_1.Inject)(iam_audit_options_1.IAM_AUDIT_OPTIONS)),
|
|
45
|
+
__metadata("design:paramtypes", [keycloak_admin_service_1.KeycloakAdminService, Object])
|
|
46
|
+
], GetIamRolesHandler);
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { IQueryHandler } from '@nestjs/cqrs';
|
|
2
|
+
import { Result } from '@quanticjs/core';
|
|
3
|
+
import { GetIamUserDetailQuery } from './get-iam-user-detail.query';
|
|
4
|
+
import { KeycloakAdminService } from '../services/keycloak-admin.service';
|
|
5
|
+
import { IamAuditModuleOptions } from '../iam-audit.options';
|
|
6
|
+
import { IamUserDetailDto } from '../dtos/iam-audit.dtos';
|
|
7
|
+
export declare class GetIamUserDetailHandler implements IQueryHandler<GetIamUserDetailQuery> {
|
|
8
|
+
private readonly keycloakAdmin;
|
|
9
|
+
private readonly options;
|
|
10
|
+
constructor(keycloakAdmin: KeycloakAdminService, options: IamAuditModuleOptions);
|
|
11
|
+
execute(query: GetIamUserDetailQuery): Promise<Result<IamUserDetailDto>>;
|
|
12
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.GetIamUserDetailHandler = void 0;
|
|
16
|
+
const common_1 = require("@nestjs/common");
|
|
17
|
+
const cqrs_1 = require("@nestjs/cqrs");
|
|
18
|
+
const core_1 = require("@quanticjs/core");
|
|
19
|
+
const get_iam_user_detail_query_1 = require("./get-iam-user-detail.query");
|
|
20
|
+
const keycloak_admin_service_1 = require("../services/keycloak-admin.service");
|
|
21
|
+
const iam_audit_options_1 = require("../iam-audit.options");
|
|
22
|
+
let GetIamUserDetailHandler = class GetIamUserDetailHandler {
|
|
23
|
+
keycloakAdmin;
|
|
24
|
+
options;
|
|
25
|
+
constructor(keycloakAdmin, options) {
|
|
26
|
+
this.keycloakAdmin = keycloakAdmin;
|
|
27
|
+
this.options = options;
|
|
28
|
+
}
|
|
29
|
+
async execute(query) {
|
|
30
|
+
const [user, groups, clientUuids] = await Promise.all([
|
|
31
|
+
this.keycloakAdmin.getUser(query.userId),
|
|
32
|
+
this.keycloakAdmin.getUserGroups(query.userId),
|
|
33
|
+
Promise.all(this.options.clients.map((c) => this.keycloakAdmin.resolveClientUuid(c))),
|
|
34
|
+
]);
|
|
35
|
+
const clientRoles = await Promise.all(this.options.clients.map(async (clientId, i) => {
|
|
36
|
+
const roles = await this.keycloakAdmin.getUserClientRoles(query.userId, clientUuids[i]);
|
|
37
|
+
return {
|
|
38
|
+
clientId,
|
|
39
|
+
roles: roles.map((r) => ({ name: r.name, description: r.description })),
|
|
40
|
+
};
|
|
41
|
+
}));
|
|
42
|
+
return core_1.Result.success({
|
|
43
|
+
id: user.id,
|
|
44
|
+
username: user.username,
|
|
45
|
+
email: user.email,
|
|
46
|
+
firstName: user.firstName,
|
|
47
|
+
lastName: user.lastName,
|
|
48
|
+
enabled: user.enabled,
|
|
49
|
+
emailVerified: user.emailVerified,
|
|
50
|
+
createdTimestamp: user.createdTimestamp,
|
|
51
|
+
groups: groups.map((g) => ({ id: g.id, name: g.name, path: g.path })),
|
|
52
|
+
clientRoles,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
exports.GetIamUserDetailHandler = GetIamUserDetailHandler;
|
|
57
|
+
exports.GetIamUserDetailHandler = GetIamUserDetailHandler = __decorate([
|
|
58
|
+
(0, cqrs_1.QueryHandler)(get_iam_user_detail_query_1.GetIamUserDetailQuery),
|
|
59
|
+
__param(1, (0, common_1.Inject)(iam_audit_options_1.IAM_AUDIT_OPTIONS)),
|
|
60
|
+
__metadata("design:paramtypes", [keycloak_admin_service_1.KeycloakAdminService, Object])
|
|
61
|
+
], GetIamUserDetailHandler);
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GetIamUserDetailQuery = void 0;
|
|
4
|
+
class GetIamUserDetailQuery {
|
|
5
|
+
userId;
|
|
6
|
+
constructor(userId) {
|
|
7
|
+
this.userId = userId;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
exports.GetIamUserDetailQuery = GetIamUserDetailQuery;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { IQueryHandler } from '@nestjs/cqrs';
|
|
2
|
+
import { Result } from '@quanticjs/core';
|
|
3
|
+
import { GetIamUsersQuery } from './get-iam-users.query';
|
|
4
|
+
import { KeycloakAdminService } from '../services/keycloak-admin.service';
|
|
5
|
+
import { IamAuditModuleOptions } from '../iam-audit.options';
|
|
6
|
+
import { IamUserSummaryDto } from '../dtos/iam-audit.dtos';
|
|
7
|
+
export declare class GetIamUsersHandler implements IQueryHandler<GetIamUsersQuery> {
|
|
8
|
+
private readonly keycloakAdmin;
|
|
9
|
+
private readonly options;
|
|
10
|
+
constructor(keycloakAdmin: KeycloakAdminService, options: IamAuditModuleOptions);
|
|
11
|
+
execute(query: GetIamUsersQuery): Promise<Result<{
|
|
12
|
+
data: IamUserSummaryDto[];
|
|
13
|
+
total: number;
|
|
14
|
+
}>>;
|
|
15
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.GetIamUsersHandler = void 0;
|
|
16
|
+
const common_1 = require("@nestjs/common");
|
|
17
|
+
const cqrs_1 = require("@nestjs/cqrs");
|
|
18
|
+
const core_1 = require("@quanticjs/core");
|
|
19
|
+
const get_iam_users_query_1 = require("./get-iam-users.query");
|
|
20
|
+
const keycloak_admin_service_1 = require("../services/keycloak-admin.service");
|
|
21
|
+
const iam_audit_options_1 = require("../iam-audit.options");
|
|
22
|
+
let GetIamUsersHandler = class GetIamUsersHandler {
|
|
23
|
+
keycloakAdmin;
|
|
24
|
+
options;
|
|
25
|
+
constructor(keycloakAdmin, options) {
|
|
26
|
+
this.keycloakAdmin = keycloakAdmin;
|
|
27
|
+
this.options = options;
|
|
28
|
+
}
|
|
29
|
+
async execute(query) {
|
|
30
|
+
const primaryClient = this.options.primaryClient ?? this.options.clients[0];
|
|
31
|
+
const primaryUuid = await this.keycloakAdmin.resolveClientUuid(primaryClient);
|
|
32
|
+
const [users, total] = await Promise.all([
|
|
33
|
+
this.keycloakAdmin.getUsers(query.search, query.first, query.max),
|
|
34
|
+
this.keycloakAdmin.getUserCount(query.search),
|
|
35
|
+
]);
|
|
36
|
+
const data = await Promise.all(users.map(async (user) => {
|
|
37
|
+
const [groups, clientRoles] = await Promise.all([
|
|
38
|
+
this.keycloakAdmin.getUserGroups(user.id),
|
|
39
|
+
this.keycloakAdmin.getUserClientRoles(user.id, primaryUuid),
|
|
40
|
+
]);
|
|
41
|
+
return {
|
|
42
|
+
id: user.id,
|
|
43
|
+
username: user.username,
|
|
44
|
+
email: user.email,
|
|
45
|
+
firstName: user.firstName,
|
|
46
|
+
lastName: user.lastName,
|
|
47
|
+
enabled: user.enabled,
|
|
48
|
+
groups: groups.map((g) => g.name),
|
|
49
|
+
permissionCount: clientRoles.length,
|
|
50
|
+
};
|
|
51
|
+
}));
|
|
52
|
+
return core_1.Result.success({ data, total });
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
exports.GetIamUsersHandler = GetIamUsersHandler;
|
|
56
|
+
exports.GetIamUsersHandler = GetIamUsersHandler = __decorate([
|
|
57
|
+
(0, cqrs_1.QueryHandler)(get_iam_users_query_1.GetIamUsersQuery),
|
|
58
|
+
__param(1, (0, common_1.Inject)(iam_audit_options_1.IAM_AUDIT_OPTIONS)),
|
|
59
|
+
__metadata("design:paramtypes", [keycloak_admin_service_1.KeycloakAdminService, Object])
|
|
60
|
+
], GetIamUsersHandler);
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GetIamUsersQuery = void 0;
|
|
4
|
+
class GetIamUsersQuery {
|
|
5
|
+
search;
|
|
6
|
+
first;
|
|
7
|
+
max;
|
|
8
|
+
constructor(search, first = 0, max = 100) {
|
|
9
|
+
this.search = search;
|
|
10
|
+
this.first = first;
|
|
11
|
+
this.max = max;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
exports.GetIamUsersQuery = GetIamUsersQuery;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { IQueryHandler } from '@nestjs/cqrs';
|
|
2
|
+
import { Result } from '@quanticjs/core';
|
|
3
|
+
import { GetPermissionMatrixQuery } from './get-permission-matrix.query';
|
|
4
|
+
import { KeycloakAdminService } from '../services/keycloak-admin.service';
|
|
5
|
+
import { IamAuditModuleOptions } from '../iam-audit.options';
|
|
6
|
+
import { IamPermissionMatrixDto } from '../dtos/iam-audit.dtos';
|
|
7
|
+
export declare class GetPermissionMatrixHandler implements IQueryHandler<GetPermissionMatrixQuery> {
|
|
8
|
+
private readonly keycloakAdmin;
|
|
9
|
+
private readonly options;
|
|
10
|
+
constructor(keycloakAdmin: KeycloakAdminService, options: IamAuditModuleOptions);
|
|
11
|
+
execute(_query: GetPermissionMatrixQuery): Promise<Result<IamPermissionMatrixDto>>;
|
|
12
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.GetPermissionMatrixHandler = void 0;
|
|
16
|
+
const common_1 = require("@nestjs/common");
|
|
17
|
+
const cqrs_1 = require("@nestjs/cqrs");
|
|
18
|
+
const core_1 = require("@quanticjs/core");
|
|
19
|
+
const get_permission_matrix_query_1 = require("./get-permission-matrix.query");
|
|
20
|
+
const keycloak_admin_service_1 = require("../services/keycloak-admin.service");
|
|
21
|
+
const iam_audit_options_1 = require("../iam-audit.options");
|
|
22
|
+
let GetPermissionMatrixHandler = class GetPermissionMatrixHandler {
|
|
23
|
+
keycloakAdmin;
|
|
24
|
+
options;
|
|
25
|
+
constructor(keycloakAdmin, options) {
|
|
26
|
+
this.keycloakAdmin = keycloakAdmin;
|
|
27
|
+
this.options = options;
|
|
28
|
+
}
|
|
29
|
+
async execute(_query) {
|
|
30
|
+
const primaryClient = this.options.primaryClient ?? this.options.clients[0];
|
|
31
|
+
const primaryUuid = await this.keycloakAdmin.resolveClientUuid(primaryClient);
|
|
32
|
+
const [allUsers, allRoles] = await Promise.all([
|
|
33
|
+
this.keycloakAdmin.getUsers(undefined, 0, 1000),
|
|
34
|
+
this.keycloakAdmin.getClientRoles(primaryUuid),
|
|
35
|
+
]);
|
|
36
|
+
const permissions = allRoles.map((r) => r.name);
|
|
37
|
+
const users = await Promise.all(allUsers.map(async (user) => {
|
|
38
|
+
const roles = await this.keycloakAdmin.getUserClientRoles(user.id, primaryUuid);
|
|
39
|
+
return {
|
|
40
|
+
id: user.id,
|
|
41
|
+
username: user.username,
|
|
42
|
+
displayName: [user.firstName, user.lastName].filter(Boolean).join(' ') || user.username,
|
|
43
|
+
grants: roles.map((r) => r.name),
|
|
44
|
+
};
|
|
45
|
+
}));
|
|
46
|
+
return core_1.Result.success({ permissions, users });
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
exports.GetPermissionMatrixHandler = GetPermissionMatrixHandler;
|
|
50
|
+
exports.GetPermissionMatrixHandler = GetPermissionMatrixHandler = __decorate([
|
|
51
|
+
(0, cqrs_1.QueryHandler)(get_permission_matrix_query_1.GetPermissionMatrixQuery),
|
|
52
|
+
__param(1, (0, common_1.Inject)(iam_audit_options_1.IAM_AUDIT_OPTIONS)),
|
|
53
|
+
__metadata("design:paramtypes", [keycloak_admin_service_1.KeycloakAdminService, Object])
|
|
54
|
+
], GetPermissionMatrixHandler);
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { ConfigService } from '@nestjs/config';
|
|
2
|
+
import { PinoLogger } from 'nestjs-pino';
|
|
3
|
+
import { KcUser, KcGroup, KcRole, KcAdminEvent } from '../dtos/keycloak-admin.types';
|
|
4
|
+
export declare class KeycloakAdminService {
|
|
5
|
+
private readonly logger;
|
|
6
|
+
private readonly adminBaseUrl;
|
|
7
|
+
private readonly tokenUrl;
|
|
8
|
+
private readonly clientId;
|
|
9
|
+
private readonly clientSecret;
|
|
10
|
+
private serviceToken;
|
|
11
|
+
private serviceTokenExpiresAt;
|
|
12
|
+
private readonly clientUuidCache;
|
|
13
|
+
private readonly breaker;
|
|
14
|
+
constructor(config: ConfigService, logger: PinoLogger);
|
|
15
|
+
getUsers(search?: string, first?: number, max?: number): Promise<KcUser[]>;
|
|
16
|
+
getUserCount(search?: string): Promise<number>;
|
|
17
|
+
getUser(userId: string): Promise<KcUser>;
|
|
18
|
+
getUserGroups(userId: string): Promise<KcGroup[]>;
|
|
19
|
+
getUserClientRoles(userId: string, clientUuid: string): Promise<KcRole[]>;
|
|
20
|
+
getGroups(): Promise<KcGroup[]>;
|
|
21
|
+
getGroupMembers(groupId: string, first?: number, max?: number): Promise<KcUser[]>;
|
|
22
|
+
getGroupClientRoles(groupId: string, clientUuid: string): Promise<KcRole[]>;
|
|
23
|
+
getClientRoles(clientUuid: string): Promise<KcRole[]>;
|
|
24
|
+
getAdminEvents(types?: string[], first?: number, max?: number): Promise<KcAdminEvent[]>;
|
|
25
|
+
resolveClientUuid(clientIdName: string): Promise<string>;
|
|
26
|
+
private get;
|
|
27
|
+
private getServiceToken;
|
|
28
|
+
}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.KeycloakAdminService = void 0;
|
|
16
|
+
const common_1 = require("@nestjs/common");
|
|
17
|
+
const config_1 = require("@nestjs/config");
|
|
18
|
+
const nestjs_pino_1 = require("nestjs-pino");
|
|
19
|
+
const core_1 = require("@quanticjs/core");
|
|
20
|
+
let KeycloakAdminService = class KeycloakAdminService {
|
|
21
|
+
logger;
|
|
22
|
+
adminBaseUrl;
|
|
23
|
+
tokenUrl;
|
|
24
|
+
clientId;
|
|
25
|
+
clientSecret;
|
|
26
|
+
serviceToken = null;
|
|
27
|
+
serviceTokenExpiresAt = 0;
|
|
28
|
+
clientUuidCache = new Map();
|
|
29
|
+
breaker = (0, core_1.createCircuitBreaker)({
|
|
30
|
+
maxRetries: 2,
|
|
31
|
+
consecutiveFailures: 5,
|
|
32
|
+
halfOpenAfterMs: 30_000,
|
|
33
|
+
});
|
|
34
|
+
constructor(config, logger) {
|
|
35
|
+
this.logger = logger;
|
|
36
|
+
const keycloakBase = config.get('KEYCLOAK_INTERNAL_URL') ?? config.get('KEYCLOAK_URL', 'http://localhost:8081');
|
|
37
|
+
const realm = config.get('KEYCLOAK_REALM', 'masaar');
|
|
38
|
+
this.adminBaseUrl = `${keycloakBase}/admin/realms/${realm}`;
|
|
39
|
+
this.tokenUrl = `${keycloakBase}/realms/${realm}/protocol/openid-connect/token`;
|
|
40
|
+
this.clientId = config.get('KEYCLOAK_CLIENT_ID', 'delivery-hub-backend');
|
|
41
|
+
this.clientSecret = config.get('KEYCLOAK_CLIENT_SECRET', 'change-me');
|
|
42
|
+
}
|
|
43
|
+
async getUsers(search, first = 0, max = 100) {
|
|
44
|
+
const params = new URLSearchParams({ first: String(first), max: String(max) });
|
|
45
|
+
if (search)
|
|
46
|
+
params.set('search', search);
|
|
47
|
+
return this.get(`/users?${params}`);
|
|
48
|
+
}
|
|
49
|
+
async getUserCount(search) {
|
|
50
|
+
const params = new URLSearchParams();
|
|
51
|
+
if (search)
|
|
52
|
+
params.set('search', search);
|
|
53
|
+
return this.get(`/users/count?${params}`);
|
|
54
|
+
}
|
|
55
|
+
async getUser(userId) {
|
|
56
|
+
return this.get(`/users/${userId}`);
|
|
57
|
+
}
|
|
58
|
+
async getUserGroups(userId) {
|
|
59
|
+
return this.get(`/users/${userId}/groups`);
|
|
60
|
+
}
|
|
61
|
+
async getUserClientRoles(userId, clientUuid) {
|
|
62
|
+
return this.get(`/users/${userId}/role-mappings/clients/${clientUuid}`);
|
|
63
|
+
}
|
|
64
|
+
async getGroups() {
|
|
65
|
+
return this.get('/groups');
|
|
66
|
+
}
|
|
67
|
+
async getGroupMembers(groupId, first = 0, max = 100) {
|
|
68
|
+
const params = new URLSearchParams({ first: String(first), max: String(max) });
|
|
69
|
+
return this.get(`/groups/${groupId}/members?${params}`);
|
|
70
|
+
}
|
|
71
|
+
async getGroupClientRoles(groupId, clientUuid) {
|
|
72
|
+
return this.get(`/groups/${groupId}/role-mappings/clients/${clientUuid}`);
|
|
73
|
+
}
|
|
74
|
+
async getClientRoles(clientUuid) {
|
|
75
|
+
return this.get(`/clients/${clientUuid}/roles`);
|
|
76
|
+
}
|
|
77
|
+
async getAdminEvents(types, first = 0, max = 50) {
|
|
78
|
+
const params = new URLSearchParams({ first: String(first), max: String(max) });
|
|
79
|
+
if (types) {
|
|
80
|
+
for (const t of types)
|
|
81
|
+
params.append('operationTypes', t);
|
|
82
|
+
}
|
|
83
|
+
return this.get(`/admin-events?${params}`);
|
|
84
|
+
}
|
|
85
|
+
async resolveClientUuid(clientIdName) {
|
|
86
|
+
const cached = this.clientUuidCache.get(clientIdName);
|
|
87
|
+
if (cached)
|
|
88
|
+
return cached;
|
|
89
|
+
const clients = await this.get(`/clients?clientId=${encodeURIComponent(clientIdName)}`);
|
|
90
|
+
if (!clients.length) {
|
|
91
|
+
throw new Error(`Keycloak client not found: ${clientIdName}`);
|
|
92
|
+
}
|
|
93
|
+
const uuid = clients[0].id;
|
|
94
|
+
this.clientUuidCache.set(clientIdName, uuid);
|
|
95
|
+
return uuid;
|
|
96
|
+
}
|
|
97
|
+
async get(path) {
|
|
98
|
+
return this.breaker.execute(async () => {
|
|
99
|
+
const token = await this.getServiceToken();
|
|
100
|
+
const url = `${this.adminBaseUrl}${path}`;
|
|
101
|
+
const res = await fetch(url, {
|
|
102
|
+
method: 'GET',
|
|
103
|
+
headers: {
|
|
104
|
+
Authorization: `Bearer ${token}`,
|
|
105
|
+
Accept: 'application/json',
|
|
106
|
+
},
|
|
107
|
+
});
|
|
108
|
+
if (!res.ok) {
|
|
109
|
+
this.logger.error({ path, status: res.status }, 'Keycloak Admin API request failed');
|
|
110
|
+
throw new Error(`Keycloak Admin ${path}: ${res.status}`);
|
|
111
|
+
}
|
|
112
|
+
return res.json();
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
async getServiceToken() {
|
|
116
|
+
if (this.serviceToken && Date.now() < this.serviceTokenExpiresAt) {
|
|
117
|
+
return this.serviceToken;
|
|
118
|
+
}
|
|
119
|
+
const res = await fetch(this.tokenUrl, {
|
|
120
|
+
method: 'POST',
|
|
121
|
+
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
122
|
+
body: new URLSearchParams({
|
|
123
|
+
grant_type: 'client_credentials',
|
|
124
|
+
client_id: this.clientId,
|
|
125
|
+
client_secret: this.clientSecret,
|
|
126
|
+
}).toString(),
|
|
127
|
+
});
|
|
128
|
+
if (!res.ok) {
|
|
129
|
+
this.logger.error({ status: res.status }, 'Failed to obtain Keycloak service token');
|
|
130
|
+
throw new Error(`Keycloak token request failed: ${res.status}`);
|
|
131
|
+
}
|
|
132
|
+
const data = (await res.json());
|
|
133
|
+
this.serviceToken = data.access_token;
|
|
134
|
+
this.serviceTokenExpiresAt = Date.now() + (data.expires_in - 30) * 1000;
|
|
135
|
+
return this.serviceToken;
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
exports.KeycloakAdminService = KeycloakAdminService;
|
|
139
|
+
exports.KeycloakAdminService = KeycloakAdminService = __decorate([
|
|
140
|
+
(0, common_1.Injectable)(),
|
|
141
|
+
__param(1, (0, nestjs_pino_1.InjectPinoLogger)(KeycloakAdminService.name)),
|
|
142
|
+
__metadata("design:paramtypes", [config_1.ConfigService,
|
|
143
|
+
nestjs_pino_1.PinoLogger])
|
|
144
|
+
], KeycloakAdminService);
|
package/package.json
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@quanticjs/iam-audit",
|
|
3
|
+
"version": "5.10.1",
|
|
4
|
+
"description": "Config-driven IAM audit module — Keycloak Admin REST API dashboard backend for 'who has access to what'",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist"
|
|
9
|
+
],
|
|
10
|
+
"publishConfig": {
|
|
11
|
+
"registry": "https://registry.npmjs.org",
|
|
12
|
+
"access": "public"
|
|
13
|
+
},
|
|
14
|
+
"license": "MIT",
|
|
15
|
+
"scripts": {
|
|
16
|
+
"build": "tsc -p tsconfig.json",
|
|
17
|
+
"test": "jest --passWithNoTests",
|
|
18
|
+
"clean": "rm -rf dist"
|
|
19
|
+
},
|
|
20
|
+
"dependencies": {
|
|
21
|
+
"@quanticjs/core": "^5.10.1"
|
|
22
|
+
},
|
|
23
|
+
"peerDependencies": {
|
|
24
|
+
"@nestjs/common": "^11.0.0",
|
|
25
|
+
"@nestjs/core": "^11.0.0",
|
|
26
|
+
"@nestjs/cqrs": "^11.0.0",
|
|
27
|
+
"@nestjs/config": "^3.0.0 || ^4.0.0",
|
|
28
|
+
"nestjs-pino": "^4.0.0"
|
|
29
|
+
}
|
|
30
|
+
}
|