ios: NSE without passphrase in keychain (#1030)

This commit is contained in:
Evgeny Poberezkin
2022-09-07 20:06:16 +01:00
committed by GitHub
parent 85e62c4f79
commit 8097611207
5 changed files with 48 additions and 14 deletions

View File

@@ -53,6 +53,8 @@ final class ChatModel: ObservableObject {
static let shared = ChatModel()
static var ok: Bool { ChatModel.shared.chatDbStatus == .ok }
func hasChat(_ id: String) -> Bool {
chats.first(where: { $0.id == id }) != nil
}

View File

@@ -19,10 +19,14 @@ let bgSuspendTimeout: Int = 5 // seconds
let terminationTimeout: Int = 3 // seconds
private func _suspendChat(timeout: Int) {
appStateGroupDefault.set(.suspending)
apiSuspendChat(timeoutMicroseconds: timeout * 1000000)
let endTask = beginBGTask(chatSuspended)
DispatchQueue.global().asyncAfter(deadline: .now() + Double(timeout) + 1, execute: endTask)
if ChatModel.ok {
appStateGroupDefault.set(.suspending)
apiSuspendChat(timeoutMicroseconds: timeout * 1000000)
let endTask = beginBGTask(chatSuspended)
DispatchQueue.global().asyncAfter(deadline: .now() + Double(timeout) + 1, execute: endTask)
} else {
appStateGroupDefault.set(.suspended)
}
}
func suspendChat() {
@@ -47,7 +51,7 @@ func terminateChat() {
case .suspending:
// suspend instantly if already suspending
_chatSuspended()
apiSuspendChat(timeoutMicroseconds: 0)
if ChatModel.ok { apiSuspendChat(timeoutMicroseconds: 0) }
case .stopped: ()
default:
_suspendChat(timeout: terminationTimeout)
@@ -71,9 +75,9 @@ private func _chatSuspended() {
}
}
func activateChat(appState: AppState = .active, databaseReady: Bool = true) {
func activateChat(appState: AppState = .active) {
suspendLockQueue.sync {
appStateGroupDefault.set(appState)
if databaseReady { apiActivateChat() }
if ChatModel.ok { apiActivateChat() }
}
}

View File

@@ -64,7 +64,7 @@ struct SimpleXApp: App {
ChatReceiver.shared.start()
}
let appState = appStateGroupDefault.get()
activateChat(databaseReady: chatModel.chatDbStatus == .ok)
activateChat()
if appState.inactive && chatModel.chatRunning == true {
updateChats()
updateCallInvitations()

View File

@@ -105,9 +105,9 @@ class NotificationService: UNNotificationServiceExtension {
if let ntfData = userInfo["notificationData"] as? [AnyHashable : Any],
let nonce = ntfData["nonce"] as? String,
let encNtfInfo = ntfData["message"] as? String,
let _ = startChat() {
logger.debug("NotificationService: receiveNtfMessages: chat is started")
if let ntfMsgInfo = apiGetNtfMessage(nonce: nonce, encNtfInfo: encNtfInfo) {
let dbStatus = startChat() {
if case .ok = dbStatus,
let ntfMsgInfo = apiGetNtfMessage(nonce: nonce, encNtfInfo: encNtfInfo) {
logger.debug("NotificationService: receiveNtfMessages: apiGetNtfMessage \(String(describing: ntfMsgInfo), privacy: .public)")
if let connEntity = ntfMsgInfo.connEntity {
setBestAttemptNtf(createConnectionEventNtf(connEntity))
@@ -118,9 +118,11 @@ class NotificationService: UNNotificationServiceExtension {
await PendingNtfs.shared.readStream(id, for: self, msgCount: ntfMsgInfo.ntfMessages.count)
deliverBestAttemptNtf()
}
return
}
}
return
} else {
setBestAttemptNtf(createErrorNtf(dbStatus))
}
}
deliverBestAttemptNtf()
@@ -151,20 +153,26 @@ class NotificationService: UNNotificationServiceExtension {
}
}
func startChat() -> User? {
var chatStarted = false
func startChat() -> DBMigrationResult? {
hs_init(0, nil)
if chatStarted { return .ok }
let (_, dbStatus) = migrateChatDatabase()
if dbStatus != .ok { return dbStatus }
if let user = apiGetActiveUser() {
logger.debug("active user \(String(describing: user))")
do {
try setNetworkConfig(getNetCfg())
let justStarted = try apiStartChat()
chatStarted = true
if justStarted {
try apiSetFilesFolder(filesFolder: getAppFilesDirectory().path)
try apiSetIncognito(incognito: incognitoGroupDefault.get())
chatLastStartGroupDefault.set(Date.now)
Task { await receiveMessages() }
}
return user
return .ok
} catch {
logger.error("NotificationService startChat error: \(responseError(error), privacy: .public)")
}

View File

@@ -119,6 +119,26 @@ public func createConnectionEventNtf(_ connEntity: ConnectionEntity) -> UNMutabl
)
}
public func createErrorNtf(_ dbStatus: DBMigrationResult) -> UNMutableNotificationContent {
var title: String
switch dbStatus {
case .errorNotADatabase:
title = NSLocalizedString("Encrypted message: no passphrase", comment: "notification")
case .error:
title = NSLocalizedString("Encrypted message: database error", comment: "notification")
case .errorKeychain:
title = NSLocalizedString("Encrypted message: keychain error", comment: "notification")
case .unknown:
title = NSLocalizedString("Encrypted message: unexpexted error", comment: "notification")
case .ok:
title = NSLocalizedString("Encrypted message or another event", comment: "notification")
}
return createNotification(
categoryIdentifier: ntfCategoryConnectionEvent,
title: title
)
}
private func groupMsgNtfTitle(_ groupInfo: GroupInfo, _ groupMember: GroupMember, hideContent: Bool) -> String {
hideContent
? NSLocalizedString("Group message:", comment: "notification")