feat: federation batch 1+2 — bug fixes and password enforcement

Batch 1 — Bug fixes:
- Fix stale voice state on remote reconnect (clearVoiceUsersForOrigin)
- Fix logout not cleaning remote servers from store
- Fix reply-to asset normalization for remote messages
- Fix HTTPS hardcoded in autoConnectAll (store full origin, legacy fallback)

Batch 2 — Password enforcement + replication flow:
- Add connectToRemote() with home password verification before remote auth
- Auto-cascade: verify home password → register on remote → login fallback
- Replace Register/Login tabs with single password field in ConnectedInstances
- Add DifferentPasswordError for typed fallback-login UI transition
- Fallback login form shown only when remote has different password
This commit is contained in:
Jannis Braun
2026-03-04 01:51:38 +01:00
parent 3f15a8e282
commit 64fd8edfc9
7 changed files with 232 additions and 139 deletions
+15
View File
@@ -2,6 +2,7 @@ import { create } from 'zustand';
import { persist, createJSONStorage } from 'zustand/middleware';
import type { ParticipantInfo } from '../hooks/useLiveKit';
import { AudioManager } from '../audio/AudioManager';
import { useServerStore } from './serverStore';
export interface ScreenShareConfig {
height: 1080 | 720 | 540;
@@ -87,6 +88,7 @@ interface VoiceState {
clearVoiceUserStatus: (userId: string) => void;
getVoiceUsers: (channelId: string) => string[];
clearAllVoiceUsers: () => void;
clearVoiceUsersForOrigin: (origin: string) => void;
leaveVoice: () => void;
reset: () => void;
}
@@ -275,6 +277,19 @@ export const useVoiceStore = create<VoiceState>()(
clearAllVoiceUsers: () => set({ voiceUsers: new Map(), voiceUserStates: new Map() }),
clearVoiceUsersForOrigin: (origin: string) => {
const { channelOriginMap } = useServerStore.getState();
set((state) => {
const newVoiceUsers = new Map(state.voiceUsers);
for (const [channelId] of newVoiceUsers) {
if ((channelOriginMap.get(channelId) ?? '') === origin) {
newVoiceUsers.delete(channelId);
}
}
return { voiceUsers: newVoiceUsers };
});
},
// Leave voice without wiping the voiceUsers map (so sidebar still shows others)
leaveVoice: () => set({
currentVoiceChannelId: null,