// /* * Copyright (c) 2021 BWI GmbH * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import Foundation let configKey = "com.apple.configuration.managed" extension UserDefaults { @objc dynamic var appConfigData: Dictionary? { get { return dictionary(forKey: configKey) } set { set(newValue, forKey: configKey) } } } @objcMembers class AppConfigService : NSObject { static let shared = AppConfigService() private let serverUrlKey = "home_server_url" private let contentScannerKey = "contentScanner" private let pusherUrlKey = "pusherUrl" private let permalinkUrlKey = "permalinkUrl" private let savedConfig = "savedAppConfig" var appConfig = AppConfig() var completion: ((Bool) -> Void)? var configObserver: NSKeyValueObservation! var session: MXSession? var isAppConfig: Bool private func loadAppConfig() { isAppConfig = false do { if let dataIn = UserDefaults.standard.value(forKey: savedConfig) as? Data { appConfig = try JSONDecoder().decode(AppConfig.self, from: dataIn) isAppConfig = true } } catch { } } private func saveAppConfig() { do { let dataOut = try JSONEncoder().encode(appConfig) UserDefaults.standard.setValue(dataOut, forKey: savedConfig) } catch { } } private func checkUrlSavety(_ serverUrl: String) -> Bool { if BWIBuildSettings.shared.bwiEnableLoginProtection { let protectionService = LoginProtectionService() protectionService.hashes = BWIBuildSettings.shared.bwiHashes return protectionService.isValid(serverUrl) } else { return true } } override init() { isAppConfig = false super.init() self.loadAppConfig() } func registerForAppConfig() { NotificationCenter.default.addObserver(forName: UserDefaults.didChangeNotification, object: nil, queue: OperationQueue.main) { [self] (note) in handleAppConfig() } } func handleAppConfig() { if let dict = UserDefaults.standard.dictionary(forKey: configKey) { var config = AppConfig() if let serverUrl = dict[serverUrlKey] as? String { if serverUrl.count == 0 { config.serverUrl = nil } else if checkUrlSavety(serverUrl) { config.serverUrl = serverUrl } } if let contentScannerUrl = dict[contentScannerKey] as? String { if checkUrlSavety(contentScannerUrl) { config.contentScannerUrl = contentScannerUrl } } if let pusherUrl = dict[pusherUrlKey] as? String { if checkUrlSavety(pusherUrl) { config.pusherUrl = pusherUrl } } if let permalinkUrl = dict[permalinkUrlKey] as? String { if checkUrlSavety(permalinkUrl) { config.permalinkUrl = permalinkUrl } } // app config needs at least a valid server url isAppConfig = (config.serverUrl != nil) if config != appConfig { appConfig = config self.saveAppConfig() if let completion = completion { completion(true) } } UserDefaults.standard.removeObject(forKey: configKey) } } func resetConfig() { appConfig = AppConfig() self.saveAppConfig() } func serverUrl() -> String { if let url = appConfig.serverUrl { return url } else if let url = ServerURLHelper.shared.serverUrl() { return url } else if let session = session, let restClient = session.matrixRestClient { return restClient.homeserver } else { return BWIBuildSettings.shared.serverConfigDefaultHomeserverUrlString } } func pusherUrl() -> String { if let url = appConfig.pusherUrl { return url } else { return BWIBuildSettings.shared.serverConfigSygnalAPIUrlString } } func permalinkUrl() -> String? { if let url = appConfig.permalinkUrl { return "https://" + url } else if let url = ServerURLHelper.shared.httpsPermalink() { return url } else { return BWIBuildSettings.shared.clientPermalinkBaseUrl } } }