fix: Tor management system, bug fixes, federation name sync

Major changes:
- Full Tor hidden service management via systemd path unit pattern
  (tor-helper.sh + archipelago-tor-helper.path/service) — respects
  NoNewPrivileges=yes, no sudo needed from backend
- Container doctor: prefer system Tor over container, remove archy-tor
- Deploy script: fix torrc generation (read correct services.json path),
  web apps map port 80→local port, enable both tor and tor@default
- Federation: server rename pushes name to peers via background sync
- Server name: fix root-owned file, optimistic store update
- Mesh: local echo for sent messages, sendingArch loading state
- Web5: Message button → Mesh redirect, node name lookup in messages
- PeerFiles: show DID not onion in header
- Connected Nodes: flex-1 instead of fixed max-h
- Toast notifications route to Mesh
- Deploy script: fix single-quote syntax in SSH block

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Dorian
2026-03-20 02:59:29 +00:00
parent 4c0c8a83a9
commit fc1120338d
15 changed files with 904 additions and 250 deletions

View File

@@ -60,9 +60,12 @@ async function loadArchMessages() {
} catch { /* silent */ }
}
const sendingArch = ref(false)
async function sendArchMessage() {
if (!messageText.value.trim()) return
sendError.value = ''
sendingArch.value = true
try {
// Broadcast to all federated peers over Tor
const nodes = await rpcClient.federationListNodes()
@@ -74,12 +77,20 @@ async function sendArchMessage() {
sent++
} catch { /* some peers may be offline */ }
}
// Local echo — show the sent message immediately
archMessages.value.push({
from_pubkey: 'me',
message: msg,
timestamp: new Date().toISOString(),
})
messageText.value = ''
if (sent === 0) sendError.value = 'No peers reachable'
// Reload to see the message
setTimeout(loadArchMessages, 2000)
if (sent === 0) sendError.value = 'No peers reachable — message may arrive when they come online'
// Also reload in background to pick up any replies
setTimeout(loadArchMessages, 5000)
} catch (e) {
sendError.value = e instanceof Error ? e.message : 'Send failed'
} finally {
sendingArch.value = false
}
}
@@ -314,8 +325,8 @@ const chatMessages = computed(() => {
return archMessages.value.map((m, i) => ({
id: i,
peer_contact_id: -99,
peer_name: m.from_pubkey.slice(0, 12) + '...',
direction: 'received' as const,
peer_name: m.from_pubkey === 'me' ? 'You' : (m.from_pubkey.slice(0, 12) + '...'),
direction: (m.from_pubkey === 'me' ? 'sent' : 'received') as 'sent' | 'received',
plaintext: m.message,
timestamp: m.timestamp,
delivered: true,
@@ -747,10 +758,10 @@ function truncatePubkey(hex: string | null): string {
/>
<button
class="glass-button mesh-chat-send-btn"
:disabled="!messageText.trim() || mesh.sending"
:disabled="!messageText.trim() || mesh.sending || sendingArch"
@click="handleSendMessage"
>
{{ mesh.sending ? '...' : 'Send' }}
{{ (mesh.sending || sendingArch) ? '...' : 'Send' }}
</button>
</div>
</div>