keycloak-api-manager 3.2.0 → 3.2.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/.mocharc.json +7 -0
- package/Handlers/authenticationManagementHandler.js +1 -1
- package/Handlers/clientScopesHandler.js +5 -5
- package/Handlers/clientsHandler.js +1 -1
- package/Handlers/componentsHandler.js +2 -2
- package/Handlers/groupsHandler.js +2 -2
- package/Handlers/identityProvidersHandler.js +3 -3
- package/README.md +20 -16
- package/docker-compose.yml +27 -0
- package/index.mjs +21 -0
- package/package.json +14 -2
- package/test/authenticationManagement.test.js +329 -0
- package/test/clientScopes.test.js +256 -0
- package/test/clients.test.js +284 -0
- package/test/components.test.js +122 -0
- package/test/config.js +137 -0
- package/test/docker-helpers.js +111 -0
- package/test/groups.test.js +284 -0
- package/test/identityProviders.test.js +197 -0
- package/test/mocha.env.js +55 -0
- package/test/realms.test.js +349 -0
- package/test/roles.test.js +215 -0
- package/test/users.test.js +405 -0
- package/.idea/vcs.xml +0 -6
- package/.idea/workspace.xml +0 -94
package/.mocharc.json
ADDED
|
@@ -218,7 +218,7 @@ exports.updateRequiredAction=function(filter,actionRepresentation){
|
|
|
218
218
|
* @parameters:
|
|
219
219
|
* - filter: parameter provided as a JSON object that accepts the following filter:
|
|
220
220
|
* - alias: [required] The alias (providerId) of the required action to update.
|
|
221
|
-
* -
|
|
221
|
+
* - actionConfigRepresentation: The configuration object to update.
|
|
222
222
|
*/
|
|
223
223
|
exports.updateRequiredActionConfig=function(filter, actionConfigRepresentation){
|
|
224
224
|
return (kcAdminClientHandler.authenticationManagement.updateRequiredActionConfig(filter,actionConfigRepresentation));
|
|
@@ -20,8 +20,8 @@ exports.setKcAdminClient=function(kcAdminClient){
|
|
|
20
20
|
* A client scope defines a set of protocol mappers and roles that can be applied to clients,
|
|
21
21
|
* such as during login or token generation.
|
|
22
22
|
*/
|
|
23
|
-
exports.create=function(
|
|
24
|
-
return (kcAdminClientHandler.clientScopes.create(
|
|
23
|
+
exports.create=function(scopeRepresentation){
|
|
24
|
+
return (kcAdminClientHandler.clientScopes.create(scopeRepresentation ));
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
|
|
@@ -35,13 +35,13 @@ exports.create=function(scopeRappresentation){
|
|
|
35
35
|
* - filter: parameter provided as a JSON object that accepts the following filter:
|
|
36
36
|
* - id: [required] The unique ID of the client scope to update.
|
|
37
37
|
* - realm: [optional] The realm where the client scope exists.
|
|
38
|
-
* -
|
|
38
|
+
* - scopeRepresentation: The updated client scope object.
|
|
39
39
|
* - name: [optional] The name of the scope
|
|
40
40
|
* - description: [optional] The scope description
|
|
41
41
|
* - {other scope fields}
|
|
42
42
|
*/
|
|
43
|
-
exports.update=function(filter,
|
|
44
|
-
return (kcAdminClientHandler.clientScopes.update(filter,
|
|
43
|
+
exports.update=function(filter,scopeRepresentation){
|
|
44
|
+
return (kcAdminClientHandler.clientScopes.update(filter,scopeRepresentation ));
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
|
|
@@ -195,7 +195,7 @@ exports.getClientSecret=function(filter){
|
|
|
195
195
|
* - id: [required] The internal ID of the client (not clientId)
|
|
196
196
|
*/
|
|
197
197
|
exports.generateNewClientSecret=function(filter){
|
|
198
|
-
return (kcAdminClientHandler.clients.
|
|
198
|
+
return (kcAdminClientHandler.clients.generateNewClientSecret(filter));
|
|
199
199
|
}
|
|
200
200
|
|
|
201
201
|
|
|
@@ -60,8 +60,8 @@ exports.create=function(componentRepresentation){
|
|
|
60
60
|
* - bindCredential: ["secret"],
|
|
61
61
|
* - usersDn: ["ou=users,dc=example,dc=com"]
|
|
62
62
|
*/
|
|
63
|
-
exports.update=function(
|
|
64
|
-
return (kcAdminClientHandler.components.update(
|
|
63
|
+
exports.update=function(filter, componentRepresentation){
|
|
64
|
+
return (kcAdminClientHandler.components.update(filter, componentRepresentation));
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
|
|
@@ -25,8 +25,8 @@ exports.setKcAdminClient=function(kcAdminClient){
|
|
|
25
25
|
* - description: [optional] the new group Description
|
|
26
26
|
* - {other [optional] group description fields}
|
|
27
27
|
*/
|
|
28
|
-
exports.create=function(
|
|
29
|
-
return (kcAdminClientHandler.groups.create(
|
|
28
|
+
exports.create=function(groupRepresentation){
|
|
29
|
+
return (kcAdminClientHandler.groups.create(groupRepresentation));
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
|
|
@@ -18,7 +18,7 @@ exports.setKcAdminClient=function(kcAdminClient){
|
|
|
18
18
|
* or another SAML/OIDC provider.
|
|
19
19
|
* This method requires specifying an alias, the provider type, and configuration settings such as client ID, client secret, and any other provider-specific options.
|
|
20
20
|
* @parameters:
|
|
21
|
-
* -
|
|
21
|
+
* - identityProvidersRepresentation: parameter provided as a JSON object containing the configuration of the Identity Provider
|
|
22
22
|
* - alias: [required] Unique name for the IdP within the realm.
|
|
23
23
|
* - providerId: [required] Type of provider (google, facebook, oidc, saml, etc.).
|
|
24
24
|
* - enabled: [optional] Whether the IdP is enabled. Default is true.
|
|
@@ -29,8 +29,8 @@ exports.setKcAdminClient=function(kcAdminClient){
|
|
|
29
29
|
* - firstBrokerLoginFlowAlias: [optional] Flow to use on first login.
|
|
30
30
|
* - config : [optional] Provider-specific configuration, e.g., client ID, client secret, endpoints, etc.
|
|
31
31
|
*/
|
|
32
|
-
exports.create=function(
|
|
33
|
-
return (kcAdminClientHandler.identityProviders.create(
|
|
32
|
+
exports.create=function(identityProvidersRepresentation){
|
|
33
|
+
return (kcAdminClientHandler.identityProviders.create(identityProvidersRepresentation));
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
/**
|
package/README.md
CHANGED
|
@@ -95,7 +95,7 @@ const express = require('express');
|
|
|
95
95
|
// Initialize the manager with Keycloak credentials
|
|
96
96
|
await KeycloakManager.configure({
|
|
97
97
|
baseUrl: 'http://localhost:8080', // Keycloak base URL
|
|
98
|
-
|
|
98
|
+
realmName: 'master', // Realm where the admin user belongs (alias: realm)
|
|
99
99
|
clientId: 'admin-cli', // Keycloak admin client
|
|
100
100
|
username: 'admin', // Admin username
|
|
101
101
|
password: 'admin', // Admin password
|
|
@@ -165,7 +165,7 @@ const KeycloakManager = require('keycloak-api-manager');
|
|
|
165
165
|
// Initialize the manager with Keycloak credentials
|
|
166
166
|
await KeycloakManager.configure({
|
|
167
167
|
baseUrl: 'http://localhost:8080', // Keycloak base URL
|
|
168
|
-
|
|
168
|
+
realmName: 'master', // Realm where the admin user belongs (alias: realm)
|
|
169
169
|
clientId: 'admin-cli', // Keycloak admin client
|
|
170
170
|
username: 'admin', // Admin username
|
|
171
171
|
password: 'admin', // Admin password
|
|
@@ -186,7 +186,8 @@ Parameters:
|
|
|
186
186
|
exposed by this adapter, so any attempt to call KeycloakManager.{function} will result in a runtime error due to access on an undefined object
|
|
187
187
|
Main supported options:
|
|
188
188
|
- baseUrl: [required] Keycloak base Url
|
|
189
|
-
|
|
189
|
+
- realmName: [required] A String that specifies the realm to authenticate against, if different from the "keyCloakConfig.realm" parameter. If you intend to use Keycloak administrator credentials, this should be set to 'master'.
|
|
190
|
+
- realm: [optional] Alias of realmName for backward compatibility.
|
|
190
191
|
- grantType: [required] The OAuth2 grant type used for authentication. example "password". Possible values: 'password', 'client_credentials', 'refresh_token', etc.
|
|
191
192
|
- clientId: [required] string containing the client ID configured in Keycloak. Required for all grant types.
|
|
192
193
|
- tokenLifeSpan: [required] Numeric Lifetime of an access token expressed in seconds. It indicates how often the access token should be renewed. If set incorrectly and the Keycloak token expires before the renewal interval defined by this parameter, errors and exceptions may occur
|
|
@@ -412,7 +413,7 @@ It’s useful for incremental updates or merging configuration pieces.
|
|
|
412
413
|
**` -- @parameters -- `**
|
|
413
414
|
- configuration: is a JSON object that accepts filter parameters
|
|
414
415
|
- realm:[required] The name of the realm where the data should be imported.
|
|
415
|
-
-
|
|
416
|
+
- rep:[required] A JSON object representing part of the realm configuration to be imported(can include users, roles, groups, clients, etc.).
|
|
416
417
|
- ifResourceExists:[required] Defines the behavior when an imported resource already exists in the target realm.
|
|
417
418
|
Options are:
|
|
418
419
|
- 'FAIL' – the operation fails if a resource already exists.
|
|
@@ -1950,7 +1951,10 @@ Creates a new client with the provided configuration
|
|
|
1950
1951
|
```js
|
|
1951
1952
|
const KeycloakManager = require('keycloak-api-manager');
|
|
1952
1953
|
// create a client called my-client
|
|
1953
|
-
const client= await KeycloakManager.clients.create({
|
|
1954
|
+
const client= await KeycloakManager.clients.create({
|
|
1955
|
+
name: "my-client",
|
|
1956
|
+
clientId:"client-id"
|
|
1957
|
+
});
|
|
1954
1958
|
console.log("New Client Created:", client);
|
|
1955
1959
|
```
|
|
1956
1960
|
|
|
@@ -2333,7 +2337,7 @@ Default client scopes are automatically assigned to a client during token reques
|
|
|
2333
2337
|
|
|
2334
2338
|
**` -- @parameters -- `**
|
|
2335
2339
|
- filter: JSON structure that defines the filter parameters:
|
|
2336
|
-
- id: [required] The
|
|
2340
|
+
- id: [required] The internal ID of the client whose default client scopes you want to list.
|
|
2337
2341
|
|
|
2338
2342
|
```js
|
|
2339
2343
|
const KeycloakManager = require('keycloak-api-manager');
|
|
@@ -2353,7 +2357,7 @@ Optional scopes are those that a client can request explicitly but are not autom
|
|
|
2353
2357
|
|
|
2354
2358
|
**` -- @parameters -- `**
|
|
2355
2359
|
- filter: JSON structure that defines the filter parameters:
|
|
2356
|
-
- id: [required] The
|
|
2360
|
+
- id: [required] The internal ID of the client whose optional client scopes you want to list.
|
|
2357
2361
|
|
|
2358
2362
|
```js
|
|
2359
2363
|
const KeycloakManager = require('keycloak-api-manager');
|
|
@@ -4038,7 +4042,7 @@ Client scopes are reusable sets of protocol mappers and role scope mappings whic
|
|
|
4038
4042
|
can be assigned to clients to define what information about the user is included in tokens and what roles are available.
|
|
4039
4043
|
|
|
4040
4044
|
#### `entity clientScopes functions`
|
|
4041
|
-
##### `function create(
|
|
4045
|
+
##### `function create(scopeRepresentation)`
|
|
4042
4046
|
method is used to create a new client scope in a Keycloak realm.
|
|
4043
4047
|
A client scope defines a set of protocol mappers and roles that can be applied to clients,
|
|
4044
4048
|
such as during login or token generation.
|
|
@@ -4053,7 +4057,7 @@ const KeycloakManager = require('keycloak-api-manager');
|
|
|
4053
4057
|
```
|
|
4054
4058
|
|
|
4055
4059
|
|
|
4056
|
-
##### `function update(filter,
|
|
4060
|
+
##### `function update(filter,scopeRepresentation)`
|
|
4057
4061
|
The method updates the configuration of an existing client scope in a realm.
|
|
4058
4062
|
You can modify properties such as the scope’s name, description, attributes, or protocol mappers.
|
|
4059
4063
|
|
|
@@ -4061,7 +4065,7 @@ You can modify properties such as the scope’s name, description, attributes, o
|
|
|
4061
4065
|
- filter: parameter provided as a JSON object that accepts the following filter:
|
|
4062
4066
|
- id: [required] The unique ID of the client scope to update.
|
|
4063
4067
|
- realm: [optional] The realm where the client scope exists.
|
|
4064
|
-
-
|
|
4068
|
+
- scopeRepresentation: The updated client scope object. for example:
|
|
4065
4069
|
- name: [optional] The name of the scope
|
|
4066
4070
|
- description: [optional] The scope description
|
|
4067
4071
|
- other scope fields....
|
|
@@ -4890,14 +4894,14 @@ These are providers like Google, Facebook, GitHub, SAML, OIDC, etc.
|
|
|
4890
4894
|
|
|
4891
4895
|
#### `entity identityProviders functions`
|
|
4892
4896
|
|
|
4893
|
-
##### `function identityProviders.create(
|
|
4897
|
+
##### `function identityProviders.create(identityProvidersRepresentation)`
|
|
4894
4898
|
The method is used to create a new Identity Provider (IdP) in a Keycloak realm.
|
|
4895
4899
|
An IdP allows users to authenticate via external providers such as Google, Facebook, GitHub,
|
|
4896
4900
|
or another SAML/OIDC provider.
|
|
4897
4901
|
This method requires specifying an alias, the provider type, and configuration settings such as client ID, client secret, and any other provider-specific options.
|
|
4898
4902
|
|
|
4899
4903
|
**` -- @parameters -- `**
|
|
4900
|
-
-
|
|
4904
|
+
- identityProvidersRepresentation: parameter provided as a JSON object containing the configuration of the Identity Provider
|
|
4901
4905
|
- alias: [required] Unique name for the IdP within the realm.
|
|
4902
4906
|
- providerId: [required] Type of provider (google, facebook, oidc, saml, etc.).
|
|
4903
4907
|
- enabled: [optional] Whether the IdP is enabled. Default is true.
|
|
@@ -5280,7 +5284,7 @@ Groups are collections of users and can have roles and attributes assigned to th
|
|
|
5280
5284
|
Groups help organize users and assign permissions in a scalable way
|
|
5281
5285
|
|
|
5282
5286
|
#### `entity groups functions`
|
|
5283
|
-
##### `function create(
|
|
5287
|
+
##### `function create(groupRepresentation)`
|
|
5284
5288
|
Create a new group in the current realme
|
|
5285
5289
|
|
|
5286
5290
|
**` -- @parameters -- `**
|
|
@@ -5732,7 +5736,7 @@ Get a role by its Id
|
|
|
5732
5736
|
|
|
5733
5737
|
**` -- @parameters -- `**
|
|
5734
5738
|
- filters: parameter provided as a JSON object that accepts the following parameters:
|
|
5735
|
-
-
|
|
5739
|
+
- id (string, required) — The id of the role to retrieve.
|
|
5736
5740
|
- realm (string, optional if set globally) — The realm where the role is defined.
|
|
5737
5741
|
```js
|
|
5738
5742
|
const KeycloakManager = require('keycloak-api-manager');
|
|
@@ -5759,7 +5763,7 @@ Update a role by its Id
|
|
|
5759
5763
|
|
|
5760
5764
|
**` -- @parameters -- `**
|
|
5761
5765
|
- filters: parameter provided as a JSON object that accepts the following parameters:
|
|
5762
|
-
-
|
|
5766
|
+
- id (string, required) — The id of the role to retrieve.
|
|
5763
5767
|
- realm (string, optional if set globally) — The realm where the role is defined.
|
|
5764
5768
|
- role_dictionary: A JSON object representing a role dictionary as defined in Keycloak
|
|
5765
5769
|
```js
|
|
@@ -6289,7 +6293,7 @@ This allows you to modify settings such as OTP policies, password requirements,
|
|
|
6289
6293
|
**` -- @parameters -- `**
|
|
6290
6294
|
- filter: parameter provided as a JSON object that accepts the following filter:
|
|
6291
6295
|
- alias: [required] The alias (providerId) of the required action to update.
|
|
6292
|
-
-
|
|
6296
|
+
- actionConfigRepresentation: The configuration object to update.
|
|
6293
6297
|
|
|
6294
6298
|
|
|
6295
6299
|
```js
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
version: '3.8'
|
|
2
|
+
|
|
3
|
+
services:
|
|
4
|
+
keycloak:
|
|
5
|
+
image: keycloak/keycloak:latest
|
|
6
|
+
container_name: keycloak-test
|
|
7
|
+
ports:
|
|
8
|
+
- "8080:8080"
|
|
9
|
+
environment:
|
|
10
|
+
KEYCLOAK_ADMIN: admin
|
|
11
|
+
KEYCLOAK_ADMIN_PASSWORD: admin
|
|
12
|
+
KC_DB: dev-mem
|
|
13
|
+
KC_METRICS_ENABLED: 'false'
|
|
14
|
+
KC_HEALTH_ENABLED: 'true'
|
|
15
|
+
command:
|
|
16
|
+
- start-dev
|
|
17
|
+
healthcheck:
|
|
18
|
+
test: ["CMD", "curl", "-f", "http://localhost:8080/health/ready"]
|
|
19
|
+
interval: 5s
|
|
20
|
+
timeout: 5s
|
|
21
|
+
retries: 12
|
|
22
|
+
networks:
|
|
23
|
+
- keycloak-network
|
|
24
|
+
|
|
25
|
+
networks:
|
|
26
|
+
keycloak-network:
|
|
27
|
+
driver: bridge
|
package/index.mjs
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ESM wrapper for keycloak-api-manager
|
|
3
|
+
* This file provides ES Module support while the core is still CommonJS
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { createRequire } from 'module';
|
|
7
|
+
import { fileURLToPath } from 'url';
|
|
8
|
+
import path from 'path';
|
|
9
|
+
|
|
10
|
+
const require = createRequire(import.meta.url);
|
|
11
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
12
|
+
const __dirname = path.dirname(__filename);
|
|
13
|
+
|
|
14
|
+
const keycloakApiManager = require('./index.js');
|
|
15
|
+
|
|
16
|
+
export const configure = keycloakApiManager.configure;
|
|
17
|
+
export const setConfig = keycloakApiManager.setConfig;
|
|
18
|
+
export const getToken = keycloakApiManager.getToken;
|
|
19
|
+
export const auth = keycloakApiManager.auth;
|
|
20
|
+
|
|
21
|
+
export default keycloakApiManager;
|
package/package.json
CHANGED
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "keycloak-api-manager",
|
|
3
|
-
"version": "3.2.
|
|
3
|
+
"version": "3.2.1",
|
|
4
4
|
"description": "Keycloak-api-manager is a lightweight Node.js wrapper for the Keycloak Admin REST API. It provides an easy-to-use functional methods and functions to manage realms, users, roles, clients, groups, and permissions directly from your application code — just like you would from the Keycloak admin console.",
|
|
5
5
|
"main": "index.js",
|
|
6
|
+
"exports": {
|
|
7
|
+
".": {
|
|
8
|
+
"import": "./index.mjs",
|
|
9
|
+
"require": "./index.js"
|
|
10
|
+
}
|
|
11
|
+
},
|
|
6
12
|
"scripts": {
|
|
7
|
-
"test": "mocha"
|
|
13
|
+
"test": "mocha",
|
|
14
|
+
"test:watch": "mocha --watch --watch-extensions js"
|
|
8
15
|
},
|
|
9
16
|
"dependencies": {
|
|
10
17
|
"@keycloak/keycloak-admin-client": "^26.3.2",
|
|
@@ -23,6 +30,11 @@
|
|
|
23
30
|
"serve-favicon": "^2.5.0",
|
|
24
31
|
"underscore": "^1.13.7"
|
|
25
32
|
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"chai": "^4.3.10",
|
|
35
|
+
"mocha": "^10.2.0",
|
|
36
|
+
"dockerode": "^4.0.2"
|
|
37
|
+
},
|
|
26
38
|
"keywords": [
|
|
27
39
|
"keycloak",
|
|
28
40
|
"user",
|
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
const { expect } = require('chai');
|
|
2
|
+
const { getAdminClient } = require('./config');
|
|
3
|
+
|
|
4
|
+
describe('Authentication Management Handler', function () {
|
|
5
|
+
this.timeout(20000);
|
|
6
|
+
let client;
|
|
7
|
+
let testFlowId;
|
|
8
|
+
let testFlowAlias;
|
|
9
|
+
let testExecutionId;
|
|
10
|
+
let testRequiredActionAlias;
|
|
11
|
+
|
|
12
|
+
before(function () {
|
|
13
|
+
client = getAdminClient();
|
|
14
|
+
testFlowAlias = `test-flow-${Date.now()}`;
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
// ==================== AUTHENTICATION FLOWS ====================
|
|
18
|
+
describe('Authentication Flows', function () {
|
|
19
|
+
describe('getFlows', function () {
|
|
20
|
+
it('should list all authentication flows', async function () {
|
|
21
|
+
const flows = await client.authenticationManagement.getFlows({
|
|
22
|
+
realm: 'test-realm',
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
expect(flows).to.be.an('array');
|
|
26
|
+
expect(flows.length).to.be.greaterThan(0);
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
describe('createFlow', function () {
|
|
31
|
+
it('should create an authentication flow', async function () {
|
|
32
|
+
const flowRep = {
|
|
33
|
+
alias: testFlowAlias,
|
|
34
|
+
description: 'Test Flow Description',
|
|
35
|
+
flowType: 'basic-flow',
|
|
36
|
+
builtIn: false,
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
const result = await client.authenticationManagement.createFlow(
|
|
40
|
+
{ realm: 'test-realm' },
|
|
41
|
+
flowRep
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
expect(result).to.have.property('id');
|
|
45
|
+
testFlowId = result.id;
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
describe('getFlow', function () {
|
|
50
|
+
it('should retrieve a specific flow', async function () {
|
|
51
|
+
if (testFlowId) {
|
|
52
|
+
const flow = await client.authenticationManagement.getFlow({
|
|
53
|
+
realm: 'test-realm',
|
|
54
|
+
id: testFlowId,
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
expect(flow).to.exist;
|
|
58
|
+
expect(flow.id).to.equal(testFlowId);
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
describe('updateFlow', function () {
|
|
64
|
+
it('should update flow configuration', async function () {
|
|
65
|
+
if (testFlowId) {
|
|
66
|
+
const updateRep = {
|
|
67
|
+
description: 'Updated Description',
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
await client.authenticationManagement.updateFlow(
|
|
71
|
+
{ realm: 'test-realm', id: testFlowId },
|
|
72
|
+
updateRep
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
const updated = await client.authenticationManagement.getFlow({
|
|
76
|
+
realm: 'test-realm',
|
|
77
|
+
id: testFlowId,
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
expect(updated.description).to.equal('Updated Description');
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
describe('copyFlow', function () {
|
|
86
|
+
it('should copy an authentication flow', async function () {
|
|
87
|
+
if (testFlowId) {
|
|
88
|
+
try {
|
|
89
|
+
const flowCopy = await client.authenticationManagement.copyFlow(
|
|
90
|
+
{ realm: 'test-realm', id: testFlowId },
|
|
91
|
+
{ newName: `copied-${testFlowAlias}` }
|
|
92
|
+
);
|
|
93
|
+
|
|
94
|
+
expect(flowCopy).to.exist;
|
|
95
|
+
} catch (err) {
|
|
96
|
+
// Copy might not be supported in all versions
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
// ==================== FLOW EXECUTIONS ====================
|
|
104
|
+
describe('Flow Executions', function () {
|
|
105
|
+
describe('getExecutions', function () {
|
|
106
|
+
it('should retrieve flow executions', async function () {
|
|
107
|
+
if (testFlowId) {
|
|
108
|
+
const executions = await client.authenticationManagement.getExecutions({
|
|
109
|
+
realm: 'test-realm',
|
|
110
|
+
flowAlias: testFlowAlias,
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
expect(executions).to.be.an('array');
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
describe('addExecutionToFlow', function () {
|
|
119
|
+
it('should add an execution to a flow', async function () {
|
|
120
|
+
if (testFlowId) {
|
|
121
|
+
try {
|
|
122
|
+
const execution = await client.authenticationManagement.addExecutionToFlow(
|
|
123
|
+
{ realm: 'test-realm', flowAlias: testFlowAlias },
|
|
124
|
+
{ provider: 'auth-cookie' }
|
|
125
|
+
);
|
|
126
|
+
|
|
127
|
+
expect(execution).to.exist;
|
|
128
|
+
testExecutionId = execution.id;
|
|
129
|
+
} catch (err) {
|
|
130
|
+
// Execution might not be allowed
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
describe('updateExecution', function () {
|
|
137
|
+
it('should update an execution', async function () {
|
|
138
|
+
if (testExecutionId && testFlowAlias) {
|
|
139
|
+
try {
|
|
140
|
+
const updateRep = {
|
|
141
|
+
requirement: 'CONDITIONAL',
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
await client.authenticationManagement.updateExecution(
|
|
145
|
+
{ realm: 'test-realm', flowAlias: testFlowAlias },
|
|
146
|
+
updateRep
|
|
147
|
+
);
|
|
148
|
+
|
|
149
|
+
// Verify no error thrown
|
|
150
|
+
} catch (err) {
|
|
151
|
+
// Update might fail for some providers
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
describe('raisePriorityExecution', function () {
|
|
158
|
+
it('should raise execution priority', async function () {
|
|
159
|
+
if (testExecutionId && testFlowAlias) {
|
|
160
|
+
try {
|
|
161
|
+
await client.authenticationManagement.raisePriorityExecution({
|
|
162
|
+
realm: 'test-realm',
|
|
163
|
+
flowAlias: testFlowAlias,
|
|
164
|
+
executionId: testExecutionId,
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
// Verify no error thrown
|
|
168
|
+
} catch (err) {
|
|
169
|
+
// Priority adjust might not be supported
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
describe('lowerPriorityExecution', function () {
|
|
176
|
+
it('should lower execution priority', async function () {
|
|
177
|
+
if (testExecutionId && testFlowAlias) {
|
|
178
|
+
try {
|
|
179
|
+
await client.authenticationManagement.lowerPriorityExecution({
|
|
180
|
+
realm: 'test-realm',
|
|
181
|
+
flowAlias: testFlowAlias,
|
|
182
|
+
executionId: testExecutionId,
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
// Verify no error thrown
|
|
186
|
+
} catch (err) {
|
|
187
|
+
// Priority adjust might not be supported
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
});
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
// ==================== REQUIRED ACTIONS ====================
|
|
195
|
+
describe('Required Actions', function () {
|
|
196
|
+
describe('getRequiredActions', function () {
|
|
197
|
+
it('should list all required actions', async function () {
|
|
198
|
+
const actions = await client.authenticationManagement.getRequiredActions();
|
|
199
|
+
|
|
200
|
+
expect(actions).to.be.an('array');
|
|
201
|
+
expect(actions.length).to.be.greaterThan(0);
|
|
202
|
+
});
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
describe('getUnregisteredRequiredActions', function () {
|
|
206
|
+
it('should list unregistered required actions', async function () {
|
|
207
|
+
const unregistered = await client.authenticationManagement.getUnregisteredRequiredActions();
|
|
208
|
+
|
|
209
|
+
expect(unregistered).to.be.an('array');
|
|
210
|
+
});
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
describe('getRequiredActionForAlias', function () {
|
|
214
|
+
it('should retrieve a required action by alias', async function () {
|
|
215
|
+
const actions = await client.authenticationManagement.getRequiredActions();
|
|
216
|
+
if (actions.length > 0) {
|
|
217
|
+
const action = await client.authenticationManagement.getRequiredActionForAlias({
|
|
218
|
+
alias: actions[0].alias,
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
expect(action).to.exist;
|
|
222
|
+
testRequiredActionAlias = action.alias;
|
|
223
|
+
}
|
|
224
|
+
});
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
describe('updateRequiredAction', function () {
|
|
228
|
+
it('should update a required action', async function () {
|
|
229
|
+
if (testRequiredActionAlias) {
|
|
230
|
+
try {
|
|
231
|
+
const updateRep = {
|
|
232
|
+
enabled: true,
|
|
233
|
+
};
|
|
234
|
+
|
|
235
|
+
await client.authenticationManagement.updateRequiredAction(
|
|
236
|
+
{ alias: testRequiredActionAlias },
|
|
237
|
+
updateRep
|
|
238
|
+
);
|
|
239
|
+
|
|
240
|
+
// Verify no error thrown
|
|
241
|
+
} catch (err) {
|
|
242
|
+
// Update might not be allowed
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
});
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
describe('raiseRequiredActionPriority', function () {
|
|
249
|
+
it('should raise required action priority', async function () {
|
|
250
|
+
if (testRequiredActionAlias) {
|
|
251
|
+
try {
|
|
252
|
+
await client.authenticationManagement.raiseRequiredActionPriority({
|
|
253
|
+
alias: testRequiredActionAlias,
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
// Verify no error thrown
|
|
257
|
+
} catch (err) {
|
|
258
|
+
// Priority adjust might not be supported
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
});
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
describe('lowerRequiredActionPriority', function () {
|
|
265
|
+
it('should lower required action priority', async function () {
|
|
266
|
+
if (testRequiredActionAlias) {
|
|
267
|
+
try {
|
|
268
|
+
await client.authenticationManagement.lowerRequiredActionPriority({
|
|
269
|
+
alias: testRequiredActionAlias,
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
// Verify no error thrown
|
|
273
|
+
} catch (err) {
|
|
274
|
+
// Priority adjust might not be supported
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
});
|
|
278
|
+
});
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
// ==================== PROVIDER INFORMATION ====================
|
|
282
|
+
describe('Authenticator Providers', function () {
|
|
283
|
+
describe('getAuthenticatorProviders', function () {
|
|
284
|
+
it('should retrieve authenticator providers', async function () {
|
|
285
|
+
const providers = await client.authenticationManagement.getAuthenticatorProviders();
|
|
286
|
+
|
|
287
|
+
expect(providers).to.be.an('array');
|
|
288
|
+
});
|
|
289
|
+
});
|
|
290
|
+
|
|
291
|
+
describe('getClientAuthenticatorProviders', function () {
|
|
292
|
+
it('should retrieve client authenticator providers', async function () {
|
|
293
|
+
const providers = await client.authenticationManagement.getClientAuthenticatorProviders();
|
|
294
|
+
|
|
295
|
+
expect(providers).to.be.an('array');
|
|
296
|
+
});
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
describe('getFormProviders', function () {
|
|
300
|
+
it('should retrieve form providers', async function () {
|
|
301
|
+
const providers = await client.authenticationManagement.getFormProviders();
|
|
302
|
+
|
|
303
|
+
expect(providers).to.be.an('array');
|
|
304
|
+
});
|
|
305
|
+
});
|
|
306
|
+
|
|
307
|
+
describe('getFormActionProviders', function () {
|
|
308
|
+
it('should retrieve form action providers', async function () {
|
|
309
|
+
const providers = await client.authenticationManagement.getFormActionProviders();
|
|
310
|
+
|
|
311
|
+
expect(providers).to.be.an('array');
|
|
312
|
+
});
|
|
313
|
+
});
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
// ==================== CLEANUP ====================
|
|
317
|
+
after(async function () {
|
|
318
|
+
try {
|
|
319
|
+
if (testFlowId) {
|
|
320
|
+
await client.authenticationManagement.deleteFlow({
|
|
321
|
+
realm: 'test-realm',
|
|
322
|
+
id: testFlowId,
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
} catch (err) {
|
|
326
|
+
console.error('Cleanup error:', err.message);
|
|
327
|
+
}
|
|
328
|
+
});
|
|
329
|
+
});
|