2 /* eslint-disable capitalized-comments */
5 const assert
= require('assert');
6 const sinon
= require('sinon'); // eslint-disable-line node/no-unpublished-require
7 const MysteryBox
= require('../../lib/mystery-box');
8 const stubLogger
= require('../stub-logger');
10 describe('MysteryBox', function () {
11 const noExpectedException
= 'did not get expected exception';
12 let mb
, options
, object
;
13 beforeEach(function () {
15 encryptionSecret: 'this is not a very good secret',
18 afterEach(function () {
22 describe('constructor', function () {
23 it('needs a secret', async
function () {
26 mb
= new MysteryBox(stubLogger
, options
);
27 assert
.fail(noExpectedException
);
29 assert
.strictEqual(e
.message
, 'missing encryption secret', noExpectedException
);
33 it('accepts multiple secrets', async
function () {
36 encryptionSecret: ['first poor secret', 'second poor secret'],
38 mb
= new MysteryBox(stubLogger
, options
);
44 const encryptedResult
= await mb
.pack(object
);
45 const decryptedResult
= await mb
.unpack(encryptedResult
);
46 assert
.deepStrictEqual(decryptedResult
, object
);
49 it('covers options', function () {
51 mb
= new MysteryBox(stubLogger
);
52 assert
.fail(noExpectedException
);
54 assert
.strictEqual(e
.message
, 'missing encryption secret', noExpectedException
);
58 it('covers bad flags', function () {
59 options
.defaultFlags
= 300;
61 mb
= new MysteryBox(stubLogger
, options
);
62 assert
.fail(noExpectedException
);
64 assert(e
instanceof RangeError
, noExpectedException
);
68 it('covers missing ciphers', function () {
69 sinon
.stub(MysteryBox
._test
.crypto
, 'getCiphers').returns(['rot13']);
71 mb
= new MysteryBox(stubLogger
, options
);
72 assert
.fail(noExpectedException
);
74 assert
.strictEqual(e
.message
, 'no supported versions available', noExpectedException
);
79 describe('_keyFromSecret', function () {
80 it('covers invalid', async
function () {
82 await MysteryBox
._keyFromSecret('unknown deriver', 'secret', 'salt', 32);
84 assert(e
instanceof RangeError
);
89 describe('pack, unpack', function () {
90 beforeEach(function () {
91 mb
= new MysteryBox(stubLogger
, options
);
94 it('covers packing unsupported version', async
function () {
97 assert
.fail(noExpectedException
);
99 assert(e
instanceof RangeError
, noExpectedException
);
103 it('covers unpacking unsupported version', async
function () {
104 const badBuffer
= Buffer
.alloc(128);
105 badBuffer
.writeUInt8(0, 0); // No such thing as version 0
106 const badPayload
= badBuffer
.toString('base64');
108 await mb
.unpack(badPayload
);
109 assert
.fail(noExpectedException
);
111 assert(e
instanceof RangeError
, noExpectedException
);
115 it('encrypts and decrypts default version', async
function () {
122 const encryptedResult
= await mb
.pack(object
);
123 const decryptedResult
= await mb
.unpack(encryptedResult
);
124 assert
.deepStrictEqual(decryptedResult
, object
);
127 it('encrypts and decrypts default version, buffer contents', async
function () {
129 object
= Buffer
.from('a fine little buffer');
130 const encryptedResult
= await mb
.pack(object
);
131 const decryptedResult
= await mb
.unpack(encryptedResult
);
132 assert
.deepStrictEqual(decryptedResult
, object
);
135 it('decrypts secondary (older) secret', async
function () {
137 const oldmb
= new MysteryBox(stubLogger
, { encryptionSecret: 'old secret' });
138 const newmb
= new MysteryBox(stubLogger
, { encryptionSecret: ['new secret', 'old secret'] });
144 const oldEncrypted
= await oldmb
.pack(object
);
145 const newDecrypted
= await newmb
.unpack(oldEncrypted
);
146 assert
.deepStrictEqual(newDecrypted
, object
);
149 it('fails to decrypt invalid secret', async
function () {
151 const oldmb
= new MysteryBox(stubLogger
, { encryptionSecret: 'very old secret' });
152 const newmb
= new MysteryBox(stubLogger
, { encryptionSecret: ['new secret', 'old secret'] });
158 const oldEncrypted
= await oldmb
.pack(object
);
160 await newmb
.unpack(oldEncrypted
);
161 assert
.fail(noExpectedException
);
163 assert(e
instanceof Error
);
167 it('encrypts and decrypts all available versions +brotli', async
function () {
168 Object
.keys(mb
.versionParameters
).map((v
) => Number(v
)).forEach(async (version
) => {
174 const encryptedResult
= await mb
.pack(object
, version
, 0x00);
175 const decryptedResult
= await mb
.unpack(encryptedResult
);
176 assert
.deepStrictEqual(decryptedResult
, object
, `${version} results not symmetric`);
180 it('encrypts and decrypts all available versions +flate', async
function () {
181 Object
.keys(mb
.versionParameters
).map((v
) => Number(v
)).forEach(async (version
) => {
187 const encryptedResult
= await mb
.pack(object
, version
, 0x01);
188 const decryptedResult
= await mb
.unpack(encryptedResult
);
189 assert
.deepStrictEqual(decryptedResult
, object
, `${version} results not symmetric`);
193 it('handles large object +brotli', async
function () {
196 const firstChar
= 32, lastChar
= 126;
198 return Math
.floor(firstChar
+ (lastChar
- firstChar
+ 1) * Math
.random());
201 longProperty: 'x'.repeat(384 * 1024).split('').map(() => String
.fromCharCode(rnd())).join(''),
203 const encryptedResult
= await mb
.pack(object
, mb
.bestVersion
, 0x00);
204 const decryptedResult
= await mb
.unpack(encryptedResult
);
205 assert
.deepStrictEqual(decryptedResult
, object
);
208 it('handles large object +flate', async
function () {
211 const firstChar
= 32, lastChar
= 126;
213 return Math
.floor(firstChar
+ (lastChar
- firstChar
+ 1) * Math
.random());
216 longProperty: 'x'.repeat(384 * 1024).split('').map(() => String
.fromCharCode(rnd())).join(''),
218 const encryptedResult
= await mb
.pack(object
, mb
.bestVersion
, 0x01);
219 const decryptedResult
= await mb
.unpack(encryptedResult
);
220 assert
.deepStrictEqual(decryptedResult
, object
);
223 it('handles undefined', async
function () {
226 assert
.fail(noExpectedException
);
228 assert(e
instanceof RangeError
, noExpectedException
);
232 it('handles incomplete', async
function () {
234 const encryptedResult
= await mb
.pack({ foo: 'bar' });
236 await mb
.unpack(encryptedResult
.slice(0, 6));
237 assert
.fail(noExpectedException
);
239 assert(e
instanceof RangeError
, noExpectedException
);