@continuoussecuritytooling/keycloak-reporter 0.2.0 → 0.4.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.
- package/.ct.yaml +6 -0
- package/.github/CONTRIBUTING.md +48 -0
- package/.github/ISSUE_TEMPLATE/bug_report.md +34 -0
- package/.github/ISSUE_TEMPLATE/feature_request.md +25 -0
- package/.github/PULL_REQUEST_TEMPLATE.md +35 -0
- package/.github/workflows/pipeline.yml +52 -5
- package/.github/workflows/release.yml +37 -0
- package/CHANGELOG.md +22 -0
- package/Dockerfile +1 -1
- package/README.md +34 -9
- package/charts/keycloak-reporter/.helmignore +23 -0
- package/charts/keycloak-reporter/Chart.yaml +28 -0
- package/charts/keycloak-reporter/README.md +51 -0
- package/charts/keycloak-reporter/templates/NOTES.txt +0 -0
- package/charts/keycloak-reporter/templates/_helpers.tpl +62 -0
- package/charts/keycloak-reporter/templates/cronjob.yaml +66 -0
- package/charts/keycloak-reporter/templates/pvc.yaml +15 -0
- package/charts/keycloak-reporter/templates/secret.yaml +14 -0
- package/charts/keycloak-reporter/templates/serviceaccount.yaml +12 -0
- package/charts/keycloak-reporter/values.yaml +78 -0
- package/cli.ts +40 -4
- package/config/schema.json +8 -0
- package/dist/cli.js +31 -5
- package/dist/cli.js.map +1 -1
- package/dist/config/schema.json +8 -0
- package/dist/index.js +0 -0
- package/dist/index.js.map +0 -0
- package/dist/lib/client.js +0 -0
- package/dist/lib/client.js.map +0 -0
- package/dist/lib/convert.js +0 -0
- package/dist/lib/convert.js.map +0 -0
- package/dist/lib/output.js +13 -1
- package/dist/lib/output.js.map +1 -1
- package/dist/lib/user.js +0 -0
- package/dist/lib/user.js.map +0 -0
- package/dist/src/cli.js +0 -0
- package/dist/src/cli.js.map +0 -0
- package/dist/src/config.js +0 -0
- package/dist/src/config.js.map +0 -0
- package/e2e/spec/clients.js +1 -3
- package/e2e/spec/config.js +1 -3
- package/e2e/spec/users.js +1 -3
- package/e2e/spec/webhooks.js +3 -4
- package/jest.config.js +0 -1
- package/lib/output.ts +14 -1
- package/lintconf.yaml +42 -0
- package/package.json +4 -4
- package/renovate.json +15 -13
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# Default values for keycloak-reporter.
|
|
2
|
+
# This is a YAML-formatted file.
|
|
3
|
+
# Declare variables to be passed into your templates.
|
|
4
|
+
|
|
5
|
+
replicaCount: 1
|
|
6
|
+
|
|
7
|
+
image:
|
|
8
|
+
repository: continuoussecuritytooling/keycloak-reporting-cli
|
|
9
|
+
pullPolicy: IfNotPresent
|
|
10
|
+
# Overrides the image tag whose default is the chart appVersion.
|
|
11
|
+
tag: "latest"
|
|
12
|
+
|
|
13
|
+
imagePullSecrets: []
|
|
14
|
+
nameOverride: ""
|
|
15
|
+
fullnameOverride: ""
|
|
16
|
+
|
|
17
|
+
serviceAccount:
|
|
18
|
+
# Specifies whether a service account should be created
|
|
19
|
+
create: true
|
|
20
|
+
# Annotations to add to the service account
|
|
21
|
+
annotations: {}
|
|
22
|
+
# The name of the service account to use.
|
|
23
|
+
# If not set and create is true, a name is generated using the fullname template
|
|
24
|
+
name: ""
|
|
25
|
+
|
|
26
|
+
podAnnotations: {}
|
|
27
|
+
|
|
28
|
+
podSecurityContext: {}
|
|
29
|
+
# fsGroup: 2000
|
|
30
|
+
|
|
31
|
+
securityContext: {}
|
|
32
|
+
|
|
33
|
+
env: {}
|
|
34
|
+
# capabilities:
|
|
35
|
+
# drop:
|
|
36
|
+
# - ALL
|
|
37
|
+
# readOnlyRootFilesystem: true
|
|
38
|
+
# runAsNonRoot: true
|
|
39
|
+
# runAsUser: 1000
|
|
40
|
+
|
|
41
|
+
keycloak:
|
|
42
|
+
config:
|
|
43
|
+
url: ""
|
|
44
|
+
clientId: ""
|
|
45
|
+
clientSecret: ""
|
|
46
|
+
output: "webhook"
|
|
47
|
+
webhookType: ""
|
|
48
|
+
webhookUrl: ""
|
|
49
|
+
webhookMessage: ""
|
|
50
|
+
volumes:
|
|
51
|
+
reports: ""
|
|
52
|
+
|
|
53
|
+
cronjobs:
|
|
54
|
+
- name: clients
|
|
55
|
+
script: /app/index.js listClients
|
|
56
|
+
schedule: 0 0 1 */3 *
|
|
57
|
+
- name: users
|
|
58
|
+
script: /app/index.js listUsers
|
|
59
|
+
schedule: 0 0 1 */3 *
|
|
60
|
+
|
|
61
|
+
resources: {}
|
|
62
|
+
# We usually recommend not to specify default resources and to leave this as a conscious
|
|
63
|
+
# choice for the user. This also increases chances charts run on environments with little
|
|
64
|
+
# resources, such as Minikube. If you do want to specify resources, uncomment the following
|
|
65
|
+
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
|
|
66
|
+
# limits:
|
|
67
|
+
# cpu: 100m
|
|
68
|
+
# memory: 128Mi
|
|
69
|
+
# requests:
|
|
70
|
+
# cpu: 100m
|
|
71
|
+
# memory: 128Mi
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
nodeSelector: {}
|
|
75
|
+
|
|
76
|
+
tolerations: []
|
|
77
|
+
|
|
78
|
+
affinity: {}
|
package/cli.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
+
import { writeFileSync } from 'node:fs';
|
|
4
|
+
import path from 'path';
|
|
3
5
|
import yargs from 'yargs/yargs';
|
|
4
6
|
import { hideBin } from 'yargs/helpers';
|
|
5
7
|
import {
|
|
@@ -16,16 +18,24 @@ class WebhookConfig {
|
|
|
16
18
|
type: string;
|
|
17
19
|
url: string;
|
|
18
20
|
title: string;
|
|
19
|
-
|
|
21
|
+
message?: string;
|
|
22
|
+
constructor(type: string, url: string, title: string, message?: string) {
|
|
20
23
|
this.type = type;
|
|
21
24
|
this.url = url;
|
|
22
25
|
this.title = title;
|
|
26
|
+
this.message = message;
|
|
23
27
|
}
|
|
24
28
|
}
|
|
25
29
|
|
|
30
|
+
class ReportConfig {
|
|
31
|
+
name: string;
|
|
32
|
+
directory: string;
|
|
33
|
+
}
|
|
34
|
+
|
|
26
35
|
async function convert(
|
|
27
36
|
format: string,
|
|
28
37
|
output: string,
|
|
38
|
+
reports: ReportConfig,
|
|
29
39
|
config: WebhookConfig,
|
|
30
40
|
json: object
|
|
31
41
|
) {
|
|
@@ -38,6 +48,10 @@ async function convert(
|
|
|
38
48
|
default:
|
|
39
49
|
outputContent = JSON.stringify(json);
|
|
40
50
|
}
|
|
51
|
+
if (reports.directory) {
|
|
52
|
+
const date = new Date();
|
|
53
|
+
writeFileSync(path.join(`${reports.directory}`,`${reports.name}_${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}.${format.toLowerCase()}`), outputContent);
|
|
54
|
+
}
|
|
41
55
|
switch (output) {
|
|
42
56
|
case 'webhook':
|
|
43
57
|
try {
|
|
@@ -45,10 +59,12 @@ async function convert(
|
|
|
45
59
|
config.type,
|
|
46
60
|
config.url,
|
|
47
61
|
config.title,
|
|
48
|
-
outputContent
|
|
62
|
+
outputContent,
|
|
63
|
+
config.message,
|
|
49
64
|
);
|
|
50
65
|
} catch (e) {
|
|
51
66
|
console.error('Error during sending webhook: ', e);
|
|
67
|
+
throw e;
|
|
52
68
|
}
|
|
53
69
|
break;
|
|
54
70
|
// defaulting to standard out
|
|
@@ -72,10 +88,15 @@ yargs(hideBin(process.argv))
|
|
|
72
88
|
await convert(
|
|
73
89
|
argv.format as string,
|
|
74
90
|
argv.output as string,
|
|
91
|
+
{
|
|
92
|
+
name: 'user_listing',
|
|
93
|
+
directory: argv.reports as string,
|
|
94
|
+
},
|
|
75
95
|
new WebhookConfig(
|
|
76
96
|
argv.webhookType as string,
|
|
77
97
|
argv.webhookUrl as string,
|
|
78
|
-
'User Listing'
|
|
98
|
+
'User Listing',
|
|
99
|
+
argv.webhookMessage ? argv.webhookMessage as string: config.webhookMessage
|
|
79
100
|
),
|
|
80
101
|
users
|
|
81
102
|
);
|
|
@@ -95,10 +116,15 @@ yargs(hideBin(process.argv))
|
|
|
95
116
|
await convert(
|
|
96
117
|
argv.format as string,
|
|
97
118
|
argv.output as string,
|
|
119
|
+
{
|
|
120
|
+
name: 'client_listing',
|
|
121
|
+
directory: argv.reports as string,
|
|
122
|
+
},
|
|
98
123
|
new WebhookConfig(
|
|
99
124
|
argv.webhookType as string,
|
|
100
125
|
argv.webhookUrl as string,
|
|
101
|
-
'Client Listing'
|
|
126
|
+
'Client Listing',
|
|
127
|
+
argv.webhookMessage ? argv.webhookMessage as string: config.webhookMessage
|
|
102
128
|
),
|
|
103
129
|
clients
|
|
104
130
|
);
|
|
@@ -122,9 +148,19 @@ yargs(hideBin(process.argv))
|
|
|
122
148
|
default: 'slack',
|
|
123
149
|
description: 'Webhook Type',
|
|
124
150
|
})
|
|
151
|
+
.option('webhookMessage', {
|
|
152
|
+
alias: 'm',
|
|
153
|
+
type: 'string',
|
|
154
|
+
description: 'Webhook Message',
|
|
155
|
+
})
|
|
125
156
|
.option('webhookUrl', {
|
|
126
157
|
alias: 't',
|
|
127
158
|
type: 'string',
|
|
128
159
|
description: 'Webhook URL',
|
|
129
160
|
})
|
|
161
|
+
.option('reports', {
|
|
162
|
+
alias: 'r',
|
|
163
|
+
type: 'string',
|
|
164
|
+
description: 'Reports directory',
|
|
165
|
+
})
|
|
130
166
|
.parse();
|
package/config/schema.json
CHANGED
|
@@ -49,9 +49,17 @@
|
|
|
49
49
|
},
|
|
50
50
|
"description": "Type of webhook"
|
|
51
51
|
},
|
|
52
|
+
"webhookMessage": {
|
|
53
|
+
"type": "string",
|
|
54
|
+
"description": "Message added to the webhook post"
|
|
55
|
+
},
|
|
52
56
|
"webhookUrl": {
|
|
53
57
|
"type": "string",
|
|
54
58
|
"description": "URL of the webhook"
|
|
59
|
+
},
|
|
60
|
+
"reports": {
|
|
61
|
+
"type": "string",
|
|
62
|
+
"description": "Reports directory"
|
|
55
63
|
}
|
|
56
64
|
}
|
|
57
65
|
}
|
package/dist/cli.js
CHANGED
|
@@ -1,16 +1,21 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { writeFileSync } from 'node:fs';
|
|
3
|
+
import path from 'path';
|
|
2
4
|
import yargs from 'yargs/yargs';
|
|
3
5
|
import { hideBin } from 'yargs/helpers';
|
|
4
6
|
import { listUsers, listClients, convertJSON2CSV, post2Webhook, } from './index.js';
|
|
5
7
|
import config from './src/config.js';
|
|
6
8
|
class WebhookConfig {
|
|
7
|
-
constructor(type, url, title) {
|
|
9
|
+
constructor(type, url, title, message) {
|
|
8
10
|
this.type = type;
|
|
9
11
|
this.url = url;
|
|
10
12
|
this.title = title;
|
|
13
|
+
this.message = message;
|
|
11
14
|
}
|
|
12
15
|
}
|
|
13
|
-
|
|
16
|
+
class ReportConfig {
|
|
17
|
+
}
|
|
18
|
+
async function convert(format, output, reports, config, json) {
|
|
14
19
|
let outputContent;
|
|
15
20
|
switch (format) {
|
|
16
21
|
case 'csv':
|
|
@@ -20,13 +25,18 @@ async function convert(format, output, config, json) {
|
|
|
20
25
|
default:
|
|
21
26
|
outputContent = JSON.stringify(json);
|
|
22
27
|
}
|
|
28
|
+
if (reports.directory) {
|
|
29
|
+
const date = new Date();
|
|
30
|
+
writeFileSync(path.join(`${reports.directory}`, `${reports.name}_${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}.${format.toLowerCase()}`), outputContent);
|
|
31
|
+
}
|
|
23
32
|
switch (output) {
|
|
24
33
|
case 'webhook':
|
|
25
34
|
try {
|
|
26
|
-
await post2Webhook(config.type, config.url, config.title, outputContent);
|
|
35
|
+
await post2Webhook(config.type, config.url, config.title, outputContent, config.message);
|
|
27
36
|
}
|
|
28
37
|
catch (e) {
|
|
29
38
|
console.error('Error during sending webhook: ', e);
|
|
39
|
+
throw e;
|
|
30
40
|
}
|
|
31
41
|
break;
|
|
32
42
|
// defaulting to standard out
|
|
@@ -43,7 +53,10 @@ yargs(hideBin(process.argv))
|
|
|
43
53
|
clientSecret: argv.clientSecret ? argv.clientSecret : config.clientSecret,
|
|
44
54
|
rootUrl: argv.url ? argv.url : config.url,
|
|
45
55
|
});
|
|
46
|
-
await convert(argv.format, argv.output,
|
|
56
|
+
await convert(argv.format, argv.output, {
|
|
57
|
+
name: 'user_listing',
|
|
58
|
+
directory: argv.reports,
|
|
59
|
+
}, new WebhookConfig(argv.webhookType, argv.webhookUrl, 'User Listing', argv.webhookMessage ? argv.webhookMessage : config.webhookMessage), users);
|
|
47
60
|
})
|
|
48
61
|
.command('listClients [url] [clientId] [clientSecret]', 'fetches all clients in the realms.',
|
|
49
62
|
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
@@ -53,7 +66,10 @@ yargs(hideBin(process.argv))
|
|
|
53
66
|
clientSecret: argv.clientSecret ? argv.clientSecret : config.clientSecret,
|
|
54
67
|
rootUrl: argv.url ? argv.url : config.url,
|
|
55
68
|
});
|
|
56
|
-
await convert(argv.format, argv.output,
|
|
69
|
+
await convert(argv.format, argv.output, {
|
|
70
|
+
name: 'client_listing',
|
|
71
|
+
directory: argv.reports,
|
|
72
|
+
}, new WebhookConfig(argv.webhookType, argv.webhookUrl, 'Client Listing', argv.webhookMessage ? argv.webhookMessage : config.webhookMessage), clients);
|
|
57
73
|
})
|
|
58
74
|
.option('format', {
|
|
59
75
|
alias: 'f',
|
|
@@ -72,11 +88,21 @@ yargs(hideBin(process.argv))
|
|
|
72
88
|
type: 'string',
|
|
73
89
|
default: 'slack',
|
|
74
90
|
description: 'Webhook Type',
|
|
91
|
+
})
|
|
92
|
+
.option('webhookMessage', {
|
|
93
|
+
alias: 'm',
|
|
94
|
+
type: 'string',
|
|
95
|
+
description: 'Webhook Message',
|
|
75
96
|
})
|
|
76
97
|
.option('webhookUrl', {
|
|
77
98
|
alias: 't',
|
|
78
99
|
type: 'string',
|
|
79
100
|
description: 'Webhook URL',
|
|
101
|
+
})
|
|
102
|
+
.option('reports', {
|
|
103
|
+
alias: 'r',
|
|
104
|
+
type: 'string',
|
|
105
|
+
description: 'Reports directory',
|
|
80
106
|
})
|
|
81
107
|
.parse();
|
|
82
108
|
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../cli.ts"],"names":[],"mappings":";AAEA,OAAO,KAAK,MAAM,aAAa,CAAC;AAChC,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EACL,SAAS,EACT,WAAW,EAEX,eAAe,EACf,YAAY,GACb,MAAM,YAAY,CAAC;AACpB,OAAO,MAAM,MAAM,iBAAiB,CAAC;AAGrC,MAAM,aAAa;
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../cli.ts"],"names":[],"mappings":"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"}
|
package/dist/config/schema.json
CHANGED
|
@@ -49,9 +49,17 @@
|
|
|
49
49
|
},
|
|
50
50
|
"description": "Type of webhook"
|
|
51
51
|
},
|
|
52
|
+
"webhookMessage": {
|
|
53
|
+
"type": "string",
|
|
54
|
+
"description": "Message added to the webhook post"
|
|
55
|
+
},
|
|
52
56
|
"webhookUrl": {
|
|
53
57
|
"type": "string",
|
|
54
58
|
"description": "URL of the webhook"
|
|
59
|
+
},
|
|
60
|
+
"reports": {
|
|
61
|
+
"type": "string",
|
|
62
|
+
"description": "Reports directory"
|
|
55
63
|
}
|
|
56
64
|
}
|
|
57
65
|
}
|
package/dist/index.js
CHANGED
|
File without changes
|
package/dist/index.js.map
CHANGED
|
File without changes
|
package/dist/lib/client.js
CHANGED
|
File without changes
|
package/dist/lib/client.js.map
CHANGED
|
File without changes
|
package/dist/lib/convert.js
CHANGED
|
File without changes
|
package/dist/lib/convert.js.map
CHANGED
|
File without changes
|
package/dist/lib/output.js
CHANGED
|
@@ -5,7 +5,7 @@ var WebhookType;
|
|
|
5
5
|
WebhookType["SLACK"] = "slack";
|
|
6
6
|
WebhookType["TEAMS"] = "teams";
|
|
7
7
|
})(WebhookType || (WebhookType = {}));
|
|
8
|
-
export async function post2Webhook(type, url, title, reportContent) {
|
|
8
|
+
export async function post2Webhook(type, url, title, reportContent, text) {
|
|
9
9
|
//const title= 'Keycloak Reporting';
|
|
10
10
|
const date = new Date();
|
|
11
11
|
switch (type) {
|
|
@@ -33,6 +33,11 @@ export async function post2Webhook(type, url, title, reportContent) {
|
|
|
33
33
|
},
|
|
34
34
|
],
|
|
35
35
|
},
|
|
36
|
+
{
|
|
37
|
+
type: 'TextBlock',
|
|
38
|
+
text: text != null ? text : '',
|
|
39
|
+
wrap: true,
|
|
40
|
+
},
|
|
36
41
|
],
|
|
37
42
|
actions: [
|
|
38
43
|
{
|
|
@@ -72,6 +77,13 @@ export async function post2Webhook(type, url, title, reportContent) {
|
|
|
72
77
|
{
|
|
73
78
|
type: 'divider',
|
|
74
79
|
},
|
|
80
|
+
{
|
|
81
|
+
type: 'context',
|
|
82
|
+
elements: [{ type: 'plain_text', text: text != null ? text : '' }],
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
type: 'divider',
|
|
86
|
+
},
|
|
75
87
|
{
|
|
76
88
|
type: 'context',
|
|
77
89
|
elements: [
|
package/dist/lib/output.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"output.js","sourceRoot":"","sources":["../../lib/output.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,IAAI,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAEnE,OAAO,EAAE,eAAe,IAAI,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEjE,IAAK,WAGJ;AAHD,WAAK,WAAW;IACd,8BAAe,CAAA;IACf,8BAAe,CAAA;AACjB,CAAC,EAHI,WAAW,KAAX,WAAW,QAGf;AAOD,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,IAAY,EACZ,GAAW,EACX,KAAa,EACb,aAAqB;
|
|
1
|
+
{"version":3,"file":"output.js","sourceRoot":"","sources":["../../lib/output.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/user.js
CHANGED
|
File without changes
|
package/dist/lib/user.js.map
CHANGED
|
File without changes
|
package/dist/src/cli.js
CHANGED
|
File without changes
|
package/dist/src/cli.js.map
CHANGED
|
File without changes
|
package/dist/src/config.js
CHANGED
|
File without changes
|
package/dist/src/config.js.map
CHANGED
|
File without changes
|
package/e2e/spec/clients.js
CHANGED
|
@@ -23,11 +23,9 @@ test('Should list clients as JSON', { timeout: 3000 }, (t) => {
|
|
|
23
23
|
cli.stdout.on('data', (chunk) => {
|
|
24
24
|
console.log(chunk.toString())
|
|
25
25
|
t.equal(JSON.parse(chunk.toString()).length, 24);
|
|
26
|
+
t.end();
|
|
26
27
|
});
|
|
27
28
|
cli.stderr.on('data', (msg) => {
|
|
28
29
|
t.fail(msg)
|
|
29
30
|
});
|
|
30
|
-
cli.stdout.on('end', () => {
|
|
31
|
-
t.end();
|
|
32
|
-
});
|
|
33
31
|
});
|
package/e2e/spec/config.js
CHANGED
|
@@ -21,11 +21,9 @@ test('Should use config file', { timeout: 3000 }, (t) => {
|
|
|
21
21
|
cli.stdout.on('data', (chunk) => {
|
|
22
22
|
console.log(chunk.toString())
|
|
23
23
|
t.equal(JSON.parse(chunk.toString()).length, 24);
|
|
24
|
+
t.end();
|
|
24
25
|
});
|
|
25
26
|
cli.stderr.on('data', (msg) => {
|
|
26
27
|
t.fail(msg)
|
|
27
28
|
});
|
|
28
|
-
cli.stdout.on('end', () => {
|
|
29
|
-
t.end();
|
|
30
|
-
});
|
|
31
29
|
});
|
package/e2e/spec/users.js
CHANGED
|
@@ -23,11 +23,9 @@ test('Should list users as JSON', { timeout: 3000 }, (t) => {
|
|
|
23
23
|
cli.stdout.on('data', (chunk) => {
|
|
24
24
|
console.log(chunk.toString())
|
|
25
25
|
t.equal(JSON.parse(chunk.toString()).length, 3);
|
|
26
|
+
t.end();
|
|
26
27
|
});
|
|
27
28
|
cli.stderr.on('data', (msg) => {
|
|
28
29
|
t.fail(msg)
|
|
29
30
|
});
|
|
30
|
-
cli.stdout.on('end', () => {
|
|
31
|
-
t.end();
|
|
32
|
-
});
|
|
33
31
|
});
|
package/e2e/spec/webhooks.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 post message to Teams', { timeout:
|
|
7
|
+
test('Should post message to Teams', { timeout: 10000 }, (t) => {
|
|
8
8
|
const cli = spawn(
|
|
9
9
|
path.join(path.dirname('.'), 'node'),
|
|
10
10
|
[
|
|
@@ -24,7 +24,7 @@ test('Should post message to Teams', { timeout: 3000 }, (t) => {
|
|
|
24
24
|
}
|
|
25
25
|
);
|
|
26
26
|
cli.stdout.on('data', (chunk) => {
|
|
27
|
-
console.log(chunk.toString())
|
|
27
|
+
console.log(chunk.toString());
|
|
28
28
|
});
|
|
29
29
|
cli.stderr.on('data', (msg) => {
|
|
30
30
|
t.fail(msg)
|
|
@@ -34,7 +34,7 @@ test('Should post message to Teams', { timeout: 3000 }, (t) => {
|
|
|
34
34
|
});
|
|
35
35
|
});
|
|
36
36
|
|
|
37
|
-
test('Should post message to Slack', { timeout:
|
|
37
|
+
test('Should post message to Slack', { timeout: 10000 }, (t) => {
|
|
38
38
|
const cli = spawn(
|
|
39
39
|
path.join(path.dirname('.'), 'node'),
|
|
40
40
|
[
|
|
@@ -63,4 +63,3 @@ test('Should post message to Slack', { timeout: 3000 }, (t) => {
|
|
|
63
63
|
t.end();
|
|
64
64
|
});
|
|
65
65
|
});
|
|
66
|
-
|
package/jest.config.js
CHANGED
package/lib/output.ts
CHANGED
|
@@ -16,7 +16,8 @@ export async function post2Webhook(
|
|
|
16
16
|
type: string,
|
|
17
17
|
url: string,
|
|
18
18
|
title: string,
|
|
19
|
-
reportContent: string
|
|
19
|
+
reportContent: string,
|
|
20
|
+
text?: string,
|
|
20
21
|
): Promise<unknown> {
|
|
21
22
|
//const title= 'Keycloak Reporting';
|
|
22
23
|
const date = new Date();
|
|
@@ -47,6 +48,11 @@ export async function post2Webhook(
|
|
|
47
48
|
},
|
|
48
49
|
],
|
|
49
50
|
},
|
|
51
|
+
{
|
|
52
|
+
type: 'TextBlock',
|
|
53
|
+
text: text!=null ? text : '',
|
|
54
|
+
wrap: true,
|
|
55
|
+
},
|
|
50
56
|
],
|
|
51
57
|
actions: [
|
|
52
58
|
{
|
|
@@ -89,6 +95,13 @@ export async function post2Webhook(
|
|
|
89
95
|
{
|
|
90
96
|
type: 'divider',
|
|
91
97
|
},
|
|
98
|
+
{
|
|
99
|
+
type: 'context',
|
|
100
|
+
elements: [{ type: 'plain_text', text: text!=null ? text : ''}],
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
type: 'divider',
|
|
104
|
+
},
|
|
92
105
|
{
|
|
93
106
|
type: 'context',
|
|
94
107
|
elements: [
|
package/lintconf.yaml
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
---
|
|
2
|
+
rules:
|
|
3
|
+
braces:
|
|
4
|
+
min-spaces-inside: 0
|
|
5
|
+
max-spaces-inside: 0
|
|
6
|
+
min-spaces-inside-empty: -1
|
|
7
|
+
max-spaces-inside-empty: -1
|
|
8
|
+
brackets:
|
|
9
|
+
min-spaces-inside: 0
|
|
10
|
+
max-spaces-inside: 0
|
|
11
|
+
min-spaces-inside-empty: -1
|
|
12
|
+
max-spaces-inside-empty: -1
|
|
13
|
+
colons:
|
|
14
|
+
max-spaces-before: 0
|
|
15
|
+
max-spaces-after: 1
|
|
16
|
+
commas:
|
|
17
|
+
max-spaces-before: 0
|
|
18
|
+
min-spaces-after: 1
|
|
19
|
+
max-spaces-after: 1
|
|
20
|
+
comments:
|
|
21
|
+
require-starting-space: true
|
|
22
|
+
min-spaces-from-content: 2
|
|
23
|
+
document-end: disable
|
|
24
|
+
document-start: disable # No --- to start a file
|
|
25
|
+
empty-lines:
|
|
26
|
+
max: 2
|
|
27
|
+
max-start: 0
|
|
28
|
+
max-end: 0
|
|
29
|
+
hyphens:
|
|
30
|
+
max-spaces-after: 1
|
|
31
|
+
indentation:
|
|
32
|
+
spaces: consistent
|
|
33
|
+
indent-sequences: whatever # - list indentation will handle both indentation and without
|
|
34
|
+
check-multi-line-strings: false
|
|
35
|
+
key-duplicates: enable
|
|
36
|
+
line-length: disable # Lines can be any length
|
|
37
|
+
new-line-at-end-of-file: disable
|
|
38
|
+
new-lines:
|
|
39
|
+
type: unix
|
|
40
|
+
trailing-spaces: enable
|
|
41
|
+
truthy:
|
|
42
|
+
level: warning
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@continuoussecuritytooling/keycloak-reporter",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Reporting Tools for Keycloak",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"ajv": "^8.12.0",
|
|
32
32
|
"install": "^0.13.0",
|
|
33
33
|
"ms-teams-webhook": "^2.0.2",
|
|
34
|
-
"npm": "^
|
|
34
|
+
"npm": "^10.0.0",
|
|
35
35
|
"openid-client": "^5.4.2",
|
|
36
36
|
"ramda": "^0.29.0",
|
|
37
37
|
"yargs": "^17.7.2"
|
|
@@ -46,11 +46,11 @@
|
|
|
46
46
|
"eslint": "^8.40.0",
|
|
47
47
|
"gunzip-maybe": "^1.4.2",
|
|
48
48
|
"jest": "^29.5.0",
|
|
49
|
-
"jest-extended": "^
|
|
49
|
+
"jest-extended": "^4.0.0",
|
|
50
50
|
"node-fetch": "^3.3.1",
|
|
51
51
|
"tap-xunit": "^2.4.1",
|
|
52
52
|
"tape": "^5.6.3",
|
|
53
|
-
"tar-fs": "^
|
|
53
|
+
"tar-fs": "^3.0.0",
|
|
54
54
|
"ts-jest": "^29.1.0",
|
|
55
55
|
"typescript": "^5.0.4"
|
|
56
56
|
}
|
package/renovate.json
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
2
|
+
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
|
3
|
+
"extends": [
|
|
4
|
+
"config:base",":dependencyDashboard"
|
|
5
|
+
],
|
|
6
|
+
"automerge": true,
|
|
7
|
+
"platformAutomerge": true,
|
|
8
|
+
"packageRules": [
|
|
9
|
+
{
|
|
10
|
+
"description": "Automerge non-major updates",
|
|
11
|
+
"matchUpdateTypes": ["minor", "patch"],
|
|
12
|
+
"automerge": true
|
|
13
|
+
}
|
|
14
|
+
],
|
|
15
|
+
"prHourlyLimit": 10
|
|
16
|
+
}
|