Skip to content

Commit

Permalink
Fix typo and move biometrics logic
Browse files Browse the repository at this point in the history
  • Loading branch information
bgoncal committed Nov 16, 2023
1 parent e300ba5 commit 3b3a134
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 83 deletions.
2 changes: 1 addition & 1 deletion Sources/App/Resources/en.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,7 @@ Home Assistant is free and open source home automation software with a focus on
"settings_details.general.visibility.title" = "Show App In…";
"settings_details.general.security.title" = "Security";
"settings_details.general.security.action" = "Enable biometric lock";
"settings_details.general.security.footer" = "You will be required to authenticate with biometrics everytime you open the app.";
"settings_details.general.security.footer" = "You will be required to authenticate with biometrics every time you open the app.";
"settings_details.location.background_refresh.disabled" = "Disabled";
"settings_details.location.background_refresh.enabled" = "Enabled";
"settings_details.location.background_refresh.title" = "Background Refresh";
Expand Down
81 changes: 0 additions & 81 deletions Sources/App/WebView/WebViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,6 @@ class WebViewController: UIViewController, WKNavigationDelegate, WKUIDelegate, U

var keepAliveTimer: Timer?
private var initialURL: URL?
private let biometricOverlay: UIView = {
let visualEffectView = UIVisualEffectView(effect: UIBlurEffect(style: .dark))
return visualEffectView
}()

static func viewController(
withRestorationIdentifierPath identifierComponents: [String],
Expand Down Expand Up @@ -251,34 +247,6 @@ class WebViewController: UIViewController, WKNavigationDelegate, WKUIDelegate, U

styleUI()
updateWebViewForServerValues()

if #available(iOS 13.0, *) {
NotificationCenter.default.addObserver(
self,
selector: #selector(checkForBiometrics),
name: UIScene.willEnterForegroundNotification,
object: nil
)
NotificationCenter.default.addObserver(
self,
selector: #selector(protectAppIfNeeded),
name: UIScene.didEnterBackgroundNotification,
object: nil
)
} else {
NotificationCenter.default.addObserver(
self,
selector: #selector(checkForBiometrics),
name: UIApplication.willEnterForegroundNotification,
object: nil
)
NotificationCenter.default.addObserver(
self,
selector: #selector(protectAppIfNeeded),
name: UIApplication.didEnterBackgroundNotification,
object: nil
)
}
}

public func showSettingsViewController() {
Expand Down Expand Up @@ -654,43 +622,6 @@ class WebViewController: UIViewController, WKNavigationDelegate, WKUIDelegate, U
decisionHandler(.grant)
}

@objc private func checkForBiometrics() {
if Current.settingsStore.biometricsRequired {
addBiometricOverlayProtection()
Current.authenticationService.delegate = self
Current.authenticationService.authenticate()
} else {
DispatchQueue.main.async { [weak self] in
self?.biometricOverlay.removeFromSuperview()
}
}
}

@objc private func protectAppIfNeeded() {
if Current.settingsStore.biometricsRequired {
addBiometricOverlayProtection()
} else {
DispatchQueue.main.async { [weak self] in
self?.biometricOverlay.removeFromSuperview()
}
}
}

private func addBiometricOverlayProtection() {
DispatchQueue.main.async { [weak self] in
guard let self else { return }
self.biometricOverlay.removeFromSuperview()
self.biometricOverlay.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(self.biometricOverlay)
NSLayoutConstraint.activate([
self.biometricOverlay.topAnchor.constraint(equalTo: self.view.topAnchor),
self.biometricOverlay.bottomAnchor.constraint(equalTo: self.view.bottomAnchor),
self.biometricOverlay.leadingAnchor.constraint(equalTo: self.view.leadingAnchor),
self.biometricOverlay.trailingAnchor.constraint(equalTo: self.view.trailingAnchor),
])
}
}

private func updateWebViewForServerValues() {
sidebarGestureRecognizer.isEnabled = server.info.version >= .externalBusCommandSidebar
}
Expand Down Expand Up @@ -1228,15 +1159,3 @@ extension ConnectionInfo {
}
}
}

extension WebViewController: AuthenticationServiceDelegate {
func didFinishAuthentication(authorized: Bool) {
if authorized {
DispatchQueue.main.async { [weak self] in
self?.biometricOverlay.removeFromSuperview()
}
} else {
addBiometricOverlayProtection()
}
}
}
90 changes: 90 additions & 0 deletions Sources/App/WebView/WebViewWindowController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ class WebViewWindowController {

private var webViewControllerSeal: (WebViewController) -> Void
private var onboardingPreloadWebViewController: WebViewController?
private let biometricOverlay: UIView = {
let visualEffectView = UIVisualEffectView(effect: UIBlurEffect(style: .dark))
return visualEffectView
}()

init(window: UIWindow, restorationActivity: NSUserActivity?) {
self.window = window
Expand Down Expand Up @@ -88,6 +92,8 @@ class WebViewWindowController {
restorationActivity = nil
}
}

listenForBiometricsLockRelatedEvents()
}

func present(_ viewController: UIViewController, animated: Bool = true, completion: (() -> Void)? = nil) {
Expand Down Expand Up @@ -407,6 +413,36 @@ class WebViewWindowController {
hud.hide(animated: true, afterDelay: 1.0)
}
}

private func listenForBiometricsLockRelatedEvents() {
if #available(iOS 13.0, *) {
NotificationCenter.default.addObserver(
self,
selector: #selector(checkForBiometrics),
name: UIScene.willEnterForegroundNotification,
object: nil
)
NotificationCenter.default.addObserver(
self,
selector: #selector(protectAppIfNeeded),
name: UIScene.didEnterBackgroundNotification,
object: nil
)
} else {
NotificationCenter.default.addObserver(
self,
selector: #selector(checkForBiometrics),
name: UIApplication.willEnterForegroundNotification,
object: nil
)
NotificationCenter.default.addObserver(
self,
selector: #selector(protectAppIfNeeded),
name: UIApplication.didEnterBackgroundNotification,
object: nil
)
}
}
}

extension WebViewWindowController: OnboardingStateObserver {
Expand Down Expand Up @@ -469,3 +505,57 @@ extension WebViewWindowController: OnboardingStateObserver {
}
}
}

// MARK: - Biometrics lock
extension WebViewWindowController {
@objc private func checkForBiometrics() {
if Current.settingsStore.biometricsRequired {
addBiometricOverlayProtection()
Current.authenticationService.delegate = self
Current.authenticationService.authenticate()
} else {
DispatchQueue.main.async { [weak self] in
self?.biometricOverlay.removeFromSuperview()
}
}
}

@objc private func protectAppIfNeeded() {
if Current.settingsStore.biometricsRequired {
addBiometricOverlayProtection()
} else {
DispatchQueue.main.async { [weak self] in
self?.biometricOverlay.removeFromSuperview()
}
}
}

private func addBiometricOverlayProtection() {
guard let view = window.rootViewController?.view else { return }
DispatchQueue.main.async { [weak self] in
guard let self else { return }
self.biometricOverlay.removeFromSuperview()
self.biometricOverlay.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(self.biometricOverlay)
NSLayoutConstraint.activate([
self.biometricOverlay.topAnchor.constraint(equalTo: view.topAnchor),
self.biometricOverlay.bottomAnchor.constraint(equalTo: view.bottomAnchor),
self.biometricOverlay.leadingAnchor.constraint(equalTo: view.leadingAnchor),
self.biometricOverlay.trailingAnchor.constraint(equalTo: view.trailingAnchor),
])
}
}
}

// MARK: - AuthenticationServiceDelegate
extension WebViewWindowController: AuthenticationServiceDelegate {
func didFinishAuthentication(authorized: Bool) {
if authorized {
DispatchQueue.main.async { [weak self] in
self?.biometricOverlay.removeFromSuperview()
}
} else {
addBiometricOverlayProtection()
}
}
}
2 changes: 1 addition & 1 deletion Sources/Shared/Resources/Swiftgen/Strings.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1347,7 +1347,7 @@ public enum L10n {
public enum Security {
/// Enable biometric lock
public static var action: String { return L10n.tr("Localizable", "settings_details.general.security.action") }
/// You will be required to authenticate with biometrics everytime you open the app.
/// You will be required to authenticate with biometrics every time you open the app.
public static var footer: String { return L10n.tr("Localizable", "settings_details.general.security.footer") }
/// Security
public static var title: String { return L10n.tr("Localizable", "settings_details.general.security.title") }
Expand Down

0 comments on commit 3b3a134

Please sign in to comment.