Files
2022-04-25 07:28:13 +00:00

250 lines
10 KiB
Swift

//
// ProtocolPreferencesPresenter.swift
// Cyberlock
//
// Created by Jura on 9/23/19.
// Copyright © 2019 Omicronmedia. All rights reserved.
//
import Foundation
final class ProtocolPreferencesPresenter: ProtocolPreferencesViewOutput {
private struct Constants {
static let idProtocols = 2000
// static let idScramble = 2100
static let idPort = 2200
//
static let protocols = [PreferenceOptionsValue(title: "UDP", value: "UDP"),
PreferenceOptionsValue(title: "TCP", value: "TCP")
]
static let ports = [PreferenceOptionsValue(title: "1194", value: 1194),
PreferenceOptionsValue(title: "443", value: 443),
PreferenceOptionsValue(title: "8080", value: 8080),
PreferenceOptionsValue(title: "8443", value: 8443)]
static let notificationColor = 16759040 // #color(FFB900)
}
weak var viewInput: ProtocolPreferencesViewInput? {
didSet {
guard let session = try? Session.instance(),
let viewInput = self.viewInput else {
self.viewInput?.selection(enabled: false)
return
}
ProtocolPreferencesPresenter.updateEnableStateView(viewInput: viewInput, session: session)
}
}
init(output: Any?) {
// self.output = output
guard let session = try? Session.instance() else { return }
session.vpnConnectionStateEmitter.addReaction { [weak self, weak session] state, _ in
guard let session = session else {
self?.viewInput?.selection(enabled: false)
return self.isExist
}
self?.viewInput?.selection(enabled: state == .disconnected && session.currentRecord.isExist)
return self.isExist
}
session.sessionEmitter.addReaction { [weak self] sessionRecord -> ShouldContinueReceiveNotifications in
self?.viewInput?.selection(enabled: sessionRecord.isExist)
if !sessionRecord.isExist
, let proto = ProtocolPreferencesPresenter.protocols[safe: 0] {
UserSettings.shared.vpnType = proto.type
self?.viewInput?.selected(proto)
}
return self.isExist
}
}
// MARK: - Private
private static func updateEnableStateView(viewInput: ProtocolPreferencesViewInput, session: Session) {
if let value = session.vpnConnectionStateEmitter.value {
viewInput.selection(enabled: value.0 == .disconnected && session.currentRecord.isExist)
} else {
viewInput.selection(enabled: false)
}
if !session.currentRecord.isExist,
let proto = ProtocolPreferencesPresenter.protocols[safe: 0] {
UserSettings.shared.vpnType = proto.type
viewInput.selected(proto)
}
}
private static func option(by identity: Int) -> PreferenceOptions {
switch identity {
case Constants.idProtocols:
return PreferenceOptions.menu(Constants.idProtocols,
NSLocalizedString("preference.protocol.openVPN.options.protocol.title", comment: ""),
Constants.protocols.firstIndex(where: { $0.value as? String == UserSettings.shared.proto }) ?? 0,
Constants.protocols)
/*case Constants.scrambleID:
return PreferenceOptions.toggle(Constants.scrambleID,
UserSettings.shared.scramble,
PreferenceOptionsValue(title: "Scramble", value: nil))*/
case Constants.idPort:
return PreferenceOptions.menu(Constants.idPort,
NSLocalizedString("preference.protocol.openVPN.options.port.title", comment: ""),
Constants.ports.firstIndex(where: { $0.value as? Int == Int(UserSettings.shared.port) }) ?? 1194,
Constants.ports)
default:
return .empty
}
}
private static var protocols: [ProtocolPreferenceRecord] {
let options = [
self.option(by: Constants.idProtocols),
self.option(by: Constants.idPort)
]
let enableOpenVPN: Bool
let ovpnDescription: String
if #available(OSX 10.14, *) {
enableOpenVPN = true
ovpnDescription = NSLocalizedString("preference.protocol.openVPN.description", comment: "")
} else {
enableOpenVPN = false
ovpnDescription = NSLocalizedString("preference.protocol.openVPN.description.disabled", comment: "")
}
let enableWireguard: Bool
let wireguardDescription: String
if #available(OSX 10.15, *) {
enableWireguard = true
wireguardDescription = NSLocalizedString("preference.protocol.wireguard.description", comment: "")
} else {
enableWireguard = false
wireguardDescription = NSLocalizedString("preference.protocol.wireguard.description.disabled", comment: "")
}
let enabledWG = UserDefaults.standard.bool(forKey: PrivadoConstants.WireGuard.tunnelIdentifier)
let notificationWG: ProtocolPreferenceNotification?
if !enabledWG, enableWireguard {
notificationWG = .image(named: "exclamation",
text: NSLocalizedString("preference.protocol.wireguard.notification", comment: ""),
color: Constants.notificationColor)
} else {
notificationWG = nil
}
return [
ProtocolPreferenceRecord(title: NSLocalizedString("preference.protocol.automatic.title", comment: ""),
description: NSLocalizedString("preference.protocol.automatic.description", comment: ""),
enabled: true,
type: .automatic,
options: nil,
notification: nil),
ProtocolPreferenceRecord(title: NSLocalizedString("preference.protocol.ikev2.title", comment: ""),
description: NSLocalizedString("preference.protocol.ikev2.description", comment: ""),
enabled: true,
type: .ikev2,
options: nil,
notification: nil),
ProtocolPreferenceRecord(title: NSLocalizedString("preference.protocol.wireguard.title", comment: ""),
description: wireguardDescription,
enabled: enableWireguard,
type: .wireGuard,
options: nil,
notification: notificationWG),
ProtocolPreferenceRecord(title: NSLocalizedString("preference.protocol.openVPN.title", comment: ""),
description: ovpnDescription,
enabled: enableOpenVPN,
type: .openVPN,
options: options,
notification: nil)
]
}
private func update(value index: Int, with identity: Int) {
let option = ProtocolPreferencesPresenter.option(by: identity)
guard case let .menu(_, _, _, values) = option
, values.count > index else {
return
}
if identity == Constants.idProtocols
, let value = values[safe: index]?.value as? String {
UserSettings.shared.proto = value
}
if identity == Constants.idPort
, let value = values[safe: index]?.value as? Int {
UserSettings.shared.port = Int16(value)
}
CometLogger.shared.event(name: PrivadoConstants.Event.Statistic.Application.settings,
attributes: [PrivadoConstants.Event.Attributes.proto: UserSettings.shared.proto,
PrivadoConstants.Event.Attributes.port: UserSettings.shared.port],
secured: nil)
}
private func update(value enable: Bool, with identity: Int) {
/*guard identity == Constants.scrambleID else { return }
UserSettings.shared.scramble = enable*/
}
// MARK: - ProtocolPreferencesViewOutput
var titleLabelText: String { return "Server Protocols" }
func isReady() {
self.viewInput?.available(protocols: ProtocolPreferencesPresenter.protocols)
guard let record = ProtocolPreferencesPresenter.protocols.filter({ $0.type == UserSettings.shared.vpnType }).first
, let viewInput = self.viewInput else { return }
viewInput.selected(record)
if let session = try? Session.instance() {
ProtocolPreferencesPresenter.updateEnableStateView(viewInput: viewInput, session: session)
}
}
func select(_ record: ProtocolPreferenceRecord) {
guard let session = try? Session.instance()
, session.currentRecord.isExist else { return }
UserSettings.shared.vpnType = record.type
CometLogger.shared.event(name: PrivadoConstants.Event.Statistic.Application.settings,
attributes: [PrivadoConstants.Event.Attributes.vpn: record.type.description],
secured: nil)
}
func select(_ record: ProtocolPreferenceRecord, option: PreferenceOptions, enabled: Bool?, optionIndex: Int?) {
guard let session = try? Session.instance()
, session.currentRecord.isExist else { return }
guard record.type == .openVPN else { return }
switch option {
case let .menu(identity, _, _, _):
self.update(value: optionIndex ?? 0, with: identity)
case let .toggle(identity, _, _):
self.update(value: enabled ?? false, with: identity)
default:
break
}
}
}