mirror of
https://github.com/home-assistant/iOS.git
synced 2026-04-13 10:53:45 -05:00
60 lines
2.0 KiB
Swift
60 lines
2.0 KiB
Swift
import Foundation
|
|
import Shared
|
|
import WebKit
|
|
|
|
/// Use to avoid holding webview alive when adding WKScriptMessageHandler
|
|
final class SafeScriptMessageHandler: NSObject, WKScriptMessageHandler {
|
|
let server: Server
|
|
weak var delegate: WKScriptMessageHandler?
|
|
init(server: Server, delegate: WKScriptMessageHandler) {
|
|
self.server = server
|
|
self.delegate = delegate
|
|
super.init()
|
|
}
|
|
|
|
func userContentController(
|
|
_ userContentController: WKUserContentController,
|
|
didReceive message: WKScriptMessage
|
|
) {
|
|
// Only the top-level document on an allowed server origin may talk to the native bridge.
|
|
guard shouldAllowMessage(
|
|
isMainFrame: message.frameInfo.isMainFrame,
|
|
scheme: message.frameInfo.securityOrigin.protocol,
|
|
host: message.frameInfo.securityOrigin.host,
|
|
port: message.frameInfo.securityOrigin.port
|
|
) else {
|
|
return
|
|
}
|
|
delegate?.userContentController(
|
|
userContentController, didReceive: message
|
|
)
|
|
}
|
|
|
|
func shouldAllowMessage(isMainFrame: Bool, scheme: String, host: String, port: Int) -> Bool {
|
|
isMainFrame && allowedOrigins.contains(originKey(scheme: scheme, host: host, port: port))
|
|
}
|
|
|
|
private var allowedOrigins: Set<String> {
|
|
let urls = [
|
|
server.info.connection.address(for: .internal),
|
|
server.info.connection.address(for: .external),
|
|
server.info.connection.address(for: .remoteUI),
|
|
]
|
|
|
|
return Set(urls.compactMap(originKey(url:)))
|
|
}
|
|
|
|
private func originKey(url: URL?) -> String? {
|
|
guard let url, let scheme = url.scheme?.lowercased(), let host = url.host,
|
|
let port = url.portWithFallback else {
|
|
return nil
|
|
}
|
|
|
|
return originKey(scheme: scheme, host: host, port: port)
|
|
}
|
|
|
|
private func originKey(scheme: String, host: String, port: Int) -> String {
|
|
"\(scheme.lowercased())://\(host.lowercased()):\(port)"
|
|
}
|
|
}
|