Files
workavia-mail-front/ios/TwakeMailNSE/Keychain/KeychainController.swift
dab246 330c8cbaf5 TF-4269 Apply PR review: breadcrumbs, log error details, and code cleanup for NSE Sentry integration
- Replace capture(message:) with addBreadcrumb(level: .warning) in NotificationService for non-error diagnostic checkpoints
- Add addBreadcrumb method to SentryManager with category/level support
- Include error details in KeychainController SentryConfig decode failure log
- Split combined guard into two separate guards to distinguish nil state vs unchanged state
- Remove dead do-catch block in onComplete closure; use errors.forEach to capture real errors
- Translate Vietnamese doc comment to English in SentryManager
2026-04-22 09:00:56 +07:00

79 lines
2.8 KiB
Swift

import Foundation
import KeychainAccess
enum KeychainControllerService: String {
case sessions
var identifier: String {
InfoPlistReader.main.baseBundleIdentifier + "." + rawValue
}
}
class KeychainController: KeychainControllerDelegate {
private let keychain: Keychain
init(service: KeychainControllerService,
accessGroup: String) {
keychain = Keychain(service: service.identifier,
accessGroup: accessGroup).accessibility(.afterFirstUnlock)
}
func retrieveSharingSessionFromKeychain(accountId: String) -> KeychainSharingSession? {
do {
guard let sessionData = try keychain.getData(accountId) else {
return nil
}
return try JSONDecoder().decode(KeychainSharingSession.self, from: sessionData)
} catch {
return nil
}
}
func retrieveSharingSessions() -> [KeychainCredentials] {
keychain.allKeys().compactMap { accountId in
guard let sharingSession = retrieveSharingSessionFromKeychain(accountId: accountId) else {
return nil
}
return KeychainCredentials(accountId: accountId, sharingSession: sharingSession)
}
}
func updateEmailDeliveryStateToKeychain(accountId: String, newEmailDeliveryState: String) {
do {
if let sharingSession = retrieveSharingSessionFromKeychain(accountId: accountId),
let newSharingSessionData = sharingSession.updateEmailDeliveryState(newEmailDeliveryState: newEmailDeliveryState).toData() {
try keychain.set(newSharingSessionData, key: accountId)
}
} catch {}
}
func updateTokenOidc(accountId: String, newTokenOidc: TokenOidc) {
do {
if let sharingSession = retrieveSharingSessionFromKeychain(accountId: accountId),
let newSharingSessionData = sharingSession.updateTokenOidc(newTokenOidc: newTokenOidc).toData() {
try keychain.set(newSharingSessionData, key: accountId)
}
} catch {}
}
}
extension KeychainController {
/// The key used in Dart to store the Sentry configuration JSON
private var sentryConfigKey: String { "sentry_config_data" }
/// Retrieves and decodes the SentryConfig from Keychain
func retrieveSentryConfig() -> SentryConfig? {
do {
guard let configData = try keychain.getData(sentryConfigKey) else {
return nil
}
return try JSONDecoder().decode(SentryConfig.self, from: configData)
} catch {
TwakeLogger.shared.log(message: "SentryConfig could not be decoded from Keychain: \(error)")
return nil
}
}
}