keycloak-api-manager 4.0.0 → 5.0.0

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.
Files changed (48) hide show
  1. package/Handlers/attackDetectionHandler.js +64 -0
  2. package/Handlers/clientPoliciesHandler.js +120 -0
  3. package/Handlers/groupsHandler.js +32 -0
  4. package/Handlers/organizationsHandler.js +243 -0
  5. package/Handlers/serverInfoHandler.js +36 -0
  6. package/Handlers/userProfileHandler.js +121 -0
  7. package/README.md +83 -7157
  8. package/docs/architecture.md +47 -0
  9. package/docs/deployment.md +32 -0
  10. package/docs/keycloak-setup.md +47 -0
  11. package/docs/test-configuration.md +43 -0
  12. package/docs/testing.md +60 -0
  13. package/index.js +156 -240
  14. package/package.json +28 -15
  15. package/test/.mocharc.json +2 -2
  16. package/test/config/secrets.json +12 -0
  17. package/test/docker-keycloak/certs/keycloak.crt +58 -0
  18. package/test/docker-keycloak/certs/keycloak.key +28 -0
  19. package/test/docker-keycloak/docker-compose-https.yml +2 -0
  20. package/test/docker-keycloak/docker-compose.yml +4 -4
  21. package/test/helpers/matrix.js +16 -0
  22. package/test/matrix/auth.json +27 -0
  23. package/test/matrix/clients.json +45 -0
  24. package/test/matrix/realms-components-idp.json +37 -0
  25. package/test/matrix/users-roles-groups.json +26 -0
  26. package/test/package-lock.json +3032 -0
  27. package/test/specs/attackDetection.test.js +102 -0
  28. package/test/specs/clientCredentials.test.js +79 -0
  29. package/test/specs/clientPolicies.test.js +162 -0
  30. package/test/specs/{debugClientLibrary.test.js → diagnostics/debugClientLibrary.test.js} +2 -2
  31. package/test/specs/groupPermissions.test.js +87 -0
  32. package/test/specs/matrix/matrix-auth.test.js +112 -0
  33. package/test/specs/matrix/matrix-clients.test.js +59 -0
  34. package/test/specs/matrix/matrix-realms-components-idp.test.js +111 -0
  35. package/test/specs/matrix/matrix-users-roles-groups.test.js +68 -0
  36. package/test/specs/organizations.test.js +183 -0
  37. package/test/specs/serverInfo.test.js +140 -0
  38. package/test/specs/userProfile.test.js +135 -0
  39. package/test/{enableServerFeatures.js → support/enableServerFeatures.js} +43 -26
  40. package/test/{setup.js → support/setup.js} +3 -3
  41. package/test/support/testConfig.js +69 -0
  42. package/test/testConfig.js +1 -69
  43. package/test-output.log +72 -0
  44. package/test/TESTING.md +0 -327
  45. package/test/config/CONFIGURATION.md +0 -170
  46. package/test/diagnostic-protocol-mappers.js +0 -189
  47. package/test/docker-keycloak/DEPLOYMENT_GUIDE.md +0 -262
  48. package/test/helpers/setup.js +0 -186
package/test/TESTING.md DELETED
@@ -1,327 +0,0 @@
1
- # Keycloak API Manager - Test Suite
2
-
3
- Comprehensive test suite for `keycloak-api-manager` library.
4
-
5
- ## Overview
6
-
7
- This test workspace validates all administrative functions provided by the library against a real Keycloak instance. Tests cover:
8
-
9
- - **Authentication Management** - Required actions, authentication flows, executions
10
- - **Clients** - CRUD operations, roles, secrets, scopes, sessions, authorization services
11
- - **Client Scopes** - Management, protocol mappers, scope mappings
12
- - **Components** - Provider listing, CRUD operations, sub-components
13
- - **Groups** - CRUD, members, role mappings, admin permissions
14
- - **Identity Providers** - Factory listing, CRUD, mappers
15
- - **Realms** - Full lifecycle, configuration, events, keys, localization
16
- - **Roles** - CRUD, composite roles, user assignments
17
- - **Users** - CRUD, credentials, groups, role mappings, sessions, impersonation
18
-
19
- ## Architecture
20
-
21
- ### Shared Test Realm Strategy
22
-
23
- Unlike traditional test approaches where each suite creates/destroys its own realm, this implementation uses a **shared test realm** created once before all tests:
24
-
25
- **Benefits**:
26
- - ⚡ **5-10x faster** - Eliminates repeated realm creation overhead (~2-5s per test)
27
- - 🔄 **Consistent environment** - All tests run against identical infrastructure
28
- - 🛡️ **Idempotent setup** - Running tests multiple times doesn't recreate existing resources
29
- - 🎯 **Isolated resources** - Tests create unique resources (e.g., `user-${timestamp}`) to avoid conflicts
30
-
31
- **Trade-offs**:
32
- - Requires cleanup of test-specific resources (most tests handle this)
33
- - Shared realm means tests can't modify realm-level settings without affecting others
34
-
35
- ### File Structure
36
-
37
- ```
38
- test/
39
- ├── config/ # Configuration files (propertiesmanager)
40
- │ ├── default.json # Base configuration (committed)
41
- │ ├── secrets.json # Passwords (gitignored, required)
42
- │ ├── local.json # Developer overrides (gitignored, optional)
43
- │ ├── local.json.example # Template for local.json
44
- │ └── CONFIGURATION.md # Configuration documentation
45
- ├── specs/ # Test suites
46
- │ ├── authenticationManagement.test.js
47
- │ ├── clients.test.js
48
- │ ├── clientScopes.test.js
49
- │ ├── components.test.js
50
- │ ├── groups.test.js
51
- │ ├── identityProviders.test.js
52
- │ ├── realms.test.js
53
- │ ├── roles.test.js
54
- │ └── users.test.js
55
- ├── .mocharc.json # Mocha configuration
56
- ├── enableServerFeatures.js # Creates shared test infrastructure
57
- ├── package.json # Test dependencies
58
- ├── setup.js # Global Mocha hooks
59
- └── testConfig.js # Configuration loader and exports
60
- ```
61
-
62
- ### Key Components
63
-
64
- #### `testConfig.js`
65
- Centralized configuration module that:
66
- - Sets up propertiesmanager environment
67
- - Loads and merges config files (default → secrets → local)
68
- - Exports standardized constants for tests:
69
- - `KEYCLOAK_CONFIG` - Admin connection settings
70
- - `TEST_REALM` - Shared realm name
71
- - `TEST_CLIENT_*` - Client configuration
72
- - `TEST_USER_*` - User details and credentials
73
- - `TEST_ROLES` - Array of test roles
74
- - `TEST_GROUP_NAME` - Test group name
75
- - `TEST_CLIENT_SCOPE` - Client scope name
76
- - `generateUniqueName()` - Helper for unique resource names
77
-
78
- #### `setup.js`
79
- Global Mocha hooks loaded via `.mocharc.json`:
80
- - Runs `enableServerFeatures()` once in `before()` hook
81
- - Sets 30s timeout for realm creation
82
- - Logs setup progress to console
83
-
84
- #### `enableServerFeatures.js`
85
- Infrastructure setup script that creates (if not exists):
86
- 1. **Test Realm** - Isolated environment for all tests
87
- 2. **Test Client** - Service account client for auth tests
88
- 3. **Test User** - Standard user with credentials
89
- 4. **Test Roles** - Multiple roles for RBAC testing
90
- 5. **Test Group** - Group for membership tests
91
- 6. **Fine-grained Permissions** - Admin permissions (if server supports)
92
- 7. **Client Scope** - For scope mapping tests
93
-
94
- Runs idempotently - safe to execute multiple times.
95
-
96
- #### `.mocharc.json`
97
- Mocha configuration:
98
- ```json
99
- {
100
- "file": ["setup.js"], // Load global hooks before tests
101
- "spec": ["specs/*.test.js"] // Run all test suites
102
- }
103
- ```
104
-
105
- ## Running Tests
106
-
107
- ### Prerequisites
108
-
109
- 1. **Keycloak Instance**: Running and accessible
110
- 2. **Configuration**: Create `test/config/secrets.json` with admin password
111
- 3. **SSH Tunnel** (if remote): Ensure tunnel is active before running tests
112
-
113
- ### Commands
114
-
115
- ```bash
116
- # Install dependencies and run all tests
117
- npm test
118
-
119
- # Or step-by-step:
120
- npm --prefix test install # Install test dependencies
121
- npm --prefix test test # Run all tests
122
-
123
- # Run specific test suite
124
- npm --prefix test test -- --grep "Users Handler"
125
-
126
- # Run specific test
127
- npm --prefix test test -- --grep "should create, find, update, and delete clients"
128
- ```
129
-
130
- ## Diagnostics
131
-
132
- ### Protocol Mapper Diagnostic Script
133
-
134
- The file [test/diagnostic-protocol-mappers.js](test/diagnostic-protocol-mappers.js) is a manual troubleshooting script.
135
- It is not part of the automated Mocha test suite. It is used to validate protocol mapper creation via:
136
-
137
- - Direct Admin REST API calls
138
- - The library client (`keycloak-api-manager`)
139
-
140
- Run it manually when you need to debug protocol mapper behavior:
141
-
142
- ```bash
143
- node test/diagnostic-protocol-mappers.js
144
- ```
145
-
146
- It uses the same `test/config` configuration and the shared test realm.
147
-
148
- ### Expected Output
149
-
150
- ```
151
- propertiesmanager Configuration loaded successfully for environment: test
152
-
153
- === Running global test setup ===
154
-
155
- Configuring Keycloak Admin Client...
156
-
157
- 1. Setting up test realm: keycloak-api-manager-test-realm
158
- ✓ Test realm already exists: keycloak-api-manager-test-realm
159
-
160
- 2. Setting up test client...
161
- ✓ Test client updated: test-client
162
-
163
- [... additional setup output ...]
164
-
165
- ✓ Keycloak server configuration complete!
166
-
167
- === Global setup complete ===
168
-
169
- Users Handler
170
- ✔ should find, findOne, count and update users
171
- ✔ should manage password and credentials
172
- [... more tests ...]
173
-
174
- 59 passing (9s)
175
- 7 pending
176
- ```
177
-
178
- ## Configuration
179
-
180
- Configuration uses [propertiesmanager](https://www.npmjs.com/package/propertiesmanager) for hierarchical config management.
181
-
182
- **Quick Setup**:
183
-
184
- 1. Copy secrets template:
185
- ```bash
186
- cp test/config/local.json.example test/config/secrets.json
187
- ```
188
-
189
- 2. Edit `test/config/secrets.json`:
190
- ```json
191
- {
192
- "test": {
193
- "keycloak": {
194
- "password": "your-admin-password"
195
- },
196
- "realm": {
197
- "user": {
198
- "password": "test-user-password"
199
- }
200
- }
201
- }
202
- }
203
- ```
204
-
205
- 3. (Optional) Override baseUrl in `test/config/local.json`:
206
- ```json
207
- {
208
- "test": {
209
- "keycloak": {
210
- "baseUrl": "http://localhost:8080"
211
- }
212
- }
213
- }
214
- ```
215
-
216
- See [config/CONFIGURATION.md](config/CONFIGURATION.md) for detailed configuration documentation.
217
-
218
- ## Test Writing Guidelines
219
-
220
- ### Use Shared Configuration
221
-
222
- ```javascript
223
- const {
224
- TEST_REALM,
225
- TEST_CLIENT_ID,
226
- TEST_USER_USERNAME,
227
- generateUniqueName
228
- } = require('../testConfig');
229
- ```
230
-
231
- ### Create Unique Resources
232
-
233
- Avoid conflicts by using timestamps or UUIDs:
234
-
235
- ```javascript
236
- const userName = generateUniqueName('test-user');
237
- const roleName = `role-${Date.now()}`;
238
- ```
239
-
240
- ### Respect Shared Realm
241
-
242
- Don't:
243
- - Modify realm-level settings (will affect other tests)
244
- - Delete the shared realm
245
- - Assume exclusive access to shared resources (client, user, roles)
246
-
247
- Do:
248
- - Create test-specific resources with unique names
249
- - Clean up resources created during test (in `after()` hooks)
250
- - Use the shared infrastructure for read operations
251
-
252
- ### Handle Feature Availability
253
-
254
- Some Keycloak features may not be available on all server versions:
255
-
256
- ```javascript
257
- try {
258
- await keycloakManager.users.listConsents({ realm: TEST_REALM, id: userId });
259
- } catch (err) {
260
- if (err.response?.status === 404) {
261
- this.skip(); // Skip test if feature not available
262
- }
263
- throw err;
264
- }
265
- ```
266
-
267
- ## Troubleshooting
268
-
269
- ### Tests hang indefinitely
270
- - Check Keycloak instance is running and accessible
271
- - Verify SSH tunnel is active (if using remote Keycloak)
272
- - Check `baseUrl` in configuration matches your setup
273
-
274
- ### "Configuration loading failed"
275
- - Ensure `test/config/secrets.json` exists
276
- - Verify JSON syntax (no trailing commas)
277
- - Check environment wrapper present: `{ "test": { ... } }`
278
-
279
- ### "Access denied" or 403 errors
280
- - Verify admin credentials in `secrets.json`
281
- - Ensure admin user has realm-management permissions
282
- - Check `realmName` is correct (usually "master" for admin user)
283
-
284
- ### "Realm not found" errors
285
- - Check global setup ran successfully (see console output)
286
- - Verify shared realm created: look for "✓ Test realm created/exists"
287
- - Ensure realm name matches configuration
288
-
289
- ### Slow test execution
290
- - First run is slower (~10-20s) due to realm setup
291
- - Subsequent runs should be faster (~5-10s)
292
- - If still slow, check network latency to Keycloak instance
293
- - Consider using local Keycloak instance instead of remote tunnel
294
-
295
- ### Tests fail inconsistently
296
- - May indicate race conditions or shared resource conflicts
297
- - Ensure test resources use unique names
298
- - Check cleanup logic in `after()` hooks
299
- - Run single test in isolation to verify: `--grep "test name"`
300
-
301
- ## Performance Metrics
302
-
303
- Typical performance on 2020 MacBook Pro with local Keycloak:
304
-
305
- - **Global Setup**: ~10-15 seconds (runs once)
306
- - **Full Suite**: ~9 seconds (59 tests)
307
- - **Individual Test**: ~50-200ms average
308
-
309
- Performance with remote Keycloak over SSH tunnel:
310
- - **Global Setup**: ~15-25 seconds
311
- - **Full Suite**: ~15-30 seconds
312
-
313
- ## Contributing
314
-
315
- When adding new tests:
316
-
317
- 1. Follow existing patterns in `specs/` directory
318
- 2. Import shared config from `testConfig.js`
319
- 3. Use `generateUniqueName()` for test resources
320
- 4. Add cleanup in `after()` hooks
321
- 5. Handle optional features gracefully (use `this.skip()`)
322
- 6. Document any new configuration requirements
323
- 7. Update this README if adding new test categories
324
-
325
- ## License
326
-
327
- Same as parent project.
@@ -1,170 +0,0 @@
1
- # Test Configuration
2
-
3
- This directory contains hierarchical configuration files managed by [propertiesmanager](https://www.npmjs.com/package/propertiesmanager).
4
-
5
- ## Configuration Files
6
-
7
- ### `default.json` (required, committed to git)
8
- Base configuration with non-sensitive defaults. Contains the "test" environment section with:
9
-
10
- - **keycloak**: Admin connection settings (baseUrl, realmName, clientId, username, grantType)
11
- - **realm**: Test realm infrastructure specifications (realm name, client, user, roles, groups, scopes)
12
-
13
- **When to edit**: Update non-sensitive defaults that all developers should use.
14
-
15
- ### `secrets.json` (required, gitignored)
16
- Sensitive credentials overlaid on default.json. Contains passwords and secrets.
17
-
18
- **Structure**:
19
- ```json
20
- {
21
- "test": {
22
- "keycloak": {
23
- "password": "admin"
24
- },
25
- "realm": {
26
- "user": {
27
- "password": "test-password"
28
- }
29
- }
30
- }
31
- }
32
- ```
33
-
34
- **When to create**: Before running tests for the first time. Copy structure above and fill in your Keycloak admin password.
35
-
36
- ### `local.json` (optional, gitignored)
37
- Developer-specific overrides for local environments. Useful for:
38
- - Custom baseUrl (localhost instead of tunnel)
39
- - Different realm names
40
- - Custom ports
41
-
42
- **Example**:
43
- ```json
44
- {
45
- "test": {
46
- "keycloak": {
47
- "baseUrl": "http://localhost:8080"
48
- }
49
- }
50
- }
51
- ```
52
-
53
- **When to create**: Only if you need to override defaults for your local environment.
54
-
55
- ### `local.json.example` (committed to git)
56
- Template showing example local overrides. Copy to `local.json` and customize.
57
-
58
- ## Configuration Loading
59
-
60
- Files are merged in this order:
61
- 1. **default.json** - Base configuration
62
- 2. **secrets.json** - Overlays sensitive credentials
63
- 3. **local.json** - Overlays developer-specific settings (if exists)
64
-
65
- The environment section is determined by `NODE_ENV` (default: "test").
66
-
67
- ## Important Notes
68
-
69
- ### Environment Wrapper Required
70
- All configuration must be wrapped in an environment key:
71
-
72
- ✅ **Correct**:
73
- ```json
74
- {
75
- "test": {
76
- "keycloak": { "baseUrl": "..." }
77
- }
78
- }
79
- ```
80
-
81
- ❌ **Incorrect**:
82
- ```json
83
- {
84
- "keycloak": { "baseUrl": "..." }
85
- }
86
- ```
87
-
88
- ### Git Ignored Files
89
- These files are excluded from git (see `.gitignore`):
90
- - `secrets.json` - Contains passwords
91
- - `local.json` - Developer-specific customizations
92
-
93
- ### Security
94
- - Never commit `secrets.json` or `local.json`
95
- - Keep passwords out of `default.json`
96
- - Use secure passwords in production-like environments
97
-
98
- ## Configuration Schema
99
-
100
- ### keycloak (admin connection)
101
- ```json
102
- {
103
- "baseUrl": "http://127.0.0.1:9998", // Keycloak server URL
104
- "realmName": "master", // Admin realm (usually "master")
105
- "clientId": "admin-cli", // Admin client ID
106
- "username": "admin", // Admin username
107
- "password": "admin", // Admin password (in secrets.json)
108
- "grantType": "password", // OAuth2 grant type
109
- "tokenLifeSpan": 60 // Token refresh interval (seconds)
110
- }
111
- ```
112
-
113
- ## Diagnostic Script Configuration
114
-
115
- The manual diagnostic script [test/diagnostic-protocol-mappers.js](../diagnostic-protocol-mappers.js)
116
- uses the same `test` configuration (including `baseUrl`, credentials, and realm settings).
117
- It is not part of the automated test suite and must be run manually.
118
-
119
- Run it with:
120
- ```bash
121
- node test/diagnostic-protocol-mappers.js
122
- ```
123
-
124
- Make sure `baseUrl` points to a reachable Keycloak instance and `secrets.json` contains valid credentials.
125
-
126
- ### realm (test infrastructure)
127
- ```json
128
- {
129
- "name": "keycloak-api-manager-test-realm", // Test realm name
130
- "client": {
131
- "clientId": "test-client", // Test client ID
132
- "clientSecret": "test-client-secret" // Test client secret
133
- },
134
- "user": {
135
- "username": "test-user", // Test user username
136
- "password": "test-password", // Test user password (in secrets.json)
137
- "email": "test-user@test.local", // Test user email
138
- "firstName": "Test", // Test user first name
139
- "lastName": "User" // Test user last name
140
- },
141
- "roles": ["test-role-1", "test-role-2", "test-admin-role"], // Roles to create
142
- "group": {
143
- "name": "test-group" // Test group name
144
- },
145
- "clientScope": {
146
- "name": "test-scope" // Test client scope name
147
- }
148
- }
149
- ```
150
-
151
- ## Troubleshooting
152
-
153
- ### "Configuration loading failed"
154
- - Ensure `secrets.json` exists with valid JSON
155
- - Check that environment wrapper "test" is present in all files
156
- - Verify JSON syntax (no trailing commas, proper quotes)
157
-
158
- ### "Access denied" errors during tests
159
- - Check admin username/password in `secrets.json`
160
- - Verify `baseUrl` points to accessible Keycloak instance
161
- - If using SSH tunnel, ensure it's active
162
-
163
- ### "Realm not found" errors
164
- - Ensure global setup ran successfully (check console output)
165
- - Verify realm name matches between config and test expectations
166
- - Check that Keycloak instance is running and accessible
167
-
168
- ## More Information
169
-
170
- See main project [README.md](../../README.md) for overall test architecture and execution instructions.
@@ -1,189 +0,0 @@
1
- const path = require('path');
2
- const http = require('http');
3
- const https = require('https');
4
-
5
- process.env.NODE_ENV = process.env.NODE_ENV || 'test';
6
- process.env.PROPERTIES_PATH = path.join(__dirname, 'config');
7
-
8
- const { conf } = require('propertiesmanager');
9
- const keycloakManager = require('keycloak-api-manager');
10
- const { TEST_REALM } = require('./testConfig');
11
-
12
- function requestAdmin(baseUrl, token, apiPath, method = 'GET', body) {
13
- const url = new URL(apiPath, baseUrl);
14
- const transport = url.protocol === 'https:' ? https : http;
15
- const payload = body ? JSON.stringify(body) : null;
16
-
17
- const options = {
18
- method,
19
- headers: {
20
- Accept: 'application/json',
21
- Authorization: `Bearer ${token}`,
22
- ...(payload ? { 'Content-Type': 'application/json' } : {}),
23
- },
24
- };
25
-
26
- return new Promise((resolve, reject) => {
27
- const req = transport.request(url, options, (res) => {
28
- let data = '';
29
- res.on('data', (chunk) => {
30
- data += chunk;
31
- });
32
- res.on('end', () => {
33
- if (res.statusCode >= 200 && res.statusCode < 300) {
34
- try {
35
- const result = {
36
- data: data ? JSON.parse(data) : null,
37
- statusCode: res.statusCode,
38
- headers: res.headers,
39
- };
40
- resolve(result);
41
- } catch {
42
- resolve({
43
- data: data || null,
44
- statusCode: res.statusCode,
45
- headers: res.headers,
46
- });
47
- }
48
- } else {
49
- const error = new Error(`HTTP ${res.statusCode}: ${data}`);
50
- error.statusCode = res.statusCode;
51
- error.response = data;
52
- reject(error);
53
- }
54
- });
55
- });
56
-
57
- req.on('error', reject);
58
- if (payload) {
59
- req.write(payload);
60
- }
61
- req.end();
62
- });
63
- }
64
-
65
- async function main() {
66
- try {
67
- // Configura keycloak manager
68
- const keycloakConfig = (conf && conf.keycloak) || {};
69
- console.log('keycloakConfig baseUrl:', keycloakConfig.baseUrl);
70
-
71
- if (!keycloakConfig.baseUrl) {
72
- throw new Error('baseUrl not configured in keycloak config');
73
- }
74
-
75
- await keycloakManager.configure(keycloakConfig);
76
-
77
- keycloakManager.setConfig({ realmName: TEST_REALM });
78
- const token = keycloakManager.getToken();
79
- const baseUrl = keycloakConfig.baseUrl.endsWith('/') ? keycloakConfig.baseUrl : `${keycloakConfig.baseUrl}/`;
80
-
81
- console.log('\n=== PROTOCOL MAPPER DIRECT API TEST ===');
82
- console.log('Base URL:', baseUrl);
83
- console.log();
84
-
85
- // 1. Trova il test client
86
- const clients = await keycloakManager.clients.find({ clientId: 'test-client' });
87
- if (!clients || !clients.length) {
88
- console.log('❌ Test client not found');
89
- process.exit(1);
90
- }
91
- const testClient = clients[0];
92
- console.log(`✅ Found test client: ${testClient.clientId} (ID: ${testClient.id})\n`);
93
-
94
- // 2. Prova a creare un protocol mapper con API diretta
95
- const apiPath = `/admin/realms/${TEST_REALM}/clients/${testClient.id}/protocol-mappers/models`;
96
-
97
- const protocolMapper = {
98
- name: `direct-api-test-${Date.now()}`,
99
- protocol: 'openid-connect',
100
- protocolMapper: 'oidc-usermodel-attribute-mapper',
101
- consentRequired: false,
102
- config: {
103
- 'user.attribute': 'email',
104
- 'claim.name': 'email_test',
105
- 'jsonType.label': 'String',
106
- 'id.token.claim': 'true',
107
- 'access.token.claim': 'true',
108
- },
109
- };
110
-
111
- console.log(`📡 Direct API POST: ${apiPath}`);
112
- console.log(`Payload: ${JSON.stringify(protocolMapper, null, 2)}\n`);
113
-
114
- const result = await requestAdmin(
115
- baseUrl,
116
- token.accessToken,
117
- apiPath,
118
- 'POST',
119
- protocolMapper
120
- );
121
-
122
- console.log(`✅ SUCCESS - Status: ${result.statusCode}`);
123
- console.log(`Location: ${result.headers.location || 'N/A'}\n`);
124
-
125
- // 3. Verifica che sia stato creato
126
- const listResult = await requestAdmin(
127
- baseUrl,
128
- token.accessToken,
129
- apiPath,
130
- 'GET'
131
- );
132
-
133
- const createdMapper = listResult.data?.find(m => m.name === protocolMapper.name);
134
- if (createdMapper) {
135
- console.log(`✅ Mapper verified in list:`);
136
- console.log(` ID: ${createdMapper.id}`);
137
- console.log(` Name: ${createdMapper.name}`);
138
- console.log(` Protocol Mapper: ${createdMapper.protocolMapper}\n`);
139
-
140
- // Cleanup
141
- await requestAdmin(
142
- baseUrl,
143
- token.accessToken,
144
- `${apiPath}/${createdMapper.id}`,
145
- 'DELETE'
146
- );
147
- console.log('🧹 Cleanup: Mapper deleted\n');
148
- }
149
-
150
- // 4. Prova con il client manager della libreria
151
- console.log('=== TESTING THROUGH KEYCLOAK MANAGER ===\n');
152
-
153
- try {
154
- await keycloakManager.clients.addProtocolMapper(
155
- { id: testClient.id },
156
- {
157
- name: `library-test-${Date.now()}`,
158
- protocol: 'openid-connect',
159
- protocolMapper: 'oidc-usermodel-attribute-mapper',
160
- consentRequired: false,
161
- config: {
162
- 'user.attribute': 'username',
163
- 'claim.name': 'user_name',
164
- 'jsonType.label': 'String',
165
- 'id.token.claim': 'true',
166
- 'access.token.claim': 'true',
167
- },
168
- }
169
- );
170
- console.log('✅ SUCCESS through keycloak-api-manager');
171
- } catch (err) {
172
- console.log('❌ FAILED through keycloak-api-manager');
173
- console.log(`Error: ${err.message}\n`);
174
- }
175
-
176
- console.log('\n=== SUMMARY ===');
177
- console.log('Direct API: ✅ Works');
178
- console.log('Library: Check output above');
179
-
180
- } catch (err) {
181
- console.error('❌ ERROR:', err.message);
182
- if (err.response) {
183
- console.error('Response:', err.response);
184
- }
185
- process.exit(1);
186
- }
187
- }
188
-
189
- main();