Files
Termind/Frameworks/TermindPresentation/ReferenceDropLoader.swift
T
Kaede Akino 816a6ff121 feat(ssh): support hardware security key authentication
Add native security key registration, reference import, and signing on macOS and iOS. Store references in Vault metadata and route authentication through connection, Assistant, MCP, and agent forwarding flows.

Preserve signing cancellation and actionable authentication errors for security keys and Secure Enclave. Pin the released libssh2 forks as nested submodules and refresh package resolution.
2026-09-28 23:37:49 +08:00

59 lines
2.8 KiB
Swift

import Foundation
import UniformTypeIdentifiers
/// Reads a dropped reference before a provider's temporary file is released.
public nonisolated enum ReferenceDropLoader {
public static func load(_ provider: NSItemProvider) async throws -> String {
if provider.hasItemConformingToTypeIdentifier(UTType.fileURL.identifier) {
return try await withCheckedThrowingContinuation { continuation in
provider.loadObject(ofClass: NSURL.self) { value, error in
do {
guard let url = value as? URL, url.isFileURL else {
throw error ?? CocoaError(.fileReadUnknown)
}
continuation.resume(returning: try read(url))
} catch { continuation.resume(throwing: error) }
}
}
}
let fileTypes = provider.registeredTypeIdentifiers(fileOptions: .openInPlace)
let named = provider.suggestedName?.isEmpty == false
if let type = provider.registeredTypeIdentifiers.first(where: {
guard let type = UTType($0), type.conforms(to: .data), !type.conforms(to: .url) else { return false }
return !type.conforms(to: .text) || named || fileTypes.contains($0)
}) {
return try await withCheckedThrowingContinuation { continuation in
provider.loadFileRepresentation(forTypeIdentifier: type) { url, error in
do {
guard let url else { throw error ?? CocoaError(.fileReadUnknown) }
continuation.resume(returning: try read(url))
} catch { continuation.resume(throwing: error) }
}
}
}
return try await withCheckedThrowingContinuation { continuation in
provider.loadObject(ofClass: NSString.self) { value, error in
guard let text = value as? String else {
continuation.resume(throwing: error ?? CocoaError(.fileReadUnknown))
return
}
guard text.utf8.count <= 1024 * 1024 else {
continuation.resume(throwing: CocoaError(.fileReadTooLarge))
return
}
continuation.resume(returning: text)
}
}
}
private static func read(_ url: URL) throws -> String {
let scoped = url.startAccessingSecurityScopedResource()
defer { if scoped { url.stopAccessingSecurityScopedResource() } }
let values = try url.resourceValues(forKeys: [.isRegularFileKey, .fileSizeKey])
guard values.isRegularFile == true, (values.fileSize ?? 0) <= 1024 * 1024 else {
throw CocoaError(.fileReadTooLarge)
}
return try String(contentsOf: url, encoding: .utf8)
}
}