@adorsys/encrypt-down
Advanced tools
Comparing version 1.0.1 to 1.1.0
{ | ||
"name": "@adorsys/encrypt-down", | ||
"version": "1.0.1", | ||
"version": "1.1.0", | ||
"description": "Encryption layer for level-db", | ||
@@ -64,7 +64,8 @@ "main": "src/index.js", | ||
"dependencies": { | ||
"@adorsys/jwe-codec": "1.0.0", | ||
"abstract-leveldown": "5.0.0", | ||
"inherits": "2.0.3" | ||
"inherits": "2.0.3", | ||
"node-jose": "1.0.0" | ||
}, | ||
"devDependencies": { | ||
"@adorsys/jwe-codec": "1.0.0", | ||
"@commitlint/cli": "7.1.2", | ||
@@ -71,0 +72,0 @@ "@commitlint/config-conventional": "7.1.2", |
@@ -13,4 +13,9 @@ # :closed_lock_with_key: encrypt-down :closed_lock_with_key: | ||
An abstract-leveldown implementation that wraps another store to encrypt values. | ||
encrypt-down is an encryption layer for LevelDB. | ||
For LevelDB exist several persistence bindings. | ||
Amongst others bindings for [IndexedDB](https://developer.mozilla.org/de/docs/IndexedDB). | ||
So lots (several MB) of sensitive user data can be stored securely (encrypted) in the browser across user sessions. | ||
### Installation | ||
@@ -24,45 +29,9 @@ | ||
Without any options `encrypt-down` can be used but nothing is encrypted. | ||
```js | ||
const memdown = require('memdown') | ||
const encryptdown = require('@adorsys/encrypt-down') | ||
const levleup = require('levelup') | ||
We need a JSON Web Key (JWK) or JSON Web Key Set (JWKS) as specified by [RFC 7517](https://tools.ietf.org/html/rfc7517). | ||
const db = levelup(encryptdown(memdown())) | ||
db.put('key', { awesome: true }, function (err) { | ||
db.get('key', function (err, value) { | ||
console.log(value) // { awesome: true } | ||
}) | ||
}) | ||
``` | ||
Can we specify the encryption that shall be used? Yes! | ||
```js | ||
const memdown = require('memdown') | ||
const encryptdown = require('@adorsys/encrypt-down') | ||
const levleup = require('levelup') | ||
// WARNING: do not use this codec in production it is NOT ENCRYPTING | ||
const codec = { | ||
encrypt: value => Promise.resolve(value), | ||
decrypt: value => Promise.resolve(value) | ||
} | ||
const db = levelup(encryptdown(memdown(), { codec })) | ||
db.put('key', { awesome: true }, function (err) { | ||
db.get('key', function (err, value) { | ||
console.log(value) // { awesome: true } | ||
}) | ||
}) | ||
``` | ||
Is there an example that actually encrypts the values? Yes! | ||
We can use an existing encryption library like [`jwe-codec`](https://github.com/adorsys/jwe-codec). | ||
```js | ||
const memdown = require('memdown') | ||
const encryptdown = require('@adorsys/encrypt-down') | ||
const levleup = require('levelup') | ||
const jwe = require('@adorsys/jwe-codec') | ||
const key = { | ||
const encryptdown = require('./src') | ||
const levelup = require('levelup') | ||
const jwk = { | ||
kty: 'oct', | ||
@@ -73,11 +42,15 @@ alg: 'A256GCM', | ||
} | ||
const memdb = memdown() | ||
const db = levelup(encryptdown(memdb, { jwk })) | ||
jwe(key).then(function(codec) { | ||
const db = levelup(encryptdown(memdown(), { codec })) | ||
db.put('key', { awesome: true }, function (err) { | ||
db.get('key', function (err, value) { | ||
console.log(value) // { awesome: true } | ||
}) | ||
db.put('key', { awesome: true }, function (err) { | ||
memdb._get('key', { asBuffer: false }, function (err, value) { | ||
value | ||
console.log(value) | ||
// eyJlbmMiOiJBMjU2R0NNIiwiYWxnIjoiZGlyIiwia2lkIjoialpESEVqN0ZhR3N5OHNUSUZLRWlnejB4TjFEVWlBZWp0S1ZNcEl2Z3dqOCJ9..LLeRPtRCpn-Zie6-.zZc0LQ_vvHCppRAaC5fxw4yJ0041l6mGOSgLDVnaPagSv_3Khp8a8lyAo9utHQKpVX6RNVaVPBQQxJpkw_Zyljeg7L-O_Nc3N2Hi_904qE6_zwORqQRc.R0JhfgTHIcD_93kXzZ8BrA | ||
}) | ||
db.get('key', { asBuffer: false }, function (err, value) { | ||
console.log(value) | ||
// { awesome: true } | ||
}) | ||
}) | ||
@@ -92,8 +65,4 @@ ``` | ||
- `options`: | ||
- `codec`: | ||
- `encrypt`: function returning promise of encrypted value | ||
- `decrypt`: function returning promise of decrypted value | ||
- `jwk`: a JSON Web Key (JWK) or JSON Web Key Set (JWKS) as specified by [RFC 7517](https://tools.ietf.org/html/rfc7517) | ||
`encrypt` and `decrypt` both default to identity function when not explicitly specified. | ||
## Credits | ||
@@ -105,3 +74,3 @@ | ||
<!-- prettier-ignore --> | ||
| <img src="https://avatars.githubusercontent.com/u/3055345?v=3" width="100px;"/><br /><sub><b>Vincent Weevers</b></sub><br />:speech_balloon: | | | | | | | | ||
| <img src="https://avatars.githubusercontent.com/u/3055345?v=3" width="100px;"/><br /><sub><b>Vincent Weevers</b></sub><br />:speech_balloon: | <img src="https://avatars.githubusercontent.com/u/1225651?v=3" width="100px;"/><br /><sub><b>Francis Pouatcha</b></sub><br />🤔 | | | | | | | ||
| :---: | :---: | :---: | :---: | :---: | :---: | :---: | | ||
@@ -108,0 +77,0 @@ <!-- ALL-CONTRIBUTORS-LIST:END --> |
@@ -5,4 +5,5 @@ 'use strict' | ||
const AbstractIterator = require('abstract-leveldown').AbstractIterator | ||
const jose = require('node-jose') | ||
const jwe = require('@adorsys/jwe-codec') | ||
const inherits = require('inherits') | ||
const IdentityCodec = require('./identity-codec') | ||
@@ -18,8 +19,8 @@ module.exports = DB.default = DB | ||
options = options || {} | ||
if (typeof options.codec === 'undefined') { | ||
options.codec = IdentityCodec | ||
if (typeof options.jwk === 'undefined') { | ||
throw new Error('EncryptDown: a JsonWebKey is required!') | ||
} | ||
const jwks = [].concat(options.jwk) | ||
this.keystorePromise = jose.JWK.asKeyStore(jwks) | ||
this.db = db | ||
this.codec = options.codec | ||
} | ||
@@ -38,3 +39,14 @@ | ||
DB.prototype._open = function (options, callback) { | ||
this.db.open(options, callback) | ||
this.keystorePromise | ||
.then(ks => { | ||
const key = ks.get({ use: 'enc' }) | ||
return jwe(key.toJSON(true)) | ||
}) | ||
.then(codec => { | ||
this.codec = codec | ||
return this.db.open(options, callback) | ||
}) | ||
.catch(error => { | ||
return callback(error) | ||
}) | ||
} | ||
@@ -47,7 +59,6 @@ | ||
DB.prototype._put = function (key, value, options, callback) { | ||
const self = this | ||
return this.codec | ||
.encrypt(value) | ||
.then(function (cipher) { | ||
self.db.put(key, cipher, options, callback) | ||
.then(cipher => { | ||
this.db.put(key, cipher, options, callback) | ||
}) | ||
@@ -58,8 +69,7 @@ .catch(callback) | ||
DB.prototype._get = function (key, options, callback) { | ||
const self = this | ||
self.db.get(key, { ...options, asBuffer: false }, function (err, cipher) { | ||
this.db.get(key, { ...options, asBuffer: false }, (err, cipher) => { | ||
if (err) { | ||
return callback(err) | ||
} | ||
self.codec | ||
this.codec | ||
.decrypt(cipher) | ||
@@ -82,3 +92,2 @@ .then(function (value) { | ||
DB.prototype._batch = function (ops, options, callback) { | ||
const self = this | ||
Promise.all( | ||
@@ -88,3 +97,3 @@ ops.map(op => { | ||
case 'put': | ||
return encryptOperationValue(self.codec, op) | ||
return encryptOperationValue(this.codec, op) | ||
default: | ||
@@ -94,4 +103,4 @@ return Promise.resolve(op) | ||
}) | ||
).then(function (operations) { | ||
self.db._batch(operations, options, callback) | ||
).then(operations => { | ||
this.db._batch(operations, options, callback) | ||
}) | ||
@@ -116,4 +125,3 @@ } | ||
Iterator.prototype._next = function (callback) { | ||
const self = this | ||
self.it.next(function (err, key, cipher) { | ||
this.it.next((err, key, cipher) => { | ||
if (err) { | ||
@@ -125,9 +133,9 @@ return callback(err) | ||
} | ||
self.codec | ||
this.codec | ||
.decrypt(cipher) | ||
.then(function (value) { | ||
.then(value => { | ||
callback( | ||
null, | ||
key, | ||
self.options.valueAsBuffer ? Buffer.from(String(value)) : value | ||
this.options.valueAsBuffer ? Buffer.from(String(value)) : value | ||
) | ||
@@ -134,0 +142,0 @@ }) |
@@ -5,10 +5,8 @@ const test = require('ava') | ||
const ltgt = require('ltgt') | ||
const jwe = require('@adorsys/jwe-codec') | ||
const EncryptDown = require('../src') | ||
const { stringBuffer, getKey, putKey, promisify } = require('./helper') | ||
const key = require('./key.json') | ||
const jwk = require('./jwk.json') | ||
test.beforeEach(async t => { | ||
const codec = await jwe(key) | ||
const db = new EncryptDown(memdown(), { codec }) | ||
const db = new EncryptDown(memdown(), { jwk }) | ||
const promised = promisify(db) | ||
@@ -15,0 +13,0 @@ t.context.db = db |
@@ -5,32 +5,25 @@ const test = require('tape') | ||
const EncryptDown = require('../../src') | ||
const jwe = require('@adorsys/jwe-codec') | ||
const key = require('../key.json') | ||
;(async () => { | ||
const codec = await jwe(key) | ||
const factory = location => new EncryptDown(leveldown(location), { codec }) | ||
const jwk = require('../jwk.json') | ||
const factory = location => new EncryptDown(leveldown(location), { jwk }) | ||
/** compatibility with basic LevelDOWN API **/ | ||
test('integration with leveldown', t => { | ||
require('abstract-leveldown/abstract/leveldown-test').args(factory, test) | ||
require('abstract-leveldown/abstract/open-test').all( | ||
factory, | ||
t.test, | ||
testCommon | ||
) | ||
require('abstract-leveldown/abstract/del-test').all(factory, t.test) | ||
require('abstract-leveldown/abstract/get-test').all(factory, t.test) | ||
require('abstract-leveldown/abstract/put-test').all(factory, t.test) | ||
require('abstract-leveldown/abstract/put-get-del-test').all(factory, t.test) | ||
require('abstract-leveldown/abstract/batch-test').all(factory, t.test) | ||
require('abstract-leveldown/abstract/chained-batch-test').all( | ||
factory, | ||
t.test | ||
) | ||
require('abstract-leveldown/abstract/close-test').close(factory, t.test) | ||
require('abstract-leveldown/abstract/iterator-test').all(factory, t.test) | ||
require('abstract-leveldown/abstract/iterator-range-test').all( | ||
factory, | ||
t.test | ||
) | ||
}) | ||
})() | ||
/** compatibility with basic LevelDOWN API **/ | ||
test('integration with leveldown', t => { | ||
require('abstract-leveldown/abstract/leveldown-test').args(factory, test) | ||
require('abstract-leveldown/abstract/open-test').all( | ||
factory, | ||
t.test, | ||
testCommon | ||
) | ||
require('abstract-leveldown/abstract/del-test').all(factory, t.test) | ||
require('abstract-leveldown/abstract/get-test').all(factory, t.test) | ||
require('abstract-leveldown/abstract/put-test').all(factory, t.test) | ||
require('abstract-leveldown/abstract/put-get-del-test').all(factory, t.test) | ||
require('abstract-leveldown/abstract/batch-test').all(factory, t.test) | ||
require('abstract-leveldown/abstract/chained-batch-test').all(factory, t.test) | ||
require('abstract-leveldown/abstract/close-test').close(factory, t.test) | ||
require('abstract-leveldown/abstract/iterator-test').all(factory, t.test) | ||
require('abstract-leveldown/abstract/iterator-range-test').all( | ||
factory, | ||
t.test | ||
) | ||
}) |
@@ -5,32 +5,25 @@ const test = require('tape') | ||
const EncryptDown = require('../../src') | ||
const jwe = require('@adorsys/jwe-codec') | ||
const key = require('../key.json') | ||
;(async () => { | ||
const codec = await jwe(key) | ||
const factory = location => new EncryptDown(leveljs(location), { codec }) | ||
const jwk = require('../jwk.json') | ||
const factory = location => new EncryptDown(leveljs(location), { jwk }) | ||
/** compatibility with basic LevelDOWN API **/ | ||
test('integration with leveldown', t => { | ||
require('abstract-leveldown/abstract/leveldown-test').args(factory, test) | ||
require('abstract-leveldown/abstract/open-test').open( | ||
factory, | ||
t.test, | ||
testCommon | ||
) | ||
require('abstract-leveldown/abstract/del-test').all(factory, t.test) | ||
require('abstract-leveldown/abstract/get-test').all(factory, t.test) | ||
require('abstract-leveldown/abstract/put-test').all(factory, t.test) | ||
require('abstract-leveldown/abstract/put-get-del-test').all(factory, t.test) | ||
require('abstract-leveldown/abstract/batch-test').all(factory, t.test) | ||
require('abstract-leveldown/abstract/chained-batch-test').all( | ||
factory, | ||
t.test | ||
) | ||
require('abstract-leveldown/abstract/close-test').close(factory, t.test) | ||
require('abstract-leveldown/abstract/iterator-test').all(factory, t.test) | ||
require('abstract-leveldown/abstract/iterator-range-test').all( | ||
factory, | ||
t.test | ||
) | ||
}) | ||
})() | ||
/** compatibility with basic LevelDOWN API **/ | ||
test('integration with leveldown', t => { | ||
require('abstract-leveldown/abstract/leveldown-test').args(factory, test) | ||
require('abstract-leveldown/abstract/open-test').open( | ||
factory, | ||
t.test, | ||
testCommon | ||
) | ||
require('abstract-leveldown/abstract/del-test').all(factory, t.test) | ||
require('abstract-leveldown/abstract/get-test').all(factory, t.test) | ||
require('abstract-leveldown/abstract/put-test').all(factory, t.test) | ||
require('abstract-leveldown/abstract/put-get-del-test').all(factory, t.test) | ||
require('abstract-leveldown/abstract/batch-test').all(factory, t.test) | ||
require('abstract-leveldown/abstract/chained-batch-test').all(factory, t.test) | ||
require('abstract-leveldown/abstract/close-test').close(factory, t.test) | ||
require('abstract-leveldown/abstract/iterator-test').all(factory, t.test) | ||
require('abstract-leveldown/abstract/iterator-range-test').all( | ||
factory, | ||
t.test | ||
) | ||
}) |
@@ -5,37 +5,30 @@ const test = require('tape') | ||
const EncryptDown = require('../../src') | ||
const jwe = require('@adorsys/jwe-codec') | ||
const key = require('../key.json') | ||
;(async () => { | ||
const codec = await jwe(key) | ||
const factory = location => new EncryptDown(memdown(), { codec }) | ||
const jwk = require('../jwk.json') | ||
const factory = location => new EncryptDown(memdown(), { jwk }) | ||
/** compatibility with basic LevelDOWN API **/ | ||
test('integration with memdown', t => { | ||
// require('abstract-leveldown/abstract/leveldown-test').args(factory, test) | ||
require('abstract-leveldown/abstract/open-test').args( | ||
factory, | ||
t.test, | ||
testCommon | ||
) | ||
require('abstract-leveldown/abstract/open-test').open( | ||
factory, | ||
t.test, | ||
testCommon | ||
) | ||
require('abstract-leveldown/abstract/del-test').all(factory, t.test) | ||
require('abstract-leveldown/abstract/get-test').all(factory, t.test) | ||
require('abstract-leveldown/abstract/put-test').all(factory, t.test) | ||
require('abstract-leveldown/abstract/put-get-del-test').all(factory, t.test) | ||
require('abstract-leveldown/abstract/batch-test').all(factory, t.test) | ||
require('abstract-leveldown/abstract/chained-batch-test').all( | ||
factory, | ||
t.test | ||
) | ||
require('abstract-leveldown/abstract/close-test').close(factory, t.test) | ||
require('abstract-leveldown/abstract/iterator-test').all(factory, t.test) | ||
require('abstract-leveldown/abstract/iterator-range-test').all( | ||
factory, | ||
t.test | ||
) | ||
}) | ||
})() | ||
/** compatibility with basic LevelDOWN API **/ | ||
test('integration with memdown', t => { | ||
// require('abstract-leveldown/abstract/leveldown-test').args(factory, test) | ||
require('abstract-leveldown/abstract/open-test').args( | ||
factory, | ||
t.test, | ||
testCommon | ||
) | ||
require('abstract-leveldown/abstract/open-test').open( | ||
factory, | ||
t.test, | ||
testCommon | ||
) | ||
require('abstract-leveldown/abstract/del-test').all(factory, t.test) | ||
require('abstract-leveldown/abstract/get-test').all(factory, t.test) | ||
require('abstract-leveldown/abstract/put-test').all(factory, t.test) | ||
require('abstract-leveldown/abstract/put-get-del-test').all(factory, t.test) | ||
require('abstract-leveldown/abstract/batch-test').all(factory, t.test) | ||
require('abstract-leveldown/abstract/chained-batch-test').all(factory, t.test) | ||
require('abstract-leveldown/abstract/close-test').close(factory, t.test) | ||
require('abstract-leveldown/abstract/iterator-test').all(factory, t.test) | ||
require('abstract-leveldown/abstract/iterator-range-test').all( | ||
factory, | ||
t.test | ||
) | ||
}) |
Sorry, the diff of this file is too big to display
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
1758313
21
54431
0
4
75
+ Added@adorsys/jwe-codec@1.0.0
+ Addednode-jose@1.0.0
+ Added@adorsys/jwe-codec@1.0.0(transitive)
+ Addedbase64url@3.0.1(transitive)
+ Addedes6-promise@4.2.8(transitive)
+ Addedhydration@1.0.0(transitive)
+ Addedlodash.assign@4.2.0(transitive)
+ Addedlodash.clone@4.5.0(transitive)
+ Addedlodash.fill@3.4.0(transitive)
+ Addedlodash.flatten@4.4.0(transitive)
+ Addedlodash.intersection@4.4.0(transitive)
+ Addedlodash.merge@4.6.2(transitive)
+ Addedlodash.omit@4.5.0(transitive)
+ Addedlodash.partialright@4.2.1(transitive)
+ Addedlodash.pick@4.4.0(transitive)
+ Addedlodash.uniq@4.5.0(transitive)
+ Addedlong@4.0.0(transitive)
+ Addednode-forge@0.7.6(transitive)
+ Addednode-jose@1.0.0(transitive)
+ Addeduuid@3.4.0(transitive)