@auth0/auth0-checkmate 1.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.
Files changed (114) hide show
  1. package/.github/CODEOWNERS +1 -0
  2. package/.github/workflows/npm-release.yml +77 -0
  3. package/.github/workflows/sca_scan.yml +10 -0
  4. package/.github/workflows/test.yml +48 -0
  5. package/AUTHORS +5 -0
  6. package/LICENSE +203 -0
  7. package/README.md +166 -0
  8. package/THIRD-PARTY-NOTICES +226 -0
  9. package/analyzer/lib/actions/checkActionsHardCodedValues.js +151 -0
  10. package/analyzer/lib/actions/checkActionsRuntime.js +105 -0
  11. package/analyzer/lib/actions/checkDependencies.js +111 -0
  12. package/analyzer/lib/attack_protection/checkBotDetectionSetting.js +76 -0
  13. package/analyzer/lib/attack_protection/checkBreachedPassword.js +140 -0
  14. package/analyzer/lib/attack_protection/checkBruteForce.js +89 -0
  15. package/analyzer/lib/attack_protection/checkSuspiciousIPThrottling.js +89 -0
  16. package/analyzer/lib/canonical_domain/checkCanonicalDomain.js +63 -0
  17. package/analyzer/lib/clients/checkAllowedCallbacks.js +122 -0
  18. package/analyzer/lib/clients/checkAllowedLogoutUrl.js +124 -0
  19. package/analyzer/lib/clients/checkApplicationLoginUri.js +125 -0
  20. package/analyzer/lib/clients/checkCrossOriginAuthentication.js +91 -0
  21. package/analyzer/lib/clients/checkGrantTypes.js +138 -0
  22. package/analyzer/lib/clients/checkJWTSignAlg.js +118 -0
  23. package/analyzer/lib/clients/checkRefreshToken.js +108 -0
  24. package/analyzer/lib/clients/checkWebOrigins.js +55 -0
  25. package/analyzer/lib/constants.js +63 -0
  26. package/analyzer/lib/custom_domain/checkCustomDomain.js +53 -0
  27. package/analyzer/lib/databases/checkAuthenticationMethods.js +98 -0
  28. package/analyzer/lib/databases/checkDASHardCodedValues.js +163 -0
  29. package/analyzer/lib/databases/checkEmailAttributeVerification.js +114 -0
  30. package/analyzer/lib/databases/checkEnabledDatabaseCustomization.js +83 -0
  31. package/analyzer/lib/databases/checkPasswordComplexity.js +100 -0
  32. package/analyzer/lib/databases/checkPasswordHistory.js +92 -0
  33. package/analyzer/lib/databases/checkPasswordNoPersonalInfo.js +91 -0
  34. package/analyzer/lib/databases/checkPasswordPolicy.js +95 -0
  35. package/analyzer/lib/databases/checkPromotedDBConnection.js +96 -0
  36. package/analyzer/lib/email_provider/checkEmailProvider.js +37 -0
  37. package/analyzer/lib/email_templates/checkEmailTemplates.js +71 -0
  38. package/analyzer/lib/error_page_template/checkErrorPageTemplate.js +153 -0
  39. package/analyzer/lib/event_streams/checkEventStreams.js +71 -0
  40. package/analyzer/lib/executeCheck.js +12 -0
  41. package/analyzer/lib/hooks/checkHooks.js +43 -0
  42. package/analyzer/lib/listOfAnalyser.js +24 -0
  43. package/analyzer/lib/log_streams/checkLogStream.js +60 -0
  44. package/analyzer/lib/logger.js +16 -0
  45. package/analyzer/lib/multifactor/checkGuardianFactors.js +72 -0
  46. package/analyzer/lib/multifactor/checkGuardianPolicy.js +40 -0
  47. package/analyzer/lib/network_acl/checkNetworkACL.js +35 -0
  48. package/analyzer/lib/rules/checkRules.js +102 -0
  49. package/analyzer/lib/tenant_settings/checkDefaultAudience.js +53 -0
  50. package/analyzer/lib/tenant_settings/checkDefaultDirectory.js +48 -0
  51. package/analyzer/lib/tenant_settings/checkEnabledDynamicClientRegistration.js +60 -0
  52. package/analyzer/lib/tenant_settings/checkSandboxVersion.js +37 -0
  53. package/analyzer/lib/tenant_settings/checkSessionLifetime.js +95 -0
  54. package/analyzer/lib/tenant_settings/checkSupportEmail.js +61 -0
  55. package/analyzer/lib/tenant_settings/checkSupportUrl.js +61 -0
  56. package/analyzer/lib/tenant_settings/checkTenantLoginUrl.js +71 -0
  57. package/analyzer/lib/tenant_settings/checkTenantLogoutUrl.js +60 -0
  58. package/analyzer/report.js +404 -0
  59. package/analyzer/tools/auth0.js +443 -0
  60. package/analyzer/tools/helpers.js +71 -0
  61. package/analyzer/tools/summary.js +84 -0
  62. package/analyzer/tools/utils.js +72 -0
  63. package/bin/index.js +393 -0
  64. package/eslint.config.mjs +16 -0
  65. package/images/auth0.png +0 -0
  66. package/images/okta.png +0 -0
  67. package/locales/en.json +1417 -0
  68. package/package.json +66 -0
  69. package/tests/actions/checkActionsHardCodedValues.test.js +106 -0
  70. package/tests/actions/checkActionsRuntime.test.js +102 -0
  71. package/tests/actions/checkDependencies.test.js +131 -0
  72. package/tests/attack_protection/checkBreachedPassword.test.js +253 -0
  73. package/tests/attack_protection/checkBruteForce.test.js +181 -0
  74. package/tests/attack_protection/checkSuspiciousIPThrottling.test.js +222 -0
  75. package/tests/canonical_domain/checkCanonicalDomain.test.js +94 -0
  76. package/tests/clients/checkAllowedCallbacks.test.js +149 -0
  77. package/tests/clients/checkAllowedLogoutUrl.test.js +149 -0
  78. package/tests/clients/checkApplicationLoginUri.test.js +180 -0
  79. package/tests/clients/checkCrossOriginAuthentication.test.js +99 -0
  80. package/tests/clients/checkGrantTypes.test.js +154 -0
  81. package/tests/clients/checkJWTSignAlg.test.js +121 -0
  82. package/tests/clients/checkRefreshToken.test.js +63 -0
  83. package/tests/clients/checkWebOrigins.test.js +140 -0
  84. package/tests/custom_domain/checkCustomDomain.test.js +73 -0
  85. package/tests/databases/checkAuthenticationMethods.test.js +124 -0
  86. package/tests/databases/checkDASHardCodedValues.test.js +77 -0
  87. package/tests/databases/checkEmailAttributeVerification.test.js +79 -0
  88. package/tests/databases/checkEnabledDatabaseCustomization.test.js +68 -0
  89. package/tests/databases/checkPasswordComplexity.test.js +127 -0
  90. package/tests/databases/checkPasswordHistory.test.js +100 -0
  91. package/tests/databases/checkPasswordNoPersonalInfo.test.js +94 -0
  92. package/tests/databases/checkPasswordPolicy.test.js +161 -0
  93. package/tests/databases/checkPromotedDBConnection.test.js +62 -0
  94. package/tests/email_provider/checkEmailProvider.test.js +58 -0
  95. package/tests/email_templates/checkEmailTemplates.test.js +120 -0
  96. package/tests/error_page_template/checkErrorPageTemplate.test.js +315 -0
  97. package/tests/event_streams/checkEventStreams.test.js +118 -0
  98. package/tests/hooks/checkHooks.test.js +112 -0
  99. package/tests/log_streams/checkLogStream.test.js +140 -0
  100. package/tests/multifactor/checkGuardianFactors.test.js +94 -0
  101. package/tests/multifactor/checkGuardianPolicy.test.js +49 -0
  102. package/tests/rules/checkRules.test.js +102 -0
  103. package/tests/tenant_settings/checkDefaultAudience.test.js +62 -0
  104. package/tests/tenant_settings/checkDefaultDirectory.test.js +62 -0
  105. package/tests/tenant_settings/checkEnabledDynamicClientRegistration.test.js +97 -0
  106. package/tests/tenant_settings/checkSandboxVersion.test.js +50 -0
  107. package/tests/tenant_settings/checkSessionLifetime.test.js +108 -0
  108. package/tests/tenant_settings/checkSupportEmail.test.js +77 -0
  109. package/tests/tenant_settings/checkSupportUrl.test.js +77 -0
  110. package/tests/tenant_settings/checkTenantLoginUri.test.js +82 -0
  111. package/tests/tenant_settings/checkTenantLogoutUrl.test.js +108 -0
  112. package/tests/tools/auth0.test.js +833 -0
  113. package/tests/tools/helpers.test.js +692 -0
  114. package/views/pdf_cli_report.handlebars +571 -0
@@ -0,0 +1,571 @@
1
+ <html lang="{{locale}}">
2
+
3
+ <head>
4
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
5
+ <title>Checkmate for Auth0 Configuration Report</title>
6
+ <link
7
+ href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/css/bootstrap.min.css"
8
+ rel="stylesheet"
9
+ />
10
+ <link
11
+ href="https://fonts.googleapis.com/css2?family=DM+Sans:wght@400&display=swap"
12
+ rel="stylesheet"
13
+ />
14
+ <link
15
+ href="https://fonts.googleapis.com/css2?family=Noto+Sans+JP&display=swap"
16
+ rel="stylesheet"
17
+ />
18
+ <link
19
+ href="https://fonts.googleapis.com/css2?family=Noto+Sans+KR&display=swaprel="
20
+ rel="stylesheet"
21
+ />
22
+ <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
23
+
24
+ <style
25
+ >
26
+ @page: first {
27
+ size: A4;
28
+ margin: 0;
29
+ }
30
+
31
+ /* Full-page for the first page */
32
+ @page {
33
+ size: A4;
34
+ margin: 100px 20px;
35
+ }
36
+
37
+ /* Margins for the content pages */
38
+
39
+ body {
40
+ font-family: {
41
+ {
42
+ chooseFont locale
43
+ }
44
+ }
45
+
46
+ ;
47
+ background-color: #FFFFFF;
48
+ color: #191919;
49
+ margin: 20px;
50
+ padding: 20px;
51
+ }
52
+
53
+ .first-page {
54
+ font-size: 24px;
55
+ font-weight: bold;
56
+ text-align: center;
57
+ margin-top: 200px;
58
+ }
59
+
60
+ .second-page {
61
+ font-size: 24px;
62
+ margin-top: 20px;
63
+ }
64
+
65
+ .container {
66
+ max-width: 768px;
67
+ }
68
+
69
+ footer {
70
+ background-color: #333;
71
+ color: white;
72
+ text-align: center;
73
+ padding: 10px;
74
+ }
75
+
76
+ h1,
77
+ h2,
78
+ h3,
79
+ h4,
80
+ h5,
81
+ h6 {
82
+ color: #1A31A9;
83
+ margin-top: 20px;
84
+ /* Okta Blue */
85
+ }
86
+
87
+ h1 {
88
+ font-size: 36px;
89
+ margin-bottom: 20px;
90
+ }
91
+
92
+ h2 {
93
+ font-size: 30px;
94
+ margin-bottom: 18px;
95
+ }
96
+
97
+ h3 {
98
+ font-size: 24px;
99
+ margin-bottom: 16px;
100
+ }
101
+
102
+ h4 {
103
+ font-size: 20px;
104
+ margin-bottom: 14px;
105
+ }
106
+
107
+ h5 {
108
+ font-size: 18px;
109
+ margin-bottom: 12px;
110
+ }
111
+
112
+ h6 {
113
+ font-size: 16px;
114
+ margin-bottom: 10px;
115
+ }
116
+
117
+ p {
118
+ font-size: 16px;
119
+ line-height: 1.6;
120
+ margin-bottom: 16px;
121
+ }
122
+
123
+ .content {
124
+ max-width: 800px;
125
+ margin: 0 auto;
126
+ }
127
+
128
+ /* Unordered List */
129
+ ul {
130
+ list-style-type: disc;
131
+ padding-left: 20px;
132
+ margin-bottom: 16px;
133
+ }
134
+
135
+ li {
136
+ font-size: 16px;
137
+ line-height: 1.6;
138
+ margin-bottom: 8px;
139
+ }
140
+
141
+ /* Table */
142
+ table {
143
+ width: 100%;
144
+ border-collapse: collapse;
145
+ margin-top: 20px;
146
+ margin-bottom: 20px;
147
+ }
148
+
149
+ th,
150
+ td {
151
+ padding: 10px;
152
+ text-align: left;
153
+ font-size: 16px;
154
+ line-height: 1.6;
155
+ }
156
+
157
+ th {
158
+ background-color: #3F59E4;
159
+ /* Okta Blue */
160
+ color: #FFFFFF;
161
+ font-weight: 600;
162
+ }
163
+
164
+ td {
165
+ border: 1px solid #000000;
166
+ background-color: #FFFFFF;
167
+ }
168
+
169
+ .status-red {
170
+ background-color: #ffcccc;
171
+ text-align: center;
172
+ }
173
+
174
+ .status-yellow {
175
+ background-color: #ffff99;
176
+ text-align: center;
177
+ }
178
+
179
+ .status-blue {
180
+ background-color: #cce5ff;
181
+ text-align: center;
182
+ }
183
+
184
+ .status-violet {
185
+ background-color: #330099;
186
+ text-align: center;
187
+ color: #FFFFFF
188
+ }
189
+
190
+ .status-green {
191
+ background-color: #d4edda;
192
+ text-align: center;
193
+ /* Light green for low severity */
194
+ }
195
+
196
+ /* CSS class for A4 dimensions */
197
+ .a4-portrait {
198
+ width: 640px;
199
+ /* 170mm in pixels */
200
+ height: 972px;
201
+ /* 257mm in pixels */
202
+
203
+ margin-top: 50px;
204
+ }
205
+
206
+ .a4-landscape {
207
+ transform: rotate(90deg);
208
+ margin-left: 50px;
209
+ width: 1122px;
210
+ height: 793px;
211
+ page-break-before: always;
212
+ }
213
+
214
+
215
+ canvas {
216
+ display: block;
217
+ /* Ensure the canvas behaves like a block element */
218
+ margin: 0 auto;
219
+ /* Center the canvas horizontally */
220
+ }
221
+
222
+ .error {
223
+ color: red;
224
+ font-weight: bold;
225
+ }
226
+
227
+ .error-list {
228
+ list-style-type: none;
229
+ padding: 0;
230
+ }
231
+
232
+ .error-list li {
233
+ margin-bottom: 10px;
234
+ }
235
+
236
+ /* Disable link by applying pointer-events: none */
237
+ .disabled-link {
238
+ pointer-events: none;
239
+ color: #6c757d;
240
+ /* Change color to show it's disabled (optional) */
241
+ text-decoration: none;
242
+ /* Remove underline (optional) */
243
+ }
244
+
245
+ /* Page break before summary section */
246
+ .summary-section {
247
+ page-break-before: always;
248
+ }
249
+ </style>
250
+ </head>
251
+
252
+ <body>
253
+ <div class="first-page" style="page-break-after: always;">
254
+ <div
255
+ style="width: 100%; height: 50vh; display: flex; flex-direction: column; justify-content: center; align-items: center;"
256
+ >
257
+ <img src="{{logoBase64}}" alt="Auth0" width="250" height="98""/>
258
+ <h1
259
+ style="font-size: 36px; margin-bottom: 20px;"
260
+ >{{data.report.report_title}}</h1>
261
+ <p style="font-size: 20px; margin-top: 50px;">Prepared For Tenant</p>
262
+ <p style="font-size: 16px;">{{data.auth0Domain}}</p>
263
+ <p style="font-size: 14px;">Date: {{data.today}}</p>
264
+ {{!-- <p style="font-size: 12px;">Version: {{data.version}}</p> --}}
265
+ </div>
266
+ </div>
267
+ {{#if preamble.legal}}
268
+ <div class="second-page" style="page-break-after: always;">
269
+ <h1>{{preamble.legal.heading}}</h1>
270
+ {{#each preamble.legal.items}}
271
+ <h2>{{heading}}</h2>
272
+ <p>{{text}}</p>
273
+ {{/each}}
274
+ </div>
275
+ {{/if}}
276
+ {{#if preamble.executive_summary}}
277
+ <h1>{{preamble.executive_summary.heading}}</h1>
278
+ {{#each preamble.executive_summary.items}}
279
+ <h2>{{heading}}</h2>
280
+ <p>{{text}}</p>
281
+ {{/each}}
282
+ <h2>{{preamble.goals.heading}}</h2>
283
+ <ul class="">
284
+ {{#each preamble.goals.items}}
285
+ <li class="">
286
+ {{{replace this "{placeholder}" ...data.auth0Domain}}}
287
+ </li>
288
+ {{/each}}
289
+ </ul>
290
+ <h4>{{preamble.scope.heading}}</h4>
291
+ <p>{{preamble.scope.text}}</p>
292
+ <ul class="">
293
+ {{#each data.report.list_of_validators}}
294
+ <li class=""> {{title}} </li>
295
+ {{#if items}}
296
+ <ul class="">
297
+ {{#each items}}
298
+ <li class=""> {{this}}</li>
299
+ {{/each}}
300
+ </ul>
301
+ {{/if}}
302
+ {{/each}}
303
+ </ul>
304
+ {{/if}}
305
+ <div class="a4-container summary-section" id="pdf-content">
306
+ <h2>{{preamble.summary.heading}}</h2>
307
+ <p>{{{data.report.validator_summary}}}</p>
308
+ <table>
309
+ <thead>
310
+ <tr>
311
+ <th>#</th>
312
+ <th>Priority</th>
313
+ <th>Recommendation</th>
314
+ </tr>
315
+ </thead>
316
+ <tbody>
317
+
318
+ {{#each data.report.summary}}
319
+ <tr>
320
+ <td>{{inc @index}}</td>
321
+ <td class="status-{{status}}">{{severity}}</td>
322
+ <td><a href="#{{name}}">{{title}}
323
+ -
324
+ {{replace severity_message "%s" detailsLength}}</a>
325
+ </td>
326
+ {{!-- <td>{{detailsLength}}</td> --}}
327
+ </tr>
328
+ {{/each}}
329
+ </tbody>
330
+ </table>
331
+ <br />
332
+ {{#each data.report.summary}}
333
+ {{#if title}}
334
+ <div>
335
+ {{#if title}}
336
+ <div id="{{name}}">
337
+ <h5>{{title}}</h5>
338
+ </div>
339
+ {{/if}}
340
+ {{#if (and description docsPath)}}
341
+ <div>
342
+ {{#if description}} <p>{{description}}</p>{{/if}}
343
+ {{#if disclaimer}}
344
+ <p><strong>Disclaimer:</strong> {{disclaimer}}</p>{{/if}}
345
+ <table>
346
+ <thead>
347
+ <tr>
348
+ <th>#</th>
349
+ <th>Priority</th>
350
+ <th>Recommendation</th>
351
+ </tr>
352
+ </thead>
353
+ <tbody>
354
+ <tr>
355
+ <td>{{inc @index}}</td>
356
+ <td class="status-{{status}}">{{severity}}</td>
357
+ <td><a href="#{{name}}">{{title}}
358
+ -
359
+ {{replace
360
+ severity_message
361
+ "%s"
362
+ detailsLength
363
+ }}</a></td>
364
+ {{!-- <td>{{detailsLength}}</td> --}}
365
+ </tr>
366
+ </tbody>
367
+ </table>
368
+ {{#if details}}
369
+ <p><strong>Details:</strong></p>
370
+ <ul>
371
+ {{#each details}}
372
+ <li>
373
+ {{#if name}}Name:
374
+ <strong>{{name}}</strong>
375
+ <br />{{/if}}
376
+ {{#if attr}}<strong>Attribute: {{attr}} </strong>{{/if}}
377
+ {{#if message}}{{{message}}}{{/if}}
378
+ {{#if vulnFindings}}
379
+ <ul class="">
380
+ {{#each vulnFindings}}
381
+ <li><strong>{{description}}</strong></li>
382
+ <ul>
383
+ <li>{{advisory_summary}}</li>
384
+ <li><a
385
+ href="{{advisory_url}}"
386
+ target="_blank"
387
+ >{{advisory_url}}</a></li>
388
+ </ul>
389
+ {{/each}}
390
+ </ul>
391
+ {{/if}}
392
+ {{#if report}}
393
+ <ul>
394
+ {{#each report}}
395
+ <li>{{message}}</li>
396
+ {{/each}}
397
+ </ul>
398
+ {{/if}}
399
+ </li>
400
+ {{/each}}
401
+ </ul>
402
+ {{/if}}
403
+ {{#if pre_requisites}}
404
+ <p><strong>{{pre_requisites.title}}</strong></p>
405
+ <p>{{pre_requisites.description}}</p>
406
+ <ul class="">
407
+ {{#each pre_requisites.items}}
408
+ <li>{{this}}</li>
409
+ {{/each}}
410
+ </ul>
411
+ {{/if}}
412
+ {{#if advisory}}
413
+ <div>
414
+ {{#if advisory.issue}}
415
+ <p><strong>Advisory: {{advisory.issue}}</strong></p>
416
+ {{/if}}
417
+ {{#if advisory.description.what_it_is}}
418
+ <p><strong>What it is?</strong></p>
419
+ <p>{{advisory.description.what_it_is}}</p>
420
+ {{/if}}
421
+ {{#if advisory.description.why_its_risky}}
422
+ <p><strong>Why it's risky?</strong></p>
423
+ <ul>
424
+ {{#each advisory.description.why_its_risky}}
425
+ <li>{{this}}</li>
426
+ {{/each}}
427
+ </ul>
428
+ {{/if}}
429
+ {{#if advisory.how_to_fix}}
430
+ <p><strong>How to Fix?</strong></p>
431
+ <ul>
432
+ {{#each advisory.how_to_fix}}
433
+ <li>{{this}}</li>
434
+ {{/each}}
435
+ </ul>
436
+ {{/if}}
437
+ {{#if advisory.top_risks}}
438
+ <p><strong>Top Risks</strong></p>
439
+ {{#each advisory.top_risks}}
440
+ <div class="mt-3">
441
+ <p><strong>{{name}}</strong></p>
442
+ <p><strong>What it is:</strong> {{what_it_is}}</p>
443
+ <p><strong>Why it's risky:</strong>
444
+ {{why_its_risky}}</p>
445
+ <p><strong>How to fix:</strong> {{how_to_fix}}</p>
446
+ </div>
447
+ {{/each}}
448
+ {{/if}}
449
+ {{#if advisory.best_practices}}
450
+ <p><strong>Best Practices</strong></p>
451
+ <ul>
452
+ {{#each advisory.best_practices}}
453
+ <li><strong>{{@key}}:</strong> {{this}}</li>
454
+ {{/each}}
455
+ </ul>
456
+ {{/if}}
457
+ </div>
458
+ {{/if}}
459
+ {{#if docsPath}}<p><strong>Resources:</strong>
460
+ <ul>
461
+ {{#each docsPath}}
462
+
463
+ <li>
464
+ <a target="_blank" href="{{this}}">{{this}}</a>
465
+
466
+ </li>
467
+ {{/each}}
468
+ </ul>
469
+ </p>{{/if}}
470
+ </div>
471
+ {{/if}}
472
+ </div>
473
+ {{/if}}
474
+ {{/each}}
475
+ {{#if data.securityCenter}}
476
+ <h2>Threat Behavior Charts</h2>
477
+
478
+ <h4>Threat Behavior</h4>
479
+ <canvas id="threatBehaviorLineChart" class="a4-portrait"></canvas>
480
+
481
+ <h4>Breached Password Detection</h4>
482
+ <canvas id="breachedCredentialsLineChart" class="a4-portrait"></canvas>
483
+
484
+ <h4>Signup Attempts</h4>
485
+ <canvas id="signupAttemptsLineChart" class="a4-portrait"></canvas>
486
+
487
+ <h4>Login Attempts</h4>
488
+ <canvas id="loginAttemptsLineChart" class="a4-portrait"></canvas>
489
+
490
+ <h4>Brute Force</h4>
491
+ <canvas id="bruteForceLineChart" class="a4-portrait"></canvas>
492
+
493
+ <h4>Suspicious IP Throttling</h4>
494
+ <canvas id="suspiciousIpLineChart" class="a4-portrait"></canvas>
495
+
496
+ <h4>Bot Detection</h4>
497
+ <canvas id="botDetectionLineChart" class="a4-portrait"></canvas>
498
+
499
+ <h4>MFA Challenge</h4>
500
+ <canvas id="mfaChallengeLineChart" class="a4-portrait"></canvas>
501
+
502
+ <h4>MFA Success Rate</h4>
503
+ <canvas id="mfaSuccessRateLineChart" class="a4-portrait"></canvas>
504
+
505
+ <script>
506
+ const data =
507
+ {{{escapeJSON data.securityCenter}}}; function
508
+ generateRGBAColorBasedOnIndex(index) { // Use index-based math to
509
+ create RGB values const r = (index * 50) % 256; // Red component const
510
+ g = (index * 100 + 50) % 256; // Green component with an offset const
511
+ b = (index * 150 + 100) % 256; // Blue component with an offset const
512
+ alpha = 0.8; // Set a fixed alpha value for transparency return
513
+ `rgba(${r}, ${g}, ${b}, ${alpha})`; // Return the RGBA color }
514
+ function generateChart(ctx, chartData, label, backgroundColor) { //
515
+ Extract labels (dates) and values const groupedData = {};
516
+ chartData.forEach(item => { const groupName =
517
+ data.eventGroupIdToDisplayName[item.group] || `Group ${item.group}`;
518
+ if (!groupedData[groupName]) { groupedData[groupName] = []; }
519
+ groupedData[groupName].push({ date: new Date(item.date), value:
520
+ item.value }); }); // Step 2: Prepare data for Chart.js const labels =
521
+ [...new Set(chartData.map(item => new
522
+ Date(item.date).toLocaleDateString('en-GB', { day: '2-digit', month:
523
+ '2-digit', year: 'numeric', hour: '2-digit', minute: '2-digit' })))];
524
+ const datasets = Object.keys(groupedData).map((groupName, index) => {
525
+ return { label: groupName, // Line name (group name) data:
526
+ groupedData[groupName].map(item => item.value), borderColor:
527
+ generateRGBAColorBasedOnIndex(index), backgroundColor:
528
+ generateRGBAColorBasedOnIndex(index), fill: false, // Line only, no
529
+ area fill tension: 0.4 // Smooth curves }; }); // Chart.js
530
+ configuration new Chart(ctx, { type: 'line', data: { labels: labels,
531
+ datasets: datasets }, options: { responsive: true, plugins: { title: {
532
+ display: true, text: `${label} Last 7 Days` } }, scales: { x: { title:
533
+ { display: true, text: 'Date (DD-MM-YYYY HH:MM)' }, grid: { display:
534
+ false // Hide vertical grid lines } }, y: { title: { display: false,
535
+ text: 'Values' }, beginAtZero: true, grid: { drawBorder: true, //
536
+ Keeps the outer border color: 'rgba(200, 200, 200, 0.3)' // Optional:
537
+ customize horizontal grid line color } } } } }); } // Generating all
538
+ charts breachedCredentialsLineChart
539
+ generateChart(document.getElementById('threatBehaviorLineChart').getContext('2d'),
540
+ data.threatBehaviorLineChart.data, 'Threat Behavior', 'rgba(255, 99,
541
+ 132, 0.5)');
542
+ generateChart(document.getElementById('breachedCredentialsLineChart').getContext('2d'),
543
+ data.breachedCredentialsLineChart.data, 'Breached Password Detection',
544
+ 'rgba(54, 162, 235, 0.5)');
545
+ generateChart(document.getElementById('signupAttemptsLineChart').getContext('2d'),
546
+ data.signupAttemptsLineChart.data, 'Signup Attempts', 'rgba(54, 162,
547
+ 235, 0.5)');
548
+ generateChart(document.getElementById('loginAttemptsLineChart').getContext('2d'),
549
+ data.loginAttemptsLineChart.data, 'Login Attempts', 'rgba(75, 192,
550
+ 192, 0.5)');
551
+ generateChart(document.getElementById('bruteForceLineChart').getContext('2d'),
552
+ data.bruteForceLineChart.data, 'Brute Force Attempts', 'rgba(255, 206,
553
+ 86, 0.5)');
554
+ generateChart(document.getElementById('suspiciousIpLineChart').getContext('2d'),
555
+ data.suspiciousIpLineChart.data, 'Suspicious IP activities',
556
+ 'rgba(255, 206, 86, 0.5)');
557
+ generateChart(document.getElementById('botDetectionLineChart').getContext('2d'),
558
+ data.botDetectionLineChart.data, 'Bots Detected', 'rgba(153, 102, 255,
559
+ 0.5)');
560
+ generateChart(document.getElementById('mfaChallengeLineChart').getContext('2d'),
561
+ data.mfaChallengeLineChart.data, 'MFA Challenges', 'rgba(255, 159, 64,
562
+ 0.5)');
563
+ generateChart(document.getElementById('mfaSuccessRateLineChart').getContext('2d'),
564
+ data.mfaSuccessRateLineChart.data, 'MFA Success Rate', 'rgba(255, 99,
565
+ 132, 0.5)');
566
+ </script>
567
+ {{/if}}
568
+ </div>
569
+ </body>
570
+
571
+ </html>