Skip to content

Commit

Permalink
Merge pull request #48 from Terreii/compatibility
Browse files Browse the repository at this point in the history
Compatibility
  • Loading branch information
Terreii authored Nov 27, 2018
2 parents 27083cd + af4b03d commit 04c1b2e
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 6 deletions.
13 changes: 8 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,17 +148,20 @@ Every time your user signs in you also need to unlock the cryptoStore.
[`cryptoStore.setPassword(password)`](#cryptostoresetpasswordpassword) is also used for unlocking.
After sign in you __must wait for the store to sync__ and then unlock the cryptoStore.

You must wait for the sync to finish, because the `_design/cryptoStore/salt` object must be updated
to the latest version to unlock the cryptoStore! __If the salt doc is missing, a new one will be
created!__ Resulting in a new encryption key!
You must wait for the sync to finish, because the `_design/cryptoStore/salt` and
`hoodiePluginCryptoStore/salt` objects must be updated to the latest version to unlock the
cryptoStore! __If the salt doc is missing, a new one will be created!__ Resulting in a new encryption key!

Example:
```javascript
function signIn (username, password, cryptoPassword) {
return hoodie.account.signIn({username: username, password: password})

.then(function (accountProperties) {
return hoodie.store.sync() // wait for syncing to finish!
return hoodie.store.sync([
'_design/cryptoStore/salt',
'hoodiePluginCryptoStore/salt'
]) // wait for syncing to finish!
.then(function () {
return accountProperties
})
Expand Down Expand Up @@ -433,7 +436,7 @@ Argument | Type | Description | Required
`password` | String | A password for encrypting the objects | Yes

Resolves with a `salt`. A salt is a string that will be used with the password together for the encryption.
It is saved with the `id` `_design/cryptoStore/salt`.
It is saved with the `id` `_design/cryptoStore/salt`. It also tests `hoodiePluginCryptoStore/salt` for the salt.

It doesn't reject!

Expand Down
12 changes: 11 additions & 1 deletion lib/change-password.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,18 @@ function changePassword (store, state, oldPassword, newPassword) {
return Promise.reject(new Error('New password must be a string!'))
}

var isNewSaltDoc = false

return store.find('_design/cryptoStore/salt')

.catch(function (err) {
if (err.status === 404) {
isNewSaltDoc = true
return store.find('hoodiePluginCryptoStore/salt')
}
throw err
})

.then(function (saltDoc) {
// check if the old password is the same
return createKey(oldPassword, saltDoc.salt)
Expand Down Expand Up @@ -102,7 +112,7 @@ function changePassword (store, state, oldPassword, newPassword) {

.then(function (toUpdate) {
toUpdate.push({
_id: '_design/cryptoStore/salt',
_id: isNewSaltDoc ? 'hoodiePluginCryptoStore/salt' : '_design/cryptoStore/salt',
salt: data.newSalt
})
return store.update(toUpdate)
Expand Down
8 changes: 8 additions & 0 deletions lib/set-password.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,14 @@ function setPassword (store, state, isRoot, password, salt) {
if (isRoot) {
return store.find('_design/cryptoStore/salt')

.catch(function (error) {
if (error.status !== 404) {
throw error
}

return store.find('hoodiePluginCryptoStore/salt')
})

.catch(function (error) {
if (error.status !== 404) {
throw error
Expand Down
40 changes: 40 additions & 0 deletions tests/integration/change-password.js
Original file line number Diff line number Diff line change
Expand Up @@ -258,3 +258,43 @@ test('cryptoStore.changePassword() should only update objects that it can decryp
t.end(err)
})
})

test('cryptoStore.changePassword() should use hoodiePluginCryptoStore/salt', function (t) {
t.plan(2)

var hoodie = createCryptoStore()

hoodie.store.add({
_id: 'hoodiePluginCryptoStore/salt',
salt: 'bf11fa9bafca73586e103d60898989d4'
})

.then(function () {
return hoodie.cryptoStore.setPassword('test')
})

.then(function () {
return hoodie.cryptoStore.add({
_id: 'shouldUpdate',
test: 'value'
})
})

.then(function () {
return hoodie.cryptoStore.changePassword('test', 'foo')
})

.then(function (report) {
return hoodie.cryptoStore.find(['shouldUpdate', 'hoodiePluginCryptoStore/salt'])

.then(function (objects) {
t.equal(objects[0].test, 'value', 'should update objects')

t.equal(objects[1].salt, report.salt, 'should update new salt doc')
})
})

.catch(function (err) {
t.end(err)
})
})
31 changes: 31 additions & 0 deletions tests/integration/set-password.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,3 +99,34 @@ test('cryptoStore.setPassword(password) should use the saved salt', function (t)
t.end(err)
})
})

test(
'cryptoStore.setPassword(password) also should use "hoodiePluginCryptoStore/salt"',
function (t) {
t.plan(2)

var hoodie = createCryptoStore()
hoodie.store.add({
_id: 'hoodiePluginCryptoStore/salt',
salt: 'bf11fa9bafca73586e103d60898989d4'
})

.then(function () {
return hoodie.cryptoStore.setPassword('test')
})

.then(function (salt) {
t.is(salt, 'bf11fa9bafca73586e103d60898989d4', 'uses salt of hoodiePluginCryptoStore/salt')

return hoodie.store.find('_design/cryptoStore/salt')
})

.then(function () {
t.fail('_design/cryptoStore/salt shouldn\'t be created')
})

.catch(function (err) {
t.equal(err.status, 404, 'no new salt doc was created')
})
}
)

0 comments on commit 04c1b2e

Please sign in to comment.