Compare commits

...

2157 Commits

Author SHA1 Message Date
Nawaz Dhandala
100f46ab3c fix: update badge styles for previous and current state indicators in StateTransition template 2025-12-05 19:02:52 +00:00
Nawaz Dhandala
e21d080e6f fix: add previous status and color to notification data in SendStatusChangeNotification 2025-12-05 18:55:49 +00:00
Nawaz Dhandala
3740382e76 fix: enhance status badge display with color indicators in StatusTransition template 2025-12-05 18:53:41 +00:00
Nawaz Dhandala
d3864e268b fix: improve table styling and layout in StatusPageSubscriberReport template 2025-12-05 17:42:29 +00:00
Nawaz Dhandala
d3db3fd174 fix: remove outdated reliability copilot workflow file 2025-12-05 13:52:27 +00:00
Nawaz Dhandala
9f9e337350 chore: update version number to 9.2.8 2025-12-05 13:45:39 +00:00
Nawaz Dhandala
1e84ece07e fix: simplify import statements in Queue.ts for better clarity 2025-12-05 13:32:17 +00:00
Nawaz Dhandala
ee4981bd19 fix: enhance job handling in Queue class to manage repeatable jobs 2025-12-05 13:31:25 +00:00
Nawaz Dhandala
f8802eea24 fix: format code for better readability in Landing.spec.ts 2025-12-05 11:10:15 +00:00
Nawaz Dhandala
5b45cab822 fix: update link selector for OneUptime in Landing.spec.ts 2025-12-05 11:03:33 +00:00
Simon Larsen
908f16d769 Merge pull request #2159 from OneUptime/snyk-upgrade-2036816bc1d34768c430f289cb384bca
[Snyk] Upgrade react-router-dom from 6.30.1 to 6.30.2
2025-12-05 08:41:21 +00:00
Simon Larsen
e4852e5799 Merge pull request #2160 from OneUptime/chore/npm-audit-fix
chore: npm audit fix
2025-12-05 08:41:14 +00:00
simlarsen
06e672abdd chore: npm audit fix 2025-12-05 01:51:29 +00:00
snyk-bot
efed184276 fix: upgrade react-router-dom from 6.30.1 to 6.30.2
Snyk has created this PR to upgrade react-router-dom from 6.30.1 to 6.30.2.

See this package in npm:
react-router-dom

See this project in Snyk:
https://app.snyk.io/org/oneuptime-RsC2nshvQ2Vnr35jHvMnMP/project/5dd2ef9c-1270-4729-aff4-e407805f7a9c?utm_source=github&utm_medium=referral&page=upgrade-pr
2025-12-05 00:44:09 +00:00
Simon Larsen
9bd14ec3f3 Merge pull request #2158 from OneUptime/monitor-more-info
refactor: implement detailed error handling for request failures acro…
2025-12-04 22:00:18 +00:00
Nawaz Dhandala
9950f1502e refactor: enhance promise handling and error rejection in DNS and traceroute operations 2025-12-04 21:57:42 +00:00
Nawaz Dhandala
43432261e1 refactor: improve formatting and readability in error handling and network monitoring code 2025-12-04 21:54:13 +00:00
Nawaz Dhandala
bd2b8ba1fb refactor: add detailed logging for request failure scenarios in monitor response 2025-12-04 21:48:27 +00:00
Nawaz Dhandala
03742ab6f4 refactor: implement detailed error handling for request failures across monitors 2025-12-04 20:25:55 +00:00
Nawaz Dhandala
7324bff68b refactor: add NetworkPathTrace and NetworkPathMonitor for comprehensive network diagnostics 2025-12-04 19:46:34 +00:00
Nawaz Dhandala
8dbfa524e5 refactor: enhance error message validation in API error handling 2025-12-04 18:15:50 +00:00
Nawaz Dhandala
b2ef34f45f refactor: improve error handling in API class for more meaningful messages 2025-12-04 18:14:54 +00:00
Nawaz Dhandala
1ec9c885f3 refactor: enhance type annotations for SEO-related functions and improve sitemap entry configuration 2025-12-04 15:20:23 +00:00
Nawaz Dhandala
007973aa86 refactor: improve code formatting for better readability in Routes and Sitemap 2025-12-04 15:10:49 +00:00
Nawaz Dhandala
500101350f refactor: update version check logic to prevent re-releasing existing versions 2025-12-04 15:01:36 +00:00
Nawaz Dhandala
524fcae430 chore: update version number to 9.2.7 2025-12-04 15:00:26 +00:00
Nawaz Dhandala
7ec8fc5b1c chore: revert version number to 9.2.5 2025-12-04 15:00:09 +00:00
Nawaz Dhandala
6af3daa98e chore: update version number to 9.2.7 2025-12-04 14:41:16 +00:00
Nawaz Dhandala
1d35614cd3 refactor: correct grammar in the blog call-to-action header for clarity 2025-12-04 14:40:34 +00:00
Nawaz Dhandala
91219c9a96 refactor: correct grammar and improve consistency in meta descriptions and content across multiple views 2025-12-04 14:29:32 +00:00
Nawaz Dhandala
65ca7623d5 refactor: correct pluralization in product descriptions for consistency 2025-12-04 14:29:29 +00:00
Nawaz Dhandala
c569977b45 refactor: enhance sitemap configuration with detailed priority and change frequency settings 2025-12-04 14:28:47 +00:00
Nawaz Dhandala
2263916a9f refactor: implement SEO enhancements with structured metadata and dynamic canonical URLs 2025-12-04 14:26:47 +00:00
Nawaz Dhandala
2cca728dfc refactor: improve accessibility by enhancing skip link and alt text for logo 2025-12-04 14:20:58 +00:00
Nawaz Dhandala
ed687a1639 refactor: enhance alt text for images and wrap main content in <main> tags for improved accessibility 2025-12-04 14:17:52 +00:00
Nawaz Dhandala
270199806c refactor: remove LLM-related Docker workflows and associated files 2025-12-04 13:47:12 +00:00
Nawaz Dhandala
30a3c5e1b2 refactor: improve type definition for getMetricChartType in DashboardChartComponent 2025-12-04 13:38:55 +00:00
Nawaz Dhandala
0c5bd31023 refactor: remove unused chart type determination logic in MonitorMetrics 2025-12-04 13:32:44 +00:00
Nawaz Dhandala
84a75b7af6 chore: bump version to 9.2.6 2025-12-04 13:30:27 +00:00
Nawaz Dhandala
e25be96040 feat: add rounded corners to BarChart rendering for improved aesthetics 2025-12-04 13:29:48 +00:00
Nawaz Dhandala
7777f7d9aa feat: add syncid prop to BarChart component for synchronized chart rendering 2025-12-04 13:15:09 +00:00
Nawaz Dhandala
8e37df3fc0 feat: add dropdown support for chart type selection in Dashboard components 2025-12-04 12:43:55 +00:00
Nawaz Dhandala
88c9e0beb5 feat: add BarChart component and integrate chart type handling in MetricCharts and MonitorMetrics 2025-12-04 12:36:41 +00:00
Nawaz Dhandala
d751537473 feat: add migration for postmortemPostedAt column in Incident table 2025-12-04 12:22:50 +00:00
Nawaz Dhandala
60be6c00e9 chore: bump version to 9.2.5 2025-12-04 11:45:50 +00:00
Nawaz Dhandala
91bf55dc20 refactor: simplify logging for previous status duration and improve code formatting 2025-12-04 09:17:31 +00:00
Nawaz Dhandala
d20a125742 refactor: update previous status duration handling in notification template and logging 2025-12-04 09:14:41 +00:00
Nawaz Dhandala
d10bcd2edd refactor: enhance code readability by adding comments for previous status duration calculation 2025-12-04 08:59:04 +00:00
Nawaz Dhandala
0b32408bf2 refactor: update notification template and improve duration calculation logic 2025-12-04 08:58:42 +00:00
Nawaz Dhandala
269fbd3f24 feat: add dep-check script and remove tsconfig-paths from devDependencies 2025-12-04 08:51:40 +00:00
Nawaz Dhandala
2640ea8c10 refactor: streamline previous status duration calculation in notification 2025-12-03 23:21:07 +00:00
Nawaz Dhandala
f3180d3a83 feat: add previous status duration calculation to status change notification 2025-12-03 23:18:35 +00:00
Nawaz Dhandala
7727fe835f refactor: improve parameter destructuring for createIncidentStateChangedNotification method 2025-12-03 23:17:23 +00:00
Nawaz Dhandala
00fbfbc08e chore: bump version to 9.2.4 2025-12-03 23:08:21 +00:00
Nawaz Dhandala
44d1183066 feat: add monitor destination and request type details to notification templates and services 2025-12-03 23:08:04 +00:00
Nawaz Dhandala
0ccef797ab chore: bump version to 9.2.3 2025-12-03 22:44:46 +00:00
Nawaz Dhandala
9914fb905f fix: update background color for previous and current state/status badges to transparent 2025-12-03 22:43:03 +00:00
Nawaz Dhandala
35ecc19ceb fix: update background color for current state/status badge in notification templates 2025-12-03 22:37:01 +00:00
Nawaz Dhandala
fa0362f739 feat: update notification templates to include state transition details for alerts, incidents, monitors, and scheduled maintenance 2025-12-03 22:36:09 +00:00
Nawaz Dhandala
8ea9084d9e feat: enhance notification templates and logic to include previous state information for alerts, incidents, monitors, and scheduled maintenance 2025-12-03 22:25:45 +00:00
Simon Larsen
eeb31a2250 Merge pull request #2154 from OneUptime/email-improve
Email improve
2025-12-03 21:40:46 +00:00
Nawaz Dhandala
b58c91dbab fix: update version number to 9.2.2 2025-12-03 21:40:11 +00:00
Nawaz Dhandala
868bf4d3e1 fix: remove unnecessary empty row from DetailBoxEnd template for improved clarity 2025-12-03 21:37:20 +00:00
Nawaz Dhandala
a3fc20b393 fix: update incident and event title fields for improved clarity in email templates 2025-12-03 21:14:32 +00:00
Nawaz Dhandala
c8dad04b5c fix: add border-radius to logo images for improved aesthetics 2025-12-03 21:10:15 +00:00
Nawaz Dhandala
ee7db393f8 fix: update email templates to remove empty fields for improved clarity 2025-12-03 21:06:09 +00:00
Nawaz Dhandala
e52da9fef2 fix: remove emojis from email titles for consistency 2025-12-03 21:00:19 +00:00
Nawaz Dhandala
9332df5648 Refactor email templates for improved styling and structure
- Updated EmailTitle template to enhance title styling and added a title block comment.
- Adjusted spacing in End and Footer templates for better layout.
- Enhanced Footer template with new styling and added a powered by link.
- Modified InfoBlock template for improved text styling and added an info block comment.
- Refined Start template with new background color and added a top spacer.
- Updated Style template with new link and badge styles for better visual consistency.
- Enhanced SupportBlock template with a more engaging support message.
- Improved Thanks template with a more personalized closing message.
- Added TitleBlock comments for better organization.
- Updated UnsubscribeBlock for clearer subscription management options.
- Replaced VerticalSpace with a table-based spacer for consistent spacing.
- Enhanced SignupWelcomeEmail with improved messaging and button text.
- Updated SubscriberAnnouncementCreated template for better clarity and button integration.
- Refined SubscriberIncidentCreated template for improved incident details presentation.
- Enhanced SubscriberIncidentPostmortemCreated template for better postmortem details.
- Updated SubscriberIncidentStateChanged template for clearer incident state updates.
- Refined SubscriberScheduledMaintenanceEventCreated template for better event details.
- Introduced StatusBadge template for consistent incident status representation.
2025-12-03 20:40:46 +00:00
Nawaz Dhandala
120fc2ad71 fix: change field type for subscriber notification from Toggle to Checkbox 2025-12-03 19:35:49 +00:00
Nawaz Dhandala
1a7672748f fix: update title for status page visibility and add conditional display for subscriber notification 2025-12-03 19:35:07 +00:00
Nawaz Dhandala
4868e285b0 fix: simplify description for postmortem published timestamp field 2025-12-03 19:30:08 +00:00
Nawaz Dhandala
f572eb6f93 feat: add subscriber notification fields and migration for postmortem 2025-12-03 19:18:43 +00:00
Nawaz Dhandala
a0868e2f75 feat: add subscriber notification status and resend functionality in postmortem 2025-12-03 19:16:49 +00:00
Nawaz Dhandala
3dfd7a9206 feat: set subscriber notification status to Pending on postmortem published 2025-12-03 19:12:42 +00:00
Nawaz Dhandala
d7582337bf fix: remove ignoreHooks option from incident status update in postmortem notification 2025-12-03 19:11:00 +00:00
Nawaz Dhandala
23043462d7 fix: correct incident number retrieval in postmortem notification logic 2025-12-03 19:08:29 +00:00
Nawaz Dhandala
76d53c53c8 feat: add notifySubscribersOnPostmortemPublished toggle to postmortem form 2025-12-03 19:06:40 +00:00
Nawaz Dhandala
4437e912a3 feat: add notifySubscribersOnPostmortemPublished field and update notification logic 2025-12-03 19:05:28 +00:00
Nawaz Dhandala
937d4675a8 feat: add postmortem notification system for subscribers 2025-12-03 19:03:02 +00:00
Nawaz Dhandala
3cc984f149 Merge branch 'master' into release 2025-12-03 18:53:12 +00:00
Nawaz Dhandala
991928a5a5 fix: update version to 9.2.1 2025-12-03 18:53:05 +00:00
Nawaz Dhandala
6f46812418 fix: remove welcome message sending on bot installation 2025-12-03 18:52:18 +00:00
Nawaz Dhandala
6e20e7f08f fix: correct typo in debug log message for sleep duration in FetchListAndProbe 2025-12-03 18:45:25 +00:00
Nawaz Dhandala
ae406d8ee1 fix: update QEMU setup to use tonistiigi/binfmt:qemu-v10.0.4 in release workflows 2025-12-03 18:42:01 +00:00
Nawaz Dhandala
05920d5b99 fix: improve error logging for Playwright resource closure 2025-12-03 18:33:27 +00:00
Nawaz Dhandala
3a309aabcf fix: enhance browser context closure handling in SyntheticMonitor 2025-12-03 18:31:12 +00:00
Nawaz Dhandala
22a3004a3f fix: simplify error logging in safeCloseBrowserContext and adjust formatting in safeCloseBrowser 2025-12-03 18:27:09 +00:00
Nawaz Dhandala
b8f69fbea3 fix: refactor browser session management in SyntheticMonitor for improved clarity and error handling 2025-12-03 18:25:37 +00:00
Nawaz Dhandala
888aff6392 fix: format migration queries and update index for new migration 2025-12-03 14:42:10 +00:00
Nawaz Dhandala
234de977c4 fix: prevent rendering icon for non-highlighted timeline items 2025-12-03 14:41:39 +00:00
Nawaz Dhandala
fa5f606709 Merge branch 'master' of https://github.com/OneUptime/oneuptime 2025-12-03 14:20:38 +00:00
Nawaz Dhandala
b889611d16 fix: update postmortem attachment message for improved visibility and change version to 9.2.0 2025-12-03 14:04:09 +00:00
Nawaz Dhandala
43f0eeb0f8 fix: improve clarity in postmortem status page description and enhance attachment handling messages 2025-12-03 13:57:40 +00:00
Nawaz Dhandala
be311dd8b5 feat: add default value for Postmortem Published At field 2025-12-03 13:56:30 +00:00
Nawaz Dhandala
29428bf660 fix: update placeholder for Postmortem Published At field to improve clarity 2025-12-03 13:55:58 +00:00
Simon Larsen
9eebbe9dfb feat: implement retry logic with configurable attempts and delay for LMStudioClient 2025-12-03 13:51:30 +00:00
Nawaz Dhandala
0dc3bb4f33 feat: add MigrationName1764767371788 for updating OnCallDutyPolicyScheduleLayer defaults 2025-12-03 13:10:12 +00:00
Nawaz Dhandala
adf5a9c1f3 feat: add postmortemPostedAt field and update related components for incident tracking 2025-12-03 13:09:23 +00:00
Nawaz Dhandala
faaded049a feat: add DocumentCheck icon to IconProp and update incident postmortem note icon 2025-12-03 12:58:27 +00:00
Nawaz Dhandala
d02e3882be fix: adjust font size classes for TimelineItem highlight to improve readability 2025-12-03 12:52:20 +00:00
Nawaz Dhandala
e1af84fafa feat: enhance EventItem styling with conditional highlight for improved visibility 2025-12-03 12:51:03 +00:00
Nawaz Dhandala
c371f0a25f feat: add title and highlight properties to TimelineItem for enhanced event display 2025-12-03 12:42:17 +00:00
Nawaz Dhandala
c86d2c2a4a refactor: streamline API route registration and improve code readability 2025-12-03 11:50:17 +00:00
Nawaz Dhandala
a807cc10ab feat: add migration for IncidentPostmortemAttachmentFile table and related constraints 2025-12-03 11:43:31 +00:00
Nawaz Dhandala
6cc480744d Merge branch 'master' of https://github.com/OneUptime/oneuptime 2025-12-03 11:42:07 +00:00
Nawaz Dhandala
7cb6104795 feat: enhance postmortem functionality with attachment handling and status page visibility 2025-12-03 11:42:05 +00:00
Nawaz Dhandala
49dd315501 feat: implement postmortem attachment handling in Incident and StatusPage APIs 2025-12-03 11:34:00 +00:00
Simon Larsen
9ec2b458ed style: remove unnecessary first-letter styling from blog post body 2025-12-03 11:14:50 +00:00
Nawaz Dhandala
702b5811a9 fix: add missing line continuation for workspace-path in usage example 2025-12-02 22:25:59 +00:00
Nawaz Dhandala
7dc7255790 feat: add alias normalization for historical argument names in ReadFileTool 2025-12-02 22:22:19 +00:00
Nawaz Dhandala
1f620e7092 feat: update default max iterations for tool-calling rounds to 100 2025-12-02 21:48:32 +00:00
Nawaz Dhandala
87466246fa Revert "feat: enhance log file path resolution in CLI to support home directory and relative paths"
This reverts commit 12eaa17859.
2025-12-02 21:34:16 +00:00
Nawaz Dhandala
12eaa17859 feat: enhance log file path resolution in CLI to support home directory and relative paths 2025-12-02 21:31:20 +00:00
Nawaz Dhandala
e782ae6b3c feat: enhance logging in CopilotAgent and WorkspaceContext with detailed message contents 2025-12-02 21:17:34 +00:00
Nawaz Dhandala
9ad87328c2 feat: add detailed JSDoc comments for Copilot agent and tools 2025-12-02 21:04:08 +00:00
Nawaz Dhandala
8279294d15 feat: implement oneuptime-copilot-agent CLI with logging and configuration options 2025-12-02 20:52:15 +00:00
Nawaz Dhandala
8c6da51d58 Adopt PascalCase paths in Copilot 2025-12-02 20:34:27 +00:00
Nawaz Dhandala
6d114e3ac4 chore: bump version to 9.1.3 2025-12-02 20:18:07 +00:00
Nawaz Dhandala
44427d3ee7 feat: enhance ReadFileTool with optional line start and end parameters 2025-12-02 14:52:07 +00:00
Nawaz Dhandala
09b0c3b1ef feat: add debug logging instructions and example to README 2025-12-02 14:42:08 +00:00
Nawaz Dhandala
ad597fe5dd feat: update model name and workspace path in usage examples 2025-12-02 14:39:36 +00:00
Nawaz Dhandala
74f17fa45c fix: handle notification skipping for already notified scheduled maintenance events 2025-12-02 14:22:10 +00:00
Nawaz Dhandala
b19a5fa58a feat: add isCreatedState and isScheduledState checks to skip notifications for already notified incidents 2025-12-02 14:21:52 +00:00
Nawaz Dhandala
57abffa113 Merge branch 'master' of https://github.com/OneUptime/oneuptime 2025-12-02 13:06:53 +00:00
Nawaz Dhandala
e8e493ee5a Refactor code structure for improved readability and maintainability 2025-12-02 13:06:50 +00:00
Simon Larsen
e065ebdddc Merge branch 'copilot-v2' 2025-12-02 13:02:32 +00:00
Simon Larsen
39da442892 style: update blog post first paragraph styling for improved readability 2025-12-02 13:02:18 +00:00
Simon Larsen
45b02b30e3 Merge pull request #2152 from OneUptime/chore/npm-audit-fix
chore: npm audit fix
2025-12-02 11:46:04 +00:00
Nawaz Dhandala
30414327f9 feat: add Dockerfile for OneUptime-copilot setup 2025-12-02 11:05:16 +00:00
simlarsen
b99a20a588 chore: npm audit fix 2025-12-02 01:50:48 +00:00
Nawaz Dhandala
22178c282d fix: format command descriptions for consistency in MicrosoftTeamsAPI 2025-12-01 17:13:11 +00:00
Nawaz Dhandala
30389a8d49 feat: add command lists for improved interaction with OneUptime bot in Microsoft Teams 2025-12-01 17:11:37 +00:00
Nawaz Dhandala
7b73cc2ea7 fix: remove trailing spaces in action type definitions 2025-12-01 17:05:30 +00:00
Nawaz Dhandala
6d2c331216 feat: update command triggers for incident and maintenance actions 2025-12-01 17:05:05 +00:00
Nawaz Dhandala
624e4c2296 chore: update version to 9.1.2 2025-12-01 16:38:51 +00:00
Simon Larsen
5e901ee973 Merge pull request #2151 from OneUptime/copilot-v2
Copilot v2
2025-12-01 16:25:22 +00:00
Simon Larsen
a103abc7a9 fix: simplify boolean expression for hasProgressedBeyondScheduledState 2025-12-01 15:45:35 +00:00
Simon Larsen
a7dda0bd53 feat: add logic to update nextSubscriberNotificationBeforeTheEventAt for progressed scheduled maintenance events 2025-12-01 15:45:15 +00:00
Simon Larsen
6948754c86 Merge pull request #2147 from OneUptime/copilot-v2
Copilot v2
2025-12-01 15:21:05 +00:00
Simon Larsen
cc5731bb6d feat: add error handling and logging for missing tool calls and directory entries 2025-12-01 15:20:44 +00:00
Simon Larsen
6761a8a686 Merge pull request #2148 from OneUptime/snyk-upgrade-240d43adaab510cce84165a4f1ccf9b5
[Snyk] Upgrade mailparser from 3.7.5 to 3.9.0
2025-12-01 13:42:14 +00:00
Simon Larsen
6e487199aa refactor: add type annotations and improve type safety across multiple files 2025-12-01 13:41:34 +00:00
snyk-bot
cda5de92ec fix: upgrade mailparser from 3.7.5 to 3.9.0
Snyk has created this PR to upgrade mailparser from 3.7.5 to 3.9.0.

See this package in npm:
mailparser

See this project in Snyk:
https://app.snyk.io/org/oneuptime-RsC2nshvQ2Vnr35jHvMnMP/project/c3622982-05c8-495c-809c-20f301c75f92?utm_source=github&utm_medium=referral&page=upgrade-pr
2025-11-29 12:10:48 +00:00
Simon Larsen
33349341a9 refactor: improve code formatting and readability across multiple files 2025-11-28 21:53:50 +00:00
Simon Larsen
db81fdd3e7 feat: enhance logging throughout the Copilot agent and tools for better traceability 2025-11-28 21:52:33 +00:00
Simon Larsen
d71eba91dd chore: remove vscode-copilot-chat subproject reference 2025-11-28 21:45:07 +00:00
Simon Larsen
682bb805f3 feat: implement AgentLogger for file-based logging with exit handlers 2025-11-28 21:43:15 +00:00
Simon Larsen
7f38e3d417 docs: add usage example for running the agent in development mode 2025-11-28 21:31:08 +00:00
Simon Larsen
559985e93b feat: add tsconfig-paths for improved module resolution in development 2025-11-28 21:28:19 +00:00
Simon Larsen
43588cbe5a refactor: update optional properties to include 'undefined' type in various interfaces 2025-11-28 20:57:17 +00:00
Simon Larsen
0772fce477 refactor: update Telemetry class to use type assertions for loggerProviderConfig and nodeSdkConfiguration
chore: remove unused common type definitions and clean up tsconfig.json
2025-11-28 20:20:09 +00:00
Simon Larsen
78107d8b1c chore: remove unused type definitions and clean up tsconfig.json 2025-11-28 20:06:43 +00:00
Simon Larsen
078af43b0c chore: remove tsconfig.json for OneUptime Copilot Agent 2025-11-28 19:58:11 +00:00
Simon Larsen
9b9aeb2f40 feat: Implement OneUptime Copilot Agent with workspace tools
- Added SystemPrompt for guiding the agent's behavior.
- Created WorkspaceContextBuilder to gather workspace information.
- Developed main entry point in index.ts for agent execution.
- Implemented LMStudioClient for interacting with the LM Studio API.
- Added ApplyPatchTool for applying code changes via patches.
- Created ListDirectoryTool for listing files and directories.
- Implemented ReadFileTool for reading file contents.
- Developed RunCommandTool for executing shell commands.
- Added SearchWorkspaceTool for searching files in the workspace.
- Created WriteFileTool for writing content to files.
- Established ToolRegistry for managing and executing tools.
- Defined types for chat messages and tool calls.
- Added utility classes for logging and executing commands.
- Implemented WorkspacePaths for managing file paths within the workspace.
- Configured TypeScript settings in tsconfig.json.
2025-11-28 19:57:52 +00:00
Nawaz Dhandala
67577f5a2b refactor: improve formatting and readability in Incident migration and MonitorService 2025-11-28 17:42:22 +00:00
Nawaz Dhandala
4e808cf382 feat: enhance monitor deletion process to include MetricService cleanup 2025-11-28 17:40:31 +00:00
Nawaz Dhandala
c993b33dab feat: add projectId to MetricService deletion query in incident handling 2025-11-28 17:35:23 +00:00
Nawaz Dhandala
3c5a64024b feat: include projectId in MetricService deletion query for incidents 2025-11-28 17:34:30 +00:00
Nawaz Dhandala
86efe54a29 refactor: remove unused favicon handling from DashboardMasterPage 2025-11-28 17:29:43 +00:00
Simon Larsen
17bf568428 feat: Implement OneUptime Copilot Agent with core functionalities
- Add SystemPrompt to define agent behavior and principles.
- Create WorkspaceContextBuilder for workspace snapshot and Git status.
- Initialize main entry point with command-line options for agent configuration.
- Develop LMStudioClient for chat completion requests to LM Studio.
- Implement tools for file operations: ApplyPatchTool, ListDirectoryTool, ReadFileTool, RunCommandTool, SearchWorkspaceTool, WriteFileTool.
- Establish ToolRegistry for managing and executing tools.
- Define types for chat messages, tool calls, and execution results.
- Set up workspace path utilities for file management and validation.
- Configure TypeScript settings for the project.
2025-11-28 16:49:46 +00:00
Simon Larsen
26ac698cc7 Remove Copilot package configuration files 2025-11-28 15:43:36 +00:00
Simon Larsen
72bb25e036 chore: migrate VERSION_PREFIX to VERSION and update related workflows 2025-11-28 15:40:24 +00:00
Nawaz Dhandala
1f23742c1f chore: remove vscode-copilot-chat subproject 2025-11-28 14:12:12 +00:00
Nawaz Dhandala
ac66cee4aa feat: add declaredAt field to Incident model with migration and default value 2025-11-28 10:12:43 +00:00
Nawaz Dhandala
66efe2d2fa feat: add declaredAt field to Incident model and update related services and components 2025-11-28 10:10:05 +00:00
Nawaz Dhandala
0ad5c14882 feat: refactor SCIM creation in TeamMemberService tests for improved clarity 2025-11-27 14:13:14 +00:00
Nawaz Dhandala
2468b39dd2 style: format code for improved readability in TeamMemberService 2025-11-27 13:59:12 +00:00
Nawaz Dhandala
4fec2caef6 feat: update SCIM integration to manage team members with Push Groups 2025-11-27 13:58:47 +00:00
Nawaz Dhandala
dc041d924a style: update social media icons in blog post for improved accessibility 2025-11-27 12:50:30 +00:00
Nawaz Dhandala
37acc617a0 style: add styling for inline code chips in blog body 2025-11-27 12:42:54 +00:00
Nawaz Dhandala
cd28370ce3 style: update color scheme for blog post elements 2025-11-27 12:39:45 +00:00
Nawaz Dhandala
e847f430f2 feat: enhance blog post styling and add reading progress indicator 2025-11-27 12:37:19 +00:00
Nawaz Dhandala
d1e94daaca style: adjust margins for blog post body text 2025-11-27 12:17:10 +00:00
Nawaz Dhandala
df264d6766 feat: add Dockerfile language support to syntax highlighting 2025-11-27 12:16:29 +00:00
Nawaz Dhandala
49c2312c47 Merge branch 'master' of https://github.com/OneUptime/oneuptime 2025-11-27 11:30:01 +00:00
Nawaz Dhandala
0fd3121b29 chore: automate version prefix bump and PR creation in release workflow 2025-11-27 11:29:30 +00:00
Simon Larsen
ea43c43991 Merge pull request #2140 from OneUptime/chore/npm-audit-fix
chore: npm audit fix
2025-11-27 11:20:26 +00:00
simlarsen
51a128efd3 chore: npm audit fix 2025-11-27 01:46:46 +00:00
Nawaz Dhandala
847bac5c6a refactor: enhance Chrome and Firefox executable path retrieval with additional candidates 2025-11-26 16:42:10 +00:00
Nawaz Dhandala
29b137afbd refactor: enhance Chrome executable path retrieval with multiple candidate checks 2025-11-26 16:35:30 +00:00
Nawaz Dhandala
1be0b475a6 bump: update version to 9.1.1 2025-11-26 16:28:59 +00:00
Nawaz Dhandala
2467d2c02d refactor: reorder app dependency installation and Playwright browser setup in Dockerfile 2025-11-26 16:26:17 +00:00
Nawaz Dhandala
b9597250ac refactor: simplify APP_TAG assignment in release and test workflows 2025-11-26 10:58:19 +00:00
Nawaz Dhandala
203e9b8c39 chore: upgrade Docker setup actions to v3 in release and test workflows 2025-11-25 21:41:37 +00:00
Nawaz Dhandala
16078ffe3b Merge branch 'master' of https://github.com/OneUptime/oneuptime 2025-11-25 19:54:54 +00:00
Nawaz Dhandala
898c4de78f refactor: enhance subdomain handling and validation in StatusPageDomain and Domains components 2025-11-25 19:54:50 +00:00
Simon Larsen
da53b7c51c feat: add check for existing GitHub release to skip creation and publishing 2025-11-25 19:51:10 +00:00
Nawaz Dhandala
8a330e7914 refactor: implement caching for Bot Framework adapter to improve performance 2025-11-25 18:51:03 +00:00
Nawaz Dhandala
8bf7b8dfa2 feat: add Microsoft Teams app tenant ID configuration 2025-11-25 18:49:26 +00:00
Nawaz Dhandala
9d36920477 Refactor versioning in release and test workflows to remove build number suffix
- Updated versioning in release.yml to use only major_minor version for Helm chart packaging, Docker images, and GitHub releases.
- Adjusted versioning in test-release.yaml to reflect similar changes, removing build number suffix for test releases.
2025-11-25 13:08:34 +00:00
Nawaz Dhandala
264cdc7c6b refactor: improve code readability by formatting long lines in user update handlers 2025-11-25 11:58:08 +00:00
Nawaz Dhandala
3d8daa46aa refactor: streamline user update logic by consolidating PUT and PATCH handlers 2025-11-25 11:57:42 +00:00
Nawaz Dhandala
673ab6845f refactor: consolidate user update logic into a single handler for PUT and PATCH endpoints 2025-11-25 11:52:43 +00:00
Simon Larsen
bb3df528cf Merge pull request #2137 from OneUptime/chore/npm-audit-fix
chore: npm audit fix
2025-11-25 08:22:21 +00:00
simlarsen
f52e73afb2 chore: npm audit fix 2025-11-25 01:48:46 +00:00
Nawaz Dhandala
3e04d38eb1 fix: update secret usage documentation and enhance monitor secret retrieval logic 2025-11-24 21:30:08 +00:00
Nawaz Dhandala
27c2ffdfbd chore: remove outdated APK build workflow and script 2025-11-24 21:22:17 +00:00
Nawaz Dhandala
78ee52fb4d fix: add missing iarc_rating_id to the manifest file 2025-11-24 21:08:26 +00:00
Nawaz Dhandala
adc15561b9 feat: enhance SMTP transport configuration by adding flexible secure option handling 2025-11-24 21:04:48 +00:00
Nawaz Dhandala
e19a14e906 fix: update proxy_pass path for assetlinks.json in Nginx configuration 2025-11-24 20:19:49 +00:00
Simon Larsen
035f3412b8 Merge pull request #2132 from OneUptime/captcha
Captcha
2025-11-24 19:13:34 +00:00
Nawaz Dhandala
deb902463c feat: enhance captcha integration by improving type definitions and refactoring callback functions 2025-11-24 19:11:21 +00:00
Nawaz Dhandala
a03a2bf9b0 fix: update proxy_pass path for assetlinks.json in Nginx configuration 2025-11-24 19:06:01 +00:00
Nawaz Dhandala
5f396d36a4 feat: implement assetlinks.json for Android app delegation and enhance Nginx configuration for asset handling 2025-11-24 18:59:42 +00:00
Simon Larsen
99cf626d7d Merge branch 'release' of github.com:OneUptime/oneuptime into release 2025-11-24 15:47:59 +00:00
Simon Larsen
ae72437591 fix: update test-e2e workflows to include build number and version dependencies 2025-11-24 15:47:37 +00:00
Simon Larsen
86301213f0 fix: sanitize APP_TAG format by replacing '+' with '-' 2025-11-24 15:42:25 +00:00
Nawaz Dhandala
c6e889b2a8 feat: integrate captcha verification in login process 2025-11-24 15:17:31 +00:00
Nawaz Dhandala
0a053c51e3 feat: update billing payment method permissions to include Manage Billing access 2025-11-24 13:01:08 +00:00
Nawaz Dhandala
296ecbd9e3 feat: enhance error handling in certificate ordering process based on billing status 2025-11-24 12:47:31 +00:00
Nawaz Dhandala
aa4797cc54 fix: add space in subscription management email subject 2025-11-24 12:37:23 +00:00
Nawaz Dhandala
fd4759f16e feat: add site key configuration for hCaptcha in values.yaml 2025-11-24 12:28:05 +00:00
Nawaz Dhandala
a7b7dc61cf feat: add captcha configuration and environment variables to Helm chart and Docker Compose 2025-11-24 12:18:34 +00:00
Nawaz Dhandala
3b0bdca980 feat: implement captcha verification in registration process 2025-11-24 12:13:15 +00:00
Nawaz Dhandala
07bc6d4edd fix: remove public create permission from User table access control 2025-11-24 12:08:33 +00:00
Nawaz Dhandala
8642a54fec feat: add captcha configuration and verification support 2025-11-24 12:08:09 +00:00
Simon Larsen
9ed0c3cf2b Merge pull request #2130 from OneUptime/master
Release
2025-11-24 12:03:48 +00:00
Simon Larsen
396c73f601 Merge pull request #2128 from OneUptime/snyk-upgrade-f06191ee357ef468242a37c903b4b224
[Snyk] Upgrade axios from 1.13.0 to 1.13.1
2025-11-24 12:00:50 +00:00
snyk-bot
ceb54ae12d fix: upgrade axios from 1.13.0 to 1.13.1
Snyk has created this PR to upgrade axios from 1.13.0 to 1.13.1.

See this package in npm:
axios

See this project in Snyk:
https://app.snyk.io/org/oneuptime-RsC2nshvQ2Vnr35jHvMnMP/project/49c81d9c-12c2-4e8e-b9e8-72f98b1b595c?utm_source=github&utm_medium=referral&page=upgrade-pr
2025-11-24 09:37:36 +00:00
Nawaz Dhandala
8df9a14b13 fix: standardize branch name formatting in GitHub Actions workflow 2025-11-22 16:27:47 +00:00
Nawaz Dhandala
7d32627917 Update GitHub Actions workflow for versioning and Docker image builds
- Enhanced the `test-release.yaml` workflow to read and determine semantic versioning from `VERSION_PREFIX`, including major, minor, and patch components.
- Adjusted versioning format in the workflow to use a new scheme: `major.minor.patch-test+build.build_number`.
- Updated Docker image build script to sanitize version strings by replacing '+' with '-' for tagging.
- Incremented the version in `VERSION_PREFIX` from `9.0` to `9.1.0`.
2025-11-22 14:11:02 +00:00
Nawaz Dhandala
a9ea19507e fix: add missing widgets array in manifest.json 2025-11-22 14:05:15 +00:00
Nawaz Dhandala
8c2c002382 fix: update manifest.json to include scope_extensions and adjust client_mode format 2025-11-22 13:52:29 +00:00
Simon Larsen
2a2aca032e Merge pull request #2127 from OneUptime/snyk-upgrade-51c02a535e494371cbaf2b8819deeaff
[Snyk] Upgrade eslint-plugin-unused-imports from 4.2.0 to 4.3.0
2025-11-22 13:00:01 +00:00
snyk-bot
911fe180ab fix: upgrade eslint-plugin-unused-imports from 4.2.0 to 4.3.0
Snyk has created this PR to upgrade eslint-plugin-unused-imports from 4.2.0 to 4.3.0.

See this package in npm:
eslint-plugin-unused-imports

See this project in Snyk:
https://app.snyk.io/org/oneuptime-RsC2nshvQ2Vnr35jHvMnMP/project/c3622982-05c8-495c-809c-20f301c75f92?utm_source=github&utm_medium=referral&page=upgrade-pr
2025-11-22 10:06:29 +00:00
Simon Larsen
11cbe5f34a Merge pull request #2126 from OneUptime/chore/npm-audit-fix
chore: npm audit fix
2025-11-22 04:23:48 +00:00
simlarsen
883f51e2d2 chore: npm audit fix 2025-11-22 01:43:11 +00:00
Simon Larsen
8ebe034f0c fix: specify branches for push event in test-release workflow 2025-11-21 19:44:31 +00:00
Simon Larsen
96ea2f6ff7 Merge branch 'master' of github.com:OneUptime/oneuptime 2025-11-21 19:15:53 +00:00
Simon Larsen
d91a8cae67 chore: remove dashboard Android APK release job from workflow 2025-11-21 19:15:50 +00:00
Simon Larsen
959035fd14 Merge pull request #2124 from OneUptime/sp-master-pw
Sp master pw
2025-11-21 19:14:40 +00:00
Nawaz Dhandala
e1730e4d3a feat: enhance error handling and display for status page and master password components 2025-11-21 19:13:02 +00:00
Nawaz Dhandala
4aa009f46c refactor: clean up code formatting and improve readability in multiple files 2025-11-21 19:07:30 +00:00
Simon Larsen
1551401fc3 fix: disable pipefail for sdkmanager commands to prevent pipeline breakage 2025-11-21 19:02:28 +00:00
Nawaz Dhandala
3768c95aa1 feat: update description for master password rotation to include authentication impact 2025-11-21 18:59:32 +00:00
Nawaz Dhandala
57e933ee9c feat: add master password status alerts in PrivateUser and SSO pages 2025-11-21 18:55:43 +00:00
Nawaz Dhandala
add0efa6db feat: remove master password cookie on user logout 2025-11-21 18:42:19 +00:00
Simon Larsen
7d12c8997e docs: update upgrading guide to reflect removal of Kubernetes Ingress support 2025-11-21 18:42:00 +00:00
Simon Larsen
f836369c01 feat: remove Kubernetes Ingress support and update related documentation 2025-11-21 18:40:47 +00:00
Nawaz Dhandala
f48c3c608c feat: add master password storage key retrieval for user logout process 2025-11-21 18:25:04 +00:00
Simon Larsen
58a955baf7 chore: remove deprecated iOS dashboard build workflow 2025-11-21 18:14:02 +00:00
Simon Larsen
b5243cec1a fix: correct script path casing in APK build workflows 2025-11-21 18:05:10 +00:00
Nawaz Dhandala
d6336ee8f3 refactor: streamline storage key retrieval for private status page and master password requirements 2025-11-21 18:01:01 +00:00
Nawaz Dhandala
1c5506f4d1 fix: reorder access check logic in hasReadAccess method 2025-11-21 17:50:28 +00:00
Simon Larsen
31106c66d5 feat: add workflow to build and upload Dashboard Android APK on release 2025-11-21 17:47:39 +00:00
Nawaz Dhandala
bf33a5ce5d fix: correct syntax in respondWithMasterPasswordAccess function declaration 2025-11-21 17:41:26 +00:00
Simon Larsen
a9f53ec416 fix: restore signing key environment variables in APK build workflow 2025-11-21 17:41:10 +00:00
Nawaz Dhandala
64f819e0db feat: implement master password session validation and response handling 2025-11-21 17:38:07 +00:00
Nawaz Dhandala
e8816d61b0 fix: replace NotAuthenticatedException with BadDataException for invalid master password 2025-11-21 17:25:15 +00:00
Simon Larsen
42713843f3 fix: update manifest URLs and host name in dashboard APK build workflow 2025-11-21 17:20:34 +00:00
Simon Larsen
db8e23c8dc feat: streamline APK build process by introducing a dedicated build script 2025-11-21 17:19:52 +00:00
Nawaz Dhandala
c94430aabe fix: handle API response failure in master password submission 2025-11-21 17:15:47 +00:00
Simon Larsen
e8f74d0147 chore: simplify workflow triggers and environment variables in dashboard build scripts 2025-11-21 17:05:55 +00:00
Nawaz Dhandala
cda3be805b Merge branch 'master' into sp-master-pw 2025-11-21 16:40:19 +00:00
Simon Larsen
372ce67ce6 Refactor Docker image build process in GitHub Actions workflow
- Replaced inline Docker build commands with a dedicated script for building Docker images.
- Added NPM_AUTH_TOKEN environment variable for authentication.
- Updated image build commands for multiple services (mcp-server, llm, nginx, e2e, test-server, otel-collector, isolated-vm, home, status-page, test, probe-ingest, server-monitor-ingest, incoming-request-ingest, telemetry, probe, dashboard, admin-dashboard, app, api-reference, accounts, worker, copilot, workflow, docs) to use the new script.
2025-11-21 14:57:15 +00:00
Simon Larsen
62cae0d32c feat: add build number generation and version reading for test releases 2025-11-21 13:26:42 +00:00
Simon Larsen
6be92aa41d Merge branch 'master' of github.com:OneUptime/oneuptime 2025-11-21 13:22:52 +00:00
Simon Larsen
d166fe49ec Implement feature X to enhance user experience and optimize performance 2025-11-21 13:22:46 +00:00
Simon Larsen
d5f2b32fe9 Merge pull request #2125 from OneUptime/chore/npm-audit-fix
chore: npm audit fix
2025-11-21 12:53:53 +00:00
simlarsen
be71858b4a chore: npm audit fix 2025-11-21 01:46:46 +00:00
Simon Larsen
8c121869ee Add GitHub Actions workflow for building Dashboard iOS Wrapper 2025-11-20 21:11:35 +00:00
Simon Larsen
bfc761aac5 Add GitHub Actions workflow for building Dashboard Android APK 2025-11-20 21:08:18 +00:00
Simon Larsen
17f6507d0c Add build_docker_images.sh script for automated Docker image builds
- Implemented a bash script to build and push Docker images.
- Added support for multiple platforms using docker buildx.
- Included options for specifying image name, version, Dockerfile path, build context, and additional tags.
- Integrated Git SHA detection for build arguments.
- Provided usage instructions and error handling for missing required arguments.
2025-11-20 20:51:11 +00:00
Simon Larsen
4fa4dd7b6c Refactor Docker image build process to use a dedicated script for improved maintainability 2025-11-20 20:23:41 +00:00
Simon Larsen
69be00067a Add 'set -euo pipefail' to Docker build commands for improved error handling 2025-11-20 19:43:44 +00:00
Nawaz Dhandala
7af0091de2 Refactor master password validation logic to support status page-specific keys and handle legacy values 2025-11-20 19:31:41 +00:00
Simon Larsen
cd6bac1111 Update screenshots in manifest.json for improved app representation on desktop and mobile 2025-11-20 19:07:24 +00:00
Nawaz Dhandala
62578b2389 Rename package from @oneuptime/probe-ingest to @oneuptime/telemetry 2025-11-20 19:05:48 +00:00
Simon Larsen
0a791bba01 Refactor code structure for improved readability and maintainability 2025-11-20 18:59:40 +00:00
Nawaz Dhandala
accd86edf1 Refactor getLoginRoute to handle master password validation for private status pages 2025-11-20 18:42:30 +00:00
Nawaz Dhandala
8f3c06bc86 Refactor MasterPasswordPage to use BasicForm for password submission and improve error handling 2025-11-20 18:30:20 +00:00
Nawaz Dhandala
7baeaaee02 Add master password route check in DashboardMasterPage component 2025-11-20 18:06:19 +00:00
Nawaz Dhandala
8f05de6860 Add MasterPassword component and integrate master password checks in Login and SSO pages 2025-11-20 18:03:22 +00:00
Nawaz Dhandala
05e0c5528e Refactor StatusPageDelete component to reintroduce 'Require Master Password' toggle for private status pages 2025-11-20 14:21:11 +00:00
Nawaz Dhandala
91ef08595c Update read permissions for StatusPage to include necessary roles 2025-11-20 13:54:56 +00:00
Nawaz Dhandala
04459b51da Add master password rotation feature to StatusPageDelete component 2025-11-20 13:53:13 +00:00
Nawaz Dhandala
5903764395 Refactor MasterPasswordPage for improved readability and functionality 2025-11-20 13:08:06 +00:00
Simon Larsen
51ac869650 Fix formatting in manifest.json by removing unnecessary blank line 2025-11-20 13:07:40 +00:00
Simon Larsen
ce4a49fbd2 Fix app ID in manifest.json for correct routing 2025-11-20 12:59:28 +00:00
Simon Larsen
ca252d8e64 Add screenshots to manifest.json for enhanced app visibility 2025-11-20 12:59:16 +00:00
Nawaz Dhandala
850d125c82 Add migration for master password feature in StatusPage 2025-11-20 12:56:27 +00:00
Nawaz Dhandala
4b619eadc0 Implement master password feature for private status pages 2025-11-20 12:51:11 +00:00
Simon Larsen
0fc63385a5 Remove unused manifest files and service workers across multiple components for cleaner codebase 2025-11-20 12:34:20 +00:00
Simon Larsen
b5c0953c8b Merge pull request #2123 from OneUptime/chore/npm-audit-fix
chore: npm audit fix
2025-11-20 12:00:36 +00:00
Nawaz Dhandala
9deaf19d4c Remove unnecessary blank lines in config.example.env for improved readability 2025-11-20 11:59:56 +00:00
simlarsen
ac239ffe4d chore: npm audit fix 2025-11-20 01:45:52 +00:00
Simon Larsen
84ac063445 Merge pull request #2122 from OneUptime/master
Release
2025-11-19 18:29:37 +00:00
Nawaz Dhandala
904311b124 Add modal width configuration to ChangeState components for improved UI consistency 2025-11-19 18:26:34 +00:00
Nawaz Dhandala
c1562872a0 Fix formatting of response snapshot section in MonitorCriteriaEvaluator 2025-11-19 18:22:04 +00:00
Nawaz Dhandala
503d5ff946 Refactor MonitorCriteriaEvaluator to improve code readability and consistency 2025-11-19 18:18:56 +00:00
Nawaz Dhandala
271fa4c9ad Add root cause context building and enhance monitor criteria evaluation details 2025-11-19 18:18:25 +00:00
Nawaz Dhandala
a57902dd07 Fix indentation for detailsUrl in Service class to maintain code consistency 2025-11-19 18:00:35 +00:00
Nawaz Dhandala
9336a33e47 Enhance notification templates to include conditional details URLs for improved user guidance 2025-11-19 18:00:08 +00:00
Nawaz Dhandala
fe034807d7 Update PermissionHelper to mark dashboard permissions as access control permissions 2025-11-19 17:43:52 +00:00
Nawaz Dhandala
f08adc7b78 Refactor ScheduledMaintenanceService and AnnouncementView to improve notification settings handling and enhance code clarity 2025-11-19 17:43:01 +00:00
Nawaz Dhandala
e767b3f4b7 Refactor ScheduledMaintenanceService and related migrations to improve notification settings handling and enhance code clarity 2025-11-19 17:42:37 +00:00
Nawaz Dhandala
c874f4f3e2 Refactor Announcement components to enhance breadcrumb navigation and improve layout 2025-11-19 17:28:01 +00:00
Nawaz Dhandala
cb3fb984ec Refactor AnnouncementView to enhance attachment handling and improve content display 2025-11-19 17:19:34 +00:00
Nawaz Dhandala
51882a595a Refactor OpenAPIUtil to streamline permission checks and improve schema registration logic 2025-11-19 17:07:37 +00:00
Nawaz Dhandala
8d5f8454c4 Refactor FilePicker and AttachmentList components to enhance type definitions and improve code clarity 2025-11-19 16:02:41 +00:00
Nawaz Dhandala
a036830009 Refactor Response and FilePicker components for improved readability and consistency 2025-11-19 15:50:45 +00:00
Nawaz Dhandala
76c6ffeb51 Refactor AttachmentCard component for improved styling and layout 2025-11-19 15:37:17 +00:00
Nawaz Dhandala
92c9de7ca9 Add EventAttachmentList component for improved attachment display in EventItem 2025-11-19 15:34:50 +00:00
Nawaz Dhandala
e752340a16 Refactor FilePicker component to remove thumbnail generation and simplify file display 2025-11-19 14:33:37 +00:00
Nawaz Dhandala
3f7d7d4347 Refactor FilePicker component to improve file size formatting and enhance metadata display 2025-11-19 14:29:00 +00:00
Nawaz Dhandala
30651f1ca7 Update attachment routes to include projectId in URL parameters 2025-11-19 13:17:48 +00:00
Nawaz Dhandala
a04fa51c37 Add UserMiddleware for authorization in attachment routes 2025-11-19 12:47:02 +00:00
Nawaz Dhandala
5c5a4ca787 Refactor AttachmentList component styles for improved accessibility and visual consistency 2025-11-19 12:13:11 +00:00
Nawaz Dhandala
62fe797b93 Enhance AttachmentList component with file metadata and icon support 2025-11-19 12:07:39 +00:00
Nawaz Dhandala
1ee2f17b28 Add canReadOnRelationQuery property to _id in DatabaseBaseModel 2025-11-19 11:52:39 +00:00
Nawaz Dhandala
9e714af5c2 Merge branch 'file-attachments' 2025-11-19 10:45:29 +00:00
Simon Larsen
74e18a2861 Merge pull request #2113 from OneUptime/file-attachments
File attachments
2025-11-19 10:21:46 +00:00
Simon Larsen
cd9b3c1386 Merge pull request #2115 from OneUptime/snyk-upgrade-fc65b788097a8d536953d6703a423b18
[Snyk] Upgrade tailwind-merge from 2.5.4 to 2.6.0
2025-11-19 10:21:28 +00:00
Simon Larsen
40a7fc5d02 Merge pull request #2116 from OneUptime/snyk-upgrade-263ef7972ec4039196a129208a656e3e
[Snyk] Upgrade pg from 8.13.1 to 8.16.3
2025-11-19 10:21:21 +00:00
Simon Larsen
49ccb8fd75 Merge pull request #2117 from OneUptime/snyk-upgrade-f6a1bcc29ab8dd02d9ccadbb68709ae9
[Snyk] Upgrade react-big-calendar from 1.15.0 to 1.19.4
2025-11-19 10:21:14 +00:00
Simon Larsen
5c3923f534 Merge pull request #2118 from OneUptime/snyk-upgrade-17aece182fff53ced7b2e67a281299a5
[Snyk] Upgrade @opentelemetry/semantic-conventions from 1.27.0 to 1.37.0
2025-11-19 10:21:06 +00:00
Simon Larsen
7a94684cec Merge pull request #2119 from OneUptime/snyk-upgrade-412cabf449455ad4dfe0f5c97f262cd4
[Snyk] Upgrade react-router-dom from 6.28.0 to 6.30.1
2025-11-19 10:21:01 +00:00
Simon Larsen
893ccf3331 Merge pull request #2114 from OneUptime/chore/npm-audit-fix
chore: npm audit fix
2025-11-19 10:20:41 +00:00
snyk-bot
b5f354da75 fix: upgrade react-router-dom from 6.28.0 to 6.30.1
Snyk has created this PR to upgrade react-router-dom from 6.28.0 to 6.30.1.

See this package in npm:
react-router-dom

See this project in Snyk:
https://app.snyk.io/org/oneuptime-RsC2nshvQ2Vnr35jHvMnMP/project/f6446ec8-d441-487e-b58f-38373430e213?utm_source=github&utm_medium=referral&page=upgrade-pr
2025-11-19 03:38:55 +00:00
snyk-bot
b128be0c13 fix: upgrade @opentelemetry/semantic-conventions from 1.27.0 to 1.37.0
Snyk has created this PR to upgrade @opentelemetry/semantic-conventions from 1.27.0 to 1.37.0.

See this package in npm:
@opentelemetry/semantic-conventions

See this project in Snyk:
https://app.snyk.io/org/oneuptime-RsC2nshvQ2Vnr35jHvMnMP/project/f6446ec8-d441-487e-b58f-38373430e213?utm_source=github&utm_medium=referral&page=upgrade-pr
2025-11-19 03:38:52 +00:00
snyk-bot
a0fae9b514 fix: upgrade react-big-calendar from 1.15.0 to 1.19.4
Snyk has created this PR to upgrade react-big-calendar from 1.15.0 to 1.19.4.

See this package in npm:
react-big-calendar

See this project in Snyk:
https://app.snyk.io/org/oneuptime-RsC2nshvQ2Vnr35jHvMnMP/project/f6446ec8-d441-487e-b58f-38373430e213?utm_source=github&utm_medium=referral&page=upgrade-pr
2025-11-19 03:38:47 +00:00
snyk-bot
04fc51b873 fix: upgrade pg from 8.13.1 to 8.16.3
Snyk has created this PR to upgrade pg from 8.13.1 to 8.16.3.

See this package in npm:
pg

See this project in Snyk:
https://app.snyk.io/org/oneuptime-RsC2nshvQ2Vnr35jHvMnMP/project/f6446ec8-d441-487e-b58f-38373430e213?utm_source=github&utm_medium=referral&page=upgrade-pr
2025-11-19 03:38:43 +00:00
snyk-bot
2cb45d18c9 fix: upgrade tailwind-merge from 2.5.4 to 2.6.0
Snyk has created this PR to upgrade tailwind-merge from 2.5.4 to 2.6.0.

See this package in npm:
tailwind-merge

See this project in Snyk:
https://app.snyk.io/org/oneuptime-RsC2nshvQ2Vnr35jHvMnMP/project/f6446ec8-d441-487e-b58f-38373430e213?utm_source=github&utm_medium=referral&page=upgrade-pr
2025-11-19 03:38:39 +00:00
simlarsen
495f59f36b chore: npm audit fix 2025-11-19 01:47:18 +00:00
Nawaz Dhandala
21da644555 feat: add file size validation to FilePicker component 2025-11-18 20:49:58 +00:00
Nawaz Dhandala
02e7bd6f3e feat: enhance file summary rendering with subtitles and access labels 2025-11-18 20:43:04 +00:00
Nawaz Dhandala
254795261d feat: implement file summary rendering in FormSummary component 2025-11-18 20:10:17 +00:00
Nawaz Dhandala
53f0cd144c feat: prevent notifying subscribers when sending a test email directly 2025-11-18 19:49:01 +00:00
Nawaz Dhandala
679864dbaa feat: enhance FilePicker component with upload status management and progress tracking 2025-11-18 19:43:40 +00:00
Nawaz Dhandala
c6acc85d7d feat: refactor cache header handling to use Response utility method across multiple APIs 2025-11-18 19:26:18 +00:00
Nawaz Dhandala
5ea2426ea4 feat: enhance FilePicker component UI by updating file upload labels and error display 2025-11-18 19:03:07 +00:00
Nawaz Dhandala
1144783f4d feat: update button styles in FilePicker component for improved visibility 2025-11-18 18:54:51 +00:00
Nawaz Dhandala
d68bc56d1b feat: add remove button for files in FilePicker component 2025-11-18 18:50:51 +00:00
Nawaz Dhandala
5170254473 feat: improve file handling in FilePicker for better multi-file support and UI enhancements 2025-11-18 18:37:51 +00:00
Nawaz Dhandala
84353e1a05 feat: update FilePicker component to use full width for better layout 2025-11-18 18:08:39 +00:00
Nawaz Dhandala
62d74c1d84 feat: enhance file handling by adding MIME type resolution and updating file creation permissions 2025-11-18 18:05:46 +00:00
Nawaz Dhandala
654f64aaf7 feat: add attachment support to notes in Alerts, Incidents, and Scheduled Maintenance 2025-11-18 16:15:43 +00:00
Nawaz Dhandala
150af5b65d feat: enhance file attachment handling across multiple APIs and services 2025-11-18 15:59:58 +00:00
Nawaz Dhandala
3740636136 feat: add migration for AlertInternalNoteFile table and update migration index references 2025-11-18 15:50:58 +00:00
Nawaz Dhandala
d40deae7ef feat: add migration for StatusPageAnnouncementFile and AlertInternalNoteFile tables with constraints and indexes 2025-11-18 15:49:40 +00:00
Nawaz Dhandala
669ed24249 feat: implement AttachmentList component and refactor attachment rendering in various views 2025-11-18 15:47:19 +00:00
Nawaz Dhandala
ae341eae08 refactor: clean up import statements and improve code readability across multiple files 2025-11-18 15:32:17 +00:00
Nawaz Dhandala
241ff7671d feat: add file attachment support to status page announcements, including API endpoints and UI updates 2025-11-18 15:30:56 +00:00
Nawaz Dhandala
b7492f0706 feat: implement file attachment functionality for internal notes, including API endpoints and UI integration 2025-11-18 15:11:16 +00:00
Nawaz Dhandala
fcd076d057 feat: add migration for ScheduledMaintenanceInternalNoteFile and ScheduledMaintenancePublicNoteFile tables 2025-11-18 14:53:19 +00:00
Nawaz Dhandala
b924d68c51 feat: implement file attachment support for scheduled maintenance notes and API endpoints 2025-11-18 14:52:31 +00:00
Nawaz Dhandala
4713a42829 feat: add migration for IncidentInternalNoteFile and IncidentPublicNoteFile tables 2025-11-18 13:17:25 +00:00
Nawaz Dhandala
9399907bfc feat: add attachment handling to incident public notes in event timeline 2025-11-18 13:13:37 +00:00
Nawaz Dhandala
2a84fd6751 feat: add endpoint to retrieve incident public note attachments 2025-11-18 12:04:50 +00:00
Nawaz Dhandala
4efd3d0428 feat: add file attachment rendering to IncidentDelete and PublicNote components 2025-11-18 11:38:38 +00:00
Simon Larsen
535ae01dee Merge pull request #2112 from OneUptime/snyk-fix-645fef7c043ef7c5c2bc5ebfdc48dccb
[Snyk] Security upgrade xmlbuilder2 from 3.1.1 to 4.0.0
2025-11-18 11:29:33 +00:00
Nawaz Dhandala
b04b59b0a9 feat: add support for multiple file attachments in IncidentFeed form 2025-11-18 10:42:38 +00:00
snyk-bot
92025ce415 fix: Home/package.json to reduce vulnerabilities
The following vulnerabilities are fixed with an upgrade:
- https://snyk.io/vuln/SNYK-JS-JSYAML-13961110
2025-11-18 10:35:30 +00:00
Nawaz Dhandala
4893b01f38 feat: implement file attachment handling in IncidentInternalNote and IncidentPublicNote services 2025-11-18 10:33:00 +00:00
Nawaz Dhandala
0f8436b92f feat: enhance FormField to support multiple file uploads 2025-11-18 10:26:14 +00:00
Nawaz Dhandala
5e4aa44f2a feat: add file attachment support to IncidentInternalNote and IncidentPublicNote APIs 2025-11-18 10:20:07 +00:00
Simon Larsen
0290355cfc Merge pull request #2111 from OneUptime/chore/npm-audit-fix
chore: npm audit fix
2025-11-18 09:49:22 +00:00
simlarsen
64360fc3fe chore: npm audit fix 2025-11-18 01:47:15 +00:00
Simon Larsen
dd07cb6312 Merge pull request #2110 from OneUptime/incidents-attachments
Incidents attachments
2025-11-17 15:58:11 +00:00
Nawaz Dhandala
46e5aae8e4 fix: update path resolution for blank profile picture 2025-11-17 15:57:49 +00:00
Nawaz Dhandala
626b6d93a8 fix: update path resolution for blank profile picture 2025-11-17 15:46:41 +00:00
Nawaz Dhandala
e570030319 fix: correct import path for AppApiRoute in User utility 2025-11-17 15:38:56 +00:00
Nawaz Dhandala
97d3a34abc refactor: remove permissions from TableAccessControl in File model 2025-11-17 14:43:01 +00:00
Nawaz Dhandala
848c441419 refactor: simplify API route attachment and improve error handling in UserAPI 2025-11-17 14:41:02 +00:00
Nawaz Dhandala
5b7e52a94e feat: enhance user profile picture handling with improved blank profile logic and route management 2025-11-17 14:35:03 +00:00
Nawaz Dhandala
77e3394638 feat: update user profile picture handling to use userId instead of profilePictureId 2025-11-17 14:21:33 +00:00
Nawaz Dhandala
93721350c6 feat: update logo URL handling and introduce UserAPI for profile picture management 2025-11-17 14:09:38 +00:00
Nawaz Dhandala
1bc6eca55c refactor: streamline logo URL route handling in various components 2025-11-17 13:56:40 +00:00
Nawaz Dhandala
29560e3a4a feat: update logo URL handling for status pages across various services 2025-11-17 13:45:36 +00:00
Simon Larsen
03cc76ab07 Merge pull request #2109 from OneUptime/chore/npm-audit-fix
chore: npm audit fix
2025-11-15 07:56:37 +00:00
simlarsen
dade1d0403 chore: npm audit fix 2025-11-15 01:44:36 +00:00
Nawaz Dhandala
8a3feab3d0 feat: enhance number formatting in CompareCriteria class 2025-11-13 15:10:17 +00:00
Nawaz Dhandala
7864bbb87b feat: simplify telemetry monitor type check in SummaryInfo component 2025-11-13 14:55:44 +00:00
Nawaz Dhandala
d112d87b80 feat: add ObjectID type for projectId in ExceptionInstanceTable component 2025-11-13 14:35:58 +00:00
Nawaz Dhandala
2f8fcabce4 refactor: clean up code formatting and improve readability in Telemetry and ExceptionInstanceTable components 2025-11-13 14:35:36 +00:00
Nawaz Dhandala
0023560588 feat: enhance error handling with auth refresh logic in API class 2025-11-13 14:35:00 +00:00
Nawaz Dhandala
0bc14acde9 feat: migrate exception monitors to ExceptionInstance (analytics)
- Replace TelemetryException with ExceptionInstance across types and telemetry query
- Rename MonitorStepExceptionMonitorUtil.toQuery -> toAnalyticsQuery and map fields (telemetryServiceId->serviceId, lastSeenAt->time)
- Use ExceptionInstanceService and Query<ExceptionInstance> in MonitorTelemetryMonitor
- Minor MonitorResource variable cleanup for ExceptionMonitorResponse
- Add ExceptionInstanceTable component and switch UI (forms, Alert/Incident views) to use ExceptionInstance
2025-11-13 14:33:01 +00:00
Nawaz Dhandala
3f3956edd6 feat: implement SDK-side aggregation selector for modern metrics API 2025-11-13 13:32:35 +00:00
Nawaz Dhandala
93755da2e8 Merge branch 'master' of https://github.com/OneUptime/oneuptime 2025-11-13 12:06:46 +00:00
Nawaz Dhandala
0657222ea7 Add support for Exception monitor type in MonitorCriteriaInstance 2025-11-13 12:06:42 +00:00
Nawaz Dhandala
ca352826ca Add Exception Monitor functionality with related types and components 2025-11-13 12:02:17 +00:00
Simon Larsen
3cbd99042b Merge pull request #2107 from OneUptime/chore/npm-audit-fix
chore: npm audit fix
2025-11-13 09:38:52 +00:00
simlarsen
2f102acdc2 chore: npm audit fix 2025-11-13 01:48:58 +00:00
Nawaz Dhandala
b76811d152 Fix indentation for headers in API requests across multiple components 2025-11-12 17:55:54 +00:00
Nawaz Dhandala
2335935a3e Add conditional rendering for app.enabled in app.yaml 2025-11-12 17:53:01 +00:00
Nawaz Dhandala
c324fe03d3 Update API header retrieval to remove dependency on StatusPageUtil for all subscription and announcement pages 2025-11-12 17:52:44 +00:00
Nawaz Dhandala
d5bc83a5a1 Remove deprecated @opentelemetry/sdk-trace-node dependency from package.json and package-lock.json 2025-11-12 17:44:28 +00:00
Nawaz Dhandala
e2baa449f5 Refactor Telemetry initialization to explicitly type webTraceExporter as WebSpanExporter 2025-11-12 16:18:39 +00:00
Nawaz Dhandala
51b88eb065 Refactor Telemetry class to streamline span processor registration 2025-11-12 16:16:34 +00:00
Nawaz Dhandala
b0d95bb7df Add 'enabled' property to various components in values schema and YAML templates 2025-11-12 16:15:29 +00:00
Nawaz Dhandala
8bf8c891ab Refactor telemetry exports to improve type handling and streamline initialization 2025-11-12 13:32:27 +00:00
Nawaz Dhandala
fcf919c70b Refactor session handling and cookie management in StatusPage authentication 2025-11-12 12:52:19 +00:00
Nawaz Dhandala
f0f3d32d31 Merge remote-tracking branch 'origin/snyk-upgrade-b70b2734abb0e16d5d110c8cd2735c35' 2025-11-12 11:49:20 +00:00
Nawaz Dhandala
444e8f17b6 Implement feature X to enhance user experience and fix bug Y in module Z 2025-11-12 11:46:44 +00:00
Nawaz Dhandala
3aabf44b4e Merge branch 'snyk-upgrade-f017994c6dac770941ee664640830ac7' 2025-11-12 11:45:47 +00:00
Simon Larsen
c11fcc3c8e Merge pull request #2106 from OneUptime/user-refresh-token
User refresh token
2025-11-12 11:42:29 +00:00
Simon Larsen
52519c9af8 Merge pull request #2104 from OneUptime/snyk-upgrade-d659682fbd62c498810b328f5aaca524
[Snyk] Upgrade @opentelemetry/exporter-trace-otlp-http from 0.52.1 to 0.207.0
2025-11-12 11:42:08 +00:00
Simon Larsen
2483cf9499 Merge pull request #2102 from OneUptime/snyk-upgrade-289d4467acd89e4854c2a2dc61916341
[Snyk] Upgrade @opentelemetry/exporter-logs-otlp-http from 0.52.1 to 0.207.0
2025-11-12 11:41:44 +00:00
Simon Larsen
634e21b13c Merge pull request #2101 from OneUptime/snyk-upgrade-8678075385220dcc2c31b1b4a3900956
[Snyk] Upgrade @opentelemetry/sdk-logs from 0.52.1 to 0.207.0
2025-11-12 11:41:35 +00:00
Nawaz Dhandala
aad933b9eb feat(Authentication, Session Management): implement finalizeStatusPageLogin and refresh-token endpoints for enhanced session handling 2025-11-12 11:40:52 +00:00
Nawaz Dhandala
9356f2964e feat(Authentication): integrate UserSession model and enhance finalizeUserLogin type definition
feat(Express): define HeaderValue type and improve type annotations for headerValueToString and extractDeviceInfo functions
2025-11-11 21:41:20 +00:00
Nawaz Dhandala
aae70ead3b refactor: streamline code formatting and improve readability across multiple files 2025-11-11 21:36:12 +00:00
Nawaz Dhandala
8a482dce10 feat(UserSession): enhance session management with comprehensive session handling methods and metadata 2025-11-11 21:34:11 +00:00
Nawaz Dhandala
9fdf46889c feat(Text): add truncate method for string length limitation 2025-11-11 21:32:57 +00:00
Nawaz Dhandala
40ca9dc04c feat(Authentication, SSO): enhance session management with user session creation and refresh token handling 2025-11-11 21:22:21 +00:00
Nawaz Dhandala
74937f2208 feat(DeviceInfo): add extractDeviceInfo function and RequestDeviceInfo type for enhanced device data retrieval 2025-11-11 21:20:07 +00:00
Nawaz Dhandala
c02ab56477 feat(Cookie): enhance cookie management with refresh token support and default access token expiry 2025-11-11 21:11:34 +00:00
Nawaz Dhandala
3f99b9680f feat(Migration): add UserSession and StatusPagePrivateUserSession migrations with constraints and indexes 2025-11-11 19:51:54 +00:00
Nawaz Dhandala
b08c39037d feat(Index): add StatusPagePrivateUserSessionService and UserSessionService to services 2025-11-11 19:49:32 +00:00
Nawaz Dhandala
f7cc3c00da feat(Migration): add migration for StatusPagePrivateUserSession and UserSession tables 2025-11-11 19:48:42 +00:00
Nawaz Dhandala
ac4286935a refactor(StatusPagePrivateUserSession): remove unnecessary blank line for cleaner code
refactor(UserSession): format description for additional info column for improved readability
2025-11-11 19:47:08 +00:00
Nawaz Dhandala
90a0b2e4a8 refactor(StatusPagePrivateUserSession): simplify access control by removing specific permissions 2025-11-11 19:46:19 +00:00
Nawaz Dhandala
9b22c48d27 feat(UserSession): add UserSession model for managing active user sessions and security tokens 2025-11-11 19:41:41 +00:00
Nawaz Dhandala
9c9dad5da0 feat(UserSettings): add user settings page and integrate into side menu 2025-11-11 19:18:20 +00:00
Nawaz Dhandala
e986f74025 fix(TeamMemberService): skip one-member guard when SCIM manages project membership 2025-11-11 19:07:11 +00:00
snyk-bot
deb2e81b21 fix: upgrade @opentelemetry/exporter-trace-otlp-proto from 0.52.1 to 0.207.0
Snyk has created this PR to upgrade @opentelemetry/exporter-trace-otlp-proto from 0.52.1 to 0.207.0.

See this package in npm:
@opentelemetry/exporter-trace-otlp-proto

See this project in Snyk:
https://app.snyk.io/org/oneuptime-RsC2nshvQ2Vnr35jHvMnMP/project/f6446ec8-d441-487e-b58f-38373430e213?utm_source=github&utm_medium=referral&page=upgrade-pr
2025-11-11 17:46:09 +00:00
snyk-bot
0f8b322892 fix: upgrade @opentelemetry/exporter-trace-otlp-http from 0.52.1 to 0.207.0
Snyk has created this PR to upgrade @opentelemetry/exporter-trace-otlp-http from 0.52.1 to 0.207.0.

See this package in npm:
@opentelemetry/exporter-trace-otlp-http

See this project in Snyk:
https://app.snyk.io/org/oneuptime-RsC2nshvQ2Vnr35jHvMnMP/project/f6446ec8-d441-487e-b58f-38373430e213?utm_source=github&utm_medium=referral&page=upgrade-pr
2025-11-11 17:46:03 +00:00
snyk-bot
23c7de3ecd fix: upgrade @opentelemetry/exporter-metrics-otlp-proto from 0.52.1 to 0.207.0
Snyk has created this PR to upgrade @opentelemetry/exporter-metrics-otlp-proto from 0.52.1 to 0.207.0.

See this package in npm:
@opentelemetry/exporter-metrics-otlp-proto

See this project in Snyk:
https://app.snyk.io/org/oneuptime-RsC2nshvQ2Vnr35jHvMnMP/project/f6446ec8-d441-487e-b58f-38373430e213?utm_source=github&utm_medium=referral&page=upgrade-pr
2025-11-11 17:45:57 +00:00
snyk-bot
ad144a6240 fix: upgrade @opentelemetry/exporter-logs-otlp-http from 0.52.1 to 0.207.0
Snyk has created this PR to upgrade @opentelemetry/exporter-logs-otlp-http from 0.52.1 to 0.207.0.

See this package in npm:
@opentelemetry/exporter-logs-otlp-http

See this project in Snyk:
https://app.snyk.io/org/oneuptime-RsC2nshvQ2Vnr35jHvMnMP/project/f6446ec8-d441-487e-b58f-38373430e213?utm_source=github&utm_medium=referral&page=upgrade-pr
2025-11-11 17:45:52 +00:00
snyk-bot
debfef0388 fix: upgrade @opentelemetry/sdk-logs from 0.52.1 to 0.207.0
Snyk has created this PR to upgrade @opentelemetry/sdk-logs from 0.52.1 to 0.207.0.

See this package in npm:
@opentelemetry/sdk-logs

See this project in Snyk:
https://app.snyk.io/org/oneuptime-RsC2nshvQ2Vnr35jHvMnMP/project/f6446ec8-d441-487e-b58f-38373430e213?utm_source=github&utm_medium=referral&page=upgrade-pr
2025-11-11 17:45:46 +00:00
Nawaz Dhandala
bb85c9f8c8 refactor(BaseModelTable): enhance filter function for dropdown labels to improve type safety 2025-11-11 17:23:14 +00:00
Nawaz Dhandala
25ab1cdbf9 refactor(BaseModelTable): improve code formatting and simplify access control value handling 2025-11-11 17:21:51 +00:00
Nawaz Dhandala
44b8a9ddc9 feat(BaseModelTable): integrate access control column handling and update dropdown labels with color support 2025-11-11 17:16:52 +00:00
Nawaz Dhandala
c388ff9550 fix(IncidentCreate): remove unnecessary whitespace in color mapping function 2025-11-11 15:59:04 +00:00
Nawaz Dhandala
321d1680e6 feat(IncidentCreate): enhance incident state options with color attribute 2025-11-11 15:58:13 +00:00
Nawaz Dhandala
6c0e9f0fed refactor: remove unnecessary whitespace in model classes and improve code formatting 2025-11-11 15:49:20 +00:00
Nawaz Dhandala
99349ecb30 fix: restore @ColorField decorator in multiple model classes for color handling 2025-11-11 15:47:57 +00:00
Nawaz Dhandala
258bbbd9cf feat(BaseModelTable): enhance dropdown options with color handling based on the first color column 2025-11-11 15:37:56 +00:00
Nawaz Dhandala
1094a07fc6 fix(DropdownUtil): ensure color variable is explicitly typed as Color | null
refactor(ColorField): add return type annotation for ColorField function
2025-11-11 14:30:33 +00:00
Nawaz Dhandala
14a5671645 feat(Color, Dropdown, ModelForm): enhance color handling in Color class and Dropdown options 2025-11-11 14:05:30 +00:00
Nawaz Dhandala
5a41c66953 refactor(DatabaseBaseModel, ColorField): improve formatting and readability of type definitions and method implementations 2025-11-11 13:26:02 +00:00
Nawaz Dhandala
af605fce4c feat(DatabaseBaseModel): add getFirstColorColumn method to retrieve the first color field column 2025-11-11 13:23:55 +00:00
Nawaz Dhandala
f8ef6c69fe feat(ColorField): add ColorField decorator and related utility functions for color field management in database models 2025-11-11 13:20:42 +00:00
Simon Larsen
e1848f44f7 Merge pull request #2100 from OneUptime/dropdown-lbl
Dropdown lbl
2025-11-11 12:49:54 +00:00
Nawaz Dhandala
825bd39dda feat(Dropdown): enhance type definitions for styling functions and improve label rendering 2025-11-11 12:49:25 +00:00
Nawaz Dhandala
b99905dfe8 fix(Telemetry): add npm install step for Common directory in workflow 2025-11-11 12:45:06 +00:00
Nawaz Dhandala
a4bf40a2c1 fix(Label): correct indentation for icon property in LabelElement 2025-11-11 12:44:05 +00:00
Nawaz Dhandala
711998b048 feat(Icon): add strokeWidth to EmptyCircle icon rendering 2025-11-11 12:42:36 +00:00
Nawaz Dhandala
132e044c07 feat(Icon): add EmptyCircle icon and update Label to use it 2025-11-11 12:16:01 +00:00
Nawaz Dhandala
8ecc307451 feat(Dropdown): implement label rendering and color resolution for selected labels 2025-11-11 12:02:49 +00:00
Nawaz Dhandala
c85c29989f feat(Dropdown): update styling for focused and selected states, enhance multi-value appearance 2025-11-10 23:29:16 +00:00
Nawaz Dhandala
95726e0f21 feat(Dropdown): enhance dropdown options with label support and improve styling 2025-11-10 23:13:10 +00:00
Nawaz Dhandala
adc15992e9 refactor(Label): simplify import statements for Pill component 2025-11-10 22:49:36 +00:00
Nawaz Dhandala
58d83a2a80 feat(Pill): add thickness prop to Icon component in Pill 2025-11-10 22:48:57 +00:00
Nawaz Dhandala
5461cd4502 feat(Pill): add icon support to Pill component and update tests 2025-11-10 22:44:07 +00:00
Nawaz Dhandala
478465a65b refactor: update label imports and restructure label components for consistency 2025-11-10 22:34:33 +00:00
Nawaz Dhandala
bef57b784d Merge branch 'release' of https://github.com/OneUptime/oneuptime into release 2025-11-10 16:38:32 +00:00
Nawaz Dhandala
601eed0e70 refactor(Page): enhance layout and spacing for title and labels section
refactor(ModelPage): improve formatting of labelsColumn assignment
refactor(DatabaseBaseModel): remove unnecessary blank line
2025-11-10 16:31:29 +00:00
Nawaz Dhandala
dc1215f28b refactor(Page): adjust title font size for improved readability 2025-11-10 15:55:44 +00:00
Nawaz Dhandala
f617330484 refactor: remove labelsColumn and associated method, update ModelPage to use getAccessControlColumn 2025-11-10 15:53:44 +00:00
Simon Larsen
888d8d6fbf refactor: clean up code formatting and improve readability across multiple files 2025-11-10 14:36:44 +00:00
Simon Larsen
79a9bb2229 chore(notification): include WhatsApp in balance, auto-recharge and notification copy
Update Project model and NotificationSettings UI text to mention WhatsApp alongside SMS and Call for current balance, auto-recharge settings, and related notifications.
2025-11-10 14:15:47 +00:00
Simon Larsen
0578f9f1be Merge pull request #2092 from OneUptime/master
Release
2025-11-10 09:35:46 +00:00
Simon Larsen
ebbddbd797 Merge pull request #2091 from OneUptime/snyk-fix-633d6e2055ebd39def346bdc57989683
[Snyk] Security upgrade nginx from 1.29.2-alpine to 1.29.3-alpine
2025-11-10 09:35:11 +00:00
Simon Larsen
6cdaaf1489 Merge pull request #2090 from OneUptime/chore/npm-audit-fix
chore: npm audit fix
2025-11-10 09:35:02 +00:00
snyk-bot
93e62befbb fix: Nginx/Dockerfile.tpl to reduce vulnerabilities
The following vulnerabilities are fixed with an upgrade:
- https://snyk.io/vuln/SNYK-ALPINE322-PCRE2-13637025
2025-11-08 10:56:45 +00:00
simlarsen
bccd2f484b chore: npm audit fix 2025-11-08 01:40:56 +00:00
Nawaz Dhandala
c01fc9ee64 chore(migration): drop jwtRefreshToken column from User and StatusPagePrivateUser tables
- remove jwtRefreshToken property from User model
- add migration to drop column from User and StatusPagePrivateUser and restore it on down
- register new migration in SchemaMigrations index
2025-11-07 22:37:25 +00:00
Simon Larsen
be9dcbd01e Merge pull request #2089 from OneUptime/otel-ingest-rename
Otel ingest rename
2025-11-07 22:22:27 +00:00
Nawaz Dhandala
48f85df04c fix(header): use w-64 instead of max-w-64 for ProjectPicker container to enforce fixed width 2025-11-07 22:01:32 +00:00
Nawaz Dhandala
fc08578ff2 chore(telemetry): remove openTelemetryCollectorHost and OTEL collector nginx/ingress config 2025-11-07 21:49:42 +00:00
Nawaz Dhandala
ea9a245b82 chore(nginx): rename open-telemetry-ingest upstream to telemetry and update proxy_pass targets (/telemetry, fluentd and syslog endpoints) 2025-11-07 21:42:26 +00:00
Nawaz Dhandala
f49b1995df feat(telemetry): add new Telemetry service (OTel, Syslog, Fluent, Metrics, Traces) and unified ingestion pipeline
- Add Telemetry service entrypoint
  - Telemetry/Index.ts: app bootstrap, routes mounting, infrastructure init and Telemetry SDK init.

- Unified queue + worker
  - Telemetry/Jobs/TelemetryIngest/ProcessTelemetry.ts: single worker that dispatches queued jobs to specific processors (logs, traces, metrics, syslog, fluent logs).
  - Telemetry/Services/Queue/TelemetryQueueService.ts: central queue API and job payload types.
  - Per-type Queue wrappers (LogsQueueService, MetricsQueueService, TracesQueueService, FluentLogsQueueService, SyslogQueueService).

- OpenTelemetry ingestion middleware and proto support
  - Telemetry/Middleware/OtelRequestMiddleware.ts: detect OTLP endpoint (logs/traces/metrics), decode protobuf bodies using protobufjs and set product type.
  - Telemetry/ProtoFiles/OTel/v1/*.proto: include common.proto, logs.proto, metrics.proto, resource.proto, traces.proto for OTLP v1 messages.

- Ingest services
  - Telemetry/Services/OtelLogsIngestService.ts: parse incoming OTLP logs, map attributes, convert timestamps, batch insert logs.
  - Telemetry/Services/OtelTracesIngestService.ts: parse OTLP traces, build span rows, extract exceptions, batch insert spans and exceptions, save telemetry exception summary.
  - Telemetry/Services/OtelMetricsIngestService.ts: parse OTLP metrics, normalize datapoints, batch insert metrics and index metric name -> service map.
  - Telemetry/Services/SyslogIngestService.ts: syslog ingestion endpoints, parser integration, map syslog fields to attributes and logs.
  - Telemetry/Services/FluentLogsIngestService.ts: ingest Fluentd style logs, normalize entries and insert into log backend.
  - Telemetry/Services/OtelIngestBaseService.ts: helpers to resolve service name from attributes/headers.

- Syslog parser and utilities
  - Telemetry/Utils/SyslogParser.ts: robust RFC5424 and RFC3164 parser, structured data extraction and sanitization.
  - Telemetry/Tests/Utils/SyslogParser.test.ts: unit tests for parser behavior.

- Telemetry exception utilities
  - Telemetry/Utils/Exception.ts: generate exception fingerprint and upsert telemetry exception status (saveOrUpdateTelemetryException).

- Queue & job integration
  - New integration with Common/Server/Infrastructure/Queue and QueueWorker, job id generation and telemetry job types.
  - Telemetry services add ingestion jobs instead of processing synchronously.

- Config, build and dev tooling
  - Add Telemetry/package.json, package-lock.json, tsconfig.json, nodemon.json, jest config.
  - New script configs and dependencies (protobufjs, ts-node, jest, nodemon, etc).

- Docker / environment updates
  - docker-compose.base.yml, docker-compose.dev.yml, docker-compose.yml: rename service from open-telemetry-ingest -> telemetry and wire TELEMETRY_* envs.
  - config.example.env: rename and consolidate environment variables (OPEN_TELEMETRY_* -> TELEMETRY_*, update hostnames and ports).
  - Tests/Scripts/status-check.sh: update ready-check target to telemetry/status/ready.

- Other
  - Telemetry/Services/Queue/*: export helpers and legacy-compatible job interface shims.
  - Memory cleanup and batching safeguards across ingest services.
  - Logging and capture spans added to key code paths.

BREAKING CHANGES / MIGRATION NOTES:
- Environment variables and docker service names changed:
  - Replace OPEN_TELEMETRY_... vars with TELEMETRY_... (PORT, HOSTNAME, CONCURRENCY, DISABLE_TELEMETRY, etc).
  - docker-compose entries moved from "open-telemetry-ingest" to "telemetry" and image name changed to oneuptime/telemetry.
  - Update any deployment automation and monitoring checks referencing the old service name or endpoints.
- Consumers: OTLP endpoints and behavior remain supported, but ingestion is now queued and processed asynchronously.

Testing / Running:
- Install deps in Telemetry/ (npm install) after syncing Common workspace.
- Run dev: npx nodemon (nodemon.json) or build & start using provided scripts.
- Run tests with jest (Telemetry test suite includes SyslogParser unit tests).

Files added/modified (high level):
- Added many files under Telemetry/: Index, Jobs, Middleware, ProtoFiles, Services, Utils, Tests, package and config artifacts.
- Modified docker-compose.* and config.example.env and status check script to use new TELEMETRY service/vars.
2025-11-07 21:36:47 +00:00
Simon Larsen
351fc4828b Merge pull request #2088 from OneUptime/merge-fluentd
Merge fluentd
2025-11-07 20:40:14 +00:00
Nawaz Dhandala
04cb7da6d6 chore(fluentd): update production endpoint and x-oneuptime token in Fluentd config (Fluentd/fluent.conf) 2025-11-07 20:38:23 +00:00
Nawaz Dhandala
c6e2f41351 chore(docker-compose): add fluentd service to docker-compose.base.yml 2025-11-07 20:27:50 +00:00
Simon Larsen
e524dfda6d chore(fluent-ingest): normalize formatting in FluentLogsIngestService and Index.ts 2025-11-07 20:22:51 +00:00
Simon Larsen
30b6353714 chore(fluent-ingest): route fluent log ingest through TelemetryQueueService, add FluentLogsIngestService and remove legacy ProcessFluentLogs job 2025-11-07 20:20:25 +00:00
Simon Larsen
29be9b399f chore(fluent-ingest): route fluent log ingest through TelemetryQueueService and remove legacy queue endpoints
- Replace FluentLogsQueueService import/use with TelemetryQueueService.addFluentLogIngestJob in Fluent API.
- Remove ClusterKeyAuthorization-protected queue admin endpoints (stats, size, failed) from Fluent API.
- Remove ProcessFluentLogs job import from service initialization.
2025-11-07 20:02:22 +00:00
Simon Larsen
36cdeec916 chore(queue): remove FluentLogs from QueueName enum 2025-11-07 19:46:29 +00:00
Simon Larsen
a80b7ba88c chore(fluent-ingest): migrate fluent log ingest into open-telemetry-ingest and remove legacy fluent-ingest service
- Move Fluent/Fluent Bit logs ingestion into open-telemetry-ingest:
  - Add OpenTelemetryIngest/API/Fluent.ts (routes for /fluentd and queue endpoints)
  - Add Queue service, job worker and processor:
    - OpenTelemetryIngest/Services/Queue/FluentLogsQueueService.ts
    - OpenTelemetryIngest/Jobs/TelemetryIngest/ProcessFluentLogs.ts
  - Register Fluent API and job processing in OpenTelemetryIngest/Index.ts
  - Introduce QueueName.FluentLogs and related queue usage

- Remove legacy FluentIngest service and configuration:
  - Delete fluent-ingest docker-compose/dev/base entries and docker-compose.yml service
  - Remove fluent-ingest related helm values, KEDA scaledobject, ingress host and schema entries
  - Remove FLUENTD_HOST env/values and replace FLUENT_INGEST_HOSTNAME -> FLUENT_LOGS_HOSTNAME (pointing to open-telemetry-ingest)
  - Update config.example.env keys (FLUENT_LOGS_CONCURRENCY, DISABLE_TELEMETRY_FOR_FLUENT_LOGS)
  - Remove FluentIngestRoute and FLUENT_INGEST_URL/hostname usages from UI config/templates
  - Remove VSCode launch debug config for Fluent Ingest
  - Remove Fluent ingest E2E status check entry in Tests/Scripts/status-check.sh
  - Update docs/architecture diagram and Helm templates to reflect "FluentLogs" / Fluent Bit flow

- Misc:
  - Remove FLUENTD_HOST environment injection from docker-compose.base.yml
  - Cleanup related values.schema.json and values.yaml entries

This consolidates log ingestion under the OpenTelemetry ingest service and removes the separate FluentIngest service and its configuration.
2025-11-07 19:37:31 +00:00
Simon Larsen
b31d1076b8 chore(fluent-ingest): remove /fluent-ingest nginx proxy location from default.conf.template 2025-11-07 19:04:46 +00:00
Simon Larsen
788e82497c chore(fluent-ingest): remove fluent-ingest upstream and Fluentd collector nginx config; route fluentd/syslog endpoints to open-telemetry-ingest 2025-11-07 19:04:32 +00:00
Simon Larsen
3409b0f66e chore(fluent-ingest): remove FluentIngest E2E status check tests 2025-11-07 18:57:06 +00:00
Simon Larsen
cafed35795 chore(fluent-ingest): remove FluentIngest service and all related sources, configs and artifacts 2025-11-07 18:49:09 +00:00
Simon Larsen
69ae1eb310 chore(ci/infra): remove FluentIngest from workflows, charts and compose; bump OpenTelemetryIngest deps
- Remove FluentIngest CI jobs and release/test deploy steps (build.yml, compile.yml, release.yml, test-release.yaml)
- Delete test.fluent-ingest workflow
- Remove Fluent-related env vars/hostnames from config.example.env, docker-compose.base.yml, HelmChart templates and EnvironmentConfig.ts
- Remove fluent-ingest service block from docker-compose.base.yml
- Bump Playwright and TypeORM versions in OpenTelemetryIngest package-lock.json
2025-11-07 18:46:27 +00:00
Nawaz Dhandala
4335c46e3e fix: ProjectPicker use max-w-64 instead of w-64 for responsive container 2025-11-07 18:36:49 +00:00
Simon Larsen
863f1ae82e Merge pull request #2087 from OneUptime/snyk-fix-c8a12071f54add6476bd98c6671cd43d
[Snyk] Security upgrade typeorm from 0.3.20 to 0.3.26
2025-11-07 13:30:31 +00:00
snyk-bot
0755c15886 fix: Common/package.json & Common/package-lock.json to reduce vulnerabilities
The following vulnerabilities are fixed with an upgrade:
- https://snyk.io/vuln/SNYK-JS-TYPEORM-13746469
2025-11-07 13:25:43 +00:00
Nawaz Dhandala
72ed43563e Merge branch 'master' of https://github.com/OneUptime/oneuptime 2025-11-07 13:24:21 +00:00
Nawaz Dhandala
15ded6cd46 Merge remote-tracking branch 'origin/snyk-upgrade-4b64a1ce29eed910e23d56c358729865' 2025-11-07 13:24:15 +00:00
Simon Larsen
9e238dc660 Merge pull request #2085 from OneUptime/chore/npm-audit-fix
chore: npm audit fix
2025-11-07 13:23:08 +00:00
Nawaz Dhandala
9f3ccc7d74 style(exec): type-annotate spawned child as ChildProcess and format spawn call 2025-11-07 13:22:24 +00:00
simlarsen
9e5db22235 chore: npm audit fix 2025-11-07 01:46:40 +00:00
Nawaz Dhandala
e31417c5bf style(exec, nginx, docs): tidy formatting and indentation across Execute.ts, NginxConfigurator.ts, and Telemetry Documentation 2025-11-06 19:41:57 +00:00
Nawaz Dhandala
bf6e97c35d feat(exec): add executeCommandInheritStdio and use it for nginx config test
- Add spawn and SpawnOptions imports and implement Execute.executeCommandInheritStdio
  that runs commands with inherited stdio, logs errors, and rejects on non-zero exit.
- Update NginxConfigurator to run `nginx -t -c /etc/nginx/nginx.conf` via the new
  inherit-stdio helper before reloading nginx.
2025-11-06 19:41:01 +00:00
Nawaz Dhandala
28073ba819 nginx(config): ensure log directory and access/error log files exist before reload 2025-11-06 14:20:13 +00:00
Nawaz Dhandala
4909a5c980 ci(workflows): disable Docker build cache in GitHub Actions
Add --no-cache to docker build and docker buildx commands across build.yml, release.yml and test-release.yaml to force fresh image builds and avoid using cached layers.
2025-11-06 13:54:58 +00:00
Nawaz Dhandala
c4adc24562 ci(release): handle npm publish --dry-run errors and skip if version already published 2025-11-06 13:33:14 +00:00
Nawaz Dhandala
597344483a docs(telemetry): expand common use cases into detailed sections with rsyslog and Fluent Bit examples 2025-11-06 13:21:01 +00:00
Simon Larsen
05d9b79ba2 docs(opentelemetry-ingest): add Syslog testing instructions with RFC5424 curl example 2025-11-06 12:51:56 +00:00
Simon Larsen
af14edb175 docs(telemetry): add "Send Native Syslog" tile to Documentation component 2025-11-06 12:49:36 +00:00
Simon Larsen
0255bd37d0 docs(telemetry): add "Common Use Cases" section to Syslog guide 2025-11-06 12:47:30 +00:00
Simon Larsen
2e6b463bd7 Merge branch 'master' of github.com:OneUptime/oneuptime 2025-11-06 12:41:33 +00:00
Simon Larsen
95e355ff7d style(opentelemetry-ingest): add RequestHandler/type annotations and simplify parser regexes
- Type setSyslogProductType as RequestHandler
- Import and use ParsedSyslogMessage in parser tests (explicit typed parsed variables)
- Simplify regex usage/formatting in SyslogParser for version and procId matching
- Minor import formatting cleanup
2025-11-06 12:41:29 +00:00
Simon Larsen
cccdcdaf93 style(opentelemetry-ingest): normalize formatting and line-wrapping across ingest code
- Remove extraneous blank line in OTelIngest router
- Reflow imports, function signatures and wrapped expressions in:
  OtelIngestBaseService, SyslogQueueService, SyslogIngestService
- Tidy regex/whitespace and token handling formatting in SyslogParser
- Simplify quoting and compact multiline expectations in SyslogParser tests
- Pure stylistic changes only — no behavioral modifications
2025-11-06 12:34:38 +00:00
Simon Larsen
9256f8b4bd feat(opentelemetry-ingest): add Syslog ingestion API and RFC3164/5424 parsing
- Add new Syslog API (POST /syslog/v1/logs) with product-type middleware and mount it in OpenTelemetryIngest Index
- Move syslog route out of OTelIngest and clean up related imports
- Add parseRfc5424Timestamp and parseRfc3164Timestamp to OneUptimeDate (handles normalization and year rollovers)
- Refactor SyslogParser to use OneUptimeDate parsing helpers and remove duplicated timestamp parsing code
- Update NGINX template to proxy /syslog/v1/logs to open-telemetry-ingest with proper headers/resolver and connection settings
2025-11-06 12:33:36 +00:00
Simon Larsen
b27acbfd38 feat(opentelemetry-ingest): add native Syslog ingestion, parsing, queuing, docs & tests
- Add /syslog/v1/logs endpoint and syslog product-type middleware
- Implement SyslogIngestService: normalize/parse messages, build attributes, batch flush to LogService
- Add robust Syslog parser (RFC5424 & RFC3164) and comprehensive unit tests
- Add TelemetryType.Syslog, SyslogQueueService, and queue handling (enqueue + worker processing)
- Expose OPEN_TELEMETRY_INGEST_SYSLOG_FLUSH_BATCH_SIZE config
- Update Otel ingest router, base service helpers, and ProcessTelemetry worker to support Syslog
- Add documentation page and navigation entry for Syslog telemetry
2025-11-06 12:22:48 +00:00
Nawaz Dhandala
ad9771f222 Merge branch 'release' 2025-11-06 11:55:36 +00:00
Nawaz Dhandala
20a3eab3a0 fix(email): validate using RFC5322 regex and remove redundant Zod check 2025-11-06 11:55:14 +00:00
Nawaz Dhandala
fbe198f0c0 fix(nginx): ensure /var/log/nginx and logs exist; set error_log to /var/log/nginx/error.log
Create /var/log/nginx and touch access.log/error.log in run.sh so nginx -t succeeds before reloads.
Revert nginx.conf error_log to /var/log/nginx/error.log (notice).
2025-11-06 11:34:19 +00:00
Nawaz Dhandala
bb48776e02 fix(nginx): use stderr for error_log to enable container-friendly logging 2025-11-05 21:38:59 +00:00
Nawaz Dhandala
0f92342742 fix(nginx): write error_log to /proc/self/fd/2 for container-friendly logging 2025-11-05 20:33:32 +00:00
Nawaz Dhandala
6ed41b87dd fix(nginx): send error_log to /dev/stderr for container-friendly logging 2025-11-05 19:52:06 +00:00
Nawaz Dhandala
12364415aa ci(release): skip npm publish if version already published; fail on other errors 2025-11-05 19:37:45 +00:00
Nawaz Dhandala
1a3301e715 fix(monitor): normalize disk paths when matching disk metrics (handle backslashes, trailing slashes and root path) 2025-11-05 17:47:33 +00:00
Nawaz Dhandala
8be7b68faf fix(helm): move nodeSelector into e2e CronJob pod template and add per-job override 2025-11-05 16:58:07 +00:00
Nawaz Dhandala
47f9d3914e fix(queue): normalize job IDs (replace ':' with '-') when adding/removing jobs and handling repeatable keys 2025-11-05 15:14:51 +00:00
Nawaz Dhandala
8a1afbe7dc Merge branch 'master' of https://github.com/OneUptime/oneuptime 2025-11-05 13:32:12 +00:00
Simon Larsen
87ac6f3106 Merge branch 'master' of github.com:OneUptime/oneuptime 2025-11-05 13:23:25 +00:00
Simon Larsen
2df32e4cdd fix(monitor): return null for cached monitor status name instead of undefined 2025-11-05 13:23:23 +00:00
Nawaz Dhandala
2e2adffe17 fix(nginx): use findAllBy and remove LIMIT_MAX when fetching certs for disk write jobs 2025-11-05 13:11:58 +00:00
Nawaz Dhandala
2a15cf8676 fix(acme): adjust ACME challenge route to /acme-challenge/.well-known/:token 2025-11-05 13:02:02 +00:00
Nawaz Dhandala
d249579c1c fix(acme): mount .well-known/acme-challenge router on main router to expose ACME challenge endpoint 2025-11-05 12:52:42 +00:00
Nawaz Dhandala
05681b108b style(monitor): add explicit type annotations and minor formatting cleanup in EvaluationLogList 2025-11-05 12:38:50 +00:00
Nawaz Dhandala
36867a0b8c style(monitor): render criteria message using Alert component in EvaluationLogList 2025-11-05 12:27:12 +00:00
Nawaz Dhandala
0e5a832628 feat(monitor): include incident/alert numbers in evaluation events and show them in UI
- select incidentNumber/alertNumber when loading open incidents/alerts
- attach relatedIncidentNumber / relatedAlertNumber to evaluation events (created/resolved/skipped)
- add number fields to MonitorEvaluationEvent type
- decorate event title/message in EvaluationLogList to include "Incident #N" / "Alert #N"
2025-11-05 12:25:20 +00:00
Nawaz Dhandala
46f69fdde5 Merge branch 'master' of https://github.com/OneUptime/oneuptime 2025-11-05 12:14:21 +00:00
Nawaz Dhandala
70e6c0abe1 style(monitor): wrap criteria message and met notice in styled callouts with icons 2025-11-05 12:14:15 +00:00
Simon Larsen
c5938956af docs(readme,helm): add Community vs. Enterprise table to main README; expand Enterprise Edition details in Helm chart README 2025-11-05 12:12:42 +00:00
Simon Larsen
e9bfe74b5d Merge branch 'master' of github.com:OneUptime/oneuptime 2025-11-05 12:09:46 +00:00
Simon Larsen
55085a5e6c docs(helm): add Community vs. Enterprise table, document ssl.provision and image.type, remove duplicate Uninstall section 2025-11-05 12:09:42 +00:00
Nawaz Dhandala
9cb48a41e7 style(monitor): restore criteria 'not checked' notice and use ArrowCircleRight icon for events 2025-11-05 12:03:14 +00:00
Nawaz Dhandala
dd8179c0a7 refactor(monitor): remove short-circuit notice and related logic from EvaluationLogList
Remove firstMetCriteriaIndex and shouldShowShortCircuitMessage, and delete the UI block that displayed the "remaining criteria were not evaluated" short-circuit message. Simplifies criteria rendering by removing unused short-circuit handling.
2025-11-05 12:01:04 +00:00
Simon Larsen
f9f84d4104 docs(helm): note Let's Encrypt requires host reachable on ports 80 and 443 2025-11-05 11:58:54 +00:00
Simon Larsen
827663675d refactor(queue): extract BullMQAdapter array and cast to BullBoardQueues for type compatibility 2025-11-05 11:57:48 +00:00
Nawaz Dhandala
0e8d7f2d6b fix(monitor): show short-circuit notice only for first met criteria, remove unused import, and tweak spacing/styles 2025-11-05 11:56:51 +00:00
Nawaz Dhandala
0dd9dfb505 style(monitor): fix JSX conditional formatting in EvaluationLogList 2025-11-05 11:40:36 +00:00
Nawaz Dhandala
b3c68df77e refactor(monitor): centralize persistence of latest monitor payload
Extract persistLatestMonitorPayload and consolidate handling of serverMonitorResponse
and incomingMonitorRequest. Ensure monitor payload updates are saved consistently
(including when there are no steps or no matching monitor step) and before writing logs.
Also clone incomingMonitorRequest via JSON to avoid mutating the original payload and
normalize debug messages.
2025-11-05 11:38:34 +00:00
Nawaz Dhandala
06d0510667 Merge branch 'master' of https://github.com/OneUptime/oneuptime 2025-11-05 11:34:28 +00:00
Nawaz Dhandala
059b7db474 fix(nginx): narrow ACME challenge location to /.well-known/acme-challenge 2025-11-05 11:30:17 +00:00
Simon Larsen
ff17d990d1 fix(scim): make Create Group idempotent — reuse existing team and return 200 when reused
- Reuse an existing team instead of throwing BadRequest on duplicate group names.
- Create a new team when not found, setting isTeamEditable/isTeamDeleteable and allowing empty groups.
- Ensure member additions operate on the resolved target team.
- Expand team select fields and fetch the team for response; return 201 for newly created teams and 200 when reusing an existing one.
2025-11-05 11:17:28 +00:00
Nawaz Dhandala
2e6658542b delete scim readme 2025-11-05 11:12:27 +00:00
Nawaz Dhandala
04a4d6e4de fix(monitor): show short-circuit note for satisfied criteria and normalize met text color
- Add notice when a criteria is satisfied under FilterCondition.Any to indicate remaining criteria were not evaluated.
- Ensure FilterCondition is imported where used.
- Change "Criteria met" text color in Logs view from green to gray for consistent summary styling.
2025-11-05 10:52:03 +00:00
Nawaz Dhandala
2f595fe490 Merge branch 'monitor-log-summary-update' 2025-11-05 10:49:48 +00:00
Nawaz Dhandala
303554d644 refactor(monitor): group identical criteria filters in EvaluationLogList, aggregate metadata & status; use NORMAL small action buttons 2025-11-05 10:49:24 +00:00
Simon Larsen
2ca45b143d Merge pull request #2083 from OneUptime/monitor-log-summary-update
Monitor log summary update
2025-11-05 10:32:57 +00:00
Nawaz Dhandala
b5722256c5 refactor(email): replace custom RFC5322 regex with Zod email validation and add early falsy check 2025-11-05 09:41:42 +00:00
Nawaz Dhandala
0d231a6132 chore(eslint): enable no-control-regex and tidy rule formatting 2025-11-05 09:38:26 +00:00
Simon Larsen
ecc1d841e2 Merge pull request #2080 from OneUptime/snyk-upgrade-ad5a46fc6886b9d33f00f95d68951c86
[Snyk] Upgrade zod from 3.25.30 to 3.25.76
2025-11-05 09:34:42 +00:00
Simon Larsen
cddf534449 Merge pull request #2081 from OneUptime/snyk-upgrade-58044c8091e4244c9346f20e7029dcbd
[Snyk] Upgrade @opentelemetry/api-logs from 0.52.1 to 0.206.0
2025-11-05 09:34:36 +00:00
Simon Larsen
a4ba662211 Merge pull request #2078 from OneUptime/snyk-upgrade-a266987590b01e591eec631cb95143b3
[Snyk] Upgrade bullmq from 5.26.2 to 5.61.0
2025-11-05 09:34:20 +00:00
Simon Larsen
604bc33fb3 Merge pull request #2077 from OneUptime/snyk-upgrade-60fa724635c3f357d78809a2791dae5d
[Snyk] Upgrade posthog-js from 1.186.3 to 1.275.3
2025-11-05 09:34:12 +00:00
Simon Larsen
a1ae1bee89 Merge pull request #2082 from OneUptime/monitor-log-summary-update
Monitor log summary update
2025-11-05 09:33:51 +00:00
Nawaz Dhandala
775b8846c7 refactor(monitor): tidy formatting, consolidate imports and add type annotations
- Normalize whitespace/indentation and reformat several monitor utilities and message builders
- Consolidate and reorder imports (including MonitorEvaluationSummary) across evaluator/data-extractor modules
- Add explicit types (MonitorStatus, BasicDiskMetrics) and tighten type annotations in observation/resource code
- Minor cleanups to conditional formatting in dashboard components (EvaluationLogList, SummaryInfo)
2025-11-05 09:33:29 +00:00
Nawaz Dhandala
3837208023 refactor(monitor): split MonitorCriteriaMessageBuilder into smaller responsibility-focused modules
Move expectation, observation, data-extraction and formatting logic out of the large
MonitorCriteriaMessageBuilder into new classes:
- MonitorCriteriaExpectationBuilder
- MonitorCriteriaObservationBuilder
- MonitorCriteriaDataExtractor
- MonitorCriteriaMessageFormatter

Keep MonitorCriteriaMessageBuilder slim: it now orchestrates message construction and
delegates description/formatting responsibilities to the new modules.
2025-11-05 09:23:14 +00:00
Nawaz Dhandala
b45910a22e refactor(monitor): extract criteria evaluation, message builder, metrics & log utils from MonitorResource
- Move criteria processing into MonitorCriteriaEvaluator
- Move filter/observation message logic into MonitorCriteriaMessageBuilder
- Move monitor metrics logic into MonitorMetricUtil
- Move monitor log persistence into MonitorLogUtil
- Replace large in-file implementations in MonitorResource with calls to the new utilities to reduce complexity and improve separation of concerns
2025-11-05 08:59:14 +00:00
Nawaz Dhandala
c787d7eca0 refactor(monitor): format compare messages and add value formatting helpers 2025-11-05 08:38:04 +00:00
snyk-bot
9771c4cd69 fix: upgrade @opentelemetry/api-logs from 0.52.1 to 0.206.0
Snyk has created this PR to upgrade @opentelemetry/api-logs from 0.52.1 to 0.206.0.

See this package in npm:
@opentelemetry/api-logs

See this project in Snyk:
https://app.snyk.io/org/oneuptime-RsC2nshvQ2Vnr35jHvMnMP/project/f6446ec8-d441-487e-b58f-38373430e213?utm_source=github&utm_medium=referral&page=upgrade-pr
2025-11-04 23:28:08 +00:00
snyk-bot
4471d6bec4 fix: upgrade zod from 3.25.30 to 3.25.76
Snyk has created this PR to upgrade zod from 3.25.30 to 3.25.76.

See this package in npm:
zod

See this project in Snyk:
https://app.snyk.io/org/oneuptime-RsC2nshvQ2Vnr35jHvMnMP/project/f6446ec8-d441-487e-b58f-38373430e213?utm_source=github&utm_medium=referral&page=upgrade-pr
2025-11-04 23:28:03 +00:00
snyk-bot
95e24d9ae0 fix: upgrade playwright from 1.55.1 to 1.56.0
Snyk has created this PR to upgrade playwright from 1.55.1 to 1.56.0.

See this package in npm:
playwright

See this project in Snyk:
https://app.snyk.io/org/oneuptime-RsC2nshvQ2Vnr35jHvMnMP/project/f6446ec8-d441-487e-b58f-38373430e213?utm_source=github&utm_medium=referral&page=upgrade-pr
2025-11-04 23:27:58 +00:00
snyk-bot
f8a7330f79 fix: upgrade bullmq from 5.26.2 to 5.61.0
Snyk has created this PR to upgrade bullmq from 5.26.2 to 5.61.0.

See this package in npm:
bullmq

See this project in Snyk:
https://app.snyk.io/org/oneuptime-RsC2nshvQ2Vnr35jHvMnMP/project/f6446ec8-d441-487e-b58f-38373430e213?utm_source=github&utm_medium=referral&page=upgrade-pr
2025-11-04 23:27:53 +00:00
snyk-bot
ae177c920f fix: upgrade posthog-js from 1.186.3 to 1.275.3
Snyk has created this PR to upgrade posthog-js from 1.186.3 to 1.275.3.

See this package in npm:
posthog-js

See this project in Snyk:
https://app.snyk.io/org/oneuptime-RsC2nshvQ2Vnr35jHvMnMP/project/f6446ec8-d441-487e-b58f-38373430e213?utm_source=github&utm_medium=referral&page=upgrade-pr
2025-11-04 23:27:47 +00:00
Nawaz Dhandala
9faa38454d refactor(monitor): improve criteria filter messages and add rich observation descriptions
- Replace ad-hoc success/failure messaging with buildCriteriaFilterMessage / buildCriteriaFilterFailureMessage
- Add detailed describe*Observation helpers for many CheckOn types (response, headers, body, isOnline, timeouts, incoming requests, CPU/memory/disk, processes, SSL, synthetic/custom code, metrics, logs, spans)
- Introduce utility helpers: formatNumber, formatPercentage, formatBytes, formatList, formatSnippet, describeProcesses, computeDiskUsagePercent, summarizeNumericSeries, formatResultValue, and various response extractors
- Enhance metric value extraction to select correct aggregated result by alias and return summarized numeric series
- Wire new messaging into MonitorResource evaluation flow (use filterMessage everywhere)
- Import and use FilterType and ServerProcess types plus several monitor response types
- Small fix in ServerMonitorCriteria: find disk metric and prefer percentUsed (fall back to percentFree) when computing disk usage percent
2025-11-04 22:39:51 +00:00
Nawaz Dhandala
a4198ec409 refactor(monitor): consolidate evaluation logs for probe-based monitors
Compute a probable evaluationSummary from props.evaluationSummary or the first probe response that has one, remove per-probe EvaluationLogList, and render evaluation logs once for probable (probe) monitors to avoid duplicated log lists.
2025-11-04 22:11:58 +00:00
Nawaz Dhandala
24d184debf feat(monitor, dashboard): resolve monitor status names in events and add view buttons for incidents/alerts
Cache and fetch monitor status names in MonitorResource and include readable status names in evaluationSummary events. Add action buttons in EvaluationLogList to navigate to related incident/alert views.
2025-11-04 22:08:08 +00:00
Nawaz Dhandala
f307c904b0 fix(monitor): persist monitor log on early exits and add input guards to saveMonitorLog 2025-11-04 21:31:54 +00:00
Nawaz Dhandala
2d20b7fd13 refactor(monitor): add explicit typings for render functions and evaluationSummary; simplify catch
Add explicit function type annotations for renderCriteriaResult, renderEvent and renderEvaluationLogs in SummaryView to improve type safety and readability. Also type the evaluationSummary variable in Monitor view and simplify the catch block by removing the unused error parameter.
2025-11-04 21:11:18 +00:00
Nawaz Dhandala
fd738b23d0 refactor(monitor, dashboard): normalize multiline formatting and simplify conditional logic
- Normalize multiline/inline formatting in MonitorResource.ts, EvaluationLogList.tsx and Logs.tsx
- Simplify nested else to else-if for FilterCondition.All in MonitorResource
- Minor JSX spacing and map return cleanup for clearer readability
2025-11-04 21:09:02 +00:00
Simon Larsen
deffa6489d feat(monitor): fetch and surface evaluationSummary from MonitorLog in Monitor view and Logs
- Add AnalyticsModelAPI call in Monitor view to load the latest MonitorLog and extract evaluationSummary into component state.
- Pass latest evaluationSummary to Summary component in Monitor view.
- Add Evaluation Outcome column to Monitor Logs table to show criteria met / no criteria / not recorded.
- Pass evaluationSummary into the Logs modal's SummaryInfo.
- Import MonitorEvaluationSummary types and MonitorLog analytics model.
2025-11-04 21:00:14 +00:00
Simon Larsen
e5f1d5553e feat(monitor): add MonitorEvaluationSummary and evaluation logs
- introduce MonitorEvaluationSummary type and related result/event types
- thread evaluationSummary through probe/monitor response types and probe ingest flow
- initialize and populate evaluationSummary in MonitorResource (criteriaResults, events)
- record events for criteria evaluation, monitor status changes, incident/alert create/skip/resolve
- update criteria filter evaluation to produce structured filter results and messages
- add EvaluationLogList UI and wire evaluationSummary into Summary/SummaryInfo views
- minor Date utility usages to timestamp events
2025-11-04 20:58:18 +00:00
Nawaz Dhandala
d2ee3c5409 refactor(admin-dashboard, nginx): normalize multiline formatting in Serve.ts, NginxConfigurator.ts and WriteServerCertToDisk.ts 2025-11-04 20:39:53 +00:00
Nawaz Dhandala
9a1ecd7fe0 fix(admin-dashboard): clarify NotAuthorizedException messages in Serve.ts
Replace generic "Only master admins can access this app." with
"Unauthorized: Only master admins can access the admin dashboard." to
provide clearer, more informative authorization errors.
2025-11-04 20:39:14 +00:00
Simon Larsen
b41d8ab5ab Merge pull request #2076 from OneUptime/ssl-load
Ssl load
2025-11-04 20:36:03 +00:00
Nawaz Dhandala
b809e1c43b refactor(analytics): extract includesValues and simplify numeric-array detection in Statement.toColumnType 2025-11-04 20:35:33 +00:00
Nawaz Dhandala
743f8721f3 fix(helm): correct YAML indentation for SERVER_ADMIN_DASHBOARD_HOSTNAME in _helpers.tpl 2025-11-04 20:06:40 +00:00
Simon Larsen
c0aa2b7905 Merge pull request #2075 from OneUptime/ssl-load
Ssl load
2025-11-04 19:56:35 +00:00
Nawaz Dhandala
4ac5819e6a fix(nginx): generate placeholder certs and guard HTTPS directives; test config after envsubst
Add ensure_placeholder_certificate to envsubst-on-templates.sh to generate a temporary self-signed cert when PRIMARY_DOMAIN is set but cert files are missing. Only export SSL listen/certificate directives if certs (real or placeholder) are available; otherwise disable HTTPS directives and emit warnings. Simplify PRIMARY_DOMAIN logging.

Also run "nginx -t" immediately after running the envsubst script in NginxConfigurator to validate generated config before attempting reload.
2025-11-04 19:55:22 +00:00
Nawaz Dhandala
158663c44b fix(nginx): only write/reload when certs change; derive primary domain and guard SSL directives
- WriteServerCertToDisk: read existing cert/key from disk and compare with DB values; skip writing when unchanged. After writing, run envsubst-on-templates.sh and reload nginx with try/catch and logging.
- envsubst-on-templates.sh: derive PRIMARY_DOMAIN from HOST when not set, compute cert/key paths, and only export PROVISION_SSL_* directives when certificate files exist (otherwise clear directives and log).
2025-11-04 19:44:55 +00:00
Simon Larsen
3d2bcfa579 refactor(admin): add types for ensureMasterAdminAccess and JSONWebToken decode result 2025-11-04 19:21:07 +00:00
Simon Larsen
21984c8684 chore(docker-compose): consolidate common-ui/server anchors into common-runtime-variables
Replace <<: *common-ui-variables and <<: *common-server-variables with <<: *common-runtime-variables across services and remove the IS_SERVER flag from the server anchor.
2025-11-04 19:18:28 +00:00
Simon Larsen
ad63d18f0a fix(helm): replace runtime env include with oneuptime.env.oneuptimeSecret in isolated-vm template 2025-11-04 19:17:45 +00:00
Simon Larsen
e5af008079 chore(helm): unify runtime env template and update deployments
Replace separate commonServer/commonUi and oneuptimeSecret includes with a single
oneuptime.env.runtime include across deployments. Move oneuptimeSecret into the
common env where appropriate and remove SERVER_ADMIN_DASHBOARD_HOSTNAME.
Update all affected templates to use the new runtime include.
2025-11-04 19:14:27 +00:00
Simon Larsen
3e72b2a9a4 fix(admin): restrict AdminDashboard to master admins and guard index render
Add ensureMasterAdminAccess in AdminDashboard/Serve.ts to decode JWT, validate
isMasterAdmin and return a NotAuthorized response when access is not allowed.
Wire this function into App.init as getVariablesToRenderIndexPage so the admin
frontend is protected.

Also add a res.headersSent guard in StartServer.ts to skip rendering the index
page if a response was already sent, avoiding duplicate responses.
2025-11-04 18:28:10 +00:00
Nawaz Dhandala
6d66c6c369 ci(test-release): replace MCP server Docker builds with Worker image builds
Update test-release workflow to build and push Worker images (./Worker/Dockerfile) and adjust tags (including enterprise variants) instead of the previous MCP server build steps.
2025-11-04 17:58:41 +00:00
Nawaz Dhandala
9544dc2a6c chore(env): use explicit callback body for prefix startsWith check in getFrontendEnvVars 2025-11-04 16:47:07 +00:00
Simon Larsen
a22e3b63e0 Merge branch 'master' of github.com:OneUptime/oneuptime 2025-11-04 16:08:53 +00:00
Simon Larsen
5f1f0cde4a fix(env): restrict frontend env vars and use sanitized getFrontendEnvVars in env.js
Add getFrontendEnvVars with an allow-list and allowed prefixes to EnvironmentConfig to avoid exposing the entire process.env to the browser. Update StartServer to use getFrontendEnvVars when rendering /env.js and embed the serialized env object directly.
2025-11-04 16:08:47 +00:00
Nawaz Dhandala
3025880d6d chore(nginx): move conditional SSL listen/certificate directives into envsubst variables 2025-11-04 15:59:14 +00:00
Nawaz Dhandala
00994b56c5 chore(values.yaml): relocate image configuration next to ssl and remove duplicate block 2025-11-04 15:35:27 +00:00
Nawaz Dhandala
d56fd8bf69 fix(domain): disallow creating verified domains for non-root users; require post-create verification 2025-11-04 15:09:41 +00:00
Nawaz Dhandala
1229d5d204 style(domain): normalize whitespace and formatting in DomainService.ts 2025-11-04 12:18:14 +00:00
Nawaz Dhandala
c4f1f4e711 fix(domain): allow setting deletedByUserId on create for project roles 2025-11-04 12:17:33 +00:00
Nawaz Dhandala
7b8986b011 fix(domain): require projectId for verification and verify TXT for all project domains; set isVerified false for non-root creates
- set createBy.data.isVerified = false for non-root creations
- require projectId (from query.projectId or props.tenantId) when verifying domains
- query by projectId and other filters, use LIMIT_PER_PROJECT and iterate results to verify TXT records
- add missing imports (LIMIT_PER_PROJECT, ObjectID, FindWhere) and improve error handling/messages
2025-11-04 12:14:51 +00:00
Nawaz Dhandala
46e6176e6a refactor(queue): use Redis.getRedisOptions() for BullMQ connections; remove direct Redis env usage 2025-11-04 11:53:43 +00:00
Simon Larsen
61f9572956 Merge pull request #2073 from OneUptime/chore/npm-audit-fix
chore: npm audit fix
2025-11-04 10:48:58 +00:00
simlarsen
3adc6901da chore: npm audit fix 2025-11-04 01:46:29 +00:00
Simon Larsen
d7f1bfb52a Merge pull request #2072 from OneUptime/core-ssl
refactor(helm): evaluate PROVISION_SSL once in oneuptime.env.common a…
2025-11-03 22:17:55 +00:00
Nawaz Dhandala
53968e681c refactor(helm): evaluate PROVISION_SSL once in oneuptime.env.common and replace dig call 2025-11-03 22:14:19 +00:00
Simon Larsen
3b8c854744 Merge pull request #2071 from OneUptime/core-ssl
Core ssl
2025-11-03 22:01:25 +00:00
Nawaz Dhandala
669ed2580c refactor(coressl,nginx): normalize formatting in WriteServerCertToDisk job
Wrap logger calls and LocalFile.write arguments for consistent multiline formatting.
2025-11-03 22:00:24 +00:00
Nawaz Dhandala
2f29c2e24c refactor(helm): move provisionSSL under ssl.provision and update templates/schema
Nest the top-level provisionSSL into ssl.provision in values.yaml and values.schema.json,
and update _helpers.tpl to read the new path (using default false via dig) so PROVISION_SSL
env is derived from ssl.provision.
2025-11-03 21:56:17 +00:00
Nawaz Dhandala
f0a2f454e2 feat(config,docker-compose): add PROVISION_SSL env and document Let's Encrypt provisioning
Expose PROVISION_SSL in docker-compose common variables and update config.example.env docs to explain automatic ACME/Let's Encrypt TLS provisioning and reverse-proxy alternative.
2025-11-03 21:51:14 +00:00
Nawaz Dhandala
d8206e12de feat(nginx): add ServerCerts volume/mount and enable conditional primary-domain SSL provisioning
- add server-certs emptyDir volume and mount to nginx Deployment
- update default.conf.template to conditionally listen on 7850 and use /etc/nginx/certs/ServerCerts/${PRIMARY_DOMAIN}.crt/.key when PROVISION_SSL is set
- enhance run.sh to export PRIMARY_DOMAIN, temporarily adjust PROVISION_SSL for envsubst, and restore original PROVISION_SSL afterwards
2025-11-03 21:48:15 +00:00
Nawaz Dhandala
f84434ada4 feat(nginx,coressl): add job to write primary host TLS certificate to disk and initialize it 2025-11-03 21:27:22 +00:00
Nawaz Dhandala
d5fbe0443e refactor(acme,coressl): normalize formatting for AcmeChallenge routing, handler signature, and provisioning log 2025-11-03 21:12:46 +00:00
Nawaz Dhandala
2732cd65ed feat(acme): add ACME HTTP-01 challenge routing and nginx proxy
- Refactor AcmeChallengeAPI into a BaseAPI-backed class that exposes a well-known router.
- Add CrudApiEndpoint(Route("/acme-challenge")) to AcmeChallenge model.
- Register AcmeChallengeAPI router in BaseAPIFeatureSet via (new AcmeChallengeAPI).getRouter().
- Add nginx location /.well-known to proxy ACME challenge requests to /api/acme-challenge/.well-known with proper headers, resolver and websocket support.
2025-11-03 21:12:01 +00:00
Nawaz Dhandala
7624523446 feat(api): add ACME HTTP-01 challenge endpoint and register AcmeChallengeAPI 2025-11-03 20:59:02 +00:00
Nawaz Dhandala
5851286548 feat(coressl): add automated Let's Encrypt provisioning for primary host
- add ProvisionPrimaryDomain worker job to order/renew ACME certificates for the HOST
- register job import in Worker Routes
- add ProvisionSsl env flag in Common/Server/EnvironmentConfig
- expose PROVISION_SSL in Helm chart (values.yaml, values.schema.json, _helpers.tpl)
2025-11-03 20:48:07 +00:00
Simon Larsen
123d9b07bc Merge pull request #2067 from OneUptime/service-catalog-pages
Service catalog pages
2025-11-03 19:50:54 +00:00
Nawaz Dhandala
9edc6ac428 refactor(metrics): normalize type annotations and formatting in MetricExplorer/MetricQuery/MetricView 2025-11-03 19:47:27 +00:00
Nawaz Dhandala
72fc633bf1 refactor(metrics): treat metric query alias as meaningful so alias-only queries are preserved in URL/state 2025-11-03 19:44:21 +00:00
Nawaz Dhandala
3264322054 refactor(metrics): support metric query alias in URL/state
- add MetricQueryAliasFromUrl type
- populate initial metric alias fields from parsed URL into initial query configs
- include alias when building metricQueries for the URL and when parsing metricQueries from the URL
- add sanitizeAlias and buildAliasFromMetricAliasData helpers to validate/serialize alias fields
2025-11-03 19:41:48 +00:00
Nawaz Dhandala
d8fedc0b19 refactor(filters,metrics): default to showing advanced filters and optimize metric fetching
- add showAdvancedFiltersByDefault prop to FiltersForm and use it to initialize advanced filter visibility
- MetricQuery: default showAdvancedFilters to true, pass showAdvancedFiltersByDefault to FiltersForm and call onAdvancedFiltersToggle once on mount
- MetricView: introduce getFetchRelevantState and lastFetchSnapshotRef; only fetch aggregated results when relevant state (start/end dates or queryConfigs) actually changes
2025-11-03 19:33:12 +00:00
Nawaz Dhandala
fc7cc5fe7f Merge branch 'master' into service-catalog-pages 2025-11-03 18:55:32 +00:00
Nawaz Dhandala
5b4eb72521 refactor(modal,edition-label): make Modal onSubmit optional and centralize modal props
- Make Modal.onSubmit and ModalFooter.onSubmit optional and use safe optional chaining when invoking
- Extract modalSubmitButtonText, modalOnSubmit, modalIsLoading, and modalDisableSubmitButton in EditionLabel to simplify JSX and reduce inline conditional logic
2025-11-03 18:54:27 +00:00
Nawaz Dhandala
d84cfe9b09 refactor(enterprise): register EnterpriseLicense migration and clean up license validation/env config; refactor(edition-label): adjust alert formatting 2025-11-03 18:35:00 +00:00
Nawaz Dhandala
0e8926a786 refactor(edition-label): update edition labels and streamline license validation UI
- Change "Enterprise Edition (Verified)" -> "Enterprise Edition"
- Change "Enterprise Edition (License Needed)" -> "Enterprise Edition (License Required)"
- Render success Alert without extra wrapper
- Only show license input, validation error and explanatory text when license is not valid
2025-11-03 18:33:33 +00:00
Nawaz Dhandala
12ff3062de feat(enterprise): add server license validation endpoint and integrate UI
- Add POST /global-config/license handler to validate enterprise license via
  EnterpriseLicenseValidationUrl and store results in GlobalConfig.
- Introduce EnterpriseLicenseValidationUrl in EnvironmentConfig.
- Update EditionLabel to call /global-config/license (POST) for validation,
  remove direct ModelAPI update and ObjectID usage, and replace inline messages
  with Alert component. Minor styling and import cleanup.
2025-11-03 18:21:23 +00:00
Simon Larsen
30aad2866f fix(enterprise): remove oneuptime.com host restriction from license validation (comment out Host import and serverHost check) 2025-11-03 15:25:53 +00:00
Simon Larsen
3de636ab9e refactor(edition-label): remove refresh flow and unify license validation
- Remove isRefreshing state and handleRefresh function; use isValidating for all validation/loading logic
- Make modal submit perform license validation (label "Validate License") and derive isLoading/disable state from licenseKeyInput, isValidating, and isConfigLoading
- Change retry button style to DANGER
- Expand enterprise features copy ("Audit logs and many more enterprise-focused features.")
- Reorder and simplify dialog markup (remove in-body Validate button)
2025-11-03 15:10:58 +00:00
Simon Larsen
a1bf9cbaae feat(enterprise): add EnterpriseLicense DB migration (1762181014879) and register in migrations index 2025-11-03 14:46:00 +00:00
Simon Larsen
12c800b81f refactor(edition-label): add explicit types for ref and callbacks, tidy formatting and normalize config.example.env newline 2025-11-03 14:29:36 +00:00
Simon Larsen
677e687662 fix(enterprise): restrict enterprise license validation to oneuptime.com and import Host 2025-11-03 14:16:45 +00:00
Simon Larsen
93719d67be refactor(link): use ReactNode for children and handle numeric children 2025-11-03 14:12:29 +00:00
Simon Larsen
7d23209198 chore(format): tidy formatting in GlobalConfig, EditionLabel, and Config 2025-11-03 14:09:09 +00:00
Simon Larsen
4461127a36 feat(enterprise): add /global-config/license endpoint and make EditionLabel fetch license via API
- Add GET /global-config/license that returns enterprise license fields (companyName, expiresAt, licenseKey, token).
- Update EditionLabel to use APP_API_URL and fetch license from the new endpoint instead of ModelAPI.getItem.
- Replace hard-coded validation URL with APP_API_URL-based URL.
2025-11-03 14:08:20 +00:00
Simon Larsen
8326bf2c9e chore(edition-label): no-op commit (no code changes) 2025-11-03 14:03:06 +00:00
Simon Larsen
be9d2f6beb feat(enterprise): add enterprise license fields to GlobalConfig
Add enterpriseCompanyName, enterpriseLicenseKey, enterpriseLicenseExpiresAt and enterpriseLicenseToken to store validated enterprise license metadata.
2025-11-03 14:01:24 +00:00
Simon Larsen
214dae6204 feat(enterprise): add license validation endpoint to EnterpriseLicense API
Add POST /.../validate route that verifies license key, checks expiration,
and returns license info with a signed JWT token.
2025-11-03 13:40:09 +00:00
Simon Larsen
71c845d94e feat(enterprise): add EnterpriseLicense API
Add EnterpriseLicenseAPI class that extends BaseAPI to expose CRUD operations
for the EnterpriseLicense model using EnterpriseLicenseService.
2025-11-03 13:32:52 +00:00
Simon Larsen
87d709dd05 feat(enterprise): add EnterpriseLicense model, service and API; register model/service and add IsEnterpriseEdition env flag 2025-11-03 12:19:55 +00:00
Simon Larsen
25332f99fd chore(helm): add IS_ENTERPRISE_EDITION env var to oneuptime.env.common 2025-11-03 11:43:18 +00:00
Simon Larsen
1ac6e71f7e chore(config,docker,ci,ui): rename IS_ENTERPRISE to IS_ENTERPRISE_EDITION across env, Dockerfiles, compose and workflows 2025-11-03 11:25:12 +00:00
Simon Larsen
f1efd65ada Merge pull request #2070 from OneUptime/snyk-upgrade-ecc4458d6ea952fff3607671e1a1fb1d
[Snyk] Upgrade react-router-dom from 6.23.1 to 6.30.1
2025-11-03 08:51:04 +00:00
snyk-bot
bc338f41c7 fix: upgrade react-router-dom from 6.23.1 to 6.30.1
Snyk has created this PR to upgrade react-router-dom from 6.23.1 to 6.30.1.

See this package in npm:
react-router-dom

See this project in Snyk:
https://app.snyk.io/org/oneuptime-RsC2nshvQ2Vnr35jHvMnMP/project/40b17bc5-1bd4-48b1-88f1-5b4dc1400e80?utm_source=github&utm_medium=referral&page=upgrade-pr
2025-11-02 10:11:06 +00:00
Simon Larsen
39153735b5 Merge pull request #2069 from OneUptime/chore/npm-audit-fix
chore: npm audit fix
2025-11-02 09:18:55 +00:00
simlarsen
ae9a78f1f4 chore: npm audit fix 2025-11-01 01:49:26 +00:00
Nawaz Dhandala
f224ad6092 fix(ui): display correct feature list and icon for Community Edition
- Map communityFeatures (not enterpriseFeatures) in the Community Edition panel
- Replace wrong/Danger icon with Check and add muted gray styling
2025-10-31 18:14:32 +00:00
Nawaz Dhandala
1abb8bc83f style(ui): reformat EditionLabel and trim whitespace in Dashboard Footer
- Reflow imports, map callbacks and wrapped long strings in EditionLabel for improved readability.
- Remove stray trailing space in Dashboard Footer link.
2025-10-31 18:07:23 +00:00
Nawaz Dhandala
46704b7c5a fix(ui): correct IconProp relative import path in EditionLabel 2025-10-31 16:48:17 +00:00
Nawaz Dhandala
143d91ceab feat(ui): revamp EditionLabel to use shared enterpriseFeatures and render feature lists with icons 2025-10-31 16:46:28 +00:00
Nawaz Dhandala
ea58cacd1b feat(ui): revamp EditionLabel and allow Footer content links
- Update EditionLabel UI: new button styling, status indicator, compact CTA text
- Expand modal content with Community vs Enterprise comparison and use enterprise demo URL
- Pass ModalWidth to modal and refine primary action behavior
- Extend Footer types to accept ReactNode content and render content links
- Embed EditionLabel into Dashboard footer links
2025-10-31 16:43:07 +00:00
Nawaz Dhandala
5e19849ac8 feat(ui): add EditionLabel and expose IS_ENTERPRISE across apps
- Add EditionLabel component to Common UI to show current edition and info modal
- Show edition label in Login page, Dashboard header and Footer
- Add IS_ENTERPRISE env var to config.example.env and export in Common UI Config
- Propagate IS_ENTERPRISE into docker-compose.base.yml service envs
2025-10-31 15:47:12 +00:00
Nawaz Dhandala
f7c05645a9 feat(helm-chart): add image helper and support enterprise image type
- Add Helm helpers oneuptime.image.tag and oneuptime.image to centralize image name/tag formatting
- If image.type is "enterprise-edition" and tag doesn't already contain "enterprise", prefix tag with "enterprise-"
- Replace inline image printf calls with include "oneuptime.image" across deployments, cronjob and tests
- Add image.type to values.schema.json and set default type to "community-edition" in values.yaml
2025-10-31 15:17:41 +00:00
Nawaz Dhandala
1c1a48b78f chore(ci): build/publish enterprise image variants and add IS_ENTERPRISE arg to Dockerfiles 2025-10-31 14:49:07 +00:00
Nawaz Dhandala
13860be56d chore(helm-chart): remove cert-manager integration from oneuptime chart
- Remove cert-manager dependency from Chart.yaml and update Chart.lock (digest/timestamp)
- Delete bundled cert-manager chart (charts/cert-manager-v1.18.2.tgz)
- Remove ClusterIssuer template and cert-manager/Let's Encrypt-related ingress annotations and secret handling
- Remove cert-manager and certManagerLetsEncrypt entries from values.schema.json and values.yaml
- Clean up README to remove Cert-Manager / Let's Encrypt documentation and references
2025-10-30 21:52:19 +00:00
Nawaz Dhandala
38c29664ea refactor(metrics): strengthen typings and clean up MetricExplorer
- Add explicit types for initialQueryConfigs (MetricQueryConfigData) and map callbacks
- Use FilterData<MetricsQuery> and explicit Record<string, unknown> for safer access
- Type lastSerializedStateRef as React.MutableRefObject<string>
- Simplify catch blocks (remove unused error variables) and tidy parsing/sanitization logic
- Minor formatting and type-safe attribute sanitization improvements
2025-10-30 21:36:44 +00:00
Nawaz Dhandala
df1507b314 feat(metrics): persist multiple metric queries & time range in URL
- Refactor MetricExplorer to parse/serialize a metricQueries URL param (array of metricName, attributes, aggregationType) and startTime/endTime.
- Add helpers to sanitize attributes, map aggregation types, and build metric query state.
- Update MetricsTable to generate metricQueries payload (with attributes and aggregationType) when navigating to metric view.
- Minor JSX/formatting cleanup.
2025-10-30 21:33:30 +00:00
Nawaz Dhandala
65c999b5fc feat(metrics): support filtering by multiple telemetry services
Replace telemetryServiceId/telemetryServiceName props with telemetryServiceIds array.
Update MetricsTable to accept multiple IDs, construct view route when exactly one
telemetry service is selected, query with Includes for multiple services, and add
select/filters/column to show telemetry service info. Update ServiceCatalog and
Telemetry Service Metrics pages to pass telemetryServiceIds and remove redundant
single-service fetching/state.
2025-10-30 20:32:35 +00:00
Nawaz Dhandala
803d0436ca feat(service-catalog): reorganize side menu and tidy view components
- Move "Telemetry Services" into the Resources section and introduce an Operations
  section for Alerts and Incidents; update corresponding icons and route targets.
- Reformat FunctionComponent type annotations and async fetch function bodies
  in Alerts, Logs, Traces and Metrics for consistent indentation and readability.
- Minor formatting cleanup for pageRoute/path prop in ServiceCatalogRoutes.
2025-10-30 20:12:52 +00:00
Nawaz Dhandala
b98e7f13a5 feat(service-catalog): add Alerts, Logs, Traces and Metrics pages, routes and menu
- Add new ServiceCatalog view pages: Alerts.tsx, Logs.tsx, Traces.tsx, Metrics.tsx
  (fetch monitors/telemetry service ids and render respective tables/viewers).
- Register lazy routes and PageRoute entries in ServiceCatalogRoutes for alerts,
  logs, traces and metrics.
- Extend PageMap and RouteMap with new keys/paths and Route entries.
- Update SideMenu to include Alerts under Operations and Logs/Traces/Metrics under
  a Telemetry section.
- Add breadcrumbs entries for the new service catalog pages.
2025-10-30 20:08:52 +00:00
Simon Larsen
0785f11abe Merge pull request #2066 from OneUptime/live-logs
Live logs
2025-10-30 18:58:45 +00:00
Nawaz Dhandala
f0d9f7c594 chore(incidents): add IncidentUpdatePayload type and use it for updatedIncidentData 2025-10-30 18:58:19 +00:00
Nawaz Dhandala
dc9463f73d chore(logs-viewer,logs): add explicit types for liveRequestInFlight, fetchItems and handleLiveToggle 2025-10-30 18:45:54 +00:00
Nawaz Dhandala
37c8e8b6b6 chore(logs-viewer,logs): tweak LiveLogsToggle styling for improved contrast
- add bg-white/90 and backdrop-blur to base classes
- update active/inactive border, text and hover classes
- adjust indicator colors and make "Live" label font-semibold
2025-10-30 18:42:41 +00:00
Nawaz Dhandala
763dfaa1c9 chore(logs-viewer,logs): track live-updating state and disable live toggle during live fetches 2025-10-30 18:37:55 +00:00
Nawaz Dhandala
c2e0d402d5 chore(logs-viewer,logs): remove live updating indicator and tooltip; simplify LiveLogsToggle API
- Remove isUpdating and tooltip from LiveLogsToggle props and types
- Drop Tooltip import and spinner markup; always return button content
- Remove isLiveUpdating state and related updates from Dashboard LogsViewer
- Simplify liveOptions to only pass isLive and onToggle
2025-10-30 18:34:48 +00:00
Simon Larsen
cdc1526fbf chore(logs-viewer,logs): normalize formatting - inline LiveLogsToggle JSX and reformat catch callback 2025-10-30 18:20:10 +00:00
Simon Larsen
13ebd34e8f feat(logs-viewer): add live logs toggle and realtime refresh support
- Add LiveLogsOptions type and LiveLogsToggle component.
- Wire liveOptions through LogsViewer -> LogsViewerToolbar to render the live toggle.
- Update Dashboard LogsViewer to support live mode:
  - add isLiveEnabled, isLiveUpdating state and liveRequestInFlight ref.
  - change fetchItems to accept skipLoadingState to perform lightweight live refreshes (sets isLiveUpdating instead of full loader).
  - poll every 10s when live is enabled (only on page 1, sorted by time desc) and use skipLoadingState for background refreshes.
  - integrate with realtime listener and avoid overlapping live requests.
  - add handleLiveToggle to enforce page/sort when enabling and to stop live updates when disabling.
- Automatically disable live mode when user changes filters, page, or sort in ways that conflict with live behavior.
- Minor imports/exports and typing adjustments.
2025-10-30 18:17:17 +00:00
Nawaz Dhandala
3b97c23039 Merge branch 'release' of https://github.com/OneUptime/oneuptime into release 2025-10-30 16:45:43 +00:00
Simon Larsen
7c15424565 Merge pull request #2064 from OneUptime/incident-postmortem
Incident postmortem
2025-10-30 16:45:20 +00:00
Nawaz Dhandala
6817443d9a chore: normalize formatting and comment style across migrations, jobs and postmortem UI
- Reformat MigrationName1761834523183.ts SQL queries to multi-line strings and consistent quoting
- Add trailing comma to migrations Index export
- Convert inline // comments to /* ... */ block comments in KeepCurrentStateConsistent jobs (Alert, Incident, Monitor, ScheduledMaintenance) for consistency
- Minor refactor in IncidentPostmortem: expand setRefreshToggle updater to an explicit return
2025-10-30 16:44:54 +00:00
Nawaz Dhandala
f40a6395a6 feat(incident): set create/edit modal width for incident postmortem templates 2025-10-30 16:42:25 +00:00
Nawaz Dhandala
81eb735aab feat(incident): extract postmortem form fields and apply templates via edit modal 2025-10-30 16:39:25 +00:00
Nawaz Dhandala
923339710b feat(incident): add migration to create IncidentPostmortemTemplate and add postmortemNote to Incident 2025-10-30 14:30:56 +00:00
Nawaz Dhandala
1f9ec3011c feat(incident): add postmortem UI, templates, routes and breadcrumbs
- Add Incident Postmortem page to incident view with:
  - Postmortem note CardModelDetail (edit/save)
  - "Apply Template" modal to pick and apply a postmortem template
- Add Settings pages for postmortem templates:
  - IncidentPostmortemTemplates (list/create)
  - IncidentPostmortemTemplateView (view/edit/delete)
- Wire up routes, route map, page map and side menu links for postmortem views
- Add breadcrumbs entries for incident postmortem and settings pages
- Minor cleanup/formatting tweaks in IncidentPostmortemTemplate model and IncidentService
2025-10-30 14:17:24 +00:00
Nawaz Dhandala
668093b09c feat(incident): add postmortem template & postmortem note feed support
- add IncidentPostmortemTemplate model and IncidentPostmortemTemplateService
- expose model in Common/Models/DatabaseModels index and register API route in BaseAPI
- add postmortemNote column to Incident model
- add IncidentFeedEventType.PostmortemNote enum value
- emit IncidentFeed item when postmortemNote is added/updated/cleared (IncidentService)
- update Dashboard IncidentFeed to show Book icon for PostmortemNote events
2025-10-30 12:27:13 +00:00
Simon Larsen
f39f51e8ee Merge pull request #2063 from OneUptime/master
chore(jobs): comment out KeepCurrentStateConsistent implementations a…
2025-10-30 12:08:05 +00:00
Nawaz Dhandala
0bff616ca9 chore(jobs): comment out KeepCurrentStateConsistent implementations and unused imports for Alert, Incident, Monitor, and ScheduledMaintenance 2025-10-30 11:59:07 +00:00
Nawaz Dhandala
709b9b8343 fix(link): add title to ComponentProps and forward it to the anchor element 2025-10-30 11:36:46 +00:00
Nawaz Dhandala
aa93252407 Merge branch 'master' into release 2025-10-29 20:38:27 +00:00
Simon Larsen
b4e7ffce43 Merge pull request #2062 from OneUptime/log-ui
Log UI
2025-10-29 20:37:16 +00:00
Nawaz Dhandala
1053d22d3f refactor(logs-viewer): add overflow-y-hidden to table container to prevent vertical overflow 2025-10-29 20:35:09 +00:00
Nawaz Dhandala
a37bdb303d refactor(logs-viewer): simplify empty-state copy, remove decorative '>' and tone down text colors 2025-10-29 20:33:31 +00:00
Nawaz Dhandala
860af1bbf3 refactor(logs-viewer): polish empty-state layout and styling
Replace bare empty message with a centered card-style panel:
- add full-height centered wrapper with slate background
- constrain width, add rounded border, padding and inner shadow
- update typography to monospace, uppercase tracking and emerald accent
- tweak spacing and muted text color for helper copy
2025-10-29 20:30:26 +00:00
Nawaz Dhandala
d5e72c1af2 refactor(logs-viewer): normalize formatting and tidy JSX
- Clean up multiline signatures and expressions for readability
- Standardize JSX tag formatting and expanded-content rendering (explicit return)
- Minor whitespace/indentation tweaks in LogsViewer, LogsTable, LogDetailsPanel, and Dashboard LogsViewer

No functional changes.
2025-10-29 20:29:07 +00:00
Nawaz Dhandala
6cc6fc4bf1 refactor(logs-viewer): polish LogDetailsPanel layout, surface cards, badges and trace/span links 2025-10-29 20:27:50 +00:00
Nawaz Dhandala
f890f24650 refactor(logs-viewer): use icon sort indicators and refine table styling
- replace text-based sort markers with Icon (Chevron/ArrowUpDown) and add helper funcs
- adjust table/header/tbody classes (dividers, background, text colors)
- tweak row hover/selected styles and message/service text colors for better contrast
- update small typography and trace/span color for consistency
2025-10-29 20:22:34 +00:00
Nawaz Dhandala
d077e55241 refactor(logs-viewer): add pagination & sorting API, move sort controls to table headers
- Add server/client-aware pagination & sorting to LogsViewer (props: totalCount, page, pageSize, onPageChange, onPageSizeChange, sortField, sortOrder, onSortChange)
- Implement client-side sort fallback, severity-weight sorting and stable time sorting
- Move sort UI into LogsTable column headers and remove autoscroll / toolbar sort buttons
- Introduce internal page/size/sort state, reset behavior on filter/apply, and improved displayedLogs handling
- Update page size defaults and options (DEFAULT_PAGE_SIZE=100, PAGE_SIZE_OPTIONS=[100,250,500,1000])
- Wire Dashboard viewer to new API (pass totalCount, page, pageSize, sort handlers) and adjust realtime fetch logic
- Reduce default page limit usages from 250 to 100
2025-10-29 20:07:59 +00:00
Nawaz Dhandala
a4b7c99b8a refactor(logs-viewer): replace gradients with solid backgrounds and enable log message wrapping 2025-10-29 19:18:06 +00:00
Nawaz Dhandala
671be425ae refactor(logs-viewer): render log details inline and unify panel variants
- Add renderExpandedContent prop to LogsTable and render LogDetailsPanel inline for expanded rows
- Introduce "embedded" variant in LogDetailsPanel and extract container/header/card classes for shared styling
- Update table and surrounding container styles (rounded, gradients, backdrop) and add a click-to-open hint banner
- Remove standalone selectedLog memo and the separate details pane UI; use selectedLogId to control inline expansion
2025-10-29 19:01:53 +00:00
Nawaz Dhandala
d2d7a51842 Merge branch 'master' of https://github.com/OneUptime/oneuptime 2025-10-29 18:24:49 +00:00
Simon Larsen
1142a20d64 refactor(logs-viewer): tighten types and clean up formatting across components
- Add explicit type annotations for callbacks, helpers and theme (SeverityTheme)
- Strengthen severityTheme getSeverityTheme signature and consume typed return
- Remove unused catch variables and mark unused params where applicable
- Minor JSX/formatting tweaks and whitespace cleanup in table, pagination, details panel
- Small import/format fix in Execute.ts
2025-10-29 18:02:19 +00:00
Simon Larsen
8d0d7dc759 refactor(logs-viewer): modularize viewer into table, pagination and details panel
- Remove legacy LogItem and the old scroll-based monolithic layout.
- Add modular components under LogsViewer/components:
  - LogsTable (tabular list view, row selection, copy actions)
  - LogDetailsPanel (expanded details, copy buttons, trace/span links)
  - LogsViewerToolbar (autoscroll toggle, sort controls, summary)
  - LogsPagination (page controls & page-size selector)
  - LogsFilterCard (filters wrapper using FiltersForm)
  - SeverityBadge + severityTheme (centralized severity styling)
- Replace manual scroll alignment with page-based auto-scroll and safer pagination logic.
- Preserve getTraceRoute/getSpanRoute behavior and filter lifecycle (attributes loading, apply filters).
- Improve state handling (selection, pagination, page size, service map loading) and reduce component complexity.
2025-10-29 17:52:26 +00:00
Simon Larsen
cedf06ba42 chore(ci): schedule npm-audit-fix workflow and create PR via action
Switch workflow to run on a daily schedule (and via workflow_dispatch) and
replace direct git commit/push steps with peter-evans/create-pull-request to
open changes as a PR instead of pushing to the default branch.
2025-10-29 17:02:50 +00:00
Nawaz Dhandala
b347e18749 chore: update package-locks — add deps, bump versions & sync subdeps
- Update lockfiles for root, TestServer, Worker and Workflow
- Add new/top-level packages and types:
  - @simplewebauthn/server, archiver, botbuilder
  - @types/archiver
- Bump notable package versions:
  - axios, nodemailer, playwright, react-syntax-highlighter
- Sync a large set of transitive dependency upgrades:
  - @babel/* (code-frame, parser, template, types, helpers, helper-*), brace-expansion, braces, fill-range, micromatch, picocolors, cross-spawn, to-regex-range and others
- Remove/clean outdated lock entries (e.g. to-fast-properties removed where unnecessary)
- Add/fix license fields for several packages in the lockfiles
- General lockfile normalization to ensure consistent subdependency versions across packages

This keeps dependency trees aligned across monorepo packages and pulls in recent bug/security fixes from transitive upgrades.
2025-10-29 16:43:36 +00:00
Nawaz Dhandala
50e9a53547 chore(ci): don't mark whole run as failed when npm audit fix errors; only report the error 2025-10-29 16:26:40 +00:00
Nawaz Dhandala
d0de004498 docs(devpromps): fix typo in TerraformPrompt.md and add note to avoid editing generated provider code 2025-10-29 16:24:51 +00:00
Nawaz Dhandala
65c4998048 chore(isolated-vm): update package-lock.json — bump dependencies, add new & transitive packages 2025-10-29 16:12:16 +00:00
Nawaz Dhandala
5e7a3795c7 chore(ci): add npm-audit-fix workflow and helper script, expose audit-fix npm script 2025-10-29 13:25:31 +00:00
Nawaz Dhandala
cf83319a90 style(execute): normalize import formatting and reindent exec callback 2025-10-28 19:26:44 +00:00
Nawaz Dhandala
87dc9d88d0 chore(common): update package-lock.json with dependency bumps and transitive additions
Bump multiple deps (notably @babel/*, express, undici, brace-expansion, sha.js, call-bind)
Add transitive packages: call-bound, is-typed-array, to-buffer, typed-array-buffer
Include updated metadata (engines, funding) and adjust dev flags/pruned entries in lockfile
2025-10-28 19:24:48 +00:00
Nawaz Dhandala
444cf040a6 refactor(execute,code-repository): allow ExecOptions in Execute.executeCommand and use cwd instead of 'cd'
- Extend Execute.executeCommand to accept ExecOptions and forward them to child_process.exec
- Log stderr on error and debug-log stderr when present
- Update CodeRepository to pass cwd to Execute.executeCommand instead of prefixing commands with "cd"
2025-10-28 17:37:06 +00:00
Nawaz Dhandala
2754657a6f chore(probe): update package-lock with dependency version bumps and new packages
- Bump axios, playwright, playwright-core, react-syntax-highlighter, nodemailer
- Add @simplewebauthn/server, @types/archiver, archiver, botbuilder
- Update resolved versions/integrity in lockfile
2025-10-28 16:58:30 +00:00
Nawaz Dhandala
38ca6b1e9e style(code-repository): normalize logger debug formatting and wrap long expressions for readability 2025-10-28 16:52:54 +00:00
Nawaz Dhandala
f481ef4f5e refactor(code-repository,github): replace ad-hoc shell commands with structured git execution, sanitize paths, and improve logging
- Use CodeRepositoryUtil.runGitCommand / Execute.executeCommandFile instead of building shell command strings.
- Properly resolve and sanitize file paths when adding files to git; skip empty/invalid paths and add relative sanitized paths.
- Use resolvePathWithinRepo and path.relative for accurate file/argument resolution.
- Trim returned git commit hash.
- Improve debug messages for branch creation/checkout, user.name setting, adding remotes, and pushing branches.
- Encode credentials when constructing remote URL for push and use cwd for git operations.
2025-10-28 16:50:30 +00:00
Nawaz Dhandala
ad9adca473 docs(devpromps): add SecurityFix.md prompt to locate and fix security vulnerabilities 2025-10-28 16:04:47 +00:00
Nawaz Dhandala
819bd54a1f refactor(worker,server): remove unused import, add missing LIMIT_PER_PROJECT import, and normalize object literal formatting 2025-10-28 15:00:24 +00:00
Nawaz Dhandala
e212079b4a refactor(database,worker): remove batchSize option and default to LIMIT_MAX
- Remove batchSize field from FindAllBy type.
- Update DatabaseService.findAllBy to stop reading/validating batchSize and use LIMIT_MAX as the batch size.
- Remove per-job batch size constants and batchSize parameters from multiple worker cron jobs (AlertOwners, Incident*, ScheduledMaintenance*, StatusPage*, Announcement, OnCall, Workflow, UserOnCallLog, ServerMonitor, PaymentProvider, etc.).
- Simplify call sites to rely on findAllBy's default batching behavior.
2025-10-28 14:56:38 +00:00
Nawaz Dhandala
bb09dafbcc refactor(database,worker): add paginated findAllBy and migrate jobs to batch fetching
- Add FindAllBy type and implement DatabaseService.findAllBy with batchSize/limit/skip support.
- Add normalizePositiveNumber helper used by findAllBy.
- Add ProjectService.getAllActiveProjects convenience wrapper that uses findAllBy.
- Replace many worker cron jobs' findBy calls with findAllBy, introduce per-job batch size constants, remove LIMIT_MAX imports, and pass batchSize/skip instead of one large limit.
- Convert long-running deletes/hard-deletes to paginated loops (repeat until no more records deleted).
- Adjust various query usages to use LIMIT_PER_PROJECT where appropriate as batchSize.
2025-10-28 14:32:45 +00:00
Nawaz Dhandala
60c472cc09 refactor(monitor-resource): replace Metric/MonitorLog models with JSON rows and add builders
Introduce buildMonitorMetricAttributes and buildMonitorMetricRow helpers to centralize attribute/timestamp logic. Replace creation of Metric and MonitorLog model instances with JSON row construction and use MetricService.insertJsonRows / MonitorLogService.insertJsonRows. Remove setAttributeKeys/Metric import usage and simplify metric aggregation code paths.
2025-10-28 12:33:12 +00:00
Nawaz Dhandala
0e272f0f31 refactor(fluent-ingest): replace Log model with JSON rows and add batching
- Remove dependency on Log model; build log JSON rows inline (IDs, ISO timestamps, unix nano)
- Buffer logs and flush in batches using new flushLogBuffer helper and LogService.insertJsonRows
- Add FLUENT_INGEST_LOG_FLUSH_BATCH_SIZE constant and simplify processing loop
2025-10-28 12:20:43 +00:00
Nawaz Dhandala
f5de74611d refactor(code-repository): centralize git execution with runGitCommand and improve clone folder detection
Replace ad-hoc shell command construction/Execute.executeCommand calls with a new runGitCommand wrapper that uses Execute.executeCommandFile. Update various methods (getCurrentCommitHash, addAllChangedFilesToGit, setAuthorIdentity, discardAllChangesOnCurrentBranch, pullChanges, createOrCheckoutBranch, discardChanges, etc.) to use the helper. Also improve cloneRepository to derive the cloned folder name from the repo URL and throw a clear error if it can't be determined.
2025-10-28 12:14:00 +00:00
Nawaz Dhandala
03d157b850 refactor(identity,code-repository): allow SCIM group updates by removing isTeamEditable guard; type readDirectory entries as fs.Dirent 2025-10-27 20:50:27 +00:00
Nawaz Dhandala
da21cfc1ff refactor(code-repository,local-file): normalize arrow return style and reformat sanitizeFilePath/readDirectory signatures 2025-10-27 17:53:18 +00:00
Nawaz Dhandala
2781bf0583 refactor(execute,code-repository): add executeCommandFile (execFile wrapper) and use it in commitChanges 2025-10-27 17:52:00 +00:00
Nawaz Dhandala
69b16c1c85 refactor(code-repository): use LocalFile.read for getFileContent and add resolvePathWithinRepo to sanitize/validate paths 2025-10-27 17:47:49 +00:00
Nawaz Dhandala
727f009d79 refactor(code-repository): replace shell ls/file usage with LocalFile.readDirectory and Dirent checks; add readDirectory helper 2025-10-27 17:44:00 +00:00
Nawaz Dhandala
65d916f349 refactor(code-repository): replace shell rm -rf with LocalFile.deleteDirectory and add LocalFile.deleteDirectory helper 2025-10-27 17:40:02 +00:00
Nawaz Dhandala
4373c7b49c refactor(telemetry): collapse multi-line if into single-line in TelemetryUsageBillingService 2025-10-27 16:29:41 +00:00
Nawaz Dhandala
34737fbba4 feat(telemetry): account for Exceptions in usage billing and add avg exception row size
- Update TelemetryUsageBilling description to include Exceptions.
- Add AverageExceptionRowSizeInBytes env/config (env example, docker-compose, Helm values & schema).
- Use ExceptionInstanceService in TelemetryUsageBillingService to include exception row counts when estimating bytes for Traces.
- Add helper to read average exception row size and adjust billing calculations.
2025-10-27 16:26:46 +00:00
Nawaz Dhandala
90fcfd1c7e Merge remote-tracking branch 'origin/snyk-upgrade-89594c7cd11449f44c7d156474899af6' 2025-10-27 15:49:24 +00:00
Simon Larsen
b55320f02c Merge pull request #2059 from OneUptime/otel-writer
Efficient Otel Writer
2025-10-27 15:45:51 +00:00
Nawaz Dhandala
34dc078197 fix(analytics): set wait_for_async_insert=0 for ClickHouse async inserts and tidy formatting 2025-10-27 15:45:20 +00:00
Nawaz Dhandala
2eacc90714 refactor(opentelemetry): format timestamps as ClickHouse UTC datetimes
- add OneUptimeDate.toClickhouseDateTime to produce UTC "YYYY-MM-DD HH:mm:ss"
- use ClickHouse-formatted timestamps for createdAt/updatedAt and time fields in OtelLogsIngestService, OtelMetricsIngestService and OtelTracesIngestService
- extend metric timestamp parsing to include db/date (and propagate db for DB storage)
- switch intermediate handling to Date objects to avoid extra ISO-string conversions
2025-10-27 15:41:13 +00:00
Nawaz Dhandala
9d93d59f91 fix(analytics): set wait_for_async_insert=1 and log ClickHouse insert result 2025-10-27 15:19:58 +00:00
Nawaz Dhandala
d84039e621 refactor(analytics): make ClickHouse client nullable and centralize retrieval
Change databaseClient to ClickhouseClient | null and add getDatabaseClient() to
lazily refresh/validate the client. Update insert/execute/executeQuery and
useDefaultDatabase to use the centralized getter and remove unsafe casts and
duplicated null checks.
2025-10-27 15:13:10 +00:00
Nawaz Dhandala
4eb46cf8a0 docs(clickhouse): add SQL to calculate average uncompressed row size per table and close code fence 2025-10-27 13:46:24 +00:00
Nawaz Dhandala
1ef27b7f52 fix(settings): clarify usage history no-items message to mention end-of-day data availability 2025-10-27 13:22:28 +00:00
Nawaz Dhandala
412bd370df refactor(telemetry): add explicit types for attribute value variables in TelemetryUtil 2025-10-27 13:20:33 +00:00
Nawaz Dhandala
1131b80a52 style(otel-ingest): normalize .catch callback formatting in span exception handling 2025-10-27 13:16:16 +00:00
Nawaz Dhandala
8b55f5c348 refactor(otel-ingest): decouple exception handling from analytics model
- Remove direct usage of ExceptionInstance model in OtelTracesIngestService.
- Build and push exceptions as ExceptionEventPayload objects, compute fingerprint from payload.
- Update buildExceptionRow to accept ExceptionEventPayload and map fields accordingly.
- Change ExceptionUtil API: introduce ExceptionFingerprintInput and TelemetryExceptionPayload types; update getFingerprint and saveOrUpdateTelemetryException signatures.
2025-10-27 13:14:07 +00:00
Nawaz Dhandala
159e5c4023 refactor(otel-ingest): switch telemetry ingestion to ClickHouse bulk writer
Replace model-based createMany calls with ClickhouseBulkWriter.insert for logs, metrics, spans and exceptions. Build plain JSON rows (with createdAt/updatedAt, timestamps, attributes, attributeKeys, trace/span ids, severity, etc.) and change buffers to JSONObject arrays. Add helper builders and utilities (buildMetricRow, buildSpanRow, buildExceptionRow, safeParseUnixNano, toNumberOrNull, toBoolean, convertBase64ToHexSafe, calculateDurationNano) to improve timestamp/attribute parsing and robustness. Add new ClickhouseBulkWriter utility.
2025-10-27 13:05:49 +00:00
Nawaz Dhandala
4970538d43 docs: correct example pagination request method to POST 2025-10-27 12:39:22 +00:00
Nawaz Dhandala
d7ca021d52 refactor: improve TelemetryUtil attribute parsing, typing and null handling 2025-10-27 12:17:31 +00:00
Simon Larsen
27eff7f415 Merge pull request #2057 from OneUptime/snyk-upgrade-ef9e383973f8732d2d959dd964599c61
[Snyk] Upgrade axios from 1.12.0 to 1.12.2
2025-10-27 10:32:46 +00:00
Simon Larsen
50543ec7bf Merge pull request #2058 from OneUptime/snyk-upgrade-7e0a372e41cd67fc4ed46876443edaa8
[Snyk] Upgrade react-router-dom from 6.23.1 to 6.30.1
2025-10-27 10:32:39 +00:00
snyk-bot
94c39408ed fix: upgrade react-router-dom from 6.23.1 to 6.30.1
Snyk has created this PR to upgrade react-router-dom from 6.23.1 to 6.30.1.

See this package in npm:
react-router-dom

See this project in Snyk:
https://app.snyk.io/org/oneuptime-RsC2nshvQ2Vnr35jHvMnMP/project/11bb5528-45f9-473c-a635-dc097fd03b3c?utm_source=github&utm_medium=referral&page=upgrade-pr
2025-10-27 09:53:27 +00:00
snyk-bot
7219e1850f fix: upgrade axios from 1.12.0 to 1.12.2
Snyk has created this PR to upgrade axios from 1.12.0 to 1.12.2.

See this package in npm:
axios

See this project in Snyk:
https://app.snyk.io/org/oneuptime-RsC2nshvQ2Vnr35jHvMnMP/project/49c81d9c-12c2-4e8e-b9e8-72f98b1b595c?utm_source=github&utm_medium=referral&page=upgrade-pr
2025-10-27 09:51:39 +00:00
Simon Larsen
3180ed7149 Merge pull request #2055 from OneUptime/snyk-upgrade-9e6de76051d1dee73345ae37a0e51d09
[Snyk] Upgrade react-router-dom from 6.23.1 to 6.30.1
2025-10-26 17:24:46 +00:00
Simon Larsen
79f32b80c8 Merge pull request #2054 from OneUptime/snyk-upgrade-bad1e870c8252b45aa78fe78e19570b0
[Snyk] Upgrade globals from 15.6.0 to 15.15.0
2025-10-26 17:24:27 +00:00
Simon Larsen
cebfde6bf2 Merge pull request #2052 from OneUptime/snyk-upgrade-7a970ceafec3776b6998e6c88441b566
[Snyk] Upgrade typeorm from 0.3.20 to 0.3.27
2025-10-26 17:24:05 +00:00
Simon Larsen
ca644d9dc7 Merge pull request #2051 from OneUptime/snyk-upgrade-6a98a9360c422231b9e06b3e3624ea4f
[Snyk] Upgrade @readme/openapi-parser from 4.1.0 to 4.1.2
2025-10-26 17:23:59 +00:00
snyk-bot
ca4d9cb176 fix: upgrade react-router-dom from 6.23.1 to 6.30.1
Snyk has created this PR to upgrade react-router-dom from 6.23.1 to 6.30.1.

See this package in npm:
react-router-dom

See this project in Snyk:
https://app.snyk.io/org/oneuptime-RsC2nshvQ2Vnr35jHvMnMP/project/8ca4ee75-8bc5-43a1-a3bc-244ceebf1437?utm_source=github&utm_medium=referral&page=upgrade-pr
2025-10-26 10:52:13 +00:00
snyk-bot
56204e02a9 fix: upgrade globals from 15.6.0 to 15.15.0
Snyk has created this PR to upgrade globals from 15.6.0 to 15.15.0.

See this package in npm:
globals

See this project in Snyk:
https://app.snyk.io/org/oneuptime-RsC2nshvQ2Vnr35jHvMnMP/project/c3622982-05c8-495c-809c-20f301c75f92?utm_source=github&utm_medium=referral&page=upgrade-pr
2025-10-25 11:38:53 +00:00
snyk-bot
c8e8a6d687 fix: upgrade jest from 30.0.0 to 30.2.0
Snyk has created this PR to upgrade jest from 30.0.0 to 30.2.0.

See this package in npm:
jest

See this project in Snyk:
https://app.snyk.io/org/oneuptime-RsC2nshvQ2Vnr35jHvMnMP/project/c3622982-05c8-495c-809c-20f301c75f92?utm_source=github&utm_medium=referral&page=upgrade-pr
2025-10-25 11:38:49 +00:00
snyk-bot
5bd2204eee fix: upgrade typeorm from 0.3.20 to 0.3.27
Snyk has created this PR to upgrade typeorm from 0.3.20 to 0.3.27.

See this package in npm:
typeorm

See this project in Snyk:
https://app.snyk.io/org/oneuptime-RsC2nshvQ2Vnr35jHvMnMP/project/c3622982-05c8-495c-809c-20f301c75f92?utm_source=github&utm_medium=referral&page=upgrade-pr
2025-10-25 11:38:44 +00:00
snyk-bot
72a31ed268 fix: upgrade @readme/openapi-parser from 4.1.0 to 4.1.2
Snyk has created this PR to upgrade @readme/openapi-parser from 4.1.0 to 4.1.2.

See this package in npm:
@readme/openapi-parser

See this project in Snyk:
https://app.snyk.io/org/oneuptime-RsC2nshvQ2Vnr35jHvMnMP/project/f8557d79-3b3d-4201-8e2b-598120aedb5c?utm_source=github&utm_medium=referral&page=upgrade-pr
2025-10-25 11:34:15 +00:00
Nawaz Dhandala
ee188dd050 chore(values.schema): add noProxy option to proxy configuration 2025-10-24 17:48:29 +01:00
Nawaz Dhandala
3807aad63b Merge branch 'master' of https://github.com/OneUptime/oneuptime 2025-10-24 17:40:33 +01:00
Nawaz Dhandala
055ec956fd build(esbuild-config): add refractor compatibility plugin to resolve refractor imports
Add createRefractorCompatibilityPlugin that maps imports from refractor/lib and refractor/lang
to the local refractor package (searching candidate node_modules paths), and include it in the
plugins list so esbuild can correctly resolve refractor modules.
2025-10-24 17:40:31 +01:00
Simon Larsen
e7767e59d1 Merge pull request #2048 from OneUptime/probe-no-prpoxy
Probe no prpoxy
2025-10-24 17:24:47 +01:00
Nawaz Dhandala
f643e907b4 refactor(proxy-config): normalize & resolve ports for NO_PROXY matching; add protocol resolution helpers 2025-10-24 17:24:22 +01:00
Nawaz Dhandala
2eec57befd refactor(proxy-config): robust hostname/port extraction, normalize ports, and tidy formatting
- Improve extractHostnameAndPort and splitHostAndPort to handle IPv6 brackets, single-colon ports, and trimmed port values; return explicit result objects.
- Normalize host/port parsing logic and ensure port values are trimmed before use.
- Consolidate import formatting and split long method signatures for readability.
- Minor formatting/whitespace cleanups in Probe Config, Alive, Register, Monitor, and NO_PROXY parsing.
2025-10-24 15:12:12 +01:00
Nawaz Dhandala
dd653f8deb feat(proxy): add NO_PROXY support and per-request proxy bypass based on target URL
- import NO_PROXY and log its entries during configuration
- allow callers to pass a target URL to getHttpProxyAgent/getHttpsProxyAgent/getRequestProxyAgents
- implement shouldBypassProxy with URL/host:port extraction and pattern matching (including wildcard, subdomains, IPv6, and scheme/port-aware patterns)
- return no agents when a target matches NO_PROXY or when proxy is not configured
2025-10-24 15:04:05 +01:00
Nawaz Dhandala
f403c6a9e9 feat(proxy): add NO_PROXY support and use request URL for proxy agent selection
- Parse NO_PROXY / no_proxy in Probe Config into a trimmed list
- Wire NO_PROXY into UI docs, Helm chart values, and probe Docker/compose examples
- Add NO_PROXY env var to Helm probe template when provided
- Pass target URL to ProxyConfig.getRequestProxyAgents / getHttpProxyAgent / getHttpsProxyAgent so proxy selection is per-request
- Update probe calls (Alive, Metrics, FetchList, FetchMonitorTest, Register, Monitor ingest/reporting, Api/Website/Ssl monitors) to use local URL variables and supply them to proxy helpers
- Minor refactors to avoid inline URL construction where reused
2025-10-24 15:02:36 +01:00
Nawaz Dhandala
35f9b7f5c4 refactor(log-item): move collapse toggle to header container and remove redundant handler 2025-10-24 13:16:11 +01:00
Nawaz Dhandala
3c487ff9b9 refactor(log-item): use monospaced font for collapsed row and message previews; make header toggleable 2025-10-24 13:11:37 +01:00
Nawaz Dhandala
41fca346b9 refactor(table-row): extract columnContent and consolidate column rendering
- Move per-column value/element logic into a single columnContent variable
- Add contentWrapperClassName and actionsContainerClassName to unify wrappers
- Remove duplicated JSX branches for desktop row cells and simplify action rendering
2025-10-24 13:00:24 +01:00
Nawaz Dhandala
91b54ced67 refactor(exceptions): normalize icon sizes in TelemetryExceptionElement by adding min-h-6 and min-w-6 to icon wrappers 2025-10-24 12:59:49 +01:00
Nawaz Dhandala
ebdd97b8e9 refactor(exceptions): normalize icon sizes and simplify className usage in TelemetryExceptionElement
- Remove redundant h-6 w-6 classes from Icon elements and rely on wrapper sizing.
- Simplify container className interpolation (remove fallback empty string).
2025-10-24 12:56:13 +01:00
Nawaz Dhandala
8eb1eac629 refactor(table-row): inline column content rendering and remove temporary wrapper variables 2025-10-24 12:53:15 +01:00
Nawaz Dhandala
a075b3c4dd refactor(table-row, exceptions): dedupe column rendering, wrap content, and normalize icon sizes
- Extract columnContent and content/action wrapper class names in TableRow to remove duplicated conditional rendering and wrap cell content with the configured className.
- Replace inline action container with actionsContainerClassName for consistent alignment.
- Add explicit h-6 w-6 classes to exception icons for consistent sizing.
2025-10-24 12:50:59 +01:00
Nawaz Dhandala
738f901a51 refactor(vm-runner, logs-viewer, server-monitor, embedded-status): simplify script generation, add explicit typings, and tidy UI text 2025-10-24 12:18:25 +01:00
Nawaz Dhandala
683a8f5a58 chore(eslint): enable no-constant-binary-expression rule (set to error) 2025-10-24 12:11:30 +01:00
Nawaz Dhandala
160eba1ea4 refactor(exceptions): expose className prop on TelemetryExceptionElement and pass max-w-3xl from ExceptionsTable 2025-10-24 12:09:49 +01:00
Nawaz Dhandala
89b65d1e02 style(logs-viewer): inline ternary expressions in Icon className strings 2025-10-24 12:06:38 +01:00
Nawaz Dhandala
caf709a38a chore(probe): bump Node base image to public.ecr.aws/docker/library/node:24.9 (from 23.8) 2025-10-24 12:01:50 +01:00
Simon Larsen
d57433e4a0 Merge pull request #2045 from OneUptime/telemetry-billing
Telemetry billing
2025-10-24 11:08:18 +01:00
Simon Larsen
5e2aa4e622 Merge pull request #2044 from OneUptime/log-fix
feat(logs-viewer): add toggleable log ordering and update scroll-to-l…
2025-10-24 10:13:40 +01:00
Nawaz Dhandala
6cb51dd54b refactor(logs-viewer): replace sort toggle with segmented "Newest first"/"Oldest first" buttons and extract applySortDirection
Extract applySortDirection to centralize sort toggle + scroll alignment logic and replace the single ArrowUpDown button with two styled buttons (BarsArrowDown / BarsArrowUp) to improve UX and clarity.
2025-10-24 10:11:45 +01:00
Nawaz Dhandala
53ea843bdc Merge branch 'master' into log-fix 2025-10-24 09:52:13 +01:00
Nawaz Dhandala
71eeaf7ecd chore(dashboard): add archiver/@simplewebauthn/server and bump several deps
- add @simplewebauthn/server, archiver, @types/archiver, botbuilder
- bump nodemailer -> ^7.0.7, playwright -> ^1.55.1, react-syntax-highlighter -> ^16.0.0
2025-10-24 09:51:54 +01:00
Simon Larsen
1d0168fcc6 Merge pull request #2043 from OneUptime/embedded-sttaus
Embedded sttaus
2025-10-24 09:49:47 +01:00
Nawaz Dhandala
99c3d440c5 refactor(status-page): remove inline token exposure warning from Embedded Status Badge card 2025-10-24 09:39:12 +01:00
Nawaz Dhandala
5959ce728f refactor(status-page): wrap Embedded Status CardModelDetail in container and tidy props
Wrap the CardModelDetail for the embedded status badge in a surrounding <div> to group it with the other cards, and reorganize/tidy card/form properties (move description to cardProps, clean up formField ordering and types). Also minor JSX/formatting cleanup.
2025-10-24 09:38:47 +01:00
Nawaz Dhandala
0cb9e382a6 refactor(status-page): use provisioned domain for badge docs, replace Alert with inline warning, and tidy embedded badge UI
- Fetch latest SSL-provisioned StatusPageDomain and build a status page URL to use in the badge documentation/markdown embeds (falls back to STATUS_PAGE_URL).
- Add state for statusPageUrl and effect to resolve domain via ModelAPI (Query/Sort).
- Replace Alert component with inline informational paragraph and a highlighted yellow warning box.
- Minor cleanup: remove an obsolete comment, adjust Card layout/spacing and documentation markdown link.
2025-10-24 09:37:04 +01:00
Nawaz Dhandala
0c6d561b7c refactor(status-page): remove redundant "Badge Usage" header and drop h-full from token/preview cards
Remove the "## Badge Usage" heading from the documentation markdown and remove the
className="h-full" from the Security Token and Badge Preview Card components to
simplify and stabilize the embedded badge layout.
2025-10-24 09:21:05 +01:00
Nawaz Dhandala
4291a76dd4 refactor(exceptions/status-page): improve exception message wrapping and simplify embedded badge layout
- Add contentClassName to the "Exception Message" column to constrain width and allow proper wrapping.
- Remove the surrounding grid wrapper and the lg:col-span-2 on the Badge Documentation card to simplify the embedded badge layout.
2025-10-24 09:14:53 +01:00
Nawaz Dhandala
05b1f0ea82 refactor(status-page): use Alert component for token regeneration warning in embedded badge card 2025-10-24 09:12:41 +01:00
Nawaz Dhandala
b943505b1d refactor(status-page): include embeddedOverallStatusToken in modelDetailProps 2025-10-24 09:08:31 +01:00
Simon Larsen
1ed236eb91 Merge pull request #2046 from OneUptime/snyk-upgrade-6c5f58f1b138b8c82cfd6bdcdf7dbcce
[Snyk] Upgrade react-router-dom from 6.23.1 to 6.30.1
2025-10-24 09:02:22 +01:00
snyk-bot
44795182c9 fix: upgrade react-router-dom from 6.23.1 to 6.30.1
Snyk has created this PR to upgrade react-router-dom from 6.23.1 to 6.30.1.

See this package in npm:
react-router-dom

See this project in Snyk:
https://app.snyk.io/org/oneuptime-RsC2nshvQ2Vnr35jHvMnMP/project/5dd2ef9c-1270-4729-aff4-e407805f7a9c?utm_source=github&utm_medium=referral&page=upgrade-pr
2025-10-24 04:01:13 +00:00
Simon Larsen
50267534e0 Merge pull request #2003 from OneUptime/snyk-fix-2b1cd110cd50d4d7d2d3aab8e21c4982
[Snyk] Security upgrade axios from 1.7.2 to 1.12.0
2025-10-23 21:24:39 +01:00
Simon Larsen
f60836a4dc Merge pull request #2027 from OneUptime/snyk-fix-12d4523821beb1a61df8fdd2378e8e5f
[Snyk] Security upgrade nodemailer from 6.9.16 to 7.0.7
2025-10-23 21:24:33 +01:00
Simon Larsen
303294bb5e Merge pull request #2038 from OneUptime/snyk-fix-bb0bdd9905b96cdaeceb0ee81316a34f
[Snyk] Security upgrade playwright from 1.50.0 to 1.55.1
2025-10-23 21:21:36 +01:00
Simon Larsen
1212a8e4be Merge pull request #2031 from OneUptime/snyk-fix-e2f14fffff98beb03eb482adc84b328d
[Snyk] Security upgrade nginx from 1.28.0-alpine to 1.29.2-alpine
2025-10-23 21:21:29 +01:00
Simon Larsen
25c626d2d4 Merge pull request #2030 from OneUptime/snyk-fix-311183f6327ea1b45e86908c4fe82d3a
[Snyk] Security upgrade mailparser from 3.7.1 to 3.7.5
2025-10-23 21:21:20 +01:00
Simon Larsen
ff6f9c89fa Merge pull request #2040 from OneUptime/snyk-fix-66c920d77215ccde82d8cbc57644a387
[Snyk] Fix for 2 vulnerabilities
2025-10-23 21:20:49 +01:00
Nawaz Dhandala
7f6e905c74 refactor(markdown-viewer): reduce padding for pre and syntax highlighter code blocks 2025-10-23 21:04:33 +01:00
Nawaz Dhandala
2cc64838aa refactor(status-page): keep token in state after regeneration, move regen button to card header, and tweak layout/preview styles
- Remove unused default Button import
- Replace window.location.reload() with setToken(newToken) so UI updates without a full page reload
- Move "Regenerate Token" into Card.buttons with loading/disabled states
- Rework card layout into responsive grid, add bodyClassName, and adjust preview styling (dashed container, max height for badge)
2025-10-23 20:49:07 +01:00
Nawaz Dhandala
3de5c8da8c refactor(status-page): consolidate token rotation UI, use useMemo for modelId, fix side menu icon
- Wrap modelId retrieval in useMemo for stable value
- Move "Regenerate Token" button and helper text into the Security Token card and remove the separate "Token Rotation" card
- Update SideMenu icon for "HTML, CSS & JavaScript" to IconProp.Circle
2025-10-23 20:41:53 +01:00
Nawaz Dhandala
7403ffa053 refactor(status-page): simplify embedded badge state and docs UI
- Remove statusPage state and store embeddedOverallStatusToken and enableEmbeddedOverallStatus
  in separate token and isEmbeddedStatusEnabled states.
- Set token and enabled flag directly in onItemLoaded.
- Simplify "Badge Documentation" card to render MarkdownViewer only (remove raw source/preview split)
- Tweak card description copy.
2025-10-23 20:37:03 +01:00
Nawaz Dhandala
fa473474a2 feat(status-page): improve embedded badge UI, use secure token generation, add preview & docs
- Replace non-cryptographic token generation with ObjectID.generate()
- Add statusPage state, token/isEnabled checks and computed badge URLs
- Split UI into Security Token, Token Rotation, Badge Preview and Badge Documentation cards
- Use HiddenText for copyable token and MarkdownViewer for rendered docs
- Wire CardModelDetail onItemLoaded to populate statusPage for live preview
2025-10-23 20:33:45 +01:00
Nawaz Dhandala
20cbcf9a74 refactor(status-page): remove ModelPage wrapper and routing/side menu from EmbeddedStatus
- Return Fragment directly instead of wrapping with ModelPage
- Remove breadcrumb links and sideMenu usage
- Remove unused imports: PageMap, RouteMap, RouteUtil, Route, SideMenu, ModelPage
2025-10-23 20:12:17 +01:00
Nawaz Dhandala
e6fd4b8304 refactor(types): add explicit typings for env parser and telemetry billing
Add a full function signature for parsePositiveNumberFromEnv and strengthen typing in TelemetryUsageBillingService: import TelemetryServiceModel, type telemetryServices as Array<TelemetryServiceModel>, and annotate count results as PositiveNumber for traces, logs and metrics to improve type-safety and readability.
2025-10-23 20:02:57 +01:00
Nawaz Dhandala
4a3a743dcd chore(format): normalize multiline argument formatting in EnvironmentConfig and TelemetryUsageBillingService 2025-10-23 19:53:09 +01:00
Nawaz Dhandala
6f1e2234d3 feat(telemetry): stage daily usage and centralize telemetry billing
- Add stageTelemetryUsageForProject to TelemetryUsageBillingService:
  count traces/logs/metrics per telemetry service via AnalyticsQueryHelper,
  estimate bytes using average row size env vars, convert to GB and create/update
  daily usage records (uses day + usageDate for deduplication).
- Update updateUsageBilling to accept usageDate, set createdAt to usageDate and
  query by day instead of createdAt ranges.
- Add helper getAverageRowSizeForProduct and import LIMIT_INFINITY,
  DEFAULT_RETENTION_IN_DAYS, TelemetryServiceService, Span/Log/Metric services,
  DiskSize, AnalyticsQueryHelper and logger.
- Call stageTelemetryUsageForProject from TelemetryMeteredPlan before reporting
  to the billing provider.
- Remove direct billing invocation from FluentIngest worker to decouple ingestion
  from billing staging.
2025-10-23 19:51:11 +01:00
Nawaz Dhandala
07189b4567 feat(env): add average telemetry row size settings and expose as env vars
- add billing.telemetry.{averageSpanRowSizeInBytes, averageLogRowSizeInBytes, averageMetricRowSizeInBytes} to values.yaml with defaults
- add schema validation for these fields in values.schema.json (integer, minimum 1)
- expose AVERAGE_SPAN_ROW_SIZE_IN_BYTES, AVERAGE_LOG_ROW_SIZE_IN_BYTES, AVERAGE_METRIC_ROW_SIZE_IN_BYTES in templates/_helpers.tpl
2025-10-23 19:49:59 +01:00
Nawaz Dhandala
b1bc02cec4 feat(env): add average telemetry row size env vars with validation
- introduce parsePositiveNumberFromEnv helper in EnvironmentConfig.ts
- add AverageSpan/Log/MetricRowSizeInBytes exports with positive-number parsing and defaults
- document AVERAGE_* vars in config.example.env and expose them in docker-compose.base.yml
2025-10-23 19:49:24 +01:00
Simon Larsen
6f7795aa31 feat(logs-viewer): add toggleable log ordering and update scroll-to-latest behavior
- add isDescending state and useMemo displayLogs to reverse logs when needed
- rename showScrollToBottom -> showScrollToLatest and replace scrollToBottom with scrollToLatest
- convert handleScroll to useCallback and make it order-aware (top vs bottom)
- update scroll button icon/title and ensure scroll position recalculates after toggling order
- render and count displayLogs (use reversed list) and update empty state checks
- minor comment update in Dashboard LogsViewer
2025-10-23 19:24:02 +01:00
Nawaz Dhandala
50ee87c86f chore(mobile): remove MobileApp configuration files
Remove obsolete MobileApp project configuration and dependency files to clean up the repository:
- MobileApp/package.json
- MobileApp/tailwind.config.js
- MobileApp/tsconfig.json

These files contained Expo / React Native specific settings (dependencies, Nativewind/Tailwind config, and TS config) for a mobile app that is no longer maintained in this repo. Removing them reduces clutter and prevents confusion about supported platforms.
2025-10-23 17:21:20 +01:00
Simon Larsen
a75c6b6a43 feat(status-page): add Embedded Status page with token regeneration and wire up route/menu; remove legacy Embedded component 2025-10-23 16:53:58 +01:00
Simon Larsen
f6168c969e feat(status-page): add embedded status badge UI and token regeneration
- Add advanced options UI for embedded overall status badge: enable toggle, security token display, badge preview, and HTML/Markdown embed examples.
- Implement regenerate token flow with confirmation modal and regenerateToken function that creates a new token and updates the StatusPage via ModelAPI.
- Add local state hooks for modal/loading and construct badge URL with token placeholder.
- Rename/export component from StatusPageDelete to StatusPageAdvancedOptions.
2025-10-23 16:26:45 +01:00
Simon Larsen
2b0f9f2e7a feat(status-page): add embedded overall status badge toggle and token with migration
- Add enableEmbeddedOverallStatus boolean column and embeddedOverallStatusToken (with index) to StatusPage model
- Include billing and column access controls for new fields
- Add corresponding TypeORM migration and register it in migrations index
2025-10-23 16:20:18 +01:00
Nawaz Dhandala
14377c68fe Merge branch 'release' of https://github.com/OneUptime/oneuptime into release 2025-10-23 15:45:59 +01:00
Nawaz Dhandala
9176fa2c9b style(forms): add className override to FieldLabel and apply to Dictionary labels 2025-10-23 15:44:26 +01:00
Nawaz Dhandala
4f29fef5f6 feat(model-filter): add isAdvancedFilter and propagate to table
Add isAdvancedFilter to Filter interface, pass it into the ClassicFilter mapping
in BaseModelTable, and include props.filters in the showFilterModal effect deps
so filters refresh when changed. Mark the TraceTable "Attributes" filter as an
advanced filter.
2025-10-23 13:46:06 +01:00
Simon Larsen
f28c7695ab Merge pull request #2041 from OneUptime/master
Release
2025-10-22 18:16:10 +01:00
Nawaz Dhandala
bc234deb0e style(analytics): simplify empty projections to [] in Log/Metric/Span and remove stray blank line in TableManegement 2025-10-22 18:08:18 +01:00
Nawaz Dhandala
546b4a4fb3 refactor(analytics): expose AnalyticsTableManagement helpers and remove projection/materialized view creation from createTables
- Make utility methods public: doesProjectionExist, materializeProjection, escapeForQuery, escapeIdentifier, doesMaterializedViewExist, createMaterializedView
- Remove inline projection and materialized view creation logic from createTables (createTables now only ensures tables exist)
- Remove unused Projection import
2025-10-22 18:07:45 +01:00
Nawaz Dhandala
1300c4e667 feat(analytics): add materialized view support to analytics models and table management
- add MaterializedView type
- wire materializedViews into AnalyticsBaseModel (constructor param, property, getter/setter)
- implement materialized view processing in AnalyticsTableManagement (validation, existence check, creation)
2025-10-22 18:04:51 +01:00
Nawaz Dhandala
988d5d327c style(analytics): remove attribute projection definitions from Log, Metric and Span models 2025-10-22 17:52:44 +01:00
Nawaz Dhandala
f2510a7b89 style(exceptions): format message div across multiple lines for improved readability 2025-10-22 15:05:54 +01:00
Nawaz Dhandala
a2f16ca0eb style(exceptions): remove container truncate and add break-words to message text to allow long words to wrap 2025-10-22 15:04:44 +01:00
Nawaz Dhandala
1448288395 style(autocompleteTextInput,dictionary): normalize type annotations and tidy JSX formatting 2025-10-22 14:58:24 +01:00
Nawaz Dhandala
734481df6c style(dictionary): replace equals Icon with '=' text, adjust item row spacing/alignment, and remove unused Icon import 2025-10-22 14:57:00 +01:00
Nawaz Dhandala
43c534b76a feat(dictionary): add FieldLabelElement labels for Key, Type and Value fields 2025-10-22 14:44:31 +01:00
Nawaz Dhandala
1b593403b6 refactor(dictionary): remove autoConvertValueTypes and implicit conversions
- Remove NumberUtil/BooleanUtil and the autoConvertValueTypes prop from Dictionary
- Stop automatic string->number/boolean coercion; preserve original values (normalize undefined/null to "")
- Use getDefaultValueForType when adding or changing a value's type
- Update JSONFilter and FormField to import ValueType and pass explicit valueTypes
2025-10-22 14:40:59 +01:00
Nawaz Dhandala
54e60cc380 feat(dictionary): replace key input/dropdown with AutocompleteTextInput and add component 2025-10-22 14:24:49 +01:00
Nawaz Dhandala
28d9879dbd style(logs,traces): add explicit typings and clean up callback formatting
- LogItem: annotate onClick/onAuxClick handlers with React.MouseEvent<HTMLDivElement>
- LogsViewer: add OptionalTraceRouteProps/OptionalSpanRouteProps types and type annotate trace/span route props passed to LogItem
- TraceExplorer: introduce/clarify function type aliases (PromiseVoidFunction, FetchSpansFunction) and annotate callbacks (fetchTelemetryServices, fetchSpans, fetchItems, handleShowNextSpans, handleShowAllSpans); reflow long JSX for readability
2025-10-22 14:08:18 +01:00
Nawaz Dhandala
22c417ac92 feat(traces): show compact loading pill for span load actions in TraceExplorer
Replace disabled "Show next" / "Show all" buttons with a single inline loading indicator while additional spans are being fetched, and restore the action buttons when not loading to improve loading UX and reduce visual clutter.
2025-10-22 13:39:42 +01:00
Nawaz Dhandala
401926c792 feat(traces): add paginated/batched span loading and load-more controls in TraceExplorer
Introduce INITIAL_SPAN_FETCH_SIZE, SPAN_PAGE_SIZE and MAX_SPAN_FETCH_BATCH and refactor span loading to support pagination and batching. Change fetchSpans to accept {limit, skip, mode} and return fetched count (replace | append). Remove spanLimitRef and add handleShowNextSpans / handleShowAllSpans to incrementally load spans (with batch loop for "show all"). Update UI to show a descriptive banner with "Show next" and "Show all remaining" buttons and improve loading/error state handling and metrics messaging.
2025-10-22 13:35:35 +01:00
Nawaz Dhandala
90bc4de84a feat(traces): incremental span loading and improved loading/error UX in TraceExplorer
- split telemetry & span fetching (fetchTelemetryServices, fetchSpans(limit, options))
- add totalSpanCount, spanLimitRef and isLoadingMoreSpans to support partial loading
- add handleShowAllSpans and UI banners/buttons to "Show N more spans" and indicate "Showing all N spans"
- show PageLoader only for initial empty-load; surface non-blocking errors inline when spans exist and keep blocking error when no spans
- show loaded/total counts in Spans metric
- reset span-related state (limit, spans, selection, total) when traceId changes
2025-10-22 13:17:16 +01:00
Nawaz Dhandala
93fd2a9ed7 style(date,gantt): reflow multiline returns in OneUptimeDate and format Row isHighlighted prop for readability 2025-10-22 12:27:31 +01:00
Nawaz Dhandala
231451e359 feat(date,span): add humanized duration formatter and use it in SpanUtil 2025-10-22 12:26:22 +01:00
snyk-bot
3073891a38 fix: Common/package.json & Common/package-lock.json to reduce vulnerabilities
The following vulnerabilities are fixed with an upgrade:
- https://snyk.io/vuln/SNYK-JS-PLAYWRIGHTCORE-13553173
- https://snyk.io/vuln/SNYK-JS-PRISMJS-9055448
2025-10-22 11:16:45 +00:00
Nawaz Dhandala
2b62d31e8b fix(blog): set default pageSize to 25 for blog and tag listing endpoints 2025-10-22 12:04:21 +01:00
Nawaz Dhandala
bc43e6e6ea feat(traces): make card title/description reflect active tab (All / Root Spans) 2025-10-22 11:44:53 +01:00
Nawaz Dhandala
2204ebde26 feat(traces): add tabs for All/Root spans and apply root-span filtering in TraceTable 2025-10-22 11:41:35 +01:00
Nawaz Dhandala
57a8547e14 style(gantt): use conditional prop spreads and refine row/label highlight styling
- Replace direct optional prop passing with conditional spread for
  multiSelect and highlightBarIds in GanttChart Index, Rows and Row to
  avoid passing undefined values.
- Add labelPaddingLeft and adjust row layout: normalize borders, add
  transitions, spacing, overflow handling and subtle ring/shadow when
  highlighted.
- Pass isHighlighted into RowLabel and update RowLabel to apply
  highlighted title/description styles (font weight and colors).
- Normalize Bar isHighlighted check to a boolean expression for safety.
2025-10-22 11:30:35 +01:00
Nawaz Dhandala
53a70e1b93 feat(gantt,traces): add span highlighting support and propagate highlight state
- Add highlightBarIds prop to GanttChart and propagate through Rows -> RowIndex -> Row -> Bar
- Row: compute highlight set, detect highlighted descendants, auto-expand rows with highlights, and apply highlight styles (background, rounded container, data attribute)
- Bar: accept isHighlighted, apply highlight visuals (box-shadow, z-index) and adjust label styling
- Rows/RowIndex: include highlightBarIds in component interfaces and pass-through props
- TraceExplorer: accept highlightSpanIds, sanitize input, derive highlightableSpanIds from displayed spans, and include them in the generated GanttChartProps
- Trace view pages: extract spanId query param, normalize to highlightSpanIds, and pass to TraceExplorer

This enables highlighting specific spans (via spanId query) in the Gantt chart UI and ensures highlighted rows are visible and visually emphasized.
2025-10-22 11:22:32 +01:00
Nawaz Dhandala
3eb72ef7f9 style(telemetry,ingest,ui): normalize TelemetryUtil.getAttributeKeys call formatting and tidy LogItem JSX/whitespace 2025-10-22 11:03:26 +01:00
Nawaz Dhandala
2a471133c5 feat(logs): make span IDs clickable and refine trace link styling
- Add getSpanRoute prop to LogsViewer and LogItem and thread it through from callers.
- Implement renderSpanId to render clickable span links (resolves via getSpanRoute or by appending spanId to trace route).
- Show "No span" placeholder when spanId is missing.
- Prevent link clicks from toggling the log row (stopPropagation on span links).
- Tweak trace link decoration and external-link icon color for improved hover styling.
- Minor prop typing / pass-through cleanup in LogsViewer.
2025-10-22 11:02:07 +01:00
Nawaz Dhandala
34e92679b2 feat(logs): render trace IDs as clickable links with external-link icon and refined styling 2025-10-22 10:41:25 +01:00
Nawaz Dhandala
8b0c2a7320 feat(analytics): make trace IDs clickable in logs
Add an optional getTraceRoute prop to LogItem and LogsViewer and render traceId as a Link when a route is provided. Stop event propagation on link clicks to avoid toggling collapse. Wire getTraceRoute from Dashboard and Span viewers using RouteUtil.populateRouteParams.
2025-10-22 10:34:28 +01:00
Nawaz Dhandala
353d894394 feat(analytics): mark attributeKeys as required on Log, Metric and Span models 2025-10-21 22:22:48 +01:00
Nawaz Dhandala
09e4f0ff97 fix(analytics): cast metric.attributes when computing attributeKeys to satisfy TelemetryUtil signature 2025-10-21 22:10:46 +01:00
Nawaz Dhandala
247c4bc637 feat(analytics): populate attributeKeys on telemetry records and prefer attributeKeys column when querying
- Add TelemetryUtil.getAttributeKeys helper.
- Populate attributeKeys for Logs, Metrics, Spans, Alerts, Incidents and Monitor metrics during ingest/processing.
- Ensure FluentIngest initializes attributeKeys for raw logs.
- Update TelemetryAttributeService to use attributeKeys column when available and fall back to JSONExtractKeys(attrs).
- Improve attribute extraction SQL to filter empty/null attribute keys.
2025-10-21 22:05:48 +01:00
Nawaz Dhandala
72e2edd49d feat(analytics): add attributeKeys column to Log/Metric/Span, update projections and add migration 2025-10-21 22:04:49 +01:00
Nawaz Dhandala
1be494169d fix(analytics): rename ClickHouse projections to singular 'AttributeProjection' for Log, Metric and Span models 2025-10-21 21:05:52 +01:00
Nawaz Dhandala
3796053403 style(analytics): remove extra blank line in doesProjectionExist catch block 2025-10-21 21:04:17 +01:00
Nawaz Dhandala
f316bfb9fd feat(analytics): materialize projections after creation and add error handling
Call materializeProjection after creating a projection to ensure it is materialized.
Introduce materializeProjection to run ALTER TABLE ... MATERIALIZE PROJECTION and
add escapeIdentifier for safe identifier quoting. Wrap the projection-existence
query in try/catch with logging and rethrow on failure.
2025-10-21 21:03:10 +01:00
Nawaz Dhandala
40f9613bd3 chore(docker): bump clickhouse server image to 25.7 in docker-compose.base.yml 2025-10-21 20:49:33 +01:00
Nawaz Dhandala
a3bb9f003f style(analytics): add debug logging to projection processing in TableManegement.ts 2025-10-21 19:48:41 +01:00
Nawaz Dhandala
70714b2f21 feat(analytics): add ClickHouse projections for attributes to Log, Metric and Span models
Add projection definitions (ALTER TABLE ...) to Log, Metric and Span analytics models to extract distinct attribute keys per project (LogItemAttributesProjection, MetricItemAttributesProjection, SpanItemAttributesProjection).

style(telemetry): simplify empty query object in DeleteOldData.ts
2025-10-21 19:46:48 +01:00
Nawaz Dhandala
a62543bff0 feat(telemetry): iterate active projects and prune telemetry data per service
- Use ProjectService.getActiveProjectStatusQuery() to fetch active projects
- Query telemetry services per project and scope deletions by project.id
- Add try/catch blocks and logger calls for better error isolation and robustness
- Preserve default retention (15 days) and perform deletes for logs, spans, and metrics
2025-10-21 19:27:19 +01:00
Nawaz Dhandala
826a2006d0 style(telemetry): reformat retentionCutOff assignment in DeleteOldData.ts 2025-10-21 18:55:07 +01:00
Nawaz Dhandala
a4075fe349 feat(telemetry): compute single retention cutoff, prune by primary keys, and delete metrics
- compute retentionCutOff once per service instead of repeated calls
- use primary-key columns (time/startTime) for efficient pruning of logs and spans
- implement MetricService.deleteBy to remove old OpenTelemetry metrics
- minor import/order adjustments
2025-10-21 18:53:44 +01:00
Nawaz Dhandala
eb70a923f3 style(analytics): add explicit types for executeQuery result and json response in TableManegement.ts 2025-10-21 16:00:38 +01:00
Nawaz Dhandala
11d39898d3 style(analytics): normalize escaped variable formatting in TableManegement.ts 2025-10-21 15:54:45 +01:00
Nawaz Dhandala
8e5907d523 feat(analytics): check for existing projections before creating; add doesProjectionExist and escapeForQuery helpers and required imports 2025-10-21 15:51:07 +01:00
Nawaz Dhandala
c9e57fcb19 feat(analytics): add Projection type and use typed projections in models and table creation 2025-10-21 15:46:57 +01:00
Nawaz Dhandala
8c6bc331a4 style(analytics): normalize AnalyticsTableColumn constructor formatting
Reformat multi-line new AnalyticsTableColumn(...) expressions to a consistent style and tidy up minor inline description/spacing in ExceptionInstance, Log, Metric and Span models.
2025-10-21 14:56:01 +01:00
Nawaz Dhandala
20129e606a feat(analytics): add projections support to models and apply projection statements on table creation
- add projections param, backing field and accessors to AnalyticsBaseModel (defaults to [])
- update analytics models (ExceptionInstance, Log, Metric, MonitorLog, Span) to include projections: []
- execute each model.projections SQL statement in AnalyticsTableManagement when creating tables
2025-10-21 14:37:22 +01:00
Nawaz Dhandala
55e0eede68 refactor(analytics): extract AnalyticsTableColumn definitions into local variables
Move repeated new AnalyticsTableColumn(...) definitions into named constants and reuse them in tableColumns for Log, Metric, Span, MonitorLog and ExceptionInstance models. Reduces duplication and improves readability without changing behavior.
2025-10-21 14:18:57 +01:00
Nawaz Dhandala
ffa603503d fix: update image tag to use GitHub Container Registry for release builds 2025-10-21 11:19:04 +01:00
Nawaz Dhandala
18429caabe fix: refactor Microsoft Teams pagination logic to use configurable maximum pages 2025-10-20 15:31:18 +01:00
Simon Larsen
ccbfef1cfe Merge pull request #2039 from tollercode/fix/pagination-msteams-fetch-teams-list
fix: pagination msteams fetch teams list
2025-10-20 15:20:37 +01:00
Nils T
4789a15ce7 fix: make maximum pages for fetching teams configurable to prevent infinite loop 2025-10-20 12:47:13 +00:00
Nils T
9633307de0 fix: add pagination limit to prevent infinite loop when fetching teams from Microsoft Graph API 2025-10-20 12:43:24 +00:00
Nils T
ee5c2a0f33 fix: implement pagination for fetching all teams from Microsoft Graph API 2025-10-20 12:17:26 +00:00
snyk-bot
5c3b181507 fix: Probe/package.json to reduce vulnerabilities
The following vulnerabilities are fixed with an upgrade:
- https://snyk.io/vuln/SNYK-JS-PLAYWRIGHTCORE-13553173
2025-10-20 10:50:12 +00:00
Nawaz Dhandala
6bbf2f866c fix: update hard delete logic to retain items for 3 years instead of 120 days 2025-10-18 10:37:53 +01:00
Nawaz Dhandala
60e4b51ec9 fix: update Microsoft Teams app manifest version to 1.5.0 2025-10-17 10:43:32 +01:00
Nawaz Dhandala
f244f872d4 fix: improve formatting and consistency in tenant ID retrieval checks in MicrosoftTeamsUtil 2025-10-17 10:14:45 +01:00
Nawaz Dhandala
3e910c1308 fix: ensure tenant ID is retrieved and validated in MicrosoftTeamsUtil 2025-10-17 10:13:58 +01:00
Nawaz Dhandala
2b0067fd17 fix: update tenant ID retrieval logic in MicrosoftTeamsAPI 2025-10-17 10:11:54 +01:00
Nawaz Dhandala
cb23b6b55b Merge branch 'master' of https://github.com/OneUptime/oneuptime 2025-10-16 21:01:31 +01:00
Nawaz Dhandala
4406d52307 feat: add queries management section to Clickhouse documentation 2025-10-16 20:52:52 +01:00
Simon Larsen
03b6bec6d0 feat: add validation for required fields in WorkspaceProjectAuthTokenService and MicrosoftTeamsUtil 2025-10-16 20:36:45 +01:00
Nawaz Dhandala
ff0bd88b02 fix: ensure Microsoft Teams tenant ID is provided before creating Bot Framework adapter 2025-10-16 20:23:50 +01:00
Simon Larsen
94290c77db feat: add advanced filters toggle functionality across various components 2025-10-16 16:35:57 +01:00
Simon Larsen
003e44d331 refactor: clean up code formatting and improve readability in TelemetryAttributeService and LogsViewer components 2025-10-16 16:08:34 +01:00
Simon Larsen
b4cf798246 Merge branch 'master' of github.com:OneUptime/oneuptime 2025-10-16 16:06:49 +01:00
Simon Larsen
e607367809 feat: enhance Filters and LogsViewer components with advanced filters functionality and loading states 2025-10-16 16:06:14 +01:00
Nawaz Dhandala
82a7b5794c fix: reduce row scan limit from 100000 to 10000 in TelemetryAttributeService 2025-10-16 15:59:28 +01:00
Nawaz Dhandala
37c1674029 fix: reduce cache stale time from 10 to 5 minutes in TelemetryAttributeService 2025-10-16 15:59:12 +01:00
Nawaz Dhandala
cd2a5222b8 fix: add expiration options for cache entries in GlobalCache and TelemetryAttributeService 2025-10-16 15:58:53 +01:00
Nawaz Dhandala
875d6c5df9 fix: enhance caching mechanism and improve attribute fetching in TelemetryAttributeService 2025-10-16 15:52:44 +01:00
Nawaz Dhandala
7eea90a55a fix: format constructor parameters for consistency in IdentityAPI 2025-10-16 15:42:13 +01:00
Nawaz Dhandala
c401b86a2e fix: update route handling to use Route class for URL construction across multiple services 2025-10-16 15:30:18 +01:00
Nawaz Dhandala
e96f781157 fix: refactor URL construction for view details and redirect routes in UserNotificationLogTimelineAPI 2025-10-16 15:05:57 +01:00
Nawaz Dhandala
73cc5f8f9e fix: update route handling in EnvironmentConfig for consistency 2025-10-16 15:04:52 +01:00
Nawaz Dhandala
0ee9876de9 fix: format code for consistency in OtelIngest services 2025-10-16 14:22:09 +01:00
Nawaz Dhandala
b76a75479d Implement OpenTelemetry Ingest Services for Logs, Metrics, and Traces
- Added OtelIngestBaseService as a base class for common functionality.
- Implemented OtelLogsIngestService to handle log ingestion, including processing and flushing logs to the database.
- Implemented OtelMetricsIngestService to handle metric ingestion, including processing and flushing metrics to the database.
- Implemented OtelTracesIngestService to handle trace ingestion, including processing spans and exceptions, and flushing them to the database.
- Introduced error handling and logging throughout the ingestion process to ensure robustness.
- Utilized CaptureSpan decorator for telemetry tracking in key methods.
- Enhanced service name extraction from request attributes for better traceability.
2025-10-16 14:21:44 +01:00
Simon Larsen
79b9cf4c06 Merge pull request #2034 from OneUptime/telemetry-attr
Telemetry attr
2025-10-15 18:13:17 +01:00
Nawaz Dhandala
a6da59c966 fix: add Results and DbJSONResponse types to AnalyticsDatabaseService and update TelemetryAttributeService to use them 2025-10-15 18:12:34 +01:00
Nawaz Dhandala
b84695feb9 fix: remove TelemetryType references and indexAttributes calls from various services 2025-10-15 17:21:56 +01:00
Nawaz Dhandala
b77973441d fix: remove TelemetryAttribute and TelemetryAttributeService references and related code 2025-10-15 16:26:05 +01:00
Nawaz Dhandala
27e9c07c57 fix: remove padding from MarkdownViewer component 2025-10-15 15:57:45 +01:00
Nawaz Dhandala
cbf8684d8c fix: remove force garbage collection method and its calls from OtelIngestService 2025-10-15 15:47:22 +01:00
Nawaz Dhandala
87057757a5 fix: remove --expose-gc option from NODE_OPTIONS in Dockerfile, nodemon.json, and package.json 2025-10-15 15:42:29 +01:00
Nawaz Dhandala
23b587f0f6 fix: remove unused EnableWorkflow import from TelemetryException model 2025-10-15 15:22:53 +01:00
Nawaz Dhandala
81c7a4eeb7 fix: remove EnableWorkflow decorator from TelemetryException model 2025-10-15 14:49:56 +01:00
Nawaz Dhandala
549dbfd6c7 fix: format nodemon.json and adjust package.json dev script indentation 2025-10-15 13:45:54 +01:00
Nawaz Dhandala
a2eac673eb fix: update NODE_OPTIONS to include --expose-gc and --use-openssl-ca in Dockerfile and nodemon configuration 2025-10-15 13:45:07 +01:00
Nawaz Dhandala
086a0a661d feat: implement dynamic batch size configuration for OpenTelemetry ingestion 2025-10-15 13:39:11 +01:00
Nawaz Dhandala
da0620eafa fix: improve logging of request body in OpenTelemetry middleware 2025-10-15 12:53:15 +01:00
Nawaz Dhandala
ca90ab0db4 fix: update Kubernetes cheatsheet to include OOMKilled pods in cleanup section 2025-10-15 12:36:06 +01:00
Nawaz Dhandala
94dacc20db feat: add Kubernetes cheatsheet for pod cleanup commands 2025-10-15 12:30:34 +01:00
Nawaz Dhandala
7e887bd4cd feat: enhance app description with HTML formatting and update support links 2025-10-14 19:37:28 +01:00
Nawaz Dhandala
b50dfcdf1c fix: update Microsoft Teams setup guide URL to correct link 2025-10-14 19:02:34 +01:00
Nawaz Dhandala
e2bc0ea4aa feat: add welcome card state management to prevent duplicate sends 2025-10-14 19:02:06 +01:00
Simon Larsen
7d018b94d3 Merge pull request #2033 from OneUptime/fix-change-plan
Fix change plan
2025-10-14 14:12:05 +01:00
Nawaz Dhandala
9fb7a70dc9 feat: add createOrUpdateApiUrl prop to CardModelDetail and update Billing page to generate change plan API URL 2025-10-14 14:02:45 +01:00
Nawaz Dhandala
a37b3fc0b3 feat: implement change plan API with billing permission checks 2025-10-14 13:54:38 +01:00
Nawaz Dhandala
c06ef5ddfc fix: add ManageProjectBilling permission for project updates 2025-10-14 13:34:12 +01:00
Nawaz Dhandala
0fb7174e94 chore: remove unused devDependencies from package.json and package-lock.json 2025-10-14 11:59:17 +01:00
Nawaz Dhandala
84a7cd976d fix: update template IDs for AlertCreated and IncidentCreated in WhatsAppTemplates 2025-10-14 10:44:27 +01:00
Nawaz Dhandala
f7c8c00f04 t psh
:wq!
Merge branch 'master' into release
2025-10-13 13:33:02 +01:00
Simon Larsen
51c3fcd3ca Merge pull request #2032 from OneUptime/whatsapp-webhook
Whatsapp webhook
2025-10-13 13:32:25 +01:00
Nawaz Dhandala
74c3dde7f1 refactor: improve type annotations and enhance readability in WhatsApp API and LogsTable components 2025-10-13 13:31:56 +01:00
Nawaz Dhandala
6bf45f6f31 refactor: streamline code formatting and improve readability in WhatsApp components and services 2025-10-13 13:26:57 +01:00
Nawaz Dhandala
4de4ad8022 feat: enhance status color handling in WhatsAppLogsTable component 2025-10-13 13:26:19 +01:00
Nawaz Dhandala
e263900115 feat: add migration for metaWhatsAppWebhookVerifyToken in GlobalConfig 2025-10-13 13:15:57 +01:00
Nawaz Dhandala
34aaa34fb3 refactor: remove shorthand webhook URL and simplify callback URL instructions in WhatsApp setup markdown 2025-10-13 13:14:10 +01:00
Nawaz Dhandala
9f72a8e554 feat: add webhook verification and enhance WhatsApp status handling 2025-10-13 12:44:48 +01:00
Nawaz Dhandala
8dfabfd96f feat: enhance WhatsApp status handling and add webhook verify token to GlobalConfig 2025-10-13 12:33:39 +01:00
Nawaz Dhandala
14cdc3ea86 chore: update package.json and package-lock.json to add ts-jest and new dependencies 2025-10-13 12:31:52 +01:00
Nawaz Dhandala
cd6abe63ea refactor: format code and ensure consistent import/export statements across migration and mobile app files 2025-10-13 11:52:41 +01:00
Nawaz Dhandala
aeb6d53b9d refactor: remove unused imports and simplify status message handling in WhatsAppLogsTable 2025-10-13 11:41:29 +01:00
Nawaz Dhandala
efa7224718 fix: update ConfirmModal description styling for better text wrapping 2025-10-13 10:56:46 +01:00
Nawaz Dhandala
a2c406d7cc refactor: simplify database properties handling in WhatsAppLogAPI 2025-10-13 10:51:52 +01:00
Nawaz Dhandala
1933e37beb refactor: move getMetaWhatsAppConfig call to improve message handling logic 2025-10-13 10:43:46 +01:00
Nawaz Dhandala
0b0336f9ea Merge branch 'master' of https://github.com/OneUptime/oneuptime 2025-10-13 10:35:51 +01:00
Simon Larsen
9304079a1c feat: implement WhatsAppLogAPI for fetching WhatsApp message status and update WhatsAppLogsTable to display message ID 2025-10-13 10:35:41 +01:00
Nawaz Dhandala
1e2dcf332b fix: enhance type handling for return values in VM router 2025-10-13 10:15:46 +01:00
Simon Larsen
ca860f54a8 feat: update permissions to replace ReadSmsLog with ReadWhatsAppLog in WhatsAppLog model and Permission types 2025-10-13 10:01:05 +01:00
Simon Larsen
513e4146ed feat: add migration for WhatsAppMessageId field in WhatsAppLog table with index 2025-10-13 09:59:33 +01:00
Simon Larsen
43d31ddbe9 feat: add WhatsAppMessageId field to WhatsAppLog model with access control and metadata 2025-10-13 09:55:22 +01:00
Simon Larsen
18231f42aa feat: update MobileAppPrompt.md for UI guidelines and add react-native-webview dependency in package.json; create AuthSession type 2025-10-12 12:38:36 +01:00
Simon Larsen
60291cc218 docs: update MobileAppPrompt.md to clarify usage of @oneuptime/common package 2025-10-12 12:33:46 +01:00
Simon Larsen
3658f0349e feat: add react-native-worklets dependency to package.json and package-lock.json 2025-10-12 12:29:29 +01:00
Simon Larsen
02133165d8 chore: update dependencies and configure Tailwind CSS with NativeWind
- Added @expo/metro-runtime, nativewind, prettier-plugin-tailwindcss, react-dom, and tailwindcss to dependencies.
- Updated react-native-safe-area-context to version 5.4.0.
- Added global.css for Tailwind CSS styles.
- Created metro.config.js to integrate NativeWind with Expo.
- Added nativewind-env.d.ts for TypeScript support.
- Created tailwind.config.js to configure Tailwind CSS with NativeWind.
- Updated tsconfig.json to include nativewind-env.d.ts.
2025-10-12 12:28:30 +01:00
Simon Larsen
837b841352 refactor: remove unused ObjectID generation and related state management 2025-10-12 10:29:00 +01:00
Simon Larsen
10e344dad5 feat: add react-native-get-random-values dependency and import in App component 2025-10-12 10:08:23 +01:00
Simon Larsen
848bfb358f chore: add @oneuptime/common dependency and update tsconfig to exclude Common directory 2025-10-12 10:05:18 +01:00
Simon Larsen
2ca1c64532 Implement new feature for user authentication and improve error handling 2025-10-12 09:55:28 +01:00
Simon Larsen
d9a79eafbd fix: clarify file naming conventions in mobile app development prompt 2025-10-12 09:26:31 +01:00
Simon Larsen
a1dc16f4b6 feat: refactor styles into separate Styles.ts file for better organization 2025-10-12 09:25:23 +01:00
Nawaz Dhandala
674613c0d6 feat: add initial mobile app development prompt in MobileAppPrompt.md 2025-10-12 09:20:09 +01:00
Nawaz Dhandala
e4e095798a fix: enhance type definitions and import statements in App.tsx 2025-10-11 12:22:15 +01:00
Nawaz Dhandala
2e07185584 fix: standardize formatting in App.tsx and tsconfig.json 2025-10-11 12:19:33 +01:00
Nawaz Dhandala
144001981a Add initial configuration for mobile app with Expo
- Created package.json for project dependencies and scripts
- Added TypeScript configuration with strict settings and React Native support
2025-10-11 12:16:39 +01:00
Nawaz Dhandala
cd096f66ea fix: update app approval status message to include manual sideloading instructions 2025-10-11 12:15:52 +01:00
Nawaz Dhandala
036b29da51 fix: standardize error messages and improve formatting in MicrosoftTeamsAPI 2025-10-11 11:12:49 +01:00
Nawaz Dhandala
d0d59147ae fix: add download button for app manifest and manual sideloading instructions 2025-10-11 11:12:15 +01:00
snyk-bot
565fbe6cd3 fix: Nginx/Dockerfile.tpl to reduce vulnerabilities 2025-10-11 08:37:10 +00:00
snyk-bot
12c3f9b25c fix: package.json & package-lock.json to reduce vulnerabilities
The following vulnerabilities are fixed with an upgrade:
- https://snyk.io/vuln/SNYK-JS-NODEMAILER-13378253
2025-10-11 08:35:50 +00:00
Nawaz Dhandala
02cffe9f8b fix: update Microsoft Teams outline image 2025-10-10 20:39:12 +01:00
Nawaz Dhandala
9c52e8966f fix: update Microsoft Teams outline image 2025-10-10 17:38:24 +01:00
Nawaz Dhandala
9257a949fe fix: add Microsoft Teams app client ID and secret placeholders to config example 2025-10-10 16:34:25 +01:00
Nawaz Dhandala
7528ed8e0c fix: update Microsoft Teams app manifest version and improve error handling 2025-10-10 15:55:18 +01:00
Nawaz Dhandala
98b6f3eac3 fix: streamline text formatting in Microsoft Teams integration messages 2025-10-10 09:17:34 +01:00
Nawaz Dhandala
a2561b3ae8 fix: update acknowledge route to acknowledge-page in UserNotificationRuleService 2025-10-10 09:15:55 +01:00
Nawaz Dhandala
368f5c6bbc Merge branch 'master' of https://github.com/OneUptime/oneuptime 2025-10-10 09:01:23 +01:00
Nawaz Dhandala
0e2e30b0a9 fix: remove Microsoft identity association endpoint for cleanup 2025-10-10 09:00:42 +01:00
Simon Larsen
2664a24875 fix: update outline image for Microsoft Teams integration 2025-10-09 18:47:58 +01:00
Simon Larsen
40e486669f feat: enhance app description and support information in Microsoft Teams API 2025-10-09 18:36:45 +01:00
Simon Larsen
ae64cbc718 feat: implement welcome adaptive card for OneUptime bot in Microsoft Teams 2025-10-09 18:35:32 +01:00
Simon Larsen
e14f691cc4 feat: add comment for Microsoft identity verification endpoint 2025-10-09 18:21:40 +01:00
Simon Larsen
89c607a530 feat: add endpoint for Microsoft identity association JSON 2025-10-09 18:21:03 +01:00
Simon Larsen
90f4e7418f fix: streamline SCIM group schema definition and ensure proper syntax in migrations 2025-10-09 17:40:44 +01:00
Simon Larsen
79fed2da09 fix: remove deprecated SCIM 1.1 schema references for improved compatibility 2025-10-09 17:34:37 +01:00
Simon Larsen
1dd41c103f Merge branch 'release' of github.com:OneUptime/oneuptime into release 2025-10-09 17:34:18 +01:00
Simon Larsen
988e85affc fix: remove deprecated SCIM schema reference in formatTeamForSCIM function 2025-10-09 17:34:15 +01:00
Nawaz Dhandala
2810516987 Merge branch 'master' of https://github.com/OneUptime/oneuptime 2025-10-09 17:19:00 +01:00
Nawaz Dhandala
679c1971a2 fix: update WhatsApp setup instructions for token generation and template creation 2025-10-09 17:18:58 +01:00
Nawaz Dhandala
3abdbb7ef9 fix: correct typo in IncidentStateChangedOwnerNotification template ID 2025-10-09 17:12:17 +01:00
Simon Larsen
0d647f5dc1 fix: improve release retrieval by using pagination and handle missing release tags 2025-10-09 13:43:43 +01:00
Nawaz Dhandala
bd1df491a2 Remove MobileApp components, themes, and configuration files
- Deleted package.json, removing all dependencies and scripts for the mobile app.
- Removed FeatureCard, GlowingButton, MetricCard, SafeAreaContainer, and HomeScreen components.
- Eliminated color, layout, and typography theme files.
- Deleted TypeScript configuration file (tsconfig.json).
2025-10-09 11:59:34 +01:00
Nawaz Dhandala
feb872d05c feat: add E2E testing support with docker-compose configuration 2025-10-09 11:39:30 +01:00
Nawaz Dhandala
64b6b99a21 refactor: replace retry action with shell commands for preinstall and E2E tests 2025-10-08 20:10:19 +01:00
Nawaz Dhandala
8046c244b1 feat: add react-dom and react-native-web dependencies to package.json 2025-10-08 18:52:29 +01:00
Nawaz Dhandala
6928316ba0 feat: implement initial structure and components for OneUptime Mobile app 2025-10-08 18:33:50 +01:00
Nawaz Dhandala
36c74642f2 Initialize MobileApp with package.json and tsconfig.json for Expo project setup 2025-10-08 18:14:29 +01:00
Nawaz Dhandala
5a992e99c8 refactor: format publisherDocsUrl for better readability in Microsoft Teams app manifest 2025-10-08 18:06:52 +01:00
Nawaz Dhandala
ff9230f878 refactor: add publisherDocsUrl to Microsoft Teams app manifest 2025-10-08 17:08:45 +01:00
Nawaz Dhandala
9afa861ff2 refactor: remove obsolete migration files and update index 2025-10-08 17:04:59 +01:00
Nawaz Dhandala
6d7486e76d refactor: update developer name from "OneUptime" to "HackerBay Inc" in MicrosoftTeamsAPI 2025-10-08 17:02:59 +01:00
Nawaz Dhandala
8529012b19 refactor: remove "whatsAppText" column from WhatsAppLog table 2025-10-08 16:45:29 +01:00
Nawaz Dhandala
f704bd47a3 refactor: remove unused column "whatsAppText" from WhatsAppLog table 2025-10-08 14:58:24 +01:00
Nawaz Dhandala
239f2fc34e refactor: streamline actionLink resolution in createWhatsAppMessageFromTemplate 2025-10-08 14:35:31 +01:00
Nawaz Dhandala
5d5183b08e refactor: remove action_link from templateVariables in createWhatsAppMessageFromTemplate 2025-10-08 14:29:13 +01:00
Nawaz Dhandala
7cad0fab0f refactor: clean up whitespace and improve code formatting in multiple files 2025-10-08 14:20:41 +01:00
Nawaz Dhandala
98e0d55ee3 feat: update template variable iteration to include parameter names 2025-10-08 14:19:01 +01:00
Nawaz Dhandala
2d8f0d7a58 feat: add recipient_type to WhatsApp message payload for individual recipients 2025-10-08 13:46:55 +01:00
Nawaz Dhandala
643303cd7a feat: enhance error handling to include HTTPErrorResponse support 2025-10-08 13:27:26 +01:00
snyk-bot
9ee0e0f3cb fix: Common/package.json & Common/package-lock.json to reduce vulnerabilities
The following vulnerabilities are fixed with an upgrade:
- https://snyk.io/vuln/SNYK-JS-NODEMAILER-13378253
2025-10-08 05:10:50 +00:00
Nawaz Dhandala
dc692203be feat: add selectMoreFields for delivery channel options in notification settings 2025-10-07 22:40:29 +01:00
Nawaz Dhandala
648c51d007 feat: enhance notification settings with delivery channel options and icons 2025-10-07 22:37:40 +01:00
Nawaz Dhandala
0e5b106333 fix: update icon for resend code button from WhatsApp to SMS 2025-10-07 22:20:24 +01:00
Nawaz Dhandala
40e9ea2ab6 feat: add WhatsApp alert options to notification settings 2025-10-07 22:19:16 +01:00
Nawaz Dhandala
2157e228b9 Merge branch 'master' of https://github.com/OneUptime/oneuptime 2025-10-07 21:49:36 +01:00
Nawaz Dhandala
5c5534adb8 fix: add type annotation for response in sendWhatsAppMessage method 2025-10-07 21:49:34 +01:00
Nawaz Dhandala
379297cd7e fix: streamline async function signatures in API routes for consistency 2025-10-07 21:49:14 +01:00
Nawaz Dhandala
b3730e9708 fix: add user authorization middleware to /test endpoint 2025-10-07 21:48:31 +01:00
Nawaz Dhandala
2fbc44d5c3 Refactor API endpoints to include error handling middleware
- Updated multiple API routes to use NextFunction for error handling.
- Wrapped asynchronous route handlers in try-catch blocks to catch and pass errors to the next middleware.
- Ensured consistent error responses across various endpoints, improving maintainability and readability.
- Enhanced the structure of the code by reducing nested try-catch blocks and improving flow control.
2025-10-07 21:46:25 +01:00
Nawaz Dhandala
12f05937af fix: enhance error handling in API endpoints by adding NextFunction support 2025-10-07 21:17:59 +01:00
Simon Larsen
5ea440492b Merge branch 'master' of github.com:OneUptime/oneuptime 2025-10-07 21:16:14 +01:00
Simon Larsen
57b851a498 refactor: rename github-release job to draft-github-release and add finalize-github-release job for publishing 2025-10-07 21:15:45 +01:00
Nawaz Dhandala
00f806b077 fix: enhance error handling in WhatsApp message template rendering for missing variables 2025-10-07 21:13:40 +01:00
Nawaz Dhandala
975c20a788 fix: improve error handling in verification endpoints by adding NextFunction support 2025-10-07 20:49:27 +01:00
Nawaz Dhandala
948e2d93c1 fix: handle errors in resend verification code endpoint and add NextFunction support 2025-10-07 20:38:11 +01:00
Nawaz Dhandala
6de3c93745 fix: refactor error handling for WhatsApp verification and resend code modals 2025-10-07 20:31:47 +01:00
Nawaz Dhandala
1f63110561 feat: enhance WhatsApp verification code handling with error logging and improved response management 2025-10-07 20:25:32 +01:00
Nawaz Dhandala
8a94c35450 feat: enforce template key requirement for WhatsApp messages and add debug logging for API requests 2025-10-07 16:59:53 +01:00
Nawaz Dhandala
fdc97284a5 fix: update DEFAULT_META_WHATSAPP_API_VERSION to v23.0 2025-10-07 16:48:22 +01:00
Nawaz Dhandala
792ecfdbdc fix: remove 'From' column from WhatsApp logs table 2025-10-07 16:04:24 +01:00
Nawaz Dhandala
121b01dc08 feat: add WhatsApp notifications toggle to notification settings 2025-10-07 16:01:27 +01:00
Nawaz Dhandala
1aa49071eb feat: add UserWhatsAppAPI for handling WhatsApp verification and resend functionality 2025-10-07 15:57:06 +01:00
Nawaz Dhandala
66bef1284a feat: add documentation for canceling all GitHub actions jobs using GitHub CLI 2025-10-07 15:53:37 +01:00
Nawaz Dhandala
1526f708de fix: enhance error handling and logging for WhatsApp message sending failures 2025-10-07 15:49:34 +01:00
Nawaz Dhandala
53198e4486 fix: improve error logging for WhatsApp message sending failures 2025-10-07 15:39:10 +01:00
Nawaz Dhandala
a66bf2df2a feat: enhance WhatsApp icon SVG with stroke properties and viewBox 2025-10-07 15:31:20 +01:00
Nawaz Dhandala
34422721c3 feat: add WhatsApp logs table to Notification Logs 2025-10-07 15:19:36 +01:00
Nawaz Dhandala
b5008c2363 Merge branch 'whatsapp' 2025-10-07 15:15:48 +01:00
Nawaz Dhandala
1cbab2be08 refactor: remove unused dashboard link and update WhatsApp message template variables 2025-10-07 15:15:25 +01:00
Simon Larsen
1bdcfd71f7 Merge pull request #2026 from OneUptime/whatsapp
Whatsapp
2025-10-07 15:05:58 +01:00
Nawaz Dhandala
792271b146 Merge branch 'whatsapp' of https://github.com/OneUptime/oneuptime into whatsapp 2025-10-07 15:02:44 +01:00
Nawaz Dhandala
3de5fbd35c fix: correct variable assignment for templateKey in test message route 2025-10-07 15:02:19 +01:00
Nawaz Dhandala
6f8dc1ed59 feat: update test message sending functionality to use predefined template and language 2025-10-07 15:00:41 +01:00
Nawaz Dhandala
92309d8fb2 feat: add test notification template and implement test message sending functionality in WhatsApp setup 2025-10-07 14:57:00 +01:00
Simon Larsen
d3070975cb Merge branch 'whatsapp' of github.com:OneUptime/oneuptime into whatsapp 2025-10-07 14:37:26 +01:00
Simon Larsen
69c0da5b17 refactor: remove WhatsApp high-risk cost variable and update related configurations 2025-10-07 14:37:23 +01:00
Nawaz Dhandala
1736690f01 feat: enhance WhatsApp setup markdown with detailed instructions for Business Account ID, App ID, and App Secret 2025-10-07 14:22:43 +01:00
Nawaz Dhandala
78a92905e9 feat: update WhatsApp setup markdown for clarity and improved instructions 2025-10-07 14:21:24 +01:00
Nawaz Dhandala
801c1b4ccb feat: remove header from WhatsApp setup markdown for improved clarity 2025-10-07 14:15:37 +01:00
Nawaz Dhandala
703b1dca51 feat: enhance WhatsApp setup markdown formatting for better structure and clarity 2025-10-07 14:12:55 +01:00
Nawaz Dhandala
e5ef97abd9 feat: improve WhatsApp setup markdown formatting for clarity and structure 2025-10-07 13:58:28 +01:00
Nawaz Dhandala
3053856990 feat: enhance WhatsApp setup markdown formatting for improved readability 2025-10-07 13:45:12 +01:00
Nawaz Dhandala
b8e82e2801 feat: add WhatsApp configuration fields to GlobalConfig migration and update template IDs for type safety 2025-10-07 13:36:21 +01:00
Nawaz Dhandala
2187fe63f0 feat: refactor WhatsApp template IDs and messages for improved type safety and export structure 2025-10-07 13:29:36 +01:00
Nawaz Dhandala
b1f842f9e1 feat: enhance WhatsApp setup documentation with prerequisites and structured steps 2025-10-07 13:25:52 +01:00
Nawaz Dhandala
43e03fb61c feat: update WhatsApp icon SVG path for improved rendering 2025-10-07 13:19:29 +01:00
Nawaz Dhandala
2327ab84c2 feat: add migration for WhatsApp configuration fields in GlobalConfig 2025-10-07 13:16:19 +01:00
Nawaz Dhandala
93034b6018 refactor: update WhatsApp migration and enhance type definitions in WhatsApp settings 2025-10-07 13:10:54 +01:00
Nawaz Dhandala
e45022b5cb feat: add migration for WhatsApp notifications and related database changes 2025-10-07 13:06:47 +01:00
Nawaz Dhandala
c022b70e6d Merge branch 'whatsapp' of https://github.com/OneUptime/oneuptime into whatsapp 2025-10-07 13:06:11 +01:00
Nawaz Dhandala
5615ba2df7 Merge branch 'master' into whatsapp 2025-10-07 13:05:46 +01:00
Nawaz Dhandala
268960bc5b refactor: simplify destructuring of connection settings in getTransporter method 2025-10-07 12:58:19 +01:00
Nawaz Dhandala
508a713ecf refactor: enhance connection handling in TransporterPool for improved email server configuration 2025-10-07 12:57:43 +01:00
Simon Larsen
36e50b591a refactor: update WhatsApp template messages for improved clarity and conciseness 2025-10-07 12:17:04 +01:00
Nawaz Dhandala
05c1f95ba4 fix: enable tool-cache in release workflow for improved build efficiency 2025-10-07 11:52:13 +01:00
Simon Larsen
9d355691ae refactor: rename scheduled_maintenance_number to scheduled_event_number in WhatsApp templates and notification jobs for consistency 2025-10-07 11:32:54 +01:00
Simon Larsen
73c58186b6 refactor: enhance WhatsApp template messages with scheduled maintenance number for better context 2025-10-06 20:23:11 +01:00
Simon Larsen
eb8d3e4dfd refactor: update WhatsApp template messages for clarity and conciseness 2025-10-06 20:17:38 +01:00
Nawaz Dhandala
987f30e5c7 feat: add PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD environment variable to Dockerfiles for improved build performance 2025-10-06 19:45:46 +01:00
Simon Larsen
b7a0dbf81b refactor: replace action_link with corresponding link variables in notification templates 2025-10-06 18:25:59 +01:00
Simon Larsen
7368a0eb7c Refactor notification links in WhatsApp templates and services
- Updated variable names for links in various services to improve consistency:
  - Changed `*_link_on_dashboard` to `*_link` across multiple services including MonitorService, OnCallDutyPolicyEscalationRuleService, and UserNotificationRuleService.

- Modified WhatsApp template messages to reflect the new link variable names, ensuring that the notifications sent to users contain the correct links.

- Adjusted the link variable names in the WhatsAppTemplateUtil to match the updated naming convention.

- Ensured all related notification jobs (e.g., SendCreatedResourceNotification, SendNotePostedNotification) are updated to use the new link variables for better clarity and maintainability.
2025-10-06 18:07:39 +01:00
Nawaz Dhandala
ef0b6f3e14 refactor: replace docker login actions with retry mechanism for improved reliability 2025-10-06 16:36:28 +01:00
Simon Larsen
af8691f61d refactor: remove Meta WhatsApp API version handling and update documentation 2025-10-06 16:31:29 +01:00
Simon Larsen
f7aee2e253 feat: add Meta WhatsApp settings page and configuration options 2025-10-06 16:26:05 +01:00
Nawaz Dhandala
0a1b74d911 fix: update @simplewebauthn/server to version 13.2.2 in package.json and package-lock.json 2025-10-06 16:13:53 +01:00
Nawaz Dhandala
ab48da447d refactor: add test jobs to push-release-tags workflow for enhanced testing coverage 2025-10-06 16:08:43 +01:00
Nawaz Dhandala
1cc0630939 feat: add APP_TAG pinning to versioned release in config.env 2025-10-06 16:06:16 +01:00
Simon Larsen
5391ff4688 Add dashboard links to WhatsApp notifications for various resources
- Added `monitor_link_on_dashboard` to MonitorService notifications.
- Added `on_call_policy_link_on_dashboard` to OnCallDutyPolicyEscalationRule services.
- Added `on_call_schedule_link_on_dashboard` to OnCallDutyPolicyScheduleService.
- Added `probe_link_on_dashboard` to ProbeService notifications.
- Enhanced UserNotificationRuleService to include `alert_link_on_dashboard` and `incident_link_on_dashboard`.
- Updated WhatsApp templates to include links to the OneUptime dashboard for alerts, incidents, monitors, probes, scheduled maintenance, and status pages.
- Added `status_page_link_on_dashboard` to StatusPageOwners notifications.
2025-10-06 15:56:12 +01:00
Nawaz Dhandala
f6d96676fe refactor: update dependencies for test-e2e-release-saas job to include publish-mcp-server 2025-10-06 15:54:50 +01:00
Simon Larsen
cf02842ab1 Refactor WhatsApp message handling across services
- Updated `createWhatsAppMessageFromTemplate` to return a typed `WhatsAppMessagePayload`.
- Added type annotations for `WhatsAppTemplateId` in various services to improve type safety.
- Refactored WhatsApp message creation in `ProbeService`, `UserNotificationRuleService`, `UserNotificationSettingService`, and other worker jobs to ensure consistent typing.
- Enhanced readability and maintainability by using explicit types for event types and WhatsApp message payloads.
- Improved the structure of WhatsApp template ID definitions for better clarity and type inference.
2025-10-06 15:12:29 +01:00
Nawaz Dhandala
b63fcf6b99 refactor: update push-release-tags job dependencies for improved workflow order 2025-10-06 14:54:08 +01:00
Nawaz Dhandala
36069c1b4e refactor: update job dependencies for push-release-tags and github-release in release workflow 2025-10-06 14:48:05 +01:00
Simon Larsen
d2846decce refactor: improve code formatting and readability across multiple files 2025-10-06 14:47:15 +01:00
Simon Larsen
60a8a3f052 feat: include alert and incident identifiers in SMS notifications for better context 2025-10-06 14:45:46 +01:00
Simon Larsen
e2d15dc2e7 Merge branch 'master' of github.com:OneUptime/oneuptime into whatsapp 2025-10-06 14:39:00 +01:00
Simon Larsen
7cdefdeccd feat: add incident and alert numbers to WhatsApp notification templates and related services 2025-10-06 14:37:45 +01:00
Simon Larsen
684b8822af feat: simplify WhatsApp template messages for clarity and user engagement 2025-10-06 14:20:52 +01:00
Nawaz Dhandala
231bc47942 refactor: improve type annotations and formatting in TeamService for clarity 2025-10-06 14:14:11 +01:00
Nawaz Dhandala
965a497be3 feat: implement SCIM mutation checks for team creation and deletion 2025-10-06 14:12:19 +01:00
Nawaz Dhandala
f50a7fb99b refactor: adjust job dependencies and increase timeout for E2E tests in release workflows 2025-10-06 14:08:50 +01:00
Simon Larsen
50a5e75d1a feat: enhance WhatsApp template messages with additional information for user guidance 2025-10-06 14:00:01 +01:00
Simon Larsen
84e838a055 refactor: streamline WhatsApp message creation by removing unused template string imports 2025-10-04 13:49:12 +01:00
Simon Larsen
6d6c78e974 feat: Integrate WhatsApp notifications for various alert and incident events
- Added WhatsApp message creation for alert owner notifications in SendCreatedResourceNotification, SendNotePostedNotification, SendOwnerAddedNotification, and SendStateChangeNotification jobs.
- Implemented WhatsApp message functionality for incident owner notifications in SendCreatedResourceNotification, SendNotePostedNotification, SendOwnerAddedNotification, and SendStateChangeNotification jobs.
- Enhanced monitor owner notifications with WhatsApp messages in SendCreatedResourceNotification, SendOwnerAddedNotification, and SendStatusChangeNotification jobs.
- Included WhatsApp message creation for scheduled maintenance owner notifications in SendCreatedResourceNotification, SendNotePostedNotification, SendOwnerAddedNotification, and SendStateChangeNotification jobs.
- Added WhatsApp message functionality for status page owner notifications in SendAnnouncementCreatedNotification, SendCreatedResourceNotification, and SendOwnerAddedNotification jobs.
- Introduced WhatsAppTemplateUtil to manage WhatsApp message templates and creation logic.
2025-10-04 13:22:56 +01:00
Simon Larsen
778d5b7c6b feat: add UserWhatsAppService and integrate WhatsApp verification code template 2025-10-03 19:25:53 +01:00
Nawaz Dhandala
8051146f41 refactor: enhance type safety and improve variable naming in OnCallDutyScheduleSettings 2025-10-03 19:19:46 +01:00
Simon Larsen
86a359a230 feat: enhance WhatsApp notification handling with template support and error logging 2025-10-03 19:17:10 +01:00
Simon Larsen
c16dac65cc feat: add WhatsApp template IDs and rendering logic for notifications 2025-10-03 19:16:04 +01:00
Simon Larsen
437c9ecdbc feat: add support for WhatsApp notifications in project and user notification settings 2025-10-03 19:04:33 +01:00
Nawaz Dhandala
bf4eec2bdf refactor: improve code formatting and comments for better readability in SCIM and TimePicker components 2025-10-03 19:00:49 +01:00
Nawaz Dhandala
08367f3c7f refactor: update onDuplicateSuccess type to support Promise and implement duplication logic in OnCallDutyScheduleSettings 2025-10-03 18:23:29 +01:00
Simon Larsen
f5d077956a feat: integrate UserWhatsApp into notification settings and management 2025-10-03 18:12:07 +01:00
Simon Larsen
ca74005262 feat: add WhatsApp phone display in NotificationMethodView and create WhatsApp management component 2025-10-03 18:11:10 +01:00
Simon Larsen
52c936935e feat: add UserWhatsApp relation and ID to UserOnCallLogTimeline model 2025-10-03 17:51:34 +01:00
Simon Larsen
2951600ed9 feat: add UserWhatsApp relation and ID to UserNotificationRule model 2025-10-03 17:51:15 +01:00
Simon Larsen
d12c8c778c feat: Add UserWhatsApp and WhatsAppLog models with associated services
- Created UserWhatsApp model to manage WhatsApp numbers linked to users and projects.
- Implemented WhatsAppLog model to log messages sent via WhatsApp, including details like recipient, status, and associated incidents or alerts.
- Developed WhatsAppLogService for managing WhatsApp log entries, including automatic deletion of old logs if billing is enabled.
- Introduced WhatsAppService for sending WhatsApp messages with various contextual options.
2025-10-03 17:28:31 +01:00
Simon Larsen
77d4527a00 feat: add WhatsApp integration with API and configuration support 2025-10-03 17:24:59 +01:00
Nawaz Dhandala
1ef3353155 fix: update modelId retrieval to correctly use parameter for OnCallDutyScheduleSettings 2025-10-03 17:11:04 +01:00
Nawaz Dhandala
2c635c0d1e refactor: add modulePathIgnorePatterns to jest config for build directory 2025-10-03 16:17:45 +01:00
Nawaz Dhandala
44799f4625 Merge branch 'master' of https://github.com/OneUptime/oneuptime into timepkr 2025-10-03 15:39:38 +01:00
Nawaz Dhandala
4bc6e625d2 refactor: adjust spacing for timezone label display in TimePicker component 2025-10-03 15:38:49 +01:00
Nawaz Dhandala
9ff773dd81 refactor: update timezone label display in TimePicker component for improved clarity 2025-10-03 15:37:09 +01:00
Nawaz Dhandala
bf2c2afbb8 refactor: simplify browser locale detection for 12-hour format and enhance timezone label display 2025-10-03 15:01:26 +01:00
Simon Larsen
3efa3b374f feat: add push-release-tags job to create Docker release tags after GitHub release 2025-10-03 14:59:29 +01:00
Nawaz Dhandala
f76b004e2a refactor: implement browser locale detection for 12-hour time format preference 2025-10-03 14:55:47 +01:00
Nawaz Dhandala
cb535bd114 refactor: add type annotations for improved type safety in TimePicker component 2025-10-03 14:45:56 +01:00
Simon Larsen
9b09082d13 feat: add settings page for on-call duty schedule with duplication functionality 2025-10-03 14:37:20 +01:00
Nawaz Dhandala
5ac6e7ba7b refactor: improve code readability in Input and TimePicker components 2025-10-03 14:32:51 +01:00
Nawaz Dhandala
044183dbd7 refactor: enhance TimePicker input size and icon styling for improved usability 2025-10-03 14:27:23 +01:00
Nawaz Dhandala
fb13609c37 refactor: add margin to TimePicker component for improved layout 2025-10-03 14:23:36 +01:00
Nawaz Dhandala
1c602b1ad3 refactor: adjust TimePicker input size and improve clickability indication 2025-10-03 14:18:52 +01:00
Nawaz Dhandala
1affb76085 refactor: update TimePicker component layout and styling for improved usability 2025-10-03 14:16:40 +01:00
Nawaz Dhandala
0e02083dec refactor: implement modal for time selection in TimePicker component 2025-10-03 14:13:51 +01:00
Nawaz Dhandala
a442b02337 refactor: update TimePicker import path to use the correct index file 2025-10-03 14:07:33 +01:00
Simon Larsen
3ab47328f6 refactor: enhance SCIM group schema compatibility by including SCIM 1.1 core schema 2025-10-03 14:01:42 +01:00
Nawaz Dhandala
57ff8c007b refactor: integrate TimePicker component for time selection in FormField and adjust Input spellCheck logic 2025-10-03 13:59:30 +01:00
Nawaz Dhandala
c83d1babcd refactor: update jest configuration to support TypeScript and improve coverage collection 2025-10-03 13:54:50 +01:00
Simon Larsen
1bc96d04fa refactor: enhance artifact naming in release workflows to include job and run attempt 2025-10-03 13:51:52 +01:00
Nawaz Dhandala
e03a9b52ae refactor: remove InputType.TIME usage and implement TimePicker component for time selection 2025-10-03 13:43:53 +01:00
Simon Larsen
a307a68ec1 refactor: implement retry logic for E2E tests in release workflows 2025-10-03 13:36:19 +01:00
Nawaz Dhandala
1032f01278 refactor: enhance query execution logic to handle query parameters more effectively 2025-10-02 19:43:52 +01:00
Nawaz Dhandala
83286aa34d refactor: remove maxmemory-policy from redis config and set to noeviction in values.yaml 2025-10-02 19:31:53 +01:00
Nawaz Dhandala
543757a2b5 refactor: update helm template command to specify chart directory for improved clarity 2025-10-02 16:46:04 +01:00
Nawaz Dhandala
d0bbb12f92 refactor: improve formatting and readability of Microsoft Teams installation instructions 2025-10-02 16:44:40 +01:00
Nawaz Dhandala
066e785a53 refactor: add Microsoft Teams navigation links and integration documentation 2025-10-02 15:15:38 +01:00
Nawaz Dhandala
2f46eadcd4 refactor: add call scheduling feature with inline calendar integration to support page 2025-10-02 15:00:32 +01:00
Nawaz Dhandala
c472555f55 refactor: update installation instructions to include app approval status for Microsoft Teams integration 2025-10-02 14:56:30 +01:00
Nawaz Dhandala
83c9255b98 refactor: enhance Microsoft Teams integration with billing conditionals and installation instructions 2025-10-02 14:47:54 +01:00
Nawaz Dhandala
1748a198c7 refactor: update Microsoft Teams permissions documentation for clarity and conciseness 2025-10-02 14:42:35 +01:00
Nawaz Dhandala
a4841f4b6e refactor: remove ts-ignore and update axios mock type for improved type safety 2025-10-02 13:15:57 +01:00
Nawaz Dhandala
1c750d274e refactor: replace ts-ignore with ts-expect-error for improved type safety in Handlebars helpers and test mocks 2025-10-02 12:18:10 +01:00
Nawaz Dhandala
2dda68c462 refactor: update comment styles for consistency across ProjectAPI, DataPoint, and ComponentCode 2025-10-02 11:57:39 +01:00
Nawaz Dhandala
6d5bc111ba Refactor comments across multiple files to improve clarity and consistency
- Updated comments in Probe/Config.ts to use block comments for proxy configuration.
- Refactored comments in PortMonitor.ts, SyntheticMonitor.ts, and OnlineCheck.ts to block comments for better readability.
- Adjusted comments in ProbeIngest/API/Monitor.ts and ProbeIngest/API/Probe.ts to block comments for clarity.
- Standardized comments in various data migration scripts to block comments for consistency.
- Modified eslint.config.js to enforce multiline comment style as an error.
2025-10-02 11:53:55 +01:00
Nawaz Dhandala
0e1c8df7ab refactor: simplify logging and formatting in Microsoft Teams actions 2025-10-02 11:40:47 +01:00
Nawaz Dhandala
4b55cb3d84 feat: refine incident action handling to improve clarity and flow 2025-10-02 11:36:45 +01:00
Nawaz Dhandala
eb66b57939 feat: prevent duplicate message processing for new incident and scheduled maintenance submissions 2025-10-02 11:33:53 +01:00
Nawaz Dhandala
b53119d249 feat: implement separate handling for new scheduled maintenance creation in Microsoft Teams 2025-10-02 11:32:24 +01:00
Nawaz Dhandala
95c2db5ace feat: streamline incident and scheduled maintenance confirmation by sending messages after hiding form cards 2025-10-02 11:23:41 +01:00
Nawaz Dhandala
8c4bc48c44 feat: add incident and scheduled maintenance links in response messages 2025-10-02 11:18:56 +01:00
Nawaz Dhandala
28f3b98d44 feat: implement new incident and scheduled maintenance submission handling in Microsoft Teams 2025-10-02 11:13:31 +01:00
Nawaz Dhandala
742da27d87 feat: add commands for creating new incidents and scheduled maintenance in Microsoft Teams 2025-10-02 10:55:28 +01:00
Nawaz Dhandala
e2ba7dff8d refactor: update KEDA autoscaling configuration comments for clarity 2025-10-02 09:25:47 +01:00
Simon Larsen
3f6a58a087 Merge pull request #2024 from calvinbui/master
helm: allow removing the auto-generated date label
2025-10-02 09:25:07 +01:00
Calvin Bui
3f2005bd34 fix jinja 2025-10-02 11:38:16 +10:00
Calvin Bui
651ba4247e fix: remove auto-generated date label causing constant updates 2025-10-02 11:36:07 +10:00
Nawaz Dhandala
ba71cf5980 fix: Remove system status command from Microsoft Teams bot responses 2025-10-01 20:57:55 +01:00
Nawaz Dhandala
442a4b935b feat: Enhance incident and maintenance messages with severity icons and dashboard links 2025-10-01 20:52:39 +01:00
Nawaz Dhandala
5caf5e8991 fix: Update command list formatting in bot help message for consistency 2025-10-01 20:50:00 +01:00
Nawaz Dhandala
b5e4545193 fix: Simplify conditional check for TOTP and WebAuthn lists in login function 2025-10-01 20:38:01 +01:00
Nawaz Dhandala
ce4cc70815 refactor: Improve type annotations for error handling and channel name mapping in WorkspaceNotificationRuleService 2025-10-01 20:32:19 +01:00
Nawaz Dhandala
426dda60fe refactor: Enhance two-factor authentication verification logic and improve placeholder formatting in NotificationRuleForm 2025-10-01 20:28:18 +01:00
Nawaz Dhandala
c6be5a9ebf fix: Update placeholder text for existing channel input based on workspace type in NotificationRuleForm 2025-10-01 20:21:33 +01:00
Nawaz Dhandala
eb19b8926b docs: Update setup instructions for Microsoft Teams integration 2025-10-01 18:29:21 +01:00
Nawaz Dhandala
955a3f784d refactor: Remove duplicate code for handling Adaptive Card submits in MicrosoftTeamsUtil 2025-10-01 18:25:11 +01:00
Nawaz Dhandala
756dc88289 refactor: Simplify error message mapping and improve readability in WorkspaceNotificationRuleService 2025-10-01 18:12:08 +01:00
Nawaz Dhandala
c116f9adc1 refactor: Update existing channel handling to use WorkspaceChannel objects and include teamId for Microsoft Teams integration 2025-10-01 18:07:36 +01:00
Nawaz Dhandala
324f29edc3 fix: Improve error messages for missing teamId in Microsoft Teams channel resolution and message sending 2025-10-01 17:56:38 +01:00
Nawaz Dhandala
03064308ef feat: Add teamId to WorkspaceChannel interface and update MicrosoftTeamsUtil to include teamId in channel creation 2025-10-01 14:11:59 +01:00
Nawaz Dhandala
9dd4ac6f6b feat: Add error handling for message sending in Microsoft Teams and Slack integrations 2025-10-01 14:08:29 +01:00
Nawaz Dhandala
8b8f1ba530 fix: Ensure teamId is required for resolving channel names and sending messages in Microsoft Teams 2025-10-01 14:02:47 +01:00
Nawaz Dhandala
31e77d2208 feat: Add optional teamId to WorkspaceMessagePayload for Microsoft Teams integration 2025-10-01 13:53:38 +01:00
Nawaz Dhandala
c6e78a3264 fix: Update Buffer handling to use Uint8Array and ArrayBuffer for improved type safety 2025-10-01 12:51:16 +01:00
Nawaz Dhandala
c474d3b1e5 chore: update eslint-plugin-react to version 7.37.5 2025-09-30 20:30:54 +01:00
Nawaz Dhandala
3afbbfae5a fix: Update schema to allow null values for various string and object properties 2025-09-30 20:12:33 +01:00
Nawaz Dhandala
92c3c619ee refactor: Clean up code formatting and improve readability in Microsoft Teams components 2025-09-30 19:58:52 +01:00
Nawaz Dhandala
b65e28684e fix: Improve KEDA autoscaler condition checks for probes and enhance values.yaml structure 2025-09-30 19:53:51 +01:00
Nawaz Dhandala
dabf1464f2 fix: Update nodeSelector handling in multiple deployment templates for improved clarity and consistency 2025-09-30 19:33:51 +01:00
Nawaz Dhandala
9f618acc31 fix: Refactor security context handling for pods and containers to improve clarity and maintainability 2025-09-30 19:27:32 +01:00
Nawaz Dhandala
3dd4caeae9 feat: Update security context handling for various deployments 2025-09-30 19:23:18 +01:00
Nawaz Dhandala
1345693175 feat: Add pod and container security context support for PostgreSQL, ClickHouse, and Redis 2025-09-30 18:21:54 +01:00
Nawaz Dhandala
b5a422e8aa fix: Change oneuptimeSecret type from object to string and adjust encryptionSecret definition 2025-09-30 18:16:56 +01:00
Nawaz Dhandala
122773b0ba fix: Update comment for oneuptimeSecret to clarify string requirement 2025-09-30 18:16:16 +01:00
Nawaz Dhandala
cfc1d5d820 Merge branch 'master' of https://github.com/OneUptime/oneuptime 2025-09-30 18:12:14 +01:00
Nawaz Dhandala
18d1df86d5 feat: Add pod and container security context support across deployments
- Updated deployment templates to merge podSecurityContext and containerSecurityContext from values.
- Enhanced the values schema and default values to include podSecurityContext and containerSecurityContext for various services.
- Ensured that security contexts are applied consistently across all relevant templates including accounts, admin-dashboard, api-reference, app, dashboard, docs, fluent-ingest, home, incoming-request-ingest, isolated-vm, nginx, open-telemetry-ingest, otel-collector, probe-ingest, server-monitor-ingest, status-page, test-server, worker, and workflow.
2025-09-30 18:12:11 +01:00
Nawaz Dhandala
4b65366080 feat: Merge nodeSelector values for various deployments in Helm templates 2025-09-30 17:52:19 +01:00
Nawaz Dhandala
74bb6acd62 feat: Add resources and nodeSelector fields to various components in values.yaml and values.schema.json 2025-09-30 17:47:06 +01:00
Simon Larsen
a47b0fe21d Merge pull request #2023 from calvinbui/master
helm: add deployment update strategy
2025-09-30 17:43:30 +01:00
Nawaz Dhandala
349e64e3a2 Merge branch 'yubikey-auth' 2025-09-30 17:14:39 +01:00
Nawaz Dhandala
0f64b49f9c refactor: Clean up code formatting and improve readability in various files 2025-09-30 17:14:23 +01:00
Nawaz Dhandala
1f8d4967ee refactor: Improve logging for email verification process 2025-09-30 17:07:44 +01:00
Nawaz Dhandala
e8b580ab4c refactor: Ensure TOTP and WebAuthn lists are always returned as arrays in fetchTotpAuthList 2025-09-30 17:04:32 +01:00
Nawaz Dhandala
866183d95a refactor: Rename two-factor authentication API endpoints to use TOTP terminology 2025-09-30 17:00:24 +01:00
Nawaz Dhandala
ca64843de0 refactor: Add validation for email and password in login function 2025-09-30 16:50:18 +01:00
Calvin Bui
d7427b9abe update values.schema.json 2025-09-30 23:43:05 +10:00
Calvin Bui
77537999b0 add deployment update strategy 2025-09-30 23:24:17 +10:00
Nawaz Dhandala
263c341792 refactor: Update login function to handle multiple two-factor authentication methods 2025-09-30 13:47:00 +01:00
Nawaz Dhandala
45b1dcbb7e refactor: Update WebAuthn verification API to use initial values and remove unused endpoint 2025-09-30 13:38:20 +01:00
Nawaz Dhandala
43e344dfb1 refactor: Update login function to check for both TOTP and WebAuthn verification 2025-09-30 13:34:20 +01:00
Nawaz Dhandala
e5b2e70ce2 refactor: Rename verifyTwoFactorAuth to verifyTotpAuth for consistency 2025-09-30 13:31:38 +01:00
Nawaz Dhandala
602383a720 refactor: Rename UserTwoFactorAuth table to UserTotpAuth in migration 2025-09-30 13:18:28 +01:00
Nawaz Dhandala
c10e691bf5 refactor: Remove UserTwoFactorAuth model and service in favor of TotpAuth implementation 2025-09-30 13:15:09 +01:00
Nawaz Dhandala
ab7c8c1df9 feat: Add UserWebAuthnAPI routes for authentication verification and update API paths 2025-09-30 13:13:45 +01:00
Nawaz Dhandala
72236b025f refactor: replace TwoFactorAuth with TotpAuth and update related implementations 2025-09-30 13:08:58 +01:00
Nawaz Dhandala
1c5c9ee3ad refactor: update UserWebAuthnAPI and UserWebAuthnService for improved type definitions and clarity 2025-09-30 13:06:46 +01:00
Nawaz Dhandala
352c923e74 refactor: rename UserTwoFactorAuth to UserTotpAuth and update related services, APIs, and models
- Replaced all instances of UserTwoFactorAuth with UserTotpAuth across the codebase.
- Updated API endpoints to reflect the new naming convention.
- Modified database models and services to accommodate the changes.
- Adjusted frontend components to utilize the new UserTotpAuth model.
- Ensured all references, imports, and exports are consistent with the new naming.
2025-09-30 13:02:32 +01:00
Nawaz Dhandala
d3ebbf1c88 feat: Add migration to remove two-factor authentication columns from User table 2025-09-30 12:51:09 +01:00
Simon Larsen
411a455d54 Merge branch 'yubikey-auth' of github.com:OneUptime/oneuptime into yubikey-auth 2025-09-30 12:47:44 +01:00
Nawaz Dhandala
4570d617b2 feat: Implement WebAuthn authentication verification and update login function to support multiple verification methods 2025-09-30 12:46:19 +01:00
Nawaz Dhandala
305094a8b2 feat: Refactor UserWebAuthnAPI and UserWebAuthnService to utilize service methods for registration and authentication options generation 2025-09-30 12:43:13 +01:00
Simon Larsen
b02d1da202 refactor: Simplify master admin status assignment in LoginUtil 2025-09-30 12:29:43 +01:00
Simon Larsen
1407a0fce9 feat: Replace loading spinner and error message with reusable components in LoginPage 2025-09-30 11:58:31 +01:00
Simon Larsen
836fb91cbe refactor: Update terminology to "Security Key-Based Two-Factor Authentication" for clarity and consistency 2025-09-30 11:55:07 +01:00
Simon Larsen
4c819ca906 feat: Move "Add Security Key" button to the right side of the security keys table for improved UI layout 2025-09-30 11:52:57 +01:00
Simon Larsen
3bd7fb7c59 refactor: Update terminology to "Authenticator Based Two Factor Authentication" for clarity and consistency 2025-09-30 11:51:38 +01:00
Simon Larsen
99e7193961 feat: Integrate Base64 encoding for WebAuthn challenge and credential handling in UserWebAuthnAPI and LoginPage 2025-09-30 11:49:23 +01:00
Simon Larsen
db10bba4d3 feat: Implement Base64 utility functions and integrate them into WebAuthn registration process 2025-09-30 11:47:48 +01:00
Simon Larsen
31a425d34d fix: Ensure security keys are always verified by default in UserWebAuthnService 2025-09-30 11:31:54 +01:00
Simon Larsen
7870406295 feat: Integrate WebAuthn verification in two-factor authentication checks 2025-09-30 11:31:40 +01:00
Simon Larsen
77de0a1116 feat: Upgrade Node.js base image to version 24.9-alpine3.21 in multiple Dockerfiles and remove debugging flag from nodemon configurations 2025-09-30 11:27:03 +01:00
Simon Larsen
f2da31a6f9 feat: Update package-lock.json to add new dependencies for testing and TypeScript 2025-09-29 21:40:34 +01:00
Simon Larsen
d36577069f feat: Add UserWebAuthn migration for WebAuthn credential management 2025-09-29 20:54:24 +01:00
Simon Larsen
4cdf959a01 fix: Update channel name comparison logic to use displayName for accurate matching 2025-09-29 20:21:12 +01:00
Simon Larsen
62adb3fd76 fix: Ensure team selection is required for Microsoft Teams integration in notification rules 2025-09-29 20:13:56 +01:00
Simon Larsen
5bc6e67c21 refactor: Enhance button styles and update team item display in TeamsAvailableModal 2025-09-29 20:07:13 +01:00
Simon Larsen
d7e86a56e6 refactor: Remove search functionality and simplify team list display in TeamsAvailableModal 2025-09-29 19:56:19 +01:00
Simon Larsen
c2b569c13a feat: Implement TeamsAvailableModal for improved team selection in Microsoft Teams integration 2025-09-29 19:41:06 +01:00
Simon Larsen
6d6555396a fix: Correct API URL handling in Microsoft Teams integration 2025-09-29 19:19:42 +01:00
Simon Larsen
13018c8169 refactor: Update API URL handling for Microsoft Teams integration 2025-09-29 19:14:53 +01:00
Simon Larsen
82f462785b feat: Add modal to display and refresh Microsoft Teams list in integration 2025-09-29 19:08:44 +01:00
Simon Larsen
9f21725949 refactor: Simplify teams retrieval by removing redundant checks and updating refresh logic 2025-09-29 17:37:19 +01:00
Nawaz Dhandala
82bee44933 Refactor Microsoft Teams integration code for improved type safety and clarity
- Added type annotations for various variables and constants in Incident, Monitor, ScheduledMaintenance, and MicrosoftTeams actions.
- Enhanced type definitions for JSON-related imports and improved handling of JSON values.
- Updated methods to ensure consistent use of types across the Microsoft Teams integration.
- Refactored message formatting in incident and monitor details to explicitly define message types.
- Improved readability and maintainability of the code by restructuring some conditional statements and variable declarations.
- Ensured proper handling of project authentication and access tokens with clearer logging and error handling.
2025-09-29 17:22:05 +01:00
Nawaz Dhandala
b67c702d4d Refactor Microsoft Teams integration components and improve code readability
- Removed unnecessary blank lines in Workspace.ts and MicrosoftTeamsIntegration.tsx.
- Reformatted function parameters for better readability in WorkspaceType.ts.
- Simplified imports in MicrosoftTeamsIntegration.tsx and NotificationRuleForm.tsx.
- Enhanced conditional checks for better clarity in NotificationRuleForm.tsx and NotificationRuleViewElement.tsx.
- Improved formatting and consistency in MicrosoftTeamsIntegrationDocumentation.tsx.
- Updated state management and conditional rendering in WorkspaceNotificationRulesTable.tsx.
- Ensured consistent use of line breaks and indentation across various components for improved maintainability.
2025-09-29 16:59:33 +01:00
Simon Larsen
e5017908ae Merge pull request #2006 from OneUptime/v4-ms-teams
feat: Add Microsoft Teams integration with configuration and action t…
2025-09-29 16:58:25 +01:00
Simon Larsen
eff87e1705 feat: Implement method to retrieve user's joined teams in Microsoft Teams integration 2025-09-29 16:50:27 +01:00
Simon Larsen
9fabdbbb2b feat: Add method to refresh teams list for a user in Microsoft Teams integration 2025-09-29 16:43:48 +01:00
Simon Larsen
56908674bb feat: Add endpoint to refresh teams list in Microsoft Teams API 2025-09-29 16:43:02 +01:00
Simon Larsen
9fe3fb041e feat: Add refresh teams functionality and loading state in Microsoft Teams integration 2025-09-29 16:35:19 +01:00
Simon Larsen
46d3bf527b feat: Update team selection titles and labels in NotificationRuleForm for clarity 2025-09-29 16:28:30 +01:00
Simon Larsen
06e11aa8d7 feat: Update card title for admin consent status in Microsoft Teams integration 2025-09-29 16:23:58 +01:00
Simon Larsen
acd9a87694 feat: Update card title for manual app installation prompt in Microsoft Teams 2025-09-29 16:21:42 +01:00
Simon Larsen
9a4f799145 feat: Remove channelCache from MicrosoftTeamsMiscData interface 2025-09-29 15:29:45 +01:00
Simon Larsen
edd067f79f feat: Add tenantId handling in Microsoft Teams request and auth token retrieval 2025-09-29 14:45:20 +01:00
Simon Larsen
36b6b8423a feat: Simplify Microsoft Teams data loading by removing unnecessary try-catch block 2025-09-29 14:41:01 +01:00
Simon Larsen
81c558dc21 feat: Refactor Microsoft Teams integration to use MicrosoftTeamsTeam type for improved type safety 2025-09-29 14:38:18 +01:00
Simon Larsen
a23d585ec6 feat: Update teamId handling in Microsoft Teams channel existence check 2025-09-29 14:32:27 +01:00
Simon Larsen
c193bd71d7 feat: Replace SlackMiscData with WorkspaceMiscData in refreshAuthToken method 2025-09-29 14:27:36 +01:00
Simon Larsen
b1791602c8 feat: Define WorkspaceMiscData type to unify Slack and Microsoft Teams miscellaneous data structures 2025-09-29 14:26:40 +01:00
Simon Larsen
e98059e4ee feat: Add optional teamId parameter to workspace channel methods for improved Microsoft Teams integration 2025-09-29 14:26:32 +01:00
Simon Larsen
371ba8f414 feat: Enhance Microsoft Teams integration by adding teamId support and fetching available teams 2025-09-29 14:20:19 +01:00
Simon Larsen
a271ba2cd9 feat: Add MicrosoftTeamsTeam interface and availableTeams property to MicrosoftTeamsMiscData 2025-09-29 14:10:26 +01:00
Simon Larsen
a337065c4f feat: Remove unused imports from MicrosoftTeamsIntegration component 2025-09-29 13:42:47 +01:00
Simon Larsen
22479a6f9e feat: Add teamId support for notification channels and update related interfaces 2025-09-29 13:41:56 +01:00
Simon Larsen
29051c3010 feat: Simplify Microsoft Teams integration by removing team selection logic and updating connection messages 2025-09-29 13:40:36 +01:00
Simon Larsen
aaa29c87ca feat: Rename microsoftTeams prop to microsoftTeamsTeams for clarity 2025-09-29 13:38:46 +01:00
Simon Larsen
0385dc7ac8 feat: Add Microsoft Teams team selection for existing and new channel creation in notification rules 2025-09-29 13:38:31 +01:00
Simon Larsen
d55e354a07 feat: Update instructions for building and compiling with proper formatting and clarity 2025-09-29 13:35:08 +01:00
Nawaz Dhandala
20716b7c7e feat: Refactor WebAuthn integration in login and user management components for improved readability and maintainability 2025-09-29 13:07:48 +01:00
Nawaz Dhandala
86143d1585 feat: Add WebAuthn support to the login page for enhanced two-factor authentication 2025-09-29 13:01:57 +01:00
Nawaz Dhandala
214915528b feat: Implement UserWebAuthn model and API for WebAuthn credential management 2025-09-29 13:00:52 +01:00
Nawaz Dhandala
9b24ff50ec feat: Enhance two-factor authentication by integrating WebAuthn support and updating fetch function to return webAuthnList 2025-09-29 12:55:33 +01:00
Nawaz Dhandala
9caeb34f63 feat: Add WebAuthn support for two-factor authentication
- Introduced new API paths for generating and verifying WebAuthn authentication options.
- Integrated UserWebAuthnAPI into the BaseAPI feature set.
- Added UserWebAuthn model to the database models.
- Implemented UserWebAuthnService for handling WebAuthn-related database operations.
- Updated the User Profile page to include functionality for managing WebAuthn security keys.
- Added UI components for registering and displaying WebAuthn security keys.
- Included necessary dependencies for WebAuthn functionality in package.json and package-lock.json.
2025-09-29 12:54:44 +01:00
Simon Larsen
368f33db24 feat: Enhance bot message handling by checking for direct messages and mentions 2025-09-29 11:40:26 +01:00
Simon Larsen
5d7a18cbe2 feat: Integrate getWorkspaceTypeDisplayName for improved workspace type display in notification rules 2025-09-29 11:21:25 +01:00
Simon Larsen
19f663d0fd feat: Simplify form card hiding by using deleteActivity method in Microsoft Teams actions 2025-09-29 11:16:49 +01:00
Simon Larsen
d857024fbe feat: Update activity text to ensure proper form card hiding in Microsoft Teams actions 2025-09-29 10:51:45 +01:00
Simon Larsen
027d766e03 feat: Hide form card after adding notes and executing actions in Microsoft Teams alert, incident, and scheduled maintenance actions 2025-09-29 10:49:19 +01:00
Simon Larsen
e7599c2202 feat: Add null handling for on-call policy cards in MicrosoftTeamsAlertActions and MicrosoftTeamsIncidentActions 2025-09-29 10:42:12 +01:00
Simon Larsen
703b525310 feat: Enhance Microsoft Teams actions with new incident and alert functionalities, including viewing and submitting notes, executing on-call policies, and changing states 2025-09-29 09:52:27 +01:00
Simon Larsen
534882bc17 feat: Add new incident note actions for viewing and submitting notes in MicrosoftTeamsIncidentActionType 2025-09-27 13:12:05 +01:00
Simon Larsen
bdb2170663 refactor: Consolidate incident action handling into MicrosoftTeamsIncidentActions class 2025-09-27 13:04:24 +01:00
Simon Larsen
dffb11b304 fix: Correct casing for incident action type values in MicrosoftTeamsIncidentActionType enum 2025-09-27 12:44:51 +01:00
Simon Larsen
4e5386fccf fix: Normalize incident action type values and improve logging in MicrosoftTeamsUtil 2025-09-27 12:09:01 +01:00
Simon Larsen
6c11fbf850 fix: Remove fallback text for accessibility in adaptive card message handling 2025-09-27 11:50:08 +01:00
Simon Larsen
f713eb7546 fix: Improve error handling for missing AAD Object ID in Teams bot invoke activity 2025-09-27 11:22:24 +01:00
Simon Larsen
0d1f07b5ae feat: Add method to extract action type and value from Teams Adaptive Card submits 2025-09-27 11:15:38 +01:00
Simon Larsen
ffcaaf213f fix: Simplify action type mapping in MicrosoftTeamsUtil and improve logging 2025-09-27 11:08:25 +01:00
Simon Larsen
b05a0619fb feat: Enhance MicrosoftTeamsUtil to support adaptive card actions and improve message handling 2025-09-27 10:59:20 +01:00
Simon Larsen
cbd4d26189 feat: Add helm template command to generate Kubernetes manifests in release workflow 2025-09-27 10:30:06 +01:00
Simon Larsen
1f24a79a8a fix: Update JSON schema to include commonConfiguration and allow additional properties for cert-manager 2025-09-27 10:24:03 +01:00
Simon Larsen
94227a103d feat: Add comprehensive JSON schema for OneUptime Helm chart configuration, defining properties for various components including global settings, database configurations, and service parameters. 2025-09-27 10:20:22 +01:00
Simon Larsen
cd1bf5befe fix: Enhance markdown handling in MicrosoftTeamsUtil to clean up links and bold markers for better rendering 2025-09-26 18:02:22 +01:00
Simon Larsen
e50e75b009 fix: Replace LIMIT_PER_PROJECT with a fixed limit of 10 for query results in MicrosoftTeams utility 2025-09-26 17:50:13 +01:00
Simon Larsen
9656fbdae4 feat: Enhance Microsoft Teams bot with new commands for active incidents, scheduled maintenance, ongoing maintenance, and active alerts 2025-09-26 17:45:24 +01:00
Simon Larsen
1004251175 fix: Update Microsoft Teams app type to single-tenant and adjust bot adapter initialization for tenant-specific handling 2025-09-26 15:08:53 +01:00
Simon Larsen
5c70aea851 fix: Update import for ConfigurationBotFrameworkAuthenticationOptions and type definition for authConfig in MicrosoftTeamsUtil 2025-09-26 15:02:51 +01:00
Simon Larsen
25d5cc2a47 refactor: Remove HomeClientUrl export from EnvironmentConfig for code clarity 2025-09-26 14:38:40 +01:00
Simon Larsen
b6802bf949 Merge branch 'master' into v4-ms-teams 2025-09-26 14:23:46 +01:00
Simon Larsen
5af14af52a feat: Add EnableWorkflow decorator to OnCallDutyPolicy models for enhanced access control 2025-09-26 14:20:47 +01:00
Nawaz Dhandala
fffe84526e refactor: Clean up logging statements in ScheduledMaintenanceService.ts for improved clarity 2025-09-25 19:46:39 +01:00
Simon Larsen
e776186070 feat: Enhance logging for scheduled maintenance notifications with detailed debug information 2025-09-25 19:45:51 +01:00
Nawaz Dhandala
0f4f974d04 refactor: Remove unnecessary blank lines in SCIM.ts and TeamMemberService.ts for improved code clarity 2025-09-25 19:35:41 +01:00
Simon Larsen
22ecea6381 Merge branch 'master' of github.com:OneUptime/oneuptime 2025-09-25 19:32:22 +01:00
Simon Larsen
d9ad2e3036 refactor: Remove ignoreHooks property from team member operations and adjust SCIM checks for root users 2025-09-25 19:32:19 +01:00
Nawaz Dhandala
42e60213c6 refactor: Improve code formatting and readability in SCIM.ts 2025-09-25 19:22:27 +01:00
Simon Larsen
6817a0759a feat: Add enablePushGroups option to SCIM configuration for enhanced group management 2025-09-25 19:21:49 +01:00
Nawaz Dhandala
963e2ffc6d refactor: Update SCIM check function signature and type annotations in TeamView and Users components 2025-09-25 16:36:25 +01:00
Nawaz Dhandala
5c2c50ecc6 refactor: Improve code formatting and readability in ScheduledMaintenanceService, TeamMemberService, TeamView, and Users components 2025-09-25 16:32:38 +01:00
Simon Larsen
1bb4e77075 Merge branch 'scim-push' 2025-09-25 16:26:30 +01:00
Simon Larsen
1f22c231d6 feat: Update SCIM error modal title for clarity on user management 2025-09-25 15:21:00 +01:00
Simon Larsen
4b3baa9ad3 feat: Add SCIM error modal to prevent user invitations when SCIM is enabled 2025-09-25 15:14:07 +01:00
Simon Larsen
503728345f feat: Implement SCIM checks in TeamView and Teams to restrict member invitations and deletions when SCIM is enabled 2025-09-25 15:11:19 +01:00
Nawaz Dhandala
958b6bf72c fix: Improve notification settings handling for scheduled maintenance updates 2025-09-25 14:40:27 +01:00
Simon Larsen
6bb5ec12f5 feat: Implement SCIM checks in TeamMemberService to prevent member invitations and deletions when SCIM is enabled 2025-09-25 14:23:30 +01:00
Simon Larsen
30b2b63b9b feat: Enhance user creation process in SCIM by integrating auto-provisioning and team assignment logic 2025-09-25 13:56:37 +01:00
Simon Larsen
6c37290f49 feat: Refactor user existence checks in SCIM team operations for improved clarity and efficiency 2025-09-25 13:26:30 +01:00
Nawaz Dhandala
b19302f8b9 feat: Refactor SCIM member handling to use SCIMMember type for improved type safety 2025-09-25 13:03:06 +01:00
Nawaz Dhandala
acd0629791 chore: update eslint and typescript-eslint dependencies to latest versions 2025-09-25 12:54:45 +01:00
Nawaz Dhandala
3fa1aebceb chore: update eslint and eslint-plugin-unused-imports dependencies
- upgraded eslint-plugin-unused-imports from 3.2.0 to 4.1.0
- downgraded eslint from 9.36.0 to 8.57.1
- updated typescript-eslint packages to use scoped package names
2025-09-25 12:51:54 +01:00
Simon Larsen
1d6a645241 chore: update dependencies for eslint and typescript
- upgraded eslint from ^8.57.0 to ^9.36.0
- upgraded typescript from ^5.8.3 to ^5.9.2
- upgraded typescript-eslint from ^8.33.1 to ^8.44.1
2025-09-25 12:47:23 +01:00
Simon Larsen
922e30f162 feat: Add MigrationName1758798730753 to schema migrations 2025-09-25 12:13:02 +01:00
Simon Larsen
73beb80056 feat: Add enablePushGroups column to ProjectSCIM for SCIM provisioning 2025-09-25 12:12:48 +01:00
Simon Larsen
72fd74862c feat: Add conditional display for Teams based on enablePushGroups setting in SCIM configuration 2025-09-25 12:02:42 +01:00
Simon Larsen
13d403ecf8 feat: Add enablePushGroups option to SCIM configuration for group provisioning 2025-09-25 12:02:29 +01:00
Simon Larsen
30bca619dd feat: Add enablePushGroups configuration to ProjectSCIM for SCIM provisioning 2025-09-25 11:59:08 +01:00
Simon Larsen
f969adba9c fix: Update Okta integration instructions for SCIM application setup 2025-09-25 11:46:58 +01:00
Simon Larsen
b42abc6e42 Merge branch 'master' into scim-push 2025-09-25 11:26:10 +01:00
Simon Larsen
7ec183f9e9 fix: Add Cert-Manager configuration instructions for Let's Encrypt in README 2025-09-25 11:18:16 +01:00
Simon Larsen
d33c739372 fix: Correct secretName assignment logic for TLS hosts in ingress template 2025-09-24 21:55:07 +01:00
Simon Larsen
d8e12daec5 fix: Update ingress and cluster-issuer templates for ACME challenge handling 2025-09-24 21:26:55 +01:00
Simon Larsen
2a54cfc527 fix: Add ACME certificate profile to ClusterIssuer configuration 2025-09-24 20:51:15 +01:00
Simon Larsen
c0241a2e20 refactor: Update Cert-Manager integration in README and templates for clarity and consistency 2025-09-24 11:32:45 +01:00
Simon Larsen
e32d7cb368 fix: Add note to enable cert-manager before Let's Encrypt configuration 2025-09-24 11:28:16 +01:00
Simon Larsen
4dec1290e8 refactor: Update cert-manager configuration to use new naming convention for Let's Encrypt settings 2025-09-24 11:21:41 +01:00
Simon Larsen
04f6493a6d Refactor code structure for improved readability and maintainability 2025-09-24 11:19:15 +01:00
Simon Larsen
f113e84aa5 fix: Remove cert-manager CRDs installation option from values.yaml 2025-09-24 11:09:45 +01:00
Simon Larsen
57f764b92a refactor: Update cert-manager configuration to use index for improved clarity 2025-09-24 11:03:03 +01:00
Simon Larsen
c4c7d10d16 Add ClusterIssuer configuration for cert-manager with Let's Encrypt support
- Introduced a new template for ClusterIssuer in the Helm chart.
- Configured ACME server and email for Let's Encrypt.
- Set up HTTP01 solver with ingress class from values.
2025-09-24 10:47:34 +01:00
Simon Larsen
00ba94f372 feat: Include status page ID in SEO response for improved tracking 2025-09-24 10:35:52 +01:00
Simon Larsen
f85f41ffa9 fix: Ensure non-null assertion for repeatableJobs when adding job 2025-09-23 21:45:51 +01:00
Simon Larsen
21dfcdfa63 Merge pull request #2017 from OneUptime/queue-readd
feat: Implement repeatable job handling on queue reconnection; add lo…
2025-09-23 21:13:12 +01:00
Nawaz Dhandala
c818decfc8 refactor: Enhance type definitions and error handling in reconnect listener setup 2025-09-23 21:04:55 +01:00
Simon Larsen
1386fef470 refactor: Extract reconnect listener setup into a separate method for improved readability and error handling 2025-09-23 21:01:25 +01:00
Simon Larsen
4c0cbc17a2 refactor: Update queue event listener to use async IIFE for improved readability and reliability 2025-09-23 20:53:38 +01:00
Simon Larsen
3c42447b41 Merge branch 'master' into queue-readd 2025-09-23 20:44:26 +01:00
Simon Larsen
e31f616dc1 Merge pull request #2016 from OneUptime/sp-rss
Sp rss
2025-09-23 20:39:23 +01:00
Nawaz Dhandala
cfbb65f7ae refactor: Replace inline type definitions with RSSItem type for improved readability and consistency 2025-09-23 20:31:54 +01:00
Nawaz Dhandala
52c42dae1e refactor: Enhance type annotations for getStatusPageData and handleRSS functions; streamline code structure 2025-09-23 20:30:21 +01:00
Simon Larsen
d838d377a0 feat: Add HomeClientUrl to EnvironmentConfig and update RSS feed URL generation to use HttpProtocol 2025-09-23 20:22:56 +01:00
Simon Larsen
3a6f8b4c95 feat: Add atom link and guid to RSS feed XML generation 2025-09-23 20:17:37 +01:00
Simon Larsen
1039bd9f0b feat: Implement RSS feed handling and status page data retrieval logic 2025-09-23 20:16:20 +01:00
Nawaz Dhandala
5f84c7195c feat: Implement repeatable job handling on queue reconnection; add logging for job re-addition 2025-09-23 20:13:54 +01:00
Nawaz Dhandala
9597f66ab1 refactor: Improve type annotations for TeamComplianceStatusTable component; remove unnecessary line in SendStateChangeNotification 2025-09-23 19:37:16 +01:00
Simon Larsen
1562f8ee6a fix: Update @oneuptime/common and axios versions in package-lock.json; modify compile command to include npm update 2025-09-23 19:34:01 +01:00
Simon Larsen
11b0477cd6 fix: Add validation for projectId and scheduledMaintenanceId in getDashboardUrl method; include projectId in scheduled maintenance selection 2025-09-23 19:30:41 +01:00
Simon Larsen
174694e040 fix: Update axios version in package-lock.json and clean up unused imports in TeamComplianceStatusTable and TeamView 2025-09-23 19:24:12 +01:00
Simon Larsen
f5664116b9 Merge branch 'release' of github.com:OneUptime/oneuptime into release 2025-09-23 18:14:41 +01:00
Simon Larsen
0eb502b77a Merge branch 'master' into release 2025-09-23 18:14:20 +01:00
Nawaz Dhandala
1460521dc0 fix: Add type annotation for complianceStatusTableRef in TeamView 2025-09-23 18:14:03 +01:00
Nawaz Dhandala
e73c8bca16 refactor: Improve code readability by formatting user name assignment and useImperativeHandle in TeamComplianceStatusTable and TeamView 2025-09-23 18:10:43 +01:00
Simon Larsen
a0fef8df3d feat: Update notification method labels for clarity in TeamView 2025-09-23 17:16:43 +01:00
Simon Larsen
1821377dfa feat: Add refresh functionality to TeamComplianceStatusTable and integrate with TeamView 2025-09-23 17:13:22 +01:00
Simon Larsen
ac2c501058 feat: Refactor TeamComplianceStatusTable rendering and integrate Card component for better UI structure 2025-09-23 17:04:28 +01:00
Simon Larsen
3ce3d1ee65 feat: Improve loading and empty state handling in TeamComplianceStatusTable 2025-09-23 17:00:52 +01:00
Simon Larsen
ad17e49177 feat: Enhance user name retrieval in compliance status to include email as fallback 2025-09-23 16:58:50 +01:00
Simon Larsen
18389a0c31 feat: Update ComplianceRuleType enum values for consistency and clarity 2025-09-23 13:19:49 +01:00
Nawaz Dhandala
9d04975759 feat: Update migration for ruleType column in TeamComplianceSetting and improve notification rule labels in TeamView 2025-09-23 13:14:13 +01:00
Simon Larsen
3bb9b3d78b feat: Replace migration for ruleType column in TeamComplianceSetting and update OnCallDutyPolicyScheduleLayer defaults 2025-09-23 13:13:35 +01:00
Simon Larsen
ddfae282e6 Merge branch 'team-compliacne-rules' 2025-09-23 13:09:56 +01:00
Simon Larsen
02663bb33a feat: Change ruleType column type to LongText for improved compliance rule descriptions 2025-09-23 13:08:35 +01:00
Simon Larsen
6cb1a49128 feat: Update notification rule labels in TeamView for clarity 2025-09-23 13:07:53 +01:00
Nawaz Dhandala
4bcddf860c feat: Enhance TeamComplianceAPI and TeamComplianceService to include user compliance statuses and improve type safety 2025-09-23 13:05:34 +01:00
Nawaz Dhandala
d8d4593d38 feat: Refactor code for improved readability and maintainability across multiple files 2025-09-23 12:57:28 +01:00
Simon Larsen
f76381525f Merge pull request #2015 from OneUptime/team-compliacne-rules
Team compliance rules
2025-09-23 12:55:47 +01:00
Simon Larsen
91abb2318b feat: Add migration for unique index on teamId and ruleType in TeamComplianceSetting and update OnCallDutyPolicyScheduleLayer defaults 2025-09-23 12:55:14 +01:00
Simon Larsen
3a9e695336 feat: Add unique index on teamId and ruleType in TeamComplianceSetting and implement validation in TeamComplianceSettingService 2025-09-23 12:54:25 +01:00
Simon Larsen
e270c5d70a feat: Enhance compliance checks by aggregating missing notification rules for incident and alert severities 2025-09-23 12:45:27 +01:00
Simon Larsen
b40e88e8ec feat: Add userProfilePictureId to UserComplianceStatus and update rendering in TeamComplianceStatusTable 2025-09-23 12:38:26 +01:00
Simon Larsen
2173ed288a feat: Refactor TeamComplianceStatusTable to use LocalTable component for improved rendering 2025-09-23 12:28:44 +01:00
Simon Larsen
82669c8f23 feat: Update API endpoint for fetching team compliance status and add common headers 2025-09-23 12:25:51 +01:00
Simon Larsen
b093a730ab feat: Add migration for TeamComplianceSetting table and related constraints 2025-09-23 12:15:20 +01:00
Simon Larsen
8700068468 feat: Enhance compliance checks by integrating incident and alert severity notification rules 2025-09-23 12:08:47 +01:00
Simon Larsen
13e322944b feat: Implement TeamComplianceService for managing team compliance status and user notifications 2025-09-23 12:02:11 +01:00
Simon Larsen
62aecc6e9f feat: Add Team Compliance Settings and Status tables to TeamView 2025-09-23 12:00:13 +01:00
Nawaz Dhandala
61eca28545 Merge branch 'release' of https://github.com/OneUptime/oneuptime into release 2025-09-23 11:56:14 +01:00
Nawaz Dhandala
c289027efc fix: Implement retry mechanism for npm prerun command in workflow files to enhance reliability 2025-09-23 11:55:46 +01:00
Simon Larsen
ecdae56ffa feat: Add TeamComplianceStatusTable component for displaying team compliance status 2025-09-23 11:49:40 +01:00
Nawaz Dhandala
005536633c fix: Implement retry mechanism for Dockerfile generation to enhance reliability 2025-09-23 11:48:52 +01:00
Simon Larsen
d1ec1d6936 feat: Implement TeamComplianceAPI for retrieving team compliance status 2025-09-23 11:48:07 +01:00
Simon Larsen
6f68629f29 feat: Add TeamComplianceAPI to BaseAPIFeatureSet for compliance management 2025-09-23 11:46:18 +01:00
Simon Larsen
8af4bece10 feat: Add TeamComplianceSetting model and service with compliance rule types 2025-09-23 11:25:16 +01:00
Simon Larsen
18a0d6ab26 Merge branch 'master' into v4-ms-teams 2025-09-22 12:58:52 +01:00
Simon Larsen
6d73bb8a12 Merge branch 'release' of github.com:OneUptime/oneuptime into release 2025-09-22 12:56:31 +01:00
Simon Larsen
85b0f47be1 feat: Add Code of Conduct page and link in legal section 2025-09-22 12:55:41 +01:00
Simon Larsen
cc3596fc8e fix: Enhance adaptive card sending via Bot Framework with improved error handling and accessibility features 2025-09-22 11:26:02 +01:00
Simon Larsen
654367dbd8 fix: Refactor bot user ID handling and ensure fallback for undefined user ID in message sending 2025-09-22 10:44:08 +01:00
Simon Larsen
e5ccdc1a56 fix: Enhance access token expiration handling in Microsoft Teams utility 2025-09-22 10:33:27 +01:00
Simon Larsen
84389212f6 fix: Update Microsoft Teams app version to 1.1.0 in API manifest 2025-09-21 19:52:10 +01:00
Simon Larsen
5b01c202eb fix: Update Microsoft Teams API permissions for channel message and creation handling 2025-09-21 19:47:42 +01:00
Simon Larsen
153ee4fc20 fix: Update Microsoft Teams API permissions to include ChannelMessage.Send and additional channel-related permissions 2025-09-21 16:56:57 +01:00
Simon Larsen
03e176794e fix: Update Microsoft Teams app version to 2.1.0 and enhance permissions for message team members 2025-09-21 16:08:46 +01:00
Simon Larsen
9783f4897c fix: Correct indentation for Group.Read.All permission in Microsoft Teams integration documentation 2025-09-21 16:03:39 +01:00
Simon Larsen
928f6457bc fix: Update Microsoft Teams API to use Teams API for fetching available teams and add documentation for Group.Read.All permission 2025-09-21 16:00:39 +01:00
Simon Larsen
b628bd3ad1 fix: Enhance Microsoft Teams integration by updating project connection logic and handling admin consent state 2025-09-21 15:46:29 +01:00
Simon Larsen
dba0d69f63 fix: Update admin consent installation instructions for clarity in Microsoft Teams integration 2025-09-21 15:34:12 +01:00
Simon Larsen
64c203259a fix: Move admin consent card rendering to the bottom for improved UI flow in Microsoft Teams integration 2025-09-21 15:32:06 +01:00
Simon Larsen
25ec5c8df0 fix: Update admin consent button titles for clarity in Microsoft Teams integration 2025-09-21 15:31:46 +01:00
Simon Larsen
22270c62f4 fix: Remove admin consent reminder UI when consent is completed in Microsoft Teams integration 2025-09-21 15:31:14 +01:00
Simon Larsen
bb7176252c fix: Ensure loading state is updated correctly in error handling of Microsoft Teams integration 2025-09-21 15:30:53 +01:00
Simon Larsen
97f62b1458 fix: Remove unnecessary return statement in error handling of Microsoft Teams integration 2025-09-21 15:28:13 +01:00
Simon Larsen
5eb333ccfc feat: Update admin consent handling in Microsoft Teams integration 2025-09-21 15:15:33 +01:00
Simon Larsen
bd05afb0a7 feat: Implement admin consent handling and UI updates in Microsoft Teams integration 2025-09-21 14:57:53 +01:00
Simon Larsen
96e6780e7b feat: Enhance project auth token handling in Microsoft Teams integration 2025-09-21 14:54:06 +01:00
Simon Larsen
5e8ed144ae feat: Update title for manual app installation in Microsoft Teams integration 2025-09-21 14:39:27 +01:00
Simon Larsen
588ff245ec feat: Add admin consent callback URL to Microsoft Teams integration documentation 2025-09-21 14:38:17 +01:00
Simon Larsen
02cef807ea feat: Add scope parameter to admin consent URL for Microsoft Teams integration 2025-09-21 14:36:23 +01:00
Simon Larsen
041ffdfbe0 Merge pull request #2014 from OneUptime/master
Release
2025-09-21 14:31:24 +01:00
Simon Larsen
e2c362a5b3 feat: Add admin consent flow for Microsoft Teams integration with callback handling 2025-09-21 13:13:37 +01:00
Simon Larsen
000ff4ad45 refactor: Update API post call to use object syntax for improved clarity 2025-09-21 12:52:54 +01:00
Simon Larsen
064e16cc6f refactor: Improve API call syntax and remove unnecessary comments for better readability 2025-09-21 12:37:10 +01:00
Simon Larsen
fbc6b8fa48 fix: Correct typos and improve clarity in Microsoft Teams integration documentation 2025-09-20 10:05:01 +01:00
Simon Larsen
4e0935873d Merge branch 'master' into v4-ms-teams 2025-09-20 09:50:20 +01:00
Nawaz Dhandala
35a40a431e fix: Correct balance display logic to ensure accurate message for negative balances 2025-09-20 09:24:02 +01:00
Simon Larsen
d24c245b4a refactor: Update API post calls to use structured object syntax for improved readability 2025-09-20 09:23:11 +01:00
Simon Larsen
99f59f2f1e refactor: Update API call to use object destructuring for contributors request 2025-09-20 09:20:11 +01:00
Simon Larsen
c558eb578f refactor: Update API call syntax to use object destructuring for improved readability 2025-09-19 23:01:16 +01:00
Simon Larsen
97380a5410 Merge branch 'master' into v4-ms-teams 2025-09-19 22:58:45 +01:00
Simon Larsen
462f40680e fix: Update balance display logic to show message for negative balances 2025-09-19 22:58:16 +01:00
Simon Larsen
8a11dbe35b fix: Change sort order of createdAt to descending in StatusPageAPI 2025-09-19 22:47:34 +01:00
Nawaz Dhandala
d2c1467a07 refactor: Simplify API call syntax and improve code readability across multiple files 2025-09-19 22:37:25 +01:00
Simon Larsen
ff57061190 Refactor API calls to use new request structure
- Updated API.post and API.get calls across multiple components to use the new object structure for requests, including specifying `url`, `data`, and `headers` explicitly.
- This change improves code readability and consistency in how API requests are made throughout the application.
2025-09-19 22:36:05 +01:00
Simon Larsen
63f1034f4a refactor: Update API calls to use object destructuring for parameters in multiple components 2025-09-19 22:19:50 +01:00
Simon Larsen
87ddec9e6c refactor: Update API method calls to use object destructuring for parameters 2025-09-19 22:15:02 +01:00
Simon Larsen
b2ea52e549 refactor: Simplify API method signatures by consolidating parameters into a single options object 2025-09-19 22:01:25 +01:00
Simon Larsen
92bb753cbf fix: Update API call in Billing settings to use undefined for data parameter 2025-09-19 21:51:36 +01:00
Simon Larsen
7428e75643 refactor: Remove inheritance from BaseAPI and restructure BillingAPI class 2025-09-19 21:45:29 +01:00
Simon Larsen
0a2ed040f0 feat: Add discountPercent field to Project model and corresponding migration 2025-09-19 21:33:48 +01:00
Simon Larsen
ded0aba399 feat: Implement customer balance retrieval in BillingAPI and update Billing settings page to display balance 2025-09-19 21:25:52 +01:00
Simon Larsen
0658248535 refactor: Remove dark mode styles from BarChart and LineChart components for consistency 2025-09-19 21:10:41 +01:00
Simon Larsen
6cf2d842ad Merge branch 'master' of github.com:OneUptime/oneuptime 2025-09-19 21:02:46 +01:00
Simon Larsen
4a6bf95ef3 refactor: Simplify styles in LogsViewer and LegendItem components for cleaner UI 2025-09-19 21:02:41 +01:00
Nawaz Dhandala
af7835fc8a refactor: Improve code formatting and readability in various service and utility files 2025-09-19 20:58:32 +01:00
Nawaz Dhandala
5e7ed2be73 Merge branch 'master' of https://github.com/OneUptime/oneuptime 2025-09-19 20:57:56 +01:00
Nawaz Dhandala
11894d0ba5 Refactor API calls to use unified request structure
- Updated MicrosoftTeams and Slack classes to use the new API.post structure with url and data properties.
- Refactored API utility methods to accept a single options object for HTTP requests, improving consistency across the codebase.
- Modified various service and utility classes (e.g., CopilotPullRequestService, CodeRepositoryUtil, and ApiMonitor) to align with the new API request format.
- Enhanced error handling and logging for API responses.
- Updated tests to accommodate changes in API method signatures.
2025-09-19 20:57:54 +01:00
Simon Larsen
8bb92bbeb3 docs: Clarify server restart instructions in Microsoft Teams integration documentation 2025-09-19 15:58:58 +01:00
Simon Larsen
a50af21ce0 docs: Revise Microsoft Teams integration documentation for app manifest upload steps and server restart instructions 2025-09-19 15:57:55 +01:00
Simon Larsen
df29ed2b78 docs: Update Microsoft Teams integration documentation to clarify app registration details and configuration steps 2025-09-19 15:44:39 +01:00
Simon Larsen
58cba788fc docs: Update Microsoft Teams integration documentation to correct bot service creation steps 2025-09-19 15:37:02 +01:00
Simon Larsen
760044f603 docs: Add clarification on secret value usage in Microsoft Teams integration documentation 2025-09-19 15:36:08 +01:00
Simon Larsen
fb099a1c3e refactor: Remove redundant notes on Microsoft Teams permissions for clarity 2025-09-19 15:35:41 +01:00
Simon Larsen
32692bc939 docs: Enhance Microsoft Teams integration documentation with detailed permissions information 2025-09-19 15:35:21 +01:00
Simon Larsen
c514b9cb74 refactor: Update Microsoft Teams integration documentation for clarity and accuracy 2025-09-19 15:17:12 +01:00
Simon Larsen
5d44943958 fix: Update Microsoft Teams app registration details for clarity and accuracy 2025-09-19 15:15:44 +01:00
Simon Larsen
df4138e5d3 Merge branch 'master' into v4-ms-teams 2025-09-19 14:56:04 +01:00
Simon Larsen
51777709f3 Revert "refactor: Enhance email template styles and structure for improved readability and aesthetics"
This reverts commit 43b6fdf45d.
2025-09-19 13:47:49 +01:00
Simon Larsen
f7416bb0a6 feat: Add alertId and incidentId to notification payloads for enhanced tracking 2025-09-19 12:46:53 +01:00
Simon Larsen
43b6fdf45d refactor: Enhance email template styles and structure for improved readability and aesthetics 2025-09-19 12:35:44 +01:00
Simon Larsen
818995a6ae feat: enhance bot authentication configuration for multi-tenant Microsoft Teams apps 2025-09-18 21:02:48 +01:00
Simon Larsen
38fa1ba9f8 refactor: streamline message handling by utilizing TurnContext for sending messages in Microsoft Teams 2025-09-18 20:51:48 +01:00
Simon Larsen
b862ac113f feat: Refactor Bot Framework activity handling to use botbuilder SDK's adapter for improved processing 2025-09-18 20:40:57 +01:00
Simon Larsen
a2526a5a99 refactor: change logging level from info to debug for bot message operations 2025-09-18 20:22:18 +01:00
Simon Larsen
4124e7e9f7 chore: add botbuilder dependency to Common package.json 2025-09-18 20:16:51 +01:00
Simon Larsen
05d3e73b83 docs: Update Microsoft Teams integration documentation for bot messaging endpoint configuration 2025-09-18 20:10:21 +01:00
Simon Larsen
907f0149d8 Merge branch 'master' into v4-ms-teams 2025-09-18 16:56:57 +01:00
Simon Larsen
54f4c63a51 feat: Add dynamic loading of Mermaid.js for rendering diagrams in blog posts 2025-09-18 16:56:27 +01:00
Simon Larsen
80388adb59 refactor: Implement JWT validation for Bot Framework authentication in MicrosoftTeamsAPI 2025-09-17 21:23:32 +01:00
Simon Larsen
ca0792a7f7 refactor: Enhance Bot Framework authentication validation and access token retrieval logging 2025-09-17 21:15:40 +01:00
Simon Larsen
7c1e42cff9 refactor: Add validation for Bot Framework service URLs and implement access token retrieval method 2025-09-17 21:09:08 +01:00
Simon Larsen
e9904c0e74 refactor: Move Bot Framework activity handlers to MicrosoftTeamsUtil for better organization and maintainability 2025-09-17 20:58:00 +01:00
Simon Larsen
dd9d296e62 refactor: Enhance logging and add test endpoint for Bot Framework integration in MicrosoftTeamsAPI 2025-09-17 20:54:50 +01:00
Simon Larsen
c0005618fe refactor: Implement Bot Framework messaging endpoint and activity handlers in MicrosoftTeamsAPI 2025-09-17 20:47:11 +01:00
Simon Larsen
feb503b448 refactor: Update image path handling and fix URL formatting in MicrosoftTeamsIntegration 2025-09-17 20:32:29 +01:00
Simon Larsen
d2c411c9d6 refactor: Simplify icon path handling by removing fallback checks in MicrosoftTeamsAPI 2025-09-17 20:26:59 +01:00
Simon Larsen
562e930ca0 refactor: Replace fs with LocalFile utility for icon file handling in MicrosoftTeamsAPI 2025-09-17 20:26:13 +01:00
Simon Larsen
e97b2904e8 refactor: Simplify icon handling logic by removing fallback checks for Microsoft Teams icons 2025-09-17 16:47:01 +01:00
Simon Larsen
fd07d70575 refactor: Update Teams app manifest version and improve icon handling logic 2025-09-17 16:44:35 +01:00
Simon Larsen
3e6c8b3f68 refactor: Remove fallback for MicrosoftTeamsAppClientId and add packageName to manifest 2025-09-17 16:23:26 +01:00
Simon Larsen
ad772c4a5b refactor: Remove fallback for MicrosoftTeamsAppClientId in webApplicationInfo 2025-09-17 16:22:10 +01:00
Simon Larsen
5396c0c9cf refactor: Specify type for archive variable in MicrosoftTeamsAPI 2025-09-17 16:13:56 +01:00
Simon Larsen
c6e6ae5be0 refactor: Update Microsoft Teams app manifest version and improve icon directory handling 2025-09-17 16:13:32 +01:00
Simon Larsen
82397fec5a refactor: Update Teams app manifest versioning logic and add client ID to docker-compose 2025-09-17 16:04:32 +01:00
Simon Larsen
6301e24c02 refactor: Add Microsoft Teams app client ID and secret to configuration files 2025-09-17 15:37:03 +01:00
Simon Larsen
23b3a4d9dd refactor: Add Microsoft Teams app configuration to environment and docker-compose files 2025-09-17 15:34:50 +01:00
Simon Larsen
e6c158b2b5 refactor: Use AppVersion for Teams app manifest versioning 2025-09-17 15:30:43 +01:00
Simon Larsen
5a4f2e0744 refactor: Add validation for Microsoft Teams App Client ID in getTeamsAppManifest method 2025-09-17 15:29:34 +01:00
Simon Larsen
545335a74d refactor: Update nodemon.json files to ignore node_modules and public directories 2025-09-17 14:50:58 +01:00
Simon Larsen
5ab49052fe Merge branch 'master' into v4-ms-teams 2025-09-17 14:22:25 +01:00
Simon Larsen
2985b7675d refactor: Remove unused Button import and clean up API call parameters in SlackChannelCacheModal component 2025-09-17 14:01:18 +01:00
Simon Larsen
49cd04c5d5 refactor: Simplify channel cache management by replacing rows with a dictionary component in SlackChannelCacheModal 2025-09-17 13:54:56 +01:00
Simon Larsen
2a23d1a962 refactor: Update API call to include common headers and remove unnecessary modal properties in SlackChannelCacheModal component 2025-09-17 13:48:56 +01:00
Nawaz Dhandala
13f19adc13 refactor: Enhance type annotations and improve code clarity in SlackAPI, CopyTextButton, LogItem, LogsViewer, and SlackChannelCacheModal components 2025-09-17 13:20:05 +01:00
Nawaz Dhandala
3e79bbf55f refactor: Improve code formatting and readability across multiple components 2025-09-17 13:10:30 +01:00
Nawaz Dhandala
b400e89a3b Merge branch 'release' 2025-09-17 13:09:59 +01:00
Nawaz Dhandala
fc8362e7e5 feat: Implement SlackChannelCacheModal for viewing and editing cached Slack channels 2025-09-17 13:09:29 +01:00
Nawaz Dhandala
8b209e82d5 feat: Add endpoint to fetch and cache all Slack channels for the current tenant's project 2025-09-17 13:08:09 +01:00
Simon Larsen
6fb4fdf698 Merge pull request #2009 from OneUptime/better-log-ui
refactor: Enhance LogsViewer with improved scroll handling and UI upd…
2025-09-17 13:04:07 +01:00
Simon Larsen
9551e64b16 refactor: Replace SVG icons with Icon component for consistency in CopyTextButton and LogItem components 2025-09-17 12:58:36 +01:00
Simon Larsen
232f938d2c refactor: Update log message styling for improved readability in LogItem component 2025-09-17 12:51:25 +01:00
Simon Larsen
0dc24b36e6 refactor: Consolidate copy button logic for log message display in LogItem component 2025-09-17 12:46:38 +01:00
Simon Larsen
a77eaf214f refactor: Remove wrapLines toggle and associated UI elements for a cleaner toolbar in LogsViewer component 2025-09-17 12:44:45 +01:00
Simon Larsen
5ab08fbfcb refactor: Simplify click handling for collapse button in LogItem component 2025-09-17 12:34:16 +01:00
Simon Larsen
a73c2eb32c refactor: Update CopyTextButton integration in LogItem component with improved props and styling 2025-09-17 12:31:19 +01:00
Nawaz Dhandala
8f9e6d5bec refactor: Increase maxPages limit for improved pagination in SlackUtil 2025-09-17 12:30:34 +01:00
Nawaz Dhandala
790e26d608 refactor: Increase limit for faster searches in requestBody 2025-09-17 12:30:22 +01:00
Simon Larsen
79b96bcce8 refactor: Simplify severity badge handling and improve log body rendering in LogItem component 2025-09-17 12:22:27 +01:00
Simon Larsen
592a7f893e refactor: Enhance LogItem and LogsViewer components with improved styling and functionality 2025-09-17 12:18:48 +01:00
Simon Larsen
7408f9c204 Merge pull request #2008 from OneUptime/snyk-fix-649148701c5ddf7371d98302b082212e
[Snyk] Security upgrade axios from 1.7.7 to 1.12.0
2025-09-17 11:47:38 +01:00
Nawaz Dhandala
307de42434 feat: Add generateGroupsListResponse function for SCIM group list responses 2025-09-17 11:28:41 +01:00
Nawaz Dhandala
d1ae7f67c4 refactor: Adjust indentation for @CaptureSpan() annotation in updateChannelCache method 2025-09-17 11:07:30 +01:00
Simon Larsen
b4616885b2 refactor: Implement bulk channel cache updates and improve cache handling in SlackUtil 2025-09-17 11:05:50 +01:00
Nawaz Dhandala
7fb7f3719f refactor: Update lastUpdated timestamp format and clean up code style in SlackUtil 2025-09-17 10:56:59 +01:00
Nawaz Dhandala
d1d1d1935d refactor: Enhance LogsViewer with improved scroll handling and UI updates 2025-09-17 10:55:05 +01:00
Simon Larsen
5b54f66821 refactor: Add projectId parameter to getAllWorkspaceChannels and implement bulk cache update 2025-09-17 10:54:04 +01:00
Simon Larsen
e99a954387 refactor: Add projectId parameter to getAllWorkspaceChannels method 2025-09-17 10:50:40 +01:00
Simon Larsen
93fd9ce3cc refactor: Limit API pagination to maxPages and adjust channel search limit 2025-09-17 10:46:26 +01:00
Simon Larsen
3a3e510b11 refactor: Exclude archived channels in Slack API requests 2025-09-17 10:43:44 +01:00
Simon Larsen
cbaf1edf89 refactor: Increase maxPages limit for API search in SlackUtil 2025-09-17 10:41:59 +01:00
snyk-bot
94b21b5fc3 fix: Common/package.json & Common/package-lock.json to reduce vulnerabilities
The following vulnerabilities are fixed with an upgrade:
- https://snyk.io/vuln/SNYK-JS-AXIOS-12613773
2025-09-17 01:44:58 +00:00
Simon Larsen
f60cc4c199 fix: Correct configurationUrl formatting in MicrosoftTeamsAPI 2025-09-16 21:37:24 +01:00
Simon Larsen
81b1f120ee refactor: Remove manifest state and props from MicrosoftTeamsIntegration and MicrosoftTeamsIntegrationDocumentation components 2025-09-16 21:30:49 +01:00
Simon Larsen
48a0036023 feat: Add manual app installation instructions and download option for app manifest in MicrosoftTeamsIntegration 2025-09-16 21:25:34 +01:00
Simon Larsen
9925a6a5a5 feat: Update MicrosoftTeamsAPI and EnvironmentConfig to improve app manifest handling and add HomeClientUrl 2025-09-16 21:17:51 +01:00
Simon Larsen
e5ca287dcb feat: Update MicrosoftTeamsAPI to read pre-resized icons from the filesystem instead of using placeholder images 2025-09-16 21:12:51 +01:00
Simon Larsen
1a5962c430 feat: Refactor token validation in MicrosoftTeamsUtil to enhance error handling and refresh logic 2025-09-16 21:05:55 +01:00
Simon Larsen
ba5a664fca feat: Update MicrosoftTeamsAPI to disable notification-only mode and extract tenant ID from JWT for improved token validation 2025-09-16 21:05:43 +01:00
Simon Larsen
f7d05c642f feat: Refactor MicrosoftTeams integration in WorkspaceUtil to use MicrosoftTeamsUtil and include projectId in user name retrieval 2025-09-16 20:52:20 +01:00
Simon Larsen
877810219c feat: Enhance MicrosoftTeamsUtil with detailed debug logging for access token management and message sending 2025-09-16 20:48:56 +01:00
Simon Larsen
fed8c9a261 feat: Add detailed debug logging for message sending in MicrosoftTeamsUtil 2025-09-16 20:43:25 +01:00
Simon Larsen
896d36b16b feat: Add detailed logging for channel retrieval and message posting in MicrosoftTeamsUtil 2025-09-16 20:41:21 +01:00
Simon Larsen
a9c6d565f4 feat: Implement access token refresh mechanism in MicrosoftTeamsUtil for improved token management 2025-09-16 20:39:33 +01:00
Simon Larsen
ae58a33456 refactor: Improve debug logging format for channel search in SlackUtil 2025-09-16 18:17:34 +01:00
Simon Larsen
d689d7a12a feat: Enhance MicrosoftTeamsUtil with valid access token retrieval and update interfaces for additional data fields 2025-09-16 16:44:24 +01:00
Simon Larsen
f28ada8994 fix: Add undefined parameter to API calls in MicrosoftTeamsUtil for consistency 2025-09-16 16:33:34 +01:00
Nawaz Dhandala
4d9de1d326 refactor: Add debug logging for channel search in SlackUtil 2025-09-16 14:42:28 +01:00
Simon Larsen
405b28ee91 feat: Pass workspaceType to query in WorkspaceNotificationRuleTable component 2025-09-16 14:33:11 +01:00
Simon Larsen
245aeac4a9 refactor: Remove Coming Soon component and update Microsoft Teams connection messages for consistency 2025-09-16 14:16:56 +01:00
Nawaz Dhandala
6b8f8db991 feat: add archiver package and update Microsoft Teams integration components
- Added `archiver` package to `package.json` and `package-lock.json`.
- Refactored `MicrosoftTeamsIntegration.tsx` for improved readability and consistency.
- Updated error handling and state management in `MicrosoftTeamsIntegration`.
- Enhanced documentation component for Microsoft Teams integration.
- Cleaned up formatting and structure in `MicrosoftTeamsIntegrationDocumentation.tsx`.
- Adjusted settings page to utilize the updated Microsoft Teams integration component.
2025-09-16 14:08:40 +01:00
Simon Larsen
6c06c6682a refactor: Update team selection UI layout and button styles for improved alignment 2025-09-16 14:02:01 +01:00
Simon Larsen
f48da38ae1 feat: Replace button elements with reusable Button component for team selection UI 2025-09-16 13:55:47 +01:00
Simon Larsen
29de1dfbb2 refactor: Remove team search functionality and update team selection UI 2025-09-16 13:53:59 +01:00
Simon Larsen
9063bd145f feat: Replace team selection buttons with radio buttons for improved UX 2025-09-16 13:50:55 +01:00
Simon Larsen
436a393cb1 refactor: Enhance team selection UI with improved styling and search functionality 2025-09-16 13:46:53 +01:00
Simon Larsen
a7f6e264f5 feat: Implement team selection UI for Microsoft Teams integration with search functionality 2025-09-16 13:30:10 +01:00
Simon Larsen
777c2a36bf refactor: Remove optional serviceCatalogId from MicrosoftTeamsMiscData interface 2025-09-16 12:23:53 +01:00
Simon Larsen
c005448103 feat: Update Microsoft Teams API scopes to include User.Read permission 2025-09-16 12:05:03 +01:00
Simon Larsen
54f7be2c62 feat: Update Microsoft Teams OAuth flow to use static redirect URI with state parameter for projectId and userId 2025-09-16 11:53:26 +01:00
Simon Larsen
1f52b91bc5 refactor: Simplify Microsoft Teams integration page by removing unnecessary components and structure 2025-09-16 11:45:14 +01:00
Simon Larsen
d54bafd5d1 Merge branch 'master' of github.com:OneUptime/oneuptime into v4-ms-teams 2025-09-16 11:20:37 +01:00
Simon Larsen
7728e84f34 Merge pull request #2007 from OneUptime/span-fix
refactor: Enhance root span detection logic in TraceExplorer component
2025-09-16 11:15:37 +01:00
Simon Larsen
a5808eac5e refactor: Enhance root span detection logic in TraceExplorer component 2025-09-16 11:15:13 +01:00
Simon Larsen
5fdb54a8d9 feat: Implement Microsoft Teams API with endpoints for app manifest, OAuth, and webhooks 2025-09-16 10:47:09 +01:00
Simon Larsen
f02a4de88d feat: Refactor channel ID handling to include team ID and improve channel info retrieval from Microsoft Graph API 2025-09-16 10:38:18 +01:00
Simon Larsen
49b2999d4f feat: Enhance Microsoft Teams integration with new messaging and channel management features 2025-09-16 10:33:59 +01:00
Simon Larsen
60c1caa11f feat: Add Microsoft Teams integration component with authentication handling 2025-09-16 10:26:40 +01:00
Simon Larsen
3eb21895d8 feat: Implement Microsoft Teams authentication actions and request handling 2025-09-16 10:26:13 +01:00
Simon Larsen
2d9527e94d feat: Add Microsoft Teams integration documentation component 2025-09-16 10:10:55 +01:00
Simon Larsen
9f26e6f75d feat: Update Microsoft Teams incident action types to use specific incident action constants 2025-09-16 09:59:25 +01:00
Simon Larsen
7890698f7d feat: Refactor scheduled maintenance action handling to use constants for action types 2025-09-16 09:58:55 +01:00
Simon Larsen
e738db0b24 feat: Add Microsoft Teams action handlers for alerts, incidents, monitors, and on-call duties; update scheduled maintenance action types 2025-09-16 09:48:25 +01:00
Simon Larsen
67524ee869 feat: Implement Microsoft Teams scheduled maintenance actions and update alert action types 2025-09-16 09:34:49 +01:00
Simon Larsen
0e5c0d1509 feat: Add Microsoft Teams integration with configuration and action types 2025-09-16 09:32:43 +01:00
Simon Larsen
cdff9338d9 refactor: Simplify stats initialization and update logic in TraceExplorer component 2025-09-15 18:50:46 +01:00
Simon Larsen
074926ee41 Merge pull request #2005 from OneUptime/on-call-loop
On call loop
2025-09-15 18:35:29 +01:00
Nawaz Dhandala
b0ef6e23a3 refactor: Improve readability and structure in LayerUtil's getEvents method 2025-09-15 18:35:08 +01:00
Simon Larsen
1ab6bc5af9 test: Enhance overnight window test to validate distinct segments across midnight 2025-09-15 18:18:22 +01:00
Simon Larsen
04dba20871 feat: Implement weekly restrictions handling in LayerUtil and add corresponding tests 2025-09-15 18:15:13 +01:00
Simon Larsen
1cd5c927f6 feat: Add comprehensive tests for LayerUtil including daily restrictions and rotation handoff scenarios 2025-09-15 18:10:35 +01:00
Simon Larsen
6513222c3b feat: Add support for overnight event windows in getEventsByDailyRestriction method 2025-09-15 18:09:07 +01:00
Simon Larsen
498abd5251 fix: Update error handling to exclude status 400 for network-related errors 2025-09-15 17:21:48 +01:00
Nawaz Dhandala
fc46a81eb8 refactor: Improve code readability and consistency in various components 2025-09-15 12:41:12 +01:00
Simon Larsen
c3fb6e9f32 Merge branch 'master' of github.com:OneUptime/oneuptime 2025-09-15 12:35:58 +01:00
Simon Larsen
3aba42b965 feat: Enhance TraceExplorer UI with trace ID display and copy functionality 2025-09-15 12:22:51 +01:00
Simon Larsen
5651a43b22 feat: Add service filtering and statistics display in TraceExplorer 2025-09-15 12:19:29 +01:00
Simon Larsen
929792ef6a feat: Enhance TraceExplorer with error filtering and summary stats display 2025-09-15 11:54:20 +01:00
Simon Larsen
e13cdc4523 Merge pull request #2004 from OneUptime/span-improve
Span improve
2025-09-15 11:50:47 +01:00
Simon Larsen
8dc0535dac feat: Enhance JSONTable grouping logic to always override existing keys with grouped array representation 2025-09-15 11:50:21 +01:00
Simon Larsen
dc4541739a feat: Implement grouping for primitive arrays in JSONTable component 2025-09-15 11:41:07 +01:00
Simon Larsen
a4a3da7e2e feat: Add UI improvement task with Tailwind CSS guidelines for modern design 2025-09-15 11:30:54 +01:00
Simon Larsen
21432e1416 feat: Add default sorting to TelemetryServiceTable by name in ascending order 2025-09-15 11:23:57 +01:00
Simon Larsen
2f568f1319 feat: Add JSONTable component for improved display of JSON attributes in SpanViewer 2025-09-15 11:17:04 +01:00
Simon Larsen
50bdd592b4 refactor: Clean up telemetry span attributes by removing unnecessary properties 2025-09-15 10:50:02 +01:00
snyk-bot
50be2a666c fix: Probe/package.json & Probe/package-lock.json to reduce vulnerabilities
The following vulnerabilities are fixed with an upgrade:
- https://snyk.io/vuln/SNYK-JS-AXIOS-12613773
2025-09-15 08:22:25 +00:00
Simon Larsen
3938637b84 feat: Enhance MarkdownViewer styling and improve preformatted code handling 2025-09-10 20:08:30 +01:00
Simon Larsen
3ed9e21271 Merge branch 'master' of github.com:OneUptime/oneuptime 2025-09-10 19:09:57 +01:00
Simon Larsen
63e1266e2b feat: Improve MarkdownViewer styling with enhanced Tailwind CSS classes for better readability and aesthetics 2025-09-10 19:09:53 +01:00
Nawaz Dhandala
a552812711 feat: Add projectId support to SlackUtil message sending for incident and scheduled maintenance actions 2025-09-10 18:21:30 +01:00
Nawaz Dhandala
ad07ab75fe feat: Add elkjs dependency for enhanced functionality 2025-09-10 18:13:59 +01:00
Nawaz Dhandala
c8deffebb0 refactor: Improve code readability by standardizing formatting and spacing in SlackUtil methods 2025-09-10 17:12:51 +01:00
Simon Larsen
67a3ea5109 feat: Enhance SlackUtil with projectId support and caching for channel operations 2025-09-10 17:11:04 +01:00
Simon Larsen
6728cc0458 feat: Add projectId parameter to channel-related methods for improved context handling 2025-09-10 17:08:02 +01:00
Simon Larsen
f84ab2474f feat: Optimize channel existence checks by introducing getWorkspaceChannelByName method and streamline channel name normalization 2025-09-10 16:47:36 +01:00
Simon Larsen
5c8ce04eed feat: Enhance pagination handling by supporting 'skip' and 'limit' parameters from both query and body 2025-09-09 16:56:55 +01:00
Nawaz Dhandala
3064aa0364 feat: Improve code formatting and descriptions in announcement-related components and migrations for better readability 2025-09-09 14:36:32 +01:00
Simon Larsen
9625f1381c feat: Add migration for AnnouncementMonitor and AnnouncementTemplateMonitor tables with foreign key constraints 2025-09-09 14:12:33 +01:00
Simon Larsen
6ecd3ad166 Merge branch 'master' into announcement-monitor 2025-09-09 14:04:36 +01:00
Simon Larsen
8e54cac86e feat: Add createEditModalWidth prop with large size to multiple template views for consistent modal presentation 2025-09-09 14:01:46 +01:00
Nawaz Dhandala
cc52bb76d1 feat: Enhance incident state handling by adding type definitions, improving error handling, and updating default state display 2025-09-09 13:54:52 +01:00
Nawaz Dhandala
4c037f54f4 feat: Refactor incident state migration and update related components for improved clarity and functionality 2025-09-09 13:49:34 +01:00
Simon Larsen
b869628d4a feat: Implement fetch for initial incident state and update form values 2025-09-09 13:48:11 +01:00
Simon Larsen
0fbeb503ad feat: Update incident state field title and description for clarity 2025-09-09 13:06:29 +01:00
Simon Larsen
a302e4dc6c feat: Implement automatic selection of the first incident state and update related references 2025-09-09 12:58:07 +01:00
Nawaz Dhandala
00c8783137 feat: Add monitor selection to status page announcements and templates, enhancing resource notification capabilities 2025-09-09 12:56:42 +01:00
Simon Larsen
11211f4a62 feat: Update initial incident state description to reflect default behavior 2025-09-09 12:53:30 +01:00
Simon Larsen
d29750d66e feat: Add initialIncidentState field to IncidentTemplates for incident creation 2025-09-09 12:47:15 +01:00
Simon Larsen
7dc590dab4 feat: Add initialIncidentStateId migration and update index references 2025-09-09 12:37:43 +01:00
Simon Larsen
1d0ed64c1a feat: Rename currentIncidentState to initialIncidentState and update related references in IncidentTemplate, IncidentService, and IncidentTemplatesView 2025-09-09 12:26:48 +01:00
Simon Larsen
0cf3884be4 Merge branch 'master' into select-incident-state 2025-09-09 12:21:12 +01:00
Simon Larsen
165f5608e6 feat: Add step to free disk space in GitHub Actions runner for improved image build efficiency 2025-09-09 12:18:07 +01:00
Nawaz Dhandala
f2b8cfbffb Merge branch 'master' of https://github.com/OneUptime/oneuptime 2025-09-09 12:12:57 +01:00
Nawaz Dhandala
6084e15f20 refactor: Enhance type annotations in MarkdownEditor and tests for improved type safety 2025-09-09 12:12:55 +01:00
Simon Larsen
b1db4187de Learn more about Markdown syntax. 2025-09-09 12:12:09 +01:00
Nawaz Dhandala
20ce8a8c74 refactor: Clean up MarkdownEditor and FormField code for improved readability and consistency 2025-09-09 11:45:00 +01:00
Simon Larsen
39200249d1 feat: Update spell check handling in MarkdownEditor and tests for improved functionality 2025-09-09 11:38:58 +01:00
Simon Larsen
27533125e4 feat: Add createEditModalWidth prop to multiple components for consistent modal sizing 2025-09-09 11:23:20 +01:00
Simon Larsen
99dd421329 feat: Add createEditModalWidth prop to IncidentDelete for consistent modal sizing 2025-09-09 11:17:11 +01:00
Simon Larsen
4184894f27 feat: Refactor MarkdownEditor toolbar layout for improved organization and readability 2025-09-09 11:12:40 +01:00
Simon Larsen
a7a00dc0fa feat: Add dataTestId prop to MarkdownEditor and FormField for improved testing 2025-09-09 10:58:06 +01:00
Simon Larsen
9340f69789 feat: Add additional toolbar buttons and formatting options in MarkdownEditor 2025-09-09 10:35:10 +01:00
Simon Larsen
ba33bc0c23 feat: Enhance MarkdownEditor with improved heading handling and toolbar buttons 2025-09-09 10:27:41 +01:00
Simon Larsen
b8cac60c6e feat: Enhance Markdown preview with improved code block handling and styling 2025-09-09 09:59:32 +01:00
Simon Larsen
3a5d5253d0 feat: Enhance MarkdownEditor with toolbar buttons and preview functionality 2025-09-09 09:53:44 +01:00
Simon Larsen
64010b0348 feat: Add initial incident state selection to incident templates and creation forms 2025-09-09 08:35:46 +01:00
Simon Larsen
84ca2ff311 fix: Remove redundant APP_VERSION build argument in Docker image deployment steps 2025-09-08 22:08:00 +01:00
Simon Larsen
c0becebadc feat: Update date formatting to user-friendly display in getMonitorStatusTimelineForStatusPage method 2025-09-08 21:58:53 +01:00
Nawaz Dhandala
6ef99fd890 refactor: Specify types for format and testDate in OneUptimeDate class methods 2025-09-08 21:52:31 +01:00
Nawaz Dhandala
a55f2f7842 refactor: Improve code readability by formatting function arguments and return values in date handling methods 2025-09-08 21:51:53 +01:00
Simon Larsen
0aae7877c7 feat: Update date formatting to user-friendly display in various components 2025-09-08 21:49:19 +01:00
Simon Larsen
8d6cc37f7a feat: Update date formatting to user-friendly display across various components 2025-09-08 21:41:57 +01:00
Simon Larsen
1a0f7eb1e7 feat: Enhance date formatting to user-friendly display in Scheduled Maintenance components 2025-09-08 21:36:47 +01:00
Simon Larsen
6ed65ed3ef fix: Change tag type from semver to raw for Docker image deployments 2025-09-08 20:43:09 +01:00
Simon Larsen
2ac342e26a feat: Add billing_enabled variable to Nginx configuration 2025-09-08 20:29:28 +01:00
Simon Larsen
fe80d6b1ff fix: Remove unnecessary markdown syntax from upgrading guide 2025-09-08 18:44:43 +01:00
Simon Larsen
a68254be6d fix: Clarify reason for discontinuing Bitnami charts in upgrading guide 2025-09-08 18:43:14 +01:00
Simon Larsen
49a9e355fe feat: Add upgrading guide and navigation link to documentation 2025-09-08 18:41:40 +01:00
Simon Larsen
7091e35393 Update GitHub Actions workflow to read version prefix from VERSION_PREFIX file and adjust versioning scheme
- Added a new job 'read-version' to read the major and minor version from VERSION_PREFIX file.
- Updated dependent jobs to use the version read from 'read-version' instead of hardcoded version.
- Changed versioning format in multiple jobs to reflect the new versioning scheme based on the content of VERSION_PREFIX.
- Created VERSION_PREFIX file with initial version set to 8.0.
2025-09-07 15:17:47 +01:00
Simon Larsen
34cc8a43ab Merge pull request #1995 from OneUptime/bitnami-mgr-postgres
Bitnami mgr postgres
2025-09-07 13:21:41 +01:00
Simon Larsen
75333ef36c feat: Add pod security context configuration for ClickHouse and Redis StatefulSets 2025-09-07 13:03:09 +01:00
Simon Larsen
d4b3f1b60b feat: Add primary pod security context configuration for PostgreSQL 2025-09-07 12:59:27 +01:00
Simon Larsen
318d20a5a5 feat: Update PostgreSQL StatefulSet to use primary nodeSelector, affinity, tolerations, and resources 2025-09-07 12:56:29 +01:00
Simon Larsen
44b9c33e5c feat: Add primary ConfigMaps for PostgreSQL configuration and pg_hba settings 2025-09-07 12:45:32 +01:00
Simon Larsen
317a17cbab feat: Rename PostgreSQL ConfigMaps to include 'primary' in their names for clarity 2025-09-07 12:40:23 +01:00
Simon Larsen
6d2cb53760 feat: Update PostgreSQL configuration to use primary settings for ConfigMaps 2025-09-07 12:37:30 +01:00
Simon Larsen
7ddc4be319 feat: Add pg_hba.conf configuration and corresponding ConfigMap for PostgreSQL 2025-09-07 12:32:47 +01:00
Simon Larsen
604776551b feat: Add PostgreSQL configuration checksum and update container args 2025-09-07 12:25:41 +01:00
Simon Larsen
26b085030d refactor: Remove initContainers from PostgreSQL StatefulSet and enable default configuration settings 2025-09-07 12:17:13 +01:00
Simon Larsen
e1046d2424 Merge branch 'master' into bitnami-mgr-postgres 2025-09-07 11:08:46 +01:00
Simon Larsen
cf2a7b9dfa feat: Enhance diagnostics collection in KinD setup script 2025-09-07 11:05:34 +01:00
Simon Larsen
55f4c0b65d docs: Add SQL query to check used and free space in Postgres 2025-09-06 20:38:34 +01:00
Simon Larsen
5100fbda52 docs: Add SQL query to check used and free space in Clickhouse 2025-09-06 20:35:17 +01:00
Simon Larsen
9e36188975 fix: Update image registry and repository in ci-values.yaml 2025-09-06 17:47:47 +01:00
Simon Larsen
26c2d41dfa Merge branch 'master' into bitnami-mgr-postgres 2025-09-06 17:45:00 +01:00
Simon Larsen
a511a433b1 refactor: Remove security context and default profiles from ClickHouse configuration 2025-09-06 11:27:50 +01:00
Simon Larsen
cc581e91b5 Merge pull request #1994 from OneUptime/bitnami-mgr
Bitnami mgr
2025-09-06 11:09:13 +01:00
Simon Larsen
3fd95fe8aa Merge branch 'master' into bitnami-mgr 2025-09-06 11:09:01 +01:00
Simon Larsen
6f2455c265 fix: Set ClickHouse resourcesPreset to "none" to override default value 2025-09-05 21:26:00 +01:00
Simon Larsen
de5b32a609 refactor: Remove default resourcesPreset for ClickHouse configuration 2025-09-05 21:17:13 +01:00
Simon Larsen
155b0d90f1 refactor: Transition from MicroK8s to KinD for Kubernetes cluster setup in CI scripts 2025-09-05 21:15:58 +01:00
Simon Larsen
3da5e12a0d feat: Add auto-generated password option for ClickHouse configuration 2025-09-05 21:14:58 +01:00
Simon Larsen
8accdc6bd4 Merge branch 'master' of github.com:OneUptime/oneuptime 2025-09-05 20:56:35 +01:00
Simon Larsen
22a10702ac feat: Add comprehensive architecture diagram and explanation for self-hosted setup 2025-09-05 20:56:32 +01:00
Nawaz Dhandala
a013c86fae refactor: Standardize wait duration for pod readiness checks 2025-09-05 16:24:25 +01:00
Nawaz Dhandala
361626d21f refactor: Enhance pod readiness check with improved diagnostics and error handling 2025-09-05 16:23:01 +01:00
Simon Larsen
6615ac63d7 refactor: Simplify legal page structure and enhance navigation with Bootstrap styling 2025-09-05 14:50:22 +01:00
Simon Larsen
655611b28d refactor: Revamp support page layout and content for improved user experience 2025-09-05 14:45:55 +01:00
Simon Larsen
9bd45ecd14 Merge branch 'master' into bitnami-mgr-postgres 2025-09-05 14:01:46 +01:00
Simon Larsen
53c9babb83 refactor: Replace commented wait logic with active polling for pod readiness 2025-09-05 14:01:00 +01:00
Simon Larsen
ccc0b0142b feat: Remove default profiles configuration from ClickHouse settings in values.yaml 2025-09-05 13:51:07 +01:00
Simon Larsen
4a2f7f68cb feat: Update PostgreSQL password field to use 'postgresPassword' in values.yaml and secrets.yaml 2025-09-05 12:48:10 +01:00
Simon Larsen
de994e10de feat: Fix PostgreSQL username to be fixed as "postgres" in values.yaml 2025-09-05 12:21:43 +01:00
Simon Larsen
2ff22ca079 feat: Enhance security context handling for ClickHouse, PostgreSQL, and Redis StatefulSets 2025-09-05 12:06:28 +01:00
Simon Larsen
e6b8f60977 feat: Update security context for init and primary PostgreSQL containers 2025-09-05 11:59:37 +01:00
Simon Larsen
b823b5924a feat: Add init container for PostgreSQL configuration symlinks and update security context 2025-09-05 11:42:35 +01:00
Simon Larsen
a58ddd94d5 feat: Add POSTGRES_INITDB_ARGS environment variable for PostgreSQL initialization 2025-09-04 20:19:08 +01:00
Simon Larsen
275e15ce96 feat: Update PostgreSQL environment variables and liveness probe configuration 2025-09-04 20:12:20 +01:00
Simon Larsen
1e2a30823c feat: Remove PostgreSQL authentication environment variables from StatefulSet 2025-09-04 19:48:21 +01:00
Simon Larsen
a326e7084e feat: Remove PostgreSQL dependency and associated chart from Helm configuration 2025-09-04 17:55:18 +01:00
Simon Larsen
2c1d20f680 feat: Remove PostgreSQL dependency from Helm chart 2025-09-04 17:54:48 +01:00
Simon Larsen
95bd2db0dd feat: Add security context support for ClickHouse, PostgreSQL, and Redis StatefulSets 2025-09-04 17:44:59 +01:00
Simon Larsen
3ca875254c feat: Add PostgreSQL StatefulSet configuration to Helm chart 2025-09-04 17:35:39 +01:00
Simon Larsen
7f1f78dad6 feat: Add PostgreSQL Secret configuration to Helm chart 2025-09-04 17:27:49 +01:00
Simon Larsen
a0d6468aee feat: Add PostgreSQL ConfigMap and Service templates for Helm chart 2025-09-04 17:27:30 +01:00
Simon Larsen
914c9bc58e feat: Update PostgreSQL configuration in values.yaml and README for built-in support 2025-09-04 17:26:21 +01:00
Simon Larsen
b38031e9f7 feat: Add subPath for data and config mounts in ClickHouse StatefulSet 2025-09-04 17:03:57 +01:00
Simon Larsen
487ca71f84 fix: Rename volume and mount paths for Redis data in StatefulSet configuration 2025-09-04 15:30:27 +01:00
Simon Larsen
67cd8e7db6 refactor: Remove initContainers from ClickHouse StatefulSet configuration 2025-09-04 15:28:17 +01:00
Simon Larsen
f44017d710 feat: Add Helm annotations for release name and namespace in templates 2025-09-04 12:23:16 +01:00
Simon Larsen
78240b906b feat: Add ClickHouse StatefulSet configuration to Helm chart 2025-09-03 21:57:59 +01:00
Simon Larsen
2ef0b3be27 feat: Add ClickHouse ConfigMap template for configuration management 2025-09-03 21:43:20 +01:00
Simon Larsen
0792d8367a feat: Add ClickHouse service and secret configurations to Helm chart 2025-09-03 21:43:01 +01:00
Simon Larsen
920397cead fix: Remove ClickHouse chart package from the repository 2025-09-03 21:41:35 +01:00
Simon Larsen
42c18e94ab feat: Update ClickHouse configuration and service settings in values.yaml 2025-09-03 21:41:29 +01:00
Simon Larsen
533f7eb238 fix: Remove ClickHouse dependency from Chart.yaml and Chart.lock 2025-09-03 21:38:03 +01:00
Simon Larsen
e2f16e85f1 Merge pull request #1993 from OneUptime/bitnami-mgr
Bitnami mgr
2025-09-03 20:12:22 +01:00
Simon Larsen
c98e6b8471 feat: Add KEDA chart dependency to README 2025-09-03 20:12:09 +01:00
Simon Larsen
c16c13fd89 feat: Add built-in Redis configuration to README and update external Redis instructions 2025-09-03 20:10:43 +01:00
Simon Larsen
c8ce0e8819 fix: Remove Redis cluster configuration options from values.yaml 2025-09-03 20:00:14 +01:00
Simon Larsen
9e98f6acdb fix: Remove Redis replica persistence configuration from values.yaml 2025-09-03 19:50:07 +01:00
Simon Larsen
a7a5b15dde feat: Implement Redis StatefulSet configuration in Helm chart 2025-09-03 19:49:49 +01:00
Simon Larsen
3ebb5217a2 feat: Add Redis master and headless service definitions to Helm chart 2025-09-03 19:46:10 +01:00
Simon Larsen
f570ffe1e3 feat: Add Redis ConfigMap template to Helm chart for Redis configuration management 2025-09-03 19:43:57 +01:00
Simon Larsen
ae94bf6d7c fix: Simplify Redis password handling in Helm chart by removing unnecessary conditional checks 2025-09-03 19:42:28 +01:00
Simon Larsen
d9a6e465bb fix: Remove Redis authentication requirement in values.yaml 2025-09-03 19:42:11 +01:00
Simon Larsen
020b171b77 fix: Update Redis password handling in Helm chart to support optional authentication 2025-09-03 19:38:06 +01:00
Simon Larsen
afc4932c28 fix: Remove Redis dependency and related configurations from Helm chart 2025-09-03 19:37:30 +01:00
Nawaz Dhandala
324851c57e fix: Refactor service operations to execute sequentially with improved error handling in AlertService, IncidentService, MonitorService, and ScheduledMaintenanceService 2025-09-03 15:41:23 +01:00
Nawaz Dhandala
380ecfa096 Refactor code for consistency and readability
- Updated array and object property access from single quotes to double quotes in Pagination.ts and Permissions.ts for consistency.
- Added missing commas in function parameters and object literals across multiple files in AlertService.ts, IncidentService.ts, MonitorService.ts, ScheduledMaintenanceService.ts, and WorkspaceNotificationRuleService.ts.
- Improved error logging messages in various services for better clarity.
- Removed unnecessary line breaks in Slack.ts and Workspace.ts for cleaner code.
- Ensured consistent formatting in Routes.ts by adding missing commas and adjusting line breaks.
2025-09-03 15:37:39 +01:00
Simon Larsen
5f9f73ceaa fix: Refactor monitor creation operations to execute sequentially with improved error handling in MonitorService 2025-09-03 15:35:13 +01:00
Simon Larsen
038ca4a920 fix: Update imports and improve formatting in Routes.ts for consistency and readability 2025-09-03 15:34:29 +01:00
Simon Larsen
d15629da0f fix: Refactor scheduled maintenance operations to execute sequentially with improved error handling in ScheduledMaintenanceService 2025-09-03 15:21:03 +01:00
Simon Larsen
363bbf9dea fix: Refactor incident creation operations to execute sequentially with improved error handling in IncidentService 2025-09-03 15:17:16 +01:00
Simon Larsen
6f0a0c8e38 fix: Remove unnecessary line breaks in error messages and logging for improved readability in WorkspaceNotificationRuleService 2025-09-03 15:06:19 +01:00
Simon Larsen
a75a62c708 fix: Refactor promise chain to use async/await for better readability in AlertService; add debug logging in WorkspaceNotificationRuleService 2025-09-03 14:18:05 +01:00
Simon Larsen
db76d716b9 fix: Remove redundant logging of existing workspace channels for cleaner output 2025-09-03 14:02:12 +01:00
Simon Larsen
b0abbf64b4 fix: Improve logging format in postToWorkspaceChannels for better readability 2025-09-03 13:55:43 +01:00
Simon Larsen
3a432cf8e6 Response from Slack API for getting all channels: 2025-09-03 13:54:58 +01:00
Simon Larsen
5c7d18e3ed fix: Update createdByUser field to use _id for consistency in Alert, Incident, and Scheduled Maintenance services 2025-09-03 13:27:37 +01:00
Simon Larsen
2590850ffa fix: Correct projectId usage in alert feed info generation for accurate monitor links 2025-09-03 13:13:14 +01:00
Simon Larsen
0eeb80e16e fix: Add createdByUserId and createdByUser fields to alert, incident, and scheduled maintenance services for improved tracking 2025-09-03 13:09:38 +01:00
Simon Larsen
e1cfe24a24 fix: Update pageData property access to bracket notation for consistency 2025-09-02 22:59:23 +01:00
Simon Larsen
4e4f3a889d fix: Update type casting for statusReport and probeMonitorResponse to 'any' for improved flexibility 2025-09-02 22:51:41 +01:00
Nawaz Dhandala
ede7ae103d fix: Enhance MonitorTemplateUtil to support additional monitor types and improve type safety 2025-09-02 22:15:04 +01:00
Simon Larsen
075c0fb6bd fix: Enhance template variable support for additional monitor types in MonitorTemplateUtil and update documentation 2025-09-02 22:08:51 +01:00
Nawaz Dhandala
5ebdb1ef7d fix: Refactor code for improved readability and maintainability in various components 2025-09-02 21:57:15 +01:00
Simon Larsen
387dbf332e fix: Correct spelling in API endpoint routes for escalation rules 2025-09-02 21:48:54 +01:00
Simon Larsen
9681e1dc88 fix: Remove fallback syntax from incident alert templating examples for clarity 2025-09-02 21:47:05 +01:00
Simon Larsen
fb29014480 Merge branch 'dynamic-alert' 2025-09-02 21:45:15 +01:00
Simon Larsen
1a5c2efc59 fix: Add debug logging for storage map and template value replacement in MonitorTemplateUtil 2025-09-02 21:43:28 +01:00
Simon Larsen
3e31e44ed5 fix: Enhance value replacement logic to properly serialize objects in VMUtil class 2025-09-02 21:26:55 +01:00
Simon Larsen
9e69d69429 fix: Update titles and descriptions for Global Probes settings for clarity 2025-09-02 21:15:21 +01:00
Simon Larsen
a108deac0f fix: Improve documentation links in MonitorCriteriaAlertForm and MonitorCriteriaIncidentForm for clarity 2025-09-02 21:14:03 +01:00
Simon Larsen
c767f14bf1 fix: Correct syntax error in AlertService class 2025-09-02 21:11:28 +01:00
Simon Larsen
d69485c436 fix: Update Global Probes status messages for clarity in ProbePage component 2025-09-02 20:50:20 +01:00
Simon Larsen
67a5bdb7b8 feat: Update Global Probe settings card with improved descriptions and toggle functionality 2025-09-02 20:47:56 +01:00
Nawaz Dhandala
6504731025 refactor: Replace 'any' types with specific types for improved type safety across multiple files 2025-09-02 20:41:24 +01:00
Nawaz Dhandala
773692081c docs: Update guideline to specify stopping after fixing 25 files for review 2025-09-02 20:25:52 +01:00
Nawaz Dhandala
51c6234966 docs: Add guideline to replace "any" types with proper types 2025-09-02 20:23:53 +01:00
Nawaz Dhandala
fac6e9a1fe fix: Correct formatting issues in MonitorTemplateUtil and MonitorCriteriaAlertForm 2025-09-02 20:14:33 +01:00
Nawaz Dhandala
86e5d85d55 feat: Enhance dynamic template documentation links in MonitorCriteriaAlertForm and MonitorCriteriaIncidentForm 2025-09-02 20:10:14 +01:00
Simon Larsen
1c592435e9 Merge pull request #1990 from OneUptime/any-type
Any type
2025-09-02 20:02:38 +01:00
Nawaz Dhandala
02fed5bd6e refactor: Enhance type safety by explicitly defining ref types and simplifying conditional checks 2025-09-02 19:58:41 +01:00
Nawaz Dhandala
dd724fcc6e refactor: Improve type safety by updating formRef initialization and adding optional chaining for setFieldValue 2025-09-02 19:52:28 +01:00
Nawaz Dhandala
6ba26bcb82 refactor: Improve type safety by adding LayoutOptions type and removing 'any' casts in ServiceDependencyGraph 2025-09-02 19:51:45 +01:00
Nawaz Dhandala
799ab3220d refactor: Replace 'any' type with specific types for ref and input for improved type safety 2025-09-02 19:50:53 +01:00
Nawaz Dhandala
f73f2fb732 refactor: Change argValue type from any to unknown for better type safety 2025-09-02 19:50:34 +01:00
Simon Larsen
43d6ead92c fix: Correct formatting issues in MonitorAlert class logging and data processing 2025-09-02 19:22:31 +01:00
Simon Larsen
4c053b3f31 refactor: Improve formatting and readability in MonitorTemplateUtil methods 2025-09-02 19:02:29 +01:00
Simon Larsen
c026e411cf feat: Add dynamic template usage descriptions in MonitorCriteriaAlertForm and MonitorCriteriaIncidentForm 2025-09-02 19:01:22 +01:00
Simon Larsen
65a9e32db1 feat: Implement MonitorTemplateUtil for dynamic template processing in incidents and alerts 2025-09-02 18:58:15 +01:00
Simon Larsen
0b15e97e08 feat: Integrate MonitorTemplateUtil for dynamic alert and incident title/description processing 2025-09-02 18:56:19 +01:00
Simon Larsen
bd74b96596 feat: Add link to Incident & Alert Dynamic Templating documentation in navigation 2025-09-02 18:45:48 +01:00
Nawaz Dhandala
990d3ea750 feat: Add doNotAddGlobalProbesByDefaultOnNewMonitors column to Project table and update related files 2025-09-02 14:59:23 +01:00
Simon Larsen
30665a1907 feat: Add migration to introduce doNotAddGlobalProbesByDefaultOnNewMonitors column in Project table 2025-09-02 14:58:09 +01:00
Simon Larsen
04db4289fa feat: Add setting to control auto-adding of global probes to new monitors 2025-09-02 14:57:18 +01:00
Nawaz Dhandala
01f4c030a7 style: Format allowedDomains and homeUrl for improved readability 2025-09-02 14:29:17 +01:00
Simon Larsen
d060ed8b64 feat: Add dynamic robots.txt route to control indexing based on domain 2025-09-02 14:27:40 +01:00
Nawaz Dhandala
413240733e fix: Remove unnecessary blank lines in Markdown and Probe initialization files 2025-09-02 14:17:15 +01:00
Simon Larsen
b0799093dd feat: Enhance proxy agent support by specifying types for httpAgent and httpsAgent in WebsiteRequest and API classes 2025-09-02 14:10:42 +01:00
Simon Larsen
0ecdc775db feat: Refactor proxy configuration to use getRequestProxyAgents method across multiple modules 2025-09-02 14:02:40 +01:00
Simon Larsen
82065c20b1 feat: Add HTTP/HTTPS proxy support in FetchMonitorTest, FetchList, and Alive jobs 2025-09-02 13:58:15 +01:00
Simon Larsen
3dcd1ee604 feat: Add HTTP/HTTPS proxy support in probeMonitorTest and probeMonitor methods 2025-09-02 13:53:57 +01:00
Simon Larsen
f63c69e6a6 feat: Add per-request HTTP/HTTPS proxy agent support in API and WebsiteRequest classes 2025-09-02 13:52:25 +01:00
Simon Larsen
6ba793e871 refactor: Remove axios proxy configuration from ProxyConfig class 2025-09-02 13:49:58 +01:00
Simon Larsen
7afd243992 feat: Remove backticks from inline code rendering in Markdown 2025-09-01 21:19:39 +01:00
Simon Larsen
4f58155719 feat: Enhance inline code rendering by removing backticks from code content 2025-09-01 21:12:30 +01:00
Simon Larsen
553adc4aef feat: Add custom styling for inline code in Markdown renderer 2025-09-01 21:11:37 +01:00
Simon Larsen
f668a626d7 refactor: Simplify code block styling in Markdown renderer 2025-09-01 21:02:19 +01:00
Nawaz Dhandala
e3bd534295 refactor: Add missing commas in logging statements for SCIM and StatusPageSCIM 2025-09-01 20:50:53 +01:00
Simon Larsen
6aa5c3b314 feat: Enhance SCIM Users endpoint to support filtering by email and improve logging 2025-09-01 20:50:12 +01:00
Simon Larsen
3bc4f7267d refactor: Clean up logging statements and remove unnecessary commas in SCIM.ts 2025-09-01 20:48:54 +01:00
Simon Larsen
a7021cf045 refactor: Replace logSCIMOperation with logger.debug for consistent logging in SCIM and StatusPageSCIM 2025-09-01 20:40:27 +01:00
Simon Larsen
2709e1d976 feat: Update values.yaml to allow insecure images temporarily and specify legacy image repositories for PostgreSQL, ClickHouse, and Redis 2025-09-01 16:38:56 +01:00
Nawaz Dhandala
8ec9d2a930 feat: Add type annotations for proxy-related variables in ProxyConfig and monitors 2025-09-01 14:58:33 +01:00
Nawaz Dhandala
224c225789 Merge branch 'master' of https://github.com/OneUptime/oneuptime 2025-09-01 14:53:33 +01:00
Simon Larsen
85dae7a307 feat: Add proxy configuration options for probes in values.yaml and update README and probe.yaml 2025-09-01 14:53:24 +01:00
Nawaz Dhandala
332a479c22 feat: Improve proxy configuration handling and logging in monitors 2025-09-01 14:50:52 +01:00
Simon Larsen
d708fbbb52 feat: Add proxy configuration examples to Custom Probe documentation and component 2025-09-01 14:49:40 +01:00
Simon Larsen
03bceb959e feat: Enhance proxy support in SSL and Synthetic Monitors to prefer HTTPS, fallback to HTTP 2025-09-01 14:47:01 +01:00
Simon Larsen
efa411206e feat: Update SSL and Synthetic Monitors to use HTTPS proxy configuration 2025-09-01 14:41:57 +01:00
Simon Larsen
27fd99f2e8 feat: Update proxy configuration to support separate HTTP and HTTPS proxy URLs 2025-09-01 14:40:54 +01:00
Simon Larsen
07361bfeb7 feat: Enhance SyntheticMonitor with proxy support in browser launch options 2025-09-01 14:07:15 +01:00
Simon Larsen
bc8a5be0fa feat: Add proxy support for CustomCodeMonitor and SyntheticMonitor with logging 2025-09-01 14:00:55 +01:00
Simon Larsen
518768078a feat: Implement proxy configuration for HTTP requests and add ProxyConfig utility 2025-09-01 13:56:29 +01:00
Simon Larsen
86e95f99ff feat: Add PROXY_URL configuration option for probe and update example env file 2025-09-01 12:52:50 +01:00
Simon Larsen
ea48f56097 feat: Add custom styles for code blocks in blog posts 2025-09-01 12:43:03 +01:00
Nawaz Dhandala
b8b9dd859a Refactor migration files for consistency and readability; update BillingService and ProjectService for improved code clarity; enhance Countries interface formatting; standardize string quotes in various components; fix minor formatting issues in Settings and SendAnnouncementCreatedNotification. 2025-08-27 14:50:48 +01:00
Simon Larsen
d28c14ef24 feat: Update projectId reference in status page notification logic 2025-08-27 14:49:33 +01:00
Simon Larsen
670bec2a12 feat: Validate projectId and statusPageId in getStatusPageLinkInDashboard method 2025-08-27 14:48:40 +01:00
Simon Larsen
aff24845a8 feat: Add financeAccountingEmail handling in updateCustomerBusinessDetails method 2025-08-27 14:26:59 +01:00
Simon Larsen
f280e97c1b feat: Add migration for financeAccountingEmail field in Project model 2025-08-27 14:14:02 +01:00
Simon Larsen
62facf62dd feat: Add financeAccountingEmail field to Project model and update billing settings 2025-08-27 14:12:16 +01:00
Simon Larsen
db0387d81a feat: Update placeholder condition to include empty string check 2025-08-27 14:06:33 +01:00
Simon Larsen
5c4b19ab3d feat: Update nodemon configurations to improve performance and debugging options 2025-08-27 13:41:05 +01:00
Simon Larsen
463755fa4d This will be synced to Stripe and appear on future invoices. 2025-08-27 13:40:26 +01:00
Simon Larsen
85888572de feat: Update subscriber notification statuses to 'Success' for existing records in Incident and related tables 2025-08-27 13:20:07 +01:00
Simon Larsen
475bb25b2d feat: Add businessDetailsCountry field to Project migration and update index 2025-08-27 13:14:40 +01:00
Simon Larsen
badd200aed feat: Add country selection dropdown for billing details and implement country options 2025-08-27 13:14:01 +01:00
Simon Larsen
b40d87cbc9 feat: Add business details country field to Project model and update billing services to handle country code 2025-08-27 13:05:54 +01:00
Simon Larsen
36d0066b3a refactor: Simplify migration by removing unnecessary constraints and columns from Project and GlobalConfig tables 2025-08-27 13:03:01 +01:00
Simon Larsen
a49a0b2cba fix: Ensure blog post cards maintain full height for consistent layout 2025-08-27 12:48:41 +01:00
Simon Larsen
bada97d474 feat: Enhance customer address handling in Stripe by mapping business details to structured address fields 2025-08-27 12:42:17 +01:00
Simon Larsen
a1699f2d55 feat: Add business details field to Project model and update Stripe customer details 2025-08-27 12:37:09 +01:00
Simon Larsen
a11e054291 feat: Add custom link rendering with Tailwind styles and external link handling 2025-08-27 11:19:20 +01:00
Simon Larsen
47cf7ba763 fix: Increase timeout for SSL provisioning and delete old data jobs to accommodate longer processing times 2025-08-27 10:16:35 +01:00
Nawaz Dhandala
4e0dfb3664 fix: Simplify BadDataException handling for disabled and missing monitors in ingestion processes 2025-08-27 10:12:13 +01:00
Simon Larsen
250cb9e547 fix: Gracefully handle expected BadDataException cases for disabled and missing monitors in probe ingestion 2025-08-27 10:10:59 +01:00
Simon Larsen
541257e3c6 fix: Handle expected BadDataException cases for disabled and missing monitors in server monitor ingestion 2025-08-27 10:10:23 +01:00
Simon Larsen
ed43686736 fix: Centralize "Monitor disabled" message and improve error handling for disabled monitors 2025-08-27 10:09:26 +01:00
Simon Larsen
9ca45f23e3 fix: Replace hardcoded "Monitor not found" messages with centralized exception messages 2025-08-27 09:58:34 +01:00
Simon Larsen
e3573a9b77 fix: Refactor monitor not found error handling to use centralized exception messages 2025-08-27 09:55:19 +01:00
Simon Larsen
c9e78044e6 fix: Improve error handling in incoming request ingestion worker to handle disabled monitors gracefully 2025-08-27 09:48:54 +01:00
Nawaz Dhandala
813581dec5 fix: Add return type to logoutUser method and specify type for route in navigateToLoginPage method 2025-08-26 21:39:35 +01:00
Nawaz Dhandala
e528decf73 fix: Refactor QueueWorker options handling; improve logoutUser method formatting and navigation logic in StatusPageUtil 2025-08-26 21:36:56 +01:00
Simon Larsen
42ef41ede8 fix: Enhance QueueWorker options with lock duration and max stalled count; improve telemetry processing with yielding to avoid stall detection 2025-08-26 21:32:38 +01:00
Simon Larsen
af26472db4 fix: Simplify email validation logic and improve user lookup in SCIM user operations 2025-08-26 21:24:39 +01:00
Simon Larsen
44b5c8b668 fix: Enhance email validation and logging in SCIM user operations 2025-08-26 20:47:50 +01:00
Simon Larsen
d821b88ed7 fix: Update Docker image tags and labels for multiple services in release workflow 2025-08-26 18:52:15 +01:00
Simon Larsen
1df43e21ff fix: Refactor logoutUser method and enhance navigation logging in StatusPageUtil 2025-08-26 18:37:49 +01:00
Simon Larsen
76ca6ee7e1 fix: Add missing continuation for APP_VERSION build argument in multiple Docker image deploy jobs 2025-08-26 18:25:32 +01:00
Simon Larsen
dac731a57b refactor: Remove unused mock for ProjectUserService in TeamMemberService tests 2025-08-26 16:56:52 +01:00
Simon Larsen
0f4b248598 fix: Add missing context for Docker image build in nginx deployment 2025-08-26 16:53:25 +01:00
Simon Larsen
b2c14e0380 fix: Add missing build context for multiple Docker image deploy jobs 2025-08-26 16:51:51 +01:00
Simon Larsen
3ab9705bbe fix: Allow deletion of teams in Users component by setting isDeleteable to true 2025-08-26 16:34:19 +01:00
Nawaz Dhandala
40812c8749 refactor: Clean up whitespace in TeamMemberService and SCIM files; update description formatting in Users component 2025-08-26 15:59:22 +01:00
Simon Larsen
45ae1501f2 refactor: Replace ProjectUser with TeamMember in SCIM query for team members 2025-08-26 15:55:23 +01:00
Simon Larsen
13d9f19606 refactor: Remove ProjectUserService calls to streamline TeamMemberService operations 2025-08-26 15:52:28 +01:00
Simon Larsen
ad3221310a refactor: Remove ProjectUser model and associated service to streamline user management 2025-08-26 15:51:06 +01:00
Simon Larsen
659042fcfb fix: Update isCreateable property to false for Teams component 2025-08-26 14:43:54 +01:00
Simon Larsen
d65b9c7b29 feat: Refactor Teams component to use TeamMember model and update filtering logic 2025-08-26 14:42:14 +01:00
Simon Larsen
dc77206e6f feat: Add debug logging for SCIM team operations to track user additions 2025-08-26 14:25:31 +01:00
Nawaz Dhandala
9c1910d3f1 refactor: Remove unnecessary context argument from Docker build commands in workflows 2025-08-26 14:09:31 +01:00
Nawaz Dhandala
afe8f8e6f4 refactor: Implement retry mechanism for account and isolated VM compilation steps in workflows 2025-08-26 13:15:54 +01:00
Nawaz Dhandala
015bd0f870 refactor: Implement retry mechanism for Docker image builds in multiple workflows 2025-08-26 13:12:18 +01:00
Nawaz Dhandala
383c145186 refactor: Integrate retry mechanism for Docker image builds in workflows 2025-08-26 13:06:55 +01:00
Simon Larsen
f155795e6b fix: Remove single quotes from changelog delimiter for correct output formatting 2025-08-26 11:56:22 +01:00
Nawaz Dhandala
757f5b5721 refactor: Improve type annotations for better clarity in error handling 2025-08-26 11:42:15 +01:00
Nawaz Dhandala
694215df06 refactor: Improve code formatting for better readability in multiple files 2025-08-26 11:40:01 +01:00
Nawaz Dhandala
0eb6022f1d Merge branch 'master' of https://github.com/OneUptime/oneuptime 2025-08-26 11:38:10 +01:00
Nawaz Dhandala
3109006828 refactor: Replace regex literals with RegExp constructor for improved clarity in MarkdownViewer and StringUtils 2025-08-26 11:38:08 +01:00
Simon Larsen
272695bd11 feat: Enhance error handling and logging in processMetricsAsync and processTracesAsync methods for improved robustness 2025-08-26 11:36:47 +01:00
Simon Larsen
330e3bc106 fix: Correct syntax error in JavaScript expression example for incoming request monitors 2025-08-26 11:26:01 +01:00
Nawaz Dhandala
c7876bf3a3 refactor: Improve regex pattern for fact extraction and enhance code formatting in OtelIngestService 2025-08-26 11:22:36 +01:00
Simon Larsen
345ada5404 feat: Enhance error handling and logging in processLogsAsync method for improved telemetry data ingestion 2025-08-26 11:16:32 +01:00
Simon Larsen
4f97b1b460 feat: Enhance image loading and layout stability across blog views 2025-08-25 10:46:19 +01:00
Nawaz Dhandala
e35ef1809f refactor: Improve code formatting and consistency across Microsoft Teams integration files 2025-08-21 14:45:34 +01:00
Simon Larsen
c2926f3542 feat: Implement structured MessageCard creation from markdown for Microsoft Teams
- Added a method to build a structured MessageCard from markdown input, enhancing message formatting for Teams.
- Extracted title, facts, and actions from markdown to improve rendering in Teams notifications.
2025-08-21 14:43:13 +01:00
Simon Larsen
9495b4bd47 feat: Add Microsoft Teams incoming webhook option to subscriber settings
- Introduced a new property for Microsoft Teams incoming webhook URL in the StatusPageSubscriberService.
- Enhanced subscriber configuration to support Microsoft Teams notifications.
2025-08-21 14:25:49 +01:00
Simon Larsen
ad3f36fdf5 refactor: Simplify Slack and Microsoft Teams notification handling in StatusPageSubscriberService
- Removed try-catch blocks for sending notifications and replaced them with promise chaining for better readability.
- Added logging for successful notification sends and error handling directly in the promise catch.
2025-08-21 14:11:06 +01:00
Simon Larsen
f2221b0a40 feat: Implement Microsoft Teams webhook validation and notification in StatusPage subscriber service
- Added validation for Microsoft Teams incoming webhook URL during subscriber setup.
- Implemented notification sending to Microsoft Teams channel upon successful subscription.
- Updated SideMenu components to reflect the new naming convention for Microsoft Teams subscribers.
2025-08-21 14:04:20 +01:00
Simon Larsen
62fbc1f4be feat: Enhance Microsoft Teams subscriber validation and handling in StatusPage API
- Added validation to ensure Microsoft Teams subscribers are only processed if enabled.
- Updated error messages to include Microsoft Teams workspace name requirements.
- Implemented handling for Microsoft Teams incoming webhook URL and workspace name in subscriber setup.
2025-08-21 13:52:35 +01:00
Simon Larsen
054a2bc8f5 feat: Enable Microsoft Teams subscribers in StatusPage API 2025-08-21 13:49:28 +01:00
Simon Larsen
896787109c feat: Add Microsoft Teams subscriber option to Email, Slack, and SMS subscription pages 2025-08-21 13:47:13 +01:00
Simon Larsen
3a55fcc872 feat: Update microsoftTeamsIncomingWebhookUrl column type to text and add migration 2025-08-21 13:27:44 +01:00
Simon Larsen
2945a48d05 feat: Update microsoftTeamsWorkspaceName column type to VeryLongText and add migration 2025-08-21 13:15:44 +01:00
Simon Larsen
da3a7ddb2e feat: Add migration for Microsoft Teams subscriber functionality in StatusPage 2025-08-21 12:57:16 +01:00
Simon Larsen
04a0bfedaa fix: Make Microsoft Teams subscriber prop required in SideMenu component 2025-08-21 12:17:00 +01:00
Simon Larsen
fa5c7b1e73 feat: Add Microsoft Teams subscriber functionality
- Implemented Microsoft Teams subscribers in the dashboard side menu.
- Created Microsoft Teams subscriber settings page with toggle options.
- Added routes for Microsoft Teams subscribers in the routing configuration.
- Updated page map and route map to include Microsoft Teams subscriber paths.
- Enhanced the app state management to handle Microsoft Teams subscription settings.
- Integrated Microsoft Teams notification sending in the announcement and incident jobs.
- Developed Microsoft Teams subscription management and creation forms.
- Added UI components for managing Microsoft Teams subscribers in the status page.
2025-08-21 12:09:53 +01:00
Simon Larsen
a1c2918cd7 feat: Update homepage heading for improved clarity and emphasis on monitoring capabilities 2025-08-21 10:24:49 +01:00
Simon Larsen
91b11b12c1 fix: Update canonical links for blog posts and remove redundant canonical tags in head partials 2025-08-21 10:15:52 +01:00
Simon Larsen
778a34d631 feat: Implement fallback to commit messages in changelog if empty 2025-08-20 09:17:53 +01:00
Simon Larsen
6dbd838ca4 refactor: Remove mobile redirect script from homepage for cleaner code 2025-08-19 22:23:20 +01:00
Simon Larsen
e09634dc6f feat: Enhance blog listing with featured post display and improved layout 2025-08-19 22:21:12 +01:00
Simon Larsen
af60715de2 Merge branch 'master' of github.com:OneUptime/oneuptime 2025-08-19 22:11:14 +01:00
Simon Larsen
3b4c54876e feat: Update default page size for blog pagination from 50 to 24 for improved performance 2025-08-19 22:11:12 +01:00
Nawaz Dhandala
e357100e46 refactor: Remove redundant dynamic section checks from sitemap tests 2025-08-19 20:43:08 +01:00
Simon Larsen
7f3a50076d feat: Add reference section check to sitemap tests for improved coverage 2025-08-19 14:25:37 +01:00
Simon Larsen
9d182b6d55 feat: Add additional static paths to sitemap generation for improved coverage 2025-08-19 14:25:16 +01:00
Simon Larsen
33fce0b53c feat: Implement caching for home URL retrieval to improve performance 2025-08-19 14:15:47 +01:00
Nawaz Dhandala
3db8419349 refactor: Simplify error handling in BlogPostUtil by removing unused error variables 2025-08-19 13:50:35 +01:00
Nawaz Dhandala
dfc324b099 refactor: Improve code formatting and readability in Markdown and BlogPost utilities 2025-08-19 12:58:17 +01:00
Simon Larsen
36521ef37c feat: Update blog post listing to improve layout and add Open Source Commitment section 2025-08-19 12:55:09 +01:00
Simon Larsen
a6f336340e feat: Implement pagination and tag filtering for blog posts 2025-08-19 12:40:51 +01:00
Simon Larsen
c36f782192 feat: Refactor blog post listing and tags display for improved layout and user experience 2025-08-19 12:34:23 +01:00
Simon Larsen
5219f1cfc0 feat: Remove unused imports and the getNameOfGitHubUser function from BlogPostUtil class 2025-08-19 12:29:27 +01:00
Simon Larsen
7f84d50baa feat: Add optional bio field for authors and update blog post template to display it 2025-08-19 12:28:12 +01:00
Simon Larsen
cd2ce3f1a8 feat: Add a newline for improved readability in BlogPostUtil class 2025-08-19 12:15:23 +01:00
Simon Larsen
01b0e01ca8 feat: Implement caching for blog metadata and improve author resolution without GitHub API calls 2025-08-19 12:07:33 +01:00
Simon Larsen
73dc6bb5db feat: Remove social media image display from blog post template 2025-08-19 11:55:38 +01:00
Simon Larsen
ab7fc1c244 feat: Enhance Markdown renderer with improved code block styling and add support for horizontal rules, emphasis, and strikethrough 2025-08-19 11:50:48 +01:00
Simon Larsen
3927bea29c feat: Enhance Markdown rendering with improved list, table, and inline code support; update tag display styling for better visual consistency 2025-08-19 11:47:21 +01:00
Simon Larsen
6060d66c2b feat: Revamp blog post layout with enhanced styling, author details, and reading time estimation 2025-08-19 11:37:10 +01:00
Nawaz Dhandala
9f4869b05f test: Enhance sitemap tests to validate presence of dynamic sections 2025-08-19 10:07:11 +01:00
Nawaz Dhandala
17bdfee012 refactor: Simplify regex usage in sitemap tests and improve middleware formatting 2025-08-19 10:05:59 +01:00
Simon Larsen
4988b9fc7a feat: Refactor mobile menu implementation for improved accessibility and usability 2025-08-19 10:04:20 +01:00
Simon Larsen
9edc6b9f18 feat: Enhance mobile navigation and improve header styling for better accessibility 2025-08-19 09:58:03 +01:00
Simon Larsen
525e19faa6 feat: Improve tab accessibility and keyboard navigation with semantic identifiers 2025-08-19 09:49:23 +01:00
Simon Larsen
588e8976d2 feat: Add middleware to inject home URL for canonical links and update canonical tag in head-basic.ejs 2025-08-19 09:47:59 +01:00
Simon Larsen
d5e28e98fb Merge branch 'master' of github.com:OneUptime/oneuptime 2025-08-19 09:39:45 +01:00
Simon Larsen
0e84bc9c40 feat: Enhance accessibility and keyboard navigation for product tabs 2025-08-19 09:39:42 +01:00
Nawaz Dhandala
39e8b1da6b refactor: Enhance type annotations and improve code readability in sitemap tests 2025-08-18 13:47:35 +01:00
Nawaz Dhandala
66c4badd94 refactor: Improve formatting of product pages check in sitemap tests 2025-08-18 13:41:01 +01:00
Simon Larsen
a245fabc34 feat: Add end-to-end tests for sitemap loading and validation 2025-08-18 13:39:19 +01:00
Nawaz Dhandala
fa9fce2774 refactor: Improve type annotations and error handling in various modules 2025-08-18 12:59:17 +01:00
Nawaz Dhandala
a256f4be54 Refactor logging statements for improved readability and consistency across services
- Updated logging statements in Sitemap.ts to enhance code clarity.
- Reformatted logger.info calls in IncomingRequestIngest, OpenTelemetryIngest, Probe, ProbeIngest, and ServerMonitorIngest to use multi-line formatting for better readability.
- Adjusted import statements in Probe to follow a consistent multi-line format.
2025-08-18 12:48:23 +01:00
Simon Larsen
4869172648 feat: Ensure home URL is prioritized in sitemap XML generation 2025-08-18 12:46:45 +01:00
Simon Larsen
1abd323b00 feat: Refactor sitemap generation and clean up unused imports 2025-08-18 12:45:06 +01:00
Simon Larsen
fa196a55cd feat: Update XML builder import and fix attribute assignment in URL set creation 2025-08-18 12:32:57 +01:00
Simon Larsen
29b4417aca feat: Update robots.txt to remove disallowed paths and simplify access 2025-08-18 12:31:57 +01:00
Simon Larsen
29c0d7e7e9 Merge branch 'master' of github.com:OneUptime/oneuptime 2025-08-16 15:04:23 +01:00
Simon Larsen
bfbe2437c0 feat: Add concurrency logging for various ingest services 2025-08-16 15:04:10 +01:00
Nawaz Dhandala
ca0e082daf refactor: Simplify mock setup for ProjectUserService in TeamMemberService tests 2025-08-15 19:06:41 +01:00
Nawaz Dhandala
1987b1c42e refactor: Add type annotations for domain and verificationText variables in DNS tests 2025-08-15 16:31:23 +01:00
Nawaz Dhandala
38be6edec3 feat: Improve DNS error handling with user-friendly messages and enhance tests for TXT and CNAME record verification 2025-08-15 16:29:41 +01:00
Simon Larsen
b80dda6d1a feat: Enhance DNS error handling with user-friendly messages and add tests for TXT and CNAME record verification 2025-08-15 16:23:56 +01:00
Simon Larsen
f65b2711ca feat: Change Repeat Policy Times column type from Boolean to Number 2025-08-15 11:49:57 +01:00
Simon Larsen
151c3d8c52 feat: Update logging scripts in package.json to include follow-logs command and adjust logs command 2025-08-15 11:48:16 +01:00
Simon Larsen
f17ae36dce docs: Update TerraformBuild.md to clarify restrictions on editing API key and oneuptime_url variables 2025-08-15 11:45:31 +01:00
Simon Larsen
777c6948ad feat: Add Terraform provider generation and installation instructions 2025-08-15 11:42:03 +01:00
Simon Larsen
1c6f9adbcb Merge branch 'release' of github.com:OneUptime/oneuptime into release 2025-08-14 13:52:14 +01:00
Simon Larsen
6d1b3f8568 Merge branch 'master' into release 2025-08-14 13:52:00 +01:00
Simon Larsen
11526816d1 feat: Add onCallScheduleId to UserNotificationRuleService and UserOnCallLogService for enhanced tracking 2025-08-14 13:44:45 +01:00
Nawaz Dhandala
bf190b6a32 refactor: Clean up code formatting and improve readability across multiple services and components 2025-08-14 13:10:43 +01:00
Simon Larsen
4736ea8227 feat: Refine extractSayMessagesFromCallRequest to focus on main messages for call summary 2025-08-14 12:59:38 +01:00
Simon Larsen
2cb4281fc3 feat: Update viewPageRoute in ExecutionLogsTable to use RouteUtil for dynamic route population 2025-08-14 12:47:16 +01:00
Simon Larsen
505ed980c3 feat: Improve sayMessage extraction from onInputCallRequest in CallService 2025-08-14 12:44:47 +01:00
Simon Larsen
a0b77c94b0 feat: Enhance message extraction in CallService to include onInputCallRequest messages 2025-08-14 12:37:46 +01:00
Simon Larsen
bb996ddaa2 feat: Add OnCall-related fields to notification services for enhanced tracking 2025-08-14 12:26:51 +01:00
Simon Larsen
a2f8e49bc1 feat: Enhance channel retrieval in Slack and MicrosoftTeams with error handling and fallback mechanism 2025-08-14 11:38:37 +01:00
Simon Larsen
4d6086b7fd feat: Enhance modal display in PushLogsTable with Markdown support for better formatting 2025-08-14 11:26:20 +01:00
Simon Larsen
f84a1db36a refactor: Improve modal text handling in CallLogsTable and remove unused Device Type column in PushLogsTable 2025-08-14 11:21:20 +01:00
Simon Larsen
3aa4214e54 fix: Update condition for rendering placeholder in Detail component for better null handling 2025-08-14 11:12:53 +01:00
Simon Larsen
2fb8341f9c feat: Add default value for actionType in WorkspaceNotificationLog for improved tracking 2025-08-13 21:10:09 +01:00
Simon Larsen
888d18d0a3 Merge branch 'master' of github.com:OneUptime/oneuptime 2025-08-13 21:01:53 +01:00
Simon Larsen
7f8270fac1 refactor: Add actionType to log in send message functionality for better tracking 2025-08-13 21:01:46 +01:00
Simon Larsen
318c1516cd Merge pull request #1981 from OneUptime/master
Release
2025-08-13 19:50:22 +01:00
Nawaz Dhandala
0343dcca93 refactor: Improve mail sending logic in UserService for better readability and consistency 2025-08-13 19:50:05 +01:00
Simon Larsen
7728e38029 refactor: Rename messageSummary to message in WorkspaceNotificationLog and related services for consistency 2025-08-13 19:49:36 +01:00
Simon Larsen
83a0efcbb9 refactor: Remove length restriction on joined strings in WorkspaceNotificationRuleService for improved readability 2025-08-13 19:42:17 +01:00
Simon Larsen
577ba9436e refactor: Simplify return logic in Service class and remove unnecessary TypeScript ignore comment in StatusPagesRoutes 2025-08-13 19:41:37 +01:00
Simon Larsen
a521f42417 Merge branch 'master' of github.com:OneUptime/oneuptime 2025-08-13 19:38:06 +01:00
Simon Larsen
1002616ab3 refactor: Remove redundant userId parameter from service calls for cleaner code 2025-08-13 19:38:02 +01:00
Nawaz Dhandala
13adbd2443 refactor: Update MigrationName1755109893911 for consistent formatting and include in index 2025-08-13 19:36:34 +01:00
Simon Larsen
12b82252f1 refactor: Remove unnecessary await from CallService.makeCall in UserNotificationRuleService and UserNotificationSettingService for improved performance 2025-08-13 19:35:43 +01:00
Simon Larsen
bdb9cb9b9a Merge branch 'master' of github.com:OneUptime/oneuptime 2025-08-13 19:32:27 +01:00
Simon Larsen
c5e19db669 refactor: Add deviceName column to PushNotificationLog and update default actionType in WorkspaceNotificationLog for improved tracking 2025-08-13 19:32:23 +01:00
Nawaz Dhandala
345bdf80e1 refactor: Update device handling in PushNotification to support new devices format and improve error handling 2025-08-13 19:29:55 +01:00
Nawaz Dhandala
c4bf5e5001 refactor: Enhance device handling in PushNotification and improve type safety in PushNotificationService and PushLogsTable 2025-08-13 19:25:27 +01:00
Nawaz Dhandala
a3685b3698 refactor: Update push notification handling to use devices array with optional device names for improved clarity 2025-08-13 19:20:27 +01:00
Nawaz Dhandala
388f6e3530 refactor: Add deviceName field to PushNotificationLog and update PushLogsTable for improved device tracking 2025-08-13 19:09:32 +01:00
Nawaz Dhandala
0493dabb93 refactor: Remove unnecessary whitespace in makeCall method for improved code consistency 2025-08-13 18:57:10 +01:00
Simon Larsen
2383b2d352 refactor: Replace userBelongsToTeamId with teamId in CallService, UserNotificationRuleService, and UserNotificationSettingService for consistency 2025-08-13 18:56:21 +01:00
Simon Larsen
c526c0e320 refactor: Replace userBelongsToTeamId and overridedByUserId with teamId in notification services for consistency 2025-08-13 18:45:42 +01:00
Nawaz Dhandala
7d607608b3 refactor: Enhance user display handling in notification log tables for improved clarity 2025-08-13 18:18:27 +01:00
Nawaz Dhandala
abece559ea refactor: Simplify onClick handlers in CallLogsTable and EmailLogsTable for improved readability 2025-08-13 18:09:46 +01:00
Simon Larsen
f9b0c499ed refactor: Simplify props in CallLogsTable, EmailLogsTable, PushLogsTable, SmsLogsTable, and WorkspaceLogsTable for improved readability and maintainability 2025-08-13 18:07:26 +01:00
Nawaz Dhandala
38594f5198 refactor: Align query prop indentation in PushLogsTable, SmsLogsTable, and WorkspaceLogsTable for consistency 2025-08-13 18:00:41 +01:00
Simon Larsen
8f08ec42c7 refactor: Update query prop type to use Query<BaseModel> for improved type safety in log tables 2025-08-13 17:59:59 +01:00
Simon Larsen
8c697149e3 refactor: Remove unused log components (CallLog, EmailLog, PushLog, SmsLog) 2025-08-13 17:57:56 +01:00
Simon Larsen
2ff3dee440 refactor: Remove CallLog, EmailLog, and SmsLog components to streamline dashboard settings 2025-08-13 17:52:07 +01:00
Nawaz Dhandala
c0e8193614 refactor: Update NotificationLogsTabs to use typed Query object for improved type safety 2025-08-13 17:42:14 +01:00
Nawaz Dhandala
c1d06fdae5 refactor: Simplify component formatting in NotificationLogsTabs and related pages 2025-08-13 17:40:33 +01:00
Simon Larsen
00ed20ea68 fix: Update import path for NotificationLogs component in ScheduledMaintenanceEventsRoutes 2025-08-13 17:40:02 +01:00
Simon Larsen
db93cc8841 Merge branch 'master' of github.com:OneUptime/oneuptime 2025-08-13 17:37:41 +01:00
Simon Larsen
374e8ecb4c refactor: Update NotificationLogsTabs to use query object for improved flexibility 2025-08-13 17:37:14 +01:00
Nawaz Dhandala
9ac17850a6 refactor: Simplify MailService sendMail calls and improve formatting in Notification components 2025-08-13 17:34:58 +01:00
Simon Larsen
a38d75b8f0 Refactor Notification Logs: Consolidate Tabs into NotificationLogsTabs Component
- Removed individual log components for Email, SMS, Call, Push, and Workspace from various pages.
- Replaced existing tab implementations with a unified NotificationLogsTabs component.
- Updated pages for Incidents, OnCallDuty, ScheduledMaintenanceEvents, StatusPages, and Settings to use the new NotificationLogsTabs.
- The NotificationLogsTabs component dynamically generates tabs based on the provided singular name and query key.
2025-08-13 17:32:47 +01:00
Simon Larsen
1bfdf90bca fix: Remove unnecessary userId parameter from signup request handling 2025-08-13 17:30:33 +01:00
Simon Larsen
49e3db9442 fix: Update icon in SideMenu components from List to Bell for improved clarity 2025-08-13 17:19:18 +01:00
Simon Larsen
83ab7030a4 fix: Update icon for SideMenuItem to improve visual consistency 2025-08-13 17:18:18 +01:00
Simon Larsen
76abf62917 feat: Add on-call policy related fields to notification services and API endpoints 2025-08-13 17:13:04 +01:00
Simon Larsen
a5c2f19846 fix: Remove unnecessary userId parameter from signup response handling 2025-08-13 15:59:01 +01:00
Simon Larsen
d37e783aeb fix: Remove unnecessary userId parameter from signup request handling 2025-08-13 15:58:17 +01:00
Simon Larsen
657ea0ec09 refactor: Update default messages in notification log tables to specify project context 2025-08-13 15:56:27 +01:00
Simon Larsen
e59f7a0a7f refactor: Update action type values in WorkspaceNotificationLog and related services for consistency 2025-08-13 15:55:02 +01:00
Nawaz Dhandala
35fc80de1e refactor: Rename "Initiated by" to "User" in notification log tables for consistency 2025-08-13 15:21:49 +01:00
Nawaz Dhandala
5e2dea40a3 refactor: Adjust formatting in Tabs component for improved readability 2025-08-13 15:18:30 +01:00
Nawaz Dhandala
a66f92e0b9 refactor: Simplify TabElement class assignment and clean up Tabs component structure 2025-08-13 15:16:58 +01:00
Nawaz Dhandala
a2ce7c9433 refactor: Remove unnecessary blank line before SettingsWorkspaceLog component 2025-08-13 15:02:49 +01:00
Nawaz Dhandala
eab1dc4b1b refactor: Replace SettingsWorkspaceLog component with direct import of WorkspaceLogsTable and remove unused WorkspaceLog file 2025-08-13 15:01:23 +01:00
Nawaz Dhandala
6939c70ed8 feat: Add actionType to WorkspaceNotificationLog and update OnCallDutyPolicyScheduleLayer defaults in migration 2025-08-13 14:58:11 +01:00
Simon Larsen
cce0dc8a45 feat: Add migration to include actionType in WorkspaceNotificationLog and update OnCallDutyPolicyScheduleLayer defaults 2025-08-13 14:53:05 +01:00
Simon Larsen
ec51d7b574 Merge branch 'master' of github.com:OneUptime/oneuptime 2025-08-13 14:38:16 +01:00
Simon Larsen
d4129cfa8e fix: Correct permission assignment for creating incident state timelines 2025-08-13 14:38:12 +01:00
Nawaz Dhandala
1ee7c092d3 Refactor Workspace Notification Log Service and related components
- Added missing commas in migration index for consistency.
- Cleaned up whitespace in WorkspaceNotificationLogService for better readability.
- Updated logChannelCreated and logUserInvited methods to improve code clarity.
- Enhanced button press logging in Slack actions for better error handling.
- Standardized formatting in ScheduledMaintenance and Incident Slack actions.
- Improved code structure in UptimeUtil for better readability.
- Refactored Notification components in Dashboard for consistent formatting.
- Updated WorkspaceLog component to include color typing for action types.
2025-08-13 14:30:51 +01:00
Simon Larsen
daf3b13e00 refactor: Remove unused resource association logic from user invitation process 2025-08-13 14:27:09 +01:00
Simon Larsen
5035319cc6 feat: Add action type column to WorkspaceLogsTable for improved visibility 2025-08-13 14:23:17 +01:00
Simon Larsen
3d53889d1e feat: Refactor notification log components to simplify structure and improve readability 2025-08-13 14:22:19 +01:00
Simon Larsen
65b610ebbb feat: Enhance WorkspaceLog with action type display and filtering options 2025-08-13 14:09:49 +01:00
Simon Larsen
30d1b43178 feat: Add WorkspaceNotificationActionType enum for notification actions 2025-08-13 14:08:35 +01:00
Simon Larsen
d0645f5dc2 feat: Add on-call duty policy fields and constraints to log tables 2025-08-13 13:42:31 +01:00
Simon Larsen
2274c14098 feat: Add On-Call Duty Policy and Schedule Notification Logs
- Enhanced PushNotificationLog, SmsLog, and WorkspaceNotificationLog models to include relationships with OnCallDutyPolicy, OnCallDutyPolicyEscalationRule, OnCallDutyPolicySchedule, and Team.
- Introduced new NotificationLogs components for OnCallDutyPolicy and OnCallDutySchedule, allowing users to view logs for Email, SMS, Call, Push, and Workspace notifications.
- Updated SideMenu components to include links to the new Notification Logs pages for both OnCallDutyPolicy and OnCallDutySchedule.
- Added routes and page mappings for the new Notification Logs views in OnCallDutyRoutes and PageMap.
2025-08-13 13:40:32 +01:00
Simon Larsen
d1b4d3867a feat: Enhance event overlap checks for today's events in DayUptimeGraph and UptimeUtil 2025-08-13 13:18:08 +01:00
Simon Larsen
04d4712c81 feat: Add Notification Logs section and related components for scheduled maintenance events 2025-08-13 12:58:42 +01:00
Nawaz Dhandala
9c2d2b658b refactor: Simplify event overlap check for today's events in DayUptimeGraph 2025-08-13 12:37:00 +01:00
Nawaz Dhandala
fdb1444dc8 fix: Specify type for loop index in push log creation for clarity 2025-08-13 12:24:55 +01:00
Nawaz Dhandala
39f724b77f fix: Make 'name' property public in MigrationName class for consistency 2025-08-13 12:24:08 +01:00
Nawaz Dhandala
dbfa153209 feat: Add userId tracking to email notifications and enhance logging across services 2025-08-13 12:23:45 +01:00
Simon Larsen
1c8739237f feat: Add userId tracking to email notifications across various services 2025-08-13 12:13:19 +01:00
Simon Larsen
26cdaacf6b feat: Add AlertDescription lazy import and route for alert view description 2025-08-13 11:55:28 +01:00
Simon Larsen
bbc8f0c680 feat: Add userId field to various services for enhanced tracking and logging 2025-08-12 21:54:51 +01:00
Simon Larsen
61dd8e9202 feat: Add userId field to notification logs and services for tracking user actions 2025-08-12 21:33:29 +01:00
Simon Larsen
6e17832239 feat: Enhance PushNotificationService with detailed logging and error handling 2025-08-12 21:00:30 +01:00
Simon Larsen
6460827c4c refactor: Remove Thread ID column from WorkspaceLogsTable 2025-08-12 20:40:22 +01:00
Simon Larsen
7bfd810b73 feat: Integrate MarkdownViewer for modal description in WorkspaceLogsTable 2025-08-12 19:46:18 +01:00
Simon Larsen
8b17217778 refactor: Remove redundant error logging for missing threads in workspace notification service 2025-08-12 19:44:24 +01:00
Simon Larsen
19a86e9683 fix: Change type of elk variable to any in ServiceDependencyGraph component 2025-08-12 19:23:10 +01:00
Simon Larsen
d2fd46db50 Merge branch 'master' of github.com:OneUptime/oneuptime 2025-08-12 17:39:52 +01:00
Simon Larsen
26cfbd07cb feat: Add server names hash tuning options to nginx configuration 2025-08-12 17:39:47 +01:00
Nawaz Dhandala
33992984e2 fix: Correct indentation for metrics endpoint exposure in WorkersFeatureSet 2025-08-12 17:38:38 +01:00
Nawaz Dhandala
e295c19b19 feat: Implement KEDA autoscaling for worker service with metrics endpoint 2025-08-12 17:37:13 +01:00
Nawaz Dhandala
51d42c8436 feat: Update no items message in Notification Logs tables to include pluralization 2025-08-12 14:57:25 +01:00
Nawaz Dhandala
50f16d0fdc Refactor Notification Logs Tables and Related Components
- Updated EmailLogsTable, PushLogsTable, and SmsLogsTable components for improved readability and consistency in code formatting.
- Enhanced the structure of props in various components to maintain uniformity.
- Refactored the return statements in several components to use consistent formatting.
- Cleaned up unnecessary whitespace and improved the organization of imports across multiple files.
- Adjusted the breadcrumb and route mapping for better clarity and maintainability.
2025-08-11 16:48:29 +01:00
Nawaz Dhandala
726ab4d7c0 Merge branch 'master' of https://github.com/OneUptime/oneuptime 2025-08-11 16:47:55 +01:00
Nawaz Dhandala
1461dd0164 feat: Add source and target positions to nodes in ServiceDependencyGraph 2025-08-11 16:47:54 +01:00
Simon Larsen
5ce1a782b3 refactor: Remove 'Subject' column from EmailLogsTable component 2025-08-11 14:41:59 +01:00
Simon Larsen
741eaec1d3 feat: Add modal functionality to Notification Logs tables for viewing details 2025-08-11 14:38:35 +01:00
Simon Larsen
2d8c931641 refactor: Standardize formatting in EmailLogsTable component 2025-08-11 14:26:05 +01:00
Simon Larsen
4db479958b refactor: Remove unused imports and simplify ServiceCatalogPage component 2025-08-11 14:26:00 +01:00
Simon Larsen
8c825f1498 refactor: Update imports in ServiceDependencyGraph and clean up AnnouncementView component 2025-08-11 14:10:48 +01:00
Simon Larsen
25426992be feat: Add route for deleting announcement view in Status Pages 2025-08-11 14:01:25 +01:00
Simon Larsen
861a72d194 feat: Enhance Notification Logs tables with singular and plural naming support 2025-08-11 13:54:54 +01:00
Simon Larsen
0857cebcfc Refactor Notification Logs: Replace ModelTable with dedicated components for Call, Email, Push, SMS, and Workspace logs
- Introduced new components: CallLogsTable, EmailLogsTable, PushLogsTable, SmsLogsTable, and WorkspaceLogsTable.
- Updated NotificationLogsSms, NotificationLogsEmail, NotificationLogsCall, NotificationLogsPush, and NotificationLogsWorkspace to utilize the new components.
- Removed redundant column and filter definitions from the individual log pages, centralizing them in the new table components.
- Enhanced code readability and maintainability by separating concerns and reducing duplication.
2025-08-11 13:28:50 +01:00
Nawaz Dhandala
975af2c22a Merge branch 'master' of https://github.com/OneUptime/oneuptime 2025-08-11 13:16:02 +01:00
Nawaz Dhandala
98d15f91b0 feat: Integrate ELK for layout management in ServiceDependencyGraph and add typings for elkjs 2025-08-11 13:15:59 +01:00
Simon Larsen
6d55b59a21 Merge branch 'master' of github.com:OneUptime/oneuptime 2025-08-11 12:47:35 +01:00
Simon Larsen
8a27651d84 feat: Add Notification Logs section and related components for Status Pages 2025-08-11 12:45:05 +01:00
Nawaz Dhandala
6a35dffcb5 feat: Update ServiceDependencyGraph to enhance edge styling and add read-only view styles 2025-08-11 12:34:49 +01:00
Nawaz Dhandala
1e4c46bb3f feat: Enhance ServiceDependencyGraph with luminance-based text color and update SideMenu icon 2025-08-11 12:33:11 +01:00
Simon Larsen
fe44c0fde4 feat: Add migration for WorkspaceNotificationLog table and related constraints 2025-08-11 12:09:54 +01:00
Nawaz Dhandala
089f612ec4 refactor: Improve code formatting and consistency across various components and routes 2025-08-11 12:01:59 +01:00
Simon Larsen
8dbd9e7430 Merge pull request #1982 from OneUptime/service-catalog-dependency
feat: Implement Service Catalog Dependency Graph and associated layou…
2025-08-11 11:58:53 +01:00
Simon Larsen
66eb9eede0 feat: Update notification log routes and components for consistency across Alerts, Incidents, Settings, and Status Pages 2025-08-11 11:57:02 +01:00
Nawaz Dhandala
e8db6fcb7f feat: Implement Service Catalog Dependency Graph and associated layout components 2025-08-11 11:47:08 +01:00
Simon Larsen
d9e7f44590 feat: Consolidate notification logs into unified components across Alerts, Incidents, Settings, and Status Pages 2025-08-10 15:20:14 +01:00
Simon Larsen
b7df0a7d05 Merge branch 'master' of github.com:OneUptime/oneuptime 2025-08-10 14:51:25 +01:00
Nawaz Dhandala
4101954862 refactor: Enhance type definitions and improve message summary functions in WorkspaceNotificationRuleService 2025-08-10 14:51:09 +01:00
Nawaz Dhandala
d68e4737e7 refactor: Improve code formatting and readability across multiple components 2025-08-10 14:46:44 +01:00
Nawaz Dhandala
bfb80388a0 Merge branch 'master' of https://github.com/OneUptime/oneuptime 2025-08-10 14:45:52 +01:00
Nawaz Dhandala
1beb96345b feat: Add Workspace Logs functionality across various pages
- Introduced Workspace Logs link in the SideMenu for Alerts, Incidents, Settings, and Status Pages.
- Created new routes for viewing Workspace Logs in Alerts, Incidents, Settings, and Status Pages.
- Added WorkspaceNotificationLog model to handle logs related to messages sent to Slack and Microsoft Teams.
- Implemented WorkspaceNotificationLogService for managing log entries.
- Developed UI components for displaying Workspace Logs in Alerts, Incidents, Settings, and Status Pages.
- Added filtering options for Workspace Logs based on status and workspace type.
2025-08-10 14:45:50 +01:00
Simon Larsen
1eb2af737d feat: Add routes for viewing alert, incident, and announcement logs 2025-08-10 14:28:00 +01:00
Simon Larsen
18f756a29b Merge branch 'master' of github.com:OneUptime/oneuptime 2025-08-10 14:21:36 +01:00
Simon Larsen
002f98720c feat: Add route for Push Logs settings page 2025-08-10 14:21:32 +01:00
Nawaz Dhandala
fdf5aacc2b Refactor notification log components for improved readability and consistency
- Updated AlertPushLogs, AlertSmsLogs, IncidentCallLogs, IncidentSmsLogs, IncidentEmailLogs, and related components to enhance code formatting and structure.
- Improved the layout of column definitions and filter options for better readability.
- Ensured consistent use of object destructuring and formatting across components.
- Added missing line breaks and indentation for clarity.
- Updated query and cardProps formatting for consistency across components.
2025-08-10 13:28:44 +01:00
Simon Larsen
574cad6806 feat: Add migration for PushNotificationLog table and related constraints 2025-08-10 13:27:28 +01:00
Simon Larsen
34c4ae947b feat: Add Push Notification Logs functionality
- Introduced PushNotificationLog model to track push notifications sent to users.
- Added permissions for reading push logs in the Permission enum.
- Updated various side menus to include links to Push Logs in Alerts, Incidents, and Settings.
- Created routes for viewing Push Logs in Alerts, Incidents, and Status Pages.
- Implemented UI components for displaying Push Logs in respective pages.
- Added filtering and column configuration for Push Logs tables.
- Integrated PushStatus enum to manage the status of push notifications.
- Implemented PushNotificationLogService for database interactions related to push logs.
2025-08-10 13:25:53 +01:00
Simon Larsen
8d9fc46506 feat: Add migration for new fields and constraints in CallLog, EmailLog, and SmsLog 2025-08-09 22:50:27 +01:00
Simon Larsen
c41fbefdcb feat: Add status page announcement logs to Call, Email, and SMS logs
- Enhanced CallLog, EmailLog, and SmsLog models to include relationships with StatusPageAnnouncement.
- Updated CallService, MailService, and SmsService to handle statusPageAnnouncementId.
- Introduced AnnouncementViewLayout and AnnouncementSideMenu for better navigation.
- Created dedicated components for viewing Email, SMS, and Call logs related to announcements.
- Added routes for viewing logs and deleting announcements.
- Implemented filtering and display of logs in the UI.
2025-08-09 22:47:24 +01:00
Simon Larsen
3e47051233 Add notification logs for alerts and incidents
- Implemented Email, SMS, and Call logs for alerts in the dashboard.
- Created corresponding components for viewing logs: AlertEmailLogs, AlertSmsLogs, AlertCallLogs.
- Added routes for accessing alert notification logs.
- Enhanced the SideMenu to include links to notification logs for alerts.
- Implemented Email, SMS, and Call logs for incidents in the dashboard.
- Created corresponding components for viewing logs: IncidentEmailLogs, IncidentSmsLogs, IncidentCallLogs.
- Added routes for accessing incident notification logs.
- Enhanced the SideMenu to include links to notification logs for incidents.
- Updated various services to include statusPageId and incidentId where necessary for better tracking.
2025-08-09 21:09:57 +01:00
Simon Larsen
8219f44708 fix: Adjust job removal counts in Queue class to manage Redis bloat more effectively 2025-08-08 22:05:54 +01:00
Simon Larsen
59e6505aa3 Merge branch 'master' of github.com:OneUptime/oneuptime 2025-08-08 22:03:46 +01:00
Simon Larsen
1f971b932a feat: Implement initial cleanup for legacy jobs in Queue class to manage memory and prevent Redis bloat 2025-08-08 22:03:43 +01:00
Nawaz Dhandala
d0e12ae86f fix: Adjust indentation for improved readability in Config and Routes files 2025-08-08 21:56:35 +01:00
Simon Larsen
cd11a450cd feat: Introduce configurable concurrency settings for ingest workers in environment variables 2025-08-08 21:52:49 +01:00
Simon Larsen
c0259fc041 feat: Add concurrency setting for OpenTelemetry Ingest worker and update related configurations 2025-08-08 21:21:53 +01:00
Simon Larsen
db1f5a29bb fix: Update notification handling to mark announcements and public notes as Skipped when no related entities are found 2025-08-08 19:17:55 +01:00
Simon Larsen
a9ecaf2dc8 fix: Update incident handling to mark subscriber notifications as Skipped when no monitors are attached 2025-08-08 19:14:52 +01:00
Nawaz Dhandala
138aad596a Refactor logging statements for improved readability and consistency across worker jobs; ensure all debug messages are formatted uniformly. Update migration index to include trailing comma for consistency. Simplify route initialization in Workers feature set. 2025-08-08 18:53:40 +01:00
Simon Larsen
2577b339aa fix: Reorder route initialization to ensure worker routes are registered before default catch-alls 2025-08-08 18:44:09 +01:00
Simon Larsen
80e7731cca fix: Remove ClusterKeyAuthorization middleware from inspector route 2025-08-08 18:13:03 +01:00
Simon Larsen
9da7b258f9 feat: Add migration to rename subscriber notification fields and update database schema 2025-08-08 17:48:07 +01:00
Simon Larsen
0ec3b1aa39 fix: Remove obsolete migration files and update index to reflect changes 2025-08-08 17:42:27 +01:00
Simon Larsen
7a9bb22813 fix: Add UpdateSubscriberNotificationStatusToEnum migration for subscriber notification status updates 2025-08-08 17:34:12 +01:00
Simon Larsen
92550ac7d6 fix: Remove unnecessary createdAt condition in subscriber notification jobs and add debug logging for better traceability 2025-08-08 16:56:47 +01:00
Nawaz Dhandala
101df5b9b7 fix: Refactor error message in StatusPageDelete for better readability and clarity 2025-08-08 15:17:54 +01:00
Simon Larsen
c3d7672935 fix: Remove unnecessary NOT NULL constraint on subscriberNotificationStatusOnIncidentCreated in Incident table migration 2025-08-08 15:08:03 +01:00
Simon Larsen
859c6378af fix: Update Dockerfile to use apt-get for installing bash and curl 2025-08-08 14:05:51 +01:00
Simon Larsen
620979eab2 fix: Correct typo in notification status message 2025-08-08 13:37:52 +01:00
Simon Larsen
0aa1c51efa fix: Update error message in StatusPageDelete to clarify environment variable setup for Docker and Helm 2025-08-08 13:37:13 +01:00
Simon Larsen
1985e9fc25 fix: Update error message in StatusPageDelete to include environment variable requirement for custom domains 2025-08-08 13:35:27 +01:00
Simon Larsen
ba4093838b fix: Add type assertion for categoryColors in ChartLegend to ensure correct type usage 2025-08-07 22:31:54 +01:00
Nawaz Dhandala
4bd7902afe fix: Refactor ResourceGenerator to improve type annotations and code clarity 2025-08-07 22:05:47 +01:00
Simon Larsen
5c300ed513 feat: Enhance update method to conditionally include fields based on change detection 2025-08-07 22:03:21 +01:00
Simon Larsen
c4a50e853c feat: Add logging for unauthorized update attempts in ColumnPermissions 2025-08-07 21:29:13 +01:00
Simon Larsen
20c1f13876 fix: Exclude computed fields from default empty list assignment in ResourceGenerator 2025-08-07 21:22:48 +01:00
Simon Larsen
09426ed6be Merge branch 'master' of github.com:OneUptime/oneuptime 2025-08-07 21:11:42 +01:00
Nawaz Dhandala
675a031ee6 fix: Correct return type of getYAxisDomain function to match expected output 2025-08-07 21:02:59 +01:00
Simon Larsen
92986ac1f8 feat: Add isDefaultValueColumn flag to Downtime Monitor Statuses field in StatusPage model 2025-08-07 17:38:07 +01:00
Simon Larsen
2b95d608dc fix: Remove redundant build command for darwin arm architecture 2025-08-07 16:55:43 +01:00
Nawaz Dhandala
2696071933 fix: Correct formatting in ProjectSSO and UserNotificationSetting models; update conditional logic in DatabaseService 2025-08-07 16:46:14 +01:00
Nawaz Dhandala
684a61b599 feat: Add default values for boolean fields in various database models 2025-08-07 16:45:33 +01:00
Nawaz Dhandala
633a89161e Merge branch 'master' of https://github.com/OneUptime/oneuptime 2025-08-07 15:03:02 +01:00
Nawaz Dhandala
fd24781783 refactor: Optimize onBarClick and shape rendering logic in BarChart component 2025-08-07 15:03:00 +01:00
Simon Larsen
903b13d515 feat: Handle null values for required fields in data processing 2025-08-07 14:48:01 +01:00
Simon Larsen
58a128a05e Merge branch 'master' of github.com:OneUptime/oneuptime 2025-08-07 14:45:51 +01:00
Simon Larsen
ec1d567813 feat: Set default values for status page configuration options 2025-08-07 14:45:48 +01:00
Nawaz Dhandala
0a53161eac refactor: Improve type annotations and code consistency across various components 2025-08-07 14:31:13 +01:00
Nawaz Dhandala
83b91af708 Refactor code for consistency and readability across various components
- Updated import statements for better formatting in multiple files.
- Added semicolons for consistency in BarChart and SparkChart components.
- Improved code readability by using braces for single-line if statements in various functions.
- Enhanced the structure of return statements for clarity in SubscriberNotificationStatus and other components.
- Refactored map functions to use explicit return statements for better readability.
- Cleaned up whitespace and formatting in multiple files for a more uniform code style.
2025-08-07 13:55:08 +01:00
Simon Larsen
3fefee8725 feat: Enhance notification status handling and improve UI components 2025-08-07 13:49:53 +01:00
Simon Larsen
9b2cc7d377 feat: Update create permissions for Incident and Scheduled Maintenance models 2025-08-07 12:52:00 +01:00
Simon Larsen
1fb71ed2e3 feat: Implement subscriber notification status handling across multiple services 2025-08-07 12:46:40 +01:00
Simon Larsen
94a5abdb31 feat: Add SparkChart component with Area, Line, and Bar chart implementations 2025-08-07 11:52:44 +01:00
Simon Larsen
73f4559943 feat: Refactor BarChart component for improved type safety and event handling 2025-08-07 11:47:59 +01:00
Simon Larsen
9c3c6ee4e9 feat: Add BarChart component for enhanced data visualization 2025-08-07 11:29:19 +01:00
Simon Larsen
56743214a0 feat: Update button style in SubscriberNotificationStatus for improved UI consistency 2025-08-07 11:29:14 +01:00
Simon Larsen
9136c6d40e feat: Update color imports in SubscriberNotificationStatus for consistent branding 2025-08-07 11:23:46 +01:00
Simon Larsen
920a9baee9 feat: Update ConfirmModal behavior in SubscriberNotificationStatus for improved user interaction 2025-08-07 11:20:23 +01:00
Simon Larsen
1c4aad2d81 feat: Add SubscriberNotificationStatus component to IncidentViewStateTimeline and ScheduledMaintenanceDelete for enhanced notification display 2025-08-07 11:17:34 +01:00
Simon Larsen
8a4644922a feat: Add textColor prop to IconText component and update SubscriberNotificationStatus to utilize it 2025-08-07 11:04:20 +01:00
Simon Larsen
c3f4b7d3d4 feat: Enhance SubscriberNotificationStatus component with IconText and ConfirmModal for improved status display and user interaction 2025-08-07 10:54:10 +01:00
Simon Larsen
6f7c0814ee feat: Implement IconText component and refactor CheckboxViewer to use it 2025-08-07 10:49:21 +01:00
Nawaz Dhandala
77cd3fc4c0 refactor: Enhance type definitions for handleResendNotification and getNotificationStatusInfo across components 2025-08-06 16:02:57 +01:00
Nawaz Dhandala
e7cbc3d739 Refactor notification status assignments and improve code readability in incident and scheduled maintenance notification jobs
- Updated subscriber notification status assignments for better readability by breaking long lines.
- Added handling for non-visible scheduled maintenance events to set status to Skipped.
- Improved error handling and logging for scheduled maintenance public notes and state timelines.
- Ensured consistent formatting and structure across notification jobs for clarity and maintainability.
2025-08-06 15:41:28 +01:00
Simon Larsen
6d14ea19b9 feat: Add subscriberNotificationStatusMessage to selectMoreFields in multiple components 2025-08-06 14:47:13 +01:00
Simon Larsen
1290d3b946 fix: Remove unnecessary className from subscriberNotificationStatusMessage in PublicNote component 2025-08-06 14:29:51 +01:00
Simon Larsen
c0c58546d0 feat: Integrate Tooltip for subscriberNotificationStatusMessage in SubscriberNotificationStatus component 2025-08-06 14:17:37 +01:00
Simon Larsen
6c5ef10606 feat: Update migration files to rename subscriberNotificationFailedReason to subscriberNotificationStatusMessage and adjust imports 2025-08-06 14:05:26 +01:00
Simon Larsen
ec4c6ff7c5 feat: Rename subscriberNotificationFailedReason to subscriberNotificationStatusMessage across models and update related components 2025-08-06 14:04:06 +01:00
Simon Larsen
616e6e43ab feat: Update access control permissions for Incident, Scheduled Maintenance, and related models 2025-08-06 13:03:55 +01:00
Simon Larsen
aa08cd904b feat: Update SCIMPage to use Route for documentation link instead of URL 2025-08-06 12:34:21 +01:00
Simon Larsen
fef1c1055c feat: Integrate SubscriberNotificationStatus component in Incident and Scheduled Maintenance views, replacing checkbox logic 2025-08-06 12:31:14 +01:00
Simon Larsen
22e33809f9 feat: Remove style prop from SubscriberNotificationStatus component usage across various views 2025-08-06 11:39:59 +01:00
Simon Larsen
eb8324a3c2 feat: Replace NotificationStatusPill with SubscriberNotificationStatus component across various views 2025-08-06 11:25:35 +01:00
Simon Larsen
fa6dedc9a1 feat: Add resend notification functionality to NotificationStatusPill and related components 2025-08-06 11:24:20 +01:00
Simon Larsen
099cd807bf feat: Remove unused notification status fields and components from Announcements, Incidents, and Scheduled Maintenance tables 2025-08-06 10:58:15 +01:00
Simon Larsen
5d0b010fc4 feat: Remove unused StatusPageSCIM from AllModelTypes 2025-08-05 21:56:55 +01:00
Simon Larsen
1fc421f92a feat: Refactor notification status handling with NotificationStatusPill component 2025-08-05 21:31:08 +01:00
Simon Larsen
14a14e2341 feat: Add .claude/settings.local.json to .gitignore 2025-08-05 21:09:10 +01:00
Simon Larsen
ab23cca264 feat: Remove unused ActionButtonSchema import from multiple components 2025-08-05 20:42:06 +01:00
Simon Larsen
678a961fb9 feat: Add migration for updating subscriber notification status to the migration index 2025-08-05 18:35:49 +01:00
Simon Larsen
c2e458f035 feat: Rename notification failure reason columns for consistency and update types to text 2025-08-05 18:35:14 +01:00
Simon Larsen
4daf17dc8c feat: Add SCIM documentation for automated user provisioning and deprovisioning 2025-08-05 18:04:59 +01:00
Simon Larsen
842aa4b88d feat: Rename notification failure reason fields to subscriberNotificationFailedReason for consistency across incident and scheduled maintenance jobs 2025-08-05 18:03:33 +01:00
Simon Larsen
fd51142693 feat: Update notification failure reason fields to subscriberNotificationFailedReason and change type to VeryLongText 2025-08-05 17:57:17 +01:00
Simon Larsen
e0ddf80aa6 feat: Add migration for updating subscriber notification status and handling failure reasons in Incident and ScheduledMaintenance tables 2025-08-05 17:53:06 +01:00
Simon Larsen
e8d55164c6 feat: Update notification handling for subscribers across various jobs
- Introduced a new enum `StatusPageSubscriberNotificationStatus` to manage notification statuses (Skipped, Pending, InProgress, Success, Failed).
- Updated `SendNotificationToSubscribers` jobs for Announcements, Incidents, Scheduled Maintenance, and Public Notes to utilize the new notification status system.
- Added logic to mark notifications as Skipped if they should not be sent, and to update the status to InProgress when notifications are being processed.
- Implemented success and failure handling for notifications, updating the respective status and logging errors as needed.
- Modified database schema to replace old boolean notification flags with the new enum-based status fields, ensuring backward compatibility with existing records.
- Added migration script to handle the transition of existing records to the new notification status system.
2025-08-05 17:49:28 +01:00
Nawaz Dhandala
5cd8795e7a refactor: Clean up code formatting and improve readability in SCIM and StatusPageSCIM files 2025-08-05 12:49:04 +01:00
Simon Larsen
aebf7a4f2e feat: Remove Groups Endpoint display and enhance user identifier information in SCIM settings 2025-08-05 12:48:10 +01:00
Simon Larsen
3ef093eee1 feat: Add password generation for private users and update SideMenu icon 2025-08-05 12:46:09 +01:00
Simon Larsen
b4c530a6a5 feat: Update SCIM links and enhance HiddenText component for copy functionality 2025-08-05 12:37:34 +01:00
Simon Larsen
166228cad5 feat: Enhance SCIM configuration handling and update UI elements 2025-08-05 12:28:48 +01:00
Simon Larsen
1eb95c71fe feat: Add StatusPageSCIM API integration to BaseAPIFeatureSet 2025-08-05 12:16:24 +01:00
Simon Larsen
56f33f256b feat: Increase concurrency limit for ingest job processing to improve throughput 2025-08-05 11:13:49 +01:00
Simon Larsen
42afd164b7 feat: Increase concurrency limit for telemetry job processing to improve performance 2025-08-05 11:11:12 +01:00
Nawaz Dhandala
0796166a55 fix: Correct syntax errors in navigation group array in Nav.ts 2025-08-05 11:07:45 +01:00
Nawaz Dhandala
170bfa8515 refactor: Improve code formatting and consistency across SCIM-related files 2025-08-05 11:03:00 +01:00
Simon Larsen
2f517d8dcc feat: Update SCIM documentation URLs to use environment configuration 2025-08-05 11:00:18 +01:00
Simon Larsen
cb5c4dce45 feat: Add SCIM API documentation for user provisioning and deprovisioning 2025-08-05 10:52:57 +01:00
Simon Larsen
d9abeda60d feat: Refactor SCIM utility functions for improved modularity and logging 2025-08-05 10:33:38 +01:00
Simon Larsen
15c4c89310 feat: Add StatusPageSCIM model and related database migration
- Implemented StatusPageSCIM model with necessary fields and access controls.
- Created migration script to set up StatusPageSCIM table in the database.
- Developed StatusPageSCIMService for handling SCIM configurations, including bearer token generation.
- Added SCIM management page in the dashboard with functionalities for creating, editing, and resetting bearer tokens.
2025-08-05 10:07:24 +01:00
Simon Larsen
8c1d5652f4 feat: Change button style type for resetting bearer token to outline 2025-08-04 22:14:31 +01:00
Nawaz Dhandala
fbf87cf8d4 refactor: Add type annotations to formatUserForSCIM and resetBearerToken functions for improved type safety 2025-08-04 22:10:06 +01:00
Nawaz Dhandala
1c12ad94dd fix: Add type annotations for improved type safety in SCIM and Metrics modules 2025-08-04 22:07:10 +01:00
Nawaz Dhandala
aa09bab7c9 Refactor SCIM migrations and models; update formatting and improve readability
- Added missing comma in AllModelTypes array in Index.ts.
- Refactored MigrationName1754304193228 to improve query formatting and readability.
- Refactored MigrationName1754315774827 for consistency in formatting.
- Updated migration index file to include new migration.
- Standardized string quotes in Queue.ts for consistency.
- Cleaned up SCIMAuthorization.ts by removing unnecessary whitespace and improving log formatting.
- Refactored StartServer.ts to standardize content-type header handling.
- Improved formatting in SCIM.tsx for better readability and consistency.
- Refactored Metrics.ts to standardize queueSize extraction and type checking.
- Enhanced Probe.ts logging for clarity and consistency.
2025-08-04 21:36:11 +01:00
Simon Larsen
f7d1975ab0 feat: Add debug logging for parsing names from SCIM users 2025-08-04 21:35:30 +01:00
Simon Larsen
99c9a591cb feat: Refactor SCIM user handling to improve name parsing and team operations 2025-08-04 21:29:16 +01:00
Simon Larsen
c956d01789 feat: Enhance user name handling in SCIM responses by parsing full names into given and family names 2025-08-04 21:22:01 +01:00
Simon Larsen
17c829869b feat: Implement user activation handling by adding users to configured teams 2025-08-04 21:18:03 +01:00
Simon Larsen
d65e91a912 feat: Enhance SCIM user update logging and handle user deactivation by removing from teams 2025-08-04 21:17:28 +01:00
Simon Larsen
39710ba9b0 feat: Enhance SCIM user update and delete logging, and improve team removal logic 2025-08-04 21:12:49 +01:00
Simon Larsen
8c70a4dfae feat: Update SCIM user handling to improve pagination and remove duplicates 2025-08-04 18:00:20 +01:00
Simon Larsen
ff99055594 feat: Refactor SCIM endpoints to enhance logging and improve user query handling 2025-08-04 17:44:23 +01:00
Simon Larsen
f01cc2fd71 feat: Enhance logging for SCIM requests and responses across various endpoints 2025-08-04 17:34:28 +01:00
Simon Larsen
49b43593b1 feat: Add middleware to handle SCIM content type before JSON parsing 2025-08-04 17:25:01 +01:00
Simon Larsen
e293ffd0eb feat: Remove isEnabled column from ProjectSCIM and update related services and migrations 2025-08-04 14:58:25 +01:00
Simon Larsen
b62a5e7722 feat: Add functionality to reset Bearer Token with confirmation modals 2025-08-04 14:47:45 +01:00
Simon Larsen
8f8ba0abb8 feat: Enhance SCIM middleware logging and update SCIM page state management 2025-08-04 13:01:09 +01:00
Simon Larsen
5525556b54 feat: Rename ProjectScima to ProjectSCIM and update imports 2025-08-04 12:28:09 +01:00
Simon Larsen
669066b70a feat: Implement ProjectSCIM model and SCIM page functionality 2025-08-04 12:27:48 +01:00
Simon Larsen
76d2abed08 fix: Update SCIM endpoint URLs to include versioning 2025-08-04 12:01:50 +01:00
Simon Larsen
a6c18b3f21 fix: Remove HTTP_PROTOCOL from SCIM endpoint URLs in SCIMPage component 2025-08-04 12:01:24 +01:00
Simon Larsen
955ea7bc31 feat: Restore ProjectSCIM service with bearer token generation logic 2025-08-04 11:58:18 +01:00
Simon Larsen
45719d4656 feat: Reintroduce ProjectSCIM service with bearer token generation logic 2025-08-04 11:58:07 +01:00
Simon Larsen
796c94a261 fix: Correct import casing for ProjectSCIM across multiple files 2025-08-04 11:46:56 +01:00
Simon Larsen
d2fe822cb7 feat: Integrate ProjectSCIM model and service into the Base API feature set 2025-08-04 11:44:02 +01:00
Simon Larsen
289a369eab feat: Add migration for ProjectSCIM and ProjectScimTeam tables with foreign key constraints 2025-08-04 11:43:44 +01:00
Simon Larsen
6f07e3e119 feat: Update SCIM API endpoints to include versioning in the URL 2025-08-04 11:19:17 +01:00
Simon Larsen
8cdc1e9faf feat: Add SCIM API endpoints and middleware for user management and configuration 2025-08-04 11:09:52 +01:00
Simon Larsen
d4609a84ef feat: Implement Project SCIM service with bearer token generation 2025-08-04 10:15:34 +01:00
Simon Larsen
eb4a91a598 feat: Add SCIM settings page and routing to the dashboard 2025-08-04 10:14:47 +01:00
Simon Larsen
5bea404d6c feat: Add SCIM API integration to Identity feature set 2025-08-04 10:13:44 +01:00
Simon Larsen
df3f8b6a74 feat: Add optional stackTrace field to job data structures for enhanced error tracking 2025-08-03 12:59:51 +01:00
Simon Larsen
0c9d2c821a feat: Add advanced horizontal pod autoscaler configuration for improved scaling behavior 2025-08-02 13:05:05 +01:00
Simon Larsen
ba49aaf0c3 fix: Skip probe offline email notifications when billing is enabled 2025-08-02 12:36:50 +01:00
Simon Larsen
6ea5ad7fe8 fix: Update nextPingAt calculation to use a 2-minute offset for improved timing accuracy 2025-08-02 11:42:01 +01:00
Simon Larsen
962866d109 fix: Improve queue size extraction and handling in metrics endpoint 2025-08-01 20:58:58 +01:00
Simon Larsen
115216561c feat: Add ports configuration for OneUptime probe service 2025-08-01 20:36:30 +01:00
Simon Larsen
f709c90cc4 fix: Update probe port handling in KEDA ScaledObjects for improved configuration 2025-08-01 20:21:41 +01:00
Simon Larsen
d7f01b0189 fix: Update default port value in probe template for better configuration handling 2025-08-01 20:19:31 +01:00
Simon Larsen
c3eaa8995c fix ports 2025-08-01 20:19:10 +01:00
Simon Larsen
53b482b9f3 refactor: Update Helm templates to use new port structure in values.yaml 2025-08-01 20:13:30 +01:00
Simon Larsen
d52670f39c refactor: Update Helm templates to use new port structure in values.yaml 2025-08-01 18:22:05 +01:00
Simon Larsen
fdc1332b9e Merge branch 'master' of github.com:OneUptime/oneuptime 2025-08-01 16:17:09 +01:00
Simon Larsen
a937416663 fix: Update autoscaler condition to prevent conflicts with KEDA configuration 2025-08-01 16:17:05 +01:00
Nawaz Dhandala
546d41da81 fix: Clean up formatting and ensure consistent return structure in metrics endpoints 2025-08-01 16:13:05 +01:00
Simon Larsen
c4c6793b29 feat: Implement KEDA autoscaling configuration for probes and add metrics endpoints 2025-08-01 15:38:04 +01:00
Simon Larsen
c894b112e6 fix: Await monitorResource call to ensure proper error handling in incoming request processing 2025-08-01 14:34:17 +01:00
Simon Larsen
304baf1bb4 fix: Await monitorResource call to ensure proper error handling in probe response processing 2025-08-01 14:33:17 +01:00
Simon Larsen
9adea6b1ba feat: Remove Helm annotations for post-install and post-upgrade hooks from templates 2025-08-01 14:01:04 +01:00
Simon Larsen
5498521e02 feat: Add Helm annotations for post-install and post-upgrade hooks 2025-08-01 13:47:52 +01:00
Simon Larsen
9e97c6ddbc feat: Update autoscaler conditions for fluent-ingest, incoming-request-ingest, probe-ingest, and server-monitor-ingest templates 2025-08-01 13:23:39 +01:00
Nawaz Dhandala
63272e09f8 refactor: Simplify function parameter formatting and improve readability in various files 2025-08-01 10:45:55 +01:00
Simon Larsen
327c28afdc feat: Implement fluent ingest worker for processing queue jobs 2025-08-01 10:34:17 +01:00
Simon Larsen
896020b93b feat: Add KEDA autoscaling configuration for various ingests
- Introduced KEDA autoscaling configuration in values.yaml for probeIngest, fluentIngest, incomingRequestIngest, and serverMonitorIngest.
- Added endpoints for queue statistics, size, and failed jobs in IncomingRequestIngest and ProbeIngest APIs.
- Implemented asynchronous processing of incoming requests and probes using job queues.
- Created Metrics API for KEDA metrics integration in IncomingRequestIngest, ProbeIngest, and ServerMonitorIngest.
- Refactored IncomingRequest and Probe APIs to utilize queue services for processing.
- Added job processing logic for incoming requests and probes in respective job files.
- Implemented queue service classes for managing job addition and retrieval of queue statistics.
2025-08-01 10:29:02 +01:00
Simon Larsen
15a68472b0 feat: comment out ClusterKeyAuthorization import for KEDA debugging 2025-07-31 21:23:41 +01:00
Simon Larsen
0210480d97 feat: remove Prometheus metrics endpoint for KEDA debugging 2025-07-31 21:22:04 +01:00
Simon Larsen
72fdc06687 feat: temporarily disable authentication middleware for KEDA debugging in metrics endpoint 2025-07-31 20:52:10 +01:00
Simon Larsen
3710b81b9a feat: add replica count support for deployments in Helm templates 2025-07-31 20:03:25 +01:00
Simon Larsen
9fcb3dc2e0 feat: update cluster key handling for KEDA compatibility in authorization middleware and Helm chart 2025-07-31 19:50:25 +01:00
Simon Larsen
43e2ccf51a feat: improve secret handling in Helm chart for upgrade scenarios 2025-07-31 19:29:07 +01:00
Nawaz Dhandala
48c3d8603a fix: format code for better readability and consistency in MonitorResource and Metrics 2025-07-31 12:57:39 +01:00
Simon Larsen
9cfc912161 feat: enhance response messages for incoming request checks with time difference 2025-07-31 12:56:06 +01:00
Simon Larsen
29e3ee57ab feat: add metrics-api endpoint for queue size retrieval in KEDA autoscaling 2025-07-31 12:44:48 +01:00
Simon Larsen
be7e849822 feat: add KEDA ScaledObjects for OpenTelemetry Ingest with configurable metrics 2025-07-31 12:34:43 +01:00
Simon Larsen
59d76b601a feat: add KEDA autoscaling support for OpenTelemetry Ingest with configurable metrics 2025-07-31 12:18:57 +01:00
Simon Larsen
b77ef336b8 feat: add replica count configuration for multiple deployments in Helm templates 2025-07-31 11:47:03 +01:00
Nawaz Dhandala
7df21fe8e5 refactor: add type annotations for pagination parameters in OTelIngest 2025-07-30 22:42:24 +01:00
Nawaz Dhandala
f39e1943c7 refactor: improve code formatting and readability in Queue and TelemetryQueueService 2025-07-30 22:40:45 +01:00
Simon Larsen
966a903646 feat: implement pagination for retrieving failed jobs from the queue 2025-07-30 22:39:58 +01:00
Simon Larsen
1d9d37c6d1 refactor: optimize queue size and stats calculations by using count methods 2025-07-30 22:37:46 +01:00
Simon Larsen
7edcc4dbce feat: add endpoint to retrieve failed jobs from the queue 2025-07-30 22:37:08 +01:00
Simon Larsen
0939294d22 Refactor code structure for improved readability and maintainability 2025-07-30 19:45:46 +01:00
Simon Larsen
dbcbfe5f79 refactor: simplify telemetry processing worker initialization and remove unused export 2025-07-30 19:25:52 +01:00
Simon Larsen
a638972817 feat: update @oneuptime/common dependency in test-release workflow 2025-07-30 16:44:05 +01:00
Simon Larsen
37c6310465 feat: update @oneuptime/common to version 7.0.4800 and adjust workflow dependencies 2025-07-30 16:42:39 +01:00
Nawaz Dhandala
a7d38389fd style: improve formatting and consistency in Prometheus metrics generation 2025-07-30 16:30:26 +01:00
Nawaz Dhandala
2f55336db7 Merge branch 'master' of https://github.com/OneUptime/oneuptime 2025-07-30 16:29:25 +01:00
Nawaz Dhandala
f99a15b95b refactor: enhance type annotations for better clarity in queue processing methods 2025-07-30 16:28:53 +01:00
Simon Larsen
de5bff2ffe feat: add Prometheus metrics endpoint for telemetry queue monitoring 2025-07-30 16:26:38 +01:00
Nawaz Dhandala
cef2764499 style: format code for better readability and consistency across multiple files 2025-07-30 16:22:26 +01:00
1423 changed files with 158873 additions and 64076 deletions

17
.github/instructions/instructions.md vendored Normal file
View File

@@ -0,0 +1,17 @@
---
applyTo: '**'
---
# Building and Compiling
If you would like to compile or build any project. Please cd into the directory and run the following command:
```
npm run compile
```
Ths will make sure there are no type / syntax errors.
# Typescript Types.
Please do not use "any" types. Please create proper types where required.

View File

@@ -19,11 +19,19 @@ jobs:
uses: actions/checkout@v4
- name: Preinstall
run: npm run prerun
uses: nick-fields/retry@v3
with:
timeout_minutes: 10
max_attempts: 3
command: npm run prerun
# build image for accounts service
- name: build docker image
run: sudo docker build -f ./Accounts/Dockerfile .
uses: nick-fields/retry@v3
with:
timeout_minutes: 45
max_attempts: 3
command: sudo docker build --no-cache -f ./Accounts/Dockerfile .
docker-build-isolated-vm:
runs-on: ubuntu-latest
@@ -34,11 +42,19 @@ jobs:
uses: actions/checkout@v4
- name: Preinstall
run: npm run prerun
uses: nick-fields/retry@v3
with:
timeout_minutes: 10
max_attempts: 3
command: npm run prerun
# build image for accounts service
- name: build docker image
run: sudo docker build -f ./IsolatedVM/Dockerfile .
uses: nick-fields/retry@v3
with:
timeout_minutes: 45
max_attempts: 3
command: sudo docker build --no-cache -f ./IsolatedVM/Dockerfile .
docker-build-home:
runs-on: ubuntu-latest
@@ -49,11 +65,19 @@ jobs:
uses: actions/checkout@v4
- name: Preinstall
run: npm run prerun
uses: nick-fields/retry@v3
with:
timeout_minutes: 10
max_attempts: 3
command: npm run prerun
# build image for accounts service
- name: build docker image
run: sudo docker build -f ./Home/Dockerfile .
uses: nick-fields/retry@v3
with:
timeout_minutes: 45
max_attempts: 3
command: sudo docker build --no-cache -f ./Home/Dockerfile .
docker-build-worker:
runs-on: ubuntu-latest
@@ -64,11 +88,19 @@ jobs:
uses: actions/checkout@v4
- name: Preinstall
run: npm run prerun
uses: nick-fields/retry@v3
with:
timeout_minutes: 10
max_attempts: 3
command: npm run prerun
# build image for accounts service
- name: build docker image
run: sudo docker build -f ./Worker/Dockerfile .
uses: nick-fields/retry@v3
with:
timeout_minutes: 45
max_attempts: 3
command: sudo docker build --no-cache -f ./Worker/Dockerfile .
docker-build-workflow:
runs-on: ubuntu-latest
@@ -79,11 +111,19 @@ jobs:
uses: actions/checkout@v4
- name: Preinstall
run: npm run prerun
uses: nick-fields/retry@v3
with:
timeout_minutes: 10
max_attempts: 3
command: npm run prerun
# build image for accounts service
- name: build docker image
run: sudo docker build -f ./Workflow/Dockerfile .
uses: nick-fields/retry@v3
with:
timeout_minutes: 45
max_attempts: 3
command: sudo docker build --no-cache -f ./Workflow/Dockerfile .
docker-build-api-reference:
runs-on: ubuntu-latest
@@ -94,11 +134,19 @@ jobs:
uses: actions/checkout@v4
- name: Preinstall
run: npm run prerun
uses: nick-fields/retry@v3
with:
timeout_minutes: 10
max_attempts: 3
command: npm run prerun
# build image for accounts service
- name: build docker image
run: sudo docker build -f ./APIReference/Dockerfile .
uses: nick-fields/retry@v3
with:
timeout_minutes: 45
max_attempts: 3
command: sudo docker build --no-cache -f ./APIReference/Dockerfile .
docker-build-docs:
runs-on: ubuntu-latest
@@ -109,11 +157,19 @@ jobs:
uses: actions/checkout@v4
- name: Preinstall
run: npm run prerun
uses: nick-fields/retry@v3
with:
timeout_minutes: 10
max_attempts: 3
command: npm run prerun
# build image for accounts service
- name: build docker image
run: sudo docker build -f ./Docs/Dockerfile .
uses: nick-fields/retry@v3
with:
timeout_minutes: 45
max_attempts: 3
command: sudo docker build --no-cache -f ./Docs/Dockerfile .
docker-build-otel-collector:
@@ -125,11 +181,19 @@ jobs:
uses: actions/checkout@v4
- name: Preinstall
run: npm run prerun
uses: nick-fields/retry@v3
with:
timeout_minutes: 10
max_attempts: 3
command: npm run prerun
# build image for accounts service
- name: build docker image
run: sudo docker build -f ./OTelCollector/Dockerfile .
uses: nick-fields/retry@v3
with:
timeout_minutes: 45
max_attempts: 3
command: sudo docker build --no-cache -f ./OTelCollector/Dockerfile .
docker-build-app:
runs-on: ubuntu-latest
@@ -140,12 +204,20 @@ jobs:
uses: actions/checkout@v4
- name: Preinstall
run: npm run prerun
uses: nick-fields/retry@v3
with:
timeout_minutes: 10
max_attempts: 3
command: npm run prerun
# build image for accounts service
- name: build docker image
run: sudo docker build -f ./App/Dockerfile .
uses: nick-fields/retry@v3
with:
timeout_minutes: 45
max_attempts: 3
command: sudo docker build --no-cache -f ./App/Dockerfile .
docker-build-copilot:
@@ -157,11 +229,19 @@ jobs:
uses: actions/checkout@v4
- name: Preinstall
run: npm run prerun
uses: nick-fields/retry@v3
with:
timeout_minutes: 10
max_attempts: 3
command: npm run prerun
# build image for accounts service
- name: build docker image
run: sudo docker build -f ./Copilot/Dockerfile .
uses: nick-fields/retry@v3
with:
timeout_minutes: 45
max_attempts: 3
command: sudo docker build --no-cache -f ./Copilot/Dockerfile .
docker-build-e2e:
runs-on: ubuntu-latest
@@ -172,12 +252,20 @@ jobs:
uses: actions/checkout@v4
- name: Preinstall
run: npm run prerun
uses: nick-fields/retry@v3
with:
timeout_minutes: 10
max_attempts: 3
command: npm run prerun
# build image for accounts service
- name: build docker image
run: sudo docker build -f ./E2E/Dockerfile .
uses: nick-fields/retry@v3
with:
timeout_minutes: 45
max_attempts: 3
command: sudo docker build --no-cache -f ./E2E/Dockerfile .
docker-build-admin-dashboard:
runs-on: ubuntu-latest
@@ -188,11 +276,19 @@ jobs:
uses: actions/checkout@v4
- name: Preinstall
run: npm run prerun
uses: nick-fields/retry@v3
with:
timeout_minutes: 10
max_attempts: 3
command: npm run prerun
# build image for home
- name: build docker image
run: sudo docker build -f ./AdminDashboard/Dockerfile .
uses: nick-fields/retry@v3
with:
timeout_minutes: 45
max_attempts: 3
command: sudo docker build --no-cache -f ./AdminDashboard/Dockerfile .
docker-build-dashboard:
runs-on: ubuntu-latest
@@ -203,11 +299,19 @@ jobs:
uses: actions/checkout@v4
- name: Preinstall
run: npm run prerun
uses: nick-fields/retry@v3
with:
timeout_minutes: 10
max_attempts: 3
command: npm run prerun
# build image for home
- name: build docker image
run: sudo docker build -f ./Dashboard/Dockerfile .
uses: nick-fields/retry@v3
with:
timeout_minutes: 45
max_attempts: 3
command: sudo docker build --no-cache -f ./Dashboard/Dockerfile .
docker-build-probe:
runs-on: ubuntu-latest
@@ -218,11 +322,19 @@ jobs:
uses: actions/checkout@v4
- name: Preinstall
run: npm run prerun
uses: nick-fields/retry@v3
with:
timeout_minutes: 10
max_attempts: 3
command: npm run prerun
# build image probe api
- name: build docker image
run: sudo docker build -f ./Probe/Dockerfile .
uses: nick-fields/retry@v3
with:
timeout_minutes: 45
max_attempts: 3
command: sudo docker build --no-cache -f ./Probe/Dockerfile .
docker-build-probe-ingest:
runs-on: ubuntu-latest
@@ -233,11 +345,19 @@ jobs:
uses: actions/checkout@v4
- name: Preinstall
run: npm run prerun
uses: nick-fields/retry@v3
with:
timeout_minutes: 10
max_attempts: 3
command: npm run prerun
# build image probe api
- name: build docker image
run: sudo docker build -f ./ProbeIngest/Dockerfile .
uses: nick-fields/retry@v3
with:
timeout_minutes: 45
max_attempts: 3
command: sudo docker build --no-cache -f ./ProbeIngest/Dockerfile .
docker-build-server-monitor-ingest:
runs-on: ubuntu-latest
@@ -248,13 +368,21 @@ jobs:
uses: actions/checkout@v4
- name: Preinstall
run: npm run prerun
uses: nick-fields/retry@v3
with:
timeout_minutes: 10
max_attempts: 3
command: npm run prerun
# build image probe api
- name: build docker image
run: sudo docker build -f ./ServerMonitorIngest/Dockerfile .
uses: nick-fields/retry@v3
with:
timeout_minutes: 45
max_attempts: 3
command: sudo docker build --no-cache -f ./ServerMonitorIngest/Dockerfile .
docker-build-open-telemetry-ingest:
docker-build-telemetry:
runs-on: ubuntu-latest
env:
CI_PIPELINE_ID: ${{github.run_number}}
@@ -263,11 +391,19 @@ jobs:
uses: actions/checkout@v4
- name: Preinstall
run: npm run prerun
uses: nick-fields/retry@v3
with:
timeout_minutes: 10
max_attempts: 3
command: npm run prerun
# build image probe api
- name: build docker image
run: sudo docker build -f ./OpenTelemetryIngest/Dockerfile .
uses: nick-fields/retry@v3
with:
timeout_minutes: 45
max_attempts: 3
command: sudo docker build --no-cache -f ./Telemetry/Dockerfile .
docker-build-incoming-request-ingest:
runs-on: ubuntu-latest
@@ -278,26 +414,19 @@ jobs:
uses: actions/checkout@v4
- name: Preinstall
run: npm run prerun
uses: nick-fields/retry@v3
with:
timeout_minutes: 10
max_attempts: 3
command: npm run prerun
# build image probe api
- name: build docker image
run: sudo docker build -f ./IncomingRequestIngest/Dockerfile .
docker-build-fluent-ingest:
runs-on: ubuntu-latest
env:
CI_PIPELINE_ID: ${{github.run_number}}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Preinstall
run: npm run prerun
# build image probe api
- name: build docker image
run: sudo docker build -f ./FluentIngest/Dockerfile .
uses: nick-fields/retry@v3
with:
timeout_minutes: 45
max_attempts: 3
command: sudo docker build --no-cache -f ./IncomingRequestIngest/Dockerfile .
docker-build-status-page:
runs-on: ubuntu-latest
@@ -308,11 +437,19 @@ jobs:
uses: actions/checkout@v4
- name: Preinstall
run: npm run prerun
uses: nick-fields/retry@v3
with:
timeout_minutes: 10
max_attempts: 3
command: npm run prerun
# build image for home
- name: build docker image
run: sudo docker build -f ./StatusPage/Dockerfile .
uses: nick-fields/retry@v3
with:
timeout_minutes: 45
max_attempts: 3
command: sudo docker build --no-cache -f ./StatusPage/Dockerfile .
docker-build-test-server:
runs-on: ubuntu-latest
@@ -323,8 +460,16 @@ jobs:
uses: actions/checkout@v4
- name: Preinstall
run: npm run prerun
uses: nick-fields/retry@v3
with:
timeout_minutes: 10
max_attempts: 3
command: npm run prerun
# build image for mail service
- name: build docker image
run: sudo docker build -f ./TestServer/Dockerfile .
uses: nick-fields/retry@v3
with:
timeout_minutes: 45
max_attempts: 3
command: sudo docker build --no-cache -f ./TestServer/Dockerfile .

View File

@@ -20,7 +20,12 @@ jobs:
with:
node-version: latest
- run: cd Common && npm install
- run: cd Accounts && npm install && npm run compile && npm run dep-check
- name: Compile Accounts
uses: nick-fields/retry@v3
with:
timeout_minutes: 30
max_attempts: 3
command: cd Accounts && npm install && npm run compile && npm run dep-check
compile-isolated-vm:
runs-on: ubuntu-latest
@@ -32,7 +37,12 @@ jobs:
with:
node-version: latest
- run: cd Common && npm install
- run: cd IsolatedVM && npm install && npm run compile && npm run dep-check
- name: Compile IsolatedVM
uses: nick-fields/retry@v3
with:
timeout_minutes: 30
max_attempts: 3
command: cd IsolatedVM && npm install && npm run compile && npm run dep-check
compile-common:
runs-on: ubuntu-latest
@@ -43,7 +53,12 @@ jobs:
- uses: actions/setup-node@v4
with:
node-version: latest
- run: cd Common && npm install && npm run compile && npm run dep-check
- name: Compile Common
uses: nick-fields/retry@v3
with:
timeout_minutes: 30
max_attempts: 3
command: cd Common && npm install && npm run compile && npm run dep-check
compile-app:
runs-on: ubuntu-latest
@@ -55,7 +70,12 @@ jobs:
with:
node-version: latest
- run: cd Common && npm install
- run: cd App && npm install && npm run compile && npm run dep-check
- name: Compile App
uses: nick-fields/retry@v3
with:
timeout_minutes: 30
max_attempts: 3
command: cd App && npm install && npm run compile && npm run dep-check
compile-home:
runs-on: ubuntu-latest
@@ -67,7 +87,12 @@ jobs:
with:
node-version: latest
- run: cd Common && npm install
- run: cd Home && npm install && npm run compile && npm run dep-check
- name: Compile Home
uses: nick-fields/retry@v3
with:
timeout_minutes: 30
max_attempts: 3
command: cd Home && npm install && npm run compile && npm run dep-check
compile-worker:
runs-on: ubuntu-latest
@@ -79,7 +104,12 @@ jobs:
with:
node-version: latest
- run: cd Common && npm install
- run: cd Worker && npm install && npm run compile && npm run dep-check
- name: Compile Worker
uses: nick-fields/retry@v3
with:
timeout_minutes: 30
max_attempts: 3
command: cd Worker && npm install && npm run compile && npm run dep-check
compile-workflow:
runs-on: ubuntu-latest
@@ -91,7 +121,12 @@ jobs:
with:
node-version: latest
- run: cd Common && npm install
- run: cd Workflow && npm install && npm run compile && npm run dep-check
- name: Compile Workflow
uses: nick-fields/retry@v3
with:
timeout_minutes: 30
max_attempts: 3
command: cd Workflow && npm install && npm run compile && npm run dep-check
compile-api-reference:
runs-on: ubuntu-latest
@@ -103,7 +138,12 @@ jobs:
with:
node-version: latest
- run: cd Common && npm install
- run: cd APIReference && npm install && npm run compile && npm run dep-check
- name: Compile API Reference
uses: nick-fields/retry@v3
with:
timeout_minutes: 30
max_attempts: 3
command: cd APIReference && npm install && npm run compile && npm run dep-check
compile-docs-reference:
runs-on: ubuntu-latest
@@ -115,7 +155,12 @@ jobs:
with:
node-version: latest
- run: cd Common && npm install
- run: cd Docs && npm install && npm run compile && npm run dep-check
- name: Compile Docs Reference
uses: nick-fields/retry@v3
with:
timeout_minutes: 30
max_attempts: 3
command: cd Docs && npm install && npm run compile && npm run dep-check
compile-copilot:
runs-on: ubuntu-latest
@@ -127,7 +172,12 @@ jobs:
with:
node-version: latest
- run: cd Common && npm install
- run: cd Copilot && npm install && npm run compile && npm run dep-check
- name: Compile Copilot
uses: nick-fields/retry@v3
with:
timeout_minutes: 30
max_attempts: 3
command: cd Copilot && npm install && npm run compile && npm run dep-check
compile-nginx:
runs-on: ubuntu-latest
@@ -140,7 +190,12 @@ jobs:
node-version: latest
- run: cd Common && npm install
- run: cd Nginx && npm install && npm run compile && npm run dep-check
- name: Compile Nginx
uses: nick-fields/retry@v3
with:
timeout_minutes: 30
max_attempts: 3
command: cd Nginx && npm install && npm run compile && npm run dep-check
compile-infrastructure-agent:
runs-on: ubuntu-latest
@@ -150,7 +205,12 @@ jobs:
- uses: actions/checkout@v4
# Setup Go
- uses: actions/setup-go@v5
- run: cd InfrastructureAgent && go build .
- name: Compile Infrastructure Agent
uses: nick-fields/retry@v3
with:
timeout_minutes: 30
max_attempts: 3
command: cd InfrastructureAgent && go build .
compile-admin-dashboard:
@@ -164,7 +224,12 @@ jobs:
node-version: latest
- run: cd Common && npm install
- run: cd AdminDashboard && npm install && npm run compile && npm run dep-check
- name: Compile Admin Dashboard
uses: nick-fields/retry@v3
with:
timeout_minutes: 30
max_attempts: 3
command: cd AdminDashboard && npm install && npm run compile && npm run dep-check
compile-dashboard:
runs-on: ubuntu-latest
@@ -177,7 +242,12 @@ jobs:
node-version: latest
- run: cd Common && npm install
- run: cd Dashboard && npm install && npm run compile && npm run dep-check
- name: Compile Dashboard
uses: nick-fields/retry@v3
with:
timeout_minutes: 30
max_attempts: 3
command: cd Dashboard && npm install && npm run compile && npm run dep-check
compile-e2e:
@@ -191,7 +261,12 @@ jobs:
node-version: latest
- run: sudo apt-get update
- run: cd Common && npm install
- run: cd E2E && npm install && npm run compile && npm run dep-check
- name: Compile E2E
uses: nick-fields/retry@v3
with:
timeout_minutes: 30
max_attempts: 3
command: cd E2E && npm install && npm run compile && npm run dep-check
compile-probe:
runs-on: ubuntu-latest
@@ -203,7 +278,12 @@ jobs:
with:
node-version: latest
- run: cd Common && npm install
- run: cd Probe && npm install && npm run compile && npm run dep-check
- name: Compile Probe
uses: nick-fields/retry@v3
with:
timeout_minutes: 30
max_attempts: 3
command: cd Probe && npm install && npm run compile && npm run dep-check
compile-probe-ingest:
runs-on: ubuntu-latest
@@ -215,7 +295,12 @@ jobs:
with:
node-version: latest
- run: cd Common && npm install
- run: cd ProbeIngest && npm install && npm run compile && npm run dep-check
- name: Compile Probe Ingest
uses: nick-fields/retry@v3
with:
timeout_minutes: 30
max_attempts: 3
command: cd ProbeIngest && npm install && npm run compile && npm run dep-check
compile-server-monitor-ingest:
runs-on: ubuntu-latest
@@ -227,9 +312,14 @@ jobs:
with:
node-version: latest
- run: cd Common && npm install
- run: cd ServerMonitorIngest && npm install && npm run compile && npm run dep-check
- name: Compile Server Monitor Ingest
uses: nick-fields/retry@v3
with:
timeout_minutes: 30
max_attempts: 3
command: cd ServerMonitorIngest && npm install && npm run compile && npm run dep-check
compile-open-telemetry-ingest:
compile-telemetry:
runs-on: ubuntu-latest
env:
CI_PIPELINE_ID: ${{github.run_number}}
@@ -239,7 +329,12 @@ jobs:
with:
node-version: latest
- run: cd Common && npm install
- run: cd OpenTelemetryIngest && npm install && npm run compile && npm run dep-check
- name: Compile Telemetry
uses: nick-fields/retry@v3
with:
timeout_minutes: 30
max_attempts: 3
command: cd Telemetry && npm install && npm run compile && npm run dep-check
compile-incoming-request-ingest:
@@ -252,20 +347,12 @@ jobs:
with:
node-version: latest
- run: cd Common && npm install
- run: cd IncomingRequestIngest && npm install && npm run compile && npm run dep-check
compile-fluent-ingest:
runs-on: ubuntu-latest
env:
CI_PIPELINE_ID: ${{github.run_number}}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
- name: Compile Incoming Request Ingest
uses: nick-fields/retry@v3
with:
node-version: latest
- run: cd Common && npm install
- run: cd FluentIngest && npm install && npm run compile && npm run dep-check
timeout_minutes: 30
max_attempts: 3
command: cd IncomingRequestIngest && npm install && npm run compile && npm run dep-check
compile-status-page:
runs-on: ubuntu-latest
@@ -278,7 +365,12 @@ jobs:
node-version: latest
- run: cd Common && npm install
- run: cd StatusPage && npm install && npm run compile && npm run dep-check
- name: Compile Status Page
uses: nick-fields/retry@v3
with:
timeout_minutes: 30
max_attempts: 3
command: cd StatusPage && npm install && npm run compile && npm run dep-check
compile-test-server:
runs-on: ubuntu-latest
@@ -290,7 +382,12 @@ jobs:
with:
node-version: latest
- run: cd Common && npm install
- run: cd TestServer && npm install && npm run compile && npm run dep-check
- name: Compile Test Server
uses: nick-fields/retry@v3
with:
timeout_minutes: 30
max_attempts: 3
command: cd TestServer && npm install && npm run compile && npm run dep-check
compile-mcp:
runs-on: ubuntu-latest
@@ -302,4 +399,9 @@ jobs:
with:
node-version: latest
- run: cd Common && npm install
- run: cd MCP && npm install && npm run compile && npm run dep-check
- name: Compile MCP
uses: nick-fields/retry@v3
with:
timeout_minutes: 30
max_attempts: 3
command: cd MCP && npm update @oneuptime/common && npm install && npm run compile && npm run dep-check

49
.github/workflows/npm-audit-fix.yml vendored Normal file
View File

@@ -0,0 +1,49 @@
name: NPM Audit Fix
on:
schedule:
- cron: '0 0 * * *'
workflow_dispatch:
permissions:
contents: write
pull-requests: write
jobs:
npm-audit-fix:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: 20
- name: Run npm audit fix across packages
run: npm run audit-fix
- name: Detect changes
id: changes
run: |
if git status --porcelain | grep .; then
echo "has_changes=true" >> $GITHUB_OUTPUT
else
echo "has_changes=false" >> $GITHUB_OUTPUT
fi
- name: Create pull request
if: steps.changes.outputs.has_changes == 'true'
uses: peter-evans/create-pull-request@v6
with:
commit-message: "chore: npm audit fix"
title: "chore: npm audit fix"
body: |
Automated npm audit fix run.
Workflow: ${{ github.workflow }}
Run ID: ${{ github.run_id }}
branch: chore/npm-audit-fix
delete-branch: true

File diff suppressed because it is too large Load Diff

View File

@@ -1,32 +0,0 @@
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
name: "OneUptime Reliability Copilot"
on:
push:
branches: [ master ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ master ]
schedule:
# Run every day at midnight UTC
- cron: '0 0 * * *'
jobs:
analyze:
name: Analyze Code
runs-on: ubuntu-latest
steps:
# Run Reliability Copilot in Docker Container
- name: Run Copilot
run: |
docker run --rm \
-e ONEUPTIME_URL="https://test.oneuptime.com" \
-e ONEUPTIME_REPOSITORY_SECRET_KEY="${{ secrets.COPILOT_ONEUPTIME_REPOSITORY_SECRET_KEY }}" \
-e CODE_REPOSITORY_PASSWORD="${{ github.token }}" \
-e CODE_REPOSITORY_USERNAME="simlarsen" \
-e OPENAI_API_KEY="${{ secrets.OPENAI_API_KEY }}" \
--net=host oneuptime/copilot:test

View File

@@ -77,17 +77,21 @@ jobs:
ls -la "$PROVIDER_DIR" || true
- name: Test Go build
run: |
PROVIDER_DIR="./Terraform"
if [ -d "$PROVIDER_DIR" ] && [ -f "$PROVIDER_DIR/go.mod" ]; then
cd "$PROVIDER_DIR"
echo "🔨 Testing Go build..."
go mod tidy
go build -v ./...
echo "✅ Go build successful"
else
echo "⚠️ Cannot test build - missing go.mod or provider directory"
fi
uses: nick-fields/retry@v3
with:
timeout_minutes: 30
max_attempts: 3
command: |
PROVIDER_DIR="./Terraform"
if [ -d "$PROVIDER_DIR" ] && [ -f "$PROVIDER_DIR/go.mod" ]; then
cd "$PROVIDER_DIR"
echo "🔨 Testing Go build..."
go mod tidy
go build -v ./...
echo "✅ Go build successful"
else
echo "⚠️ Cannot test build - missing go.mod or provider directory"
fi
- name: Upload Terraform provider as artifact
uses: actions/upload-artifact@v4

File diff suppressed because it is too large Load Diff

View File

@@ -1,20 +0,0 @@
name: Fluent Ingest Test
on:
pull_request:
push:
branches-ignore:
- 'hotfix-*' # excludes hotfix branches
- 'release'
jobs:
test:
runs-on: ubuntu-latest
env:
CI_PIPELINE_ID: ${{github.run_number}}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: latest
- run: cd FluentIngest && npm install && npm run test

View File

@@ -1,4 +1,4 @@
name: OpenTelemetryIngest Test
name: Telemetry Test
on:
pull_request:
@@ -17,5 +17,6 @@ jobs:
- uses: actions/setup-node@v4
with:
node-version: latest
- run: cd OpenTelemetryIngest && npm install && npm run test
- run: cd Common && npm install
- run: cd Telemetry && npm install && npm run test

1
.gitignore vendored
View File

@@ -127,3 +127,4 @@ MCP/build/
MCP/.env
MCP/node_modules
Dashboard/public/sw.js
.claude/settings.local.json

18
.vscode/launch.json vendored
View File

@@ -205,8 +205,8 @@
},
{
"address": "127.0.0.1",
"localRoot": "${workspaceFolder}/OpenTelemetryIngest",
"name": "OpenTelemetryIngest: Debug with Docker",
"localRoot": "${workspaceFolder}/Telemetry",
"name": "Telemetry: Debug with Docker",
"port": 9938,
"remoteRoot": "/usr/src/app",
"request": "attach",
@@ -217,20 +217,6 @@
"restart": true,
"autoAttachChildProcesses": true
},
{
"address": "127.0.0.1",
"localRoot": "${workspaceFolder}/FluentIngest",
"name": "Fluent Ingest: Debug with Docker",
"port": 9937,
"remoteRoot": "/usr/src/app",
"request": "attach",
"skipFiles": [
"<node_internals>/**"
],
"type": "node",
"restart": true,
"autoAttachChildProcesses": true
},
{
"address": "127.0.0.1",
"localRoot": "${workspaceFolder}/IsolatedVM",

View File

@@ -3,7 +3,7 @@
#
# Pull base image nodejs image.
FROM public.ecr.aws/docker/library/node:23.8-alpine3.21
FROM public.ecr.aws/docker/library/node:24.9-alpine3.21
RUN mkdir /tmp/npm && chmod 2777 /tmp/npm && chown 1000:1000 /tmp/npm && npm config set cache /tmp/npm --global
RUN npm config set fetch-retries 5
@@ -14,9 +14,12 @@ RUN npm config set fetch-retry-maxtimeout 600000
ARG GIT_SHA
ARG APP_VERSION
ARG IS_ENTERPRISE_EDITION=false
ENV GIT_SHA=${GIT_SHA}
ENV APP_VERSION=${APP_VERSION}
ENV IS_ENTERPRISE_EDITION=${IS_ENTERPRISE_EDITION}
ENV PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1
# IF APP_VERSION is not set, set it to 1.0.0

View File

@@ -2,6 +2,7 @@ import { IsBillingEnabled } from "Common/Server/EnvironmentConfig";
import { ViewsPath } from "../Utils/Config";
import ResourceUtil, { ModelDocumentation } from "../Utils/Resources";
import { ExpressRequest, ExpressResponse } from "Common/Server/Utils/Express";
import Dictionary from "Common/Types/Dictionary";
// Retrieve resources documentation
const Resources: Array<ModelDocumentation> = ResourceUtil.getResources();
@@ -16,7 +17,7 @@ export default class ServiceHandler {
// Extract page parameter from request
const page: string | undefined = req.params["page"];
const pageData: any = {};
const pageData: Dictionary<unknown> = {};
// Set default page title and description for the authentication page
pageTitle = "Authentication";

View File

@@ -4,6 +4,7 @@ import ResourceUtil, { ModelDocumentation } from "../Utils/Resources";
import LocalCache from "Common/Server/Infrastructure/LocalCache";
import { ExpressRequest, ExpressResponse } from "Common/Server/Utils/Express";
import LocalFile from "Common/Server/Utils/LocalFile";
import Dictionary from "Common/Types/Dictionary";
const Resources: Array<ModelDocumentation> = ResourceUtil.getResources();
@@ -12,9 +13,9 @@ export default class ServiceHandler {
_req: ExpressRequest,
res: ExpressResponse,
): Promise<void> {
const pageData: any = {};
const pageData: Dictionary<unknown> = {};
pageData.selectCode = await LocalCache.getOrSetString(
pageData["selectCode"] = await LocalCache.getOrSetString(
"data-type",
"select",
async () => {
@@ -22,7 +23,7 @@ export default class ServiceHandler {
},
);
pageData.sortCode = await LocalCache.getOrSetString(
pageData["sortCode"] = await LocalCache.getOrSetString(
"data-type",
"sort",
async () => {
@@ -30,7 +31,7 @@ export default class ServiceHandler {
},
);
pageData.equalToCode = await LocalCache.getOrSetString(
pageData["equalToCode"] = await LocalCache.getOrSetString(
"data-type",
"equal-to",
async () => {
@@ -38,7 +39,7 @@ export default class ServiceHandler {
},
);
pageData.equalToOrNullCode = await LocalCache.getOrSetString(
pageData["equalToOrNullCode"] = await LocalCache.getOrSetString(
"data-type",
"equal-to-or-null",
async () => {
@@ -48,7 +49,7 @@ export default class ServiceHandler {
},
);
pageData.greaterThanCode = await LocalCache.getOrSetString(
pageData["greaterThanCode"] = await LocalCache.getOrSetString(
"data-type",
"greater-than",
async () => {
@@ -58,7 +59,7 @@ export default class ServiceHandler {
},
);
pageData.greaterThanOrEqualCode = await LocalCache.getOrSetString(
pageData["greaterThanOrEqualCode"] = await LocalCache.getOrSetString(
"data-type",
"greater-than-or-equal",
async () => {
@@ -68,7 +69,7 @@ export default class ServiceHandler {
},
);
pageData.lessThanCode = await LocalCache.getOrSetString(
pageData["lessThanCode"] = await LocalCache.getOrSetString(
"data-type",
"less-than",
async () => {
@@ -78,7 +79,7 @@ export default class ServiceHandler {
},
);
pageData.lessThanOrEqualCode = await LocalCache.getOrSetString(
pageData["lessThanOrEqualCode"] = await LocalCache.getOrSetString(
"data-type",
"less-than-or-equal",
async () => {
@@ -88,7 +89,7 @@ export default class ServiceHandler {
},
);
pageData.includesCode = await LocalCache.getOrSetString(
pageData["includesCode"] = await LocalCache.getOrSetString(
"data-type",
"includes",
async () => {
@@ -98,7 +99,7 @@ export default class ServiceHandler {
},
);
pageData.lessThanOrNullCode = await LocalCache.getOrSetString(
pageData["lessThanOrNullCode"] = await LocalCache.getOrSetString(
"data-type",
"less-than-or-equal",
async () => {
@@ -108,7 +109,7 @@ export default class ServiceHandler {
},
);
pageData.greaterThanOrNullCode = await LocalCache.getOrSetString(
pageData["greaterThanOrNullCode"] = await LocalCache.getOrSetString(
"data-type",
"less-than-or-equal",
async () => {
@@ -118,7 +119,7 @@ export default class ServiceHandler {
},
);
pageData.isNullCode = await LocalCache.getOrSetString(
pageData["isNullCode"] = await LocalCache.getOrSetString(
"data-type",
"is-null",
async () => {
@@ -126,7 +127,7 @@ export default class ServiceHandler {
},
);
pageData.notNullCode = await LocalCache.getOrSetString(
pageData["notNullCode"] = await LocalCache.getOrSetString(
"data-type",
"not-null",
async () => {
@@ -134,7 +135,7 @@ export default class ServiceHandler {
},
);
pageData.notEqualToCode = await LocalCache.getOrSetString(
pageData["notEqualToCode"] = await LocalCache.getOrSetString(
"data-type",
"not-equals",
async () => {

View File

@@ -2,6 +2,7 @@ import { IsBillingEnabled } from "Common/Server/EnvironmentConfig";
import { ViewsPath } from "../Utils/Config";
import ResourceUtil, { ModelDocumentation } from "../Utils/Resources";
import { ExpressRequest, ExpressResponse } from "Common/Server/Utils/Express";
import Dictionary from "Common/Types/Dictionary";
// Fetch a list of resources used in the application
const Resources: Array<ModelDocumentation> = ResourceUtil.getResources();
@@ -17,7 +18,7 @@ export default class ServiceHandler {
// Get the 'page' parameter from the request
const page: string | undefined = req.params["page"];
const pageData: any = {};
const pageData: Dictionary<unknown> = {};
// Set the default page title and description
pageTitle = "Errors";

View File

@@ -2,6 +2,7 @@ import { IsBillingEnabled } from "Common/Server/EnvironmentConfig";
import { ViewsPath } from "../Utils/Config";
import ResourceUtil, { ModelDocumentation } from "../Utils/Resources";
import { ExpressRequest, ExpressResponse } from "Common/Server/Utils/Express";
import Dictionary from "Common/Types/Dictionary";
// Get all resources and featured resources from ResourceUtil
const Resources: Array<ModelDocumentation> = ResourceUtil.getResources();
@@ -20,10 +21,10 @@ export default class ServiceHandler {
// Get the requested page from the URL parameters
const page: string | undefined = req.params["page"];
const pageData: any = {};
const pageData: Dictionary<unknown> = {};
// Set featured resources for the page
pageData.featuredResources = FeaturedResources;
pageData["featuredResources"] = FeaturedResources;
// Set page title and description
pageTitle = "Introduction";

View File

@@ -3,7 +3,10 @@ import ResourceUtil, { ModelDocumentation } from "../Utils/Resources";
import PageNotFoundServiceHandler from "./PageNotFound";
import { AppApiRoute } from "Common/ServiceRoute";
import { ColumnAccessControl } from "Common/Types/BaseDatabase/AccessControl";
import { getTableColumns } from "Common/Types/Database/TableColumn";
import {
getTableColumns,
TableColumnMetadata,
} from "Common/Types/Database/TableColumn";
import Dictionary from "Common/Types/Dictionary";
import ObjectID from "Common/Types/ObjectID";
import Permission, {
@@ -33,7 +36,7 @@ export default class ServiceHandler {
let pageTitle: string = "";
let pageDescription: string = "";
let page: string | undefined = req.params["page"];
const pageData: any = {};
const pageData: Dictionary<unknown> = {};
// Check if page is provided
if (!page) {
@@ -56,7 +59,9 @@ export default class ServiceHandler {
page = "model";
// Get table columns for current resource
const tableColumns: any = getTableColumns(currentResource.model);
const tableColumns: Dictionary<TableColumnMetadata> = getTableColumns(
currentResource.model,
);
// Filter out columns with no access
for (const key in tableColumns) {
@@ -77,12 +82,14 @@ export default class ServiceHandler {
continue;
}
if (tableColumns[key].hideColumnInDocumentation) {
if (tableColumns[key] && tableColumns[key]!.hideColumnInDocumentation) {
delete tableColumns[key];
continue;
}
tableColumns[key].permissions = accessControl;
if (tableColumns[key]) {
(tableColumns[key] as any).permissions = accessControl;
}
}
// Remove unnecessary columns
@@ -92,11 +99,11 @@ export default class ServiceHandler {
delete tableColumns["version"];
// Set page data
pageData.title = currentResource.model.singularName;
pageData.description = currentResource.model.tableDescription;
pageData.columns = tableColumns;
pageData["title"] = currentResource.model.singularName;
pageData["description"] = currentResource.model.tableDescription;
pageData["columns"] = tableColumns;
pageData.tablePermissions = {
pageData["tablePermissions"] = {
read: currentResource.model.readRecordPermissions.map(
(permission: Permission) => {
return PermissionDictionary[permission];
@@ -120,7 +127,7 @@ export default class ServiceHandler {
};
// Cache the list request data
pageData.listRequest = await LocalCache.getOrSetString(
pageData["listRequest"] = await LocalCache.getOrSetString(
"model",
"list-request",
async () => {
@@ -130,7 +137,7 @@ export default class ServiceHandler {
);
// Cache the item request data
pageData.itemRequest = await LocalCache.getOrSetString(
pageData["itemRequest"] = await LocalCache.getOrSetString(
"model",
"item-request",
async () => {
@@ -140,7 +147,7 @@ export default class ServiceHandler {
);
// Cache the item response data
pageData.itemResponse = await LocalCache.getOrSetString(
pageData["itemResponse"] = await LocalCache.getOrSetString(
"model",
"item-response",
async () => {
@@ -152,7 +159,7 @@ export default class ServiceHandler {
);
// Cache the count request data
pageData.countRequest = await LocalCache.getOrSetString(
pageData["countRequest"] = await LocalCache.getOrSetString(
"model",
"count-request",
async () => {
@@ -164,7 +171,7 @@ export default class ServiceHandler {
);
// Cache the count response data
pageData.countResponse = await LocalCache.getOrSetString(
pageData["countResponse"] = await LocalCache.getOrSetString(
"model",
"count-response",
async () => {
@@ -175,7 +182,7 @@ export default class ServiceHandler {
},
);
pageData.updateRequest = await LocalCache.getOrSetString(
pageData["updateRequest"] = await LocalCache.getOrSetString(
"model",
"update-request",
async () => {
@@ -186,7 +193,7 @@ export default class ServiceHandler {
},
);
pageData.updateResponse = await LocalCache.getOrSetString(
pageData["updateResponse"] = await LocalCache.getOrSetString(
"model",
"update-response",
async () => {
@@ -197,7 +204,7 @@ export default class ServiceHandler {
},
);
pageData.createRequest = await LocalCache.getOrSetString(
pageData["createRequest"] = await LocalCache.getOrSetString(
"model",
"create-request",
async () => {
@@ -208,7 +215,7 @@ export default class ServiceHandler {
},
);
pageData.createResponse = await LocalCache.getOrSetString(
pageData["createResponse"] = await LocalCache.getOrSetString(
"model",
"create-response",
async () => {
@@ -219,7 +226,7 @@ export default class ServiceHandler {
},
);
pageData.deleteRequest = await LocalCache.getOrSetString(
pageData["deleteRequest"] = await LocalCache.getOrSetString(
"model",
"delete-request",
async () => {
@@ -230,7 +237,7 @@ export default class ServiceHandler {
},
);
pageData.deleteResponse = await LocalCache.getOrSetString(
pageData["deleteResponse"] = await LocalCache.getOrSetString(
"model",
"delete-response",
async () => {
@@ -242,7 +249,7 @@ export default class ServiceHandler {
);
// Get list response from cache or set it if it's not available
pageData.listResponse = await LocalCache.getOrSetString(
pageData["listResponse"] = await LocalCache.getOrSetString(
"model",
"list-response",
async () => {
@@ -254,14 +261,15 @@ export default class ServiceHandler {
);
// Generate a unique ID for the example object
pageData.exampleObjectID = ObjectID.generate();
pageData["exampleObjectID"] = ObjectID.generate();
// Construct the API path for the current resource
pageData.apiPath =
pageData["apiPath"] =
AppApiRoute.toString() + currentResource.model.crudApiPath?.toString();
// Check if the current resource is a master admin API
pageData.isMasterAdminApiDocs = currentResource.model.isMasterAdminApiDocs;
pageData["isMasterAdminApiDocs"] =
currentResource.model.isMasterAdminApiDocs;
// Render the index page with the required data
return res.render(`${ViewsPath}/pages/index`, {

View File

@@ -7,6 +7,7 @@ import { ViewsPath } from "../Utils/Config";
import ResourceUtil, { ModelDocumentation } from "../Utils/Resources";
import { ExpressRequest, ExpressResponse } from "Common/Server/Utils/Express";
import URL from "Common/Types/API/URL";
import Dictionary from "Common/Types/Dictionary";
// Fetch a list of resources used in the application
const Resources: Array<ModelDocumentation> = ResourceUtil.getResources();
@@ -22,7 +23,7 @@ export default class ServiceHandler {
// Get the 'page' parameter from the request
const page: string | undefined = req.params["page"];
const pageData: any = {
const pageData: Dictionary<unknown> = {
hostUrl: new URL(HttpProtocol, Host).toString(),
};

View File

@@ -4,6 +4,7 @@ import ResourceUtil, { ModelDocumentation } from "../Utils/Resources";
import LocalCache from "Common/Server/Infrastructure/LocalCache";
import { ExpressRequest, ExpressResponse } from "Common/Server/Utils/Express";
import LocalFile from "Common/Server/Utils/LocalFile";
import Dictionary from "Common/Types/Dictionary";
const Resources: Array<ModelDocumentation> = ResourceUtil.getResources(); // Get all resources from ResourceUtil
@@ -15,14 +16,14 @@ export default class ServiceHandler {
let pageTitle: string = ""; // Initialize page title
let pageDescription: string = ""; // Initialize page description
const page: string | undefined = req.params["page"]; // Get the page parameter from the request
const pageData: any = {}; // Initialize page data object
const pageData: Dictionary<unknown> = {}; // Initialize page data object
// Set page title and description
pageTitle = "Pagination";
pageDescription = "Learn how to paginate requests with OneUptime API";
// Get response and request code from LocalCache or LocalFile
pageData.responseCode = await LocalCache.getOrSetString(
pageData["responseCode"] = await LocalCache.getOrSetString(
"pagination",
"response",
async () => {
@@ -33,7 +34,7 @@ export default class ServiceHandler {
},
);
pageData.requestCode = await LocalCache.getOrSetString(
pageData["requestCode"] = await LocalCache.getOrSetString(
"pagination",
"request",
async () => {

View File

@@ -3,6 +3,7 @@ import ResourceUtil, { ModelDocumentation } from "../Utils/Resources";
import { PermissionHelper, PermissionProps } from "Common/Types/Permission";
import { ExpressRequest, ExpressResponse } from "Common/Server/Utils/Express";
import { IsBillingEnabled } from "Common/Server/EnvironmentConfig";
import Dictionary from "Common/Types/Dictionary";
const Resources: Array<ModelDocumentation> = ResourceUtil.getResources();
@@ -17,14 +18,14 @@ export default class ServiceHandler {
// Get the requested page
const page: string | undefined = req.params["page"];
const pageData: any = {};
const pageData: Dictionary<unknown> = {};
// Set page title and description
pageTitle = "Permissions";
pageDescription = "Learn how permissions work with OneUptime";
// Filter permissions to only include those assignable to tenants
pageData.permissions = PermissionHelper.getAllPermissionProps().filter(
pageData["permissions"] = PermissionHelper.getAllPermissionProps().filter(
(i: PermissionProps) => {
return i.isAssignableToTenant;
},

View File

@@ -1,8 +1,14 @@
{
"watch": ["./","../Common/Server", "../Common/Types", "../Common/Utils", "../Common/Models"],
"ext": "ts,json,tsx,env,js,jsx,hbs",
"ext": "ts,tsx",
"ignore": [
"./node_modules/**",
"./public/**",
"./bin/**",
"./build/**",
"greenlock.d/*"
],
"exec": "node --inspect=0.0.0.0:9229 --require ts-node/register Index.ts"
"watchOptions": {"useFsEvents": false, "interval": 500},
"env": {"TS_NODE_TRANSPILE_ONLY": "1", "TS_NODE_FILES": "false"},
"exec": "node -r ts-node/register/transpile-only Index.ts"
}

View File

@@ -29,27 +29,29 @@
"@bull-board/express": "^5.21.4",
"@clickhouse/client": "^1.10.1",
"@elastic/elasticsearch": "^8.12.1",
"@hcaptcha/react-hcaptcha": "^1.14.0",
"@monaco-editor/react": "^4.4.6",
"@opentelemetry/api": "^1.9.0",
"@opentelemetry/api-logs": "^0.52.1",
"@opentelemetry/api-logs": "^0.206.0",
"@opentelemetry/context-zone": "^1.25.1",
"@opentelemetry/exporter-logs-otlp-http": "^0.52.1",
"@opentelemetry/exporter-metrics-otlp-proto": "^0.52.1",
"@opentelemetry/exporter-trace-otlp-http": "^0.52.1",
"@opentelemetry/exporter-trace-otlp-proto": "^0.52.1",
"@opentelemetry/exporter-logs-otlp-http": "^0.207.0",
"@opentelemetry/exporter-metrics-otlp-proto": "^0.207.0",
"@opentelemetry/exporter-trace-otlp-http": "^0.207.0",
"@opentelemetry/exporter-trace-otlp-proto": "^0.207.0",
"@opentelemetry/id-generator-aws-xray": "^1.2.2",
"@opentelemetry/instrumentation": "^0.52.1",
"@opentelemetry/instrumentation-fetch": "^0.52.1",
"@opentelemetry/instrumentation-xml-http-request": "^0.52.1",
"@opentelemetry/instrumentation": "^0.207.0",
"@opentelemetry/instrumentation-fetch": "^0.207.0",
"@opentelemetry/instrumentation-xml-http-request": "^0.207.0",
"@opentelemetry/resources": "^1.25.1",
"@opentelemetry/sdk-logs": "^0.52.1",
"@opentelemetry/sdk-logs": "^0.207.0",
"@opentelemetry/sdk-metrics": "^1.25.1",
"@opentelemetry/sdk-node": "^0.52.1",
"@opentelemetry/sdk-trace-node": "^1.25.1",
"@opentelemetry/sdk-node": "^0.207.0",
"@opentelemetry/sdk-trace-web": "^1.25.1",
"@opentelemetry/semantic-conventions": "^1.26.0",
"@opentelemetry/semantic-conventions": "^1.37.0",
"@remixicon/react": "^4.2.0",
"@simplewebauthn/server": "^13.2.2",
"@tippyjs/react": "^4.2.6",
"@types/archiver": "^6.0.3",
"@types/crypto-js": "^4.2.2",
"@types/qrcode": "^1.5.5",
"@types/react-highlight": "^0.12.8",
@@ -58,14 +60,17 @@
"@types/web-push": "^3.6.4",
"acme-client": "^5.3.0",
"airtable": "^0.12.2",
"axios": "^1.7.2",
"bullmq": "^5.3.3",
"archiver": "^7.0.1",
"axios": "^1.12.0",
"botbuilder": "^4.23.3",
"bullmq": "^5.61.0",
"cookie-parser": "^1.4.7",
"cors": "^2.8.5",
"cron-parser": "^4.8.1",
"crypto-js": "^4.2.0",
"dotenv": "^16.4.4",
"ejs": "^3.1.10",
"elkjs": "^0.10.0",
"esbuild": "^0.25.5",
"express": "^4.21.1",
"formik": "^2.4.6",
@@ -79,26 +84,26 @@
"moment": "^2.30.1",
"moment-timezone": "^0.5.45",
"node-cron": "^3.0.3",
"nodemailer": "^6.9.10",
"nodemailer": "^7.0.7",
"otpauth": "^9.3.1",
"pg": "^8.7.3",
"playwright": "^1.50.0",
"posthog-js": "^1.139.6",
"pg": "^8.16.3",
"playwright": "^1.56.0",
"posthog-js": "^1.275.3",
"prop-types": "^15.8.1",
"qrcode": "^1.5.3",
"react": "^18.3.1",
"react-beautiful-dnd": "^13.1.1",
"react-big-calendar": "^1.13.0",
"react-big-calendar": "^1.19.4",
"react-color": "^2.19.3",
"react-dom": "^18.3.1",
"react-dropzone": "^14.2.2",
"react-error-boundary": "^4.0.13",
"react-highlight": "^0.15.0",
"react-markdown": "^8.0.3",
"react-router-dom": "^6.24.1",
"react-router-dom": "^6.30.1",
"react-select": "^5.4.0",
"react-spinners": "^0.14.1",
"react-syntax-highlighter": "^15.5.0",
"react-syntax-highlighter": "^16.0.0",
"react-toggle": "^4.1.3",
"reactflow": "^11.11.4",
"recharts": "^2.12.7",
@@ -110,16 +115,16 @@
"socket.io": "^4.7.4",
"socket.io-client": "^4.7.5",
"stripe": "^10.17.0",
"tailwind-merge": "^2.5.2",
"tailwind-merge": "^2.6.0",
"tippy.js": "^6.3.7",
"twilio": "^4.22.0",
"typeorm": "^0.3.20",
"typeorm": "^0.3.26",
"typeorm-extension": "^2.2.13",
"universal-cookie": "^7.2.1",
"use-async-effect": "^2.2.6",
"uuid": "^8.3.2",
"web-push": "^3.6.7",
"zod": "^3.25.30"
"zod": "^3.25.76"
},
"devDependencies": {
"@faker-js/faker": "^8.0.2",
@@ -242,89 +247,20 @@
}
},
"node_modules/@babel/code-frame": {
"version": "7.23.5",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz",
"integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==",
"version": "7.27.1",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz",
"integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/highlight": "^7.23.4",
"chalk": "^2.4.2"
"@babel/helper-validator-identifier": "^7.27.1",
"js-tokens": "^4.0.0",
"picocolors": "^1.1.1"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/code-frame/node_modules/ansi-styles": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
"dev": true,
"dependencies": {
"color-convert": "^1.9.0"
},
"engines": {
"node": ">=4"
}
},
"node_modules/@babel/code-frame/node_modules/chalk": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
"dev": true,
"dependencies": {
"ansi-styles": "^3.2.1",
"escape-string-regexp": "^1.0.5",
"supports-color": "^5.3.0"
},
"engines": {
"node": ">=4"
}
},
"node_modules/@babel/code-frame/node_modules/color-convert": {
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
"dev": true,
"dependencies": {
"color-name": "1.1.3"
}
},
"node_modules/@babel/code-frame/node_modules/color-name": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
"integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
"dev": true
},
"node_modules/@babel/code-frame/node_modules/escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
"integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
"dev": true,
"engines": {
"node": ">=0.8.0"
}
},
"node_modules/@babel/code-frame/node_modules/has-flag": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
"integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
"dev": true,
"engines": {
"node": ">=4"
}
},
"node_modules/@babel/code-frame/node_modules/supports-color": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
"dev": true,
"dependencies": {
"has-flag": "^3.0.0"
},
"engines": {
"node": ">=4"
}
},
"node_modules/@babel/compat-data": {
"version": "7.23.5",
"resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.5.tgz",
@@ -500,19 +436,21 @@
}
},
"node_modules/@babel/helper-string-parser": {
"version": "7.23.4",
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz",
"integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==",
"version": "7.27.1",
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
"integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-validator-identifier": {
"version": "7.22.20",
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz",
"integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==",
"version": "7.28.5",
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz",
"integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=6.9.0"
}
@@ -527,109 +465,28 @@
}
},
"node_modules/@babel/helpers": {
"version": "7.23.6",
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.6.tgz",
"integrity": "sha512-wCfsbN4nBidDRhpDhvcKlzHWCTlgJYUUdSJfzXb2NuBssDSIjc3xcb+znA7l+zYsFljAcGM0aFkN40cR3lXiGA==",
"version": "7.28.4",
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.4.tgz",
"integrity": "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/template": "^7.22.15",
"@babel/traverse": "^7.23.6",
"@babel/types": "^7.23.6"
"@babel/template": "^7.27.2",
"@babel/types": "^7.28.4"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/highlight": {
"version": "7.23.4",
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz",
"integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==",
"dev": true,
"dependencies": {
"@babel/helper-validator-identifier": "^7.22.20",
"chalk": "^2.4.2",
"js-tokens": "^4.0.0"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/highlight/node_modules/ansi-styles": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
"dev": true,
"dependencies": {
"color-convert": "^1.9.0"
},
"engines": {
"node": ">=4"
}
},
"node_modules/@babel/highlight/node_modules/chalk": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
"dev": true,
"dependencies": {
"ansi-styles": "^3.2.1",
"escape-string-regexp": "^1.0.5",
"supports-color": "^5.3.0"
},
"engines": {
"node": ">=4"
}
},
"node_modules/@babel/highlight/node_modules/color-convert": {
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
"dev": true,
"dependencies": {
"color-name": "1.1.3"
}
},
"node_modules/@babel/highlight/node_modules/color-name": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
"integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
"dev": true
},
"node_modules/@babel/highlight/node_modules/escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
"integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
"dev": true,
"engines": {
"node": ">=0.8.0"
}
},
"node_modules/@babel/highlight/node_modules/has-flag": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
"integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
"dev": true,
"engines": {
"node": ">=4"
}
},
"node_modules/@babel/highlight/node_modules/supports-color": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
"dev": true,
"dependencies": {
"has-flag": "^3.0.0"
},
"engines": {
"node": ">=4"
}
},
"node_modules/@babel/parser": {
"version": "7.23.6",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.6.tgz",
"integrity": "sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==",
"version": "7.28.5",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz",
"integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/types": "^7.28.5"
},
"bin": {
"parser": "bin/babel-parser.js"
},
@@ -800,14 +657,15 @@
}
},
"node_modules/@babel/template": {
"version": "7.22.15",
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz",
"integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==",
"version": "7.27.2",
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz",
"integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/code-frame": "^7.22.13",
"@babel/parser": "^7.22.15",
"@babel/types": "^7.22.15"
"@babel/code-frame": "^7.27.1",
"@babel/parser": "^7.27.2",
"@babel/types": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
@@ -835,14 +693,14 @@
}
},
"node_modules/@babel/types": {
"version": "7.23.6",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.6.tgz",
"integrity": "sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==",
"version": "7.28.5",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz",
"integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-string-parser": "^7.23.4",
"@babel/helper-validator-identifier": "^7.22.20",
"to-fast-properties": "^2.0.0"
"@babel/helper-string-parser": "^7.27.1",
"@babel/helper-validator-identifier": "^7.28.5"
},
"engines": {
"node": ">=6.9.0"
@@ -1759,21 +1617,23 @@
}
},
"node_modules/brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"version": "1.1.12",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
"integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
}
},
"node_modules/braces": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
"dev": true,
"license": "MIT",
"dependencies": {
"fill-range": "^7.0.1"
"fill-range": "^7.1.1"
},
"engines": {
"node": ">=8"
@@ -2003,10 +1863,11 @@
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ=="
},
"node_modules/cross-spawn": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
"integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
"version": "7.0.6",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
"integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
"dev": true,
"license": "MIT",
"dependencies": {
"path-key": "^3.1.0",
"shebang-command": "^2.0.0",
@@ -2075,9 +1936,10 @@
}
},
"node_modules/ejs": {
"version": "3.1.9",
"resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.9.tgz",
"integrity": "sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ==",
"version": "3.1.10",
"resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz",
"integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==",
"license": "Apache-2.0",
"dependencies": {
"jake": "^10.8.5"
},
@@ -2224,9 +2086,10 @@
}
},
"node_modules/filelist/node_modules/brace-expansion": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
"integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0"
}
@@ -2243,10 +2106,11 @@
}
},
"node_modules/fill-range": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
"dev": true,
"license": "MIT",
"dependencies": {
"to-regex-range": "^5.0.1"
},
@@ -2541,6 +2405,7 @@
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=0.12.0"
}
@@ -3238,13 +3103,15 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
"dev": true
"dev": true,
"license": "MIT"
},
"node_modules/js-yaml": {
"version": "3.14.1",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
"integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
"version": "3.14.2",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz",
"integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==",
"dev": true,
"license": "MIT",
"dependencies": {
"argparse": "^1.0.7",
"esprima": "^4.0.0"
@@ -3397,12 +3264,13 @@
"dev": true
},
"node_modules/micromatch": {
"version": "4.0.5",
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
"integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
"integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
"dev": true,
"license": "MIT",
"dependencies": {
"braces": "^3.0.2",
"braces": "^3.0.3",
"picomatch": "^2.3.1"
},
"engines": {
@@ -3683,10 +3551,11 @@
"dev": true
},
"node_modules/picocolors": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
"integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
"dev": true
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
"integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
"dev": true,
"license": "ISC"
},
"node_modules/picomatch": {
"version": "2.3.1",
@@ -4106,20 +3975,12 @@
"integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==",
"dev": true
},
"node_modules/to-fast-properties": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
"integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==",
"dev": true,
"engines": {
"node": ">=4"
}
},
"node_modules/to-regex-range": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"is-number": "^7.0.0"
},

View File

@@ -108,7 +108,7 @@
</div>
</div>
<div class="[&amp;>:first-child]:mt-0 [&amp;>:last-child]:mb-0">
<%- include('../partials/code', {title: "Example Pagination Request", requestUrl: "/api/monitors/get-list?skip=0&limit=3", requestType: "GET", code: pageData.requestCode }) -%>
<%- include('../partials/code', {title: "Example Pagination Request", requestUrl: "/api/monitors/get-list?skip=0&limit=3", requestType: "POST", code: pageData.requestCode }) -%>
<%- include('../partials/code', {title: "Example Pagination Response" , requestUrl: "", requestType: "", code: pageData.responseCode }) -%>
</div>
</div>

View File

@@ -135,7 +135,6 @@
<link rel="apple-touch-icon-precomposed" href="/img/ou-wb.svg">
<link rel="icon" href="/img/ou-wb.svg">
<link rel="image_src" type="image/png" href="/img/hou-wb.svg">
<link rel="canonical" href="/">
<link rel="manifest" href="/manifest.json">
<meta property="og:title" content="OneUptime - One Complete Observability platform.">
<meta property="og:url" content="https://oneuptime.com">

View File

@@ -3,7 +3,7 @@
#
# Pull base image nodejs image.
FROM public.ecr.aws/docker/library/node:23.8-alpine3.21
FROM public.ecr.aws/docker/library/node:24.9-alpine3.21
RUN mkdir /tmp/npm && chmod 2777 /tmp/npm && chown 1000:1000 /tmp/npm && npm config set cache /tmp/npm --global
RUN npm config set fetch-retries 5
@@ -14,9 +14,12 @@ RUN npm config set fetch-retry-maxtimeout 600000
ARG GIT_SHA
ARG APP_VERSION
ARG IS_ENTERPRISE_EDITION=false
ENV GIT_SHA=${GIT_SHA}
ENV APP_VERSION=${APP_VERSION}
ENV IS_ENTERPRISE_EDITION=${IS_ENTERPRISE_EDITION}
ENV PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1
# IF APP_VERSION is not set, set it to 1.0.0

View File

@@ -1,7 +1,10 @@
{
"watch": ["./","../Common/UI", "../Common/Types", "../Common/Utils", "../Common/Models"],
"ext": "ts,json,tsx,env,js,jsx,hbs",
"ext": "ts,tsx",
"ignore": [
"./node_modules/**",
"./public/**",
"./bin/**",
"./public/**",
"./public/dist/**",
"./build/*",

View File

@@ -12,7 +12,7 @@
"ejs": "^3.1.10",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-router-dom": "^6.23.1",
"react-router-dom": "^6.30.1",
"use-async-effect": "^2.2.7"
},
"devDependencies": {
@@ -33,27 +33,29 @@
"@bull-board/express": "^5.21.4",
"@clickhouse/client": "^1.10.1",
"@elastic/elasticsearch": "^8.12.1",
"@hcaptcha/react-hcaptcha": "^1.14.0",
"@monaco-editor/react": "^4.4.6",
"@opentelemetry/api": "^1.9.0",
"@opentelemetry/api-logs": "^0.52.1",
"@opentelemetry/api-logs": "^0.206.0",
"@opentelemetry/context-zone": "^1.25.1",
"@opentelemetry/exporter-logs-otlp-http": "^0.52.1",
"@opentelemetry/exporter-metrics-otlp-proto": "^0.52.1",
"@opentelemetry/exporter-trace-otlp-http": "^0.52.1",
"@opentelemetry/exporter-trace-otlp-proto": "^0.52.1",
"@opentelemetry/exporter-logs-otlp-http": "^0.207.0",
"@opentelemetry/exporter-metrics-otlp-proto": "^0.207.0",
"@opentelemetry/exporter-trace-otlp-http": "^0.207.0",
"@opentelemetry/exporter-trace-otlp-proto": "^0.207.0",
"@opentelemetry/id-generator-aws-xray": "^1.2.2",
"@opentelemetry/instrumentation": "^0.52.1",
"@opentelemetry/instrumentation-fetch": "^0.52.1",
"@opentelemetry/instrumentation-xml-http-request": "^0.52.1",
"@opentelemetry/instrumentation": "^0.207.0",
"@opentelemetry/instrumentation-fetch": "^0.207.0",
"@opentelemetry/instrumentation-xml-http-request": "^0.207.0",
"@opentelemetry/resources": "^1.25.1",
"@opentelemetry/sdk-logs": "^0.52.1",
"@opentelemetry/sdk-logs": "^0.207.0",
"@opentelemetry/sdk-metrics": "^1.25.1",
"@opentelemetry/sdk-node": "^0.52.1",
"@opentelemetry/sdk-trace-node": "^1.25.1",
"@opentelemetry/sdk-node": "^0.207.0",
"@opentelemetry/sdk-trace-web": "^1.25.1",
"@opentelemetry/semantic-conventions": "^1.26.0",
"@opentelemetry/semantic-conventions": "^1.37.0",
"@remixicon/react": "^4.2.0",
"@simplewebauthn/server": "^13.2.2",
"@tippyjs/react": "^4.2.6",
"@types/archiver": "^6.0.3",
"@types/crypto-js": "^4.2.2",
"@types/qrcode": "^1.5.5",
"@types/react-highlight": "^0.12.8",
@@ -62,14 +64,17 @@
"@types/web-push": "^3.6.4",
"acme-client": "^5.3.0",
"airtable": "^0.12.2",
"axios": "^1.7.2",
"bullmq": "^5.3.3",
"archiver": "^7.0.1",
"axios": "^1.12.0",
"botbuilder": "^4.23.3",
"bullmq": "^5.61.0",
"cookie-parser": "^1.4.7",
"cors": "^2.8.5",
"cron-parser": "^4.8.1",
"crypto-js": "^4.2.0",
"dotenv": "^16.4.4",
"ejs": "^3.1.10",
"elkjs": "^0.10.0",
"esbuild": "^0.25.5",
"express": "^4.21.1",
"formik": "^2.4.6",
@@ -83,26 +88,26 @@
"moment": "^2.30.1",
"moment-timezone": "^0.5.45",
"node-cron": "^3.0.3",
"nodemailer": "^6.9.10",
"nodemailer": "^7.0.7",
"otpauth": "^9.3.1",
"pg": "^8.7.3",
"playwright": "^1.50.0",
"posthog-js": "^1.139.6",
"pg": "^8.16.3",
"playwright": "^1.56.0",
"posthog-js": "^1.275.3",
"prop-types": "^15.8.1",
"qrcode": "^1.5.3",
"react": "^18.3.1",
"react-beautiful-dnd": "^13.1.1",
"react-big-calendar": "^1.13.0",
"react-big-calendar": "^1.19.4",
"react-color": "^2.19.3",
"react-dom": "^18.3.1",
"react-dropzone": "^14.2.2",
"react-error-boundary": "^4.0.13",
"react-highlight": "^0.15.0",
"react-markdown": "^8.0.3",
"react-router-dom": "^6.24.1",
"react-router-dom": "^6.30.1",
"react-select": "^5.4.0",
"react-spinners": "^0.14.1",
"react-syntax-highlighter": "^15.5.0",
"react-syntax-highlighter": "^16.0.0",
"react-toggle": "^4.1.3",
"reactflow": "^11.11.4",
"recharts": "^2.12.7",
@@ -114,16 +119,16 @@
"socket.io": "^4.7.4",
"socket.io-client": "^4.7.5",
"stripe": "^10.17.0",
"tailwind-merge": "^2.5.2",
"tailwind-merge": "^2.6.0",
"tippy.js": "^6.3.7",
"twilio": "^4.22.0",
"typeorm": "^0.3.20",
"typeorm": "^0.3.26",
"typeorm-extension": "^2.2.13",
"universal-cookie": "^7.2.1",
"use-async-effect": "^2.2.6",
"uuid": "^8.3.2",
"web-push": "^3.6.7",
"zod": "^3.25.30"
"zod": "^3.25.76"
},
"devDependencies": {
"@faker-js/faker": "^8.0.2",
@@ -343,9 +348,9 @@
}
},
"node_modules/@remix-run/router": {
"version": "1.16.1",
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.16.1.tgz",
"integrity": "sha512-es2g3dq6Nb07iFxGk5GuHN20RwBZOsuDQN7izWIisUcv9r+d2C5jQxqmgkdebXgReWfiyUabcki6Fg77mSNrig==",
"version": "1.23.0",
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.23.0.tgz",
"integrity": "sha512-O3rHJzAQKamUz1fvE0Qaw0xSFqsA/yafi2iqeE0pvdFtCO1viYx8QL6f3Ln/aCCTLxs68SLf0KPM9eSeM8yBnA==",
"license": "MIT",
"engines": {
"node": ">=14.0.0"
@@ -521,21 +526,23 @@
}
},
"node_modules/brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"version": "1.1.12",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
"integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
}
},
"node_modules/braces": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
"dev": true,
"license": "MIT",
"dependencies": {
"fill-range": "^7.0.1"
"fill-range": "^7.1.1"
},
"engines": {
"node": ">=8"
@@ -682,9 +689,9 @@
}
},
"node_modules/filelist/node_modules/brace-expansion": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
"integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0"
@@ -703,10 +710,11 @@
}
},
"node_modules/fill-range": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
"dev": true,
"license": "MIT",
"dependencies": {
"to-regex-range": "^5.0.1"
},
@@ -793,6 +801,7 @@
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=0.12.0"
}
@@ -957,12 +966,12 @@
}
},
"node_modules/react-router": {
"version": "6.23.1",
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.23.1.tgz",
"integrity": "sha512-fzcOaRF69uvqbbM7OhvQyBTFDVrrGlsFdS3AL+1KfIBtGETibHzi3FkoTRyiDJnWNc2VxrfvR+657ROHjaNjqQ==",
"version": "6.30.1",
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.30.1.tgz",
"integrity": "sha512-X1m21aEmxGXqENEPG3T6u0Th7g0aS4ZmoNynhbs+Cn+q+QGTLt+d5IQ2bHAXKzKcxGJjxACpVbnYQSCRcfxHlQ==",
"license": "MIT",
"dependencies": {
"@remix-run/router": "1.16.1"
"@remix-run/router": "1.23.0"
},
"engines": {
"node": ">=14.0.0"
@@ -972,13 +981,13 @@
}
},
"node_modules/react-router-dom": {
"version": "6.23.1",
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.23.1.tgz",
"integrity": "sha512-utP+K+aSTtEdbWpC+4gxhdlPFwuEfDKq8ZrPFU65bbRJY+l706qjR7yaidBpo3MSeA/fzwbXWbKBI6ftOnP3OQ==",
"version": "6.30.1",
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.30.1.tgz",
"integrity": "sha512-llKsgOkZdbPU1Eg3zK8lCn+sjD9wMRZZPuzmdWWX5SUs8OFkN5HnFVC0u5KMeMaC9aoancFI/KoLuKPqN+hxHw==",
"license": "MIT",
"dependencies": {
"@remix-run/router": "1.16.1",
"react-router": "6.23.1"
"@remix-run/router": "1.23.0",
"react-router": "6.30.1"
},
"engines": {
"node": ">=14.0.0"
@@ -1008,6 +1017,16 @@
"loose-envify": "^1.1.0"
}
},
"node_modules/semver": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz",
"integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==",
"dev": true,
"license": "ISC",
"bin": {
"semver": "bin/semver.js"
}
},
"node_modules/simple-update-notifier": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-1.1.0.tgz",
@@ -1020,15 +1039,6 @@
"node": ">=8.10.0"
}
},
"node_modules/simple-update-notifier/node_modules/semver": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz",
"integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==",
"dev": true,
"bin": {
"semver": "bin/semver.js"
}
},
"node_modules/supports-color": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
@@ -1046,6 +1056,7 @@
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"is-number": "^7.0.0"
},

View File

@@ -33,7 +33,7 @@
"ejs": "^3.1.10",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-router-dom": "^6.23.1",
"react-router-dom": "^6.30.1",
"use-async-effect": "^2.2.7"
},
"devDependencies": {

View File

@@ -1,28 +1,44 @@
import {
LOGIN_API_URL,
VERIFY_TWO_FACTOR_AUTH_API_URL,
VERIFY_TOTP_AUTH_API_URL,
GENERATE_WEBAUTHN_AUTH_OPTIONS_API_URL,
VERIFY_WEBAUTHN_AUTH_API_URL,
} from "../Utils/ApiPaths";
import Route from "Common/Types/API/Route";
import URL from "Common/Types/API/URL";
import { JSONArray, JSONObject } from "Common/Types/JSON";
import ModelForm, { FormType } from "Common/UI/Components/Forms/ModelForm";
import ModelForm, {
FormType,
ModelField,
} from "Common/UI/Components/Forms/ModelForm";
import { CustomElementProps } from "Common/UI/Components/Forms/Types/Field";
import FormValues from "Common/UI/Components/Forms/Types/FormValues";
import FormFieldSchemaType from "Common/UI/Components/Forms/Types/FormFieldSchemaType";
import Link from "Common/UI/Components/Link/Link";
import { DASHBOARD_URL } from "Common/UI/Config";
import Captcha from "Common/UI/Components/Captcha/Captcha";
import {
DASHBOARD_URL,
CAPTCHA_ENABLED,
CAPTCHA_SITE_KEY,
} from "Common/UI/Config";
import OneUptimeLogo from "Common/UI/Images/logos/OneUptimeSVG/3-transparent.svg";
import EditionLabel from "Common/UI/Components/EditionLabel/EditionLabel";
import UiAnalytics from "Common/UI/Utils/Analytics";
import LoginUtil from "Common/UI/Utils/Login";
import UserTwoFactorAuth from "Common/Models/DatabaseModels/UserTwoFactorAuth";
import UserTotpAuth from "Common/Models/DatabaseModels/UserTotpAuth";
import UserWebAuthn from "Common/Models/DatabaseModels/UserWebAuthn";
import Navigation from "Common/UI/Utils/Navigation";
import UserUtil from "Common/UI/Utils/User";
import User from "Common/Models/DatabaseModels/User";
import React from "react";
import useAsyncEffect from "use-async-effect";
import StaticModelList from "Common/UI/Components/ModelList/StaticModelList";
import BasicForm from "Common/UI/Components/Forms/BasicForm";
import API from "Common/UI/Utils/API/API";
import HTTPErrorResponse from "Common/Types/API/HTTPErrorResponse";
import HTTPResponse from "Common/Types/API/HTTPResponse";
import Base64 from "Common/Utils/Base64";
import ErrorMessage from "Common/UI/Components/ErrorMessage/ErrorMessage";
import ComponentLoader from "Common/UI/Components/ComponentLoader/ComponentLoader";
const LoginPage: () => JSX.Element = () => {
const apiUrl: URL = LOGIN_API_URL;
@@ -36,19 +52,115 @@ const LoginPage: () => JSX.Element = () => {
const [showTwoFactorAuth, setShowTwoFactorAuth] =
React.useState<boolean>(false);
const [twoFactorAuthList, setTwoFactorAuthList] = React.useState<
UserTwoFactorAuth[]
>([]);
const [totpAuthList, setTotpAuthList] = React.useState<UserTotpAuth[]>([]);
const [selectedTwoFactorAuth, setSelectedTwoFactorAuth] = React.useState<
UserTwoFactorAuth | undefined
const [webAuthnList, setWebAuthnList] = React.useState<UserWebAuthn[]>([]);
const [selectedTotpAuth, setSelectedTotpAuth] = React.useState<
UserTotpAuth | undefined
>(undefined);
const [selectedWebAuthn, setSelectedWebAuthn] = React.useState<
UserWebAuthn | undefined
>(undefined);
type TwoFactorMethod = {
type: "totp" | "webauthn";
item: UserTotpAuth | UserWebAuthn;
};
const twoFactorMethods: TwoFactorMethod[] = [
...totpAuthList.map((item: UserTotpAuth) => {
return { type: "totp" as const, item };
}),
...webAuthnList.map((item: UserWebAuthn) => {
return { type: "webauthn" as const, item };
}),
];
const [isTwoFactorAuthLoading, setIsTwoFactorAuthLoading] =
React.useState<boolean>(false);
const [twofactorAuthError, setTwoFactorAuthError] =
React.useState<string>("");
const isCaptchaEnabled: boolean =
CAPTCHA_ENABLED && Boolean(CAPTCHA_SITE_KEY);
const [shouldResetCaptcha, setShouldResetCaptcha] =
React.useState<boolean>(false);
const [captchaResetSignal, setCaptchaResetSignal] = React.useState<number>(0);
const handleCaptchaReset: () => void = React.useCallback(() => {
setCaptchaResetSignal((current: number) => {
return current + 1;
});
}, []);
let loginFields: Array<ModelField<User>> = [
{
field: {
email: true,
},
fieldType: FormFieldSchemaType.Email,
placeholder: "jeff@example.com",
required: true,
disabled: Boolean(initialValues && initialValues["email"]),
title: "Email",
dataTestId: "email",
disableSpellCheck: true,
},
{
field: {
password: true,
},
title: "Password",
required: true,
validation: {
minLength: 6,
},
fieldType: FormFieldSchemaType.Password,
sideLink: {
text: "Forgot password?",
url: new Route("/accounts/forgot-password"),
openLinkInNewTab: false,
},
dataTestId: "password",
disableSpellCheck: true,
},
];
if (isCaptchaEnabled) {
loginFields = loginFields.concat([
{
overrideField: {
captchaToken: true,
},
overrideFieldKey: "captchaToken",
fieldType: FormFieldSchemaType.CustomComponent,
title: "Human Verification",
description:
"Complete the captcha challenge so we know you're not a bot.",
required: true,
showEvenIfPermissionDoesNotExist: true,
getCustomElement: (
_values: FormValues<User>,
customProps: CustomElementProps,
) => {
return (
<Captcha
siteKey={CAPTCHA_SITE_KEY}
resetSignal={captchaResetSignal}
error={customProps.error}
onTokenChange={(token: string) => {
customProps.onChange?.(token);
}}
onBlur={customProps.onBlur}
/>
);
},
},
]);
}
useAsyncEffect(async () => {
if (Navigation.getQueryStringByName("email")) {
setInitialValues({
@@ -57,6 +169,96 @@ const LoginPage: () => JSX.Element = () => {
}
}, []);
useAsyncEffect(async () => {
if (selectedWebAuthn) {
setIsTwoFactorAuthLoading(true);
try {
const result: HTTPResponse<JSONObject> = await API.post({
url: GENERATE_WEBAUTHN_AUTH_OPTIONS_API_URL,
data: {
data: {
email: initialValues["email"],
},
},
});
if (result instanceof HTTPErrorResponse) {
throw result;
}
const data: any = result.data as any;
// Convert base64url strings back to Uint8Array
data.options.challenge = Base64.base64UrlToUint8Array(
data.options.challenge,
);
if (data.options.allowCredentials) {
data.options.allowCredentials.forEach((cred: any) => {
cred.id = Base64.base64UrlToUint8Array(cred.id);
});
}
// Use WebAuthn API
const credential: PublicKeyCredential =
(await navigator.credentials.get({
publicKey: data.options,
})) as PublicKeyCredential;
const assertionResponse: AuthenticatorAssertionResponse =
credential.response as AuthenticatorAssertionResponse;
// Verify
const verifyResult: HTTPResponse<JSONObject> = await API.post({
url: VERIFY_WEBAUTHN_AUTH_API_URL,
data: {
data: {
...initialValues,
challenge: data.challenge,
credential: {
id: credential.id,
rawId: Base64.uint8ArrayToBase64Url(
new Uint8Array(credential.rawId),
),
response: {
authenticatorData: Base64.uint8ArrayToBase64Url(
new Uint8Array(assertionResponse.authenticatorData),
),
clientDataJSON: Base64.uint8ArrayToBase64Url(
new Uint8Array(assertionResponse.clientDataJSON),
),
signature: Base64.uint8ArrayToBase64Url(
new Uint8Array(assertionResponse.signature),
),
userHandle: assertionResponse.userHandle
? Base64.uint8ArrayToBase64Url(
new Uint8Array(assertionResponse.userHandle),
)
: null,
},
type: credential.type,
},
},
},
});
if (verifyResult instanceof HTTPErrorResponse) {
throw verifyResult;
}
const user: User = User.fromJSON(
verifyResult.data as JSONObject,
User,
) as User;
const miscData: JSONObject = {};
login(user as User, miscData);
} catch (error) {
setTwoFactorAuthError(API.getFriendlyErrorMessage(error as Error));
}
setIsTwoFactorAuthLoading(false);
}
}, [selectedWebAuthn]);
type LoginFunction = (user: User, miscData: JSONObject) => void;
const login: LoginFunction = (user: User, miscData: JSONObject): void => {
@@ -79,6 +281,9 @@ const LoginPage: () => JSX.Element = () => {
src={OneUptimeLogo}
alt="OneUptime"
/>
<div className="mt-4 flex justify-center">
<EditionLabel />
</div>
{!showTwoFactorAuth && (
<>
<h2 className="mt-6 text-center text-2xl tracking-tight text-gray-900">
@@ -111,61 +316,64 @@ const LoginPage: () => JSX.Element = () => {
modelType={User}
id="login-form"
name="Login"
fields={[
{
field: {
email: true,
},
fieldType: FormFieldSchemaType.Email,
placeholder: "jeff@example.com",
required: true,
disabled: Boolean(initialValues && initialValues["email"]),
title: "Email",
dataTestId: "email",
disableSpellCheck: true,
},
{
field: {
password: true,
},
title: "Password",
required: true,
validation: {
minLength: 6,
},
fieldType: FormFieldSchemaType.Password,
sideLink: {
text: "Forgot password?",
url: new Route("/accounts/forgot-password"),
openLinkInNewTab: false,
},
dataTestId: "password",
disableSpellCheck: true,
},
]}
fields={loginFields}
createOrUpdateApiUrl={apiUrl}
formType={FormType.Create}
submitButtonText={"Login"}
onBeforeCreate={(data: User) => {
onBeforeCreate={(data: User, miscDataProps: JSONObject) => {
if (isCaptchaEnabled) {
const captchaToken: string | undefined = (
miscDataProps["captchaToken"] as string | undefined
)
?.toString()
.trim();
if (!captchaToken) {
throw new Error(
"Please complete the captcha challenge before signing in.",
);
}
miscDataProps["captchaToken"] = captchaToken;
setShouldResetCaptcha(true);
}
setInitialValues(User.toJSON(data, User));
return Promise.resolve(data);
}}
onLoadingChange={(loading: boolean) => {
if (!isCaptchaEnabled) {
return;
}
if (!loading && shouldResetCaptcha) {
setShouldResetCaptcha(false);
handleCaptchaReset();
}
}}
onSuccess={(
value: User | JSONObject,
miscData: JSONObject | undefined,
) => {
if (
miscData &&
(miscData as JSONObject)["twoFactorAuth"] === true
((((miscData as JSONObject)["totpAuthList"] as JSONArray)
?.length || 0) > 0 ||
(((miscData as JSONObject)["webAuthnList"] as JSONArray)
?.length || 0) > 0)
) {
const twoFactorAuthList: Array<UserTwoFactorAuth> =
UserTwoFactorAuth.fromJSONArray(
(miscData as JSONObject)[
"twoFactorAuthList"
] as JSONArray,
UserTwoFactorAuth,
const totpAuthList: Array<UserTotpAuth> =
UserTotpAuth.fromJSONArray(
(miscData as JSONObject)["totpAuthList"] as JSONArray,
UserTotpAuth,
);
setTwoFactorAuthList(twoFactorAuthList);
const webAuthnList: Array<UserWebAuthn> =
UserWebAuthn.fromJSONArray(
(miscData as JSONObject)["webAuthnList"] as JSONArray,
UserWebAuthn,
);
setTotpAuthList(totpAuthList);
setWebAuthnList(webAuthnList);
setShowTwoFactorAuth(true);
return;
}
@@ -187,19 +395,53 @@ const LoginPage: () => JSX.Element = () => {
/>
)}
{showTwoFactorAuth && !selectedTwoFactorAuth && (
<StaticModelList<UserTwoFactorAuth>
titleField="name"
descriptionField=""
selectedItems={[]}
list={twoFactorAuthList}
onClick={(item: UserTwoFactorAuth) => {
setSelectedTwoFactorAuth(item);
}}
/>
{showTwoFactorAuth && !selectedTotpAuth && !selectedWebAuthn && (
<div className="space-y-4">
{twoFactorMethods.map(
(method: TwoFactorMethod, index: number) => {
return (
<div
key={index}
className="cursor-pointer p-4 border border-gray-300 rounded-lg hover:bg-gray-50"
onClick={() => {
if (method.type === "totp") {
setSelectedTotpAuth(method.item as UserTotpAuth);
} else {
setSelectedWebAuthn(method.item as UserWebAuthn);
}
}}
>
<div className="font-medium">
{(method.item as any).name}
</div>
<div className="text-sm text-gray-500">
{method.type === "totp"
? "Authenticator App"
: "Security Key"}
</div>
</div>
);
},
)}
</div>
)}
{showTwoFactorAuth && selectedTwoFactorAuth && (
{showTwoFactorAuth && selectedWebAuthn && (
<div className="text-center">
<div className="text-lg font-medium mb-4">
Authenticating with Security Key
</div>
<div className="text-sm text-gray-500 mb-4">
Please follow the instructions on your security key device.
</div>
{isTwoFactorAuthLoading && <ComponentLoader />}
{twofactorAuthError && (
<ErrorMessage message={twofactorAuthError} />
)}
</div>
)}
{showTwoFactorAuth && selectedTotpAuth && (
<BasicForm
id="two-factor-auth-form"
name="Two Factor Auth"
@@ -225,14 +467,17 @@ const LoginPage: () => JSX.Element = () => {
try {
const code: string = data["code"] as string;
const twoFactorAuthId: string =
selectedTwoFactorAuth.id?.toString() as string;
selectedTotpAuth!.id?.toString() as string;
const result: HTTPErrorResponse | HTTPResponse<JSONObject> =
await API.post(VERIFY_TWO_FACTOR_AUTH_API_URL, {
await API.post({
url: VERIFY_TOTP_AUTH_API_URL,
data: {
...initialValues,
code: code,
twoFactorAuthId: twoFactorAuthId,
data: {
...initialValues,
code: code,
twoFactorAuthId: twoFactorAuthId,
},
},
});
@@ -261,7 +506,7 @@ const LoginPage: () => JSX.Element = () => {
)}
</div>
<div className="mt-10 text-center">
{!selectedTwoFactorAuth && (
{!selectedTotpAuth && !selectedWebAuthn && (
<div className="text-muted mb-0 text-gray-500">
Don&apos;t have an account?{" "}
<Link
@@ -272,11 +517,12 @@ const LoginPage: () => JSX.Element = () => {
</Link>
</div>
)}
{selectedTwoFactorAuth ? (
{selectedTotpAuth || selectedWebAuthn ? (
<div className="text-muted mb-0 text-gray-500">
<Link
onClick={() => {
setSelectedTwoFactorAuth(undefined);
setSelectedTotpAuth(undefined);
setSelectedWebAuthn(undefined);
}}
className="text-indigo-500 hover:text-indigo-900 cursor-pointer"
>

View File

@@ -42,12 +42,12 @@ const LoginPage: () => JSX.Element = () => {
try {
// get sso config by email.
const listResult: HTTPErrorResponse | HTTPResponse<JSONArray> =
await API.get(
URL.fromString(apiUrl.toString()).addQueryParam(
await API.get({
url: URL.fromString(apiUrl.toString()).addQueryParam(
"email",
email.toString(),
),
);
});
if (listResult instanceof HTTPErrorResponse) {
throw listResult;

View File

@@ -4,12 +4,22 @@ import URL from "Common/Types/API/URL";
import Dictionary from "Common/Types/Dictionary";
import { JSONObject } from "Common/Types/JSON";
import ErrorMessage from "Common/UI/Components/ErrorMessage/ErrorMessage";
import ModelForm, { FormType } from "Common/UI/Components/Forms/ModelForm";
import Fields from "Common/UI/Components/Forms/Types/Fields";
import ModelForm, {
FormType,
ModelField,
} from "Common/UI/Components/Forms/ModelForm";
import { CustomElementProps } from "Common/UI/Components/Forms/Types/Field";
import FormFieldSchemaType from "Common/UI/Components/Forms/Types/FormFieldSchemaType";
import FormValues from "Common/UI/Components/Forms/Types/FormValues";
import Link from "Common/UI/Components/Link/Link";
import PageLoader from "Common/UI/Components/Loader/PageLoader";
import { BILLING_ENABLED, DASHBOARD_URL } from "Common/UI/Config";
import Captcha from "Common/UI/Components/Captcha/Captcha";
import {
BILLING_ENABLED,
DASHBOARD_URL,
CAPTCHA_ENABLED,
CAPTCHA_SITE_KEY,
} from "Common/UI/Config";
import OneUptimeLogo from "Common/UI/Images/logos/OneUptimeSVG/3-transparent.svg";
import BaseAPI from "Common/UI/Utils/API/API";
import UiAnalytics from "Common/UI/Utils/Analytics";
@@ -36,6 +46,19 @@ const RegisterPage: () => JSX.Element = () => {
undefined,
);
const isCaptchaEnabled: boolean =
CAPTCHA_ENABLED && Boolean(CAPTCHA_SITE_KEY);
const [shouldResetCaptcha, setShouldResetCaptcha] =
React.useState<boolean>(false);
const [captchaResetSignal, setCaptchaResetSignal] = React.useState<number>(0);
const handleCaptchaReset: () => void = React.useCallback(() => {
setCaptchaResetSignal((current: number) => {
return current + 1;
});
}, []);
if (UserUtil.isLoggedIn()) {
Navigation.navigate(DASHBOARD_URL);
}
@@ -93,7 +116,7 @@ const RegisterPage: () => JSX.Element = () => {
}
}, []);
let formFields: Fields<User> = [
let formFields: Array<ModelField<User>> = [
{
field: {
email: true,
@@ -183,6 +206,39 @@ const RegisterPage: () => JSX.Element = () => {
},
]);
if (isCaptchaEnabled) {
formFields = formFields.concat([
{
overrideField: {
captchaToken: true,
},
overrideFieldKey: "captchaToken",
fieldType: FormFieldSchemaType.CustomComponent,
title: "Human Verification",
description:
"Complete the captcha challenge so we know you're not a bot.",
required: true,
showEvenIfPermissionDoesNotExist: true,
getCustomElement: (
_values: FormValues<User>,
customProps: CustomElementProps,
) => {
return (
<Captcha
siteKey={CAPTCHA_SITE_KEY}
resetSignal={captchaResetSignal}
error={customProps.error}
onTokenChange={(token: string) => {
customProps.onChange?.(token);
}}
onBlur={customProps.onBlur}
/>
);
},
},
]);
}
if (error) {
return <ErrorMessage message={error} />;
}
@@ -222,7 +278,27 @@ const RegisterPage: () => JSX.Element = () => {
maxPrimaryButtonWidth={true}
fields={formFields}
createOrUpdateApiUrl={apiUrl}
onBeforeCreate={(item: User): Promise<User> => {
onBeforeCreate={(
item: User,
miscDataProps: JSONObject,
): Promise<User> => {
if (isCaptchaEnabled) {
const captchaToken: string | undefined = (
miscDataProps["captchaToken"] as string | undefined
)
?.toString()
.trim();
if (!captchaToken) {
throw new Error(
"Please complete the captcha challenge before signing up.",
);
}
miscDataProps["captchaToken"] = captchaToken;
setShouldResetCaptcha(true);
}
const utmParams: Dictionary<string> = UserUtil.getUtmParams();
if (utmParams && Object.keys(utmParams).length > 0) {
@@ -240,6 +316,16 @@ const RegisterPage: () => JSX.Element = () => {
}}
formType={FormType.Create}
submitButtonText={"Sign Up"}
onLoadingChange={(loading: boolean) => {
if (!isCaptchaEnabled) {
return;
}
if (!loading && shouldResetCaptcha) {
setShouldResetCaptcha(false);
handleCaptchaReset();
}
}}
onSuccess={(value: User, miscData: JSONObject | undefined) => {
if (value && value.email) {
UiAnalytics.userAuth(value.email);

View File

@@ -1,6 +1,6 @@
import Route from "Common/Types/API/Route";
import URL from "Common/Types/API/URL";
import { IDENTITY_URL } from "Common/UI/Config";
import { IDENTITY_URL, APP_API_URL } from "Common/UI/Config";
export const SIGNUP_API_URL: URL = URL.fromURL(IDENTITY_URL).addRoute(
new Route("/signup"),
@@ -9,9 +9,17 @@ export const LOGIN_API_URL: URL = URL.fromURL(IDENTITY_URL).addRoute(
new Route("/login"),
);
export const VERIFY_TWO_FACTOR_AUTH_API_URL: URL = URL.fromURL(
export const VERIFY_TOTP_AUTH_API_URL: URL = URL.fromURL(IDENTITY_URL).addRoute(
new Route("/verify-totp-auth"),
);
export const GENERATE_WEBAUTHN_AUTH_OPTIONS_API_URL: URL = URL.fromURL(
APP_API_URL,
).addRoute(new Route("/user-webauthn/generate-authentication-options"));
export const VERIFY_WEBAUTHN_AUTH_API_URL: URL = URL.fromURL(
IDENTITY_URL,
).addRoute(new Route("/verify-two-factor-auth"));
).addRoute(new Route("/verify-webauthn-auth"));
export const SERVICE_PROVIDER_LOGIN_URL: URL = URL.fromURL(
IDENTITY_URL,

View File

@@ -3,7 +3,7 @@
#
# Pull base image nodejs image.
FROM public.ecr.aws/docker/library/node:23.8-alpine3.21
FROM public.ecr.aws/docker/library/node:24.9-alpine3.21
RUN mkdir /tmp/npm && chmod 2777 /tmp/npm && chown 1000:1000 /tmp/npm && npm config set cache /tmp/npm --global
RUN npm config set fetch-retries 5
@@ -14,9 +14,12 @@ RUN npm config set fetch-retry-maxtimeout 600000
ARG GIT_SHA
ARG APP_VERSION
ARG IS_ENTERPRISE_EDITION=false
ENV GIT_SHA=${GIT_SHA}
ENV APP_VERSION=${APP_VERSION}
ENV IS_ENTERPRISE_EDITION=${IS_ENTERPRISE_EDITION}
ENV PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1
# IF APP_VERSION is not set, set it to 1.0.0

View File

@@ -1,13 +1,74 @@
import { PromiseVoidFunction } from "Common/Types/FunctionTypes";
import Express, { ExpressApplication } from "Common/Server/Utils/Express";
import Express, {
ExpressApplication,
ExpressRequest,
ExpressResponse,
} from "Common/Server/Utils/Express";
import logger from "Common/Server/Utils/Logger";
import App from "Common/Server/Utils/StartServer";
import Response from "Common/Server/Utils/Response";
import UserMiddleware from "Common/Server/Middleware/UserAuthorization";
import JSONWebToken from "Common/Server/Utils/JsonWebToken";
import NotAuthorizedException from "Common/Types/Exception/NotAuthorizedException";
import { JSONObject } from "Common/Types/JSON";
import "ejs";
import JSONWebTokenData from "Common/Types/JsonWebTokenData";
export const APP_NAME: string = "admin";
const app: ExpressApplication = Express.getExpressApp();
type EnsureMasterAdminAccessFunction = (
req: ExpressRequest,
res: ExpressResponse,
) => Promise<JSONObject>;
const ensureMasterAdminAccess: EnsureMasterAdminAccessFunction = async (
req: ExpressRequest,
res: ExpressResponse,
): Promise<JSONObject> => {
try {
const accessToken: string | undefined =
UserMiddleware.getAccessTokenFromExpressRequest(req);
if (!accessToken) {
Response.sendErrorResponse(
req,
res,
new NotAuthorizedException(
"Unauthorized: Only master admins can access the admin dashboard.",
),
);
return {};
}
const authData: JSONWebTokenData = JSONWebToken.decode(accessToken);
if (!authData.isMasterAdmin) {
Response.sendErrorResponse(
req,
res,
new NotAuthorizedException(
"Unauthorized: Only master admins can access the admin dashboard.",
),
);
return {};
}
return {};
} catch (error) {
logger.error(error);
Response.sendErrorResponse(
req,
res,
new NotAuthorizedException(
"Unauthorized: Only master admins can access the admin dashboard.",
),
);
return {};
}
};
const init: PromiseVoidFunction = async (): Promise<void> => {
try {
// init the app
@@ -19,6 +80,7 @@ const init: PromiseVoidFunction = async (): Promise<void> => {
liveCheck: async () => {},
readyCheck: async () => {},
},
getVariablesToRenderIndexPage: ensureMasterAdminAccess,
});
// add default routes

View File

@@ -1,7 +1,10 @@
{
"watch": ["./","../Common/UI", "../Common/Types", "../Common/Utils", "../Common/Models"],
"ext": "ts,json,tsx,env,js,jsx,hbs",
"ext": "ts,tsx",
"ignore": [
"./node_modules/**",
"./public/**",
"./bin/**",
"./public/**",
"./public/dist/**",
"./build/*",

View File

@@ -12,7 +12,7 @@
"ejs": "^3.1.10",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-router-dom": "^6.23.1"
"react-router-dom": "^6.30.1"
},
"devDependencies": {
"@types/node": "^16.11.35",
@@ -32,27 +32,29 @@
"@bull-board/express": "^5.21.4",
"@clickhouse/client": "^1.10.1",
"@elastic/elasticsearch": "^8.12.1",
"@hcaptcha/react-hcaptcha": "^1.14.0",
"@monaco-editor/react": "^4.4.6",
"@opentelemetry/api": "^1.9.0",
"@opentelemetry/api-logs": "^0.52.1",
"@opentelemetry/api-logs": "^0.206.0",
"@opentelemetry/context-zone": "^1.25.1",
"@opentelemetry/exporter-logs-otlp-http": "^0.52.1",
"@opentelemetry/exporter-metrics-otlp-proto": "^0.52.1",
"@opentelemetry/exporter-trace-otlp-http": "^0.52.1",
"@opentelemetry/exporter-trace-otlp-proto": "^0.52.1",
"@opentelemetry/exporter-logs-otlp-http": "^0.207.0",
"@opentelemetry/exporter-metrics-otlp-proto": "^0.207.0",
"@opentelemetry/exporter-trace-otlp-http": "^0.207.0",
"@opentelemetry/exporter-trace-otlp-proto": "^0.207.0",
"@opentelemetry/id-generator-aws-xray": "^1.2.2",
"@opentelemetry/instrumentation": "^0.52.1",
"@opentelemetry/instrumentation-fetch": "^0.52.1",
"@opentelemetry/instrumentation-xml-http-request": "^0.52.1",
"@opentelemetry/instrumentation": "^0.207.0",
"@opentelemetry/instrumentation-fetch": "^0.207.0",
"@opentelemetry/instrumentation-xml-http-request": "^0.207.0",
"@opentelemetry/resources": "^1.25.1",
"@opentelemetry/sdk-logs": "^0.52.1",
"@opentelemetry/sdk-logs": "^0.207.0",
"@opentelemetry/sdk-metrics": "^1.25.1",
"@opentelemetry/sdk-node": "^0.52.1",
"@opentelemetry/sdk-trace-node": "^1.25.1",
"@opentelemetry/sdk-node": "^0.207.0",
"@opentelemetry/sdk-trace-web": "^1.25.1",
"@opentelemetry/semantic-conventions": "^1.26.0",
"@opentelemetry/semantic-conventions": "^1.37.0",
"@remixicon/react": "^4.2.0",
"@simplewebauthn/server": "^13.2.2",
"@tippyjs/react": "^4.2.6",
"@types/archiver": "^6.0.3",
"@types/crypto-js": "^4.2.2",
"@types/qrcode": "^1.5.5",
"@types/react-highlight": "^0.12.8",
@@ -61,14 +63,17 @@
"@types/web-push": "^3.6.4",
"acme-client": "^5.3.0",
"airtable": "^0.12.2",
"axios": "^1.7.2",
"bullmq": "^5.3.3",
"archiver": "^7.0.1",
"axios": "^1.12.0",
"botbuilder": "^4.23.3",
"bullmq": "^5.61.0",
"cookie-parser": "^1.4.7",
"cors": "^2.8.5",
"cron-parser": "^4.8.1",
"crypto-js": "^4.2.0",
"dotenv": "^16.4.4",
"ejs": "^3.1.10",
"elkjs": "^0.10.0",
"esbuild": "^0.25.5",
"express": "^4.21.1",
"formik": "^2.4.6",
@@ -82,26 +87,26 @@
"moment": "^2.30.1",
"moment-timezone": "^0.5.45",
"node-cron": "^3.0.3",
"nodemailer": "^6.9.10",
"nodemailer": "^7.0.7",
"otpauth": "^9.3.1",
"pg": "^8.7.3",
"playwright": "^1.50.0",
"posthog-js": "^1.139.6",
"pg": "^8.16.3",
"playwright": "^1.56.0",
"posthog-js": "^1.275.3",
"prop-types": "^15.8.1",
"qrcode": "^1.5.3",
"react": "^18.3.1",
"react-beautiful-dnd": "^13.1.1",
"react-big-calendar": "^1.13.0",
"react-big-calendar": "^1.19.4",
"react-color": "^2.19.3",
"react-dom": "^18.3.1",
"react-dropzone": "^14.2.2",
"react-error-boundary": "^4.0.13",
"react-highlight": "^0.15.0",
"react-markdown": "^8.0.3",
"react-router-dom": "^6.24.1",
"react-router-dom": "^6.30.1",
"react-select": "^5.4.0",
"react-spinners": "^0.14.1",
"react-syntax-highlighter": "^15.5.0",
"react-syntax-highlighter": "^16.0.0",
"react-toggle": "^4.1.3",
"reactflow": "^11.11.4",
"recharts": "^2.12.7",
@@ -113,16 +118,16 @@
"socket.io": "^4.7.4",
"socket.io-client": "^4.7.5",
"stripe": "^10.17.0",
"tailwind-merge": "^2.5.2",
"tailwind-merge": "^2.6.0",
"tippy.js": "^6.3.7",
"twilio": "^4.22.0",
"typeorm": "^0.3.20",
"typeorm": "^0.3.26",
"typeorm-extension": "^2.2.13",
"universal-cookie": "^7.2.1",
"use-async-effect": "^2.2.6",
"uuid": "^8.3.2",
"web-push": "^3.6.7",
"zod": "^3.25.30"
"zod": "^3.25.76"
},
"devDependencies": {
"@faker-js/faker": "^8.0.2",
@@ -342,9 +347,9 @@
"dev": true
},
"node_modules/@remix-run/router": {
"version": "1.16.1",
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.16.1.tgz",
"integrity": "sha512-es2g3dq6Nb07iFxGk5GuHN20RwBZOsuDQN7izWIisUcv9r+d2C5jQxqmgkdebXgReWfiyUabcki6Fg77mSNrig==",
"version": "1.23.0",
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.23.0.tgz",
"integrity": "sha512-O3rHJzAQKamUz1fvE0Qaw0xSFqsA/yafi2iqeE0pvdFtCO1viYx8QL6f3Ln/aCCTLxs68SLf0KPM9eSeM8yBnA==",
"license": "MIT",
"engines": {
"node": ">=14.0.0"
@@ -490,21 +495,23 @@
}
},
"node_modules/brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"version": "1.1.12",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
"integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
}
},
"node_modules/braces": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
"dev": true,
"license": "MIT",
"dependencies": {
"fill-range": "^7.0.1"
"fill-range": "^7.1.1"
},
"engines": {
"node": ">=8"
@@ -600,9 +607,10 @@
}
},
"node_modules/filelist/node_modules/brace-expansion": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
"integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0"
}
@@ -619,10 +627,11 @@
}
},
"node_modules/fill-range": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
"dev": true,
"license": "MIT",
"dependencies": {
"to-regex-range": "^5.0.1"
},
@@ -709,6 +718,7 @@
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=0.12.0"
}
@@ -936,12 +946,12 @@
}
},
"node_modules/react-router": {
"version": "6.23.1",
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.23.1.tgz",
"integrity": "sha512-fzcOaRF69uvqbbM7OhvQyBTFDVrrGlsFdS3AL+1KfIBtGETibHzi3FkoTRyiDJnWNc2VxrfvR+657ROHjaNjqQ==",
"version": "6.30.1",
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.30.1.tgz",
"integrity": "sha512-X1m21aEmxGXqENEPG3T6u0Th7g0aS4ZmoNynhbs+Cn+q+QGTLt+d5IQ2bHAXKzKcxGJjxACpVbnYQSCRcfxHlQ==",
"license": "MIT",
"dependencies": {
"@remix-run/router": "1.16.1"
"@remix-run/router": "1.23.0"
},
"engines": {
"node": ">=14.0.0"
@@ -951,13 +961,13 @@
}
},
"node_modules/react-router-dom": {
"version": "6.23.1",
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.23.1.tgz",
"integrity": "sha512-utP+K+aSTtEdbWpC+4gxhdlPFwuEfDKq8ZrPFU65bbRJY+l706qjR7yaidBpo3MSeA/fzwbXWbKBI6ftOnP3OQ==",
"version": "6.30.1",
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.30.1.tgz",
"integrity": "sha512-llKsgOkZdbPU1Eg3zK8lCn+sjD9wMRZZPuzmdWWX5SUs8OFkN5HnFVC0u5KMeMaC9aoancFI/KoLuKPqN+hxHw==",
"license": "MIT",
"dependencies": {
"@remix-run/router": "1.16.1",
"react-router": "6.23.1"
"@remix-run/router": "1.23.0",
"react-router": "6.30.1"
},
"engines": {
"node": ">=14.0.0"
@@ -987,6 +997,16 @@
"loose-envify": "^1.1.0"
}
},
"node_modules/semver": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz",
"integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==",
"dev": true,
"license": "ISC",
"bin": {
"semver": "bin/semver.js"
}
},
"node_modules/simple-update-notifier": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-1.1.0.tgz",
@@ -999,15 +1019,6 @@
"node": ">=8.10.0"
}
},
"node_modules/simple-update-notifier/node_modules/semver": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz",
"integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==",
"dev": true,
"bin": {
"semver": "bin/semver.js"
}
},
"node_modules/supports-color": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
@@ -1025,6 +1036,7 @@
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"is-number": "^7.0.0"
},

View File

@@ -8,7 +8,7 @@
"ejs": "^3.1.10",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-router-dom": "^6.23.1"
"react-router-dom": "^6.30.2"
},
"scripts": {
"dev-build": "NODE_ENV=development node esbuild.config.js",

View File

@@ -3,7 +3,6 @@
<link rel="icon" type="image/png" sizes="194x194" href="/favicon-194x194.png">
<link rel="icon" type="image/png" sizes="192x192" href="/android-chrome-192x192.png">
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
<link rel="manifest" href="/site.webmanifest">
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5">
<meta name="msapplication-TileColor" content="#121212">
<meta name="theme-color" content="#121212">

View File

@@ -1,56 +0,0 @@
{
"name": "OneUptime Account",
"short_name": "OneUptime",
"icons": [
{
"src": "/accounts/assets/img/favicons/android-chrome-36x36.png",
"sizes": "36x36",
"type": "image/png"
},
{
"src": "/accounts/assets/img/favicons/android-chrome-48x48.png",
"sizes": "48x48",
"type": "image/png"
},
{
"src": "/accounts/assets/img/favicons/android-chrome-72x72.png",
"sizes": "72x72",
"type": "image/png"
},
{
"src": "/accounts/assets/img/favicons/android-chrome-96x96.png",
"sizes": "96x96",
"type": "image/png"
},
{
"src": "/accounts/assets/img/favicons/android-chrome-144x144.png",
"sizes": "144x144",
"type": "image/png"
},
{
"src": "/accounts/assets/img/favicons/android-chrome-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "/accounts/assets/img/favicons/android-chrome-256x256.png",
"sizes": "256x256",
"type": "image/png"
},
{
"src": "/accounts/assets/img/favicons/android-chrome-384x384.png",
"sizes": "384x384",
"type": "image/png"
},
{
"src": "/accounts/assets/img/favicons/android-chrome-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
],
"start_url": ".",
"theme_color": "#121212",
"background_color": "#121212",
"display": "standalone"
}

View File

@@ -1,25 +0,0 @@
{
"short_name": "React App",
"name": "Create React App Sample",
"icons": [
{
"src": "./assets/img/favicons/favicon.ico",
"sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon"
},
{
"src": "logo192.png",
"type": "image/png",
"sizes": "192x192"
},
{
"src": "logo512.png",
"type": "image/png",
"sizes": "512x512"
}
],
"start_url": ".",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}

View File

@@ -5,6 +5,7 @@ import Projects from "./Pages/Projects/Index";
import SettingsAPIKey from "./Pages/Settings/APIKey/Index";
import SettingsAuthentication from "./Pages/Settings/Authentication/Index";
import SettingsCallSMS from "./Pages/Settings/CallSMS/Index";
import SettingsWhatsApp from "./Pages/Settings/WhatsApp/Index";
// Settings Pages.
import SettingsEmail from "./Pages/Settings/Email/Index";
import SettingsProbes from "./Pages/Settings/Probes/Index";
@@ -25,6 +26,7 @@ import {
} from "react-router-dom";
import UserView from "./Pages/Users/View/Index";
import UserDelete from "./Pages/Users/View/Delete";
import UserSettings from "./Pages/Users/View/Settings";
import ProjectView from "./Pages/Projects/View/Index";
import ProjectDelete from "./Pages/Projects/View/Delete";
@@ -70,6 +72,11 @@ const App: () => JSX.Element = () => {
element={<UserView />}
/>
<PageRoute
path={RouteMap[PageMap.USER_SETTINGS]?.toString() || ""}
element={<UserSettings />}
/>
<PageRoute
path={RouteMap[PageMap.USER_DELETE]?.toString() || ""}
element={<UserDelete />}
@@ -105,6 +112,11 @@ const App: () => JSX.Element = () => {
element={<SettingsCallSMS />}
/>
<PageRoute
path={RouteMap[PageMap.SETTINGS_WHATSAPP]?.toString() || ""}
element={<SettingsWhatsApp />}
/>
<PageRoute
path={RouteMap[PageMap.SETTINGS_PROBES]?.toString() || ""}
element={<SettingsProbes />}

View File

@@ -54,9 +54,9 @@ const DashboardFooter: () => JSX.Element = () => {
const fetchAppVersion: (appName: string) => Promise<JSONObject> = async (
appName: string,
): Promise<JSONObject> => {
const response: HTTPResponse<JSONObject> = await API.get<JSONObject>(
URL.fromString(`${HTTP_PROTOCOL}/${HOST}${appName}/version`),
);
const response: HTTPResponse<JSONObject> = await API.get<JSONObject>({
url: URL.fromString(`${HTTP_PROTOCOL}/${HOST}${appName}/version`),
});
if (response.data) {
return response.data as JSONObject;

View File

@@ -3,6 +3,7 @@ import Logo from "./Logo";
import UserProfile from "./UserProfile";
import Button, { ButtonStyleType } from "Common/UI/Components/Button/Button";
import Header from "Common/UI/Components/Header/Header";
import EditionLabel from "Common/UI/Components/EditionLabel/EditionLabel";
import { DASHBOARD_URL } from "Common/UI/Config";
import Navigation from "Common/UI/Utils/Navigation";
import React, { FunctionComponent, ReactElement } from "react";
@@ -27,6 +28,7 @@ const DashboardHeader: FunctionComponent = (): ReactElement => {
}
rightComponents={
<>
<EditionLabel className="mr-3 hidden md:inline-flex" />
<Button
title="Exit Admin"
buttonStyle={ButtonStyleType.NORMAL}

View File

@@ -50,6 +50,15 @@ const DashboardSideMenu: () => JSX.Element = (): ReactElement => {
}}
icon={IconProp.Call}
/>
<SideMenuItem
link={{
title: "WhatsApp",
to: RouteUtil.populateRouteParams(
RouteMap[PageMap.SETTINGS_WHATSAPP] as Route,
),
}}
icon={IconProp.WhatsApp}
/>
</SideMenuSection>
<SideMenuSection title="Monitoring">

View File

@@ -0,0 +1,491 @@
import PageMap from "../../../Utils/PageMap";
import RouteMap, { RouteUtil } from "../../../Utils/RouteMap";
import DashboardSideMenu from "../SideMenu";
import Route from "Common/Types/API/Route";
import ObjectID from "Common/Types/ObjectID";
import FormFieldSchemaType from "Common/UI/Components/Forms/Types/FormFieldSchemaType";
import CardModelDetail from "Common/UI/Components/ModelDetail/CardModelDetail";
import Page from "Common/UI/Components/Page/Page";
import FieldType from "Common/UI/Components/Types/FieldType";
import GlobalConfig from "Common/Models/DatabaseModels/GlobalConfig";
import React, { FunctionComponent, ReactElement, useState } from "react";
import Card from "Common/UI/Components/Card/Card";
import MarkdownViewer from "Common/UI/Components/Markdown.tsx/MarkdownViewer";
import BasicForm from "Common/UI/Components/Forms/BasicForm";
import Alert, { AlertType } from "Common/UI/Components/Alerts/Alert";
import { JSONObject } from "Common/Types/JSON";
import HTTPErrorResponse from "Common/Types/API/HTTPErrorResponse";
import HTTPResponse from "Common/Types/API/HTTPResponse";
import URL from "Common/Types/API/URL";
import API from "Common/UI/Utils/API/API";
import { APP_API_URL } from "Common/UI/Config";
import WhatsAppTemplateMessages, {
WhatsAppTemplateId,
WhatsAppTemplateIds,
WhatsAppTemplateLanguage,
} from "Common/Types/WhatsApp/WhatsAppTemplates";
type ToFriendlyName = (value: string) => string;
const toFriendlyName: ToFriendlyName = (value: string): string => {
return value
.replace(/([a-z0-9])([A-Z])/g, "$1 $2")
.replace(/_/g, " ")
.replace(/\s+/g, " ")
.trim();
};
type ExtractTemplateVariables = (template: string) => Array<string>;
const extractTemplateVariables: ExtractTemplateVariables = (
template: string,
): Array<string> => {
const matches: RegExpMatchArray | null = template.match(/\{\{(.*?)\}\}/g);
if (!matches) {
return [];
}
const uniqueVariables: Set<string> = new Set<string>();
for (const match of matches) {
const variable: string = match.replace("{{", "").replace("}}", "").trim();
if (variable) {
uniqueVariables.add(variable);
}
}
return Array.from(uniqueVariables).sort((a: string, b: string) => {
return a.localeCompare(b);
});
};
type BuildWhatsAppSetupMarkdown = () => string;
const buildWhatsAppSetupMarkdown: BuildWhatsAppSetupMarkdown = (): string => {
const templateKeys: Array<keyof typeof WhatsAppTemplateIds> = Object.keys(
WhatsAppTemplateIds,
) as Array<keyof typeof WhatsAppTemplateIds>;
const appApiBaseUrl: string = APP_API_URL.toString().replace(/\/$/, "");
const primaryWebhookUrl: string = `${appApiBaseUrl}/notification/whatsapp/webhook`;
const description: string =
"Follow these steps to connect Meta WhatsApp with OneUptime so notifications can be delivered via WhatsApp.";
const prerequisitesList: Array<string> = [
"Meta Business Manager admin access for the WhatsApp Business Account.",
"A WhatsApp Business phone number approved for API messaging.",
"Admin access to OneUptime with permission to edit global notification settings.",
"A webhook verify token string that you'll configure identically in Meta and OneUptime.",
];
const setupStepsList: Array<string> = [
"Sign in to the [Meta Business Manager](https://business.facebook.com/) with admin access to your WhatsApp Business Account.",
"From **Business Settings → Accounts → WhatsApp Accounts**, create or select the account that owns your sender phone number.",
"In Buisness Portfolio, create a system user and assign it to the WhatsApp Business Account with the role of **Admin**.",
"Generate a token for this system user and this will be your long-lived access token. Make sure to select the **whatsapp_business_management** and **whatsapp_business_messaging** permissions when generating the token.",
"Paste the access token, phone number ID, and webhook verify token into the **Meta WhatsApp Settings** card above, then save.",
"For the **Business Account ID**, go to **Business Settings → Business Info** (or **Business Settings → WhatsApp Accounts → Settings**) and copy the **WhatsApp Business Account ID** value.",
"To locate the **App ID** and **App Secret**, open [Meta for Developers](https://developers.facebook.com/apps/), select your WhatsApp app, then navigate to **Settings → Basic**. The App ID is shown at the top; click **Show** next to **App Secret** to reveal and copy it.",
"Create each template listed below in the Meta WhatsApp Manager. Make sure the template name, language, and variables match exactly. You can however change the content to your preference. Please make sure it's approved by Meta.",
"Send a test notification from OneUptime to confirm that WhatsApp delivery succeeds.",
];
const prerequisitesMarkdown: string = prerequisitesList
.map((item: string) => {
return `- ${item}`;
})
.join("\n");
const setupStepsMarkdown: string = setupStepsList
.map((item: string, index: number) => {
return `${index + 1}. ${item}`;
})
.join("\n");
const tableRows: string = templateKeys
.map((enumKey: keyof typeof WhatsAppTemplateIds) => {
const templateId: WhatsAppTemplateId = WhatsAppTemplateIds[enumKey];
const friendlyName: string = toFriendlyName(enumKey.toString());
const templateMessage: string = WhatsAppTemplateMessages[templateId];
const language: string = WhatsAppTemplateLanguage[templateId] || "en";
const variables: Array<string> =
extractTemplateVariables(templateMessage);
const variableList: string =
variables.length > 0
? variables
.map((variable: string) => {
return `\`${variable}\``;
})
.join(", ")
: "_None_";
return `| ${friendlyName} | \`${templateId}\` | ${language} | ${variableList} |`;
})
.join("\n");
const templateBodies: string = templateKeys
.map((enumKey: keyof typeof WhatsAppTemplateIds) => {
const templateId: WhatsAppTemplateId = WhatsAppTemplateIds[enumKey];
const friendlyName: string = toFriendlyName(enumKey.toString());
const templateMessage: string = WhatsAppTemplateMessages[templateId];
const language: string = WhatsAppTemplateLanguage[templateId] || "en";
const variables: Array<string> =
extractTemplateVariables(templateMessage);
const variableMarkdown: string =
variables.length > 0
? variables
.map((variable: string) => {
return `- \`${variable}\``;
})
.join("\n")
: "_None_";
const variablesHeading: string = variables.length
? `**Variables (${variables.length})**`
: "**Variables**";
return [
`#### ${friendlyName}`,
"",
`**Template Name:** \`${templateId}\``,
`**Language:** ${language}`,
"",
variablesHeading,
variableMarkdown,
"",
"**Body**",
"```plaintext",
templateMessage,
"```",
"",
"---",
].join("\n");
})
.join("\n\n");
const templateSummaryTable: string = [
"| Friendly Name | Template Name | Language | Variables |",
"| --- | --- | --- | --- |",
tableRows,
]
.filter(Boolean)
.join("\n");
const webhookSection: string = [
"### Configure Meta Webhook Subscription",
"1. In the OneUptime Admin Dashboard, open **Settings → WhatsApp → Meta WhatsApp Settings** and enter a strong value in **Webhook Verify Token**. Save the form so the encrypted token is stored in Global Config.",
"2. Keep that verify token handy—Meta does not generate one for you. You'll paste the exact same value when configuring the callback.",
"3. In [Meta for Developers](https://developers.facebook.com/apps/), select your WhatsApp app and navigate to **WhatsApp → Configuration → Webhooks**.",
`4. Click **Configure**, then supply one of the following callback URLs when Meta asks for your endpoint:\n - \`${primaryWebhookUrl}\`\n `,
"5. Paste the verify token from step 1 into Meta's **Verify Token** field and submit. Meta will call the callback URL and expect that value to match before it approves the subscription.",
"6. After verification succeeds, subscribe to the **messages** field (and any other WhatsApp webhook categories you need) so delivery status updates are forwarded to OneUptime.",
]
.filter(Boolean)
.join("\n\n");
return [
description,
"### Prerequisites",
prerequisitesMarkdown,
"### Setup Steps",
setupStepsMarkdown,
webhookSection,
"### Required WhatsApp Templates",
templateSummaryTable,
"### Template Bodies",
"> Copy the exact template body below—including punctuation and spacing—when creating each template inside Meta. The variables list shows every placeholder that must be configured in WhatsApp Manager.",
templateBodies,
]
.filter(Boolean)
.join("\n\n");
};
const whatsappSetupMarkdown: string = buildWhatsAppSetupMarkdown();
const SettingsWhatsApp: FunctionComponent = (): ReactElement => {
const [isSendingTest, setIsSendingTest] = useState<boolean>(false);
const [testError, setTestError] = useState<string>("");
const [testSuccess, setTestSuccess] = useState<string>("");
return (
<Page
title={"Admin Settings"}
breadcrumbLinks={[
{
title: "Admin Dashboard",
to: RouteUtil.populateRouteParams(RouteMap[PageMap.HOME] as Route),
},
{
title: "Settings",
to: RouteUtil.populateRouteParams(
RouteMap[PageMap.SETTINGS] as Route,
),
},
{
title: "WhatsApp",
to: RouteUtil.populateRouteParams(
RouteMap[PageMap.SETTINGS_WHATSAPP] as Route,
),
},
]}
sideMenu={<DashboardSideMenu />}
>
<CardModelDetail
name="Meta WhatsApp Settings"
cardProps={{
title: "Meta WhatsApp Settings",
description:
"Configure Meta WhatsApp credentials. These values are used to send WhatsApp notifications from OneUptime.",
}}
isEditable={true}
editButtonText="Edit Meta WhatsApp Config"
formSteps={[
{
title: "Credentials",
id: "meta-credentials",
},
{
title: "Meta App",
id: "meta-app",
},
]}
formFields={[
{
field: {
metaWhatsAppAccessToken: true,
},
title: "Access Token",
stepId: "meta-credentials",
fieldType: FormFieldSchemaType.EncryptedText,
required: true,
description:
"Long-lived access token generated in the Meta WhatsApp Business Platform.",
placeholder: "EAAG...",
},
{
field: {
metaWhatsAppPhoneNumberId: true,
},
title: "Phone Number ID",
stepId: "meta-credentials",
fieldType: FormFieldSchemaType.Text,
required: true,
description:
"The WhatsApp Business phone number ID associated with your sending number.",
placeholder: "123456789012345",
},
{
field: {
metaWhatsAppBusinessAccountId: true,
},
title: "Business Account ID",
stepId: "meta-credentials",
fieldType: FormFieldSchemaType.Text,
required: false,
description:
"Optional Business Account ID that owns the WhatsApp templates.",
placeholder: "123456789012345",
},
{
field: {
metaWhatsAppWebhookVerifyToken: true,
},
title: "Webhook Verify Token",
stepId: "meta-credentials",
fieldType: FormFieldSchemaType.EncryptedText,
required: false,
description:
"Secret token configured in Meta to validate webhook subscription requests.",
placeholder: "Webhook verify token",
},
{
field: {
metaWhatsAppAppId: true,
},
title: "App ID",
stepId: "meta-app",
fieldType: FormFieldSchemaType.Text,
required: false,
description:
"Optional Facebook App ID tied to your WhatsApp integration.",
placeholder: "987654321098765",
},
{
field: {
metaWhatsAppAppSecret: true,
},
title: "App Secret",
stepId: "meta-app",
fieldType: FormFieldSchemaType.EncryptedText,
required: false,
description:
"Optional Facebook App Secret used for webhook signature verification.",
placeholder: "Facebook App Secret",
},
]}
modelDetailProps={{
modelType: GlobalConfig,
id: "model-detail-global-config-meta-whatsapp",
fields: [
{
field: {
metaWhatsAppAccessToken: true,
},
title: "Access Token",
fieldType: FieldType.HiddenText,
placeholder: "Not Configured",
},
{
field: {
metaWhatsAppPhoneNumberId: true,
},
title: "Phone Number ID",
fieldType: FieldType.Text,
placeholder: "Not Configured",
},
{
field: {
metaWhatsAppBusinessAccountId: true,
},
title: "Business Account ID",
fieldType: FieldType.Text,
placeholder: "Not Configured",
},
{
field: {
metaWhatsAppWebhookVerifyToken: true,
},
title: "Webhook Verify Token",
fieldType: FieldType.HiddenText,
placeholder: "Not Configured",
},
{
field: {
metaWhatsAppAppId: true,
},
title: "App ID",
fieldType: FieldType.Text,
placeholder: "Not Configured",
},
{
field: {
metaWhatsAppAppSecret: true,
},
title: "App Secret",
fieldType: FieldType.HiddenText,
placeholder: "Not Configured",
},
],
modelId: ObjectID.getZeroObjectID(),
}}
/>
<Card
title="Send Test WhatsApp Message"
description="Send a test WhatsApp template message to confirm your Meta configuration."
>
{testSuccess ? (
<Alert
type={AlertType.SUCCESS}
title={testSuccess}
className="mb-4"
/>
) : (
<></>
)}
<BasicForm
id="send-test-whatsapp-form"
name="Send Test WhatsApp Message"
isLoading={isSendingTest}
error={testError || ""}
submitButtonText="Send Test Message"
maxPrimaryButtonWidth={true}
initialValues={{
phoneNumber: "",
}}
fields={[
{
field: {
phoneNumber: true,
},
title: "Recipient WhatsApp Number",
description:
"Enter the full international phone number (including country code) that should receive the test message.",
placeholder: "+11234567890",
required: true,
fieldType: FormFieldSchemaType.Phone,
disableSpellCheck: true,
},
]}
onSubmit={async (
values: JSONObject,
onSubmitSuccessful?: () => void,
) => {
const toPhone: string = String(values["phoneNumber"] || "").trim();
if (!toPhone) {
setTestSuccess("");
setTestError(
"Please enter a WhatsApp number before sending a test message.",
);
return;
}
setIsSendingTest(true);
setTestError("");
setTestSuccess("");
try {
const response: HTTPResponse<JSONObject> | HTTPErrorResponse =
await API.post({
url: URL.fromString(APP_API_URL.toString()).addRoute(
"/notification/whatsapp/test",
),
data: {
toPhone,
templateKey: WhatsAppTemplateIds.TestNotification,
templateLanguageCode:
WhatsAppTemplateLanguage[
WhatsAppTemplateIds.TestNotification
],
},
});
if (response instanceof HTTPErrorResponse) {
throw response;
}
if (response.isFailure()) {
throw new Error("Failed to send test WhatsApp message.");
}
setTestSuccess(
"Test WhatsApp message sent successfully. Check the recipient device to confirm delivery.",
);
if (onSubmitSuccessful) {
onSubmitSuccessful();
}
} catch (err) {
setTestError(API.getFriendlyMessage(err));
} finally {
setIsSendingTest(false);
}
}}
/>
</Card>
<Card
title="Meta WhatsApp Setup Guide"
description="Steps to connect Meta WhatsApp and the templates you must provision."
>
<MarkdownViewer text={whatsappSetupMarkdown} />
</Card>
</Page>
);
};
export default SettingsWhatsApp;

View File

@@ -0,0 +1,94 @@
import PageMap from "../../../Utils/PageMap";
import RouteMap, { RouteUtil } from "../../../Utils/RouteMap";
import Route from "Common/Types/API/Route";
import ObjectID from "Common/Types/ObjectID";
import Navigation from "Common/UI/Utils/Navigation";
import React, { FunctionComponent, ReactElement } from "react";
import SideMenuComponent from "./SideMenu";
import User from "Common/Models/DatabaseModels/User";
import ModelPage from "Common/UI/Components/Page/ModelPage";
import CardModelDetail from "Common/UI/Components/ModelDetail/CardModelDetail";
import FormFieldSchemaType from "Common/UI/Components/Forms/Types/FormFieldSchemaType";
import FieldType from "Common/UI/Components/Types/FieldType";
const UserSettings: FunctionComponent = (): ReactElement => {
const modelId: ObjectID = Navigation.getLastParamAsObjectID(1);
return (
<ModelPage<User>
modelId={modelId}
modelNameField="email"
modelType={User}
title={"User"}
breadcrumbLinks={[
{
title: "Admin Dashboard",
to: RouteUtil.populateRouteParams(RouteMap[PageMap.HOME] as Route),
},
{
title: "Users",
to: RouteUtil.populateRouteParams(RouteMap[PageMap.USERS] as Route),
},
{
title: "User",
to: RouteUtil.populateRouteParams(
RouteMap[PageMap.USER_VIEW] as Route,
{
modelId: modelId,
},
),
},
{
title: "Settings",
to: RouteUtil.populateRouteParams(
RouteMap[PageMap.USER_SETTINGS] as Route,
{
modelId: modelId,
},
),
},
]}
sideMenu={<SideMenuComponent modelId={modelId} />}
>
<CardModelDetail<User>
name="user-master-admin-settings"
cardProps={{
title: "Master Admin Access",
description:
"Grant or revoke master admin access for this user. Master admins can manage every project and workspace.",
}}
isEditable={true}
editButtonText="Update Access"
formFields={[
{
field: {
isMasterAdmin: true,
},
title: "Master Admin",
description:
"Enable to give this user full access to the entire platform.",
fieldType: FormFieldSchemaType.Toggle,
required: true,
},
]}
modelDetailProps={{
modelType: User,
id: "user-master-admin-settings-detail",
fields: [
{
field: {
isMasterAdmin: true,
},
title: "Master Admin",
fieldType: FieldType.Boolean,
placeholder: "No",
},
],
modelId: modelId,
}}
/>
</ModelPage>
);
};
export default UserSettings;

View File

@@ -30,6 +30,18 @@ const SideMenuComponent: FunctionComponent<SideMenuProps> = (
}}
icon={IconProp.Info}
/>
<SideMenuItem
link={{
title: "Settings",
to: RouteUtil.populateRouteParams(
RouteMap[PageMap.USER_SETTINGS] as Route,
{
modelId: props.modelId,
},
),
}}
icon={IconProp.Settings}
/>
</SideMenuSection>
<SideMenuSection title="Advanced">

View File

@@ -6,6 +6,7 @@ enum PageMap {
USERS = "USERS",
USER_VIEW = "USER_VIEW",
USER_SETTINGS = "USER_SETTINGS",
USER_DELETE = "USER_DELETE",
PROJECTS = "PROJECTS",
@@ -15,6 +16,7 @@ enum PageMap {
SETTINGS_HOST = "SETTINGS_HOST",
SETTINGS_SMTP = "SETTINGS_SMTP",
SETTINGS_CALL_AND_SMS = "SETTINGS_CALL_AND_SMS",
SETTINGS_WHATSAPP = "SETTINGS_WHATSAPP",
SETTINGS_PROBES = "SETTINGS_PROBES",
SETTINGS_AUTHENTICATION = "SETTINGS_AUTHENTICATION",
SETTINGS_API_KEY = "SETTINGS_API_KEY",

View File

@@ -18,6 +18,9 @@ const RouteMap: Dictionary<Route> = {
[PageMap.USERS]: new Route(`/admin/users`),
[PageMap.USER_VIEW]: new Route(`/admin/users/${RouteParams.ModelID}`),
[PageMap.USER_SETTINGS]: new Route(
`/admin/users/${RouteParams.ModelID}/settings`,
),
[PageMap.USER_DELETE]: new Route(
`/admin/users/${RouteParams.ModelID}/delete`,
),
@@ -25,6 +28,7 @@ const RouteMap: Dictionary<Route> = {
[PageMap.SETTINGS_HOST]: new Route(`/admin/settings/host`),
[PageMap.SETTINGS_SMTP]: new Route(`/admin/settings/smtp`),
[PageMap.SETTINGS_CALL_AND_SMS]: new Route(`/admin/settings/call-and-sms`),
[PageMap.SETTINGS_WHATSAPP]: new Route(`/admin/settings/whatsapp`),
[PageMap.SETTINGS_PROBES]: new Route(`/admin/settings/probes`),
[PageMap.SETTINGS_AUTHENTICATION]: new Route(
`/admin/settings/authentication`,

View File

@@ -22,7 +22,6 @@
<!-- End Google Tag Manager -->
<% } %>
<link rel="manifest" href="/admin/assets/img/favicons/ma">
<link rel="apple-touch-icon" sizes="180x180" href="/admin/assets/img/favicons/apple-touch-icon.png">
<link rel="shortcut icon" href="/admin/assets/img/favicons/favicon.ico">
<link rel="icon" type="image/png" sizes="32x32" href="/admin/assets/img/favicons/favicon-32x32.png">
@@ -75,20 +74,6 @@
<title>OneUptime Admin Dashboard</title>
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
</head>
<body class="h-full bg-gray-50">
<% if(typeof enableGoogleTagManager !== 'undefined' ? enableGoogleTagManager : false){ %>

View File

@@ -3,7 +3,7 @@
#
# Pull base image nodejs image.
FROM public.ecr.aws/docker/library/node:23.8-alpine3.21
FROM public.ecr.aws/docker/library/node:24.9-alpine3.21
RUN mkdir /tmp/npm && chmod 2777 /tmp/npm && chown 1000:1000 /tmp/npm && npm config set cache /tmp/npm --global
RUN npm config set fetch-retries 5
@@ -14,9 +14,12 @@ RUN npm config set fetch-retry-maxtimeout 600000
ARG GIT_SHA
ARG APP_VERSION
ARG IS_ENTERPRISE_EDITION=false
ENV GIT_SHA=${GIT_SHA}
ENV APP_VERSION=${APP_VERSION}
ENV IS_ENTERPRISE_EDITION=${IS_ENTERPRISE_EDITION}
ENV PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1
# IF APP_VERSION is not set, set it to 1.0.0

View File

@@ -1,5 +1,6 @@
import BaseAPI from "Common/Server/API/BaseAPI";
import BaseAnalyticsAPI from "Common/Server/API/BaseAnalyticsAPI";
import BillingAPI from "Common/Server/API/BillingAPI";
import BillingInvoiceAPI from "Common/Server/API/BillingInvoiceAPI";
import BillingPaymentMethodAPI from "Common/Server/API/BillingPaymentMethodAPI";
import CopilotCodeRepositoryAPI from "Common/Server/API/CopilotCodeRepositoryAPI";
@@ -13,9 +14,11 @@ import TelemetryAPI from "Common/Server/API/TelemetryAPI";
import ProbeAPI from "Common/Server/API/ProbeAPI";
import ProjectAPI from "Common/Server/API/ProjectAPI";
import ProjectSsoAPI from "Common/Server/API/ProjectSSO";
import WhatsAppLogAPI from "./WhatsAppLogAPI";
// Import API
import ResellerPlanAPI from "Common/Server/API/ResellerPlanAPI";
import EnterpriseLicenseAPI from "Common/Server/API/EnterpriseLicenseAPI";
import MonitorAPI from "Common/Server/API/MonitorAPI";
import ShortLinkAPI from "Common/Server/API/ShortLinkAPI";
import StatusPageAPI from "Common/Server/API/StatusPageAPI";
@@ -23,13 +26,21 @@ import WorkspaceNotificationRuleAPI from "Common/Server/API/WorkspaceNotificatio
import StatusPageDomainAPI from "Common/Server/API/StatusPageDomainAPI";
import StatusPageSubscriberAPI from "Common/Server/API/StatusPageSubscriberAPI";
import UserCallAPI from "Common/Server/API/UserCallAPI";
import UserTwoFactorAuthAPI from "Common/Server/API/UserTwoFactorAuthAPI";
import UserTotpAuthAPI from "Common/Server/API/UserTotpAuthAPI";
import UserWebAuthnAPI from "Common/Server/API/UserWebAuthnAPI";
import MonitorTest from "Common/Models/DatabaseModels/MonitorTest";
import IncidentInternalNoteAPI from "Common/Server/API/IncidentInternalNoteAPI";
import IncidentPublicNoteAPI from "Common/Server/API/IncidentPublicNoteAPI";
import ScheduledMaintenanceInternalNoteAPI from "Common/Server/API/ScheduledMaintenanceInternalNoteAPI";
import ScheduledMaintenancePublicNoteAPI from "Common/Server/API/ScheduledMaintenancePublicNoteAPI";
import IncidentAPI from "Common/Server/API/IncidentAPI";
// User Notification methods.
import UserEmailAPI from "Common/Server/API/UserEmailAPI";
import UserNotificationLogTimelineAPI from "Common/Server/API/UserOnCallLogTimelineAPI";
import UserSMSAPI from "Common/Server/API/UserSmsAPI";
import UserWhatsAppAPI from "Common/Server/API/UserWhatsAppAPI";
import UserPushAPI from "Common/Server/API/UserPushAPI";
import UserAPI from "Common/Server/API/UserAPI";
import ApiKeyPermissionService, {
Service as ApiKeyPermissionServiceType,
} from "Common/Server/Services/ApiKeyPermissionService";
@@ -55,9 +66,7 @@ import EmailVerificationTokenService, {
import AlertCustomFieldService, {
Service as AlertCustomFieldServiceType,
} from "Common/Server/Services/AlertCustomFieldService";
import AlertInternalNoteService, {
Service as AlertInternalNoteServiceType,
} from "Common/Server/Services/AlertInternalNoteService";
import AlertInternalNoteAPI from "Common/Server/API/AlertInternalNoteAPI";
import AlertNoteTemplateService, {
Service as AlertNoteTemplateServiceType,
} from "Common/Server/Services/AlertNoteTemplateService";
@@ -88,12 +97,12 @@ import AlertStateTimelineService, {
import IncidentCustomFieldService, {
Service as IncidentCustomFieldServiceType,
} from "Common/Server/Services/IncidentCustomFieldService";
import IncidentInternalNoteService, {
Service as IncidentInternalNoteServiceType,
} from "Common/Server/Services/IncidentInternalNoteService";
import IncidentNoteTemplateService, {
Service as IncidentNoteTemplateServiceType,
} from "Common/Server/Services/IncidentNoteTemplateService";
import IncidentPostmortemTemplateService, {
Service as IncidentPostmortemTemplateServiceType,
} from "Common/Server/Services/IncidentPostmortemTemplateService";
import TableViewService, {
Service as TableViewServiceType,
} from "Common/Server/Services/TableViewService";
@@ -103,12 +112,6 @@ import IncidentOwnerTeamService, {
import IncidentOwnerUserService, {
Service as IncidentOwnerUserServiceType,
} from "Common/Server/Services/IncidentOwnerUserService";
import IncidentPublicNoteService, {
Service as IncidentPublicNoteServiceType,
} from "Common/Server/Services/IncidentPublicNoteService";
import IncidentService, {
Service as IncidentServiceType,
} from "Common/Server/Services/IncidentService";
import IncidentSeverityService, {
Service as IncidentSeverityServiceType,
} from "Common/Server/Services/IncidentSeverityService";
@@ -137,9 +140,6 @@ import LogService, {
LogService as LogServiceType,
} from "Common/Server/Services/LogService";
import TelemetryAttributeService, {
TelemetryAttributeService as TelemetryAttributeServiceType,
} from "Common/Server/Services/TelemetryAttributeService";
import CopilotActionTypePriorityService, {
Service as CopilotActionTypePriorityServiceType,
} from "Common/Server/Services/CopilotActionTypePriorityService";
@@ -227,9 +227,6 @@ import ResellerService, {
import ScheduledMaintenanceCustomFieldService, {
Service as ScheduledMaintenanceCustomFieldServiceType,
} from "Common/Server/Services/ScheduledMaintenanceCustomFieldService";
import ScheduledMaintenanceInternalNoteService, {
Service as ScheduledMaintenanceInternalNoteServiceType,
} from "Common/Server/Services/ScheduledMaintenanceInternalNoteService";
import ScheduledMaintenanceNoteTemplateService, {
Service as ScheduledMaintenanceNoteTemplateServiceType,
} from "Common/Server/Services/ScheduledMaintenanceNoteTemplateService";
@@ -239,9 +236,6 @@ import ScheduledMaintenanceOwnerTeamService, {
import ScheduledMaintenanceOwnerUserService, {
Service as ScheduledMaintenanceOwnerUserServiceType,
} from "Common/Server/Services/ScheduledMaintenanceOwnerUserService";
import ScheduledMaintenancePublicNoteService, {
Service as ScheduledMaintenancePublicNoteServiceType,
} from "Common/Server/Services/ScheduledMaintenancePublicNoteService";
import ScheduledMaintenanceService, {
Service as ScheduledMaintenanceServiceType,
} from "Common/Server/Services/ScheduledMaintenanceService";
@@ -282,12 +276,13 @@ import ShortLinkService, {
import SmsLogService, {
Service as SmsLogServiceType,
} from "Common/Server/Services/SmsLogService";
import PushNotificationLogService, {
Service as PushNotificationLogServiceType,
} from "Common/Server/Services/PushNotificationLogService";
import SpanService, {
SpanService as SpanServiceType,
} from "Common/Server/Services/SpanService";
import StatusPageAnnouncementService, {
Service as StatusPageAnnouncementServiceType,
} from "Common/Server/Services/StatusPageAnnouncementService";
import StatusPageAnnouncementAPI from "Common/Server/API/StatusPageAnnouncementAPI";
import StatusPageCustomFieldService, {
Service as StatusPageCustomFieldServiceType,
} from "Common/Server/Services/StatusPageCustomFieldService";
@@ -324,6 +319,9 @@ import TeamMemberService, {
import TeamPermissionService, {
Service as TeamPermissionServiceType,
} from "Common/Server/Services/TeamPermissionService";
import TeamComplianceSettingService, {
TeamComplianceSettingService as TeamComplianceSettingServiceType,
} from "Common/Server/Services/TeamComplianceSettingService";
import TeamService, {
Service as TeamServiceType,
} from "Common/Server/Services/TeamService";
@@ -342,9 +340,6 @@ import UserNotificationSettingService, {
import UserOnCallLogService, {
Service as UserNotificationLogServiceType,
} from "Common/Server/Services/UserOnCallLogService";
import UserService, {
Service as UserServiceType,
} from "Common/Server/Services/UserService";
import WorkflowLogService, {
Service as WorkflowLogServiceType,
} from "Common/Server/Services/WorkflowLogService";
@@ -370,6 +365,7 @@ import TelemetryExceptionService, {
import ExceptionInstanceService, {
ExceptionInstanceService as ExceptionInstanceServiceType,
} from "Common/Server/Services/ExceptionInstanceService";
import AcmeChallengeAPI from "Common/Server/API/AcmeChallengeAPI";
import FeatureSet from "Common/Server/Types/FeatureSet";
import Express, { ExpressApplication } from "Common/Server/Utils/Express";
@@ -379,6 +375,8 @@ import Span from "Common/Models/AnalyticsModels/Span";
import ApiKey from "Common/Models/DatabaseModels/ApiKey";
import ApiKeyPermission from "Common/Models/DatabaseModels/ApiKeyPermission";
import CallLog from "Common/Models/DatabaseModels/CallLog";
import PushNotificationLog from "Common/Models/DatabaseModels/PushNotificationLog";
import WorkspaceNotificationLog from "Common/Models/DatabaseModels/WorkspaceNotificationLog";
import Domain from "Common/Models/DatabaseModels/Domain";
import EmailLog from "Common/Models/DatabaseModels/EmailLog";
import EmailVerificationToken from "Common/Models/DatabaseModels/EmailVerificationToken";
@@ -386,7 +384,6 @@ import Dashboard from "Common/Models/DatabaseModels/Dashboard";
import Alert from "Common/Models/DatabaseModels/Alert";
import AlertCustomField from "Common/Models/DatabaseModels/AlertCustomField";
import AlertInternalNote from "Common/Models/DatabaseModels/AlertInternalNote";
import AlertNoteTemplate from "Common/Models/DatabaseModels/AlertNoteTemplate";
import AlertOwnerTeam from "Common/Models/DatabaseModels/AlertOwnerTeam";
import AlertOwnerUser from "Common/Models/DatabaseModels/AlertOwnerUser";
@@ -394,13 +391,11 @@ import AlertSeverity from "Common/Models/DatabaseModels/AlertSeverity";
import AlertState from "Common/Models/DatabaseModels/AlertState";
import AlertStateTimeline from "Common/Models/DatabaseModels/AlertStateTimeline";
import Incident from "Common/Models/DatabaseModels/Incident";
import IncidentCustomField from "Common/Models/DatabaseModels/IncidentCustomField";
import IncidentInternalNote from "Common/Models/DatabaseModels/IncidentInternalNote";
import IncidentNoteTemplate from "Common/Models/DatabaseModels/IncidentNoteTemplate";
import IncidentPostmortemTemplate from "Common/Models/DatabaseModels/IncidentPostmortemTemplate";
import IncidentOwnerTeam from "Common/Models/DatabaseModels/IncidentOwnerTeam";
import IncidentOwnerUser from "Common/Models/DatabaseModels/IncidentOwnerUser";
import IncidentPublicNote from "Common/Models/DatabaseModels/IncidentPublicNote";
import IncidentSeverity from "Common/Models/DatabaseModels/IncidentSeverity";
import IncidentState from "Common/Models/DatabaseModels/IncidentState";
import IncidentStateTimeline from "Common/Models/DatabaseModels/IncidentStateTimeline";
@@ -435,11 +430,9 @@ import PromoCode from "Common/Models/DatabaseModels/PromoCode";
import Reseller from "Common/Models/DatabaseModels/Reseller";
import ScheduledMaintenance from "Common/Models/DatabaseModels/ScheduledMaintenance";
import ScheduledMaintenanceCustomField from "Common/Models/DatabaseModels/ScheduledMaintenanceCustomField";
import ScheduledMaintenanceInternalNote from "Common/Models/DatabaseModels/ScheduledMaintenanceInternalNote";
import ScheduledMaintenanceNoteTemplate from "Common/Models/DatabaseModels/ScheduledMaintenanceNoteTemplate";
import ScheduledMaintenanceOwnerTeam from "Common/Models/DatabaseModels/ScheduledMaintenanceOwnerTeam";
import ScheduledMaintenanceOwnerUser from "Common/Models/DatabaseModels/ScheduledMaintenanceOwnerUser";
import ScheduledMaintenancePublicNote from "Common/Models/DatabaseModels/ScheduledMaintenancePublicNote";
import ScheduledMaintenanceState from "Common/Models/DatabaseModels/ScheduledMaintenanceState";
import ScheduledMaintenanceStateTimeline from "Common/Models/DatabaseModels/ScheduledMaintenanceStateTimeline";
import ServiceCatalog from "Common/Models/DatabaseModels/ServiceCatalog";
@@ -448,7 +441,6 @@ import ServiceCatalogOwnerUser from "Common/Models/DatabaseModels/ServiceCatalog
import ServiceCopilotCodeRepository from "Common/Models/DatabaseModels/ServiceCopilotCodeRepository";
import ShortLink from "Common/Models/DatabaseModels/ShortLink";
import SmsLog from "Common/Models/DatabaseModels/SmsLog";
import StatusPageAnnouncement from "Common/Models/DatabaseModels/StatusPageAnnouncement";
// Custom Fields API
import StatusPageCustomField from "Common/Models/DatabaseModels/StatusPageCustomField";
import StatusPageFooterLink from "Common/Models/DatabaseModels/StatusPageFooterLink";
@@ -464,9 +456,9 @@ import StatusPageSSO from "Common/Models/DatabaseModels/StatusPageSso";
import Team from "Common/Models/DatabaseModels/Team";
import TeamMember from "Common/Models/DatabaseModels/TeamMember";
import TeamPermission from "Common/Models/DatabaseModels/TeamPermission";
import TeamComplianceSetting from "Common/Models/DatabaseModels/TeamComplianceSetting";
import TelemetryService from "Common/Models/DatabaseModels/TelemetryService";
import TelemetryUsageBilling from "Common/Models/DatabaseModels/TelemetryUsageBilling";
import User from "Common/Models/DatabaseModels/User";
import UserNotificationRule from "Common/Models/DatabaseModels/UserNotificationRule";
import UserNotificationSetting from "Common/Models/DatabaseModels/UserNotificationSetting";
import UserOnCallLog from "Common/Models/DatabaseModels/UserOnCallLog";
@@ -476,10 +468,12 @@ import WorkflowVariable from "Common/Models/DatabaseModels/WorkflowVariable";
import ProbeOwnerTeam from "Common/Models/DatabaseModels/ProbeOwnerTeam";
import ProbeOwnerUser from "Common/Models/DatabaseModels/ProbeOwnerUser";
import ServiceCatalogDependency from "Common/Models/DatabaseModels/ServiceCatalogDependency";
import TelemetryAttribute from "Common/Models/AnalyticsModels/TelemetryAttribute";
import ExceptionInstance from "Common/Models/AnalyticsModels/ExceptionInstance";
import TelemetyException from "Common/Models/DatabaseModels/TelemetryException";
import CopilotActionTypePriority from "Common/Models/DatabaseModels/CopilotActionTypePriority";
import WorkspaceNotificationLogService, {
Service as WorkspaceNotificationLogServiceType,
} from "Common/Server/Services/WorkspaceNotificationLogService";
// scheduled maintenance template
import ScheduledMaintenanceTemplate from "Common/Models/DatabaseModels/ScheduledMaintenanceTemplate";
@@ -513,6 +507,7 @@ import ScheduledMaintenanceFeedService, {
} from "Common/Server/Services/ScheduledMaintenanceFeedService";
import SlackAPI from "Common/Server/API/SlackAPI";
import MicrosoftTeamsAPI from "Common/Server/API/MicrosoftTeamsAPI";
import WorkspaceProjectAuthToken from "Common/Models/DatabaseModels/WorkspaceProjectAuthToken";
import WorkspaceProjectAuthTokenService, {
@@ -530,11 +525,6 @@ import WorkspaceSettingService, {
Service as WorkspaceSettingServiceType,
} from "Common/Server/Services/WorkspaceSettingService";
import ProjectUser from "Common/Models/DatabaseModels/ProjectUser";
import ProjectUserService, {
Service as ProjectUserServiceType,
} from "Common/Server/Services/ProjectUserService";
import MonitorFeed from "Common/Models/DatabaseModels/MonitorFeed";
import MonitorFeedService, {
Service as MonitorFeedServiceType,
@@ -547,10 +537,7 @@ import MetricTypeService, {
import MetricType from "Common/Models/DatabaseModels/MetricType";
import OnCallDutyPolicyAPI from "Common/Server/API/OnCallDutyPolicyAPI";
// OnCallDutyPolicyOwnerTeam
// OnCallDutyPolicyOwnerUser
// OnCallDutyPolicyFeed
import TeamComplianceAPI from "Common/Server/API/TeamComplianceAPI";
import OnCallDutyPolicyFeed from "Common/Models/DatabaseModels/OnCallDutyPolicyFeed";
import OnCallDutyPolicyFeedService, {
@@ -583,6 +570,18 @@ import StatusPageAnnouncementTemplateService, {
Service as StatusPageAnnouncementTemplateServiceType,
} from "Common/Server/Services/StatusPageAnnouncementTemplateService";
// ProjectSCIM
import ProjectSCIM from "Common/Models/DatabaseModels/ProjectSCIM";
import ProjectSCIMService, {
Service as ProjectSCIMServiceType,
} from "Common/Server/Services/ProjectSCIMService";
// StatusPageSCIM
import StatusPageSCIM from "Common/Models/DatabaseModels/StatusPageSCIM";
import StatusPageSCIMService, {
Service as StatusPageSCIMServiceType,
} from "Common/Server/Services/StatusPageSCIMService";
// Open API Spec
import OpenAPI from "Common/Server/API/OpenAPI";
@@ -594,10 +593,7 @@ const BaseAPIFeatureSet: FeatureSet = {
app.use(
`/${APP_NAME.toLocaleLowerCase()}`,
new BaseAnalyticsAPI<TelemetryAttribute, TelemetryAttributeServiceType>(
TelemetryAttribute,
TelemetryAttributeService,
).getRouter(),
new AcmeChallengeAPI().getRouter(),
);
app.use(`/${APP_NAME.toLocaleLowerCase()}`, OpenAPI.getRouter());
@@ -618,6 +614,24 @@ const BaseAPIFeatureSet: FeatureSet = {
).getRouter(),
);
// Project SCIM
app.use(
`/${APP_NAME.toLocaleLowerCase()}`,
new BaseAPI<ProjectSCIM, ProjectSCIMServiceType>(
ProjectSCIM,
ProjectSCIMService,
).getRouter(),
);
// Status Page SCIM
app.use(
`/${APP_NAME.toLocaleLowerCase()}`,
new BaseAPI<StatusPageSCIM, StatusPageSCIMServiceType>(
StatusPageSCIM,
StatusPageSCIMService,
).getRouter(),
);
// status page announcement templates
app.use(
`/${APP_NAME.toLocaleLowerCase()}`,
@@ -698,14 +712,6 @@ const BaseAPIFeatureSet: FeatureSet = {
).getRouter(),
);
app.use(
`/${APP_NAME.toLocaleLowerCase()}`,
new BaseAPI<ProjectUser, ProjectUserServiceType>(
ProjectUser,
ProjectUserService,
).getRouter(),
);
//service provider setting
app.use(
`/${APP_NAME.toLocaleLowerCase()}`,
@@ -818,10 +824,7 @@ const BaseAPIFeatureSet: FeatureSet = {
app.use(
`/${APP_NAME.toLocaleLowerCase()}`,
new BaseAPI<AlertInternalNote, AlertInternalNoteServiceType>(
AlertInternalNote,
AlertInternalNoteService,
).getRouter(),
new AlertInternalNoteAPI().getRouter(),
);
app.use(
@@ -1018,10 +1021,7 @@ const BaseAPIFeatureSet: FeatureSet = {
app.use(
`/${APP_NAME.toLocaleLowerCase()}`,
new BaseAPI<StatusPageAnnouncement, StatusPageAnnouncementServiceType>(
StatusPageAnnouncement,
StatusPageAnnouncementService,
).getRouter(),
new StatusPageAnnouncementAPI().getRouter(),
);
app.use(
@@ -1142,6 +1142,14 @@ const BaseAPIFeatureSet: FeatureSet = {
).getRouter(),
);
app.use(
`/${APP_NAME.toLocaleLowerCase()}`,
new BaseAPI<TeamComplianceSetting, TeamComplianceSettingServiceType>(
TeamComplianceSetting,
TeamComplianceSettingService,
).getRouter(),
);
app.use(
`/${APP_NAME.toLocaleLowerCase()}`,
new BaseAPI<MonitorStatus, MonitorStatusServiceType>(
@@ -1257,13 +1265,7 @@ const BaseAPIFeatureSet: FeatureSet = {
).getRouter(),
);
app.use(
`/${APP_NAME.toLocaleLowerCase()}`,
new BaseAPI<Incident, IncidentServiceType>(
Incident,
IncidentService,
).getRouter(),
);
app.use(`/${APP_NAME.toLocaleLowerCase()}`, new IncidentAPI().getRouter());
app.use(
`/${APP_NAME.toLocaleLowerCase()}`,
@@ -1361,6 +1363,17 @@ const BaseAPIFeatureSet: FeatureSet = {
).getRouter(),
);
app.use(
`/${APP_NAME.toLocaleLowerCase()}`,
new BaseAPI<
IncidentPostmortemTemplate,
IncidentPostmortemTemplateServiceType
>(
IncidentPostmortemTemplate,
IncidentPostmortemTemplateService,
).getRouter(),
);
app.use(
`/${APP_NAME.toLocaleLowerCase()}`,
new BaseAPI<
@@ -1501,6 +1514,27 @@ const BaseAPIFeatureSet: FeatureSet = {
new BaseAPI<SmsLog, SmsLogServiceType>(SmsLog, SmsLogService).getRouter(),
);
app.use(
`/${APP_NAME.toLocaleLowerCase()}`,
new WhatsAppLogAPI().getRouter(),
);
app.use(
`/${APP_NAME.toLocaleLowerCase()}`,
new BaseAPI<PushNotificationLog, PushNotificationLogServiceType>(
PushNotificationLog,
PushNotificationLogService,
).getRouter(),
);
app.use(
`/${APP_NAME.toLocaleLowerCase()}`,
new BaseAPI<
WorkspaceNotificationLog,
WorkspaceNotificationLogServiceType
>(WorkspaceNotificationLog, WorkspaceNotificationLogService).getRouter(),
);
app.use(
`/${APP_NAME.toLocaleLowerCase()}`,
new BaseAPI<EmailLog, EmailLogServiceType>(
@@ -1540,7 +1574,6 @@ const BaseAPIFeatureSet: FeatureSet = {
MonitorTimelineStatusService,
).getRouter(),
);
app.use(`/${APP_NAME.toLocaleLowerCase()}`, new ShortLinkAPI().getRouter());
app.use(`/${APP_NAME.toLocaleLowerCase()}`, new MonitorAPI().getRouter());
app.use(
@@ -1554,6 +1587,12 @@ const BaseAPIFeatureSet: FeatureSet = {
new OnCallDutyPolicyAPI().getRouter(),
);
// TeamComplianceAPI
app.use(
`/${APP_NAME.toLocaleLowerCase()}`,
new TeamComplianceAPI().getRouter(),
);
app.use(
`/${APP_NAME.toLocaleLowerCase()}`,
new WorkspaceNotificationRuleAPI().getRouter(),
@@ -1577,7 +1616,15 @@ const BaseAPIFeatureSet: FeatureSet = {
`/${APP_NAME.toLocaleLowerCase()}`,
new ResellerPlanAPI().getRouter(),
);
app.use(
`/${APP_NAME.toLocaleLowerCase()}`,
new EnterpriseLicenseAPI().getRouter(),
);
app.use(`/${APP_NAME.toLocaleLowerCase()}`, new SlackAPI().getRouter());
app.use(
`/${APP_NAME.toLocaleLowerCase()}`,
new MicrosoftTeamsAPI().getRouter(),
);
app.use(
`/${APP_NAME.toLocaleLowerCase()}`,
new GlobalConfigAPI().getRouter(),
@@ -1605,10 +1652,18 @@ const BaseAPIFeatureSet: FeatureSet = {
app.use(`/${APP_NAME.toLocaleLowerCase()}`, new UserCallAPI().getRouter());
app.use(
`/${APP_NAME.toLocaleLowerCase()}`,
new UserTwoFactorAuthAPI().getRouter(),
new UserTotpAuthAPI().getRouter(),
);
app.use(
`/${APP_NAME.toLocaleLowerCase()}`,
new UserWebAuthnAPI().getRouter(),
);
app.use(`/${APP_NAME.toLocaleLowerCase()}`, new UserEmailAPI().getRouter());
app.use(`/${APP_NAME.toLocaleLowerCase()}`, new UserSMSAPI().getRouter());
app.use(
`/${APP_NAME.toLocaleLowerCase()}`,
new UserWhatsAppAPI().getRouter(),
);
app.use(`/${APP_NAME.toLocaleLowerCase()}`, new UserPushAPI().getRouter());
app.use(`/${APP_NAME.toLocaleLowerCase()}`, new ProbeAPI().getRouter());
@@ -1629,42 +1684,26 @@ const BaseAPIFeatureSet: FeatureSet = {
new BillingInvoiceAPI().getRouter(),
);
app.use(`/${APP_NAME.toLocaleLowerCase()}`, new BillingAPI().getRouter());
app.use(
`/${APP_NAME.toLocaleLowerCase()}`,
new BaseAPI<
ScheduledMaintenancePublicNote,
ScheduledMaintenancePublicNoteServiceType
>(
ScheduledMaintenancePublicNote,
ScheduledMaintenancePublicNoteService,
).getRouter(),
new ScheduledMaintenancePublicNoteAPI().getRouter(),
);
app.use(
`/${APP_NAME.toLocaleLowerCase()}`,
new BaseAPI<
ScheduledMaintenanceInternalNote,
ScheduledMaintenanceInternalNoteServiceType
>(
ScheduledMaintenanceInternalNote,
ScheduledMaintenanceInternalNoteService,
).getRouter(),
new ScheduledMaintenanceInternalNoteAPI().getRouter(),
);
app.use(
`/${APP_NAME.toLocaleLowerCase()}`,
new BaseAPI<IncidentPublicNote, IncidentPublicNoteServiceType>(
IncidentPublicNote,
IncidentPublicNoteService,
).getRouter(),
new IncidentPublicNoteAPI().getRouter(),
);
app.use(
`/${APP_NAME.toLocaleLowerCase()}`,
new BaseAPI<IncidentInternalNote, IncidentInternalNoteServiceType>(
IncidentInternalNote,
IncidentInternalNoteService,
).getRouter(),
new IncidentInternalNoteAPI().getRouter(),
);
app.use(
@@ -1781,10 +1820,7 @@ const BaseAPIFeatureSet: FeatureSet = {
app.use(`/${APP_NAME.toLocaleLowerCase()}`, TelemetryAPI);
//attach api's
app.use(
`/${APP_NAME.toLocaleLowerCase()}`,
new BaseAPI<User, UserServiceType>(User, UserService).getRouter(),
);
app.use(`/${APP_NAME.toLocaleLowerCase()}`, new UserAPI().getRouter());
},
};

View File

@@ -0,0 +1,14 @@
import BaseAPI from "Common/Server/API/BaseAPI";
import WhatsAppLog from "Common/Models/DatabaseModels/WhatsAppLog";
import WhatsAppLogService, {
Service as WhatsAppLogServiceType,
} from "Common/Server/Services/WhatsAppLogService";
export default class WhatsAppLogAPI extends BaseAPI<
WhatsAppLog,
WhatsAppLogServiceType
> {
public constructor() {
super(WhatsAppLog, WhatsAppLogService);
}
}

View File

@@ -24,23 +24,72 @@ import AccessTokenService from "Common/Server/Services/AccessTokenService";
import EmailVerificationTokenService from "Common/Server/Services/EmailVerificationTokenService";
import MailService from "Common/Server/Services/MailService";
import UserService from "Common/Server/Services/UserService";
import UserTwoFactorAuthService from "Common/Server/Services/UserTwoFactorAuthService";
import UserTotpAuthService from "Common/Server/Services/UserTotpAuthService";
import UserSessionService, {
SessionMetadata,
} from "Common/Server/Services/UserSessionService";
import CookieUtil from "Common/Server/Utils/Cookie";
import Express, {
ExpressRequest,
ExpressResponse,
ExpressRouter,
NextFunction,
extractDeviceInfo,
getClientIp,
headerValueToString,
} from "Common/Server/Utils/Express";
import CaptchaUtil from "Common/Server/Utils/Captcha";
import logger from "Common/Server/Utils/Logger";
import Response from "Common/Server/Utils/Response";
import TwoFactorAuth from "Common/Server/Utils/TwoFactorAuth";
import TotpAuth from "Common/Server/Utils/TotpAuth";
import EmailVerificationToken from "Common/Models/DatabaseModels/EmailVerificationToken";
import User from "Common/Models/DatabaseModels/User";
import UserTwoFactorAuth from "Common/Models/DatabaseModels/UserTwoFactorAuth";
import UserSession from "Common/Models/DatabaseModels/UserSession";
import UserTotpAuth from "Common/Models/DatabaseModels/UserTotpAuth";
import UserWebAuthn from "Common/Models/DatabaseModels/UserWebAuthn";
import UserWebAuthnService from "Common/Server/Services/UserWebAuthnService";
import NotAuthenticatedException from "Common/Types/Exception/NotAuthenticatedException";
const router: ExpressRouter = Express.getRouter();
const ACCESS_TOKEN_EXPIRY_SECONDS: number = 15 * 60;
type FinalizeUserLoginInput = {
req: ExpressRequest;
res: ExpressResponse;
user: User;
isGlobalLogin: boolean;
};
const finalizeUserLogin: (
data: FinalizeUserLoginInput,
) => Promise<SessionMetadata> = async (
data: FinalizeUserLoginInput,
): Promise<SessionMetadata> => {
const { req, res, user, isGlobalLogin } = data;
const sessionMetadata: SessionMetadata =
await UserSessionService.createSession({
userId: user.id!,
isGlobalLogin,
ipAddress: getClientIp(req),
userAgent: headerValueToString(req.headers["user-agent"]),
...extractDeviceInfo(req),
});
CookieUtil.setUserCookie({
expressResponse: res,
user,
isGlobalLogin,
sessionId: sessionMetadata.session.id!,
refreshToken: sessionMetadata.refreshToken,
refreshTokenExpiresAt: sessionMetadata.refreshTokenExpiresAt,
accessTokenExpiresInSeconds: ACCESS_TOKEN_EXPIRY_SECONDS,
});
return sessionMetadata;
};
router.post(
"/signup",
async (
@@ -59,6 +108,16 @@ router.post(
);
}
const miscDataProps: JSONObject =
(req.body["miscDataProps"] as JSONObject) || {};
await CaptchaUtil.verifyCaptcha({
token:
(miscDataProps["captchaToken"] as string | undefined) ||
(req.body["captchaToken"] as string | undefined),
remoteIp: getClientIp(req) || null,
});
const data: JSONObject = req.body["data"];
/* Creating a type that is a partial of the TBaseModel type. */
@@ -183,9 +242,9 @@ router.post(
if (savedUser) {
// Refresh Permissions for this user here.
await AccessTokenService.refreshUserAllPermissions(savedUser.id!);
CookieUtil.setUserCookie({
expressResponse: res,
await finalizeUserLogin({
req,
res,
user: savedUser,
isGlobalLogin: true,
});
@@ -485,6 +544,127 @@ router.post(
},
);
router.post(
"/refresh-token",
async (
req: ExpressRequest,
res: ExpressResponse,
next: NextFunction,
): Promise<void> => {
try {
const refreshToken: string | undefined =
CookieUtil.getRefreshTokenFromExpressRequest(req);
if (!refreshToken) {
CookieUtil.removeAllCookies(req, res);
return Response.sendErrorResponse(
req,
res,
new NotAuthenticatedException(
"Refresh token missing. Please login again.",
),
);
}
const session: UserSession | null =
await UserSessionService.findActiveSessionByRefreshToken(refreshToken);
if (!session || !session.id) {
CookieUtil.removeAllCookies(req, res);
return Response.sendErrorResponse(
req,
res,
new NotAuthenticatedException("Session expired. Please login again."),
);
}
if (
session.refreshTokenExpiresAt &&
OneUptimeDate.hasExpired(session.refreshTokenExpiresAt)
) {
await UserSessionService.revokeSessionById(session.id, {
reason: "Refresh token expired",
});
CookieUtil.removeAllCookies(req, res);
return Response.sendErrorResponse(
req,
res,
new NotAuthenticatedException("Session expired. Please login again."),
);
}
if (!session.userId) {
await UserSessionService.revokeSessionById(session.id, {
reason: "Session missing user",
});
CookieUtil.removeAllCookies(req, res);
return Response.sendErrorResponse(
req,
res,
new NotAuthenticatedException("Session expired. Please login again."),
);
}
const user: User | null = await UserService.findOneById({
id: session.userId,
props: {
isRoot: true,
},
select: {
_id: true,
email: true,
name: true,
isMasterAdmin: true,
profilePictureId: true,
timezone: true,
enableTwoFactorAuth: true,
},
});
if (!user) {
await UserSessionService.revokeSessionById(session.id, {
reason: "User not found",
});
CookieUtil.removeAllCookies(req, res);
return Response.sendErrorResponse(
req,
res,
new NotAuthenticatedException("Account no longer exists."),
);
}
const additionalInfo: JSONObject = (session.additionalInfo ||
{}) as JSONObject;
const isGlobalLogin: boolean =
typeof additionalInfo["isGlobalLogin"] === "boolean"
? (additionalInfo["isGlobalLogin"] as boolean)
: true;
const renewedSession: SessionMetadata =
await UserSessionService.renewSessionWithNewRefreshToken({
session,
ipAddress: getClientIp(req),
userAgent: headerValueToString(req.headers["user-agent"]),
...extractDeviceInfo(req),
});
CookieUtil.setUserCookie({
expressResponse: res,
user,
isGlobalLogin,
sessionId: renewedSession.session.id!,
refreshToken: renewedSession.refreshToken,
refreshTokenExpiresAt: renewedSession.refreshTokenExpiresAt,
accessTokenExpiresInSeconds: ACCESS_TOKEN_EXPIRY_SECONDS,
});
return Response.sendEmptySuccessResponse(req, res);
} catch (err) {
return next(err);
}
},
);
router.post(
"/logout",
async (
@@ -493,6 +673,15 @@ router.post(
next: NextFunction,
): Promise<void> => {
try {
const refreshToken: string | undefined =
CookieUtil.getRefreshTokenFromExpressRequest(req);
if (refreshToken) {
await UserSessionService.revokeSessionByRefreshToken(refreshToken, {
reason: "User logout",
});
}
CookieUtil.removeAllCookies(req, res);
return Response.sendEmptySuccessResponse(req, res);
@@ -503,7 +692,7 @@ router.post(
);
router.post(
"/verify-two-factor-auth",
"/verify-totp-auth",
async (
req: ExpressRequest,
res: ExpressResponse,
@@ -513,7 +702,25 @@ router.post(
req: req,
res: res,
next: next,
verifyTwoFactorAuth: true,
verifyTotpAuth: true,
verifyWebAuthn: false,
});
},
);
router.post(
"/verify-webauthn-auth",
async (
req: ExpressRequest,
res: ExpressResponse,
next: NextFunction,
): Promise<void> => {
return login({
req: req,
res: res,
next: next,
verifyTotpAuth: false,
verifyWebAuthn: true,
});
},
);
@@ -529,62 +736,111 @@ router.post(
req: req,
res: res,
next: next,
verifyTwoFactorAuth: false,
verifyTotpAuth: false,
verifyWebAuthn: false,
});
},
);
type FetchTwoFactorAuthListFunction = (
userId: ObjectID,
) => Promise<Array<UserTwoFactorAuth>>;
type FetchTotpAuthListFunction = (userId: ObjectID) => Promise<{
totpAuthList: Array<UserTotpAuth>;
webAuthnList: Array<UserWebAuthn>;
}>;
const fetchTwoFactorAuthList: FetchTwoFactorAuthListFunction = async (
const fetchTotpAuthList: FetchTotpAuthListFunction = async (
userId: ObjectID,
): Promise<Array<UserTwoFactorAuth>> => {
const twoFactorAuthList: Array<UserTwoFactorAuth> =
await UserTwoFactorAuthService.findBy({
query: {
userId: userId,
isVerified: true,
},
select: {
_id: true,
userId: true,
name: true,
},
limit: LIMIT_PER_PROJECT,
skip: 0,
props: {
isRoot: true,
},
});
): Promise<{
totpAuthList: Array<UserTotpAuth>;
webAuthnList: Array<UserWebAuthn>;
}> => {
const totpAuthList: Array<UserTotpAuth> = await UserTotpAuthService.findBy({
query: {
userId: userId,
isVerified: true,
},
select: {
_id: true,
userId: true,
name: true,
},
limit: LIMIT_PER_PROJECT,
skip: 0,
props: {
isRoot: true,
},
});
return twoFactorAuthList;
const webAuthnList: Array<UserWebAuthn> = await UserWebAuthnService.findBy({
query: {
userId: userId,
isVerified: true,
},
select: {
_id: true,
userId: true,
name: true,
},
limit: LIMIT_PER_PROJECT,
skip: 0,
props: {
isRoot: true,
},
});
return {
totpAuthList: totpAuthList || [],
webAuthnList: webAuthnList || [],
};
};
type LoginFunction = (options: {
req: ExpressRequest;
res: ExpressResponse;
next: NextFunction;
verifyTwoFactorAuth: boolean;
verifyTotpAuth: boolean;
verifyWebAuthn: boolean;
}) => Promise<void>;
const login: LoginFunction = async (options: {
req: ExpressRequest;
res: ExpressResponse;
next: NextFunction;
verifyTwoFactorAuth: boolean;
verifyTotpAuth: boolean;
verifyWebAuthn: boolean;
}): Promise<void> => {
const req: ExpressRequest = options.req;
const res: ExpressResponse = options.res;
const next: NextFunction = options.next;
const verifyTwoFactorAuth: boolean = options.verifyTwoFactorAuth;
const verifyTotpAuth: boolean = options.verifyTotpAuth;
const verifyWebAuthn: boolean = options.verifyWebAuthn;
try {
const miscDataProps: JSONObject =
(req.body["miscDataProps"] as JSONObject) || {};
if (!verifyTotpAuth && !verifyWebAuthn) {
await CaptchaUtil.verifyCaptcha({
token:
(miscDataProps["captchaToken"] as string | undefined) ||
(req.body["captchaToken"] as string | undefined),
remoteIp: getClientIp(req) || null,
});
}
const data: JSONObject = req.body["data"];
logger.debug("Login request data: " + JSON.stringify(req.body, null, 2));
const user: User = BaseModel.fromJSON(data as JSONObject, User) as User;
if (!user.email || !user.password) {
return Response.sendErrorResponse(
req,
res,
new BadDataException("Email and password are required."),
);
}
await user.password?.hashValue(EncryptionSecret);
const alreadySavedUser: User | null = await UserService.findOneBy({
@@ -638,13 +894,21 @@ const login: LoginFunction = async (options: {
);
}
if (alreadySavedUser.enableTwoFactorAuth && !verifyTwoFactorAuth) {
if (
alreadySavedUser.enableTwoFactorAuth &&
!verifyTotpAuth &&
!verifyWebAuthn
) {
// If two factor auth is enabled then we will send the user to the two factor auth page.
const twoFactorAuthList: Array<UserTwoFactorAuth> =
await fetchTwoFactorAuthList(alreadySavedUser.id!);
const { totpAuthList, webAuthnList } = await fetchTotpAuthList(
alreadySavedUser.id!,
);
if (!twoFactorAuthList || twoFactorAuthList.length === 0) {
if (
(!totpAuthList || totpAuthList.length === 0) &&
(!webAuthnList || webAuthnList.length === 0)
) {
const errorMessage: string = IsBillingEnabled
? "Two Factor Authentication is enabled but no two factor auth is setup. Please contact OneUptime support for help."
: "Two Factor Authentication is enabled but no two factor auth is setup. Please contact your server admin to disable two factor auth for this account.";
@@ -656,69 +920,76 @@ const login: LoginFunction = async (options: {
);
}
return Response.sendEntityResponse(req, res, user, User, {
return Response.sendEntityResponse(req, res, alreadySavedUser, User, {
miscData: {
twoFactorAuthList: UserTwoFactorAuth.toJSONArray(
twoFactorAuthList,
UserTwoFactorAuth,
),
twoFactorAuth: true,
totpAuthList: UserTotpAuth.toJSONArray(totpAuthList, UserTotpAuth),
webAuthnList: UserWebAuthn.toJSONArray(webAuthnList, UserWebAuthn),
},
});
}
if (verifyTwoFactorAuth) {
// code from req
const code: string = data["code"] as string;
const twoFactorAuthId: string = data["twoFactorAuthId"] as string;
if (verifyTotpAuth || verifyWebAuthn) {
if (verifyTotpAuth) {
// code from req
const code: string = data["code"] as string;
const twoFactorAuthId: string = data["twoFactorAuthId"] as string;
const twoFactorAuth: UserTwoFactorAuth | null =
await UserTwoFactorAuthService.findOneBy({
query: {
_id: twoFactorAuthId,
userId: alreadySavedUser.id!,
isVerified: true,
},
select: {
_id: true,
twoFactorSecret: true,
},
props: {
isRoot: true,
},
const totpAuth: UserTotpAuth | null =
await UserTotpAuthService.findOneBy({
query: {
_id: twoFactorAuthId,
userId: alreadySavedUser.id!,
isVerified: true,
},
select: {
_id: true,
twoFactorSecret: true,
},
props: {
isRoot: true,
},
});
if (!totpAuth) {
return Response.sendErrorResponse(
req,
res,
new BadDataException("Invalid two factor auth id."),
);
}
const isVerified: boolean = TotpAuth.verifyToken({
token: code,
secret: totpAuth.twoFactorSecret!,
email: alreadySavedUser.email!,
});
if (!twoFactorAuth) {
return Response.sendErrorResponse(
req,
res,
new BadDataException("Invalid two factor auth id."),
);
if (!isVerified) {
return Response.sendErrorResponse(
req,
res,
new BadDataException("Invalid code."),
);
}
} else if (verifyWebAuthn) {
const expectedChallenge: string = data["challenge"] as string;
const credential: any = data["credential"];
await UserWebAuthnService.verifyAuthentication({
userId: alreadySavedUser.id!.toString(),
challenge: expectedChallenge,
credential: credential,
});
}
const isVerified: boolean = TwoFactorAuth.verifyToken({
token: code,
secret: twoFactorAuth.twoFactorSecret!,
email: alreadySavedUser.email!,
});
if (!isVerified) {
return Response.sendErrorResponse(
req,
res,
new BadDataException("Invalid code."),
);
}
}
// Refresh Permissions for this user here.
} // Refresh Permissions for this user here.
await AccessTokenService.refreshUserAllPermissions(alreadySavedUser.id!);
if (alreadySavedUser.password.toString() === user.password!.toString()) {
logger.info("User logged in: " + alreadySavedUser.email?.toString());
CookieUtil.setUserCookie({
expressResponse: res,
await finalizeUserLogin({
req,
res,
user: alreadySavedUser,
isGlobalLogin: true,
});

File diff suppressed because it is too large Load Diff

View File

@@ -20,6 +20,9 @@ import AccessTokenService from "Common/Server/Services/AccessTokenService";
import ProjectSSOService from "Common/Server/Services/ProjectSsoService";
import TeamMemberService from "Common/Server/Services/TeamMemberService";
import UserService from "Common/Server/Services/UserService";
import UserSessionService, {
SessionMetadata,
} from "Common/Server/Services/UserSessionService";
import QueryHelper from "Common/Server/Types/Database/QueryHelper";
import Select from "Common/Server/Types/Database/Select";
import CookieUtil from "Common/Server/Utils/Cookie";
@@ -28,6 +31,9 @@ import Express, {
ExpressResponse,
ExpressRouter,
NextFunction,
extractDeviceInfo,
getClientIp,
headerValueToString,
} from "Common/Server/Utils/Express";
import logger from "Common/Server/Utils/Logger";
import Response from "Common/Server/Utils/Response";
@@ -40,12 +46,20 @@ import Name from "Common/Types/Name";
const router: ExpressRouter = Express.getRouter();
// This route is used to get the SSO config for the user.
// when the user logs in from OneUptime and not from the IDP.
const ACCESS_TOKEN_EXPIRY_SECONDS: number = 15 * 60;
/*
* This route is used to get the SSO config for the user.
* when the user logs in from OneUptime and not from the IDP.
*/
router.get(
"/service-provider-login",
async (req: ExpressRequest, res: ExpressResponse): Promise<void> => {
async (
req: ExpressRequest,
res: ExpressResponse,
next: NextFunction,
): Promise<void> => {
try {
if (!req.query["email"]) {
return Response.sendErrorResponse(
@@ -150,7 +164,11 @@ router.get(
} catch (err) {
logger.error(err);
Response.sendErrorResponse(req, res, err as Exception);
if (err instanceof Exception) {
return next(err);
}
return next(new ServerException());
}
},
);
@@ -160,7 +178,7 @@ router.get(
async (
req: ExpressRequest,
res: ExpressResponse,
_next: NextFunction,
next: NextFunction,
): Promise<void> => {
try {
if (!req.params["projectId"]) {
@@ -236,22 +254,42 @@ router.get(
} catch (err) {
logger.error(err);
Response.sendErrorResponse(req, res, err as Exception);
if (err instanceof Exception) {
return next(err);
}
return next(new ServerException());
}
},
);
router.get(
"/idp-login/:projectId/:projectSsoId",
async (req: ExpressRequest, res: ExpressResponse): Promise<void> => {
return await loginUserWithSso(req, res);
async (
req: ExpressRequest,
res: ExpressResponse,
next: NextFunction,
): Promise<void> => {
try {
await loginUserWithSso(req, res);
} catch (err) {
return next(err);
}
},
);
router.post(
"/idp-login/:projectId/:projectSsoId",
async (req: ExpressRequest, res: ExpressResponse): Promise<void> => {
return await loginUserWithSso(req, res);
async (
req: ExpressRequest,
res: ExpressResponse,
next: NextFunction,
): Promise<void> => {
try {
await loginUserWithSso(req, res);
} catch (err) {
return next(err);
}
},
);
@@ -434,8 +472,10 @@ const loginUserWithSso: LoginUserWithSsoFunction = async (
isNewUser = true;
}
// If he does not then add him to teams that he should belong and log in.
// This should never happen because email is verified before he logs in with SSO.
/*
* If he does not then add him to teams that he should belong and log in.
* This should never happen because email is verified before he logs in with SSO.
*/
if (!alreadySavedUser.isEmailVerified && !isNewUser) {
await AuthenticationEmail.sendVerificationEmail(alreadySavedUser!);
@@ -507,15 +547,31 @@ const loginUserWithSso: LoginUserWithSsoFunction = async (
expressResponse: res,
});
// Refresh Permissions for this user here.
await AccessTokenService.refreshUserAllPermissions(alreadySavedUser.id!);
const sessionMetadata: SessionMetadata =
await UserSessionService.createSession({
userId: alreadySavedUser.id!,
isGlobalLogin: false,
ipAddress: getClientIp(req),
userAgent: headerValueToString(req.headers["user-agent"]),
...extractDeviceInfo(req),
additionalInfo: {
projectId: projectId.toString(),
},
});
CookieUtil.setUserCookie({
expressResponse: res,
user: alreadySavedUser,
isGlobalLogin: false,
sessionId: sessionMetadata.session.id!,
refreshToken: sessionMetadata.refreshToken,
refreshTokenExpiresAt: sessionMetadata.refreshTokenExpiresAt,
accessTokenExpiresInSeconds: ACCESS_TOKEN_EXPIRY_SECONDS,
});
// Refresh Permissions for this user here.
await AccessTokenService.refreshUserAllPermissions(alreadySavedUser.id!);
const host: Hostname = await DatabaseConfig.getHost();
const httpProtocol: Protocol = await DatabaseConfig.getHttpProtocol();

View File

@@ -1,35 +1,145 @@
import BaseModel from "Common/Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel";
import { FileRoute } from "Common/ServiceRoute";
import { StatusPageApiRoute } from "Common/ServiceRoute";
import Hostname from "Common/Types/API/Hostname";
import Protocol from "Common/Types/API/Protocol";
import URL from "Common/Types/API/URL";
import OneUptimeDate from "Common/Types/Date";
import EmailTemplateType from "Common/Types/Email/EmailTemplateType";
import BadDataException from "Common/Types/Exception/BadDataException";
import NotAuthenticatedException from "Common/Types/Exception/NotAuthenticatedException";
import { JSONObject } from "Common/Types/JSON";
import JSONFunctions from "Common/Types/JSONFunctions";
import ObjectID from "Common/Types/ObjectID";
import PositiveNumber from "Common/Types/PositiveNumber";
import DatabaseConfig from "Common/Server/DatabaseConfig";
import { EncryptionSecret } from "Common/Server/EnvironmentConfig";
import MailService from "Common/Server/Services/MailService";
import StatusPagePrivateUserService from "Common/Server/Services/StatusPagePrivateUserService";
import StatusPageService from "Common/Server/Services/StatusPageService";
import StatusPagePrivateUserSessionService, {
SessionMetadata as StatusPageSessionMetadata,
} from "Common/Server/Services/StatusPagePrivateUserSessionService";
import CookieUtil from "Common/Server/Utils/Cookie";
import JSONWebToken from "Common/Server/Utils/JsonWebToken";
import Express, {
ExpressRequest,
ExpressResponse,
ExpressRouter,
NextFunction,
extractDeviceInfo,
getClientIp,
headerValueToString,
} from "Common/Server/Utils/Express";
import JSONWebToken from "Common/Server/Utils/JsonWebToken";
import logger from "Common/Server/Utils/Logger";
import Response from "Common/Server/Utils/Response";
import StatusPage from "Common/Models/DatabaseModels/StatusPage";
import StatusPagePrivateUser from "Common/Models/DatabaseModels/StatusPagePrivateUser";
import StatusPagePrivateUserSession from "Common/Models/DatabaseModels/StatusPagePrivateUserSession";
import { MASTER_PASSWORD_COOKIE_IDENTIFIER } from "Common/Types/StatusPage/MasterPassword";
const router: ExpressRouter = Express.getRouter();
const ACCESS_TOKEN_EXPIRY_SECONDS: number = 15 * 60;
type MasterPasswordAuthInput = {
req: ExpressRequest;
res?: ExpressResponse;
statusPageId: ObjectID;
};
const hasValidMasterPasswordSession: (
data: MasterPasswordAuthInput,
) => boolean = (data: MasterPasswordAuthInput): boolean => {
const token: string | undefined = CookieUtil.getCookieFromExpressRequest(
data.req,
CookieUtil.getStatusPageMasterPasswordKey(data.statusPageId),
);
if (!token) {
return false;
}
try {
const payload: JSONObject = JSONWebToken.decodeJsonPayload(token);
return (
payload["statusPageId"] === data.statusPageId.toString() &&
payload["type"] === MASTER_PASSWORD_COOKIE_IDENTIFIER
);
} catch (err) {
logger.error(err);
}
return false;
};
const respondWithMasterPasswordAccess: (
data: MasterPasswordAuthInput & { res: ExpressResponse },
) => boolean = (
data: MasterPasswordAuthInput & { res: ExpressResponse },
): boolean => {
if (!hasValidMasterPasswordSession(data)) {
return false;
}
Response.sendEmptySuccessResponse(data.req, data.res);
return true;
};
type FinalizeStatusPageLoginInput = {
req: ExpressRequest;
res: ExpressResponse;
user: StatusPagePrivateUser;
};
const finalizeStatusPageLogin: (data: FinalizeStatusPageLoginInput) => Promise<{
sessionMetadata: StatusPageSessionMetadata;
accessToken: string;
}> = async (
data: FinalizeStatusPageLoginInput,
): Promise<{
sessionMetadata: StatusPageSessionMetadata;
accessToken: string;
}> => {
const { req, res, user } = data;
if (!user.projectId) {
throw new BadDataException(
"Status page user is missing associated projectId.",
);
}
if (!user.statusPageId) {
throw new BadDataException(
"Status page user is missing associated statusPageId.",
);
}
const sessionMetadata: StatusPageSessionMetadata =
await StatusPagePrivateUserSessionService.createSession({
projectId: user.projectId,
statusPageId: user.statusPageId,
statusPagePrivateUserId: user.id!,
ipAddress: getClientIp(req),
userAgent: headerValueToString(req.headers["user-agent"]),
...extractDeviceInfo(req),
});
const accessToken: string = CookieUtil.setStatusPagePrivateUserCookie({
expressResponse: res,
user,
statusPageId: user.statusPageId,
sessionId: sessionMetadata.session.id!,
refreshToken: sessionMetadata.refreshToken,
refreshTokenExpiresAt: sessionMetadata.refreshTokenExpiresAt,
accessTokenExpiresInSeconds: ACCESS_TOKEN_EXPIRY_SECONDS,
});
return {
sessionMetadata,
accessToken,
};
};
router.post(
"/logout/:statuspageid",
async (
@@ -46,7 +156,21 @@ router.post(
req.params["statuspageid"].toString(),
);
CookieUtil.removeCookie(res, CookieUtil.getUserTokenKey(statusPageId)); // remove the cookie.
const refreshToken: string | undefined =
CookieUtil.getRefreshTokenFromExpressRequest(req, statusPageId);
if (refreshToken) {
await StatusPagePrivateUserSessionService.revokeSessionByRefreshToken(
refreshToken,
{
reason: "User logged out",
},
);
}
CookieUtil.removeCookie(res, CookieUtil.getUserTokenKey(statusPageId));
CookieUtil.removeCookie(res, CookieUtil.getRefreshTokenKey(statusPageId));
CookieUtil.removeStatusPageMasterPasswordCookie(res, statusPageId);
return Response.sendEmptySuccessResponse(req, res);
} catch (err) {
@@ -55,6 +179,258 @@ router.post(
},
);
router.post(
"/refresh-token/:statuspageid",
async (
req: ExpressRequest,
res: ExpressResponse,
next: NextFunction,
): Promise<void> => {
try {
const statusPageIdParam: string | undefined = req.params["statuspageid"];
if (!statusPageIdParam) {
throw new BadDataException("Status Page ID is required.");
}
const statusPageId: ObjectID = new ObjectID(statusPageIdParam.toString());
const refreshToken: string | undefined =
CookieUtil.getRefreshTokenFromExpressRequest(req, statusPageId);
if (!refreshToken) {
CookieUtil.removeCookie(res, CookieUtil.getUserTokenKey(statusPageId));
CookieUtil.removeCookie(
res,
CookieUtil.getRefreshTokenKey(statusPageId),
);
if (
respondWithMasterPasswordAccess({
req,
res,
statusPageId,
})
) {
return;
}
return Response.sendErrorResponse(
req,
res,
new NotAuthenticatedException(
"Refresh token missing. Please login again.",
),
);
}
const session: StatusPagePrivateUserSession | null =
await StatusPagePrivateUserSessionService.findActiveSessionByRefreshToken(
refreshToken,
);
if (!session || !session.id || !session.statusPageId) {
CookieUtil.removeCookie(res, CookieUtil.getUserTokenKey(statusPageId));
CookieUtil.removeCookie(
res,
CookieUtil.getRefreshTokenKey(statusPageId),
);
if (
respondWithMasterPasswordAccess({
req,
res,
statusPageId,
})
) {
return;
}
return Response.sendErrorResponse(
req,
res,
new NotAuthenticatedException("Session expired. Please login again."),
);
}
if (session.statusPageId.toString() !== statusPageId.toString()) {
await StatusPagePrivateUserSessionService.revokeSessionById(
session.id,
{
reason: "Status page mismatch",
},
);
CookieUtil.removeCookie(res, CookieUtil.getUserTokenKey(statusPageId));
CookieUtil.removeCookie(
res,
CookieUtil.getRefreshTokenKey(statusPageId),
);
if (
respondWithMasterPasswordAccess({
req,
res,
statusPageId,
})
) {
return;
}
return Response.sendErrorResponse(
req,
res,
new NotAuthenticatedException("Session expired. Please login again."),
);
}
if (
session.refreshTokenExpiresAt &&
OneUptimeDate.hasExpired(session.refreshTokenExpiresAt)
) {
await StatusPagePrivateUserSessionService.revokeSessionById(
session.id,
{
reason: "Refresh token expired",
},
);
CookieUtil.removeCookie(res, CookieUtil.getUserTokenKey(statusPageId));
CookieUtil.removeCookie(
res,
CookieUtil.getRefreshTokenKey(statusPageId),
);
if (
respondWithMasterPasswordAccess({
req,
res,
statusPageId,
})
) {
return;
}
return Response.sendErrorResponse(
req,
res,
new NotAuthenticatedException("Session expired. Please login again."),
);
}
if (!session.statusPagePrivateUserId) {
await StatusPagePrivateUserSessionService.revokeSessionById(
session.id,
{
reason: "Session missing user",
},
);
CookieUtil.removeCookie(res, CookieUtil.getUserTokenKey(statusPageId));
CookieUtil.removeCookie(
res,
CookieUtil.getRefreshTokenKey(statusPageId),
);
if (
respondWithMasterPasswordAccess({
req,
res,
statusPageId,
})
) {
return;
}
return Response.sendErrorResponse(
req,
res,
new NotAuthenticatedException("Session expired. Please login again."),
);
}
const user: StatusPagePrivateUser | null =
await StatusPagePrivateUserService.findOneById({
id: session.statusPagePrivateUserId,
props: {
isRoot: true,
},
select: {
_id: true,
email: true,
statusPageId: true,
projectId: true,
},
});
if (!user) {
await StatusPagePrivateUserSessionService.revokeSessionById(
session.id,
{
reason: "User not found",
},
);
CookieUtil.removeCookie(res, CookieUtil.getUserTokenKey(statusPageId));
CookieUtil.removeCookie(
res,
CookieUtil.getRefreshTokenKey(statusPageId),
);
if (
respondWithMasterPasswordAccess({
req,
res,
statusPageId,
})
) {
return;
}
return Response.sendErrorResponse(
req,
res,
new NotAuthenticatedException("Account no longer exists."),
);
}
const renewedSession: StatusPageSessionMetadata =
await StatusPagePrivateUserSessionService.renewSessionWithNewRefreshToken(
{
session,
ipAddress: getClientIp(req),
userAgent: headerValueToString(req.headers["user-agent"]),
...extractDeviceInfo(req),
},
);
const accessToken: string = CookieUtil.setStatusPagePrivateUserCookie({
expressResponse: res,
user,
statusPageId: user.statusPageId!,
sessionId: renewedSession.session.id!,
refreshToken: renewedSession.refreshToken,
refreshTokenExpiresAt: renewedSession.refreshTokenExpiresAt,
accessTokenExpiresInSeconds: ACCESS_TOKEN_EXPIRY_SECONDS,
});
return Response.sendEntityResponse(
req,
res,
user,
StatusPagePrivateUser,
{
miscData: {
token: accessToken,
},
},
);
} catch (err) {
return next(err);
}
},
);
router.post(
"/forgot-password",
async (
@@ -146,6 +522,8 @@ router.post(
const host: Hostname = await DatabaseConfig.getHost();
const httpProtocol: Protocol = await DatabaseConfig.getHttpProtocol();
const statusPageIdString: string | null =
statusPage.id?.toString() || statusPage._id?.toString() || null;
MailService.sendMail(
{
@@ -154,12 +532,13 @@ router.post(
templateType: EmailTemplateType.StatusPageForgotPassword,
vars: {
statusPageName: statusPageName!,
logoUrl: statusPage.logoFileId
? new URL(httpProtocol, host)
.addRoute(FileRoute)
.addRoute("/image/" + statusPage.logoFileId)
.toString()
: "",
logoUrl:
statusPage.logoFileId && statusPageIdString
? new URL(httpProtocol, host)
.addRoute(StatusPageApiRoute)
.addRoute(`/logo/${statusPageIdString}`)
.toString()
: "",
homeURL: statusPageURL,
tokenVerifyUrl: URL.fromString(statusPageURL)
.addRoute("/reset-password/" + token)
@@ -168,6 +547,7 @@ router.post(
},
{
projectId: statusPage.projectId!,
statusPageId: statusPage.id!,
},
).catch((err: Error) => {
logger.error(err);
@@ -287,6 +667,8 @@ router.post(
const host: Hostname = await DatabaseConfig.getHost();
const httpProtocol: Protocol = await DatabaseConfig.getHttpProtocol();
const statusPageIdString: string | null =
statusPage.id?.toString() || statusPage._id?.toString() || null;
MailService.sendMail(
{
@@ -296,16 +678,18 @@ router.post(
vars: {
homeURL: statusPageURL,
statusPageName: statusPageName || "",
logoUrl: statusPage.logoFileId
? new URL(httpProtocol, host)
.addRoute(FileRoute)
.addRoute("/image/" + statusPage.logoFileId)
.toString()
: "",
logoUrl:
statusPage.logoFileId && statusPageIdString
? new URL(httpProtocol, host)
.addRoute(StatusPageApiRoute)
.addRoute(`/logo/${statusPageIdString}`)
.toString()
: "",
},
},
{
projectId: statusPage.projectId!,
statusPageId: statusPage.id!,
},
).catch((err: Error) => {
logger.error(err);
@@ -374,6 +758,7 @@ router.post(
password: true,
email: true,
statusPageId: true,
projectId: true,
},
props: {
isRoot: true,
@@ -381,31 +766,38 @@ router.post(
});
if (alreadySavedUser) {
const token: string = JSONWebToken.sign({
data: alreadySavedUser,
expiresInSeconds: OneUptimeDate.getSecondsInDays(
new PositiveNumber(30),
),
const { accessToken } = await finalizeStatusPageLogin({
req,
res,
user: alreadySavedUser,
});
CookieUtil.setCookie(
res,
CookieUtil.getUserTokenKey(alreadySavedUser.statusPageId!),
token,
{
httpOnly: true,
maxAge: OneUptimeDate.getMillisecondsInDays(new PositiveNumber(30)),
},
);
const sanitizedUser: StatusPagePrivateUser | null =
await StatusPagePrivateUserService.findOneById({
id: alreadySavedUser.id!,
props: {
isRoot: true,
},
select: {
_id: true,
email: true,
statusPageId: true,
projectId: true,
},
});
if (!sanitizedUser && (alreadySavedUser as any).password) {
delete (alreadySavedUser as any).password;
}
return Response.sendEntityResponse(
req,
res,
alreadySavedUser,
sanitizedUser || alreadySavedUser,
StatusPagePrivateUser,
{
miscData: {
token: token,
token: accessToken,
},
},
);

View File

@@ -0,0 +1,606 @@
import SCIMMiddleware from "Common/Server/Middleware/SCIMAuthorization";
import StatusPagePrivateUserService from "Common/Server/Services/StatusPagePrivateUserService";
import Express, {
ExpressRequest,
ExpressResponse,
ExpressRouter,
NextFunction,
OneUptimeRequest,
} from "Common/Server/Utils/Express";
import Response from "Common/Server/Utils/Response";
import logger from "Common/Server/Utils/Logger";
import ObjectID from "Common/Types/ObjectID";
import Email from "Common/Types/Email";
import { JSONObject } from "Common/Types/JSON";
import StatusPagePrivateUser from "Common/Models/DatabaseModels/StatusPagePrivateUser";
import StatusPageSCIM from "Common/Models/DatabaseModels/StatusPageSCIM";
import BadRequestException from "Common/Types/Exception/BadRequestException";
import NotFoundException from "Common/Types/Exception/NotFoundException";
import LIMIT_MAX, { LIMIT_PER_PROJECT } from "Common/Types/Database/LimitMax";
import {
formatUserForSCIM,
generateServiceProviderConfig,
} from "../Utils/SCIMUtils";
import Text from "Common/Types/Text";
import HashedString from "Common/Types/HashedString";
const router: ExpressRouter = Express.getRouter();
// SCIM Service Provider Configuration - GET /status-page-scim/v2/ServiceProviderConfig
router.get(
"/status-page-scim/v2/:statusPageScimId/ServiceProviderConfig",
SCIMMiddleware.isAuthorizedSCIMRequest,
async (
req: ExpressRequest,
res: ExpressResponse,
next: NextFunction,
): Promise<void> => {
try {
logger.debug(
`Status Page SCIM ServiceProviderConfig - scimId: ${req.params["statusPageScimId"]!}`,
);
const serviceProviderConfig: JSONObject = generateServiceProviderConfig(
req,
req.params["statusPageScimId"]!,
"status-page",
);
return Response.sendJsonObjectResponse(req, res, serviceProviderConfig);
} catch (err) {
logger.error(err);
return next(err);
}
},
);
// Status Page Users endpoint - GET /status-page-scim/v2/Users
router.get(
"/status-page-scim/v2/:statusPageScimId/Users",
SCIMMiddleware.isAuthorizedSCIMRequest,
async (
req: ExpressRequest,
res: ExpressResponse,
next: NextFunction,
): Promise<void> => {
try {
logger.debug(
`Status Page SCIM Users list request for statusPageScimId: ${req.params["statusPageScimId"]}`,
);
const oneuptimeRequest: OneUptimeRequest = req as OneUptimeRequest;
const bearerData: JSONObject =
oneuptimeRequest.bearerTokenData as JSONObject;
const statusPageId: ObjectID = bearerData["statusPageId"] as ObjectID;
// Parse query parameters
const startIndex: number =
parseInt(req.query["startIndex"] as string) || 1;
const count: number = Math.min(
parseInt(req.query["count"] as string) || 100,
LIMIT_PER_PROJECT,
);
const filter: string = req.query["filter"] as string;
logger.debug(
`Status Page SCIM Users - statusPageId: ${statusPageId}, startIndex: ${startIndex}, count: ${count}, filter: ${filter || "none"}`,
);
// Build query for status page users
const query: any = {
statusPageId: statusPageId,
};
// Handle SCIM filter for userName
if (filter) {
const emailMatch: RegExpMatchArray | null = filter.match(
/userName eq "([^"]+)"/i,
);
if (emailMatch) {
const email: string = emailMatch[1]!;
logger.debug(
`Status Page SCIM Users list - statusPageScimId: ${req.params["statusPageScimId"]!}, filter by email: ${email}`,
);
if (email) {
if (Email.isValid(email)) {
query.email = new Email(email);
logger.debug(
`Status Page SCIM Users list - statusPageScimId: ${req.params["statusPageScimId"]!}, filtering by email: ${email}`,
);
} else {
logger.debug(
`Status Page SCIM Users list - statusPageScimId: ${req.params["statusPageScimId"]!}, invalid email format in filter: ${email}`,
);
return Response.sendJsonObjectResponse(req, res, {
schemas: ["urn:ietf:params:scim:api:messages:2.0:ListResponse"],
totalResults: 0,
startIndex: startIndex,
itemsPerPage: 0,
Resources: [],
});
}
}
}
}
// Get all private users for this status page
const statusPageUsers: Array<StatusPagePrivateUser> =
await StatusPagePrivateUserService.findBy({
query: query,
select: {
_id: true,
email: true,
createdAt: true,
updatedAt: true,
},
skip: 0,
limit: LIMIT_MAX,
props: { isRoot: true },
});
logger.debug(
`Status Page SCIM Users - found ${statusPageUsers.length} users`,
);
// Format users for SCIM
const users: Array<JSONObject> = statusPageUsers.map(
(user: StatusPagePrivateUser) => {
return formatUserForSCIM(
user,
req,
req.params["statusPageScimId"]!,
"status-page",
);
},
);
// Paginate the results
const paginatedUsers: Array<JSONObject> = users.slice(
(startIndex - 1) * count,
startIndex * count,
);
logger.debug(
`Status Page SCIM Users response prepared with ${users.length} users`,
);
return Response.sendJsonObjectResponse(req, res, {
schemas: ["urn:ietf:params:scim:api:messages:2.0:ListResponse"],
totalResults: users.length,
startIndex: startIndex,
itemsPerPage: paginatedUsers.length,
Resources: paginatedUsers,
});
} catch (err) {
logger.error(err);
return next(err);
}
},
);
// Get Individual Status Page User - GET /status-page-scim/v2/Users/{id}
router.get(
"/status-page-scim/v2/:statusPageScimId/Users/:userId",
SCIMMiddleware.isAuthorizedSCIMRequest,
async (
req: ExpressRequest,
res: ExpressResponse,
next: NextFunction,
): Promise<void> => {
try {
logger.debug(
`Status Page SCIM Get individual user request for userId: ${req.params["userId"]}, statusPageScimId: ${req.params["statusPageScimId"]}`,
);
const oneuptimeRequest: OneUptimeRequest = req as OneUptimeRequest;
const bearerData: JSONObject =
oneuptimeRequest.bearerTokenData as JSONObject;
const statusPageId: ObjectID = bearerData["statusPageId"] as ObjectID;
const userId: string = req.params["userId"]!;
logger.debug(
`Status Page SCIM Get user - statusPageId: ${statusPageId}, userId: ${userId}`,
);
if (!userId) {
throw new BadRequestException("User ID is required");
}
// Check if user exists and belongs to this status page
const statusPageUser: StatusPagePrivateUser | null =
await StatusPagePrivateUserService.findOneBy({
query: {
statusPageId: statusPageId,
_id: new ObjectID(userId),
},
select: {
_id: true,
email: true,
createdAt: true,
updatedAt: true,
},
props: { isRoot: true },
});
if (!statusPageUser) {
logger.debug(
`Status Page SCIM Get user - user not found for userId: ${userId}`,
);
throw new NotFoundException(
"User not found or not part of this status page",
);
}
const user: JSONObject = formatUserForSCIM(
statusPageUser,
req,
req.params["statusPageScimId"]!,
"status-page",
);
logger.debug(
`Status Page SCIM Get user - returning user with id: ${statusPageUser.id}`,
);
return Response.sendJsonObjectResponse(req, res, user);
} catch (err) {
logger.error(err);
return next(err);
}
},
);
// Create Status Page User - POST /status-page-scim/v2/Users
router.post(
"/status-page-scim/v2/:statusPageScimId/Users",
SCIMMiddleware.isAuthorizedSCIMRequest,
async (
req: ExpressRequest,
res: ExpressResponse,
next: NextFunction,
): Promise<void> => {
try {
logger.debug(
`Status Page SCIM Create user request for statusPageScimId: ${req.params["statusPageScimId"]}`,
);
const oneuptimeRequest: OneUptimeRequest = req as OneUptimeRequest;
const bearerData: JSONObject =
oneuptimeRequest.bearerTokenData as JSONObject;
const statusPageId: ObjectID = bearerData["statusPageId"] as ObjectID;
const scimConfig: StatusPageSCIM = bearerData[
"scimConfig"
] as StatusPageSCIM;
if (!scimConfig.autoProvisionUsers) {
throw new BadRequestException(
"Auto-provisioning is disabled for this status page",
);
}
const scimUser: JSONObject = req.body;
logger.debug(
`Status Page SCIM Create user - statusPageId: ${statusPageId}`,
);
logger.debug(
`Request body for Status Page SCIM Create user: ${JSON.stringify(scimUser, null, 2)}`,
);
// Extract user data from SCIM payload
const email: string =
(scimUser["userName"] as string) ||
((scimUser["emails"] as JSONObject[])?.[0]?.["value"] as string);
if (!email) {
throw new BadRequestException("Email is required for user creation");
}
logger.debug(`Status Page SCIM Create user - email: ${email}`);
// Check if user already exists for this status page
let user: StatusPagePrivateUser | null =
await StatusPagePrivateUserService.findOneBy({
query: {
statusPageId: statusPageId,
email: new Email(email),
},
select: {
_id: true,
email: true,
createdAt: true,
updatedAt: true,
},
props: { isRoot: true },
});
if (!user) {
logger.debug(
`Status Page SCIM Create user - creating new user with email: ${email}`,
);
const privateUser: StatusPagePrivateUser = new StatusPagePrivateUser();
privateUser.statusPageId = statusPageId;
privateUser.email = new Email(email);
privateUser.password = new HashedString(Text.generateRandomText(32));
privateUser.projectId = bearerData["projectId"] as ObjectID;
// Create new status page private user
user = await StatusPagePrivateUserService.create({
data: privateUser as any,
props: { isRoot: true },
});
} else {
logger.debug(
`Status Page SCIM Create user - user already exists with id: ${user.id}`,
);
}
const createdUser: JSONObject = formatUserForSCIM(
user,
req,
req.params["statusPageScimId"]!,
"status-page",
);
logger.debug(
`Status Page SCIM Create user - returning created user with id: ${user.id}`,
);
res.status(201);
return Response.sendJsonObjectResponse(req, res, createdUser);
} catch (err) {
logger.error(err);
return next(err);
}
},
);
const handleStatusPageUserUpdate: (
req: ExpressRequest,
res: ExpressResponse,
next: NextFunction,
) => Promise<void> = async (
req: ExpressRequest,
res: ExpressResponse,
next: NextFunction,
): Promise<void> => {
try {
logger.debug(
`Status Page SCIM Update user request for userId: ${req.params["userId"]}, statusPageScimId: ${req.params["statusPageScimId"]}`,
);
const oneuptimeRequest: OneUptimeRequest = req as OneUptimeRequest;
const bearerData: JSONObject =
oneuptimeRequest.bearerTokenData as JSONObject;
const statusPageId: ObjectID = bearerData["statusPageId"] as ObjectID;
const userId: string = req.params["userId"]!;
const scimUser: JSONObject = req.body;
logger.debug(
`Status Page SCIM Update user - statusPageId: ${statusPageId}, userId: ${userId}`,
);
logger.debug(
`Request body for Status Page SCIM Update user: ${JSON.stringify(scimUser, null, 2)}`,
);
if (!userId) {
throw new BadRequestException("User ID is required");
}
// Check if user exists and belongs to this status page
const statusPageUser: StatusPagePrivateUser | null =
await StatusPagePrivateUserService.findOneBy({
query: {
statusPageId: statusPageId,
_id: new ObjectID(userId),
},
select: {
_id: true,
email: true,
createdAt: true,
updatedAt: true,
},
props: { isRoot: true },
});
if (!statusPageUser) {
logger.debug(
`Status Page SCIM Update user - user not found for userId: ${userId}`,
);
throw new NotFoundException(
"User not found or not part of this status page",
);
}
// Update user information
const email: string =
(scimUser["userName"] as string) ||
((scimUser["emails"] as JSONObject[])?.[0]?.["value"] as string);
const active: boolean = scimUser["active"] as boolean;
logger.debug(
`Status Page SCIM Update user - email: ${email}, active: ${active}`,
);
// Handle user deactivation by deleting from status page
if (active === false) {
logger.debug(
`Status Page SCIM Update user - user marked as inactive, removing from status page`,
);
const scimConfig: StatusPageSCIM = bearerData[
"scimConfig"
] as StatusPageSCIM;
if (scimConfig.autoDeprovisionUsers) {
await StatusPagePrivateUserService.deleteOneById({
id: new ObjectID(userId),
props: { isRoot: true },
});
logger.debug(
`Status Page SCIM Update user - user removed from status page`,
);
// Return empty response for deleted user
return Response.sendJsonObjectResponse(req, res, {});
}
}
// Prepare update data
const updateData: {
email?: Email;
} = {};
if (email && email !== statusPageUser.email?.toString()) {
updateData.email = new Email(email);
}
// Only update if there are changes
if (Object.keys(updateData).length > 0) {
logger.debug(
`Status Page SCIM Update user - updating user with data: ${JSON.stringify(updateData)}`,
);
await StatusPagePrivateUserService.updateOneById({
id: new ObjectID(userId),
data: updateData,
props: { isRoot: true },
});
logger.debug(`Status Page SCIM Update user - user updated successfully`);
// Fetch updated user
const updatedUser: StatusPagePrivateUser | null =
await StatusPagePrivateUserService.findOneById({
id: new ObjectID(userId),
select: {
_id: true,
email: true,
createdAt: true,
updatedAt: true,
},
props: { isRoot: true },
});
if (updatedUser) {
const user: JSONObject = formatUserForSCIM(
updatedUser,
req,
req.params["statusPageScimId"]!,
"status-page",
);
return Response.sendJsonObjectResponse(req, res, user);
}
}
logger.debug(
`Status Page SCIM Update user - no updates made, returning existing user`,
);
// If no updates were made, return the existing user
const user: JSONObject = formatUserForSCIM(
statusPageUser,
req,
req.params["statusPageScimId"]!,
"status-page",
);
return Response.sendJsonObjectResponse(req, res, user);
} catch (err) {
logger.error(err);
return next(err);
}
};
// Update Status Page User - PUT /status-page-scim/v2/Users/{id}
router.put(
"/status-page-scim/v2/:statusPageScimId/Users/:userId",
SCIMMiddleware.isAuthorizedSCIMRequest,
handleStatusPageUserUpdate,
);
// Update Status Page User - PATCH /status-page-scim/v2/Users/{id}
router.patch(
"/status-page-scim/v2/:statusPageScimId/Users/:userId",
SCIMMiddleware.isAuthorizedSCIMRequest,
handleStatusPageUserUpdate,
);
// Delete Status Page User - DELETE /status-page-scim/v2/Users/{id}
router.delete(
"/status-page-scim/v2/:statusPageScimId/Users/:userId",
SCIMMiddleware.isAuthorizedSCIMRequest,
async (
req: ExpressRequest,
res: ExpressResponse,
next: NextFunction,
): Promise<void> => {
try {
logger.debug(
`Status Page SCIM Delete user request for userId: ${req.params["userId"]}, statusPageScimId: ${req.params["statusPageScimId"]}`,
);
const oneuptimeRequest: OneUptimeRequest = req as OneUptimeRequest;
const bearerData: JSONObject =
oneuptimeRequest.bearerTokenData as JSONObject;
const statusPageId: ObjectID = bearerData["statusPageId"] as ObjectID;
const scimConfig: StatusPageSCIM = bearerData[
"scimConfig"
] as StatusPageSCIM;
const userId: string = req.params["userId"]!;
if (!scimConfig.autoDeprovisionUsers) {
throw new BadRequestException(
"Auto-deprovisioning is disabled for this status page",
);
}
logger.debug(
`Status Page SCIM Delete user - statusPageId: ${statusPageId}, userId: ${userId}`,
);
if (!userId) {
throw new BadRequestException("User ID is required");
}
// Check if user exists and belongs to this status page
const statusPageUser: StatusPagePrivateUser | null =
await StatusPagePrivateUserService.findOneBy({
query: {
statusPageId: statusPageId,
_id: new ObjectID(userId),
},
select: {
_id: true,
},
props: { isRoot: true },
});
if (!statusPageUser) {
logger.debug(
`Status Page SCIM Delete user - user not found for userId: ${userId}`,
);
// SCIM spec says to return 404 for non-existent resources
throw new NotFoundException("User not found");
}
// Delete the user from status page
await StatusPagePrivateUserService.deleteOneById({
id: new ObjectID(userId),
props: { isRoot: true },
});
logger.debug(
`Status Page SCIM Delete user - user deleted successfully for userId: ${userId}`,
);
// Return 204 No Content for successful deletion
res.status(204);
return Response.sendEmptySuccessResponse(req, res);
} catch (err) {
logger.error(err);
return next(err);
}
},
);
export default router;

View File

@@ -1,6 +1,5 @@
import SSOUtil from "../Utils/SSO";
import URL from "Common/Types/API/URL";
import OneUptimeDate from "Common/Types/Date";
import Email from "Common/Types/Email";
import BadRequestException from "Common/Types/Exception/BadRequestException";
import Exception from "Common/Types/Exception/Exception";
@@ -8,9 +7,11 @@ import ServerException from "Common/Types/Exception/ServerException";
import HashedString from "Common/Types/HashedString";
import { JSONObject } from "Common/Types/JSON";
import ObjectID from "Common/Types/ObjectID";
import PositiveNumber from "Common/Types/PositiveNumber";
import { Host, HttpProtocol } from "Common/Server/EnvironmentConfig";
import StatusPagePrivateUserService from "Common/Server/Services/StatusPagePrivateUserService";
import StatusPagePrivateUserSessionService, {
SessionMetadata as StatusPageSessionMetadata,
} from "Common/Server/Services/StatusPagePrivateUserSessionService";
import StatusPageService from "Common/Server/Services/StatusPageService";
import StatusPageSsoService from "Common/Server/Services/StatusPageSsoService";
import CookieUtil from "Common/Server/Utils/Cookie";
@@ -19,8 +20,10 @@ import Express, {
ExpressResponse,
ExpressRouter,
NextFunction,
extractDeviceInfo,
getClientIp,
headerValueToString,
} from "Common/Server/Utils/Express";
import JSONWebToken from "Common/Server/Utils/JsonWebToken";
import logger from "Common/Server/Utils/Logger";
import Response from "Common/Server/Utils/Response";
import StatusPagePrivateUser from "Common/Models/DatabaseModels/StatusPagePrivateUser";
@@ -30,6 +33,8 @@ import xml2js from "xml2js";
// Initialize Express router.
const router: ExpressRouter = Express.getRouter();
const ACCESS_TOKEN_EXPIRY_SECONDS: number = 15 * 60;
// Define a GET route for SSO in a status page context.
router.get(
"/status-page-sso/:statusPageId/:statusPageSsoId",
@@ -115,7 +120,11 @@ router.get(
router.post(
"/status-page-idp-login/:statusPageId/:statusPageSsoId",
async (req: ExpressRequest, res: ExpressResponse): Promise<void> => {
async (
req: ExpressRequest,
res: ExpressResponse,
next: NextFunction,
): Promise<void> => {
try {
const samlResponseBase64: string = req.body.SAMLResponse;
@@ -281,24 +290,30 @@ router.post(
});
}
const token: string = JSONWebToken.sign({
data: alreadySavedUser,
expiresInSeconds: OneUptimeDate.getSecondsInDays(
new PositiveNumber(30),
),
if (!alreadySavedUser.projectId) {
alreadySavedUser.projectId = projectId;
}
const sessionMetadata: StatusPageSessionMetadata =
await StatusPagePrivateUserSessionService.createSession({
projectId: alreadySavedUser.projectId!,
statusPageId: statusPageId,
statusPagePrivateUserId: alreadySavedUser.id!,
ipAddress: getClientIp(req),
userAgent: headerValueToString(req.headers["user-agent"]),
...extractDeviceInfo(req),
});
const token: string = CookieUtil.setStatusPagePrivateUserCookie({
expressResponse: res,
user: alreadySavedUser,
statusPageId: statusPageId,
sessionId: sessionMetadata.session.id!,
refreshToken: sessionMetadata.refreshToken,
refreshTokenExpiresAt: sessionMetadata.refreshTokenExpiresAt,
accessTokenExpiresInSeconds: ACCESS_TOKEN_EXPIRY_SECONDS,
});
CookieUtil.setCookie(
res,
CookieUtil.getUserTokenKey(alreadySavedUser.statusPageId!),
token,
{
httpOnly: true,
maxAge: OneUptimeDate.getMillisecondsInDays(new PositiveNumber(30)),
},
);
// get status page URL.
const statusPageURL: string =
await StatusPageService.getStatusPageFirstURL(statusPageId);
@@ -312,7 +327,11 @@ router.post(
);
} catch (err) {
logger.error(err);
Response.sendErrorResponse(req, res, new ServerException());
if (err instanceof Exception) {
return next(err);
}
return next(new ServerException());
}
},
);

View File

@@ -1,8 +1,10 @@
import AuthenticationAPI from "./API/Authentication";
import ResellerAPI from "./API/Reseller";
import SsoAPI from "./API/SSO";
import SCIMAPI from "./API/SCIM";
import StatusPageAuthenticationAPI from "./API/StatusPageAuthentication";
import StatusPageSsoAPI from "./API/StatusPageSSO";
import StatusPageSCIMAPI from "./API/StatusPageSCIM";
import FeatureSet from "Common/Server/Types/FeatureSet";
import Express, { ExpressApplication } from "Common/Server/Utils/Express";
import "ejs";
@@ -19,6 +21,10 @@ const IdentityFeatureSet: FeatureSet = {
app.use([`/${APP_NAME}`, "/"], SsoAPI);
app.use([`/${APP_NAME}`, "/"], SCIMAPI);
app.use([`/${APP_NAME}`, "/"], StatusPageSCIMAPI);
app.use([`/${APP_NAME}`, "/"], StatusPageSsoAPI);
app.use(

View File

@@ -35,6 +35,8 @@ export default class AuthenticationEmail {
const host: Hostname = await DatabaseConfig.getHost();
const httpProtocol: Protocol = await DatabaseConfig.getHttpProtocol();
logger.debug("Sending verification email");
MailService.sendMail({
toEmail: user.email!,
subject: "Please verify email.",
@@ -50,8 +52,13 @@ export default class AuthenticationEmail {
).toString(),
homeUrl: new URL(httpProtocol, host).toString(),
},
}).catch((err: Error) => {
logger.error(err);
});
})
.then(() => {
logger.debug("Verification email sent");
})
.catch((err: Error) => {
logger.debug("Error sending verification email");
logger.error(err);
});
}
}

View File

@@ -0,0 +1,265 @@
import { ExpressRequest } from "Common/Server/Utils/Express";
import logger from "Common/Server/Utils/Logger";
import { JSONObject } from "Common/Types/JSON";
import Email from "Common/Types/Email";
import Name from "Common/Types/Name";
import ObjectID from "Common/Types/ObjectID";
/**
* Shared SCIM utility functions for both Project SCIM and Status Page SCIM
*/
// Base interface for SCIM user-like objects - compatible with User model
export interface SCIMUser {
id?: ObjectID | null;
email?: Email;
name?: Name | string;
createdAt?: Date;
updatedAt?: Date;
}
/**
* Parse name information from SCIM user payload
*/
export const parseNameFromSCIM: (scimUser: JSONObject) => string = (
scimUser: JSONObject,
): string => {
logger.debug(
`SCIM - Parsing name from SCIM user: ${JSON.stringify(scimUser, null, 2)}`,
);
const givenName: string =
((scimUser["name"] as JSONObject)?.["givenName"] as string) || "";
const familyName: string =
((scimUser["name"] as JSONObject)?.["familyName"] as string) || "";
const formattedName: string = (scimUser["name"] as JSONObject)?.[
"formatted"
] as string;
// Construct full name: prefer formatted, then combine given+family, then fallback to displayName
if (formattedName) {
return formattedName;
} else if (givenName || familyName) {
return `${givenName} ${familyName}`.trim();
} else if (scimUser["displayName"]) {
return scimUser["displayName"] as string;
}
return "";
};
/**
* Parse full name into SCIM name format
*/
export const parseNameToSCIMFormat: (fullName: string) => {
givenName: string;
familyName: string;
formatted: string;
} = (
fullName: string,
): { givenName: string; familyName: string; formatted: string } => {
const nameParts: string[] = fullName.trim().split(/\s+/);
const givenName: string = nameParts[0] || "";
const familyName: string = nameParts.slice(1).join(" ") || "";
return {
givenName,
familyName,
formatted: fullName,
};
};
/**
* Format user object for SCIM response
*/
export const formatUserForSCIM: (
user: SCIMUser,
req: ExpressRequest,
scimId: string,
scimType: "project" | "status-page",
) => JSONObject = (
user: SCIMUser,
req: ExpressRequest,
scimId: string,
scimType: "project" | "status-page",
): JSONObject => {
const baseUrl: string = `${req.protocol}://${req.get("host")}`;
const userName: string = user.email?.toString() || "";
const fullName: string =
user.name?.toString() || userName.split("@")[0] || "Unknown User";
const nameData: { givenName: string; familyName: string; formatted: string } =
parseNameToSCIMFormat(fullName);
// Determine the correct endpoint path based on SCIM type
const endpointPath: string =
scimType === "project"
? `/scim/v2/${scimId}/Users/${user.id?.toString()}`
: `/status-page-scim/v2/${scimId}/Users/${user.id?.toString()}`;
return {
schemas: ["urn:ietf:params:scim:schemas:core:2.0:User"],
id: user.id?.toString(),
userName: userName,
displayName: nameData.formatted,
name: {
formatted: nameData.formatted,
familyName: nameData.familyName,
givenName: nameData.givenName,
},
emails: [
{
value: userName,
type: "work",
primary: true,
},
],
active: true,
meta: {
resourceType: "User",
created: user.createdAt?.toISOString(),
lastModified: user.updatedAt?.toISOString(),
location: `${baseUrl}${endpointPath}`,
},
};
};
/**
* Extract email from SCIM user payload
*/
export const extractEmailFromSCIM: (scimUser: JSONObject) => string = (
scimUser: JSONObject,
): string => {
return (
(scimUser["userName"] as string) ||
((scimUser["emails"] as JSONObject[])?.[0]?.["value"] as string) ||
""
);
};
/**
* Extract active status from SCIM user payload
*/
export const extractActiveFromSCIM: (scimUser: JSONObject) => boolean = (
scimUser: JSONObject,
): boolean => {
return scimUser["active"] !== false; // Default to true if not specified
};
/**
* Generate SCIM ServiceProviderConfig response
*/
export const generateServiceProviderConfig: (
req: ExpressRequest,
scimId: string,
scimType: "project" | "status-page",
documentationUrl?: string,
) => JSONObject = (
req: ExpressRequest,
scimId: string,
scimType: "project" | "status-page",
documentationUrl: string = "https://oneuptime.com/docs/identity/scim",
): JSONObject => {
const baseUrl: string = `${req.protocol}://${req.get("host")}`;
const endpointPath: string =
scimType === "project"
? `/scim/v2/${scimId}`
: `/status-page-scim/v2/${scimId}`;
return {
schemas: ["urn:ietf:params:scim:schemas:core:2.0:ServiceProviderConfig"],
documentationUri: documentationUrl,
patch: {
supported: true,
},
bulk: {
supported: true,
maxOperations: 1000,
maxPayloadSize: 1048576,
},
filter: {
supported: true,
maxResults: 200,
},
changePassword: {
supported: false,
},
sort: {
supported: true,
},
etag: {
supported: false,
},
authenticationSchemes: [
{
type: "httpbearer",
name: "HTTP Bearer",
description: "Authentication scheme using HTTP Bearer Token",
primary: true,
},
],
meta: {
location: `${baseUrl}${endpointPath}/ServiceProviderConfig`,
resourceType: "ServiceProviderConfig",
created: "2023-01-01T00:00:00Z",
lastModified: "2023-01-01T00:00:00Z",
},
};
};
/**
* Generate SCIM ListResponse for users
*/
export const generateUsersListResponse: (
users: JSONObject[],
startIndex: number,
totalResults: number,
) => JSONObject = (
users: JSONObject[],
startIndex: number,
totalResults: number,
): JSONObject => {
return {
schemas: ["urn:ietf:params:scim:api:messages:2.0:ListResponse"],
totalResults: totalResults,
startIndex: startIndex,
itemsPerPage: users.length,
Resources: users,
};
};
/**
* Generate SCIM ListResponse for groups
*/
export const generateGroupsListResponse: (
groups: JSONObject[],
startIndex: number,
totalResults: number,
) => JSONObject = (
groups: JSONObject[],
startIndex: number,
totalResults: number,
): JSONObject => {
return {
schemas: ["urn:ietf:params:scim:api:messages:2.0:ListResponse"],
totalResults: totalResults,
startIndex: startIndex,
itemsPerPage: groups.length,
Resources: groups,
};
};
/**
* Parse query parameters for SCIM list requests
*/
export const parseSCIMQueryParams: (req: ExpressRequest) => {
startIndex: number;
count: number;
} = (req: ExpressRequest): { startIndex: number; count: number } => {
const startIndex: number = parseInt(req.query["startIndex"] as string) || 1;
const count: number = Math.min(
parseInt(req.query["count"] as string) || 100,
200, // SCIM recommended max
);
return { startIndex, count };
};

View File

@@ -184,15 +184,17 @@ export default class SSOUtil {
return null;
}
// get displayName attribute.
// {
// "$": {
// "Name": "http://schemas.microsoft.com/identity/claims/displayname"
// },
// "AttributeValue": [
// "Nawaz Dhandala"
// ]
// },
/*
* get displayName attribute.
* {
* "$": {
* "Name": "http://schemas.microsoft.com/identity/claims/displayname"
* },
* "AttributeValue": [
* "Nawaz Dhandala"
* ]
* },
*/
for (let i: number = 0; i < samlAttribute.length; i++) {
const attribute: JSONObject = samlAttribute[i] as JSONObject;

View File

@@ -67,7 +67,6 @@
<link rel="apple-touch-icon-precomposed" href="/img/ou-wb.svg">
<link rel="icon" href="/img/ou-wb.svg">
<link rel="image_src" type="image/png" href="/img/hou-wb.svg">
<link rel="canonical" href="/">
<link rel="manifest" href="/manifest.json">
<meta property="og:title" content="OneUptime - One Complete Observability platform.">
<meta property="og:url" content="https://oneuptime.com">

View File

@@ -12,6 +12,7 @@ import Express, {
ExpressRequest,
ExpressResponse,
ExpressRouter,
NextFunction,
} from "Common/Server/Utils/Express";
import logger from "Common/Server/Utils/Logger";
import Response from "Common/Server/Utils/Response";
@@ -22,123 +23,146 @@ const router: ExpressRouter = Express.getRouter();
router.post(
"/make-call",
ClusterKeyAuthorization.isAuthorizedServiceMiddleware,
async (req: ExpressRequest, res: ExpressResponse) => {
const body: JSONObject = JSONFunctions.deserialize(req.body);
async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
try {
const body: JSONObject = JSONFunctions.deserialize(req.body);
await CallService.makeCall(body["callRequest"] as CallRequest, {
projectId: body["projectId"] as ObjectID,
isSensitive: (body["isSensitive"] as boolean) || false,
userOnCallLogTimelineId:
(body["userOnCallLogTimelineId"] as ObjectID) || undefined,
customTwilioConfig: body["customTwilioConfig"] as any,
});
await CallService.makeCall(body["callRequest"] as CallRequest, {
projectId: body["projectId"] as ObjectID,
isSensitive: (body["isSensitive"] as boolean) || false,
userOnCallLogTimelineId:
(body["userOnCallLogTimelineId"] as ObjectID) || undefined,
customTwilioConfig: body["customTwilioConfig"] as any,
incidentId: (body["incidentId"] as ObjectID) || undefined,
alertId: (body["alertId"] as ObjectID) || undefined,
scheduledMaintenanceId:
(body["scheduledMaintenanceId"] as ObjectID) || undefined,
statusPageId: (body["statusPageId"] as ObjectID) || undefined,
statusPageAnnouncementId:
(body["statusPageAnnouncementId"] as ObjectID) || undefined,
userId: (body["userId"] as ObjectID) || undefined,
onCallPolicyId: (body["onCallPolicyId"] as ObjectID) || undefined,
onCallPolicyEscalationRuleId:
(body["onCallPolicyEscalationRuleId"] as ObjectID) || undefined,
onCallDutyPolicyExecutionLogTimelineId:
(body["onCallDutyPolicyExecutionLogTimelineId"] as ObjectID) ||
undefined,
onCallScheduleId: (body["onCallScheduleId"] as ObjectID) || undefined,
teamId: (body["teamId"] as ObjectID) || undefined,
});
return Response.sendEmptySuccessResponse(req, res);
return Response.sendEmptySuccessResponse(req, res);
} catch (err) {
return next(err);
}
},
);
router.post("/test", async (req: ExpressRequest, res: ExpressResponse) => {
const body: JSONObject = req.body;
router.post(
"/test",
async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
try {
const body: JSONObject = req.body;
const callSMSConfigId: ObjectID = new ObjectID(
body["callSMSConfigId"] as string,
);
const callSMSConfigId: ObjectID = new ObjectID(
body["callSMSConfigId"] as string,
);
const config: ProjectCallSMSConfig | null =
await ProjectCallSMSConfigService.findOneById({
id: callSMSConfigId,
props: {
isRoot: true,
},
select: {
_id: true,
twilioAccountSID: true,
twilioAuthToken: true,
twilioPrimaryPhoneNumber: true,
twilioSecondaryPhoneNumbers: true,
projectId: true,
},
});
const config: ProjectCallSMSConfig | null =
await ProjectCallSMSConfigService.findOneById({
id: callSMSConfigId,
props: {
isRoot: true,
},
select: {
_id: true,
twilioAccountSID: true,
twilioAuthToken: true,
twilioPrimaryPhoneNumber: true,
twilioSecondaryPhoneNumbers: true,
projectId: true,
},
});
if (!config) {
return Response.sendErrorResponse(
req,
res,
new BadDataException(
"call and sms config not found for id" + callSMSConfigId.toString(),
),
);
}
if (!config) {
return Response.sendErrorResponse(
req,
res,
new BadDataException(
"call and sms config not found for id" + callSMSConfigId.toString(),
),
);
}
const toPhone: Phone = new Phone(body["toPhone"] as string);
const toPhone: Phone = new Phone(body["toPhone"] as string);
if (!toPhone) {
return Response.sendErrorResponse(
req,
res,
new BadDataException("toPhone is required"),
);
}
if (!toPhone) {
return Response.sendErrorResponse(
req,
res,
new BadDataException("toPhone is required"),
);
}
// if any of the twilio config is missing, we will not send make the call
// if any of the twilio config is missing, we will not send make the call
if (!config.twilioAccountSID) {
return Response.sendErrorResponse(
req,
res,
new BadDataException("twilioAccountSID is required"),
);
}
if (!config.twilioAccountSID) {
return Response.sendErrorResponse(
req,
res,
new BadDataException("twilioAccountSID is required"),
);
}
if (!config.twilioAuthToken) {
return Response.sendErrorResponse(
req,
res,
new BadDataException("twilioAuthToken is required"),
);
}
if (!config.twilioAuthToken) {
return Response.sendErrorResponse(
req,
res,
new BadDataException("twilioAuthToken is required"),
);
}
if (!config.twilioPrimaryPhoneNumber) {
return Response.sendErrorResponse(
req,
res,
new BadDataException("twilioPrimaryPhoneNumber is required"),
);
}
if (!config.twilioPrimaryPhoneNumber) {
return Response.sendErrorResponse(
req,
res,
new BadDataException("twilioPrimaryPhoneNumber is required"),
);
}
const twilioConfig: TwilioConfig | undefined =
ProjectCallSMSConfigService.toTwilioConfig(config);
const twilioConfig: TwilioConfig | undefined =
ProjectCallSMSConfigService.toTwilioConfig(config);
try {
if (!twilioConfig) {
throw new BadDataException("twilioConfig is undefined");
try {
if (!twilioConfig) {
throw new BadDataException("twilioConfig is undefined");
}
const testCallRequest: CallRequest = {
data: [
{
sayMessage: "This is a test call from OneUptime.",
},
],
to: toPhone,
};
await CallService.makeCall(testCallRequest, {
projectId: config.projectId,
customTwilioConfig: twilioConfig,
});
} catch (err) {
logger.error(err);
throw new BadDataException(
"Error making test call. Please check the twilio logs for more details",
);
}
return Response.sendEmptySuccessResponse(req, res);
} catch (err) {
return next(err);
}
const testCallRequest: CallRequest = {
data: [
{
sayMessage: "This is a test call from OneUptime.",
},
],
to: toPhone,
};
await CallService.makeCall(testCallRequest, {
projectId: config.projectId,
customTwilioConfig: twilioConfig,
});
} catch (err) {
logger.error(err);
return Response.sendErrorResponse(
req,
res,
new BadDataException(
"Error making test call. Please check the twilio logs for more details",
),
);
}
return Response.sendEmptySuccessResponse(req, res);
});
},
);
export default router;

View File

@@ -11,6 +11,7 @@ import Express, {
ExpressRequest,
ExpressResponse,
ExpressRouter,
NextFunction,
} from "Common/Server/Utils/Express";
import Response from "Common/Server/Utils/Response";
@@ -19,33 +20,74 @@ const router: ExpressRouter = Express.getRouter();
router.post(
"/send",
ClusterKeyAuthorization.isAuthorizedServiceMiddleware,
async (req: ExpressRequest, res: ExpressResponse) => {
const body: JSONObject = req.body;
async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
try {
const body: JSONObject = req.body;
const mail: EmailMessage = {
templateType: body["templateType"] as EmailTemplateType,
toEmail: new Email(body["toEmail"] as string),
subject: body["subject"] as string,
vars: body["vars"] as Dictionary<string>,
body: (body["body"] as string) || "",
};
const mail: EmailMessage = {
templateType: body["templateType"] as EmailTemplateType,
toEmail: new Email(body["toEmail"] as string),
subject: body["subject"] as string,
vars: body["vars"] as Dictionary<string>,
body: (body["body"] as string) || "",
};
let mailServer: EmailServer | undefined = undefined;
let mailServer: EmailServer | undefined = undefined;
if (hasMailServerSettingsInBody(body)) {
mailServer = MailService.getEmailServer(req.body);
if (hasMailServerSettingsInBody(body)) {
mailServer = MailService.getEmailServer(req.body);
}
await MailService.send(mail, {
projectId: body["projectId"]
? new ObjectID(body["projectId"] as string)
: undefined,
emailServer: mailServer,
userOnCallLogTimelineId:
(body["userOnCallLogTimelineId"] as ObjectID) || undefined,
incidentId: body["incidentId"]
? new ObjectID(body["incidentId"].toString())
: undefined,
alertId: body["alertId"]
? new ObjectID(body["alertId"].toString())
: undefined,
scheduledMaintenanceId: body["scheduledMaintenanceId"]
? new ObjectID(body["scheduledMaintenanceId"].toString())
: undefined,
statusPageId: body["statusPageId"]
? new ObjectID(body["statusPageId"].toString())
: undefined,
statusPageAnnouncementId: body["statusPageAnnouncementId"]
? new ObjectID(body["statusPageAnnouncementId"].toString())
: undefined,
userId: body["userId"]
? new ObjectID(body["userId"].toString())
: undefined,
onCallPolicyId: body["onCallPolicyId"]
? new ObjectID(body["onCallPolicyId"].toString())
: undefined,
onCallPolicyEscalationRuleId: body["onCallPolicyEscalationRuleId"]
? new ObjectID(body["onCallPolicyEscalationRuleId"].toString())
: undefined,
onCallDutyPolicyExecutionLogTimelineId: body[
"onCallDutyPolicyExecutionLogTimelineId"
]
? new ObjectID(
body["onCallDutyPolicyExecutionLogTimelineId"].toString(),
)
: undefined,
onCallScheduleId: body["onCallScheduleId"]
? new ObjectID(body["onCallScheduleId"].toString())
: undefined,
teamId: body["teamId"]
? new ObjectID(body["teamId"].toString())
: undefined,
});
return Response.sendEmptySuccessResponse(req, res);
} catch (err) {
return next(err);
}
await MailService.send(mail, {
projectId: body["projectId"]
? new ObjectID(body["projectId"] as string)
: undefined,
emailServer: mailServer,
userOnCallLogTimelineId:
(body["userOnCallLogTimelineId"] as ObjectID) || undefined,
});
return Response.sendEmptySuccessResponse(req, res);
},
);

View File

@@ -0,0 +1,70 @@
import PushService from "../Services/PushNotificationService";
import ClusterKeyAuthorization from "Common/Server/Middleware/ClusterKeyAuthorization";
import ObjectID from "Common/Types/ObjectID";
import Express, {
ExpressRequest,
ExpressResponse,
ExpressRouter,
NextFunction,
} from "Common/Server/Utils/Express";
import Response from "Common/Server/Utils/Response";
import { JSONObject } from "Common/Types/JSON";
import JSONFunctions from "Common/Types/JSONFunctions";
const router: ExpressRouter = Express.getRouter();
router.post(
"/send",
ClusterKeyAuthorization.isAuthorizedServiceMiddleware,
async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
try {
const body: JSONObject = JSONFunctions.deserialize(req.body);
// Support both new devices format and legacy deviceTokens/deviceNames format
let devices: Array<{ token: string; name?: string }> = [];
if (body["devices"]) {
// New format: devices as array of objects
devices = body["devices"] as Array<{ token: string; name?: string }>;
} else {
throw new Error("Invalid request format: 'devices' array is required.");
}
await PushService.send(
{
devices,
deviceType: (body["deviceType"] as any) || "web",
message: body["message"] as any,
},
{
projectId: (body["projectId"] as ObjectID) || undefined,
isSensitive: (body["isSensitive"] as boolean) || false,
userOnCallLogTimelineId:
(body["userOnCallLogTimelineId"] as ObjectID) || undefined,
incidentId: (body["incidentId"] as ObjectID) || undefined,
alertId: (body["alertId"] as ObjectID) || undefined,
scheduledMaintenanceId:
(body["scheduledMaintenanceId"] as ObjectID) || undefined,
statusPageId: (body["statusPageId"] as ObjectID) || undefined,
statusPageAnnouncementId:
(body["statusPageAnnouncementId"] as ObjectID) || undefined,
userId: (body["userId"] as ObjectID) || undefined,
onCallPolicyId: (body["onCallPolicyId"] as ObjectID) || undefined,
onCallPolicyEscalationRuleId:
(body["onCallPolicyEscalationRuleId"] as ObjectID) || undefined,
onCallDutyPolicyExecutionLogTimelineId:
(body["onCallDutyPolicyExecutionLogTimelineId"] as ObjectID) ||
undefined,
onCallScheduleId: (body["onCallScheduleId"] as ObjectID) || undefined,
teamId: (body["teamId"] as ObjectID) || undefined,
},
);
return Response.sendEmptySuccessResponse(req, res);
} catch (err) {
return next(err);
}
},
);
export default router;

View File

@@ -11,6 +11,7 @@ import Express, {
ExpressRequest,
ExpressResponse,
ExpressRouter,
NextFunction,
} from "Common/Server/Utils/Express";
import logger from "Common/Server/Utils/Logger";
import Response from "Common/Server/Utils/Response";
@@ -21,114 +22,141 @@ const router: ExpressRouter = Express.getRouter();
router.post(
"/send",
ClusterKeyAuthorization.isAuthorizedServiceMiddleware,
async (req: ExpressRequest, res: ExpressResponse) => {
const body: JSONObject = JSONFunctions.deserialize(req.body);
async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
try {
const body: JSONObject = JSONFunctions.deserialize(req.body);
await SmsService.sendSms(body["to"] as Phone, body["message"] as string, {
projectId: body["projectId"] as ObjectID,
isSensitive: (body["isSensitive"] as boolean) || false,
userOnCallLogTimelineId:
(body["userOnCallLogTimelineId"] as ObjectID) || undefined,
customTwilioConfig: body["customTwilioConfig"] as any,
});
await SmsService.sendSms(body["to"] as Phone, body["message"] as string, {
projectId: body["projectId"] as ObjectID,
isSensitive: (body["isSensitive"] as boolean) || false,
userOnCallLogTimelineId:
(body["userOnCallLogTimelineId"] as ObjectID) || undefined,
customTwilioConfig: body["customTwilioConfig"] as any,
incidentId: (body["incidentId"] as ObjectID) || undefined,
alertId: (body["alertId"] as ObjectID) || undefined,
scheduledMaintenanceId:
(body["scheduledMaintenanceId"] as ObjectID) || undefined,
statusPageId: (body["statusPageId"] as ObjectID) || undefined,
statusPageAnnouncementId:
(body["statusPageAnnouncementId"] as ObjectID) || undefined,
userId: (body["userId"] as ObjectID) || undefined,
onCallPolicyId: (body["onCallPolicyId"] as ObjectID) || undefined,
onCallPolicyEscalationRuleId:
(body["onCallPolicyEscalationRuleId"] as ObjectID) || undefined,
onCallDutyPolicyExecutionLogTimelineId:
(body["onCallDutyPolicyExecutionLogTimelineId"] as ObjectID) ||
undefined,
onCallScheduleId: (body["onCallScheduleId"] as ObjectID) || undefined,
teamId: (body["teamId"] as ObjectID) || undefined,
});
return Response.sendEmptySuccessResponse(req, res);
return Response.sendEmptySuccessResponse(req, res);
} catch (err) {
return next(err);
}
},
);
router.post("/test", async (req: ExpressRequest, res: ExpressResponse) => {
const body: JSONObject = req.body;
router.post(
"/test",
async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
try {
const body: JSONObject = req.body;
const callSMSConfigId: ObjectID = new ObjectID(
body["callSMSConfigId"] as string,
);
const callSMSConfigId: ObjectID = new ObjectID(
body["callSMSConfigId"] as string,
);
const config: ProjectCallSMSConfig | null =
await ProjectCallSMSConfigService.findOneById({
id: callSMSConfigId,
props: {
isRoot: true,
},
select: {
_id: true,
twilioAccountSID: true,
twilioAuthToken: true,
twilioPrimaryPhoneNumber: true,
twilioSecondaryPhoneNumbers: true,
projectId: true,
},
});
const config: ProjectCallSMSConfig | null =
await ProjectCallSMSConfigService.findOneById({
id: callSMSConfigId,
props: {
isRoot: true,
},
select: {
_id: true,
twilioAccountSID: true,
twilioAuthToken: true,
twilioPrimaryPhoneNumber: true,
twilioSecondaryPhoneNumbers: true,
projectId: true,
},
});
if (!config) {
return Response.sendErrorResponse(
req,
res,
new BadDataException(
"call and sms config not found for id" + callSMSConfigId.toString(),
),
);
}
if (!config) {
return Response.sendErrorResponse(
req,
res,
new BadDataException(
"call and sms config not found for id" + callSMSConfigId.toString(),
),
);
}
const toPhone: Phone = new Phone(body["toPhone"] as string);
const toPhone: Phone = new Phone(body["toPhone"] as string);
if (!toPhone) {
return Response.sendErrorResponse(
req,
res,
new BadDataException("toPhone is required"),
);
}
if (!toPhone) {
return Response.sendErrorResponse(
req,
res,
new BadDataException("toPhone is required"),
);
}
// if any of the twilio config is missing, we will not send make the call
// if any of the twilio config is missing, we will not send make the call
if (!config.twilioAccountSID) {
return Response.sendErrorResponse(
req,
res,
new BadDataException("twilioAccountSID is required"),
);
}
if (!config.twilioAccountSID) {
return Response.sendErrorResponse(
req,
res,
new BadDataException("twilioAccountSID is required"),
);
}
if (!config.twilioAuthToken) {
return Response.sendErrorResponse(
req,
res,
new BadDataException("twilioAuthToken is required"),
);
}
if (!config.twilioAuthToken) {
return Response.sendErrorResponse(
req,
res,
new BadDataException("twilioAuthToken is required"),
);
}
if (!config.twilioPrimaryPhoneNumber) {
return Response.sendErrorResponse(
req,
res,
new BadDataException("twilioPrimaryPhoneNumber is required"),
);
}
if (!config.twilioPrimaryPhoneNumber) {
return Response.sendErrorResponse(
req,
res,
new BadDataException("twilioPrimaryPhoneNumber is required"),
);
}
const twilioConfig: TwilioConfig | undefined =
ProjectCallSMSConfigService.toTwilioConfig(config);
const twilioConfig: TwilioConfig | undefined =
ProjectCallSMSConfigService.toTwilioConfig(config);
try {
if (!twilioConfig) {
throw new BadDataException("twilioConfig is undefined");
try {
if (!twilioConfig) {
throw new BadDataException("twilioConfig is undefined");
}
await SmsService.sendSms(
toPhone,
"This is a test SMS from OneUptime.",
{
projectId: config.projectId,
customTwilioConfig: twilioConfig,
},
);
} catch (err) {
logger.error(err);
throw new BadDataException(
"Failed to send test SMS. Please check the twilio logs for more details.",
);
}
return Response.sendEmptySuccessResponse(req, res);
} catch (err) {
return next(err);
}
await SmsService.sendSms(toPhone, "This is a test SMS from OneUptime.", {
projectId: config.projectId,
customTwilioConfig: twilioConfig,
});
} catch (err) {
logger.error(err);
return Response.sendErrorResponse(
req,
res,
new BadDataException(
"Failed to send test SMS. Please check the twilio logs for more details.",
),
);
}
return Response.sendEmptySuccessResponse(req, res);
});
},
);
export default router;

View File

@@ -11,6 +11,7 @@ import Express, {
ExpressRequest,
ExpressResponse,
ExpressRouter,
NextFunction,
} from "Common/Server/Utils/Express";
import logger from "Common/Server/Utils/Logger";
import Response from "Common/Server/Utils/Response";
@@ -18,87 +19,92 @@ import ProjectSmtpConfig from "Common/Models/DatabaseModels/ProjectSmtpConfig";
const router: ExpressRouter = Express.getRouter();
router.post("/test", async (req: ExpressRequest, res: ExpressResponse) => {
const body: JSONObject = req.body;
router.post(
"/test",
async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
try {
const body: JSONObject = req.body;
const smtpConfigId: ObjectID = new ObjectID(body["smtpConfigId"] as string);
const smtpConfigId: ObjectID = new ObjectID(
body["smtpConfigId"] as string,
);
const config: ProjectSmtpConfig | null =
await ProjectSMTPConfigService.findOneById({
id: smtpConfigId,
props: {
isRoot: true,
},
select: {
_id: true,
hostname: true,
port: true,
username: true,
password: true,
fromEmail: true,
fromName: true,
secure: true,
projectId: true,
},
});
const config: ProjectSmtpConfig | null =
await ProjectSMTPConfigService.findOneById({
id: smtpConfigId,
props: {
isRoot: true,
},
select: {
_id: true,
hostname: true,
port: true,
username: true,
password: true,
fromEmail: true,
fromName: true,
secure: true,
projectId: true,
},
});
if (!config) {
return Response.sendErrorResponse(
req,
res,
new BadDataException(
"smtp-config not found for id" + smtpConfigId.toString(),
),
);
}
if (!config) {
return Response.sendErrorResponse(
req,
res,
new BadDataException(
"smtp-config not found for id" + smtpConfigId.toString(),
),
);
}
const toEmail: Email = new Email(body["toEmail"] as string);
const toEmail: Email = new Email(body["toEmail"] as string);
if (!toEmail) {
return Response.sendErrorResponse(
req,
res,
new BadDataException("toEmail is required"),
);
}
if (!toEmail) {
return Response.sendErrorResponse(
req,
res,
new BadDataException("toEmail is required"),
);
}
const mail: EmailMessage = {
templateType: EmailTemplateType.SMTPTest,
toEmail: new Email(body["toEmail"] as string),
subject: "Test Email from OneUptime",
vars: {},
body: "",
};
const mail: EmailMessage = {
templateType: EmailTemplateType.SMTPTest,
toEmail: new Email(body["toEmail"] as string),
subject: "Test Email from OneUptime",
vars: {},
body: "",
};
const mailServer: EmailServer = {
id: config.id!,
host: config.hostname!,
port: config.port!,
username: config.username!,
password: config.password!,
fromEmail: config.fromEmail!,
fromName: config.fromName!,
secure: Boolean(config.secure),
};
const mailServer: EmailServer = {
id: config.id!,
host: config.hostname!,
port: config.port!,
username: config.username!,
password: config.password!,
fromEmail: config.fromEmail!,
fromName: config.fromName!,
secure: Boolean(config.secure),
};
try {
await MailService.send(mail, {
emailServer: mailServer,
projectId: config.projectId!,
timeout: 4000,
});
} catch (err) {
logger.error(err);
return Response.sendErrorResponse(
req,
res,
new BadDataException(
"Cannot send email. Please check your SMTP config. If you are using Google or Gmail, please dont since it does not support machine access to their mail servers. If you are still having issues, please uncheck SSL/TLS toggle and try again. We recommend using SendGrid or Mailgun or any large volume mail provider for SMTP.",
),
);
}
try {
await MailService.send(mail, {
emailServer: mailServer,
projectId: config.projectId!,
timeout: 4000,
});
} catch (err) {
logger.error(err);
throw new BadDataException(
"Cannot send email. Please check your SMTP config. If you are using Google or Gmail, please dont since it does not support machine access to their mail servers. If you are still having issues, please uncheck SSL/TLS toggle and try again. We recommend using SendGrid or Mailgun or any large volume mail provider for SMTP.",
);
}
return Response.sendEmptySuccessResponse(req, res);
});
return Response.sendEmptySuccessResponse(req, res);
} catch (err) {
return next(err);
}
},
);
export default router;

View File

@@ -0,0 +1,491 @@
import WhatsAppService from "../Services/WhatsAppService";
import BadDataException from "Common/Types/Exception/BadDataException";
import GlobalConfig from "Common/Models/DatabaseModels/GlobalConfig";
import { JSONArray, JSONObject } from "Common/Types/JSON";
import ObjectID from "Common/Types/ObjectID";
import Phone from "Common/Types/Phone";
import WhatsAppMessage from "Common/Types/WhatsApp/WhatsAppMessage";
import {
WhatsAppTemplateId,
WhatsAppTemplateIds,
WhatsAppTemplateLanguage,
} from "Common/Types/WhatsApp/WhatsAppTemplates";
import WhatsAppStatus from "Common/Types/WhatsAppStatus";
import ClusterKeyAuthorization from "Common/Server/Middleware/ClusterKeyAuthorization";
import WhatsAppLogService from "Common/Server/Services/WhatsAppLogService";
import GlobalConfigService from "Common/Server/Services/GlobalConfigService";
import Express, {
ExpressRequest,
ExpressResponse,
ExpressRouter,
NextFunction,
} from "Common/Server/Utils/Express";
import logger from "Common/Server/Utils/Logger";
import Response from "Common/Server/Utils/Response";
const router: ExpressRouter = Express.getRouter();
const MAX_STATUS_MESSAGE_LENGTH: number = 500;
export const mapWebhookStatusToWhatsAppStatus: (
status?: string,
) => WhatsAppStatus = (status?: string): WhatsAppStatus => {
switch ((status || "").toLowerCase()) {
case "sent":
return WhatsAppStatus.Sent;
case "delivered":
return WhatsAppStatus.Delivered;
case "read":
return WhatsAppStatus.Read;
case "failed":
return WhatsAppStatus.Failed;
case "deleted":
case "removed":
return WhatsAppStatus.Deleted;
case "warning":
return WhatsAppStatus.Warning;
case "queued":
case "pending":
return WhatsAppStatus.Queued;
case "error":
return WhatsAppStatus.Error;
case "success":
return WhatsAppStatus.Success;
default:
return WhatsAppStatus.Unknown;
}
};
export const buildStatusMessage: (payload: JSONObject) => string | undefined = (
payload: JSONObject,
): string | undefined => {
const messageParts: Array<string> = [];
const rawStatus: string | undefined = payload["status"]
? String(payload["status"])
: undefined;
if (rawStatus) {
messageParts.push(`Status: ${rawStatus}`);
}
const timestamp: string | undefined = payload["timestamp"]
? String(payload["timestamp"])
: undefined;
if (timestamp) {
const numericTimestamp: number = Number(timestamp);
if (!isNaN(numericTimestamp)) {
messageParts.push(
`Timestamp: ${new Date(numericTimestamp * 1000).toISOString()}`,
);
} else {
messageParts.push(`Timestamp: ${timestamp}`);
}
}
const conversation: JSONObject | undefined =
(payload["conversation"] as JSONObject | undefined) || undefined;
if (conversation) {
if (conversation["id"]) {
messageParts.push(`Conversation: ${conversation["id"]}`);
}
const origin: JSONObject | undefined =
(conversation["origin"] as JSONObject | undefined) || undefined;
if (origin?.["type"]) {
messageParts.push(`Origin: ${origin["type"]}`);
}
if (conversation["expiration_timestamp"]) {
const expirationTimestamp: number = Number(
conversation["expiration_timestamp"],
);
if (!isNaN(expirationTimestamp)) {
messageParts.push(
`Conversation expires: ${new Date(expirationTimestamp * 1000).toISOString()}`,
);
}
}
}
const pricing: JSONObject | undefined =
(payload["pricing"] as JSONObject | undefined) || undefined;
if (pricing) {
const pricingParts: Array<string> = [];
if (pricing["billable"] !== undefined) {
pricingParts.push(`billable=${pricing["billable"]}`);
}
if (pricing["category"]) {
pricingParts.push(`category=${pricing["category"]}`);
}
if (pricing["pricing_model"]) {
pricingParts.push(`model=${pricing["pricing_model"]}`);
}
if (pricingParts.length > 0) {
messageParts.push(`Pricing: ${pricingParts.join(", ")}`);
}
}
const errors: JSONArray | undefined =
(payload["errors"] as JSONArray | undefined) || undefined;
if (Array.isArray(errors) && errors.length > 0) {
const firstError: JSONObject = errors[0] as JSONObject;
const errorParts: Array<string> = [];
if (firstError["title"]) {
errorParts.push(String(firstError["title"]));
}
if (firstError["code"]) {
errorParts.push(`code=${firstError["code"]}`);
}
if (firstError["detail"]) {
errorParts.push(String(firstError["detail"]));
}
if (errorParts.length > 0) {
messageParts.push(`Error: ${errorParts.join(" - ")}`);
}
}
if (messageParts.length === 0) {
return undefined;
}
const statusMessage: string = messageParts.join(" | ");
if (statusMessage.length <= MAX_STATUS_MESSAGE_LENGTH) {
return statusMessage;
}
return `${statusMessage.substring(0, MAX_STATUS_MESSAGE_LENGTH - 3)}...`;
};
const updateWhatsAppLogStatus: (
statusPayload: JSONObject,
) => Promise<void> = async (statusPayload: JSONObject): Promise<void> => {
const messageId: string | undefined = statusPayload["id"]
? String(statusPayload["id"])
: undefined;
if (!messageId) {
logger.warn(
`[Meta WhatsApp Webhook] Received status payload without message id. Payload: ${JSON.stringify(statusPayload)}`,
);
return;
}
const rawStatus: string | undefined = statusPayload["status"]
? String(statusPayload["status"])
: undefined;
const derivedStatus: WhatsAppStatus =
mapWebhookStatusToWhatsAppStatus(rawStatus);
const statusMessage: string | undefined = buildStatusMessage(statusPayload);
const updateResult: number = await WhatsAppLogService.updateOneBy({
query: {
whatsAppMessageId: messageId,
},
data: {
status: derivedStatus,
...(statusMessage ? { statusMessage } : {}),
},
props: {
isRoot: true,
},
});
if (updateResult === 0) {
logger.warn(
`[Meta WhatsApp Webhook] No WhatsApp log found for message id ${messageId}. Payload: ${JSON.stringify(statusPayload)}`,
);
} else {
logger.debug(
`[Meta WhatsApp Webhook] Updated WhatsApp log for message id ${messageId} with status ${derivedStatus}.`,
);
}
};
const toTemplateVariables: (
rawVariables: JSONObject | undefined,
) => Record<string, string> | undefined = (
rawVariables: JSONObject | undefined,
): Record<string, string> | undefined => {
if (!rawVariables) {
return undefined;
}
const result: Record<string, string> = {};
for (const key of Object.keys(rawVariables)) {
const value: unknown = rawVariables[key];
if (value !== null && value !== undefined) {
result[key] = String(value);
}
}
return Object.keys(result).length > 0 ? result : undefined;
};
router.post(
"/send",
ClusterKeyAuthorization.isAuthorizedServiceMiddleware,
async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
const body: JSONObject = req.body as JSONObject;
if (!body["to"]) {
throw new BadDataException("`to` phone number is required");
}
const toPhone: Phone = new Phone(body["to"] as string);
const message: WhatsAppMessage = {
to: toPhone,
body: (body["body"] as string) || "",
templateKey: (body["templateKey"] as string) || undefined,
templateVariables: toTemplateVariables(
body["templateVariables"] as JSONObject | undefined,
),
templateLanguageCode:
(body["templateLanguageCode"] as string) || undefined,
};
try {
await WhatsAppService.sendWhatsApp(message, {
projectId: body["projectId"]
? new ObjectID(body["projectId"] as string)
: undefined,
isSensitive: (body["isSensitive"] as boolean) || false,
userOnCallLogTimelineId: body["userOnCallLogTimelineId"]
? new ObjectID(body["userOnCallLogTimelineId"] as string)
: undefined,
incidentId: body["incidentId"]
? new ObjectID(body["incidentId"] as string)
: undefined,
alertId: body["alertId"]
? new ObjectID(body["alertId"] as string)
: undefined,
scheduledMaintenanceId: body["scheduledMaintenanceId"]
? new ObjectID(body["scheduledMaintenanceId"] as string)
: undefined,
statusPageId: body["statusPageId"]
? new ObjectID(body["statusPageId"] as string)
: undefined,
statusPageAnnouncementId: body["statusPageAnnouncementId"]
? new ObjectID(body["statusPageAnnouncementId"] as string)
: undefined,
userId: body["userId"]
? new ObjectID(body["userId"] as string)
: undefined,
onCallPolicyId: body["onCallPolicyId"]
? new ObjectID(body["onCallPolicyId"] as string)
: undefined,
onCallPolicyEscalationRuleId: body["onCallPolicyEscalationRuleId"]
? new ObjectID(body["onCallPolicyEscalationRuleId"] as string)
: undefined,
onCallDutyPolicyExecutionLogTimelineId: body[
"onCallDutyPolicyExecutionLogTimelineId"
]
? new ObjectID(
body["onCallDutyPolicyExecutionLogTimelineId"] as string,
)
: undefined,
onCallScheduleId: body["onCallScheduleId"]
? new ObjectID(body["onCallScheduleId"] as string)
: undefined,
teamId: body["teamId"]
? new ObjectID(body["teamId"] as string)
: undefined,
});
return Response.sendEmptySuccessResponse(req, res);
} catch (err) {
return next(err);
}
},
);
router.get("/webhook", async (req: ExpressRequest, res: ExpressResponse) => {
const mode: string | undefined = req.query["hub.mode"]
? String(req.query["hub.mode"])
: undefined;
const verifyToken: string | undefined = req.query["hub.verify_token"]
? String(req.query["hub.verify_token"])
: undefined;
const challenge: string | undefined = req.query["hub.challenge"]
? String(req.query["hub.challenge"])
: undefined;
if (mode === "subscribe" && challenge) {
const globalConfigTokenResponse: GlobalConfig | null =
await GlobalConfigService.findOneBy({
query: {
_id: ObjectID.getZeroObjectID().toString(),
},
props: {
isRoot: true,
},
select: {
metaWhatsAppWebhookVerifyToken: true,
},
});
const configuredVerifyToken: string | undefined =
globalConfigTokenResponse?.metaWhatsAppWebhookVerifyToken?.trim() ||
undefined;
if (!configuredVerifyToken) {
logger.error(
"Meta WhatsApp webhook verify token is not configured. Rejecting verification request.",
);
res.sendStatus(403);
return;
}
if (verifyToken === configuredVerifyToken) {
res.status(200).send(challenge);
return;
}
logger.warn(
"Meta WhatsApp webhook verification failed due to token mismatch.",
);
res.sendStatus(403);
return;
}
res.sendStatus(400);
});
router.post(
"/webhook",
async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
try {
const body: JSONObject = req.body as JSONObject;
if (
(body["object"] as string | undefined) !== "whatsapp_business_account"
) {
logger.debug(
`[Meta WhatsApp Webhook] Received event for unsupported object: ${JSON.stringify(body)}`,
);
return Response.sendEmptySuccessResponse(req, res);
}
const entries: JSONArray | undefined = body["entry"] as
| JSONArray
| undefined;
if (!Array.isArray(entries)) {
logger.warn(
`[Meta WhatsApp Webhook] Payload did not include entries array. Payload: ${JSON.stringify(body)}`,
);
return Response.sendEmptySuccessResponse(req, res);
}
const statusUpdatePromises: Array<Promise<void>> = [];
for (const entry of entries) {
const entryObject: JSONObject = entry as JSONObject;
const changes: JSONArray | undefined =
(entryObject["changes"] as JSONArray | undefined) || undefined;
if (!Array.isArray(changes)) {
continue;
}
for (const change of changes) {
const changeObject: JSONObject = change as JSONObject;
const value: JSONObject | undefined =
(changeObject["value"] as JSONObject | undefined) || undefined;
if (!value) {
continue;
}
const statuses: JSONArray | undefined =
(value["statuses"] as JSONArray | undefined) || undefined;
if (Array.isArray(statuses)) {
for (const statusItem of statuses) {
statusUpdatePromises.push(
updateWhatsAppLogStatus(statusItem as JSONObject),
);
}
}
}
}
if (statusUpdatePromises.length > 0) {
await Promise.allSettled(statusUpdatePromises);
}
return Response.sendEmptySuccessResponse(req, res);
} catch (err) {
return next(err);
}
},
);
router.post(
"/test",
async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
try {
const body: JSONObject = req.body as JSONObject;
if (!body["toPhone"]) {
throw new BadDataException("toPhone is required");
}
const toPhone: Phone = new Phone(body["toPhone"] as string);
const templateKey: WhatsAppTemplateId =
WhatsAppTemplateIds.TestNotification;
const templateLanguageCode: string =
WhatsAppTemplateLanguage[templateKey] || "en";
const message: WhatsAppMessage = {
to: toPhone,
body: "",
templateKey,
templateVariables: undefined,
templateLanguageCode,
};
try {
await WhatsAppService.sendWhatsApp(message, {
projectId: body["projectId"]
? new ObjectID(body["projectId"] as string)
: undefined,
isSensitive: false,
});
} catch (err) {
const errorMsg: string =
err instanceof Error && err.message
? err.message
: "Failed to send test WhatsApp message.";
throw new BadDataException(errorMsg);
}
return Response.sendEmptySuccessResponse(req, res);
} catch (err) {
return next(err);
}
},
);
export default router;

View File

@@ -12,6 +12,8 @@ import Phone from "Common/Types/Phone";
type GetGlobalSMTPConfig = () => Promise<EmailServer | null>;
export const DEFAULT_META_WHATSAPP_API_VERSION: string = "v23.0";
export const getGlobalSMTPConfig: GetGlobalSMTPConfig =
async (): Promise<EmailServer | null> => {
const globalConfig: GlobalConfig | null =
@@ -222,6 +224,83 @@ export const SMSHighRiskCostInCents: number = process.env[
? parseInt(process.env["SMS_HIGH_RISK_COST_IN_CENTS"])
: 0;
export interface MetaWhatsAppConfig {
accessToken: string;
phoneNumberId: string;
businessAccountId?: string | undefined;
appId?: string | undefined;
appSecret?: string | undefined;
apiVersion?: string | undefined;
}
type GetMetaWhatsAppConfigFunction = () => Promise<MetaWhatsAppConfig>;
export const getMetaWhatsAppConfig: GetMetaWhatsAppConfigFunction =
async (): Promise<MetaWhatsAppConfig> => {
const globalConfig: GlobalConfig | null =
await GlobalConfigService.findOneBy({
query: {
_id: ObjectID.getZeroObjectID().toString(),
},
props: {
isRoot: true,
},
select: {
metaWhatsAppAccessToken: true,
metaWhatsAppPhoneNumberId: true,
metaWhatsAppBusinessAccountId: true,
metaWhatsAppAppId: true,
metaWhatsAppAppSecret: true,
},
});
if (!globalConfig) {
throw new BadDataException("Global Config not found");
}
const accessToken: string | undefined =
globalConfig.metaWhatsAppAccessToken?.trim();
const phoneNumberId: string | undefined =
globalConfig.metaWhatsAppPhoneNumberId?.trim();
if (!accessToken) {
throw new BadDataException(
"Meta WhatsApp access token not configured. Please set it in the Admin Dashboard: " +
AdminDashboardClientURL.toString(),
);
}
if (!phoneNumberId) {
throw new BadDataException(
"Meta WhatsApp phone number ID not configured. Please set it in the Admin Dashboard: " +
AdminDashboardClientURL.toString(),
);
}
const businessAccountId: string | undefined =
globalConfig.metaWhatsAppBusinessAccountId?.trim() || undefined;
const appId: string | undefined =
globalConfig.metaWhatsAppAppId?.trim() || undefined;
const appSecret: string | undefined =
globalConfig.metaWhatsAppAppSecret?.trim() || undefined;
const apiVersion: string = DEFAULT_META_WHATSAPP_API_VERSION;
return {
accessToken,
phoneNumberId,
businessAccountId,
appId,
appSecret,
apiVersion,
};
};
export const WhatsAppTextDefaultCostInCents: number = process.env[
"WHATSAPP_TEXT_DEFAULT_COST_IN_CENTS"
]
? parseInt(process.env["WHATSAPP_TEXT_DEFAULT_COST_IN_CENTS"])
: 0;
export const CallHighRiskCostInCentsPerMinute: number = process.env[
"CALL_HIGH_RISK_COST_IN_CENTS_PER_MINUTE"
]

View File

@@ -2,6 +2,8 @@ import CallAPI from "./API/Call";
// API
import MailAPI from "./API/Mail";
import SmsAPI from "./API/SMS";
import WhatsAppAPI from "./API/WhatsApp";
import PushNotificationAPI from "./API/PushNotification";
import SMTPConfigAPI from "./API/SMTPConfig";
import "./Utils/Handlebars";
import FeatureSet from "Common/Server/Types/FeatureSet";
@@ -15,6 +17,8 @@ const NotificationFeatureSet: FeatureSet = {
app.use([`/${APP_NAME}/email`, "/email"], MailAPI);
app.use([`/${APP_NAME}/sms`, "/sms"], SmsAPI);
app.use([`/${APP_NAME}/whatsapp`, "/whatsapp"], WhatsAppAPI);
app.use([`/${APP_NAME}/push`, "/push"], PushNotificationAPI);
app.use([`/${APP_NAME}/call`, "/call"], CallAPI);
app.use([`/${APP_NAME}/smtp-config`, "/smtp-config"], SMTPConfigAPI);
},

View File

@@ -28,6 +28,38 @@ import Twilio from "twilio";
import { CallInstance } from "twilio/lib/rest/api/v2010/account/call";
import Phone from "Common/Types/Phone";
/**
* Extracts the main sayMessage values from a CallRequest's data array for call summary.
* Excludes acknowledgment responses, error messages, and other system messages.
* @param callRequest The call request containing data array with various objects
* @returns A string containing main call content messages separated by newlines
*/
function extractSayMessagesFromCallRequest(callRequest: CallRequest): string {
const sayMessages: string[] = [];
if (callRequest.data && Array.isArray(callRequest.data)) {
for (const item of callRequest.data) {
// Check if the item is a Say object with sayMessage
if ((item as Say).sayMessage) {
sayMessages.push((item as Say).sayMessage);
}
// Check if the item is a GatherInput with introMessage
if ((item as GatherInput).introMessage) {
sayMessages.push((item as GatherInput).introMessage);
}
/*
* NOTE: Excluding noInputMessage and onInputCallRequest messages from summary
* as they contain system responses like "Good bye", "Invalid input", "You have acknowledged"
* which should not be included in the call summary according to user requirements
*/
}
}
return sayMessages.length > 0
? sayMessages.join(" ")
: "No message content found";
}
export default class CallService {
public static async makeCall(
callRequest: CallRequest,
@@ -36,6 +68,18 @@ export default class CallService {
isSensitive?: boolean; // if true, message will not be logged
userOnCallLogTimelineId?: ObjectID | undefined; // user notification log timeline id
customTwilioConfig?: TwilioConfig | undefined;
incidentId?: ObjectID | undefined;
alertId?: ObjectID | undefined;
scheduledMaintenanceId?: ObjectID | undefined;
statusPageId?: ObjectID | undefined;
statusPageAnnouncementId?: ObjectID | undefined;
userId?: ObjectID | undefined;
// On-call policy related fields
onCallPolicyId?: ObjectID | undefined;
onCallPolicyEscalationRuleId?: ObjectID | undefined;
onCallDutyPolicyExecutionLogTimelineId?: ObjectID | undefined;
onCallScheduleId?: ObjectID | undefined;
teamId?: ObjectID | undefined;
},
): Promise<void> {
let callError: Error | null = null;
@@ -82,14 +126,58 @@ export default class CallService {
callLog.fromNumber = fromNumber;
callLog.callData =
options && options.isSensitive
? { message: "This call is sensitive and is not logged" }
: JSON.parse(JSON.stringify(callRequest));
? ({ message: "This call is sensitive and is not logged" } as any)
: ({
message: extractSayMessagesFromCallRequest(callRequest),
} as any);
callLog.callCostInUSDCents = 0;
if (options.projectId) {
callLog.projectId = options.projectId;
}
if (options.incidentId) {
callLog.incidentId = options.incidentId;
}
if (options.alertId) {
callLog.alertId = options.alertId;
}
if (options.scheduledMaintenanceId) {
callLog.scheduledMaintenanceId = options.scheduledMaintenanceId;
}
if (options.statusPageId) {
callLog.statusPageId = options.statusPageId;
}
if (options.statusPageAnnouncementId) {
callLog.statusPageAnnouncementId = options.statusPageAnnouncementId;
}
if (options.userId) {
callLog.userId = options.userId;
}
if (options.teamId) {
callLog.teamId = options.teamId;
}
// Set OnCall-related fields
if (options.onCallPolicyId) {
callLog.onCallDutyPolicyId = options.onCallPolicyId;
}
if (options.onCallPolicyEscalationRuleId) {
callLog.onCallDutyPolicyEscalationRuleId =
options.onCallPolicyEscalationRuleId;
}
if (options.onCallScheduleId) {
callLog.onCallDutyPolicyScheduleId = options.onCallScheduleId;
}
let project: Project | null = null;
// make sure project has enough balance.

View File

@@ -37,11 +37,49 @@ class TransporterPool {
private static semaphore: Map<string, number> = new Map();
private static readonly MAX_CONCURRENT_CONNECTIONS = 100;
private static resolveConnectionSettings(emailServer: EmailServer): {
portNumber: number;
wantsSecureConnection: boolean;
secureConnection: boolean;
requireTLS: boolean;
mode: "implicit-tls" | "starttls" | "plain";
} {
const portNumber: number = emailServer.port.toNumber();
const wantsSecureConnection: boolean = emailServer.secure;
const isImplicitTLSPort: boolean = portNumber === 465;
const secureConnection: boolean = isImplicitTLSPort;
const requireTLS: boolean = wantsSecureConnection && !isImplicitTLSPort;
let mode: "implicit-tls" | "starttls" | "plain" = "plain";
if (secureConnection) {
mode = "implicit-tls";
} else if (requireTLS) {
mode = "starttls";
}
return {
portNumber,
wantsSecureConnection,
secureConnection,
requireTLS,
mode,
};
}
private static getPoolKey(emailServer: EmailServer): string {
const { portNumber, mode } = this.resolveConnectionSettings(emailServer);
const username: string = emailServer.username || "noauth";
return `${emailServer.host.toString()}:${portNumber}:${username}:${mode}`;
}
public static getTransporter(
emailServer: EmailServer,
options: { timeout?: number | undefined },
): Transporter {
const key: string = `${emailServer.host.toString()}:${emailServer.port.toNumber()}:${emailServer.username || "noauth"}`;
const key: string = this.getPoolKey(emailServer);
if (!this.pools.has(key)) {
const transporter: Transporter = this.createTransporter(
@@ -59,9 +97,12 @@ class TransporterPool {
emailServer: EmailServer,
options: { timeout?: number | undefined },
): Transporter {
const { portNumber, wantsSecureConnection, secureConnection, requireTLS } =
this.resolveConnectionSettings(emailServer);
let tlsOptions: tls.ConnectionOptions | undefined = undefined;
if (!emailServer.secure) {
if (!wantsSecureConnection) {
tlsOptions = {
rejectUnauthorized: false,
};
@@ -69,8 +110,9 @@ class TransporterPool {
return nodemailer.createTransport({
host: emailServer.host.toString(),
port: emailServer.port.toNumber(),
secure: emailServer.secure,
port: portNumber,
secure: secureConnection,
requireTLS,
tls: tlsOptions,
auth:
emailServer.username && emailServer.password
@@ -88,7 +130,7 @@ class TransporterPool {
public static async acquireConnection(
emailServer: EmailServer,
): Promise<void> {
const key: string = `${emailServer.host.toString()}:${emailServer.port.toNumber()}:${emailServer.username || "noauth"}`;
const key: string = this.getPoolKey(emailServer);
while ((this.semaphore.get(key) || 0) >= this.MAX_CONCURRENT_CONNECTIONS) {
await new Promise<void>((resolve: () => void) => {
@@ -100,7 +142,7 @@ class TransporterPool {
}
public static releaseConnection(emailServer: EmailServer): void {
const key: string = `${emailServer.host.toString()}:${emailServer.port.toNumber()}:${emailServer.username || "noauth"}`;
const key: string = this.getPoolKey(emailServer);
const current: number = this.semaphore.get(key) || 0;
this.semaphore.set(key, Math.max(0, current - 1));
}
@@ -345,6 +387,18 @@ export default class MailService {
emailServer?: EmailServer | undefined;
userOnCallLogTimelineId?: ObjectID | undefined;
timeout?: number | undefined;
incidentId?: ObjectID | undefined;
alertId?: ObjectID | undefined;
scheduledMaintenanceId?: ObjectID | undefined;
statusPageId?: ObjectID | undefined;
statusPageAnnouncementId?: ObjectID | undefined;
userId?: ObjectID | undefined;
// On-call policy related fields
onCallPolicyId?: ObjectID | undefined;
onCallPolicyEscalationRuleId?: ObjectID | undefined;
onCallDutyPolicyExecutionLogTimelineId?: ObjectID | undefined;
onCallScheduleId?: ObjectID | undefined;
teamId?: ObjectID | undefined;
}
| undefined,
): Promise<void> {
@@ -359,6 +413,48 @@ export default class MailService {
if (options.emailServer?.id) {
emailLog.projectSmtpConfigId = options.emailServer?.id;
}
if (options.incidentId) {
emailLog.incidentId = options.incidentId;
}
if (options.alertId) {
emailLog.alertId = options.alertId;
}
if (options.scheduledMaintenanceId) {
emailLog.scheduledMaintenanceId = options.scheduledMaintenanceId;
}
if (options.statusPageId) {
emailLog.statusPageId = options.statusPageId;
}
if (options.statusPageAnnouncementId) {
emailLog.statusPageAnnouncementId = options.statusPageAnnouncementId;
}
if (options.userId) {
emailLog.userId = options.userId;
}
if (options.teamId) {
emailLog.teamId = options.teamId;
}
// Set OnCall-related fields
if (options.onCallPolicyId) {
emailLog.onCallDutyPolicyId = options.onCallPolicyId;
}
if (options.onCallPolicyEscalationRuleId) {
emailLog.onCallDutyPolicyEscalationRuleId =
options.onCallPolicyEscalationRuleId;
}
if (options.onCallScheduleId) {
emailLog.onCallDutyPolicyScheduleId = options.onCallScheduleId;
}
}
// default vars.

View File

@@ -0,0 +1,44 @@
import PushNotificationRequest from "Common/Types/PushNotification/PushNotificationRequest";
import ObjectID from "Common/Types/ObjectID";
import PushNotificationServiceCommon from "Common/Server/Services/PushNotificationService";
export default class PushNotificationService {
public static async send(
request: PushNotificationRequest,
options: {
projectId?: ObjectID | undefined;
isSensitive?: boolean;
userOnCallLogTimelineId?: ObjectID | undefined;
incidentId?: ObjectID | undefined;
alertId?: ObjectID | undefined;
scheduledMaintenanceId?: ObjectID | undefined;
statusPageId?: ObjectID | undefined;
statusPageAnnouncementId?: ObjectID | undefined;
userId?: ObjectID | undefined;
onCallPolicyId?: ObjectID | undefined;
onCallPolicyEscalationRuleId?: ObjectID | undefined;
onCallDutyPolicyExecutionLogTimelineId?: ObjectID | undefined;
onCallScheduleId?: ObjectID | undefined;
teamId?: ObjectID | undefined;
} = {},
): Promise<void> {
// Delegate to Common service which now handles logging and timeline updates
await PushNotificationServiceCommon.sendPushNotification(request, {
projectId: options.projectId,
isSensitive: Boolean(options.isSensitive),
userOnCallLogTimelineId: options.userOnCallLogTimelineId,
incidentId: options.incidentId,
alertId: options.alertId,
scheduledMaintenanceId: options.scheduledMaintenanceId,
statusPageId: options.statusPageId,
statusPageAnnouncementId: options.statusPageAnnouncementId,
userId: options.userId,
onCallPolicyId: options.onCallPolicyId,
onCallPolicyEscalationRuleId: options.onCallPolicyEscalationRuleId,
onCallDutyPolicyExecutionLogTimelineId:
options.onCallDutyPolicyExecutionLogTimelineId,
onCallScheduleId: options.onCallScheduleId,
teamId: options.teamId,
});
}
}

View File

@@ -31,6 +31,18 @@ export default class SmsService {
customTwilioConfig?: TwilioConfig | undefined;
isSensitive?: boolean; // if true, message will not be logged
userOnCallLogTimelineId?: ObjectID | undefined;
incidentId?: ObjectID | undefined;
alertId?: ObjectID | undefined;
scheduledMaintenanceId?: ObjectID | undefined;
statusPageId?: ObjectID | undefined;
statusPageAnnouncementId?: ObjectID | undefined;
userId?: ObjectID | undefined;
// On-call policy related fields
onCallPolicyId?: ObjectID | undefined;
onCallPolicyEscalationRuleId?: ObjectID | undefined;
onCallDutyPolicyExecutionLogTimelineId?: ObjectID | undefined;
onCallScheduleId?: ObjectID | undefined;
teamId?: ObjectID | undefined;
},
): Promise<void> {
let smsError: Error | null = null;
@@ -71,6 +83,48 @@ export default class SmsService {
smsLog.projectId = options.projectId;
}
if (options.incidentId) {
smsLog.incidentId = options.incidentId;
}
if (options.alertId) {
smsLog.alertId = options.alertId;
}
if (options.scheduledMaintenanceId) {
smsLog.scheduledMaintenanceId = options.scheduledMaintenanceId;
}
if (options.statusPageId) {
smsLog.statusPageId = options.statusPageId;
}
if (options.statusPageAnnouncementId) {
smsLog.statusPageAnnouncementId = options.statusPageAnnouncementId;
}
if (options.userId) {
smsLog.userId = options.userId;
}
if (options.teamId) {
smsLog.teamId = options.teamId;
}
// Set OnCall-related fields
if (options.onCallPolicyId) {
smsLog.onCallDutyPolicyId = options.onCallPolicyId;
}
if (options.onCallPolicyEscalationRuleId) {
smsLog.onCallDutyPolicyEscalationRuleId =
options.onCallPolicyEscalationRuleId;
}
if (options.onCallScheduleId) {
smsLog.onCallDutyPolicyScheduleId = options.onCallScheduleId;
}
const twilioConfig: TwilioConfig | null =
options.customTwilioConfig || (await getTwilioConfig());

View File

@@ -0,0 +1,497 @@
import {
WhatsAppTextDefaultCostInCents,
getMetaWhatsAppConfig,
MetaWhatsAppConfig,
DEFAULT_META_WHATSAPP_API_VERSION,
} from "../Config";
import BadDataException from "Common/Types/Exception/BadDataException";
import ObjectID from "Common/Types/ObjectID";
import UserNotificationStatus from "Common/Types/UserNotification/UserNotificationStatus";
import WhatsAppMessage from "Common/Types/WhatsApp/WhatsAppMessage";
import WhatsAppStatus from "Common/Types/WhatsAppStatus";
import {
AuthenticationTemplates,
WhatsAppTemplateId,
} from "Common/Types/WhatsApp/WhatsAppTemplates";
import { JSONArray, JSONObject } from "Common/Types/JSON";
import { IsBillingEnabled } from "Common/Server/EnvironmentConfig";
import NotificationService from "Common/Server/Services/NotificationService";
import ProjectService from "Common/Server/Services/ProjectService";
import UserOnCallLogTimelineService from "Common/Server/Services/UserOnCallLogTimelineService";
import WhatsAppLogService from "Common/Server/Services/WhatsAppLogService";
import logger from "Common/Server/Utils/Logger";
import Project from "Common/Models/DatabaseModels/Project";
import WhatsAppLog from "Common/Models/DatabaseModels/WhatsAppLog";
import API from "Common/Utils/API";
import HTTPErrorResponse from "Common/Types/API/HTTPErrorResponse";
import HTTPResponse from "Common/Types/API/HTTPResponse";
import Protocol from "Common/Types/API/Protocol";
import Route from "Common/Types/API/Route";
import URL from "Common/Types/API/URL";
const SENSITIVE_MESSAGE_PLACEHOLDER: string =
"This message is sensitive and is not logged";
export default class WhatsAppService {
public static async sendWhatsApp(
message: WhatsAppMessage,
options: {
projectId?: ObjectID | undefined;
isSensitive?: boolean | undefined;
userOnCallLogTimelineId?: ObjectID | undefined;
incidentId?: ObjectID | undefined;
alertId?: ObjectID | undefined;
scheduledMaintenanceId?: ObjectID | undefined;
statusPageId?: ObjectID | undefined;
statusPageAnnouncementId?: ObjectID | undefined;
userId?: ObjectID | undefined;
onCallPolicyId?: ObjectID | undefined;
onCallPolicyEscalationRuleId?: ObjectID | undefined;
onCallDutyPolicyExecutionLogTimelineId?: ObjectID | undefined;
onCallScheduleId?: ObjectID | undefined;
teamId?: ObjectID | undefined;
} = {},
): Promise<void> {
let sendError: Error | null = null;
const whatsAppLog: WhatsAppLog = new WhatsAppLog();
try {
if (!message.to) {
throw new BadDataException(
"WhatsApp recipient phone number is required",
);
}
if (!message.body && !message.templateKey) {
throw new BadDataException(
"Either WhatsApp message body or template key must be provided",
);
}
const isSensitiveMessage: boolean = Boolean(options.isSensitive);
const messageSummary: string = isSensitiveMessage
? SENSITIVE_MESSAGE_PLACEHOLDER
: message.body ||
(message.templateKey
? `Template: ${message.templateKey}${
message.templateVariables
? " Variables: " + JSON.stringify(message.templateVariables)
: ""
}`
: "");
whatsAppLog.toNumber = message.to;
whatsAppLog.messageText = messageSummary;
whatsAppLog.whatsAppCostInUSDCents = 0;
if (options.projectId) {
whatsAppLog.projectId = options.projectId;
}
if (options.incidentId) {
whatsAppLog.incidentId = options.incidentId;
}
if (options.alertId) {
whatsAppLog.alertId = options.alertId;
}
if (options.scheduledMaintenanceId) {
whatsAppLog.scheduledMaintenanceId = options.scheduledMaintenanceId;
}
if (options.statusPageId) {
whatsAppLog.statusPageId = options.statusPageId;
}
if (options.statusPageAnnouncementId) {
whatsAppLog.statusPageAnnouncementId = options.statusPageAnnouncementId;
}
if (options.userId) {
whatsAppLog.userId = options.userId;
}
if (options.teamId) {
whatsAppLog.teamId = options.teamId;
}
if (options.onCallPolicyId) {
whatsAppLog.onCallDutyPolicyId = options.onCallPolicyId;
}
if (options.onCallPolicyEscalationRuleId) {
whatsAppLog.onCallDutyPolicyEscalationRuleId =
options.onCallPolicyEscalationRuleId;
}
if (options.onCallScheduleId) {
whatsAppLog.onCallDutyPolicyScheduleId = options.onCallScheduleId;
}
const config: MetaWhatsAppConfig = await getMetaWhatsAppConfig();
let messageCost: number = 0;
const shouldChargeForMessage: boolean = IsBillingEnabled;
if (shouldChargeForMessage) {
messageCost = WhatsAppTextDefaultCostInCents / 100;
}
let project: Project | null = null;
if (options.projectId) {
project = await ProjectService.findOneById({
id: options.projectId,
select: {
smsOrCallCurrentBalanceInUSDCents: true,
lowCallAndSMSBalanceNotificationSentToOwners: true,
name: true,
notEnabledSmsOrCallNotificationSentToOwners: true,
},
props: {
isRoot: true,
},
});
if (!project) {
whatsAppLog.status = WhatsAppStatus.Error;
whatsAppLog.statusMessage = `Project ${options.projectId.toString()} not found.`;
logger.error(whatsAppLog.statusMessage);
await WhatsAppLogService.create({
data: whatsAppLog,
props: {
isRoot: true,
},
});
return;
}
if (shouldChargeForMessage) {
let updatedBalance: number =
project.smsOrCallCurrentBalanceInUSDCents || 0;
try {
updatedBalance = await NotificationService.rechargeIfBalanceIsLow(
project.id!,
);
} catch (err) {
logger.error(err);
}
project.smsOrCallCurrentBalanceInUSDCents = updatedBalance;
if (!project.smsOrCallCurrentBalanceInUSDCents) {
whatsAppLog.status = WhatsAppStatus.LowBalance;
whatsAppLog.statusMessage = `Project ${options.projectId.toString()} does not have enough balance for WhatsApp messages.`;
logger.error(whatsAppLog.statusMessage);
await WhatsAppLogService.create({
data: whatsAppLog,
props: {
isRoot: true,
},
});
if (!project.lowCallAndSMSBalanceNotificationSentToOwners) {
await ProjectService.updateOneById({
id: project.id!,
data: {
lowCallAndSMSBalanceNotificationSentToOwners: true,
},
props: {
isRoot: true,
},
});
await ProjectService.sendEmailToProjectOwners(
project.id!,
`Low WhatsApp message balance for ${project.name || ""}`,
`We tried to send a WhatsApp message to ${message.to.toString()} with message:<br/><br/>${messageSummary}<br/><br/>The message was not sent because your project does not have enough balance for WhatsApp messages. Current balance is ${
(project.smsOrCallCurrentBalanceInUSDCents || 0) / 100
} USD. Required balance for this message is ${messageCost} USD. Please enable auto recharge or recharge manually.`,
);
}
return;
}
if (project.smsOrCallCurrentBalanceInUSDCents < messageCost * 100) {
whatsAppLog.status = WhatsAppStatus.LowBalance;
whatsAppLog.statusMessage = `Project does not have enough balance to send WhatsApp message. Current balance is ${
project.smsOrCallCurrentBalanceInUSDCents / 100
} USD. Required balance is ${messageCost} USD.`;
logger.error(whatsAppLog.statusMessage);
await WhatsAppLogService.create({
data: whatsAppLog,
props: {
isRoot: true,
},
});
if (!project.lowCallAndSMSBalanceNotificationSentToOwners) {
await ProjectService.updateOneById({
id: project.id!,
data: {
lowCallAndSMSBalanceNotificationSentToOwners: true,
},
props: {
isRoot: true,
},
});
await ProjectService.sendEmailToProjectOwners(
project.id!,
`Low WhatsApp message balance for ${project.name || ""}`,
`We tried to send a WhatsApp message to ${message.to.toString()} with message:<br/><br/>${messageSummary}<br/><br/>The message was not sent because your project does not have enough balance for WhatsApp messages. Current balance is ${
project.smsOrCallCurrentBalanceInUSDCents / 100
} USD. Required balance is ${messageCost} USD. Please enable auto recharge or recharge manually.`,
);
}
return;
}
}
}
const payload: JSONObject = {
messaging_product: "whatsapp",
recipient_type: "individual",
to: message.to.toString(),
} as JSONObject;
if (!message.templateKey) {
throw new BadDataException("WhatsApp message template key is required");
}
if (message.templateKey) {
const template: JSONObject = {
name: message.templateKey,
language: {
code: message.templateLanguageCode || "en",
},
} as JSONObject;
const components: JSONArray = [];
if (
message.templateVariables &&
Object.keys(message.templateVariables).length > 0
) {
const parameters: JSONArray = [];
for (const [key, value] of Object.entries(
message.templateVariables,
)) {
parameters.push({
type: "text",
parameter_name: key,
text: value,
} as JSONObject);
}
if (parameters.length > 0) {
components.push({
type: "body",
parameters,
} as JSONObject);
}
}
/*
* Check if this is an authentication template
* Authentication templates may have special requirements including button components
*/
const isAuthTemplate: boolean = AuthenticationTemplates.has(
message.templateKey as WhatsAppTemplateId,
);
if (isAuthTemplate) {
logger.info(
`Sending authentication template: ${message.templateKey}`,
);
/*
* Authentication templates in WhatsApp may have a button component for "Copy Code"
* If the template was created with a button, we need to provide button parameters
*/
if (message.templateVariables) {
const otpCode: string | undefined =
message.templateVariables["1"] ||
message.templateVariables["otp"] ||
message.templateVariables["code"];
if (otpCode) {
/*
* Add button component - the index should match the button position in the template
* Usually authentication templates have the button as the first (and only) button
*/
components.push({
type: "button",
sub_type: "url",
index: 0,
parameters: [
{
type: "text",
text: otpCode,
},
],
} as JSONObject);
}
}
}
if (components.length > 0) {
template["components"] = components;
}
payload["type"] = "template";
payload["template"] = template;
} else {
payload["type"] = "text";
payload["text"] = {
body: message.body || "",
} as JSONObject;
}
const apiVersion: string =
config.apiVersion?.trim() || DEFAULT_META_WHATSAPP_API_VERSION;
const url: URL = new URL(
Protocol.HTTPS,
"graph.facebook.com",
new Route(`${apiVersion}/${config.phoneNumberId}/messages`),
);
logger.debug(`WhatsApp API request: ${JSON.stringify(payload)}`);
const response: HTTPResponse<JSONObject> | HTTPErrorResponse =
await API.post<JSONObject>({
url,
data: payload,
headers: {
Authorization: `Bearer ${config.accessToken}`,
"Content-Type": "application/json",
},
});
if (response instanceof HTTPErrorResponse) {
logger.error("Failed to send WhatsApp message.");
logger.error(response);
const responseDataAsJSONObject: JSONObject = response.data;
const responseJsonAsJSONObject: JSONObject | undefined =
(response.jsonData as JSONObject | undefined) || undefined;
// Log full error details for debugging
const errorObject: JSONObject | undefined =
(responseDataAsJSONObject["error"] as JSONObject | undefined) ||
(responseJsonAsJSONObject?.["error"] as JSONObject | undefined);
if (errorObject) {
logger.error("WhatsApp API Error Details:");
logger.error(JSON.stringify(errorObject, null, 2));
}
const detailedErrorMessage: string | undefined =
((responseDataAsJSONObject["error"] as JSONObject | undefined)?.[
"message"
] as string | undefined) ||
((responseJsonAsJSONObject?.["error"] as JSONObject | undefined)?.[
"message"
] as string | undefined);
throw new BadDataException(
detailedErrorMessage || "Failed to send WhatsApp message.",
);
}
const responseData: JSONObject = (response.jsonData || {}) as JSONObject;
let messageId: string | undefined = undefined;
const messagesArray: JSONArray | undefined =
(responseData["messages"] as JSONArray) || undefined;
if (Array.isArray(messagesArray) && messagesArray.length > 0) {
const firstMessage: JSONObject = messagesArray[0] as JSONObject;
if (firstMessage["id"]) {
messageId = firstMessage["id"] as string;
}
}
if (messageId) {
whatsAppLog.whatsAppMessageId = messageId;
}
whatsAppLog.status = WhatsAppStatus.Sent;
whatsAppLog.statusMessage = messageId
? `Message ID: ${messageId}`
: "WhatsApp message sent successfully";
if (shouldChargeForMessage && project) {
const deduction: number = Math.floor(messageCost * 100);
whatsAppLog.whatsAppCostInUSDCents = deduction;
project.smsOrCallCurrentBalanceInUSDCents = Math.max(
0,
Math.floor(
(project.smsOrCallCurrentBalanceInUSDCents || 0) - deduction,
),
);
await ProjectService.updateOneById({
id: project.id!,
data: {
smsOrCallCurrentBalanceInUSDCents:
project.smsOrCallCurrentBalanceInUSDCents,
notEnabledSmsOrCallNotificationSentToOwners: false,
},
props: {
isRoot: true,
},
});
}
} catch (error: any) {
logger.error("Failed to send WhatsApp message.");
logger.error(error);
whatsAppLog.whatsAppCostInUSDCents = 0;
whatsAppLog.status = WhatsAppStatus.Error;
const errorMessage: string =
error && error.message ? error.message.toString() : `${error}`;
whatsAppLog.statusMessage = errorMessage;
sendError = error;
}
if (options.projectId) {
await WhatsAppLogService.create({
data: whatsAppLog,
props: {
isRoot: true,
},
});
}
if (options.userOnCallLogTimelineId) {
await UserOnCallLogTimelineService.updateOneById({
id: options.userOnCallLogTimelineId,
data: {
status: [
WhatsAppStatus.Success,
WhatsAppStatus.Sent,
WhatsAppStatus.Delivered,
WhatsAppStatus.Read,
].includes(whatsAppLog.status || WhatsAppStatus.Error)
? UserNotificationStatus.Sent
: UserNotificationStatus.Error,
statusMessage: whatsAppLog.statusMessage,
},
props: {
isRoot: true,
},
});
}
if (sendError) {
throw sendError;
}
}
}

View File

@@ -13,10 +13,8 @@
{{> DetailBoxField title="Current State: " text=currentState }}
{{> DetailBoxField title="Resources Affected: " text=resourcesAffected }}
{{> DetailBoxField title="Severity: " text=alertSeverity }}
{{> DetailBoxField title="Root Cause: " text="" }}
{{> DetailBoxField title="" text=rootCause }}
{{> DetailBoxField title="Description: " text="" }}
{{> DetailBoxField title="" text=alertDescription }}
{{> DetailBoxField title="Root Cause: " text=rootCause }}
{{> DetailBoxField title="Description: " text=alertDescription }}
{{> DetailBoxEnd this }}

View File

@@ -13,10 +13,8 @@
{{> DetailBoxField title="Current State: " text=currentState }}
{{> DetailBoxField title="Resources Affected: " text=resourcesAffected }}
{{> DetailBoxField title="Severity: " text=incidentSeverity }}
{{> DetailBoxField title="Root Cause: " text="" }}
{{> DetailBoxField title="" text=rootCause }}
{{> DetailBoxField title="Description: " text="" }}
{{> DetailBoxField title="" text=incidentDescription }}
{{> DetailBoxField title="Root Cause: " text=rootCause }}
{{> DetailBoxField title="Description: " text=incidentDescription }}
{{> DetailBoxEnd this }}

View File

@@ -13,8 +13,7 @@
{{> DetailBoxField title="Current State: " text=currentState }}
{{> DetailBoxField title="Resources Affected: " text=resourcesAffected }}
{{> DetailBoxField title="Severity: " text=alertSeverity }}
{{> DetailBoxField title="Description: " text="" }}
{{> DetailBoxField title="" text=alertDescription }}
{{> DetailBoxField title="Description: " text=alertDescription }}
{{> DetailBoxEnd this }}

View File

@@ -14,11 +14,10 @@
{{> DetailBoxField title="Resources Affected: " text=resourcesAffected }}
{{> DetailBoxField title="Severity: " text=alertSeverity }}
{{#if isPrivateNote}}
{{> DetailBoxField title="Private Note: " text="" }}
{{> DetailBoxField title="Private Note: " text=note }}
{{else}}
{{> DetailBoxField title="Public Note: " text="" }}
{{> DetailBoxField title="Public Note: " text=note }}
{{/if}}
{{> DetailBoxField title="" text=note }}
{{> DetailBoxEnd this }}

View File

@@ -13,16 +13,12 @@
{{> DetailBoxField title="Current State: " text=currentState }}
{{> DetailBoxField title="Resources Affected: " text=resourcesAffected }}
{{> DetailBoxField title="Alert Declared By: " text=declaredBy }}
{{> DetailBoxField title="Alert Declared At: " text="" }}
{{> DetailBoxField title="" text=declaredAt }}
{{> DetailBoxField title="Alert Declared At: " text=declaredAt }}
{{> DetailBoxField title="Severity: " text=alertSeverity }}
{{> DetailBoxField title="Root Cause: " text="" }}
{{> DetailBoxField title="" text=rootCause }}
{{> DetailBoxField title="Description: " text="" }}
{{> DetailBoxField title="" text=alertDescription }}
{{> DetailBoxField title="Root Cause: " text=rootCause }}
{{> DetailBoxField title="Description: " text=alertDescription }}
{{#ifNotCond remediationNotes ""}}
{{> DetailBoxField title="Remediation Notes: " text="" }}
{{> DetailBoxField title="" text=remediationNotes }}
{{> DetailBoxField title="Remediation Notes: " text=remediationNotes }}
{{/ifNotCond}}
{{> DetailBoxEnd this }}

View File

@@ -4,19 +4,17 @@
{{> Logo this}}
{{> EmailTitle title=(concat "Alert: " alertTitle) }}
{{> InfoBlock info=(concat "Alert state changed to - " currentState)}}
{{> InfoBlock info="Alert state has changed"}}
{{> InfoBlock info="Here are the details: "}}
{{> DetailBoxStart this }}
{{> StateTransition this}}
{{> DetailBoxField title="Alert Title:" text=alertTitle }}
{{> DetailBoxField title="New State: " text=currentState }}
{{> DetailBoxField title="State changed at: " text="" }}
{{> DetailBoxField title="" text=stateChangedAt }}
{{> DetailBoxField title="Resources Affected: " text=resourcesAffected }}
{{> DetailBoxField title="Severity: " text=alertSeverity }}
{{> DetailBoxField title="Description: " text="" }}
{{> DetailBoxField title="" text=alertDescription }}
{{> DetailBoxField title="State changed at:" text=stateChangedAt }}
{{> DetailBoxField title="Resources Affected:" text=resourcesAffected }}
{{> DetailBoxField title="Severity:" text=alertSeverity }}
{{> DetailBoxField title="Description:" text=alertDescription }}
{{> DetailBoxEnd this }}

View File

@@ -2,15 +2,20 @@
{{> Logo this}}
{{> EmailTitle title="Forgot Password? We're here to help." }}
{{> EmailTitle title="Reset Your Password" }}
{{> InfoBlock info="Please click on the 'Reset your password' button below which will help you reset your password and once you're done, You're good to go!"}}
{{> InfoBlock info="We received a request to reset your password. Click the button below to create a new password for your account."}}
{{> ButtonBlock buttonUrl=tokenVerifyUrl buttonText="Reset your password"}}
{{> ButtonBlock buttonUrl=tokenVerifyUrl buttonText="Reset Password"}}
{{> InfoBlock info="You can also copy and paste this link:"}}
{{> VerticalSpace this}}
{{> InfoBlock info="Or copy and paste this link into your browser:"}}
{{> InfoBlock info=tokenVerifyUrl}}
{{> InfoBlock info="This password reset link expires in 24 hours."}}
{{> VerticalSpace this}}
{{> InfoBlock info="<strong>Note:</strong> This password reset link will expire in 24 hours. If you didn't request this reset, you can safely ignore this email."}}
{{> SupportBlock this }}

View File

@@ -13,8 +13,7 @@
{{> DetailBoxField title="Current State: " text=currentState }}
{{> DetailBoxField title="Resources Affected: " text=resourcesAffected }}
{{> DetailBoxField title="Severity: " text=incidentSeverity }}
{{> DetailBoxField title="Description: " text="" }}
{{> DetailBoxField title="" text=incidentDescription }}
{{> DetailBoxField title="Description: " text=incidentDescription }}
{{> DetailBoxEnd this }}

View File

@@ -14,11 +14,10 @@
{{> DetailBoxField title="Resources Affected: " text=resourcesAffected }}
{{> DetailBoxField title="Severity: " text=incidentSeverity }}
{{#if isPrivateNote}}
{{> DetailBoxField title="Private Note: " text="" }}
{{> DetailBoxField title="Private Note: " text=note }}
{{else}}
{{> DetailBoxField title="Public Note: " text="" }}
{{> DetailBoxField title="Public Note: " text=note }}
{{/if}}
{{> DetailBoxField title="" text=note }}
{{> DetailBoxEnd this }}

View File

@@ -13,16 +13,12 @@
{{> DetailBoxField title="Current State: " text=currentState }}
{{> DetailBoxField title="Resources Affected: " text=resourcesAffected }}
{{> DetailBoxField title="Incident Declared By: " text=declaredBy }}
{{> DetailBoxField title="Incident Declared At: " text="" }}
{{> DetailBoxField title="" text=declaredAt }}
{{> DetailBoxField title="Incident Declared At: " text=declaredAt }}
{{> DetailBoxField title="Severity: " text=incidentSeverity }}
{{> DetailBoxField title="Root Cause: " text="" }}
{{> DetailBoxField title="" text=rootCause }}
{{> DetailBoxField title="Description: " text="" }}
{{> DetailBoxField title="" text=incidentDescription }}
{{> DetailBoxField title="Root Cause: " text=rootCause }}
{{> DetailBoxField title="Description: " text=incidentDescription }}
{{#ifNotCond remediationNotes ""}}
{{> DetailBoxField title="Remediation Notes: " text="" }}
{{> DetailBoxField title="" text=remediationNotes }}
{{> DetailBoxField title="Remediation Notes: " text=remediationNotes }}
{{/ifNotCond}}
{{> DetailBoxEnd this }}

View File

@@ -4,19 +4,17 @@
{{> Logo this}}
{{> EmailTitle title=(concat "Incident: " incidentTitle) }}
{{> InfoBlock info=(concat "Incident state changed to - " currentState)}}
{{> InfoBlock info="Incident state has changed"}}
{{> InfoBlock info="Here are the details: "}}
{{> DetailBoxStart this }}
{{> StateTransition this}}
{{> DetailBoxField title="Incident Title:" text=incidentTitle }}
{{> DetailBoxField title="New State: " text=currentState }}
{{> DetailBoxField title="State changed at: " text="" }}
{{> DetailBoxField title="" text=stateChangedAt }}
{{> DetailBoxField title="Resources Affected: " text=resourcesAffected }}
{{> DetailBoxField title="Severity: " text=incidentSeverity }}
{{> DetailBoxField title="Description: " text="" }}
{{> DetailBoxField title="" text=incidentDescription }}
{{> DetailBoxField title="State changed at:" text=stateChangedAt }}
{{> DetailBoxField title="Resources Affected:" text=resourcesAffected }}
{{> DetailBoxField title="Severity:" text=incidentSeverity }}
{{> DetailBoxField title="Description:" text=incidentDescription }}
{{> DetailBoxEnd this }}

View File

@@ -2,28 +2,33 @@
{{> Logo this}}
{{> EmailTitle title=(concat "You have been invited to " projectName) }}
{{> EmailTitle title=(concat "👋 You're Invited to " projectName) }}
{{#ifCond isNewUser "true"}}
{{> InfoBlock info="Please sign up to a new account to accept this invitation"}}
{{> InfoBlock info="You've been invited to join a project on OneUptime. Create your account to get started."}}
{{> ButtonBlock buttonUrl=registerLink buttonText="Sign up to a new account"}}
{{> ButtonBlock buttonUrl=registerLink buttonText="Create Your Account"}}
{{> InfoBlock info="You can also copy and paste this link:"}}
{{> VerticalSpace this}}
{{> InfoBlock info="Or copy and paste this link into your browser:"}}
{{> InfoBlock info=registerLink}}
{{/ifCond}}
{{#ifCond isNewUser "false"}}
{{> InfoBlock info="Please sign in to your account to see all your invitations and manage them."}}
{{> InfoBlock info="You've been invited to join a project on OneUptime. Sign in to view and manage your invitations."}}
{{> ButtonBlock buttonUrl=signInLink buttonText="Sign in to OneUptime"}}
{{> ButtonBlock buttonUrl=signInLink buttonText="Sign In to OneUptime"}}
{{> InfoBlock info="You can also copy and paste this link:"}}
{{> VerticalSpace this}}
{{> InfoBlock info="Or copy and paste this link into your browser:"}}
{{> InfoBlock info=signInLink}}
{{/ifCond}}
{{> VerticalSpace this}}
{{> InfoBlock info="If you have not signed up to OneUptime so far. You'll be redirected to the account sign up page to sign up first."}}
{{> InfoBlock info="<em>If you don't have an account yet, you'll be redirected to create one first.</em>"}}
{{> SupportBlock this }}

View File

@@ -10,9 +10,15 @@
{{> DetailBoxStart this }}
{{> DetailBoxField title="Monitor Name:" text=monitorName }}
{{#ifNotCond monitorDestination ""}}
{{#ifCond monitorType "API"}}
{{> DetailBoxField title="Monitor URL:" text=(concat requestType " " monitorDestination) }}
{{else}}
{{> DetailBoxField title="Monitor Destination:" text=monitorDestination }}
{{/ifCond}}
{{/ifNotCond}}
{{> DetailBoxField title="Current Status: " text=currentStatus }}
{{> DetailBoxField title="Description: " text="" }}
{{> DetailBoxField title="" text=monitorDescription }}
{{> DetailBoxField title="Description: " text=monitorDescription }}
{{> DetailBoxEnd this }}

View File

@@ -10,9 +10,15 @@
{{> DetailBoxStart this }}
{{> DetailBoxField title="Monitor Name:" text=monitorName }}
{{#ifNotCond monitorDestination ""}}
{{#ifCond monitorType "API"}}
{{> DetailBoxField title="Monitor URL:" text=(concat requestType " " monitorDestination) }}
{{else}}
{{> DetailBoxField title="Monitor Destination:" text=monitorDestination }}
{{/ifCond}}
{{/ifNotCond}}
{{> DetailBoxField title="Current Status: " text=currentStatus }}
{{> DetailBoxField title="Description: " text="" }}
{{> DetailBoxField title="" text=monitorDescription }}
{{> DetailBoxField title="Description: " text=monitorDescription }}
{{> DetailBoxEnd this }}

View File

@@ -4,21 +4,28 @@
{{> Logo this}}
{{> EmailTitle title=(concat "Monitor: " monitorName) }}
{{> InfoBlock info=(concat "Monitor status changed to - " currentStatus)}}
{{> InfoBlock info="Monitor status has changed"}}
{{> InfoBlock info="Here are the details: "}}
{{> DetailBoxStart this }}
{{> DetailBoxField title="Monitor Name:" text=monitorName }}
{{> DetailBoxField title="New Status: " text=currentStatus }}
{{#ifNotCond rootCause ""}}
{{> DetailBoxField title="Root Cause: " text="" }}
{{> DetailBoxField title="" text=rootCause }}
{{> StatusTransition this}}
{{#ifNotCond previousStatusDurationText ""}}
{{> DetailBoxField title="Duration in Previous Status:" text=previousStatusDurationText }}
{{/ifNotCond}}
{{> DetailBoxField title="Status changed at: " text="" }}
{{> DetailBoxField title="" text=statusChangedAt }}
{{> DetailBoxField title="Description: " text="" }}
{{> DetailBoxField title="" text=monitorDescription }}
{{> DetailBoxField title="Monitor Name:" text=monitorName }}
{{#ifNotCond monitorDestination ""}}
{{#ifCond monitorType "API"}}
{{> DetailBoxField title="Monitor URL:" text=(concat requestType " " monitorDestination) }}
{{else}}
{{> DetailBoxField title="Monitor Destination:" text=monitorDestination }}
{{/ifCond}}
{{/ifNotCond}}
{{#ifNotCond rootCause ""}}
{{> DetailBoxField title="Root Cause:" text=rootCause }}
{{/ifNotCond}}
{{> DetailBoxField title="Status changed at:" text=statusChangedAt }}
{{> DetailBoxField title="Description:" text=monitorDescription }}
{{> DetailBoxEnd this }}

View File

@@ -8,8 +8,14 @@
{{> DetailBoxStart this }}
{{> DetailBoxField title="Monitor Name:" text=monitorName }}
{{> DetailBoxField title="Monitor Description: " text="" }}
{{> DetailBoxField title="" text=monitorDescription }}
{{#ifNotCond monitorDestination ""}}
{{#ifCond monitorType "API"}}
{{> DetailBoxField title="Monitor URL:" text=(concat requestType " " monitorDestination) }}
{{else}}
{{> DetailBoxField title="Monitor Destination:" text=monitorDestination }}
{{/ifCond}}
{{/ifNotCond}}
{{> DetailBoxField title="Monitor Description: " text=monitorDescription }}
{{> DetailBoxField title="Probe Status: " text=currentStatus }}
{{> DetailBoxEnd this }}

View File

@@ -1,3 +1,4 @@
<!-- Primary Action Button -->
<table class="st-Copy st-Width st-Width--mobile" border="0" cellpadding="0" cellspacing="0"
width="600" style="min-width: 600px;">
<tbody>
@@ -8,26 +9,26 @@
<div class="st-Spacer st-Spacer--filler"></div>
</td>
<td class="st-Font st-Font--body"
style="border: 0; margin: 0; padding: 0; color: #000000; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Ubuntu, sans-serif; font-size: 16px; line-height: 24px;">
style="border: 0; margin: 0; padding: 0; color: #1a1a2e; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Ubuntu, sans-serif; font-size: 16px; line-height: 24px;">
<!-- Button & Modifier: fullWidth -->
<!-- Button & Modifier: fullWidth with gradient -->
<table class="st-Button st-Button--fullWidth" border="0" cellpadding="0" cellspacing="0"
width="100%">
<tbody>
<tr>
<td align="center" class="st-Button-area" height="38" valign="middle"
style="border: 0; margin: 0; padding: 0; background-color: #000000; border-radius: 5px; text-align: center;">
<td align="center" class="st-Button-area" height="48" valign="middle"
style="border: 0; margin: 0; padding: 0; background: linear-gradient(135deg, #1a1a2e 0%, #000000 100%); border-radius: 8px; text-align: center; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);">
<a class="st-Button-link"
style="border: 0; margin: 0; padding: 0; color: #ffffff; display: block; height: 38px; text-align: center; text-decoration: none;"
style="border: 0; margin: 0; padding: 0; color: #ffffff; display: block; height: 48px; text-align: center; text-decoration: none;"
href={{buttonUrl}}>
<span class="st-Button-internal"
style="border: 0; margin: 0; padding: 0; color: #ffffff; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Ubuntu, sans-serif; font-size: 16px; font-weight: bold; height: 38px; line-height: 38px; mso-line-height-rule: exactly; text-decoration: none; vertical-align: middle; white-space: nowrap; width: 100%;">{{buttonText}}</span>
style="border: 0; margin: 0; padding: 0; color: #ffffff; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Ubuntu, sans-serif; font-size: 15px; font-weight: 600; height: 48px; line-height: 48px; mso-line-height-rule: exactly; text-decoration: none; vertical-align: middle; white-space: nowrap; width: 100%; letter-spacing: 0.3px;">{{buttonText}}</span>
</a>
</td>
</tr>
</tbody>
</table>
<!-- /Button & Modifier: fullWidth -->
<!-- /Button & Modifier: fullWidth with gradient -->
</td>
<td class="st-Spacer st-Spacer--gutter"
@@ -37,10 +38,11 @@
</td>
</tr>
<tr>
<td class="st-Spacer st-Spacer--stacked" colspan="3" height="12"
<td class="st-Spacer st-Spacer--stacked" colspan="3" height="16"
style="border: 0; margin: 0; padding: 0; font-size: 1px; line-height: 1px; mso-line-height-rule: exactly;">
<div class="st-Spacer st-Spacer--filler"></div>
</td>
</tr>
</tbody>
</table>
</table>
<!-- /Primary Action Button -->

View File

@@ -19,7 +19,7 @@
<a style="border: 0; margin: 0; padding: 0; text-decoration: none;" href={{homeURL}}>
<img alt="OneUptime" height="70" border="0"
style="height:70px; border: 0; margin: 0; padding: 0; color: #000000; display: block; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Ubuntu, sans-serif; font-size: 12px; font-weight: normal;"
style="height:70px; border: 0; margin: 0; padding: 0; color: #000000; display: block; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Ubuntu, sans-serif; font-size: 12px; font-weight: normal; border-radius: 10%;"
src="{{logoUrl}}">
</a>
</div>

View File

@@ -1,4 +1,4 @@
<!-- End Detail Card Field Container -->
</td>
</tr>
</tbody>
@@ -10,4 +10,5 @@
</td>
</tr>
</tbody>
</table>
</table>
<!-- /Detail Card Container -->

View File

@@ -1,7 +1,9 @@
<p style="Margin:0;font-size:16px;font-family:'inter','helvetica neue',helvetica,arial,sans-serif;line-height:30px;color:#424761">
<!-- Detail Card Field -->
<div class="st-DetailCard-field" style="padding: 10px 0; border-bottom: 1px solid #e2e8f0;">
{{#if title}}
<strong>{{{title}}} </strong>{{{text}}} </span>
{{else}}
{{{text}}}
<p class="st-DetailCard-label" style="Margin:0 0 4px 0;font-size:11px;font-family:'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', sans-serif;line-height:16px;color:#64748b;font-weight:600;text-transform:uppercase;letter-spacing:0.5px;">{{{title}}}</p>
{{/if}}
</p>
{{#if text}}
<p class="st-DetailCard-value" style="Margin:0;font-size:15px;font-family:'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', sans-serif;line-height:24px;color:#1e293b;font-weight:500;">{{{text}}}</p>
{{/if}}
</div>

View File

@@ -1,19 +1,20 @@
<table class="st-Copy st-Width st-Width--mobile" border="0" cellpadding="0" cellspacing="0"
width="500" style="min-width: 500px;margin: 10px 50px;">
<!-- Detail Card Container -->
<table class="st-Copy st-Width st-Width--mobile st-DetailCard" border="0" cellpadding="0" cellspacing="0"
width="472" style="min-width: 472px; margin: 16px 64px; border-radius: 12px; overflow: hidden;">
<tbody>
<tr style="border-collapse:collapse">
<td width="720" align="center" valign="top" style="padding:0;Margin:0"></td>
<td width="100%" align="center" valign="top" style="padding:0;Margin:0"></td>
</tr>
<tr style="border-collapse:collapse">
<td align="left"
style="padding:0;Margin:0;padding-top:0px;padding-left:40px;padding-right:40px;padding-bottom:30px;background-color:#f7f8fa;border-radius: 5px">
style="padding:0;Margin:0;padding-top:0px;padding-left:0;padding-right:0;padding-bottom:0;background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);border-radius: 12px; border: 1px solid #e2e8f0; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);">
<table cellpadding="0" cellspacing="0" width="100%"
style="border-collapse:collapse;border-spacing:0px">
<tbody>
<tr style="border-collapse:collapse">
<td width="720" align="center" valign="top" style="padding:0;Margin:0">
<td width="100%" align="center" valign="top" style="padding:0;Margin:0">
<table cellpadding="0" cellspacing="0" width="100%" role="presentation"
style="border-collapse:collapse;border-spacing:0px">
<tbody>
<tr style="border-collapse:collapse">
<td align="left" style="padding:0;Margin:0;padding-top:30px">
<td align="left" style="padding:24px 28px 0 28px;Margin:0;">

View File

@@ -1,3 +1,4 @@
<!-- Email Title Block -->
<table class="st-Copy st-Width st-Width--mobile" border="0" cellpadding="0" cellspacing="0"
width="600" style="min-width: 600px;">
<tbody>
@@ -7,10 +8,10 @@
width="64">
<div class="st-Spacer st-Spacer--filler"></div>
</td>
<td class="st-Font st-Font--body"
style="color: #000000 !important; border:0;margin:0;padding:0; font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,'Helvetica Neue',Ubuntu,sans-serif;font-size:16px;line-height:24px">
<td class="st-Font st-Font--title"
style="color: #1a1a2e !important; border:0;margin:0;padding:0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Ubuntu, sans-serif;font-size:24px;line-height:32px;font-weight:700;">
<h3>{{title}}</h3>
<h2 style="margin: 0; padding: 0; font-size: 24px; line-height: 32px; font-weight: 700; color: #1a1a2e;">{{title}}</h2>
</td>
<td class="st-Spacer st-Spacer--gutter"
@@ -20,10 +21,11 @@
</td>
</tr>
<tr>
<td class="st-Spacer st-Spacer--stacked" colspan="3" height="12"
<td class="st-Spacer st-Spacer--stacked" colspan="3" height="16"
style="border: 0; margin: 0; padding: 0; font-size: 1px; line-height: 1px; mso-line-height-rule: exactly;">
<div class="st-Spacer st-Spacer--filler"></div>
</td>
</tr>
</tbody>
</table>
</table>
<!-- /Email Title Block -->

Some files were not shown because too many files have changed in this diff Show More