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:
Evgeny
2026-10-05 09:46:55 +01:00
committed by GitHub
co-authored by Evgeny @ SimpleX Chat
parent 86671a1699
commit 905df659d3
8 changed files with 29 additions and 8 deletions
@@ -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):
+5
View File
@@ -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):
+10 -4
View File
@@ -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)
}
+2 -2
View File
@@ -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
}
}
+1 -1
View File
@@ -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")
+1
View File
@@ -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
---