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.
@@ -0,0 +1,256 @@
1
+ const { expect } = require('chai');
2
+ const { getAdminClient } = require('./config');
3
+
4
+ describe('Client Scopes Handler', function () {
5
+ this.timeout(15000);
6
+ let client;
7
+ let testScopeId;
8
+ let testScopeName;
9
+
10
+ before(function () {
11
+ client = getAdminClient();
12
+ testScopeName = `test-scope-${Date.now()}`;
13
+ });
14
+
15
+ // ==================== CLIENT SCOPE CRUD ====================
16
+ describe('CRUD Operations', function () {
17
+ describe('create', function () {
18
+ it('should create a client scope with valid representation', async function () {
19
+ const scopeRep = {
20
+ name: testScopeName,
21
+ displayName: 'Test Scope Display',
22
+ protocol: 'openid-connect',
23
+ description: 'Test scope for integration',
24
+ };
25
+
26
+ const result = await client.clientScopes.create(
27
+ { realm: 'test-realm' },
28
+ scopeRep
29
+ );
30
+
31
+ expect(result).to.have.property('id');
32
+ testScopeId = result.id;
33
+ });
34
+ });
35
+
36
+ describe('find', function () {
37
+ it('should list all client scopes', async function () {
38
+ const scopes = await client.clientScopes.find({ realm: 'test-realm' });
39
+
40
+ expect(scopes).to.be.an('array');
41
+ expect(scopes.length).to.be.greaterThan(0);
42
+ expect(scopes.some((s) => s.name === testScopeName)).to.be.true;
43
+ });
44
+ });
45
+
46
+ describe('findOne', function () {
47
+ it('should find a specific scope by id', async function () {
48
+ const scope = await client.clientScopes.findOne({
49
+ realm: 'test-realm',
50
+ id: testScopeId,
51
+ });
52
+
53
+ expect(scope).to.exist;
54
+ expect(scope.name).to.equal(testScopeName);
55
+ });
56
+ });
57
+
58
+ describe('findOneByName', function () {
59
+ it('should find a specific scope by name', async function () {
60
+ const scope = await client.clientScopes.findOneByName({
61
+ realm: 'test-realm',
62
+ name: testScopeName,
63
+ });
64
+
65
+ expect(scope).to.exist;
66
+ expect(scope.name).to.equal(testScopeName);
67
+ });
68
+ });
69
+
70
+ describe('update', function () {
71
+ it('should update scope attributes', async function () {
72
+ const updateRep = {
73
+ displayName: 'Updated Scope Display',
74
+ description: 'Updated description',
75
+ };
76
+
77
+ await client.clientScopes.update(
78
+ { realm: 'test-realm', id: testScopeId },
79
+ updateRep
80
+ );
81
+
82
+ const updated = await client.clientScopes.findOne({
83
+ realm: 'test-realm',
84
+ id: testScopeId,
85
+ });
86
+
87
+ expect(updated.displayName).to.equal('Updated Scope Display');
88
+ });
89
+ });
90
+
91
+ describe('delByName', function () {
92
+ it('should delete scope by name', async function () {
93
+ // Create temp scope for deletion test
94
+ const tempScope = await client.clientScopes.create(
95
+ { realm: 'test-realm' },
96
+ { name: `temp-scope-${Date.now()}` }
97
+ );
98
+
99
+ await client.clientScopes.delByName({
100
+ realm: 'test-realm',
101
+ name: tempScope.name,
102
+ });
103
+
104
+ // Verify deleted
105
+ });
106
+ });
107
+ });
108
+
109
+ // ==================== DEFAULT CLIENT SCOPES ====================
110
+ describe('Default Client Scopes', function () {
111
+ describe('listDefaultClientScopes', function () {
112
+ it('should list default client scopes', async function () {
113
+ const scopes = await client.clientScopes.listDefaultClientScopes({
114
+ realm: 'test-realm',
115
+ });
116
+
117
+ expect(scopes).to.be.an('array');
118
+ });
119
+ });
120
+
121
+ describe('addDefaultClientScope', function () {
122
+ it('should add a client scope to defaults', async function () {
123
+ await client.clientScopes.addDefaultClientScope({
124
+ realm: 'test-realm',
125
+ id: testScopeId,
126
+ });
127
+
128
+ const defaults = await client.clientScopes.listDefaultClientScopes({
129
+ realm: 'test-realm',
130
+ });
131
+
132
+ expect(defaults.some((s) => s.id === testScopeId)).to.be.true;
133
+ });
134
+ });
135
+
136
+ describe('delDefaultClientScope', function () {
137
+ it('should remove client scope from defaults', async function () {
138
+ await client.clientScopes.delDefaultClientScope({
139
+ realm: 'test-realm',
140
+ id: testScopeId,
141
+ });
142
+
143
+ const defaults = await client.clientScopes.listDefaultClientScopes({
144
+ realm: 'test-realm',
145
+ });
146
+
147
+ expect(defaults.some((s) => s.id === testScopeId)).to.be.false;
148
+ });
149
+ });
150
+ });
151
+
152
+ // ==================== DEFAULT OPTIONAL CLIENT SCOPES ====================
153
+ describe('Default Optional Client Scopes', function () {
154
+ describe('listDefaultOptionalClientScopes', function () {
155
+ it('should list default optional client scopes', async function () {
156
+ const scopes = await client.clientScopes.listDefaultOptionalClientScopes({
157
+ realm: 'test-realm',
158
+ });
159
+
160
+ expect(scopes).to.be.an('array');
161
+ });
162
+ });
163
+
164
+ describe('addDefaultOptionalClientScope', function () {
165
+ it('should add scope to default optional', async function () {
166
+ await client.clientScopes.addDefaultOptionalClientScope({
167
+ realm: 'test-realm',
168
+ id: testScopeId,
169
+ });
170
+
171
+ const optionals = await client.clientScopes.listDefaultOptionalClientScopes({
172
+ realm: 'test-realm',
173
+ });
174
+
175
+ expect(optionals.some((s) => s.id === testScopeId)).to.be.true;
176
+ });
177
+ });
178
+
179
+ describe('delDefaultOptionalClientScope', function () {
180
+ it('should remove scope from default optional', async function () {
181
+ await client.clientScopes.delDefaultOptionalClientScope({
182
+ realm: 'test-realm',
183
+ id: testScopeId,
184
+ });
185
+
186
+ const optionals = await client.clientScopes.listDefaultOptionalClientScopes({
187
+ realm: 'test-realm',
188
+ });
189
+
190
+ expect(optionals.some((s) => s.id === testScopeId)).to.be.false;
191
+ });
192
+ });
193
+ });
194
+
195
+ // ==================== PROTOCOL MAPPERS ====================
196
+ describe('Protocol Mappers', function () {
197
+ describe('listProtocolMappers', function () {
198
+ it('should list protocol mappers for scope', async function () {
199
+ const mappers = await client.clientScopes.listProtocolMappers({
200
+ realm: 'test-realm',
201
+ id: testScopeId,
202
+ });
203
+
204
+ expect(mappers).to.be.an('array');
205
+ });
206
+ });
207
+
208
+ describe('findProtocolMappersByProtocol', function () {
209
+ it('should find protocol mappers by protocol', async function () {
210
+ const mappers = await client.clientScopes.findProtocolMappersByProtocol({
211
+ realm: 'test-realm',
212
+ id: testScopeId,
213
+ protocol: 'openid-connect',
214
+ });
215
+
216
+ expect(mappers).to.be.an('array');
217
+ });
218
+ });
219
+ });
220
+
221
+ // ==================== SCOPE MAPPINGS ====================
222
+ describe('Scope Mappings', function () {
223
+ describe('listScopeMappings', function () {
224
+ it('should list all scope mappings', async function () {
225
+ const mappings = await client.clientScopes.listScopeMappings({
226
+ realm: 'test-realm',
227
+ id: testScopeId,
228
+ });
229
+
230
+ expect(mappings).to.be.an('object');
231
+ });
232
+ });
233
+
234
+ describe('listRealmScopeMappings', function () {
235
+ it('should list realm scope mappings', async function () {
236
+ const mappings = await client.clientScopes.listRealmScopeMappings({
237
+ realm: 'test-realm',
238
+ id: testScopeId,
239
+ });
240
+
241
+ expect(mappings).to.be.an('array');
242
+ });
243
+ });
244
+ });
245
+
246
+ // ==================== CLEANUP ====================
247
+ after(async function () {
248
+ try {
249
+ if (testScopeId) {
250
+ await client.clientScopes.del({ realm: 'test-realm', id: testScopeId });
251
+ }
252
+ } catch (err) {
253
+ console.error('Cleanup error:', err.message);
254
+ }
255
+ });
256
+ });
@@ -0,0 +1,284 @@
1
+ const { expect } = require('chai');
2
+ const { getAdminClient } = require('./config');
3
+
4
+ describe('Clients Handler', function () {
5
+ this.timeout(15000);
6
+ let client;
7
+ let testClientId;
8
+ let testRoleId;
9
+
10
+ before(async function () {
11
+ client = getAdminClient();
12
+
13
+ // Create a test role for client role mappings
14
+ const role = await client.roles.create(
15
+ { realm: 'test-realm' },
16
+ { name: 'clients-test-role' }
17
+ );
18
+ testRoleId = role.id;
19
+ });
20
+
21
+ // ==================== CLIENT CRUD ====================
22
+ describe('CRUD Operations', function () {
23
+ describe('create', function () {
24
+ it('should create a client with valid representation', async function () {
25
+ const clientRep = {
26
+ clientId: `test-client-${Date.now()}`,
27
+ name: 'Integration Test Client',
28
+ enabled: true,
29
+ publicClient: false,
30
+ standardFlowEnabled: true,
31
+ directAccessGrantsEnabled: true,
32
+ };
33
+
34
+ const result = await client.clients.create(
35
+ { realm: 'test-realm' },
36
+ clientRep
37
+ );
38
+
39
+ expect(result).to.have.property('id');
40
+ testClientId = result.id;
41
+ });
42
+
43
+ it('should fail creating duplicate clientId', async function () {
44
+ const clientId = `unique-client-${Date.now()}`;
45
+
46
+ await client.clients.create({ realm: 'test-realm' }, {
47
+ clientId,
48
+ enabled: true,
49
+ });
50
+
51
+ try {
52
+ await client.clients.create({ realm: 'test-realm' }, {
53
+ clientId,
54
+ enabled: true,
55
+ });
56
+ expect.fail('Should have thrown error for duplicate clientId');
57
+ } catch (err) {
58
+ expect(err).to.exist;
59
+ }
60
+ });
61
+ });
62
+
63
+ describe('find', function () {
64
+ it('should list all clients in realm', async function () {
65
+ const clients = await client.clients.find({ realm: 'test-realm' });
66
+
67
+ expect(clients).to.be.an('array');
68
+ expect(clients.length).to.be.greaterThan(0);
69
+ });
70
+
71
+ it('should search clients by clientId', async function () {
72
+ const foundClients = await client.clients.find({
73
+ realm: 'test-realm',
74
+ clientId: `test-client-${Date.now()}`,
75
+ });
76
+
77
+ expect(foundClients).to.be.an('array');
78
+ });
79
+ });
80
+
81
+ describe('findOne', function () {
82
+ it('should find a specific client by id', async function () {
83
+ const foundClient = await client.clients.findOne({
84
+ realm: 'test-realm',
85
+ id: testClientId,
86
+ });
87
+
88
+ expect(foundClient).to.exist;
89
+ expect(foundClient.id).to.equal(testClientId);
90
+ });
91
+ });
92
+
93
+ describe('update', function () {
94
+ it('should update client attributes', async function () {
95
+ const updateRep = {
96
+ name: 'Updated Client Name',
97
+ description: 'Updated description',
98
+ publicClient: true,
99
+ attributes: {
100
+ 'custom-attr': 'value',
101
+ },
102
+ };
103
+
104
+ await client.clients.update(
105
+ { realm: 'test-realm', id: testClientId },
106
+ updateRep
107
+ );
108
+
109
+ const updated = await client.clients.findOne({
110
+ realm: 'test-realm',
111
+ id: testClientId,
112
+ });
113
+
114
+ expect(updated.name).to.equal('Updated Client Name');
115
+ expect(updated.description).to.equal('Updated description');
116
+ });
117
+ });
118
+ });
119
+
120
+ // ==================== CLIENT SECRETS ====================
121
+ describe('Secret Management', function () {
122
+ describe('generateNewClientSecret', function () {
123
+ it('should generate a new client secret', async function () {
124
+ const secret = await client.clients.generateNewClientSecret({
125
+ realm: 'test-realm',
126
+ id: testClientId,
127
+ });
128
+
129
+ expect(secret).to.have.property('value');
130
+ expect(secret.value).to.be.a('string');
131
+ expect(secret.value.length).to.be.greaterThan(0);
132
+ });
133
+ });
134
+
135
+ describe('getClientSecret', function () {
136
+ it('should retrieve the current client secret', async function () {
137
+ const secret = await client.clients.getClientSecret({
138
+ realm: 'test-realm',
139
+ id: testClientId,
140
+ });
141
+
142
+ expect(secret).to.have.property('value');
143
+ expect(secret.value).to.be.a('string');
144
+ });
145
+ });
146
+ });
147
+
148
+ // ==================== CLIENT CREDENTIALS ====================
149
+ describe('Credential Management', function () {
150
+ describe('listClientCredentials', function () {
151
+ it('should list all client credentials', async function () {
152
+ const creds = await client.clients.getCredentials({
153
+ realm: 'test-realm',
154
+ id: testClientId,
155
+ });
156
+
157
+ expect(creds).to.be.an('array');
158
+ });
159
+ });
160
+ });
161
+
162
+ // ==================== CLIENT SESSIONS ====================
163
+ describe('Session Management', function () {
164
+ describe('getUserConsents', function () {
165
+ it('should retrieve user consents for client', async function () {
166
+ // This might be empty but should not error
167
+ try {
168
+ const consents = await client.clients.getUserConsents({
169
+ realm: 'test-realm',
170
+ id: testClientId,
171
+ });
172
+
173
+ expect(consents).to.be.an('array');
174
+ } catch (err) {
175
+ // Some versions might not support this
176
+ }
177
+ });
178
+ });
179
+
180
+ describe('getActiveSessions', function () {
181
+ it('should retrieve active sessions for client', async function () {
182
+ const sessions = await client.clients.getActiveSessions({
183
+ realm: 'test-realm',
184
+ id: testClientId,
185
+ });
186
+
187
+ expect(sessions).to.be.an('array');
188
+ });
189
+ });
190
+
191
+ describe('getOfflineSessions', function () {
192
+ it('should retrieve offline sessions for client', async function () {
193
+ const sessions = await client.clients.getOfflineSessions({
194
+ realm: 'test-realm',
195
+ id: testClientId,
196
+ });
197
+
198
+ expect(sessions).to.be.an('array');
199
+ });
200
+ });
201
+ });
202
+
203
+ // ==================== CLIENT ROLE MAPPINGS ====================
204
+ describe('Role Mappings', function () {
205
+ describe('listServiceAccountRoleMappings', function () {
206
+ it('should list service account role mappings', async function () {
207
+ try {
208
+ const mappings = await client.clients.listServiceAccountRoleMappings({
209
+ realm: 'test-realm',
210
+ id: testClientId,
211
+ });
212
+
213
+ expect(mappings).to.be.an('object');
214
+ } catch (err) {
215
+ // Service account might not be enabled
216
+ }
217
+ });
218
+ });
219
+ });
220
+
221
+ // ==================== PROTOCOL MAPPERS ====================
222
+ describe('Protocol Mappers', function () {
223
+ describe('listProtocolMappers', function () {
224
+ it('should list protocol mappers', async function () {
225
+ const mappers = await client.clients.listProtocolMappers({
226
+ realm: 'test-realm',
227
+ id: testClientId,
228
+ });
229
+
230
+ expect(mappers).to.be.an('array');
231
+ });
232
+ });
233
+
234
+ describe('addProtocolMapper', function () {
235
+ it('should add a protocol mapper', async function () {
236
+ const mapper = {
237
+ name: 'test-mapper',
238
+ protocol: 'openid-connect',
239
+ protocolMapper: 'oidc-usermodel-attribute-mapper',
240
+ config: {
241
+ 'user.attribute': 'email',
242
+ 'claim.name': 'email',
243
+ 'jsonType.label': 'String',
244
+ },
245
+ };
246
+
247
+ const result = await client.clients.addProtocolMapper(
248
+ { realm: 'test-realm', id: testClientId },
249
+ mapper
250
+ );
251
+
252
+ expect(result).to.exist;
253
+ });
254
+ });
255
+ });
256
+
257
+ // ==================== SCOPE MAPPINGS ====================
258
+ describe('Scope Mappings', function () {
259
+ describe('listScopeMappings', function () {
260
+ it('should list all scope mappings', async function () {
261
+ const mappings = await client.clients.listScopeMappings({
262
+ realm: 'test-realm',
263
+ id: testClientId,
264
+ });
265
+
266
+ expect(mappings).to.be.an('object');
267
+ });
268
+ });
269
+ });
270
+
271
+ // ==================== CLEANUP ====================
272
+ after(async function () {
273
+ try {
274
+ if (testClientId) {
275
+ await client.clients.del({ realm: 'test-realm', id: testClientId });
276
+ }
277
+ if (testRoleId) {
278
+ await client.roles.del({ realm: 'test-realm', id: testRoleId });
279
+ }
280
+ } catch (err) {
281
+ console.error('Cleanup error:', err.message);
282
+ }
283
+ });
284
+ });
@@ -0,0 +1,122 @@
1
+ const { expect } = require('chai');
2
+ const { getAdminClient } = require('./config');
3
+
4
+ describe('Components Handler', function () {
5
+ this.timeout(15000);
6
+ let client;
7
+ let testComponentId;
8
+
9
+ before(function () {
10
+ client = getAdminClient();
11
+ });
12
+
13
+ // ==================== COMPONENT CRUD ====================
14
+ describe('CRUD Operations', function () {
15
+ describe('create', function () {
16
+ it('should create a component with valid representation', async function () {
17
+ const componentRep = {
18
+ name: `test-component-${Date.now()}`,
19
+ providerId: 'org.keycloak.storage.UserStorageProvider',
20
+ providerType: 'org.keycloak.storage.UserStorageProvider',
21
+ config: {
22
+ priority: ['0'],
23
+ },
24
+ };
25
+
26
+ const result = await client.components.create(
27
+ { realm: 'test-realm' },
28
+ componentRep
29
+ );
30
+
31
+ expect(result).to.have.property('id');
32
+ testComponentId = result.id;
33
+ });
34
+ });
35
+
36
+ describe('find', function () {
37
+ it('should list all components', async function () {
38
+ const components = await client.components.find({ realm: 'test-realm' });
39
+
40
+ expect(components).to.be.an('array');
41
+ });
42
+
43
+ it('should filter components by type', async function () {
44
+ const components = await client.components.find({
45
+ realm: 'test-realm',
46
+ type: 'org.keycloak.storage.UserStorageProvider',
47
+ });
48
+
49
+ expect(components).to.be.an('array');
50
+ });
51
+
52
+ it('should filter components by provider id', async function () {
53
+ const components = await client.components.find({
54
+ realm: 'test-realm',
55
+ filter: 'org.keycloak.storage.UserStorageProvider',
56
+ });
57
+
58
+ expect(components).to.be.an('array');
59
+ });
60
+ });
61
+
62
+ describe('findOne', function () {
63
+ it('should find a specific component by id', async function () {
64
+ const component = await client.components.findOne({
65
+ realm: 'test-realm',
66
+ id: testComponentId,
67
+ });
68
+
69
+ expect(component).to.exist;
70
+ expect(component.id).to.equal(testComponentId);
71
+ });
72
+ });
73
+
74
+ describe('update', function () {
75
+ it('should update component attributes', async function () {
76
+ const updateRep = {
77
+ name: `updated-component-${Date.now()}`,
78
+ config: {
79
+ priority: ['1'],
80
+ },
81
+ };
82
+
83
+ await client.components.update(
84
+ { realm: 'test-realm', id: testComponentId },
85
+ updateRep
86
+ );
87
+
88
+ const updated = await client.components.findOne({
89
+ realm: 'test-realm',
90
+ id: testComponentId,
91
+ });
92
+
93
+ expect(updated.name).to.include('updated-component');
94
+ });
95
+ });
96
+ });
97
+
98
+ // ==================== SUBCOMPONENTS ====================
99
+ describe('Subcomponents', function () {
100
+ describe('listSubComponents', function () {
101
+ it('should list subcomponents', async function () {
102
+ const subcomponents = await client.components.listSubComponents({
103
+ realm: 'test-realm',
104
+ id: testComponentId,
105
+ });
106
+
107
+ expect(subcomponents).to.be.an('array');
108
+ });
109
+ });
110
+ });
111
+
112
+ // ==================== CLEANUP ====================
113
+ after(async function () {
114
+ try {
115
+ if (testComponentId) {
116
+ await client.components.del({ realm: 'test-realm', id: testComponentId });
117
+ }
118
+ } catch (err) {
119
+ console.error('Cleanup error:', err.message);
120
+ }
121
+ });
122
+ });