feat(core): Remove discontinued crypto-js (#8104)

Since crypto-js was
[discontinued](1da3dabf93),
[we migrated all our backend encryption to native
crypto](https://github.com/n8n-io/n8n/pull/7556).
However I decided back then to not remove crypto-js just yet in
expressions, as I wanted to use `SubtleCrypto`. Unfortunately for that
to work, we'd need to make expressions async.
So, to get rid of `crypto-js`, I propose this interim solution. 

## Related tickets and issues
N8N-7020

## Review / Merge checklist
- [x] PR title and summary are descriptive
- [x] Tests included
This commit is contained in:
कारतोफ्फेलस्क्रिप्ट™
2023-12-21 14:13:02 +01:00
committed by GitHub
parent b67b5ae6b2
commit 01e9a79238
5 changed files with 93 additions and 65 deletions

View File

@@ -1,21 +1,20 @@
// import { createHash } from 'crypto';
import SHA from 'jssha';
import MD5 from 'md5';
import { encode } from 'js-base64';
import { titleCase } from 'title-case';
import type { ExtensionMap } from './Extensions';
import CryptoJS from 'crypto-js';
import { encode } from 'js-base64';
import { transliterate } from 'transliteration';
import { ExpressionExtensionError } from '../errors/expression-extension.error';
const hashFunctions: Record<string, typeof CryptoJS.MD5> = {
md5: CryptoJS.MD5,
sha1: CryptoJS.SHA1,
sha224: CryptoJS.SHA224,
sha256: CryptoJS.SHA256,
sha384: CryptoJS.SHA384,
sha512: CryptoJS.SHA512,
sha3: CryptoJS.SHA3,
ripemd160: CryptoJS.RIPEMD160,
};
export const SupportedHashAlgorithms = [
'md5',
'sha1',
'sha224',
'sha256',
'sha384',
'sha512',
'sha3',
] as const;
// All symbols from https://www.xe.com/symbols/ as for 2022/11/09
const CURRENCY_REGEXP =
@@ -113,23 +112,35 @@ const URL_REGEXP =
const CHAR_TEST_REGEXP = /\p{L}/u;
const PUNC_TEST_REGEXP = /[!?.]/;
function hash(value: string, extraArgs?: unknown): string {
const [algorithm = 'MD5'] = extraArgs as string[];
if (algorithm.toLowerCase() === 'base64') {
// We're using a library instead of btoa because btoa only
// works on ASCII
return encode(value);
function hash(value: string, extraArgs: string[]): string {
const algorithm = extraArgs[0]?.toLowerCase() ?? 'md5';
switch (algorithm) {
case 'base64':
return encode(value);
case 'md5':
return MD5(value);
case 'sha1':
case 'sha224':
case 'sha256':
case 'sha384':
case 'sha512':
case 'sha3':
const variant = (
{
sha1: 'SHA-1',
sha224: 'SHA-224',
sha256: 'SHA-256',
sha384: 'SHA-384',
sha512: 'SHA-512',
sha3: 'SHA3-512',
} as const
)[algorithm];
return new SHA(variant, 'TEXT').update(value).getHash('HEX');
default:
throw new ExpressionExtensionError(
`Unknown algorithm ${algorithm}. Available algorithms are: ${SupportedHashAlgorithms.join()}, and Base64.`,
);
}
const hashFunction = hashFunctions[algorithm.toLowerCase()];
if (!hashFunction) {
throw new ExpressionExtensionError(
`Unknown algorithm ${algorithm}. Available algorithms are: ${Object.keys(hashFunctions)
.map((s) => s.toUpperCase())
.join(', ')}, and Base64.`,
);
}
return hashFunction(value.toString()).toString();
// return createHash(format).update(value.toString()).digest('hex');
}
function isEmpty(value: string): boolean {