mirror of https://github.com/oxen-io/session-ios
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
190 lines
8.6 KiB
Swift
190 lines
8.6 KiB
Swift
// Copyright © 2022 Rangeproof Pty Ltd. All rights reserved.
|
|
|
|
import Foundation
|
|
import GRDB
|
|
import SessionUtilitiesKit
|
|
|
|
enum _018_DisappearingMessagesConfiguration: Migration {
|
|
static let target: TargetMigrations.Identifier = .messagingKit
|
|
static let identifier: String = "DisappearingMessagesWithTypes"
|
|
static let minExpectedRunDuration: TimeInterval = 0.1
|
|
static let createdTables: [(TableRecord & FetchableRecord).Type] = []
|
|
|
|
static func migrate(_ db: Database, using dependencies: Dependencies) throws {
|
|
try db.alter(table: "disappearingMessagesConfiguration") { t in
|
|
t.add(column: "type", .integer)
|
|
}
|
|
|
|
try db.alter(table: "contact") { t in
|
|
t.add(column: "lastKnownClientVersion", .integer)
|
|
}
|
|
|
|
/// Add index on interaction table for wasRead and variant
|
|
///
|
|
/// This is due to new disappearing messages will need some info messages to be able to be unread,
|
|
/// but we only want to count the unread message number by incoming visible messages and call messages.
|
|
try db.create(
|
|
indexOn: "interaction",
|
|
columns: ["wasRead", "variant"]
|
|
)
|
|
|
|
// If there isn't already a user account then we can just finish here (there will be no
|
|
// threads/configs to update and the configs won't be setup which would cause this to crash
|
|
guard
|
|
MigrationHelper.userExists(db),
|
|
let userEd25519SecretKey: Data = MigrationHelper.fetchIdentityValue(db, key: "ed25519SecretKey")
|
|
else { return Storage.update(progress: 1, for: self, in: target, using: dependencies) }
|
|
|
|
// Set the disappearing messages type per conversation
|
|
let userSessionId: SessionId = MigrationHelper.userSessionId(db)
|
|
let timestampMs: Int64 = Int64(dependencies.dateNow.timeIntervalSince1970 * TimeInterval(1000))
|
|
let userProfileType: DisappearingMessagesConfiguration.DisappearingMessageType = .disappearAfterSend
|
|
let contactType: DisappearingMessagesConfiguration.DisappearingMessageType = .disappearAfterRead
|
|
let legacyGroupType: DisappearingMessagesConfiguration.DisappearingMessageType = .disappearAfterSend
|
|
try db.execute(sql: """
|
|
UPDATE disappearingMessagesConfiguration
|
|
SET type = \(userProfileType.rawValue)
|
|
WHERE disappearingMessagesConfiguration.threadId = '\(userSessionId.hexString)'
|
|
""")
|
|
try db.execute(sql: """
|
|
UPDATE disappearingMessagesConfiguration
|
|
SET type = \(contactType.rawValue)
|
|
WHERE threadId IN (
|
|
SELECT id FROM thread WHERE variant = \(SessionThread.Variant.contact.rawValue)
|
|
)
|
|
""")
|
|
try db.execute(sql: """
|
|
UPDATE disappearingMessagesConfiguration
|
|
SET type = \(legacyGroupType.rawValue)
|
|
WHERE threadId IN (
|
|
SELECT id FROM thread WHERE variant = \(SessionThread.Variant.legacyGroup.rawValue)
|
|
)
|
|
""")
|
|
|
|
// Also need to update libSession with the new settings
|
|
let disappearingMessageInfo: [Row] = try Row.fetchAll(db, sql: """
|
|
SELECT
|
|
thread.id,
|
|
thread.variant,
|
|
disappearingMessagesConfiguration.isEnabled,
|
|
disappearingMessagesConfiguration.durationSeconds
|
|
FROM disappearingMessagesConfiguration
|
|
JOIN thread ON thread.id = disappearingMessagesConfiguration.threadId
|
|
""")
|
|
|
|
let cache: LibSession.Cache = LibSession.Cache(userSessionId: userSessionId, using: dependencies)
|
|
let userProfileConfig: LibSession.Config = try cache.loadState(
|
|
for: .userProfile,
|
|
sessionId: userSessionId,
|
|
userEd25519SecretKey: Array(userEd25519SecretKey),
|
|
groupEd25519SecretKey: nil,
|
|
cachedData: MigrationHelper.configDump(db, for: ConfigDump.Variant.userProfile.rawValue)
|
|
)
|
|
let contactsConfig: LibSession.Config = try cache.loadState(
|
|
for: .contacts,
|
|
sessionId: userSessionId,
|
|
userEd25519SecretKey: Array(userEd25519SecretKey),
|
|
groupEd25519SecretKey: nil,
|
|
cachedData: MigrationHelper.configDump(db, for: ConfigDump.Variant.contacts.rawValue)
|
|
)
|
|
let userGroupsConfig: LibSession.Config = try cache.loadState(
|
|
for: .userGroups,
|
|
sessionId: userSessionId,
|
|
userEd25519SecretKey: Array(userEd25519SecretKey),
|
|
groupEd25519SecretKey: nil,
|
|
cachedData: MigrationHelper.configDump(db, for: ConfigDump.Variant.userGroups.rawValue)
|
|
)
|
|
|
|
// Update the configs so the settings are synced
|
|
if let noteToSelfInfo: Row = disappearingMessageInfo.first(where: { $0["id"] == userSessionId.hexString }) {
|
|
try LibSession.updateNoteToSelf(
|
|
disappearingMessagesConfig: DisappearingMessagesConfiguration(
|
|
threadId: noteToSelfInfo["id"],
|
|
isEnabled: noteToSelfInfo["isEnabled"],
|
|
durationSeconds: noteToSelfInfo["durationSeconds"],
|
|
type: userProfileType
|
|
),
|
|
in: userProfileConfig
|
|
)
|
|
}
|
|
|
|
try LibSession.upsert(
|
|
contactData: disappearingMessageInfo
|
|
.filter {
|
|
$0["id"] != userSessionId.hexString &&
|
|
$0["variant"] == SessionThread.Variant.contact.rawValue
|
|
}
|
|
.map {
|
|
LibSession.SyncedContactInfo(
|
|
id: $0["id"],
|
|
disappearingMessagesConfig: DisappearingMessagesConfiguration(
|
|
threadId: $0["id"],
|
|
isEnabled: $0["isEnabled"],
|
|
durationSeconds: $0["durationSeconds"],
|
|
type: contactType
|
|
)
|
|
)
|
|
},
|
|
in: contactsConfig,
|
|
using: dependencies
|
|
)
|
|
|
|
try LibSession.upsert(
|
|
legacyGroups: disappearingMessageInfo
|
|
.filter { $0["variant"] == SessionThread.Variant.legacyGroup.rawValue }
|
|
.map {
|
|
LibSession.LegacyGroupInfo(
|
|
id: $0["id"],
|
|
disappearingMessageInfo: LibSession.DisappearingMessageInfo(
|
|
isEnabled: $0["isEnabled"],
|
|
durationSeconds: $0["durationSeconds"],
|
|
rawType: legacyGroupType.rawValue
|
|
)
|
|
)
|
|
},
|
|
in: userGroupsConfig
|
|
)
|
|
|
|
// Now that the state is updated we need to save the updated config dumps
|
|
if cache.configNeedsDump(userProfileConfig), let dumpData: Data = try userProfileConfig.dump() {
|
|
try db.execute(
|
|
sql: """
|
|
INSERT INTO configDump (variant, publicKey, data, timestampMs)
|
|
VALUES ('userProfile', '\(userSessionId.hexString)', ?, \(timestampMs))
|
|
ON CONFLICT(variant, publicKey) DO UPDATE SET
|
|
data = ?,
|
|
timestampMs = \(timestampMs)
|
|
""",
|
|
arguments: [dumpData, dumpData]
|
|
)
|
|
}
|
|
if cache.configNeedsDump(contactsConfig), let dumpData: Data = try contactsConfig.dump() {
|
|
try db.execute(
|
|
sql: """
|
|
INSERT INTO configDump (variant, publicKey, data, timestampMs)
|
|
VALUES ('contacts', '\(userSessionId.hexString)', ?, \(timestampMs))
|
|
ON CONFLICT(variant, publicKey) DO UPDATE SET
|
|
data = ?,
|
|
timestampMs = \(timestampMs)
|
|
""",
|
|
arguments: [dumpData, dumpData]
|
|
)
|
|
}
|
|
if cache.configNeedsDump(userGroupsConfig), let dumpData: Data = try userGroupsConfig.dump() {
|
|
try db.execute(
|
|
sql: """
|
|
INSERT INTO configDump (variant, publicKey, data, timestampMs)
|
|
VALUES ('userGroups', '\(userSessionId.hexString)', ?, \(timestampMs))
|
|
ON CONFLICT(variant, publicKey) DO UPDATE SET
|
|
data = ?,
|
|
timestampMs = \(timestampMs)
|
|
""",
|
|
arguments: [dumpData, dumpData]
|
|
)
|
|
}
|
|
|
|
Storage.update(progress: 1, for: self, in: target, using: dependencies)
|
|
}
|
|
}
|
|
|