diff --git a/Mastodon/Supporting Files/AppDelegate.swift b/Mastodon/Supporting Files/AppDelegate.swift index 79eaeb5cd..2778baad6 100644 --- a/Mastodon/Supporting Files/AppDelegate.swift +++ b/Mastodon/Supporting Files/AppDelegate.swift @@ -18,6 +18,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate { let appContext = AppContext() func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + AuthenticationServiceProvider.shared.migrateLegacyAuthenticationsIfRequired(in: appContext.managedObjectContext) AuthenticationServiceProvider.shared.restore() AppSecret.default.register() diff --git a/MastodonSDK/Sources/MastodonCore/AuthenticationServiceProvider.swift b/MastodonSDK/Sources/MastodonCore/AuthenticationServiceProvider.swift index 5a9c77228..f7ec62718 100644 --- a/MastodonSDK/Sources/MastodonCore/AuthenticationServiceProvider.swift +++ b/MastodonSDK/Sources/MastodonCore/AuthenticationServiceProvider.swift @@ -6,10 +6,14 @@ import CoreDataStack import MastodonSDK import KeychainAccess import MastodonCommon +import os.log public class AuthenticationServiceProvider: ObservableObject { + private let logger = Logger(subsystem: "AuthenticationServiceProvider", category: "Authentication") + public static let shared = AuthenticationServiceProvider() private static let keychain = Keychain(service: "org.joinmastodon.app.authentications", accessGroup: AppName.groupID) + private let userDefaults: UserDefaults = .shared private init() {} @@ -63,6 +67,35 @@ public extension AuthenticationServiceProvider { return try? JSONDecoder().decode(MastodonAuthentication.self, from: data) } } + + func migrateLegacyAuthenticationsIfRequired(in context: NSManagedObjectContext) { + guard !userDefaults.didMigrateAuthentications else { return } + + defer { userDefaults.didMigrateAuthentications = true } + + do { + let request = NSFetchRequest(entityName: "MastodonAuthentication") + let legacyAuthentications = try context.fetch(request) + + self.authentications = legacyAuthentications.map { auth in + MastodonAuthentication( + identifier: auth.identifier, + domain: auth.domain, + username: auth.username, + appAccessToken: auth.appAccessToken, + userAccessToken: auth.userAccessToken, + clientID: auth.clientID, + clientSecret: auth.clientSecret, + createdAt: auth.createdAt, + updatedAt: auth.updatedAt, + activedAt: auth.activedAt, + userID: auth.userID + ) + } + } catch { + logger.log(level: .error, "Could not migrate legacy authentications") + } + } } // MARK: - Private @@ -73,3 +106,13 @@ private extension AuthenticationServiceProvider { } } } + +private extension UserDefaults { + @objc dynamic var didMigrateAuthentications: Bool { + get { + register(defaults: [#function: false]) + return bool(forKey: #function) + } + set { self[#function] = newValue } + } +}