Improve edit password to make it consistent with Pass
This commit is contained in:
parent
86cb8a84cd
commit
055ea243a3
6 changed files with 136 additions and 103 deletions
|
|
@ -53,7 +53,7 @@ class EditPasswordTableViewController: PasswordEditorTableViewController {
|
|||
if cellContents["additions"]! != "" {
|
||||
plainText = "\(cellContents["password"]!)\n\(cellContents["additions"]!)"
|
||||
} else {
|
||||
plainText = "\(cellContents["password"]!)\n"
|
||||
plainText = "\(cellContents["password"]!)"
|
||||
}
|
||||
let name = URL(string: cellContents["name"]!)!.lastPathComponent
|
||||
let url = URL(string: cellContents["name"]!)!.appendingPathExtension("gpg")
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ class GitConfigSettingTableViewController: UITableViewController {
|
|||
}
|
||||
|
||||
override func shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool {
|
||||
print("test should perform \(identifier)")
|
||||
if identifier == "saveGitConfigSettingSegue" {
|
||||
guard let name = nameTextField.text, !name.isEmpty else {
|
||||
Utils.alert(title: "Cannot Save", message: "Please set name first.", controller: self, completion: nil)
|
||||
|
|
|
|||
|
|
@ -212,28 +212,26 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni
|
|||
}
|
||||
|
||||
@IBAction private func saveEditPassword(segue: UIStoryboardSegue) {
|
||||
if self.password!.changed {
|
||||
if self.password!.changed != 0 {
|
||||
SVProgressHUD.show(withStatus: "Saving")
|
||||
DispatchQueue.global(qos: .userInitiated).async {
|
||||
do {
|
||||
self.passwordEntity = try self.passwordStore.update(passwordEntity: self.passwordEntity!, password: self.password!)
|
||||
self.passwordEntity = try self.passwordStore.edit(passwordEntity: self.passwordEntity!, password: self.password!)
|
||||
} catch {
|
||||
DispatchQueue.main.async {
|
||||
Utils.alert(title: "Error", message: error.localizedDescription, controller: self, completion: nil)
|
||||
}
|
||||
}
|
||||
DispatchQueue.main.async {
|
||||
self.setTableData()
|
||||
self.tableView.reloadData()
|
||||
SVProgressHUD.showSuccess(withStatus: "Success")
|
||||
SVProgressHUD.dismiss(withDelay: 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@IBAction private func deletePassword(segue: UIStoryboardSegue) {
|
||||
passwordStore.delete(passwordEntity: passwordEntity!)
|
||||
do {
|
||||
try passwordStore.delete(passwordEntity: passwordEntity!)
|
||||
} catch {
|
||||
Utils.alert(title: "Error", message: error.localizedDescription, controller: self, completion: nil)
|
||||
}
|
||||
let _ = navigationController?.popViewController(animated: true)
|
||||
}
|
||||
|
||||
|
|
@ -387,22 +385,16 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni
|
|||
}
|
||||
|
||||
// commit the change of HOTP counter
|
||||
if password!.changed {
|
||||
DispatchQueue.global(qos: .userInitiated).async {
|
||||
if password!.changed != 0 {
|
||||
do {
|
||||
self.passwordEntity = try self.passwordStore.update(passwordEntity: self.passwordEntity!, password: self.password!)
|
||||
self.passwordEntity = try self.passwordStore.edit(passwordEntity: self.passwordEntity!, password: self.password!)
|
||||
} catch {
|
||||
DispatchQueue.main.async {
|
||||
Utils.alert(title: "Error", message: error.localizedDescription, controller: self, completion: nil)
|
||||
}
|
||||
}
|
||||
DispatchQueue.main.async {
|
||||
SVProgressHUD.showSuccess(withStatus: "Password Copied\nCounter Updated")
|
||||
SVProgressHUD.dismiss(withDelay: 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func openLink() {
|
||||
guard let urlString = self.password?.getURLString(), let url = URL(string: urlString) else {
|
||||
|
|
|
|||
|
|
@ -16,6 +16,12 @@ struct AdditionField {
|
|||
var content: String
|
||||
}
|
||||
|
||||
enum PasswordChange: Int {
|
||||
case path = 0x01
|
||||
case content = 0x02
|
||||
case none = 0x00
|
||||
}
|
||||
|
||||
class Password {
|
||||
static let otpKeywords = ["otp_secret", "otp_type", "otp_algorithm", "otp_period", "otp_digits", "otp_counter", "otpauth"]
|
||||
|
||||
|
|
@ -32,7 +38,7 @@ class Password {
|
|||
var password = ""
|
||||
var additions = [String: String]()
|
||||
var additionKeys = [String]()
|
||||
var changed = false
|
||||
var changed: Int = 0
|
||||
var plainText = ""
|
||||
|
||||
private var firstLineIsOTPField = false
|
||||
|
|
@ -62,8 +68,13 @@ class Password {
|
|||
|
||||
func updatePassword(name: String, url: URL?, plainText: String) {
|
||||
if self.plainText != plainText || self.url != url {
|
||||
if self.plainText != plainText {
|
||||
changed = changed|PasswordChange.content.rawValue
|
||||
}
|
||||
if self.url != url {
|
||||
changed = changed|PasswordChange.path.rawValue
|
||||
}
|
||||
self.initEverything(name: name, url: url, plainText: plainText)
|
||||
changed = true
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -31,4 +31,11 @@ extension PasswordEntity {
|
|||
passwordCategoryArray.reverse()
|
||||
return passwordCategoryArray.joined(separator: " > ")
|
||||
}
|
||||
|
||||
func getURL() -> URL? {
|
||||
if let p = path {
|
||||
return URL(string: p)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -509,43 +509,51 @@ class PasswordStore {
|
|||
func updateRemoteRepo() {
|
||||
}
|
||||
|
||||
func createAddCommitInRepository(message: String, path: String) -> GTCommit? {
|
||||
do {
|
||||
try storeRepository?.index().addFile(path)
|
||||
try storeRepository?.index().write()
|
||||
let newTree = try storeRepository!.index().writeTree()
|
||||
let headReference = try storeRepository!.headReference()
|
||||
let commitEnum = try GTEnumerator(repository: storeRepository!)
|
||||
private func gitAdd(path: String) throws {
|
||||
if let repo = storeRepository {
|
||||
try repo.index().addFile(path)
|
||||
try repo.index().write()
|
||||
}
|
||||
}
|
||||
|
||||
private func gitRm(path: String) throws {
|
||||
if let repo = storeRepository {
|
||||
var url = storeURL.appendingPathComponent(path)
|
||||
Utils.removeFileIfExists(at: url)
|
||||
let fm = FileManager.default
|
||||
url.deleteLastPathComponent()
|
||||
var count = try fm.contentsOfDirectory(atPath: url.path).count
|
||||
while count == 0 {
|
||||
Utils.removeFileIfExists(atPath: url.path)
|
||||
url.deleteLastPathComponent()
|
||||
count = try fm.contentsOfDirectory(atPath: url.path).count
|
||||
}
|
||||
try repo.index().removeFile(path)
|
||||
try repo.index().write()
|
||||
}
|
||||
}
|
||||
|
||||
private func gitMv(from: String, to: String) throws {
|
||||
let fm = FileManager.default
|
||||
try fm.moveItem(at: storeURL.appendingPathComponent(from), to: storeURL.appendingPathComponent(to))
|
||||
try gitAdd(path: to)
|
||||
try gitRm(path: from)
|
||||
}
|
||||
|
||||
private func gitCommit(message: String) throws -> GTCommit? {
|
||||
if let repo = storeRepository {
|
||||
let newTree = try repo.index().writeTree()
|
||||
let headReference = try repo.headReference()
|
||||
let commitEnum = try GTEnumerator(repository: repo)
|
||||
try commitEnum.pushSHA(headReference.targetOID.sha!)
|
||||
let parent = commitEnum.nextObject() as! GTCommit
|
||||
let signature = gitSignatureForNow
|
||||
let commit = try storeRepository!.createCommit(with: newTree, message: message, author: signature, committer: signature, parents: [parent], updatingReferenceNamed: headReference.name)
|
||||
let commit = try repo.createCommit(with: newTree, message: message, author: signature, committer: signature, parents: [parent], updatingReferenceNamed: headReference.name)
|
||||
return commit
|
||||
} catch {
|
||||
print(error)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func createRemoveCommitInRepository(message: String, path: String) -> GTCommit? {
|
||||
do {
|
||||
try storeRepository?.index().removeFile(path)
|
||||
try storeRepository?.index().write()
|
||||
let newTree = try storeRepository!.index().writeTree()
|
||||
let headReference = try storeRepository!.headReference()
|
||||
let commitEnum = try GTEnumerator(repository: storeRepository!)
|
||||
try commitEnum.pushSHA(headReference.targetOID.sha!)
|
||||
let parent = commitEnum.nextObject() as! GTCommit
|
||||
let signature = gitSignatureForNow
|
||||
let commit = try storeRepository!.createCommit(with: newTree, message: message, author: signature, committer: signature, parents: [parent], updatingReferenceNamed: headReference.name)
|
||||
return commit
|
||||
} catch {
|
||||
print(error)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
private func getLocalBranch(withName branchName: String) -> GTBranch? {
|
||||
do {
|
||||
let reference = GTBranch.localNamePrefix().appending(branchName)
|
||||
|
|
@ -567,7 +575,11 @@ class PasswordStore {
|
|||
try storeRepository?.push(masterBranch, to: remote, withOptions: options, progress: transferProgressBlock)
|
||||
}
|
||||
|
||||
private func addPasswordEntities(password: Password) -> PasswordEntity? {
|
||||
private func addPasswordEntities(password: Password) throws -> PasswordEntity? {
|
||||
guard !passwordExisted(password: password) else {
|
||||
throw NSError(domain: "me.mssun.pass.error", code: 2, userInfo: [NSLocalizedDescriptionKey: "Cannot add password: password duplicated."])
|
||||
}
|
||||
|
||||
var passwordURL = password.url!
|
||||
var paths: [String] = []
|
||||
while passwordURL.path != "." {
|
||||
|
|
@ -599,7 +611,6 @@ class PasswordStore {
|
|||
|
||||
private func insertPasswordEntity(name: String, path: String, parent: PasswordEntity?, synced: Bool = false, isDir: Bool = false) -> PasswordEntity? {
|
||||
var ret: PasswordEntity? = nil
|
||||
DispatchQueue.main.sync {
|
||||
if let passwordEntity = NSEntityDescription.insertNewObject(forEntityName: "PasswordEntity", into: self.context) as? PasswordEntity {
|
||||
passwordEntity.name = name
|
||||
passwordEntity.path = path
|
||||
|
|
@ -613,35 +624,44 @@ class PasswordStore {
|
|||
fatalError("Failed to insert a PasswordEntity: \(error)")
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func add(password: Password) throws -> PasswordEntity? {
|
||||
guard !passwordExisted(password: password) else {
|
||||
throw NSError(domain: "me.mssun.pass.error", code: 2, userInfo: [NSLocalizedDescriptionKey: "Cannot add password: password duplicated."])
|
||||
}
|
||||
let newPasswordEntity = addPasswordEntities(password: password)
|
||||
print("new: \(newPasswordEntity!.path!)")
|
||||
let newPasswordEntity = try addPasswordEntities(password: password)
|
||||
let saveURL = storeURL.appendingPathComponent(password.url!.path)
|
||||
try self.encrypt(password: password).write(to: saveURL)
|
||||
let _ = createAddCommitInRepository(message: "Add password for \(password.url!.deletingPathExtension().path) to store using Pass for iOS.", path: password.url!.path)
|
||||
try gitAdd(path: password.url!.path)
|
||||
let _ = try gitCommit(message: "Add password for \(password.url!.deletingPathExtension().path) to store using Pass for iOS.")
|
||||
NotificationCenter.default.post(name: .passwordStoreUpdated, object: nil)
|
||||
return newPasswordEntity
|
||||
}
|
||||
|
||||
func update(passwordEntity: PasswordEntity, password: Password) throws -> PasswordEntity? {
|
||||
delete(passwordEntity: passwordEntity)
|
||||
return try add(password: password)
|
||||
func edit(passwordEntity: PasswordEntity, password: Password) throws -> PasswordEntity? {
|
||||
var newPasswordEntity: PasswordEntity? = passwordEntity
|
||||
|
||||
if password.changed&PasswordChange.content.rawValue != 0 {
|
||||
let saveURL = storeURL.appendingPathComponent(password.url!.path)
|
||||
try self.encrypt(password: password).write(to: saveURL)
|
||||
try gitAdd(path: password.url!.path)
|
||||
let _ = try gitCommit(message: "Edit password for \(password.url!.deletingPathExtension().path) to store using Pass for iOS.")
|
||||
}
|
||||
guard newPasswordEntity != nil else {
|
||||
return nil
|
||||
}
|
||||
if password.changed&PasswordChange.path.rawValue != 0 {
|
||||
let oldPasswordURL = newPasswordEntity!.getURL()
|
||||
try self.deletePasswordEntities(passwordEntity: newPasswordEntity!)
|
||||
newPasswordEntity = try self.addPasswordEntities(password: password)
|
||||
try gitMv(from: oldPasswordURL!.path, to: password.url!.path)
|
||||
let _ = try gitCommit(message: "Rename \(oldPasswordURL!.deletingPathExtension().path) to \(password.url!.deletingPathExtension().path) using Pass for iOS.")
|
||||
}
|
||||
return newPasswordEntity
|
||||
}
|
||||
|
||||
|
||||
public func delete(passwordEntity: PasswordEntity) {
|
||||
DispatchQueue.main.async {
|
||||
let _ = self.createRemoveCommitInRepository(message: "Remove \(passwordEntity.nameWithCategory) from store using Pass for iOS", path: passwordEntity.path!)
|
||||
private func deletePasswordEntities(passwordEntity: PasswordEntity) throws {
|
||||
var current: PasswordEntity? = passwordEntity
|
||||
while current != nil && (current!.children!.count == 0 || !current!.isDir) {
|
||||
Utils.removeFileIfExists(at: self.storeURL.appendingPathComponent(current!.path!))
|
||||
let parent = current!.parent
|
||||
self.context.delete(current!)
|
||||
current = parent
|
||||
|
|
@ -651,9 +671,13 @@ class PasswordStore {
|
|||
fatalError("Failed to delete a PasswordEntity: \(error)")
|
||||
}
|
||||
}
|
||||
NotificationCenter.default.post(name: .passwordStoreUpdated, object: nil)
|
||||
|
||||
}
|
||||
|
||||
public func delete(passwordEntity: PasswordEntity) throws {
|
||||
try gitRm(path: passwordEntity.path!)
|
||||
let _ = try gitCommit(message: "Remove \(passwordEntity.nameWithCategory) from store using Pass for iOS.")
|
||||
try deletePasswordEntities(passwordEntity: passwordEntity)
|
||||
NotificationCenter.default.post(name: .passwordStoreUpdated, object: nil)
|
||||
}
|
||||
|
||||
func saveUpdated(passwordEntity: PasswordEntity) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue