Skip to content

Dev#519

Merged
mayanayza merged 75 commits intomainfrom
dev
Feb 28, 2026
Merged

Dev#519
mayanayza merged 75 commits intomainfrom
dev

Conversation

@mayanayza
Copy link
Collaborator

No description provided.

Hide the Update button when a daemon is unreachable since it cannot
be upgraded without connectivity. This prevents the Retry Connection
and Update buttons from rendering on top of each other.
- Change display logic from OR to AND so checklist hides
  when all steps complete OR when user dismisses
- Remove allComplete guard on dismiss button so users can
  dismiss at any time
- Remove dead "Setup complete" heading branch (unreachable)
- Add uniqueness check in start_session() using discovery_sessions map
- Return 409 Conflict when a session is already running for a discovery
- Change start_session() return type from anyhow::Error to ApiError
- Sync discovery_sessions removal in all session lifecycle methods:
  update_session, cancel_session, clear_sessions_for_daemon,
  cleanup_old_sessions, cleanup_stalled_sessions
- Add 409 response to start_session OpenAPI spec
- Add with_snmp() helper to set sys_descr, sys_object_id, sys_location,
  sys_contact, and chassis_id on host tuples from create_host()
- Populate SNMP fields on 13 hosts: firewalls (pfSense, FortiGate),
  switches (UniFi, Arista), hypervisors (Proxmox), NAS (TrueNAS,
  Synology), APs (UniFi U6-Pro/LR/Lite), and printer (HP LaserJet)
- Add snmp_credential_id (Network Devices) to 3 APs that were missing it
- Set chassis_id on switches and APs for LLDP deduplication
- VMs, containers, and software servers remain without SNMP (realistic)
- Replace TelemetryOperation enum with BillingOperation (10 variants)
  and OnboardingOperation (14 variants, no legacy)
- Replace TelemetryEvent struct with BillingEvent and OnboardingEvent
- Update Event enum: Telemetry → Billing + Onboarding
- Update EventFilter, EventBus publish methods, and all subscribers
- Graceful JSONB deserialization drops legacy variants silently
- Remove legacy guards (PersonalPlanSelected, CommercialPlanSelected)
- Update frontend schema and 4 Svelte components
- Add /share/{*rest} route to public_share_app serving index.html
  without the frame-ancestors 'self' header that blocked embedding
- Only share pages are affected; all other SPA pages retain
  clickjacking protection via protected_app's fallback
- API-level embed enforcement (billing gate, domain restrictions)
  remains unchanged
…ipts

- Extract ALLOWED_LOGO_DOMAINS constant to definitions/mod.rs for shared use
- Build CSP img-src dynamically from ALLOWED_LOGO_DOMAINS (keeps test + CSP in sync)
- Allow PostHog analytics (ph.scanopy.net) in script-src and connect-src
- Allow 'unsafe-inline' in script-src for SvelteKit adapter-static inline scripts
- Add chrono-tz dependency and timezone field to RunType::Scheduled
- Use JobBuilder with .with_timezone() for DST-correct cron evaluation
- Validate timezone on create/update, reschedule on timezone change
- Replace frequency days/hours UI with day-of-week toggles + time picker
- Add raw cron editor toggle for advanced users
- Add timezone selector defaulting to browser timezone
- Add TimeInput.svelte component following DateInput pattern
- Update schedule card to show "Mon, Wed at 03:00 (America/New_York)"
- Backward compatible: existing records without timezone default to UTC
- Replace single-origin CORS with mirror_request() to reflect any
  requesting origin, enabling browser-based API key consumers from
  arbitrary domains
- Use AllowCredentials::predicate() to send credentials header only
  for app.scanopy.net and demo.scanopy.net origins (session cookies)
- Give health endpoint its own permissive CORS layer (Any origin,
  GET only) so marketing site and uptime monitors can reach it
- Remove unnecessary cors.clone() since cors is now used only once
- Add scan_subnet_streaming() to sendarp.rs that returns mpsc::Receiver,
  matching the broadcast ARP interface for the discovery pipeline
- Wire up SendARP streaming in arp/mod.rs so Windows daemons with
  use_npcap=false can scan subnets
- Fix Npcap fallback: when use_npcap=true but broadcast fails, fall
  through to SendARP instead of returning the error
- Host modal: all 7 tabs always visible, progressively unlocked via
  furthestReached as user advances through wizard steps. Data-dependent
  tabs (IF Entries, Virtualization) disabled based on data availability.
- Group modal: all 3 tabs always visible, same progressive unlock pattern.
- Both modals use enabledTabs derivation for navigation, skipping disabled
  tabs when clicking Next/Back.
- Edit mode: all wizard-step tabs enabled (data-dependent tabs still
  conditional). Matches existing daemon modal pattern.
- Add hidden `website` field to RegisterRequest (backend + frontend)
- If filled, return fake 200 success without creating user/org/session
- Log blocked attempts with IP, email, and honeypot value
- Hidden input uses off-screen positioning, aria-hidden, tabindex=-1
- Wrap SnmpQueryCredential.community in redact::Secret<String> so it is
  redacted by default in Debug output, serde serialization, SSE streams,
  and all API responses
- Add to_daemon_value()/to_exposed_value() for the single code path that
  needs plaintext: HTTP transmission to the daemon for SNMP queries
- Remove sanitized() chain — no longer needed since Secret<String>
  handles redaction at the type level
- Wrap day-of-week buttons in form.Field for Svelte 5 reactivity
  (field.state.value triggers re-render, form.state.values did not)
- Use bail_validation! for invalid timezone (returns 400 not 500)
- Collapse if-let per clippy collapsible_if lint
- Use wizardSteps array for last-step detection instead of enabledTabs
  length (enabledTabs only had 1 item at furthestReached=0, causing
  immediate submit instead of advancing)
- IF Entries tab now always enabled in edit mode (shows empty state
  message when no data); still disabled in create mode without data
…c::string::String]

Custom serialize_with function matches the convention used by
SnmpCredentialBase's redact_secret serializer.
@const inside {#each} evaluates once and never re-evaluates when
field.state.value changes. Replaced with isDaySelected() and
toggleDay() helper functions that read field.state.value on each
render, allowing Svelte 5 to track the reactive dependency.
mayanayza and others added 29 commits February 28, 2026 10:08
- Create OsSelector.svelte with OS button group, Linux binary/docker
  sub-toggle, and FreeBSD/OpenBSD unsupported warnings with PostHog
  feature-request buttons
- Update InstallStep.svelte and DaemonUpgradeModal.svelte to use
  OsSelector, eliminating ~60 lines of duplicated markup each
- Add i18n keys for upgrade-specific labels (upgradeDownload,
  upgradeRestartProcess, upgradeRestartSystemd)
The previous order (download, then restart) doesn't make sense for
macOS/Windows where no service manager handles the process. Reorder
to: (1) stop daemon, (2) download new version, (3) start daemon.
Linux systemd stays as download + restart since systemctl handles it.
- Add copyable stop/start commands for macOS (pkill/scanopy-daemon)
  and Windows (Stop-Process/exe) instead of generic text
- Include --name flag in start commands for custom-named daemons
- Add "config preserved" info note so users know no flags are needed
- Show actual target version in Docker pinned image tag (v0.14.9)
  instead of :latest
Linux binary previously used download + systemctl restart, which
assumed a default service name and didn't handle custom daemon names.
Now all platforms (Linux, macOS, Windows) use the same 3-step flow:
stop daemon, download update, start daemon — with --name flag
included when the daemon has a custom name.
- Always include --name flag in start commands for all platforms,
  since users may run multiple daemons on one machine
- Unify Linux binary upgrade to same stop/download/start flow as
  macOS and Windows (removes systemd-specific restart)
- Make upgrade modal deep-linkable via ?modal=upgrade-daemon&id=<id>
Show the "config is preserved" info once at the top of the upgrade
modal rather than repeated at the bottom of each OS section.
Adds an InlineInfo note to each binary upgrade section (Linux, macOS,
Windows) warning users with multiple daemons that they share the same
binary and need to restart each one individually. Includes a
platform-specific command to list daemon config directories. Also bumps
modal size from lg to xl.
Replace clunky InlineInfo + CodeContainer combo with a native <details>
element. When collapsed, shows a single clickable line "Running multiple
daemons on this machine?" that most users skip. When expanded, shows
explanation, platform-specific config listing command, and link to
docs at scanopy.net/docs/multiple-daemons/.
Move collapsible details between "Step 3" label and its code container
so it reads as a sub-note of the step. Style summary as text-tertiary
for visual distinction from step headers. Replace arrow entity with
ExternalLink icon from lucide-svelte, matching BlockerFlow convention.
Replace {@html} docs links with a DocsHint component that renders the
lucide ExternalLink icon natively. i18n keys now use a {link} placeholder
so translators can position the link freely in each language's sentence
structure. Removes .docs-hint CSS from InstallStep and AdvancedStep.

Also updates the multiple daemons question to be use-case oriented:
"Scanning multiple networks from a single machine?"

Adds docs hint for multiple daemons to the install step alongside
existing multi-VLAN and macvlan hints.
Prevents checkboxes from being interleaved with text/number inputs
in the 2-column grid, keeping the layout visually clean.
…mon_docsLink

Paraglide was interpreting {link} as a parameter and replacing it with
undefined. Switch to %link% which paraglide ignores, letting DocsHint
split on it instead.

Extract common_docsLink ("For more details, see the %link%.") for
generic docs hints. Remove redundant daemons_docsDockerProxy and
daemons_docsMultipleDaemons text keys. Keep macvlan question format
since it adds useful context.
… step

The create daemon modal needs contextual framing ("Scanning multiple
networks from a single machine?") since the user may not be aware of the
feature. The upgrade modal keeps common_docsLink since the user has
already expanded the multi-daemon details section.
- Bump svelte 5.53.2 → 5.53.6 (fixes XSS in SSR hydration markers and contenteditable binding)
- Bump minimatch 10.2.2 → 10.2.4 (fixes ReDoS in matchOne)
- Move isLastWizardStep declaration before first use in GroupEditModal
- Add email campaign docs to gitignore
@mayanayza mayanayza merged commit ff4e843 into main Feb 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant