From 2c0d79e62e6cf05ee86723cc1b6acdfb325a6e4d Mon Sep 17 00:00:00 2001 From: Markus Tamm Date: Mon, 12 Jan 2026 17:20:03 +0200 Subject: [PATCH 1/5] Add functionality to create one time log file Alert when deactivating logging Add ENABLE_LOGGING flag refactor Direcotires --- .../Sources/CommonsLib/Constants.swift | 1 + .../include/Conf/DigiDocConfWrapper.mm | 6 +- .../Sources/UtilsLib/File/Directories.swift | 108 +++------ .../Sources/UtilsLib/File/FileUtil.swift | 42 +++- .../UtilsLib/File/FileUtilProtocol.swift | 4 + RIADigiDoc/DI/AppContainer.swift | 4 +- RIADigiDoc/Domain/Preferences/DataStore.swift | 19 +- .../Preferences/DataStoreProtocol.swift | 7 +- RIADigiDoc/LibrarySetup.swift | 22 +- .../Supporting files/Localizable.xcstrings | 20 +- RIADigiDoc/UI/Component/DiagnosticsView.swift | 85 ++++++- .../ViewModel/DiagnosticsViewModel.swift | 223 +++++++++++++++--- .../DiagnosticsViewModelProtocol.swift | 14 +- .../ViewModel/DiagnosticsViewModelTests.swift | 33 +-- codemagic.yaml | 6 +- 15 files changed, 423 insertions(+), 171 deletions(-) diff --git a/Modules/CommonsLib/Sources/CommonsLib/Constants.swift b/Modules/CommonsLib/Sources/CommonsLib/Constants.swift index a520687b..bc4f8d4d 100644 --- a/Modules/CommonsLib/Sources/CommonsLib/Constants.swift +++ b/Modules/CommonsLib/Sources/CommonsLib/Constants.swift @@ -98,6 +98,7 @@ public struct Constants { } public struct File { + public static let LibDigidocLog = "libdigidocpp.log" public static let LDAPCertsPem = "ldapCerts.pem" } diff --git a/Modules/LibdigidocLib/Sources/LibdigidocObjC/include/Conf/DigiDocConfWrapper.mm b/Modules/LibdigidocLib/Sources/LibdigidocObjC/include/Conf/DigiDocConfWrapper.mm index 520a01e2..8d0fa4b5 100644 --- a/Modules/LibdigidocLib/Sources/LibdigidocObjC/include/Conf/DigiDocConfWrapper.mm +++ b/Modules/LibdigidocLib/Sources/LibdigidocObjC/include/Conf/DigiDocConfWrapper.mm @@ -183,11 +183,7 @@ int logLevel() const final { } std::string logFile() const final { - return logFileLocation(currentConf.logFile); - } - - std::string logFileLocation(NSString *logsFolderPath) const { - return [logsFolderPath stringByAppendingPathComponent:@"libdigidocpp.log"].UTF8String; + return currentConf.logFile.UTF8String; } std::vector toX509Certs(NSArray *certBundle, NSURL *cert = nil) const { diff --git a/Modules/UtilsLib/Sources/UtilsLib/File/Directories.swift b/Modules/UtilsLib/Sources/UtilsLib/File/Directories.swift index 5bb32b73..134494c8 100644 --- a/Modules/UtilsLib/Sources/UtilsLib/File/Directories.swift +++ b/Modules/UtilsLib/Sources/UtilsLib/File/Directories.swift @@ -28,19 +28,9 @@ public struct Directories { ) throws -> URL { var tempDirectory = fileManager.temporaryDirectory .appending(path: BundleUtil.getBundleIdentifier(), directoryHint: .isDirectory) - if !subfolder.isEmpty { - tempDirectory = tempDirectory.appending(path: subfolder, directoryHint: .isDirectory) - } - - if !fileManager.fileExists(atPath: tempDirectory.resolvedPath) { - try fileManager - .createDirectory( - at: tempDirectory, - withIntermediateDirectories: true, - attributes: nil - ) - } + tempDirectory = appendSubfolder(baseFolder: tempDirectory, subfolder: subfolder) + try createDirectoryIfNeeded(at: tempDirectory, fileManager: fileManager) return tempDirectory } @@ -56,16 +46,7 @@ public struct Directories { } let sharedContainerSubfolder = sharedContainerURL.appending(path: subfolder) - - if !fileManager.fileExists(atPath: sharedContainerSubfolder.resolvedPath) { - try fileManager - .createDirectory( - at: sharedContainerSubfolder, - withIntermediateDirectories: true, - attributes: nil - ) - } - + try createDirectoryIfNeeded(at: sharedContainerSubfolder, fileManager: fileManager) return sharedContainerSubfolder } @@ -80,54 +61,26 @@ public struct Directories { create: false) .appending(path: BundleUtil.getBundleIdentifier(), directoryHint: .isDirectory) - if !subfolder.isEmpty { - cacheDirectory = cacheDirectory.appending(path: subfolder, directoryHint: .isDirectory) - } - - if !fileManager.fileExists(atPath: cacheDirectory.resolvedPath) { - try fileManager - .createDirectory( - at: cacheDirectory, - withIntermediateDirectories: true, - attributes: nil - ) - } - + cacheDirectory = appendSubfolder(baseFolder: cacheDirectory, subfolder: subfolder) + try createDirectoryIfNeeded(at: cacheDirectory, fileManager: fileManager) return cacheDirectory } - public static func getLibraryDirectory( - fileManager: FileManagerProtocol - ) -> URL? { - if let libraryDirectory = fileManager.urls(for: .libraryDirectory, in: .userDomainMask).first { - return libraryDirectory - } - return nil + public static func getLibraryDirectory(fileManager: FileManagerProtocol) -> URL? { + return fileManager.urls(for: .libraryDirectory, in: .userDomainMask).first } - public static func getDocumentsDirectory( - fileManager: FileManagerProtocol - ) -> URL? { - if let documentsDirectory = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first { - return documentsDirectory - } - return nil + public static func getDocumentsDirectory(fileManager: FileManagerProtocol) -> URL? { + return fileManager.urls(for: .documentDirectory, in: .userDomainMask).first } - public static func getApplicationDirectory( - fileManager: FileManagerProtocol - ) -> URL? { - if let applicationDirectory = fileManager.urls(for: .applicationDirectory, in: .userDomainMask).first { - return applicationDirectory - } - return nil + public static func getApplicationDirectory(fileManager: FileManagerProtocol) -> URL? { + return fileManager.urls(for: .applicationDirectory, in: .userDomainMask).first } public static func getConfigDirectory(from directory: URL? = nil, fileManager: FileManagerProtocol) throws -> URL { let baseDirectory = try directory ?? getCacheDirectory(fileManager: fileManager) - return baseDirectory.appending(path: - Constants.Configuration.CacheConfigFolder, directoryHint: .isDirectory - ) + return appendSubfolder(baseFolder: baseDirectory, subfolder: Constants.Configuration.CacheConfigFolder) } public static func getTslCacheDirectory(fileManager: FileManagerProtocol) -> URL? { @@ -138,34 +91,29 @@ public struct Directories { from directory: URL?, fileManager: FileManagerProtocol ) throws -> URL? { - let libdigidocppLogFile = "libdigidocpp.log" - - if let mainDirectory = directory { - let primaryLogsDirectory = mainDirectory.appending(path: "logs") + let baseDirectory = try directory ?? getCacheDirectory(fileManager: fileManager) + let logsDirectory = baseDirectory.appending(path: "logs") + try createDirectoryIfNeeded(at: logsDirectory, fileManager: fileManager) + return logsDirectory.appending(path: Constants.File.LibDigidocLog) + } - if !fileManager.fileExists(atPath: primaryLogsDirectory.resolvedPath) { - try fileManager.createDirectory( - at: primaryLogsDirectory, - withIntermediateDirectories: true, - attributes: nil - ) - return primaryLogsDirectory.appending(path: libdigidocppLogFile) - } else { - return primaryLogsDirectory.appending(path: libdigidocppLogFile) - } + private static func appendSubfolder(baseFolder: URL, subfolder: String = "") -> URL { + if !subfolder.isEmpty { + return baseFolder.appending(path: subfolder, directoryHint: .isDirectory) } + return baseFolder + } - let cacheDirectory = try getCacheDirectory(fileManager: fileManager) - let fallbackLogsDirectory = cacheDirectory.appending(path: "logs") - - if !fileManager.fileExists(atPath: fallbackLogsDirectory.resolvedPath) { + private static func createDirectoryIfNeeded( + at url: URL, + fileManager: FileManagerProtocol + ) throws { + if !fileManager.fileExists(atPath: url.resolvedPath) { try fileManager.createDirectory( - at: fallbackLogsDirectory, + at: url, withIntermediateDirectories: true, attributes: nil ) } - - return fallbackLogsDirectory.appending(path: libdigidocppLogFile) } } diff --git a/Modules/UtilsLib/Sources/UtilsLib/File/FileUtil.swift b/Modules/UtilsLib/Sources/UtilsLib/File/FileUtil.swift index 37b365bc..6a5d1b17 100644 --- a/Modules/UtilsLib/Sources/UtilsLib/File/FileUtil.swift +++ b/Modules/UtilsLib/Sources/UtilsLib/File/FileUtil.swift @@ -282,16 +282,50 @@ public struct FileUtil: FileUtilProtocol, Loggable { } public func removeSavedFilesDirectory(savedFilesDirectory: URL? = nil) { - 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") + removeDirectory(at: directory, description: "Saved Files directory") } catch { - FileUtil.logger().error("Unable to delete saved files directory: \(error.localizedDescription)") + FileUtil.logger().error("Unable to locate Saved Files directory: \(error.localizedDescription)") + } + } + + public func removeCacheLogsDirectory() { + do { + let directory = try Directories.getCacheDirectory( + subfolder: CommonsLib.Constants.Folder.Logs, + fileManager: fileManager + ) + removeDirectory(at: directory, description: "cache/logs directory") + } catch { + FileUtil.logger().error("Unable to locate cache/logs directory: \(error.localizedDescription)") + } + } + + public func removeLibraryLogsDirectory(directory: URL? = nil) { + guard let libraryDirectory = directory ?? Directories.getLibraryDirectory( + fileManager: fileManager + ) else { + FileUtil.logger().error("Unable to locate library directory") + return + } + let directory = libraryDirectory.appendingPathComponent( + "logs", + isDirectory: true + ) + removeDirectory(at: directory, description: "library/logs directory") + } + + private func removeDirectory(at url: URL, description: String) { + FileUtil.logger().debug("Removing \(description)") + do { + try fileManager.removeItem(at: url) + FileUtil.logger().debug("\(description) removed") + } catch { + FileUtil.logger().error("Unable to remove \(description): \(error.localizedDescription)") } } } diff --git a/Modules/UtilsLib/Sources/UtilsLib/File/FileUtilProtocol.swift b/Modules/UtilsLib/Sources/UtilsLib/File/FileUtilProtocol.swift index caa471d1..6f2a45f4 100644 --- a/Modules/UtilsLib/Sources/UtilsLib/File/FileUtilProtocol.swift +++ b/Modules/UtilsLib/Sources/UtilsLib/File/FileUtilProtocol.swift @@ -48,4 +48,8 @@ public protocol FileUtilProtocol: Sendable { func removeSharedFiles(url: URL?) throws func removeSavedFilesDirectory(savedFilesDirectory: URL?) + + func removeCacheLogsDirectory() + + func removeLibraryLogsDirectory(directory: URL?) } diff --git a/RIADigiDoc/DI/AppContainer.swift b/RIADigiDoc/DI/AppContainer.swift index 4633a0fa..b3077bb8 100644 --- a/RIADigiDoc/DI/AppContainer.swift +++ b/RIADigiDoc/DI/AppContainer.swift @@ -32,6 +32,7 @@ extension Container { configurationLoader: self.configurationLoader(), configurationRepository: self.configurationRepository(), fileManager: self.fileManager(), + fileUtil: self.fileUtil(), tslUtil: self.tslUtil(), dataStore: self.dataStore(), advancedSettingsRepository: self.advancedSettingsRepository(), @@ -250,7 +251,8 @@ extension Container { configurationRepository: self.configurationRepository(), tslUtil: self.tslUtil(), dataStore: self.dataStore(), - proxyUtil: self.proxyUtil() + proxyUtil: self.proxyUtil(), + fileUtil: self.fileUtil() ) } } diff --git a/RIADigiDoc/Domain/Preferences/DataStore.swift b/RIADigiDoc/Domain/Preferences/DataStore.swift index 7a43a5f5..8965f4c3 100644 --- a/RIADigiDoc/Domain/Preferences/DataStore.swift +++ b/RIADigiDoc/Domain/Preferences/DataStore.swift @@ -464,12 +464,20 @@ public actor DataStore: DataStoreProtocol { // MARK: - Logging - public func getIsLoggingEnabled() async -> Bool { - userDefaults().bool(forKey: Keys.isLoggingEnabled) + public func getEnableLoggingNextSession() async -> Bool { + userDefaults().bool(forKey: Keys.enableLoggingNextSession) } - public func setIsLoggingEnabled(_ isEnabled: Bool) async { - userDefaults().set(isEnabled, forKey: Keys.isLoggingEnabled) + public func setEnableLoggingNextSession(_ isEnabled: Bool) async { + userDefaults().set(isEnabled, forKey: Keys.enableLoggingNextSession) + } + + public func getEnableLoggingThisSession() async -> Bool { + userDefaults().bool(forKey: Keys.enableLoggingThisSession) + } + + public func setEnableLoggingThisSession(_ isEnabled: Bool) async { + userDefaults().set(isEnabled, forKey: Keys.enableLoggingThisSession) } // MARK: - Constants @@ -534,6 +542,7 @@ public actor DataStore: DataStoreProtocol { static let roleZipCode = "roleZipCode" static let nfcCanNumber = "nfcCanNumber" static let nfcRememberMe = "nfcRememberMe" - static let isLoggingEnabled = "isLoggingEnabled" + static let enableLoggingNextSession = "enableLoggingNextSession" + static let enableLoggingThisSession = "enableLoggingThisSession" } } diff --git a/RIADigiDoc/Domain/Preferences/DataStoreProtocol.swift b/RIADigiDoc/Domain/Preferences/DataStoreProtocol.swift index b00654e5..0ee9c751 100644 --- a/RIADigiDoc/Domain/Preferences/DataStoreProtocol.swift +++ b/RIADigiDoc/Domain/Preferences/DataStoreProtocol.swift @@ -19,6 +19,7 @@ import CommonsLib import ConfigLib +import Foundation /// @mockable public protocol DataStoreProtocol: Sendable { @@ -108,6 +109,8 @@ public protocol DataStoreProtocol: Sendable { func setNFCInputData(_ inputData: NFCInputData) async // MARK: - Logging - func getIsLoggingEnabled() async -> Bool - func setIsLoggingEnabled(_ isEnabled: Bool) async + func getEnableLoggingNextSession() async -> Bool + func setEnableLoggingNextSession(_ isEnabled: Bool) async + func getEnableLoggingThisSession() async -> Bool + func setEnableLoggingThisSession(_ isEnabled: Bool) async } diff --git a/RIADigiDoc/LibrarySetup.swift b/RIADigiDoc/LibrarySetup.swift index fc5524d8..2e1201fe 100644 --- a/RIADigiDoc/LibrarySetup.swift +++ b/RIADigiDoc/LibrarySetup.swift @@ -30,6 +30,7 @@ actor LibrarySetup: Loggable { private let configurationLoader: ConfigurationLoaderProtocol private let configurationRepository: ConfigurationRepositoryProtocol private let fileManager: FileManagerProtocol + private let fileUtil: FileUtilProtocol private let tslUtil: TSLUtilProtocol private let dataStore: DataStoreProtocol private let advancedSettingsRepository: AdvancedSettingsRepositoryProtocol @@ -41,6 +42,7 @@ actor LibrarySetup: Loggable { configurationLoader: ConfigurationLoaderProtocol, configurationRepository: ConfigurationRepositoryProtocol, fileManager: FileManagerProtocol, + fileUtil: FileUtilProtocol, tslUtil: TSLUtilProtocol, dataStore: DataStoreProtocol, advancedSettingsRepository: AdvancedSettingsRepositoryProtocol, @@ -51,6 +53,7 @@ actor LibrarySetup: Loggable { self.configurationLoader = configurationLoader self.configurationRepository = configurationRepository self.fileManager = fileManager + self.fileUtil = fileUtil self.tslUtil = tslUtil self.dataStore = dataStore self.advancedSettingsRepository = advancedSettingsRepository @@ -60,8 +63,7 @@ actor LibrarySetup: Loggable { } func setupLibraries() async { - let isLoggingEnabled = await dataStore.getIsLoggingEnabled() - await initializeLogging(isLoggingEnabled: isLoggingEnabled) + let isLoggingEnabled = await initializeLogging() do { let proxyInfo = await proxyUtil.getProxyInfo() @@ -166,8 +168,22 @@ actor LibrarySetup: Loggable { ) } - private func initializeLogging(isLoggingEnabled: Bool) async { + private func initializeLogging() async -> Bool { + #if DEBUG || ENABLE_LOGGING + let isLoggingEnabled = true + #else + let isLoggingEnabled = await dataStore.getEnableLoggingNextSession() + if !isLoggingEnabled { + fileUtil.removeCacheLogsDirectory() + fileUtil.removeLibraryLogsDirectory(directory: nil) + } + #endif + Container.shared.isLoggingEnabled.register { isLoggingEnabled } + await dataStore.setEnableLoggingNextSession(false) + await dataStore.setEnableLoggingThisSession(isLoggingEnabled) + + return isLoggingEnabled } private func getTSAOption() async -> ServicesSettingsOption { diff --git a/RIADigiDoc/Supporting files/Localizable.xcstrings b/RIADigiDoc/Supporting files/Localizable.xcstrings index 5ce46743..7b19044a 100644 --- a/RIADigiDoc/Supporting files/Localizable.xcstrings +++ b/RIADigiDoc/Supporting files/Localizable.xcstrings @@ -2895,6 +2895,24 @@ } } }, + "Main diagnostics restart message deactivate" : { + "comment" : "Main diagnostics restart message deactivate logging", + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Restart RIA DigiDoc to deactivate logging." + } + }, + "et" : { + "stringUnit" : { + "state" : "translated", + "value" : "Logimise deaktiveerimiseks taaskäivita RIA DigiDoc." + } + } + } + }, "Main diagnostics restart message restart now" : { "comment" : "Main diagnostics restart message restart now", "extractionState" : "manual", @@ -7262,4 +7280,4 @@ } }, "version" : "1.1" -} +} \ No newline at end of file diff --git a/RIADigiDoc/UI/Component/DiagnosticsView.swift b/RIADigiDoc/UI/Component/DiagnosticsView.swift index 2a0c01bd..c0bd8948 100644 --- a/RIADigiDoc/UI/Component/DiagnosticsView.swift +++ b/RIADigiDoc/UI/Component/DiagnosticsView.swift @@ -25,15 +25,19 @@ struct DiagnosticsView: View { @AppTheme private var theme @Environment(LanguageSettings.self) private var languageSettings - @Environment(\.dismiss) private var dismiss + @Environment(\.openURL) var openURL private let fileUtil: FileUtilProtocol - @State private var enableOneTimeLogGeneration = false // TODO: implement one time log generation logic + private enum ExportType { + case diagnosticsFile + case logFile + } - @State private var tempDiagnosticsFileURL: URL? - @State private var isShowingFileSaver = false + @State private var activeExportType: ExportType? + @State private var tempFileURL: URL? + @State private var isShowingFileSaver: Bool = false @State private var isFileSaved: Bool = false @State private var viewModel: DiagnosticsViewModel @@ -67,22 +71,32 @@ struct DiagnosticsView: View { }, onSaveDiagnosticsClick: { Task { - tempDiagnosticsFileURL = await viewModel.createLogFile( + tempFileURL = await viewModel.createDiagnosticsFile( languageSettings: languageSettings ) - - if fileUtil.fileExists(fileLocation: tempDiagnosticsFileURL) { - isShowingFileSaver = true - } + triggerFileSaver(type: .diagnosticsFile) } } ) ToggleSection( - isOn: $enableOneTimeLogGeneration, + isOn: $viewModel.enableOneTimeLogGeneration, label: languageSettings.localized("Main diagnostics logging switch") ) + if viewModel.showSaveLogButton { + PrimaryOutlinedButton( + text: languageSettings.localized("Main diagnostics save log"), + assetImageName: "ic_m3_download_48pt_wght400", + action: { + Task { + tempFileURL = await viewModel.createLogFile() + triggerFileSaver(type: .logFile) + } + } + ) + } + DiagnosticsSections( versionSectionContent: viewModel.versionSectionContent, osSectionContent: viewModel.osSectionContent, @@ -98,14 +112,22 @@ struct DiagnosticsView: View { .background( FileSaverHandler( isPresented: $isShowingFileSaver, - fileURL: tempDiagnosticsFileURL, + fileURL: tempFileURL, languageSettings: languageSettings, onComplete: { - viewModel.removeLogFilesDirectory() + handleFileSaverCompletion() }, isFileSaved: $isFileSaved ) ) + .alert( + languageSettings.localized("Main diagnostics restart message"), + isPresented: $viewModel.showRestartActivateAlert + ) {alertContent} + .alert( + languageSettings.localized("Main diagnostics restart message deactivate"), + isPresented: $viewModel.showRestartDeactivateAlert + ) {alertContent} .task { await viewModel .getConfigurationData( @@ -117,6 +139,11 @@ struct DiagnosticsView: View { Task { await viewModel.getConfigurationData(configuration: newConfig) } } }) + .onChange(of: viewModel.enableOneTimeLogGeneration) { _, newValue in + Task { + await viewModel.onEnableOneTimeLogGenerationChange(newValue) + } + } .onDisappear { Task { await viewModel.removeObservers() @@ -126,6 +153,40 @@ struct DiagnosticsView: View { } ) } + + @ViewBuilder + private var alertContent: some View { + Button(languageSettings.localized("OK")) {} + Button(languageSettings.localized("Read more here")) { + if let url = URL( + string: languageSettings.localized("main diagnostics restart message url") + ) { + openURL(url) + } + } + } + + private func triggerFileSaver(type: ExportType) { + self.activeExportType = type + if fileUtil.fileExists(fileLocation: tempFileURL) { + isShowingFileSaver = true + } + } + + private func handleFileSaverCompletion() { + guard let type = activeExportType else { return } + + switch type { + case .diagnosticsFile: + viewModel.onDiagnosticsFileSavingComplete() + case .logFile: + Task { + await viewModel.onLogFileSavingComplete() + } + } + + activeExportType = nil + } } // MARK: - Preview diff --git a/RIADigiDoc/ViewModel/DiagnosticsViewModel.swift b/RIADigiDoc/ViewModel/DiagnosticsViewModel.swift index 1a783c69..539ffe3e 100644 --- a/RIADigiDoc/ViewModel/DiagnosticsViewModel.swift +++ b/RIADigiDoc/ViewModel/DiagnosticsViewModel.swift @@ -17,10 +17,10 @@ * */ -import SwiftUI import CommonsLib import ConfigLib import LibdigidocLibSwift +import OSLog import UtilsLib @Observable @@ -28,6 +28,11 @@ import UtilsLib class DiagnosticsViewModel: DiagnosticsViewModelProtocol, Loggable { var configuration: ConfigurationProvider? + var enableOneTimeLogGeneration = false + var showSaveLogButton = false + var showRestartActivateAlert = false + var showRestartDeactivateAlert = false + // MARK: - section content var versionSectionContent: String = "" var osSectionContent: (key: String, content: String) = (key: "", content: "") @@ -45,6 +50,7 @@ class DiagnosticsViewModel: DiagnosticsViewModelProtocol, Loggable { private let tslUtil: TSLUtilProtocol private let dataStore: DataStoreProtocol private let proxyUtil: ProxyUtilProtocol + private let fileUtil: FileUtilProtocol private var configurationObservationTask: Task? @@ -55,7 +61,8 @@ class DiagnosticsViewModel: DiagnosticsViewModelProtocol, Loggable { configurationRepository: ConfigurationRepositoryProtocol, tslUtil: TSLUtilProtocol, dataStore: DataStoreProtocol, - proxyUtil: ProxyUtilProtocol + proxyUtil: ProxyUtilProtocol, + fileUtil: FileUtilProtocol ) { self.containerWrapper = containerWrapper self.fileManager = fileManager @@ -64,6 +71,7 @@ class DiagnosticsViewModel: DiagnosticsViewModelProtocol, Loggable { self.tslUtil = tslUtil self.dataStore = dataStore self.proxyUtil = proxyUtil + self.fileUtil = fileUtil configurationObservationTask = Task { await observeConfigurationUpdates() @@ -71,6 +79,7 @@ class DiagnosticsViewModel: DiagnosticsViewModelProtocol, Loggable { Task { await loadLibdigidocVersion() + await loadLoggingVariables() } } @@ -78,7 +87,7 @@ class DiagnosticsViewModel: DiagnosticsViewModelProtocol, Loggable { configurationObservationTask?.cancel() } - // MARK: - Fetching content + // MARK: - Fetching content - public func getConfigurationData( configuration: ConfigurationProvider?, @@ -92,6 +101,8 @@ class DiagnosticsViewModel: DiagnosticsViewModelProtocol, Loggable { loadCentralConfigurationContent(configuration: configuration) } + // MARK: - Fetching content - private + func getRpUuid() async -> String { await dataStore.getRelyingPartyUUID() } @@ -213,43 +224,24 @@ class DiagnosticsViewModel: DiagnosticsViewModelProtocol, Loggable { return "\(dateTime.date) \(dateTime.time)" } - // MARK: - Create Log File + // MARK: - Create Diagnostics File - public - func createLogFile(languageSettings: LanguageSettingsProtocol, directory: URL? = nil) async -> URL? { + func createDiagnosticsFile(languageSettings: LanguageSettingsProtocol, directory: URL? = nil) async -> URL? { let diagnosticsText = buildDiagnosticsText(languageSettings: languageSettings) - do { - - let savedFilesDirectory = try directory ?? Directories.getCacheDirectory( - subfolder: CommonsLib.Constants.Folder.Logs, - fileManager: fileManager - ) - let diagnosticsFileName = "ria_digidoc_\(self.versionSectionContent)_diagnostics.log" - let fileURL = savedFilesDirectory.appending(path: diagnosticsFileName) - - try diagnosticsText.write(to: fileURL, atomically: true, encoding: .utf8) - - return fileURL - } catch { - DiagnosticsViewModel.logger().error( - "Failed to write diagnostics file: \(error.localizedDescription)") - } - return nil + let diagnosticsFileName = "ria_digidoc_\(self.versionSectionContent)_diagnostics.log" + return writeToTempFile( + content: diagnosticsText, + fileName: diagnosticsFileName, + directory: directory + ) } - func removeLogFilesDirectory() { - do { - let directory = try Directories.getCacheDirectory( - subfolder: CommonsLib.Constants.Folder.Logs, - fileManager: fileManager - ) - try fileManager.removeItem(at: directory) - DiagnosticsViewModel.logger().debug("Saved Files directory removed") - } catch { - DiagnosticsViewModel.logger().error( - "Unable to delete saved files directory: \(error.localizedDescription)") - } + func onDiagnosticsFileSavingComplete() { + fileUtil.removeCacheLogsDirectory() } + // MARK: - Create Diagnostics File - private + private func buildDiagnosticsText(languageSettings: LanguageSettingsProtocol) -> String { var lines: [String] = [] @@ -287,7 +279,15 @@ class DiagnosticsViewModel: DiagnosticsViewModelProtocol, Loggable { return lines.joined(separator: "\n") } - // MARK: - Update configuration + private func getTempFileURL(fileName: String, directory: URL? = nil) throws -> URL { + let savedFilesDirectory = try directory ?? Directories.getCacheDirectory( + subfolder: CommonsLib.Constants.Folder.Logs, + fileManager: fileManager + ) + return savedFilesDirectory.appending(path: fileName) + } + + // MARK: - Update configuration - public func updateConfiguration() async -> Bool { do { @@ -308,6 +308,159 @@ class DiagnosticsViewModel: DiagnosticsViewModelProtocol, Loggable { } } + // MARK: - Creating Log - public + + public func onEnableOneTimeLogGenerationChange(_ isEnabled: Bool) async { + let dataStoreValue = await dataStore.getEnableLoggingNextSession() + if isEnabled == dataStoreValue { + return + } + + if isEnabled { + self.showRestartActivateAlert = true + } + await dataStore.setEnableLoggingNextSession(isEnabled) + + if !isEnabled { + showSaveLogButton = false + removeAllLogFiles() + await dataStore.setEnableLoggingThisSession(false) + } + } + + public func createLogFile(directory: URL? = nil) async -> URL? { + let appLogEntries = await readAppLogEntries() + let libdigidocLogEntries = await readLibDigidocLogEntries() + let mergedLines = mergeLogEntries(appLogEntries, libdigidocLogEntries) + let logFileName = "ria_digidoc_\(self.versionSectionContent).log" + return writeToTempFile( + content: mergedLines, + fileName: logFileName, + directory: directory + ) + } + + private func writeToTempFile(content: String, fileName: String, directory: URL?) -> URL? { + do { + let fileURL = try getTempFileURL(fileName: fileName, directory: directory) + try content.write(to: fileURL, atomically: true, encoding: .utf8) + return fileURL + } catch { + DiagnosticsViewModel.logger().error("Unable to write \"\(fileName)\" file: \(error)") + } + return nil + } + + public func onLogFileSavingComplete() async { + removeAllLogFiles() + + await dataStore.setEnableLoggingNextSession(false) + self.enableOneTimeLogGeneration = false + self.showSaveLogButton = false + self.showRestartDeactivateAlert = true + } + + // MARK: - Creating Log - private + + private func loadLoggingVariables() async { + enableOneTimeLogGeneration = await dataStore.getEnableLoggingNextSession() + showSaveLogButton = await dataStore.getEnableLoggingThisSession() + } + + private func removeAllLogFiles() { + fileUtil.removeCacheLogsDirectory() + fileUtil.removeLibraryLogsDirectory(directory: nil) + } + + nonisolated private func entriesToLines(_ entries: AnySequence) -> [String] { + var lines = [String]() + for entry in entries { + if let log = entry as? OSLogEntryLog { + lines.append(""" + \(entry.date) \ + [\(log.subsystem):\(log.category)] - \ + \(entry.composedMessage)\n + """) + } else { + lines.append("\(entry.date): \(entry.composedMessage)\n") + } + + } + return lines + } + + private func readAppLogEntries() async -> [String]? { + await Task.detached { + do { + let store = try OSLogStore(scope: .currentProcessIdentifier) + + let oneDayAgo = Date().addingTimeInterval(-24 * 60 * 60) + let position = store.position(date: oneDayAgo) + let bundleIdentifier = BundleUtil.getBundleIdentifier() + let predicate = NSPredicate( + format: "subsystem BEGINSWITH %@", + bundleIdentifier + ) + + let entries = try store.getEntries(at: position, matching: predicate) + return self.entriesToLines(entries) + + } catch { + DiagnosticsViewModel.logger().error("Unable to get app log entries: \(error)") + return nil + } + }.value + } + + private func readLibDigidocLogEntries() async -> [String]? { + if let libdigidocLogURL = await getLibDigidocLogURL() { + return getLines(from: libdigidocLogURL) + } + return nil + } + + private func getLibDigidocLogURL() async -> URL? { + do { + return try Directories.getLibdigidocLogFile( + from: Directories.getLibraryDirectory(fileManager: fileManager), + fileManager: fileManager + ) + } catch { + DiagnosticsViewModel.logger().error("Unable to get libdigidoc log URL: \(error)") + } + return nil + } + + private func getLines(from url: URL?) -> [String] { + guard let url = url, fileManager.fileExists(atPath: url.path) else { return [] } + do { + let content = try String(contentsOf: url, encoding: .utf8) + return content.components(separatedBy: .newlines).filter { !$0.isEmpty } + } catch { + return [] + } + } + + private func mergeLogEntries(_ appLogEntries: [String]?, _ libDigidocLogEntries: [String]?) -> String { + var allEntries: [String] = [] + + allEntries.append("===== File: \(Constants.File.LibDigidocLog) =====") + allEntries.append("") + if let libDigidocLogEntries = libDigidocLogEntries { + allEntries.append(contentsOf: libDigidocLogEntries) + } + + allEntries.append("") + allEntries.append("") + allEntries.append("===== File: ria_digidoc.log =====") + allEntries.append("") + if let appLogEntries = appLogEntries { + allEntries.append(contentsOf: appLogEntries) + } + + return allEntries.joined(separator: "\n") + } + // MARK: - Observer public func observeConfigurationUpdates() async { diff --git a/RIADigiDoc/ViewModel/Protocols/DiagnosticsViewModelProtocol.swift b/RIADigiDoc/ViewModel/Protocols/DiagnosticsViewModelProtocol.swift index f755a034..fa688840 100644 --- a/RIADigiDoc/ViewModel/Protocols/DiagnosticsViewModelProtocol.swift +++ b/RIADigiDoc/ViewModel/Protocols/DiagnosticsViewModelProtocol.swift @@ -25,6 +25,11 @@ import CommonsLib @MainActor public protocol DiagnosticsViewModelProtocol: Sendable { // MARK: Published properties + var enableOneTimeLogGeneration: Bool { get } + var showSaveLogButton: Bool { get } + var showRestartActivateAlert: Bool { get } + var showRestartDeactivateAlert: Bool { get } + var versionSectionContent: String { get } var osSectionContent: (key: String, content: String) { get } var libdigidocVersion: String { get } @@ -38,8 +43,13 @@ public protocol DiagnosticsViewModelProtocol: Sendable { // MARK: Actions func updateConfiguration() async -> Bool - func createLogFile(languageSettings: LanguageSettingsProtocol, directory: URL?) async -> URL? - func removeLogFilesDirectory() + func createDiagnosticsFile(languageSettings: LanguageSettingsProtocol, directory: URL?) async -> URL? + func onDiagnosticsFileSavingComplete() + func onEnableOneTimeLogGenerationChange(_ isEnabled: Bool) async + func createLogFile(directory: URL?) async -> URL? + func onLogFileSavingComplete() async func removeObservers() async + func getRpUuid() async -> String + func observeConfigurationUpdates() async } diff --git a/RIADigiDocTests/ViewModel/DiagnosticsViewModelTests.swift b/RIADigiDocTests/ViewModel/DiagnosticsViewModelTests.swift index 252bbcdf..d3c21b18 100644 --- a/RIADigiDocTests/ViewModel/DiagnosticsViewModelTests.swift +++ b/RIADigiDocTests/ViewModel/DiagnosticsViewModelTests.swift @@ -40,6 +40,7 @@ final class DiagnosticsViewModelTests { private let mockTSLUtil: TSLUtilProtocolMock private let mockDataStore: DataStoreProtocolMock private let mockProxyUtil: ProxyUtilProtocolMock + private let mockFileUtil: FileUtilProtocolMock let mockConfigProvider: ConfigurationProvider? @@ -51,6 +52,7 @@ final class DiagnosticsViewModelTests { mockTSLUtil = TSLUtilProtocolMock() mockDataStore = DataStoreProtocolMock() mockProxyUtil = ProxyUtilProtocolMock() + mockFileUtil = FileUtilProtocolMock() mockConfigProvider = try TestConfigurationProvider.mockConfigurationProvider() TestConfigurationSetup.configureMocks( @@ -67,7 +69,8 @@ final class DiagnosticsViewModelTests { configurationRepository: mockConfigurationRepository, tslUtil: mockTSLUtil, dataStore: mockDataStore, - proxyUtil: mockProxyUtil + proxyUtil: mockProxyUtil, + fileUtil: mockFileUtil ) } @@ -254,10 +257,10 @@ final class DiagnosticsViewModelTests { #expect(rpUuid == uuid) } - // MARK: - Create Log File Tests + // MARK: - Create Diagnostics File Tests @Test - func createLogFile_success() async throws { + func createDiagnosticsFile_success() async throws { let mockLanguageSettings = LanguageSettingsProtocolMock() await viewModel.getConfigurationData(configuration: mockConfigProvider) @@ -272,7 +275,7 @@ final class DiagnosticsViewModelTests { try? FileManager.default.removeItem(at: tempDirectoryURL) } - if let logFileUrl = await viewModel.createLogFile( + if let logFileUrl = await viewModel.createDiagnosticsFile( languageSettings: mockLanguageSettings, directory: tempDirectoryURL ) { @@ -281,34 +284,24 @@ final class DiagnosticsViewModelTests { } @Test - func createLogFile_returnsNilWhenDirectoryDoesNotExist() async throws { + func createDiagnosticsFile_returnsNilWhenDirectoryDoesNotExist() async throws { mockFileManager.fileExistsHandler = { _ in false } let mockLanguageSettings = LanguageSettingsProtocolMock() await viewModel.getConfigurationData(configuration: mockConfigProvider) - let logFileUrl = await self.viewModel.createLogFile( + let logFileUrl = await self.viewModel.createDiagnosticsFile( languageSettings: mockLanguageSettings, ) #expect(logFileUrl == nil) } - // MARK: - Remove Log Files Directory Tests + // MARK: - onDiagnosticsFileSavingComplete Tests @Test - func removeLogFilesDirectory_success() async throws { - viewModel.removeLogFilesDirectory() - #expect(mockFileManager.removeItemCallCount == 1) - } - - @Test - func removeLogFilesDirectory_doesNotThrowWhenFails() async throws { - mockFileManager.removeItemHandler = { _ in - throw NSError(domain: "TestError", code: 1, userInfo: nil) - } - #expect(throws: Never.self) { - self.viewModel.removeLogFilesDirectory() - } + func onDiagnosticsFileSavingComplete_success() async throws { + viewModel.onDiagnosticsFileSavingComplete() + #expect(mockFileUtil.removeCacheLogsDirectoryCallCount == 1) } // MARK: - Update Configuration Tests diff --git a/codemagic.yaml b/codemagic.yaml index ec6f78be..05303a39 100644 --- a/codemagic.yaml +++ b/codemagic.yaml @@ -167,7 +167,11 @@ workflows: REPO_RIA_CONF_FLAGS="DEFAULT_CENTRAL_CONFIGURATION_URL='' DEFAULT_CENTRAL_CONFIGURATION_UPDATE_INTERVAL=4 DEFAULT_CENTRAL_CONFIGURATION_TSL_URL=''" fi - ARCHIVE_FLAGS="$REPO_RIA_CONF_FLAGS" + # Enable logging flag + LOGGING_FLAGS="OTHER_SWIFT_FLAGS=\"\$(inherited) -DENABLE_LOGGING\"" + + # Add logging flag to conf flags + ARCHIVE_FLAGS="$REPO_RIA_CONF_FLAGS $LOGGING_FLAGS" xcode-project build-ipa \ --clean \ From 59ae9bb4189fa8b9a49c571ca2fabacc910eb12e Mon Sep 17 00:00:00 2001 From: Markus Tamm Date: Mon, 19 Jan 2026 11:02:08 +0200 Subject: [PATCH 2/5] Refactor LogStore task --- .../ViewModel/DiagnosticsViewModel.swift | 46 ++++++++++--------- 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/RIADigiDoc/ViewModel/DiagnosticsViewModel.swift b/RIADigiDoc/ViewModel/DiagnosticsViewModel.swift index 539ffe3e..3f69d68d 100644 --- a/RIADigiDoc/ViewModel/DiagnosticsViewModel.swift +++ b/RIADigiDoc/ViewModel/DiagnosticsViewModel.swift @@ -372,7 +372,7 @@ class DiagnosticsViewModel: DiagnosticsViewModelProtocol, Loggable { fileUtil.removeLibraryLogsDirectory(directory: nil) } - nonisolated private func entriesToLines(_ entries: AnySequence) -> [String] { + private func entriesToLines(_ entries: AnySequence) -> [String] { var lines = [String]() for entry in entries { if let log = entry as? OSLogEntryLog { @@ -384,32 +384,36 @@ class DiagnosticsViewModel: DiagnosticsViewModelProtocol, Loggable { } else { lines.append("\(entry.date): \(entry.composedMessage)\n") } - } return lines } private func readAppLogEntries() async -> [String]? { - await Task.detached { - do { - let store = try OSLogStore(scope: .currentProcessIdentifier) - - let oneDayAgo = Date().addingTimeInterval(-24 * 60 * 60) - let position = store.position(date: oneDayAgo) - let bundleIdentifier = BundleUtil.getBundleIdentifier() - let predicate = NSPredicate( - format: "subsystem BEGINSWITH %@", - bundleIdentifier - ) - - let entries = try store.getEntries(at: position, matching: predicate) - return self.entriesToLines(entries) - - } catch { - DiagnosticsViewModel.logger().error("Unable to get app log entries: \(error)") - return nil + return await withCheckedContinuation { continuation in + Task.detached(priority: .userInitiated) { + do { + let store = try OSLogStore(scope: .currentProcessIdentifier) + let oneDayAgo = Calendar.current.date(byAdding: .day, value: -1, to: Date()) + guard let yesterday = oneDayAgo else { + continuation.resume(returning: nil) + return + } + + let position = store.position(date: yesterday) + let bundleIdentifier = BundleUtil.getBundleIdentifier() + let predicate = NSPredicate( + format: "subsystem BEGINSWITH %@", + bundleIdentifier + ) + let entries = try store.getEntries(at: position, matching: predicate) + let lines = await self.entriesToLines(entries) + continuation.resume(returning: lines) + } catch { + DiagnosticsViewModel.logger().error("Unable to get app log entries: \(error)") + continuation.resume(returning: nil) + } } - }.value + } } private func readLibDigidocLogEntries() async -> [String]? { From c13b3e7ce00feb246a2e831e235d71d3220ae458 Mon Sep 17 00:00:00 2001 From: Markus Tamm Date: Mon, 19 Jan 2026 12:09:45 +0200 Subject: [PATCH 3/5] Refactor DiagnosticsViewModel --- .../ViewModel/DiagnosticsViewModel.swift | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/RIADigiDoc/ViewModel/DiagnosticsViewModel.swift b/RIADigiDoc/ViewModel/DiagnosticsViewModel.swift index 3f69d68d..07dba86c 100644 --- a/RIADigiDoc/ViewModel/DiagnosticsViewModel.swift +++ b/RIADigiDoc/ViewModel/DiagnosticsViewModel.swift @@ -340,17 +340,6 @@ class DiagnosticsViewModel: DiagnosticsViewModelProtocol, Loggable { ) } - private func writeToTempFile(content: String, fileName: String, directory: URL?) -> URL? { - do { - let fileURL = try getTempFileURL(fileName: fileName, directory: directory) - try content.write(to: fileURL, atomically: true, encoding: .utf8) - return fileURL - } catch { - DiagnosticsViewModel.logger().error("Unable to write \"\(fileName)\" file: \(error)") - } - return nil - } - public func onLogFileSavingComplete() async { removeAllLogFiles() @@ -367,6 +356,17 @@ class DiagnosticsViewModel: DiagnosticsViewModelProtocol, Loggable { showSaveLogButton = await dataStore.getEnableLoggingThisSession() } + private func writeToTempFile(content: String, fileName: String, directory: URL?) -> URL? { + do { + let fileURL = try getTempFileURL(fileName: fileName, directory: directory) + try content.write(to: fileURL, atomically: true, encoding: .utf8) + return fileURL + } catch { + DiagnosticsViewModel.logger().error("Unable to write \"\(fileName)\" file: \(error)") + } + return nil + } + private func removeAllLogFiles() { fileUtil.removeCacheLogsDirectory() fileUtil.removeLibraryLogsDirectory(directory: nil) From c47b4e3958cceb52c4bfaf3ce222e657df416b41 Mon Sep 17 00:00:00 2001 From: Markus Tamm Date: Thu, 22 Jan 2026 15:53:49 +0200 Subject: [PATCH 4/5] Refactor fileutil --- .../UtilsLib/Sources/UtilsLib/File/FileUtil.swift | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/Modules/UtilsLib/Sources/UtilsLib/File/FileUtil.swift b/Modules/UtilsLib/Sources/UtilsLib/File/FileUtil.swift index 6a5d1b17..f89e8dae 100644 --- a/Modules/UtilsLib/Sources/UtilsLib/File/FileUtil.swift +++ b/Modules/UtilsLib/Sources/UtilsLib/File/FileUtil.swift @@ -287,7 +287,7 @@ public struct FileUtil: FileUtilProtocol, Loggable { subfolder: CommonsLib.Constants.Folder.SavedFiles, fileManager: fileManager ) - removeDirectory(at: directory, description: "Saved Files directory") + removeDirectory(at: directory) } catch { FileUtil.logger().error("Unable to locate Saved Files directory: \(error.localizedDescription)") } @@ -299,7 +299,7 @@ public struct FileUtil: FileUtilProtocol, Loggable { subfolder: CommonsLib.Constants.Folder.Logs, fileManager: fileManager ) - removeDirectory(at: directory, description: "cache/logs directory") + removeDirectory(at: directory) } catch { FileUtil.logger().error("Unable to locate cache/logs directory: \(error.localizedDescription)") } @@ -316,16 +316,17 @@ public struct FileUtil: FileUtilProtocol, Loggable { "logs", isDirectory: true ) - removeDirectory(at: directory, description: "library/logs directory") + removeDirectory(at: directory) } - private func removeDirectory(at url: URL, description: String) { - FileUtil.logger().debug("Removing \(description)") + private func removeDirectory(at url: URL) { + let filePath = url.path(percentEncoded: false) + FileUtil.logger().debug("Removing \(filePath)") do { try fileManager.removeItem(at: url) - FileUtil.logger().debug("\(description) removed") + FileUtil.logger().debug("\(filePath) removed") } catch { - FileUtil.logger().error("Unable to remove \(description): \(error.localizedDescription)") + FileUtil.logger().error("Unable to remove \(filePath): \(error.localizedDescription)") } } } From 32b168f609b4a0609861212bf8164ebe90b3d03e Mon Sep 17 00:00:00 2001 From: Markus Tamm Date: Tue, 27 Jan 2026 14:15:51 +0200 Subject: [PATCH 5/5] Change debug to info --- .../ViewModel/ShareViewModel.swift | 8 ++-- .../CommonsLib/System/SystemUtil.swift | 4 +- .../Loader/ConfigurationLoader.swift | 20 ++++----- .../Sources/CryptoSwift/CryptoContainer.swift | 6 +-- .../Sources/CryptoSwift/Ldap/OpenLdap.swift | 20 ++++----- .../IdCardLib/CardActions/CardReaderNFC.swift | 34 +++++++------- .../CardActions/CardReaderiR301.swift | 8 ++-- .../Operations/UsbReaderConnection.swift | 16 +++---- .../Domain/Container/ContainerWrapper.swift | 4 +- .../LibdigidocSwift/SignedContainer.swift | 12 ++--- .../UtilsLib/Container/ContainerUtil.swift | 4 +- .../Sources/UtilsLib/File/FileUtil.swift | 44 +++++++++---------- .../Notification/NotificationUtil.swift | 14 +++--- .../Validator/PersonalCodeValidator.swift | 2 +- .../Validator/PhoneNumberValidator.swift | 8 ++-- RIADigiDoc/LibrarySetup.swift | 5 ++- RIADigiDoc/ViewModel/ContentViewModel.swift | 6 +-- .../CryptoFileOpeningViewModel.swift | 6 +-- RIADigiDoc/ViewModel/DataFilesViewModel.swift | 2 +- .../ViewModel/DiagnosticsViewModel.swift | 2 +- RIADigiDoc/ViewModel/EncryptViewModel.swift | 6 +-- .../ViewModel/FileOpeningViewModel.swift | 8 ++-- .../Signing/MobileId/MobileIdViewModel.swift | 34 +++++++------- .../Signing/SmartId/SmartIdViewModel.swift | 32 +++++++------- RIADigiDoc/ViewModel/SigningViewModel.swift | 6 +-- 25 files changed, 156 insertions(+), 155 deletions(-) diff --git a/Extensions/FileImportShareExtension/ViewModel/ShareViewModel.swift b/Extensions/FileImportShareExtension/ViewModel/ShareViewModel.swift index 07322c02..4239a0eb 100644 --- a/Extensions/FileImportShareExtension/ViewModel/ShareViewModel.swift +++ b/Extensions/FileImportShareExtension/ViewModel/ShareViewModel.swift @@ -42,7 +42,7 @@ class ShareViewModel: ShareViewModelProtocol, Loggable { @discardableResult func importFiles(_ items: [ImportedFileItem]) async -> Bool { - ShareViewModel.logger().debug("Importing files...") + ShareViewModel.logger().info("Importing files...") guard !items.isEmpty else { await MainActor.run { [weak self] in self?.status = .failed @@ -57,7 +57,7 @@ class ShareViewModel: ShareViewModelProtocol, Loggable { ) if isImported { - ShareViewModel.logger().debug("Files imported successfully") + ShareViewModel.logger().info("Files imported successfully") } else { ShareViewModel.logger().error("Could not import files") } @@ -178,7 +178,7 @@ class ShareViewModel: ShareViewModelProtocol, Loggable { } func downloadFileFromUrl(_ itemUrl: URL) async -> Bool { - ShareViewModel.logger().debug("Downloading file from \(itemUrl.absoluteString)") + ShareViewModel.logger().info("Downloading file from \(itemUrl.absoluteString)") do { let destinationURL = try Directories.getTempDirectory( @@ -198,7 +198,7 @@ class ShareViewModel: ShareViewModelProtocol, Loggable { for await progress in request.downloadProgress() { let fileName = itemUrl.lastPathComponent let downloadProgress = progress.fractionCompleted * 100 - ShareViewModel.logger().debug( + ShareViewModel.logger().info( "\(String(format: "Download progress for file '%@': %.2f%%", fileName, downloadProgress))" ) } diff --git a/Modules/CommonsLib/Sources/CommonsLib/System/SystemUtil.swift b/Modules/CommonsLib/Sources/CommonsLib/System/SystemUtil.swift index 26f4f6f7..a162dc08 100644 --- a/Modules/CommonsLib/Sources/CommonsLib/System/SystemUtil.swift +++ b/Modules/CommonsLib/Sources/CommonsLib/System/SystemUtil.swift @@ -22,7 +22,7 @@ import Foundation public struct SystemUtil: Loggable { public static var isSimulator: Bool { #if targetEnvironment(simulator) - logger().debug("App is running on a simulator") + logger().info("App is running on a simulator") return true #else return false @@ -32,7 +32,7 @@ public struct SystemUtil: Loggable { 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().info("Operating system version: \(versionString)") return versionString } } diff --git a/Modules/ConfigLib/Sources/ConfigLib/Configuration/Loader/ConfigurationLoader.swift b/Modules/ConfigLib/Sources/ConfigLib/Configuration/Loader/ConfigurationLoader.swift index 8524facf..527a476b 100644 --- a/Modules/ConfigLib/Sources/ConfigLib/Configuration/Loader/ConfigurationLoader.swift +++ b/Modules/ConfigLib/Sources/ConfigLib/Configuration/Loader/ConfigurationLoader.swift @@ -58,7 +58,7 @@ public actor ConfigurationLoader: ConfigurationLoaderProtocol, Loggable { } public func initConfiguration(cacheDir: URL, proxyInfo: ProxyInfo) async throws { - ConfigurationLoader.logger().debug("Initializing configuration") + ConfigurationLoader.logger().info("Initializing configuration") if !fileManager.fileExists(atPath: cacheDir.resolvedPath) { try fileManager.createDirectory( @@ -70,11 +70,11 @@ public actor ConfigurationLoader: ConfigurationLoaderProtocol, Loggable { try await loadConfigurationProperty() if try await shouldCheckForUpdates() { - ConfigurationLoader.logger().debug("Checking for configuration updates...") + ConfigurationLoader.logger().info("Checking for configuration updates...") try await loadCentralConfiguration(cacheDir: cacheDir, proxyInfo: proxyInfo) } - ConfigurationLoader.logger().debug("Finished initializing configuration") + ConfigurationLoader.logger().info("Finished initializing configuration") finishConfigurationUpdate() } @@ -124,7 +124,7 @@ public actor ConfigurationLoader: ConfigurationLoaderProtocol, Loggable { fileManager.fileExists(atPath: signatureFile.resolvedPath) if configFilesExist { - ConfigurationLoader.logger().debug("Initializing cached configuration") + ConfigurationLoader.logger().info("Initializing cached configuration") let confFileContents = try String(contentsOf: confFile, encoding: .utf8) let publicKeyContents = try String(contentsOf: publicKeyFile, encoding: .utf8) @@ -141,7 +141,7 @@ public actor ConfigurationLoader: ConfigurationLoaderProtocol, Loggable { from: Data(contentsOf: confFile) ) - ConfigurationLoader.logger().debug( + ConfigurationLoader.logger().info( "Using cached configuration version \(configurationProvider.metaInf.serial)" ) @@ -179,7 +179,7 @@ public actor ConfigurationLoader: ConfigurationLoaderProtocol, Loggable { updateConfiguration(configurationProvider) } } else { - ConfigurationLoader.logger().debug( + ConfigurationLoader.logger().info( "Cached configuration not found. Initializing default configuration") try await loadDefaultConfiguration(cacheDir: configDir) } @@ -239,7 +239,7 @@ public actor ConfigurationLoader: ConfigurationLoaderProtocol, Loggable { ConfigurationProvider.self, from: Data(contentsOf: confDataURL) ) - ConfigurationLoader.logger().debug( + ConfigurationLoader.logger().info( "Initializing default configuration version \(configurationProvider.metaInf.serial)" ) @@ -281,7 +281,7 @@ public actor ConfigurationLoader: ConfigurationLoaderProtocol, Loggable { ).trimmingCharacters(in: .whitespaces) if !centralSignature.isEmpty && currentSignature != centralSignature.data(using: .utf8) { - ConfigurationLoader.logger().debug("Found new configuration") + ConfigurationLoader.logger().info("Found new configuration") let centralConfig = try await centralConfigurationRepository.fetchConfiguration( proxyInfo: proxyInfo @@ -293,7 +293,7 @@ public actor ConfigurationLoader: ConfigurationLoaderProtocol, Loggable { let centralConfigurationProvider = try JSONDecoder().decode( ConfigurationProvider.self, from: Data(centralConfig.utf8) ) - ConfigurationLoader.logger().debug( + ConfigurationLoader.logger().info( "Initializing configuration version \(centralConfigurationProvider.metaInf.serial)" ) @@ -337,7 +337,7 @@ public actor ConfigurationLoader: ConfigurationLoaderProtocol, Loggable { try await loadCachedConfiguration(afterCentralCheck: true, cacheDir: configDir) } } else { - ConfigurationLoader.logger().debug( + ConfigurationLoader.logger().info( "New configuration not found. Using cached configuration" ) try await loadCachedConfiguration(afterCentralCheck: true, cacheDir: configDir) diff --git a/Modules/CryptoLib/Sources/CryptoSwift/CryptoContainer.swift b/Modules/CryptoLib/Sources/CryptoSwift/CryptoContainer.swift index 09a0b3fe..b261b5d5 100644 --- a/Modules/CryptoLib/Sources/CryptoSwift/CryptoContainer.swift +++ b/Modules/CryptoLib/Sources/CryptoSwift/CryptoContainer.swift @@ -195,7 +195,7 @@ 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().info("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") throw CryptoError.containerCreationFailed( @@ -240,10 +240,10 @@ extension CryptoContainer { } if dataFiles.count == 1 && isFirstDataFileContainer { - CryptoContainer.logger().debug("Opening existing crypto container") + CryptoContainer.logger().info("Opening existing crypto container") return try await open(containerFile: containerFile) } else { - CryptoContainer.logger().debug("Creating a new crypto container") + CryptoContainer.logger().info("Creating a new crypto container") return try await create( containerFile: containerFile, dataFiles: dataFiles, diff --git a/Modules/CryptoLib/Sources/CryptoSwift/Ldap/OpenLdap.swift b/Modules/CryptoLib/Sources/CryptoSwift/Ldap/OpenLdap.swift index 443716f0..8b36cabe 100644 --- a/Modules/CryptoLib/Sources/CryptoSwift/Ldap/OpenLdap.swift +++ b/Modules/CryptoLib/Sources/CryptoSwift/Ldap/OpenLdap.swift @@ -91,14 +91,14 @@ final public class OpenLdap: OpenLdapProtocol, Loggable { if fileManager.fileExists(atPath: ldapCertFilePath) { filePath = ldapCertFilePath } else { - OpenLdap.logger().debug("File ldapCerts.pem does not exist at directory path: \(ldapCertFilePath)") + OpenLdap.logger().info("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().info("Searching with personal code from LDAP") var result = [Addressee]() var tooManyResults = false for url in await self.ldapConfiguration.getLdapPersonURLS() { @@ -116,7 +116,7 @@ final public class OpenLdap: OpenLdapProtocol, Loggable { return (result, tooManyResults) } else { if let ldapCorpURL = await self.ldapConfiguration.getLdapCorpURL() { - OpenLdap.logger().debug("Searching with corporation keyword from LDAP") + OpenLdap.logger().info("Searching with corporation keyword from LDAP") let (addresses, found) = OpenLdap.search( searchType: searchType, url: ldapCorpURL, @@ -145,7 +145,7 @@ final public class OpenLdap: OpenLdapProtocol, Loggable { 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().info( "ldap_set_option(LDAP_OPT_X_TLS_NEWCTX) failed: \(String(cString: ldap_err2string(result)))" ) return ([], 0) @@ -167,14 +167,14 @@ final public class OpenLdap: OpenLdapProtocol, Loggable { 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().info("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().info( "ldap_set_option(PROTOCOL_VERSION) failed: \(String(cString: ldap_err2string(ldapReturnCode)))" ) return ([], 0) @@ -186,7 +186,7 @@ final public class OpenLdap: OpenLdapProtocol, Loggable { } else { distinguishedName.remove(at: distinguishedName.startIndex) } - OpenLdap.logger().debug("Searching from LDAP. Url: \(url) \(distinguishedName) \(searchType.filter)") + OpenLdap.logger().info("Searching from LDAP. Url: \(url) \(distinguishedName) \(searchType.filter)") var msgId: Int32 = 0 var attr = Array("userCertificate;binary".utf8CString) ldapReturnCode = attr.withUnsafeMutableBufferPointer { attr in @@ -209,7 +209,7 @@ final public class OpenLdap: OpenLdapProtocol, Loggable { } guard ldapReturnCode == LDAP_SUCCESS else { - OpenLdap.logger().debug("ldap_search_ext failed: \(String(cString: ldap_err2string(ldapReturnCode)))") + OpenLdap.logger().info("ldap_search_ext failed: \(String(cString: ldap_err2string(ldapReturnCode)))") return ([], 0) } @@ -231,7 +231,7 @@ final public class OpenLdap: OpenLdapProtocol, Loggable { case Int32(LDAP_SUCCESS): break default: - OpenLdap.logger().debug("ldap_result failed: \(String(cString: ldap_err2string(ldapReturnCode)))") + OpenLdap.logger().info("ldap_result failed: \(String(cString: ldap_err2string(ldapReturnCode)))") return (addressees: result, totalAddressees: totalAddressees) } } @@ -278,7 +278,7 @@ final public class OpenLdap: OpenLdapProtocol, Loggable { } if let namePointer = ldap_get_dn(ldap, currentMessage) { - OpenLdap.logger().debug("Result (\(result.count)) \(String(cString: namePointer))") + OpenLdap.logger().info("Result (\(result.count)) \(String(cString: namePointer))") ldap_memfree(namePointer) } } diff --git a/Modules/IdCardLib/Sources/IdCardLib/CardActions/CardReaderNFC.swift b/Modules/IdCardLib/Sources/IdCardLib/CardActions/CardReaderNFC.swift index 2291e7f5..b3ffae39 100644 --- a/Modules/IdCardLib/Sources/IdCardLib/CardActions/CardReaderNFC.swift +++ b/Modules/IdCardLib/Sources/IdCardLib/CardActions/CardReaderNFC.swift @@ -72,9 +72,9 @@ class CardReaderNFC: CardReader, Loggable { init(_ tag: NFCISO7816Tag, CAN: String) async throws { self.tag = tag - CardReaderNFC.logger().debug("Select CardAccess") + CardReaderNFC.logger().info("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().info("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)? @@ -102,9 +102,9 @@ class CardReaderNFC: CardReader, Loggable { // Step1 - General Authentication let nonceEnc = try await tag.sendPaceCommand(records: [], tagExpected: 0x80) - CardReaderNFC.logger().debug("Challenge \(nonceEnc.value.toHex)") + CardReaderNFC.logger().info("Challenge \(nonceEnc.value.toHex)") let nonce = try CardReaderNFC.decryptNonce(CAN: CAN, encryptedNonce: nonceEnc.value) - CardReaderNFC.logger().debug("Nonce \(nonce.toHex)") + CardReaderNFC.logger().info("Nonce \(nonce.toHex)") // Step2 let (terminalPubKey, terminalPrivKey) = domain.makeKeyPair() @@ -115,7 +115,7 @@ class CardReaderNFC: CardReader, Loggable { )], tagExpected: 0x82 ) - CardReaderNFC.logger().debug("Mapping key \(mappingKey.value.toHex)") + CardReaderNFC.logger().info("Mapping key \(mappingKey.value.toHex)") guard let cardPubKey = try ECPublicKey(domain: domain, point: mappingKey.value) else { throw IdCardInternalError.authenticationFailed } @@ -123,17 +123,17 @@ class CardReaderNFC: CardReader, Loggable { 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().info("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().info("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().info("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", @@ -153,17 +153,17 @@ class CardReaderNFC: CardReader, Loggable { )], tagExpected: 0x84 ) - CardReaderNFC.logger().debug("Card Ephermal key \(ephemeralKey.value.toHex)") + CardReaderNFC.logger().info("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().info("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().info("KS.Enc \(self.ksEnc.toHex)") + CardReaderNFC.logger().info("KS.Mac \(self.ksMac.toHex)") // Mutual authentication let macCalc = try AES.CMAC(key: ksMac) @@ -183,7 +183,7 @@ class CardReaderNFC: CardReader, Loggable { )], tagExpected: 0x86 ) - CardReaderNFC.logger().debug("Mac response \(macValue.data.toHex)") + CardReaderNFC.logger().info("Mac response \(macValue.data.toHex)") // verify chip's MAC let macResult = TLV(tag: 0x7f49, records: [ @@ -229,14 +229,14 @@ class CardReaderNFC: CardReader, Loggable { case 0x87: tlvEnc = tlv case 0x99: tlvRes = tlv case 0x8E: tlvMac = tlv - default: CardReaderNFC.logger().debug("Unknown tag") + default: CardReaderNFC.logger().info("Unknown tag") } } return (tlvEnc, tlvRes, tlvMac) } func transmit(_ apduData: Bytes) async throws -> (responseData: Bytes, sw: UInt16) { - CardReaderNFC.logger().debug("Plain >: \(apduData.toHex)") + CardReaderNFC.logger().info("Plain >: \(apduData.toHex)") guard let apdu = NFCISO7816APDU(data: Data(apduData)) else { throw IdCardInternalError.invalidAPDU } @@ -269,12 +269,12 @@ class CardReaderNFC: CardReader, Loggable { throw IdCardInternalError.invalidMACValue } guard let tlvEnc else { - CardReaderNFC.logger().debug("Plain <: \(tlvRes.value.toHex)") + CardReaderNFC.logger().info("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().info("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 4890b361..5dfbebdc 100644 --- a/Modules/IdCardLib/Sources/IdCardLib/CardActions/CardReaderiR301.swift +++ b/Modules/IdCardLib/Sources/IdCardLib/CardActions/CardReaderiR301.swift @@ -47,7 +47,7 @@ class CardReaderiR301: CardReader, Loggable { return Int(modelNameLength) } - CardReaderiR301.logger().debug("ID-CARD: Checking if card reader is supported: \(modelName)") + CardReaderiR301.logger().info("ID-CARD: Checking if card reader is supported: \(modelName)") guard modelName.hasPrefix("iR301") else { CardReaderiR301.logger().error("ID-CARD: Unsupported reader: \(modelName)") return nil @@ -94,7 +94,7 @@ class CardReaderiR301: CardReader, Loggable { } initializedCount = Int(atrSize) } - CardReaderiR301.logger().debug("SCardStatus status: \(dwStatus) ATR: \(self.atr.hex))") + CardReaderiR301.logger().info("SCardStatus status: \(dwStatus) ATR: \(self.atr.hex))") guard dwStatus == SCARD_PRESENT else { CardReaderiR301.logger().error("ID-CARD: Did not successfully power on card") @@ -103,7 +103,7 @@ class CardReaderiR301: CardReader, Loggable { } func transmit(_ apdu: Bytes) async throws -> (responseData: Bytes, sw: UInt16) { - CardReaderiR301.logger().debug("ID-CARD Transmitting: \(apdu.hex)") + CardReaderiR301.logger().info("ID-CARD Transmitting: \(apdu.hex)") var responseSize: DWORD = 512 var response = try Bytes(unsafeUninitializedCapacity: Int(responseSize)) { buffer, initializedCount in guard SCardTransmit( @@ -126,7 +126,7 @@ class CardReaderiR301: CardReader, Loggable { "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().info("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/Operations/UsbReaderConnection.swift b/Modules/IdCardLib/Sources/IdCardLib/Operations/UsbReaderConnection.swift index a9268d64..a21581a3 100644 --- a/Modules/IdCardLib/Sources/IdCardLib/Operations/UsbReaderConnection.swift +++ b/Modules/IdCardLib/Sources/IdCardLib/Operations/UsbReaderConnection.swift @@ -51,19 +51,19 @@ public class UsbReaderConnection: Loggable { UsbReaderConnection.logger().error("ID-CARD: Reader discovery is already running") return } - UsbReaderConnection.logger().debug("ID-CARD: Starting reader discovery") + UsbReaderConnection.logger().info("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().info("ID-CARD: Started reader discovery: \(self.handle)") } public func stopDiscoveringReaders(with status: UsbReaderStatus = .sInitial) { - UsbReaderConnection.logger().debug("ID-CARD: Stopping reader discovery") + UsbReaderConnection.logger().info("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().info("ID-CARD: Stopped reader discovery with status: \(self.handle)") handle = 0 } @@ -85,12 +85,12 @@ private class UsbReaderInterfaceHandler: NSObject, @MainActor ReaderInterfaceDel } func readerInterfaceDidChange(_ attached: Bool, bluetoothID _: String?) { - UsbReaderInterfaceHandler.logger().debug("ID-CARD attached: \(attached)") + UsbReaderInterfaceHandler.logger().info("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().info("ID-CARD: Card (interface) attached: \(attached)") do { guard attached, let reader = try CardReaderiR301(contextHandle: UsbReaderConnection.shared.handle) else { return UsbReaderConnection.shared.updateStatus(.sReaderConnected) @@ -100,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().info("ID-CARD: Unable to power on card") UsbReaderConnection.shared.updateStatus(.sReaderProcessFailed) } } @@ -110,6 +110,6 @@ private class UsbReaderInterfaceHandler: NSObject, @MainActor ReaderInterfaceDel } func findPeripheralReader(_ readerName: String) { - UsbReaderInterfaceHandler.logger().debug("ID-CARD: Reader name: \(readerName)") + UsbReaderInterfaceHandler.logger().info("ID-CARD: Reader name: \(readerName)") } } diff --git a/Modules/LibdigidocLib/Sources/LibdigidocSwift/Domain/Container/ContainerWrapper.swift b/Modules/LibdigidocLib/Sources/LibdigidocSwift/Domain/Container/ContainerWrapper.swift index 821d0b6c..0f934339 100644 --- a/Modules/LibdigidocLib/Sources/LibdigidocSwift/Domain/Container/ContainerWrapper.swift +++ b/Modules/LibdigidocLib/Sources/LibdigidocSwift/Domain/Container/ContainerWrapper.swift @@ -84,7 +84,7 @@ public actor ContainerWrapper: ContainerWrapperProtocol, Loggable { saveDataFile: dataFile.fileId, to: tempSavedFileLocation.resolvedPath ) - ContainerWrapper.logger().debug("Successfully saved \(sanitizedFilename) to 'Saved Files' directory") + ContainerWrapper.logger().info("Successfully saved \(sanitizedFilename) to 'Saved Files' directory") return tempSavedFileLocation } catch { let nsError = (error as NSError?) ?? NSError(domain: "ContainerWrapper - cannot save data file", code: 2) @@ -108,7 +108,7 @@ public actor ContainerWrapper: ContainerWrapperProtocol, Loggable { @MainActor public func open(containerFile: URL, isSivaConfirmed: Bool) async throws -> ContainerWrapper { - ContainerWrapper.logger().debug("Opening container file '\(containerFile.lastPathComponent)'") + ContainerWrapper.logger().info("Opening container file '\(containerFile.lastPathComponent)'") do { let container = try DigiDocContainerWrapper.open( diff --git a/Modules/LibdigidocLib/Sources/LibdigidocSwift/SignedContainer.swift b/Modules/LibdigidocLib/Sources/LibdigidocSwift/SignedContainer.swift index 9d747d4c..b2a87fa8 100644 --- a/Modules/LibdigidocLib/Sources/LibdigidocSwift/SignedContainer.swift +++ b/Modules/LibdigidocLib/Sources/LibdigidocSwift/SignedContainer.swift @@ -309,7 +309,7 @@ extension SignedContainer { containerUtil: ContainerUtilProtocol = Container.shared.containerUtil(), isSivaConfirmed: Bool ) async throws -> SignedContainerProtocol { - logger().debug("Opening or creating container. Found \(dataFiles.count) datafile(s)") + logger().info("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") throw DigiDocError.containerCreationFailed( @@ -349,11 +349,11 @@ extension SignedContainer { } if dataFiles.count == 1 && isFirstDataFileContainer { - SignedContainer.logger().debug("Opening existing container") + SignedContainer.logger().info("Opening existing container") return try await open(file: containerFile, isSivaConfirmed: isSivaConfirmed) } - SignedContainer.logger().debug("Creating a new container") + SignedContainer.logger().info("Creating a new container") return try await create(containerFile: containerFile, dataFiles: dataFiles) } @@ -433,20 +433,20 @@ extension SignedContainer { containerUtil: Container.shared.containerUtil() ) - SignedContainer.logger().debug("Container created. Removing \(dataFiles.count) saved data files") + SignedContainer.logger().info("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().info( "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().info("Data file: '\(dataFile.lastPathComponent)' removed") } } diff --git a/Modules/UtilsLib/Sources/UtilsLib/Container/ContainerUtil.swift b/Modules/UtilsLib/Sources/UtilsLib/Container/ContainerUtil.swift index 4216b92b..5d0751cf 100644 --- a/Modules/UtilsLib/Sources/UtilsLib/Container/ContainerUtil.swift +++ b/Modules/UtilsLib/Sources/UtilsLib/Container/ContainerUtil.swift @@ -62,7 +62,7 @@ public struct ContainerUtil: ContainerUtilProtocol, Loggable { do { try fileManager .createDirectory(at: signedContainersDirectory, withIntermediateDirectories: true, attributes: [:]) - ContainerUtil.logger().debug( + ContainerUtil.logger().info( "Directories created or already exist for \(signedContainersDirectory.resolvedPath)" ) } catch { @@ -118,7 +118,7 @@ public struct ContainerUtil: ContainerUtilProtocol, Loggable { attributes: [:] ) if let base = directory { - ContainerUtil.logger().debug("Directories created or already exist for \(base.resolvedPath)") + ContainerUtil.logger().info("Directories created or already exist for \(base.resolvedPath)") } } catch { ContainerUtil.logger().error("Failed to create directory: \(error.localizedDescription)") diff --git a/Modules/UtilsLib/Sources/UtilsLib/File/FileUtil.swift b/Modules/UtilsLib/Sources/UtilsLib/File/FileUtil.swift index f89e8dae..8e569315 100644 --- a/Modules/UtilsLib/Sources/UtilsLib/File/FileUtil.swift +++ b/Modules/UtilsLib/Sources/UtilsLib/File/FileUtil.swift @@ -64,7 +64,7 @@ public struct FileUtil: FileUtilProtocol, Loggable { // 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().info("Getting valid path for file: \(url)") let resolvedURL = url.resolvingSymlinksInPath() let filePath = FilePath(resolvedURL.resolvedPath).lexicallyNormalized() @@ -96,7 +96,7 @@ public struct FileUtil: FileUtilProtocol, Loggable { .lexicallyNormalized() if filePath.starts(with: appContainerPath) { - FileUtil.logger().debug("Resolved valid file path: \(resolvedURL)") + FileUtil.logger().info("Resolved valid file path: \(resolvedURL)") return resolvedURL } } @@ -104,39 +104,39 @@ public struct FileUtil: FileUtilProtocol, Loggable { // 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().info("File is from app group: \(fileUrl)") return fileUrl } if isFileInsideMailFolder(resolvedURL) { - FileUtil.logger().debug("File is from Mail app") + FileUtil.logger().info("File is from Mail app") return resolvedURL } else { - FileUtil.logger().debug("Checking if file is from iCloud") + FileUtil.logger().info("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().info( "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().info("File '\(resolvedURL.lastPathComponent)' downloaded from iCloud") return fileUrl } else { - FileUtil.logger().debug( + FileUtil.logger().info( "Unable to download file '\(resolvedURL.lastPathComponent)' from iCloud") return nil } } else { - FileUtil.logger().debug("File '\(resolvedURL.lastPathComponent)' from iCloud is already downloaded") + FileUtil.logger().info("File '\(resolvedURL.lastPathComponent)' from iCloud is already downloaded") return url } } } - FileUtil.logger().debug("File is NOT from iCloud") + FileUtil.logger().info("File is NOT from iCloud") return nil } @@ -162,7 +162,7 @@ public struct FileUtil: FileUtilProtocol, Loggable { ) if isFromAppGroup { - FileUtil.logger().debug("File is from app group: \(normalizedURL)") + FileUtil.logger().info("File is from app group: \(normalizedURL)") return normalizedURL } @@ -190,7 +190,7 @@ public struct FileUtil: FileUtilProtocol, Loggable { let values = try fileURL.resourceValues(forKeys: [.ubiquitousItemDownloadingStatusKey]) if let downloadingStatus = values.ubiquitousItemDownloadingStatus, downloadingStatus == .current { - FileUtil.logger().debug("File downloaded from iCloud") + FileUtil.logger().info("File downloaded from iCloud") return true } } catch { @@ -208,13 +208,13 @@ public struct FileUtil: FileUtilProtocol, Loggable { public func downloadFileFromiCloud(fileURL: URL) async -> URL? { do { try fileManager.startDownloadingUbiquitousItem(at: fileURL) - FileUtil.logger().debug("Downloading file '\(fileURL.lastPathComponent)' from iCloud") + FileUtil.logger().info("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().info("iCloud file '\(fileURL.lastPathComponent)' downloaded") return fileURL } catch { FileUtil.logger().error( @@ -229,7 +229,7 @@ public struct FileUtil: FileUtilProtocol, Loggable { let filePath = FilePath(stringLiteral: url.resolvedPath).lexicallyNormalized() if filePath == mailFolderPath { - FileUtil.logger().debug("File '\(url.lastPathComponent)' is from Mail app") + FileUtil.logger().info("File '\(url.lastPathComponent)' is from Mail app") return true } @@ -238,18 +238,18 @@ public struct FileUtil: FileUtilProtocol, Loggable { let filePathString = filePath.string if filePathString.count == mailPathString.count { - FileUtil.logger().debug("File '\(url.lastPathComponent)' is from Mail app") + FileUtil.logger().info("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().info("File '\(url.lastPathComponent)' is from Mail app") return true } } - FileUtil.logger().debug("File '\(url.lastPathComponent)' is NOT from Mail app") + FileUtil.logger().info("File '\(url.lastPathComponent)' is NOT from Mail app") return false } @@ -268,7 +268,7 @@ public struct FileUtil: FileUtilProtocol, Loggable { } public func removeSharedFiles(url: URL?) throws { - FileUtil.logger().debug("Removing shared files") + FileUtil.logger().info("Removing shared files") let sharedFilesFolder = try url ?? Directories.getSharedFolder(fileManager: fileManager) @@ -278,7 +278,7 @@ public struct FileUtil: FileUtilProtocol, Loggable { try fileManager.removeItem(at: fileURL) } - FileUtil.logger().debug("Shared files removed") + FileUtil.logger().info("Shared files removed") } public func removeSavedFilesDirectory(savedFilesDirectory: URL? = nil) { @@ -321,10 +321,10 @@ public struct FileUtil: FileUtilProtocol, Loggable { private func removeDirectory(at url: URL) { let filePath = url.path(percentEncoded: false) - FileUtil.logger().debug("Removing \(filePath)") + FileUtil.logger().info("Removing \(filePath)") do { try fileManager.removeItem(at: url) - FileUtil.logger().debug("\(filePath) removed") + FileUtil.logger().info("\(filePath) removed") } catch { FileUtil.logger().error("Unable to remove \(filePath): \(error.localizedDescription)") } diff --git a/Modules/UtilsLib/Sources/UtilsLib/Notification/NotificationUtil.swift b/Modules/UtilsLib/Sources/UtilsLib/Notification/NotificationUtil.swift index 2e525db9..033b0fa3 100644 --- a/Modules/UtilsLib/Sources/UtilsLib/Notification/NotificationUtil.swift +++ b/Modules/UtilsLib/Sources/UtilsLib/Notification/NotificationUtil.swift @@ -29,14 +29,14 @@ public final class NotificationUtil: NSObject, NotificationUtilProtocol, Loggabl } public func requestAuthorization() async -> Bool { - NotificationUtil.logger().debug("Requesting authorization to send notifications") + NotificationUtil.logger().info("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().info("Notification sending authorized: \(granted)") return granted } catch { - NotificationUtil.logger().debug("Unable to request authorization to send notifications. \(error)") + NotificationUtil.logger().info("Unable to request authorization to send notifications. \(error)") return false } } @@ -45,7 +45,7 @@ public final class NotificationUtil: NSObject, NotificationUtilProtocol, Loggabl title: String, body: String ) async throws -> String { - NotificationUtil.logger().debug("Sending notification (\(title))") + NotificationUtil.logger().info("Sending notification (\(title))") let notificationId = UUID().uuidString let content = UNMutableNotificationContent() @@ -57,17 +57,17 @@ public final class NotificationUtil: NSObject, NotificationUtilProtocol, Loggabl try await UNUserNotificationCenter.current().add(request) - NotificationUtil.logger().debug("Notification sent. ID: \(notificationId)") + NotificationUtil.logger().info("Notification sent. ID: \(notificationId)") return notificationId } public func removeNotification(id: String) { - NotificationUtil.logger().debug("Removing notification (\(id))") + NotificationUtil.logger().info("Removing notification (\(id))") let center = UNUserNotificationCenter.current() center.removePendingNotificationRequests(withIdentifiers: [id]) center.removeDeliveredNotifications(withIdentifiers: [id]) - NotificationUtil.logger().debug("Removed notification \(id)") + NotificationUtil.logger().info("Removed notification \(id)") } } diff --git a/Modules/UtilsLib/Sources/UtilsLib/Validator/PersonalCodeValidator.swift b/Modules/UtilsLib/Sources/UtilsLib/Validator/PersonalCodeValidator.swift index c076144f..cf7ae617 100644 --- a/Modules/UtilsLib/Sources/UtilsLib/Validator/PersonalCodeValidator.swift +++ b/Modules/UtilsLib/Sources/UtilsLib/Validator/PersonalCodeValidator.swift @@ -38,7 +38,7 @@ public struct PersonalCodeValidator: Loggable { guard !personalCode.isEmpty, personalCode.count == Constants.Validation.MaximumLatvianPersonalCodeLength else { - PersonalCodeValidator.logger().debug("Personal code is NOT Latvian") + PersonalCodeValidator.logger().info("Personal code is NOT Latvian") return false } diff --git a/Modules/UtilsLib/Sources/UtilsLib/Validator/PhoneNumberValidator.swift b/Modules/UtilsLib/Sources/UtilsLib/Validator/PhoneNumberValidator.swift index 77338a3d..fb3d15f6 100644 --- a/Modules/UtilsLib/Sources/UtilsLib/Validator/PhoneNumberValidator.swift +++ b/Modules/UtilsLib/Sources/UtilsLib/Validator/PhoneNumberValidator.swift @@ -27,22 +27,22 @@ public struct PhoneNumberValidator: Loggable { 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().info("Phone number country code is correct") return true } - PhoneNumberValidator.logger().debug("Phone number country code is NOT correct") + PhoneNumberValidator.logger().info("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().info("Is phone number correct: \(isCorrect)") return isCorrect } } diff --git a/RIADigiDoc/LibrarySetup.swift b/RIADigiDoc/LibrarySetup.swift index 2e1201fe..a55675c6 100644 --- a/RIADigiDoc/LibrarySetup.swift +++ b/RIADigiDoc/LibrarySetup.swift @@ -93,7 +93,7 @@ actor LibrarySetup: Loggable { LibrarySetup.logger().error("Unable to initialize configuration: \(error)") } - LibrarySetup.logger().debug("Initializing Libdigidocpp") + LibrarySetup.logger().info("Initializing Libdigidocpp") try await DigiDocConf.initDigiDoc( isLoggingEnabled: isLoggingEnabled, tsaOption: getTSAOption(), @@ -171,16 +171,17 @@ actor LibrarySetup: Loggable { private func initializeLogging() async -> Bool { #if DEBUG || ENABLE_LOGGING let isLoggingEnabled = true + await dataStore.setEnableLoggingNextSession(true) #else let isLoggingEnabled = await dataStore.getEnableLoggingNextSession() if !isLoggingEnabled { fileUtil.removeCacheLogsDirectory() fileUtil.removeLibraryLogsDirectory(directory: nil) } + await dataStore.setEnableLoggingNextSession(false) #endif Container.shared.isLoggingEnabled.register { isLoggingEnabled } - await dataStore.setEnableLoggingNextSession(false) await dataStore.setEnableLoggingThisSession(isLoggingEnabled) return isLoggingEnabled diff --git a/RIADigiDoc/ViewModel/ContentViewModel.swift b/RIADigiDoc/ViewModel/ContentViewModel.swift index b9e064ea..2e508f2f 100644 --- a/RIADigiDoc/ViewModel/ContentViewModel.swift +++ b/RIADigiDoc/ViewModel/ContentViewModel.swift @@ -38,7 +38,7 @@ class ContentViewModel: ContentViewModelProtocol, Loggable { func getSharedFiles() async -> [URL] { do { - ContentViewModel.logger().debug("Checking for shared files...") + ContentViewModel.logger().info("Checking for shared files...") let sharedFolderURL = try await Directories.getSharedFolder(fileManager: fileManager) .validURL(fileUtil: fileUtil) @@ -48,9 +48,9 @@ class ContentViewModel: ContentViewModelProtocol, Loggable { options: .skipsHiddenFiles) if contents.isEmpty { - ContentViewModel.logger().debug("Shared files folder is empty") + ContentViewModel.logger().info("Shared files folder is empty") } else { - ContentViewModel.logger().debug("Found \(contents.count) shared files") + ContentViewModel.logger().info("Found \(contents.count) shared files") } return contents diff --git a/RIADigiDoc/ViewModel/CryptoFileOpeningViewModel.swift b/RIADigiDoc/ViewModel/CryptoFileOpeningViewModel.swift index feb8ccb4..8de369dd 100644 --- a/RIADigiDoc/ViewModel/CryptoFileOpeningViewModel.swift +++ b/RIADigiDoc/ViewModel/CryptoFileOpeningViewModel.swift @@ -60,17 +60,17 @@ class CryptoFileOpeningViewModel: CryptoFileOpeningViewModelProtocol, Loggable { func handleFiles() async { do { - CryptoFileOpeningViewModel.logger().debug("Handling chosen files from file system or from external sources") + CryptoFileOpeningViewModel.logger().info("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().info("Found \(validFiles.count) valid file(s)") if validFiles.isEmpty { - CryptoFileOpeningViewModel.logger().debug("No valid files found") + CryptoFileOpeningViewModel.logger().info("No valid files found") throw FileOpeningError.noDataFiles } diff --git a/RIADigiDoc/ViewModel/DataFilesViewModel.swift b/RIADigiDoc/ViewModel/DataFilesViewModel.swift index d104b96b..f73f2e3a 100644 --- a/RIADigiDoc/ViewModel/DataFilesViewModel.swift +++ b/RIADigiDoc/ViewModel/DataFilesViewModel.swift @@ -62,7 +62,7 @@ class DataFilesViewModel: DataFilesViewModelProtocol, Loggable { fileManager: fileManager ) try fileManager.removeItem(at: directory) - DataFilesViewModel.logger().debug("Saved Files directory removed") + DataFilesViewModel.logger().info("Saved Files directory removed") } catch { DataFilesViewModel.logger().error("Unable to delete saved files directory: \(error.localizedDescription)") } diff --git a/RIADigiDoc/ViewModel/DiagnosticsViewModel.swift b/RIADigiDoc/ViewModel/DiagnosticsViewModel.swift index 07dba86c..c6285911 100644 --- a/RIADigiDoc/ViewModel/DiagnosticsViewModel.swift +++ b/RIADigiDoc/ViewModel/DiagnosticsViewModel.swift @@ -379,7 +379,7 @@ class DiagnosticsViewModel: DiagnosticsViewModelProtocol, Loggable { lines.append(""" \(entry.date) \ [\(log.subsystem):\(log.category)] - \ - \(entry.composedMessage)\n + \(entry.composedMessage) """) } else { lines.append("\(entry.date): \(entry.composedMessage)\n") diff --git a/RIADigiDoc/ViewModel/EncryptViewModel.swift b/RIADigiDoc/ViewModel/EncryptViewModel.swift index 0526cb79..52a595d1 100644 --- a/RIADigiDoc/ViewModel/EncryptViewModel.swift +++ b/RIADigiDoc/ViewModel/EncryptViewModel.swift @@ -84,7 +84,7 @@ class EncryptViewModel: EncryptViewModelProtocol, Loggable { } func loadContainerData(cryptoContainer: CryptoContainerProtocol?) async { - EncryptViewModel.logger().debug("Loading container data") + EncryptViewModel.logger().info("Loading container data") let openedContainer = (cryptoContainer ?? sharedContainerViewModel.currentContainer()) as? any CryptoContainerProtocol guard let openedContainer else { @@ -100,7 +100,7 @@ class EncryptViewModel: EncryptViewModelProtocol, Loggable { self.containerMimetype = await openedContainer.getContainerMimetype() self.containerURL = await openedContainer.getRawContainerFile() - EncryptViewModel.logger().debug("Container data loaded") + EncryptViewModel.logger().info("Container data loaded") } func createCopyOfContainerForSaving(containerURL: URL?) -> URL? { @@ -157,7 +157,7 @@ class EncryptViewModel: EncryptViewModelProtocol, Loggable { } await cryptoContainer?.addDataFiles(files) - EncryptViewModel.logger().debug("Added data files to container") + EncryptViewModel.logger().info("Added data files to container") errorMessage = ErrorMessage( key: files.count == 1 ? "File successfully added" : "Files successfully added", args: [] diff --git a/RIADigiDoc/ViewModel/FileOpeningViewModel.swift b/RIADigiDoc/ViewModel/FileOpeningViewModel.swift index 569ed1de..b4bfbf60 100644 --- a/RIADigiDoc/ViewModel/FileOpeningViewModel.swift +++ b/RIADigiDoc/ViewModel/FileOpeningViewModel.swift @@ -61,17 +61,17 @@ class FileOpeningViewModel: FileOpeningViewModelProtocol, Loggable { func handleFiles() async { do { - FileOpeningViewModel.logger().debug("Handling chosen files from file system or from external sources") + FileOpeningViewModel.logger().info("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().info("Found \(validFiles.count) valid file(s)") if validFiles.isEmpty { - FileOpeningViewModel.logger().debug("No valid files found") + FileOpeningViewModel.logger().info("No valid files found") throw FileOpeningError.noDataFiles } @@ -118,7 +118,7 @@ class FileOpeningViewModel: FileOpeningViewModelProtocol, Loggable { let container = try await fileOpeningRepository .openOrCreateContainer(urls: files, isSivaConfirmed: false) sharedContainerViewModel.setSignedContainer(container) - FileOpeningViewModel.logger().debug("Asics signed container set successfully") + FileOpeningViewModel.logger().info("Asics signed container set successfully") handleLoadingSuccess(isSivaConfirmed: false) } catch { FileOpeningViewModel.logger().error("Unable to handle SiVa container. \(error)") diff --git a/RIADigiDoc/ViewModel/Signing/MobileId/MobileIdViewModel.swift b/RIADigiDoc/ViewModel/Signing/MobileId/MobileIdViewModel.swift index a70f26f1..d5a1389f 100644 --- a/RIADigiDoc/ViewModel/Signing/MobileId/MobileIdViewModel.swift +++ b/RIADigiDoc/ViewModel/Signing/MobileId/MobileIdViewModel.swift @@ -109,7 +109,7 @@ class MobileIdViewModel: MobileIdViewModelProtocol, Loggable { roleData: RoleData, signedContainer: SignedContainerProtocol ) async -> SignedContainerProtocol? { - MobileIdViewModel.logger().debug("Mobile-ID: Signing with Mobile-ID") + MobileIdViewModel.logger().info("Mobile-ID: Signing with Mobile-ID") let currentConfiguration = await configurationRepository.getConfiguration() guard let configuration = currentConfiguration else { @@ -135,7 +135,7 @@ class MobileIdViewModel: MobileIdViewModelProtocol, Loggable { do { containerFile = try await getContainerFile(signedContainer: signedContainer) } catch { - MobileIdViewModel.logger().debug("Mobile-ID: Unable to get container file from container") + MobileIdViewModel.logger().info("Mobile-ID: Unable to get container file from container") handleSigningError(error) return nil } @@ -150,7 +150,7 @@ class MobileIdViewModel: MobileIdViewModelProtocol, Loggable { proxyInfo: proxyInfo ) } catch { - MobileIdViewModel.logger().debug("Mobile-ID: Unable to request certificate or get cert from response") + MobileIdViewModel.logger().info("Mobile-ID: Unable to request certificate or get cert from response") handleSigningError(error) return nil } @@ -164,7 +164,7 @@ class MobileIdViewModel: MobileIdViewModelProtocol, Loggable { signedContainer: signedContainer ) } catch { - MobileIdViewModel.logger().debug("Mobile-ID: Unable to prepare signature for signing") + MobileIdViewModel.logger().info("Mobile-ID: Unable to prepare signature for signing") handleSigningError(error) return nil } @@ -173,14 +173,14 @@ class MobileIdViewModel: MobileIdViewModelProtocol, Loggable { do { verificationCode = try await getVerificationCode(hash: hash) } catch { - MobileIdViewModel.logger().debug("Mobile-ID: Unable to get verification code (control code)") + MobileIdViewModel.logger().info("Mobile-ID: Unable to get verification code (control code)") handleSigningError(error) return nil } controlCode = verificationCode - MobileIdViewModel.logger().debug("Mobile-ID: Getting language") + MobileIdViewModel.logger().info("Mobile-ID: Getting language") let language = await dataStore.getSelectedLanguage() let sessionId: String @@ -195,7 +195,7 @@ class MobileIdViewModel: MobileIdViewModelProtocol, Loggable { proxyInfo: proxyInfo ) } catch { - MobileIdViewModel.logger().debug("Mobile-ID: Unable to request signature") + MobileIdViewModel.logger().info("Mobile-ID: Unable to request signature") handleSigningError(error) return nil } @@ -209,7 +209,7 @@ class MobileIdViewModel: MobileIdViewModelProtocol, Loggable { proxyInfo: proxyInfo ) } catch { - MobileIdViewModel.logger().debug( + MobileIdViewModel.logger().info( "Mobile-ID: Unable to request session" ) handleSigningError(error) @@ -224,7 +224,7 @@ class MobileIdViewModel: MobileIdViewModelProtocol, Loggable { containerFile: containerFile ) - MobileIdViewModel.logger().debug("Signature added successfully (Mobile-ID)") + MobileIdViewModel.logger().info("Signature added successfully (Mobile-ID)") mobileIdMessageKey = "Signature added" return updatedContainer } catch { @@ -245,7 +245,7 @@ class MobileIdViewModel: MobileIdViewModelProtocol, Loggable { trustedCertificates: [SecCertificate], proxyInfo: ProxyInfo ) async throws -> Data { - MobileIdViewModel.logger().debug("Mobile-ID: Getting certificate") + MobileIdViewModel.logger().info("Mobile-ID: Getting certificate") let certResponse = try await mobileIdSignService .getCertificateRequest( url: "\(midUrl)\(MobileIdViewModel.certificateEndpoint)", @@ -278,7 +278,7 @@ class MobileIdViewModel: MobileIdViewModelProtocol, Loggable { trustedCertificates: [SecCertificate], proxyInfo: ProxyInfo ) async throws -> String { - MobileIdViewModel.logger().debug("Mobile-ID: Getting signature") + MobileIdViewModel.logger().info("Mobile-ID: Getting signature") let signatureResponse = try await mobileIdSignService.getSignatureRequest( url: "\(midUrl)\(MobileIdViewModel.signatureEndpoint)", relyingPartyName: Constants.Signing.RelyingPartyName, @@ -294,7 +294,7 @@ class MobileIdViewModel: MobileIdViewModelProtocol, Loggable { proxyInfo: proxyInfo ) - MobileIdViewModel.logger().debug("Mobile-ID: Getting sessionID") + MobileIdViewModel.logger().info("Mobile-ID: Getting sessionID") guard let sessionId = signatureResponse.sessionID else { MobileIdViewModel.logger().error("Unable to get Mobile-ID sessionID") mobileIdMessageKey = "Technical error" @@ -310,7 +310,7 @@ class MobileIdViewModel: MobileIdViewModelProtocol, Loggable { trustedCertificates: [SecCertificate], proxyInfo: ProxyInfo ) async throws -> Data { - MobileIdViewModel.logger().debug("Mobile-ID: Getting session request") + MobileIdViewModel.logger().info("Mobile-ID: Getting session request") let sessionResponse = try await mobileIdSignService.getSessionRequest( url: "\(midUrl)\(MobileIdViewModel.signatureSessionEndpoint)", sessionId: sessionId, @@ -332,7 +332,7 @@ class MobileIdViewModel: MobileIdViewModelProtocol, Loggable { roleData: RoleData, signedContainer: SignedContainerProtocol ) async throws -> Data { - MobileIdViewModel.logger().debug( + MobileIdViewModel.logger().info( "Mobile-ID: Preparing signature. Calculating hash" ) @@ -345,7 +345,7 @@ class MobileIdViewModel: MobileIdViewModelProtocol, Loggable { } private func getVerificationCode(hash: Data) async throws -> String { - MobileIdViewModel.logger().debug( + MobileIdViewModel.logger().info( "Mobile-ID: Calculating verification code (control code)" ) guard let verificationCode = await mobileIdSignService.getVerificationCode(hash: hash) else { @@ -374,7 +374,7 @@ class MobileIdViewModel: MobileIdViewModelProtocol, Loggable { } private func getTrustedCertificates(certificates: [Data]) -> [SecCertificate] { - MobileIdViewModel.logger().debug("Mobile-ID: Getting trusted certificates list") + MobileIdViewModel.logger().info("Mobile-ID: Getting trusted certificates list") return certificates.compactMap { certificateUtil.certificate(from: $0) } } @@ -409,7 +409,7 @@ class MobileIdViewModel: MobileIdViewModelProtocol, Loggable { case .explicitlyCancelled: // Do not throw an error if user cancelled signing with back button - MobileIdViewModel.logger().debug("Mobile-ID signing manually cancelled") + MobileIdViewModel.logger().info("Mobile-ID signing manually cancelled") mobileIdMessageKey = nil case .timeout: diff --git a/RIADigiDoc/ViewModel/Signing/SmartId/SmartIdViewModel.swift b/RIADigiDoc/ViewModel/Signing/SmartId/SmartIdViewModel.swift index 7fcf2a4a..c46c92f3 100644 --- a/RIADigiDoc/ViewModel/Signing/SmartId/SmartIdViewModel.swift +++ b/RIADigiDoc/ViewModel/Signing/SmartId/SmartIdViewModel.swift @@ -117,7 +117,7 @@ class SmartIdViewModel: SmartIdViewModelProtocol, Loggable { roleData: RoleData, signedContainer: SignedContainerProtocol ) async -> SignedContainerProtocol? { - SmartIdViewModel.logger().debug("Smart-ID: Signing with Smart-ID") + SmartIdViewModel.logger().info("Smart-ID: Signing with Smart-ID") let currentConfiguration = await configurationRepository.getConfiguration() @@ -144,7 +144,7 @@ class SmartIdViewModel: SmartIdViewModelProtocol, Loggable { do { containerFile = try await getContainerFile(signedContainer: signedContainer) } catch { - SmartIdViewModel.logger().debug("Smart-ID: Unable to get container file from container") + SmartIdViewModel.logger().info("Smart-ID: Unable to get container file from container") handleSigningError(error) return nil } @@ -162,7 +162,7 @@ class SmartIdViewModel: SmartIdViewModelProtocol, Loggable { proxyInfo: proxyInfo ) } catch { - SmartIdViewModel.logger().debug("Smart-ID: Unable to request certificate or get response") + SmartIdViewModel.logger().info("Smart-ID: Unable to request certificate or get response") handleSigningError(error) return nil } @@ -184,7 +184,7 @@ class SmartIdViewModel: SmartIdViewModelProtocol, Loggable { signedContainer: signedContainer ) } catch { - SmartIdViewModel.logger().debug("Smart-ID: Unable to prepare signature for signing") + SmartIdViewModel.logger().info("Smart-ID: Unable to prepare signature for signing") handleSigningError(error) return nil } @@ -193,7 +193,7 @@ class SmartIdViewModel: SmartIdViewModelProtocol, Loggable { do { verificationCode = try await getVerificationCode(hash: hash) } catch { - SmartIdViewModel.logger().debug("Smart-ID: Unable to get verification code (control code)") + SmartIdViewModel.logger().info("Smart-ID: Unable to get verification code (control code)") handleSigningError(error) return nil } @@ -233,7 +233,7 @@ class SmartIdViewModel: SmartIdViewModelProtocol, Loggable { ) } catch { endBackgroundTask() - SmartIdViewModel.logger().debug("Smart-ID: Unable to request signature or get cert from response") + SmartIdViewModel.logger().info("Smart-ID: Unable to request signature or get cert from response") handleSigningError(error) notificationUtil.removeNotification(id: notificationIdentifier) return nil @@ -249,7 +249,7 @@ class SmartIdViewModel: SmartIdViewModelProtocol, Loggable { containerFile: containerFile ) - SmartIdViewModel.logger().debug("Signature added successfully (Smart-ID)") + SmartIdViewModel.logger().info("Signature added successfully (Smart-ID)") smartIdMessageKey = "Signature added" notificationUtil.removeNotification(id: notificationIdentifier) return updatedContainer @@ -293,7 +293,7 @@ class SmartIdViewModel: SmartIdViewModelProtocol, Loggable { trustedCertificates: [SecCertificate], proxyInfo: ProxyInfo ) async throws -> SmartIdSessionResponse { - SmartIdViewModel.logger().debug("Smart-ID: Getting certificate") + SmartIdViewModel.logger().info("Smart-ID: Getting certificate") let certResponse = try await smartIdSignService .getCertificateRequest( url: "\(sidUrl)\(SmartIdViewModel.certificateEndpoint)", @@ -309,7 +309,7 @@ class SmartIdViewModel: SmartIdViewModelProtocol, Loggable { throw SmartIdError.missingSessionId } - SmartIdViewModel.logger().debug("Smart-ID: Requesting session from certificate response") + SmartIdViewModel.logger().info("Smart-ID: Requesting session from certificate response") return try await requestSession( sidUrl: "\(sidUrl)\(SmartIdViewModel.sessionEndpoint)", @@ -332,7 +332,7 @@ class SmartIdViewModel: SmartIdViewModelProtocol, Loggable { trustedCertificates: [SecCertificate], proxyInfo: ProxyInfo ) async throws -> Data { - SmartIdViewModel.logger().debug("Smart-ID: Getting signature") + SmartIdViewModel.logger().info("Smart-ID: Getting signature") let certResponse = try await smartIdSignService .getSignatureRequest( @@ -352,7 +352,7 @@ class SmartIdViewModel: SmartIdViewModelProtocol, Loggable { throw SmartIdError.missingSessionId } - SmartIdViewModel.logger().debug("Smart-ID: Requesting session from signature response") + SmartIdViewModel.logger().info("Smart-ID: Requesting session from signature response") let sessionResponse = try await requestSession( sidUrl: "\(sidUrl)\(SmartIdViewModel.sessionEndpoint)", @@ -389,7 +389,7 @@ class SmartIdViewModel: SmartIdViewModelProtocol, Loggable { trustedCertificates: [SecCertificate], proxyInfo: ProxyInfo ) async throws -> SmartIdSessionResponse { - SmartIdViewModel.logger().debug("Smart-ID: Getting session") + SmartIdViewModel.logger().info("Smart-ID: Getting session") return try await smartIdSignService.getSessionRequest( url: sidUrl, sessionId: sessionId, @@ -404,7 +404,7 @@ class SmartIdViewModel: SmartIdViewModelProtocol, Loggable { } private func getTrustedCertificates(certificates: [Data]) -> [SecCertificate] { - SmartIdViewModel.logger().debug("Smart-ID: Getting trusted certificates list") + SmartIdViewModel.logger().info("Smart-ID: Getting trusted certificates list") return certificates.compactMap { certificateUtil.certificate(from: $0) } } @@ -426,7 +426,7 @@ class SmartIdViewModel: SmartIdViewModelProtocol, Loggable { roleData: RoleData, signedContainer: SignedContainerProtocol ) async throws -> Data { - SmartIdViewModel.logger().debug( + SmartIdViewModel.logger().info( "Smart-ID: Preparing signature. Calculating hash" ) @@ -439,7 +439,7 @@ class SmartIdViewModel: SmartIdViewModelProtocol, Loggable { } private func getVerificationCode(hash: Data) async throws -> String { - SmartIdViewModel.logger().debug( + SmartIdViewModel.logger().info( "Smart-ID: Calculating verification code (control code)" ) return await smartIdSignService.getVerificationCode(digest: sha256(data: hash)) @@ -471,7 +471,7 @@ class SmartIdViewModel: SmartIdViewModelProtocol, Loggable { case .explicitlyCancelled: // Do not throw an error if user cancelled signing with back button - SmartIdViewModel.logger().debug("Smart-ID signing manually cancelled") + SmartIdViewModel.logger().info("Smart-ID signing manually cancelled") smartIdMessageKey = nil case .noInternetConnection, .noResponse: diff --git a/RIADigiDoc/ViewModel/SigningViewModel.swift b/RIADigiDoc/ViewModel/SigningViewModel.swift index c4fead1c..6fb83305 100644 --- a/RIADigiDoc/ViewModel/SigningViewModel.swift +++ b/RIADigiDoc/ViewModel/SigningViewModel.swift @@ -77,7 +77,7 @@ class SigningViewModel: SigningViewModelProtocol, Loggable { } func loadContainerData(signedContainer: SignedContainerProtocol?) async { - SigningViewModel.logger().debug("Loading container data") + SigningViewModel.logger().info("Loading container data") sharedContainerViewModel.setIsSignatureAdded(false) let openedContainer = (signedContainer ?? sharedContainerViewModel.currentContainer()) as? any SignedContainerProtocol @@ -100,7 +100,7 @@ class SigningViewModel: SigningViewModelProtocol, Loggable { self.containerNotifications = await getContainerNotifications(container: openedContainer) - SigningViewModel.logger().debug("Container data loaded") + SigningViewModel.logger().info("Container data loaded") } func getContainerNotifications(container: SignedContainerProtocol) async -> [ContainerNotificationType] { @@ -184,7 +184,7 @@ class SigningViewModel: SigningViewModelProtocol, Loggable { do { let updatedContainer = try await signedContainer?.addDataFiles(files, to: container) - SigningViewModel.logger().debug("Added data files to container") + SigningViewModel.logger().info("Added data files to container") errorMessage = ErrorMessage( key: files.count == 1 ? "File successfully added" : "Files successfully added", args: []