Files
bundesmessenger-ios/bwi/AppConfig/AppConfigService.swift
2024-02-27 14:36:30 +01:00

207 lines
6.5 KiB
Swift

//
/*
* 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<String, Any>?
{
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 externalUrlSchemeKey = "external_url_scheme"
private let federationAnnouncementKey = "should_show_federation_announcement"
private let savedConfig = "savedAppConfig"
var appConfig = AppConfig()
var completion: ((Bool, String) -> Void)?
var configObserver: NSKeyValueObservation!
var session: MXSession?
var isAppConfig: Bool
var lastDictionary: [String: Any]?
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()
}
deinit {
NotificationCenter.default.removeObserver(self)
}
private func isSameConfig( dict: [String: Any]) -> Bool {
if let lastDictionary = lastDictionary {
if lastDictionary.count != dict.count {
return false
}
if let newURl = dict[serverUrlKey] as? String, let oldURL = lastDictionary[serverUrlKey] as? String, newURl == oldURL {
return true
}
}
return false
}
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) {
// only compute if serverURL has not changed (this may need to be changed on Adminportal integration
if !isSameConfig(dict: dict) {
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
}
}
if let externalUrlScheme = dict[externalUrlSchemeKey] as? String {
config.externalUrlScheme = externalUrlScheme
}
// app config needs at least a valid server url
if let serverUrl = config.serverUrl {
isAppConfig = true
appConfig = config
lastDictionary = dict
self.saveAppConfig()
if let completion = self.completion {
completion(true, serverUrl)
}
}
}
}
}
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? {
ServerURLHelper.shared.selectedIndex = ServerURLHelper.shared.indexOf(self.serverUrl())
if let url = appConfig.permalinkUrl {
return "https://" + url
} else if let url = ServerURLHelper.shared.httpsPermalink() {
return url
} else {
return BWIBuildSettings.shared.clientPermalinkBaseUrl
}
}
func externalUrlScheme() -> String? {
return appConfig.externalUrlScheme
}
}