Fix web UI messaging, alias resolution, and onboarding
Messaging: - Append \n to WS IPC sends so bufio.Scanner fires (messages from web were silently dropped — the line scanner never saw a newline) - Handle session_ready in web store to update peer aliases after hello Alias resolution: - Seed AddPeer alias from SQLite cache so returning peers resolve immediately, before hello exchange completes - Remove stale SavePeer call from AddPeer (was writing placeholder IDs) - Add PeerAlias() point-lookup to store Onboarding redesign: - Three-state UI: disconnected (daemon instructions), connecting, connected-no-network (join form) - Read ?n= / ?network= / ?anchor= / ?invite=waste:... URL params to pre-fill the join form for invite links - Show daemon alias + peer ID before any network is joined (master_alias + master_id now included in state_snapshot) - Identity backup: export (passphrase-protected yaw-key-backup-1 JSON, download button) and restore (paste + passphrase verify) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -345,9 +345,12 @@ func handleClient(conn net.Conn, mgr *netmgr.Manager) {
|
||||
func stateSnapshot(mgr *netmgr.Manager) proto.IpcMessage {
|
||||
all := mgr.All()
|
||||
|
||||
master := mgr.MasterIdentity()
|
||||
msg := proto.IpcMessage{
|
||||
Type: proto.EvtStateSnapshot,
|
||||
Rooms: []string{"general"},
|
||||
Type: proto.EvtStateSnapshot,
|
||||
Rooms: []string{"general"},
|
||||
MasterAlias: master.Alias,
|
||||
MasterID: string(master.PeerID()),
|
||||
}
|
||||
|
||||
var netInfos []proto.NetworkInfo
|
||||
|
||||
@@ -89,16 +89,17 @@ func (m *Mesh) ScanShareDir() []proto.FileEntry {
|
||||
|
||||
// AddPeer registers a connected peer and notifies subscribers.
|
||||
func (m *Mesh) AddPeer(conn *PeerConn) {
|
||||
// Seed alias from cache so returning peers resolve immediately (before hello).
|
||||
if m.Store != nil {
|
||||
if cached := m.Store.PeerAlias(conn.Info.ID); cached != "" {
|
||||
conn.Info.Alias = cached
|
||||
}
|
||||
}
|
||||
|
||||
m.mu.Lock()
|
||||
m.peers[conn.Info.ID] = conn
|
||||
m.mu.Unlock()
|
||||
|
||||
if m.Store != nil && conn.Info.Alias != "" {
|
||||
if err := m.Store.SavePeer(conn.Info.ID, conn.Info.Alias); err != nil {
|
||||
log.Printf("mesh: store peer %s: %v", conn.Info.ID.Short(), err)
|
||||
}
|
||||
}
|
||||
|
||||
m.emit(proto.IpcMessage{
|
||||
Type: proto.EvtPeerConnected,
|
||||
Peer: &conn.Info,
|
||||
|
||||
@@ -280,6 +280,8 @@ type IpcMessage struct {
|
||||
BytesReceived int64 `json:"bytes_received,omitempty"`
|
||||
TotalBytes int64 `json:"total_bytes,omitempty"`
|
||||
// state_snapshot fields (existing shape preserved for backward compat)
|
||||
MasterAlias string `json:"master_alias,omitempty"` // daemon's alias (available before any network join)
|
||||
MasterID string `json:"master_id,omitempty"` // daemon's master public key hex
|
||||
LocalPeer *PeerInfo `json:"local_peer,omitempty"`
|
||||
ConnectedPeers []PeerInfo `json:"connected_peers,omitempty"`
|
||||
Rooms []string `json:"rooms,omitempty"`
|
||||
|
||||
@@ -77,6 +77,13 @@ func (s *Store) SavePeer(peerID proto.PeerID, alias string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// PeerAlias returns the cached alias for a peer, or "" if unknown.
|
||||
func (s *Store) PeerAlias(peerID proto.PeerID) string {
|
||||
var alias string
|
||||
s.db.QueryRow(`SELECT alias FROM peers WHERE peer_id = ?`, string(peerID)).Scan(&alias) //nolint:errcheck
|
||||
return alias
|
||||
}
|
||||
|
||||
// RecentMessages returns up to limit messages for a room, oldest first.
|
||||
func (s *Store) RecentMessages(room string, limit int) ([]proto.ChatMessage, error) {
|
||||
rows, err := s.db.Query(
|
||||
|
||||
Reference in New Issue
Block a user