SHA256
feat(ios): implement SwiftUI companion with isolated WKWebView sessions
Add HTTPS onboarding, origin policy, native recovery/settings, isolated web sign-in and file export. Portable production URL policy tests pass on Linux; all Swift sources parse. Xcode build and simulator validation remain required on macOS.
This commit is contained in:
1 parent
ed8d5cb1c1
commit
74c2c9e6e8
11 files changed
+691
No files matched your search
@@ -0,0 +1,47 @@
|
||||
import Foundation
|
||||
|
||||
struct ServerAddress: Equatable {
|
||||
let url: URL
|
||||
|
||||
init(_ input: String) throws {
|
||||
let value = input.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
guard !value.contains("\\"), !value.contains(where: { $0.isWhitespace }),
|
||||
var parts = URLComponents(string: value),
|
||||
parts.scheme?.lowercased() == "https",
|
||||
let host = parts.host, !host.isEmpty,
|
||||
parts.user == nil, parts.password == nil,
|
||||
parts.query == nil, parts.fragment == nil,
|
||||
parts.percentEncodedPath.isEmpty || parts.percentEncodedPath == "/",
|
||||
parts.port == nil || (1...65535).contains(parts.port!) else {
|
||||
throw ConnectionError.invalidAddress
|
||||
}
|
||||
parts.scheme = "https"
|
||||
parts.host = host.lowercased()
|
||||
parts.path = ""
|
||||
if parts.port == 443 { parts.port = nil }
|
||||
guard let url = parts.url else { throw ConnectionError.invalidAddress }
|
||||
self.url = url
|
||||
}
|
||||
|
||||
func owns(_ candidate: URL) -> Bool {
|
||||
guard let parts = URLComponents(url: candidate, resolvingAgainstBaseURL: false),
|
||||
let own = URLComponents(url: url, resolvingAgainstBaseURL: false) else { return false }
|
||||
return parts.scheme?.lowercased() == "https" && parts.user == nil && parts.password == nil
|
||||
&& parts.host?.lowercased() == own.host?.lowercased()
|
||||
&& (parts.port ?? 443) == (own.port ?? 443)
|
||||
}
|
||||
}
|
||||
|
||||
enum ConnectionError: LocalizedError {
|
||||
case invalidAddress, incompatible, unavailable
|
||||
var errorDescription: String? {
|
||||
switch self {
|
||||
case .invalidAddress:
|
||||
return "Use a root HTTPS URL with a valid host and port. Remove credentials, subpaths, query and fragment."
|
||||
case .incompatible:
|
||||
return "This server does not expose compatible Yuvomi metadata."
|
||||
case .unavailable:
|
||||
return "Cannot verify the server. Check its certificate, VPN, network and reverse proxy."
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user