diff --git a/Frameworks/Account/Account.swift b/Frameworks/Account/Account.swift index 6c436895c..32598e41a 100644 --- a/Frameworks/Account/Account.swift +++ b/Frameworks/Account/Account.swift @@ -252,6 +252,9 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container, // MARK: - API public func storeCredentials(_ credentials: Credentials) throws { + // The delegate may need the credentials to determine the server + delegate.credentials = credentials + guard let server = delegate.server else { throw CredentialsError.incompleteCredentials } @@ -259,7 +262,9 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container, switch credentials { case .basic(let username, _): self.username = username - case .googleLogin(let username, _, _, _): + case .googleBasicLogin(let username, _, _): + self.username = username + case .googleAuthLogin(let username, _, _): self.username = username } @@ -284,7 +289,7 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container, self.username = nil } - public static func validateCredentials(transport: Transport = URLSession.webserviceTransport(), type: AccountType, credentials: Credentials, completion: @escaping (Result) -> Void) { + public static func validateCredentials(transport: Transport = URLSession.webserviceTransport(), type: AccountType, credentials: Credentials, completion: @escaping (Result) -> Void) { switch type { case .onMyMac: LocalAccountDelegate.validateCredentials(transport: transport, credentials: credentials, completion: completion) diff --git a/Frameworks/Account/AccountDelegate.swift b/Frameworks/Account/AccountDelegate.swift index 314a944c5..4d9a312b4 100644 --- a/Frameworks/Account/AccountDelegate.swift +++ b/Frameworks/Account/AccountDelegate.swift @@ -46,6 +46,6 @@ protocol AccountDelegate { // Called at the end of account’s init method. func accountDidInitialize(_ account: Account) - static func validateCredentials(transport: Transport, credentials: Credentials, completion: @escaping (Result) -> Void) + static func validateCredentials(transport: Transport, credentials: Credentials, completion: @escaping (Result) -> Void) } diff --git a/Frameworks/Account/Feedbin/FeedbinAPICaller.swift b/Frameworks/Account/Feedbin/FeedbinAPICaller.swift index ba1e0fa94..7c4c482c1 100644 --- a/Frameworks/Account/Feedbin/FeedbinAPICaller.swift +++ b/Frameworks/Account/Feedbin/FeedbinAPICaller.swift @@ -42,7 +42,7 @@ final class FeedbinAPICaller: NSObject { self.transport = transport } - func validateCredentials(completion: @escaping (Result) -> Void) { + func validateCredentials(completion: @escaping (Result) -> Void) { let callURL = feedbinBaseURL.appendingPathComponent("authentication.json") let request = URLRequest(url: callURL, credentials: credentials) @@ -50,12 +50,12 @@ final class FeedbinAPICaller: NSObject { transport.send(request: request) { result in switch result { case .success: - completion(.success(true)) + completion(.success(self.credentials)) case .failure(let error): switch error { case TransportError.httpError(let status): if status == 401 { - completion(.success(false)) + completion(.success(self.credentials)) } else { completion(.failure(error)) } diff --git a/Frameworks/Account/Feedbin/FeedbinAccountDelegate.swift b/Frameworks/Account/Feedbin/FeedbinAccountDelegate.swift index eddcd43b1..cf444ce4f 100644 --- a/Frameworks/Account/Feedbin/FeedbinAccountDelegate.swift +++ b/Frameworks/Account/Feedbin/FeedbinAccountDelegate.swift @@ -485,7 +485,7 @@ final class FeedbinAccountDelegate: AccountDelegate { accountMetadata = account.metadata } - static func validateCredentials(transport: Transport, credentials: Credentials, completion: @escaping (Result) -> Void) { + static func validateCredentials(transport: Transport, credentials: Credentials, completion: @escaping (Result) -> Void) { let caller = FeedbinAPICaller(transport: transport) caller.credentials = credentials diff --git a/Frameworks/Account/GoogleReaderCompatible/GoogleReaderCompatibleAPICaller.swift b/Frameworks/Account/GoogleReaderCompatible/GoogleReaderCompatibleAPICaller.swift index 002da3d61..a5bdd5005 100644 --- a/Frameworks/Account/GoogleReaderCompatible/GoogleReaderCompatibleAPICaller.swift +++ b/Frameworks/Account/GoogleReaderCompatible/GoogleReaderCompatibleAPICaller.swift @@ -35,41 +35,43 @@ final class GoogleReaderCompatibleAPICaller: NSObject { private var transport: Transport! var credentials: Credentials? - var apiAuthToken: String? weak var accountMetadata: AccountMetadata? + var server: String? { + get { + guard let localCredentials = credentials else { + return nil + } + + switch localCredentials { + case .googleBasicLogin(_, _, let apiUrl): + return apiUrl.host + case .googleAuthLogin(_, _, let apiUrl): + return apiUrl.host + default: + return nil + } + } + } + + init(transport: Transport) { super.init() self.transport = transport } - func validateCredentials(completion: @escaping (Result) -> Void) { + func validateCredentials(completion: @escaping (Result) -> Void) { guard let credentials = credentials else { completion(.failure(CredentialsError.incompleteCredentials)) return } - guard case .googleLogin(let username, let password, let apiUrl, _) = credentials else { + guard case .googleBasicLogin(let username, _, let apiUrl) = credentials else { completion(.failure(CredentialsError.incompleteCredentials)) return } - guard var loginURL = URLComponents(url: apiUrl.appendingPathComponent("/accounts/ClientLogin"), resolvingAgainstBaseURL: false) else { - completion(.failure(CredentialsError.incompleteCredentials)) - return - } - - loginURL.queryItems = [ - URLQueryItem(name: "Email", value: username), - URLQueryItem(name: "Passwd", value: password) - ] - - guard let callURL = loginURL.url else { - completion(.failure(CredentialsError.incompleteCredentials)) - return - } - - let request = URLRequest(url: callURL, credentials: credentials) + let request = URLRequest(url: apiUrl.appendingPathComponent("/accounts/ClientLogin"), credentials: credentials) transport.send(request: request) { result in switch result { @@ -97,20 +99,11 @@ final class GoogleReaderCompatibleAPICaller: NSObject { } // Save Auth Token for later use - self.apiAuthToken = authString + self.credentials = .googleAuthLogin(username: username, apiKey: authString, url: apiUrl) - completion(.success(true)) + completion(.success(self.credentials)) case .failure(let error): - switch error { - case TransportError.httpError(let status): - if status == 401 { - completion(.success(false)) - } else { - completion(.failure(error)) - } - default: - completion(.failure(error)) - } + completion(.failure(error)) } } diff --git a/Frameworks/Account/GoogleReaderCompatible/GoogleReaderCompatibleAccountDelegate.swift b/Frameworks/Account/GoogleReaderCompatible/GoogleReaderCompatibleAccountDelegate.swift index 14dacd849..b27193885 100644 --- a/Frameworks/Account/GoogleReaderCompatible/GoogleReaderCompatibleAccountDelegate.swift +++ b/Frameworks/Account/GoogleReaderCompatible/GoogleReaderCompatibleAccountDelegate.swift @@ -31,7 +31,12 @@ final class GoogleReaderCompatibleAccountDelegate: AccountDelegate { private var log = OSLog(subsystem: Bundle.main.bundleIdentifier!, category: "GoogleReaderCompatible") let supportsSubFolders = false - let server: String? = "api.GoogleReaderCompatible.com" + var server: String? { + get { + return caller.server + } + } + var opmlImportInProgress = false var credentials: Credentials? { @@ -485,7 +490,7 @@ final class GoogleReaderCompatibleAccountDelegate: AccountDelegate { accountMetadata = account.metadata } - static func validateCredentials(transport: Transport, credentials: Credentials, completion: @escaping (Result) -> Void) { + static func validateCredentials(transport: Transport, credentials: Credentials, completion: @escaping (Result) -> Void) { let caller = GoogleReaderCompatibleAPICaller(transport: transport) caller.credentials = credentials diff --git a/Frameworks/Account/LocalAccount/LocalAccountDelegate.swift b/Frameworks/Account/LocalAccount/LocalAccountDelegate.swift index f9efdbc31..cf06a8074 100644 --- a/Frameworks/Account/LocalAccount/LocalAccountDelegate.swift +++ b/Frameworks/Account/LocalAccount/LocalAccountDelegate.swift @@ -182,8 +182,8 @@ final class LocalAccountDelegate: AccountDelegate { func accountDidInitialize(_ account: Account) { } - static func validateCredentials(transport: Transport, credentials: Credentials, completion: (Result) -> Void) { - return completion(.success(false)) + static func validateCredentials(transport: Transport, credentials: Credentials, completion: (Result) -> Void) { + return completion(.success(nil)) } } diff --git a/Mac/Preferences/Accounts/AccountsFeedbinWindowController.swift b/Mac/Preferences/Accounts/AccountsFeedbinWindowController.swift index 11cdcc109..191599c07 100644 --- a/Mac/Preferences/Accounts/AccountsFeedbinWindowController.swift +++ b/Mac/Preferences/Accounts/AccountsFeedbinWindowController.swift @@ -74,38 +74,36 @@ class AccountsFeedbinWindowController: NSWindowController { self.progressIndicator.stopAnimation(self) switch result { - case .success(let authenticated): - - if authenticated { - - var newAccount = false - if self.account == nil { - self.account = AccountManager.shared.createAccount(type: .feedbin) - newAccount = true - } - - do { - try self.account?.removeBasicCredentials() - try self.account?.storeCredentials(credentials) - if newAccount { - self.account?.refreshAll() { result in - switch result { - case .success: - break - case .failure(let error): - NSApplication.shared.presentError(error) - } + case .success(let validatedCredentials): + + guard let validatedCredentials = validatedCredentials else { + self.errorMessageLabel.stringValue = NSLocalizedString("Invalid email/password combination.", comment: "Credentials Error") + return + } + var newAccount = false + if self.account == nil { + self.account = AccountManager.shared.createAccount(type: .feedbin) + newAccount = true + } + + do { + try self.account?.removeBasicCredentials() + try self.account?.storeCredentials(validatedCredentials) + if newAccount { + self.account?.refreshAll() { result in + switch result { + case .success: + break + case .failure(let error): + NSApplication.shared.presentError(error) } } - self.hostWindow?.endSheet(self.window!, returnCode: NSApplication.ModalResponse.OK) - } catch { - self.errorMessageLabel.stringValue = NSLocalizedString("Keychain error while storing credentials.", comment: "Credentials Error") } - - } else { - self.errorMessageLabel.stringValue = NSLocalizedString("Invalid email/password combination.", comment: "Credentials Error") + self.hostWindow?.endSheet(self.window!, returnCode: NSApplication.ModalResponse.OK) + } catch { + self.errorMessageLabel.stringValue = NSLocalizedString("Keychain error while storing credentials.", comment: "Credentials Error") } - + case .failure: self.errorMessageLabel.stringValue = NSLocalizedString("Network error. Try again later.", comment: "Credentials Error") diff --git a/Mac/Preferences/Accounts/AccountsGoogleReaderCompatibleWindowController.swift b/Mac/Preferences/Accounts/AccountsGoogleReaderCompatibleWindowController.swift index a8471eba7..71072ae24 100644 --- a/Mac/Preferences/Accounts/AccountsGoogleReaderCompatibleWindowController.swift +++ b/Mac/Preferences/Accounts/AccountsGoogleReaderCompatibleWindowController.swift @@ -70,7 +70,7 @@ class AccountsGoogleReaderCompatibleWindowController: NSWindowController { return } - let credentials = Credentials.googleLogin(username: usernameTextField.stringValue, password: passwordTextField.stringValue, apiUrl: apiURL, apiKey: nil) + let credentials = Credentials.googleBasicLogin(username: usernameTextField.stringValue, password: passwordTextField.stringValue, url: apiURL) Account.validateCredentials(type: .googleReaderCompatible, credentials: credentials) { [weak self] result in guard let self = self else { return } @@ -80,42 +80,39 @@ class AccountsGoogleReaderCompatibleWindowController: NSWindowController { self.progressIndicator.stopAnimation(self) switch result { - case .success(let authenticated): + case .success(let validatedCredentials): + guard let validatedCredentials = validatedCredentials else { + self.errorMessageLabel.stringValue = NSLocalizedString("Invalid email/password combination.", comment: "Credentials Error") + return + } - if authenticated { - - var newAccount = false - if self.account == nil { - self.account = AccountManager.shared.createAccount(type: .googleReaderCompatible) - newAccount = true - } - - do { - try self.account?.removeBasicCredentials() - try self.account?.storeCredentials(credentials) - if newAccount { - self.account?.refreshAll() { result in - switch result { - case .success: - break - case .failure(let error): - NSApplication.shared.presentError(error) - } + + var newAccount = false + if self.account == nil { + self.account = AccountManager.shared.createAccount(type: .googleReaderCompatible) + newAccount = true + } + + do { + try self.account?.removeBasicCredentials() + try self.account?.storeCredentials(validatedCredentials) + if newAccount { + self.account?.refreshAll() { result in + switch result { + case .success: + break + case .failure(let error): + NSApplication.shared.presentError(error) } } - self.hostWindow?.endSheet(self.window!, returnCode: NSApplication.ModalResponse.OK) - } catch { - self.errorMessageLabel.stringValue = NSLocalizedString("Keychain error while storing credentials.", comment: "Credentials Error") } - - } else { - self.errorMessageLabel.stringValue = NSLocalizedString("Invalid email/password combination.", comment: "Credentials Error") + self.hostWindow?.endSheet(self.window!, returnCode: NSApplication.ModalResponse.OK) + } catch { + self.errorMessageLabel.stringValue = NSLocalizedString("Keychain error while storing credentials.", comment: "Credentials Error") } - + case .failure: - self.errorMessageLabel.stringValue = NSLocalizedString("Network error. Try again later.", comment: "Credentials Error") - } } diff --git a/submodules/RSWeb b/submodules/RSWeb index 261feb753..07ec7f917 160000 --- a/submodules/RSWeb +++ b/submodules/RSWeb @@ -1 +1 @@ -Subproject commit 261feb7537eb7c6dc425fd1c9e24b22dea8fc982 +Subproject commit 07ec7f9179dfdf7e89fc97a4a90c4690fa71581a