46 lines
1.3 KiB
Swift
46 lines
1.3 KiB
Swift
import Foundation
|
|
|
|
enum DatabaseEncryptionKeyError: Error {
|
|
case keyNotAvailable
|
|
}
|
|
|
|
final class DatabaseEncryptionKeyManager {
|
|
static let shared = DatabaseEncryptionKeyManager()
|
|
|
|
private let keychainService: KeychainService
|
|
private let serviceName = "yobble.database.encryption"
|
|
private let accountName = "sqlcipher_key"
|
|
/// Hardcoded dev key used until the user saves their own password-derived key.
|
|
private let fallbackKey: String
|
|
|
|
init(
|
|
keychainService: KeychainService = .shared,
|
|
fallbackKey: String = AppConfig.DEFAULT_DATABASE_ENCRYPTION_KEY
|
|
) {
|
|
self.keychainService = keychainService
|
|
self.fallbackKey = fallbackKey
|
|
}
|
|
|
|
func currentKey() throws -> String {
|
|
if let key = keychainService.get(forKey: accountName, service: serviceName), !key.isEmpty {
|
|
return key
|
|
}
|
|
guard !fallbackKey.isEmpty else {
|
|
throw DatabaseEncryptionKeyError.keyNotAvailable
|
|
}
|
|
return fallbackKey
|
|
}
|
|
|
|
func persistKey(_ key: String) {
|
|
keychainService.save(key, forKey: accountName, service: serviceName)
|
|
}
|
|
|
|
func clearPersistedKey() {
|
|
keychainService.delete(forKey: accountName, service: serviceName)
|
|
}
|
|
|
|
func hasPersistedKey() -> Bool {
|
|
keychainService.get(forKey: accountName, service: serviceName) != nil
|
|
}
|
|
}
|