Skip to content
This repository has been archived by the owner on Jun 7, 2020. It is now read-only.

Persist auth data & recover it case DB gets corrupted or destroyed #525

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions Rocket.Chat/Controllers/MainViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ final class MainViewController: BaseViewController {
}
}

override func viewDidLoad() {
super.viewDidLoad()
AuthManager.recoverAuthIfNeeded()
}

override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)

Expand All @@ -37,6 +42,8 @@ final class MainViewController: BaseViewController {
super.viewWillAppear(animated)

if let auth = AuthManager.isAuthenticated() {
AuthManager.persistAuthInformation(auth)

labelAuthenticationStatus.isHidden = true
buttonConnect.isHidden = true
activityIndicator.startAnimating()
Expand Down
53 changes: 53 additions & 0 deletions Rocket.Chat/Managers/Model/AuthManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,14 @@
import Foundation
import RealmSwift

struct AuthManagerPersistKeys {
static let token = "kAuthToken"
static let serverURL = "kAuthServerURL"
static let userId = "kUserId"
}

struct AuthManager {

/**
- returns: Last auth object (sorted by lastAccess), if exists.
*/
Expand All @@ -26,6 +33,47 @@ struct AuthManager {
guard let user = try? Realm().object(ofType: User.self, forPrimaryKey: auth.userId) else { return nil }
return user
}

/**
This method is going to persist the authentication informations
that was latest used in NSUserDefaults to keep it safe if something
goes wrong on database migration.
*/
static func persistAuthInformation(_ auth: Auth) {
let defaults = UserDefaults.standard
defaults.set(auth.token, forKey: AuthManagerPersistKeys.token)
defaults.set(auth.serverURL, forKey: AuthManagerPersistKeys.serverURL)
defaults.set(auth.userId, forKey: AuthManagerPersistKeys.userId)
}

static func recoverAuthIfNeeded() {
if AuthManager.isAuthenticated() != nil {
return
}

guard
let token = UserDefaults.standard.string(forKey: AuthManagerPersistKeys.token),
let serverURL = UserDefaults.standard.string(forKey: AuthManagerPersistKeys.serverURL),
let userId = UserDefaults.standard.string(forKey: AuthManagerPersistKeys.userId) else {
return
}

Realm.executeOnMainThread({ (realm) in
// Clear database
realm.deleteAll()

let auth = Auth()
auth.lastSubscriptionFetch = nil
auth.lastAccess = Date()
auth.serverURL = serverURL
auth.token = token
auth.userId = userId

PushManager.updatePushToken()

realm.add(auth)
})
}
}

// MARK: Socket Management
Expand Down Expand Up @@ -214,6 +262,11 @@ extension AuthManager {
SocketManager.clear()
GIDSignIn.sharedInstance().signOut()

let defaults = UserDefaults.standard
defaults.removeObject(forKey: AuthManagerPersistKeys.token)
defaults.removeObject(forKey: AuthManagerPersistKeys.serverURL)
defaults.removeObject(forKey: AuthManagerPersistKeys.userId)

Realm.executeOnMainThread({ (realm) in
realm.deleteAll()
})
Expand Down