session-ios/SessionUtilitiesKit/Database/Migrations/_003_YDBToGRDBMigration.swift

106 lines
4.1 KiB
Swift

// Copyright © 2022 Rangeproof Pty Ltd. All rights reserved.
import Foundation
import GRDB
enum _003_YDBToGRDBMigration: Migration {
static let identifier: String = "YDBToGRDBMigration"
static let minExpectedRunDuration: TimeInterval = 0.1
static let needsConfigSync: Bool = false
static func migrate(_ db: Database) throws {
// MARK: - Identity keys
// Note: Want to exclude the Snode's we already added from the 'onionRequestPathResult'
var registeredNumber: String?
var seedHexString: String?
var userEd25519SecretKeyHexString: String?
var userEd25519PublicKeyHexString: String?
var userX25519KeyPair: SUKLegacy.KeyPair?
// Map the Legacy types for the NSKeyedUnarchiver
NSKeyedUnarchiver.setClass(
SUKLegacy.KeyPair.self,
forClassName: "ECKeyPair"
)
Storage.read { transaction in
registeredNumber = transaction.object(
forKey: SUKLegacy.userAccountRegisteredNumberKey,
inCollection: SUKLegacy.userAccountCollection
) as? String
// Note: The 'seed', 'ed25519SecretKey' and 'ed25519PublicKey' were
// all previously stored as hex strings, so we need to convert them
// to data before we store them in the new database
seedHexString = transaction.object(
forKey: SUKLegacy.identityKeyStoreSeedKey,
inCollection: SUKLegacy.identityKeyStoreCollection
) as? String
userEd25519SecretKeyHexString = transaction.object(
forKey: SUKLegacy.identityKeyStoreEd25519SecretKey,
inCollection: SUKLegacy.identityKeyStoreCollection
) as? String
userEd25519PublicKeyHexString = transaction.object(
forKey: SUKLegacy.identityKeyStoreEd25519PublicKey,
inCollection: SUKLegacy.identityKeyStoreCollection
) as? String
userX25519KeyPair = transaction.object(
forKey: SUKLegacy.identityKeyStoreIdentityKey,
inCollection: SUKLegacy.identityKeyStoreCollection
) as? SUKLegacy.KeyPair
}
// No need to continue if the user isn't registered
if registeredNumber == nil { return }
// If the user is registered then it's all-or-nothing for these values
guard
let seedHexString: String = seedHexString,
let userEd25519SecretKeyHexString: String = userEd25519SecretKeyHexString,
let userEd25519PublicKeyHexString: String = userEd25519PublicKeyHexString,
let userX25519KeyPair: SUKLegacy.KeyPair = userX25519KeyPair
else {
// If this is a fresh install then we would have created all of the Identity
// values directly within the 'Identity' table so this is actually a valid
// case and we don't need to throw
if try Identity.fetchCount(db) == Identity.Variant.allCases.count {
return
}
throw StorageError.migrationFailed
}
print("RAWR publicKey \(userX25519KeyPair.publicKey.toHexString())")
try autoreleasepool {
// Insert the data into GRDB
try Identity(
variant: .seed,
data: Data(hex: seedHexString)
).insert(db)
try Identity(
variant: .ed25519SecretKey,
data: Data(hex: userEd25519SecretKeyHexString)
).insert(db)
try Identity(
variant: .ed25519PublicKey,
data: Data(hex: userEd25519PublicKeyHexString)
).insert(db)
try Identity(
variant: .x25519PrivateKey,
data: userX25519KeyPair.privateKey
).insert(db)
try Identity(
variant: .x25519PublicKey,
data: userX25519KeyPair.publicKey
).insert(db)
}
}
}