return;
}
- const { url, prf: prfPromise } = await getPrf(getPrfOptions);
- if (!getPrfOptions.autoOpen) {
- if (!silent) { console.log(`Open this page in a web browser to complete the passkey flow: ${url}`); }
- }
- const prf = await prfPromise;
- if (prf === null) {
- throw new InputError('Unable to get passkey.');
- }
-
+ let prf = null;
/** @type {Env} */const encryptedEnv = Object.create(null);
for (const [envVar, value] of Object.entries(env)) {
if (value === undefined) {
}
}
+ if (prf === null) {
+ const { url, prf: prfPromise } = await getPrf(getPrfOptions);
+ if (!getPrfOptions.autoOpen) {
+ if (!silent) { console.log(`Open this page in a web browser to complete the passkey flow: ${url}`); }
+ }
+ prf = await prfPromise;
+ if (prf === null) {
+ throw new InputError('Unable to get passkey.');
+ }
+ }
const encryptedValue = await encryptRaw({ prf, value });
encryptedEnv[envVar] = encryptedValue;
}
return;
}
- const { url, prf: prfPromise } = await getPrf(getPrfOptions);
- if (!getPrfOptions.autoOpen) {
- if (!silent) { console.log(`Open this page in a web browser to complete the passkey flow: ${url}`); }
- }
- const prf = await prfPromise;
- if (prf === null) {
- throw new InputError('Unable to get passkey.');
- }
-
+ let prf = null;
/** @type {Env} */const decryptedEnv = {};
for (const [envVar, value] of Object.entries(env)) {
if (value === undefined) {
case 'error': throw new Error(`Environment variable "${envVar}" is not encrypted.`);
}
}
+
+ if (prf === null) {
+ const { url, prf: prfPromise } = await getPrf(getPrfOptions);
+ if (!getPrfOptions.autoOpen) {
+ if (!silent) { console.log(`Open this page in a web browser to complete the passkey flow: ${url}`); }
+ }
+ prf = await prfPromise;
+ if (prf === null) {
+ throw new InputError('Unable to get passkey.');
+ }
+ }
const decryptedValue = await decryptRaw({ prf, value: parsedValue });
decryptedEnv[envVar] = decryptedValue;
}
import { suite, test } from 'node:test';
-import { readFile } from 'node:fs/promises';
+import { deepStrictEqual } from 'node:assert';
import { encrypt, decrypt } from '#src/index.js';
+import { BROWSER } from '#src/getPrf.js';
import { setupPlaywright, setupEnv, mockOpen, assertConsole, fileEqual, fileNotEqual } from '#test/setup.js';
/** Standard value of the .env file used for most setups. */
await decrypt({ inFile: envFile, silent: true });
await fileEqual(envFile, '');
});
- test('ignores variables already encrypted', async (t) => {
- const { page } = await setupPlaywright(t);
- const envFile = await setupEnv(t, STD_ENV);
- mockOpen(t, page);
- assertConsole(t, { log: 3 });
-
- await fileEqual(envFile, STD_ENV);
- await encrypt({ inFile: envFile });
+ test('encrypt does nothing when all variables are already encrypted', async (t) => {
+ const openMock = t.mock.method(BROWSER, 'open');
+ const env = 'A=envpass:v1:AAA\nB=envpass:v1:BBB\nC=envpass:v1:CCC\n';
+ const envFile = await setupEnv(t, env);
+ assertConsole(t, { log: 1 });
- const newContent = await readFile(envFile, { encoding: 'utf8' });
await encrypt({ inFile: envFile });
- await fileEqual(envFile, newContent);
- await decrypt({ inFile: envFile });;
- await fileEqual(envFile, STD_ENV);
+ await fileEqual(envFile, env);
+ deepStrictEqual(openMock.mock.calls.length, 0);
});
- test('ignores variables already decrypted', async (t) => {
- const { page } = await setupPlaywright(t);
+ test('decrypt does nothing when all variables are already decrypted', async (t) => {
+ const openMock = t.mock.method(BROWSER, 'open');
const envFile = await setupEnv(t, STD_ENV);
- mockOpen(t, page);
assertConsole(t, { log: 1 });
- await fileEqual(envFile, STD_ENV);
await decrypt({ inFile: envFile });
+
await fileEqual(envFile, STD_ENV);
+ deepStrictEqual(openMock.mock.calls.length, 0);
});
});