keycloak-api-manager 6.0.2 → 6.0.3
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/Handlers/attackDetectionHandler.js +12 -8
- package/Handlers/clientScopesHandler.js +9 -9
- package/Handlers/groupsHandler.js +3 -2
- package/Handlers/rolesHandler.js +14 -12
- package/README.md +1 -1
- package/docs/api/attack-detection.md +82 -16
- package/docs/api/authentication-management.md +356 -70
- package/docs/api/client-policies.md +103 -16
- package/docs/api/client-scopes.md +52 -4
- package/docs/api/components.md +107 -19
- package/docs/api/groups.md +46 -5
- package/docs/api/identity-providers.md +50 -5
- package/docs/api/roles.md +37 -7
- package/docs/api/server-info.md +42 -17
- package/docs/api/user-profile.md +55 -10
- package/docs/test-configuration.md +19 -1
- package/docs/testing.md +86 -0
- package/package.json +1 -1
- package/test/config/secrets.json.example +1 -1
package/docs/api/roles.md
CHANGED
|
@@ -2,7 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
Realm and client role management, including composite roles.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Namespace: KeycloakManager.roles
|
|
6
|
+
|
|
7
|
+
## Overview
|
|
8
|
+
|
|
9
|
+
This handler manages realm roles and composite relationships.
|
|
10
|
+
It covers CRUD, user-role lookup, and composite role operations for realm and client roles.
|
|
6
11
|
|
|
7
12
|
## Role CRUD
|
|
8
13
|
|
|
@@ -16,25 +21,28 @@ Create a realm role.
|
|
|
16
21
|
### find(filters)
|
|
17
22
|
List realm roles.
|
|
18
23
|
|
|
19
|
-
- **Optional**: `first`, `max`, `search`, `briefRepresentation`
|
|
24
|
+
- **Optional**: `first`, `max`, `search`, `briefRepresentation`, `realm`
|
|
20
25
|
- **Returns**: Promise<Array<RoleRepresentation>>
|
|
21
26
|
|
|
22
27
|
### findOneByName(filters)
|
|
23
28
|
Get role by name.
|
|
24
29
|
|
|
25
30
|
- **Required**: `filters.name` (string)
|
|
31
|
+
- **Optional**: `filters.realm` (string)
|
|
26
32
|
- **Returns**: Promise<RoleRepresentation>
|
|
27
33
|
|
|
28
34
|
### findOneById(filters)
|
|
29
35
|
Get role by id.
|
|
30
36
|
|
|
31
37
|
- **Required**: `filters.id` (string)
|
|
38
|
+
- **Optional**: `filters.realm` (string)
|
|
32
39
|
- **Returns**: Promise<RoleRepresentation>
|
|
33
40
|
|
|
34
41
|
### updateByName(filters, role_dictionary)
|
|
35
42
|
Update role by name.
|
|
36
43
|
|
|
37
44
|
- **Required**: `filters.name` (string)
|
|
45
|
+
- **Optional**: `filters.realm` (string)
|
|
38
46
|
- **Required**: `role_dictionary` (partial role)
|
|
39
47
|
- **Returns**: Promise<void>
|
|
40
48
|
|
|
@@ -42,6 +50,7 @@ Update role by name.
|
|
|
42
50
|
Update role by id.
|
|
43
51
|
|
|
44
52
|
- **Required**: `filters.id` (string)
|
|
53
|
+
- **Optional**: `filters.realm` (string)
|
|
45
54
|
- **Required**: `role_dictionary` (partial role)
|
|
46
55
|
- **Returns**: Promise<void>
|
|
47
56
|
|
|
@@ -49,6 +58,7 @@ Update role by id.
|
|
|
49
58
|
Delete role by name.
|
|
50
59
|
|
|
51
60
|
- **Required**: `filters.name` (string)
|
|
61
|
+
- **Optional**: `filters.realm` (string)
|
|
52
62
|
- **Returns**: Promise<void>
|
|
53
63
|
|
|
54
64
|
## Composite Roles
|
|
@@ -56,27 +66,31 @@ Delete role by name.
|
|
|
56
66
|
### createComposite(filters, roles)
|
|
57
67
|
Add composites to a realm role.
|
|
58
68
|
|
|
59
|
-
- **Required**: `filters.
|
|
69
|
+
- **Required**: `filters.roleId` (string)
|
|
70
|
+
- **Optional**: `filters.realm` (string)
|
|
60
71
|
- **Required**: `roles` (Array<{id,name}>), realm or client roles
|
|
61
72
|
- **Returns**: Promise<void>
|
|
62
73
|
|
|
63
74
|
### getCompositeRoles(filters)
|
|
64
75
|
Get all composites for a role.
|
|
65
76
|
|
|
66
|
-
- **Required**: `filters.
|
|
77
|
+
- **Required**: `filters.id` (string)
|
|
78
|
+
- **Optional**: `filters.realm` (string)
|
|
67
79
|
- **Returns**: Promise<Array<RoleRepresentation>>
|
|
68
80
|
|
|
69
81
|
### getCompositeRolesForRealm(filters)
|
|
70
82
|
Get realm-level composites.
|
|
71
83
|
|
|
72
|
-
- **Required**: `filters.
|
|
84
|
+
- **Required**: `filters.id` (string)
|
|
85
|
+
- **Optional**: `filters.realm` (string)
|
|
73
86
|
- **Returns**: Promise<Array<RoleRepresentation>>
|
|
74
87
|
|
|
75
88
|
### getCompositeRolesForClient(filters)
|
|
76
89
|
Get client-level composites.
|
|
77
90
|
|
|
78
|
-
- **Required**: `filters.
|
|
79
|
-
- **Required**: `filters.
|
|
91
|
+
- **Required**: `filters.id` (string)
|
|
92
|
+
- **Required**: `filters.clientId` (string, client UUID)
|
|
93
|
+
- **Optional**: `filters.realm` (string)
|
|
80
94
|
- **Returns**: Promise<Array<RoleRepresentation>>
|
|
81
95
|
|
|
82
96
|
## Users with Role
|
|
@@ -85,6 +99,7 @@ Get client-level composites.
|
|
|
85
99
|
List users that have a specific realm role.
|
|
86
100
|
|
|
87
101
|
- **Required**: `filters.name` (role name)
|
|
102
|
+
- **Optional**: `filters.realm` (string)
|
|
88
103
|
- **Optional**: `first`, `max`
|
|
89
104
|
- **Returns**: Promise<Array<UserRepresentation>>
|
|
90
105
|
|
|
@@ -94,6 +109,21 @@ List users that have a specific realm role.
|
|
|
94
109
|
await KeycloakManager.roles.create({ name: 'realm-admin' });
|
|
95
110
|
const role = await KeycloakManager.roles.findOneByName({ name: 'realm-admin' });
|
|
96
111
|
const users = await KeycloakManager.roles.findUsersWithRole({ name: 'realm-admin' });
|
|
112
|
+
|
|
113
|
+
// Composite role with one realm role and one client role
|
|
114
|
+
await KeycloakManager.roles.createComposite(
|
|
115
|
+
{ roleId: compositeRoleId },
|
|
116
|
+
[
|
|
117
|
+
{ id: realmRoleId, name: 'test-role-1' },
|
|
118
|
+
{ id: clientRoleId, name: 'client-role-a', clientRole: true, containerId: clientUuid }
|
|
119
|
+
]
|
|
120
|
+
);
|
|
121
|
+
|
|
122
|
+
const realmComposites = await KeycloakManager.roles.getCompositeRolesForRealm({ id: compositeRoleId });
|
|
123
|
+
const clientComposites = await KeycloakManager.roles.getCompositeRolesForClient({
|
|
124
|
+
id: compositeRoleId,
|
|
125
|
+
clientId: clientUuid,
|
|
126
|
+
});
|
|
97
127
|
```
|
|
98
128
|
|
|
99
129
|
## See Also
|
package/docs/api/server-info.md
CHANGED
|
@@ -2,37 +2,62 @@
|
|
|
2
2
|
|
|
3
3
|
Read Keycloak server capabilities and runtime metadata.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Namespace: KeycloakManager.serverInfo
|
|
6
|
+
|
|
7
|
+
## Overview
|
|
8
|
+
|
|
9
|
+
Use this handler to inspect server capabilities before enabling advanced features in automation.
|
|
10
|
+
It is useful for diagnostics and compatibility checks in CI pipelines.
|
|
6
11
|
|
|
7
12
|
## Methods
|
|
8
13
|
|
|
9
14
|
### getInfo()
|
|
10
|
-
Get full server-info payload.
|
|
11
15
|
|
|
12
|
-
-
|
|
13
|
-
|
|
16
|
+
Fetch the full server-info payload from the configured realm context.
|
|
17
|
+
|
|
18
|
+
Parameters:
|
|
19
|
+
|
|
20
|
+
- none
|
|
21
|
+
|
|
22
|
+
Returns:
|
|
23
|
+
|
|
24
|
+
- Promise<object>: full server info payload.
|
|
25
|
+
|
|
26
|
+
Common top-level sections returned by Keycloak include:
|
|
14
27
|
|
|
15
|
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
-
|
|
20
|
-
-
|
|
21
|
-
-
|
|
22
|
-
-
|
|
23
|
-
-
|
|
24
|
-
-
|
|
25
|
-
- `enums`
|
|
28
|
+
- systemInfo
|
|
29
|
+
- memoryInfo
|
|
30
|
+
- profileInfo
|
|
31
|
+
- themes
|
|
32
|
+
- providers
|
|
33
|
+
- componentTypes
|
|
34
|
+
- passwordPolicies
|
|
35
|
+
- protocolMapperTypes
|
|
36
|
+
- clientInstallations
|
|
37
|
+
- enums
|
|
26
38
|
|
|
27
|
-
|
|
39
|
+
Example: basic inspection
|
|
28
40
|
|
|
29
41
|
```js
|
|
30
42
|
const info = await KeycloakManager.serverInfo.getInfo();
|
|
31
43
|
|
|
32
44
|
console.log('Keycloak version:', info.systemInfo?.version);
|
|
33
45
|
console.log('Available themes:', Object.keys(info.themes || {}));
|
|
34
|
-
console.log('
|
|
46
|
+
console.log('Provider categories:', Object.keys(info.providers || {}));
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Example: feature guard before workflow
|
|
50
|
+
|
|
51
|
+
```js
|
|
52
|
+
const info = await KeycloakManager.serverInfo.getInfo();
|
|
53
|
+
const hasOrganizationFeature = Boolean(info.profileInfo?.features?.organization);
|
|
54
|
+
|
|
55
|
+
if (!hasOrganizationFeature) {
|
|
56
|
+
throw new Error('Organization feature is not enabled on this Keycloak server.');
|
|
57
|
+
}
|
|
35
58
|
```
|
|
36
59
|
|
|
37
60
|
## See Also
|
|
61
|
+
|
|
38
62
|
- [API Reference](../api-reference.md)
|
|
63
|
+
- [Keycloak Setup and Feature Flags](../keycloak-setup.md)
|
package/docs/api/user-profile.md
CHANGED
|
@@ -2,28 +2,72 @@
|
|
|
2
2
|
|
|
3
3
|
Manage realm user-profile configuration and metadata.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Namespace: KeycloakManager.userProfile
|
|
6
|
+
|
|
7
|
+
## Overview
|
|
8
|
+
|
|
9
|
+
This handler manages declarative user-profile schema in a realm.
|
|
10
|
+
It allows you to inspect current schema, update it, and read resolved metadata (validators, capabilities, attribute model).
|
|
11
|
+
|
|
12
|
+
Note: endpoints are accessed through direct REST calls in the handler for compatibility across admin-client versions.
|
|
6
13
|
|
|
7
14
|
## Methods
|
|
8
15
|
|
|
9
16
|
### getConfiguration(filter)
|
|
10
|
-
Get user-profile configuration for realm.
|
|
11
17
|
|
|
12
|
-
|
|
13
|
-
|
|
18
|
+
Get the current declarative user-profile configuration.
|
|
19
|
+
|
|
20
|
+
Parameters:
|
|
21
|
+
|
|
22
|
+
- filter (object, optional):
|
|
23
|
+
- realm (string, optional): override target realm.
|
|
24
|
+
|
|
25
|
+
Returns:
|
|
26
|
+
|
|
27
|
+
- Promise<object>: current profile configuration.
|
|
14
28
|
|
|
15
29
|
### updateConfiguration(filter, userProfileConfig)
|
|
30
|
+
|
|
16
31
|
Update user-profile configuration.
|
|
17
32
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
-
|
|
33
|
+
Parameters:
|
|
34
|
+
|
|
35
|
+
- filter (object, optional):
|
|
36
|
+
- realm (string, optional): override target realm.
|
|
37
|
+
- userProfileConfig (object, required): full or partial schema payload.
|
|
38
|
+
|
|
39
|
+
Common top-level fields:
|
|
40
|
+
|
|
41
|
+
- attributes (array): attribute definitions.
|
|
42
|
+
- groups (array, optional): grouped attributes.
|
|
43
|
+
- unmanagedAttributePolicy (string, optional)
|
|
44
|
+
|
|
45
|
+
Common attribute fields:
|
|
46
|
+
|
|
47
|
+
- name (string, required): attribute key.
|
|
48
|
+
- displayName (string, optional)
|
|
49
|
+
- required (object, optional): required rules.
|
|
50
|
+
- permissions (object, optional): view/edit permissions.
|
|
51
|
+
- validations (object, optional): validation rules.
|
|
52
|
+
- annotations (object, optional): UI/metadata annotations.
|
|
53
|
+
- multivalued (boolean, optional): enable list values.
|
|
54
|
+
|
|
55
|
+
Returns:
|
|
56
|
+
|
|
57
|
+
- Promise<void|object>: usually no content (204), or response payload if provided by server.
|
|
21
58
|
|
|
22
59
|
### getMetadata(filter)
|
|
23
|
-
Get resolved user-profile metadata.
|
|
24
60
|
|
|
25
|
-
-
|
|
26
|
-
|
|
61
|
+
Get user-profile metadata resolved by the server.
|
|
62
|
+
|
|
63
|
+
Parameters:
|
|
64
|
+
|
|
65
|
+
- filter (object, optional):
|
|
66
|
+
- realm (string, optional): override target realm.
|
|
67
|
+
|
|
68
|
+
Returns:
|
|
69
|
+
|
|
70
|
+
- Promise<object>: metadata payload (validators, resolved attributes, capabilities).
|
|
27
71
|
|
|
28
72
|
## Common User Profile Structure
|
|
29
73
|
|
|
@@ -56,6 +100,7 @@ await KeycloakManager.userProfile.updateConfiguration({}, {
|
|
|
56
100
|
});
|
|
57
101
|
|
|
58
102
|
const metadata = await KeycloakManager.userProfile.getMetadata();
|
|
103
|
+
console.log('Available validators:', Object.keys(metadata.validators || {}));
|
|
59
104
|
```
|
|
60
105
|
|
|
61
106
|
## See Also
|
|
@@ -19,13 +19,31 @@ The active section is selected by `NODE_ENV` (defaults to `test` in suite bootst
|
|
|
19
19
|
- `test.keycloak.password` (typically in `secrets.json`)
|
|
20
20
|
- `test.keycloak.grantType`
|
|
21
21
|
|
|
22
|
+
## Recommended Local Setup
|
|
23
|
+
|
|
24
|
+
1. Keep non-sensitive defaults in `default.json`.
|
|
25
|
+
2. Put secrets in `secrets.json`.
|
|
26
|
+
3. Override per-machine host/ports in `local.json`.
|
|
27
|
+
|
|
28
|
+
Example `local.json` for local Docker Keycloak:
|
|
29
|
+
|
|
30
|
+
```json
|
|
31
|
+
{
|
|
32
|
+
"test": {
|
|
33
|
+
"keycloak": {
|
|
34
|
+
"baseUrl": "http://127.0.0.1:8080"
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
22
40
|
## Example `secrets.json`
|
|
23
41
|
|
|
24
42
|
```json
|
|
25
43
|
{
|
|
26
44
|
"test": {
|
|
27
45
|
"keycloak": {
|
|
28
|
-
"password": "admin"
|
|
46
|
+
"password": "your-admin-password-here"
|
|
29
47
|
},
|
|
30
48
|
"realm": {
|
|
31
49
|
"user": {
|
package/docs/testing.md
CHANGED
|
@@ -2,6 +2,75 @@
|
|
|
2
2
|
|
|
3
3
|
The test suite validates the package against a real Keycloak server.
|
|
4
4
|
|
|
5
|
+
## Quick Start (End-to-End)
|
|
6
|
+
|
|
7
|
+
Use these steps to create the test environment, start it, and run the suite.
|
|
8
|
+
|
|
9
|
+
### 1) Install dependencies
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install
|
|
13
|
+
npm --prefix test install
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
### 2) Prepare local test config
|
|
17
|
+
|
|
18
|
+
Create local override files from examples:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
cp test/config/local.json.example test/config/local.json
|
|
22
|
+
cp test/config/secrets.json.example test/config/secrets.json
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Then edit:
|
|
26
|
+
|
|
27
|
+
- `test/config/local.json` to set the Keycloak URL you can reach locally.
|
|
28
|
+
- `test/config/secrets.json` to set admin credentials.
|
|
29
|
+
|
|
30
|
+
For local Docker on default HTTP port, a common value is:
|
|
31
|
+
|
|
32
|
+
```json
|
|
33
|
+
{
|
|
34
|
+
"test": {
|
|
35
|
+
"keycloak": {
|
|
36
|
+
"baseUrl": "http://127.0.0.1:8080",
|
|
37
|
+
"password": "admin"
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### 3) Start Keycloak for tests
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
docker compose -f test/docker-keycloak/docker-compose.yml up -d
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Wait until ready:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
docker compose -f test/docker-keycloak/docker-compose.yml ps
|
|
53
|
+
curl -f http://127.0.0.1:8080/health/ready
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### 4) Run tests
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
npm test
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### 5) Stop environment (optional but recommended)
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
docker compose -f test/docker-keycloak/docker-compose.yml down
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
If you want to remove container volumes too:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
docker compose -f test/docker-keycloak/docker-compose.yml down -v
|
|
72
|
+
```
|
|
73
|
+
|
|
5
74
|
## Test Architecture
|
|
6
75
|
|
|
7
76
|
The suite uses a shared realm strategy:
|
|
@@ -40,6 +109,21 @@ npm --prefix test test -- --grep "Organizations Handler Tests"
|
|
|
40
109
|
npm --prefix test test -- --grep "Matrix -"
|
|
41
110
|
```
|
|
42
111
|
|
|
112
|
+
## HTTPS Variant
|
|
113
|
+
|
|
114
|
+
For HTTPS-like environments use the dedicated compose file:
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
export KEYCLOAK_CERT_PATH=/absolute/path/to/certs
|
|
118
|
+
export KEYCLOAK_HOSTNAME=keycloak.local
|
|
119
|
+
docker compose -f test/docker-keycloak/docker-compose-https.yml up -d
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
The cert directory must contain:
|
|
123
|
+
|
|
124
|
+
- `keycloak.crt`
|
|
125
|
+
- `keycloak.key`
|
|
126
|
+
|
|
43
127
|
## Setup Flow
|
|
44
128
|
|
|
45
129
|
`test/support/setup.js` runs before all suites and executes `test/support/enableServerFeatures.js` to provision:
|
|
@@ -52,6 +136,8 @@ npm --prefix test test -- --grep "Matrix -"
|
|
|
52
136
|
- client scope
|
|
53
137
|
- fine-grained permissions (when feature-enabled)
|
|
54
138
|
|
|
139
|
+
The same bootstrap also performs cleanup in global teardown by deleting the shared test realm.
|
|
140
|
+
|
|
55
141
|
## Writing New Tests
|
|
56
142
|
|
|
57
143
|
- Import config from `test/testConfig.js`.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "keycloak-api-manager",
|
|
3
|
-
"version": "6.0.
|
|
3
|
+
"version": "6.0.3",
|
|
4
4
|
"description": "Enhanced Node.js wrapper for Keycloak Admin REST API. Professional alternative to @keycloak/keycloak-admin-client with advanced features, bug fixes, automatic token refresh, Organizations API support, fine-grained permissions, and comprehensive resource management. Battle-tested with 113+ integration tests.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|