Skip to content

Commit

Permalink
Importing and exporting in JSON possible
Browse files Browse the repository at this point in the history
  • Loading branch information
Sn0wfreezeDev committed Jan 4, 2022
1 parent ebfe792 commit 190d9f3
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 12 deletions.
85 changes: 75 additions & 10 deletions OpenHaystack/OpenHaystack/HaystackApp/AccessoryController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ class AccessoryController: ObservableObject {
var selfObserver: AnyCancellable?
var listElementsObserver = [AnyCancellable]()
let findMyController: FindMyController

weak var savePanel: NSSavePanel?

init(accessories: [Accessory], findMyController: FindMyController) {
self.accessories = accessories
Expand Down Expand Up @@ -99,28 +101,65 @@ class AccessoryController: ObservableObject {
let savePanel = NSSavePanel()
// savePanel.allowedFileTypes = ["plist", "json"]
if #available(macOS 12.0, *) {
savePanel.allowedContentTypes = [.propertyList, .json]
savePanel.allowedContentTypes = [.propertyList]
}else {
savePanel.allowedFileTypes = ["plist"]
}
savePanel.allowedFileTypes = ["plist", "json"]

savePanel.canCreateDirectories = true
savePanel.directoryURL = try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
savePanel.message = "This export contains all private keys! Keep the file save to protect your location data"
savePanel.nameFieldLabel = "Filename"
savePanel.nameFieldStringValue = "openhaystack_accessories.plist"
savePanel.nameFieldStringValue = "openhaystack_accessories"
savePanel.prompt = "Export"
savePanel.title = "Export accessories & keys"
savePanel.isExtensionHidden = false

let accessoryView = NSView()
let popUpButton = NSPopUpButton(title: "File type", target: self, action: #selector(exportFileTypeChanged(button:)))
popUpButton.addItems(withTitles: ["Property List", "JSON"])
popUpButton.selectItem(at: 0)
popUpButton.stringValue = "File type"
popUpButton.translatesAutoresizingMaskIntoConstraints = false
accessoryView.addSubview(popUpButton)

let popUpButtonLabel = NSTextField(labelWithString: "File type")
popUpButtonLabel.translatesAutoresizingMaskIntoConstraints = false
accessoryView.addSubview(popUpButtonLabel)
accessoryView.translatesAutoresizingMaskIntoConstraints = false

// popUpButtonLabel.leadingAnchor.constraint(greaterThanOrEqualTo: accessoryView.leadingAnchor, constant: 20.0).isActive = true
popUpButtonLabel.trailingAnchor.constraint(equalTo: popUpButton.leadingAnchor, constant: -8.0).isActive = true
popUpButtonLabel.trailingAnchor.constraint(lessThanOrEqualTo: accessoryView.centerXAnchor, constant: 0).isActive = true
popUpButtonLabel.centerYAnchor.constraint(equalTo: popUpButton.centerYAnchor, constant: 0).isActive = true
// popUpButton.trailingAnchor.constraint(lessThanOrEqualTo: accessoryView.trailingAnchor, constant: -20.0).isActive = true
popUpButton.leadingAnchor.constraint(lessThanOrEqualTo: accessoryView.centerXAnchor, constant: 0).isActive = true
popUpButton.topAnchor.constraint(equalTo: accessoryView.topAnchor, constant: 8.0).isActive = true
popUpButton.bottomAnchor.constraint(equalTo: accessoryView.bottomAnchor, constant: -8.0).isActive = true
popUpButton.heightAnchor.constraint(greaterThanOrEqualToConstant: 20.0).isActive = true
popUpButton.widthAnchor.constraint(lessThanOrEqualToConstant: 200.0).isActive = true

savePanel.accessoryView = accessoryView
self.savePanel = savePanel

let result = savePanel.runModal()

if result == .OK,
let url = savePanel.url
var url = savePanel.url
{
let selectedItemIndex = popUpButton.indexOfSelectedItem

// Store the accessory file
if url.pathExtension == "plist" {
if selectedItemIndex == 0 {
if url.pathExtension != "plist" {
url = url.appendingPathExtension("plist")
}
let propertyList = try PropertyListEncoder().encode(accessories)
try propertyList.write(to: url)
}else if url.pathExtension == "json" {
}else if selectedItemIndex == 1 {
if url.pathExtension != "json" {
url = url.appendingPathExtension("json")
}
let jsonObject = try JSONEncoder().encode(accessories)
try jsonObject.write(to: url)
}
Expand All @@ -129,11 +168,32 @@ class AccessoryController: ObservableObject {
}
throw ImportError.cancelled
}

@objc func exportFileTypeChanged(button: NSPopUpButton) {
if button.indexOfSelectedItem == 0 {
if #available(macOS 12.0, *) {
self.savePanel?.allowedContentTypes = [.propertyList]
}else {
self.savePanel?.allowedFileTypes = ["plist"]
}
}else {
if #available(macOS 12.0, *) {
self.savePanel?.allowedContentTypes = [.json]
}else {
self.savePanel?.allowedFileTypes = ["json"]
}
}
}

/// Let the user select a file to import the accessories exported by another OpenHaystack instance.
func importAccessories() throws {
let openPanel = NSOpenPanel()
openPanel.allowedFileTypes = ["plist"]
if #available(macOS 12.0, *) {
openPanel.allowedContentTypes = [.json, .propertyList]
}else {
openPanel.allowedFileTypes = ["json", "plist"]
}

openPanel.canCreateDirectories = true
openPanel.directoryURL = try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
openPanel.message = "Import an accessories file that includes the private keys"
Expand All @@ -144,9 +204,14 @@ class AccessoryController: ObservableObject {
if result == .OK,
let url = openPanel.url
{
let propertyList = try Data(contentsOf: url)
var importedAccessories = try PropertyListDecoder().decode([Accessory].self, from: propertyList)

let accessoryData = try Data(contentsOf: url)
var importedAccessories: [Accessory]
if url.pathExtension == "plist" {
importedAccessories = try PropertyListDecoder().decode([Accessory].self, from: accessoryData)
}else {
importedAccessories = try JSONDecoder().decode([Accessory].self, from: accessoryData)
}

var updatedAccessories = self.accessories
// Filter out accessories with the same id (no duplicates)
importedAccessories = importedAccessories.filter({ acc in !self.accessories.contains(where: { acc.id == $0.id }) })
Expand Down
5 changes: 3 additions & 2 deletions OpenHaystack/OpenHaystack/HaystackApp/Model/Accessory.swift
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,10 @@ class Accessory: ObservableObject, Codable, Identifiable, Equatable, Hashable {
self.name = try container.decode(String.self, forKey: .name)
self.id = try container.decode(Int.self, forKey: .id)
self.privateKey = try container.decode(Data.self, forKey: .privateKey)
self.symmetricKey = (try? container.decode(Data.self, forKey: .symmetricKey)) ?? SymmetricKey(size: .bits256).withUnsafeBytes { return Data($0) }
let symmetricKey = (try? container.decode(Data.self, forKey: .symmetricKey)) ?? SymmetricKey(size: .bits256).withUnsafeBytes { return Data($0) }
self.symmetricKey = symmetricKey
self.usesDerivation = (try? container.decode(Bool.self, forKey: .usesDerivation)) ?? false
self.oldestRelevantSymmetricKey = (try? container.decode(Data.self, forKey: .oldestRelevantSymmetricKey)) ?? self.symmetricKey
self.oldestRelevantSymmetricKey = (try? container.decode(Data.self, forKey: .oldestRelevantSymmetricKey)) ?? symmetricKey
self.lastDerivationTimestamp = (try? container.decode(Date.self, forKey: .lastDerivationTimestamp)) ?? Date()
self.updateInterval = (try? container.decode(TimeInterval.self, forKey: .updateInterval)) ?? TimeInterval(60 * 60 * 24)
self.icon = (try? container.decode(String.self, forKey: .icon)) ?? ""
Expand Down

0 comments on commit 190d9f3

Please sign in to comment.