keycloak-api-manager 6.0.2 → 6.0.4
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 +43 -22
- 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/configuration.md +6 -16
- 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/api-reference.md +6 -6
- package/docs/architecture.md +2 -3
- package/docs/guides/PKCE-Login-Flow.md +4 -17
- package/docs/test-configuration.md +2 -40
- package/docs/testing.md +240 -1
- 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
|
package/docs/api-reference.md
CHANGED
|
@@ -5,7 +5,7 @@ Complete API documentation for keycloak-api-manager.
|
|
|
5
5
|
## Table of Contents
|
|
6
6
|
|
|
7
7
|
### Guides
|
|
8
|
-
- [OIDC Migration Plan](../OIDC_MIGRATION_PLAN.md) -
|
|
8
|
+
- [OIDC Migration Plan](../OIDC_MIGRATION_PLAN.md) - Migration notes for legacy OIDC helpers
|
|
9
9
|
|
|
10
10
|
### Core API
|
|
11
11
|
- [Configuration & Authentication](api/configuration.md) - Setup, authentication, and lifecycle management
|
|
@@ -61,7 +61,8 @@ await KeycloakManager.configure({
|
|
|
61
61
|
tokenLifeSpan: 60
|
|
62
62
|
});
|
|
63
63
|
|
|
64
|
-
//
|
|
64
|
+
// Alternative after configure(): switch runtime context without calling
|
|
65
|
+
// configure() again (no new login/token flow is performed).
|
|
65
66
|
KeycloakManager.setConfig({ realmName: 'my-realm' });
|
|
66
67
|
|
|
67
68
|
// Use handlers
|
|
@@ -79,10 +80,7 @@ KeycloakManager.stop();
|
|
|
79
80
|
| `configure()` | Authentication and setup | Core |
|
|
80
81
|
| `setConfig()` | Runtime configuration | Core |
|
|
81
82
|
| `getToken()` | Get current access/refresh token pair | Core |
|
|
82
|
-
|
|
|
83
|
-
| `generateAuthorizationUrl()` | Deprecated PKCE helper (moved to keycloak-express-middleware) | Core |
|
|
84
|
-
| `loginPKCE()` | Deprecated PKCE token exchange helper (moved to keycloak-express-middleware) | Core |
|
|
85
|
-
| `auth()` | Deprecated backward-compatible alias of `login()` | Core |
|
|
83
|
+
| Legacy OIDC helpers | Backward-compatibility methods (`login`, `generateAuthorizationUrl`, `loginPKCE`, `auth`) | Core |
|
|
86
84
|
| `stop()` | Stop token refresh timer | Core |
|
|
87
85
|
| `realms` | Realm management | realmsHandler |
|
|
88
86
|
| `users` | User management | usersHandler |
|
|
@@ -99,6 +97,8 @@ KeycloakManager.stop();
|
|
|
99
97
|
| `clientPolicies` | Client policy management | clientPoliciesHandler |
|
|
100
98
|
| `serverInfo` | Server information | serverInfoHandler |
|
|
101
99
|
|
|
100
|
+
For deprecation status and migration guidance, see [README - OIDC Deprecation Notice](../README.md#oidc-deprecation-notice).
|
|
101
|
+
|
|
102
102
|
## Parameter Conventions
|
|
103
103
|
|
|
104
104
|
Throughout the API:
|
package/docs/architecture.md
CHANGED
|
@@ -15,10 +15,9 @@ This package exposes a single runtime (`index.js`) that initializes one Keycloak
|
|
|
15
15
|
- Keeps active session/token management in place.
|
|
16
16
|
|
|
17
17
|
3. `login(credentials)`
|
|
18
|
-
-
|
|
19
|
-
- Intended for application-level third-party authentication use-cases.
|
|
18
|
+
- Legacy OIDC helper kept for backward compatibility.
|
|
20
19
|
- Does not mutate the internal admin client session established by `configure()`.
|
|
21
|
-
-
|
|
20
|
+
- For deprecation and migration guidance, see the README OIDC Deprecation Notice.
|
|
22
21
|
|
|
23
22
|
4. `stop()`
|
|
24
23
|
- Stops refresh timer for clean process termination.
|
|
@@ -1,21 +1,8 @@
|
|
|
1
|
-
# PKCE Login Flow
|
|
1
|
+
# PKCE Login Flow
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
PKCE and user-authentication helpers in this package are deprecated and retained only for backward compatibility.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
- `generateAuthorizationUrl(options)`
|
|
8
|
-
- `loginPKCE(credentials)`
|
|
9
|
-
- `login(credentials)`
|
|
10
|
-
- `auth(credentials)`
|
|
11
|
-
|
|
12
|
-
These methods are planned for removal in v7.0.0.
|
|
13
|
-
|
|
14
|
-
For production user authentication flows (including Authorization Code + PKCE), use:
|
|
15
|
-
|
|
16
|
-
- https://github.com/smartenv-crs4/keycloak-express-middleware
|
|
17
|
-
|
|
18
|
-
Migration references:
|
|
5
|
+
For the canonical deprecation notice and migration path, see:
|
|
19
6
|
|
|
7
|
+
- [README - OIDC Deprecation Notice](../../README.md#oidc-deprecation-notice)
|
|
20
8
|
- [OIDC Migration Plan](../../OIDC_MIGRATION_PLAN.md)
|
|
21
|
-
- [Configuration & Authentication](../api/configuration.md)
|
|
@@ -1,43 +1,5 @@
|
|
|
1
1
|
# Test Configuration
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
This file has been merged into the unified [Testing Guide](testing.md).
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
1. `test/config/default.json` (committed defaults)
|
|
8
|
-
2. `test/config/secrets.json` (gitignored sensitive values)
|
|
9
|
-
3. `test/config/local.json` (gitignored machine-specific overrides)
|
|
10
|
-
|
|
11
|
-
The active section is selected by `NODE_ENV` (defaults to `test` in suite bootstrap).
|
|
12
|
-
|
|
13
|
-
## Required Keys
|
|
14
|
-
|
|
15
|
-
- `test.keycloak.baseUrl`
|
|
16
|
-
- `test.keycloak.realmName`
|
|
17
|
-
- `test.keycloak.clientId`
|
|
18
|
-
- `test.keycloak.username`
|
|
19
|
-
- `test.keycloak.password` (typically in `secrets.json`)
|
|
20
|
-
- `test.keycloak.grantType`
|
|
21
|
-
|
|
22
|
-
## Example `secrets.json`
|
|
23
|
-
|
|
24
|
-
```json
|
|
25
|
-
{
|
|
26
|
-
"test": {
|
|
27
|
-
"keycloak": {
|
|
28
|
-
"password": "admin"
|
|
29
|
-
},
|
|
30
|
-
"realm": {
|
|
31
|
-
"user": {
|
|
32
|
-
"password": "test-password"
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
## Security Rules
|
|
40
|
-
|
|
41
|
-
- Never commit `secrets.json`.
|
|
42
|
-
- Never commit production credentials.
|
|
43
|
-
- Keep `default.json` non-sensitive.
|
|
5
|
+
See [Testing Guide — Test Configuration](testing.md#test-configuration) for all config details.
|
package/docs/testing.md
CHANGED
|
@@ -1,6 +1,199 @@
|
|
|
1
1
|
# Testing Guide
|
|
2
2
|
|
|
3
|
-
The test suite validates the package against a real Keycloak server.
|
|
3
|
+
The test suite validates the package against a real Keycloak server. This guide covers both test environment setup and configuration.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
- [Quick Start](#quick-start-end-to-end)
|
|
8
|
+
- [Test Configuration](#test-configuration)
|
|
9
|
+
- [Test Architecture](#test-architecture)
|
|
10
|
+
- [Test Layout](#current-test-layout)
|
|
11
|
+
- [Commands](#commands)
|
|
12
|
+
- [HTTPS Variant](#https-variant)
|
|
13
|
+
- [Setup Flow](#setup-flow)
|
|
14
|
+
- [Writing New Tests](#writing-new-tests)
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## Quick Start (End-to-End)
|
|
19
|
+
|
|
20
|
+
### 1) Install dependencies
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npm install
|
|
24
|
+
npm --prefix test install
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### 2) Prepare local test config
|
|
28
|
+
|
|
29
|
+
Create local override files from the provided examples:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
cp test/config/local.json.example test/config/local.json
|
|
33
|
+
cp test/config/secrets.json.example test/config/secrets.json
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Then edit:
|
|
37
|
+
|
|
38
|
+
- `test/config/local.json` to set the Keycloak URL you can reach locally.
|
|
39
|
+
- `test/config/secrets.json` to set admin credentials.
|
|
40
|
+
|
|
41
|
+
For local Docker on default HTTP port:
|
|
42
|
+
|
|
43
|
+
```json
|
|
44
|
+
{
|
|
45
|
+
"test": {
|
|
46
|
+
"keycloak": {
|
|
47
|
+
"baseUrl": "http://127.0.0.1:8080",
|
|
48
|
+
"password": "admin"
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### 3) Prepare Keycloak for tests (choose one mode)
|
|
55
|
+
|
|
56
|
+
Choose one of the following modes.
|
|
57
|
+
|
|
58
|
+
#### Mode A: Existing Keycloak instance (no Docker startup here)
|
|
59
|
+
|
|
60
|
+
If you already have a reachable Keycloak instance:
|
|
61
|
+
|
|
62
|
+
- set `test.keycloak.baseUrl` in `test/config/local.json` to that instance URL
|
|
63
|
+
- ensure admin credentials in `test/config/secrets.json` are valid for that instance
|
|
64
|
+
- skip any startup command and run tests directly
|
|
65
|
+
|
|
66
|
+
Example using an existing instance:
|
|
67
|
+
|
|
68
|
+
```json
|
|
69
|
+
{
|
|
70
|
+
"test": {
|
|
71
|
+
"keycloak": {
|
|
72
|
+
"baseUrl": "https://my-keycloak.company.net"
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Then run:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
npm test
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
#### Mode B: Automated setup with `npm run setup-keycloak`
|
|
85
|
+
|
|
86
|
+
Use this when you do not already have a ready instance and want the helper to provision one.
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
npm run setup-keycloak
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
What this command does:
|
|
93
|
+
|
|
94
|
+
- runs an interactive setup (local or remote, HTTP or HTTPS)
|
|
95
|
+
- starts Keycloak via Docker Compose in the selected mode
|
|
96
|
+
- waits for readiness
|
|
97
|
+
- updates `test/config/default.json` with the generated `test.keycloak.baseUrl`
|
|
98
|
+
|
|
99
|
+
#### Mode C: Manual Docker startup
|
|
100
|
+
|
|
101
|
+
Use this if you prefer full manual control instead of the setup helper:
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
docker compose -f test/docker-keycloak/docker-compose.yml up -d
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Wait until ready:
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
docker compose -f test/docker-keycloak/docker-compose.yml ps
|
|
111
|
+
curl -f http://127.0.0.1:8080/health/ready
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### 4) Run tests
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
npm test
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### 5) Stop environment (optional but recommended)
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
docker compose -f test/docker-keycloak/docker-compose.yml down
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
To also remove container volumes:
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
docker compose -f test/docker-keycloak/docker-compose.yml down -v
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
## Test Configuration
|
|
135
|
+
|
|
136
|
+
Test configuration uses `propertiesmanager` with a layered file strategy. Files are merged in this priority order (higher overrides lower):
|
|
137
|
+
|
|
138
|
+
1. `test/config/default.json` — committed defaults, non-sensitive
|
|
139
|
+
2. `test/config/secrets.json` — gitignored, admin credentials and passwords
|
|
140
|
+
3. `test/config/local.json` — gitignored, machine-specific host/port overrides
|
|
141
|
+
|
|
142
|
+
The active section is selected by `NODE_ENV` (defaults to `test` in suite bootstrap).
|
|
143
|
+
|
|
144
|
+
### Required Configuration Keys
|
|
145
|
+
|
|
146
|
+
| Key | Description |
|
|
147
|
+
|-----|-------------|
|
|
148
|
+
| `test.keycloak.baseUrl` | Keycloak server URL |
|
|
149
|
+
| `test.keycloak.realmName` | Realm used for authentication |
|
|
150
|
+
| `test.keycloak.clientId` | Client ID (usually `admin-cli`) |
|
|
151
|
+
| `test.keycloak.username` | Admin username |
|
|
152
|
+
| `test.keycloak.password` | Admin password (put in `secrets.json`) |
|
|
153
|
+
| `test.keycloak.grantType` | Usually `password` |
|
|
154
|
+
|
|
155
|
+
### Recommended Pattern
|
|
156
|
+
|
|
157
|
+
- Keep defaults and non-sensitive values in `default.json`.
|
|
158
|
+
- Put admin passwords and test user passwords in `secrets.json`.
|
|
159
|
+
- Put local machine-specific URLs/ports in `local.json`.
|
|
160
|
+
|
|
161
|
+
Example `local.json`:
|
|
162
|
+
|
|
163
|
+
```json
|
|
164
|
+
{
|
|
165
|
+
"test": {
|
|
166
|
+
"keycloak": {
|
|
167
|
+
"baseUrl": "http://127.0.0.1:8080"
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
Example `secrets.json`:
|
|
174
|
+
|
|
175
|
+
```json
|
|
176
|
+
{
|
|
177
|
+
"test": {
|
|
178
|
+
"keycloak": {
|
|
179
|
+
"password": "your-admin-password-here"
|
|
180
|
+
},
|
|
181
|
+
"realm": {
|
|
182
|
+
"user": {
|
|
183
|
+
"password": "test-password"
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### Security Rules
|
|
191
|
+
|
|
192
|
+
- Never commit `secrets.json` or `local.json`.
|
|
193
|
+
- Never commit production credentials.
|
|
194
|
+
- Keep `default.json` non-sensitive.
|
|
195
|
+
|
|
196
|
+
---
|
|
4
197
|
|
|
5
198
|
## Test Architecture
|
|
6
199
|
|
|
@@ -12,6 +205,8 @@ The suite uses a shared realm strategy:
|
|
|
12
205
|
|
|
13
206
|
This improves speed and keeps the environment deterministic.
|
|
14
207
|
|
|
208
|
+
---
|
|
209
|
+
|
|
15
210
|
## Current Test Layout
|
|
16
211
|
|
|
17
212
|
```text
|
|
@@ -26,9 +221,14 @@ test/
|
|
|
26
221
|
testConfig.js
|
|
27
222
|
```
|
|
28
223
|
|
|
224
|
+
---
|
|
225
|
+
|
|
29
226
|
## Commands
|
|
30
227
|
|
|
31
228
|
```bash
|
|
229
|
+
# interactive provisioning helper (starts docker and sets baseUrl)
|
|
230
|
+
npm run setup-keycloak
|
|
231
|
+
|
|
32
232
|
# full suite
|
|
33
233
|
npm test
|
|
34
234
|
|
|
@@ -40,6 +240,41 @@ npm --prefix test test -- --grep "Organizations Handler Tests"
|
|
|
40
240
|
npm --prefix test test -- --grep "Matrix -"
|
|
41
241
|
```
|
|
42
242
|
|
|
243
|
+
### Command Difference: `npm test` vs `npm --prefix test test`
|
|
244
|
+
|
|
245
|
+
- `npm test` (from repository root): runs the root test script, which first installs test workspace dependencies and then executes the suite.
|
|
246
|
+
- `npm --prefix test test`: runs the test workspace script directly, without performing the install step.
|
|
247
|
+
|
|
248
|
+
Current root script behavior:
|
|
249
|
+
|
|
250
|
+
```text
|
|
251
|
+
npm test => npm --prefix test install && npm --prefix test test
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
Practical rule:
|
|
255
|
+
|
|
256
|
+
- use `npm test` when setting up a fresh environment or after dependency changes
|
|
257
|
+
- use `npm --prefix test test` for faster repeated runs when dependencies are already installed
|
|
258
|
+
|
|
259
|
+
---
|
|
260
|
+
|
|
261
|
+
## HTTPS Variant
|
|
262
|
+
|
|
263
|
+
For HTTPS-like environments use the dedicated compose file:
|
|
264
|
+
|
|
265
|
+
```bash
|
|
266
|
+
export KEYCLOAK_CERT_PATH=/absolute/path/to/certs
|
|
267
|
+
export KEYCLOAK_HOSTNAME=keycloak.local
|
|
268
|
+
docker compose -f test/docker-keycloak/docker-compose-https.yml up -d
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
The cert directory must contain:
|
|
272
|
+
|
|
273
|
+
- `keycloak.crt`
|
|
274
|
+
- `keycloak.key`
|
|
275
|
+
|
|
276
|
+
---
|
|
277
|
+
|
|
43
278
|
## Setup Flow
|
|
44
279
|
|
|
45
280
|
`test/support/setup.js` runs before all suites and executes `test/support/enableServerFeatures.js` to provision:
|
|
@@ -52,6 +287,10 @@ npm --prefix test test -- --grep "Matrix -"
|
|
|
52
287
|
- client scope
|
|
53
288
|
- fine-grained permissions (when feature-enabled)
|
|
54
289
|
|
|
290
|
+
The same bootstrap also performs cleanup in global teardown by deleting the shared test realm.
|
|
291
|
+
|
|
292
|
+
---
|
|
293
|
+
|
|
55
294
|
## Writing New Tests
|
|
56
295
|
|
|
57
296
|
- Import config from `test/testConfig.js`.
|