diff --git a/Extensions/FileImportShareExtension/UI/ShareViewController.swift b/Extensions/FileImportShareExtension/UI/ShareViewController.swift index 53dc8707..e5c1ac4c 100644 --- a/Extensions/FileImportShareExtension/UI/ShareViewController.swift +++ b/Extensions/FileImportShareExtension/UI/ShareViewController.swift @@ -17,16 +17,13 @@ * */ +import CommonsLib import UIKit import SwiftUI -import OSLog import UniformTypeIdentifiers import FactoryKit -class ShareViewController: UIViewController, Sendable { - - private static let logger = Logger(subsystem: "ee.ria.digidoc.RIADigiDoc", category: "ShareViewController") - +class ShareViewController: UIViewController, Sendable, Loggable { let viewModel = Container.shared.shareViewModel() override func viewDidLoad() { @@ -127,7 +124,7 @@ class ShareViewController: UIViewController, Sendable { )) } } catch let error { - ShareViewController.logger.error("Unable to load item: \(error.localizedDescription)") + ShareViewController.logger().error("Unable to load item: \(error.localizedDescription)") } } } diff --git a/Extensions/FileImportShareExtension/ViewModel/ShareViewModel.swift b/Extensions/FileImportShareExtension/ViewModel/ShareViewModel.swift index f2365933..07322c02 100644 --- a/Extensions/FileImportShareExtension/ViewModel/ShareViewModel.swift +++ b/Extensions/FileImportShareExtension/ViewModel/ShareViewModel.swift @@ -18,7 +18,6 @@ */ import Foundation -import OSLog import UniformTypeIdentifiers import FactoryKit import CommonsLib @@ -27,12 +26,7 @@ import Alamofire @Observable @MainActor -class ShareViewModel: ShareViewModelProtocol { - private static let logger = Logger( - subsystem: "ee.ria.digidoc.FileImportShareExtension", - category: "ShareViewController" - ) - +class ShareViewModel: ShareViewModelProtocol, Loggable { private let fileManager: FileManagerProtocol private let resourceChecker: URLResourceCheckerProtocol @@ -48,7 +42,7 @@ class ShareViewModel: ShareViewModelProtocol { @discardableResult func importFiles(_ items: [ImportedFileItem]) async -> Bool { - ShareViewModel.logger.debug("Importing files...") + ShareViewModel.logger().debug("Importing files...") guard !items.isEmpty else { await MainActor.run { [weak self] in self?.status = .failed @@ -63,9 +57,9 @@ class ShareViewModel: ShareViewModelProtocol { ) if isImported { - ShareViewModel.logger.debug("Files imported successfully") + ShareViewModel.logger().debug("Files imported successfully") } else { - ShareViewModel.logger.error("Could not import files") + ShareViewModel.logger().error("Could not import files") } await MainActor.run { [weak self] in @@ -74,7 +68,7 @@ class ShareViewModel: ShareViewModelProtocol { return isImported } catch { - ShareViewModel.logger.error("Unable to import files: \(error.localizedDescription)") + ShareViewModel.logger().error("Unable to import files: \(error.localizedDescription)") await MainActor.run { [weak self] in self?.status = .failed } @@ -174,7 +168,7 @@ class ShareViewModel: ShareViewModelProtocol { return true } catch { - ShareViewModel.logger.error("Unable to cache file: \(error.localizedDescription)") + ShareViewModel.logger().error("Unable to cache file: \(error.localizedDescription)") } } else if itemUrl.isValidURL() { return await downloadFileFromUrl(itemUrl) @@ -184,7 +178,7 @@ class ShareViewModel: ShareViewModelProtocol { } func downloadFileFromUrl(_ itemUrl: URL) async -> Bool { - ShareViewModel.logger.debug("Downloading file from \(itemUrl.absoluteString)") + ShareViewModel.logger().debug("Downloading file from \(itemUrl.absoluteString)") do { let destinationURL = try Directories.getTempDirectory( @@ -204,7 +198,7 @@ class ShareViewModel: ShareViewModelProtocol { for await progress in request.downloadProgress() { let fileName = itemUrl.lastPathComponent let downloadProgress = progress.fractionCompleted * 100 - ShareViewModel.logger.debug( + ShareViewModel.logger().debug( "\(String(format: "Download progress for file '%@': %.2f%%", fileName, downloadProgress))" ) } @@ -216,7 +210,7 @@ class ShareViewModel: ShareViewModelProtocol { return await cacheFileOnUrl(fileURL) } catch let error { let errorDescription = error.localizedDescription - ShareViewModel.logger.error( + ShareViewModel.logger().error( "\(String(format: "Unable to download file %@: %@", itemUrl.absoluteString, errorDescription))" ) return false diff --git a/Modules/CommonsLib/Sources/CommonsLib/Bundle/BundleUtil.swift b/Modules/CommonsLib/Sources/CommonsLib/Bundle/BundleUtil.swift index e6344dac..8b1711d8 100644 --- a/Modules/CommonsLib/Sources/CommonsLib/Bundle/BundleUtil.swift +++ b/Modules/CommonsLib/Sources/CommonsLib/Bundle/BundleUtil.swift @@ -18,28 +18,18 @@ */ import Foundation -import OSLog - -public struct BundleUtil { - - private static let logger = Logger(subsystem: "ee.ria.digidoc.CommonsLib", category: "BundleUtil") +public struct BundleUtil: Loggable { public static func getBundleIdentifier() -> String { - let bundleIdentifier = Bundle.main.bundleIdentifier ?? "ee.ria.digidoc" - logger.debug("Using bundle identifier: \(bundleIdentifier)") - return bundleIdentifier + return Bundle.main.bundleIdentifier ?? "ee.ria.digidoc" } public static func getBundleShortVersionString(bundle: Bundle = Bundle.main) -> String { - let versionString = bundle.infoDictionary?["CFBundleShortVersionString"] as? String ?? "3.0.0" - logger.debug("Bundle short version string from info.plist: \(versionString)") - return versionString + return bundle.infoDictionary?["CFBundleShortVersionString"] as? String ?? "3.0.0" } public static func getBundleVersion(bundle: Bundle = Bundle.main) -> String { - let appVersion = bundle.infoDictionary?["CFBundleVersion"] as? String ?? "1" - logger.debug("Bundle version from info.plist: \(appVersion)") - return appVersion + return bundle.infoDictionary?["CFBundleVersion"] as? String ?? "1" } public static func getAppVersion(bundle: Bundle = Bundle.main) -> String { diff --git a/Modules/CommonsLib/Sources/CommonsLib/DI/CommonsLibContainer.swift b/Modules/CommonsLib/Sources/CommonsLib/DI/CommonsLibContainer.swift index fbd19696..8ff50f3f 100644 --- a/Modules/CommonsLib/Sources/CommonsLib/DI/CommonsLibContainer.swift +++ b/Modules/CommonsLib/Sources/CommonsLib/DI/CommonsLibContainer.swift @@ -30,4 +30,10 @@ public extension Container { var urlResourceChecker: Factory { self { URLResourceChecker() } } + + var isLoggingEnabled: Factory { + // Default value, will be overridden on app initialization + self { false } + .singleton + } } diff --git a/Modules/CommonsLib/Sources/CommonsLib/Logging/Loggable.swift b/Modules/CommonsLib/Sources/CommonsLib/Logging/Loggable.swift new file mode 100644 index 00000000..90f91201 --- /dev/null +++ b/Modules/CommonsLib/Sources/CommonsLib/Logging/Loggable.swift @@ -0,0 +1,46 @@ +/* + * Copyright 2017 - 2025 Riigi Infosüsteemi Amet + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +import Foundation +import OSLog + +public protocol Loggable: Sendable {} + +public extension Loggable { + static func logger(file: String = #fileID) -> Logger { + guard LoggingSystem.configuration.isLoggingEnabled else { + return Logger(.disabled) + } + + let filePath = String(file) + let moduleName = URL(fileURLWithPath: filePath) + .lastPathComponent + .split(separator: ".") + .first + .map(String.init) ?? "UnknownModule" + + let subsystem = "\(BundleUtil.getBundleIdentifier()).\(moduleName)" + + return Logger(subsystem: subsystem, category: category) + } + + static var category: String { + String(describing: Self.self) + } +} diff --git a/Modules/CommonsLib/Sources/CommonsLib/Logging/LoggingConfiguration.swift b/Modules/CommonsLib/Sources/CommonsLib/Logging/LoggingConfiguration.swift new file mode 100644 index 00000000..d935031a --- /dev/null +++ b/Modules/CommonsLib/Sources/CommonsLib/Logging/LoggingConfiguration.swift @@ -0,0 +1,28 @@ +/* + * Copyright 2017 - 2025 Riigi Infosüsteemi Amet + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +import Foundation + +public struct LoggingConfiguration: Sendable { + public let isLoggingEnabled: Bool + + public init(isLoggingEnabled: Bool) { + self.isLoggingEnabled = isLoggingEnabled + } +} diff --git a/Modules/CommonsLib/Sources/CommonsLib/Logging/LoggingSystem.swift b/Modules/CommonsLib/Sources/CommonsLib/Logging/LoggingSystem.swift new file mode 100644 index 00000000..fb6af8db --- /dev/null +++ b/Modules/CommonsLib/Sources/CommonsLib/Logging/LoggingSystem.swift @@ -0,0 +1,26 @@ +/* + * Copyright 2017 - 2025 Riigi Infosüsteemi Amet + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +import FactoryKit + +public struct LoggingSystem: Sendable { + public static let configuration: LoggingConfiguration = LoggingConfiguration( + isLoggingEnabled: Container.shared.isLoggingEnabled() + ) +} diff --git a/Modules/CommonsLib/Sources/CommonsLib/System/SystemUtil.swift b/Modules/CommonsLib/Sources/CommonsLib/System/SystemUtil.swift index 8835d1a6..26f4f6f7 100644 --- a/Modules/CommonsLib/Sources/CommonsLib/System/SystemUtil.swift +++ b/Modules/CommonsLib/Sources/CommonsLib/System/SystemUtil.swift @@ -18,15 +18,11 @@ */ import Foundation -import OSLog - -public struct SystemUtil { - - private static let logger = Logger(subsystem: "ee.ria.digidoc.CommonsLib", category: "SystemUtil") +public struct SystemUtil: Loggable { public static var isSimulator: Bool { #if targetEnvironment(simulator) - logger.debug("App is running on a simulator") + logger().debug("App is running on a simulator") return true #else return false @@ -36,7 +32,7 @@ public struct SystemUtil { public static func getOSVersion() -> String { let osVersion = ProcessInfo.processInfo.operatingSystemVersion let versionString = "\(osVersion.majorVersion).\(osVersion.minorVersion).\(osVersion.patchVersion)" - logger.debug("Operating system version: \(versionString)") + logger().debug("Operating system version: \(versionString)") return versionString } } diff --git a/Modules/ConfigLib/Sources/ConfigLib/Configuration/Cache/ConfigurationCache.swift b/Modules/ConfigLib/Sources/ConfigLib/Configuration/Cache/ConfigurationCache.swift index 417b5890..86080c0b 100644 --- a/Modules/ConfigLib/Sources/ConfigLib/Configuration/Cache/ConfigurationCache.swift +++ b/Modules/ConfigLib/Sources/ConfigLib/Configuration/Cache/ConfigurationCache.swift @@ -18,14 +18,11 @@ */ import Foundation -import OSLog import FactoryKit import CommonsLib import UtilsLib -actor ConfigurationCache: ConfigurationCacheProtocol { - - private static let logger = Logger(subsystem: "ee.ria.digidoc.ConfigLib", category: "ConfigurationCache") +actor ConfigurationCache: ConfigurationCacheProtocol, Loggable { private let fileManager: FileManagerProtocol @@ -100,7 +97,7 @@ actor ConfigurationCache: ConfigurationCacheProtocol { try data.write(to: configFile) } catch { - ConfigurationCache.logger.error("\(error.localizedDescription)") + ConfigurationCache.logger().error("\(error.localizedDescription)") throw ConfigurationCacheError.unableToCacheFile(fileName) } } diff --git a/Modules/ConfigLib/Sources/ConfigLib/Configuration/Domain/Model/ConfigurationViewModel.swift b/Modules/ConfigLib/Sources/ConfigLib/Configuration/Domain/Model/ConfigurationViewModel.swift index f4397f65..00a11b3d 100644 --- a/Modules/ConfigLib/Sources/ConfigLib/Configuration/Domain/Model/ConfigurationViewModel.swift +++ b/Modules/ConfigLib/Sources/ConfigLib/Configuration/Domain/Model/ConfigurationViewModel.swift @@ -18,13 +18,11 @@ */ import Foundation -import OSLog import UtilsLib import CommonsLib @MainActor -class ConfigurationViewModel { - private static let logger = Logger(subsystem: "ee.ria.digidoc.RIADigiDoc", category: "ConfigurationViewModel") +class ConfigurationViewModel: Loggable { private(set) var configuration: ConfigurationProvider? @@ -45,7 +43,7 @@ class ConfigurationViewModel { cacheDir: Directories.getConfigDirectory(fileManager: fileManager), proxyInfo: proxyInfo ) else { - ConfigurationViewModel.logger.error("No configuration updates available.") + ConfigurationViewModel.logger().error("No configuration updates available.") return } @@ -58,14 +56,14 @@ class ConfigurationViewModel { } } } catch { - ConfigurationViewModel.logger.error("Unable to fetch configuration: \(error.localizedDescription)") + ConfigurationViewModel.logger().error("Unable to fetch configuration: \(error.localizedDescription)") } } func getConfiguration() async -> ConfigurationProvider? { do { guard let updates = await repository.getConfigurationUpdates() else { - ConfigurationViewModel.logger.error("Configuration updates provider is nil") + ConfigurationViewModel.logger().error("Configuration updates provider is nil") return nil } @@ -75,7 +73,7 @@ class ConfigurationViewModel { } } } catch { - ConfigurationViewModel.logger.error("Unable to get configuration: \(error.localizedDescription)") + ConfigurationViewModel.logger().error("Unable to get configuration: \(error.localizedDescription)") return nil } return nil diff --git a/Modules/ConfigLib/Sources/ConfigLib/Configuration/Loader/ConfigurationLoader.swift b/Modules/ConfigLib/Sources/ConfigLib/Configuration/Loader/ConfigurationLoader.swift index 6b96260e..8524facf 100644 --- a/Modules/ConfigLib/Sources/ConfigLib/Configuration/Loader/ConfigurationLoader.swift +++ b/Modules/ConfigLib/Sources/ConfigLib/Configuration/Loader/ConfigurationLoader.swift @@ -20,14 +20,9 @@ import CommonsLib import FactoryKit import Foundation -import OSLog import UtilsLib -public actor ConfigurationLoader: ConfigurationLoaderProtocol { - - private static let logger = Logger( - subsystem: "ee.ria.digidoc.RIADigiDoc", category: "ConfigurationLoader") - +public actor ConfigurationLoader: ConfigurationLoaderProtocol, Loggable { private var configuration: ConfigurationProvider? public typealias ConfigStream = AsyncThrowingStream @@ -63,7 +58,7 @@ public actor ConfigurationLoader: ConfigurationLoaderProtocol { } public func initConfiguration(cacheDir: URL, proxyInfo: ProxyInfo) async throws { - ConfigurationLoader.logger.debug("Initializing configuration") + ConfigurationLoader.logger().debug("Initializing configuration") if !fileManager.fileExists(atPath: cacheDir.resolvedPath) { try fileManager.createDirectory( @@ -75,11 +70,11 @@ public actor ConfigurationLoader: ConfigurationLoaderProtocol { try await loadConfigurationProperty() if try await shouldCheckForUpdates() { - ConfigurationLoader.logger.debug("Checking for configuration updates...") + ConfigurationLoader.logger().debug("Checking for configuration updates...") try await loadCentralConfiguration(cacheDir: cacheDir, proxyInfo: proxyInfo) } - ConfigurationLoader.logger.debug("Finished initializing configuration") + ConfigurationLoader.logger().debug("Finished initializing configuration") finishConfigurationUpdate() } @@ -129,7 +124,7 @@ public actor ConfigurationLoader: ConfigurationLoaderProtocol { fileManager.fileExists(atPath: signatureFile.resolvedPath) if configFilesExist { - ConfigurationLoader.logger.debug("Initializing cached configuration") + ConfigurationLoader.logger().debug("Initializing cached configuration") let confFileContents = try String(contentsOf: confFile, encoding: .utf8) let publicKeyContents = try String(contentsOf: publicKeyFile, encoding: .utf8) @@ -146,7 +141,7 @@ public actor ConfigurationLoader: ConfigurationLoaderProtocol { from: Data(contentsOf: confFile) ) - ConfigurationLoader.logger.debug( + ConfigurationLoader.logger().debug( "Using cached configuration version \(configurationProvider.metaInf.serial)" ) @@ -184,7 +179,7 @@ public actor ConfigurationLoader: ConfigurationLoaderProtocol { updateConfiguration(configurationProvider) } } else { - ConfigurationLoader.logger.debug( + ConfigurationLoader.logger().debug( "Cached configuration not found. Initializing default configuration") try await loadDefaultConfiguration(cacheDir: configDir) } @@ -244,7 +239,7 @@ public actor ConfigurationLoader: ConfigurationLoaderProtocol { ConfigurationProvider.self, from: Data(contentsOf: confDataURL) ) - ConfigurationLoader.logger.debug( + ConfigurationLoader.logger().debug( "Initializing default configuration version \(configurationProvider.metaInf.serial)" ) @@ -286,7 +281,7 @@ public actor ConfigurationLoader: ConfigurationLoaderProtocol { ).trimmingCharacters(in: .whitespaces) if !centralSignature.isEmpty && currentSignature != centralSignature.data(using: .utf8) { - ConfigurationLoader.logger.debug("Found new configuration") + ConfigurationLoader.logger().debug("Found new configuration") let centralConfig = try await centralConfigurationRepository.fetchConfiguration( proxyInfo: proxyInfo @@ -298,7 +293,7 @@ public actor ConfigurationLoader: ConfigurationLoaderProtocol { let centralConfigurationProvider = try JSONDecoder().decode( ConfigurationProvider.self, from: Data(centralConfig.utf8) ) - ConfigurationLoader.logger.debug( + ConfigurationLoader.logger().debug( "Initializing configuration version \(centralConfigurationProvider.metaInf.serial)" ) @@ -342,7 +337,7 @@ public actor ConfigurationLoader: ConfigurationLoaderProtocol { try await loadCachedConfiguration(afterCentralCheck: true, cacheDir: configDir) } } else { - ConfigurationLoader.logger.debug( + ConfigurationLoader.logger().debug( "New configuration not found. Using cached configuration" ) try await loadCachedConfiguration(afterCentralCheck: true, cacheDir: configDir) diff --git a/Modules/ConfigLib/Sources/ConfigLib/Configuration/Service/CentralConfigurationService.swift b/Modules/ConfigLib/Sources/ConfigLib/Configuration/Service/CentralConfigurationService.swift index 1c403a24..4a08971b 100644 --- a/Modules/ConfigLib/Sources/ConfigLib/Configuration/Service/CentralConfigurationService.swift +++ b/Modules/ConfigLib/Sources/ConfigLib/Configuration/Service/CentralConfigurationService.swift @@ -18,14 +18,10 @@ */ import Foundation -import OSLog import Alamofire import CommonsLib -public actor CentralConfigurationService: CentralConfigurationServiceProtocol { - - private static let logger = Logger(subsystem: "ee.ria.digidoc.RIADigiDoc", category: "CentralConfigurationService") - +public actor CentralConfigurationService: CentralConfigurationServiceProtocol, Loggable { private let userAgent: String private let configurationProperty: ConfigurationProperty private let session: Session? @@ -58,7 +54,7 @@ public actor CentralConfigurationService: CentralConfigurationServiceProtocol { return response } catch { - CentralConfigurationService.logger + CentralConfigurationService.logger() .error("Unable to fetch central configuration: \(error)") throw URLError(.resourceUnavailable) } @@ -82,7 +78,7 @@ public actor CentralConfigurationService: CentralConfigurationServiceProtocol { return response } catch { - CentralConfigurationService.logger + CentralConfigurationService.logger() .error("Unable to fetch central configuration public key: \(error)") throw URLError(.resourceUnavailable) } @@ -109,7 +105,7 @@ public actor CentralConfigurationService: CentralConfigurationServiceProtocol { return responseString } catch { - CentralConfigurationService.logger + CentralConfigurationService.logger() .error("Unable to fetch central configuration signature: \(error)") throw URLError(.resourceUnavailable) } diff --git a/Modules/ConfigLib/Tests/ConfigLibTests/Configuration/Shared/TestRSAKeyGenerator.swift b/Modules/ConfigLib/Tests/ConfigLibTests/Configuration/Shared/TestRSAKeyGenerator.swift index 68bb583c..72250d5d 100644 --- a/Modules/ConfigLib/Tests/ConfigLibTests/Configuration/Shared/TestRSAKeyGenerator.swift +++ b/Modules/ConfigLib/Tests/ConfigLibTests/Configuration/Shared/TestRSAKeyGenerator.swift @@ -17,15 +17,13 @@ * */ +import CommonsLib import Foundation -import OSLog import Testing import Security @testable import ConfigLib -struct TestRSAKeyGenerator { - - private static let logger = Logger(subsystem: "ee.ria.digidoc.RIADigiDoc", category: "TestRSAKeyGenerator") +struct TestRSAKeyGenerator: Loggable { static func generateKeyPair() -> (publicKeyPEM: String, privateKey: SecKey)? { let attributes: [CFString: Any] = [ @@ -36,12 +34,13 @@ struct TestRSAKeyGenerator { var error: Unmanaged? guard let privateKey = SecKeyCreateRandomKey(attributes as CFDictionary, &error), let publicKey = SecKeyCopyPublicKey(privateKey) else { - TestRSAKeyGenerator.logger.error("Key generation error: \(String(describing: error?.takeRetainedValue()))") + TestRSAKeyGenerator.logger().error( + "Key generation error: \(String(describing: error?.takeRetainedValue()))") return nil } guard let publicKeyData = SecKeyCopyExternalRepresentation(publicKey, &error) as Data? else { - TestRSAKeyGenerator.logger.error( + TestRSAKeyGenerator.logger().error( "Public key export error: \(String(describing: error?.takeRetainedValue()))" ) return nil @@ -63,7 +62,7 @@ struct TestRSAKeyGenerator { var error: Unmanaged? guard let signature = SecKeyCreateSignature(privateKey, algorithm, messageData as CFData, &error) else { - TestRSAKeyGenerator.logger.error("Signing error: \(String(describing: error?.takeRetainedValue()))") + TestRSAKeyGenerator.logger().error("Signing error: \(String(describing: error?.takeRetainedValue()))") return nil } diff --git a/Modules/ConfigLib/Tests/Mocks/TestConfigurationProvider.swift b/Modules/ConfigLib/Tests/Mocks/TestConfigurationProvider.swift index 89488329..b16c2f20 100644 --- a/Modules/ConfigLib/Tests/Mocks/TestConfigurationProvider.swift +++ b/Modules/ConfigLib/Tests/Mocks/TestConfigurationProvider.swift @@ -18,13 +18,11 @@ */ import Foundation -import OSLog import CommonsTestShared @testable import ConfigLib public class TestConfigurationProvider { - private static let logger = Logger(subsystem: "ee.ria.digidoc.RIADigiDoc", category: "TestConfigurationProvider") public static func mockConfigurationProvider( metaInfUrl: String = "https://someUrl.abc", diff --git a/Modules/CryptoLib/Sources/CryptoObjCWrapper/Conf/CDoc2Setting.swift b/Modules/CryptoLib/Sources/CryptoObjCWrapper/Conf/CDoc2Setting.swift index 655ec9f9..c8736e48 100644 --- a/Modules/CryptoLib/Sources/CryptoObjCWrapper/Conf/CDoc2Setting.swift +++ b/Modules/CryptoLib/Sources/CryptoObjCWrapper/Conf/CDoc2Setting.swift @@ -20,15 +20,8 @@ import Foundation import CommonsLib import ConfigLib -import OSLog - -public final class CDoc2Setting: NSObject, Sendable { - - private static let logger = Logger( - subsystem: "ee.ria.digidoc.RIADigiDoc", - category: "CDoc2Setting" - ) +public final class CDoc2Setting: NSObject, Sendable, Loggable { @objc @MainActor static public var isEncryptionEnabled: Bool = Constants.CryptoDefaultValues.encryptionUseCdoc2 @objc @MainActor static public var isOnlineEncryptionEnabled: Bool = Constants.CryptoDefaultValues.encryptionUseKeyTransfer @@ -131,7 +124,7 @@ public final class CDoc2Setting: NSObject, Sendable { return nil default: let message = SecCopyErrorMessageString(status, nil) as String? ?? "Unknown error" - logger.error("Keychain lookup failed (\(status)): \(message)") + logger().error("Keychain lookup failed (\(status)): \(message)") return nil } } diff --git a/Modules/CryptoLib/Sources/CryptoObjCWrapper/Domain/CdocInfo.swift b/Modules/CryptoLib/Sources/CryptoObjCWrapper/Domain/CdocInfo.swift index 308eec69..79a1e734 100644 --- a/Modules/CryptoLib/Sources/CryptoObjCWrapper/Domain/CdocInfo.swift +++ b/Modules/CryptoLib/Sources/CryptoObjCWrapper/Domain/CdocInfo.swift @@ -17,11 +17,10 @@ * */ +import CommonsLib import Foundation -import OSLog -@objc public class CdocInfo: NSObject { - private static let logger = Logger(subsystem: "ee.ria.digidoc.RIADigiDoc", category: "CdocInfo") +@objc public final class CdocInfo: NSObject, Loggable { public let format: String @objc public let addressees: [Addressee] @objc public let dataFiles: [CryptoDataFile] @@ -40,7 +39,7 @@ import OSLog @objc public init(cdoc1Path path: String) throws { guard let parser = XMLParser(contentsOf: URL(fileURLWithPath: path)) else { - CdocInfo.logger.error("Error: Unable to read file at \(path)") + CdocInfo.logger().error("Error: Unable to read file at \(path)") throw NSError(domain: XMLParser.errorDomain, code: XMLParser.ErrorCode.internalError.rawValue, userInfo: [ NSLocalizedDescriptionKey: "Failed to create XML parser for file at \(path)" ]) @@ -49,7 +48,7 @@ import OSLog parser.externalEntityResolvingPolicy = .never parser.delegate = delegate guard parser.parse() else { - CdocInfo.logger.error("Error: Failed to parse XML") + CdocInfo.logger().error("Error: Failed to parse XML") throw parser.parserError ?? NSError( domain: XMLParser.errorDomain, code: XMLParser.ErrorCode.internalError.rawValue, diff --git a/Modules/CryptoLib/Sources/CryptoSwift/CryptoContainer.swift b/Modules/CryptoLib/Sources/CryptoSwift/CryptoContainer.swift index 5ddcf4f9..09a0b3fe 100644 --- a/Modules/CryptoLib/Sources/CryptoSwift/CryptoContainer.swift +++ b/Modules/CryptoLib/Sources/CryptoSwift/CryptoContainer.swift @@ -18,7 +18,6 @@ */ import Foundation -import OSLog import FactoryKit import CryptoObjC import CryptoObjCWrapper @@ -26,8 +25,7 @@ import IdCardLib import CommonsLib import UtilsLib -public actor CryptoContainer: CryptoContainerProtocol { - private static let logger = Logger(subsystem: "ee.ria.digidoc.CryptoLib", category: "CryptoContainer") +public actor CryptoContainer: CryptoContainerProtocol, Loggable { private static let cryptoContainerLogTag: String = "CryptoContainer" @@ -197,9 +195,9 @@ extension CryptoContainer { dataFiles: [URL], containerUtil: ContainerUtilProtocol = Container.shared.containerUtil(), ) async throws -> CryptoContainerProtocol { - logger.debug("Opening or creating crypto container. Found \(dataFiles.count) datafile(s)") + logger().debug("Opening or creating crypto container. Found \(dataFiles.count) datafile(s)") guard let firstFile = dataFiles.first else { - logger.error("Unable to create or open crypto container. First datafile is nil") + logger().error("Unable to create or open crypto container. First datafile is nil") throw CryptoError.containerCreationFailed( CryptoErrorDetail( message: "Cannot create or open crypto container. Datafiles are empty" @@ -242,10 +240,10 @@ extension CryptoContainer { } if dataFiles.count == 1 && isFirstDataFileContainer { - CryptoContainer.logger.debug("Opening existing crypto container") + CryptoContainer.logger().debug("Opening existing crypto container") return try await open(containerFile: containerFile) } else { - CryptoContainer.logger.debug("Creating a new crypto container") + CryptoContainer.logger().debug("Creating a new crypto container") return try await create( containerFile: containerFile, dataFiles: dataFiles, @@ -286,7 +284,7 @@ extension CryptoContainer { ) if !isCreated { - CryptoContainer.logger.error("Unable to create file at path: \(destinationPath.resolvedPath)") + CryptoContainer.logger().error("Unable to create file at path: \(destinationPath.resolvedPath)") } } diff --git a/Modules/CryptoLib/Sources/CryptoSwift/Ldap/OpenLdap.swift b/Modules/CryptoLib/Sources/CryptoSwift/Ldap/OpenLdap.swift index 10819e38..443716f0 100644 --- a/Modules/CryptoLib/Sources/CryptoSwift/Ldap/OpenLdap.swift +++ b/Modules/CryptoLib/Sources/CryptoSwift/Ldap/OpenLdap.swift @@ -21,16 +21,10 @@ import CryptoObjC import CryptoObjCWrapper import CommonsLib import LDAP -import OSLog import ASN1Decoder import Foundation -final public class OpenLdap: OpenLdapProtocol { - private static let logger = Logger( - subsystem: "ee.ria.digidoc.RIADigiDoc", - category: "OpenLdap" - ) - +final public class OpenLdap: OpenLdapProtocol, Loggable { private let ldapConfiguration: LdapConfigurationProtocol private let fileManager: FileManagerProtocol @@ -97,14 +91,14 @@ final public class OpenLdap: OpenLdapProtocol { if fileManager.fileExists(atPath: ldapCertFilePath) { filePath = ldapCertFilePath } else { - OpenLdap.logger.debug("File ldapCerts.pem does not exist at directory path: \(ldapCertFilePath)") + OpenLdap.logger().debug("File ldapCerts.pem does not exist at directory path: \(ldapCertFilePath)") filePath = nil } } let searchType = SearchType(from: identityCode) if case .personalCode = searchType { - OpenLdap.logger.debug("Searching with personal code from LDAP") + OpenLdap.logger().debug("Searching with personal code from LDAP") var result = [Addressee]() var tooManyResults = false for url in await self.ldapConfiguration.getLdapPersonURLS() { @@ -122,7 +116,7 @@ final public class OpenLdap: OpenLdapProtocol { return (result, tooManyResults) } else { if let ldapCorpURL = await self.ldapConfiguration.getLdapCorpURL() { - OpenLdap.logger.debug("Searching with corporation keyword from LDAP") + OpenLdap.logger().debug("Searching with corporation keyword from LDAP") let (addresses, found) = OpenLdap.search( searchType: searchType, url: ldapCorpURL, @@ -151,7 +145,7 @@ final public class OpenLdap: OpenLdapProtocol { var ldapConnectionReset = 0 let result = ldap_set_option(nil, LDAP_OPT_X_TLS_NEWCTX, &ldapConnectionReset) guard result == LDAP_SUCCESS else { - OpenLdap.logger.debug( + OpenLdap.logger().debug( "ldap_set_option(LDAP_OPT_X_TLS_NEWCTX) failed: \(String(cString: ldap_err2string(result)))" ) return ([], 0) @@ -173,14 +167,14 @@ final public class OpenLdap: OpenLdapProtocol { if let ldap = ldap { ldap_destroy(ldap) } } guard ldapReturnCode == LDAP_SUCCESS else { - OpenLdap.logger.debug("Failed to initialize LDAP: \(String(cString: ldap_err2string(ldapReturnCode)))") + OpenLdap.logger().debug("Failed to initialize LDAP: \(String(cString: ldap_err2string(ldapReturnCode)))") return ([], 0) } var ldapVersion = LDAP_VERSION3 ldapReturnCode = ldap_set_option(ldap, LDAP_OPT_PROTOCOL_VERSION, &ldapVersion) guard ldapReturnCode == LDAP_SUCCESS else { - OpenLdap.logger.debug( + OpenLdap.logger().debug( "ldap_set_option(PROTOCOL_VERSION) failed: \(String(cString: ldap_err2string(ldapReturnCode)))" ) return ([], 0) @@ -192,7 +186,7 @@ final public class OpenLdap: OpenLdapProtocol { } else { distinguishedName.remove(at: distinguishedName.startIndex) } - OpenLdap.logger.debug("Searching from LDAP. Url: \(url) \(distinguishedName) \(searchType.filter)") + OpenLdap.logger().debug("Searching from LDAP. Url: \(url) \(distinguishedName) \(searchType.filter)") var msgId: Int32 = 0 var attr = Array("userCertificate;binary".utf8CString) ldapReturnCode = attr.withUnsafeMutableBufferPointer { attr in @@ -215,7 +209,7 @@ final public class OpenLdap: OpenLdapProtocol { } guard ldapReturnCode == LDAP_SUCCESS else { - OpenLdap.logger.debug("ldap_search_ext failed: \(String(cString: ldap_err2string(ldapReturnCode)))") + OpenLdap.logger().debug("ldap_search_ext failed: \(String(cString: ldap_err2string(ldapReturnCode)))") return ([], 0) } @@ -237,7 +231,7 @@ final public class OpenLdap: OpenLdapProtocol { case Int32(LDAP_SUCCESS): break default: - OpenLdap.logger.debug("ldap_result failed: \(String(cString: ldap_err2string(ldapReturnCode)))") + OpenLdap.logger().debug("ldap_result failed: \(String(cString: ldap_err2string(ldapReturnCode)))") return (addressees: result, totalAddressees: totalAddressees) } } @@ -254,7 +248,7 @@ final public class OpenLdap: OpenLdapProtocol { value ) if result != LDAP_SUCCESS { - OpenLdap.logger.error("ldap_set_option failed: \(String(cString: ldap_err2string(result)))") + OpenLdap.logger().error("ldap_set_option failed: \(String(cString: ldap_err2string(result)))") return false } return true @@ -284,7 +278,7 @@ final public class OpenLdap: OpenLdapProtocol { } if let namePointer = ldap_get_dn(ldap, currentMessage) { - OpenLdap.logger.debug("Result (\(result.count)) \(String(cString: namePointer))") + OpenLdap.logger().debug("Result (\(result.count)) \(String(cString: namePointer))") ldap_memfree(namePointer) } } diff --git a/Modules/IdCardLib/Package.swift b/Modules/IdCardLib/Package.swift index f3bd76c5..d05eab11 100644 --- a/Modules/IdCardLib/Package.swift +++ b/Modules/IdCardLib/Package.swift @@ -15,7 +15,8 @@ let package = Package( .package(url: "https://github.com/leif-ibsen/Digest.git", exact: .init(1, 13, 0)), .package(url: "https://github.com/apple/swift-asn1.git", exact: .init(1, 4, 0)), .package(url: "https://github.com/apple/swift-certificates.git", exact: .init(1, 7, 0)), - .package(url: "https://github.com/leif-ibsen/SwiftECC.git", exact: .init(5, 5, 0)) + .package(url: "https://github.com/leif-ibsen/SwiftECC.git", exact: .init(5, 5, 0)), + .package(path: "../CommonsLib") ], targets: [ .target( @@ -36,7 +37,8 @@ let package = Package( "BigInt", "Digest", "SwiftECC", - "iR301" + "iR301", + "CommonsLib" ], path: "Sources/IdCardLib", swiftSettings: [ diff --git a/Modules/IdCardLib/Sources/IdCardLib/CardActions/CardReaderNFC.swift b/Modules/IdCardLib/Sources/IdCardLib/CardActions/CardReaderNFC.swift index b3fe5f9e..2291e7f5 100644 --- a/Modules/IdCardLib/Sources/IdCardLib/CardActions/CardReaderNFC.swift +++ b/Modules/IdCardLib/Sources/IdCardLib/CardActions/CardReaderNFC.swift @@ -17,15 +17,14 @@ * */ +import CommonsLib import CoreNFC import CommonCrypto import CryptoTokenKit internal import SwiftECC import BigInt -import OSLog -class CardReaderNFC: CardReader { - private static let logger = Logger(subsystem: "ee.ria.digidoc.RIADigiDoc", category: "CardReaderNFC") +class CardReaderNFC: CardReader, Loggable { // swiftlint:disable identifier_name enum PasswordType: UInt8 { case id_PasswordType_MRZ = 1 // 0.4.0.127.0.7.2.2.12.1 @@ -73,9 +72,9 @@ class CardReaderNFC: CardReader { init(_ tag: NFCISO7816Tag, CAN: String) async throws { self.tag = tag - CardReaderNFC.logger.debug("Select CardAccess") + CardReaderNFC.logger().debug("Select CardAccess") _ = try await tag.sendCommand(cls: 0x00, ins: 0xA4, p1Byte: 0x02, p2Byte: 0x0C, data: Data([0x01, 0x1C])) - CardReaderNFC.logger.debug("Read CardAccess") + CardReaderNFC.logger().debug("Read CardAccess") let data = try await tag.sendCommand(cls: 0x00, ins: 0xB0, p1Byte: 0x00, p2Byte: 0x00, leByte: 256) guard let (mappingType, parameterId) = TLV.sequenceOfRecords(from: data)? @@ -103,9 +102,9 @@ class CardReaderNFC: CardReader { // Step1 - General Authentication let nonceEnc = try await tag.sendPaceCommand(records: [], tagExpected: 0x80) - CardReaderNFC.logger.debug("Challenge \(nonceEnc.value.toHex)") + CardReaderNFC.logger().debug("Challenge \(nonceEnc.value.toHex)") let nonce = try CardReaderNFC.decryptNonce(CAN: CAN, encryptedNonce: nonceEnc.value) - CardReaderNFC.logger.debug("Nonce \(nonce.toHex)") + CardReaderNFC.logger().debug("Nonce \(nonce.toHex)") // Step2 let (terminalPubKey, terminalPrivKey) = domain.makeKeyPair() @@ -116,7 +115,7 @@ class CardReaderNFC: CardReader { )], tagExpected: 0x82 ) - CardReaderNFC.logger.debug("Mapping key \(mappingKey.value.toHex)") + CardReaderNFC.logger().debug("Mapping key \(mappingKey.value.toHex)") guard let cardPubKey = try ECPublicKey(domain: domain, point: mappingKey.value) else { throw IdCardInternalError.authenticationFailed } @@ -124,17 +123,17 @@ class CardReaderNFC: CardReader { let nonceS = BInt(magnitude: nonce) let mappingBasePoint = ECPublicKey(privateKey: try ECPrivateKey(domain: domain, s: nonceS)) // S*G // swiftlint:disable line_length - CardReaderNFC.logger.debug("Card Key x: \(mappingBasePoint.w.x.asMagnitudeBytes().toHex, privacy: .public), y: \(mappingBasePoint.w.y.asMagnitudeBytes().toHex, privacy: .public)") + CardReaderNFC.logger().debug("Card Key x: \(mappingBasePoint.w.x.asMagnitudeBytes().toHex, privacy: .public), y: \(mappingBasePoint.w.y.asMagnitudeBytes().toHex, privacy: .public)") // swiftlint:enable line_length let sharedSecretH = try domain.multiplyPoint(cardPubKey.w, terminalPrivKey.s) // swiftlint:disable line_length - CardReaderNFC.logger.debug("Shared Secret x: \(sharedSecretH.x.asMagnitudeBytes().toHex, privacy: .public), y: \(sharedSecretH.y.asMagnitudeBytes().toHex, privacy: .public)") + CardReaderNFC.logger().debug("Shared Secret x: \(sharedSecretH.x.asMagnitudeBytes().toHex, privacy: .public), y: \(sharedSecretH.y.asMagnitudeBytes().toHex, privacy: .public)") // swiftlint:enable line_length let mappedPoint = try domain.addPoints(mappingBasePoint.w, sharedSecretH) // MAP G = (S*G) + H // Ephemeral data // swiftlint:disable line_length - CardReaderNFC.logger.debug("Mapped point x: \(mappedPoint.x.asMagnitudeBytes().toHex, privacy: .public), y: \(mappedPoint.y.asMagnitudeBytes().toHex, privacy: .public)") + CardReaderNFC.logger().debug("Mapped point x: \(mappedPoint.x.asMagnitudeBytes().toHex, privacy: .public), y: \(mappedPoint.y.asMagnitudeBytes().toHex, privacy: .public)") // swiftlint:enable line_length let mappedDomain = try Domain.instance( name: domain.name + " Mapped", @@ -154,17 +153,17 @@ class CardReaderNFC: CardReader { )], tagExpected: 0x84 ) - CardReaderNFC.logger.debug("Card Ephermal key \(ephemeralKey.value.toHex)") + CardReaderNFC.logger().debug("Card Ephermal key \(ephemeralKey.value.toHex)") guard let ephemeralCardPubKey = try ECPublicKey(domain: mappedDomain, point: ephemeralKey.value) else { throw IdCardInternalError.authenticationFailed } // Derive shared secret and session keys let sharedSecret = try terminalEphemeralPrivKey.sharedSecret(pubKey: ephemeralCardPubKey) - CardReaderNFC.logger.debug("Shared secret \(sharedSecret.toHex)") + CardReaderNFC.logger().debug("Shared secret \(sharedSecret.toHex)") ksEnc = CardReaderNFC.KDF(key: sharedSecret, counter: 1) ksMac = CardReaderNFC.KDF(key: sharedSecret, counter: 2) - CardReaderNFC.logger.debug("KS.Enc \(self.ksEnc.toHex)") - CardReaderNFC.logger.debug("KS.Mac \(self.ksMac.toHex)") + CardReaderNFC.logger().debug("KS.Enc \(self.ksEnc.toHex)") + CardReaderNFC.logger().debug("KS.Mac \(self.ksMac.toHex)") // Mutual authentication let macCalc = try AES.CMAC(key: ksMac) @@ -184,7 +183,7 @@ class CardReaderNFC: CardReader { )], tagExpected: 0x86 ) - CardReaderNFC.logger.debug("Mac response \(macValue.data.toHex)") + CardReaderNFC.logger().debug("Mac response \(macValue.data.toHex)") // verify chip's MAC let macResult = TLV(tag: 0x7f49, records: [ @@ -230,14 +229,14 @@ class CardReaderNFC: CardReader { case 0x87: tlvEnc = tlv case 0x99: tlvRes = tlv case 0x8E: tlvMac = tlv - default: CardReaderNFC.logger.debug("Unknown tag") + default: CardReaderNFC.logger().debug("Unknown tag") } } return (tlvEnc, tlvRes, tlvMac) } func transmit(_ apduData: Bytes) async throws -> (responseData: Bytes, sw: UInt16) { - CardReaderNFC.logger.debug("Plain >: \(apduData.toHex)") + CardReaderNFC.logger().debug("Plain >: \(apduData.toHex)") guard let apdu = NFCISO7816APDU(data: Data(apduData)) else { throw IdCardInternalError.invalidAPDU } @@ -270,12 +269,12 @@ class CardReaderNFC: CardReader { throw IdCardInternalError.invalidMACValue } guard let tlvEnc else { - CardReaderNFC.logger.debug("Plain <: \(tlvRes.value.toHex)") + CardReaderNFC.logger().debug("Plain <: \(tlvRes.value.toHex)") return (.init(), UInt16(tlvRes.value[0], tlvRes.value[1])) } let ivValue = try AES.CBC(key: ksEnc).encrypt(SSC) let responseData = try (try AES.CBC(key: ksEnc, ivVal: ivValue).decrypt(tlvEnc.value[1...])).removePadding() - CardReaderNFC.logger.debug("Plain <: \(responseData.toHex) \(tlvRes.value.toHex)") + CardReaderNFC.logger().debug("Plain <: \(responseData.toHex) \(tlvRes.value.toHex)") return (Bytes(responseData), UInt16(tlvRes.value[0], tlvRes.value[1])) } diff --git a/Modules/IdCardLib/Sources/IdCardLib/CardActions/CardReaderiR301.swift b/Modules/IdCardLib/Sources/IdCardLib/CardActions/CardReaderiR301.swift index c74d307f..4890b361 100644 --- a/Modules/IdCardLib/Sources/IdCardLib/CardActions/CardReaderiR301.swift +++ b/Modules/IdCardLib/Sources/IdCardLib/CardActions/CardReaderiR301.swift @@ -17,12 +17,10 @@ * */ +import CommonsLib import iR301 -import OSLog - -class CardReaderiR301: CardReader { - private static let logger = Logger(subsystem: "ee.ria.digidoc.RIADigiDoc", category: "CardReaderiR301") +class CardReaderiR301: CardReader, Loggable { let atr: Bytes private var cardHandle: SCARDHANDLE = 0 private var pioSendPci = SCARD_IO_REQUEST(dwProtocol: UInt32(SCARD_PROTOCOL_UNDEFINED), @@ -36,22 +34,22 @@ class CardReaderiR301: CardReader { init?(contextHandle: SCARDCONTEXT) throws { guard contextHandle != 0 else { - CardReaderiR301.logger.error("ID-CARD: Invalid context handle: \(contextHandle)") + CardReaderiR301.logger().error("ID-CARD: Invalid context handle: \(contextHandle)") return nil } var modelNameLength: UInt32 = 100 let modelName = String(unsafeUninitializedCapacity: Int(modelNameLength)) { buffer in guard FtGetAccessoryModelName(contextHandle, &modelNameLength, buffer.baseAddress) == 0 else { - CardReaderiR301.logger.error("ID-CARD: Failed to identify reader") + CardReaderiR301.logger().error("ID-CARD: Failed to identify reader") return 0 } return Int(modelNameLength) } - CardReaderiR301.logger.debug("ID-CARD: Checking if card reader is supported: \(modelName)") + CardReaderiR301.logger().debug("ID-CARD: Checking if card reader is supported: \(modelName)") guard modelName.hasPrefix("iR301") else { - CardReaderiR301.logger.error("ID-CARD: Unsupported reader: \(modelName)") + CardReaderiR301.logger().error("ID-CARD: Unsupported reader: \(modelName)") return nil } @@ -59,7 +57,7 @@ class CardReaderiR301: CardReader { let mszReaders = try String(unsafeUninitializedCapacity: Int(dwReaders)) { buffer in let listReadersResult = SCardListReaders(contextHandle, nil, buffer.baseAddress, &dwReaders) guard listReadersResult == SCARD_S_SUCCESS else { - CardReaderiR301.logger.error("SCardListReaders error \(listReadersResult)") + CardReaderiR301.logger().error("SCardListReaders error \(listReadersResult)") throw IdCardInternalError.readerProcessFailed } return Int(dwReaders) @@ -91,21 +89,21 @@ class CardReaderiR301: CardReader { buffer.baseAddress, &atrSize ) == SCARD_S_SUCCESS else { - CardReaderiR301.logger.error("ID-CARD: Failed to get card status") + CardReaderiR301.logger().error("ID-CARD: Failed to get card status") throw IdCardInternalError.readerProcessFailed } initializedCount = Int(atrSize) } - CardReaderiR301.logger.debug("SCardStatus status: \(dwStatus) ATR: \(self.atr.hex))") + CardReaderiR301.logger().debug("SCardStatus status: \(dwStatus) ATR: \(self.atr.hex))") guard dwStatus == SCARD_PRESENT else { - CardReaderiR301.logger.error("ID-CARD: Did not successfully power on card") + CardReaderiR301.logger().error("ID-CARD: Did not successfully power on card") throw IdCardInternalError.readerProcessFailed } } func transmit(_ apdu: Bytes) async throws -> (responseData: Bytes, sw: UInt16) { - CardReaderiR301.logger.debug("ID-CARD Transmitting: \(apdu.hex)") + CardReaderiR301.logger().debug("ID-CARD Transmitting: \(apdu.hex)") var responseSize: DWORD = 512 var response = try Bytes(unsafeUninitializedCapacity: Int(responseSize)) { buffer, initializedCount in guard SCardTransmit( @@ -118,16 +116,17 @@ class CardReaderiR301: CardReader { &responseSize ) == SCARD_S_SUCCESS else { - CardReaderiR301.logger.error("ID-CARD: Failed to send APDU data") + CardReaderiR301.logger().error("ID-CARD: Failed to send APDU data") throw IdCardInternalError.readerProcessFailed } initializedCount = Int(responseSize) } guard response.count >= 2 else { - CardReaderiR301.logger.error("ID-CARD: Response size must be at least 2. Response size: \(response.count)") + CardReaderiR301.logger().error( + "ID-CARD: Response size must be at least 2. Response size: \(response.count)") throw IdCardInternalError.readerProcessFailed } - CardReaderiR301.logger.debug("ID-CARD Response: \(response.hex)") + CardReaderiR301.logger().debug("ID-CARD Response: \(response.hex)") let swVal = UInt16(response[response.count - 2], response[response.count - 1]) response.removeLast(2) return (response, swVal) diff --git a/Modules/IdCardLib/Sources/IdCardLib/Extensions/NFCISO7816Tag+Extensions.swift b/Modules/IdCardLib/Sources/IdCardLib/Extensions/NFCISO7816Tag+Extensions.swift index 8037a298..5708f3a5 100644 --- a/Modules/IdCardLib/Sources/IdCardLib/Extensions/NFCISO7816Tag+Extensions.swift +++ b/Modules/IdCardLib/Sources/IdCardLib/Extensions/NFCISO7816Tag+Extensions.swift @@ -17,12 +17,13 @@ * */ +import CommonsLib import CoreNFC import CryptoTokenKit -import OSLog -extension NFCISO7816Tag { +private struct NFCISO7816TagLogger: Loggable {} +extension NFCISO7816Tag { func sendCommand( cls: UInt8, ins: UInt8, @@ -91,8 +92,7 @@ extension NFCISO7816Tag { throw IdCardInternalError.invalidResponse(message: "response conversion failed") } } catch let error as IdCardInternalError { - let logger = Logger(subsystem: "ee.ria.digidoc.RIADigiDoc", category: "NFCISO7816Tag") - logger.error("sendPaceCommand \(error.localizedDescription)") + NFCISO7816TagLogger.logger().error("sendPaceCommand \(error.localizedDescription)") switch error { case .sendCommandFailed(message: let message): throw IdCardInternalError.invalidResponse(message: message) diff --git a/Modules/IdCardLib/Sources/IdCardLib/Operations/UsbReaderConnection.swift b/Modules/IdCardLib/Sources/IdCardLib/Operations/UsbReaderConnection.swift index 3ba05ae6..a9268d64 100644 --- a/Modules/IdCardLib/Sources/IdCardLib/Operations/UsbReaderConnection.swift +++ b/Modules/IdCardLib/Sources/IdCardLib/Operations/UsbReaderConnection.swift @@ -17,9 +17,9 @@ * */ +import CommonsLib import Foundation import iR301 -import OSLog public protocol UsbReaderConnectionDelegate: AnyObject { func readerStatusDidChange(_ status: UsbReaderStatus) @@ -35,8 +35,7 @@ public enum UsbReaderStatus { } @MainActor -public class UsbReaderConnection { - private static let logger = Logger(subsystem: "ee.ria.digidoc.RIADigiDoc", category: "ReaderConnection") +public class UsbReaderConnection: Loggable { public static let shared = UsbReaderConnection() public weak var delegate: UsbReaderConnectionDelegate? @@ -49,22 +48,22 @@ public class UsbReaderConnection { public func startDiscoveringReaders() { guard handle == 0 else { - UsbReaderConnection.logger.error("ID-CARD: Reader discovery is already running") + UsbReaderConnection.logger().error("ID-CARD: Reader discovery is already running") return } - UsbReaderConnection.logger.debug("ID-CARD: Starting reader discovery") + UsbReaderConnection.logger().debug("ID-CARD: Starting reader discovery") updateStatus(status) SCardEstablishContext(DWORD(SCARD_SCOPE_SYSTEM), nil, nil, &handle) - UsbReaderConnection.logger.debug("ID-CARD: Started reader discovery: \(self.handle)") + UsbReaderConnection.logger().debug("ID-CARD: Started reader discovery: \(self.handle)") } public func stopDiscoveringReaders(with status: UsbReaderStatus = .sInitial) { - UsbReaderConnection.logger.debug("ID-CARD: Stopping reader discovery") + UsbReaderConnection.logger().debug("ID-CARD: Stopping reader discovery") self.status = status FtDidEnterBackground(1) SCardCancel(handle) SCardReleaseContext(handle) - UsbReaderConnection.logger.debug("ID-CARD: Stopped reader discovery with status: \(self.handle)") + UsbReaderConnection.logger().debug("ID-CARD: Stopped reader discovery with status: \(self.handle)") handle = 0 } @@ -77,8 +76,7 @@ public class UsbReaderConnection { } @MainActor -private class UsbReaderInterfaceHandler: NSObject, @MainActor ReaderInterfaceDelegate { - private static let logger = Logger(subsystem: "ee.ria.digidoc.RIADigiDoc", category: "ReaderInterfaceDelegate") +private class UsbReaderInterfaceHandler: NSObject, @MainActor ReaderInterfaceDelegate, Loggable { private let readerInterface = ReaderInterface() override init() { @@ -87,12 +85,12 @@ private class UsbReaderInterfaceHandler: NSObject, @MainActor ReaderInterfaceDel } func readerInterfaceDidChange(_ attached: Bool, bluetoothID _: String?) { - UsbReaderInterfaceHandler.logger.debug("ID-CARD attached: \(attached)") + UsbReaderInterfaceHandler.logger().debug("ID-CARD attached: \(attached)") UsbReaderConnection.shared.updateStatus(attached ? .sReaderConnected : .sReaderNotConnected) } func cardInterfaceDidDetach(_ attached: Bool) { - UsbReaderInterfaceHandler.logger.debug("ID-CARD: Card (interface) attached: \(attached)") + UsbReaderInterfaceHandler.logger().debug("ID-CARD: Card (interface) attached: \(attached)") do { guard attached, let reader = try CardReaderiR301(contextHandle: UsbReaderConnection.shared.handle) else { return UsbReaderConnection.shared.updateStatus(.sReaderConnected) @@ -102,7 +100,7 @@ private class UsbReaderInterfaceHandler: NSObject, @MainActor ReaderInterfaceDel UsbReaderConnection.shared.updateStatus(.sCardConnected(handler)) } } catch { - UsbReaderInterfaceHandler.logger.debug("ID-CARD: Unable to power on card") + UsbReaderInterfaceHandler.logger().debug("ID-CARD: Unable to power on card") UsbReaderConnection.shared.updateStatus(.sReaderProcessFailed) } } @@ -112,6 +110,6 @@ private class UsbReaderInterfaceHandler: NSObject, @MainActor ReaderInterfaceDel } func findPeripheralReader(_ readerName: String) { - UsbReaderInterfaceHandler.logger.debug("ID-CARD: Reader name: \(readerName)") + UsbReaderInterfaceHandler.logger().debug("ID-CARD: Reader name: \(readerName)") } } diff --git a/Modules/LibdigidocLib/Sources/LibdigidocSwift/Domain/Conf/DigiDocConf.swift b/Modules/LibdigidocLib/Sources/LibdigidocSwift/Domain/Conf/DigiDocConf.swift index 4a9c05ec..5b109d20 100644 --- a/Modules/LibdigidocLib/Sources/LibdigidocSwift/Domain/Conf/DigiDocConf.swift +++ b/Modules/LibdigidocLib/Sources/LibdigidocSwift/Domain/Conf/DigiDocConf.swift @@ -18,15 +18,13 @@ */ import Foundation -import OSLog import FactoryKit import LibdigidocLibObjC import ConfigLib import UtilsLib import CommonsLib -public struct DigiDocConf: DigiDocConfProtocol { - private static let logger = Logger(subsystem: "ee.ria.digidoc.RIADigiDoc", category: "DigiDocConf") +public struct DigiDocConf: DigiDocConfProtocol, Loggable { @MainActor static let sharedInitializer = DigiDocInitializer( configurationRepository: Container.shared.configurationRepository(), @@ -35,6 +33,7 @@ public struct DigiDocConf: DigiDocConfProtocol { public static func initDigiDoc( configuration: ConfigurationProvider? = nil, + isLoggingEnabled: Bool = false, tsaOption: ServicesSettingsOption? = nil, tsaUrl: URL? = nil, tsaCert: Data? = nil, @@ -43,7 +42,10 @@ public struct DigiDocConf: DigiDocConfProtocol { sivaCert: Data? = nil, proxyInfo: ProxyInfo? = nil ) async throws { - try await sharedInitializer.initializeDigiDoc(configuration: configuration) + try await sharedInitializer.initializeDigiDoc( + configuration: configuration, + isLoggingEnabled: isLoggingEnabled + ) if let tsaOption { setTSAInfo(url: tsaUrl, cert: tsaCert, option: tsaOption, isInit: true) @@ -60,7 +62,7 @@ public struct DigiDocConf: DigiDocConfProtocol { Task { guard let configStream = await configurationRepository.observeConfigurationUpdates( ) else { - logger.error("Unable to get configuration updates stream") + logger().error("Unable to get configuration updates stream") return } do { @@ -68,7 +70,7 @@ public struct DigiDocConf: DigiDocConfProtocol { try await sharedInitializer.overrideConfiguration(newConfig: config) } } catch { - logger.error("Unable to override configuration updates: \(error)") + logger().error("Unable to override configuration updates: \(error)") } } } @@ -165,7 +167,7 @@ public struct DigiDocConf: DigiDocConfProtocol { } } -public actor DigiDocInitializer { +public actor DigiDocInitializer: Loggable { private var isInitialized = false private var initializationError: ErrorDetail? @@ -185,22 +187,25 @@ public actor DigiDocInitializer { self.fileManager = fileManager } - func initializeDigiDoc(configuration: ConfigurationProvider? = nil) async throws { + func initializeDigiDoc(configuration: ConfigurationProvider? = nil, isLoggingEnabled: Bool) async throws { guard !isInitialized else { throw DigiDocError.alreadyInitialized } + let logLevel = isLoggingEnabled ? DigiDocInitializer.libdigidocppLogLevel : 0 + if let customConf = configuration { try await initDigiDoc( conf: toDigiDocConfig( - logLevel: DigiDocInitializer.libdigidocppLogLevel, + logLevel: logLevel, logFile: overrideLogFile(), tslCache: overrideTSLCache(), configurationProvider: customConf ) ) } else { + digidocConf.logLevel = overrideLogLevel(logLevel: logLevel) try await initDigiDoc(conf: digidocConf) } isInitialized = true diff --git a/Modules/LibdigidocLib/Sources/LibdigidocSwift/Domain/Container/ContainerWrapper.swift b/Modules/LibdigidocLib/Sources/LibdigidocSwift/Domain/Container/ContainerWrapper.swift index e68f17af..821d0b6c 100644 --- a/Modules/LibdigidocLib/Sources/LibdigidocSwift/Domain/Container/ContainerWrapper.swift +++ b/Modules/LibdigidocLib/Sources/LibdigidocSwift/Domain/Container/ContainerWrapper.swift @@ -18,13 +18,11 @@ */ import Foundation -import OSLog import LibdigidocLibObjC import CommonsLib import UtilsLib -public actor ContainerWrapper: ContainerWrapperProtocol { - private static let logger = Logger(subsystem: "ee.ria.digidoc.LibdigidocLib", category: "ContainerWrapper") +public actor ContainerWrapper: ContainerWrapperProtocol, Loggable { private var containerURL: URL private var dataFiles: [DataFileWrapper] @@ -86,7 +84,7 @@ public actor ContainerWrapper: ContainerWrapperProtocol { saveDataFile: dataFile.fileId, to: tempSavedFileLocation.resolvedPath ) - ContainerWrapper.logger.debug("Successfully saved \(sanitizedFilename) to 'Saved Files' directory") + ContainerWrapper.logger().debug("Successfully saved \(sanitizedFilename) to 'Saved Files' directory") return tempSavedFileLocation } catch { let nsError = (error as NSError?) ?? NSError(domain: "ContainerWrapper - cannot save data file", code: 2) @@ -110,7 +108,7 @@ public actor ContainerWrapper: ContainerWrapperProtocol { @MainActor public func open(containerFile: URL, isSivaConfirmed: Bool) async throws -> ContainerWrapper { - ContainerWrapper.logger.debug("Opening container file '\(containerFile.lastPathComponent)'") + ContainerWrapper.logger().debug("Opening container file '\(containerFile.lastPathComponent)'") do { let container = try DigiDocContainerWrapper.open( @@ -151,7 +149,7 @@ public actor ContainerWrapper: ContainerWrapperProtocol { return try await open(containerFile: containerFile, isSivaConfirmed: true) } catch { - ContainerWrapper.logger.error("Unable to add data files. \(error)") + ContainerWrapper.logger().error("Unable to add data files. \(error)") let nsError = error as NSError @@ -300,7 +298,7 @@ public actor ContainerWrapper: ContainerWrapperProtocol { return dataFiles.compactMap { item in guard let dataFile = item as? DigiDocDataFile else { - ContainerWrapper.logger.error("Unexpected type: \(type(of: item))") + ContainerWrapper.logger().error("Unexpected type: \(type(of: item))") return DataFileWrapper(fileId: "", fileName: "", fileSize: 0, mediaType: "") } diff --git a/Modules/LibdigidocLib/Sources/LibdigidocSwift/SignedContainer.swift b/Modules/LibdigidocLib/Sources/LibdigidocSwift/SignedContainer.swift index 762241b5..9d747d4c 100644 --- a/Modules/LibdigidocLib/Sources/LibdigidocSwift/SignedContainer.swift +++ b/Modules/LibdigidocLib/Sources/LibdigidocSwift/SignedContainer.swift @@ -18,14 +18,12 @@ */ import Foundation -import OSLog import FactoryKit import LibdigidocLibObjC import CommonsLib import UtilsLib -public actor SignedContainer: SignedContainerProtocol { - private static let logger = Logger(subsystem: "ee.ria.digidoc.LibdigidocLib", category: "SignedContainer") +public actor SignedContainer: SignedContainerProtocol, Loggable { private static let signedContainerLogTag: String = "SignedContainer" @@ -311,9 +309,9 @@ extension SignedContainer { containerUtil: ContainerUtilProtocol = Container.shared.containerUtil(), isSivaConfirmed: Bool ) async throws -> SignedContainerProtocol { - logger.debug("Opening or creating container. Found \(dataFiles.count) datafile(s)") + logger().debug("Opening or creating container. Found \(dataFiles.count) datafile(s)") guard let firstFile = dataFiles.first else { - logger.error("Unable to create or open container. First datafile is nil") + logger().error("Unable to create or open container. First datafile is nil") throw DigiDocError.containerCreationFailed( ErrorDetail( message: "Cannot create or open container. Datafiles are empty" @@ -351,11 +349,11 @@ extension SignedContainer { } if dataFiles.count == 1 && isFirstDataFileContainer { - SignedContainer.logger.debug("Opening existing container") + SignedContainer.logger().debug("Opening existing container") return try await open(file: containerFile, isSivaConfirmed: isSivaConfirmed) } - SignedContainer.logger.debug("Creating a new container") + SignedContainer.logger().debug("Creating a new container") return try await create(containerFile: containerFile, dataFiles: dataFiles) } @@ -435,20 +433,20 @@ extension SignedContainer { containerUtil: Container.shared.containerUtil() ) - SignedContainer.logger.debug("Container created. Removing \(dataFiles.count) saved data files") + SignedContainer.logger().debug("Container created. Removing \(dataFiles.count) saved data files") for (index, dataFile) in dataFiles.enumerated() { let containerName = await signedContainer.getContainerName() if await dataFile.isContainer() && containerName == dataFile.lastPathComponent { continue } - SignedContainer.logger.debug( + SignedContainer.logger().debug( "Removing data file (\(index + 1) / \(dataFiles.count)): \(dataFile.lastPathComponent)" ) if fileManager.fileExists(atPath: dataFile.resolvedPath) && fileManager.isDeletableFile(atPath: dataFile.resolvedPath) { try fileManager.removeItem(at: dataFile) - SignedContainer.logger.debug("Data file: '\(dataFile.lastPathComponent)' removed") + SignedContainer.logger().debug("Data file: '\(dataFile.lastPathComponent)' removed") } } diff --git a/Modules/MobileIdLib/Sources/MobileIdLib/Service/MobileIdSignService.swift b/Modules/MobileIdLib/Sources/MobileIdLib/Service/MobileIdSignService.swift index c3832612..480825ea 100644 --- a/Modules/MobileIdLib/Sources/MobileIdLib/Service/MobileIdSignService.swift +++ b/Modules/MobileIdLib/Sources/MobileIdLib/Service/MobileIdSignService.swift @@ -18,14 +18,11 @@ */ import Foundation -import OSLog import Alamofire import CommonsLib import UtilsLib -actor MobileIdSignService: MobileIdSignServiceProtocol { - private static let logger = Logger(subsystem: "ee.ria.digidoc.RIADigiDoc", category: "MobileIdSignService") - +actor MobileIdSignService: MobileIdSignServiceProtocol, Loggable { private var session: Session? private var currentProxy: ProxyInfo? @@ -160,7 +157,7 @@ actor MobileIdSignService: MobileIdSignServiceProtocol { return try response.result.get() } catch { - MobileIdSignService.logger.error( + MobileIdSignService.logger().error( "Unable to perform Mobile-ID request: \(error)" ) @@ -186,7 +183,7 @@ actor MobileIdSignService: MobileIdSignServiceProtocol { currentProxy = proxyInfo guard let host = URL(string: url)?.host else { - MobileIdSignService.logger.error( + MobileIdSignService.logger().error( "Unable to parse host from URL: \(url)" ) throw URLError(.badURL) diff --git a/Modules/SmartIdLib/Sources/SmartIdLib/Service/SmartIdSignService.swift b/Modules/SmartIdLib/Sources/SmartIdLib/Service/SmartIdSignService.swift index 552a366c..a72ae9ef 100644 --- a/Modules/SmartIdLib/Sources/SmartIdLib/Service/SmartIdSignService.swift +++ b/Modules/SmartIdLib/Sources/SmartIdLib/Service/SmartIdSignService.swift @@ -18,18 +18,12 @@ */ import Foundation -import OSLog import Alamofire import CommonsLib import UtilsLib import UIKit -public actor SmartIdSignService: SmartIdSignServiceProtocol { - private static let logger = Logger( - subsystem: "ee.ria.digidoc.RIADigiDoc", - category: "SmartIdSignService" - ) - +public actor SmartIdSignService: SmartIdSignServiceProtocol, Loggable { private var session: Session? private var currentProxy: ProxyInfo? @@ -217,7 +211,7 @@ public actor SmartIdSignService: SmartIdSignServiceProtocol { currentProxy = proxyInfo guard let host = URL(string: url)?.host else { - SmartIdSignService.logger.error( + SmartIdSignService.logger().error( "Unable to parse host from URL: \(url)" ) throw URLError(.badURL) diff --git a/Modules/Test/CommonsTestShared/Sources/CommonsTestShared/File/TestFileUtil.swift b/Modules/Test/CommonsTestShared/Sources/CommonsTestShared/File/TestFileUtil.swift index f6f64322..46a6bb05 100644 --- a/Modules/Test/CommonsTestShared/Sources/CommonsTestShared/File/TestFileUtil.swift +++ b/Modules/Test/CommonsTestShared/Sources/CommonsTestShared/File/TestFileUtil.swift @@ -18,24 +18,17 @@ */ import Foundation -import OSLog import FactoryKit import CommonsLib -public struct TestFileUtil { - - private static let logger = Logger( - subsystem: "ee.ria.digidoc.CommonsLib.CommonsTestShared", - category: "TestFileUtil" - ) - +public struct TestFileUtil: Loggable { private static let bundleIdentifier = Bundle.main.bundleIdentifier ?? "ee.ria.digidoc" public init() {} public static func getURL(string: String) throws -> URL { guard let url = URL(string: string) else { - TestFileUtil.logger.error("'\(string)' is not a valid URL") + TestFileUtil.logger().error("'\(string)' is not a valid URL") throw URLError(.badURL) } return url @@ -58,7 +51,7 @@ public struct TestFileUtil { ) } } catch { - logger.error( + logger().error( "Unable to create temporary file directory or remove existing file: \(error.localizedDescription)" ) } @@ -85,7 +78,7 @@ public struct TestFileUtil { ) if !isCreated { - logger.error( + logger().error( "Unable to create file at path: \(tempFileDirectory.standardizedFileURL.path(percentEncoded: false))" ) } diff --git a/Modules/Test/CommonsTestShared/Sources/CommonsTestShared/Url/MockURLProtocol.swift b/Modules/Test/CommonsTestShared/Sources/CommonsTestShared/Url/MockURLProtocol.swift index 1c61470d..8ccb2f8d 100644 --- a/Modules/Test/CommonsTestShared/Sources/CommonsTestShared/Url/MockURLProtocol.swift +++ b/Modules/Test/CommonsTestShared/Sources/CommonsTestShared/Url/MockURLProtocol.swift @@ -19,8 +19,8 @@ // swiftlint:disable static_over_final_class unused_parameter +import CommonsLib import Foundation -import OSLog import Alamofire public final class MockURLProtocol: URLProtocol { @@ -56,12 +56,7 @@ public final class MockURLProtocol: URLProtocol { public override func stopLoading() { } } -final class MockInterceptor: RequestInterceptor { - private static let logger = Logger( - subsystem: "ee.ria.digidoc.RIADigiDoc.CommonsTestShared", - category: "MockInterceptor" - ) - +final class MockInterceptor: RequestInterceptor, Loggable { let handler: MockURLProtocol.Handler init(handler: @escaping MockURLProtocol.Handler) { @@ -76,7 +71,7 @@ final class MockInterceptor: RequestInterceptor { let mutableRequest = (urlRequest as NSURLRequest).mutableCopy() as? NSMutableURLRequest guard let request = mutableRequest else { - MockInterceptor.logger.error("Unable to get mutable URLRequest") + MockInterceptor.logger().error("Unable to get mutable URLRequest") return } diff --git a/Modules/UtilsLib/Sources/UtilsLib/Container/ContainerUtil.swift b/Modules/UtilsLib/Sources/UtilsLib/Container/ContainerUtil.swift index 7fa22bf7..4216b92b 100644 --- a/Modules/UtilsLib/Sources/UtilsLib/Container/ContainerUtil.swift +++ b/Modules/UtilsLib/Sources/UtilsLib/Container/ContainerUtil.swift @@ -18,13 +18,10 @@ */ import Foundation -import OSLog import FactoryKit import CommonsLib -public struct ContainerUtil: ContainerUtilProtocol { - - private static let logger = Logger(subsystem: "ee.ria.digidoc.UtilsLib", category: "ContainerUtil") +public struct ContainerUtil: ContainerUtilProtocol, Loggable { private let dataFileDirectory = "%@-data-files" @@ -65,11 +62,11 @@ public struct ContainerUtil: ContainerUtilProtocol { do { try fileManager .createDirectory(at: signedContainersDirectory, withIntermediateDirectories: true, attributes: [:]) - ContainerUtil.logger.debug( + ContainerUtil.logger().debug( "Directories created or already exist for \(signedContainersDirectory.resolvedPath)" ) } catch { - ContainerUtil.logger.error("Unable to create signature containers dir: \(error.localizedDescription)") + ContainerUtil.logger().error("Unable to create signature containers dir: \(error.localizedDescription)") throw error } @@ -121,10 +118,10 @@ public struct ContainerUtil: ContainerUtilProtocol { attributes: [:] ) if let base = directory { - ContainerUtil.logger.debug("Directories created or already exist for \(base.resolvedPath)") + ContainerUtil.logger().debug("Directories created or already exist for \(base.resolvedPath)") } } catch { - ContainerUtil.logger.error("Failed to create directory: \(error.localizedDescription)") + ContainerUtil.logger().error("Failed to create directory: \(error.localizedDescription)") } return targetDirectory diff --git a/Modules/UtilsLib/Sources/UtilsLib/Extensions/StringExtensions.swift b/Modules/UtilsLib/Sources/UtilsLib/Extensions/StringExtensions.swift index 85a7c54d..1f3d8937 100644 --- a/Modules/UtilsLib/Sources/UtilsLib/Extensions/StringExtensions.swift +++ b/Modules/UtilsLib/Sources/UtilsLib/Extensions/StringExtensions.swift @@ -18,11 +18,9 @@ */ import Foundation -import OSLog import CommonsLib extension String { - private static let logger = Logger(subsystem: "ee.ria.digidoc.RIADigiDoc", category: "String extension") public func sanitized() -> String { var forbidden = CharacterSet.illegalCharacters diff --git a/Modules/UtilsLib/Sources/UtilsLib/Extensions/URLExtensions.swift b/Modules/UtilsLib/Sources/UtilsLib/Extensions/URLExtensions.swift index 30301831..6559bcea 100644 --- a/Modules/UtilsLib/Sources/UtilsLib/Extensions/URLExtensions.swift +++ b/Modules/UtilsLib/Sources/UtilsLib/Extensions/URLExtensions.swift @@ -21,7 +21,6 @@ import Foundation import CryptoKit import PDFKit import UniformTypeIdentifiers -import OSLog import System import ZIPFoundation import FactoryKit diff --git a/Modules/UtilsLib/Sources/UtilsLib/File/FileUtil.swift b/Modules/UtilsLib/Sources/UtilsLib/File/FileUtil.swift index 13080a60..37b365bc 100644 --- a/Modules/UtilsLib/Sources/UtilsLib/File/FileUtil.swift +++ b/Modules/UtilsLib/Sources/UtilsLib/File/FileUtil.swift @@ -18,15 +18,12 @@ */ import Foundation -import OSLog import System import ZIPFoundation import FactoryKit import CommonsLib -public struct FileUtil: FileUtilProtocol { - - private static let logger = Logger(subsystem: "ee.ria.digidoc.UtilsLib", category: "FileUtil") +public struct FileUtil: FileUtilProtocol, Loggable { private let fileManager: FileManagerProtocol @@ -67,7 +64,7 @@ public struct FileUtil: FileUtilProtocol { // Check file path so its valid and is not modified by someone else public func getValidPath(url: URL) async -> URL? { - FileUtil.logger.debug("Getting valid path for file: \(url)") + FileUtil.logger().debug("Getting valid path for file: \(url)") let resolvedURL = url.resolvingSymlinksInPath() let filePath = FilePath(resolvedURL.resolvedPath).lexicallyNormalized() @@ -99,7 +96,7 @@ public struct FileUtil: FileUtilProtocol { .lexicallyNormalized() if filePath.starts(with: appContainerPath) { - FileUtil.logger.debug("Resolved valid file path: \(resolvedURL)") + FileUtil.logger().debug("Resolved valid file path: \(resolvedURL)") return resolvedURL } } @@ -107,38 +104,39 @@ public struct FileUtil: FileUtilProtocol { // Check if file is opened externally (outside of application) let fileFromAppGroup = getFileUrlFromAppGroup(resolvedURL, appGroupIdentifier: Constants.Identifier.Group) if let fileUrl = fileFromAppGroup { - FileUtil.logger.debug("File is from app group: \(fileUrl)") + FileUtil.logger().debug("File is from app group: \(fileUrl)") return fileUrl } if isFileInsideMailFolder(resolvedURL) { - FileUtil.logger.debug("File is from Mail app") + FileUtil.logger().debug("File is from Mail app") return resolvedURL } else { - FileUtil.logger.debug("Checking if file is from iCloud") + FileUtil.logger().debug("Checking if file is from iCloud") // Check if file is opened from iCloud if isFileFromiCloud(fileURL: resolvedURL) { if !isFileDownloadedFromiCloud(fileURL: resolvedURL) { - FileUtil.logger.debug( + FileUtil.logger().debug( "File '\(resolvedURL.lastPathComponent)' from iCloud is not downloaded. Downloading..." ) let downloadedFileUrl = await downloadFileFromiCloud(fileURL: resolvedURL) if let fileUrl = downloadedFileUrl { - FileUtil.logger.debug("File '\(resolvedURL.lastPathComponent)' downloaded from iCloud") + FileUtil.logger().debug("File '\(resolvedURL.lastPathComponent)' downloaded from iCloud") return fileUrl } else { - FileUtil.logger.debug("Unable to download file '\(resolvedURL.lastPathComponent)' from iCloud") + FileUtil.logger().debug( + "Unable to download file '\(resolvedURL.lastPathComponent)' from iCloud") return nil } } else { - FileUtil.logger.debug("File '\(resolvedURL.lastPathComponent)' from iCloud is already downloaded") + FileUtil.logger().debug("File '\(resolvedURL.lastPathComponent)' from iCloud is already downloaded") return url } } } - FileUtil.logger.debug("File is NOT from iCloud") + FileUtil.logger().debug("File is NOT from iCloud") return nil } @@ -164,7 +162,7 @@ public struct FileUtil: FileUtilProtocol { ) if isFromAppGroup { - FileUtil.logger.debug("File is from app group: \(normalizedURL)") + FileUtil.logger().debug("File is from app group: \(normalizedURL)") return normalizedURL } @@ -179,7 +177,7 @@ public struct FileUtil: FileUtilProtocol { return true } } catch { - FileUtil.logger.error( + FileUtil.logger().error( "Unable to check iCloud file '\(fileURL.lastPathComponent)' status: \(error.localizedDescription)" ) } @@ -192,7 +190,7 @@ public struct FileUtil: FileUtilProtocol { let values = try fileURL.resourceValues(forKeys: [.ubiquitousItemDownloadingStatusKey]) if let downloadingStatus = values.ubiquitousItemDownloadingStatus, downloadingStatus == .current { - FileUtil.logger.debug("File downloaded from iCloud") + FileUtil.logger().debug("File downloaded from iCloud") return true } } catch { @@ -201,7 +199,7 @@ public struct FileUtil: FileUtilProtocol { fileURL.lastPathComponent, error.localizedDescription ) - FileUtil.logger.error("\(errorMessage)") + FileUtil.logger().error("\(errorMessage)") } return false @@ -210,16 +208,16 @@ public struct FileUtil: FileUtilProtocol { public func downloadFileFromiCloud(fileURL: URL) async -> URL? { do { try fileManager.startDownloadingUbiquitousItem(at: fileURL) - FileUtil.logger.debug("Downloading file '\(fileURL.lastPathComponent)' from iCloud") + FileUtil.logger().debug("Downloading file '\(fileURL.lastPathComponent)' from iCloud") while !isFileDownloadedFromiCloud(fileURL: fileURL) { try await Task.sleep(for: .seconds(0.5)) } - FileUtil.logger.debug("iCloud file '\(fileURL.lastPathComponent)' downloaded") + FileUtil.logger().debug("iCloud file '\(fileURL.lastPathComponent)' downloaded") return fileURL } catch { - FileUtil.logger.error( + FileUtil.logger().error( "Unable to start iCloud file '\(fileURL.lastPathComponent)' download: \(error.localizedDescription)" ) return nil @@ -231,7 +229,7 @@ public struct FileUtil: FileUtilProtocol { let filePath = FilePath(stringLiteral: url.resolvedPath).lexicallyNormalized() if filePath == mailFolderPath { - FileUtil.logger.debug("File '\(url.lastPathComponent)' is from Mail app") + FileUtil.logger().debug("File '\(url.lastPathComponent)' is from Mail app") return true } @@ -240,18 +238,18 @@ public struct FileUtil: FileUtilProtocol { let filePathString = filePath.string if filePathString.count == mailPathString.count { - FileUtil.logger.debug("File '\(url.lastPathComponent)' is from Mail app") + FileUtil.logger().debug("File '\(url.lastPathComponent)' is from Mail app") return true } let index = filePathString.index(filePathString.startIndex, offsetBy: mailPathString.count) if filePathString[index] == "/" { - FileUtil.logger.debug("File '\(url.lastPathComponent)' is from Mail app") + FileUtil.logger().debug("File '\(url.lastPathComponent)' is from Mail app") return true } } - FileUtil.logger.debug("File '\(url.lastPathComponent)' is NOT from Mail app") + FileUtil.logger().debug("File '\(url.lastPathComponent)' is NOT from Mail app") return false } @@ -270,7 +268,7 @@ public struct FileUtil: FileUtilProtocol { } public func removeSharedFiles(url: URL?) throws { - FileUtil.logger.debug("Removing shared files") + FileUtil.logger().debug("Removing shared files") let sharedFilesFolder = try url ?? Directories.getSharedFolder(fileManager: fileManager) @@ -280,20 +278,20 @@ public struct FileUtil: FileUtilProtocol { try fileManager.removeItem(at: fileURL) } - FileUtil.logger.debug("Shared files removed") + FileUtil.logger().debug("Shared files removed") } public func removeSavedFilesDirectory(savedFilesDirectory: URL? = nil) { - FileUtil.logger.debug("Removing saved files directory") + FileUtil.logger().debug("Removing saved files directory") do { let directory = try savedFilesDirectory ?? Directories.getCacheDirectory( subfolder: CommonsLib.Constants.Folder.SavedFiles, fileManager: fileManager ) try fileManager.removeItem(at: directory) - FileUtil.logger.debug("Saved Files directory removed") + FileUtil.logger().debug("Saved Files directory removed") } catch { - FileUtil.logger.error("Unable to delete saved files directory: \(error.localizedDescription)") + FileUtil.logger().error("Unable to delete saved files directory: \(error.localizedDescription)") } } } diff --git a/Modules/UtilsLib/Sources/UtilsLib/Notification/NotificationUtil.swift b/Modules/UtilsLib/Sources/UtilsLib/Notification/NotificationUtil.swift index 153d7c4f..2e525db9 100644 --- a/Modules/UtilsLib/Sources/UtilsLib/Notification/NotificationUtil.swift +++ b/Modules/UtilsLib/Sources/UtilsLib/Notification/NotificationUtil.swift @@ -17,31 +17,26 @@ * */ +import CommonsLib import Foundation import NotificationCenter -import OSLog @MainActor -public final class NotificationUtil: NSObject, NotificationUtilProtocol { - private static let logger = Logger( - subsystem: "ee.ria.digidoc.RIADigiDoc", - category: "NotificationUtil" - ) - +public final class NotificationUtil: NSObject, NotificationUtilProtocol, Loggable { override init() { super.init() UNUserNotificationCenter.current().delegate = self } public func requestAuthorization() async -> Bool { - NotificationUtil.logger.debug("Requesting authorization to send notifications") + NotificationUtil.logger().debug("Requesting authorization to send notifications") let center = UNUserNotificationCenter.current() do { let granted = try await center.requestAuthorization(options: [.alert, .sound, .badge]) - NotificationUtil.logger.debug("Notification sending authorized: \(granted)") + NotificationUtil.logger().debug("Notification sending authorized: \(granted)") return granted } catch { - NotificationUtil.logger.debug("Unable to request authorization to send notifications. \(error)") + NotificationUtil.logger().debug("Unable to request authorization to send notifications. \(error)") return false } } @@ -50,7 +45,7 @@ public final class NotificationUtil: NSObject, NotificationUtilProtocol { title: String, body: String ) async throws -> String { - NotificationUtil.logger.debug("Sending notification (\(title))") + NotificationUtil.logger().debug("Sending notification (\(title))") let notificationId = UUID().uuidString let content = UNMutableNotificationContent() @@ -62,17 +57,17 @@ public final class NotificationUtil: NSObject, NotificationUtilProtocol { try await UNUserNotificationCenter.current().add(request) - NotificationUtil.logger.debug("Notification sent. ID: \(notificationId)") + NotificationUtil.logger().debug("Notification sent. ID: \(notificationId)") return notificationId } public func removeNotification(id: String) { - NotificationUtil.logger.debug("Removing notification (\(id))") + NotificationUtil.logger().debug("Removing notification (\(id))") let center = UNUserNotificationCenter.current() center.removePendingNotificationRequests(withIdentifiers: [id]) center.removeDeliveredNotifications(withIdentifiers: [id]) - NotificationUtil.logger.debug("Removed notification \(id)") + NotificationUtil.logger().debug("Removed notification \(id)") } } diff --git a/Modules/UtilsLib/Sources/UtilsLib/Validator/PersonalCodeValidator.swift b/Modules/UtilsLib/Sources/UtilsLib/Validator/PersonalCodeValidator.swift index 95d8b29c..c076144f 100644 --- a/Modules/UtilsLib/Sources/UtilsLib/Validator/PersonalCodeValidator.swift +++ b/Modules/UtilsLib/Sources/UtilsLib/Validator/PersonalCodeValidator.swift @@ -18,11 +18,9 @@ */ import Foundation -import OSLog import CommonsLib -public struct PersonalCodeValidator { - private static let logger = Logger(subsystem: "ee.ria.digidoc.RIADigiDoc", category: "PersonalCodeValidator") +public struct PersonalCodeValidator: Loggable { public static func isPersonalCodeValid(_ personalCode: String) -> Bool { return ( @@ -40,7 +38,7 @@ public struct PersonalCodeValidator { guard !personalCode.isEmpty, personalCode.count == Constants.Validation.MaximumLatvianPersonalCodeLength else { - PersonalCodeValidator.logger.debug("Personal code is NOT Latvian") + PersonalCodeValidator.logger().debug("Personal code is NOT Latvian") return false } @@ -60,14 +58,14 @@ public struct PersonalCodeValidator { let dateOfBirth = try parseDateOfBirth(personalCode) return dateOfBirth < Date() } catch { - PersonalCodeValidator.logger.error("Invalid personal code or birth date: \(error)") + PersonalCodeValidator.logger().error("Invalid personal code or birth date: \(error)") return false } } private static func parseDateOfBirth(_ personalCode: String) throws -> Date { guard let firstDigit = personalCode.first?.wholeNumberValue else { - PersonalCodeValidator.logger.error("Personal code cannot be empty") + PersonalCodeValidator.logger().error("Personal code cannot be empty") throw PersonalCodeError.invalidPersonalCode("Personal code cannot be empty") } @@ -82,7 +80,7 @@ public struct PersonalCodeValidator { case 7, 8: century = 2100 default: - PersonalCodeValidator.logger.error("Unable to get century from: \(firstDigit)") + PersonalCodeValidator.logger().error("Unable to get century from: \(firstDigit)") throw PersonalCodeError.invalidPersonalCode("Unable to get century from: \(firstDigit)") } @@ -93,7 +91,7 @@ public struct PersonalCodeValidator { guard let yearOffset = Int(yearString), let month = Int(monthString), let day = Int(dayString) else { - PersonalCodeValidator.logger.error("Invalid date \(dayString).\(monthString).\(yearString)") + PersonalCodeValidator.logger().error("Invalid date \(dayString).\(monthString).\(yearString)") throw PersonalCodeError.invalidDate("Invalid date \(dayString).\(monthString).\(yearString)") } @@ -105,7 +103,7 @@ public struct PersonalCodeValidator { components.day = day guard let date = Calendar.current.date(from: components) else { - PersonalCodeValidator.logger.error("Invalid date \(components)") + PersonalCodeValidator.logger().error("Invalid date \(components)") throw PersonalCodeError.invalidDate("Invalid date \(components)") } @@ -124,7 +122,7 @@ public struct PersonalCodeValidator { let char = personalCode[index] guard let personalCodeNumber = Int(String(char)) else { - PersonalCodeValidator.logger.error("Unable to parse personal code number at index \(digitIndex)") + PersonalCodeValidator.logger().error("Unable to parse personal code number at index \(digitIndex)") continue } @@ -145,7 +143,7 @@ public struct PersonalCodeValidator { guard let lastChar = personalCode.last, let lastNumber = Int(String(lastChar)) else { - PersonalCodeValidator.logger.error("Personal code checksum is NOT valid") + PersonalCodeValidator.logger().error("Personal code checksum is NOT valid") return false } diff --git a/Modules/UtilsLib/Sources/UtilsLib/Validator/PhoneNumberValidator.swift b/Modules/UtilsLib/Sources/UtilsLib/Validator/PhoneNumberValidator.swift index e41d6655..77338a3d 100644 --- a/Modules/UtilsLib/Sources/UtilsLib/Validator/PhoneNumberValidator.swift +++ b/Modules/UtilsLib/Sources/UtilsLib/Validator/PhoneNumberValidator.swift @@ -18,34 +18,31 @@ */ import Foundation -import OSLog import CommonsLib -public struct PhoneNumberValidator { - private static let logger = Logger(subsystem: "ee.ria.digidoc.RIADigiDoc", category: "PhoneNumberValidator") - +public struct PhoneNumberValidator: Loggable { private static let minimumPhoneNumberLength = Constants.Validation.MinimumPhoneNumberLength private static let allowedPhoneNumberCountryCodes = Constants.Validation.AllowedPhoneNumberCountryCodes public static func isCountryCodeMissing(_ phoneNumber: String) -> Bool { let isCountryCodeMissing = (4.. Bool { for allowedCountryCode in allowedPhoneNumberCountryCodes where phoneNumber.hasPrefix(allowedCountryCode) { - PhoneNumberValidator.logger.debug("Phone number country code is correct") + PhoneNumberValidator.logger().debug("Phone number country code is correct") return true } - PhoneNumberValidator.logger.debug("Phone number country code is NOT correct") + PhoneNumberValidator.logger().debug("Phone number country code is NOT correct") return false } public static func isPhoneNumberCorrect(_ phoneNumber: String) -> Bool { let isCorrect = phoneNumber.count >= minimumPhoneNumberLength - PhoneNumberValidator.logger.debug("Is phone number correct: \(isCorrect)") + PhoneNumberValidator.logger().debug("Is phone number correct: \(isCorrect)") return isCorrect } } diff --git a/RIADigiDoc/ContentView.swift b/RIADigiDoc/ContentView.swift index ece1f916..0c1a30a4 100644 --- a/RIADigiDoc/ContentView.swift +++ b/RIADigiDoc/ContentView.swift @@ -19,7 +19,6 @@ import FactoryKit import SwiftUI -import OSLog import UtilsLib struct ContentView: View { diff --git a/RIADigiDoc/Domain/Preferences/DataStore.swift b/RIADigiDoc/Domain/Preferences/DataStore.swift index 51ad6b80..7a43a5f5 100644 --- a/RIADigiDoc/Domain/Preferences/DataStore.swift +++ b/RIADigiDoc/Domain/Preferences/DataStore.swift @@ -462,6 +462,16 @@ public actor DataStore: DataStoreProtocol { userDefaults().set(inputData.rememberMe, forKey: Keys.nfcRememberMe) } + // MARK: - Logging + + public func getIsLoggingEnabled() async -> Bool { + userDefaults().bool(forKey: Keys.isLoggingEnabled) + } + + public func setIsLoggingEnabled(_ isEnabled: Bool) async { + userDefaults().set(isEnabled, forKey: Keys.isLoggingEnabled) + } + // MARK: - Constants private enum DefaultValues { @@ -524,5 +534,6 @@ public actor DataStore: DataStoreProtocol { static let roleZipCode = "roleZipCode" static let nfcCanNumber = "nfcCanNumber" static let nfcRememberMe = "nfcRememberMe" + static let isLoggingEnabled = "isLoggingEnabled" } } diff --git a/RIADigiDoc/Domain/Preferences/DataStoreProtocol.swift b/RIADigiDoc/Domain/Preferences/DataStoreProtocol.swift index b47735ce..b00654e5 100644 --- a/RIADigiDoc/Domain/Preferences/DataStoreProtocol.swift +++ b/RIADigiDoc/Domain/Preferences/DataStoreProtocol.swift @@ -106,4 +106,8 @@ public protocol DataStoreProtocol: Sendable { // MARK: - NFC Input Methods func getNFCInputData() async -> NFCInputData func setNFCInputData(_ inputData: NFCInputData) async + + // MARK: - Logging + func getIsLoggingEnabled() async -> Bool + func setIsLoggingEnabled(_ isEnabled: Bool) async } diff --git a/RIADigiDoc/Domain/Preferences/KeychainStore.swift b/RIADigiDoc/Domain/Preferences/KeychainStore.swift index 75189c90..e0138452 100644 --- a/RIADigiDoc/Domain/Preferences/KeychainStore.swift +++ b/RIADigiDoc/Domain/Preferences/KeychainStore.swift @@ -19,11 +19,8 @@ import CommonsLib import Foundation -import OSLog - -public actor KeychainStore: KeychainStoreProtocol { - private static let logger = Logger(subsystem: "ee.ria.digidoc.RIADigiDoc", category: "KeychainStore") +public actor KeychainStore: KeychainStoreProtocol, Loggable { private let bundleIdentifier: String public init(bundleIdentifier: String? = nil) { @@ -51,7 +48,7 @@ public actor KeychainStore: KeychainStoreProtocol { let addStatus = SecItemAdd(queryWithAttributes as CFDictionary, nil) return addStatus == errSecSuccess } else { - await KeychainStore.logger.error("Unable to save \(key.rawValue): \(status)") + KeychainStore.logger().error("Unable to save \(key.rawValue): \(status)") return false } } @@ -80,7 +77,7 @@ public actor KeychainStore: KeychainStoreProtocol { let status = SecItemDelete(query as CFDictionary) if status != errSecSuccess { - await KeychainStore.logger.error("Error removing key from Keychain: \(status)") + KeychainStore.logger().error("Error removing key from Keychain: \(status)") } } diff --git a/RIADigiDoc/Domain/Repository/AdvancedSettings/AdvancedSettingsRepository.swift b/RIADigiDoc/Domain/Repository/AdvancedSettings/AdvancedSettingsRepository.swift index b93ac6b4..688f00f3 100644 --- a/RIADigiDoc/Domain/Repository/AdvancedSettings/AdvancedSettingsRepository.swift +++ b/RIADigiDoc/Domain/Repository/AdvancedSettings/AdvancedSettingsRepository.swift @@ -18,14 +18,11 @@ */ import Foundation -import OSLog import UniformTypeIdentifiers import UtilsLib import CommonsLib -actor AdvancedSettingsRepository: AdvancedSettingsRepositoryProtocol { - private static let logger = Logger(subsystem: "ee.ria.digidoc.RIADigiDoc", category: "AdvancedSettingsRepository") - +actor AdvancedSettingsRepository: AdvancedSettingsRepositoryProtocol, Loggable { private let fileManager: FileManagerProtocol private let certificateUtil: CertificateUtilProtocol @@ -52,7 +49,7 @@ actor AdvancedSettingsRepository: AdvancedSettingsRepositoryProtocol { else { return nil } return try await getCertificateContent(certFileURL: certFileURL) } catch { - await AdvancedSettingsRepository.logger.error("Unable to load certificate: \(error)") + AdvancedSettingsRepository.logger().error("Unable to load certificate: \(error)") return nil } } @@ -116,7 +113,7 @@ actor AdvancedSettingsRepository: AdvancedSettingsRepositoryProtocol { return try await getCertificateContent(certFileURL: destinationURL) } catch { - await AdvancedSettingsRepository.logger.error("Unable to import certificate: \(error)") + AdvancedSettingsRepository.logger().error("Unable to import certificate: \(error)") return nil } } diff --git a/RIADigiDoc/LibrarySetup.swift b/RIADigiDoc/LibrarySetup.swift index 05825af8..fc5524d8 100644 --- a/RIADigiDoc/LibrarySetup.swift +++ b/RIADigiDoc/LibrarySetup.swift @@ -18,7 +18,7 @@ */ import Foundation -import OSLog +import FactoryKit import LibdigidocLibSwift import CryptoObjCWrapper import CryptoSwift @@ -26,9 +26,7 @@ import ConfigLib import CommonsLib import UtilsLib -actor LibrarySetup { - private static let logger = Logger(subsystem: "ee.ria.digidoc.RIADigiDoc", category: "LibrarySetup") - +actor LibrarySetup: Loggable { private let configurationLoader: ConfigurationLoaderProtocol private let configurationRepository: ConfigurationRepositoryProtocol private let fileManager: FileManagerProtocol @@ -62,6 +60,9 @@ actor LibrarySetup { } func setupLibraries() async { + let isLoggingEnabled = await dataStore.getIsLoggingEnabled() + await initializeLogging(isLoggingEnabled: isLoggingEnabled) + do { let proxyInfo = await proxyUtil.getProxyInfo() @@ -72,7 +73,7 @@ actor LibrarySetup { if let schemaDirectory = Directories.getLibraryDirectory(fileManager: fileManager) { try tslUtil.setupTSLFiles(tsls: [], destinationDir: schemaDirectory) } else { - LibrarySetup.logger.error("Unable to setup TSL files. Library directory does not exist") + LibrarySetup.logger().error("Unable to setup TSL files. Library directory does not exist") } let configDirectory = try Directories.getCacheDirectory( fileManager: fileManager @@ -87,11 +88,12 @@ actor LibrarySetup { proxyInfo: proxyInfo ) } catch { - LibrarySetup.logger.error("Unable to initialize configuration: \(error)") + LibrarySetup.logger().error("Unable to initialize configuration: \(error)") } - LibrarySetup.logger.debug("Initializing Libdigidocpp") + LibrarySetup.logger().debug("Initializing Libdigidocpp") try await DigiDocConf.initDigiDoc( + isLoggingEnabled: isLoggingEnabled, tsaOption: getTSAOption(), tsaUrl: getTSAUrl(), tsaCert: getTSACert(), @@ -100,7 +102,7 @@ actor LibrarySetup { sivaCert: getSiVaCert(), proxyInfo: proxyInfo ) - LibrarySetup.logger.info("Libdigidocpp initialized successfully") + LibrarySetup.logger().info("Libdigidocpp initialized successfully") let configurationProvider = await configurationRepository.getConfiguration() @@ -112,10 +114,10 @@ actor LibrarySetup { } catch let error { switch error { case DigiDocError.initializationFailed(let errorDetail): - LibrarySetup.logger.error("\(errorDetail.description)") + LibrarySetup.logger().error("\(errorDetail.description)") case DigiDocError.alreadyInitialized: - LibrarySetup.logger.error("Cannot initialize Libdigidocpp: Already initialized") - default: LibrarySetup.logger.error( + LibrarySetup.logger().error("Cannot initialize Libdigidocpp: Already initialized") + default: LibrarySetup.logger().error( "Unknown initialization error: \(error.localizedDescription). Error: \(error)") } } @@ -164,6 +166,10 @@ actor LibrarySetup { ) } + private func initializeLogging(isLoggingEnabled: Bool) async { + Container.shared.isLoggingEnabled.register { isLoggingEnabled } + } + private func getTSAOption() async -> ServicesSettingsOption { return await dataStore.getTSAUrlOption() } diff --git a/RIADigiDoc/Util/Certificate/CertificateUtil.swift b/RIADigiDoc/Util/Certificate/CertificateUtil.swift index 1bcb2b18..cb567df8 100644 --- a/RIADigiDoc/Util/Certificate/CertificateUtil.swift +++ b/RIADigiDoc/Util/Certificate/CertificateUtil.swift @@ -17,15 +17,13 @@ * */ +import CommonsLib import Foundation -import OSLog import SwiftASN1 import X509 import UtilsLib -public struct CertificateUtil: CertificateUtilProtocol { - private static let logger = Logger(subsystem: "ee.ria.digidoc.RIADigiDoc", category: "CertificateUtil") - +public struct CertificateUtil: CertificateUtilProtocol, Loggable { public init() {} public func pemToDerData(fromPEM pem: Data) -> Data? { @@ -50,7 +48,7 @@ public struct CertificateUtil: CertificateUtilProtocol { .first { $0.type == attribute }?.value ?? RelativeDistinguishedName.Attribute .Value(utf8String: "")) } catch { - CertificateUtil.logger.error( + CertificateUtil.logger().error( "Unable to get issuer attribute \(attribute) from certificate: \(error.localizedDescription)" ) return "" @@ -77,7 +75,7 @@ public struct CertificateUtil: CertificateUtilProtocol { return dateTime.date } } catch { - CertificateUtil.logger.error( + CertificateUtil.logger().error( "Unable to get not valid after from certificate: \(error.localizedDescription)" ) return "" diff --git a/RIADigiDoc/ViewModel/AdvancedSettingsViewModel.swift b/RIADigiDoc/ViewModel/AdvancedSettingsViewModel.swift index 07fc4c1f..8926f299 100644 --- a/RIADigiDoc/ViewModel/AdvancedSettingsViewModel.swift +++ b/RIADigiDoc/ViewModel/AdvancedSettingsViewModel.swift @@ -21,14 +21,10 @@ import CommonsLib import ConfigLib import Foundation import LibdigidocLibSwift -import OSLog @Observable @MainActor -class AdvancedSettingsViewModel: AdvancedSettingsViewModelProtocol { - private static let logger = Logger( - subsystem: "ee.ria.digidoc.RIADigiDoc", category: "AdvancedSettingsViewModel") - +class AdvancedSettingsViewModel: AdvancedSettingsViewModelProtocol, Loggable { var configuration: ConfigurationProvider? private let dataStore: DataStoreProtocol @@ -76,7 +72,7 @@ class AdvancedSettingsViewModel: AdvancedSettingsViewModelProtocol { CommonsLib.Constants.Folder.EncryptionKeyTransferCert ]) } catch { - AdvancedSettingsViewModel.logger.error("Unable to remove all certificates") + AdvancedSettingsViewModel.logger().error("Unable to remove all certificates") } } diff --git a/RIADigiDoc/ViewModel/CertificateDetailViewModel.swift b/RIADigiDoc/ViewModel/CertificateDetailViewModel.swift index ea4677a4..83e544d8 100644 --- a/RIADigiDoc/ViewModel/CertificateDetailViewModel.swift +++ b/RIADigiDoc/ViewModel/CertificateDetailViewModel.swift @@ -17,8 +17,8 @@ * */ +import CommonsLib import Foundation -import OSLog import X509 import SwiftASN1 import CryptoKit @@ -28,8 +28,7 @@ import UtilsLib @Observable @MainActor -class CertificateDetailViewModel: CertificateDetailViewModelProtocol { - private static let logger = Logger(subsystem: "ee.ria.digidoc.RIADigiDoc", category: "CertificateDetailViewModel") +class CertificateDetailViewModel: CertificateDetailViewModelProtocol, Loggable { private static let oidToExtensionName: [String: String] = [ "2.5.29.14": "SubjectKeyIdentifier", @@ -56,7 +55,7 @@ class CertificateDetailViewModel: CertificateDetailViewModelProtocol { .first { $0.type == attribute }?.value ?? RelativeDistinguishedName.Attribute .Value(utf8String: "")) } catch { - CertificateDetailViewModel.logger.error( + CertificateDetailViewModel.logger().error( "Unable to get issuer attribute \(attribute) from certificate: \(error.localizedDescription)" ) return "" @@ -72,7 +71,7 @@ class CertificateDetailViewModel: CertificateDetailViewModelProtocol { .first { $0.type == attribute }?.value ?? RelativeDistinguishedName.Attribute .Value(utf8String: "")) } catch { - CertificateDetailViewModel.logger.error( + CertificateDetailViewModel.logger().error( "Unable to get issuer attribute \(attribute) from certificate: \(error.localizedDescription)" ) return "" @@ -85,7 +84,7 @@ class CertificateDetailViewModel: CertificateDetailViewModelProtocol { return String(describing: certificate.serialNumber) } catch { - CertificateDetailViewModel.logger.error( + CertificateDetailViewModel.logger().error( "Unable to get serial number from certificate: \(error.localizedDescription)" ) return "" @@ -97,7 +96,7 @@ class CertificateDetailViewModel: CertificateDetailViewModelProtocol { let certificate = try Certificate(derEncoded: cert.map { $0 }) return String(describing: certificate.version) } catch { - CertificateDetailViewModel.logger.error( + CertificateDetailViewModel.logger().error( "Unable to get version from certificate: \(error.localizedDescription)" ) return "" @@ -109,7 +108,7 @@ class CertificateDetailViewModel: CertificateDetailViewModelProtocol { let certificate = try Certificate(derEncoded: cert.map { $0 }) return String(describing: certificate.signatureAlgorithm).description } catch { - CertificateDetailViewModel.logger.error( + CertificateDetailViewModel.logger().error( "Unable to get signature algorithm from certificate: \(error.localizedDescription)" ) return "" @@ -121,7 +120,7 @@ class CertificateDetailViewModel: CertificateDetailViewModelProtocol { let certificate = try Certificate(derEncoded: cert.map { $0 }) return String(describing: certificate.notValidBefore) } catch { - CertificateDetailViewModel.logger.error( + CertificateDetailViewModel.logger().error( "Unable to get not valid before from certificate: \(error.localizedDescription)" ) return "" @@ -133,7 +132,7 @@ class CertificateDetailViewModel: CertificateDetailViewModelProtocol { let certificate = try Certificate(derEncoded: cert.map { $0 }) return String(describing: certificate.notValidAfter) } catch { - CertificateDetailViewModel.logger.error( + CertificateDetailViewModel.logger().error( "Unable to get not valid after from certificate: \(error.localizedDescription)" ) return "" diff --git a/RIADigiDoc/ViewModel/ContentViewModel.swift b/RIADigiDoc/ViewModel/ContentViewModel.swift index e9c18bdd..b9e064ea 100644 --- a/RIADigiDoc/ViewModel/ContentViewModel.swift +++ b/RIADigiDoc/ViewModel/ContentViewModel.swift @@ -18,17 +18,13 @@ */ import Foundation -import OSLog import FactoryKit import UtilsLib import CommonsLib @Observable @MainActor -class ContentViewModel: ContentViewModelProtocol { - - private static let logger = Logger(subsystem: "ee.ria.digidoc.RIADigiDoc", category: "ContentViewModel") - +class ContentViewModel: ContentViewModelProtocol, Loggable { private let fileUtil: FileUtilProtocol private let fileManager: FileManagerProtocol @@ -42,7 +38,7 @@ class ContentViewModel: ContentViewModelProtocol { func getSharedFiles() async -> [URL] { do { - ContentViewModel.logger.debug("Checking for shared files...") + ContentViewModel.logger().debug("Checking for shared files...") let sharedFolderURL = try await Directories.getSharedFolder(fileManager: fileManager) .validURL(fileUtil: fileUtil) @@ -52,14 +48,14 @@ class ContentViewModel: ContentViewModelProtocol { options: .skipsHiddenFiles) if contents.isEmpty { - ContentViewModel.logger.debug("Shared files folder is empty") + ContentViewModel.logger().debug("Shared files folder is empty") } else { - ContentViewModel.logger.debug("Found \(contents.count) shared files") + ContentViewModel.logger().debug("Found \(contents.count) shared files") } return contents } catch { - ContentViewModel.logger.error("Unable to get shared files: \(error.localizedDescription)") + ContentViewModel.logger().error("Unable to get shared files: \(error.localizedDescription)") return [] } } diff --git a/RIADigiDoc/ViewModel/CryptoFileOpeningViewModel.swift b/RIADigiDoc/ViewModel/CryptoFileOpeningViewModel.swift index 99039b8a..feb8ccb4 100644 --- a/RIADigiDoc/ViewModel/CryptoFileOpeningViewModel.swift +++ b/RIADigiDoc/ViewModel/CryptoFileOpeningViewModel.swift @@ -18,7 +18,6 @@ */ import Foundation -import OSLog import FactoryKit import CryptoSwift import CommonsLib @@ -26,7 +25,7 @@ import UtilsLib @Observable @MainActor -class CryptoFileOpeningViewModel: CryptoFileOpeningViewModelProtocol { +class CryptoFileOpeningViewModel: CryptoFileOpeningViewModelProtocol, Loggable { var isFileOpeningLoading: Bool = false var isNavigatingToNextView: Bool = false @@ -37,8 +36,6 @@ class CryptoFileOpeningViewModel: CryptoFileOpeningViewModelProtocol { var errorMessage: ToastMessage? - private static let logger = Logger(subsystem: "ee.ria.digidoc.RIADigiDoc", category: "FileOpeningViewModel") - private let fileOpeningRepository: FileOpeningRepositoryProtocol private let sivaRepository: SivaRepositoryProtocol private let sharedContainerViewModel: SharedContainerViewModelProtocol @@ -63,23 +60,23 @@ class CryptoFileOpeningViewModel: CryptoFileOpeningViewModelProtocol { func handleFiles() async { do { - CryptoFileOpeningViewModel.logger.debug("Handling chosen files from file system or from external sources") + CryptoFileOpeningViewModel.logger().debug("Handling chosen files from file system or from external sources") let validFiles = try await fileOpeningRepository.getValidFiles( sharedContainerViewModel.getFileOpeningResult() ?? .failure(FileOpeningError.noDataFiles) ) try fileUtil.removeSharedFiles(url: Directories.getSharedFolder(fileManager: fileManager)) - CryptoFileOpeningViewModel.logger.debug("Found \(validFiles.count) valid file(s)") + CryptoFileOpeningViewModel.logger().debug("Found \(validFiles.count) valid file(s)") if validFiles.isEmpty { - CryptoFileOpeningViewModel.logger.debug("No valid files found") + CryptoFileOpeningViewModel.logger().debug("No valid files found") throw FileOpeningError.noDataFiles } files = validFiles } catch { - CryptoFileOpeningViewModel.logger.error("Unable to handle files. \(error)") + CryptoFileOpeningViewModel.logger().error("Unable to handle files. \(error)") handleError(error) } } @@ -93,7 +90,7 @@ class CryptoFileOpeningViewModel: CryptoFileOpeningViewModelProtocol { handleLoadingSuccess() } catch { - CryptoFileOpeningViewModel.logger.error("Unable to handle Crypto container. \(error)") + CryptoFileOpeningViewModel.logger().error("Unable to handle Crypto container. \(error)") handleError(error) } } @@ -121,10 +118,10 @@ class CryptoFileOpeningViewModel: CryptoFileOpeningViewModelProtocol { private func handleError(_ error: Error) { let ddeMessage = (error as? CryptoError)?.description ?? error.localizedDescription - CryptoFileOpeningViewModel.logger.error("\(ddeMessage)") + CryptoFileOpeningViewModel.logger().error("\(ddeMessage)") if let dde = error as? CryptoError { - CryptoFileOpeningViewModel.logger.error("\(dde)") + CryptoFileOpeningViewModel.logger().error("\(dde)") errorMessage = createToastMessage(for: dde) } else { errorMessage = ToastMessage(key: error.localizedDescription) diff --git a/RIADigiDoc/ViewModel/CryptoHomeViewModel.swift b/RIADigiDoc/ViewModel/CryptoHomeViewModel.swift index f5bf0fdd..9d3f4ab7 100644 --- a/RIADigiDoc/ViewModel/CryptoHomeViewModel.swift +++ b/RIADigiDoc/ViewModel/CryptoHomeViewModel.swift @@ -19,15 +19,13 @@ import Foundation import FactoryKit -import OSLog import CryptoSwift import CommonsLib import UtilsLib @Observable @MainActor -class CryptoHomeViewModel: CryptoHomeViewModelProtocol { - private static let logger = Logger(subsystem: "ee.ria.digidoc.RIADigiDoc", category: "HomeViewModel") +class CryptoHomeViewModel: CryptoHomeViewModelProtocol, Loggable { var isImporting = false var signedContainer: CryptoContainerProtocol = CryptoContainer( @@ -48,7 +46,7 @@ class CryptoHomeViewModel: CryptoHomeViewModelProtocol { func didUserCancelFileOpening(isImportingValue: Bool, isFileOpeningLoading: Bool) -> Bool { if !isImportingValue && !isFileOpeningLoading { - CryptoHomeViewModel.logger.info("User cancelled the file chooser") + CryptoHomeViewModel.logger().info("User cancelled the file chooser") return true } @@ -64,7 +62,7 @@ class CryptoHomeViewModel: CryptoHomeViewModelProtocol { return try Directories.getCacheDirectory(fileManager: fileManager) .appending(path: Constants.Folder.CryptoContainerFolder) } catch { - CryptoHomeViewModel.logger.error("Unable to get crypto recent documents folder: \(error)") + CryptoHomeViewModel.logger().error("Unable to get crypto recent documents folder: \(error)") return nil } } diff --git a/RIADigiDoc/ViewModel/DataFilesViewModel.swift b/RIADigiDoc/ViewModel/DataFilesViewModel.swift index 901957b8..d104b96b 100644 --- a/RIADigiDoc/ViewModel/DataFilesViewModel.swift +++ b/RIADigiDoc/ViewModel/DataFilesViewModel.swift @@ -18,15 +18,13 @@ */ import Foundation -import OSLog import LibdigidocLibSwift import CommonsLib import UtilsLib @Observable @MainActor -class DataFilesViewModel: DataFilesViewModelProtocol { - private static let logger = Logger(subsystem: "ee.ria.digidoc.RIADigiDoc", category: "DataFilesViewModel") +class DataFilesViewModel: DataFilesViewModelProtocol, Loggable { private let sharedContainerViewModel: SharedContainerViewModelProtocol private let fileManager: FileManagerProtocol @@ -45,7 +43,7 @@ class DataFilesViewModel: DataFilesViewModelProtocol { .currentContainer() as? any SignedContainerProtocol)? .saveDataFile(dataFile: dataFile, to: nil) } catch { - DataFilesViewModel.logger.error( + DataFilesViewModel.logger().error( "Unable to save datafile \(dataFile.fileName): \(error.localizedDescription)" ) return nil @@ -64,9 +62,9 @@ class DataFilesViewModel: DataFilesViewModelProtocol { fileManager: fileManager ) try fileManager.removeItem(at: directory) - DataFilesViewModel.logger.debug("Saved Files directory removed") + DataFilesViewModel.logger().debug("Saved Files directory removed") } catch { - DataFilesViewModel.logger.error("Unable to delete saved files directory: \(error.localizedDescription)") + DataFilesViewModel.logger().error("Unable to delete saved files directory: \(error.localizedDescription)") } } } diff --git a/RIADigiDoc/ViewModel/DiagnosticsViewModel.swift b/RIADigiDoc/ViewModel/DiagnosticsViewModel.swift index 15db62b9..1a783c69 100644 --- a/RIADigiDoc/ViewModel/DiagnosticsViewModel.swift +++ b/RIADigiDoc/ViewModel/DiagnosticsViewModel.swift @@ -21,15 +21,11 @@ import SwiftUI import CommonsLib import ConfigLib import LibdigidocLibSwift -import OSLog import UtilsLib @Observable @MainActor -class DiagnosticsViewModel: DiagnosticsViewModelProtocol { - private static let logger = Logger( - subsystem: "ee.ria.digidoc.RIADigiDoc", category: "DiagnosticsViewModel") - +class DiagnosticsViewModel: DiagnosticsViewModelProtocol, Loggable { var configuration: ConfigurationProvider? // MARK: - section content @@ -153,7 +149,7 @@ class DiagnosticsViewModel: DiagnosticsViewModelProtocol { private func loadTslSectionContent(schemaDirectory: URL? = nil) { let directory = schemaDirectory ?? Directories.getLibraryDirectory(fileManager: fileManager) guard let schemaDirectory = directory else { - DiagnosticsViewModel.logger.error("Unable to get the schema directory") + DiagnosticsViewModel.logger().error("Unable to get the schema directory") return } @@ -174,7 +170,7 @@ class DiagnosticsViewModel: DiagnosticsViewModelProtocol { filesWithSequenceNumber.append("\(fileName) (\(sequenceNumber))") } catch { - DiagnosticsViewModel.logger.error( + DiagnosticsViewModel.logger().error( "Failed to parse \(fileURL): \(error.localizedDescription)") filesWithSequenceNumber.append(fileName) } @@ -183,7 +179,7 @@ class DiagnosticsViewModel: DiagnosticsViewModelProtocol { self.tslSectionContent = filesWithSequenceNumber } catch { - DiagnosticsViewModel.logger.error("Could not list TSL directory: \(error)") + DiagnosticsViewModel.logger().error("Could not list TSL directory: \(error)") } } @@ -234,7 +230,7 @@ class DiagnosticsViewModel: DiagnosticsViewModelProtocol { return fileURL } catch { - DiagnosticsViewModel.logger.error( + DiagnosticsViewModel.logger().error( "Failed to write diagnostics file: \(error.localizedDescription)") } return nil @@ -247,9 +243,9 @@ class DiagnosticsViewModel: DiagnosticsViewModelProtocol { fileManager: fileManager ) try fileManager.removeItem(at: directory) - DiagnosticsViewModel.logger.debug("Saved Files directory removed") + DiagnosticsViewModel.logger().debug("Saved Files directory removed") } catch { - DiagnosticsViewModel.logger.error( + DiagnosticsViewModel.logger().error( "Unable to delete saved files directory: \(error.localizedDescription)") } } @@ -307,7 +303,7 @@ class DiagnosticsViewModel: DiagnosticsViewModelProtocol { ) return true } catch { - DiagnosticsViewModel.logger.error("Unable to update configuration: \(error)") + DiagnosticsViewModel.logger().error("Unable to update configuration: \(error)") return false } } @@ -320,7 +316,7 @@ class DiagnosticsViewModel: DiagnosticsViewModelProtocol { } guard let configStream = await configurationRepository.observeConfigurationUpdates() else { - DiagnosticsViewModel.logger.error("Unable to get configuration updates stream") + DiagnosticsViewModel.logger().error("Unable to get configuration updates stream") return } @@ -331,7 +327,7 @@ class DiagnosticsViewModel: DiagnosticsViewModelProtocol { } } } catch { - DiagnosticsViewModel.logger.error("Unable to get configuration from stream") + DiagnosticsViewModel.logger().error("Unable to get configuration from stream") } } } diff --git a/RIADigiDoc/ViewModel/EncryptRecipientViewModel.swift b/RIADigiDoc/ViewModel/EncryptRecipientViewModel.swift index 75a52bca..8803759a 100644 --- a/RIADigiDoc/ViewModel/EncryptRecipientViewModel.swift +++ b/RIADigiDoc/ViewModel/EncryptRecipientViewModel.swift @@ -19,15 +19,13 @@ import Foundation import FactoryKit -import OSLog import CommonsLib import CryptoSwift import CryptoObjCWrapper @Observable @MainActor -class EncryptRecipientViewModel: EncryptRecipientViewModelProtocol { - private static let logger = Logger(subsystem: "ee.ria.digidoc.RIADigiDoc", category: "EncryptRecipientViewModel") +class EncryptRecipientViewModel: EncryptRecipientViewModelProtocol, Loggable { var isImporting = false var recipients: [Addressee] = [] @@ -59,14 +57,14 @@ class EncryptRecipientViewModel: EncryptRecipientViewModelProtocol { let cryptoContainer = sharedContainerViewModel.currentContainer() as? any CryptoContainerProtocol guard let cryptoContainer else { - EncryptRecipientViewModel.logger.error("Cannot load container data. Crypto container is nil.") + EncryptRecipientViewModel.logger().error("Cannot load container data. Crypto container is nil.") return } let recipients = await cryptoContainer.getRecipients() for recipient in recipients where chosenRecipient.data == recipient.data { errorMessage = "Recipient already exists in the container" - EncryptRecipientViewModel.logger.error("Recipient already exists in the container") + EncryptRecipientViewModel.logger().error("Recipient already exists in the container") return } @@ -79,7 +77,7 @@ class EncryptRecipientViewModel: EncryptRecipientViewModelProtocol { if result.tooManyResults { recipients = [] errorMessage = "Too many results" - EncryptRecipientViewModel.logger.error("Too many results for \(self.searchText)") + EncryptRecipientViewModel.logger().error("Too many results for \(self.searchText)") } else { recipients = result.addressees } @@ -96,7 +94,7 @@ class EncryptRecipientViewModel: EncryptRecipientViewModelProtocol { let cryptoContainer = sharedContainerViewModel.currentContainer() as? any CryptoContainerProtocol guard let cryptoContainer else { - EncryptRecipientViewModel.logger.error("Cannot load container data. Crypto container is nil.") + EncryptRecipientViewModel.logger().error("Cannot load container data. Crypto container is nil.") return [] } @@ -111,14 +109,14 @@ class EncryptRecipientViewModel: EncryptRecipientViewModelProtocol { let cryptoContainer = sharedContainerViewModel.currentContainer() as? any CryptoContainerProtocol guard let cryptoContainer else { - EncryptRecipientViewModel.logger.error("Cannot load container data. Crypto container is nil.") + EncryptRecipientViewModel.logger().error("Cannot load container data. Crypto container is nil.") return } try await cryptoContainer.removeRecipient(recipient) } catch { errorMessage = "Failed to remove recipient" - EncryptRecipientViewModel.logger.error("Unable to delete recipient: \(error)") + EncryptRecipientViewModel.logger().error("Unable to delete recipient: \(error)") } } } diff --git a/RIADigiDoc/ViewModel/EncryptViewModel.swift b/RIADigiDoc/ViewModel/EncryptViewModel.swift index 81a938ff..0526cb79 100644 --- a/RIADigiDoc/ViewModel/EncryptViewModel.swift +++ b/RIADigiDoc/ViewModel/EncryptViewModel.swift @@ -19,7 +19,6 @@ import Foundation import FactoryKit -import OSLog import CryptoSwift import CryptoObjCWrapper import CommonsLib @@ -27,8 +26,7 @@ import UtilsLib @Observable @MainActor -class EncryptViewModel: EncryptViewModelProtocol { - private static let logger = Logger(subsystem: "ee.ria.digidoc.RIADigiDoc", category: "EncryptViewModel") +class EncryptViewModel: EncryptViewModelProtocol, Loggable { var dataFiles: [URL] = [] var recipients: [Addressee] = [] @@ -86,11 +84,11 @@ class EncryptViewModel: EncryptViewModelProtocol { } func loadContainerData(cryptoContainer: CryptoContainerProtocol?) async { - EncryptViewModel.logger.debug("Loading container data") + EncryptViewModel.logger().debug("Loading container data") let openedContainer = (cryptoContainer ?? sharedContainerViewModel.currentContainer()) as? any CryptoContainerProtocol guard let openedContainer else { - EncryptViewModel.logger.error("Cannot load container data. Crypto container is nil.") + EncryptViewModel.logger().error("Cannot load container data. Crypto container is nil.") return } @@ -102,12 +100,12 @@ class EncryptViewModel: EncryptViewModelProtocol { self.containerMimetype = await openedContainer.getContainerMimetype() self.containerURL = await openedContainer.getRawContainerFile() - EncryptViewModel.logger.debug("Container data loaded") + EncryptViewModel.logger().debug("Container data loaded") } func createCopyOfContainerForSaving(containerURL: URL?) -> URL? { guard let containerLocation = containerURL else { - EncryptViewModel.logger.error("Unable to get container to create copy for saving") + EncryptViewModel.logger().error("Unable to get container to create copy for saving") return nil } @@ -127,7 +125,7 @@ class EncryptViewModel: EncryptViewModelProtocol { do { try fileManager.removeItem(at: tempSavedFileLocation) } catch { - EncryptViewModel.logger.error("Unable to remove existing file: \(error.localizedDescription)") + EncryptViewModel.logger().error("Unable to remove existing file: \(error.localizedDescription)") return nil } } @@ -135,13 +133,13 @@ class EncryptViewModel: EncryptViewModelProtocol { do { try fileManager.copyItem(at: containerLocation, to: tempSavedFileLocation) } catch { - EncryptViewModel.logger.error("Unable to copy file: \(error.localizedDescription)") + EncryptViewModel.logger().error("Unable to copy file: \(error.localizedDescription)") return nil } return tempSavedFileLocation } catch { - EncryptViewModel.logger.error("Unable to get cache directory: \(error.localizedDescription)") + EncryptViewModel.logger().error("Unable to get cache directory: \(error.localizedDescription)") return nil } } @@ -159,7 +157,7 @@ class EncryptViewModel: EncryptViewModelProtocol { } await cryptoContainer?.addDataFiles(files) - EncryptViewModel.logger.debug("Added data files to container") + EncryptViewModel.logger().debug("Added data files to container") errorMessage = ErrorMessage( key: files.count == 1 ? "File successfully added" : "Files successfully added", args: [] @@ -249,7 +247,7 @@ class EncryptViewModel: EncryptViewModelProtocol { cryptoContainer: encryptedContainer ) } catch { - EncryptViewModel.logger.error("Unable to encrypt container: \(error)") + EncryptViewModel.logger().error("Unable to encrypt container: \(error)") handleEncryptionError(error) } } @@ -278,7 +276,7 @@ class EncryptViewModel: EncryptViewModelProtocol { do { return try await cryptoContainer?.renameContainer(to: newName) } catch { - EncryptViewModel.logger.error("Unable to rename container: \(error)") + EncryptViewModel.logger().error("Unable to rename container: \(error)") if let cryptoError = error as? CryptoError { switch cryptoError { case .containerRenamingFailed(let errorDetail), @@ -333,7 +331,7 @@ class EncryptViewModel: EncryptViewModelProtocol { try await openNestedContainer(fileURL: fileURL) // TODO: Open signed container files } catch { - EncryptViewModel.logger.error("Failed to open nested container: \(error)") + EncryptViewModel.logger().error("Failed to open nested container: \(error)") errorMessage = ErrorMessage(key: "Failed to open container", args: [dataFile.lastPathComponent]) } } else { @@ -508,7 +506,7 @@ class EncryptViewModel: EncryptViewModelProtocol { func removeRecipient(_ recipient: Addressee) async { guard let container = cryptoContainer else { - EncryptViewModel.logger.error( + EncryptViewModel.logger().error( "Unable to remove signature from container. CryptoContainer or containerURL is nil" ) errorMessage = ErrorMessage( @@ -522,7 +520,7 @@ class EncryptViewModel: EncryptViewModelProtocol { try await container.removeRecipient(recipient) await loadContainerData(cryptoContainer: container) } catch { - EncryptViewModel.logger.error("Unable to remove signature from container. \(error)") + EncryptViewModel.logger().error("Unable to remove signature from container. \(error)") errorMessage = ErrorMessage( key: "Failed to remove signature from container", args: [] @@ -533,7 +531,7 @@ class EncryptViewModel: EncryptViewModelProtocol { func removeDataFile(_ dataFile: URL) async { guard let container = cryptoContainer else { - EncryptViewModel.logger.error( + EncryptViewModel.logger().error( "Unable to remove file from container. CryptoContainer or containerURL is nil" ) errorMessage = ErrorMessage( @@ -553,7 +551,7 @@ class EncryptViewModel: EncryptViewModelProtocol { await loadContainerData(cryptoContainer: container) return } catch { - EncryptViewModel.logger.error("Unable to remove file from container. \(error)") + EncryptViewModel.logger().error("Unable to remove file from container. \(error)") errorMessage = ErrorMessage( key: "Failed to remove file from container", args: [dataFile.lastPathComponent] diff --git a/RIADigiDoc/ViewModel/EncryptionSettingsViewModel.swift b/RIADigiDoc/ViewModel/EncryptionSettingsViewModel.swift index 164760cc..182243e6 100644 --- a/RIADigiDoc/ViewModel/EncryptionSettingsViewModel.swift +++ b/RIADigiDoc/ViewModel/EncryptionSettingsViewModel.swift @@ -20,14 +20,10 @@ import CommonsLib import ConfigLib import Foundation -import OSLog @Observable @MainActor -class EncryptionSettingsViewModel: EncryptionSettingsViewModelProtocol { - private static let logger = Logger( - subsystem: "ee.ria.digidoc.RIADigiDoc", category: "EncryptionSettingsViewModel") - +class EncryptionSettingsViewModel: EncryptionSettingsViewModelProtocol, Loggable { var configuration: ConfigurationProvider? var certData: Data? var encryptionCdocOption: EncryptionCdocOption = .cdoc1 diff --git a/RIADigiDoc/ViewModel/FileOpeningViewModel.swift b/RIADigiDoc/ViewModel/FileOpeningViewModel.swift index aafb2564..569ed1de 100644 --- a/RIADigiDoc/ViewModel/FileOpeningViewModel.swift +++ b/RIADigiDoc/ViewModel/FileOpeningViewModel.swift @@ -18,7 +18,6 @@ */ import Foundation -import OSLog import FactoryKit import LibdigidocLibSwift import CommonsLib @@ -26,7 +25,7 @@ import UtilsLib @Observable @MainActor -class FileOpeningViewModel: FileOpeningViewModelProtocol { +class FileOpeningViewModel: FileOpeningViewModelProtocol, Loggable { var isFileOpeningLoading: Bool = false var isNavigatingToNextView: Bool = false var isSivaConfirmed = false @@ -38,8 +37,6 @@ class FileOpeningViewModel: FileOpeningViewModelProtocol { var errorMessage: ToastMessage? - private static let logger = Logger(subsystem: "ee.ria.digidoc.RIADigiDoc", category: "FileOpeningViewModel") - private let fileOpeningRepository: FileOpeningRepositoryProtocol private let sivaRepository: SivaRepositoryProtocol private let sharedContainerViewModel: SharedContainerViewModelProtocol @@ -64,23 +61,23 @@ class FileOpeningViewModel: FileOpeningViewModelProtocol { func handleFiles() async { do { - FileOpeningViewModel.logger.debug("Handling chosen files from file system or from external sources") + FileOpeningViewModel.logger().debug("Handling chosen files from file system or from external sources") let validFiles = try await fileOpeningRepository.getValidFiles( sharedContainerViewModel.getFileOpeningResult() ?? .failure(FileOpeningError.noDataFiles) ) try fileUtil.removeSharedFiles(url: Directories.getSharedFolder(fileManager: fileManager)) - FileOpeningViewModel.logger.debug("Found \(validFiles.count) valid file(s)") + FileOpeningViewModel.logger().debug("Found \(validFiles.count) valid file(s)") if validFiles.isEmpty { - FileOpeningViewModel.logger.debug("No valid files found") + FileOpeningViewModel.logger().debug("No valid files found") throw FileOpeningError.noDataFiles } files = validFiles } catch { - FileOpeningViewModel.logger.error("Unable to handle files. \(error)") + FileOpeningViewModel.logger().error("Unable to handle files. \(error)") handleError(error) } } @@ -99,7 +96,7 @@ class FileOpeningViewModel: FileOpeningViewModelProtocol { try await container.getRawContainerFile()?.markAsOpened() handleLoadingSuccess(isSivaConfirmed: true) } catch { - FileOpeningViewModel.logger.error("Unable to handle SiVa container. \(error)") + FileOpeningViewModel.logger().error("Unable to handle SiVa container. \(error)") handleError(error) } } @@ -121,10 +118,10 @@ class FileOpeningViewModel: FileOpeningViewModelProtocol { let container = try await fileOpeningRepository .openOrCreateContainer(urls: files, isSivaConfirmed: false) sharedContainerViewModel.setSignedContainer(container) - FileOpeningViewModel.logger.debug("Asics signed container set successfully") + FileOpeningViewModel.logger().debug("Asics signed container set successfully") handleLoadingSuccess(isSivaConfirmed: false) } catch { - FileOpeningViewModel.logger.error("Unable to handle SiVa container. \(error)") + FileOpeningViewModel.logger().error("Unable to handle SiVa container. \(error)") handleError(error) } } @@ -171,10 +168,10 @@ class FileOpeningViewModel: FileOpeningViewModelProtocol { private func handleError(_ error: Error) { let ddeMessage = (error as? DigiDocError)?.description ?? error.localizedDescription - FileOpeningViewModel.logger.error("\(ddeMessage)") + FileOpeningViewModel.logger().error("\(ddeMessage)") if let dde = error as? DigiDocError { - FileOpeningViewModel.logger.error("\(dde)") + FileOpeningViewModel.logger().error("\(dde)") errorMessage = createToastMessage(for: dde) } else { errorMessage = ToastMessage(key: error.localizedDescription) diff --git a/RIADigiDoc/ViewModel/HomeViewModel.swift b/RIADigiDoc/ViewModel/HomeViewModel.swift index f42191bf..e3f7a66d 100644 --- a/RIADigiDoc/ViewModel/HomeViewModel.swift +++ b/RIADigiDoc/ViewModel/HomeViewModel.swift @@ -19,16 +19,13 @@ import Foundation import FactoryKit -import OSLog import LibdigidocLibSwift import CommonsLib import UtilsLib @Observable @MainActor -class HomeViewModel: HomeViewModelProtocol { - private static let logger = Logger(subsystem: "ee.ria.digidoc.RIADigiDoc", category: "HomeViewModel") - +class HomeViewModel: HomeViewModelProtocol, Loggable { var isImporting = false var signedContainer: SignedContainerProtocol = SignedContainer( fileManager: Container.shared.fileManager(), @@ -48,7 +45,7 @@ class HomeViewModel: HomeViewModelProtocol { func didUserCancelFileOpening(isImportingValue: Bool, isFileOpeningLoading: Bool) -> Bool { if !isImportingValue && !isFileOpeningLoading { - HomeViewModel.logger.info("User cancelled the file chooser") + HomeViewModel.logger().info("User cancelled the file chooser") return true } @@ -64,7 +61,7 @@ class HomeViewModel: HomeViewModelProtocol { return try Directories.getCacheDirectory(fileManager: fileManager) .appending(path: Constants.Folder.SignedContainerFolder) } catch { - HomeViewModel.logger.error("Unable to get signed containers recent documents folder: \(error)") + HomeViewModel.logger().error("Unable to get signed containers recent documents folder: \(error)") return nil } } diff --git a/RIADigiDoc/ViewModel/InitViewModel.swift b/RIADigiDoc/ViewModel/InitViewModel.swift index 5a956d47..ae97bfd4 100644 --- a/RIADigiDoc/ViewModel/InitViewModel.swift +++ b/RIADigiDoc/ViewModel/InitViewModel.swift @@ -17,13 +17,11 @@ * */ +import CommonsLib import Foundation -import OSLog @MainActor -class InitViewModel: InitViewModelProtocol, ObservableObject { - private static let logger = Logger(subsystem: "ee.ria.digidoc.RIADigiDoc", category: "InitViewModel") - +class InitViewModel: InitViewModelProtocol, ObservableObject, Loggable { private let languageSettings: LanguageSettingsProtocol private let dataStore: DataStoreProtocol diff --git a/RIADigiDoc/ViewModel/LanguageChooserViewModel.swift b/RIADigiDoc/ViewModel/LanguageChooserViewModel.swift index b8cf32b0..8d0c9731 100644 --- a/RIADigiDoc/ViewModel/LanguageChooserViewModel.swift +++ b/RIADigiDoc/ViewModel/LanguageChooserViewModel.swift @@ -17,14 +17,12 @@ * */ -import OSLog +import CommonsLib +import Foundation @Observable @MainActor -class LanguageChooserViewModel: LanguageChooserViewModelProtocol { - private static let logger = Logger( - subsystem: "ee.ria.digidoc.RIADigiDoc", category: "LanguageChooserViewModel") - +class LanguageChooserViewModel: LanguageChooserViewModelProtocol, Loggable { var selectedLanguage: String = "en" private let languageSettings: LanguageSettingsProtocol diff --git a/RIADigiDoc/ViewModel/MobileIDSmartIDSettingsViewModel.swift b/RIADigiDoc/ViewModel/MobileIDSmartIDSettingsViewModel.swift index 48d89dc4..f8526fc6 100644 --- a/RIADigiDoc/ViewModel/MobileIDSmartIDSettingsViewModel.swift +++ b/RIADigiDoc/ViewModel/MobileIDSmartIDSettingsViewModel.swift @@ -18,14 +18,11 @@ */ import CommonsLib -import OSLog +import Foundation @Observable @MainActor -class MobileIDSmartIDSettingsViewModel: MobileIDSmartIDSettingsViewModelProtocol { - private static let logger = Logger( - subsystem: "ee.ria.digidoc.RIADigiDoc", category: "MobileIDAndSmartIDServicesSettingsViewModel") - +class MobileIDSmartIDSettingsViewModel: MobileIDSmartIDSettingsViewModelProtocol, Loggable { var relyingPartyUUID: String = "" var selectedOption: ServicesSettingsOption = .defaultSetting diff --git a/RIADigiDoc/ViewModel/MyEid/MyEidPinChangeViewModel.swift b/RIADigiDoc/ViewModel/MyEid/MyEidPinChangeViewModel.swift index 6cf9f757..ec76961b 100644 --- a/RIADigiDoc/ViewModel/MyEid/MyEidPinChangeViewModel.swift +++ b/RIADigiDoc/ViewModel/MyEid/MyEidPinChangeViewModel.swift @@ -18,14 +18,11 @@ */ import Foundation -import OSLog import IdCardLib @MainActor @Observable final class MyEidPinChangeViewModel: MyEidPinChangeViewModelProtocol { - private static let logger = Logger(subsystem: "ee.ria.digidoc.RIADigiDoc", category: "MyEidPinChangeViewModel") - private(set) var pinAction: MyEidPinCodeAction private(set) var codeType: CodeType diff --git a/RIADigiDoc/ViewModel/MyEid/MyEidRootViewModel.swift b/RIADigiDoc/ViewModel/MyEid/MyEidRootViewModel.swift index ec239ed1..6814f329 100644 --- a/RIADigiDoc/ViewModel/MyEid/MyEidRootViewModel.swift +++ b/RIADigiDoc/ViewModel/MyEid/MyEidRootViewModel.swift @@ -17,15 +17,13 @@ * */ +import CommonsLib import Foundation -import OSLog import Observation @Observable @MainActor -class MyEidRootViewModel: MyEidRootViewModelProtocol { - private static let logger = Logger(subsystem: "ee.ria.digidoc.RIADigiDoc", category: "MyEidRootViewModel") - +class MyEidRootViewModel: MyEidRootViewModelProtocol, Loggable { private let dataStore: DataStoreProtocol init(dataStore: DataStoreProtocol) { diff --git a/RIADigiDoc/ViewModel/ProxySettingsViewModel.swift b/RIADigiDoc/ViewModel/ProxySettingsViewModel.swift index 279aba49..b455abb5 100644 --- a/RIADigiDoc/ViewModel/ProxySettingsViewModel.swift +++ b/RIADigiDoc/ViewModel/ProxySettingsViewModel.swift @@ -21,14 +21,10 @@ import Alamofire import CommonsLib import Foundation import LibdigidocLibSwift -import OSLog @Observable @MainActor -class ProxySettingsViewModel: ProxySettingsViewModelProtocol { - private static let logger = Logger( - subsystem: "ee.ria.digidoc.RIADigiDoc", category: "ProxySettingsViewModel") - +class ProxySettingsViewModel: ProxySettingsViewModelProtocol, Loggable { var proxyInfo: ProxyInfo = ProxyInfo() var portText: String = "80" diff --git a/RIADigiDoc/ViewModel/RecentDocumentsViewModel.swift b/RIADigiDoc/ViewModel/RecentDocumentsViewModel.swift index 26587ab3..53033671 100644 --- a/RIADigiDoc/ViewModel/RecentDocumentsViewModel.swift +++ b/RIADigiDoc/ViewModel/RecentDocumentsViewModel.swift @@ -19,13 +19,11 @@ import Foundation import FactoryKit -import OSLog import CommonsLib @Observable @MainActor -class RecentDocumentsViewModel: RecentDocumentsViewModelProtocol { - private static let logger = Logger(subsystem: "ee.ria.digidoc.RIADigiDoc", category: "RecentDocumentsViewModel") +class RecentDocumentsViewModel: RecentDocumentsViewModelProtocol, Loggable { var isImporting = false var files: [FileItem] = [] @@ -85,7 +83,7 @@ class RecentDocumentsViewModel: RecentDocumentsViewModelProtocol { } catch { files = [] errorMessage = "Could not load selected files" - RecentDocumentsViewModel.logger.error("Unable to load files: \(error)") + RecentDocumentsViewModel.logger().error("Unable to load files: \(error)") } } @@ -95,7 +93,7 @@ class RecentDocumentsViewModel: RecentDocumentsViewModelProtocol { files.removeAll { $0.url == file.url } } catch { errorMessage = "Failed to remove file" - RecentDocumentsViewModel.logger.error("Unable to delete file: \(error)") + RecentDocumentsViewModel.logger().error("Unable to delete file: \(error)") } } } diff --git a/RIADigiDoc/ViewModel/SignatureDetailViewModel.swift b/RIADigiDoc/ViewModel/SignatureDetailViewModel.swift index 76e107a8..4ed362d9 100644 --- a/RIADigiDoc/ViewModel/SignatureDetailViewModel.swift +++ b/RIADigiDoc/ViewModel/SignatureDetailViewModel.swift @@ -17,14 +17,13 @@ * */ +import CommonsLib import Foundation -import OSLog import X509 @Observable @MainActor -class SignatureDetailViewModel: SignatureDetailViewModelProtocol { - private static let logger = Logger(subsystem: "ee.ria.digidoc.RIADigiDoc", category: "SignatureDetailViewModel") +class SignatureDetailViewModel: SignatureDetailViewModelProtocol, Loggable { func getIssuerName(cert: Data) -> String { do { @@ -36,7 +35,7 @@ class SignatureDetailViewModel: SignatureDetailViewModelProtocol { .first { $0.type == .RDNAttributeType.commonName }?.value ?? RelativeDistinguishedName.Attribute.Value(utf8String: "")) } catch { - SignatureDetailViewModel.logger + SignatureDetailViewModel.logger() .error("Unable to get issuer CommonName from certificate: \(error.localizedDescription)") return "" } @@ -52,7 +51,7 @@ class SignatureDetailViewModel: SignatureDetailViewModelProtocol { .first { $0.type == .RDNAttributeType.commonName }?.value ?? RelativeDistinguishedName.Attribute.Value(utf8String: "")) } catch { - SignatureDetailViewModel.logger + SignatureDetailViewModel.logger() .error("Unable to get subject CommonName from certificate: \(error.localizedDescription)") return "" } diff --git a/RIADigiDoc/ViewModel/Signing/ActionMethod/ActionMethodSelectionViewModel.swift b/RIADigiDoc/ViewModel/Signing/ActionMethod/ActionMethodSelectionViewModel.swift index 5ae152ec..ac8e9342 100644 --- a/RIADigiDoc/ViewModel/Signing/ActionMethod/ActionMethodSelectionViewModel.swift +++ b/RIADigiDoc/ViewModel/Signing/ActionMethod/ActionMethodSelectionViewModel.swift @@ -17,17 +17,12 @@ * */ +import CommonsLib import Foundation -import OSLog @Observable @MainActor -class ActionMethodSelectionViewModel: ActionMethodSelectionViewModelProtocol { - private static let logger = Logger( - subsystem: "ee.ria.digidoc.RIADigiDoc", - category: "ActionMethodSelectionViewModel" - ) - +class ActionMethodSelectionViewModel: ActionMethodSelectionViewModelProtocol, Loggable { private let dataStore: DataStoreProtocol init(dataStore: DataStoreProtocol) { diff --git a/RIADigiDoc/ViewModel/Signing/MobileId/MobileIdViewModel.swift b/RIADigiDoc/ViewModel/Signing/MobileId/MobileIdViewModel.swift index 7d9d532a..a70f26f1 100644 --- a/RIADigiDoc/ViewModel/Signing/MobileId/MobileIdViewModel.swift +++ b/RIADigiDoc/ViewModel/Signing/MobileId/MobileIdViewModel.swift @@ -18,7 +18,6 @@ */ import Foundation -import OSLog import Alamofire import MobileIdLib import LibdigidocLibSwift @@ -28,8 +27,7 @@ import CommonsLib @Observable @MainActor -class MobileIdViewModel: MobileIdViewModelProtocol { - private static let logger = Logger(subsystem: "ee.ria.digidoc.RIADigiDoc", category: "MobileIdViewModel") +class MobileIdViewModel: MobileIdViewModelProtocol, Loggable { private static let certificateEndpoint = "/certificate" private static let signatureEndpoint = "/signature" @@ -111,11 +109,11 @@ class MobileIdViewModel: MobileIdViewModelProtocol { roleData: RoleData, signedContainer: SignedContainerProtocol ) async -> SignedContainerProtocol? { - MobileIdViewModel.logger.debug("Mobile-ID: Signing with Mobile-ID") + MobileIdViewModel.logger().debug("Mobile-ID: Signing with Mobile-ID") let currentConfiguration = await configurationRepository.getConfiguration() guard let configuration = currentConfiguration else { - MobileIdViewModel.logger.error( + MobileIdViewModel.logger().error( "Mobile-ID: Unable to get configuration to sign with Mobile-ID" ) mobileIdMessageKey = "General error" @@ -137,7 +135,7 @@ class MobileIdViewModel: MobileIdViewModelProtocol { do { containerFile = try await getContainerFile(signedContainer: signedContainer) } catch { - MobileIdViewModel.logger.debug("Mobile-ID: Unable to get container file from container") + MobileIdViewModel.logger().debug("Mobile-ID: Unable to get container file from container") handleSigningError(error) return nil } @@ -152,7 +150,7 @@ class MobileIdViewModel: MobileIdViewModelProtocol { proxyInfo: proxyInfo ) } catch { - MobileIdViewModel.logger.debug("Mobile-ID: Unable to request certificate or get cert from response") + MobileIdViewModel.logger().debug("Mobile-ID: Unable to request certificate or get cert from response") handleSigningError(error) return nil } @@ -166,7 +164,7 @@ class MobileIdViewModel: MobileIdViewModelProtocol { signedContainer: signedContainer ) } catch { - MobileIdViewModel.logger.debug("Mobile-ID: Unable to prepare signature for signing") + MobileIdViewModel.logger().debug("Mobile-ID: Unable to prepare signature for signing") handleSigningError(error) return nil } @@ -175,14 +173,14 @@ class MobileIdViewModel: MobileIdViewModelProtocol { do { verificationCode = try await getVerificationCode(hash: hash) } catch { - MobileIdViewModel.logger.debug("Mobile-ID: Unable to get verification code (control code)") + MobileIdViewModel.logger().debug("Mobile-ID: Unable to get verification code (control code)") handleSigningError(error) return nil } controlCode = verificationCode - MobileIdViewModel.logger.debug("Mobile-ID: Getting language") + MobileIdViewModel.logger().debug("Mobile-ID: Getting language") let language = await dataStore.getSelectedLanguage() let sessionId: String @@ -197,7 +195,7 @@ class MobileIdViewModel: MobileIdViewModelProtocol { proxyInfo: proxyInfo ) } catch { - MobileIdViewModel.logger.debug("Mobile-ID: Unable to request signature") + MobileIdViewModel.logger().debug("Mobile-ID: Unable to request signature") handleSigningError(error) return nil } @@ -211,7 +209,7 @@ class MobileIdViewModel: MobileIdViewModelProtocol { proxyInfo: proxyInfo ) } catch { - MobileIdViewModel.logger.debug( + MobileIdViewModel.logger().debug( "Mobile-ID: Unable to request session" ) handleSigningError(error) @@ -226,11 +224,11 @@ class MobileIdViewModel: MobileIdViewModelProtocol { containerFile: containerFile ) - MobileIdViewModel.logger.debug("Signature added successfully (Mobile-ID)") + MobileIdViewModel.logger().debug("Signature added successfully (Mobile-ID)") mobileIdMessageKey = "Signature added" return updatedContainer } catch { - MobileIdViewModel.logger.error("Unable to sign container with Mobile-ID: \(error)") + MobileIdViewModel.logger().error("Unable to sign container with Mobile-ID: \(error)") handleSignatureAddingError(error) return nil } @@ -247,7 +245,7 @@ class MobileIdViewModel: MobileIdViewModelProtocol { trustedCertificates: [SecCertificate], proxyInfo: ProxyInfo ) async throws -> Data { - MobileIdViewModel.logger.debug("Mobile-ID: Getting certificate") + MobileIdViewModel.logger().debug("Mobile-ID: Getting certificate") let certResponse = try await mobileIdSignService .getCertificateRequest( url: "\(midUrl)\(MobileIdViewModel.certificateEndpoint)", @@ -262,7 +260,7 @@ class MobileIdViewModel: MobileIdViewModelProtocol { guard let certData = Data( base64Encoded: certResponse.cert ?? "" ) else { - MobileIdViewModel.logger.error("Unable to get Mobile-ID certificate as data") + MobileIdViewModel.logger().error("Unable to get Mobile-ID certificate as data") mobileIdMessageKey = "General error" throw MobileIdError.generalError } @@ -280,7 +278,7 @@ class MobileIdViewModel: MobileIdViewModelProtocol { trustedCertificates: [SecCertificate], proxyInfo: ProxyInfo ) async throws -> String { - MobileIdViewModel.logger.debug("Mobile-ID: Getting signature") + MobileIdViewModel.logger().debug("Mobile-ID: Getting signature") let signatureResponse = try await mobileIdSignService.getSignatureRequest( url: "\(midUrl)\(MobileIdViewModel.signatureEndpoint)", relyingPartyName: Constants.Signing.RelyingPartyName, @@ -296,9 +294,9 @@ class MobileIdViewModel: MobileIdViewModelProtocol { proxyInfo: proxyInfo ) - MobileIdViewModel.logger.debug("Mobile-ID: Getting sessionID") + MobileIdViewModel.logger().debug("Mobile-ID: Getting sessionID") guard let sessionId = signatureResponse.sessionID else { - MobileIdViewModel.logger.error("Unable to get Mobile-ID sessionID") + MobileIdViewModel.logger().error("Unable to get Mobile-ID sessionID") mobileIdMessageKey = "Technical error" throw MobileIdError.technicalError } @@ -312,7 +310,7 @@ class MobileIdViewModel: MobileIdViewModelProtocol { trustedCertificates: [SecCertificate], proxyInfo: ProxyInfo ) async throws -> Data { - MobileIdViewModel.logger.debug("Mobile-ID: Getting session request") + MobileIdViewModel.logger().debug("Mobile-ID: Getting session request") let sessionResponse = try await mobileIdSignService.getSessionRequest( url: "\(midUrl)\(MobileIdViewModel.signatureSessionEndpoint)", sessionId: sessionId, @@ -334,7 +332,7 @@ class MobileIdViewModel: MobileIdViewModelProtocol { roleData: RoleData, signedContainer: SignedContainerProtocol ) async throws -> Data { - MobileIdViewModel.logger.debug( + MobileIdViewModel.logger().debug( "Mobile-ID: Preparing signature. Calculating hash" ) @@ -347,11 +345,11 @@ class MobileIdViewModel: MobileIdViewModelProtocol { } private func getVerificationCode(hash: Data) async throws -> String { - MobileIdViewModel.logger.debug( + MobileIdViewModel.logger().debug( "Mobile-ID: Calculating verification code (control code)" ) guard let verificationCode = await mobileIdSignService.getVerificationCode(hash: hash) else { - MobileIdViewModel.logger.error("Unable to get Mobile-ID verification code") + MobileIdViewModel.logger().error("Unable to get Mobile-ID verification code") mobileIdMessageKey = "General error" throw MobileIdError.generalError } @@ -361,7 +359,7 @@ class MobileIdViewModel: MobileIdViewModelProtocol { private func getContainerFile(signedContainer: SignedContainerProtocol) async throws -> URL { guard let containerFile = await signedContainer.getRawContainerFile() else { - MobileIdViewModel.logger.error( + MobileIdViewModel.logger().error( "Unable to sign with Mobile-ID. Unable to get container file" ) mobileIdMessageKey = "General error" @@ -376,7 +374,7 @@ class MobileIdViewModel: MobileIdViewModelProtocol { } private func getTrustedCertificates(certificates: [Data]) -> [SecCertificate] { - MobileIdViewModel.logger.debug("Mobile-ID: Getting trusted certificates list") + MobileIdViewModel.logger().debug("Mobile-ID: Getting trusted certificates list") return certificates.compactMap { certificateUtil.certificate(from: $0) } } @@ -389,10 +387,10 @@ class MobileIdViewModel: MobileIdViewModelProtocol { // swiftlint:disable:next cyclomatic_complexity private func handleSigningError(_ error: Error) { - MobileIdViewModel.logger.error("Unable to sign container with Mobile-ID: \(error)") + MobileIdViewModel.logger().error("Unable to sign container with Mobile-ID: \(error)") if let cancellationError = error as? CancellationError { - MobileIdViewModel.logger.error("Mobile-ID signing manually cancelled: \(cancellationError)") + MobileIdViewModel.logger().error("Mobile-ID signing manually cancelled: \(cancellationError)") // Do not throw an error if user cancelled signing with back button return } @@ -411,7 +409,7 @@ class MobileIdViewModel: MobileIdViewModelProtocol { case .explicitlyCancelled: // Do not throw an error if user cancelled signing with back button - MobileIdViewModel.logger.debug("Mobile-ID signing manually cancelled") + MobileIdViewModel.logger().debug("Mobile-ID signing manually cancelled") mobileIdMessageKey = nil case .timeout: @@ -461,10 +459,10 @@ class MobileIdViewModel: MobileIdViewModelProtocol { // swiftlint:disable:next cyclomatic_complexity private func handleSignatureAddingError(_ error: Error) { - MobileIdViewModel.logger.error("Unable to sign container with Mobile-ID: \(error)") + MobileIdViewModel.logger().error("Unable to sign container with Mobile-ID: \(error)") if let cancellationError = error as? CancellationError { - MobileIdViewModel.logger.error("Mobile-ID signing manually cancelled: \(cancellationError)") + MobileIdViewModel.logger().error("Mobile-ID signing manually cancelled: \(cancellationError)") return } diff --git a/RIADigiDoc/ViewModel/Signing/NFC/NFCViewModel.swift b/RIADigiDoc/ViewModel/Signing/NFC/NFCViewModel.swift index edbb6ae9..181235cd 100644 --- a/RIADigiDoc/ViewModel/Signing/NFC/NFCViewModel.swift +++ b/RIADigiDoc/ViewModel/Signing/NFC/NFCViewModel.swift @@ -18,14 +18,12 @@ */ import Foundation -import OSLog import LibdigidocLibSwift import CommonsLib @Observable @MainActor -class NFCViewModel: NFCViewModelProtocol { - private static let logger = Logger(subsystem: "ee.ria.digidoc.RIADigiDoc", category: "NFCViewModel") +class NFCViewModel: NFCViewModelProtocol, Loggable { var canNumberErrorKey: String? var canNumberErrorExtraArguments: [String] = [] diff --git a/RIADigiDoc/ViewModel/Signing/RoleAndAddress/RoleViewModel.swift b/RIADigiDoc/ViewModel/Signing/RoleAndAddress/RoleViewModel.swift index a335c4bb..72f14edc 100644 --- a/RIADigiDoc/ViewModel/Signing/RoleAndAddress/RoleViewModel.swift +++ b/RIADigiDoc/ViewModel/Signing/RoleAndAddress/RoleViewModel.swift @@ -18,13 +18,11 @@ */ import Foundation -import OSLog import CommonsLib @Observable @MainActor -class RoleViewModel: RoleViewModelProtocol { - private static let logger = Logger(subsystem: "ee.ria.digidoc.RIADigiDoc", category: "RoleViewModel") +class RoleViewModel: RoleViewModelProtocol, Loggable { private let dataStore: DataStoreProtocol diff --git a/RIADigiDoc/ViewModel/Signing/RootView/SigningRootViewModel.swift b/RIADigiDoc/ViewModel/Signing/RootView/SigningRootViewModel.swift index ce724385..8743cc29 100644 --- a/RIADigiDoc/ViewModel/Signing/RootView/SigningRootViewModel.swift +++ b/RIADigiDoc/ViewModel/Signing/RootView/SigningRootViewModel.swift @@ -17,14 +17,13 @@ * */ +import CommonsLib import Foundation -import OSLog import Observation @Observable @MainActor -class SigningRootViewModel: SigningRootViewModelProtocol { - private static let logger = Logger(subsystem: "ee.ria.digidoc.RIADigiDoc", category: "SigningRootViewModel") +class SigningRootViewModel: SigningRootViewModelProtocol, Loggable { private let dataStore: DataStoreProtocol diff --git a/RIADigiDoc/ViewModel/Signing/SmartId/SmartIdViewModel.swift b/RIADigiDoc/ViewModel/Signing/SmartId/SmartIdViewModel.swift index 14a156c0..7fcf2a4a 100644 --- a/RIADigiDoc/ViewModel/Signing/SmartId/SmartIdViewModel.swift +++ b/RIADigiDoc/ViewModel/Signing/SmartId/SmartIdViewModel.swift @@ -18,7 +18,6 @@ */ import UIKit -import OSLog import Alamofire import SmartIdLib import LibdigidocLibSwift @@ -29,12 +28,7 @@ import CryptoKit @Observable @MainActor -class SmartIdViewModel: SmartIdViewModelProtocol { - private static let logger = Logger( - subsystem: "ee.ria.digidoc.RIADigiDoc", - category: "SmartIdViewModel" - ) - +class SmartIdViewModel: SmartIdViewModelProtocol, Loggable { private var backgroundTask: UIBackgroundTaskIdentifier = .invalid private static let certificateEndpoint = "/certificatechoice/etsi" @@ -123,12 +117,12 @@ class SmartIdViewModel: SmartIdViewModelProtocol { roleData: RoleData, signedContainer: SignedContainerProtocol ) async -> SignedContainerProtocol? { - SmartIdViewModel.logger.debug("Smart-ID: Signing with Smart-ID") + SmartIdViewModel.logger().debug("Smart-ID: Signing with Smart-ID") let currentConfiguration = await configurationRepository.getConfiguration() guard let configuration = currentConfiguration else { - SmartIdViewModel.logger.error( + SmartIdViewModel.logger().error( "Smart-ID: Unable to get configuration to sign with Smart-ID" ) smartIdMessageKey = "General error" @@ -150,7 +144,7 @@ class SmartIdViewModel: SmartIdViewModelProtocol { do { containerFile = try await getContainerFile(signedContainer: signedContainer) } catch { - SmartIdViewModel.logger.debug("Smart-ID: Unable to get container file from container") + SmartIdViewModel.logger().debug("Smart-ID: Unable to get container file from container") handleSigningError(error) return nil } @@ -168,7 +162,7 @@ class SmartIdViewModel: SmartIdViewModelProtocol { proxyInfo: proxyInfo ) } catch { - SmartIdViewModel.logger.debug("Smart-ID: Unable to request certificate or get response") + SmartIdViewModel.logger().debug("Smart-ID: Unable to request certificate or get response") handleSigningError(error) return nil } @@ -190,7 +184,7 @@ class SmartIdViewModel: SmartIdViewModelProtocol { signedContainer: signedContainer ) } catch { - SmartIdViewModel.logger.debug("Smart-ID: Unable to prepare signature for signing") + SmartIdViewModel.logger().debug("Smart-ID: Unable to prepare signature for signing") handleSigningError(error) return nil } @@ -199,7 +193,7 @@ class SmartIdViewModel: SmartIdViewModelProtocol { do { verificationCode = try await getVerificationCode(hash: hash) } catch { - SmartIdViewModel.logger.debug("Smart-ID: Unable to get verification code (control code)") + SmartIdViewModel.logger().debug("Smart-ID: Unable to get verification code (control code)") handleSigningError(error) return nil } @@ -219,7 +213,7 @@ class SmartIdViewModel: SmartIdViewModelProtocol { ) } } catch { - SmartIdViewModel.logger.error( + SmartIdViewModel.logger().error( "Smart-ID: Unable to send verification code (control code) notification. \(error)" ) } @@ -239,7 +233,7 @@ class SmartIdViewModel: SmartIdViewModelProtocol { ) } catch { endBackgroundTask() - SmartIdViewModel.logger.debug("Smart-ID: Unable to request signature or get cert from response") + SmartIdViewModel.logger().debug("Smart-ID: Unable to request signature or get cert from response") handleSigningError(error) notificationUtil.removeNotification(id: notificationIdentifier) return nil @@ -255,12 +249,12 @@ class SmartIdViewModel: SmartIdViewModelProtocol { containerFile: containerFile ) - SmartIdViewModel.logger.debug("Signature added successfully (Smart-ID)") + SmartIdViewModel.logger().debug("Signature added successfully (Smart-ID)") smartIdMessageKey = "Signature added" notificationUtil.removeNotification(id: notificationIdentifier) return updatedContainer } catch { - SmartIdViewModel.logger.error("Unable to sign container with Smart-ID: \(error)") + SmartIdViewModel.logger().error("Unable to sign container with Smart-ID: \(error)") handleSignatureAddingError(error) notificationUtil.removeNotification(id: notificationIdentifier) return nil @@ -299,7 +293,7 @@ class SmartIdViewModel: SmartIdViewModelProtocol { trustedCertificates: [SecCertificate], proxyInfo: ProxyInfo ) async throws -> SmartIdSessionResponse { - SmartIdViewModel.logger.debug("Smart-ID: Getting certificate") + SmartIdViewModel.logger().debug("Smart-ID: Getting certificate") let certResponse = try await smartIdSignService .getCertificateRequest( url: "\(sidUrl)\(SmartIdViewModel.certificateEndpoint)", @@ -315,7 +309,7 @@ class SmartIdViewModel: SmartIdViewModelProtocol { throw SmartIdError.missingSessionId } - SmartIdViewModel.logger.debug("Smart-ID: Requesting session from certificate response") + SmartIdViewModel.logger().debug("Smart-ID: Requesting session from certificate response") return try await requestSession( sidUrl: "\(sidUrl)\(SmartIdViewModel.sessionEndpoint)", @@ -338,7 +332,7 @@ class SmartIdViewModel: SmartIdViewModelProtocol { trustedCertificates: [SecCertificate], proxyInfo: ProxyInfo ) async throws -> Data { - SmartIdViewModel.logger.debug("Smart-ID: Getting signature") + SmartIdViewModel.logger().debug("Smart-ID: Getting signature") let certResponse = try await smartIdSignService .getSignatureRequest( @@ -358,7 +352,7 @@ class SmartIdViewModel: SmartIdViewModelProtocol { throw SmartIdError.missingSessionId } - SmartIdViewModel.logger.debug("Smart-ID: Requesting session from signature response") + SmartIdViewModel.logger().debug("Smart-ID: Requesting session from signature response") let sessionResponse = try await requestSession( sidUrl: "\(sidUrl)\(SmartIdViewModel.sessionEndpoint)", @@ -395,7 +389,7 @@ class SmartIdViewModel: SmartIdViewModelProtocol { trustedCertificates: [SecCertificate], proxyInfo: ProxyInfo ) async throws -> SmartIdSessionResponse { - SmartIdViewModel.logger.debug("Smart-ID: Getting session") + SmartIdViewModel.logger().debug("Smart-ID: Getting session") return try await smartIdSignService.getSessionRequest( url: sidUrl, sessionId: sessionId, @@ -410,13 +404,13 @@ class SmartIdViewModel: SmartIdViewModelProtocol { } private func getTrustedCertificates(certificates: [Data]) -> [SecCertificate] { - SmartIdViewModel.logger.debug("Smart-ID: Getting trusted certificates list") + SmartIdViewModel.logger().debug("Smart-ID: Getting trusted certificates list") return certificates.compactMap { certificateUtil.certificate(from: $0) } } private func getContainerFile(signedContainer: SignedContainerProtocol) async throws -> URL { guard let containerFile = await signedContainer.getRawContainerFile() else { - SmartIdViewModel.logger.error( + SmartIdViewModel.logger().error( "Unable to sign with Smart-ID. Unable to get container file" ) smartIdMessageKey = "General error" @@ -432,7 +426,7 @@ class SmartIdViewModel: SmartIdViewModelProtocol { roleData: RoleData, signedContainer: SignedContainerProtocol ) async throws -> Data { - SmartIdViewModel.logger.debug( + SmartIdViewModel.logger().debug( "Smart-ID: Preparing signature. Calculating hash" ) @@ -445,7 +439,7 @@ class SmartIdViewModel: SmartIdViewModelProtocol { } private func getVerificationCode(hash: Data) async throws -> String { - SmartIdViewModel.logger.debug( + SmartIdViewModel.logger().debug( "Smart-ID: Calculating verification code (control code)" ) return await smartIdSignService.getVerificationCode(digest: sha256(data: hash)) @@ -458,10 +452,10 @@ class SmartIdViewModel: SmartIdViewModelProtocol { // swiftlint:disable:next cyclomatic_complexity private func handleSigningError(_ error: Error) { - SmartIdViewModel.logger.error("Unable to sign container with Smart-ID: \(error)") + SmartIdViewModel.logger().error("Unable to sign container with Smart-ID: \(error)") if let cancellationError = error as? CancellationError { - SmartIdViewModel.logger.error("Smart-ID signing manually cancelled: \(cancellationError)") + SmartIdViewModel.logger().error("Smart-ID signing manually cancelled: \(cancellationError)") // Do not throw an error if user cancelled signing with back button return } @@ -477,7 +471,7 @@ class SmartIdViewModel: SmartIdViewModelProtocol { case .explicitlyCancelled: // Do not throw an error if user cancelled signing with back button - SmartIdViewModel.logger.debug("Smart-ID signing manually cancelled") + SmartIdViewModel.logger().debug("Smart-ID signing manually cancelled") smartIdMessageKey = nil case .noInternetConnection, .noResponse: @@ -544,10 +538,10 @@ class SmartIdViewModel: SmartIdViewModelProtocol { // swiftlint:disable:next cyclomatic_complexity private func handleSignatureAddingError(_ error: Error) { - SmartIdViewModel.logger.error("Unable to sign container with Smart-ID: \(error)") + SmartIdViewModel.logger().error("Unable to sign container with Smart-ID: \(error)") if let cancellationError = error as? CancellationError { - SmartIdViewModel.logger.error("Smart-ID signing manually cancelled: \(cancellationError)") + SmartIdViewModel.logger().error("Smart-ID signing manually cancelled: \(cancellationError)") return } diff --git a/RIADigiDoc/ViewModel/SigningViewModel.swift b/RIADigiDoc/ViewModel/SigningViewModel.swift index 7b006a0c..c4fead1c 100644 --- a/RIADigiDoc/ViewModel/SigningViewModel.swift +++ b/RIADigiDoc/ViewModel/SigningViewModel.swift @@ -19,15 +19,13 @@ import Foundation import FactoryKit -import OSLog import LibdigidocLibSwift import CommonsLib import UtilsLib @Observable @MainActor -class SigningViewModel: SigningViewModelProtocol { - private static let logger = Logger(subsystem: "ee.ria.digidoc.RIADigiDoc", category: "SigningViewModel") +class SigningViewModel: SigningViewModelProtocol, Loggable { var dataFiles: [DataFileWrapper] = [] var signatures: [SignatureWrapper] = [] @@ -79,12 +77,12 @@ class SigningViewModel: SigningViewModelProtocol { } func loadContainerData(signedContainer: SignedContainerProtocol?) async { - SigningViewModel.logger.debug("Loading container data") + SigningViewModel.logger().debug("Loading container data") sharedContainerViewModel.setIsSignatureAdded(false) let openedContainer = (signedContainer ?? sharedContainerViewModel.currentContainer()) as? any SignedContainerProtocol guard let openedContainer else { - SigningViewModel.logger.error("Cannot load container data. Signed container is nil.") + SigningViewModel.logger().error("Cannot load container data. Signed container is nil.") return } @@ -102,7 +100,7 @@ class SigningViewModel: SigningViewModelProtocol { self.containerNotifications = await getContainerNotifications(container: openedContainer) - SigningViewModel.logger.debug("Container data loaded") + SigningViewModel.logger().debug("Container data loaded") } func getContainerNotifications(container: SignedContainerProtocol) async -> [ContainerNotificationType] { @@ -133,7 +131,7 @@ class SigningViewModel: SigningViewModelProtocol { func createCopyOfContainerForSaving(containerURL: URL?) -> URL? { guard let containerLocation = containerURL else { - SigningViewModel.logger.error("Unable to get container to create copy for saving") + SigningViewModel.logger().error("Unable to get container to create copy for saving") return nil } @@ -153,7 +151,7 @@ class SigningViewModel: SigningViewModelProtocol { do { try fileManager.removeItem(at: tempSavedFileLocation) } catch { - SigningViewModel.logger.error("Unable to remove existing file: \(error.localizedDescription)") + SigningViewModel.logger().error("Unable to remove existing file: \(error.localizedDescription)") return nil } } @@ -161,13 +159,13 @@ class SigningViewModel: SigningViewModelProtocol { do { try fileManager.copyItem(at: containerLocation, to: tempSavedFileLocation) } catch { - SigningViewModel.logger.error("Unable to copy file: \(error.localizedDescription)") + SigningViewModel.logger().error("Unable to copy file: \(error.localizedDescription)") return nil } return tempSavedFileLocation } catch { - SigningViewModel.logger.error("Unable to get cache directory: \(error.localizedDescription)") + SigningViewModel.logger().error("Unable to get cache directory: \(error.localizedDescription)") return nil } } @@ -186,7 +184,7 @@ class SigningViewModel: SigningViewModelProtocol { do { let updatedContainer = try await signedContainer?.addDataFiles(files, to: container) - SigningViewModel.logger.debug("Added data files to container") + SigningViewModel.logger().debug("Added data files to container") errorMessage = ErrorMessage( key: files.count == 1 ? "File successfully added" : "Files successfully added", args: [] @@ -205,7 +203,7 @@ class SigningViewModel: SigningViewModelProtocol { do { try url.removeLastOpenedXattr() } catch { - SigningViewModel.logger.error("Unable to remove last opened xattr: \(error)") + SigningViewModel.logger().error("Unable to remove last opened xattr: \(error)") } } @@ -258,7 +256,7 @@ class SigningViewModel: SigningViewModelProtocol { } private func handleAddFilesError(_ error: Error, container: URL) async { - SigningViewModel.logger.error("Unable to add data files to container: \(error.localizedDescription)") + SigningViewModel.logger().error("Unable to add data files to container: \(error.localizedDescription)") var totalFilesCount = 0 var failedFileCount = 0 @@ -312,7 +310,7 @@ class SigningViewModel: SigningViewModelProtocol { await loadContainerData(signedContainer: renamedContainer) return await renamedContainer?.getRawContainerFile() } catch { - SigningViewModel.logger.error("Unable to rename container: \(error)") + SigningViewModel.logger().error("Unable to rename container: \(error)") if let digiDocError = error as? DigiDocError { switch digiDocError { case .containerRenamingFailed(let errorDetail), @@ -366,15 +364,15 @@ class SigningViewModel: SigningViewModelProtocol { do { try await openNestedContainer(fileURL: fileURL, isSivaConfirmed: isSivaConfirmed) } catch { - SigningViewModel.logger.error("Failed to open nested container: \(error)") + SigningViewModel.logger().error("Failed to open nested container: \(error)") errorMessage = ErrorMessage(key: "Failed to open container", args: [dataFile.fileName]) if error.localizedDescription.contains("Online validation disabled") { - SigningViewModel.logger.error( + SigningViewModel.logger().error( "Unable to open container '\([dataFile.fileName])'. Sending to SiVa not allowed." ) errorMessage = nil } else { - SigningViewModel.logger.error("Failed to open nested container: \(error)") + SigningViewModel.logger().error("Failed to open nested container: \(error)") errorMessage = ErrorMessage(key: "Failed to open container", args: [dataFile.fileName]) } } @@ -468,7 +466,7 @@ class SigningViewModel: SigningViewModelProtocol { func removeSignature(_ signature: SignatureWrapper) async { guard let container = signedContainer, let containerFile = containerURL else { - SigningViewModel.logger.error( + SigningViewModel.logger().error( "Unable to remove signature from container. SignedContainer or containerURL is nil" ) errorMessage = ErrorMessage(key: "Failed to remove signature from container", args: []) @@ -479,7 +477,7 @@ class SigningViewModel: SigningViewModelProtocol { let container = try await container.removeSignature(index: signature.pos, containerFile: containerFile) await loadContainerData(signedContainer: container) } catch { - SigningViewModel.logger.error("Unable to remove signature from container. \(error)") + SigningViewModel.logger().error("Unable to remove signature from container. \(error)") errorMessage = ErrorMessage(key: "Failed to remove signature from container", args: []) return } @@ -487,7 +485,7 @@ class SigningViewModel: SigningViewModelProtocol { func removeDataFile(_ dataFile: DataFileWrapper) async { guard let container = signedContainer, let containerFile = containerURL else { - SigningViewModel.logger.error( + SigningViewModel.logger().error( "Unable to remove file from container. SignedContainer or containerURL is nil" ) errorMessage = ErrorMessage( @@ -498,7 +496,7 @@ class SigningViewModel: SigningViewModelProtocol { } guard let index = dataFiles.firstIndex(where: { $0.fileId == dataFile.fileId }) else { - SigningViewModel.logger.error( + SigningViewModel.logger().error( "Unable to remove file from container. File not found in container" ) errorMessage = ErrorMessage(key: "Failed to remove file from container", args: [dataFile.fileName]) @@ -516,7 +514,7 @@ class SigningViewModel: SigningViewModelProtocol { await loadContainerData(signedContainer: container) return } catch { - SigningViewModel.logger.error("Unable to remove file from container. \(error)") + SigningViewModel.logger().error("Unable to remove file from container. \(error)") errorMessage = ErrorMessage( key: "Failed to remove file from container", args: [dataFile.fileName] diff --git a/RIADigiDoc/ViewModel/TimeStampSettingsViewModel.swift b/RIADigiDoc/ViewModel/TimeStampSettingsViewModel.swift index ac5ed52f..768152f5 100644 --- a/RIADigiDoc/ViewModel/TimeStampSettingsViewModel.swift +++ b/RIADigiDoc/ViewModel/TimeStampSettingsViewModel.swift @@ -21,16 +21,12 @@ import CommonsLib import ConfigLib import LibdigidocLibSwift import LibdigidocLibObjC -import OSLog import UniformTypeIdentifiers import UtilsLib @Observable @MainActor -class TimeStampSettingsViewModel: TimeStampSettingsViewModelProtocol { - private static let logger = Logger( - subsystem: "ee.ria.digidoc.RIADigiDoc", category: "TimeStampServicesSettingsViewModel") - +class TimeStampSettingsViewModel: TimeStampSettingsViewModelProtocol, Loggable { // MARK: - Variables var configuration: ConfigurationProvider? var tsaUrl: String = "" diff --git a/RIADigiDoc/ViewModel/ValidationSettingsViewModel.swift b/RIADigiDoc/ViewModel/ValidationSettingsViewModel.swift index a48b6c3d..8b659200 100644 --- a/RIADigiDoc/ViewModel/ValidationSettingsViewModel.swift +++ b/RIADigiDoc/ViewModel/ValidationSettingsViewModel.swift @@ -20,16 +20,12 @@ import CommonsLib import ConfigLib import LibdigidocLibSwift -import OSLog import UniformTypeIdentifiers import UtilsLib @Observable @MainActor -class ValidationSettingsViewModel: ValidationSettingsViewModelProtocol { - private static let logger = Logger( - subsystem: "ee.ria.digidoc.RIADigiDoc", category: "ValidationSettingsViewModel") - +class ValidationSettingsViewModel: ValidationSettingsViewModelProtocol, Loggable { var configuration: ConfigurationProvider? var validationServiceUrl: String = "" var selectedOption: ServicesSettingsOption = .defaultSetting diff --git a/RIADigiDocTests/ViewModel/DiagnosticsViewModelTests.swift b/RIADigiDocTests/ViewModel/DiagnosticsViewModelTests.swift index aaac84a2..252bbcdf 100644 --- a/RIADigiDocTests/ViewModel/DiagnosticsViewModelTests.swift +++ b/RIADigiDocTests/ViewModel/DiagnosticsViewModelTests.swift @@ -25,7 +25,6 @@ import ConfigLibMocks import Foundation import LibdigidocLibSwift import LibdigidocLibSwiftMocks -import OSLog import Testing import UtilsLib import UtilsLibMocks diff --git a/RIADigiDocTests/ViewModel/SigningViewModelTests.swift b/RIADigiDocTests/ViewModel/SigningViewModelTests.swift index 87bf76bf..2fbdc022 100644 --- a/RIADigiDocTests/ViewModel/SigningViewModelTests.swift +++ b/RIADigiDocTests/ViewModel/SigningViewModelTests.swift @@ -18,7 +18,6 @@ */ import Foundation -import OSLog import LibdigidocLibSwift import Testing import UtilsLib @@ -29,8 +28,7 @@ import UtilsLibMocks import LibdigidocLibSwiftMocks @MainActor -struct SigningViewModelTests { - private static let logger = Logger(subsystem: "ee.ria.digidoc.RIADigiDoc", category: "SigningViewModelTests") +struct SigningViewModelTests: Loggable { private let mockSharedContainerViewModel: SharedContainerViewModelProtocolMock private let viewModel: SigningViewModel