SHA256
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.
48 lines
2.0 KiB
Swift
48 lines
2.0 KiB
Swift
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."
|
|
}
|
|
}
|
|
}
|