feat: server config, token client, TLS pinning, connection test (Phase 1)

ServerConfig parses https base URL and derives wss livekit URL;
TokenClient POSTs /token with clean 503/offline error states;
TLSPinning holds optional cert SHA-384 pins (empty = system trust);
Settings gains a Connection test screen proving the endpoint works.
This commit is contained in:
snowspeeder committed 2026-08-29 17:18:38 -04:00
1 parent 297fbaa19c
commit 378b8cb36f
7 files changed
+263

No files matched your search

+24
View File
@@ -8,9 +8,13 @@
/* Begin PBXBuildFile section */
1ECD63F10A8EAF33FD2A5B62 /* VoiceApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FED8976B60FBC13BC980FCB /* VoiceApp.swift */; };
302BEC55CA9A10E49C307977 /* ServerConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5683993A1DE677121FFA1F3 /* ServerConfig.swift */; };
36DF44D9A7896F18A064847D /* ConversationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F3FA9F420065D2127B0AEC0 /* ConversationView.swift */; };
720C26EC163AE46713B02DD8 /* TLSPinning.swift in Sources */ = {isa = PBXBuildFile; fileRef = D9B40076934C28BA4B92D808 /* TLSPinning.swift */; };
8DE1363CC0119B5AF9E4E117 /* ConnectionTestView.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC4B9073EE8EAB51F8C55760 /* ConnectionTestView.swift */; };
98BA1A0F92DB7B98A8BA7814 /* SettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48F76881B4AE51DEE74511CC /* SettingsView.swift */; };
A94F6C509E3FE215115B2C58 /* SettingsStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D0D153557BB1C756ED04C61 /* SettingsStore.swift */; };
D18AD347DFF72AB6361165BA /* TokenClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9681E7410B684D2D38752A70 /* TokenClient.swift */; };
D9A0059E342955A06A021D6C /* LiveKit in Frameworks */ = {isa = PBXBuildFile; productRef = A6BAD55715F383C0DB5F306F /* LiveKit */; };
/* End PBXBuildFile section */
@@ -20,6 +24,10 @@
3F3FA9F420065D2127B0AEC0 /* ConversationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConversationView.swift; sourceTree = "<group>"; };
48F76881B4AE51DEE74511CC /* SettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsView.swift; sourceTree = "<group>"; };
6D0D153557BB1C756ED04C61 /* SettingsStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsStore.swift; sourceTree = "<group>"; };
9681E7410B684D2D38752A70 /* TokenClient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TokenClient.swift; sourceTree = "<group>"; };
AC4B9073EE8EAB51F8C55760 /* ConnectionTestView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConnectionTestView.swift; sourceTree = "<group>"; };
D9B40076934C28BA4B92D808 /* TLSPinning.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TLSPinning.swift; sourceTree = "<group>"; };
F5683993A1DE677121FFA1F3 /* ServerConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerConfig.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -37,11 +45,22 @@
0DF0591DF1D767F89099F62C /* Settings */ = {
isa = PBXGroup;
children = (
AC4B9073EE8EAB51F8C55760 /* ConnectionTestView.swift */,
48F76881B4AE51DEE74511CC /* SettingsView.swift */,
);
path = Settings;
sourceTree = "<group>";
};
6B2AB34274D9B37E77178C6C /* Networking */ = {
isa = PBXGroup;
children = (
F5683993A1DE677121FFA1F3 /* ServerConfig.swift */,
D9B40076934C28BA4B92D808 /* TLSPinning.swift */,
9681E7410B684D2D38752A70 /* TokenClient.swift */,
);
path = Networking;
sourceTree = "<group>";
};
6F99423E59017FED59B4D71D /* Products */ = {
isa = PBXGroup;
children = (
@@ -89,6 +108,7 @@
children = (
CE49A38E40AAF659A9281B85 /* App */,
8DA8BEF2EE3E0F4181A94EB9 /* Features */,
6B2AB34274D9B37E77178C6C /* Networking */,
);
path = Sources;
sourceTree = "<group>";
@@ -156,9 +176,13 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
8DE1363CC0119B5AF9E4E117 /* ConnectionTestView.swift in Sources */,
36DF44D9A7896F18A064847D /* ConversationView.swift in Sources */,
302BEC55CA9A10E49C307977 /* ServerConfig.swift in Sources */,
A94F6C509E3FE215115B2C58 /* SettingsStore.swift in Sources */,
98BA1A0F92DB7B98A8BA7814 /* SettingsView.swift in Sources */,
720C26EC163AE46713B02DD8 /* TLSPinning.swift in Sources */,
D18AD347DFF72AB6361165BA /* TokenClient.swift in Sources */,
1ECD63F10A8EAF33FD2A5B62 /* VoiceApp.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;