Skip to content

Commit 2598c16

Browse files
committed
test: add environments to encrypton tests
1 parent 0d5c00a commit 2598c16

File tree

1 file changed

+176
-8
lines changed

1 file changed

+176
-8
lines changed

app-config-encryption/src/encryption.test.ts

Lines changed: 176 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -282,11 +282,171 @@ describe('Value Encryption', () => {
282282
});
283283
});
284284

285+
describe('per environment encryption E2E', () => {
286+
it('sets up, trusts and untrusts users correctly', () => {
287+
const cwd = process.cwd();
288+
289+
return withTempFiles({}, async (inDir) => {
290+
// run environmentless
291+
delete process.env.NODE_ENV;
292+
293+
process.chdir(inDir('.'));
294+
process.env.APP_CONFIG_SECRETS_KEYCHAIN_FOLDER = inDir('keychain');
295+
296+
const keys = await initializeKeysManually({
297+
name: 'Tester',
298+
299+
});
300+
301+
const dirs = {
302+
keychain: inDir('keychain'),
303+
privateKey: inDir('keychain/private-key.asc'),
304+
publicKey: inDir('keychain/public-key.asc'),
305+
revocationCert: inDir('keychain/revocation.asc'),
306+
};
307+
308+
expect(await initializeLocalKeys(keys, dirs)).toEqual({
309+
publicKeyArmored: keys.publicKeyArmored,
310+
});
311+
312+
const publicKey = await loadPublicKey();
313+
const privateKey = await loadPrivateKey();
314+
315+
// this is what init-repo does
316+
await trustTeamMember(publicKey, privateKey);
317+
318+
// at this point, we should have ourselves trusted, and 1 symmetric key
319+
const { value: meta } = await loadMetaConfig();
320+
321+
expect(meta.teamMembers).toHaveProperty('default');
322+
expect(meta.encryptionKeys).toHaveProperty('default');
323+
expect((meta.teamMembers! as any).default).toHaveLength(1);
324+
expect((meta.encryptionKeys! as any).default).toHaveLength(1);
325+
326+
const encryptionKey = await loadLatestSymmetricKey(privateKey);
327+
const encrypted = await encryptValue('a secret value', encryptionKey);
328+
await expect(decryptValue(encrypted, encryptionKey)).resolves.toBe('a secret value');
329+
330+
// now lets create a new environment
331+
await trustTeamMember(publicKey, privateKey, { ...defaultEnvOptions, override: 'prod' });
332+
333+
// at this point, we should have a default and a prod env with 1 trusted member and 1 key each
334+
const { value: prodEnvMeta } = await loadMetaConfig();
335+
336+
expect(prodEnvMeta.teamMembers).toHaveProperty('default');
337+
expect(prodEnvMeta.encryptionKeys).toHaveProperty('default');
338+
expect((prodEnvMeta.teamMembers! as any).default).toHaveLength(1);
339+
expect((prodEnvMeta.encryptionKeys! as any).default).toHaveLength(1);
340+
expect(prodEnvMeta.teamMembers).toHaveProperty('production');
341+
expect(prodEnvMeta.encryptionKeys).toHaveProperty('production');
342+
expect((prodEnvMeta.teamMembers! as any).production).toHaveLength(1);
343+
expect((prodEnvMeta.encryptionKeys! as any).production).toHaveLength(1);
344+
345+
const prodEncryptionKey = await loadLatestSymmetricKey(privateKey);
346+
const prodEncrypted = await encryptValue('a secret value', prodEncryptionKey);
347+
await expect(decryptValue(prodEncrypted, prodEncryptionKey)).resolves.toBe('a secret value');
348+
349+
const teammateKeys = await initializeKeysManually({
350+
name: 'A Teammate',
351+
352+
});
353+
354+
const teammatePublicKey = await loadPublicKey(teammateKeys.publicKeyArmored);
355+
const teammatePrivateKey = await loadPrivateKey(teammateKeys.privateKeyArmored);
356+
357+
await trustTeamMember(teammatePublicKey, privateKey);
358+
359+
// at this point, we should have 2 team members, but still 1 symmetric key
360+
const { value: metaAfterTrustingTeammate } = await loadMetaConfig();
361+
362+
expect(metaAfterTrustingTeammate.teamMembers).toHaveProperty('default');
363+
expect(metaAfterTrustingTeammate.encryptionKeys).toHaveProperty('default');
364+
expect((metaAfterTrustingTeammate.teamMembers! as any).default).toHaveLength(2);
365+
expect((metaAfterTrustingTeammate.encryptionKeys! as any).default).toHaveLength(1);
366+
expect(metaAfterTrustingTeammate.teamMembers).toHaveProperty('production');
367+
expect(metaAfterTrustingTeammate.encryptionKeys).toHaveProperty('production');
368+
expect((metaAfterTrustingTeammate.teamMembers! as any).production).toHaveLength(1);
369+
expect((metaAfterTrustingTeammate.encryptionKeys! as any).production).toHaveLength(1);
370+
371+
// ensures that the teammate can now encrypt/decrypt values
372+
const encryptedByTeammate = await encryptValue(
373+
'a secret value',
374+
await loadLatestSymmetricKey(teammatePrivateKey),
375+
);
376+
await expect(
377+
decryptValue(encryptedByTeammate, await loadLatestSymmetricKey(teammatePrivateKey)),
378+
).resolves.toBe('a secret value');
379+
380+
// ensures that we can still encrypt/decrypt values
381+
const encryptedByUs = await encryptValue(
382+
'a secret value',
383+
await loadLatestSymmetricKey(privateKey),
384+
);
385+
await expect(
386+
decryptValue(encryptedByUs, await loadLatestSymmetricKey(privateKey)),
387+
).resolves.toBe('a secret value');
388+
389+
await untrustTeamMember('[email protected]', privateKey);
390+
391+
// at this point, we should have 1 team members, and a newly generated symmetric key
392+
const { value: metaAfterUntrustingTeammate } = await loadMetaConfig();
393+
394+
expect(metaAfterUntrustingTeammate.teamMembers).toHaveProperty('default');
395+
expect(metaAfterUntrustingTeammate.encryptionKeys).toHaveProperty('default');
396+
expect((metaAfterUntrustingTeammate.teamMembers! as any).default).toHaveLength(1);
397+
expect((metaAfterUntrustingTeammate.encryptionKeys! as any).default).toHaveLength(2);
398+
expect(metaAfterUntrustingTeammate.teamMembers).toHaveProperty('production');
399+
expect(metaAfterUntrustingTeammate.encryptionKeys).toHaveProperty('production');
400+
expect((metaAfterUntrustingTeammate.teamMembers! as any).production).toHaveLength(1);
401+
expect((metaAfterUntrustingTeammate.encryptionKeys! as any).production).toHaveLength(1);
402+
403+
// ensures that we can still encrypt/decrypt values
404+
const newlyEncryptedByUs = await encryptValue(
405+
'a secret value',
406+
await loadLatestSymmetricKey(privateKey),
407+
);
408+
await expect(
409+
decryptValue(newlyEncryptedByUs, await loadLatestSymmetricKey(privateKey)),
410+
).resolves.toBe('a secret value');
411+
412+
// now, the teammate should have no access
413+
await expect(loadLatestSymmetricKey(teammatePrivateKey)).rejects.toThrow();
414+
415+
// just for test coverage, create a new symmetric key
416+
const latestSymmetricKey = await loadLatestSymmetricKey(privateKey);
417+
418+
const newRevisionNumber = getRevisionNumber(latestSymmetricKey.revision) + 1;
419+
420+
await saveNewSymmetricKey(
421+
await generateSymmetricKey(newRevisionNumber.toString()),
422+
await loadTeamMembers(),
423+
);
424+
425+
const { value: metaAfterNewSymmetricKey } = await loadMetaConfig();
426+
427+
expect(metaAfterNewSymmetricKey.teamMembers).toHaveProperty('default');
428+
expect(metaAfterNewSymmetricKey.encryptionKeys).toHaveProperty('default');
429+
expect((metaAfterNewSymmetricKey.teamMembers! as any).default).toHaveLength(1);
430+
expect((metaAfterNewSymmetricKey.encryptionKeys! as any).default).toHaveLength(3);
431+
expect(metaAfterNewSymmetricKey.teamMembers).toHaveProperty('production');
432+
expect(metaAfterNewSymmetricKey.encryptionKeys).toHaveProperty('production');
433+
expect((metaAfterNewSymmetricKey.teamMembers! as any).production).toHaveLength(1);
434+
expect((metaAfterNewSymmetricKey.encryptionKeys! as any).production).toHaveLength(1);
435+
436+
// get out of the directory, Windows doesn't like unlink while cwd
437+
process.chdir(cwd);
438+
});
439+
});
440+
});
441+
285442
describe('E2E Encrypted Repo', () => {
286443
it('sets up, trusts and untrusts users correctly', () => {
287444
const cwd = process.cwd();
288445

289446
return withTempFiles({}, async (inDir) => {
447+
// run environmentless
448+
delete process.env.NODE_ENV;
449+
290450
process.chdir(inDir('.'));
291451
process.env.APP_CONFIG_SECRETS_KEYCHAIN_FOLDER = inDir('keychain');
292452

@@ -315,8 +475,10 @@ describe('E2E Encrypted Repo', () => {
315475
// at this point, we should have ourselves trusted, and 1 symmetric key
316476
const { value: meta } = await loadMetaConfig();
317477

318-
expect(meta.teamMembers).toHaveLength(1);
319-
expect(meta.encryptionKeys).toHaveLength(1);
478+
expect(meta.teamMembers).toHaveProperty('default');
479+
expect(meta.encryptionKeys).toHaveProperty('default');
480+
expect((meta.teamMembers! as any).default).toHaveLength(1);
481+
expect((meta.encryptionKeys! as any).default).toHaveLength(1);
320482

321483
const encryptionKey = await loadLatestSymmetricKey(privateKey);
322484
const encrypted = await encryptValue('a secret value', encryptionKey);
@@ -335,8 +497,10 @@ describe('E2E Encrypted Repo', () => {
335497
// at this point, we should have 2 team members, but still 1 symmetric key
336498
const { value: metaAfterTrustingTeammate } = await loadMetaConfig();
337499

338-
expect(metaAfterTrustingTeammate.teamMembers).toHaveLength(2);
339-
expect(metaAfterTrustingTeammate.encryptionKeys).toHaveLength(1);
500+
expect(metaAfterTrustingTeammate.teamMembers).toHaveProperty('default');
501+
expect(metaAfterTrustingTeammate.encryptionKeys).toHaveProperty('default');
502+
expect((metaAfterTrustingTeammate.teamMembers! as any).default).toHaveLength(2);
503+
expect((metaAfterTrustingTeammate.encryptionKeys! as any).default).toHaveLength(1);
340504

341505
// ensures that the teammate can now encrypt/decrypt values
342506
const encryptedByTeammate = await encryptValue(
@@ -361,8 +525,10 @@ describe('E2E Encrypted Repo', () => {
361525
// at this point, we should have 1 team members, and a newly generated symmetric key
362526
const { value: metaAfterUntrustingTeammate } = await loadMetaConfig();
363527

364-
expect(metaAfterUntrustingTeammate.teamMembers).toHaveLength(1);
365-
expect(metaAfterUntrustingTeammate.encryptionKeys).toHaveLength(2);
528+
expect(metaAfterUntrustingTeammate.teamMembers).toHaveProperty('default');
529+
expect(metaAfterUntrustingTeammate.encryptionKeys).toHaveProperty('default');
530+
expect((metaAfterUntrustingTeammate.teamMembers! as any).default).toHaveLength(1);
531+
expect((metaAfterUntrustingTeammate.encryptionKeys! as any).default).toHaveLength(2);
366532

367533
// ensures that we can still encrypt/decrypt values
368534
const newlyEncryptedByUs = await encryptValue(
@@ -388,8 +554,10 @@ describe('E2E Encrypted Repo', () => {
388554

389555
const { value: metaAfterNewSymmetricKey } = await loadMetaConfig();
390556

391-
expect(metaAfterNewSymmetricKey.teamMembers).toHaveLength(1);
392-
expect(metaAfterNewSymmetricKey.encryptionKeys).toHaveLength(3);
557+
expect(metaAfterNewSymmetricKey.teamMembers).toHaveProperty('default');
558+
expect(metaAfterNewSymmetricKey.encryptionKeys).toHaveProperty('default');
559+
expect((metaAfterNewSymmetricKey.teamMembers! as any).default).toHaveLength(1);
560+
expect((metaAfterNewSymmetricKey.encryptionKeys! as any).default).toHaveLength(3);
393561

394562
// get out of the directory, Windows doesn't like unlink while cwd
395563
process.chdir(cwd);

0 commit comments

Comments
 (0)