Commit Graph
57 Commits
Author SHA1 Message Date
Alexander Holliday 6eba53d716 Merge pull request #3837 from egeoztass/fix/email-error-propagation
fix: propagate SMTP transport errors from EmailService.sendEmail
2026-08-18 10:36:02 -07:00
Alexander Holliday 5cca0fb2d3 Merge pull request #3839 from egeoztass/feat/ntfy-authentication
feat: add authentication support to ntfy notifications
2026-08-18 10:30:08 -07:00
Alex Holliday 7478bd7d17 remove duplicate validation 2026-08-17 13:08:43 -07:00
Alex Holliday 7b1d6c763f tighten types, remove duplicate calls 2026-08-17 13:05:03 -07:00
Alex Holliday ab7f2cd8f4 update openapi docs 2026-08-17 12:36:39 -07:00
Alex Holliday c1f0bf3dd4 wire controller 2026-08-17 12:31:01 -07:00
Alex Holliday 6f9642c298 tighten timezone validation 2026-08-17 11:48:56 -07:00
Alex Holliday 3a22d3e819 add range buckets for status pages 2026-08-17 11:48:44 -07:00
egeoztass c35b22e1ac fix: propagate SMTP transport errors from EmailService.sendEmail
sendEmail caught transport failures internally and resolved to false or
undefined, so every caller's .catch() was dead code and send failures were
silently suppressed. Password recovery in particular reported "email sent
successfully" while the user received nothing.

sendEmail now throws an AppError carrying the underlying cause, and returns
Promise<string> instead of Promise<string | false | undefined>.

Call sites updated for the new contract:
- UserService.registerUser: the existing .catch() now actually fires
- UserService.requestRecovery: the failure reaches the client instead of a
  misleading success response
- InviteService and the test-email endpoint: keep their user-facing messages
  and attach the SMTP cause
- EmailProvider: catches and returns false, because NotificationsService fans
  providers out through Promise.all and a rejection there would abort the
  other channels' alerts

Closes #3757
2026-08-14 14:11:16 +03:00
egeoztass 1c9739d1da feat: add authentication support to ntfy notifications
ntfy servers that require auth rejected every Checkmate alert because the
provider posted without an Authorization header, so alerts to protected
topics failed silently.

Adds ntfyAuthType ("none" | "token" | "basic"):
- token: Authorization: Bearer <accessToken>
- basic: Authorization: Basic base64(ntfyUsername:accessToken)

Both types store their secret in the existing accessToken field rather than
introducing a new secret, so credential handling stays in one place.

Incomplete credentials fail the send instead of falling back to an anonymous
post, and validation rejects partial auth config up front so a channel can't
be saved looking authenticated while posting anonymously.

Backend only; frontend follows once this lands.

Closes #3717
2026-08-14 14:01:06 +03:00
colinjtsen2010 75516a220d fix: handle IPs, avoid wrong parent-domain lookups, cache whois results
- Bare IP addresses and non-domain hosts (localhost, IPv6) now return a
  null expiry instead of throwing, so they no longer spam error logs.
- Extract the registrable domain with tldts instead of walking up
  hostname labels, so a subdomain can never accidentally return its
  parent domain's expiry date.
- Cache WHOIS lookups per registrable domain (1h positive, 10min
  negative) so visiting details pages does not re-query the registry
  every time.

Addresses review feedback on #3834.
2026-08-13 12:02:49 +08:00
colinjtsen2010 e5959ca91d feat: add domain registration expiry monitoring
Adds a GET /monitors/domain/:monitorId endpoint that looks up the
registrable domain's WHOIS expiry date (walking up from subdomains),
and displays it next to the certificate expiry on the uptime details
page.

Fixes #2094
2026-08-11 00:34:21 +08:00
Marcos Paulo Diniz 466d356ad1 refactor(validation): use Zod URL protocols
Refs #3821
2026-08-05 08:34:12 -03:00
Marcos Paulo Diniz 750fc9e238 feat(notifications): add Rocket.Chat provider
Refs #3821
2026-08-02 01:59:11 -03:00
Alex Holliday 8a608961e6 remove server side normalization 2026-07-31 10:31:39 -07:00
Alex Holliday c102cd8d26 openapi schemas 2026-07-30 10:35:01 -07:00
Alex Holliday e3075318b6 denormalize resposne times 2026-07-29 10:57:20 -07:00
Alex Holliday ed36db172a dedupe hardware stat definitions, fix tests, remove misleading null return types 2026-07-24 11:32:00 -07:00
Alex Holliday 80d4e818f1 remove unused static vars 2026-07-22 10:36:16 -07:00
Alex Holliday 586e79efb2 remove unused getters 2026-07-22 10:13:37 -07:00
Alex Holliday d53785b768 remove unused utilities, fix delete profile image issue 2026-07-22 10:03:48 -07:00
Alex Holliday 8e600e9a87 remove inline enum definitions 2026-07-21 10:48:18 -07:00
Alex Holliday 36434c1160 convert router classes to exported functions 2026-07-20 11:25:39 -07:00
Alex Holliday 4d9e5821a8 purge unused groups route, update tests 2026-07-20 10:21:43 -07:00
Alex Holliday bd13e9d9c8 add catchAsync to handle errors, remove all try/catch blocks from contorllers 2026-07-15 10:02:36 -07:00
Alex Holliday cc1814f507 whitelist monitor properties instead of blacklist for status pages 2026-07-07 09:47:29 -07:00
Alex Holliday 436c11bcba Merge branch 'develop' into fix/status-page-monitor-leak 2026-07-07 09:02:48 -07:00
Alex adba25269c tighten regex validation 2026-07-06 09:39:28 -07:00
Alex Holliday 8bf5db0834 remove dead code and tests 2026-07-03 11:28:00 -07:00
Alexander Holliday 552b7a037d Merge pull request #3743 from bluewave-labs/feat/helm
feat: Update helm charts
2026-07-02 10:13:28 -07:00
Alex Holliday c0e33eb4fa skip general rate limiter on dev mode 2026-06-30 09:08:20 -07:00
Arnaud GRIMBERT 969d24e369 Merge branch 'develop' into feat/customcss-status-page 2026-06-24 20:27:57 +02:00
Buco7854 a4cc322a55 feat: apply status page CSP to custom domains
Detect custom domains by comparing the request host to the app host and apply
the tightened CSP there too, not just on the public path. Run the middleware
before express.static so static-served root documents get the header, and keep
helmet after static so its default-src does not block custom domain API calls.
2026-06-24 18:21:16 +00:00
Alex Holliday 74783fd738 clean up logger 2026-06-24 10:53:03 -07:00
Buco7854 ffbf223288 feat: tighten CSP on the public status page document
Layer a stricter Content-Security-Policy on the /status/public document so
custom CSS cannot load external images, fonts, or stylesheets. Browsers
enforce the intersection of all CSP headers, so this only narrows the public
status page and never loosens the global policy, while keeping the app's
Google Fonts. Browser-enforced backstop behind the validator.
2026-06-23 19:25:40 +00:00
Alex Holliday c9b8f434cd split worker into a scheduler and worker 2026-06-23 11:22:37 -07:00
Buco7854 3685e0c476 feat: reject custom CSS that references external resources
Reject status page custom CSS containing @import or a url() / image-set()
/ image() / cross-fade() whose target is http(s) or protocol-relative,
while allowing data: and relative URLs. The check normalizes comments and
CSS escapes first so obfuscated forms cannot slip past. Enforced in the
create/update body validation.
2026-06-22 23:49:58 +00:00
Alex Holliday 3489ee000d add super refine to reject method HEAD and advanced matching/json path 2026-06-22 10:31:13 -07:00
Alex Holliday 32ec909bf7 add default GET for imported monitors 2026-06-22 10:25:27 -07:00
Alex Holliday 8e5757beb1 add a method field to model, add enums and validation for http methods 2026-06-22 10:15:14 -07:00
Alexander Holliday 8277c4ed13 Merge pull request #3728 from bluewave-labs/feat/db-queue
feat: db queue
2026-06-17 09:48:40 -07:00
Alex Holliday f65238da6c reformat 2026-06-17 09:45:59 -07:00
Buco7854 6165ae60e6 Merge branch 'develop' of https://github.com/bluewave-labs/checkmate into feat/customcss-status-page
# Conflicts:
#	server/src/api/routes/statusPageRoute.ts
2026-06-12 16:01:03 +00:00
Buco7854 69e142f711 fix: restrict status page mutations to admins and superadmins
Creating, updating and deleting status pages was only guarded by
verifyJWT, so any authenticated team member could set fields including
the new customCSS via a direct API call. The admin gating existed only
in the client UI (hidden buttons), and the create/configure routes had
no guard, so the form was reachable by URL. Enforce the role at the API
with isAllowed, matching the monitor routes.
2026-06-12 15:43:58 +00:00
Alex Holliday 8d637dbcac update validation 2026-06-11 14:18:56 -07:00
Ian Troisi 517139cbf4 fix: cache negative custom domain CORS lookups
Use a shorter TTL for rejected origins so unknown domains do not hit
the database on every cross-origin request.
2026-06-11 14:48:31 -04:00
Ian Troisi ef049b6521 fix: resolve CORS TypeScript error and format server files
Type defaultCorsOptions as CorsOptions so allowedHeaders is compatible
with the cors middleware. Format files from develop merge for CI.
2026-06-11 13:55:10 -04:00
Ian Troisi 33f8641f3a Merge branch 'develop' into feat/status-page-custom-domain 2026-06-11 13:54:27 -04:00
Alex Holliday a43363ebfc apply middleware 2026-06-11 10:42:05 -07:00
Alex Holliday 091c36cbf3 create upload middleware 2026-06-11 10:40:59 -07:00