diff --git a/lib/importer.js b/lib/importer.js index 5731a98..723f35f 100644 --- a/lib/importer.js +++ b/lib/importer.js @@ -24,6 +24,15 @@ var sanitise = function(string) { return string.replace(/(\\+u0000)|\u0000/g, ''); // eslint-disable-line }; +const removeSecurityDetails = function(doc) { + const isUserDoc = doc && doc.type === 'user' && doc._id.startsWith('org.couchdb.user:'); + if (isUserDoc) { + delete doc.password_scheme; + delete doc.derived_key; + delete doc.salt; + } +}; + var deleteDocuments = function(db, postgresTable, docIdsToDelete) { if (docIdsToDelete && docIdsToDelete.length) { var query = format(DELETE_STMT, postgresTable, docIdsToDelete); @@ -95,16 +104,13 @@ var loadAndStoreDocs = function(db, couchdb, concurrentDocLimit, docsToDownload, }).then(function(couchDbResult) { log.debug('Inserting ' + couchDbResult.rows.length + ' results into postgresql'); - var insertSql = format( - INSERT_DOC_STMT, - postgresTable, - couchDbResult.rows.map(function(row) { - return [row.doc]; - }) - ); + const docsToInsert = couchDbResult.rows.map(function(row) { + removeSecurityDetails(row.doc); + return [row.doc]; + }); + let insertSql = format(INSERT_DOC_STMT, postgresTable, docsToInsert); insertSql = sanitise(insertSql); - return db.query(insertSql); }).then(function() { return loadAndStoreDocs(db, couchdb, concurrentDocLimit, docsToDownload, postgresTable); diff --git a/package-lock.json b/package-lock.json index d90315a..13dfd88 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "couch2pg", - "version": "0.7.0", + "version": "0.7.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 4f5f000..be37e44 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "couch2pg", - "version": "0.7.0", + "version": "0.7.1", "bin": { "couch2pg": "./cli.js" }, diff --git a/tests/unit/importer.js b/tests/unit/importer.js index dd92de8..2166c27 100644 --- a/tests/unit/importer.js +++ b/tests/unit/importer.js @@ -71,6 +71,50 @@ describe('importer', function() { allDocs.args[0][0].keys.should.deep.equal(['123']); }); }); + + it('removes security information from user docs', function () { + const userDocId = 'org.couchdb.user:test_user'; + sinon.stub(db, 'one').resolves(STORED_SEQ); + sinon.stub(couchdb, 'changes') + .onCall(0).resolves({ + results: [ + { id: userDocId, seq: 1 }, + ], + last_seq: 2 + }) + .onCall(1).resolves({ + results: [], + last_seq: 2 + }); + const query = sinon.stub(db, 'query').resolves(); + const allDocs = sinon.stub(couchdb, 'allDocs'); + allDocs.resolves({ + rows: [{ + id: userDocId, + doc: { + _id: userDocId, + _rev: '3-37b63ea82ca461bfa6b3d4cfda7dbf88', + name: 'test_user', + type: 'user', + roles: ['chw'], + facility_id: 'c0ca5e2b-508a-4ba7-b934-f6e4751223bf', + password_scheme: 'pbkdf2', + iterations: 10, + derived_key: '5ccbfab2b06a67450c3fbcda9fc0f4e27e5ba957', + salt: '713733ce185df96773d6bd4a860749ee' + } + }], + }); + + return importer(db, couchdb).importBatch().then(function() { + allDocs.args[0][0].keys.should.deep.equal([userDocId]); + query.args[1][0].should.include(`INSERT INTO couchdb (doc) VALUES ('{"_id":"${userDocId}"`); + query.args[1][0].should.include(`"roles":["chw"],`); + query.args[1][0].should.not.include('derived_key'); + query.args[1][0].should.not.include('salt'); + query.args[1][0].should.not.include('password_scheme'); + }); + }) }); describe('IO failure propagation:', function() {