2f2b734e0a3271c47530b90d11b03664d59a2383
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 let mb
, options
, object
;
12 beforeEach(function () {
14 encryptionSecret: 'this is not a very good secret',
17 afterEach(function () {
21 describe('constructor', function () {
22 it('needs a secret', async
function () {
24 assert
.rejects(() => new MysteryBox(stubLogger
, options
));
27 it('accepts multiple secrets', async
function () {
30 encryptionSecret: ['first poor secret', 'second poor secret'],
32 mb
= new MysteryBox(stubLogger
, options
);
38 const encryptedResult
= await mb
.pack(object
);
39 const decryptedResult
= await mb
.unpack(encryptedResult
);
40 assert
.deepStrictEqual(decryptedResult
, object
);
43 it('covers options', function () {
44 assert
.rejects(() => new MysteryBox(stubLogger
));
47 it('covers bad flags', function () {
48 options
.defaultFlags
= 300;
49 assert
.rejects(() => new MysteryBox(stubLogger
, options
), RangeError
);
52 it('covers missing ciphers', function () {
53 sinon
.stub(MysteryBox
._test
.crypto
, 'getCiphers').returns(['rot13']);
54 assert
.rejects(() => new MysteryBox(stubLogger
, options
));
58 describe('_keyFromSecret', function () {
59 it('covers invalid', async
function () {
60 assert
.rejects(() => MysteryBox
._keyFromSecret('unknown deriver', 'secret', 'salt', 32), RangeError
);
64 describe('pack, unpack', function () {
65 beforeEach(function () {
66 mb
= new MysteryBox(stubLogger
, options
);
69 it('covers packing unsupported version', async
function () {
70 assert
.rejects(() => mb
.pack({}, 0), RangeError
);
73 it('covers unpacking unsupported version', async
function () {
74 const badBuffer
= Buffer
.alloc(128);
75 badBuffer
.writeUInt8(0, 0); // No such thing as version 0
76 const badPayload
= badBuffer
.toString('base64');
77 assert
.rejects(() => mb
.unpack(badPayload
), RangeError
);
80 it('encrypts and decrypts default version', async
function () {
87 const encryptedResult
= await mb
.pack(object
);
88 const decryptedResult
= await mb
.unpack(encryptedResult
);
89 assert
.deepStrictEqual(decryptedResult
, object
);
92 it('encrypts and decrypts default version, buffer contents', async
function () {
94 object
= Buffer
.from('a fine little buffer');
95 const encryptedResult
= await mb
.pack(object
);
96 const decryptedResult
= await mb
.unpack(encryptedResult
);
97 assert
.deepStrictEqual(decryptedResult
, object
);
100 it('decrypts secondary (older) secret', async
function () {
102 const oldmb
= new MysteryBox(stubLogger
, { encryptionSecret: 'old secret' });
103 const newmb
= new MysteryBox(stubLogger
, { encryptionSecret: ['new secret', 'old secret'] });
109 const oldEncrypted
= await oldmb
.pack(object
);
110 const newDecrypted
= await newmb
.unpack(oldEncrypted
);
111 assert
.deepStrictEqual(newDecrypted
, object
);
114 it('fails to decrypt invalid secret', async
function () {
116 const oldmb
= new MysteryBox(stubLogger
, { encryptionSecret: 'very old secret' });
117 const newmb
= new MysteryBox(stubLogger
, { encryptionSecret: ['new secret', 'old secret'] });
123 const oldEncrypted
= await oldmb
.pack(object
);
124 assert
.rejects(() => newmb
.unpack(oldEncrypted
));
127 it('encrypts and decrypts all available versions +brotli', async
function () {
128 Object
.keys(mb
.versionParameters
).map((v
) => Number(v
)).forEach(async (version
) => {
134 const encryptedResult
= await mb
.pack(object
, version
, 0x00);
135 const decryptedResult
= await mb
.unpack(encryptedResult
);
136 assert
.deepStrictEqual(decryptedResult
, object
, `${version} results not symmetric`);
140 it('encrypts and decrypts all available versions +flate', async
function () {
141 Object
.keys(mb
.versionParameters
).map((v
) => Number(v
)).forEach(async (version
) => {
147 const encryptedResult
= await mb
.pack(object
, version
, 0x01);
148 const decryptedResult
= await mb
.unpack(encryptedResult
);
149 assert
.deepStrictEqual(decryptedResult
, object
, `${version} results not symmetric`);
153 it('handles large object +brotli', async
function () {
156 const firstChar
= 32, lastChar
= 126;
158 return Math
.floor(firstChar
+ (lastChar
- firstChar
+ 1) * Math
.random());
161 longProperty: 'x'.repeat(384 * 1024).split('').map(() => String
.fromCharCode(rnd())).join(''),
163 const encryptedResult
= await mb
.pack(object
, mb
.bestVersion
, 0x00);
164 const decryptedResult
= await mb
.unpack(encryptedResult
);
165 assert
.deepStrictEqual(decryptedResult
, object
);
168 it('handles large object +flate', async
function () {
171 const firstChar
= 32, lastChar
= 126;
173 return Math
.floor(firstChar
+ (lastChar
- firstChar
+ 1) * Math
.random());
176 longProperty: 'x'.repeat(384 * 1024).split('').map(() => String
.fromCharCode(rnd())).join(''),
178 const encryptedResult
= await mb
.pack(object
, mb
.bestVersion
, 0x01);
179 const decryptedResult
= await mb
.unpack(encryptedResult
);
180 assert
.deepStrictEqual(decryptedResult
, object
);
183 it('handles undefined', async
function () {
184 assert
.rejects(() => mb
.unpack(), RangeError
);
187 it('handles incomplete', async
function () {
189 const encryptedResult
= await mb
.pack({ foo: 'bar' });
190 assert
.rejects(() => mb
.unpack(encryptedResult
.slice(0, 6)), RangeError
);