mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2025-06-28 20:29:53 +00:00
106 lines
4.4 KiB
Swift
106 lines
4.4 KiB
Swift
//
|
|
// LocalAuthView.swift
|
|
// SimpleX (iOS)
|
|
//
|
|
// Created by Evgeny on 10/04/2023.
|
|
// Copyright © 2023 SimpleX Chat. All rights reserved.
|
|
//
|
|
|
|
import SwiftUI
|
|
import SimpleXChat
|
|
|
|
struct LocalAuthView: View {
|
|
@EnvironmentObject var m: ChatModel
|
|
var authRequest: LocalAuthRequest
|
|
@State private var password = ""
|
|
@State private var allowToReact = true
|
|
|
|
var body: some View {
|
|
PasscodeView(passcode: $password, title: authRequest.title ?? "Enter Passcode", reason: authRequest.reason, submitLabel: "Submit",
|
|
buttonsEnabled: $allowToReact) {
|
|
if let sdPassword = kcSelfDestructPassword.get(), authRequest.selfDestruct && password == sdPassword {
|
|
allowToReact = false
|
|
deleteStorageAndRestart(sdPassword) { r in
|
|
m.laRequest = nil
|
|
authRequest.completed(r)
|
|
}
|
|
return
|
|
}
|
|
let r: LAResult
|
|
if password == authRequest.password {
|
|
if authRequest.selfDestruct && kcSelfDestructPassword.get() != nil && !m.chatInitialized {
|
|
initChatAndMigrate()
|
|
}
|
|
r = .success
|
|
} else {
|
|
r = .failed(authError: NSLocalizedString("Incorrect passcode", comment: "PIN entry"))
|
|
}
|
|
m.laRequest = nil
|
|
authRequest.completed(r)
|
|
} cancel: {
|
|
m.laRequest = nil
|
|
authRequest.completed(.failed(authError: NSLocalizedString("Authentication cancelled", comment: "PIN entry")))
|
|
}
|
|
}
|
|
|
|
private func deleteStorageAndRestart(_ password: String, completed: @escaping (LAResult) -> Void) {
|
|
Task {
|
|
do {
|
|
/** Waiting until [initializeChat] finishes */
|
|
while (m.ctrlInitInProgress) {
|
|
try await Task.sleep(nanoseconds: 50_000000)
|
|
}
|
|
if m.chatRunning == true {
|
|
try await stopChatAsync()
|
|
}
|
|
if m.chatInitialized {
|
|
/**
|
|
* The following sequence can bring a user here:
|
|
* the user opened the app, entered app passcode, went to background, returned back, entered self-destruct code.
|
|
* In this case database should be closed to prevent possible situation when OS can deny database removal command
|
|
* */
|
|
chatCloseStore()
|
|
}
|
|
deleteAppDatabaseAndFiles()
|
|
// Clear sensitive data on screen just in case app fails to hide its views while new database is created
|
|
m.chatId = nil
|
|
ItemsModel.shared.reversedChatItems = []
|
|
ItemsModel.shared.chatState.clear()
|
|
m.updateChats([])
|
|
m.users = []
|
|
_ = kcAppPassword.set(password)
|
|
_ = kcSelfDestructPassword.remove()
|
|
await NtfManager.shared.removeAllNotifications()
|
|
let displayName = UserDefaults.standard.string(forKey: DEFAULT_LA_SELF_DESTRUCT_DISPLAY_NAME)
|
|
UserDefaults.standard.removeObject(forKey: DEFAULT_LA_SELF_DESTRUCT)
|
|
UserDefaults.standard.removeObject(forKey: DEFAULT_LA_SELF_DESTRUCT_DISPLAY_NAME)
|
|
await MainActor.run {
|
|
m.chatDbChanged = true
|
|
m.chatInitialized = false
|
|
}
|
|
resetChatCtrl()
|
|
try initializeChat(start: true)
|
|
m.chatDbChanged = false
|
|
AppChatState.shared.set(.active)
|
|
if m.currentUser != nil || !m.chatInitialized { return }
|
|
var profile: Profile? = nil
|
|
if let displayName = displayName, displayName != "" {
|
|
profile = Profile(displayName: displayName, fullName: "")
|
|
}
|
|
m.currentUser = try apiCreateActiveUser(profile, pastTimestamp: true)
|
|
onboardingStageDefault.set(.onboardingComplete)
|
|
m.onboardingStage = .onboardingComplete
|
|
try startChat()
|
|
completed(.success)
|
|
} catch {
|
|
completed(.failed(authError: NSLocalizedString("Incorrect passcode", comment: "PIN entry")))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
struct LocalAuthView_Previews: PreviewProvider {
|
|
static var previews: some View {
|
|
LocalAuthView(authRequest: LocalAuthRequest.sample)
|
|
}
|
|
}
|