Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -93,14 +93,17 @@ open class FxAccountManager: @unchecked Sendable {
return state == .authenticationProblem
}

/// Set the user data before completing their authentication
public func setUserData(userData: UserData, completion: @Sendable @escaping () -> Void) {
public func handleWebChannelLogin(jsonPayload: String, completion: @Sendable @escaping () -> Void) {
DispatchQueue.global().async {
self.account?.setUserData(userData: userData)
try? self.account?.handleWebChannelLogin(jsonPayload: jsonPayload)
completion()
}
}

public func getSignedInUserForWebChannel() -> String? {
return account?.getSignedInUserForWebChannel()
}

/// Begins a new authentication flow.
///
/// This function returns a URL string that the caller should open in a webview.
Expand Down Expand Up @@ -211,16 +214,6 @@ open class FxAccountManager: @unchecked Sendable {
}
}

/// Get the session token associated with this account.
/// Note that you should have requested the `.session` scope earlier to be able to get this token.
public func getSessionToken() -> Result<String, Error> {
do {
return try .success(requireAccount().getSessionToken())
} catch {
return .failure(error)
}
}

/// Clear the access token cache for reauthentication.
public func clearAccessTokenCache() {
account?.clearAccessTokenCache()
Expand All @@ -235,12 +228,13 @@ open class FxAccountManager: @unchecked Sendable {
}
}

/// The account password has been changed locally and a new session token has been sent to us through WebChannel.
/// The account password has been changed locally; give the fxa component the data
/// we got so it can update the account state appopriately.
public func handlePasswordChanged(
newSessionToken: String,
jsonPayload: String,
completionHandler: @escaping @MainActor @Sendable () -> Void
) {
processEvent(event: .changedPassword(newSessionToken: newSessionToken)) {
processEvent(event: .changedPassword(jsonPayload: jsonPayload)) {
DispatchQueue.main.async { completionHandler() }
}
}
Expand Down Expand Up @@ -454,9 +448,9 @@ open class FxAccountManager: @unchecked Sendable {

return Event.fetchProfile(ignoreCache: false)
}
case let .changedPassword(newSessionToken): do {
case let .changedPassword(jsonPayload): do {
do {
try requireAccount().handleSessionTokenChange(sessionToken: newSessionToken)
try requireAccount().handleWebChannelPasswordChange(jsonPayload: jsonPayload)

FxALog.info("Initializing device")
requireConstellation().initDevice(
Expand All @@ -469,7 +463,7 @@ open class FxAccountManager: @unchecked Sendable {

return Event.fetchProfile(ignoreCache: false)
} catch {
FxALog.error("Error handling the session token change: \(error)")
FxALog.error("Error handling the password change: \(error)")
}
}
case let .fetchProfile(ignoreCache): do {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ enum Event {
case initialize
case accountNotFound
case accountRestored
case changedPassword(newSessionToken: String)
case changedPassword(jsonPayload: String)
case authenticated(authData: FxaAuthData)
case authenticationError /* (error: AuthException) */
case recoveredFromAuthenticationProblem
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,20 @@ class PersistedFirefoxAccount {
try inner.toJson()
}

func setUserData(userData: UserData) {
func handleWebChannelLogin(jsonPayload: String) throws {
defer { tryPersistState() }
inner.setUserData(userData: userData)
try inner.handleWebChannelLogin(jsonPayload: jsonPayload)
}

func getSignedInUserForWebChannel() -> String? {
return inner.getSignedInUserForWebChannel()
}

func handleWebChannelPasswordChange(jsonPayload: String) throws {
defer { tryPersistState() }
try notifyAuthErrors {
try self.inner.handleWebChannelPasswordChange(jsonPayload: jsonPayload)
}
}

func beginOAuthFlow(
Expand Down Expand Up @@ -218,20 +229,6 @@ class PersistedFirefoxAccount {
}
}

func getSessionToken() throws -> String {
defer { tryPersistState() }
return try notifyAuthErrors {
try self.inner.getSessionToken()
}
}

func handleSessionTokenChange(sessionToken: String) throws {
defer { tryPersistState() }
return try notifyAuthErrors {
try self.inner.handleSessionTokenChange(sessionToken: sessionToken)
}
}

func authorizeCodeUsingSessionToken(params: AuthorizationParameters) throws -> String {
defer { tryPersistState() }
return try notifyAuthErrors {
Expand Down
32 changes: 8 additions & 24 deletions firefox-ios/RustFxA/FxAWebViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import PDFKit

import enum MozillaAppServices.OAuthScope
import struct MozillaAppServices.FxaAuthData
import struct MozillaAppServices.UserData

enum FxAPageType: Equatable {
case emailLoginFlow
Expand Down Expand Up @@ -278,18 +277,10 @@ extension FxAWebViewModel {
)
case .login:
guard let data = data as? [String: Any],
let sessionToken = data["sessionToken"] as? String,
let email = data["email"] as? String,
let uid = data["uid"] as? String,
let verified = data["verified"] as? Bool
let jsonData = try? JSONSerialization.data(withJSONObject: data),
let jsonString = String(data: jsonData, encoding: .utf8)
else { return }
let userData = UserData(
sessionToken: sessionToken,
uid: uid,
email: email,
verified: verified
)
profile.rustFxA.accountManager?.setUserData(userData: userData) {}
profile.rustFxA.accountManager?.handleWebChannelLogin(jsonPayload: jsonString) {}
case .canLinkAccount:
if let id = id {
onCanLinkAccount(msgId: id, webView: webView)
Expand Down Expand Up @@ -333,19 +324,11 @@ extension FxAWebViewModel {
let data: String
switch pageType {
case .settingsPage:
// Both email and uid are required at this time to properly link the FxA settings session
let email = fxa.accountProfile()?.email ?? ""
let uid = fxa.accountProfile()?.uid ?? ""
let token = (try? fxa.getSessionToken().get()) ?? ""
let signedInUserJson = fxa.getSignedInUserForWebChannel() ?? "null"
data = """
{
capabilities: {},
signedInUser: {
sessionToken: "\(token)",
email: "\(email)",
uid: "\(uid)",
verified: true,
}
signedInUser: \(signedInUserJson),
}
"""
case .emailLoginFlow, .qrCode:
Expand Down Expand Up @@ -405,10 +388,11 @@ extension FxAWebViewModel {

private func onPasswordChange(data: Any, webView: WKWebView) {
guard let data = data as? [String: Any],
let sessionToken = data["sessionToken"] as? String
let jsonData = try? JSONSerialization.data(withJSONObject: data),
let jsonString = String(data: jsonData, encoding: .utf8)
else { return }

profile.rustFxA.accountManager?.handlePasswordChanged(newSessionToken: sessionToken) { [weak self] in
profile.rustFxA.accountManager?.handlePasswordChanged(jsonPayload: jsonString) { [weak self] in
NotificationCenter.default.post(name: .RegisterForPushNotifications, object: nil)
self?.profile.syncManager?.syncEverything(why: .enabledChange)
}
Expand Down
Loading