calvinmetcalf / crypto-pouch

plugin for encrypted pouchdb/couchdb databases
MIT License
243 stars 43 forks source link

put with _deleted: true #34

Closed gr2m closed 8 years ago

gr2m commented 8 years ago

This is rebased on #33

With the current implementation, the _deleted property gets encrypted with the other properties, so that a db.put(deletedDoc) will not remove the doc, but create a new revision without the _deleted true property. See https://travis-ci.org/calvinmetcalf/crypto-pouch/builds/128413187 for failing test

gr2m commented 8 years ago

I’ve run into another issue when I do the following in the browser (with the _deleted fix, otherwise workaround with localDb.crypto('password', ignore: '_deleted'):

  1. create a doc in local db (crypto)
  2. sync with remote db (CouchDB)
  3. delete local doc
  4. sync with remote db
  5. doc is not deleted in remote CouchDB. Reason seems to be that the POST _bulk_docs request has no _revissions key for the deleted doc.

I tried to write a test for it but it just passes:

test('sync deleted docs', function (t) {
  t.plan(1);
  var dbName = 'thirteen';
  var remoteDbName = 'fourteen';
  var db = new PouchDB(dbName, {db: memdown});
  var remoteDb = new PouchDB(remoteDbName, {db: memdown});
  db.crypto('password')

  var doc = {_id: 'baz', foo: 'bar'};
  db.put(doc).then(function (result) {
    doc._rev = result.rev;
    return replicate(db, remoteDb);
  }).then(function () {
    return remoteDb.get('baz');
  }).catch(function (err) {
    t.error('should find doc after sync');
    throw err;
  }).then(function () {
    return db.remove(doc);
  }).then(function () {
    return replicate(db, remoteDb);
  }).then(function () {
    return remoteDb.get('baz');
  }).then(function () {
    t.error('should not find doc after syncing delete');
  }).catch(function (err) {
    t.equal(err.status, 404, 'cannot find doc after syncing delete');
  });
});

function replicate (db1, db2) {
  return new Promise(function (resolve, reject) {
    db1.replicate.to(db2).on('complete', resolve).on('error', reject);
  });
}

Nevertheless I suggest we add _revisision next to _deleted, even without a test

gr2m commented 8 years ago

You can reproduce it with this test app: https://github.com/gr2m/crypto-pouch-webpack-app

make this change in entry.js

- localDb.crypto('password', {ignore: ['_attachments', '_deleted', '_revisions']})
+ localDb.crypto('password', {ignore: ['_attachments', '_deleted']})

Then below "local encrypted databse"

  1. Hit add button
  2. Hit sync button
  3. Hit delete button
  4. Hit sync button
  5. Click "open in fauxton", you’ll see the doc that you deleted.

sync-deleted-bug