zexson_toolkit
Version:
Zexson Toolkit is a powerful encryption and tokenization library developed by Zexson Team. It offers proprietary encryption algorithms, high-security random token generation, and advanced object comparison features. It includes many advanced security func
397 lines (396 loc) • 17.9 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.decryptBody = exports.encryptBody = exports.decryptObject = exports.encryptObject = exports.isEqual = exports.base64Decode = exports.base64Encode = exports.decrypt = exports.encrypt = void 0;
const generator_1 = require("./generator");
/**
* Encrypts a string using custom logic with random padding and Base64 encoding.
*
* @param {string} data - The string to encrypt.
* @param {Object} [options] - Encryption options.
* @param {CharacterSetType} [options.firstRandomCharSet] - Character set for the first random padding.
* @param {CharacterSetType} [options.secondRandomCharSet] - Character set for the second random padding.
* @param {string} [options.key] - Encryption key for additional security.
* @returns {Promise<string | undefined>} The encrypted string or `undefined` if encryption fails.
* @throws {Error} Throws if the encryption process encounters an issue.
*
* @example
* const encrypted = await encrypt("hello")
* const customEncrypted = await encrypt("hello", { key: "myCustomKey" })
*
* @since 1.0.0
* @category Encryption
*/
const encrypt = (data, options) => {
try {
if (options === undefined)
options = {
key: 'qwertyuioplkjhgfdsazxcvbnm'
};
if (typeof data === 'object')
return (0, exports.encryptObject)(data, options.key);
if (typeof data == 'number')
data = `${data}`;
if (typeof data == 'boolean')
data = `${data}`;
if (typeof data == 'string') {
data = data.trim();
let res = '';
const randomChars0 = (0, generator_1.tokenGenerator)(Math.floor(Math.random() * (5 + 15) + 1), generator_1.characterSets['defaultSet']), randomChars1 = (0, generator_1.tokenGenerator)(Math.floor(Math.random() * (5 + 15) + 1), generator_1.characterSets['defaultSet']), firsPart = String.fromCharCode(randomChars0.length + 85), secondPart = String.fromCharCode(randomChars1.length + 85);
for (let i = 0; i < data.length; i++) {
const charCode = data[i].charCodeAt(0);
res += String.fromCharCode((charCode + 80) - 70);
}
let encrypted = firsPart + randomChars0 + res + randomChars1 + secondPart;
encrypted = (0, exports.base64Encode)(encrypted.split('').map(char => {
const DataCharCode = char.charCodeAt(0);
return String.fromCharCode((DataCharCode + 80) - 70);
}).join(''), options.key);
if ((0, exports.decrypt)(encrypted, { key: options.key }) === data)
return encrypted;
else
(0, exports.encrypt)(data, options);
}
return data;
}
catch (err) {
throw new Error(`Error occurred during encoding: ${err}`);
}
};
exports.encrypt = encrypt;
/**
* Decrypts a string that was encrypted using the `encrypt` function.
*
* @param {string} data - The encrypted string to decrypt.
* @param {Object} [options] - Decryption options.
* @param {string} [options.key] - Encryption key used during encryption.
* @returns {Promise<string>} The decrypted original string.
* @throws {Error} Throws if the decryption process encounters an issue.
*
* @example
* const decrypted = await decrypt(encryptedString)
* const customDecrypted = await decrypt(encryptedString, { key: "myCustomKey" })
*
* @since 1.0.0
* @category Decryption
*/
const decrypt = (data, options = undefined) => {
try {
if (typeof data === 'undefined')
return data;
if (options === undefined)
options = { key: 'qwertyuioplkjhgfdsazxcvbnm' };
if (typeof data === 'object')
return (0, exports.decryptObject)(data, options.key);
if (typeof data == 'number')
data = `${data}`;
if (typeof data == 'boolean')
data = `${data}`;
if (typeof data == 'string') {
data = (0, exports.base64Decode)(data?.trim(), options.hasOwnProperty('key') ? options.key : 'secretKey')?.split('')?.map(char => {
const DataCharCode = char.charCodeAt(0);
return String.fromCharCode((DataCharCode - 80) + 70);
}).join('');
let res = '';
const firsPart = data[0].charCodeAt(0) - 85, secondPart = data.slice(-1).charCodeAt(0) - 85;
for (let i = firsPart + 1; i < data.length; i++) {
const charCode = data[i].charCodeAt(0), length = data.slice(i, data.length - 1).length;
if (length !== secondPart)
res += String.fromCharCode((charCode - 80) + 70);
else
break;
}
return res;
}
return data;
}
catch (err) {
throw new Error(`Error occurred during decoding: ${err}`);
}
};
exports.decrypt = decrypt;
/**
* Encodes a string using a custom Base64 algorithm with added character shifting.
*
* @param {string} data - The string to encode.
* @param {string} [key='qwertyuioplkjhgfdsazxcvbnm'] - Key for influencing the encoding process.
* @returns {string} The encoded string.
* @throws {Error} Throws if encoding fails.
*
* @example
* const encoded = base64Encode("Hello, World!")
* const customEncoded = base64Encode("Hello, World!", "customKey123")
*
* @since 1.0.5
* @category Encoding
*/
const base64Encode = (data, key = 'qwertyuioplkjhgfdsazxcvbnm') => {
if (typeof data == 'number')
data = `${data}`;
if (typeof data == 'boolean')
data = `${data}`;
if (typeof data == 'string') {
const shiftChar = (char, shift) => {
const code = char.charCodeAt(0);
return String.fromCharCode(code + shift);
}, keySum = key.split('').reduce((acc, char) => acc + char.charCodeAt(0), 0), shifted = data
.split('')
.map((char, index) => shiftChar(char, (keySum + index) % 20))
.join(''), step1 = Buffer.from(shifted).toString('base64'), step2 = Buffer.from(step1).toString('base64'), finalMix = step2
.split('')
.map((char, index) => shiftChar(char, index % 5))
.join('');
return finalMix;
}
return data;
};
exports.base64Encode = base64Encode;
/**
* Decodes a string encoded by `base64Encode` back to its original form.
*
* @param {string} encryptedData - The string to decode.
* @param {string} [key='qwertyuioplkjhgfdsazxcvbnm'] - The key used during encoding.
* @returns {string} The decoded string.
* @throws {Error} Throws if decoding fails.
*
* @example
* const decoded = base64Decode(encodedString)
* const customDecoded = base64Decode(encodedString, "customKey123")
*
* @since 1.0.5
* @category Decoding
*/
const base64Decode = (encryptedData, key = 'qwertyuioplkjhgfdsazxcvbnm') => {
if (typeof encryptedData == 'number')
encryptedData = `${encryptedData}`;
if (typeof encryptedData == 'boolean')
encryptedData = `${encryptedData}`;
if (typeof encryptedData == 'string') {
if (key === undefined)
key = 'qwertyuioplkjhgfdsazxcvbnm';
const unshiftChar = (char, shift) => {
const code = char.charCodeAt(0);
return String.fromCharCode(code - shift);
}, keySum = key.split('').reduce((acc, char) => acc + char.charCodeAt(0), 0), unmixed = encryptedData
.split('')
.map((char, index) => unshiftChar(char, index % 5))
.join(''), step1 = Buffer.from(unmixed, 'base64').toString(), step2 = Buffer.from(step1, 'base64').toString(), final = step2
.split('')
.map((char, index) => unshiftChar(char, (keySum + index) % 20))
.join('');
return final;
}
return encryptedData;
};
exports.base64Decode = base64Decode;
/**
* Compares a plain text string with an encrypted string for equality.
*
* @param {string} text - The plain text string.
* @param {string} encrypted - The encrypted string to compare.
* @param {IsEqualOptions} [options] - Comparison options (e.g., case sensitivity).
* @returns {Promise<{ isEqual: boolean; method?: string }>} Indicates if the strings match and the method used.
*
* @example
* const match = await isEqual("hello", encryptedString)
* const caseInsensitiveMatch = await isEqual("hello", encryptedString, { caseSensitive: false })
*
* @since 1.0.0
* @category Comparison
*/
const isEqual = (text, text1, options) => {
try {
if (typeof text === 'undefined')
return { isEqual: false, method: "Undefined" };
if (typeof text1 === 'undefined')
return { isEqual: false, method: "Undefined" };
let Text = text, Text1 = text1, logMessage = '';
options = options || { caseSensitive: true };
const key = options.key || undefined, isCaseSensitive = !options.caseSensitive ? "toLowerCase" : "toString", logMatch = (method, details) => options?.log ? console.log(`✅ Eşleşme bulundu ${method}:`, details) : undefined;
if (Text === Text1 || Text[isCaseSensitive]() === Text1 || Text === Text1[isCaseSensitive]() || Text[isCaseSensitive]() === Text1[isCaseSensitive]()) {
logMessage = "Direct comparison";
logMatch(logMessage, { Text: Text[isCaseSensitive](), Text1 });
return { isEqual: true, method: logMessage };
}
let decryptedText = null, decryptedText1 = null;
try {
decryptedText = (0, exports.decrypt)(Text, { key });
}
catch (error) {
decryptedText = Text;
}
try {
decryptedText1 = (0, exports.decrypt)(Text1, { key });
}
catch (error) {
decryptedText1 = Text1;
}
if (decryptedText1 === Text || decryptedText1[isCaseSensitive]() === Text || decryptedText1 === Text[isCaseSensitive]() || decryptedText1[isCaseSensitive]() === Text[isCaseSensitive]()) {
logMessage = 'Decrypted Text1 matched Text';
logMatch(logMessage, { decryptedText1, Text });
return { isEqual: true, method: logMessage };
}
if (decryptedText === Text1 || decryptedText[isCaseSensitive]() === Text1) {
logMessage = "Decrypted Text matches Text1";
logMatch(logMessage, { decryptedText, Text1 });
return { isEqual: true, method: logMessage };
}
if (decryptedText1 === decryptedText || decryptedText1[isCaseSensitive]() === decryptedText || decryptedText1 === decryptedText[isCaseSensitive]()) {
logMessage = "Both decrypted values match";
logMatch(logMessage, { decryptedText1, decryptedText });
return { isEqual: true, method: logMessage };
}
if (options.log)
console.log("❌ No matches found:", { Text, Text1, decryptedText1, decryptedText });
return { isEqual: false };
}
catch (err) {
console.error("isEqual function error:", err);
return { isEqual: false };
}
};
exports.isEqual = isEqual;
/**
* Encrypts all values in an object.
*
* @template T - An object type where keys are strings, and values are strings.
* @param {T} data - The object containing values to be encrypted.
* @param {string} [key='qwertyuioplkjhgfdsazxcvbnm'] - The encryption key to use.
* @returns {T} A new object with encrypted values.
* @throws {Error} If encryption fails for any value.
*
* @example
* const data = { username: 'JohnDoe', password: '12345' }
* const encryptedData = encryptObject(data, 'my-secret-key')
*
* @since 1.0.7
* @category Encryption
* @public
*/
const encryptObject = (data, key = 'qwertyuioplkjhgfdsazxcvbnm') => {
const encryptedData = {};
if (data == null)
return data;
for (const [k, v] of Object.entries(data == null ? {} : data)) {
if (typeof v == 'string' || typeof v == 'number' || typeof v == 'boolean' || typeof v == 'undefined')
encryptedData[k] = (0, exports.encrypt)(String(v).toString().trim(), { key });
else if (Array.isArray(v)) {
const encryptedArray = v.map(item => {
if (typeof item === 'string' || typeof item == 'number')
return (0, exports.encrypt)(String(item), { key });
if (Array.isArray(item))
return item.map(subItem => typeof subItem === 'string' || typeof subItem === 'number' ? (0, exports.encrypt)(String(subItem), { key }) :
Array.isArray(subItem) ? (0, exports.encryptObject)({ arr: subItem }, key).arr :
typeof subItem === 'object' ? (0, exports.encryptObject)(subItem, key) : subItem);
if (typeof item === 'object' && item !== null)
return (0, exports.encryptObject)(item, key);
return item;
});
encryptedData[k] = encryptedArray;
}
else if (typeof v == 'object')
encryptedData[k] = (0, exports.encryptObject)(v, key);
else
encryptedData[k] = v;
}
return encryptedData;
};
exports.encryptObject = encryptObject;
/**
* Decrypts all values in an object.
*
* @template T - An object type where keys are strings, and values are encrypted strings.
* @param {T} data - The object containing values to be decrypted.
* @param {string} [key='qwertyuioplkjhgfdsazxcvbnm'] - The decryption key to use.
* @returns {T} A new object with decrypted values.
* @throws {Error} If decryption fails for any value.
*
* @example
* const encryptedData = { username: 'abc123', password: 'def456' }
* const decryptedData = decryptObject(encryptedData, 'my-secret-key')
*
* @since 1.0.7
* @category Decryption
* @public
*/
const decryptObject = (data, key = 'qwertyuioplkjhgfdsazxcvbnm') => {
const decryptedData = {};
if (data == null)
return data;
for (const [k, v] of Object.entries(data == null ? {} : data)) {
if (typeof v == 'string')
decryptedData[k] = (0, exports.decrypt)(String(v).toString().trim(), { key });
else if (Array.isArray(v)) {
const decryptedArray = v.map(item => {
if (typeof item === 'string')
return (0, exports.decrypt)(item, { key });
if (Array.isArray(item))
return item.map(subItem => typeof subItem === 'string' ? (0, exports.decrypt)(subItem, { key }) :
Array.isArray(subItem) ? (0, exports.decryptObject)({ arr: subItem }, key).arr :
typeof subItem === 'object' ? (0, exports.decryptObject)(subItem, key) : subItem);
if (typeof item === 'object')
return (0, exports.decryptObject)(item, key);
return item;
});
decryptedData[k] = decryptedArray;
}
else if (typeof v == 'object')
decryptedData[k] = (0, exports.decryptObject)(v, key);
else
decryptedData[k] = v;
}
return decryptedData;
};
exports.decryptObject = decryptObject;
/**
* Encrypts all keys and retains their values in an object.
*
* @template T - An object type where keys are strings and values can be of any type.
* @param {T} object - The object whose keys will be encrypted and values retained.
* @param {string} [secretKey='qwertyuioplkjhgfdsazxcvbnm'] - The encryption key to use for encrypting the keys.
* @returns {EncryptableObject} A new object with encrypted keys and original values.
* @throws {Error} If encryption fails for any value or key.
*
* @example
* const data = { username: 'user123', password: 'pass456' }
* const encryptedData = encryptBody(data) // encrypts the keys and values
*
* @since 1.1.1
* @category Encryption
* @public
*/
const encryptBody = (object, secretKey = 'qwertyuioplkjhgfdsazxcvbnm') => {
const res = {};
for (const key of Object.keys(object)) {
res[(0, exports.encrypt)(key, { key: secretKey })] = object[key];
}
return (0, exports.encryptObject)(res, secretKey);
};
exports.encryptBody = encryptBody;
/**
* Decrypts all keys and retains their values in an object.
*
* @template T - An object type where keys are strings, and values are encrypted strings.
* @param {T} object - The object containing values to be decrypted, with keys being encrypted.
* @param {string} [secretKey='qwertyuioplkjhgfdsazxcvbnm'] - The decryption key to use.
* @returns {EncryptableObject} A new object with decrypted keys and original values.
* @throws {Error} If decryption fails for any value.
*
* @example
* const encryptedData = {
* 'YlWzR3exYqt4eIFDcG4PWIfz]kOr\\4tZf6FUR4oRS1Loe0V|ZpE:RTA=': 'YUjOV1qXVqR4d59DcJQPVofyekOueJp[X58xSXo7PU2@',
* 'Yn7Rh1etWrV4d3N1VFkPVYfy]kOv\\4tif5=2R4kRS1noQmR7]ZV5ejA=': 'ZH3tU2evQ4NoT5lK[VL9cofyWlq5e~NEcGJGNIM~S1nog0uQg682WYZsVmUYMl\\UX22QR\\dxXHRsZ2wGTH3n^mWYeK5jUJg9'
* }
* const decryptedData = decryptBody(encryptedData) // { username: 'user123', password: 'pass456' }
*
* @since 1.1.1
* @category Decryption
* @public
*/
const decryptBody = (object, secretKey = 'qwertyuioplkjhgfdsazxcvbnm') => {
const res = {};
for (const key of Object.keys(object)) {
res[(0, exports.decrypt)(key, { key: secretKey })] = object[key];
}
return (0, exports.decryptObject)(res, secretKey);
};
exports.decryptBody = decryptBody;
;