Compare commits

...

28 Commits

Author SHA1 Message Date
a37ae8a99b Merge branch 'master' into an/shortcuts-integration 2024-02-28 10:28:12 +01:00
2f99f5c781 Remove backward compatibility of GetPeers with SiriKit version
Signed-off-by: Alessio Nossa <alessio.nossa@gmail.com>
2024-02-28 00:36:19 +01:00
8a2a4ebd9f Add backwards compatibility of GetPeers wit SiriKit version
Signed-off-by: Alessio Nossa <alessio.nossa@gmail.com>
2024-02-28 00:36:19 +01:00
06ed6e91ad Update AppIntents Strings
Signed-off-by: Alessio Nossa <alessio.nossa@gmail.com>
2024-02-28 00:36:18 +01:00
7da272a421 Rename constant to satisfy SwiftLint
Signed-off-by: Alessio Nossa <alessio.nossa@gmail.com>
2024-02-28 00:36:18 +01:00
56c4d6cc4d Remove missing peers error in UpdateTunnelConfiguration Intent
Signed-off-by: Alessio Nossa <alessio.nossa@gmail.com>
2024-02-28 00:36:18 +01:00
7abdf6eaf2 Fix return value of AppIntents in iOS 17
Signed-off-by: Alessio Nossa <alessio.nossa@gmail.com>
2024-02-28 00:36:17 +01:00
97bf1c1309 WireguardApp: macOS: Add App Intents to macOS app
Signed-off-by: Alessio Nossa <alessio.nossa@gmail.com>
2023-04-12 00:44:03 +02:00
ee035362ec Implement UpdateTunnelConfiguration App Intent
Signed-off-by: Alessio Nossa <alessio.nossa@gmail.com>
2023-04-12 00:44:02 +02:00
e13bc40f88 Implement BuildPeerConfigurationUpdate App Intent
Signed-off-by: Alessio Nossa <alessio.nossa@gmail.com>
2023-04-12 00:44:02 +02:00
eec11c1eef Remove UpdateConfiguration Intent with Dictionary input
Signed-off-by: Alessio Nossa <alessio.nossa@gmail.com>
2023-04-12 00:44:02 +02:00
ba250fe1a5 Implement UpdateConfiguration AppIntent with Dictionary as input
Signed-off-by: Alessio Nossa <alessio.nossa@gmail.com>
2023-04-12 00:44:02 +02:00
1cb06536f1 WireguardApp: Add async variant of modify tunnel function
Signed-off-by: Alessio Nossa <alessio.nossa@gmail.com>
2023-04-12 00:44:02 +02:00
a0a6f26846 WireguardApp: iOS: Cleanup after SiriKit Intents removal
Signed-off-by: Alessio Nossa <alessio.nossa@gmail.com>
2023-04-12 00:44:01 +02:00
c1d7199f85 Remove WireGuardIntentsExtension
Signed-off-by: Alessio Nossa <alessio.nossa@gmail.com>
2023-04-12 00:09:21 +02:00
d05a1693e2 Removed UpdateConfigurationIntent SiriKit Intent
Signed-off-by: Alessio Nossa <alessio.nossa@gmail.com>
2023-04-12 00:09:21 +02:00
bee5d346b1 Implement GetPeers AppIntent
Signed-off-by: Alessio Nossa <alessio.nossa@gmail.com>
2023-04-12 00:09:21 +02:00
2952206138 Remove GetPeers SiriKit Intent
Signed-off-by: Alessio Nossa <alessio.nossa@gmail.com>
2023-04-05 13:42:56 +02:00
7ec6974005 Complete cleanup after SetTunnelStatus Intent removal
Signed-off-by: Alessio Nossa <alessio.nossa@gmail.com>
2023-04-01 16:12:32 +02:00
63c09565f2 Removed SetTunnelStatus
Signed-off-by: Alessio Nossa <alessio.nossa@gmail.com>
2023-04-01 16:00:24 +02:00
c29787f898 WireguardApp: iOS: Added Siri shortcuts donations for SetTunnelStatus intent
Signed-off-by: Alessio Nossa <alessio.nossa@gmail.com>
2022-02-01 20:14:21 +01:00
bb6ea1b2f3 Implemented SetTunnelStatus intent
Signed-off-by: Alessio Nossa <alessio.nossa@gmail.com>
2022-02-01 20:14:02 +01:00
fe3f2d089b Implemented UpdateConfiguration intent
Signed-off-by: Alessio Nossa <alessio.nossa@gmail.com>
2022-02-01 20:13:38 +01:00
ceabb4ea34 WireguardApp: iOS: Moved tunnelsManager initialization to AppDelegate
Signed-off-by: Alessio Nossa <alessio.nossa@gmail.com>
2022-02-01 20:13:13 +01:00
ab1e96fcdc Implemented GetPeers intent
Signed-off-by: Alessio Nossa <alessio.nossa@gmail.com>
2022-02-01 20:12:47 +01:00
0dd0672844 project: Added sources to WireGuardIntentsExtensioniOS
Signed-off-by: Alessio Nossa <alessio.nossa@gmail.com>
2022-02-01 20:12:15 +01:00
3c63c386b9 project: Added WireGuardIntentsExtensioniOS target and Siri capability
Signed-off-by: Alessio Nossa <alessio.nossa@gmail.com>
2022-02-01 20:11:33 +01:00
a0fe44d214 Automatic configuration files changes by Xcode
Signed-off-by: Alessio Nossa <alessio.nossa@gmail.com>
2022-02-01 20:10:59 +01:00
11 changed files with 442 additions and 44 deletions

View File

@ -206,6 +206,7 @@ class TunnelsManager {
}
}
@available(*, renamed: "modify(tunnel:tunnelConfiguration:onDemandOption:shouldEnsureOnDemandEnabled:)")
func modify(tunnel: TunnelContainer, tunnelConfiguration: TunnelConfiguration,
onDemandOption: ActivateOnDemandOption,
shouldEnsureOnDemandEnabled: Bool = false,
@ -299,6 +300,22 @@ class TunnelsManager {
}
}
@available(iOS 13.0, macOS 10.15.0, *)
func modify(tunnel: TunnelContainer, tunnelConfiguration: TunnelConfiguration,
onDemandOption: ActivateOnDemandOption,
shouldEnsureOnDemandEnabled: Bool = false) async throws {
return try await withCheckedThrowingContinuation { continuation in
modify(tunnel: tunnel, tunnelConfiguration: tunnelConfiguration, onDemandOption: onDemandOption, shouldEnsureOnDemandEnabled: shouldEnsureOnDemandEnabled) { error in
if let error = error {
continuation.resume(throwing: error)
return
}
continuation.resume(returning: ())
}
}
}
func remove(tunnel: TunnelContainer, completionHandler: @escaping (TunnelsManagerError?) -> Void) {
let tunnelProviderManager = tunnel.tunnelProvider
#if os(macOS)

View File

@ -3,6 +3,7 @@
import UIKit
import os.log
import AppIntents
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
@ -11,6 +12,10 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
var mainVC: MainViewController?
var isLaunchedForSpecificAction = false
var tunnelsManager: TunnelsManager?
static let tunnelsManagerReadyNotificationName: Notification.Name = Notification.Name(rawValue: "com.wireguard.ios.tunnelsManagerReadyNotification")
func application(_ application: UIApplication, willFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
Logger.configureGlobal(tagged: "APP", withFilePath: FileManager.logFileURL?.path)
@ -29,6 +34,29 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
self.mainVC = mainVC
// Create the tunnels manager, and when it's ready, inform tunnelsListVC
TunnelsManager.create { [weak self] result in
guard let self = self else { return }
switch result {
case .failure(let error):
ErrorPresenter.showErrorAlert(error: error, from: self.mainVC)
case .success(let tunnelsManager):
self.tunnelsManager = tunnelsManager
self.mainVC?.tunnelsListVC?.setTunnelsManager(tunnelsManager: tunnelsManager)
tunnelsManager.activationDelegate = self.mainVC
if #available(iOS 16.0, *) {
AppDependencyManager.shared.add(dependency: tunnelsManager)
}
NotificationCenter.default.post(name: AppDelegate.tunnelsManagerReadyNotificationName,
object: self,
userInfo: nil)
}
}
return true
}

View File

@ -2,10 +2,10 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundleDocumentTypes</key>
<array>
<dict>
@ -64,8 +64,6 @@
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleDisplayName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
@ -74,17 +72,22 @@
<string>$(VERSION_NAME)</string>
<key>CFBundleVersion</key>
<string>$(VERSION_ID)</string>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>LSSupportsOpeningDocumentsInPlace</key>
<false/>
<key>NSCameraUsageDescription</key>
<string>Localized</string>
<key>NSFaceIDUsageDescription</key>
<string>Localized</string>
<key>NSUserActivityTypes</key>
<array/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
</array>
<array/>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
@ -123,8 +126,6 @@
</dict>
</dict>
</array>
<key>NSFaceIDUsageDescription</key>
<string>Localized</string>
<key>com.wireguard.ios.app_group_id</key>
<string>group.$(APP_ID_IOS)</string>
</dict>

View File

@ -5,7 +5,9 @@ import UIKit
class MainViewController: UISplitViewController {
var tunnelsManager: TunnelsManager?
var tunnelsManager: TunnelsManager? {
return (UIApplication.shared.delegate as? AppDelegate)?.tunnelsManager
}
var onTunnelsManagerReady: ((TunnelsManager) -> Void)?
var tunnelsListVC: TunnelsListTableViewController?
@ -38,29 +40,24 @@ class MainViewController: UISplitViewController {
// On iPad, always show both masterVC and detailVC, even in portrait mode, like the Settings app
preferredDisplayMode = .allVisible
// Create the tunnels manager, and when it's ready, inform tunnelsListVC
TunnelsManager.create { [weak self] result in
guard let self = self else { return }
switch result {
case .failure(let error):
ErrorPresenter.showErrorAlert(error: error, from: self)
case .success(let tunnelsManager):
self.tunnelsManager = tunnelsManager
self.tunnelsListVC?.setTunnelsManager(tunnelsManager: tunnelsManager)
tunnelsManager.activationDelegate = self
self.onTunnelsManagerReady?(tunnelsManager)
self.onTunnelsManagerReady = nil
}
}
NotificationCenter.default.addObserver(self, selector: #selector(handleTunnelsManagerReady(_:)),
name: AppDelegate.tunnelsManagerReadyNotificationName, object: nil)
}
func allTunnelNames() -> [String]? {
guard let tunnelsManager = self.tunnelsManager else { return nil }
return tunnelsManager.mapTunnels { $0.name }
}
@objc
func handleTunnelsManagerReady(_ notification: Notification) {
guard let tunnelsManager = self.tunnelsManager else { return }
self.onTunnelsManagerReady?(tunnelsManager)
self.onTunnelsManagerReady = nil
NotificationCenter.default.removeObserver(self, name: AppDelegate.tunnelsManagerReadyNotificationName, object: nil)
}
}
extension MainViewController: TunnelsManagerActivationDelegate {

View File

@ -3,6 +3,7 @@
import Cocoa
import ServiceManagement
import AppIntents
@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
@ -58,6 +59,10 @@ class AppDelegate: NSObject, NSApplicationDelegate {
self.tunnelsTracker = tunnelsTracker
self.statusItemController = statusItemController
if #available(macOS 13.0, *) {
AppDependencyManager.shared.add(dependency: tunnelsManager)
}
if !isLaunchedAtLogin {
self.showManageTunnelsWindow(completion: nil)
}

View File

@ -0,0 +1,35 @@
// SPDX-License-Identifier: MIT
// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved.
// App Intents Common
"wireguardAppIntentsWrongTunnelError %@" = "Cannot find a tunnel with the name \"%1$@\"";
"wireguardAppIntentsMissingConfigurationError" = "The selected tunnel has no configuration.";
// Get peers Intent
"getPeersIntentName" = "Get Peers";
"getPeersIntentDescription" = "Get list of public keys of peers in the selected configuration";
"getPeersIntentTunnelParameterTitle" = "Tunnel";
"getPeersIntentSummary ${tunnelName}" = "Get peers of ${tunnelName}";
// Tunnel Configuration Update
"updateTunnelConfigurationIntentName" = "Update Tunnel Configuration";
"updateTunnelConfigurationDescription" = "Update peers configuration of the selected tunnel.";
"updateTunnelConfigurationIntentTunnelParameterTitle" = "Tunnel";
"updateTunnelConfigurationIntentPeersParameterTitle" = "Peers";
"updateTunnelConfigurationIntentMergeParameterTitle" = "Merge configuration";
"updateTunnelConfigurationIntentSummary ${tunnelName}" = "Update ${tunnelName} configuration";
"updateTunnelConfigurationIntentPeerOptionsUnavailableError" = "Use the output of \"Build Peer Configuration\" action to update tunnel configuration. To update multiple peers at once, you can use the \"Add to Variable\" action and pass the resulting Variable in this field.";
"updateTunnelConfigurationIntentMalformedPublicKeyError %@" = "The key \"%1$@\" is not a valid Public Key encoded in Base64 format.";
// Build Peer Configuration
"buildPeerConfigurationUpdateIntentName" = "Build Peer Configuration";
"buildPeerConfigurationUpdateIntentDescription" = "Build an item that contains the informations needed to update an peer's configuration.";
"buildPeerConfigurationUpdateIntentSummary ${publicKey}" = "Build configuration for peer ${publicKey}";
"buildPeerConfigurationUpdateIntentPublicKeyParameterTitle" = "Peer Public Key";
"buildPeerConfigurationUpdateIntentEndpointParameterTitle" = "Endpoint";
// Peer Configuration Update Entity
"peerConfigurationUpdateEntityName" = "Configuration Update - Peer";
"peerConfigurationUpdateEntityPropertyPublicKeyTitle" = "Public Key";
"peerConfigurationUpdateEntityPropertyEndpointTitle" = "Endpoint";

View File

@ -0,0 +1,77 @@
// SPDX-License-Identifier: MIT
// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved.
import AppIntents
@available(iOS 16.0, macOS 13.0, watchOS 9.0, tvOS 16.0, *)
struct BuildPeerConfigurationUpdate: AppIntent {
static var title = LocalizedStringResource("buildPeerConfigurationUpdateIntentName", table: "AppIntents")
static var description = IntentDescription(
LocalizedStringResource("buildPeerConfigurationUpdateIntentDescription", table: "AppIntents")
)
@Parameter(
title: LocalizedStringResource("buildPeerConfigurationUpdateIntentPublicKeyParameterTitle", table: "AppIntents")
)
var publicKey: String
@Parameter(
title: LocalizedStringResource("buildPeerConfigurationUpdateIntentEndpointParameterTitle", table: "AppIntents")
)
var endpoint: String
func perform() async throws -> some IntentResult & ReturnsValue<AppIntentsPeer> {
let peerConfigurationUpdate = AppIntentsPeer()
peerConfigurationUpdate.publicKey = publicKey
peerConfigurationUpdate.endpoint = endpoint
return .result(value: peerConfigurationUpdate)
}
static var parameterSummary: some ParameterSummary {
Summary("buildPeerConfigurationUpdateIntentSummary \(\.$publicKey)", table: "AppIntents") {
\.$endpoint
}
}
}
@available(iOS 16.0, macOS 13.0, watchOS 9.0, tvOS 16.0, *)
struct AppIntentsPeer: TransientAppEntity {
static let kEndpointConfigUpdateDictionaryKey = "Endpoint"
static var typeDisplayRepresentation = TypeDisplayRepresentation(
name: LocalizedStringResource("peerConfigurationUpdateEntityName", table: "AppIntents")
)
@Property(
title: LocalizedStringResource("peerConfigurationUpdateEntityPropertyPublicKeyTitle", table: "AppIntents")
)
var publicKey: String
@Property(
title: LocalizedStringResource("peerConfigurationUpdateEntityPropertyEndpointTitle", table: "AppIntents")
)
var endpoint: String?
var displayRepresentation: DisplayRepresentation {
var dictionary: [String: [String: String]] = [:]
dictionary[publicKey] = [:]
if let endpoint {
dictionary[publicKey]?.updateValue(endpoint, forKey: Self.kEndpointConfigUpdateDictionaryKey)
}
let jsonData: Data
do {
jsonData = try JSONSerialization.data(withJSONObject: dictionary)
} catch {
return DisplayRepresentation(stringLiteral: error.localizedDescription)
}
let jsonString = String(data: jsonData, encoding: .utf8)!
return DisplayRepresentation(stringLiteral: jsonString)
}
}

View File

@ -0,0 +1,55 @@
// SPDX-License-Identifier: MIT
// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved.
import Foundation
import AppIntents
@available(iOS 16.0, macOS 13.0, watchOS 9.0, tvOS 16.0, *)
struct GetPeers: AppIntent {
static var title = LocalizedStringResource("getPeersIntentName", table: "AppIntents")
static var description = IntentDescription(
LocalizedStringResource("getPeersIntentDescription", table: "AppIntents")
)
@Parameter(
title: LocalizedStringResource("getPeersIntentTunnelParameterTitle", table: "AppIntents"),
optionsProvider: TunnelsOptionsProvider()
)
var tunnelName: String
@Dependency
var tunnelsManager: TunnelsManager
func perform() async throws -> some IntentResult & ReturnsValue<[String]> {
guard let tunnelContainer = tunnelsManager.tunnel(named: tunnelName) else {
throw GetPeersIntentError.wrongTunnel(name: tunnelName)
}
guard let tunnelConfiguration = tunnelContainer.tunnelConfiguration else {
throw GetPeersIntentError.missingConfiguration
}
let publicKeys = tunnelConfiguration.peers.map { $0.publicKey.base64Key }
return .result(value: publicKeys)
}
static var parameterSummary: some ParameterSummary {
Summary("getPeersIntentSummary \(\.$tunnelName)", table: "AppIntents")
}
}
@available(iOS 16.0, macOS 13.0, watchOS 9.0, tvOS 16.0, *)
enum GetPeersIntentError: Swift.Error, CustomLocalizedStringResourceConvertible {
case wrongTunnel(name: String)
case missingConfiguration
var localizedStringResource: LocalizedStringResource {
switch self {
case .wrongTunnel(let name):
return LocalizedStringResource("wireguardAppIntentsWrongTunnelError \(name)", table: "AppIntents")
case .missingConfiguration:
return LocalizedStringResource("wireguardAppIntentsMissingConfigurationError", table: "AppIntents")
}
}
}

View File

@ -0,0 +1,15 @@
// SPDX-License-Identifier: MIT
// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved.
import AppIntents
@available(iOS 16.0, macOS 13.0, watchOS 9.0, tvOS 16.0, *)
struct TunnelsOptionsProvider: DynamicOptionsProvider {
@Dependency
var tunnelsManager: TunnelsManager
func results() async throws -> [String] {
let tunnelsNames = tunnelsManager.mapTunnels { $0.name }
return tunnelsNames
}
}

View File

@ -0,0 +1,131 @@
// SPDX-License-Identifier: MIT
// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved.
import AppIntents
@available(iOS 16.0, macOS 13.0, watchOS 9.0, tvOS 16.0, *)
struct UpdateTunnelConfiguration: AppIntent {
static var title = LocalizedStringResource("updateTunnelConfigurationIntentName", table: "AppIntents")
static var description = IntentDescription(
LocalizedStringResource("updateTunnelConfigurationDescription", table: "AppIntents")
)
@Parameter(
title: LocalizedStringResource("updateTunnelConfigurationIntentTunnelParameterTitle", table: "AppIntents"),
optionsProvider: TunnelsOptionsProvider()
)
var tunnelName: String
@Parameter(
title: LocalizedStringResource("updateTunnelConfigurationIntentPeersParameterTitle", table: "AppIntents"),
optionsProvider: AppIntentsPeerOptionsProvider()
)
var peers: [AppIntentsPeer]?
@Parameter(
title: LocalizedStringResource("updateTunnelConfigurationIntentMergeParameterTitle", table: "AppIntents"),
default: true
)
var mergeConfiguration: Bool
@Dependency
var tunnelsManager: TunnelsManager
func perform() async throws -> some IntentResult {
let peers = peers ?? []
guard let tunnelContainer = tunnelsManager.tunnel(named: tunnelName) else {
throw AppIntentConfigurationUpdateError.wrongTunnel(name: tunnelName)
}
guard let tunnelConfiguration = tunnelContainer.tunnelConfiguration else {
throw AppIntentConfigurationUpdateError.missingConfiguration
}
let newConfiguration = try buildNewConfiguration(from: tunnelConfiguration, peersUpdates: peers, mergeChanges: mergeConfiguration)
do {
try await tunnelsManager.modify(tunnel: tunnelContainer, tunnelConfiguration: newConfiguration, onDemandOption: tunnelContainer.onDemandOption)
} catch {
wg_log(.error, message: error.localizedDescription)
throw error
}
wg_log(.debug, message: "Updated configuration of tunnel \(tunnelName)")
return .result()
}
static var parameterSummary: some ParameterSummary {
Summary("updateTunnelConfigurationIntentSummary \(\.$tunnelName)", table: "AppIntents") {
\.$peers
\.$mergeConfiguration
}
}
private func buildNewConfiguration(from oldConfiguration: TunnelConfiguration, peersUpdates: [AppIntentsPeer], mergeChanges: Bool) throws -> TunnelConfiguration {
var peers = oldConfiguration.peers
for peerUpdate in peersUpdates {
let peerIndex: Array<PeerConfiguration>.Index
if let foundIndex = peers.firstIndex(where: { $0.publicKey.base64Key == peerUpdate.publicKey }) {
peerIndex = foundIndex
if mergeChanges == false {
peers[peerIndex] = PeerConfiguration(publicKey: peers[peerIndex].publicKey)
}
} else {
wg_log(.debug, message: "Failed to find peer \(peerUpdate.publicKey) in tunnel with name \(tunnelName). Adding it.")
guard let pubKeyEncoded = PublicKey(base64Key: peerUpdate.publicKey) else {
throw AppIntentConfigurationUpdateError.malformedPublicKey(key: peerUpdate.publicKey)
}
let newPeerConfig = PeerConfiguration(publicKey: pubKeyEncoded)
peerIndex = peers.endIndex
peers.append(newPeerConfig)
}
if let endpointString = peerUpdate.endpoint {
if let newEntpoint = Endpoint(from: endpointString) {
peers[peerIndex].endpoint = newEntpoint
} else {
wg_log(.debug, message: "Failed to convert \(endpointString) to Endpoint")
}
}
}
let newConfiguration = TunnelConfiguration(name: oldConfiguration.name, interface: oldConfiguration.interface, peers: peers)
return newConfiguration
}
}
@available(iOS 16.0, macOS 13.0, watchOS 9.0, tvOS 16.0, *)
struct AppIntentsPeerOptionsProvider: DynamicOptionsProvider {
func results() async throws -> ItemCollection<AppIntentsPeer> {
// The error thrown here is not displayed correctly to the user. A Feedback
// has been opened (FB12098463).
throw AppIntentConfigurationUpdateError.peerOptionsUnavailable
}
}
@available(iOS 16.0, macOS 13.0, watchOS 9.0, tvOS 16.0, *)
enum AppIntentConfigurationUpdateError: Swift.Error, CustomLocalizedStringResourceConvertible {
case wrongTunnel(name: String)
case missingConfiguration
case peerOptionsUnavailable
case malformedPublicKey(key: String)
var localizedStringResource: LocalizedStringResource {
switch self {
case .wrongTunnel(let name):
return LocalizedStringResource("wireguardAppIntentsWrongTunnelError \(name)", table: "AppIntents")
case .missingConfiguration:
return LocalizedStringResource("wireguardAppIntentsMissingConfigurationError", table: "AppIntents")
case .peerOptionsUnavailable:
return LocalizedStringResource("updateTunnelConfigurationIntentPeerOptionsUnavailableError", table: "AppIntents")
case .malformedPublicKey(let malformedKey):
return LocalizedStringResource("updateTunnelConfigurationIntentMalformedPublicKeyError \(malformedKey)", table: "AppIntents")
}
}
}

View File

@ -205,6 +205,16 @@
6FFA5DA021958ECC0001E2F7 /* ErrorNotifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FFA5D9F21958ECC0001E2F7 /* ErrorNotifier.swift */; };
6FFA5DA42197085D0001E2F7 /* ActivateOnDemandOption.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FFA5DA32197085D0001E2F7 /* ActivateOnDemandOption.swift */; };
6FFACD2021E4D8D500E9A2A5 /* ParseError+WireGuardAppError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FFACD1E21E4D89600E9A2A5 /* ParseError+WireGuardAppError.swift */; };
A25DF37029E60E870094E89B /* BuildPeerConfigurationUpdate.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6E361FB29D9AEEA00FFF234 /* BuildPeerConfigurationUpdate.swift */; };
A25DF37129E60E8C0094E89B /* UpdateTunnelConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6E361F929D9821100FFF234 /* UpdateTunnelConfiguration.swift */; };
A25DF37229E60E8F0094E89B /* GetPeers.swift in Sources */ = {isa = PBXBuildFile; fileRef = A625F05029C4C627005EF23D /* GetPeers.swift */; };
A25DF37329E60E930094E89B /* AppIntents.strings in Resources */ = {isa = PBXBuildFile; fileRef = A6E361F729D8758500FFF234 /* AppIntents.strings */; };
A25DF37429E60E960094E89B /* TunnelsOptionsProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6E361FD29D9B18C00FFF234 /* TunnelsOptionsProvider.swift */; };
A625F05529C4C627005EF23D /* GetPeers.swift in Sources */ = {isa = PBXBuildFile; fileRef = A625F05029C4C627005EF23D /* GetPeers.swift */; };
A6E361F829D8758500FFF234 /* AppIntents.strings in Resources */ = {isa = PBXBuildFile; fileRef = A6E361F729D8758500FFF234 /* AppIntents.strings */; };
A6E361FA29D9821200FFF234 /* UpdateTunnelConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6E361F929D9821100FFF234 /* UpdateTunnelConfiguration.swift */; };
A6E361FC29D9AEEA00FFF234 /* BuildPeerConfigurationUpdate.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6E361FB29D9AEEA00FFF234 /* BuildPeerConfigurationUpdate.swift */; };
A6E361FE29D9B18C00FFF234 /* TunnelsOptionsProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6E361FD29D9B18C00FFF234 /* TunnelsOptionsProvider.swift */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@ -347,8 +357,6 @@
6F6483E6229293300075BA15 /* LaunchedAtLoginDetector.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LaunchedAtLoginDetector.swift; sourceTree = "<group>"; };
6F689999218043390012E523 /* WireGuard-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "WireGuard-Bridging-Header.h"; sourceTree = "<group>"; };
6F70E20D221058DF008BDFB4 /* Base */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Base; path = Sources/WireGuardApp/Base.lproj/InfoPlist.strings; sourceTree = "<group>"; };
6F70E20D221058DF008BDFBA /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "Sources/WireGuardApp/zh-Hans.lproj/Localizable.strings"; sourceTree = "<group>"; };
6F70E20D221058DF008BDFC6 /* zh-Hant */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant"; path = "Sources/WireGuardApp/zh-Hant.lproj/Localizable.strings"; sourceTree = "<group>"; };
6F70E22922106A2D008BDFB4 /* WireGuardLoginItemHelper.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = WireGuardLoginItemHelper.app; sourceTree = BUILT_PRODUCTS_DIR; };
6F70E23222106A31008BDFB4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
6F70E23922109BEF008BDFB4 /* LoginItemHelper.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = LoginItemHelper.entitlements; sourceTree = "<group>"; };
@ -404,24 +412,24 @@
6FDEF801218646B900D8FBF6 /* ZipArchive.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ZipArchive.swift; sourceTree = "<group>"; };
6FDEF805218725D200D8FBF6 /* SettingsTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingsTableViewController.swift; sourceTree = "<group>"; };
6FE1765521C90BBE002690EA /* Base */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Base; path = Sources/WireGuardApp/Base.lproj/Localizable.strings; sourceTree = "<group>"; };
6FE1765521C90BBE002690FC /* zh-Hant */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = zh-Hant; path = Sources/WireGuardApp/zh-Hant.lproj/Localizable.strings; sourceTree = "<group>"; };
6FE1765521C90BBE002690F0 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = zh-Hans; path = Sources/WireGuardApp/zh-Hans.lproj/Localizable.strings; sourceTree = "<group>"; };
6FE1765521C90BBE002690FB /* id */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = id; path = Sources/WireGuardApp/id.lproj/Localizable.strings; sourceTree = "<group>"; };
6FE1765521C90BBE002690F2 /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = Sources/WireGuardApp/it.lproj/Localizable.strings; sourceTree = "<group>"; };
6FE1765521C90BBE002690F9 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = Sources/WireGuardApp/de.lproj/Localizable.strings; sourceTree = "<group>"; };
6FE1765521C90BBE002690EB /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = Sources/WireGuardApp/fr.lproj/Localizable.strings; sourceTree = "<group>"; };
6FE1765521C90BBE002690F5 /* fi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fi; path = Sources/WireGuardApp/fi.lproj/Localizable.strings; sourceTree = "<group>"; };
6FE1765521C90BBE002690F4 /* fa */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fa; path = Sources/WireGuardApp/fa.lproj/Localizable.strings; sourceTree = "<group>"; };
6FE1765521C90BBE002690FA /* sl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sl; path = Sources/WireGuardApp/sl.lproj/Localizable.strings; sourceTree = "<group>"; };
6FE1765521C90BBE002690EC /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = Sources/WireGuardApp/pl.lproj/Localizable.strings; sourceTree = "<group>"; };
6FE1765521C90BBE002690EF /* pa */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pa; path = Sources/WireGuardApp/pa.lproj/Localizable.strings; sourceTree = "<group>"; };
6FE1765521C90BBE002690F7 /* ko */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ko; path = Sources/WireGuardApp/ko.lproj/Localizable.strings; sourceTree = "<group>"; };
6FE1765521C90BBE002690EE /* ca */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ca; path = Sources/WireGuardApp/ca.lproj/Localizable.strings; sourceTree = "<group>"; };
6FE1765521C90BBE002690F6 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = Sources/WireGuardApp/ru.lproj/Localizable.strings; sourceTree = "<group>"; };
6FE1765521C90BBE002690F3 /* ro */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ro; path = Sources/WireGuardApp/ro.lproj/Localizable.strings; sourceTree = "<group>"; };
6FE1765521C90BBE002690F8 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = Sources/WireGuardApp/tr.lproj/Localizable.strings; sourceTree = "<group>"; };
6FE1765521C90BBE002690F1 /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = Sources/WireGuardApp/ja.lproj/Localizable.strings; sourceTree = "<group>"; };
6FE1765521C90BBE002690ED /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = Sources/WireGuardApp/es.lproj/Localizable.strings; sourceTree = "<group>"; };
6FE1765521C90BBE002690EE /* ca */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ca; path = Sources/WireGuardApp/ca.lproj/Localizable.strings; sourceTree = "<group>"; };
6FE1765521C90BBE002690EF /* pa */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pa; path = Sources/WireGuardApp/pa.lproj/Localizable.strings; sourceTree = "<group>"; };
6FE1765521C90BBE002690F0 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "Sources/WireGuardApp/zh-Hans.lproj/Localizable.strings"; sourceTree = "<group>"; };
6FE1765521C90BBE002690F1 /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = Sources/WireGuardApp/ja.lproj/Localizable.strings; sourceTree = "<group>"; };
6FE1765521C90BBE002690F2 /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = Sources/WireGuardApp/it.lproj/Localizable.strings; sourceTree = "<group>"; };
6FE1765521C90BBE002690F3 /* ro */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ro; path = Sources/WireGuardApp/ro.lproj/Localizable.strings; sourceTree = "<group>"; };
6FE1765521C90BBE002690F4 /* fa */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fa; path = Sources/WireGuardApp/fa.lproj/Localizable.strings; sourceTree = "<group>"; };
6FE1765521C90BBE002690F5 /* fi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fi; path = Sources/WireGuardApp/fi.lproj/Localizable.strings; sourceTree = "<group>"; };
6FE1765521C90BBE002690F6 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = Sources/WireGuardApp/ru.lproj/Localizable.strings; sourceTree = "<group>"; };
6FE1765521C90BBE002690F7 /* ko */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ko; path = Sources/WireGuardApp/ko.lproj/Localizable.strings; sourceTree = "<group>"; };
6FE1765521C90BBE002690F8 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = Sources/WireGuardApp/tr.lproj/Localizable.strings; sourceTree = "<group>"; };
6FE1765521C90BBE002690F9 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = Sources/WireGuardApp/de.lproj/Localizable.strings; sourceTree = "<group>"; };
6FE1765521C90BBE002690FA /* sl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sl; path = Sources/WireGuardApp/sl.lproj/Localizable.strings; sourceTree = "<group>"; };
6FE1765521C90BBE002690FB /* id */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = id; path = Sources/WireGuardApp/id.lproj/Localizable.strings; sourceTree = "<group>"; };
6FE1765521C90BBE002690FC /* zh-Hant */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant"; path = "Sources/WireGuardApp/zh-Hant.lproj/Localizable.strings"; sourceTree = "<group>"; };
6FE1765921C90E87002690EA /* LocalizationHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalizationHelper.swift; sourceTree = "<group>"; };
6FE254FA219C10800028284D /* ZipImporter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ZipImporter.swift; sourceTree = "<group>"; };
6FE254FE219C60290028284D /* ZipExporter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ZipExporter.swift; sourceTree = "<group>"; };
@ -440,6 +448,11 @@
6FFA5D9F21958ECC0001E2F7 /* ErrorNotifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorNotifier.swift; sourceTree = "<group>"; };
6FFA5DA32197085D0001E2F7 /* ActivateOnDemandOption.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActivateOnDemandOption.swift; sourceTree = "<group>"; };
6FFACD1E21E4D89600E9A2A5 /* ParseError+WireGuardAppError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ParseError+WireGuardAppError.swift"; sourceTree = "<group>"; };
A625F05029C4C627005EF23D /* GetPeers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GetPeers.swift; sourceTree = "<group>"; };
A6E361F729D8758500FFF234 /* AppIntents.strings */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; path = AppIntents.strings; sourceTree = "<group>"; };
A6E361F929D9821100FFF234 /* UpdateTunnelConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpdateTunnelConfiguration.swift; sourceTree = "<group>"; };
A6E361FB29D9AEEA00FFF234 /* BuildPeerConfigurationUpdate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BuildPeerConfigurationUpdate.swift; sourceTree = "<group>"; };
A6E361FD29D9B18C00FFF234 /* TunnelsOptionsProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TunnelsOptionsProvider.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@ -762,6 +775,7 @@
6FF4AC0B211EC46F002C96EB = {
isa = PBXGroup;
children = (
A625F04C29C4C627005EF23D /* WireguardAppIntents */,
6F70E20C221058DF008BDFB4 /* InfoPlist.strings */,
6FE1765421C90BBE002690EA /* Localizable.strings */,
6F5D0C432183B4A4000F85AD /* Shared */,
@ -813,6 +827,19 @@
name = Frameworks;
sourceTree = "<group>";
};
A625F04C29C4C627005EF23D /* WireguardAppIntents */ = {
isa = PBXGroup;
children = (
A6E361F929D9821100FFF234 /* UpdateTunnelConfiguration.swift */,
A6E361FB29D9AEEA00FFF234 /* BuildPeerConfigurationUpdate.swift */,
A625F05029C4C627005EF23D /* GetPeers.swift */,
A6E361F729D8758500FFF234 /* AppIntents.strings */,
A6E361FD29D9B18C00FFF234 /* TunnelsOptionsProvider.swift */,
);
name = WireguardAppIntents;
path = Sources/WireguardAppIntents;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXLegacyTarget section */
@ -960,7 +987,7 @@
6FF4AC0C211EC46F002C96EB /* Project object */ = {
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 1010;
LastSwiftUpdateCheck = 1320;
LastUpgradeCheck = 1010;
ORGANIZATIONNAME = "WireGuard LLC";
TargetAttributes = {
@ -1078,6 +1105,7 @@
files = (
6FB1BD6221D2607E00A991BF /* Assets.xcassets in Resources */,
6F70E20F221058E1008BDFB4 /* InfoPlist.strings in Resources */,
A25DF37329E60E930094E89B /* AppIntents.strings in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -1097,6 +1125,7 @@
6FE1765621C90BBE002690EA /* Localizable.strings in Resources */,
6FF4AC22211EC472002C96EB /* LaunchScreen.storyboard in Resources */,
6F919EDA218C65C50023B400 /* wireguard_doc_logo_44x58.png in Resources */,
A6E361F829D8758500FFF234 /* AppIntents.strings in Resources */,
6FF4AC1F211EC472002C96EB /* Assets.xcassets in Resources */,
6F919EDB218C65C50023B400 /* wireguard_doc_logo_64x64.png in Resources */,
6F919EDC218C65C50023B400 /* wireguard_doc_logo_320x320.png in Resources */,
@ -1305,6 +1334,7 @@
6FB1BDD121D50F5300A991BF /* ZipImporter.swift in Sources */,
6FB1BDD221D50F5300A991BF /* ZipExporter.swift in Sources */,
585B10642577E294004F691E /* DNSServer.swift in Sources */,
A25DF37129E60E8C0094E89B /* UpdateTunnelConfiguration.swift in Sources */,
585B108C2577E294004F691E /* Endpoint.swift in Sources */,
6FBA104621D7EBFA0051C35F /* TunnelsListTableViewController.swift in Sources */,
6FB1BDD321D50F5300A991BF /* ZipArchive.swift in Sources */,
@ -1342,11 +1372,13 @@
6FE3661D21F64F6B00F78C7D /* ConfTextColorTheme.swift in Sources */,
6F3E02E9228000F6001FE7E3 /* MainMenu.swift in Sources */,
5F52D0BF21E3788900283CEA /* NSColor+Hex.swift in Sources */,
A25DF37229E60E8F0094E89B /* GetPeers.swift in Sources */,
6FB1BDBE21D50F0200A991BF /* Logger.swift in Sources */,
6F6483E7229293300075BA15 /* LaunchedAtLoginDetector.swift in Sources */,
6FB1BDBF21D50F0200A991BF /* TunnelConfiguration+WgQuickConfig.swift in Sources */,
6FADE96C2254B8C300B838A4 /* UnusableTunnelDetailViewController.swift in Sources */,
6FFACD2021E4D8D500E9A2A5 /* ParseError+WireGuardAppError.swift in Sources */,
A25DF37029E60E870094E89B /* BuildPeerConfigurationUpdate.swift in Sources */,
6FB1BDC021D50F0200A991BF /* NETunnelProviderProtocol+Extension.swift in Sources */,
6F1075642258AE9800D78929 /* DeleteTunnelsConfirmationAlert.swift in Sources */,
6FBA101821D656000051C35F /* StatusMenu.swift in Sources */,
@ -1357,6 +1389,7 @@
6FBA104021D6B7040051C35F /* ErrorPresenterProtocol.swift in Sources */,
6FCD99AA21E0E14700BA4C82 /* ButtonedDetailViewController.swift in Sources */,
6FBA104321D6BC250051C35F /* ErrorPresenter.swift in Sources */,
A25DF37429E60E960094E89B /* TunnelsOptionsProvider.swift in Sources */,
6F2449E8226587B90047B9E9 /* MacAppStoreUpdateDetector.swift in Sources */,
585B105C2577E293004F691E /* InterfaceConfiguration.swift in Sources */,
6F907C9D224663A2003CED21 /* LogViewHelper.swift in Sources */,
@ -1407,6 +1440,7 @@
6FF3527221C2616C0008484E /* ringlogger.c in Sources */,
6F0F44CB222D55FD00B0FF04 /* EditableTextCell.swift in Sources */,
585B105E2577E293004F691E /* PeerConfiguration.swift in Sources */,
A6E361FA29D9821200FFF234 /* UpdateTunnelConfiguration.swift in Sources */,
6FF3527321C2616C0008484E /* Logger.swift in Sources */,
6F7774E421718281006A79B3 /* TunnelsListTableViewController.swift in Sources */,
585B108E2577E294004F691E /* x25519.c in Sources */,
@ -1421,8 +1455,10 @@
6FDB6D18224CC05A00EE4BC3 /* LogViewController.swift in Sources */,
6FFA5D952194454A0001E2F7 /* NETunnelProviderProtocol+Extension.swift in Sources */,
5F4541A921C451D100994C13 /* TunnelStatus.swift in Sources */,
A625F05529C4C627005EF23D /* GetPeers.swift in Sources */,
6F8F0D7422267AD2000E8335 /* ChevronCell.swift in Sources */,
6F61F1E921B932F700483816 /* WireGuardAppError.swift in Sources */,
A6E361FE29D9B18C00FFF234 /* TunnelsOptionsProvider.swift in Sources */,
6F7774E2217181B1006A79B3 /* AppDelegate.swift in Sources */,
6FDEF80021863C0100D8FBF6 /* ioapi.c in Sources */,
6F7F7E5F21C7D74B00527607 /* TunnelErrors.swift in Sources */,
@ -1437,6 +1473,7 @@
6F919EC3218A2AE90023B400 /* ErrorPresenter.swift in Sources */,
6B62E45F220A6FA900EF34A6 /* PrivateDataConfirmation.swift in Sources */,
6F5A2B4821AFF49A0081EDD8 /* FileManager+Extension.swift in Sources */,
A6E361FC29D9AEEA00FFF234 /* BuildPeerConfigurationUpdate.swift in Sources */,
5F45418C21C2D48200994C13 /* TunnelEditKeyValueCell.swift in Sources */,
6FE254FB219C10800028284D /* ZipImporter.swift in Sources */,
585B107E2577E294004F691E /* PrivateKey.swift in Sources */,