diff --git a/ConversationsClassic/AppData/Client/Client+MartinOMEMO.swift b/ConversationsClassic/AppData/Client/Client+MartinOMEMO.swift index edbb471..114b4b3 100644 --- a/ConversationsClassic/AppData/Client/Client+MartinOMEMO.swift +++ b/ConversationsClassic/AppData/Client/Client+MartinOMEMO.swift @@ -11,7 +11,6 @@ final class ClientMartinOMEMO { init(_ credentials: Credentials) { self.credentials = credentials - _ = regenerateKeys(wipe: false) print("ClientMartinOMEMO init") } @@ -24,27 +23,60 @@ final class ClientMartinOMEMO { // swiftlint:disable:next force_unwrapping let signalContext = SignalContext(withStorage: signalStorage)! signalStorage.setup(withContext: signalContext) + + _ = regenerateKeys(wipe: false, context: signalContext) + return (signalStorage, signalContext) } - private func regenerateKeys(wipe: Bool = false) -> Bool { + private func regenerateKeys(wipe: Bool = false, context: SignalContext) -> Bool { if wipe { OMEMOSession.wipe(account: credentials.bareJid) OMEMOPreKey.wipe(account: credentials.bareJid) OMEMOSignedPreKey.wipe(account: credentials.bareJid) OMEMOIdentity.wipe(account: credentials.bareJid) + Settings.getFor(credentials.bareJid)?.wipeOmemoRegId() } let hasKeyPair = keyPair() != nil if wipe || localRegistrationId() == 0 || !hasKeyPair { - // let regId: UInt32 = signalContext.generateRegistrationId() - // AccountSettings.omemoRegistrationId(for: context!.sessionObject.userBareJid!, value: regId) - // - // let keyPair = SignalIdentityKeyPair.generateKeyPair(context: signalContext) + let regId: UInt32 = context.generateRegistrationId() + + var settings = Settings.getFor(credentials.bareJid) + settings?.omemoRegId = Int(regId) + settings?.save() + + let keyPair = SignalIdentityKeyPair.generateKeyPair(context: context) + + // do { + // _ = try Database.shared.dbQueue.write { db in + // try OMEMOIdentity( + // account: credentials.bareJid, + // name: credentials.bareJid, + // deviceId: regId, + // key: keyPair.publicKey, + // fingerprint: fingerprint(publicKey: keyPair.publicKey), + // status: MartinOMEMO.IdentityStatus.trusted.rawValue, + // own: 1 + // ) + // .insert(db) + // } + // } catch { + // logIt(.error, "Error storing identity key: \(error.localizedDescription)") + // return false + // } + + // 102 // if !identityKeyStore.save(identity: SignalAddress(name: context!.sessionObject.userBareJid!.stringValue, deviceId: Int32(identityKeyStore.localRegistrationId())), key: keyPair) {} } return true } + + private func fingerprint(publicKey: Data) -> String { + publicKey.map { byte -> String in + String(format: "%02x", byte) + }.joined() + } } // MARK: - Session @@ -132,10 +164,11 @@ extension ClientMartinOMEMO: SignalSessionStoreProtocol { // MARK: - Identity extension ClientMartinOMEMO: SignalIdentityKeyStoreProtocol { func keyPair() -> (any MartinOMEMO.SignalIdentityKeyPairProtocol)? { - // guard let deviceId = localRegistrationId(forAccount: account) else { - // return nil - // } - // + let deviceId = localRegistrationId() + guard deviceId != 0 else { + return nil + } + // guard // let data = try! Database.main.reader({ database in // try database.select(query: .omemoKeyPairForAccount, params: ["account": account, "name": account.stringValue, "deviceId": deviceId]).mapFirst { $0.data(for: "key") } @@ -145,17 +178,15 @@ extension ClientMartinOMEMO: SignalIdentityKeyStoreProtocol { // } // // return SignalIdentityKeyPair(fromKeyPairData: data) - nil + return nil } func localRegistrationId() -> UInt32 { - // - // - // - // - // - // - 0 + if let settings = Settings.getFor(credentials.bareJid) { + return UInt32(settings.omemoRegId) + } else { + return 0 + } } func save(identity: MartinOMEMO.SignalAddress, key: (any MartinOMEMO.SignalIdentityKeyProtocol)?) -> Bool { diff --git a/ConversationsClassic/AppData/Model/Settings.swift b/ConversationsClassic/AppData/Model/Settings.swift new file mode 100644 index 0000000..9405a6f --- /dev/null +++ b/ConversationsClassic/AppData/Model/Settings.swift @@ -0,0 +1,49 @@ +import Foundation +import GRDB + +struct Settings: DBStorable { + static let databaseTableName = "settings" + + let bareJid: String + var omemoRegId: Int + + var id: String { + bareJid + } +} + +extension Settings { + static func getFor(_ bareJid: String) -> Settings? { + do { + return try Database.shared.dbQueue.read { db in + let settings = try Settings.filter(Column("bareJid") == bareJid).fetchOne(db) + return settings + } + } catch { + logIt(.error, "Settings not exists for \(bareJid)") + return nil + } + } + + func wipeOmemoRegId() { + do { + _ = try Database.shared.dbQueue.write { db in + try Settings + .filter(Column("bareJid") == bareJid) + .updateAll(db, Column("omemoRegId").set(to: 0)) + } + } catch { + logIt(.error, "Failed to wipe omemoRegId for \(bareJid)") + } + } + + func save() { + do { + try Database.shared.dbQueue.write { db in + try self.insert(db) + } + } catch { + logIt(.error, "Failed to save settings for \(bareJid)") + } + } +} diff --git a/ConversationsClassic/AppData/Services/Database+Migrations.swift b/ConversationsClassic/AppData/Services/Database+Migrations.swift index f43c54a..88b84c5 100644 --- a/ConversationsClassic/AppData/Services/Database+Migrations.swift +++ b/ConversationsClassic/AppData/Services/Database+Migrations.swift @@ -103,6 +103,13 @@ extension Database { // } } + migrator.registerMigration("Add settings table") { db in + try db.create(table: "settings", options: [.ifNotExists]) { table in + table.column("bareJid", .text).notNull().primaryKey().unique(onConflict: .replace) + table.column("omemoRegId", .integer).notNull() + } + } + // return migrator return migrator }()