@oneuptime/common 12.0.14 → 12.0.15

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 (195) hide show
  1. package/Models/DatabaseModels/GlobalOidc.ts +20 -0
  2. package/Models/DatabaseModels/GlobalSso.ts +20 -0
  3. package/Models/DatabaseModels/MarketingConversion.ts +19 -9
  4. package/Models/DatabaseModels/NetworkDeviceLinkRule.ts +46 -0
  5. package/Models/DatabaseModels/StatusPage.ts +7 -4
  6. package/Server/API/StatusPageAPI.ts +29 -4
  7. package/Server/EnvironmentConfig.ts +7 -0
  8. package/Server/Infrastructure/Postgres/SchemaMigrations/1787800000000-AddScopeToNetworkDeviceLinkRule.ts +19 -0
  9. package/Server/Infrastructure/Postgres/SchemaMigrations/1787900000000-AddRestrictToAttachedProjectsToGlobalSso.ts +40 -0
  10. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +4 -0
  11. package/Server/Middleware/SlackAuthorization.ts +43 -6
  12. package/Server/Middleware/UserAuthorization.ts +236 -26
  13. package/Server/Middleware/WhatsAppAuthorization.ts +43 -3
  14. package/Server/Services/GlobalOidcProjectService.ts +126 -1
  15. package/Server/Services/GlobalOidcService.ts +132 -0
  16. package/Server/Services/GlobalSsoProjectService.ts +126 -1
  17. package/Server/Services/GlobalSsoService.ts +132 -0
  18. package/Server/Services/UserEmailService.ts +4 -4
  19. package/Server/Utils/CronTab.ts +73 -0
  20. package/Server/Utils/GlobalSsoAuthorization.ts +175 -0
  21. package/Server/Utils/Marketing/ConversionUploadProvider.ts +35 -5
  22. package/Server/Utils/Marketing/Providers/GoogleAds.ts +1 -1
  23. package/Server/Utils/Marketing/Providers/LinkedIn.ts +1 -1
  24. package/Server/Utils/Marketing/Providers/Meta.ts +1 -1
  25. package/Server/Utils/Marketing/Providers/MicrosoftAds.ts +1 -1
  26. package/Server/Utils/Marketing/Providers/Reddit.ts +1 -1
  27. package/Server/Utils/Monitor/Criteria/APIRequestCriteria.ts +48 -33
  28. package/Server/Utils/Monitor/Criteria/DnsMonitorCriteria.ts +35 -30
  29. package/Server/Utils/Monitor/Criteria/DomainMonitorCriteria.ts +33 -28
  30. package/Server/Utils/Monitor/Criteria/EvaluateOverTime.ts +475 -47
  31. package/Server/Utils/Monitor/Criteria/ExternalStatusPageMonitorCriteria.ts +35 -30
  32. package/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.ts +34 -28
  33. package/Server/Utils/Monitor/Criteria/SSLMonitorCriteria.ts +33 -28
  34. package/Server/Utils/Monitor/Criteria/ServerMonitorCriteria.ts +69 -40
  35. package/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.ts +35 -29
  36. package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +8 -0
  37. package/Server/Utils/Monitor/MonitorResource.ts +161 -21
  38. package/Server/Utils/StatusPageContentSecurityPolicy.ts +56 -0
  39. package/Server/Utils/StatusPageCustomizationAccess.ts +117 -0
  40. package/Tests/Server/API/StatusPageCustomizationOrigin.test.ts +348 -0
  41. package/Tests/Server/Infrastructure/Postgres/FixTotpOtpUrlAlgorithmMigration.test.ts +9 -59
  42. package/Tests/Server/Infrastructure/Postgres/SchemaMigrationsOrdering.test.ts +227 -0
  43. package/Tests/Server/Middleware/SlackAuthorization.test.ts +149 -0
  44. package/Tests/Server/Middleware/UserAuthorization.test.ts +27 -13
  45. package/Tests/Server/Middleware/UserAuthorizationGlobalSsoGovernance.test.ts +1455 -0
  46. package/Tests/Server/Middleware/UserAuthorizationSSOProvider.test.ts +91 -2
  47. package/Tests/Server/Middleware/WhatsAppAuthorization.test.ts +233 -0
  48. package/Tests/Server/Services/DiscoveryScanClaimHookFreeSafety.test.ts +21 -8
  49. package/Tests/Server/Services/GlobalSsoProviderAuthorization.test.ts +1242 -0
  50. package/Tests/Server/Services/MonitorResourceProbeAgreementHydration.test.ts +459 -0
  51. package/Tests/Server/Services/MonitorResourceProbeAgreementReuse.test.ts +10 -0
  52. package/Tests/Server/Types/AnalyticsDatabase/AggregateUtilBucketTimestamp.test.ts +416 -0
  53. package/Tests/Server/Types/Database/QueryHelperManyToManyAndEmptyValues.test.ts +551 -0
  54. package/Tests/Server/Types/Database/SelectUtil.test.ts +348 -0
  55. package/Tests/Server/Utils/CronTab.test.ts +116 -0
  56. package/Tests/Server/Utils/GlobalSSOToken.test.ts +581 -0
  57. package/Tests/Server/Utils/GlobalSsoAuthorization.test.ts +1401 -0
  58. package/Tests/Server/Utils/Marketing/AdUploadableConversionTypes.test.ts +254 -0
  59. package/Tests/Server/Utils/Marketing/ConversionUploadProvider.test.ts +1 -1
  60. package/Tests/Server/Utils/Monitor/Criteria/APIRequestCriteriaEvaluateOverTime.test.ts +508 -0
  61. package/Tests/Server/Utils/Monitor/Criteria/APIRequestCriteriaPortTimings.test.ts +30 -9
  62. package/Tests/Server/Utils/Monitor/Criteria/EvaluateOverTime.test.ts +987 -0
  63. package/Tests/Server/Utils/Monitor/Criteria/ExternalStatusPageMonitorCriteria.test.ts +916 -0
  64. package/Tests/Server/Utils/Monitor/Criteria/ProfileMonitorCriteria.test.ts +382 -0
  65. package/Tests/Server/Utils/Monitor/Criteria/ServerMonitorCriteria.test.ts +1219 -0
  66. package/Tests/Server/Utils/Monitor/MonitorResourceIngestedStepSelection.test.ts +86 -0
  67. package/Tests/Server/Utils/StatusPageContentSecurityPolicy.test.ts +136 -0
  68. package/Tests/Server/Utils/StatusPageCustomizationAccess.test.ts +223 -0
  69. package/Tests/Types/Monitor/MonitorStepConfigHelpers.test.ts +165 -0
  70. package/Tests/Types/NetworkDevice/NetworkDeviceLinkRuleScope.test.ts +215 -0
  71. package/Tests/UI/Components/Forms/FormSubmitAnalytics.test.tsx +206 -0
  72. package/Tests/UI/Utils/AIChatExport/ConversationMarkdown.test.ts +774 -0
  73. package/Tests/UI/Utils/AIChatExport/MarkdownBlocks.test.ts +791 -0
  74. package/Tests/UI/Utils/AIChatExport/MarkdownSafety.test.ts +544 -0
  75. package/Tests/Utils/Analytics.test.ts +187 -0
  76. package/Tests/Utils/Monitor/MonitorMetricType.test.ts +80 -0
  77. package/Tests/Utils/Monitor/NetworkDeviceLinkRuleUtil.test.ts +1291 -0
  78. package/Tests/Utils/NetworkDiscovery/UnclaimedScanDiagnosis.test.ts +214 -0
  79. package/Types/Marketing/MarketingConversion.ts +12 -0
  80. package/Types/Monitor/CriteriaFilter.ts +9 -0
  81. package/Types/NetworkDevice/NetworkDeviceLinkRuleScope.ts +51 -0
  82. package/UI/Components/FormModal/BasicFormModal.tsx +12 -0
  83. package/UI/Components/Forms/BasicForm.tsx +13 -1
  84. package/UI/Components/Forms/BasicModelForm.tsx +2 -1
  85. package/UI/Components/Forms/ModelForm.tsx +10 -1
  86. package/UI/Components/Forms/Utils/FormAnalyticsName.ts +39 -0
  87. package/UI/Components/ModelFormModal/ModelFormModal.tsx +6 -1
  88. package/Utils/Analytics.ts +55 -2
  89. package/Utils/Monitor/MonitorMetricType.ts +40 -0
  90. package/Utils/Monitor/NetworkDeviceLinkRuleUtil.ts +587 -37
  91. package/Utils/NetworkDiscovery/UnclaimedScanDiagnosis.ts +115 -0
  92. package/build/dist/Models/DatabaseModels/GlobalOidc.js +21 -0
  93. package/build/dist/Models/DatabaseModels/GlobalOidc.js.map +1 -1
  94. package/build/dist/Models/DatabaseModels/GlobalSso.js +21 -0
  95. package/build/dist/Models/DatabaseModels/GlobalSso.js.map +1 -1
  96. package/build/dist/Models/DatabaseModels/MarketingConversion.js +20 -10
  97. package/build/dist/Models/DatabaseModels/MarketingConversion.js.map +1 -1
  98. package/build/dist/Models/DatabaseModels/NetworkDeviceLinkRule.js +47 -0
  99. package/build/dist/Models/DatabaseModels/NetworkDeviceLinkRule.js.map +1 -1
  100. package/build/dist/Models/DatabaseModels/StatusPage.js +4 -4
  101. package/build/dist/Models/DatabaseModels/StatusPage.js.map +1 -1
  102. package/build/dist/Server/API/StatusPageAPI.js +25 -4
  103. package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
  104. package/build/dist/Server/EnvironmentConfig.js +6 -0
  105. package/build/dist/Server/EnvironmentConfig.js.map +1 -1
  106. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787800000000-AddScopeToNetworkDeviceLinkRule.js +12 -0
  107. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787800000000-AddScopeToNetworkDeviceLinkRule.js.map +1 -0
  108. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787900000000-AddRestrictToAttachedProjectsToGlobalSso.js +29 -0
  109. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787900000000-AddRestrictToAttachedProjectsToGlobalSso.js.map +1 -0
  110. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +4 -0
  111. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  112. package/build/dist/Server/Middleware/SlackAuthorization.js +28 -4
  113. package/build/dist/Server/Middleware/SlackAuthorization.js.map +1 -1
  114. package/build/dist/Server/Middleware/UserAuthorization.js +197 -22
  115. package/build/dist/Server/Middleware/UserAuthorization.js.map +1 -1
  116. package/build/dist/Server/Middleware/WhatsAppAuthorization.js +32 -2
  117. package/build/dist/Server/Middleware/WhatsAppAuthorization.js.map +1 -1
  118. package/build/dist/Server/Services/GlobalOidcProjectService.js +105 -0
  119. package/build/dist/Server/Services/GlobalOidcProjectService.js.map +1 -1
  120. package/build/dist/Server/Services/GlobalOidcService.js +127 -0
  121. package/build/dist/Server/Services/GlobalOidcService.js.map +1 -1
  122. package/build/dist/Server/Services/GlobalSsoProjectService.js +105 -0
  123. package/build/dist/Server/Services/GlobalSsoProjectService.js.map +1 -1
  124. package/build/dist/Server/Services/GlobalSsoService.js +127 -0
  125. package/build/dist/Server/Services/GlobalSsoService.js.map +1 -1
  126. package/build/dist/Server/Services/UserEmailService.js +4 -4
  127. package/build/dist/Server/Utils/CronTab.js +66 -0
  128. package/build/dist/Server/Utils/CronTab.js.map +1 -1
  129. package/build/dist/Server/Utils/GlobalSsoAuthorization.js +112 -0
  130. package/build/dist/Server/Utils/GlobalSsoAuthorization.js.map +1 -0
  131. package/build/dist/Server/Utils/Marketing/ConversionUploadProvider.js +17 -1
  132. package/build/dist/Server/Utils/Marketing/ConversionUploadProvider.js.map +1 -1
  133. package/build/dist/Server/Utils/Marketing/Providers/GoogleAds.js +1 -1
  134. package/build/dist/Server/Utils/Marketing/Providers/GoogleAds.js.map +1 -1
  135. package/build/dist/Server/Utils/Marketing/Providers/LinkedIn.js +1 -1
  136. package/build/dist/Server/Utils/Marketing/Providers/LinkedIn.js.map +1 -1
  137. package/build/dist/Server/Utils/Marketing/Providers/Meta.js +1 -1
  138. package/build/dist/Server/Utils/Marketing/Providers/Meta.js.map +1 -1
  139. package/build/dist/Server/Utils/Marketing/Providers/MicrosoftAds.js +1 -1
  140. package/build/dist/Server/Utils/Marketing/Providers/MicrosoftAds.js.map +1 -1
  141. package/build/dist/Server/Utils/Marketing/Providers/Reddit.js +1 -1
  142. package/build/dist/Server/Utils/Marketing/Providers/Reddit.js.map +1 -1
  143. package/build/dist/Server/Utils/Monitor/Criteria/APIRequestCriteria.js +37 -35
  144. package/build/dist/Server/Utils/Monitor/Criteria/APIRequestCriteria.js.map +1 -1
  145. package/build/dist/Server/Utils/Monitor/Criteria/DnsMonitorCriteria.js +21 -25
  146. package/build/dist/Server/Utils/Monitor/Criteria/DnsMonitorCriteria.js.map +1 -1
  147. package/build/dist/Server/Utils/Monitor/Criteria/DomainMonitorCriteria.js +20 -22
  148. package/build/dist/Server/Utils/Monitor/Criteria/DomainMonitorCriteria.js.map +1 -1
  149. package/build/dist/Server/Utils/Monitor/Criteria/EvaluateOverTime.js +370 -42
  150. package/build/dist/Server/Utils/Monitor/Criteria/EvaluateOverTime.js.map +1 -1
  151. package/build/dist/Server/Utils/Monitor/Criteria/ExternalStatusPageMonitorCriteria.js +21 -25
  152. package/build/dist/Server/Utils/Monitor/Criteria/ExternalStatusPageMonitorCriteria.js.map +1 -1
  153. package/build/dist/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.js +21 -25
  154. package/build/dist/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.js.map +1 -1
  155. package/build/dist/Server/Utils/Monitor/Criteria/SSLMonitorCriteria.js +21 -25
  156. package/build/dist/Server/Utils/Monitor/Criteria/SSLMonitorCriteria.js.map +1 -1
  157. package/build/dist/Server/Utils/Monitor/Criteria/ServerMonitorCriteria.js +64 -52
  158. package/build/dist/Server/Utils/Monitor/Criteria/ServerMonitorCriteria.js.map +1 -1
  159. package/build/dist/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.js +25 -29
  160. package/build/dist/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.js.map +1 -1
  161. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +8 -0
  162. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
  163. package/build/dist/Server/Utils/Monitor/MonitorResource.js +123 -23
  164. package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
  165. package/build/dist/Server/Utils/StatusPageContentSecurityPolicy.js +39 -0
  166. package/build/dist/Server/Utils/StatusPageContentSecurityPolicy.js.map +1 -0
  167. package/build/dist/Server/Utils/StatusPageCustomizationAccess.js +85 -0
  168. package/build/dist/Server/Utils/StatusPageCustomizationAccess.js.map +1 -0
  169. package/build/dist/Types/Marketing/MarketingConversion.js +10 -0
  170. package/build/dist/Types/Marketing/MarketingConversion.js.map +1 -1
  171. package/build/dist/Types/Monitor/CriteriaFilter.js +1 -0
  172. package/build/dist/Types/Monitor/CriteriaFilter.js.map +1 -1
  173. package/build/dist/Types/NetworkDevice/NetworkDeviceLinkRuleScope.js +46 -0
  174. package/build/dist/Types/NetworkDevice/NetworkDeviceLinkRuleScope.js.map +1 -0
  175. package/build/dist/UI/Components/FormModal/BasicFormModal.js +2 -1
  176. package/build/dist/UI/Components/FormModal/BasicFormModal.js.map +1 -1
  177. package/build/dist/UI/Components/Forms/BasicForm.js +10 -1
  178. package/build/dist/UI/Components/Forms/BasicForm.js.map +1 -1
  179. package/build/dist/UI/Components/Forms/BasicModelForm.js +2 -1
  180. package/build/dist/UI/Components/Forms/BasicModelForm.js.map +1 -1
  181. package/build/dist/UI/Components/Forms/ModelForm.js +4 -1
  182. package/build/dist/UI/Components/Forms/ModelForm.js.map +1 -1
  183. package/build/dist/UI/Components/Forms/Utils/FormAnalyticsName.js +33 -0
  184. package/build/dist/UI/Components/Forms/Utils/FormAnalyticsName.js.map +1 -0
  185. package/build/dist/UI/Components/ModelFormModal/ModelFormModal.js +2 -1
  186. package/build/dist/UI/Components/ModelFormModal/ModelFormModal.js.map +1 -1
  187. package/build/dist/Utils/Analytics.js +50 -2
  188. package/build/dist/Utils/Analytics.js.map +1 -1
  189. package/build/dist/Utils/Monitor/MonitorMetricType.js +37 -0
  190. package/build/dist/Utils/Monitor/MonitorMetricType.js.map +1 -1
  191. package/build/dist/Utils/Monitor/NetworkDeviceLinkRuleUtil.js +318 -37
  192. package/build/dist/Utils/Monitor/NetworkDeviceLinkRuleUtil.js.map +1 -1
  193. package/build/dist/Utils/NetworkDiscovery/UnclaimedScanDiagnosis.js +87 -0
  194. package/build/dist/Utils/NetworkDiscovery/UnclaimedScanDiagnosis.js.map +1 -0
  195. package/package.json +1 -1
@@ -0,0 +1,149 @@
1
+ import { describe, expect, test, beforeEach } from "@jest/globals";
2
+ import crypto from "crypto";
3
+ import SlackAuthorization from "../../../Server/Middleware/SlackAuthorization";
4
+ import Response from "../../../Server/Utils/Response";
5
+ import {
6
+ ExpressResponse,
7
+ NextFunction,
8
+ OneUptimeRequest,
9
+ } from "../../../Server/Utils/Express";
10
+ import BadDataException from "../../../Types/Exception/BadDataException";
11
+
12
+ const SIGNING_SECRET: string = "slack-app-signing-secret";
13
+
14
+ /*
15
+ * Only the signing secret is overridden. Logger and CaptureSpan also read from
16
+ * EnvironmentConfig, so the rest of the module has to stay real.
17
+ */
18
+ jest.mock("../../../Server/EnvironmentConfig", () => {
19
+ return {
20
+ __esModule: true,
21
+ ...jest.requireActual("../../../Server/EnvironmentConfig"),
22
+ SlackAppSigningSecret: "slack-app-signing-secret",
23
+ };
24
+ });
25
+
26
+ jest.mock("../../../Server/Utils/Response", () => {
27
+ return {
28
+ __esModule: true,
29
+ default: {
30
+ sendErrorResponse: jest.fn(),
31
+ },
32
+ };
33
+ });
34
+
35
+ /*
36
+ * Companion to WhatsAppAuthorization.test.ts. This middleware had the same
37
+ * unguarded crypto.timingSafeEqual: the value came off the attacker-controlled
38
+ * X-Slack-Signature header, and timingSafeEqual throws RangeError when the two
39
+ * buffers differ in byte length. A missing header was worse still - it reached
40
+ * Buffer.from(undefined) and threw a TypeError before the comparison. Both now
41
+ * have to come back as the intended 400.
42
+ */
43
+ describe("SlackAuthorization.isAuthorizedSlackRequest", () => {
44
+ const TIMESTAMP: string = "1700000000";
45
+ const RAW_BODY: string = "token=abc&team_id=T123&command=%2Foneuptime";
46
+
47
+ const sendErrorResponse: jest.Mock =
48
+ Response.sendErrorResponse as unknown as jest.Mock;
49
+
50
+ const res: ExpressResponse = {} as ExpressResponse;
51
+ let next: NextFunction;
52
+
53
+ type SignFunction = (timestamp: string, body: string) => string;
54
+
55
+ const sign: SignFunction = (timestamp: string, body: string): string => {
56
+ return `v0=${crypto
57
+ .createHmac("sha256", SIGNING_SECRET)
58
+ .update(`v0:${timestamp}:${body}`)
59
+ .digest("hex")}`;
60
+ };
61
+
62
+ type BuildRequestFunction = (
63
+ signature: string | undefined,
64
+ body?: string,
65
+ ) => OneUptimeRequest;
66
+
67
+ const buildRequest: BuildRequestFunction = (
68
+ signature: string | undefined,
69
+ body: string = RAW_BODY,
70
+ ): OneUptimeRequest => {
71
+ const headers: Record<string, string> = {
72
+ "x-slack-request-timestamp": TIMESTAMP,
73
+ };
74
+
75
+ if (signature !== undefined) {
76
+ headers["x-slack-signature"] = signature;
77
+ }
78
+
79
+ return { headers, rawBody: body } as unknown as OneUptimeRequest;
80
+ };
81
+
82
+ beforeEach(() => {
83
+ jest.clearAllMocks();
84
+ next = jest.fn();
85
+ });
86
+
87
+ test("calls next when the signature matches the timestamp and body", async () => {
88
+ const req: OneUptimeRequest = buildRequest(sign(TIMESTAMP, RAW_BODY));
89
+
90
+ await SlackAuthorization.isAuthorizedSlackRequest(req, res, next);
91
+
92
+ expect(next).toHaveBeenCalled();
93
+ expect(sendErrorResponse).not.toHaveBeenCalled();
94
+ });
95
+
96
+ test("rejects a well-formed signature computed over a different body", async () => {
97
+ const req: OneUptimeRequest = buildRequest(
98
+ sign(TIMESTAMP, `${RAW_BODY}&tampered=1`),
99
+ RAW_BODY,
100
+ );
101
+
102
+ await SlackAuthorization.isAuthorizedSlackRequest(req, res, next);
103
+
104
+ expect(next).not.toHaveBeenCalled();
105
+ expect(sendErrorResponse).toHaveBeenCalledWith(
106
+ req,
107
+ res,
108
+ new BadDataException("Slack Signature Verification Failed."),
109
+ );
110
+ });
111
+
112
+ /*
113
+ * Every one of these is a byte length other than the 67 of a real
114
+ * "v0=" + 64 hex header, which is exactly what used to reach
115
+ * timingSafeEqual and throw. The absent and empty cases used to throw
116
+ * even earlier, inside Buffer.from.
117
+ */
118
+ const malformedSignatures: Array<[string, string | undefined]> = [
119
+ ["absent", undefined],
120
+ ["an empty string", ""],
121
+ ["a bare word", "nope"],
122
+ ["the prefix with no digest", "v0="],
123
+ ["a short digest", "v0=abc123"],
124
+ ["a long digest", `v0=${"a".repeat(65)}`],
125
+ ["the right length but non-hex characters", `v0=${"z".repeat(64)}`],
126
+ ["64 hex characters with no prefix", "a".repeat(64)],
127
+ ["the wrong version prefix", `v1=${"a".repeat(64)}`],
128
+ ];
129
+
130
+ describe("rejects a malformed signature with 400 rather than throwing", () => {
131
+ test.each(malformedSignatures)(
132
+ "%s",
133
+ async (_label: string, signature: string | undefined) => {
134
+ const req: OneUptimeRequest = buildRequest(signature);
135
+
136
+ await expect(
137
+ SlackAuthorization.isAuthorizedSlackRequest(req, res, next),
138
+ ).resolves.toBeUndefined();
139
+
140
+ expect(next).not.toHaveBeenCalled();
141
+ expect(sendErrorResponse).toHaveBeenCalledWith(
142
+ req,
143
+ res,
144
+ new BadDataException("Slack Signature Verification Failed."),
145
+ );
146
+ },
147
+ );
148
+ });
149
+ });
@@ -677,9 +677,16 @@ describe("UserMiddleware", () => {
677
677
  ProjectService,
678
678
  "getRequireSsoWithSsoProviderId",
679
679
  );
680
- const spyDoesSsoTokenForProjectExist: jest.SpyInstance = getJestSpyOn(
680
+ /*
681
+ * The enforcement entry point is `isSsoSatisfiedForProject`, not the
682
+ * stateless `doesSsoTokenForProjectExist`: a Global SSO token also has to
683
+ * clear the provider-trust and project-governance checks, which need the
684
+ * database. Spying here keeps these tests about the middleware's control
685
+ * flow rather than about SSO token internals.
686
+ */
687
+ const spyIsSsoSatisfiedForProject: jest.SpyInstance = getJestSpyOn(
681
688
  UserMiddleware,
682
- "doesSsoTokenForProjectExist",
689
+ "isSsoSatisfiedForProject",
683
690
  );
684
691
  const spyGetGlobalRequireSsoForLogin: jest.SpyInstance = getJestSpyOn(
685
692
  GlobalConfigService,
@@ -717,7 +724,7 @@ describe("UserMiddleware", () => {
717
724
  test("should throw SsoAuthorizationException error, when sso login is required but sso token for the projectId does not exist", async () => {
718
725
  spyGetRequireSsoForLogin.mockResolvedValueOnce(true);
719
726
 
720
- spyDoesSsoTokenForProjectExist.mockReturnValueOnce(false);
727
+ spyIsSsoSatisfiedForProject.mockResolvedValueOnce(false);
721
728
 
722
729
  await expect(
723
730
  UserMiddleware.getUserTenantAccessPermissionWithTenantId({
@@ -726,12 +733,12 @@ describe("UserMiddleware", () => {
726
733
  userId,
727
734
  }),
728
735
  ).rejects.toThrowError(new SsoAuthorizationException());
729
- expect(spyDoesSsoTokenForProjectExist).toHaveBeenCalledWith(
736
+ expect(spyIsSsoSatisfiedForProject).toHaveBeenCalledWith({
730
737
  req,
731
738
  projectId,
732
739
  userId,
733
- undefined,
734
- );
740
+ requiredSsoProviderId: undefined,
741
+ });
735
742
  });
736
743
 
737
744
  test("should return null when getUserTenantAccessPermission returns null", async () => {
@@ -797,9 +804,16 @@ describe("UserMiddleware", () => {
797
804
  ProjectService,
798
805
  "getRequireSsoWithSsoProviderId",
799
806
  );
800
- const spyDoesSsoTokenForProjectExist: jest.SpyInstance = getJestSpyOn(
807
+ /*
808
+ * The enforcement entry point is `isSsoSatisfiedForProject`, not the
809
+ * stateless `doesSsoTokenForProjectExist`: a Global SSO token also has to
810
+ * clear the provider-trust and project-governance checks, which need the
811
+ * database. Spying here keeps these tests about the middleware's control
812
+ * flow rather than about SSO token internals.
813
+ */
814
+ const spyIsSsoSatisfiedForProject: jest.SpyInstance = getJestSpyOn(
801
815
  UserMiddleware,
802
- "doesSsoTokenForProjectExist",
816
+ "isSsoSatisfiedForProject",
803
817
  );
804
818
  const spyGetGlobalRequireSsoForLogin: jest.SpyInstance = getJestSpyOn(
805
819
  GlobalConfigService,
@@ -833,7 +847,7 @@ describe("UserMiddleware", () => {
833
847
  });
834
848
 
835
849
  test("should return default tenant access permission, when project for a projectId is found, sso is required for login, but sso token does not exist for that projectId", async () => {
836
- spyDoesSsoTokenForProjectExist.mockReturnValueOnce(false);
850
+ spyIsSsoSatisfiedForProject.mockResolvedValueOnce(false);
837
851
  spyGetProjectRequireSsoForLogin.mockResolvedValueOnce(true);
838
852
 
839
853
  const spyGetDefaultUserTenantAccessPermission: jest.SpyInstance =
@@ -852,12 +866,12 @@ describe("UserMiddleware", () => {
852
866
  expect(result).toEqual({
853
867
  [projectId.toString()]: mockedUserTenantAccessPermission,
854
868
  });
855
- expect(spyDoesSsoTokenForProjectExist).toHaveBeenCalledWith(
869
+ expect(spyIsSsoSatisfiedForProject).toHaveBeenCalledWith({
856
870
  req,
857
871
  projectId,
858
872
  userId,
859
- undefined,
860
- );
873
+ requiredSsoProviderId: undefined,
874
+ });
861
875
  expect(spyGetDefaultUserTenantAccessPermission).toHaveBeenCalledWith(
862
876
  projectId,
863
877
  );
@@ -879,7 +893,7 @@ describe("UserMiddleware", () => {
879
893
  expect(result).toEqual({
880
894
  [projectId.toString()]: mockedUserTenantAccessPermission,
881
895
  });
882
- expect(spyDoesSsoTokenForProjectExist).not.toBeCalled();
896
+ expect(spyIsSsoSatisfiedForProject).not.toBeCalled();
883
897
  expect(spyGetUserTenantAccessPermission).toHaveBeenCalledWith(
884
898
  userId,
885
899
  projectId,