Skip to content

Commit

Permalink
fix: save encrypted crypto creds in a local doc
Browse files Browse the repository at this point in the history
  • Loading branch information
garbados committed Aug 3, 2021
1 parent 352d214 commit 04c5e0b
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 13 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ node_modules/
.nyc_output/
bundle.js
bundle.min.js
scratch.js
16 changes: 14 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,31 @@ const NO_COUCH = 'crypto-pouch does not work with pouchdb\'s http adapter. Use a

module.exports = {
transform,
crypto: function (password, options = {}) {
crypto: async function (password, options = {}) {
if (this.adapter === 'http') {
throw new Error(NO_COUCH)
}
if (typeof password === 'object') {
// handle `db.crypto({ password, ...options })`
options = password
password = password.password
delete options.password
}
// setup ignore list
this._ignore = IGNORE.concat(options.ignore || [])
// setup crypto helper
this._crypt = new Crypt(password)
try {
const { exportString } = await this.get('_local/crypto')
this._crypt = await Crypt.import(password, exportString)
} catch (err) {
if (err.status === 404) {
this._crypt = new Crypt(password)
const exportString = await this._crypt.export()
await this.put({ _id: '_local/crypto', exportString })
} else {
throw err
}
}
// instrument document transforms
this.transform({
incoming: async (doc) => {
Expand Down
8 changes: 5 additions & 3 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ PouchDB.plugin(require('crypto-pouch'))
const db = new PouchDB('my_db')

// init; after this, docs will be transparently en/decrypted
db.crypto(password)
db.crypto(password).then(() => { ... })

// disables transparent en/decryption,
// though encrypted docs remain encrypted
Expand All @@ -36,7 +36,7 @@ $ npm install crypto-pouch

## Usage

### db.crypto(password [, options])
### async db.crypto(password [, options])

Set up encryption on the database.

Expand All @@ -46,7 +46,9 @@ Set up encryption on the database.
You may also pass an options object as the first parameter, like so:

```javascript
db.crypto({ password, ignore: [...] })
db.crypto({ password, ignore: [...] }).then(() => {
// database will now encrypt writes and decrypt reads
})
```

### db.removeCrypto()
Expand Down
15 changes: 7 additions & 8 deletions test.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ const ATTACHMENTS = {
}

describe('crypto-pouch', function () {
beforeEach(function () {
beforeEach(async function () {
this.db = new PouchDB(NAME, { db: memdown })
this.db.crypto(PASSWORD)
await this.db.crypto(PASSWORD)
})

afterEach(async function () {
Expand Down Expand Up @@ -55,9 +55,8 @@ describe('crypto-pouch', function () {
it('should fail when using a bad password', async function () {
await this.db.put({ _id: 'a', hello: 'world' })
this.db.removeCrypto()
this.db.crypto(BAD_PASS)
try {
await this.db.get('a')
await this.db.crypto(BAD_PASS)
throw new Error('read succeeded but should have failed')
} catch (error) {
assert.equal(error.message, 'Could not decrypt!')
Expand Down Expand Up @@ -108,7 +107,7 @@ describe('crypto-pouch', function () {

it('should ignore attachments when so instructed', async function () {
this.db.removeCrypto()
this.db.crypto(PASSWORD, { ignore: '_attachments' })
await this.db.crypto(PASSWORD, { ignore: '_attachments' })
const doc = { ...DOCS[0], _attachments: ATTACHMENTS }
await this.db.put(doc)
})
Expand All @@ -128,7 +127,7 @@ describe('crypto-pouch', function () {

it('should accept crypto params as an object', async function () {
this.db.removeCrypto()
this.db.crypto({ password: PASSWORD })
await this.db.crypto({ password: PASSWORD })
const doc = DOCS[0]
await this.db.put(doc)
const { hello } = await this.db.get(doc._id)
Expand All @@ -137,8 +136,8 @@ describe('crypto-pouch', function () {

it('should fail to init with http adapter', async function () {
const db = new PouchDB('http://localhost:5984')
assert.throws(
() => { db.crypto(PASSWORD) },
assert.rejects(
async () => { await db.crypto(PASSWORD) },
new Error('crypto-pouch does not work with pouchdb\'s http adapter. Use a local adapter instead.')
)
})
Expand Down

0 comments on commit 04c5e0b

Please sign in to comment.