Skip to content

Commit

Permalink
feat: allow client to specify target iterations (#55)
Browse files Browse the repository at this point in the history
  • Loading branch information
mikesposito authored Nov 24, 2023
1 parent a44c69c commit 46263f1
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 7 deletions.
29 changes: 22 additions & 7 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -435,17 +435,25 @@ export function generateSalt(byteCount = 32): string {
*
* @param vault - The vault to update.
* @param password - The password to use for encryption.
* @param targetDerivationParams - The options to use for key derivation.
* @returns A promise resolving to the updated vault.
*/
export async function updateVault(
vault: string,
password: string,
targetDerivationParams = DEFAULT_DERIVATION_PARAMS,
): Promise<string> {
if (isVaultUpdated(vault)) {
if (isVaultUpdated(vault, targetDerivationParams)) {
return vault;
}

return encrypt(password, await decrypt(password, vault));
return encrypt(
password,
await decrypt(password, vault),
undefined,
undefined,
targetDerivationParams,
);
}

/**
Expand All @@ -457,19 +465,23 @@ export async function updateVault(
*
* @param encryptionResult - The encrypted data to update.
* @param password - The password to use for encryption.
* @param targetDerivationParams - The options to use for key derivation.
* @returns A promise resolving to the updated encrypted data and exported key.
*/
export async function updateVaultWithDetail(
encryptionResult: DetailedEncryptionResult,
password: string,
targetDerivationParams = DEFAULT_DERIVATION_PARAMS,
): Promise<DetailedEncryptionResult> {
if (isVaultUpdated(encryptionResult.vault)) {
if (isVaultUpdated(encryptionResult.vault, targetDerivationParams)) {
return encryptionResult;
}

return encryptWithDetail(
password,
await decrypt(password, encryptionResult.vault),
undefined,
targetDerivationParams,
);
}

Expand Down Expand Up @@ -539,14 +551,17 @@ function unwrapKey(encryptionKey: EncryptionKey | CryptoKey): CryptoKey {
* Checks if the provided vault is an updated encryption format.
*
* @param vault - The vault to check.
* @param targetDerivationParams - The options to use for key derivation.
* @returns Whether or not the vault is an updated encryption format.
*/
export function isVaultUpdated(vault: string): boolean {
export function isVaultUpdated(
vault: string,
targetDerivationParams = DEFAULT_DERIVATION_PARAMS,
): boolean {
const { keyMetadata } = JSON.parse(vault);
return (
isKeyDerivationOptions(keyMetadata) &&
keyMetadata.algorithm === DEFAULT_DERIVATION_PARAMS.algorithm &&
keyMetadata.params.iterations ===
DEFAULT_DERIVATION_PARAMS.params.iterations
keyMetadata.algorithm === targetDerivationParams.algorithm &&
keyMetadata.params.iterations === targetDerivationParams.params.iterations
);
}
34 changes: 34 additions & 0 deletions test/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -934,4 +934,38 @@ test.describe('encryptor:isVaultUpdated', async () => {

expect(isVaultUpdated).toBe(false);
});

test('should return false if vault does not match target params', async ({
page,
}) => {
const isVaultUpdated = await page.evaluate(
async (args) =>
window.encryptor.isVaultUpdated(args.vault, {
algorithm: 'PBKDF2',
params: {
iterations: 100_000,
},
}),
{ vault: JSON.stringify(sampleEncryptedData) },
);

expect(isVaultUpdated).toBe(false);
});

test('should return true if vault matches target params', async ({
page,
}) => {
const isVaultUpdated = await page.evaluate(
async (args) =>
window.encryptor.isVaultUpdated(args.vault, {
algorithm: 'PBKDF2',
params: {
iterations: 900_000,
},
}),
{ vault: JSON.stringify(sampleEncryptedData) },
);

expect(isVaultUpdated).toBe(true);
});
});

0 comments on commit 46263f1

Please sign in to comment.