UNPKG

5.19 kBtext/coffeescriptView Raw
1Crypto = require './crypto'
2Opdata = require './opdata'
3
4###*
5 * @class An item stores data such as usernames and passwords.
6###
7
8class Item
9
10
11 ###*
12 * Create a new Item.
13 * @param {Object} data The data to add to the Item.
14 * @param {Object} master The master encryption keys.
15 * @param {Object} overview The overview encryption keys.
16 * @return {Item} The item.
17 ###
18 @create: (data, master, overview) =>
19
20 timeNow = Math.floor Date.now() / 1000
21
22 item = new Item
23 uuid: Crypto.generateUuid()
24 created: timeNow
25 updated: timeNow
26 category: '001'
27
28 item.overview =
29 title: data.title
30 ainfo: data.username
31 url: data.url
32 URLS: [
33 l: 'website'
34 u: data.url
35 ]
36
37 item.details =
38 fields: [
39 type: 'T'
40 name: 'username'
41 value: data.username
42 designation: 'username'
43 ,
44 type: 'P'
45 name: 'password'
46 value: data.password
47 designation: 'password'
48 ]
49 notesPlain: data.notes or ''
50
51 item.keys =
52 encryption: Crypto.randomBytes(32)
53 hmac: Crypto.randomBytes(32)
54
55 ###*
56 *
57 * TODO: Move into seperate encryption functions
58 *
59
60 keys.both = Crypto.concat([encryptionKey, hmacKey])
61
62 detailsBuffer = Crypto.toBuffer(JSON.stringify(item.details), 'utf8')
63 overviewBuffer = Crypto.toBuffer(JSON.stringify(item.overview), 'utf8')
64
65 masterKey = new Opdata(master.encryption, master.hmac)
66 overviewKey = new Opdata(overview.encryption, overview.hmac)
67 itemKey = new Opdata(encryptionKey, hmacKey)
68
69 item.k = masterKey.encrypt('itemKey', encryptionAndHmacKey)
70 item.d = itemKey.encrypt('item', detailsBuffer)
71 item.o = overviewKey.encrypt('item', overviewBuffer)
72
73 ###
74
75 return item
76
77
78 ###*
79 * Create a new Item instance.
80 * @constructor
81 * @param {Object} [attrs] Any attributes to load into the item
82 ###
83 constructor: (attrs) ->
84 if attrs?
85 for key, attr of attrs
86 @[key] = attr
87
88
89 ###*
90 * Load attributes from the exported format
91 * @param {Object} data Data to load
92 * @return {this}
93 ###
94 load: (data) ->
95 for key in ['category', 'created', 'folder', 'tx', 'updated', 'uuid']
96 if data[key]? then @[key] = data[key]
97
98 for key in ['d', 'hmac', 'k', 'o']
99 continue unless data[key]?
100 @[key] = Crypto.fromBase64(data[key])
101
102 return this
103
104
105 ###*
106 * Decrypt the overview data of an item.
107 * @param {Opdata} overviewKey An Opdata profile key made with the
108 * keychain's overview keys. Used to decrypt
109 * the overview data.
110 * @return {Object} The overview data.
111 ###
112 decryptOverview: (overviewKey) ->
113 json = overviewKey.decrypt('item', @o)
114 @overview = JSON.parse(json)
115
116
117 encryptOverview: (overviewKey) ->
118 json = JSON.stringify(@overview)
119 buffer = Crypto.toBuffer(json)
120 @o = overviewKey.encrypt('item', buffer)
121 return @o
122
123
124 ###*
125 * Calculate the hmac of the item
126 * TODO: Find out why it doesn't work...
127 * @param {Buffer} key The master hmac key
128 * @return {String} The hmac of the item encoded in hex
129 ###
130 calculateHmac: (key) ->
131 dataToHmac = ""
132 for element, data of @toJSON()
133 continue if element is "hmac"
134 dataToHmac += element + data
135
136 dataToHmac = new Buffer(dataToHmac, 'utf8')
137 hmac = Crypto.hmac(dataToHmac, key, 256)
138
139 console.log hmac
140 console.log @hmac.toString('hex')
141
142
143
144 ###*
145 * Decrypt the item details.
146 * @param {Object} master The keychain's master keys. Used to decrypt the encryption keys.
147 * @return {Object} The item details.
148 ###
149 decryptDetails: (masterKey) ->
150
151 # Decrypt item keys
152 keys = masterKey.decrypt('itemKey', @k)
153 itemKey = new Opdata(keys[0], keys[1])
154
155 # Decrypt item details
156 details = itemKey.decrypt('item', @d)
157 return JSON.parse(details)
158
159
160 encryptDetails: (masterKey, details) ->
161
162 keys = masterKey.decrypt('itemKey', @k)
163 itemKey = new Opdata(keys[0], keys[1])
164
165 json = JSON.stringify(details)
166 buffer = Crypto.toBuffer(json)
167 @d = itemKey.encrypt('item', buffer)
168 return @d
169
170
171 ###*
172 * Turn an item into a JSON object.
173 * @return {Object} The JSON object.
174 ###
175 toJSON: ->
176 category: @category
177 created: @created
178 d: @d?.toString('base64')
179 # folder: ""
180 hmac: @hmac?.toString('base64')
181 k: @k?.toString('base64')
182 o: @o?.toString('base64')
183 tx: @tx
184 updated: @updated
185 uuid: @uuid
186
187
188 ###*
189 * Check to see if an item matches a query. Used for filtering items.
190 * @param {String} query The search query.
191 * @return {Boolean} Whether or not the item matches the query.
192 ###
193 match: (query) =>
194 query = query.toLowerCase()
195 @overview.title.toLowerCase().match(query)
196
197
198class Note extends Item
199 category: "003"
200
201 set: (data) ->
202 @details.notesPlain = data
203 @overview.notesPlain = data[0..79]
204
205
206
207module.exports = Item