Skip to content

feat(cloud): add dedicated Cloud page and Breach Monitor#78

Merged
dbfx merged 15 commits intomainfrom
feat/cloud-page-breach-monitor
Mar 26, 2026
Merged

feat(cloud): add dedicated Cloud page and Breach Monitor#78
dbfx merged 15 commits intomainfrom
feat/cloud-page-breach-monitor

Conversation

@dbfx
Copy link
Contributor

@dbfx dbfx commented Mar 25, 2026

Summary

  • Dedicated Cloud Page: Extracts cloud settings from Settings into a standalone /cloud route. Unlinked users see a feature showcase (local features first — threat monitor, CVE, AI safety scores — then cloud dashboard features, plan comparison with tier badges, and connect flow). Linked users see all cloud settings organized into sections (connection, monitoring, remote control, advanced).
  • Breach Monitor (full-stack): Backend cloud agent methods with new deleteApi, IPC handlers with email validation, Zustand store with optimistic removal and auto-reset on cloud unlink, and a complete UI page with add/remove emails, expandable email cards with breach details (data class pills, pwn count, verified badges), 403 upgrade prompt, and proper error handling (inline banners only when relevant, toast notifications for add/remove failures).
  • Settings page cleanup: Cloud section replaced with a single clickable card that navigates to /cloud. Removed ~300 lines of cloud state management from SettingsPage.
  • i18n: New cloud.json and breachMonitor.json translation namespaces; updated settings translations across all 27 locales.

New files

  • src/main/ipc/breach-monitor.ipc.ts — IPC handler
  • src/renderer/src/stores/breach-store.ts — Zustand store
  • src/renderer/src/pages/CloudPage.tsx — Cloud settings/showcase page
  • src/renderer/src/pages/BreachMonitorPage.tsx — Breach monitor page
  • src/renderer/src/locales/en/cloud.json — Cloud page translations
  • src/renderer/src/locales/en/breachMonitor.json — Breach monitor translations

Test plan

  • Navigate to /cloud when not linked — feature showcase renders with all sections
  • Click "Sign up free" / "Link Device" — connect flow works
  • Navigate to /cloud when linked — all settings sections render and toggles work
  • Navigate to /breach-monitor when not linked — redirects to /
  • Link a Starter plan device — page shows 403 upgrade prompt
  • Link a Basic/Pro device — page loads, shows empty state with add email input
  • Add an email — appears in list, breaches populate
  • Expand email card — breach details render correctly
  • Remove email — disappears from list
  • Sidebar shows Breach Monitor item only when cloud connected, with breach count badge
  • Unlink device — breach store resets, sidebar items hide
  • All 1891 existing tests pass

🤖 Generated with Claude Code

Extract cloud settings from SettingsPage into a standalone CloudPage
with a feature showcase for unlinked users (local features first, then
cloud dashboard features, plan comparison, and connect flow) and full
settings management for linked users.

Implement full-stack breach monitoring: cloud agent methods with
deleteApi, IPC handlers with email validation, Zustand store with
optimistic removal, and a complete UI page with add/remove emails,
expandable breach cards with data class pills, and proper error
handling (403 upgrade prompt, inline error banners, toast notifications).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
github-actions bot and others added 7 commits March 25, 2026 18:01
Redesign breach monitor page from expandable cards to an email
list + sortable table layout. Users select an email from the sidebar
list to view its breaches in a table that can be sorted by date,
accounts, or status.

Add breach acknowledgment: users can mark individual breaches or all
breaches for an email as "reviewed" via PATCH /breach-monitor/acknowledge.
Unacknowledged breaches show a "New" badge; acknowledged ones show
"Reviewed". Sidebar badge now only counts unacknowledged breaches.

Backend: add patchApi method, acknowledgeBreaches cloud agent method,
IPC handler with validation, preload bridge. Add acknowledgedAt field
to BreachEntry type.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The POST response only returns newly added emails, not the full list.
Re-fetch via GET after adding so existing emails are preserved.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… filters

Replace the two-column email sidebar + detail panel layout with a flat
table showing all breaches sorted by date. Emails appear as filter
chips and an optional dropdown when multiple are monitored. Remove
unused selectedEmail state from the store.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Show the real API error in the toast instead of a generic message, and
log breach IDs to the console for debugging.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@dbfx
Copy link
Contributor Author

dbfx commented Mar 26, 2026

@codex review

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 572f40cbbb

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

- Chunk acknowledge-all into batches of 100 to stay within IPC limit
- Separate delete/add success from refresh failure so a successful
  mutation isn't reverted or reported as failed due to a transient
  fetch error

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b16ff075ef

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

dbfx and others added 3 commits March 26, 2026 07:02
- Eagerly fetch breach data on module load when cloud-connected so the
  sidebar badge is accurate without visiting the page first
- Also fetch when a device is newly linked
- Optimistically decrement usage on email removal so the add button
  isn't blocked if the follow-up refresh fails

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Hovering the card shows per-plan email limits and an upgrade nudge.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 701620cd1c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Replace the native title attribute with a HelpCircle icon and the
project's SafetyTooltip-style popover with arrow, matching the tooltip
pattern used in StartupPage and UninstallerPage.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 08883f65d9

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +278 to +281
const raw = (await this.patchApi(path, { breach_ids: breachIds })) as Record<string, unknown>
return {
status: typeof raw.status === 'string' ? raw.status : 'ok',
acknowledged: typeof raw.acknowledged === 'number' ? raw.acknowledged : 0,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Guard acknowledge parsing when PATCH returns no JSON

patchApi can return null for successful non-JSON responses (for example a 204 No Content acknowledge endpoint), but this code immediately dereferences raw.status/raw.acknowledged. In that case, a successful acknowledge request throws a runtime TypeError and is surfaced as a failure to the UI. Please validate that raw is an object before property access and fall back to defaults when it is not.

Useful? React with 👍 / 👎.

Comment on lines +280 to +281
{emails.length === 0 && status === 'done' && (
<EmptyState icon={Mail} title={t('emptyState.noEmails')} description={t('emptyState.noEmailsDesc')} />

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Avoid showing empty state when initial fetch failed

This renders the “no emails” empty state whenever loading is done and the list is empty, even if the fetch failed. Because error toast/banner paths are also gated on emails.length > 0, first-load API failures (network/5xx) are presented as a successful zero-results state, which is misleading for users who already have monitored emails and can trigger duplicate add/remove attempts. Gate this empty state on !error or show an explicit error state.

Useful? React with 👍 / 👎.

dbfx and others added 2 commits March 26, 2026 07:31
The eager hydration can fire before the cloud agent finishes its
handshake. Now the store silently retries up to 3 times (3s apart)
on "not connected" errors instead of surfacing the error to the UI.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@dbfx dbfx merged commit 6d470e3 into main Mar 26, 2026
9 checks passed
@dbfx dbfx deleted the feat/cloud-page-breach-monitor branch March 26, 2026 05:37
Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c851b45b62

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +89 to +91
for (let i = 0; i < breachIds.length; i += 100) {
await window.kudu.breachMonitorAcknowledge(breachIds.slice(i, i + 100))
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve successful chunks when acknowledge-all partially fails

When acknowledgeBreaches processes more than 100 IDs, each chunk is sent sequentially, but any failure in a later chunk throws before local state is updated. In that case, earlier chunks may already be acknowledged server-side while the UI still shows everything as unreviewed, which leads to stale badge/count state and misleading retry behavior for large breach sets. Record per-chunk successes and apply them (or force a refetch) even if a later chunk fails.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant