@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.
- package/Models/DatabaseModels/GlobalOidc.ts +20 -0
- package/Models/DatabaseModels/GlobalSso.ts +20 -0
- package/Models/DatabaseModels/MarketingConversion.ts +19 -9
- package/Models/DatabaseModels/NetworkDeviceLinkRule.ts +46 -0
- package/Models/DatabaseModels/StatusPage.ts +7 -4
- package/Server/API/StatusPageAPI.ts +29 -4
- package/Server/EnvironmentConfig.ts +7 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1787800000000-AddScopeToNetworkDeviceLinkRule.ts +19 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1787900000000-AddRestrictToAttachedProjectsToGlobalSso.ts +40 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +4 -0
- package/Server/Middleware/SlackAuthorization.ts +43 -6
- package/Server/Middleware/UserAuthorization.ts +236 -26
- package/Server/Middleware/WhatsAppAuthorization.ts +43 -3
- package/Server/Services/GlobalOidcProjectService.ts +126 -1
- package/Server/Services/GlobalOidcService.ts +132 -0
- package/Server/Services/GlobalSsoProjectService.ts +126 -1
- package/Server/Services/GlobalSsoService.ts +132 -0
- package/Server/Services/UserEmailService.ts +4 -4
- package/Server/Utils/CronTab.ts +73 -0
- package/Server/Utils/GlobalSsoAuthorization.ts +175 -0
- package/Server/Utils/Marketing/ConversionUploadProvider.ts +35 -5
- package/Server/Utils/Marketing/Providers/GoogleAds.ts +1 -1
- package/Server/Utils/Marketing/Providers/LinkedIn.ts +1 -1
- package/Server/Utils/Marketing/Providers/Meta.ts +1 -1
- package/Server/Utils/Marketing/Providers/MicrosoftAds.ts +1 -1
- package/Server/Utils/Marketing/Providers/Reddit.ts +1 -1
- package/Server/Utils/Monitor/Criteria/APIRequestCriteria.ts +48 -33
- package/Server/Utils/Monitor/Criteria/DnsMonitorCriteria.ts +35 -30
- package/Server/Utils/Monitor/Criteria/DomainMonitorCriteria.ts +33 -28
- package/Server/Utils/Monitor/Criteria/EvaluateOverTime.ts +475 -47
- package/Server/Utils/Monitor/Criteria/ExternalStatusPageMonitorCriteria.ts +35 -30
- package/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.ts +34 -28
- package/Server/Utils/Monitor/Criteria/SSLMonitorCriteria.ts +33 -28
- package/Server/Utils/Monitor/Criteria/ServerMonitorCriteria.ts +69 -40
- package/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.ts +35 -29
- package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +8 -0
- package/Server/Utils/Monitor/MonitorResource.ts +161 -21
- package/Server/Utils/StatusPageContentSecurityPolicy.ts +56 -0
- package/Server/Utils/StatusPageCustomizationAccess.ts +117 -0
- package/Tests/Server/API/StatusPageCustomizationOrigin.test.ts +348 -0
- package/Tests/Server/Infrastructure/Postgres/FixTotpOtpUrlAlgorithmMigration.test.ts +9 -59
- package/Tests/Server/Infrastructure/Postgres/SchemaMigrationsOrdering.test.ts +227 -0
- package/Tests/Server/Middleware/SlackAuthorization.test.ts +149 -0
- package/Tests/Server/Middleware/UserAuthorization.test.ts +27 -13
- package/Tests/Server/Middleware/UserAuthorizationGlobalSsoGovernance.test.ts +1455 -0
- package/Tests/Server/Middleware/UserAuthorizationSSOProvider.test.ts +91 -2
- package/Tests/Server/Middleware/WhatsAppAuthorization.test.ts +233 -0
- package/Tests/Server/Services/DiscoveryScanClaimHookFreeSafety.test.ts +21 -8
- package/Tests/Server/Services/GlobalSsoProviderAuthorization.test.ts +1242 -0
- package/Tests/Server/Services/MonitorResourceProbeAgreementHydration.test.ts +459 -0
- package/Tests/Server/Services/MonitorResourceProbeAgreementReuse.test.ts +10 -0
- package/Tests/Server/Types/AnalyticsDatabase/AggregateUtilBucketTimestamp.test.ts +416 -0
- package/Tests/Server/Types/Database/QueryHelperManyToManyAndEmptyValues.test.ts +551 -0
- package/Tests/Server/Types/Database/SelectUtil.test.ts +348 -0
- package/Tests/Server/Utils/CronTab.test.ts +116 -0
- package/Tests/Server/Utils/GlobalSSOToken.test.ts +581 -0
- package/Tests/Server/Utils/GlobalSsoAuthorization.test.ts +1401 -0
- package/Tests/Server/Utils/Marketing/AdUploadableConversionTypes.test.ts +254 -0
- package/Tests/Server/Utils/Marketing/ConversionUploadProvider.test.ts +1 -1
- package/Tests/Server/Utils/Monitor/Criteria/APIRequestCriteriaEvaluateOverTime.test.ts +508 -0
- package/Tests/Server/Utils/Monitor/Criteria/APIRequestCriteriaPortTimings.test.ts +30 -9
- package/Tests/Server/Utils/Monitor/Criteria/EvaluateOverTime.test.ts +987 -0
- package/Tests/Server/Utils/Monitor/Criteria/ExternalStatusPageMonitorCriteria.test.ts +916 -0
- package/Tests/Server/Utils/Monitor/Criteria/ProfileMonitorCriteria.test.ts +382 -0
- package/Tests/Server/Utils/Monitor/Criteria/ServerMonitorCriteria.test.ts +1219 -0
- package/Tests/Server/Utils/Monitor/MonitorResourceIngestedStepSelection.test.ts +86 -0
- package/Tests/Server/Utils/StatusPageContentSecurityPolicy.test.ts +136 -0
- package/Tests/Server/Utils/StatusPageCustomizationAccess.test.ts +223 -0
- package/Tests/Types/Monitor/MonitorStepConfigHelpers.test.ts +165 -0
- package/Tests/Types/NetworkDevice/NetworkDeviceLinkRuleScope.test.ts +215 -0
- package/Tests/UI/Components/Forms/FormSubmitAnalytics.test.tsx +206 -0
- package/Tests/UI/Utils/AIChatExport/ConversationMarkdown.test.ts +774 -0
- package/Tests/UI/Utils/AIChatExport/MarkdownBlocks.test.ts +791 -0
- package/Tests/UI/Utils/AIChatExport/MarkdownSafety.test.ts +544 -0
- package/Tests/Utils/Analytics.test.ts +187 -0
- package/Tests/Utils/Monitor/MonitorMetricType.test.ts +80 -0
- package/Tests/Utils/Monitor/NetworkDeviceLinkRuleUtil.test.ts +1291 -0
- package/Tests/Utils/NetworkDiscovery/UnclaimedScanDiagnosis.test.ts +214 -0
- package/Types/Marketing/MarketingConversion.ts +12 -0
- package/Types/Monitor/CriteriaFilter.ts +9 -0
- package/Types/NetworkDevice/NetworkDeviceLinkRuleScope.ts +51 -0
- package/UI/Components/FormModal/BasicFormModal.tsx +12 -0
- package/UI/Components/Forms/BasicForm.tsx +13 -1
- package/UI/Components/Forms/BasicModelForm.tsx +2 -1
- package/UI/Components/Forms/ModelForm.tsx +10 -1
- package/UI/Components/Forms/Utils/FormAnalyticsName.ts +39 -0
- package/UI/Components/ModelFormModal/ModelFormModal.tsx +6 -1
- package/Utils/Analytics.ts +55 -2
- package/Utils/Monitor/MonitorMetricType.ts +40 -0
- package/Utils/Monitor/NetworkDeviceLinkRuleUtil.ts +587 -37
- package/Utils/NetworkDiscovery/UnclaimedScanDiagnosis.ts +115 -0
- package/build/dist/Models/DatabaseModels/GlobalOidc.js +21 -0
- package/build/dist/Models/DatabaseModels/GlobalOidc.js.map +1 -1
- package/build/dist/Models/DatabaseModels/GlobalSso.js +21 -0
- package/build/dist/Models/DatabaseModels/GlobalSso.js.map +1 -1
- package/build/dist/Models/DatabaseModels/MarketingConversion.js +20 -10
- package/build/dist/Models/DatabaseModels/MarketingConversion.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkDeviceLinkRule.js +47 -0
- package/build/dist/Models/DatabaseModels/NetworkDeviceLinkRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPage.js +4 -4
- package/build/dist/Models/DatabaseModels/StatusPage.js.map +1 -1
- package/build/dist/Server/API/StatusPageAPI.js +25 -4
- package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
- package/build/dist/Server/EnvironmentConfig.js +6 -0
- package/build/dist/Server/EnvironmentConfig.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787800000000-AddScopeToNetworkDeviceLinkRule.js +12 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787800000000-AddScopeToNetworkDeviceLinkRule.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787900000000-AddRestrictToAttachedProjectsToGlobalSso.js +29 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787900000000-AddRestrictToAttachedProjectsToGlobalSso.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +4 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Middleware/SlackAuthorization.js +28 -4
- package/build/dist/Server/Middleware/SlackAuthorization.js.map +1 -1
- package/build/dist/Server/Middleware/UserAuthorization.js +197 -22
- package/build/dist/Server/Middleware/UserAuthorization.js.map +1 -1
- package/build/dist/Server/Middleware/WhatsAppAuthorization.js +32 -2
- package/build/dist/Server/Middleware/WhatsAppAuthorization.js.map +1 -1
- package/build/dist/Server/Services/GlobalOidcProjectService.js +105 -0
- package/build/dist/Server/Services/GlobalOidcProjectService.js.map +1 -1
- package/build/dist/Server/Services/GlobalOidcService.js +127 -0
- package/build/dist/Server/Services/GlobalOidcService.js.map +1 -1
- package/build/dist/Server/Services/GlobalSsoProjectService.js +105 -0
- package/build/dist/Server/Services/GlobalSsoProjectService.js.map +1 -1
- package/build/dist/Server/Services/GlobalSsoService.js +127 -0
- package/build/dist/Server/Services/GlobalSsoService.js.map +1 -1
- package/build/dist/Server/Services/UserEmailService.js +4 -4
- package/build/dist/Server/Utils/CronTab.js +66 -0
- package/build/dist/Server/Utils/CronTab.js.map +1 -1
- package/build/dist/Server/Utils/GlobalSsoAuthorization.js +112 -0
- package/build/dist/Server/Utils/GlobalSsoAuthorization.js.map +1 -0
- package/build/dist/Server/Utils/Marketing/ConversionUploadProvider.js +17 -1
- package/build/dist/Server/Utils/Marketing/ConversionUploadProvider.js.map +1 -1
- package/build/dist/Server/Utils/Marketing/Providers/GoogleAds.js +1 -1
- package/build/dist/Server/Utils/Marketing/Providers/GoogleAds.js.map +1 -1
- package/build/dist/Server/Utils/Marketing/Providers/LinkedIn.js +1 -1
- package/build/dist/Server/Utils/Marketing/Providers/LinkedIn.js.map +1 -1
- package/build/dist/Server/Utils/Marketing/Providers/Meta.js +1 -1
- package/build/dist/Server/Utils/Marketing/Providers/Meta.js.map +1 -1
- package/build/dist/Server/Utils/Marketing/Providers/MicrosoftAds.js +1 -1
- package/build/dist/Server/Utils/Marketing/Providers/MicrosoftAds.js.map +1 -1
- package/build/dist/Server/Utils/Marketing/Providers/Reddit.js +1 -1
- package/build/dist/Server/Utils/Marketing/Providers/Reddit.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/APIRequestCriteria.js +37 -35
- package/build/dist/Server/Utils/Monitor/Criteria/APIRequestCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/DnsMonitorCriteria.js +21 -25
- package/build/dist/Server/Utils/Monitor/Criteria/DnsMonitorCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/DomainMonitorCriteria.js +20 -22
- package/build/dist/Server/Utils/Monitor/Criteria/DomainMonitorCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/EvaluateOverTime.js +370 -42
- package/build/dist/Server/Utils/Monitor/Criteria/EvaluateOverTime.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/ExternalStatusPageMonitorCriteria.js +21 -25
- package/build/dist/Server/Utils/Monitor/Criteria/ExternalStatusPageMonitorCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.js +21 -25
- package/build/dist/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/SSLMonitorCriteria.js +21 -25
- package/build/dist/Server/Utils/Monitor/Criteria/SSLMonitorCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/ServerMonitorCriteria.js +64 -52
- package/build/dist/Server/Utils/Monitor/Criteria/ServerMonitorCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.js +25 -29
- package/build/dist/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +8 -0
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorResource.js +123 -23
- package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
- package/build/dist/Server/Utils/StatusPageContentSecurityPolicy.js +39 -0
- package/build/dist/Server/Utils/StatusPageContentSecurityPolicy.js.map +1 -0
- package/build/dist/Server/Utils/StatusPageCustomizationAccess.js +85 -0
- package/build/dist/Server/Utils/StatusPageCustomizationAccess.js.map +1 -0
- package/build/dist/Types/Marketing/MarketingConversion.js +10 -0
- package/build/dist/Types/Marketing/MarketingConversion.js.map +1 -1
- package/build/dist/Types/Monitor/CriteriaFilter.js +1 -0
- package/build/dist/Types/Monitor/CriteriaFilter.js.map +1 -1
- package/build/dist/Types/NetworkDevice/NetworkDeviceLinkRuleScope.js +46 -0
- package/build/dist/Types/NetworkDevice/NetworkDeviceLinkRuleScope.js.map +1 -0
- package/build/dist/UI/Components/FormModal/BasicFormModal.js +2 -1
- package/build/dist/UI/Components/FormModal/BasicFormModal.js.map +1 -1
- package/build/dist/UI/Components/Forms/BasicForm.js +10 -1
- package/build/dist/UI/Components/Forms/BasicForm.js.map +1 -1
- package/build/dist/UI/Components/Forms/BasicModelForm.js +2 -1
- package/build/dist/UI/Components/Forms/BasicModelForm.js.map +1 -1
- package/build/dist/UI/Components/Forms/ModelForm.js +4 -1
- package/build/dist/UI/Components/Forms/ModelForm.js.map +1 -1
- package/build/dist/UI/Components/Forms/Utils/FormAnalyticsName.js +33 -0
- package/build/dist/UI/Components/Forms/Utils/FormAnalyticsName.js.map +1 -0
- package/build/dist/UI/Components/ModelFormModal/ModelFormModal.js +2 -1
- package/build/dist/UI/Components/ModelFormModal/ModelFormModal.js.map +1 -1
- package/build/dist/Utils/Analytics.js +50 -2
- package/build/dist/Utils/Analytics.js.map +1 -1
- package/build/dist/Utils/Monitor/MonitorMetricType.js +37 -0
- package/build/dist/Utils/Monitor/MonitorMetricType.js.map +1 -1
- package/build/dist/Utils/Monitor/NetworkDeviceLinkRuleUtil.js +318 -37
- package/build/dist/Utils/Monitor/NetworkDeviceLinkRuleUtil.js.map +1 -1
- package/build/dist/Utils/NetworkDiscovery/UnclaimedScanDiagnosis.js +87 -0
- package/build/dist/Utils/NetworkDiscovery/UnclaimedScanDiagnosis.js.map +1 -0
- 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
|
-
|
|
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
|
-
"
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
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
|
-
"
|
|
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
|
-
|
|
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(
|
|
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(
|
|
896
|
+
expect(spyIsSsoSatisfiedForProject).not.toBeCalled();
|
|
883
897
|
expect(spyGetUserTenantAccessPermission).toHaveBeenCalledWith(
|
|
884
898
|
userId,
|
|
885
899
|
projectId,
|