// // Copyright 2023 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only // import SignalServiceKit import SignalUI #if USE_DEBUG_UI class DebugUISessionState: DebugUIPage, Dependencies { let name = "Session State" func section(thread: TSThread?) -> OWSTableSection? { var items = [OWSTableItem]() if let contactThread = thread as? TSContactThread { items += [ OWSTableItem(title: "Log All Recipient Identities", actionBlock: { OWSRecipientIdentity.printAllIdentities() }), OWSTableItem(title: "Log All Sessions", actionBlock: { self.databaseStorage.read { transaction in let sessionStore = DependenciesBridge.shared.signalProtocolStoreManager.signalProtocolStore(for: .aci).sessionStore sessionStore.printAll(tx: transaction.asV2Read) } }), OWSTableItem(title: "Toggle Key Change", actionBlock: { DebugUISessionState.toggleKeyChange(for: contactThread) }), OWSTableItem(title: "Delete All Sessions", actionBlock: { self.databaseStorage.write { transaction in let sessionStore = DependenciesBridge.shared.signalProtocolStoreManager.signalProtocolStore(for: .aci).sessionStore sessionStore.deleteAllSessions(for: contactThread.contactAddress.serviceId!, tx: transaction.asV2Write) } }), OWSTableItem(title: "Archive All Sessions", actionBlock: { self.databaseStorage.write { transaction in let sessionStore = DependenciesBridge.shared.signalProtocolStoreManager.signalProtocolStore(for: .aci).sessionStore sessionStore.archiveAllSessions(for: contactThread.contactAddress.serviceId!, tx: transaction.asV2Write) } }), OWSTableItem(title: "Send Session Reset", actionBlock: { self.databaseStorage.write { transaction in self.smJobQueues.sessionResetJobQueue.add(contactThread: contactThread, transaction: transaction) } }) ] } if let groupThread = thread as? TSGroupThread { items.append(OWSTableItem(title: "Rotate Sender Key", actionBlock: { self.databaseStorage.write { transaction in self.senderKeyStore.resetSenderKeySession(for: groupThread, transaction: transaction) } })) } if let thread { items.append(OWSTableItem(title: "Update Verification State", actionBlock: { DebugUISessionState.updateIdentityVerificationForThread(thread) })) } items += [ OWSTableItem(title: "Clear Session Store", actionBlock: { self.databaseStorage.write { transaction in let sessionStore = DependenciesBridge.shared.signalProtocolStoreManager.signalProtocolStore(for: .aci).sessionStore sessionStore.resetSessionStore(tx: transaction.asV2Write) } }), OWSTableItem(title: "Clear Sender Key Store", actionBlock: { self.databaseStorage.write { transaction in self.senderKeyStore.resetSenderKeyStore(transaction: transaction) } }) ] return OWSTableSection(title: name, items: items) } // MARK: - private static func toggleKeyChange(for thread: TSContactThread) { guard let serviceId = thread.contactAddress.serviceId else { return } Logger.error("Flipping identity Key. Flip again to return.") let identityManager = DependenciesBridge.shared.identityManager databaseStorage.write { tx in guard let currentKey = identityManager.identityKey(for: SignalServiceAddress(serviceId), tx: tx.asV2Read) else { return } var flippedKey = Data(count: currentKey.count) for i in 0..