Skip to content

feat(invite): privacy + expiry + trust gate + network CTA polish - #54

Merged
8144225309 merged 1 commit into
mainfrom
polish/invite-flow
May 29, 2026
Merged

feat(invite): privacy + expiry + trust gate + network CTA polish#54
8144225309 merged 1 commit into
mainfrom
polish/invite-flow

Conversation

@8144225309

Copy link
Copy Markdown
Owner

Summary

Four invite-flow gaps surfaced during visual review of PR #53 (manual-connect modal). Each is small and self-contained.

1. inviteUrl.ts — expiry codec

  • Adds optional expires=<unix-ts> URL param
  • New parseInviteUrlDetailed(url) returns {invite, error: 'malformed' | 'expired' | null} so callers can distinguish bad-URL from stale-invite for UX messaging
  • parseInviteUrl kept as thin wrapper (backwards compat)

2. InviteModal (LSP-host side)

  • Expiry dropdown — Never / 1d / 1w / 30d / 90d. Embeds expires only when set; existing permanent-invite behavior is the default.
  • Tor-preferred toggle — when both .onion and ipv4 are advertised, default to broadcasting the .onion so casual invite-sharing doesn't leak the operator's public IP. Operator can flip back.
  • Privacy warning Alert when the chosen address is a public-routable IP (RFC1918 + loopback + .onion suppressed). Surfaces the leaked address and points the operator at the tor toggle.

3. AcceptInviteModal (client side)

  • Uses parseInviteUrlDetailed so expired invites get a clear "ask the LSP operator for a fresh one" message instead of generic "malformed URL".
  • Trust gate — if the parsed address is public-routable, render a warning Alert with an "I trust the source of this invite" checkbox. The Send-join-request button stays disabled until ticked.
  • Tor info note when the invite uses an .onion address (positive feedback).

4. ConnectList — profile-switch CTA

When the active node's network has no coordinator binding (common on regtest / sandbox profiles), the empty-state row now lists the user's other profiles that ARE covered and offers one-click switch buttons. Reuses the same NodesService.switchNode flow as NodePicker (clear stores → switch → refetch).

Test plan

  • Build / eslint / tests green in CI
  • Visual sweep against demo wallet after deploy:
    • Invite modal renders expiry dropdown
    • Invite modal renders tor toggle when both .onion + ipv4 present
    • Invite modal renders privacy warning when address resolves to public IP
    • Accept modal shows "expired" error for stale invites
    • Accept modal shows trust gate + disables Send for public IPs
    • Connect page empty state on regtest profile shows switch-to-testnet4 button and the switch fires

Four invite-flow gaps surfaced during PR #53 visual review:

1. inviteUrl.ts — add optional expires=<unix-ts> param + parseInviteUrlDetailed
   returning {invite, error: 'malformed' | 'expired' | null} so callers can
   distinguish bad URL from stale invite for UX messaging.

2. InviteModal (LSP host) —
   - Expiry dropdown (Never / 1d / 1w / 30d / 90d); embeds `expires` only
     when set so existing permanent-invite behavior is preserved by default.
   - Tor-preferred toggle: if the node advertises both .onion and ipv4,
     default to broadcasting the onion so casual invite-sharing doesn't
     leak the operator's IP. Operator can flip back.
   - Privacy warning Alert when the chosen address is a public-routable
     IP (RFC1918/loopback/.onion suppressed); shows the leaked address
     and points the operator at the tor toggle.

3. AcceptInviteModal (client side) —
   - Uses parseInviteUrlDetailed so expired invites surface a clear
     "ask the LSP operator for a fresh one" message instead of generic
     "malformed URL".
   - Trust gate: if the parsed address is public-routable, render a
     warning Alert with an "I trust the source of this invite" checkbox;
     the Send-join-request button stays disabled until ticked.
   - Tor info note when the invite uses an .onion address.

4. ConnectList — when the active node's network has no coordinator
   binding (common on regtest/sandbox profiles), the empty-state row
   now lists the user's *other* profiles that ARE covered and offers
   one-click switch buttons that reuse the same NodesService.switchNode
   flow as NodePicker (clear stores → switch → refetch).

testids added (sweep-friendly): invite-expiry, invite-prefer-tor,
invite-privacy-warning, accept-invite-trust-gate, accept-invite-trust-ack,
accept-invite-tor-note, connect-no-coord-empty, connect-switch-<network>.
@8144225309
8144225309 merged commit a2bedac into main May 29, 2026
3 checks passed
@8144225309
8144225309 deleted the polish/invite-flow branch May 29, 2026 11:00
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