-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathViewController.swift
177 lines (139 loc) · 6.25 KB
/
ViewController.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
//
// ViewController.swift
// E3db
//
import UIKit
import E3db
// Create an account and generate
// a client token from https://dashboard.tozny.com
private let e3dbToken = ""
class ViewController: UIViewController {
@IBOutlet weak var messageView: UITextView!
@IBOutlet weak var responseLabel: UILabel!
/// This is the main client performing E3db operations
var e3db: Client?
/// We'll use this to identify the most recently written record
var latestRecordId: UUID?
/// Demonstrates client registration,
/// and storing and loading client configuration
override func viewDidLoad() {
super.viewDidLoad()
// load E3db configuration under default profile name from keychain
if let config = Config() {
e3db = Client(config: config)
return
}
// make sure a client token exists
guard !e3dbToken.isEmpty else {
return print("Please register an account at https://console.tozny.com/ and generate a client token!")
}
// No client previously registered on this device,
// use the client token to register.
Client.register(token: e3dbToken, clientName: "ExampleApp") { result in
switch result {
// The operation was successful, here's the configuration
case .success(let config):
// create main E3db client with config
self.e3db = Client(config: config)
// save test config under default profile name, protects it with Secure Enclave defaults
guard config.save() else {
return print("Could not save config")
}
case .failure(let error):
print("An error occurred attempting registration: \(error).")
}
}
}
/// Demonstrates encrypting Documents securely with E3db.
@IBAction func encryptDocument() {
guard let msg = messageView.text else {
return print("Text field contains no text")
}
// Wrap message in RecordData type
let recordData = RecordData(cleartext: ["secret message": msg])
// Get EAKInfo and attempt to encrypt data to receive a Document
var encryptText = ""
var decryptText = ""
e3db?.createWriterKey(type: "example", completion: { result in
switch result {
case .success(let eak):
// Perform encrypt operation
let encrypted = try? self.e3db?.encrypt(type: "mobility-app", data: recordData, eakInfo: eak, plain: ["sent from": "my iphone"])
encryptText = "Encrypted document! \(String(describing: encrypted?.serialized()))"
// Attempt to decrypt an encrypted document with the EAKInfo instance
do {
let decrypted = try self.e3db?.decrypt(encryptedDoc: encrypted!, eakInfo: eak)
decryptText = "Decrypted document! \(String(describing: decrypted))"
}
catch {
decryptText = "Failed to decrypt!"
}
case .failure(let error):
encryptText = "An error occured attempting to encrypt a document: \(error)"
}
// Present response
print(encryptText)
self.responseLabel.text = encryptText
print(decryptText)
self.responseLabel.text = decryptText
})
}
/// Demonstrates writing data securely to E3db.
/// The `write` operation will encrypt the secret message
/// before it leaves the device, ensuring End-to-End Encryption
@IBAction func write() {
guard let msg = messageView.text else {
return print("Text field contains no text")
}
// Wrap message in RecordData type to designate
// it as sensitive information for encryption
let recordData = RecordData(cleartext: ["secret message": msg])
// Perform write operation, providing a user-defined type,
// the message, and any other non-sensitive information to associate with the data
e3db?.write(type: "my secret message", data: recordData, plain: ["Sent from": "my iPhone"]) { result in
let text: String
switch result {
// The operation was successful, here's the record
case .success(let record):
// `record.meta` holds metadata associated
// with the record, such as type. We'll use
// the `recordId` to help identify it later
self.latestRecordId = record.meta.recordId
text = "Wrote record! \(record.meta.recordId)"
case .failure(let error):
text = "An error occurred attempting to write the data: \(error)"
}
// Present response
print(text)
self.responseLabel.text = text
}
}
/// Demonstrates reading data securely from E3db.
/// The `read` operation will decrypt the secret message
/// using the user's key, ensuring End-to-End Encryption
@IBAction func read() {
guard let recordId = latestRecordId else {
return print("No records have been written yet.")
}
// Perform read operation with the recordId of the
// written record, decrypting it after getting the
// encrypted data from the server.
e3db?.read(recordId: recordId) { result in
let text: String
switch result {
// The operation was successful, here's the record
case .success(let record):
// The record returned contains the same dictionary
// supplied to the `RecordData` struct during the write
text = "Record data: \(record.data)"
case .failure(let error):
text = "An error occurred attempting to read the record: \(error)"
}
// Present response
print(text)
let alert = UIAlertController(title: "Decrypted Record", message: text, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Ok", style: .default))
self.present(alert, animated: true)
}
}
}