mirror of
https://github.com/maxgoedjen/secretive.git
synced 2025-09-15 08:50:57 +00:00
Cleanup
This commit is contained in:
parent
be28d59873
commit
e966203312
@ -21,13 +21,16 @@ let package = Package(
|
||||
targets: ["SmartCardSecretKit"]),
|
||||
.library(
|
||||
name: "SecretAgentKit",
|
||||
targets: ["SecretAgentKit"]),
|
||||
targets: ["SecretAgentKit", "XPCWrappers"]),
|
||||
.library(
|
||||
name: "SecretAgentKitHeaders",
|
||||
targets: ["SecretAgentKitHeaders"]),
|
||||
.library(
|
||||
name: "Brief",
|
||||
targets: ["Brief"]),
|
||||
.library(
|
||||
name: "XPCWrappers",
|
||||
targets: ["XPCWrappers"]),
|
||||
],
|
||||
dependencies: [
|
||||
],
|
||||
@ -70,7 +73,7 @@ let package = Package(
|
||||
),
|
||||
.target(
|
||||
name: "Brief",
|
||||
dependencies: [],
|
||||
dependencies: ["XPCWrappers"],
|
||||
resources: [localization],
|
||||
swiftSettings: swiftSettings,
|
||||
),
|
||||
@ -78,6 +81,10 @@ let package = Package(
|
||||
name: "BriefTests",
|
||||
dependencies: ["Brief"],
|
||||
),
|
||||
.target(
|
||||
name: "XPCWrappers",
|
||||
swiftSettings: swiftSettings,
|
||||
),
|
||||
]
|
||||
)
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
import Foundation
|
||||
import Observation
|
||||
import XPCWrappers
|
||||
|
||||
/// A concrete implementation of ``UpdaterProtocol`` which considers the current release and OS version.
|
||||
@Observable public final class Updater: UpdaterProtocol, Sendable {
|
||||
@ -46,14 +47,9 @@ import Observation
|
||||
|
||||
/// Manually trigger an update check.
|
||||
public func checkForUpdates() async throws {
|
||||
let session: XPCSession
|
||||
if #available(macOS 26.0, *) {
|
||||
session = try XPCSession(xpcService: "com.maxgoedjen.Secretive.ReleasesDownloader", requirement: .isFromSameTeam())
|
||||
} else {
|
||||
session = try XPCSession(xpcService: "com.maxgoedjen.Secretive.ReleasesDownloader")
|
||||
}
|
||||
let session = try XPCTypedSession<[Release], Never>(serviceName: "com.maxgoedjen.Secretive.ReleasesDownloader")
|
||||
await evaluate(releases: try await session.send())
|
||||
session.cancel(reason: "Done")
|
||||
session.complete()
|
||||
}
|
||||
|
||||
|
||||
@ -103,33 +99,3 @@ extension Updater {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private extension XPCSession {
|
||||
|
||||
func send<Response: Decodable & Sendable>(_ message: some Encodable = XPCSession.emptyMessage) async throws -> Response {
|
||||
try await withCheckedThrowingContinuation { continuation in
|
||||
do {
|
||||
try send(message) { result in
|
||||
switch result {
|
||||
case .success(let message):
|
||||
do {
|
||||
let decoded = try message.decode(as: Response.self)
|
||||
continuation.resume(returning: decoded)
|
||||
} catch {
|
||||
continuation.resume(throwing: error)
|
||||
}
|
||||
case .failure(let error):
|
||||
continuation.resume(throwing: error)
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
continuation.resume(throwing: error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static var emptyMessage: some Encodable {
|
||||
Data()
|
||||
}
|
||||
|
||||
}
|
||||
|
49
Sources/Packages/Sources/XPCWrappers/XPCWrappers.swift
Normal file
49
Sources/Packages/Sources/XPCWrappers/XPCWrappers.swift
Normal file
@ -0,0 +1,49 @@
|
||||
import Foundation
|
||||
|
||||
public struct XPCTypedSession<ResponseType: Codable & Sendable, ErrorType: Error & Codable>: Sendable {
|
||||
|
||||
private let session: XPCSession
|
||||
|
||||
public init(serviceName: String, warmup: Bool = false) throws {
|
||||
if #available(macOS 26.0, *) {
|
||||
session = try XPCSession(xpcService: serviceName, requirement: .isFromSameTeam())
|
||||
} else {
|
||||
session = try XPCSession(xpcService: serviceName)
|
||||
}
|
||||
if warmup {
|
||||
Task { [self] in
|
||||
_ = try? await send()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public func send(_ message: some Encodable = Data()) async throws -> ResponseType {
|
||||
try await withCheckedThrowingContinuation { continuation in
|
||||
do {
|
||||
try session.send(message) { result in
|
||||
switch result {
|
||||
case .success(let message):
|
||||
if let result = try? message.decode(as: ResponseType.self) {
|
||||
continuation.resume(returning: result)
|
||||
} else if let error = try? message.decode(as: ErrorType.self) {
|
||||
continuation.resume(throwing: error)
|
||||
} else {
|
||||
continuation.resume(throwing: UnknownMessageError())
|
||||
}
|
||||
case .failure(let error):
|
||||
continuation.resume(throwing: error)
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
continuation.resume(throwing: error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public func complete() {
|
||||
session.cancel(reason: "Done")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public struct UnknownMessageError: Error, Codable {}
|
@ -1,52 +1,23 @@
|
||||
import Foundation
|
||||
import SecretAgentKit
|
||||
import Brief
|
||||
import XPCWrappers
|
||||
|
||||
/// Delegates all agent input parsing to an XPC service which wraps OpenSSH
|
||||
public final class XPCAgentInputParser: SSHAgentInputParserProtocol {
|
||||
|
||||
private let session: XPCSession
|
||||
private let queue = DispatchQueue(label: "com.maxgoedjen.Secretive.AgentRequestParser", qos: .userInteractive)
|
||||
private let session: XPCTypedSession<SSHAgent.Request, SSHAgentInputParser.AgentParsingError>
|
||||
|
||||
public init() throws {
|
||||
if #available(macOS 26.0, *) {
|
||||
session = try XPCSession(xpcService: "com.maxgoedjen.Secretive.AgentRequestParser", targetQueue: queue, requirement: .isFromSameTeam())
|
||||
} else {
|
||||
session = try XPCSession(xpcService: "com.maxgoedjen.Secretive.AgentRequestParser", targetQueue: queue)
|
||||
}
|
||||
Task {
|
||||
// Warm up the XPC endpoint.
|
||||
_ = try? await parse(data: Data())
|
||||
}
|
||||
session = try XPCTypedSession(serviceName: "com.maxgoedjen.Secretive.AgentRequestParser", warmup: true)
|
||||
}
|
||||
|
||||
public func parse(data: Data) async throws -> SSHAgent.Request {
|
||||
try await withCheckedThrowingContinuation { continuation in
|
||||
do {
|
||||
try session.send(data) { result in
|
||||
switch result {
|
||||
case .success(let result):
|
||||
if let result = try? result.decode(as: SSHAgent.Request.self) {
|
||||
continuation.resume(returning: result)
|
||||
} else if let error = try? result.decode(as: SSHAgentInputParser.AgentParsingError.self) {
|
||||
continuation.resume(throwing: error)
|
||||
} else {
|
||||
continuation.resume(throwing: UnknownMessageError())
|
||||
}
|
||||
case .failure(let error):
|
||||
continuation.resume(throwing: error)
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
continuation.resume(throwing: error)
|
||||
}
|
||||
}
|
||||
try await session.send(data)
|
||||
}
|
||||
|
||||
deinit {
|
||||
session.cancel(reason: "Done")
|
||||
session.complete()
|
||||
}
|
||||
|
||||
struct UnknownMessageError: Error {}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user