diff --git a/BrowserKit/Sources/Common/Logger/LoggerCategory.swift b/BrowserKit/Sources/Common/Logger/LoggerCategory.swift index 1291b1fdd517..294dbc04cdaa 100644 --- a/BrowserKit/Sources/Common/Logger/LoggerCategory.swift +++ b/BrowserKit/Sources/Common/Logger/LoggerCategory.swift @@ -65,4 +65,7 @@ public enum LoggerCategory: String { /// Remote settings case remoteSettings + + /// Password Generator + case passwordGenerator } diff --git a/firefox-ios/Client/Frontend/PasswordGenerator/PasswordGeneratorMiddleware.swift b/firefox-ios/Client/Frontend/PasswordGenerator/PasswordGeneratorMiddleware.swift index 5671236ea897..2ae6d65061c1 100644 --- a/firefox-ios/Client/Frontend/PasswordGenerator/PasswordGeneratorMiddleware.swift +++ b/firefox-ios/Client/Frontend/PasswordGenerator/PasswordGeneratorMiddleware.swift @@ -95,16 +95,29 @@ final class PasswordGeneratorMiddleware { private func userTappedUsePassword(frame: WKFrameInfo, password: String) { passwordGeneratorTelemetry.usePasswordButtonPressed() - let jsFunctionCall = "window.__firefox__.logins.fillGeneratedPassword(\"\(password)\")" - frame.webView?.evaluateJavascriptInDefaultContentWorld(jsFunctionCall, frame) { (result, error) in - if error != nil { - self.logger.log("Error filling in password info", - level: .warning, - category: .webview) + if let escapedPassword = escapeString(string: password) { + let jsFunctionCall = "window.__firefox__.logins.fillGeneratedPassword(\(escapedPassword))" + frame.webView?.evaluateJavascriptInDefaultContentWorld(jsFunctionCall, frame) { (result, error) in + if error != nil { + self.logger.log("Error filling in password info", + level: .warning, + category: .passwordGenerator) + } } } } + private func escapeString(string: String) -> String? { + guard let jsonData = try? JSONEncoder().encode(string), + let jsonString = String(data: jsonData, encoding: .utf8) else { + self.logger.log("Error encoding generated password to JSON", + level: .warning, + category: .passwordGenerator) + return nil + } + return jsonString + } + private func userTappedRefreshPassword(frame: WKFrameInfo, windowUUID: WindowUUID) { guard let origin = frame.webView?.url?.origin else {return} generateNewPassword(frame: frame, completion: { generatedPassword in diff --git a/firefox-ios/Client/Frontend/PasswordGenerator/PasswordGeneratorViewController.swift b/firefox-ios/Client/Frontend/PasswordGenerator/PasswordGeneratorViewController.swift index e2c33e14c845..6a75d497d456 100644 --- a/firefox-ios/Client/Frontend/PasswordGenerator/PasswordGeneratorViewController.swift +++ b/firefox-ios/Client/Frontend/PasswordGenerator/PasswordGeneratorViewController.swift @@ -234,5 +234,7 @@ class PasswordGeneratorViewController: UIViewController, StoreSubscriber, Themea } extension PasswordGeneratorViewController: BottomSheetChild { - func willDismiss() { currentTab.webView?.accessoryView.reloadViewFor(.standard)} + func willDismiss() { + LoginsHelper.yieldFocusBackToField(with: currentTab) + } } diff --git a/firefox-ios/Client/Frontend/UserContent/UserScripts/AllFrames/AtDocumentStart/LoginsHelper.js b/firefox-ios/Client/Frontend/UserContent/UserScripts/AllFrames/AtDocumentStart/LoginsHelper.js index 20d799e110df..fdbe3b2eb044 100644 --- a/firefox-ios/Client/Frontend/UserContent/UserScripts/AllFrames/AtDocumentStart/LoginsHelper.js +++ b/firefox-ios/Client/Frontend/UserContent/UserScripts/AllFrames/AtDocumentStart/LoginsHelper.js @@ -468,11 +468,13 @@ window.__firefox__.includeOnce("LoginsHelper", function() { }; function fillGeneratedPassword(password) { + LoginManagerContent.fromFill = true this.yieldFocusBackToField(); const passwordField = LoginManagerContent.activeField; passwordField?.setUserInput(password); const confirmationField = Logic.findConfirmationField(passwordField, LoginFormFactory); confirmationField?.setUserInput(password); + LoginManagerContent.fromFill = false } function yieldFocusBackToField() { @@ -499,7 +501,7 @@ window.__firefox__.includeOnce("LoginsHelper", function() { const isPasswordField = field === password; const isYieldingFocus = LoginManagerContent.activeField === field; LoginManagerContent.activeField = field; - if (formHasNewPassword && isPasswordField && !isYieldingFocus) { + if (formHasNewPassword && isPasswordField && !LoginManagerContent.fromFill) { webkit.messageHandlers.loginsManagerMessageHandler.postMessage({ type: "generatePassword", });