Commit Graph

225 Commits

Author SHA1 Message Date
Oliver Kieselbach ef02ec5696 fixed bug on login site 2026-02-25 12:13:34 +01:00
Oliver Kieselbach 9c05f376ea fix robots sitemap url 2026-02-25 01:46:37 +01:00
Oliver Kieselbach f0983837ec fix url and google verification 2026-02-25 01:35:40 +01:00
Oliver Kieselbach 44e5663682 changed sitemap 2026-02-25 01:28:40 +01:00
Oliver Kieselbach 294d79a731 fixed a compiler warning 2026-02-24 23:40:05 +01:00
Oliver Kieselbach bbf815f739 remove dead UploadBundle code and fix Lenovo model detection
- Remove UploadBundleRequest, UploadBundleResponse classes (ApiModels.cs)
- Remove UploadBundle API endpoint constant (Constants.cs)
- Remove GetBundleUploadUrlAsync method (BackendApiClient.cs) — no callers anywhere
- Fix HardwareInfo: Lenovo devices report the marketing model name in
  Win32_ComputerSystemProduct.Version, not Win32_ComputerSystem.Model;
  add Lenovo-specific WMI fallback for correct model string

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 23:28:53 +01:00
Oliver Kieselbach 1b066ba634 agent: WMI query fix for lenovo model 2026-02-24 23:12:32 +01:00
Oliver Kieselbach c1c19c4f7a fix diagnostics upload 401 and enrich upload event data
- Add /api/diagnostics/upload-url to anonymous routes in AuthenticationMiddleware so the
  new device-cert-authenticated endpoint is not blocked by the JWT middleware
- Add DiagnosticsUploadResult value object to DiagnosticsPackageService carrying BlobName,
  SasUrlPrefix (truncated, safe to log), and ErrorCode
- Change CreateAndUploadAsync return type to DiagnosticsUploadResult for richer error context
- Add BuildSasUrlPrefix helper to produce a safe truncated URL for event data
- Change UploadToBlobStorageAsync to return (bool success, string errorCode) tuple
- Update MonitoringService to populate sasUrl and errorCode in diagnostics_upload_failed
  event data dict for visible timeline diagnostics

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 22:18:21 +01:00
Oliver Kieselbach 8b17b82b78 route diagnostics SAS expiry warnings to notification bell
Instead of inline banners on the settings page, expired or near-expiry
SAS URLs now fire a persistent warning/error notification to the bell icon.
The notification includes a direct "View" link to /settings#diagnostics.

NotificationContext: added optional href field to Notification; addNotification
signature extended with href parameter for both keyed and unkeyed paths.

Navbar: notifications with href render a "View" link that marks the
notification as read and navigates to the target anchor.

Settings: removed inline SAS warning banners; addNotification called on
config load when expiry <= 7 days (warning) or expired (error); diagnostics
section gets id="diagnostics" anchor for deep-linking.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 21:34:56 +01:00
Oliver Kieselbach 6aafaa5ff8 fetch diagnostics SAS URL on-demand to reduce device exposure window
Instead of delivering the long-lived SAS URL in the agent config response
(where it was cached on disk for the full enrollment period), the agent now
requests a short-lived URL via POST /api/diagnostics/upload-url just before
uploading — the URL is held in memory only and never written to config.

Backend: new GetDiagnosticsUploadUrlFunction with same cert/hardware
security validation as all other agent endpoints; GetAgentConfigFunction
now sends DiagnosticsUploadEnabled (bool) instead of the SAS URL;
ConfigVersion bumped to 6.

Agent: BackendApiClient.GetDiagnosticsUploadUrlAsync added;
DiagnosticsPackageService fetches URL on-demand via the API client;
AgentConfiguration.DiagnosticsBlobSasUrl replaced by DiagnosticsUploadEnabled.

UI: settings page parses SAS URL expiry (se= param) and shows expiry date
inline with colour coding; expired or near-expiry URLs trigger
error/warning notifications at the top of the page on load.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 21:15:50 +01:00
Oliver Kieselbach 9aa4d0a30d added tenaant management refresh button 2026-02-24 18:11:34 +01:00
Oliver Kieselbach ef7d7febed platform stats fix and english wording 2026-02-24 18:05:40 +01:00
Oliver Kieselbach 79a4407831 enhanced platform stats and better tenant management 2026-02-24 17:54:39 +01:00
Oliver Kieselbach 525cf0a0aa wording updates 2026-02-24 17:42:37 +01:00
Oliver Kieselbach 0cf6a700d8 wording, fix tenant management, preview badge 2026-02-24 17:29:11 +01:00
Oliver Kieselbach 146d53982f better admin tenant management 2026-02-24 17:14:26 +01:00
Oliver Kieselbach a63fdba9e6 fix: dark mode for docs Settings section
- Add missing globals.css overrides: text-purple-900, text-sky-900,
  text-emerald-900, text-rose-900, bg-rose-50, border-rose-200,
  divide-gray-100 (row dividers)
- Refactor SettingsGroup: split color prop into color + borderColor so
  the outer border renders with an explicit dark-aware color class
- Add bg-white to SettingsRow and Danger Zone body so they pick up the
  global .dark .bg-white override correctly
- Change default text in SettingsRow to text-gray-500 (already has dark
  override) instead of text-gray-400

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 15:12:36 +01:00
Oliver Kieselbach de2baad1d0 chore: add temporary banner about Analyze Rules refinement phase
Informs users that rules are being actively validated and changed,
occasional redeploys and inconsistent analysis results are expected.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 14:51:56 +01:00
Oliver Kieselbach d807f7de7e fix: clean up built-in analyze rules
- Remove ANALYZE-ESP-002 (Security Policy Application Failure): too many
  false positives, the pattern matched unrelated EnforcementState events
- Disable ANALYZE-CORR-001 (Slow Network) by default: download_progress
  events don't reliably indicate slow network, needs rethinking
- Disable ANALYZE-APP-009 (App Download Stalled) by default: relies on
  download_progress.status=failed which doesn't reflect actual stall
- Rename ANALYZE-APP-002 from "MSI Installation Error" to "App Installation
  Error": broadens scope, removes CCM/SCCM log reference (Intune-only),
  points to IME logs instead
- Also include Enabled in auto-update comparison so Enabled=false changes
  propagate to existing tenants on next seed check

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 14:49:50 +01:00
Oliver Kieselbach 07a66f2952 fix: support cross-tenant analysis for Galactic Admins
GetRuleResultsFunction was ignoring the tenantId query parameter and
always using the tenant from the JWT token. As a result, a Galactic
Admin viewing another tenant's session would get 'No events found'
because the data was stored under the session's tenant, not the admin's.

Now follows the same pattern as GetSessionEventsFunction:
- Read tenantId from query parameter (sent by the frontend as effectiveTenantId)
- Fall back to JWT tenant if not provided
- Allow cross-tenant access only for Galactic Admins (403 otherwise)
- Use the effective tenant ID for all storage calls and rule engine runs

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 14:31:08 +01:00
Oliver Kieselbach 8f9aec3e05 fix: make Analyze Now button actually re-run all rules
Previously, AnalyzeSessionAsync always loaded existing results and
skipped rules already evaluated (deduplication check). The reanalyze
flag from the API endpoint was never passed through, so clicking
"Analyze Now" only returned cached results.

Fix:
- Add `reanalyze` parameter to `AnalyzeSessionAsync`; when true, skip
  deduplication so all active rules evaluate against the full event stream
- In GetRuleResultsFunction, pass reanalyze=true and delete stale stored
  results before writing the fresh evaluation output

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 14:17:07 +01:00
Oliver Kieselbach d9cab13299 fix dark mode: add missing color overrides for analyze-rules page
Adds missing dark mode overrides to globals.css:

Borders:
- border-red-300 (critical severity badge)
- border-orange-200/300 (high severity badge, form cards)
- border-indigo-200/300 (event_correlation card, expanded rule ring, doc links)
- border-teal-200/300 (esp category badge)

Text:
- text-indigo-700 (enrollment badge, correlation label, doc links)
- text-indigo-600 (action/link text)
- text-purple-700 (identity category badge)
- text-orange-700 (apps category badge)
- text-orange-600 (High count stat)
- text-teal-700/600 (esp category badge)

Hover:
- hover:bg-indigo-100 (related docs link hover)
- hover:bg-indigo-50 (indigo surface hover)

Ring:
- ring-1/2 ring-indigo-200 (expanded rule card outline)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 14:06:06 +01:00
Oliver Kieselbach 6b15aa95d9 update analyze-rules UI for event_correlation support + JSON mode
- RuleCondition interface gains 6 optional fields:
  correlateEventType, joinField, timeWindowSeconds,
  eventAFilterField, eventAFilterOperator, eventAFilterValue
- SOURCES constant adds event_correlation
- Condition editor renders extra fields when source=event_correlation:
  Event B type, join field, time window, Event A filter row
  (shown in indigo-tinted card with a correlation badge)
- Form/JSON tab toggle added to both create and edit forms:
  Form view: the existing structured editor
  JSON view: full rule JSON in a resizable monospace textarea,
  with Apply JSON button to sync back to form and inline error display
- handleCreateRule/handleSaveEdit accept optional formOverride so
  JSON-mode save bypasses React state async timing

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 13:54:11 +01:00
Oliver Kieselbach 2235170a57 add generic event_correlation source for flexible cross-event rule correlation
Replaces the hardcoded app_state_regression source with a generic
event_correlation source that allows correlating any two event types
by a shared field (e.g. appId), with optional time windows and filters
on both events — all configurable via JSON without backend code changes.

RuleCondition gains 5 new nullable properties:
- CorrelateEventType: second event type (Event B)
- JoinField: field to match across both events (e.g. "appId")
- TimeWindowSeconds: max time between Event A and B
- EventAFilterField/Operator/Value: optional filter on Event A

ANALYZE-APP-010 migrated to use event_correlation source.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 13:38:46 +01:00
Oliver Kieselbach 6deb2f9845 fix ANALYZE-APP-010: correlate app regression by appId using new source type
The previous rule incorrectly matched any app_install_completed event
against any app_install_failed event without correlating by appId.

Changes:
- RuleEngine: add app_state_regression source that finds apps where
  app_install_completed is followed by app_install_failed for the same
  appId, with optional DataField filter on the failed event; returns
  appId, appName, both event details and errorDetail as evidence
- AnalyzeRule: document new app_state_regression source in comment
- ANALYZE-APP-010: rewrite to use single app_state_regression condition
  (IME-ERROR-REPORT filter) + enrollment_complete check; evidence now
  contains the exact app name and id that regressed

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 13:19:05 +01:00
Oliver Kieselbach d7ce1e772f add ANALYZE-APP-010: detect app reverted to error after successful install
New built-in correlation rule that warns when an app transitions from
app_install_completed back to app_install_failed (IME-ERROR-REPORT)
while enrollment itself completes successfully. Includes remediation
steps for investigating EnforcementState changes and detection failures.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 13:04:08 +01:00
Oliver Kieselbach 8afbab295f Merge branch 'main' of https://github.com/okieselbach/Autopilot-Monitor 2026-02-24 12:10:05 +01:00
Oliver Kieselbach 04143cd22d fix dark mode on admin config page 2026-02-24 12:06:13 +01:00
Oliver Kieselbach 306a9382f9 Update Buy Me a Coffee username in FUNDING.yml 2026-02-24 11:55:17 +01:00
Oliver Kieselbach 3aa4cb37f8 fix links 2026-02-24 11:50:31 +01:00
Oliver Kieselbach 1609a57924 added architecture to readme 2026-02-24 11:45:52 +01:00
Oliver Kieselbach 2c85fc11ef added architecture diagram 2026-02-24 11:41:48 +01:00
Oliver Kieselbach 3c43119006 fix sticky navbar 2026-02-24 11:27:44 +01:00
Oliver Kieselbach 48c3206eb5 fix dark mode preview site 2026-02-24 10:52:38 +01:00
Oliver Kieselbach 07e4ff0e06 added docs link to Preview page 2026-02-24 10:38:59 +01:00
Oliver Kieselbach e421aa99c8 fix dark theme contrast issues in admin-configuration page
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 10:17:56 +01:00
Oliver Kieselbach 9d46935e49 add Settings reference section to docs
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 10:11:40 +01:00
Oliver Kieselbach 524e4fe746 add Private Preview section to docs
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 09:58:23 +01:00
Oliver Kieselbach 7fd7fca979 changed links and design of preview page 2026-02-24 09:42:07 +01:00
Oliver Kieselbach 65d59e8085 optimize SignalR payloads: remove unused data, use delta updates
- Remove newRuleResults from "newevents" broadcast (never used by list views, saves 3-15KB)
- Replace full SessionSummary with sessionUpdate delta DTO in "newevents" (only mutable fields)
- Strip redundant sessionId/tenantId from individual events and rule results in "eventStream"
- Fix event name casing inconsistency: "eventstream" → "eventStream" in frontend listeners
- Frontend handlers updated to merge delta updates with backward compatibility fallback

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 09:38:56 +01:00
Oliver Kieselbach 64ba882f36 fix PrivatePreview Notification 2026-02-24 09:02:35 +01:00
Oliver Kieselbach 0f68cf641c a few title changes to be more generic 2026-02-24 08:36:24 +01:00
Oliver Kieselbach 85780206fe fix: fetch platform-stats manifest without browser cache
The manifest (platform-stats.json) was fetched with force-cache, causing
the browser to serve stale data even after a new daily stats file was
published. Switch manifest fetch to no-store so it is always fresh.
The versioned payload file (platform-stats.YYYY-MM-DD.json) keeps
force-cache since its filename is date-stamped and never changes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 08:12:57 +01:00
Oliver Kieselbach 335f854ed8 SEO route swap: / is now the landing page, dashboard moved to /dashboard
- app/landing/page.tsx → app/page.tsx (landing page at root)
- app/page.tsx → app/dashboard/page.tsx (dashboard at /dashboard)
- app/landing/ directory deleted
- next.config.ts: 301 redirect /landing → /
- app/layout.tsx: canonical, OG, JSON-LD metadata updated to /
- All internal router.push('/') → /dashboard in subpages
- All router.push('/landing') → / in ProtectedRoute and preview
- All href='/landing' → / in PublicSiteNavbar, roadmap, privacy, terms
- robots.ts: allow / instead of /landing, disallow /dashboard
- sitemap.ts: root URL updated to /
- Navbar.tsx: suppress on pathname === '/' instead of '/landing'
- msalConfig.ts + .env.local: post-logout redirect updated to /

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 08:06:53 +01:00
Oliver Kieselbach ca39032ed4 Add Telegram notification for new Private Preview tenant signups
Sends a Telegram message to @AutopilotMonitor-PrivatePreview whenever
a new tenant signs up. The bot webhook URL is stored in the new
PreviewConfig table (PartitionKey=TelegramBot, RowKey=config,
WebhookUrl=<url>) — same lifecycle as PreviewWhitelist, easy to remove
after GA. Notification is fire-and-forget and non-fatal.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-23 23:13:22 +01:00
Oliver Kieselbach bd48ddac00 removed old readme 2026-02-23 22:06:03 +01:00
Oliver Kieselbach fd6ca05ebc Simplify README and remove outdated docs
Replace verbose README with a concise overview and link to the
official documentation at autopilotmonitor.com/docs. Remove
CONTRIBUTING.md, QUICKSTART.md, docs/architecture.md, and
docs/getting-started.md as the website docs supersede them.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-23 21:52:11 +01:00
Oliver Kieselbach cbddf409d5 Auto-promote tenant requester as TenantAdmin on preview approval
When a Galactic Admin approves a tenant for Private Preview, the user
who originally signed up (stored in TenantConfiguration.UpdatedBy) is
automatically added as TenantAdmin. This avoids manual admin assignment
after approval. Also fixes GitHub repository link in the portal footer.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-23 21:38:05 +01:00
Oliver Kieselbach de344941ce Updated DeviceValidator with better token cache handling and retry logic for consent propagation errors 2026-02-23 17:17:31 +01:00
Oliver Kieselbach b72e8b9d31 SEO metadata 2026-02-18 18:28:42 +01:00