@oneuptime/common 12.0.13 → 12.0.14
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/OnCallDutyPolicySchedule.ts +14 -0
- package/Models/DatabaseModels/UserCall.ts +94 -3
- package/Models/DatabaseModels/UserEmail.ts +94 -3
- package/Models/DatabaseModels/UserIncomingCallNumber.ts +94 -3
- package/Models/DatabaseModels/UserPush.ts +37 -0
- package/Models/DatabaseModels/UserSMS.ts +94 -3
- package/Models/DatabaseModels/UserWhatsApp.ts +93 -2
- package/Server/API/BaseAPI.ts +79 -14
- package/Server/API/UserCallAPI.ts +53 -45
- package/Server/API/UserEmailAPI.ts +53 -44
- package/Server/API/UserIncomingCallNumberAPI.ts +48 -38
- package/Server/API/UserNotificationMethodAdminAPI.ts +481 -0
- package/Server/API/UserPushAPI.ts +126 -2
- package/Server/API/UserSmsAPI.ts +53 -44
- package/Server/API/UserWhatsAppAPI.ts +53 -50
- package/Server/Infrastructure/Postgres/SchemaMigrations/1787142779538-MigrationName.ts +154 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1787156982416-MigrationName.ts +17 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1787700000000-FixTotpOtpUrlAlgorithm.ts +45 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +6 -0
- package/Server/Middleware/VerificationCodeRateLimit.ts +586 -0
- package/Server/Services/AnalyticsDatabaseService.ts +169 -0
- package/Server/Services/DatabaseService.ts +101 -0
- package/Server/Services/LogAggregationService.ts +5 -0
- package/Server/Services/PushNotificationService.ts +127 -12
- package/Server/Services/TeamMemberService.ts +53 -13
- package/Server/Services/UserCallService.ts +55 -24
- package/Server/Services/UserEmailService.ts +83 -17
- package/Server/Services/UserIncomingCallNumberService.ts +49 -85
- package/Server/Services/UserNotificationMethodAdminService.ts +1527 -0
- package/Server/Services/UserNotificationRuleService.ts +26 -0
- package/Server/Services/UserPushService.ts +89 -0
- package/Server/Services/UserSmsService.ts +50 -17
- package/Server/Services/UserWhatsAppService.ts +48 -15
- package/Server/Types/Database/QueryHelper.ts +30 -0
- package/Server/Utils/AnalyticsDatabase/QuerySettingsHelper.ts +59 -0
- package/Server/Utils/ChannelVerification.ts +510 -0
- package/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.ts +13 -16
- package/Server/Utils/Monitor/MonitorAlert.ts +24 -21
- package/Server/Utils/Monitor/MonitorIncident.ts +21 -18
- package/Server/Utils/Monitor/MonitorResourceContext.ts +107 -0
- package/Server/Utils/Monitor/MonitorStepResourceIdentity.ts +442 -0
- package/Server/Utils/Monitor/SeriesResourceLabels.ts +3 -3
- package/Server/Utils/Monitor/SeriesResourceLinker.ts +96 -28
- package/Server/Utils/TotpAuth.ts +137 -9
- package/Server/Utils/UserRegistrationToken.ts +182 -0
- package/Server/Utils/VerificationCode.ts +134 -0
- package/Tests/App/Dashboard/AdminNotificationRulesPage.test.tsx +173 -94
- package/Tests/App/Dashboard/AdminUserNotificationMethodsPage.test.tsx +1151 -0
- package/Tests/App/Dashboard/AdminUserOnCallPages.test.tsx +905 -0
- package/Tests/App/Dashboard/DashboardCommandPalette.test.tsx +338 -0
- package/Tests/App/Dashboard/InvestigationPanel.test.tsx +1 -1
- package/Tests/App/Dashboard/MonitorTypePicker.test.tsx +28 -0
- package/Tests/Models/UserPushCriticalAlertColumn.test.ts +172 -0
- package/Tests/Server/API/BaseAPIGetListParallel.test.ts +519 -0
- package/Tests/Server/API/NotificationChannelVerificationAPI.test.ts +543 -0
- package/Tests/Server/API/UserIncomingCallNumberApi.test.ts +108 -18
- package/Tests/Server/API/UserNotificationMethodAdminAPI.test.ts +963 -0
- package/Tests/Server/API/UserPushCriticalAlertsApi.test.ts +114 -0
- package/Tests/Server/API/UserSmsApi.test.ts +107 -14
- package/Tests/Server/API/UserTotpAuthAPI.test.ts +427 -0
- package/Tests/Server/Infrastructure/Postgres/FixTotpOtpUrlAlgorithmMigration.test.ts +315 -0
- package/Tests/Server/Middleware/VerificationCodeRateLimit.test.ts +775 -0
- package/Tests/Server/Services/AddNetworkDeviceReachabilityColumnsMigration.test.ts +10 -62
- package/Tests/Server/Services/AnalyticsDatabasePaginationStability.test.ts +33 -13
- package/Tests/Server/Services/AnalyticsDatabaseSortKeyBoundary.test.ts +658 -0
- package/Tests/Server/Services/CriticalOnCallAlertDelivery.test.ts +458 -0
- package/Tests/Server/Services/CriticalPushAlertPayload.test.ts +301 -0
- package/Tests/Server/Services/DatabaseServiceAtomicIncrement.test.ts +143 -0
- package/Tests/Server/Services/DeliverNotificationForRuleExtraction.test.ts +1 -0
- package/Tests/Server/Services/LogAggregationScanMemory.test.ts +421 -0
- package/Tests/Server/Services/LogAggregationService.test.ts +2 -2
- package/Tests/Server/Services/NotificationChannelCodeIssuance.test.ts +401 -0
- package/Tests/Server/Services/PushNotificationDeliveryOptions.test.ts +204 -0
- package/Tests/Server/Services/TeamMemberAutoAcceptInvitation.test.ts +21 -1
- package/Tests/Server/Services/TeamMemberInviteRegistrationToken.test.ts +290 -0
- package/Tests/Server/Services/UserNotificationMethodAdminService.test.ts +948 -0
- package/Tests/Server/Services/UserNotificationRuleExecuteItem.test.ts +1 -0
- package/Tests/Server/Services/UserPushCriticalAlertToggle.test.ts +255 -0
- package/Tests/Server/Services/UserTotpAuthEnrolment.test.ts +218 -0
- package/Tests/Server/TestingUtils/AuthenticatorApp.ts +248 -0
- package/Tests/Server/Types/Database/Permissions/NotificationChannelVerificationColumns.test.ts +135 -0
- package/Tests/Server/Types/Database/Permissions/OnCallScheduleRelationSelect.test.ts +504 -0
- package/Tests/Server/Types/Database/QueryHelperFindWithSameTextAnyOf.test.ts +91 -0
- package/Tests/Server/Types/Workflow/Components/JsonToText.test.ts +384 -0
- package/Tests/Server/Types/Workflow/Components/MergeJson.test.ts +403 -0
- package/Tests/Server/Utils/Browser.test.ts +162 -0
- package/Tests/Server/Utils/ChannelVerification.test.ts +689 -0
- package/Tests/Server/Utils/Express.test.ts +371 -0
- package/Tests/Server/Utils/Monitor/Criteria/CustomCodeMonitorCriteria.test.ts +707 -0
- package/Tests/Server/Utils/Monitor/Criteria/DnsMonitorCriteria.test.ts +698 -0
- package/Tests/Server/Utils/Monitor/Criteria/IncomingEmailBodyCriteria.test.ts +243 -0
- package/Tests/Server/Utils/Monitor/Criteria/IncomingRequestBodyCriteria.test.ts +278 -0
- package/Tests/Server/Utils/Monitor/MonitorAlertResourceLinking.test.ts +160 -20
- package/Tests/Server/Utils/Monitor/MonitorDependencySuppressionCreatorSkip.test.ts +13 -8
- package/Tests/Server/Utils/Monitor/MonitorIncidentResourceLinking.test.ts +162 -18
- package/Tests/Server/Utils/Monitor/MonitorResourceContext.test.ts +349 -0
- package/Tests/Server/Utils/Monitor/MonitorStepResourceIdentity.test.ts +690 -0
- package/Tests/Server/Utils/Monitor/MonitorSummaryPersistence.test.ts +7 -2
- package/Tests/Server/Utils/Monitor/SeriesResourceLinker.test.ts +92 -18
- package/Tests/Server/Utils/PushNotificationUtilCreators.test.ts +267 -0
- package/Tests/Server/Utils/Telemetry/OneuptimeLabel.test.ts +439 -0
- package/Tests/Server/Utils/TotpAuth.test.ts +719 -0
- package/Tests/Server/Utils/UserRegistrationToken.test.ts +322 -0
- package/Tests/Server/Utils/VerificationCode.test.ts +296 -0
- package/Tests/Types/AutoRemediation/AutoRemediationSuggestionStatus.test.ts +192 -0
- package/Tests/Types/Call/CallRequest.test.ts +189 -0
- package/Tests/Types/Dashboard/DashboardSize.test.ts +226 -0
- package/Tests/Types/Incident/IncidentSlaStatus.test.ts +191 -0
- package/Tests/Types/Metrics/MetricDashboardMetricType.test.ts +278 -0
- package/Tests/Types/Metrics/MetricPipelineRuleType.test.ts +517 -0
- package/Tests/Types/Monitor/IncomingMonitorDefaultCriteria.test.ts +470 -0
- package/Tests/Types/Monitor/MonitorCriteriaInstance.test.ts +6 -4
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCatalog.test.ts +262 -5
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCoverage.test.ts +1 -1
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationNotificationMode.test.ts +1 -1
- package/Tests/Types/Monitor/ServiceAlertTemplates.test.ts +905 -0
- package/Tests/Types/Service/ServiceLanguage.test.ts +255 -0
- package/Tests/Types/TextRandomGeneration.test.ts +211 -0
- package/Tests/UI/Components/Button.test.tsx +175 -1
- package/Tests/UI/Components/CodeBlockLanguages.test.tsx +236 -0
- package/Tests/UI/Components/CommandPalette/CommandPalette.test.tsx +568 -0
- package/Tests/UI/Components/CommandPalette/CommandPaletteKeyboard.test.tsx +239 -0
- package/Tests/UI/Components/CommandPalette/CommandPaletteProviders.test.tsx +400 -0
- package/Tests/UI/Components/CommandPalette/PaletteFilter.test.ts +234 -0
- package/Tests/UI/Components/CommandPalette/RecentCommands.test.ts +97 -0
- package/Tests/UI/Components/CountModelSideMenuItemGuard.test.tsx +198 -0
- package/Tests/UI/Components/FeedItemSafeMode.test.tsx +1 -1
- package/Tests/UI/Components/Forms/Utils/FormFieldSchemaTypeUtil.test.ts +267 -0
- package/Tests/UI/Components/List.test.tsx +9 -2
- package/Tests/UI/Components/ListLoadingStates.test.tsx +173 -0
- package/Tests/UI/Components/MarkdownLazy.test.tsx +113 -0
- package/Tests/UI/Components/MarkdownMermaidRetry.test.tsx +110 -0
- package/Tests/UI/Components/ModelTable/useCustomFieldColumns.test.tsx +8 -0
- package/Tests/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.test.ts +692 -0
- package/Tests/UI/Components/MoreMenuMotion.test.tsx +118 -0
- package/Tests/UI/Components/NavBarCommandKGating.test.tsx +178 -0
- package/Tests/UI/Components/OrderedStatesList.test.tsx +19 -2
- package/Tests/UI/Components/SideOverMotion.test.tsx +109 -0
- package/Tests/UI/Components/Skeleton.test.tsx +71 -0
- package/Tests/UI/Components/TableLoadingStates.test.tsx +279 -0
- package/Tests/UI/Components/Tabs.test.tsx +24 -0
- package/Tests/UI/Components/Toast.test.tsx +130 -7
- package/Tests/UI/Components/ToastStacking.test.tsx +198 -0
- package/Tests/UI/Utils/Dropdown.test.ts +423 -0
- package/Tests/UI/Utils/ModelAPITenantHeader.test.ts +122 -0
- package/Tests/UI/Utils/ModelListCache.test.ts +338 -0
- package/Tests/UI/Utils/ProjectListCacheInvalidation.test.ts +225 -0
- package/Tests/Utils/API.test.ts +16 -2
- package/Tests/Utils/Dashboard/Components/DashboardKubernetesResourceListShared.test.ts +347 -0
- package/Tests/Utils/Dashboard/Components/DashboardListSharedArgs.test.ts +259 -0
- package/Tests/Utils/Dashboard/Components/DashboardMonitorListComponent.test.ts +466 -0
- package/Tests/Utils/Rum/UrlScrubberSegments.test.ts +362 -0
- package/Types/Email/EmailTemplateType.ts +1 -0
- package/Types/Monitor/MonitorCriteriaInstance.ts +41 -20
- package/Types/Monitor/Recommendation/MonitorRecommendationCatalog.ts +131 -8
- package/Types/Monitor/Recommendation/MonitorRecommendationTypes.ts +48 -8
- package/Types/Monitor/ServiceAlertTemplates.ts +1352 -0
- package/Types/Permission.ts +35 -0
- package/Types/PushNotification/AndroidNotificationChannel.ts +26 -0
- package/Types/PushNotification/PushNotificationMessage.ts +15 -0
- package/Types/PushNotification/PushNotificationRequest.ts +8 -16
- package/Types/Service/ServiceLanguage.ts +144 -0
- package/Types/Text.ts +111 -19
- package/UI/Components/Button/Button.tsx +27 -14
- package/UI/Components/CodeBlock/CodeBlock.tsx +54 -7
- package/UI/Components/CodeBlock/LanguageRegistry.ts +103 -0
- package/UI/Components/CommandPalette/CommandPalette.tsx +790 -0
- package/UI/Components/CommandPalette/PaletteFilter.ts +196 -0
- package/UI/Components/CommandPalette/PaletteRow.tsx +173 -0
- package/UI/Components/CommandPalette/RecentCommands.ts +57 -0
- package/UI/Components/CommandPalette/Types.ts +49 -0
- package/UI/Components/CommandPalette/UseProviderSearch.ts +129 -0
- package/UI/Components/Dropdown/Dropdown.tsx +6 -1
- package/UI/Components/Feed/FeedItem.tsx +1 -1
- package/UI/Components/List/List.tsx +37 -5
- package/UI/Components/List/ListSkeleton.tsx +54 -0
- package/UI/Components/Markdown.tsx/LazyMarkdownViewer.tsx +6 -1
- package/UI/Components/Markdown.tsx/MarkdownViewer.tsx +71 -26
- package/UI/Components/Modal/Modal.tsx +2 -2
- package/UI/Components/ModelTable/BaseModelTable.tsx +1 -1
- package/UI/Components/ModelTable/useCustomFieldColumns.ts +11 -5
- package/UI/Components/MoreMenu/MoreMenu.tsx +39 -1
- package/UI/Components/Navbar/NavBar.tsx +14 -1
- package/UI/Components/OrderedStatesList/OrderedStatesList.tsx +50 -5
- package/UI/Components/SideMenu/CountModelSideMenuItem.tsx +40 -1
- package/UI/Components/SideOver/SideOver.tsx +37 -2
- package/UI/Components/Skeleton/Skeleton.tsx +53 -0
- package/UI/Components/Table/Table.tsx +74 -44
- package/UI/Components/Table/TableSkeletonRows.tsx +141 -0
- package/UI/Components/Tabs/Tab.tsx +1 -1
- package/UI/Components/Toast/Toast.tsx +118 -53
- package/UI/Components/Toast/ToastInit.tsx +82 -32
- package/UI/Styles/Theme.css +40 -0
- package/UI/Utils/ModelAPI/ModelAPI.ts +20 -10
- package/UI/Utils/ModelListCache.ts +188 -0
- package/UI/Utils/Project.ts +29 -0
- package/Utils/API.ts +6 -1
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicySchedule.js +14 -0
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicySchedule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserCall.js +101 -3
- package/build/dist/Models/DatabaseModels/UserCall.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserEmail.js +101 -3
- package/build/dist/Models/DatabaseModels/UserEmail.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserIncomingCallNumber.js +101 -3
- package/build/dist/Models/DatabaseModels/UserIncomingCallNumber.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserPush.js +38 -0
- package/build/dist/Models/DatabaseModels/UserPush.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserSMS.js +101 -3
- package/build/dist/Models/DatabaseModels/UserSMS.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserWhatsApp.js +100 -2
- package/build/dist/Models/DatabaseModels/UserWhatsApp.js.map +1 -1
- package/build/dist/Server/API/BaseAPI.js +69 -13
- package/build/dist/Server/API/BaseAPI.js.map +1 -1
- package/build/dist/Server/API/UserCallAPI.js +42 -38
- package/build/dist/Server/API/UserCallAPI.js.map +1 -1
- package/build/dist/Server/API/UserEmailAPI.js +42 -38
- package/build/dist/Server/API/UserEmailAPI.js.map +1 -1
- package/build/dist/Server/API/UserIncomingCallNumberAPI.js +37 -32
- package/build/dist/Server/API/UserIncomingCallNumberAPI.js.map +1 -1
- package/build/dist/Server/API/UserNotificationMethodAdminAPI.js +341 -0
- package/build/dist/Server/API/UserNotificationMethodAdminAPI.js.map +1 -0
- package/build/dist/Server/API/UserPushAPI.js +95 -2
- package/build/dist/Server/API/UserPushAPI.js.map +1 -1
- package/build/dist/Server/API/UserSmsAPI.js +42 -38
- package/build/dist/Server/API/UserSmsAPI.js.map +1 -1
- package/build/dist/Server/API/UserWhatsAppAPI.js +42 -40
- package/build/dist/Server/API/UserWhatsAppAPI.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787142779538-MigrationName.js +89 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787142779538-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787156982416-MigrationName.js +12 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787156982416-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787700000000-FixTotpOtpUrlAlgorithm.js +40 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787700000000-FixTotpOtpUrlAlgorithm.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +6 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Middleware/VerificationCodeRateLimit.js +393 -0
- package/build/dist/Server/Middleware/VerificationCodeRateLimit.js.map +1 -0
- package/build/dist/Server/Services/AnalyticsDatabaseService.js +136 -0
- package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
- package/build/dist/Server/Services/DatabaseService.js +74 -0
- package/build/dist/Server/Services/DatabaseService.js.map +1 -1
- package/build/dist/Server/Services/LogAggregationService.js +5 -0
- package/build/dist/Server/Services/LogAggregationService.js.map +1 -1
- package/build/dist/Server/Services/PushNotificationService.js +69 -30
- package/build/dist/Server/Services/PushNotificationService.js.map +1 -1
- package/build/dist/Server/Services/TeamMemberService.js +43 -7
- package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
- package/build/dist/Server/Services/UserCallService.js +54 -22
- package/build/dist/Server/Services/UserCallService.js.map +1 -1
- package/build/dist/Server/Services/UserEmailService.js +78 -17
- package/build/dist/Server/Services/UserEmailService.js.map +1 -1
- package/build/dist/Server/Services/UserIncomingCallNumberService.js +45 -74
- package/build/dist/Server/Services/UserIncomingCallNumberService.js.map +1 -1
- package/build/dist/Server/Services/UserNotificationMethodAdminService.js +1117 -0
- package/build/dist/Server/Services/UserNotificationMethodAdminService.js.map +1 -0
- package/build/dist/Server/Services/UserNotificationRuleService.js +20 -0
- package/build/dist/Server/Services/UserNotificationRuleService.js.map +1 -1
- package/build/dist/Server/Services/UserPushService.js +77 -0
- package/build/dist/Server/Services/UserPushService.js.map +1 -1
- package/build/dist/Server/Services/UserSmsService.js +50 -17
- package/build/dist/Server/Services/UserSmsService.js.map +1 -1
- package/build/dist/Server/Services/UserWhatsAppService.js +48 -15
- package/build/dist/Server/Services/UserWhatsAppService.js.map +1 -1
- package/build/dist/Server/Types/Database/QueryHelper.js +27 -0
- package/build/dist/Server/Types/Database/QueryHelper.js.map +1 -1
- package/build/dist/Server/Utils/AnalyticsDatabase/QuerySettingsHelper.js +46 -0
- package/build/dist/Server/Utils/AnalyticsDatabase/QuerySettingsHelper.js.map +1 -1
- package/build/dist/Server/Utils/ChannelVerification.js +348 -0
- package/build/dist/Server/Utils/ChannelVerification.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.js +13 -12
- package/build/dist/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorAlert.js +20 -17
- package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorIncident.js +17 -14
- package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorResourceContext.js +95 -0
- package/build/dist/Server/Utils/Monitor/MonitorResourceContext.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/MonitorStepResourceIdentity.js +313 -0
- package/build/dist/Server/Utils/Monitor/MonitorStepResourceIdentity.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/SeriesResourceLabels.js +3 -3
- package/build/dist/Server/Utils/Monitor/SeriesResourceLinker.js +67 -26
- package/build/dist/Server/Utils/Monitor/SeriesResourceLinker.js.map +1 -1
- package/build/dist/Server/Utils/TotpAuth.js +127 -8
- package/build/dist/Server/Utils/TotpAuth.js.map +1 -1
- package/build/dist/Server/Utils/UserRegistrationToken.js +170 -0
- package/build/dist/Server/Utils/UserRegistrationToken.js.map +1 -0
- package/build/dist/Server/Utils/VerificationCode.js +120 -0
- package/build/dist/Server/Utils/VerificationCode.js.map +1 -0
- package/build/dist/Types/Email/EmailTemplateType.js +1 -0
- package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorCriteriaInstance.js +42 -21
- package/build/dist/Types/Monitor/MonitorCriteriaInstance.js.map +1 -1
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js +77 -5
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js.map +1 -1
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js +18 -6
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js.map +1 -1
- package/build/dist/Types/Monitor/ServiceAlertTemplates.js +1028 -0
- package/build/dist/Types/Monitor/ServiceAlertTemplates.js.map +1 -0
- package/build/dist/Types/Permission.js +33 -0
- package/build/dist/Types/Permission.js.map +1 -1
- package/build/dist/Types/PushNotification/AndroidNotificationChannel.js +27 -0
- package/build/dist/Types/PushNotification/AndroidNotificationChannel.js.map +1 -0
- package/build/dist/Types/Service/ServiceLanguage.js +96 -0
- package/build/dist/Types/Service/ServiceLanguage.js.map +1 -0
- package/build/dist/Types/Text.js +82 -17
- package/build/dist/Types/Text.js.map +1 -1
- package/build/dist/UI/Components/Button/Button.js +22 -14
- package/build/dist/UI/Components/Button/Button.js.map +1 -1
- package/build/dist/UI/Components/CodeBlock/CodeBlock.js +35 -3
- package/build/dist/UI/Components/CodeBlock/CodeBlock.js.map +1 -1
- package/build/dist/UI/Components/CodeBlock/LanguageRegistry.js +57 -0
- package/build/dist/UI/Components/CodeBlock/LanguageRegistry.js.map +1 -0
- package/build/dist/UI/Components/CommandPalette/CommandPalette.js +439 -0
- package/build/dist/UI/Components/CommandPalette/CommandPalette.js.map +1 -0
- package/build/dist/UI/Components/CommandPalette/PaletteFilter.js +135 -0
- package/build/dist/UI/Components/CommandPalette/PaletteFilter.js.map +1 -0
- package/build/dist/UI/Components/CommandPalette/PaletteRow.js +83 -0
- package/build/dist/UI/Components/CommandPalette/PaletteRow.js.map +1 -0
- package/build/dist/UI/Components/CommandPalette/RecentCommands.js +47 -0
- package/build/dist/UI/Components/CommandPalette/RecentCommands.js.map +1 -0
- package/build/dist/UI/Components/CommandPalette/Types.js +2 -0
- package/build/dist/UI/Components/CommandPalette/Types.js.map +1 -0
- package/build/dist/UI/Components/CommandPalette/UseProviderSearch.js +88 -0
- package/build/dist/UI/Components/CommandPalette/UseProviderSearch.js.map +1 -0
- package/build/dist/UI/Components/Dropdown/Dropdown.js +6 -1
- package/build/dist/UI/Components/Dropdown/Dropdown.js.map +1 -1
- package/build/dist/UI/Components/Feed/FeedItem.js +1 -1
- package/build/dist/UI/Components/Feed/FeedItem.js.map +1 -1
- package/build/dist/UI/Components/List/List.js +19 -5
- package/build/dist/UI/Components/List/List.js.map +1 -1
- package/build/dist/UI/Components/List/ListSkeleton.js +21 -0
- package/build/dist/UI/Components/List/ListSkeleton.js.map +1 -0
- package/build/dist/UI/Components/Markdown.tsx/LazyMarkdownViewer.js.map +1 -1
- package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js +52 -25
- package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js.map +1 -1
- package/build/dist/UI/Components/Modal/Modal.js +2 -2
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js +1 -1
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/useCustomFieldColumns.js +9 -2
- package/build/dist/UI/Components/ModelTable/useCustomFieldColumns.js.map +1 -1
- package/build/dist/UI/Components/MoreMenu/MoreMenu.js +32 -1
- package/build/dist/UI/Components/MoreMenu/MoreMenu.js.map +1 -1
- package/build/dist/UI/Components/Navbar/NavBar.js +5 -1
- package/build/dist/UI/Components/Navbar/NavBar.js.map +1 -1
- package/build/dist/UI/Components/OrderedStatesList/OrderedStatesList.js +29 -5
- package/build/dist/UI/Components/OrderedStatesList/OrderedStatesList.js.map +1 -1
- package/build/dist/UI/Components/SideMenu/CountModelSideMenuItem.js +23 -1
- package/build/dist/UI/Components/SideMenu/CountModelSideMenuItem.js.map +1 -1
- package/build/dist/UI/Components/SideOver/SideOver.js +23 -2
- package/build/dist/UI/Components/SideOver/SideOver.js.map +1 -1
- package/build/dist/UI/Components/Skeleton/Skeleton.js +23 -0
- package/build/dist/UI/Components/Skeleton/Skeleton.js.map +1 -0
- package/build/dist/UI/Components/Table/Table.js +35 -24
- package/build/dist/UI/Components/Table/Table.js.map +1 -1
- package/build/dist/UI/Components/Table/TableSkeletonRows.js +52 -0
- package/build/dist/UI/Components/Table/TableSkeletonRows.js.map +1 -0
- package/build/dist/UI/Components/Tabs/Tab.js +1 -1
- package/build/dist/UI/Components/Tabs/Tab.js.map +1 -1
- package/build/dist/UI/Components/Toast/Toast.js +77 -23
- package/build/dist/UI/Components/Toast/Toast.js.map +1 -1
- package/build/dist/UI/Components/Toast/ToastInit.js +37 -15
- package/build/dist/UI/Components/Toast/ToastInit.js.map +1 -1
- package/build/dist/UI/Utils/ModelAPI/ModelAPI.js +18 -9
- package/build/dist/UI/Utils/ModelAPI/ModelAPI.js.map +1 -1
- package/build/dist/UI/Utils/ModelListCache.js +126 -0
- package/build/dist/UI/Utils/ModelListCache.js.map +1 -0
- package/build/dist/UI/Utils/Project.js +24 -1
- package/build/dist/UI/Utils/Project.js.map +1 -1
- package/build/dist/Utils/API.js +6 -1
- package/build/dist/Utils/API.js.map +1 -1
- package/jest.config.json +1 -1
- package/package.json +2 -3
- package/Server/Utils/Monitor/MonitorClusterContext.ts +0 -182
- package/Tests/__mocks__/otpauth.js +0 -30
- package/build/dist/Server/Utils/Monitor/MonitorClusterContext.js +0 -141
- package/build/dist/Server/Utils/Monitor/MonitorClusterContext.js.map +0 -1
package/Types/Permission.ts
CHANGED
|
@@ -1085,6 +1085,24 @@ enum Permission {
|
|
|
1085
1085
|
ReadProjectUserNotificationRule = "ReadProjectUserNotificationRule",
|
|
1086
1086
|
EditProjectUserNotificationRule = "EditProjectUserNotificationRule",
|
|
1087
1087
|
|
|
1088
|
+
/*
|
|
1089
|
+
* Adding and removing the notification METHODS a member's rules point at:
|
|
1090
|
+
* the email address, phone number or device a page is actually delivered to.
|
|
1091
|
+
*
|
|
1092
|
+
* Separate from EditProjectUserNotificationRule, and deliberately not implied
|
|
1093
|
+
* by it. Repairing somebody's rules re-points their pages between devices
|
|
1094
|
+
* they have already proved they hold; adding a method introduces a device
|
|
1095
|
+
* nobody has proved anything about, so the two have different blast radii and
|
|
1096
|
+
* an installation must be able to hand out the first without the second.
|
|
1097
|
+
*
|
|
1098
|
+
* What it does NOT grant, and cannot: making a method live. A method added
|
|
1099
|
+
* this way lands unverified and the verification code goes to the address
|
|
1100
|
+
* itself, and every verify endpoint refuses a caller who is not the row's
|
|
1101
|
+
* owner. So this permission lets an administrator do the typing for a
|
|
1102
|
+
* colleague; only that colleague can finish it.
|
|
1103
|
+
*/
|
|
1104
|
+
ManageProjectUserNotificationMethod = "ManageProjectUserNotificationMethod",
|
|
1105
|
+
|
|
1088
1106
|
// Resource Permissions (Team Permission)
|
|
1089
1107
|
CreateProjectOnCallDutyPolicySchedule = "CreateProjectOnCallDutyPolicySchedule",
|
|
1090
1108
|
EditProjectOnCallDutyPolicySchedule = "EditProjectOnCallDutyPolicySchedule",
|
|
@@ -6068,6 +6086,23 @@ export class PermissionHelper {
|
|
|
6068
6086
|
isRolePermission: false,
|
|
6069
6087
|
group: PermissionGroup.OnCallDutyPolicy,
|
|
6070
6088
|
},
|
|
6089
|
+
/*
|
|
6090
|
+
* isRolePermission false for the same reason as the two above: a true
|
|
6091
|
+
* value would file it under getRolePermissionProps(), the list every
|
|
6092
|
+
* default project role is built from, and the ability to put a new phone
|
|
6093
|
+
* number on a colleague's account would then arrive silently with an
|
|
6094
|
+
* existing role rather than being handed out on purpose.
|
|
6095
|
+
*/
|
|
6096
|
+
{
|
|
6097
|
+
permission: Permission.ManageProjectUserNotificationMethod,
|
|
6098
|
+
title: "Manage User Notification Methods",
|
|
6099
|
+
description:
|
|
6100
|
+
"This permission can add and remove the notification methods (email, SMS, call, WhatsApp) of any user in this project, so an administrator can set up a member who cannot yet be paged at all. Addresses are only ever shown masked, an added method stays unverified until the person who owns the device verifies it, and that person is emailed about every change.",
|
|
6101
|
+
isAssignableToTenant: true,
|
|
6102
|
+
isAccessControlPermission: false,
|
|
6103
|
+
isRolePermission: false,
|
|
6104
|
+
group: PermissionGroup.OnCallDutyPolicy,
|
|
6105
|
+
},
|
|
6071
6106
|
|
|
6072
6107
|
{
|
|
6073
6108
|
permission: Permission.CreateProjectOnCallDutyPolicySchedule,
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Android delivers a notification with the settings of the channel it names,
|
|
3
|
+
* not the settings in the payload - importance, sound and Do Not Disturb
|
|
4
|
+
* bypass are all fixed when the app creates the channel and cannot be raised
|
|
5
|
+
* afterwards. So "ring through silent mode" is expressed by picking a channel,
|
|
6
|
+
* and these ids are the contract for that choice.
|
|
7
|
+
*
|
|
8
|
+
* The app creates channels with exactly these ids in
|
|
9
|
+
* MobileApp/src/notifications/channels.ts. An id sent from here that the app
|
|
10
|
+
* never created does not fail loudly: Android falls back to a default channel
|
|
11
|
+
* and the page arrives with default settings, which for an on-call page means
|
|
12
|
+
* silently. Keep the two lists in step.
|
|
13
|
+
*/
|
|
14
|
+
enum AndroidNotificationChannel {
|
|
15
|
+
/*
|
|
16
|
+
* Do Not Disturb bypass, alarm audio stream, MAX importance. Reserved for
|
|
17
|
+
* on-call pages from a device whose owner opted in and granted the app Do
|
|
18
|
+
* Not Disturb access.
|
|
19
|
+
*/
|
|
20
|
+
Critical = "oncall_critical",
|
|
21
|
+
High = "oncall_high",
|
|
22
|
+
Normal = "oncall_normal",
|
|
23
|
+
Low = "oncall_low",
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export default AndroidNotificationChannel;
|
|
@@ -13,6 +13,21 @@ interface PushNotificationMessage {
|
|
|
13
13
|
}>;
|
|
14
14
|
clickAction?: string;
|
|
15
15
|
url?: string;
|
|
16
|
+
/*
|
|
17
|
+
* Ask the handset to ring even when it is silenced or in Do Not Disturb.
|
|
18
|
+
* Reserved for on-call pages: a responder who has opted their device in has
|
|
19
|
+
* decided that being woken is the point. Everything else - owner
|
|
20
|
+
* subscriptions, note-posted, test pings - leaves this unset and respects
|
|
21
|
+
* the ringer switch like a normal notification.
|
|
22
|
+
*
|
|
23
|
+
* Honouring it is a three-way handshake, and all three have to agree or the
|
|
24
|
+
* page arrives silently:
|
|
25
|
+
* - the responder opts THIS device in (UserPush.isCriticalAlertEnabled),
|
|
26
|
+
* - the server stamps the flag onto the payload (PushNotificationService),
|
|
27
|
+
* - the OS lets it through (iOS critical-alert entitlement, or an Android
|
|
28
|
+
* channel granted Do Not Disturb access).
|
|
29
|
+
*/
|
|
30
|
+
isCriticalAlert?: boolean;
|
|
16
31
|
}
|
|
17
32
|
|
|
18
33
|
export default PushNotificationMessage;
|
|
@@ -1,26 +1,18 @@
|
|
|
1
1
|
import PushDeviceType from "./PushDeviceType";
|
|
2
|
+
import PushNotificationMessage from "./PushNotificationMessage";
|
|
2
3
|
|
|
3
4
|
interface PushNotificationRequest {
|
|
4
5
|
devices: Array<{
|
|
5
6
|
token: string;
|
|
6
7
|
name?: string;
|
|
7
8
|
}>;
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
requireInteraction?: boolean;
|
|
16
|
-
actions?: Array<{
|
|
17
|
-
action: string;
|
|
18
|
-
title: string;
|
|
19
|
-
icon?: string;
|
|
20
|
-
}>;
|
|
21
|
-
clickAction?: string;
|
|
22
|
-
url?: string;
|
|
23
|
-
};
|
|
9
|
+
/*
|
|
10
|
+
* The same shape PushNotificationUtil builds, referenced rather than
|
|
11
|
+
* restated: this used to be a copy of every field in PushNotificationMessage,
|
|
12
|
+
* and a copy is a place for a newly added field to go missing on the way to
|
|
13
|
+
* the sender.
|
|
14
|
+
*/
|
|
15
|
+
message: PushNotificationMessage;
|
|
24
16
|
deviceType: PushDeviceType;
|
|
25
17
|
}
|
|
26
18
|
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import TechStack from "./TechStack";
|
|
2
|
+
|
|
3
|
+
/*
|
|
4
|
+
* Which runtime a telemetry service is written in, and how to work that out
|
|
5
|
+
* from what the service actually reported.
|
|
6
|
+
*
|
|
7
|
+
* This started life inside the dashboard's service-overview charts
|
|
8
|
+
* (`serviceGoldenMetrics.ts`), where it picked which runtime charts to draw.
|
|
9
|
+
* It lives in Common now because a second consumer needs the same answer from
|
|
10
|
+
* a place the dashboard cannot reach: the monitor recommendation catalog. The
|
|
11
|
+
* recommendations a Java service should get (JVM heap pressure, GC pause
|
|
12
|
+
* time, thread exhaustion) have nothing in common with the ones a Go service
|
|
13
|
+
* should get (goroutine leaks, GC cycles), and the catalog runs in Common.
|
|
14
|
+
*
|
|
15
|
+
* `serviceGoldenMetrics.ts` re-exports everything here, so the dashboard's
|
|
16
|
+
* existing import paths are unchanged.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
// Canonical values of the telemetry.sdk.language resource attribute.
|
|
20
|
+
export type ServiceLanguage =
|
|
21
|
+
| "java"
|
|
22
|
+
| "dotnet"
|
|
23
|
+
| "nodejs"
|
|
24
|
+
| "python"
|
|
25
|
+
| "go"
|
|
26
|
+
| "ruby"
|
|
27
|
+
| "php"
|
|
28
|
+
| "rust"
|
|
29
|
+
| "erlang"
|
|
30
|
+
| "swift"
|
|
31
|
+
| "cpp"
|
|
32
|
+
| "webjs";
|
|
33
|
+
|
|
34
|
+
export const SERVICE_LANGUAGE_DISPLAY_NAMES: Record<ServiceLanguage, string> = {
|
|
35
|
+
java: "Java",
|
|
36
|
+
dotnet: ".NET",
|
|
37
|
+
nodejs: "Node.js",
|
|
38
|
+
python: "Python",
|
|
39
|
+
go: "Go",
|
|
40
|
+
ruby: "Ruby",
|
|
41
|
+
php: "PHP",
|
|
42
|
+
rust: "Rust",
|
|
43
|
+
erlang: "Erlang / Elixir",
|
|
44
|
+
swift: "Swift",
|
|
45
|
+
cpp: "C++",
|
|
46
|
+
webjs: "Browser JS",
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
const KNOWN_LANGUAGES: Array<ServiceLanguage> = Object.keys(
|
|
50
|
+
SERVICE_LANGUAGE_DISPLAY_NAMES,
|
|
51
|
+
) as Array<ServiceLanguage>;
|
|
52
|
+
|
|
53
|
+
/*
|
|
54
|
+
* process.runtime.name values seen in the wild → language. Checked as
|
|
55
|
+
* case-insensitive substrings, so "OpenJDK Runtime Environment" → java.
|
|
56
|
+
* Ordered: more specific markers first ("graalvm" before "go").
|
|
57
|
+
*/
|
|
58
|
+
const RUNTIME_NAME_MARKERS: Array<{ marker: string; lang: ServiceLanguage }> = [
|
|
59
|
+
{ marker: "openjdk", lang: "java" },
|
|
60
|
+
{ marker: "graalvm", lang: "java" },
|
|
61
|
+
{ marker: "java", lang: "java" },
|
|
62
|
+
{ marker: "dotnet", lang: "dotnet" },
|
|
63
|
+
{ marker: ".net", lang: "dotnet" },
|
|
64
|
+
{ marker: "node", lang: "nodejs" },
|
|
65
|
+
{ marker: "deno", lang: "nodejs" },
|
|
66
|
+
{ marker: "bun", lang: "nodejs" },
|
|
67
|
+
{ marker: "cpython", lang: "python" },
|
|
68
|
+
{ marker: "pypy", lang: "python" },
|
|
69
|
+
{ marker: "python", lang: "python" },
|
|
70
|
+
{ marker: "beam", lang: "erlang" },
|
|
71
|
+
{ marker: "erlang", lang: "erlang" },
|
|
72
|
+
{ marker: "ruby", lang: "ruby" },
|
|
73
|
+
{ marker: "php", lang: "php" },
|
|
74
|
+
{ marker: "rust", lang: "rust" },
|
|
75
|
+
{ marker: "swift", lang: "swift" },
|
|
76
|
+
{ marker: "go", lang: "go" },
|
|
77
|
+
];
|
|
78
|
+
|
|
79
|
+
// Manual tech-stack selections → language (JVM languages map to java).
|
|
80
|
+
const TECH_STACK_LANGUAGES: Partial<Record<TechStack, ServiceLanguage>> = {
|
|
81
|
+
[TechStack.Java]: "java",
|
|
82
|
+
[TechStack.Kotlin]: "java",
|
|
83
|
+
[TechStack.CSharp]: "dotnet",
|
|
84
|
+
[TechStack.NodeJS]: "nodejs",
|
|
85
|
+
[TechStack.TypeScript]: "nodejs",
|
|
86
|
+
[TechStack.JavaScript]: "nodejs",
|
|
87
|
+
[TechStack.React]: "webjs",
|
|
88
|
+
[TechStack.Python]: "python",
|
|
89
|
+
[TechStack.Go]: "go",
|
|
90
|
+
[TechStack.Ruby]: "ruby",
|
|
91
|
+
[TechStack.PHP]: "php",
|
|
92
|
+
[TechStack.Rust]: "rust",
|
|
93
|
+
[TechStack.Swift]: "swift",
|
|
94
|
+
[TechStack.CPlusPlus]: "cpp",
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
/*
|
|
98
|
+
* Best-effort language for a service, in descending order of trust:
|
|
99
|
+
*
|
|
100
|
+
* 1. `telemetry.sdk.language` — stamped by the SDK itself, so it is what the
|
|
101
|
+
* process actually runs on rather than what anyone believes it runs on.
|
|
102
|
+
* 2. `process.runtime.name` — present when runtime instrumentation is on but
|
|
103
|
+
* the SDK attribute did not survive a collector hop.
|
|
104
|
+
* 3. The manually-chosen tech stack — a human's answer, used only when the
|
|
105
|
+
* telemetry has not answered.
|
|
106
|
+
*
|
|
107
|
+
* Returns null when nothing identifies the runtime. Callers must treat that as
|
|
108
|
+
* "unknown", never as a default language: recommending JVM heap monitors to a
|
|
109
|
+
* service that turns out to be Go is worse than recommending nothing.
|
|
110
|
+
*/
|
|
111
|
+
export const detectServiceLanguage: (data: {
|
|
112
|
+
telemetrySdkLanguage?: string | undefined;
|
|
113
|
+
runtimeName?: string | undefined;
|
|
114
|
+
techStack?: Array<TechStack> | undefined;
|
|
115
|
+
}) => ServiceLanguage | null = (data: {
|
|
116
|
+
telemetrySdkLanguage?: string | undefined;
|
|
117
|
+
runtimeName?: string | undefined;
|
|
118
|
+
techStack?: Array<TechStack> | undefined;
|
|
119
|
+
}): ServiceLanguage | null => {
|
|
120
|
+
const sdkLanguage: string = (data.telemetrySdkLanguage || "")
|
|
121
|
+
.trim()
|
|
122
|
+
.toLowerCase();
|
|
123
|
+
if (sdkLanguage && KNOWN_LANGUAGES.includes(sdkLanguage as ServiceLanguage)) {
|
|
124
|
+
return sdkLanguage as ServiceLanguage;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const runtimeName: string = (data.runtimeName || "").trim().toLowerCase();
|
|
128
|
+
if (runtimeName) {
|
|
129
|
+
for (const entry of RUNTIME_NAME_MARKERS) {
|
|
130
|
+
if (runtimeName.includes(entry.marker)) {
|
|
131
|
+
return entry.lang;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
for (const stack of data.techStack || []) {
|
|
137
|
+
const lang: ServiceLanguage | undefined = TECH_STACK_LANGUAGES[stack];
|
|
138
|
+
if (lang) {
|
|
139
|
+
return lang;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
return null;
|
|
144
|
+
};
|
package/Types/Text.ts
CHANGED
|
@@ -236,21 +236,117 @@ export default class Text {
|
|
|
236
236
|
return null;
|
|
237
237
|
}
|
|
238
238
|
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
239
|
+
/*
|
|
240
|
+
* Cryptographically secure random bytes, or null if this runtime has no
|
|
241
|
+
* CSPRNG at all.
|
|
242
|
+
*
|
|
243
|
+
* `globalThis.crypto` is the Web Crypto API: present in every browser, and a
|
|
244
|
+
* global in Node since 19. It is used here rather than `require("crypto")`
|
|
245
|
+
* because this file is bundled into the dashboard as well as the server, so
|
|
246
|
+
* it cannot reach for a Node built-in.
|
|
247
|
+
*/
|
|
248
|
+
private static getSecureRandomBytes(byteCount: number): Uint8Array | null {
|
|
249
|
+
const webCrypto: { getRandomValues?: (array: Uint8Array) => Uint8Array } =
|
|
250
|
+
(
|
|
251
|
+
globalThis as unknown as {
|
|
252
|
+
crypto?: { getRandomValues?: (array: Uint8Array) => Uint8Array };
|
|
253
|
+
}
|
|
254
|
+
).crypto || {};
|
|
255
|
+
|
|
256
|
+
if (typeof webCrypto.getRandomValues !== "function") {
|
|
257
|
+
return null;
|
|
242
258
|
}
|
|
243
259
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
260
|
+
return webCrypto.getRandomValues(new Uint8Array(byteCount));
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/*
|
|
264
|
+
* Draw `length` characters uniformly at random from `characters`.
|
|
265
|
+
*
|
|
266
|
+
* TWO properties here are load-bearing, and this used to have neither:
|
|
267
|
+
*
|
|
268
|
+
* 1. The source is a CSPRNG. Math.random is a fast non-cryptographic PRNG
|
|
269
|
+
* (xorshift128+ in V8) whose entire internal state can be recovered from
|
|
270
|
+
* a handful of observed outputs and then run forwards AND backwards. For
|
|
271
|
+
* a value used as a secret that is worse than a short code: an attacker
|
|
272
|
+
* who sees one generated value predicts the next one exactly, with no
|
|
273
|
+
* guessing at all.
|
|
274
|
+
*
|
|
275
|
+
* 2. The draw is unbiased. `byte % n` is only uniform when n divides 256.
|
|
276
|
+
* Rejection sampling discards the short tail of the byte range instead of
|
|
277
|
+
* folding it, which is what keeps a k-character code at its full
|
|
278
|
+
* k * log2(n) bits of entropy.
|
|
279
|
+
*
|
|
280
|
+
* The Math.random fallback survives ONLY for the case where no CSPRNG exists
|
|
281
|
+
* at all, which is unreachable on any supported runtime. It is there so the
|
|
282
|
+
* non-secret callers - SQL alias suffixes in QueryHelper and friends, which
|
|
283
|
+
* run on every query - cannot be broken by an exotic environment. Secrets
|
|
284
|
+
* must NOT come through here: notification-channel codes go through
|
|
285
|
+
* Common/Server/Utils/VerificationCode.ts, which throws rather than
|
|
286
|
+
* downgrading.
|
|
287
|
+
*/
|
|
288
|
+
private static generateRandomString(
|
|
289
|
+
length: number,
|
|
290
|
+
characters: string,
|
|
291
|
+
): string {
|
|
247
292
|
const charactersLength: number = characters.length;
|
|
248
|
-
|
|
249
|
-
|
|
293
|
+
|
|
294
|
+
/*
|
|
295
|
+
* The largest multiple of charactersLength that fits in a byte. Bytes at
|
|
296
|
+
* or above it are thrown away rather than folded - that is the whole of
|
|
297
|
+
* the rejection sampling, and skipping it is what biases the result.
|
|
298
|
+
*/
|
|
299
|
+
const unbiasedCeiling: number = 256 - (256 % charactersLength);
|
|
300
|
+
|
|
301
|
+
let result: string = "";
|
|
302
|
+
|
|
303
|
+
while (result.length < length) {
|
|
304
|
+
const remaining: number = length - result.length;
|
|
305
|
+
|
|
306
|
+
/*
|
|
307
|
+
* Over-draw a little so a rejected byte usually does not cost a second
|
|
308
|
+
* trip into the CSPRNG. With a 10-character alphabet fewer than 3% of
|
|
309
|
+
* bytes are rejected, so one pass almost always finishes the job.
|
|
310
|
+
*/
|
|
311
|
+
const bytes: Uint8Array | null = Text.getSecureRandomBytes(
|
|
312
|
+
remaining + Math.ceil(remaining / 4) + 4,
|
|
313
|
+
);
|
|
314
|
+
|
|
315
|
+
if (!bytes) {
|
|
316
|
+
while (result.length < length) {
|
|
317
|
+
result += characters.charAt(
|
|
318
|
+
Math.floor(Math.random() * charactersLength),
|
|
319
|
+
);
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
return result;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
for (let i: number = 0; i < bytes.length; i++) {
|
|
326
|
+
if (result.length >= length) {
|
|
327
|
+
break;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
const byte: number | undefined = bytes[i];
|
|
331
|
+
|
|
332
|
+
if (byte === undefined || byte >= unbiasedCeiling) {
|
|
333
|
+
continue;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
result += characters.charAt(byte % charactersLength);
|
|
337
|
+
}
|
|
250
338
|
}
|
|
339
|
+
|
|
251
340
|
return result;
|
|
252
341
|
}
|
|
253
342
|
|
|
343
|
+
public static generateRandomText(length?: number): string {
|
|
344
|
+
return Text.generateRandomString(
|
|
345
|
+
length || 10,
|
|
346
|
+
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
|
|
347
|
+
);
|
|
348
|
+
}
|
|
349
|
+
|
|
254
350
|
public static trimLines(text: string): string {
|
|
255
351
|
return text
|
|
256
352
|
.split("\n")
|
|
@@ -260,18 +356,14 @@ export default class Text {
|
|
|
260
356
|
.join("\n");
|
|
261
357
|
}
|
|
262
358
|
|
|
359
|
+
/*
|
|
360
|
+
* The alphabet used to be the string "12134567890" - eleven characters, with
|
|
361
|
+
* "1" written twice and every digit therefore NOT equally likely. Combined
|
|
362
|
+
* with Math.random that made a six-digit code both biased and predictable.
|
|
363
|
+
* Both halves are fixed in generateRandomString above.
|
|
364
|
+
*/
|
|
263
365
|
public static generateRandomNumber(length?: number): string {
|
|
264
|
-
|
|
265
|
-
length = 10;
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
let result: string = "";
|
|
269
|
-
const characters: string = "12134567890";
|
|
270
|
-
const charactersLength: number = characters.length;
|
|
271
|
-
for (let i: number = 0; i < length; i++) {
|
|
272
|
-
result += characters.charAt(Math.floor(Math.random() * charactersLength));
|
|
273
|
-
}
|
|
274
|
-
return result;
|
|
366
|
+
return Text.generateRandomString(length || 10, "0123456789");
|
|
275
367
|
}
|
|
276
368
|
|
|
277
369
|
public static convertNumberToWords(num: number): string {
|
|
@@ -91,22 +91,28 @@ const Button: FunctionComponent<ComponentProps> = ({
|
|
|
91
91
|
const translatedTitle: string | undefined = translateString(title);
|
|
92
92
|
const translatedTooltip: string | undefined = translateString(tooltip);
|
|
93
93
|
useEffect(() => {
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
window.addEventListener(`keydown`, (e: KeyboardEventProp) => {
|
|
97
|
-
return handleKeyboard(e);
|
|
98
|
-
});
|
|
94
|
+
if (!shortcutKey) {
|
|
95
|
+
return undefined;
|
|
99
96
|
}
|
|
100
97
|
|
|
101
|
-
|
|
98
|
+
/*
|
|
99
|
+
* One stable function for the whole subscription. The previous version
|
|
100
|
+
* passed a fresh arrow function to removeEventListener, which never
|
|
101
|
+
* matches the one that was added — every render leaked a live keydown
|
|
102
|
+
* listener for the lifetime of the page.
|
|
103
|
+
*/
|
|
104
|
+
const onKeyDown: (event: KeyboardEventProp) => void = (
|
|
105
|
+
event: KeyboardEventProp,
|
|
106
|
+
): void => {
|
|
107
|
+
return handleKeyboard(event);
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
window.addEventListener(`keydown`, onKeyDown);
|
|
111
|
+
|
|
102
112
|
return () => {
|
|
103
|
-
|
|
104
|
-
window.removeEventListener(`keydown`, (e: KeyboardEventProp) => {
|
|
105
|
-
return handleKeyboard(e);
|
|
106
|
-
});
|
|
107
|
-
}
|
|
113
|
+
window.removeEventListener(`keydown`, onKeyDown);
|
|
108
114
|
};
|
|
109
|
-
});
|
|
115
|
+
}, [shortcutKey, onClick]);
|
|
110
116
|
|
|
111
117
|
type HandleKeyboardFunction = (event: KeyboardEventProp) => void;
|
|
112
118
|
|
|
@@ -141,7 +147,7 @@ const Button: FunctionComponent<ComponentProps> = ({
|
|
|
141
147
|
}
|
|
142
148
|
|
|
143
149
|
if (buttonStyle === ButtonStyleType.LINK) {
|
|
144
|
-
buttonStyleCssClass = `text-indigo-600 hover:text-indigo-900 space-x-2`;
|
|
150
|
+
buttonStyleCssClass = `text-indigo-600 hover:text-indigo-900 space-x-2 focus:outline-none focus-visible:ring-2 focus-visible:ring-indigo-500 focus-visible:ring-offset-2`;
|
|
145
151
|
|
|
146
152
|
if (icon) {
|
|
147
153
|
buttonStyleCssClass += ` flex`;
|
|
@@ -149,7 +155,7 @@ const Button: FunctionComponent<ComponentProps> = ({
|
|
|
149
155
|
}
|
|
150
156
|
|
|
151
157
|
if (buttonStyle === ButtonStyleType.SECONDARY_LINK) {
|
|
152
|
-
buttonStyleCssClass = `text-sm text-gray-400 hover:text-gray-500 space-x-2`;
|
|
158
|
+
buttonStyleCssClass = `text-sm text-gray-400 hover:text-gray-500 space-x-2 focus:outline-none focus-visible:ring-2 focus-visible:ring-indigo-500 focus-visible:ring-offset-2`;
|
|
153
159
|
|
|
154
160
|
if (icon) {
|
|
155
161
|
buttonStyleCssClass += ` flex`;
|
|
@@ -239,6 +245,13 @@ const Button: FunctionComponent<ComponentProps> = ({
|
|
|
239
245
|
} focus:outline-none focus:ring-2 focus:ring-yellow-500 focus:ring-offset-2 md:mt-0 md:ml-3 md:w-auto md:text-sm`;
|
|
240
246
|
}
|
|
241
247
|
|
|
248
|
+
/*
|
|
249
|
+
* The one shared point every variant funnels through: hover/focus colour
|
|
250
|
+
* changes ease in instead of snapping, at the same 150ms the other
|
|
251
|
+
* primitives use.
|
|
252
|
+
*/
|
|
253
|
+
buttonStyleCssClass += ` transition-colors duration-150 ease-out`;
|
|
254
|
+
|
|
242
255
|
buttonStyleCssClass += ` ` + buttonSize;
|
|
243
256
|
|
|
244
257
|
if (className) {
|
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
import "highlight.js/styles/a11y-dark.css";
|
|
2
|
-
import React, {
|
|
3
|
-
|
|
2
|
+
import React, {
|
|
3
|
+
FunctionComponent,
|
|
4
|
+
ReactElement,
|
|
5
|
+
useMemo,
|
|
6
|
+
useState,
|
|
7
|
+
} from "react";
|
|
8
|
+
/*
|
|
9
|
+
* Trimmed highlight.js instance — lib/core plus only the languages CodeBlock
|
|
10
|
+
* callers actually pass (see the audit in LanguageRegistry.ts). Replaces
|
|
11
|
+
* react-highlight, which imported all 194 grammars (~1.5MB) eagerly.
|
|
12
|
+
*/
|
|
13
|
+
import hljs, { resolveRegisteredLanguage } from "./LanguageRegistry";
|
|
4
14
|
import Icon from "../Icon/Icon";
|
|
5
15
|
import IconProp from "../../../Types/Icon/IconProp";
|
|
6
16
|
|
|
@@ -31,6 +41,38 @@ const CodeBlock: FunctionComponent<ComponentProps> = (
|
|
|
31
41
|
const maxHeight: string = props.maxHeight || "500px";
|
|
32
42
|
const showCopyButton: boolean = props.showCopyButton !== false;
|
|
33
43
|
|
|
44
|
+
/*
|
|
45
|
+
* react-highlight rendered <pre><code className>…</code></pre> and then ran
|
|
46
|
+
* hljs.highlightBlock over the DOM after mount (reading the language from
|
|
47
|
+
* the `language-*` class and adding the theme's `hljs` class). We keep that
|
|
48
|
+
* exact DOM shape but highlight synchronously: registered language → hljs
|
|
49
|
+
* token markup (hljs.highlight escapes the source before wrapping it in
|
|
50
|
+
* spans, so the HTML is safe to inject); unregistered language or a
|
|
51
|
+
* ReactElement child → plain React-escaped rendering. hljs is never called
|
|
52
|
+
* with an unknown language, so it never logs lookup warnings.
|
|
53
|
+
*/
|
|
54
|
+
const registeredLanguage: string | null =
|
|
55
|
+
typeof props.code === "string"
|
|
56
|
+
? resolveRegisteredLanguage(props.language)
|
|
57
|
+
: null;
|
|
58
|
+
|
|
59
|
+
const highlightedHtml: string | null = useMemo((): string | null => {
|
|
60
|
+
if (typeof props.code !== "string" || !registeredLanguage) {
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return hljs.highlight(props.code, {
|
|
65
|
+
language: registeredLanguage,
|
|
66
|
+
ignoreIllegals: true,
|
|
67
|
+
}).value;
|
|
68
|
+
}, [props.code, registeredLanguage]);
|
|
69
|
+
|
|
70
|
+
/*
|
|
71
|
+
* `hljs` carries the a11y-dark theme background; react-highlight added it
|
|
72
|
+
* post-mount, we add it up front so there is no unstyled first paint.
|
|
73
|
+
*/
|
|
74
|
+
const codeClassName: string = `hljs p-4 language-${props.language} text-sm leading-relaxed`;
|
|
75
|
+
|
|
34
76
|
return (
|
|
35
77
|
<div className="relative group">
|
|
36
78
|
{showCopyButton && typeof props.code === "string" && (
|
|
@@ -51,11 +93,16 @@ const CodeBlock: FunctionComponent<ComponentProps> = (
|
|
|
51
93
|
className="overflow-auto rounded-lg border border-gray-700"
|
|
52
94
|
style={{ maxHeight: maxHeight }}
|
|
53
95
|
>
|
|
54
|
-
<
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
96
|
+
<pre>
|
|
97
|
+
{highlightedHtml !== null ? (
|
|
98
|
+
<code
|
|
99
|
+
className={codeClassName}
|
|
100
|
+
dangerouslySetInnerHTML={{ __html: highlightedHtml }}
|
|
101
|
+
/>
|
|
102
|
+
) : (
|
|
103
|
+
<code className={codeClassName}>{props.code}</code>
|
|
104
|
+
)}
|
|
105
|
+
</pre>
|
|
59
106
|
</div>
|
|
60
107
|
</div>
|
|
61
108
|
);
|