@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,181 @@
1
+ const { expect } = require("chai");
2
+ const checkBruteForce = require("../../analyzer/lib/attack_protection/checkBruteForce");
3
+ const CONSTANTS = require("../../analyzer/lib/constants");
4
+
5
+ describe("checkBruteForce", function () {
6
+ it("should return success when brute force protection is enabled and correctly configured", function () {
7
+ const options = {
8
+ attackProtection: {
9
+ bruteForceProtection: {
10
+ enabled: true,
11
+ shields: ["block", "user_notification"],
12
+ mode: "count_per_identifier_and_ip",
13
+ allowlist: [],
14
+ max_attempts: 3,
15
+ },
16
+ },
17
+ };
18
+
19
+ checkBruteForce(options, (report) => {
20
+ // Check if the report contains expected success statuses
21
+ expect(report).to.deep.include({
22
+ field: "enabled",
23
+ status: CONSTANTS.SUCCESS,
24
+ });
25
+ expect(report).to.deep.include({
26
+ field: "shieldsConfigured",
27
+ status: CONSTANTS.SUCCESS,
28
+ });
29
+ expect(report).to.deep.include({
30
+ field: "allowlistEmpty",
31
+ status: CONSTANTS.SUCCESS,
32
+ });
33
+ expect(report).to.deep.include({
34
+ field: "stageMaxAttempts",
35
+ status: CONSTANTS.SUCCESS,
36
+ value: 3,
37
+ });
38
+ });
39
+ });
40
+
41
+ it("should return failure when brute force protection is disabled", function () {
42
+ const options = {
43
+ attackProtection: {
44
+ bruteForceProtection: {
45
+ enabled: false,
46
+ shields: ["block"],
47
+ mode: "count_per_identifier_and_ip",
48
+ allowlist: [],
49
+ max_attempts: 3,
50
+ },
51
+ },
52
+ };
53
+
54
+ checkBruteForce(options, (report) => {
55
+ expect(report).to.deep.include({
56
+ field: "disabled",
57
+ status: CONSTANTS.FAIL,
58
+ });
59
+ });
60
+ });
61
+
62
+ it("should return failure when shields have missing values", function () {
63
+ const options = {
64
+ attackProtection: {
65
+ bruteForceProtection: {
66
+ enabled: true,
67
+ shields: ["block"], // Missing "user_notification"
68
+ mode: "count_per_identifier_and_ip",
69
+ allowlist: [],
70
+ max_attempts: 3,
71
+ },
72
+ },
73
+ };
74
+
75
+ checkBruteForce(options, (report) => {
76
+ expect(report).to.deep.include({
77
+ field: "shieldsMissing",
78
+ status: CONSTANTS.FAIL,
79
+ value: "user_notification",
80
+ });
81
+ });
82
+ });
83
+
84
+ it("should return failure when allowlist is not empty", function () {
85
+ const options = {
86
+ attackProtection: {
87
+ bruteForceProtection: {
88
+ enabled: true,
89
+ shields: ["block", "user_notification"],
90
+ mode: "count_per_identifier_and_ip",
91
+ allowlist: ["127.0.0.1"],
92
+ max_attempts: 3,
93
+ },
94
+ },
95
+ };
96
+
97
+ checkBruteForce(options, (report) => {
98
+ expect(report).to.deep.include({
99
+ field: "allowlistPresent",
100
+ status: CONSTANTS.FAIL,
101
+ value: "127.0.0.1",
102
+ });
103
+ });
104
+ });
105
+
106
+ it("should return failure when max_attempts is less than or equal to 0", function () {
107
+ const options = {
108
+ attackProtection: {
109
+ bruteForceProtection: {
110
+ enabled: true,
111
+ shields: ["block", "user_notification"],
112
+ mode: "count_per_identifier_and_ip",
113
+ allowlist: [],
114
+ max_attempts: 0, // Invalid value
115
+ },
116
+ },
117
+ };
118
+
119
+ checkBruteForce(options, (report) => {
120
+ expect(report).to.deep.include({
121
+ field: "stageMaxAttemptsInvalid",
122
+ status: CONSTANTS.FAIL,
123
+ value: 0,
124
+ });
125
+ });
126
+ });
127
+
128
+ it("should return failure when rate is less than or equal to 0", function () {
129
+ const options = {
130
+ attackProtection: {
131
+ bruteForceProtection: {
132
+ enabled: true,
133
+ shields: ["block", "user_notification"],
134
+ mode: "count_per_identifier_and_ip",
135
+ allowlist: [],
136
+ max_attempts: 3,
137
+ stage: {
138
+ "pre-user-registration": {
139
+ rate: 0, // Invalid value
140
+ },
141
+ },
142
+ },
143
+ },
144
+ };
145
+
146
+ checkBruteForce(options, (report) => {
147
+ expect(report).to.deep.include({
148
+ field: "stageRateInvalid",
149
+ status: CONSTANTS.FAIL,
150
+ value: 0,
151
+ });
152
+ });
153
+ });
154
+
155
+ it("should return success when rate is valid", function () {
156
+ const options = {
157
+ attackProtection: {
158
+ bruteForceProtection: {
159
+ enabled: true,
160
+ shields: ["block", "user_notification"],
161
+ mode: "count_per_identifier_and_ip",
162
+ allowlist: [],
163
+ max_attempts: 3,
164
+ stage: {
165
+ "pre-user-registration": {
166
+ rate: 5, // Valid value
167
+ },
168
+ },
169
+ },
170
+ },
171
+ };
172
+
173
+ checkBruteForce(options, (report) => {
174
+ expect(report).to.deep.include({
175
+ field: "stageRate",
176
+ status: CONSTANTS.SUCCESS,
177
+ value: 5,
178
+ });
179
+ });
180
+ });
181
+ });
@@ -0,0 +1,222 @@
1
+ const { expect } = require("chai");
2
+ const checkSuspiciousIPThrottling = require("../../analyzer/lib/attack_protection/checkSuspiciousIPThrottling");
3
+ const CONSTANTS = require("../../analyzer/lib/constants");
4
+
5
+ describe("checkSuspiciousIPThrottling", function () {
6
+ it("should return success when suspicious IP throttling is enabled and correctly configured", function () {
7
+ const options = {
8
+ attackProtection: {
9
+ suspiciousIpThrottling: {
10
+ enabled: true,
11
+ shields: ["admin_notification", "block"],
12
+ allowlist: [],
13
+ stage: {
14
+ "pre-login": {
15
+ max_attempts: 100,
16
+ rate: 864000,
17
+ },
18
+ "pre-user-registration": {
19
+ max_attempts: 50,
20
+ rate: 1200,
21
+ },
22
+ },
23
+ },
24
+ },
25
+ };
26
+
27
+ checkSuspiciousIPThrottling(options, (report) => {
28
+ // Check if the report contains expected success statuses
29
+ expect(report).to.deep.include({
30
+ field: "enabled",
31
+ status: CONSTANTS.SUCCESS,
32
+ });
33
+ expect(report).to.deep.include({
34
+ field: "shieldsConfigured",
35
+ status: CONSTANTS.SUCCESS,
36
+ });
37
+ expect(report).to.deep.include({
38
+ field: "allowlistEmpty",
39
+ status: CONSTANTS.SUCCESS,
40
+ });
41
+ });
42
+ });
43
+
44
+ it("should return failure when suspicious IP throttling is disabled", function () {
45
+ const options = {
46
+ attackProtection: {
47
+ suspiciousIpThrottling: {
48
+ enabled: false,
49
+ shields: ["block"],
50
+ allowlist: [],
51
+ stage: {
52
+ "pre-login": {
53
+ max_attempts: 100,
54
+ rate: 864000,
55
+ },
56
+ "pre-user-registration": {
57
+ max_attempts: 50,
58
+ rate: 1200,
59
+ },
60
+ },
61
+ },
62
+ },
63
+ };
64
+
65
+ checkSuspiciousIPThrottling(options, (report) => {
66
+ expect(report).to.deep.include({
67
+ field: "disabled",
68
+ status: CONSTANTS.FAIL,
69
+ });
70
+ });
71
+ });
72
+
73
+ it("should return failure when shields are missing values", function () {
74
+ const options = {
75
+ attackProtection: {
76
+ suspiciousIpThrottling: {
77
+ enabled: true,
78
+ shields: ["block"], // Missing "admin_notification"
79
+ allowlist: [],
80
+ stage: {
81
+ "pre-login": {
82
+ max_attempts: 100,
83
+ rate: 864000,
84
+ },
85
+ "pre-user-registration": {
86
+ max_attempts: 50,
87
+ rate: 1200,
88
+ },
89
+ },
90
+ },
91
+ },
92
+ };
93
+
94
+ checkSuspiciousIPThrottling(options, (report) => {
95
+ expect(report).to.deep.include({
96
+ field: "shieldsMissing",
97
+ status: CONSTANTS.FAIL,
98
+ value: "admin_notification",
99
+ });
100
+ });
101
+ });
102
+
103
+ it("should return failure when allowlist is not empty", function () {
104
+ const options = {
105
+ attackProtection: {
106
+ suspiciousIpThrottling: {
107
+ enabled: true,
108
+ shields: ["block", "admin_notification"],
109
+ allowlist: ["192.168.0.1"],
110
+ stage: {
111
+ "pre-login": {
112
+ max_attempts: 100,
113
+ rate: 864000,
114
+ },
115
+ "pre-user-registration": {
116
+ max_attempts: 50,
117
+ rate: 1200,
118
+ },
119
+ },
120
+ },
121
+ },
122
+ };
123
+
124
+ checkSuspiciousIPThrottling(options, (report) => {
125
+ expect(report).to.deep.include({
126
+ field: "allowlistPresent",
127
+ status: CONSTANTS.FAIL,
128
+ value: "192.168.0.1",
129
+ });
130
+ });
131
+ });
132
+
133
+ it("should return failure when max_attempts is less than or equal to 0", function () {
134
+ const options = {
135
+ attackProtection: {
136
+ suspiciousIpThrottling: {
137
+ enabled: true,
138
+ shields: ["block", "admin_notification"],
139
+ allowlist: [],
140
+ stage: {
141
+ "pre-login": {
142
+ max_attempts: 0, // Invalid value
143
+ rate: 864000,
144
+ },
145
+ "pre-user-registration": {
146
+ max_attempts: 50,
147
+ rate: 1200,
148
+ },
149
+ },
150
+ },
151
+ },
152
+ };
153
+
154
+ checkSuspiciousIPThrottling(options, (report) => {
155
+ expect(report).to.deep.include({
156
+ field: "stageMaxAttemptsInvalid",
157
+ status: CONSTANTS.FAIL,
158
+ value: 0,
159
+ });
160
+ });
161
+ });
162
+
163
+ it("should return failure when rate is less than or equal to 0", function () {
164
+ const options = {
165
+ attackProtection: {
166
+ suspiciousIpThrottling: {
167
+ enabled: true,
168
+ shields: ["block", "admin_notification"],
169
+ allowlist: [],
170
+ stage: {
171
+ "pre-login": {
172
+ max_attempts: 100,
173
+ rate: 0, // Invalid value
174
+ },
175
+ "pre-user-registration": {
176
+ max_attempts: 50,
177
+ rate: 1200,
178
+ },
179
+ },
180
+ },
181
+ },
182
+ };
183
+
184
+ checkSuspiciousIPThrottling(options, (report) => {
185
+ expect(report).to.deep.include({
186
+ field: "stageRateInvalid",
187
+ status: CONSTANTS.FAIL,
188
+ value: 0,
189
+ });
190
+ });
191
+ });
192
+
193
+ it("should return success when rate is valid", function () {
194
+ const options = {
195
+ attackProtection: {
196
+ suspiciousIpThrottling: {
197
+ enabled: true,
198
+ shields: ["block", "admin_notification"],
199
+ allowlist: [],
200
+ stage: {
201
+ "pre-login": {
202
+ max_attempts: 100,
203
+ rate: 864000, // Valid value
204
+ },
205
+ "pre-user-registration": {
206
+ max_attempts: 50,
207
+ rate: 1200,
208
+ },
209
+ },
210
+ },
211
+ },
212
+ };
213
+
214
+ checkSuspiciousIPThrottling(options, (report) => {
215
+ expect(report).to.deep.include({
216
+ field: "stageRate",
217
+ status: CONSTANTS.SUCCESS,
218
+ value: 864000,
219
+ });
220
+ });
221
+ });
222
+ });
@@ -0,0 +1,94 @@
1
+ const chai = require("chai");
2
+ const expect = chai.expect;
3
+ const checkCanonicalDomain = require("../../analyzer/lib/canonical_domain/checkCanonicalDomain");
4
+ const CONSTANTS = require("../../analyzer/lib/constants");
5
+
6
+ describe("checkCanonicalDomain", function () {
7
+ it("should add the hostname to report if logs are not empty but customDomains is empty", function () {
8
+ const options = {
9
+ customDomains: [], // Empty customDomains
10
+ logs: [
11
+ {
12
+ type: "s",
13
+ hostname: "contoso.us.auth0.com",
14
+ _id: "90020250210004837491441000000000000001223372036874609060",
15
+ },
16
+ ],
17
+ };
18
+
19
+ checkCanonicalDomain(options, (report) => {
20
+ // Check that the report contains the hostname from logs
21
+ expect(report).to.have.lengthOf(1);
22
+ expect(report[0].field).to.equal("canonical_domain_used");
23
+ expect(report[0].value).to.equal(
24
+ "log_id: 90020250210004837491441000000000000001223372036874609060",
25
+ );
26
+ expect(report[0].status).to.equal(CONSTANTS.FAIL);
27
+ });
28
+ });
29
+
30
+ it("should add the hostname to report if no match is found in customDomains", function () {
31
+ const options = {
32
+ customDomains: [
33
+ {
34
+ domain: "different.com",
35
+ primary: true,
36
+ status: "ready",
37
+ tls_policy: "recommended",
38
+ type: "auth0_managed_certs",
39
+ verification: {},
40
+ },
41
+ ], // Custom domain is different
42
+ logs: [
43
+ {
44
+ type: "s",
45
+ hostname: "contoso.us.auth0.com",
46
+ _id: "90020250210004837491441000000000000001223372036874609060",
47
+ },
48
+ ],
49
+ };
50
+
51
+ checkCanonicalDomain(options, (report) => {
52
+ // Check that the report contains the hostname from logs because there is no match
53
+ expect(report).to.have.lengthOf(1);
54
+ expect(report[0].field).to.equal("canonical_domain_used");
55
+ expect(report[0].value).to.equal(
56
+ "log_id: 90020250210004837491441000000000000001223372036874609060",
57
+ );
58
+ expect(report[0].status).to.equal(CONSTANTS.FAIL);
59
+ });
60
+ });
61
+
62
+ it("should return an empty report if logs are empty", function () {
63
+ const options = {
64
+ customDomains: [
65
+ {
66
+ domain: "contoso.com",
67
+ primary: true,
68
+ status: "ready",
69
+ tls_policy: "recommended",
70
+ type: "auth0_managed_certs",
71
+ verification: {},
72
+ },
73
+ ],
74
+ logs: [], // No logs
75
+ };
76
+
77
+ checkCanonicalDomain(options, (report) => {
78
+ // Check that the report is empty
79
+ expect(report).to.be.an("array").that.is.empty;
80
+ });
81
+ });
82
+
83
+ it("should not add anything to the report if customDomains are empty and no logs exist", function () {
84
+ const options = {
85
+ customDomains: [], // No custom domains
86
+ logs: [], // No logs
87
+ };
88
+
89
+ checkCanonicalDomain(options, (report) => {
90
+ // Check that the report is empty
91
+ expect(report).to.be.an("array").that.is.empty;
92
+ });
93
+ });
94
+ });
@@ -0,0 +1,149 @@
1
+ const chai = require("chai");
2
+ const expect = chai.expect;
3
+
4
+ const checkAllowedCallbacks = require("../../analyzer/lib/clients/checkAllowedCallbacks");
5
+ const CONSTANTS = require("../../analyzer/lib/constants");
6
+
7
+ describe("checkAllowedCallbacks", function () {
8
+ it("should return an empty report when there are no clients", function () {
9
+ const options = {
10
+ clients: [], // No clients
11
+ };
12
+
13
+ checkAllowedCallbacks(options, (reports) => {
14
+ expect(reports).to.deep.equal([]); // No reports expected
15
+ });
16
+ });
17
+
18
+ it("should return a fail report when client has no callbacks and app_type is not non_interactive", function () {
19
+ const options = {
20
+ clients: [
21
+ {
22
+ name: "Test App",
23
+ client_id: "client_id",
24
+ app_type: "spa", // Not non_interactive
25
+ callbacks: [], // No callbacks
26
+ },
27
+ ],
28
+ };
29
+
30
+ checkAllowedCallbacks(options, (reports) => {
31
+ expect(reports).to.deep.equal([
32
+ {
33
+ name: "Test App",
34
+ report: [
35
+ {
36
+ name: "Test App",
37
+ client_id: "client_id",
38
+ field: "missing_callbacks",
39
+ url: "",
40
+ status: CONSTANTS.FAIL,
41
+ app_type: "spa",
42
+ },
43
+ ],
44
+ },
45
+ ]);
46
+ });
47
+ });
48
+
49
+ it("should return a fail report when client has insecure callbacks (http://localhost)", function () {
50
+ const options = {
51
+ clients: [
52
+ {
53
+ name: "Test App",
54
+ client_id: "client_id",
55
+ callbacks: ["http://localhost:3000"], // Insecure callback URL
56
+ app_type: "spa",
57
+ },
58
+ ],
59
+ };
60
+
61
+ checkAllowedCallbacks(options, (reports) => {
62
+ expect(reports).to.deep.equal([
63
+ {
64
+ name: "Test App",
65
+ report: [
66
+ {
67
+ name: "Test App",
68
+ client_id: "client_id",
69
+ field: "insecure_callbacks",
70
+ url: "http://localhost:3000",
71
+ status: CONSTANTS.FAIL,
72
+ app_type: "spa",
73
+ },
74
+ ],
75
+ },
76
+ ]);
77
+ });
78
+ });
79
+
80
+ it("should return a success report when client has secure callbacks (https://contoso.com)", function () {
81
+ const options = {
82
+ clients: [
83
+ {
84
+ name: "Test App",
85
+ client_id: "client_id",
86
+ callbacks: ["https://contoso.com"], // Secure callback URL
87
+ app_type: "spa",
88
+ },
89
+ ],
90
+ };
91
+
92
+ checkAllowedCallbacks(options, (reports) => {
93
+ expect(reports).to.deep.equal([
94
+ {
95
+ name: "Test App",
96
+ report: [
97
+ {
98
+ name: "Test App",
99
+ client_id: "client_id",
100
+ field: "secure_callbacks",
101
+ status: CONSTANTS.SUCCESS,
102
+ url: "https://contoso.com",
103
+ app_type: "spa",
104
+ },
105
+ ],
106
+ },
107
+ ]);
108
+ });
109
+ });
110
+
111
+ it("should return both fail and success reports when client has both insecure and secure callbacks", function () {
112
+ const options = {
113
+ clients: [
114
+ {
115
+ name: "Test App",
116
+ client_id: "client_id",
117
+ callbacks: ["http://localhost:3000", "https://contoso.com"], // Mix of insecure and secure URLs
118
+ app_type: "spa",
119
+ },
120
+ ],
121
+ };
122
+
123
+ checkAllowedCallbacks(options, (reports) => {
124
+ expect(reports).to.deep.equal([
125
+ {
126
+ name: "Test App",
127
+ report: [
128
+ {
129
+ name: "Test App",
130
+ client_id: "client_id",
131
+ field: "insecure_callbacks",
132
+ url: "http://localhost:3000",
133
+ status: CONSTANTS.FAIL,
134
+ app_type: "spa",
135
+ },
136
+ {
137
+ name: "Test App",
138
+ client_id: "client_id",
139
+ field: "secure_callbacks",
140
+ status: CONSTANTS.SUCCESS,
141
+ url: "https://contoso.com",
142
+ app_type: "spa",
143
+ },
144
+ ],
145
+ },
146
+ ]);
147
+ });
148
+ });
149
+ });