mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-10-06 05:37:47 +00:00
ios: show error when random database passphrase generation fails (#7621)
Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
This commit is contained in:
co-authored by
Evgeny @ SimpleX Chat
parent
86671a1699
commit
905df659d3
@@ -118,6 +118,9 @@ struct DatabaseErrorView: View {
|
||||
case .errorKeychain:
|
||||
titleText("Keychain error")
|
||||
errorView(Text("Cannot access keychain to save database password"))
|
||||
case .errorKeyGeneration:
|
||||
titleText("Database error")
|
||||
errorView(Text("Cannot generate random database passphrase"))
|
||||
case .invalidConfirmation:
|
||||
// this can only happen if incorrect parameter is passed
|
||||
titleText("Invalid migration confirmation")
|
||||
@@ -217,6 +220,8 @@ struct DatabaseErrorView: View {
|
||||
)
|
||||
case .errorKeychain:
|
||||
am.showAlertMsg(title: "Keychain error")
|
||||
case .errorKeyGeneration:
|
||||
am.showAlertMsg(title: "Database error", message: "Cannot generate random database passphrase")
|
||||
case let .errorSQL(_, error):
|
||||
am.showAlert(Alert(
|
||||
title: Text("Database error"),
|
||||
|
||||
@@ -709,6 +709,8 @@ private func showErrorOnMigrationIfNeeded(_ status: DBMigrationResult, _ alert:
|
||||
alert.wrappedValue = .wrongPassphrase()
|
||||
case .errorKeychain:
|
||||
alert.wrappedValue = .keychainError()
|
||||
case .errorKeyGeneration:
|
||||
alert.wrappedValue = .databaseError(message: NSLocalizedString("Cannot generate random database passphrase", comment: "alert message"))
|
||||
case let .errorSQL(_, error):
|
||||
alert.wrappedValue = .databaseError(message: error)
|
||||
case let .unknown(error):
|
||||
|
||||
@@ -539,7 +539,7 @@ struct MigrateToDevice: View {
|
||||
Task {
|
||||
do {
|
||||
if !hasChatCtrl() {
|
||||
chatInitControllerRemovingDatabases()
|
||||
try chatInitControllerRemovingDatabases()
|
||||
} else if ChatModel.shared.chatRunning == true {
|
||||
// cannot delete storage if chat is running
|
||||
try await stopChatAsync()
|
||||
@@ -735,6 +735,8 @@ private func showErrorOnMigrationIfNeeded(_ status: DBMigrationResult, _ alert:
|
||||
alert.wrappedValue = .wrongPassphrase()
|
||||
case .errorKeychain:
|
||||
alert.wrappedValue = .keychainError()
|
||||
case .errorKeyGeneration:
|
||||
alert.wrappedValue = .databaseError(message: NSLocalizedString("Cannot generate random database passphrase", comment: "alert message"))
|
||||
case let .errorSQL(_, error):
|
||||
alert.wrappedValue = .databaseError(message: error)
|
||||
case let .unknown(error):
|
||||
|
||||
@@ -247,6 +247,11 @@ class ShareModel: ObservableObject {
|
||||
title: "Keychain error",
|
||||
message: "Cannot access keychain to save database password"
|
||||
)
|
||||
case .errorKeyGeneration:
|
||||
ErrorAlert(
|
||||
title: "Database error",
|
||||
message: "Cannot generate random database passphrase"
|
||||
)
|
||||
case .invalidConfirmation:
|
||||
ErrorAlert("Invalid migration confirmation")
|
||||
case let .unknown(json):
|
||||
|
||||
@@ -32,7 +32,12 @@ public func chatMigrateInit(_ useKey: String? = nil, confirmMigrations: Migratio
|
||||
} else if useKeychain {
|
||||
if !hasDatabase() {
|
||||
logger.debug("chatMigrateInit generating a random DB key")
|
||||
dbKey = randomDatabasePassword()
|
||||
guard let key = randomDatabasePassword() else {
|
||||
let result = (false, DBMigrationResult.errorKeyGeneration)
|
||||
migrationResult = result
|
||||
return result
|
||||
}
|
||||
dbKey = key
|
||||
initialRandomDBPassphraseGroupDefault.set(true)
|
||||
} else if let key = kcDatabasePassword.get() {
|
||||
dbKey = key
|
||||
@@ -56,7 +61,7 @@ public func chatMigrateInit(_ useKey: String? = nil, confirmMigrations: Migratio
|
||||
|
||||
public func chatInitTemporaryDatabase(url: URL, key: String? = nil, confirmation: MigrationConfirmation = .error) -> (DBMigrationResult, chat_ctrl?) {
|
||||
let dbPath = url.path
|
||||
let dbKey = key ?? randomDatabasePassword()
|
||||
guard let dbKey = key ?? randomDatabasePassword() else { return (.errorKeyGeneration, nil) }
|
||||
logger.debug("chatInitTemporaryDatabase path: \(dbPath)")
|
||||
var temporaryController: chat_ctrl? = nil
|
||||
var cPath = dbPath.cString(using: .utf8)!
|
||||
@@ -66,14 +71,14 @@ public func chatInitTemporaryDatabase(url: URL, key: String? = nil, confirmation
|
||||
return (dbMigrationResult(dataFromCString(cjson)), temporaryController)
|
||||
}
|
||||
|
||||
public func chatInitControllerRemovingDatabases() {
|
||||
public func chatInitControllerRemovingDatabases() throws {
|
||||
let dbPath = getAppDatabasePath().path
|
||||
let fm = FileManager.default
|
||||
// Remove previous databases, otherwise, can be .errorNotADatabase with nil controller
|
||||
try? fm.removeItem(atPath: dbPath + CHAT_DB)
|
||||
try? fm.removeItem(atPath: dbPath + AGENT_DB)
|
||||
|
||||
let dbKey = randomDatabasePassword()
|
||||
guard let dbKey = randomDatabasePassword() else { throw RuntimeError("Cannot generate random database passphrase") }
|
||||
logger.debug("chatInitControllerRemovingDatabases path: \(dbPath)")
|
||||
var cPath = dbPath.cString(using: .utf8)!
|
||||
var cKey = dbKey.cString(using: .utf8)!
|
||||
@@ -353,6 +358,7 @@ public enum DBMigrationResult: Decodable, Equatable {
|
||||
case errorMigration(dbFile: String, migrationError: MigrationError)
|
||||
case errorSQL(dbFile: String, migrationSQLError: String)
|
||||
case errorKeychain
|
||||
case errorKeyGeneration
|
||||
case unknown(json: String)
|
||||
}
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ public struct KeyChainItem {
|
||||
}
|
||||
}
|
||||
|
||||
func randomDatabasePassword() -> String {
|
||||
func randomDatabasePassword() -> String? {
|
||||
var keyData = Data(count: 32)
|
||||
let status = keyData.withUnsafeMutableBytes {
|
||||
SecRandomCopyBytes(kSecRandomDefault, 32, $0.baseAddress!)
|
||||
@@ -46,7 +46,7 @@ func randomDatabasePassword() -> String {
|
||||
return keyData.base64EncodedString()
|
||||
} else {
|
||||
logger.error("randomDatabasePassword: error \(status)")
|
||||
return ""
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -138,7 +138,7 @@ public func createErrorNtf(_ dbStatus: DBMigrationResult, _ badgeCount: Int) ->
|
||||
title = NSLocalizedString("Encrypted message: no passphrase", comment: "notification")
|
||||
case .errorMigration:
|
||||
title = NSLocalizedString("Encrypted message: database migration error", comment: "notification")
|
||||
case .errorSQL:
|
||||
case .errorSQL, .errorKeyGeneration:
|
||||
title = NSLocalizedString("Encrypted message: database error", comment: "notification")
|
||||
case .errorKeychain:
|
||||
title = NSLocalizedString("Encrypted message: keychain error", comment: "notification")
|
||||
|
||||
@@ -134,6 +134,7 @@ Migration results are decoded in Swift as `DBMigrationResult`:
|
||||
- `.errorMigration(dbFile:, migrationError:)` -- migration failed
|
||||
- `.errorSQL(dbFile:, migrationSQLError:)` -- SQL error during migration
|
||||
- `.errorKeychain` -- keychain access failed
|
||||
- `.errorKeyGeneration` -- random database key generation failed
|
||||
- `.unknown(json:)` -- unrecognized response
|
||||
|
||||
---
|
||||
|
||||
Reference in New Issue
Block a user