Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix AI Chat user script leak #3858

Merged
merged 2 commits into from
Jan 24, 2025
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
31 changes: 22 additions & 9 deletions DuckDuckGo/AIChat/AIChatViewControllerManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,35 +34,35 @@ final class AIChatViewControllerManager {
private var payloadHandler = AIChatPayloadHandler()
private let privacyConfigurationManager: PrivacyConfigurationManaging
private let internalUserDecider: InternalUserDecider

private weak var userContentController: UserContentController?

init(privacyConfigurationManager: PrivacyConfigurationManaging = ContentBlocking.shared.privacyConfigurationManager,
internalUserDecider: InternalUserDecider = AppDependencyProvider.shared.internalUserDecider) {
self.privacyConfigurationManager = privacyConfigurationManager
self.internalUserDecider = internalUserDecider
}

@MainActor
lazy var aiChatViewController: AIChatViewController = {
func openAIChat(_ query: URLQueryItem? = nil, payload: Any? = nil, on viewController: UIViewController) {
let settings = AIChatSettings(privacyConfigurationManager: privacyConfigurationManager,
internalUserDecider: internalUserDecider)

let webviewConfiguration = WKWebViewConfiguration.persistent()
let userContentController = UserContentController()
userContentController.delegate = self

webviewConfiguration.userContentController = userContentController
self.userContentController = userContentController
let aiChatViewController = AIChatViewController(settings: settings,
webViewConfiguration: webviewConfiguration)
aiChatViewController.delegate = self
return aiChatViewController
}()

@MainActor
func openAIChat(_ query: URLQueryItem? = nil, payload: Any? = nil, on viewController: UIViewController) {
let roundedPageSheet = RoundedPageSheetContainerViewController(
contentViewController: aiChatViewController,
allowedOrientation: .portrait)

roundedPageSheet.delegate = self

if let query = query {
aiChatViewController.loadQuery(query)
}
Expand All @@ -74,6 +74,13 @@ final class AIChatViewControllerManager {
}
viewController.present(roundedPageSheet, animated: true, completion: nil)
}

private func cleanUpUserContent() {
Task {
await userContentController?.removeAllContentRuleLists()
await userContentController?.cleanUpBeforeClosing()
}
}
}

extension AIChatViewControllerManager: UserContentControllerDelegate {
Expand All @@ -98,6 +105,12 @@ extension AIChatViewControllerManager: AIChatViewControllerDelegate {

func aiChatViewControllerDidFinish(_ viewController: AIChatViewController) {
viewController.dismiss(animated: true)

}
}

// MARK: - RoundedPageSheetContainerViewControllerDelegate
extension AIChatViewControllerManager: RoundedPageSheetContainerViewControllerDelegate {
func roundedPageSheetContainerViewControllerDidDisappear(_ controller: RoundedPageSheetContainerViewController) {
cleanUpUserContent()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,12 @@

import UIKit

protocol RoundedPageSheetContainerViewControllerDelegate: AnyObject {
func roundedPageSheetContainerViewControllerDidDisappear(_ controller: RoundedPageSheetContainerViewController)
}

final class RoundedPageSheetContainerViewController: UIViewController {
weak var delegate: RoundedPageSheetContainerViewControllerDelegate?
let contentViewController: UIViewController
private let allowedOrientation: UIInterfaceOrientationMask
let backgroundView = UIView()
Expand Down Expand Up @@ -59,6 +64,11 @@ final class RoundedPageSheetContainerViewController: UIViewController {
setupContentViewController()
}

override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
delegate?.roundedPageSheetContainerViewControllerDidDisappear(self)
}

@objc private func handlePanGesture(_ gesture: UIPanGestureRecognizer) {
let translation = gesture.translation(in: view)
let velocity = gesture.velocity(in: view)
Expand Down Expand Up @@ -123,10 +133,6 @@ final class RoundedPageSheetContainerViewController: UIViewController {
let panGesture = UIPanGestureRecognizer(target: self, action: #selector(handlePanGesture(_:)))
contentViewController.view.addGestureRecognizer(panGesture)
}

@objc func closeController() {
dismiss(animated: true, completion: nil)
}
}

extension RoundedPageSheetContainerViewController: UIViewControllerTransitioningDelegate {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,22 +80,8 @@ extension AIChatViewController {
super.viewDidLoad()
self.view.backgroundColor = .black
setupTitleBar()
}

public override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
addWebViewController()
}

public override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
removeWebViewController()
}

public override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
removeWebViewController()
}
}

// MARK: - Public functions
Expand Down
Loading