250 lines
10 KiB
Swift
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
|
|
}
|
|
}
|
|
}
|