@continuoussecuritytooling/keycloak-reporter 1.2.0 → 1.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.
@@ -14,6 +14,9 @@ import tar from 'tar-fs'
14
14
  const DIR_NAME = path.dirname(fileURLToPath(import.meta.url))
15
15
  const SERVER_DIR = path.resolve(DIR_NAME, '../tmp/server')
16
16
  const SCRIPT_EXTENSION = process.platform === 'win32' ? '.bat' : '.sh'
17
+ const KC_BASE = 'http://localhost:8080'
18
+ const ADMIN_USER = 'admin'
19
+ const ADMIN_PASS = 'admin'
17
20
 
18
21
  // TODO: Once support for Node.js 14 has been dropped this can be replaced with an import from 'node:stream/promises'.
19
22
  // More information: https://nodejs.org/api/stream.html#streams-promises-api
@@ -24,16 +27,22 @@ await startServer()
24
27
  async function startServer () {
25
28
  await downloadServer()
26
29
 
30
+ // Wipe data so each start gets a clean realm state (binary is preserved)
31
+ const dataDir = path.join(SERVER_DIR, 'data')
32
+ if (fs.existsSync(dataDir)) {
33
+ fs.rmSync(dataDir, { recursive: true })
34
+ console.info('Cleared server data directory for clean start.')
35
+ }
36
+
27
37
  console.info('Starting server …')
28
38
 
29
- const args = process.argv.slice(2)
30
39
  const child = spawn(
31
40
  path.join(SERVER_DIR, `bin/kc${SCRIPT_EXTENSION}`),
32
- ['start-dev', ...args],
41
+ ['start-dev'],
33
42
  {
34
43
  env: {
35
- KC_BOOTSTRAP_ADMIN_USERNAME: 'master-admin',
36
- KC_BOOTSTRAP_ADMIN_PASSWORD: 'admin',
44
+ KC_BOOTSTRAP_ADMIN_USERNAME: ADMIN_USER,
45
+ KC_BOOTSTRAP_ADMIN_PASSWORD: ADMIN_PASS,
37
46
  ...process.env
38
47
  }
39
48
  }
@@ -41,6 +50,102 @@ async function startServer () {
41
50
 
42
51
  child.stdout.pipe(process.stdout)
43
52
  child.stderr.pipe(process.stderr)
53
+
54
+ await waitForReady()
55
+ await provisionKeycloakReporter()
56
+ }
57
+
58
+ async function waitForReady () {
59
+ const url = `${KC_BASE}/realms/master/.well-known/openid-configuration`
60
+ console.info('Waiting for Keycloak to be ready…')
61
+ for (let i = 0; i < 30; i++) {
62
+ try {
63
+ const res = await fetch(url)
64
+ if (res.ok) {
65
+ console.info('Keycloak is ready.')
66
+ return
67
+ }
68
+ } catch {
69
+ // not ready yet
70
+ }
71
+ await new Promise(r => setTimeout(r, 5000))
72
+ }
73
+ throw new Error('Keycloak failed to start within timeout.')
74
+ }
75
+
76
+ async function provisionKeycloakReporter () {
77
+ const tokenRes = await fetch(
78
+ `${KC_BASE}/realms/master/protocol/openid-connect/token`,
79
+ {
80
+ method: 'POST',
81
+ headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
82
+ body: new URLSearchParams({
83
+ grant_type: 'password',
84
+ client_id: 'admin-cli',
85
+ username: ADMIN_USER,
86
+ password: ADMIN_PASS,
87
+ }),
88
+ }
89
+ )
90
+ const { access_token } = /** @type {{ access_token: string }} */ (await tokenRes.json())
91
+ const headers = {
92
+ 'Content-Type': 'application/json',
93
+ Authorization: `Bearer ${access_token}`,
94
+ }
95
+
96
+ // Create the keycloak-reporter client (409 = already exists, safe to ignore)
97
+ const clientRes = await fetch(`${KC_BASE}/admin/realms/master/clients`, {
98
+ method: 'POST',
99
+ headers,
100
+ body: JSON.stringify({
101
+ clientId: 'keycloak-reporter',
102
+ secret: '3UYhI2hryFwoVtcd7ljlaDuD9HXrGV5r',
103
+ serviceAccountsEnabled: true,
104
+ directAccessGrantsEnabled: true,
105
+ publicClient: false,
106
+ enabled: true,
107
+ fullScopeAllowed: true,
108
+ }),
109
+ })
110
+ if (!clientRes.ok && clientRes.status !== 409) {
111
+ throw new Error(`Failed to create client: ${clientRes.status}`)
112
+ }
113
+
114
+ // Resolve the service account user Keycloak auto-creates
115
+ const saRes = await fetch(
116
+ `${KC_BASE}/admin/realms/master/users?username=service-account-keycloak-reporter`,
117
+ { headers }
118
+ )
119
+ const [serviceAccount] = /** @type {{ id: string }[]} */ (await saRes.json())
120
+
121
+ // Fetch the admin realm role and assign it to the service account
122
+ const roleRes = await fetch(`${KC_BASE}/admin/realms/master/roles/admin`, { headers })
123
+ const adminRole = /** @type {{ id: string, name: string }} */ (await roleRes.json())
124
+
125
+ await fetch(
126
+ `${KC_BASE}/admin/realms/master/users/${serviceAccount.id}/role-mappings/realm`,
127
+ {
128
+ method: 'POST',
129
+ headers,
130
+ body: JSON.stringify([{ id: adminRole.id, name: adminRole.name }]),
131
+ }
132
+ )
133
+
134
+ // Create a test user so e2e user-listing tests have predictable data
135
+ await fetch(`${KC_BASE}/admin/realms/master/users`, {
136
+ method: 'POST',
137
+ headers,
138
+ body: JSON.stringify({
139
+ username: 'kermit',
140
+ firstName: 'Kermit',
141
+ lastName: 'the Frog',
142
+ email: 'kermit@example.com',
143
+ enabled: true,
144
+ credentials: [{ type: 'password', value: 'kermit', temporary: false }],
145
+ }),
146
+ })
147
+
148
+ console.info('keycloak-reporter client provisioned successfully.')
44
149
  }
45
150
 
46
151
  async function downloadServer () {
@@ -55,7 +160,13 @@ async function downloadServer () {
55
160
 
56
161
  const nightlyAsset = await getNightlyAsset()
57
162
  //console.log(nightlyAsset)
163
+ if (!nightlyAsset) {
164
+ throw new Error('Could not find nightly release asset.')
165
+ }
58
166
  const assetStream = await getAssetAsStream(nightlyAsset)
167
+ if (!assetStream) {
168
+ throw new Error('Asset stream is empty.')
169
+ }
59
170
 
60
171
  await extractTarball(assetStream, SERVER_DIR, { strip: 1 })
61
172
  }
@@ -78,6 +189,7 @@ async function getNightlyAsset () {
78
189
  )
79
190
  }
80
191
 
192
+ /** @param {{ browser_download_url: string }} asset */
81
193
  async function getAssetAsStream (asset) {
82
194
  const response = await fetch(asset.browser_download_url)
83
195
 
@@ -85,9 +197,14 @@ async function getAssetAsStream (asset) {
85
197
  throw new Error('Something went wrong requesting the nightly release.')
86
198
  }
87
199
 
88
- return response.body
200
+ return /** @type {import('node:stream').Readable} */ (response.body)
89
201
  }
90
202
 
91
- function extractTarball (stream, path, options) {
92
- return pipelineAsync(stream, gunzip(), tar.extract(path, options))
93
- }
203
+ /**
204
+ * @param {import('node:stream').Readable} stream
205
+ * @param {string} destPath
206
+ * @param {object} options
207
+ */
208
+ function extractTarball (stream, destPath, options) {
209
+ return pipelineAsync(stream, gunzip(), tar.extract(destPath, options))
210
+ }
@@ -45,7 +45,7 @@ jobs:
45
45
  fetch-depth: 0
46
46
 
47
47
  - name: Set up Helm
48
- uses: azure/setup-helm@v4
48
+ uses: azure/setup-helm@v5
49
49
  with:
50
50
  version: v3.11.2
51
51
 
@@ -130,7 +130,7 @@ jobs:
130
130
  run: .bin/wait-for-server.sh
131
131
 
132
132
  - name: Run End2End Tests
133
- uses: nick-fields/retry@v3
133
+ uses: nick-fields/retry@v4
134
134
  with:
135
135
  max_attempts: 3
136
136
  retry_on: error
@@ -20,7 +20,7 @@ jobs:
20
20
  id-token: write
21
21
  steps:
22
22
 
23
- - uses: actions/create-github-app-token@v2
23
+ - uses: actions/create-github-app-token@v3
24
24
  id: app-token
25
25
  with:
26
26
  app-id: ${{ vars.CI_APP_ID }}
@@ -73,7 +73,7 @@ jobs:
73
73
  echo "BUILD_DATE=$BUILD_DATE" >> $GITHUB_ENV
74
74
 
75
75
  - name: Install Helm
76
- uses: azure/setup-helm@v4
76
+ uses: azure/setup-helm@v5
77
77
 
78
78
  - name: Install Python
79
79
  uses: actions/setup-python@v6
package/CHANGELOG.md CHANGED
@@ -1,3 +1,14 @@
1
+ ## [1.2.1](https://github.com/ContinuousSecurityTooling/keycloak-reporter/compare/v1.2.0...v1.2.1) (2026-03-27)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * Add missing packages and resolve linting errors ([cde369c](https://github.com/ContinuousSecurityTooling/keycloak-reporter/commit/cde369c61e05abb70c67f365fb755b4cec77254c))
7
+ * Correcting keycloak test config setup ([7210d49](https://github.com/ContinuousSecurityTooling/keycloak-reporter/commit/7210d49330640b5df4c796c1dfe4d9e1b8df1567))
8
+ * Exclude dist folder ([ce2f7b2](https://github.com/ContinuousSecurityTooling/keycloak-reporter/commit/ce2f7b2621fb2b10a1a53153ec9156e1c4b95b66))
9
+
10
+
11
+
1
12
  # [1.2.0](https://github.com/ContinuousSecurityTooling/keycloak-reporter/compare/v1.1.9...v1.2.0) (2026-03-10)
2
13
 
3
14
 
package/Dockerfile CHANGED
@@ -1,4 +1,4 @@
1
- FROM node:24.14.0-slim
1
+ FROM node:24.14.1-slim
2
2
 
3
3
  ARG BUILD_DATE
4
4
  ARG APP_VERSION
@@ -15,14 +15,14 @@ type: application
15
15
  # This is the chart version. This version number should be incremented each time you make changes
16
16
  # to the chart and its templates, including the app version.
17
17
  # Versions are expected to follow Semantic Versioning (https://semver.org/)
18
- version: 1.4.11
18
+ version: 1.4.12
19
19
 
20
20
  # This is the version number of the application being deployed. This version number should be
21
21
  # incremented each time you make changes to the application. Versions are not expected to
22
22
  # follow Semantic Versioning. They should reflect the version the application is using.
23
23
  # It is recommended to use it with quotes.
24
24
  # renovate: datasource=docker depName=ContinuousSecurityTooling/keycloak-reporter
25
- appVersion: 1.2.0
25
+ appVersion: 1.2.1
26
26
  maintainers:
27
27
  # Martin Reinhardt
28
28
  - name: hypery2k
@@ -1,6 +1,6 @@
1
1
  # keycloak-reporter
2
2
 
3
- ![Version: 1.4.11](https://img.shields.io/badge/Version-1.4.11-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 1.2.0](https://img.shields.io/badge/AppVersion-1.2.0-informational?style=flat-square)
3
+ ![Version: 1.4.12](https://img.shields.io/badge/Version-1.4.12-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 1.2.1](https://img.shields.io/badge/AppVersion-1.2.1-informational?style=flat-square)
4
4
 
5
5
  Keycloak user and client reporting tool for automated regular access checks.
6
6
 
@@ -1 +1 @@
1
- sha256:2517014a5097177fa36dccf235234347bb6181e4d3da8d0349b93ac4e860ce9b
1
+ sha256:fa291afd103823f1ec28ec3f5105a977b3fe7197b8ef68b8572ffae78e702eae
@@ -32,13 +32,13 @@ export async function convert(cfg) {
32
32
  switch (e.code || e.message) {
33
33
  case 'Request failed with status code 400':
34
34
  logger.error('Invalid Teams Webhook Payload. Check your params.');
35
- throw new Error('Invalid Teams Payload');
35
+ throw new Error('Invalid Teams Payload', { cause: e });
36
36
  case 'slack_webhook_http_error':
37
37
  logger.error('Invalid Slack Webhook Payload. Check your params.');
38
- throw new Error('Invalid Slack Payload');
38
+ throw new Error('Invalid Slack Payload', { cause: e });
39
39
  case 'generic_webhook_http_error':
40
40
  logger.error('Generic Webhook request failed. Check your URL and params.');
41
- throw new Error('Invalid Generic Webhook request');
41
+ throw new Error('Invalid Generic Webhook request', { cause: e });
42
42
  default:
43
43
  logger.error(`Error during sending webhook.(${e === null || e === void 0 ? void 0 : e.code})`, e === null || e === void 0 ? void 0 : e.original);
44
44
  throw e;
@@ -1 +1 @@
1
- {"version":3,"file":"report.js","sourceRoot":"","sources":["../../lib/report.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,MAAM,MAAM,aAAa,CAAC;AAEjC,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,GAAkB;IAC9C,IAAI,aAAqB,CAAC;IAC1B,QAAQ,GAAG,CAAC,MAAM,EAAE,CAAC;QACnB,KAAK,KAAK;YACR,aAAa,GAAG,CAAC,MAAM,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;YAC7D,MAAM;QACR,qBAAqB;QACrB;YACE,aAAa,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC7C,CAAC;IACD,IAAI,GAAG,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;QAC1B,MAAM,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC;QACxB,aAAa,CACX,IAAI,CAAC,IAAI,CACP,GAAG,GAAG,CAAC,OAAO,CAAC,SAAS,EAAE,EAC1B,GAAG,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,IAAI,CAAC,WAAW,EAAE,IAAI,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,IAAI,GAAG,CAAC,MAAM,CAAC,WAAW,EAAE,EAAE,CACjH,EACD,aAAa,CACd,CAAC;IACJ,CAAC;IACD,QAAQ,GAAG,CAAC,MAAM,EAAE,CAAC;QACnB,KAAK,SAAS;YACZ,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;gBACpB,MAAM,CAAC,KAAK,CAAC,4BAA4B,CAAC,CAAC;gBAC3C,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;YACnE,CAAC;YACD,IAAI,CAAC;gBACH,MAAM,CAAC,IAAI,CAAC,iCAAiC,GAAG,CAAC,MAAM,CAAC,IAAI,OAAO,CAAC,CAAC;gBACrE,MAAM,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;gBACzG,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;YAC/B,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,QAAQ,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC;oBAC5B,KAAK,qCAAqC;wBACxC,MAAM,CAAC,KAAK,CAAC,mDAAmD,CAAC,CAAC;wBAClE,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;oBAC3C,KAAK,0BAA0B;wBAC7B,MAAM,CAAC,KAAK,CAAC,mDAAmD,CAAC,CAAC;wBAClE,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;oBAC3C,KAAK,4BAA4B;wBAC/B,MAAM,CAAC,KAAK,CAAC,4DAA4D,CAAC,CAAC;wBAC3E,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;oBACrD;wBACE,MAAM,CAAC,KAAK,CAAC,iCAAiC,CAAC,aAAD,CAAC,uBAAD,CAAC,CAAE,IAAI,GAAG,EAAE,CAAC,aAAD,CAAC,uBAAD,CAAC,CAAE,QAAQ,CAAC,CAAC;wBACvE,MAAM,CAAC,CAAC;gBACZ,CAAC;YACH,CAAC;YACD,MAAM;QACR,6BAA6B;QAC7B;YACE,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IAC/B,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"report.js","sourceRoot":"","sources":["../../lib/report.ts"],"names":[],"mappings":"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"}
@@ -2,8 +2,8 @@
2
2
  {
3
3
  "id": "a7d99dcc-75f0-4630-99c6-294dcf0501ce",
4
4
  "realm": "master",
5
- "displayName": "Keycloak",
6
- "displayNameHtml": "<div class=\"kc-logo-text\"><span>Keycloak</span></div>",
5
+ "displayName": "Keycloak Reporter",
6
+ "displayNameHtml": "<div class=\"kc-logo-text\"><span>Keycloak Reporter</span></div>",
7
7
  "notBefore": 0,
8
8
  "defaultSignatureAlgorithm": "RS256",
9
9
  "revokeRefreshToken": false,
@@ -54,7 +54,9 @@
54
54
  "description": "${role_admin}",
55
55
  "composite": true,
56
56
  "composites": {
57
- "realm": ["create-realm"],
57
+ "realm": [
58
+ "create-realm"
59
+ ],
58
60
  "client": {
59
61
  "master-realm": [
60
62
  "view-events",
@@ -88,9 +90,15 @@
88
90
  "description": "${role_default-roles}",
89
91
  "composite": true,
90
92
  "composites": {
91
- "realm": ["offline_access", "uma_authorization"],
93
+ "realm": [
94
+ "offline_access",
95
+ "uma_authorization"
96
+ ],
92
97
  "client": {
93
- "account": ["manage-account", "view-profile"]
98
+ "account": [
99
+ "manage-account",
100
+ "view-profile"
101
+ ]
94
102
  }
95
103
  },
96
104
  "clientRole": false,
@@ -284,7 +292,9 @@
284
292
  "composite": true,
285
293
  "composites": {
286
294
  "client": {
287
- "master-realm": ["query-clients"]
295
+ "master-realm": [
296
+ "query-clients"
297
+ ]
288
298
  }
289
299
  },
290
300
  "clientRole": true,
@@ -307,7 +317,10 @@
307
317
  "composite": true,
308
318
  "composites": {
309
319
  "client": {
310
- "master-realm": ["query-groups", "query-users"]
320
+ "master-realm": [
321
+ "query-groups",
322
+ "query-users"
323
+ ]
311
324
  }
312
325
  },
313
326
  "clientRole": true,
@@ -350,7 +363,9 @@
350
363
  "composite": true,
351
364
  "composites": {
352
365
  "client": {
353
- "account": ["manage-account-links"]
366
+ "account": [
367
+ "manage-account-links"
368
+ ]
354
369
  }
355
370
  },
356
371
  "clientRole": true,
@@ -364,7 +379,9 @@
364
379
  "composite": true,
365
380
  "composites": {
366
381
  "client": {
367
- "account": ["view-consent"]
382
+ "account": [
383
+ "view-consent"
384
+ ]
368
385
  }
369
386
  },
370
387
  "clientRole": true,
@@ -410,7 +427,9 @@
410
427
  "clientRole": false,
411
428
  "containerId": "a7d99dcc-75f0-4630-99c6-294dcf0501ce"
412
429
  },
413
- "requiredCredentials": ["password"],
430
+ "requiredCredentials": [
431
+ "password"
432
+ ],
414
433
  "otpPolicyType": "totp",
415
434
  "otpPolicyAlgorithm": "HmacSHA1",
416
435
  "otpPolicyInitialCounter": 0,
@@ -418,10 +437,16 @@
418
437
  "otpPolicyLookAheadWindow": 1,
419
438
  "otpPolicyPeriod": 30,
420
439
  "otpPolicyCodeReusable": false,
421
- "otpSupportedApplications": ["totpAppFreeOTPName", "totpAppGoogleName", "totpAppMicrosoftAuthenticatorName"],
440
+ "otpSupportedApplications": [
441
+ "totpAppFreeOTPName",
442
+ "totpAppGoogleName",
443
+ "totpAppMicrosoftAuthenticatorName"
444
+ ],
422
445
  "localizationTexts": {},
423
446
  "webAuthnPolicyRpEntityName": "keycloak",
424
- "webAuthnPolicySignatureAlgorithms": ["ES256"],
447
+ "webAuthnPolicySignatureAlgorithms": [
448
+ "ES256"
449
+ ],
425
450
  "webAuthnPolicyRpId": "",
426
451
  "webAuthnPolicyAttestationConveyancePreference": "not specified",
427
452
  "webAuthnPolicyAuthenticatorAttachment": "not specified",
@@ -432,7 +457,9 @@
432
457
  "webAuthnPolicyAcceptableAaguids": [],
433
458
  "webAuthnPolicyExtraOrigins": [],
434
459
  "webAuthnPolicyPasswordlessRpEntityName": "keycloak",
435
- "webAuthnPolicyPasswordlessSignatureAlgorithms": ["ES256"],
460
+ "webAuthnPolicyPasswordlessSignatureAlgorithms": [
461
+ "ES256"
462
+ ],
436
463
  "webAuthnPolicyPasswordlessRpId": "",
437
464
  "webAuthnPolicyPasswordlessAttestationConveyancePreference": "not specified",
438
465
  "webAuthnPolicyPasswordlessAuthenticatorAttachment": "not specified",
@@ -443,34 +470,6 @@
443
470
  "webAuthnPolicyPasswordlessAcceptableAaguids": [],
444
471
  "webAuthnPolicyPasswordlessExtraOrigins": [],
445
472
  "users": [
446
- {
447
- "id": "44c2cc1f-dd8e-4ca2-be61-21fe72305161",
448
- "username": "admin",
449
- "firstName": "",
450
- "lastName": "",
451
- "emailVerified": false,
452
- "attributes": {
453
- "aud_usr_last-login_security-admin-console": ["2024-09-26T04:23:20.004404216Z"],
454
- "aud_usr_last-login": ["2024-09-26T04:23:20.004404216Z"]
455
- },
456
- "createdTimestamp": 1687417311137,
457
- "enabled": true,
458
- "totp": false,
459
- "credentials": [
460
- {
461
- "id": "7c62f635-9292-4c64-a420-520ebd422fad",
462
- "type": "password",
463
- "createdDate": 1687417311218,
464
- "secretData": "{\"value\":\"4h1gArnd7ss+tC2PY6P7Hmcqtf+jkJitldnEI9aPZTg=\",\"salt\":\"jYO3O/+8/wfo+o8CVrq0Gg==\",\"additionalParameters\":{}}",
465
- "credentialData": "{\"hashIterations\":5,\"algorithm\":\"argon2\",\"additionalParameters\":{\"hashLength\":[\"32\"],\"memory\":[\"7168\"],\"type\":[\"id\"],\"version\":[\"1.3\"],\"parallelism\":[\"1\"]}}"
466
- }
467
- ],
468
- "disableableCredentialTypes": [],
469
- "requiredActions": [],
470
- "realmRoles": ["default-roles-master", "admin"],
471
- "notBefore": 0,
472
- "groups": []
473
- },
474
473
  {
475
474
  "id": "7bfdd029-8dfd-49bb-abaa-09ab23dd6d3a",
476
475
  "username": "kermit",
@@ -493,7 +492,9 @@
493
492
  ],
494
493
  "disableableCredentialTypes": [],
495
494
  "requiredActions": [],
496
- "realmRoles": ["default-roles-master"],
495
+ "realmRoles": [
496
+ "default-roles-master"
497
+ ],
497
498
  "notBefore": 0,
498
499
  "groups": []
499
500
  },
@@ -508,7 +509,10 @@
508
509
  "credentials": [],
509
510
  "disableableCredentialTypes": [],
510
511
  "requiredActions": [],
511
- "realmRoles": ["default-roles-master", "admin"],
512
+ "realmRoles": [
513
+ "default-roles-master",
514
+ "admin"
515
+ ],
512
516
  "notBefore": 0,
513
517
  "groups": []
514
518
  }
@@ -516,14 +520,19 @@
516
520
  "scopeMappings": [
517
521
  {
518
522
  "clientScope": "offline_access",
519
- "roles": ["offline_access"]
523
+ "roles": [
524
+ "offline_access"
525
+ ]
520
526
  }
521
527
  ],
522
528
  "clientScopeMappings": {
523
529
  "account": [
524
530
  {
525
531
  "client": "account-console",
526
- "roles": ["manage-account", "view-groups"]
532
+ "roles": [
533
+ "manage-account",
534
+ "view-groups"
535
+ ]
527
536
  }
528
537
  ]
529
538
  },
@@ -538,7 +547,9 @@
538
547
  "enabled": true,
539
548
  "alwaysDisplayInConsole": false,
540
549
  "clientAuthenticatorType": "client-secret",
541
- "redirectUris": ["/realms/master/account/*"],
550
+ "redirectUris": [
551
+ "/realms/master/account/*"
552
+ ],
542
553
  "webOrigins": [],
543
554
  "notBefore": 0,
544
555
  "bearerOnly": false,
@@ -556,8 +567,20 @@
556
567
  "authenticationFlowBindingOverrides": {},
557
568
  "fullScopeAllowed": false,
558
569
  "nodeReRegistrationTimeout": 0,
559
- "defaultClientScopes": ["web-origins", "acr", "roles", "profile", "basic", "email"],
560
- "optionalClientScopes": ["address", "phone", "offline_access", "microprofile-jwt"]
570
+ "defaultClientScopes": [
571
+ "web-origins",
572
+ "acr",
573
+ "roles",
574
+ "profile",
575
+ "basic",
576
+ "email"
577
+ ],
578
+ "optionalClientScopes": [
579
+ "address",
580
+ "phone",
581
+ "offline_access",
582
+ "microprofile-jwt"
583
+ ]
561
584
  },
562
585
  {
563
586
  "id": "97b8fe48-63ef-4d0b-9300-3688e9f60327",
@@ -569,7 +592,9 @@
569
592
  "enabled": true,
570
593
  "alwaysDisplayInConsole": false,
571
594
  "clientAuthenticatorType": "client-secret",
572
- "redirectUris": ["/realms/master/account/*"],
595
+ "redirectUris": [
596
+ "/realms/master/account/*"
597
+ ],
573
598
  "webOrigins": [],
574
599
  "notBefore": 0,
575
600
  "bearerOnly": false,
@@ -598,8 +623,20 @@
598
623
  "config": {}
599
624
  }
600
625
  ],
601
- "defaultClientScopes": ["web-origins", "acr", "roles", "profile", "basic", "email"],
602
- "optionalClientScopes": ["address", "phone", "offline_access", "microprofile-jwt"]
626
+ "defaultClientScopes": [
627
+ "web-origins",
628
+ "acr",
629
+ "roles",
630
+ "profile",
631
+ "basic",
632
+ "email"
633
+ ],
634
+ "optionalClientScopes": [
635
+ "address",
636
+ "phone",
637
+ "offline_access",
638
+ "microprofile-jwt"
639
+ ]
603
640
  },
604
641
  {
605
642
  "id": "be4a4d27-4fdb-4547-99ed-5a7a789d7ad3",
@@ -625,8 +662,20 @@
625
662
  "authenticationFlowBindingOverrides": {},
626
663
  "fullScopeAllowed": false,
627
664
  "nodeReRegistrationTimeout": 0,
628
- "defaultClientScopes": ["web-origins", "acr", "roles", "profile", "basic", "email"],
629
- "optionalClientScopes": ["address", "phone", "offline_access", "microprofile-jwt"]
665
+ "defaultClientScopes": [
666
+ "web-origins",
667
+ "acr",
668
+ "roles",
669
+ "profile",
670
+ "basic",
671
+ "email"
672
+ ],
673
+ "optionalClientScopes": [
674
+ "address",
675
+ "phone",
676
+ "offline_access",
677
+ "microprofile-jwt"
678
+ ]
630
679
  },
631
680
  {
632
681
  "id": "3592a6f0-f576-4ca6-9de0-435a1986f59d",
@@ -641,8 +690,12 @@
641
690
  "alwaysDisplayInConsole": false,
642
691
  "clientAuthenticatorType": "client-secret",
643
692
  "secret": "3UYhI2hryFwoVtcd7ljlaDuD9HXrGV5r",
644
- "redirectUris": ["*"],
645
- "webOrigins": ["+"],
693
+ "redirectUris": [
694
+ "*"
695
+ ],
696
+ "webOrigins": [
697
+ "+"
698
+ ],
646
699
  "notBefore": 0,
647
700
  "bearerOnly": false,
648
701
  "consentRequired": false,
@@ -711,8 +764,20 @@
711
764
  }
712
765
  }
713
766
  ],
714
- "defaultClientScopes": ["web-origins", "acr", "roles", "profile", "basic", "email"],
715
- "optionalClientScopes": ["address", "phone", "offline_access", "microprofile-jwt"]
767
+ "defaultClientScopes": [
768
+ "web-origins",
769
+ "acr",
770
+ "roles",
771
+ "profile",
772
+ "basic",
773
+ "email"
774
+ ],
775
+ "optionalClientScopes": [
776
+ "address",
777
+ "phone",
778
+ "offline_access",
779
+ "microprofile-jwt"
780
+ ]
716
781
  },
717
782
  {
718
783
  "id": "7fde7727-5e5b-4808-a795-16d8f145aa76",
@@ -738,8 +803,19 @@
738
803
  "authenticationFlowBindingOverrides": {},
739
804
  "fullScopeAllowed": false,
740
805
  "nodeReRegistrationTimeout": 0,
741
- "defaultClientScopes": ["web-origins", "acr", "roles", "profile", "email"],
742
- "optionalClientScopes": ["address", "phone", "offline_access", "microprofile-jwt"]
806
+ "defaultClientScopes": [
807
+ "web-origins",
808
+ "acr",
809
+ "roles",
810
+ "profile",
811
+ "email"
812
+ ],
813
+ "optionalClientScopes": [
814
+ "address",
815
+ "phone",
816
+ "offline_access",
817
+ "microprofile-jwt"
818
+ ]
743
819
  },
744
820
  {
745
821
  "id": "55b17911-341e-42b4-84c9-ef0501314f0e",
@@ -764,8 +840,19 @@
764
840
  "authenticationFlowBindingOverrides": {},
765
841
  "fullScopeAllowed": false,
766
842
  "nodeReRegistrationTimeout": 0,
767
- "defaultClientScopes": ["web-origins", "acr", "roles", "profile", "email"],
768
- "optionalClientScopes": ["address", "phone", "offline_access", "microprofile-jwt"]
843
+ "defaultClientScopes": [
844
+ "web-origins",
845
+ "acr",
846
+ "roles",
847
+ "profile",
848
+ "email"
849
+ ],
850
+ "optionalClientScopes": [
851
+ "address",
852
+ "phone",
853
+ "offline_access",
854
+ "microprofile-jwt"
855
+ ]
769
856
  },
770
857
  {
771
858
  "id": "ef05dd18-6304-4674-b2bd-b9f5227415e5",
@@ -777,8 +864,12 @@
777
864
  "enabled": true,
778
865
  "alwaysDisplayInConsole": false,
779
866
  "clientAuthenticatorType": "client-secret",
780
- "redirectUris": ["/admin/master/console/*"],
781
- "webOrigins": ["+"],
867
+ "redirectUris": [
868
+ "/admin/master/console/*"
869
+ ],
870
+ "webOrigins": [
871
+ "+"
872
+ ],
782
873
  "notBefore": 0,
783
874
  "bearerOnly": false,
784
875
  "consentRequired": false,
@@ -813,8 +904,20 @@
813
904
  }
814
905
  }
815
906
  ],
816
- "defaultClientScopes": ["web-origins", "acr", "roles", "profile", "basic", "email"],
817
- "optionalClientScopes": ["address", "phone", "offline_access", "microprofile-jwt"]
907
+ "defaultClientScopes": [
908
+ "web-origins",
909
+ "acr",
910
+ "roles",
911
+ "profile",
912
+ "basic",
913
+ "email"
914
+ ],
915
+ "optionalClientScopes": [
916
+ "address",
917
+ "phone",
918
+ "offline_access",
919
+ "microprofile-jwt"
920
+ ]
818
921
  }
819
922
  ],
820
923
  "clientScopes": [
@@ -1363,8 +1466,21 @@
1363
1466
  ]
1364
1467
  }
1365
1468
  ],
1366
- "defaultDefaultClientScopes": ["basic", "email", "role_list", "web-origins", "acr", "roles", "profile"],
1367
- "defaultOptionalClientScopes": ["phone", "microprofile-jwt", "address", "offline_access"],
1469
+ "defaultDefaultClientScopes": [
1470
+ "basic",
1471
+ "email",
1472
+ "role_list",
1473
+ "web-origins",
1474
+ "acr",
1475
+ "roles",
1476
+ "profile"
1477
+ ],
1478
+ "defaultOptionalClientScopes": [
1479
+ "phone",
1480
+ "microprofile-jwt",
1481
+ "address",
1482
+ "offline_access"
1483
+ ],
1368
1484
  "browserSecurityHeaders": {
1369
1485
  "contentSecurityPolicyReportOnly": "",
1370
1486
  "xContentTypeOptions": "nosniff",
@@ -1376,7 +1492,10 @@
1376
1492
  },
1377
1493
  "smtpServer": {},
1378
1494
  "eventsEnabled": true,
1379
- "eventsListeners": ["jboss-logging", "kc-auditor"],
1495
+ "eventsListeners": [
1496
+ "jboss-logging",
1497
+ "kc-auditor"
1498
+ ],
1380
1499
  "enabledEventTypes": [
1381
1500
  "UPDATE_CONSENT_ERROR",
1382
1501
  "UPDATE_TOTP",
@@ -1523,7 +1642,9 @@
1523
1642
  "subType": "anonymous",
1524
1643
  "subComponents": {},
1525
1644
  "config": {
1526
- "allow-default-scopes": ["true"]
1645
+ "allow-default-scopes": [
1646
+ "true"
1647
+ ]
1527
1648
  }
1528
1649
  },
1529
1650
  {
@@ -1533,7 +1654,9 @@
1533
1654
  "subType": "anonymous",
1534
1655
  "subComponents": {},
1535
1656
  "config": {
1536
- "max-clients": ["200"]
1657
+ "max-clients": [
1658
+ "200"
1659
+ ]
1537
1660
  }
1538
1661
  },
1539
1662
  {
@@ -1543,7 +1666,9 @@
1543
1666
  "subType": "authenticated",
1544
1667
  "subComponents": {},
1545
1668
  "config": {
1546
- "allow-default-scopes": ["true"]
1669
+ "allow-default-scopes": [
1670
+ "true"
1671
+ ]
1547
1672
  }
1548
1673
  },
1549
1674
  {
@@ -1580,8 +1705,12 @@
1580
1705
  "subType": "anonymous",
1581
1706
  "subComponents": {},
1582
1707
  "config": {
1583
- "host-sending-registration-request-must-match": ["true"],
1584
- "client-uris-must-match": ["true"]
1708
+ "host-sending-registration-request-must-match": [
1709
+ "true"
1710
+ ],
1711
+ "client-uris-must-match": [
1712
+ "true"
1713
+ ]
1585
1714
  }
1586
1715
  }
1587
1716
  ],
@@ -1595,11 +1724,15 @@
1595
1724
  "privateKey": [
1596
1725
  "MIIEoQIBAAKCAQEAx2KsWSpGDhd0kr+pR36Ra+sdcBH0CKwZhujtEZJPx8VIVQIwL056rNaaQOoYLYvaa0uWW7h4CkrvXyAM1F0W8Q3MdQFtHYWAWeY5CtKJoI4kri2elCYOFr8WdU+GQh0zVYRv1tuvIPhQtxoN67ta+SenIVIhxSosXKmmhLFCAbvnEck5hIO+Zgp2Oay/kZJwN/V5k4zWqOvXBavrsmOfdjdlA4TSG8VKo2R6lL678Hr9e+HpfVtFQ5/CbF4UBpFGGzzGbDxNRaqK+wQIPWo+2HFzeUAb/83tYvamP1eXFMRj257gcf1TXy/dUmVi6n2kf4DU7sDi35pjgX8uT5aR8QIDAQABAoH/D+TJGnMyF79AgVcqJYfE5HZ1ms8X1C56mnLwdcBusENaYco/17i9WsYw9rgvlqI6XXBb6YFV9rfP/Qe3DynVZmxwrQ8jmfiepovra4RG3jqNPKZGTdUL0klXc86WmXqs5zT0lKG02XhpWkujtLVwVKXCaagNbVw8bFhRK1MIdJXPxiroyub5leUS/5xzGD4Voigbz9YiJeq0XnHJQDYpqwsuOFxmP4LgBDOWil12v0KHAUgTQmMlzynj5HfOkaqp5VXadb6pMZVraUpbtWqb3P5l3N5oueJwAjKA6JH2j1gNCpuQNcQDQYuhkqyot7LEyEPOx4uJQA8qM7bTG0fhAoGBAOY1GZO50Ar1/d8zxMdr1lzD5kZ4oR525zpLlfU6s3dwrW0fjeARFWvVApqR4ecDWAMMJ9U2RbByHvBCCMZt+qFAQ0dxAqYVQHO2IrLjewUdCmdBpC8Lq6o0PL1or0tCBKaUI7roThQoNyzVzULWLdDBNmTXa5wz06fkXzVdRujhAoGBAN25hnC266dTOiJWHXK3dRNjpxuqM5SRE6ZU8DZ4Rj55Lvc2L/PupDhLMz8nxyesUhR4x57+iJLtjU2VyL1+k3s2vN+DSh4pHMHEQfqsnKVvnSECNN8hnnnWs+cyvO7gMrfnj/6wQwZIK6OW4q3CyHbKJzqM+YnYLTOWspp6nXsRAoGAQMbGSKwrXzoy0oCVqWutqPKytDezVogsrlmge52l7ED3e9I6MMd92JbaobXU9BUbyde8yaD44RprnD1ojLVbpc4YYFzrWuJ1/VlN0Dp0Xk76o210DozhJAaI5N81HB8agekDWM+PUNq0E9ihZmIwCCKl9KAtNonaz85SAAkcL+ECgYArDD4h3CHclrgOupF1GFFOtmZXZLAnBBPAk3Uf3jIlJvoLXSXqQkb39wG4HUz5UueMufZn1BtIC38HtTEIOW8A2RvKeX8GZA0FQcldle3D4Ous4PTK7YgLN7guBxfPeQ/fzMGUPTyGF7UBSeYwvkSVa6I6J+y66pG8FmIOxAeXQQKBgQCQT6A+iUbP17iQOFd5ExdnobtaSyQdOlbSo8NYQSBFMext3kWKF9j8y9B1hk2DKGsxcwkVJwLpPuctJhbhY0r22Nqz/u63R9UOXOwqyQy2pAUWDbVO1H+2P1lIqxAN5mSKkVuPJmrpph2AejA8s8iT4w/Fq5jdIq+1OcJCYhU4TA=="
1597
1726
  ],
1598
- "keyUse": ["SIG"],
1727
+ "keyUse": [
1728
+ "SIG"
1729
+ ],
1599
1730
  "certificate": [
1600
1731
  "MIICmzCCAYMCBgGI4egv0jANBgkqhkiG9w0BAQsFADARMQ8wDQYDVQQDDAZtYXN0ZXIwHhcNMjMwNjIyMDY1OTMwWhcNMzMwNjIyMDcwMTEwWjARMQ8wDQYDVQQDDAZtYXN0ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDHYqxZKkYOF3SSv6lHfpFr6x1wEfQIrBmG6O0Rkk/HxUhVAjAvTnqs1ppA6hgti9prS5ZbuHgKSu9fIAzUXRbxDcx1AW0dhYBZ5jkK0omgjiSuLZ6UJg4WvxZ1T4ZCHTNVhG/W268g+FC3Gg3ru1r5J6chUiHFKixcqaaEsUIBu+cRyTmEg75mCnY5rL+RknA39XmTjNao69cFq+uyY592N2UDhNIbxUqjZHqUvrvwev174el9W0VDn8JsXhQGkUYbPMZsPE1Fqor7BAg9aj7YcXN5QBv/ze1i9qY/V5cUxGPbnuBx/VNfL91SZWLqfaR/gNTuwOLfmmOBfy5PlpHxAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAGQGNxSEexGEWLYDEW2u07oDdT2tLbg09QokE2O1HDN/zQZU9lqdrGzZ/icl2aDv0/+WHIRNWO3wHARK5ZpcC/ek8Itmlq7AwsB+s059oy28yg3h0MJuRmKOMYcWfFJrOSCqtx0onGNa2nnxbUgakLrjXPltsWGZbRW7SEsfZESgDKELw/VKtd6rWuxt7T6YglkXvEHP6ILcUaEnmqougihNN3cpFiCpIWLdq+hqColXgDnfsnc/I3cCXqVDELei4IPIsgaYJZjXCWXnkKwxZ0qAQNQQwN2fjaYBDlx01/dnxWtqbDO9pYlN+FuyVxxQUDupK49asI1zKCjaE1SU/+M="
1601
1732
  ],
1602
- "priority": ["100"]
1733
+ "priority": [
1734
+ "100"
1735
+ ]
1603
1736
  }
1604
1737
  },
1605
1738
  {
@@ -1608,10 +1741,18 @@
1608
1741
  "providerId": "hmac-generated",
1609
1742
  "subComponents": {},
1610
1743
  "config": {
1611
- "kid": ["65ff5817-07e7-49f8-af9b-42275ff2743d"],
1612
- "secret": ["s9r4kWThPSruxEhHM4zJSmP12pKlScTguWNQQJCSju1vgrg7aSaqPML5supbGkyuHsBwZZsWmIaiz6ahyA-IXA"],
1613
- "priority": ["100"],
1614
- "algorithm": ["HS256"]
1744
+ "kid": [
1745
+ "65ff5817-07e7-49f8-af9b-42275ff2743d"
1746
+ ],
1747
+ "secret": [
1748
+ "s9r4kWThPSruxEhHM4zJSmP12pKlScTguWNQQJCSju1vgrg7aSaqPML5supbGkyuHsBwZZsWmIaiz6ahyA-IXA"
1749
+ ],
1750
+ "priority": [
1751
+ "100"
1752
+ ],
1753
+ "algorithm": [
1754
+ "HS256"
1755
+ ]
1615
1756
  }
1616
1757
  },
1617
1758
  {
@@ -1620,9 +1761,15 @@
1620
1761
  "providerId": "aes-generated",
1621
1762
  "subComponents": {},
1622
1763
  "config": {
1623
- "kid": ["53bed235-84b5-4ba4-9596-64817056eff3"],
1624
- "secret": ["Mw2VQRtxs9cSxeDahDG7sw"],
1625
- "priority": ["100"]
1764
+ "kid": [
1765
+ "53bed235-84b5-4ba4-9596-64817056eff3"
1766
+ ],
1767
+ "secret": [
1768
+ "Mw2VQRtxs9cSxeDahDG7sw"
1769
+ ],
1770
+ "priority": [
1771
+ "100"
1772
+ ]
1626
1773
  }
1627
1774
  },
1628
1775
  {
@@ -1634,12 +1781,18 @@
1634
1781
  "privateKey": [
1635
1782
  "MIIEowIBAAKCAQEAiVvzxzny/tJlUW9U4rZZyQ9af6cz/OMg7QReBX2HPaC8Sf5XKfdO7ZlSCcCdIUYbY1+vbGWrB2b6J+wx+OQLbQfQuVls3lzmaf/7OL5MFs6tr6KCuW3QNSFB4fcPTueFfD9pTKEqGlW8b48CJOxbuqVABVhm6WcAFZh9uQfMv4yC6/KqZfDXbWloCRsCfLCE5sYPXsV8d52u166IPVkoZHcz99XYjTh6OxQY3a6cSs+kaWAQXQ6an0F9cZWT9IX7FJfYirbGIgOAwHooGPLAzNVwqvVhO1ubpaVVFjjyWkQpglTjASNMdoE0onlIX/uuqlfeRuqi7pUKNd4Xp+XB+QIDAQABAoIBAAeL2jZBTETMqU1SiP7VltQxeD7YIEaN8eKjoUi670GnAYEtLHu9PwRVroijoN5RnDKW8KvLYByNf0PPOaWbXbdVPRXZwF3tC6maKyKgbcy4+RjTnEv0qQIqPBTefmRO2uoLD81qc0Y0HKCiYjNGGvoDlyNUCn9bLcmB8bJHJ+wEBxZiOJYeXLjWdti0OIqOI412MBZXNaxw1Bi33u1nEgTBpHs39AoD0ejAksMMcWccwHNTEkioVKGcHgsI/QyFgsUNiCLql3FVg7BkrQ2BPGGv1acAllWfXzrusaLwrvFzwSMl14FzCedFcRF0HxdDrP3thjefnXWfJ/S65kxPJ6kCgYEAwP5J/PHnhWNKgdRW0qX4Q+uOs7TXNXCXBQ7tMJ+8PTMfEMjDrD/upj7C+XMiiC+rhpdCCoVEHXMVlWMEc9D06ZiPgMQJebXmPYXu4ki97KorgWAHTEidZQRQKRrNRVl7b2M/fF/Q+jsYEaRhiR9W/oE4h63tlyPXa31LeiCVDH0CgYEAtjP0wgxo9oSdaSmiXF0x5n9yi95Pr2Szpl42XVHj6z2ZCTTMniMiqBxrm19epfddvVS6i2PsYjq6xgYsuYDrGOj5SqBEHUB/Ktj3mWpeblLtGe3ytwtLN7XsAhgNOeFqFb4IKkex/5ckbcNQaV7OjGzGKsDRK7MXYTn8u2BR0C0CgYAtRHf+SI9RjjSPt0qWJi/RXpMeO7Cu7DXADfw8h3sTr8X9ndmnsWc8v0PkVskmwGevLhNjfFa5waCyZYNJ1x1bHVmrjk/aqHvUunGJyh4iQNfrhKaxkea5JwXWXl7/gTmeqtzdQ2w1BV9j4/asvxkcoRqtWHJ+HP4OTFlD0Bil0QKBgGFjiBIou/n4jILnhCdGkSOZP8rPO1yOwQ/OD9T1rpPQyvoGxNBKC348IrBb26VugSZwIX3cHT+sEKVEK6fD5uXbsVRYMdBI5zAp5L6WAn+Jx74yV6fLW5sdnFbKMFedyyxv9MFUrSnmycv5uAN6b4DTq2Cyy5tGENshOZuWMmTJAoGBAJ8FeGYzBkDRUHiraTut0B/x71F6eU8N83rJ+xrihNak/iWdOP5os896/QiKwA/lYSQAJWZrH9YSwzYi7c3jVDDRig0nZE3Cca865RSd9S2vBbYDAXbkyNhXilb+Yxo202dAw8Gcpr7kGfCTjq8fBFxzKHa7/BP4i2VJOKRc+OXo"
1636
1783
  ],
1637
- "keyUse": ["ENC"],
1784
+ "keyUse": [
1785
+ "ENC"
1786
+ ],
1638
1787
  "certificate": [
1639
1788
  "MIICmzCCAYMCBgGI4egwrTANBgkqhkiG9w0BAQsFADARMQ8wDQYDVQQDDAZtYXN0ZXIwHhcNMjMwNjIyMDY1OTMwWhcNMzMwNjIyMDcwMTEwWjARMQ8wDQYDVQQDDAZtYXN0ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCJW/PHOfL+0mVRb1TitlnJD1p/pzP84yDtBF4FfYc9oLxJ/lcp907tmVIJwJ0hRhtjX69sZasHZvon7DH45AttB9C5WWzeXOZp//s4vkwWzq2vooK5bdA1IUHh9w9O54V8P2lMoSoaVbxvjwIk7Fu6pUAFWGbpZwAVmH25B8y/jILr8qpl8NdtaWgJGwJ8sITmxg9exXx3na7Xrog9WShkdzP31diNOHo7FBjdrpxKz6RpYBBdDpqfQX1xlZP0hfsUl9iKtsYiA4DAeigY8sDM1XCq9WE7W5ulpVUWOPJaRCmCVOMBI0x2gTSieUhf+66qV95G6qLulQo13hen5cH5AgMBAAEwDQYJKoZIhvcNAQELBQADggEBAFlnzOe9lMxJql83r8rqcFtEuntQJ96v5XvumsUiIURXqOl/6hmqh2uQqhUcW/tjRdW5DhykRP9d8oPi0al8V0EvQexuBUeqlP5a/NK8qQ032mwtCVSbCw8Jvx3gg/vtW5cx2x138Rr4L8QjF+XZwdJiZTQrtWIW7WA+4iqgRvDkzY7R3S6FcjZDCaXacPCYoG6VOMX6bYjeGhlVtev+VTSO0z2msxSdfTjof28yNueg1xmn64QzLbos+OxOxQ3+EUs8WU020becqPfI2Meg9zh/TuqUqbRQEqG9ayl2q8cJHk+ALlhTWhBdn6ii8Ca1qRgfYJDN+IK4zgB93TK2kEs="
1640
1789
  ],
1641
- "priority": ["100"],
1642
- "algorithm": ["RSA-OAEP"]
1790
+ "priority": [
1791
+ "100"
1792
+ ],
1793
+ "algorithm": [
1794
+ "RSA-OAEP"
1795
+ ]
1643
1796
  }
1644
1797
  },
1645
1798
  {
@@ -1648,12 +1801,18 @@
1648
1801
  "providerId": "hmac-generated",
1649
1802
  "subComponents": {},
1650
1803
  "config": {
1651
- "kid": ["f553ff21-7a08-4f65-b6f4-7a7b7143b578"],
1804
+ "kid": [
1805
+ "f553ff21-7a08-4f65-b6f4-7a7b7143b578"
1806
+ ],
1652
1807
  "secret": [
1653
1808
  "t-tPUhbmk9ne-3Vehghh-G6vjiPYeu6qu2bYWayIkwjocoYqxR8PrfLxj1lQGxzi174dCgPNUrE5f_R4Q7ie0uMXiP3MQd9Kje4P2wM0RB8h1G1z-E7uH3qTuG-43XqPDjVf6SRWPyKoOQbWq4LvzX-_5FUNYQMdh8b1CeZ3XRw"
1654
1809
  ],
1655
- "priority": ["100"],
1656
- "algorithm": ["HS512"]
1810
+ "priority": [
1811
+ "100"
1812
+ ],
1813
+ "algorithm": [
1814
+ "HS512"
1815
+ ]
1657
1816
  }
1658
1817
  }
1659
1818
  ]
@@ -2303,4 +2462,4 @@
2303
2462
  "policies": []
2304
2463
  }
2305
2464
  }
2306
- ]
2465
+ ]
@@ -4,7 +4,7 @@ import { test } from 'tape';
4
4
  import { spawn } from 'node:child_process';
5
5
  import path from 'node:path';
6
6
 
7
- test('Should list clients as JSON', { timeout: 3000 }, (t) => {
7
+ test('Should list clients as JSON', { timeout: 10000 }, (t) => {
8
8
  const cli = spawn(
9
9
  path.join(path.dirname('.'), 'node'),
10
10
  [
@@ -20,12 +20,18 @@ test('Should list clients as JSON', { timeout: 3000 }, (t) => {
20
20
  },
21
21
  }
22
22
  );
23
+ let output = '';
23
24
  cli.stdout.on('data', (chunk) => {
24
- console.log('Response', JSON.parse(chunk.toString()));
25
- t.equal(JSON.parse(chunk.toString()).length, 7);
26
- t.end();
25
+ output += chunk.toString();
27
26
  });
28
27
  cli.stderr.on('data', (msg) => {
29
- t.fail(msg)
28
+ t.fail(msg);
29
+ });
30
+ cli.stdout.on('end', () => {
31
+ const json = output.split('\n').find((line) => line.trim().startsWith('['));
32
+ const parsed = JSON.parse(json);
33
+ console.log('Response', parsed);
34
+ t.equal(parsed.length, 7);
35
+ t.end();
30
36
  });
31
37
  });
@@ -4,36 +4,48 @@ import { test } from 'tape';
4
4
  import { spawn } from 'node:child_process';
5
5
  import path from 'node:path';
6
6
 
7
- test('Should use config file', { timeout: 3000 }, (t) => {
7
+ test('Should use config file', { timeout: 10000 }, (t) => {
8
8
  const cli = spawn(path.join(path.dirname('.'), 'node'), ['dist/cli.js', 'listClients'], {
9
9
  env: {
10
10
  CONFIG_FILE: process.cwd() + '/e2e/fixtures/config.json',
11
11
  ...process.env,
12
12
  },
13
13
  });
14
+ let output = '';
14
15
  cli.stdout.on('data', (chunk) => {
15
- console.log('Response', JSON.parse(chunk.toString()));
16
- t.equal(JSON.parse(chunk.toString()).length,7);
17
- t.end();
16
+ output += chunk.toString();
18
17
  });
19
18
  cli.stderr.on('data', (msg) => {
20
19
  t.fail(msg);
21
20
  });
21
+ cli.stdout.on('end', () => {
22
+ const json = output.split('\n').find((line) => line.trim().startsWith('['));
23
+ const parsed = JSON.parse(json);
24
+ console.log('Response', parsed);
25
+ t.equal(parsed.length, 7);
26
+ t.end();
27
+ });
22
28
  });
23
29
 
24
- test('Should validate config', { timeout: 3000 }, (t) => {
30
+ test('Should validate config', { timeout: 10000 }, (t) => {
25
31
  const cli = spawn(path.join(path.dirname('.'), 'node'), ['dist/cli.js', 'configTest'], {
26
32
  env: {
27
33
  CONFIG_FILE: process.cwd() + '/e2e/fixtures/config.json',
28
34
  ...process.env,
29
35
  },
30
36
  });
37
+ let output = '';
31
38
  cli.stdout.on('data', (chunk) => {
32
- console.log(chunk.toString());
33
- t.equal(chunk.toString(), 'Connection to http://localhost:8080 was successful: 3 users found.\n');
34
- t.end();
39
+ output += chunk.toString();
35
40
  });
36
41
  cli.stderr.on('data', (msg) => {
37
42
  t.fail(msg);
38
43
  });
44
+ cli.stdout.on('end', () => {
45
+ t.ok(
46
+ output.includes('Connection to http://localhost:8080 was successful: 2 users found.'),
47
+ 'config test output matches'
48
+ );
49
+ t.end();
50
+ });
39
51
  });
package/e2e/spec/users.js CHANGED
@@ -4,7 +4,7 @@ import { test } from 'tape';
4
4
  import { spawn } from 'node:child_process';
5
5
  import path from 'node:path';
6
6
 
7
- test('Should list users as JSON', { timeout: 3000 }, (t) => {
7
+ test('Should list users as JSON', { timeout: 10000 }, (t) => {
8
8
  const cli = spawn(
9
9
  path.join(path.dirname('.'), 'node'),
10
10
  [
@@ -20,12 +20,18 @@ test('Should list users as JSON', { timeout: 3000 }, (t) => {
20
20
  },
21
21
  }
22
22
  );
23
+ let output = '';
23
24
  cli.stdout.on('data', (chunk) => {
24
- console.log('Response', JSON.parse(chunk.toString()));
25
- t.equal(JSON.parse(chunk.toString()).length, 3);
26
- t.end();
25
+ output += chunk.toString();
27
26
  });
28
27
  cli.stderr.on('data', (msg) => {
29
- t.fail(msg)
28
+ t.fail(msg);
29
+ });
30
+ cli.stdout.on('end', () => {
31
+ const json = output.split('\n').find((line) => line.trim().startsWith('['));
32
+ const parsed = JSON.parse(json);
33
+ console.log('Response', parsed);
34
+ t.equal(parsed.length, 2);
35
+ t.end();
30
36
  });
31
37
  });
Binary file
package/lib/report.ts CHANGED
@@ -39,13 +39,13 @@ export async function convert(cfg: ConvertConfig) {
39
39
  switch (e.code || e.message) {
40
40
  case 'Request failed with status code 400':
41
41
  logger.error('Invalid Teams Webhook Payload. Check your params.');
42
- throw new Error('Invalid Teams Payload');
42
+ throw new Error('Invalid Teams Payload', { cause: e });
43
43
  case 'slack_webhook_http_error':
44
44
  logger.error('Invalid Slack Webhook Payload. Check your params.');
45
- throw new Error('Invalid Slack Payload');
45
+ throw new Error('Invalid Slack Payload', { cause: e });
46
46
  case 'generic_webhook_http_error':
47
47
  logger.error('Generic Webhook request failed. Check your URL and params.');
48
- throw new Error('Invalid Generic Webhook request');
48
+ throw new Error('Invalid Generic Webhook request', { cause: e });
49
49
  default:
50
50
  logger.error(`Error during sending webhook.(${e?.code})`, e?.original);
51
51
  throw e;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@continuoussecuritytooling/keycloak-reporter",
3
- "version": "1.2.0",
3
+ "version": "1.2.1",
4
4
  "description": "Reporting Tools for Keycloak",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -11,7 +11,7 @@
11
11
  "clean": "rm -rf dist/* && npm i",
12
12
  "build": "tsc && chmod +x dist/cli.js && cp -rp config dist/",
13
13
  "test": "eslint --config .eslintrc.cjs . && jest",
14
- "end2end:start-server": ".bin/start-server.mjs -Dkeycloak.profile.feature.account_api=enabled -Dkeycloak.profile.feature.account2=disabled -Dkeycloak.migration.action=import -Dkeycloak.migration.provider=singleFile -Dkeycloak.migration.file=e2e/fixtures/auth-utils/test-realm.json -Dkeycloak.migration.strategy=OVERWRITE_EXISTING",
14
+ "end2end:start-server": ".bin/start-server.mjs",
15
15
  "end2end:test": "./e2e/run-tests.sh",
16
16
  "changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0",
17
17
  "changelog:add": "git add CHANGELOG.md && git commit -m 'updated CHANGELOG.md'",
@@ -46,6 +46,8 @@
46
46
  "yargs": "^18.0.0"
47
47
  },
48
48
  "devDependencies": {
49
+ "@eslint/eslintrc": "^3.3.5",
50
+ "@eslint/js": "^10.0.1",
49
51
  "@octokit/rest": "^22.0.0",
50
52
  "@types/jest": "^30.0.0",
51
53
  "@types/node": "^24.0.0",
@@ -53,9 +55,10 @@
53
55
  "@typescript-eslint/eslint-plugin": "^8.0.0",
54
56
  "@typescript-eslint/parser": "^8.0.0",
55
57
  "conventional-changelog-cli": "^5.0.0",
56
- "eslint": "^9.0.0",
58
+ "eslint": "^10.0.0",
57
59
  "eslint-config-prettier": "^10.0.0",
58
60
  "eslint-plugin-prettier": "^5.0.0",
61
+ "globals": "^17.4.0",
59
62
  "gunzip-maybe": "^1.4.2",
60
63
  "jest": "^30.0.0",
61
64
  "jest-extended": "^7.0.0",
package/tsconfig.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "target": "es2017",
6
6
  "sourceMap": true,
7
7
  "outDir": "dist",
8
- "lib": ["dom", "es2017"]
8
+ "lib": ["dom", "es2017", "es2022"]
9
9
  },
10
- "exclude": ["test"]
10
+ "exclude": ["test", "dist"]
11
11
  }
Binary file