driftin-secure-ls
Version:
Secure localStorage/sessionStorage data with high level of encryption and data compression
1,224 lines (1,136 loc) • 219 kB
JavaScript
/*!
* secure-ls - v1.2.6
* URL - https://github.com/softvar/secure-ls
*
* The MIT License (MIT)
*
* Copyright (c) 2016-2024 Varun Malhotra
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*
* Dependencies used -
* 1. crypto-js - ^4.2.0
* 2. lz-string - ^1.5.0
*/
(function webpackUniversalModuleDefinition(root, factory) {
// CommonJS2
if (typeof exports === 'object' && typeof module === 'object') module.exports = factory();
// AMD
else if (typeof define === 'function' && define.amd) define([], factory);
// CommonJS
else if (typeof exports === 'object') exports['SecureLS'] = factory();
// Root
else root['SecureLS'] = factory();
})(this, () => {
return /******/ (() => {
// webpackBootstrap
/******/ var __webpack_modules__ = {
/***/ './src/Base64.js':
/*!***********************!*\
!*** ./src/Base64.js ***!
\***********************/
/***/ (__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
'use strict';
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ default: () => __WEBPACK_DEFAULT_EXPORT__,
/* harmony export */
});
const Base64 = {
_keyStr: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=',
encode: function (e) {
let t = '';
let n, r, i, s, o, u, a;
let f = 0;
e = Base64._utf8Encode(e);
while (f < e.length) {
n = e.charCodeAt(f++);
r = e.charCodeAt(f++);
i = e.charCodeAt(f++);
s = n >> 2;
o = ((n & 3) << 4) | (r >> 4);
u = ((r & 15) << 2) | (i >> 6);
a = i & 63;
if (isNaN(r)) {
u = a = 64;
} else if (isNaN(i)) {
a = 64;
}
t =
t + this._keyStr.charAt(s) + this._keyStr.charAt(o) + this._keyStr.charAt(u) + this._keyStr.charAt(a);
}
return t;
},
decode: function (e) {
let t = '';
let n, r, i;
let s, o, u, a;
let f = 0;
e = e.replace(/[^A-Za-z0-9+/=]/g, '');
while (f < e.length) {
s = this._keyStr.indexOf(e.charAt(f++));
o = this._keyStr.indexOf(e.charAt(f++));
u = this._keyStr.indexOf(e.charAt(f++));
a = this._keyStr.indexOf(e.charAt(f++));
n = (s << 2) | (o >> 4);
r = ((o & 15) << 4) | (u >> 2);
i = ((u & 3) << 6) | a;
t = t + String.fromCharCode(n);
if (u !== 64) {
t = t + String.fromCharCode(r);
}
if (a !== 64) {
t = t + String.fromCharCode(i);
}
}
t = Base64._utf8Decode(t);
return t;
},
_utf8Encode: function (e) {
e = e.replace(/\r\n/g, '\n');
let t = '';
for (let n = 0; n < e.length; n++) {
let r = e.charCodeAt(n);
if (r < 128) {
t += String.fromCharCode(r);
} else if (r > 127 && r < 2048) {
t += String.fromCharCode((r >> 6) | 192);
t += String.fromCharCode((r & 63) | 128);
} else {
t += String.fromCharCode((r >> 12) | 224);
t += String.fromCharCode(((r >> 6) & 63) | 128);
t += String.fromCharCode((r & 63) | 128);
}
}
return t;
},
_utf8Decode: function (e) {
let t = '';
let n = 0;
let r, c2, c3;
r = c2 = 0;
while (n < e.length) {
r = e.charCodeAt(n);
if (r < 128) {
t += String.fromCharCode(r);
n++;
} else if (r > 191 && r < 224) {
c2 = e.charCodeAt(n + 1);
t += String.fromCharCode(((r & 31) << 6) | (c2 & 63));
n += 2;
} else {
c2 = e.charCodeAt(n + 1);
c3 = e.charCodeAt(n + 2);
t += String.fromCharCode(((r & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
n += 3;
}
}
return t;
},
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = Base64;
/***/
},
/***/ './src/SecureLS.js':
/*!*************************!*\
!*** ./src/SecureLS.js ***!
\*************************/
/***/ (__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
'use strict';
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ SecureLS: () => /* binding */ SecureLS,
/* harmony export */
});
/* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(
/*! ./constants */ './src/constants.js',
);
/* harmony import */ var _enc_utf8__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(
/*! ./enc-utf8 */ './src/enc-utf8.js',
);
/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(
/*! ./utils */ './src/utils.js',
);
/* harmony import */ var crypto_js_aes__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(
/*! crypto-js/aes */ './node_modules/crypto-js/aes.js',
);
/* harmony import */ var crypto_js_aes__WEBPACK_IMPORTED_MODULE_3___default =
/*#__PURE__*/ __webpack_require__.n(crypto_js_aes__WEBPACK_IMPORTED_MODULE_3__);
/* harmony import */ var crypto_js_rabbit__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(
/*! crypto-js/rabbit */ './node_modules/crypto-js/rabbit.js',
);
/* harmony import */ var crypto_js_rabbit__WEBPACK_IMPORTED_MODULE_4___default =
/*#__PURE__*/ __webpack_require__.n(crypto_js_rabbit__WEBPACK_IMPORTED_MODULE_4__);
/* harmony import */ var crypto_js_rc4__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(
/*! crypto-js/rc4 */ './node_modules/crypto-js/rc4.js',
);
/* harmony import */ var crypto_js_rc4__WEBPACK_IMPORTED_MODULE_5___default =
/*#__PURE__*/ __webpack_require__.n(crypto_js_rc4__WEBPACK_IMPORTED_MODULE_5__);
/* harmony import */ var crypto_js_tripledes__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(
/*! crypto-js/tripledes */ './node_modules/crypto-js/tripledes.js',
);
/* harmony import */ var crypto_js_tripledes__WEBPACK_IMPORTED_MODULE_6___default =
/*#__PURE__*/ __webpack_require__.n(crypto_js_tripledes__WEBPACK_IMPORTED_MODULE_6__);
/* harmony import */ var lz_string_libs_lz_string__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(
/*! lz-string/libs/lz-string */ './node_modules/lz-string/libs/lz-string.js',
);
/* harmony import */ var lz_string_libs_lz_string__WEBPACK_IMPORTED_MODULE_7___default =
/*#__PURE__*/ __webpack_require__.n(lz_string_libs_lz_string__WEBPACK_IMPORTED_MODULE_7__);
/* harmony import */ var _Base64__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(
/*! ./Base64 */ './src/Base64.js',
);
const encryptors = {
[_constants__WEBPACK_IMPORTED_MODULE_0__['default'].EncrytionTypes.AES]:
crypto_js_aes__WEBPACK_IMPORTED_MODULE_3___default(),
[_constants__WEBPACK_IMPORTED_MODULE_0__['default'].EncrytionTypes.DES]:
crypto_js_tripledes__WEBPACK_IMPORTED_MODULE_6___default(),
[_constants__WEBPACK_IMPORTED_MODULE_0__['default'].EncrytionTypes.RABBIT]:
crypto_js_rabbit__WEBPACK_IMPORTED_MODULE_4___default(),
[_constants__WEBPACK_IMPORTED_MODULE_0__['default'].EncrytionTypes.RC4]:
crypto_js_rc4__WEBPACK_IMPORTED_MODULE_5___default(),
};
class SecureLS {
constructor({
encryptionSecret = '',
encryptionNamespace = '',
isCompression = true,
encodingType = _constants__WEBPACK_IMPORTED_MODULE_0__['default'].EncrytionTypes.BASE64,
storage = localStorage,
metaKey = _constants__WEBPACK_IMPORTED_MODULE_0__['default'].metaKey,
} = {}) {
// Assign libraries and utilities
Object.assign(this, {
_name: 'secure-ls',
Base64: _Base64__WEBPACK_IMPORTED_MODULE_8__['default'],
LZString: {
compressToUTF16: lz_string_libs_lz_string__WEBPACK_IMPORTED_MODULE_7__.compressToUTF16,
decompressFromUTF16: lz_string_libs_lz_string__WEBPACK_IMPORTED_MODULE_7__.decompressFromUTF16,
},
AES: crypto_js_aes__WEBPACK_IMPORTED_MODULE_3___default(),
DES: crypto_js_tripledes__WEBPACK_IMPORTED_MODULE_6___default(),
RABBIT: crypto_js_rabbit__WEBPACK_IMPORTED_MODULE_4___default(),
RC4: crypto_js_rc4__WEBPACK_IMPORTED_MODULE_5___default(),
enc: _enc_utf8__WEBPACK_IMPORTED_MODULE_1__['default'],
});
// Configuration and property assignment
this.config = {
encryptionSecret,
encryptionNamespace,
isCompression,
encodingType: encodingType.toLowerCase(),
storage,
metaKey,
};
this.encryptionSecret = encryptionSecret;
this.storage = storage;
this.metaKey = metaKey;
// Initialize the class
this.init();
}
init() {
let metaData = this.getMetaData();
this._isBase64 = this._isBase64EncryptionType();
this._isAES = this._isAESEncryptionType();
this._isDES = this._isDESEncryptionType();
this._isRabbit = this._isRabbitEncryptionType();
this._isRC4 = this._isRC4EncryptionType();
this._isCompression = this._isDataCompressionEnabled();
// fill the already present keys to the list of keys being used by secure-ls
this.allKeys = metaData.keys || this.resetAllKeys();
}
_isBase64EncryptionType() {
return (
_Base64__WEBPACK_IMPORTED_MODULE_8__['default'] &&
(typeof this.config.encodingType === 'undefined' ||
this.config.encodingType === _constants__WEBPACK_IMPORTED_MODULE_0__['default'].EncrytionTypes.BASE64)
);
}
_isAESEncryptionType() {
return (
crypto_js_aes__WEBPACK_IMPORTED_MODULE_3___default() &&
this.config.encodingType === _constants__WEBPACK_IMPORTED_MODULE_0__['default'].EncrytionTypes.AES
);
}
_isDESEncryptionType() {
return (
crypto_js_tripledes__WEBPACK_IMPORTED_MODULE_6___default() &&
this.config.encodingType === _constants__WEBPACK_IMPORTED_MODULE_0__['default'].EncrytionTypes.DES
);
}
_isRabbitEncryptionType() {
return (
crypto_js_rabbit__WEBPACK_IMPORTED_MODULE_4___default() &&
this.config.encodingType === _constants__WEBPACK_IMPORTED_MODULE_0__['default'].EncrytionTypes.RABBIT
);
}
_isRC4EncryptionType() {
return (
crypto_js_rc4__WEBPACK_IMPORTED_MODULE_5___default() &&
this.config.encodingType === _constants__WEBPACK_IMPORTED_MODULE_0__['default'].EncrytionTypes.RC4
);
}
_isDataCompressionEnabled() {
return this.config.isCompression;
}
getEncryptionSecret(key) {
let metaData = this.getMetaData();
let obj = _utils__WEBPACK_IMPORTED_MODULE_2__['default'].getObjectFromKey(metaData.keys, key);
if (!obj) {
return;
}
if (this._isAES || this._isDES || this._isRabbit || this._isRC4) {
if (typeof this.config.encryptionSecret === 'undefined') {
this.encryptionSecret = obj.s;
if (!this.encryptionSecret) {
this.encryptionSecret = _utils__WEBPACK_IMPORTED_MODULE_2__['default'].generateSecretKey();
this.setMetaData();
}
} else {
this.encryptionSecret = this.config.encryptionSecret || obj.s || '';
}
}
}
getEncryptionType() {
const encodingType = this.config.encodingType;
return encodingType
? encodingType.toLowerCase()
: _constants__WEBPACK_IMPORTED_MODULE_0__['default'].EncrytionTypes.BASE64;
}
getDataFromLocalStorage(key) {
return this.storage.getItem(key, true);
}
setDataToLocalStorage(key, data) {
this.storage.setItem(key, data);
}
setMetaData() {
let dataToStore = this.processData(
{
keys: this.allKeys,
},
true,
);
// Store the data to localStorage
this.setDataToLocalStorage(this.getMetaKey(), dataToStore);
}
getMetaData() {
return this.get(this.getMetaKey(), true) || {};
}
getMetaKey() {
return this.metaKey + (this.config.encryptionNamespace ? '__' + this.config.encryptionNamespace : '');
}
resetAllKeys() {
this.allKeys = [];
return [];
}
processData(data, isAllKeysData) {
if (data === null || data === undefined || data === '') {
return '';
}
let jsonData;
try {
jsonData = JSON.stringify(data);
} catch (err) {
throw new Error('Could not stringify data', err);
}
// Encode Based on encoding type
// If not set, default to Base64 for securing data
let encodedData = jsonData;
if (this._isBase64 || isAllKeysData) {
encodedData = _Base64__WEBPACK_IMPORTED_MODULE_8__['default'].encode(jsonData);
} else {
const encryptor = encryptors[this.getEncryptionType()];
if (encryptor) {
encodedData = encryptor.encrypt(jsonData, this.encryptionSecret);
}
encodedData = encodedData && encodedData.toString();
}
// Compress data if set to true
let compressedData = encodedData;
if (this._isCompression || isAllKeysData) {
compressedData = this.LZString.compressToUTF16(encodedData);
}
return compressedData;
}
// PUBLIC APIs
getAllKeys() {
let data = this.getMetaData();
return _utils__WEBPACK_IMPORTED_MODULE_2__['default'].extractKeyNames(data) || [];
}
get(key, isAllKeysData) {
let decodedData = '';
let jsonData = '';
if (!_utils__WEBPACK_IMPORTED_MODULE_2__['default'].is(key)) {
_utils__WEBPACK_IMPORTED_MODULE_2__['default'].warn(
_constants__WEBPACK_IMPORTED_MODULE_0__['default'].WarningEnum.KEY_NOT_PROVIDED,
);
return jsonData;
}
let data = this.getDataFromLocalStorage(key);
if (!data) {
return jsonData;
}
let deCompressedData = data; // saves else
if (this._isCompression || isAllKeysData) {
// meta data always compressed
deCompressedData = this.LZString.decompressFromUTF16(data);
}
decodedData = deCompressedData; // saves else
if (this._isBase64 || isAllKeysData) {
// meta data always Base64
decodedData = _Base64__WEBPACK_IMPORTED_MODULE_8__['default'].decode(deCompressedData);
} else {
this.getEncryptionSecret(key);
const encryptor = encryptors[this.getEncryptionType()];
if (encryptor) {
const bytes = encryptor.decrypt(deCompressedData.toString(), this.encryptionSecret);
if (bytes) {
decodedData = bytes.toString(_enc_utf8__WEBPACK_IMPORTED_MODULE_1__['default']._Utf8);
}
}
}
try {
jsonData = JSON.parse(decodedData);
} catch (err) {
throw new Error('Could not parse JSON', err);
}
return jsonData;
}
set(key, data) {
let dataToStore = '';
if (!_utils__WEBPACK_IMPORTED_MODULE_2__['default'].is(key)) {
_utils__WEBPACK_IMPORTED_MODULE_2__['default'].warn(
_constants__WEBPACK_IMPORTED_MODULE_0__['default'].WarningEnum.KEY_NOT_PROVIDED,
);
return;
}
this.getEncryptionSecret(key);
// add key(s) to Array if not already added, only for keys other than meta key
if (!(String(key) === String(this.metaKey))) {
if (!_utils__WEBPACK_IMPORTED_MODULE_2__['default'].isKeyPresent(this.allKeys, key)) {
this.allKeys.push({
k: key,
s: this.encryptionSecret,
});
this.setMetaData();
}
}
dataToStore = this.processData(data);
// Store the data to localStorage
this.setDataToLocalStorage(key, dataToStore);
}
remove(key) {
if (!_utils__WEBPACK_IMPORTED_MODULE_2__['default'].is(key)) {
_utils__WEBPACK_IMPORTED_MODULE_2__['default'].warn(
_constants__WEBPACK_IMPORTED_MODULE_0__['default'].WarningEnum.KEY_NOT_PROVIDED,
);
return;
}
if (key === this.metaKey && this.getAllKeys().length) {
_utils__WEBPACK_IMPORTED_MODULE_2__['default'].warn(
_constants__WEBPACK_IMPORTED_MODULE_0__['default'].WarningEnum.META_KEY_REMOVE,
);
return;
}
if (_utils__WEBPACK_IMPORTED_MODULE_2__['default'].isKeyPresent(this.allKeys, key)) {
_utils__WEBPACK_IMPORTED_MODULE_2__['default'].removeFromKeysList(this.allKeys, key);
this.setMetaData();
}
this.storage.removeItem(key);
}
removeAll() {
let keys = this.getAllKeys();
for (let i = 0; i < keys.length; i++) {
this.storage.removeItem(keys[i]);
}
this.storage.removeItem(this.metaKey);
this.resetAllKeys();
}
clear() {
this.storage.clear();
this.resetAllKeys();
}
}
/***/
},
/***/ './src/WordArray.js':
/*!**************************!*\
!*** ./src/WordArray.js ***!
\**************************/
/***/ (__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
'use strict';
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ default: () => __WEBPACK_DEFAULT_EXPORT__,
/* harmony export */
});
/*
ES6 compatible port of CryptoJS - WordArray for PBKDF2 password key generation
Source: https://github.com/brix/crypto-js
LICENSE: MIT
*/
let CryptoJSWordArray = {
random: function (nBytes) {
let words = [];
let r = function (mw) {
let mz = 0x3ade68b1;
let mask = 0xffffffff;
return function () {
mz = (0x9069 * (mz & 0xffff) + (mz >> 0x10)) & mask;
mw = (0x4650 * (mw & 0xffff) + (mw >> 0x10)) & mask;
let result = ((mz << 0x10) + mw) & mask;
result /= 0x100000000;
result += 0.5;
return result * (Math.random() > 0.5 ? 1 : -1);
};
};
for (let i = 0, rcache; i < nBytes; i += 4) {
let _r = r((rcache || Math.random()) * 0x100000000);
rcache = _r() * 0x3ade67b7;
words.push((_r() * 0x100000000) | 0);
}
return new CryptoJSWordArray.Set(words, nBytes);
},
Set: function (words, sigBytes) {
words = this.words = words || [];
if (sigBytes !== undefined) {
this.sigBytes = sigBytes;
} else {
this.sigBytes = words.length * 8;
}
},
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = CryptoJSWordArray;
/***/
},
/***/ './src/constants.js':
/*!**************************!*\
!*** ./src/constants.js ***!
\**************************/
/***/ (__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
'use strict';
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ default: () => __WEBPACK_DEFAULT_EXPORT__,
/* harmony export */
});
const WarningEnum = {
KEY_NOT_PROVIDED: 'keyNotProvided',
META_KEY_REMOVE: 'metaKeyRemove',
DEFAULT_TEXT: 'defaultText',
};
const WarningTypes = {};
WarningTypes[WarningEnum.KEY_NOT_PROVIDED] = 'Secure LS: Key not provided. Aborting operation!';
WarningTypes[WarningEnum.META_KEY_REMOVE] = `Secure LS: Meta key can not be removed
unless all keys created by Secure LS are removed!`;
WarningTypes[WarningEnum.DEFAULT_TEXT] = `Unexpected output`;
const constants = {
WarningEnum: WarningEnum,
WarningTypes: WarningTypes,
EncrytionTypes: {
BASE64: 'base64',
AES: 'aes',
DES: 'des',
RABBIT: 'rabbit',
RC4: 'rc4',
},
metaKey: '_secure__ls__metadata',
secretPhrase: 's3cr3t$#@135^&*246',
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = constants;
/***/
},
/***/ './src/enc-utf8.js':
/*!*************************!*\
!*** ./src/enc-utf8.js ***!
\*************************/
/***/ (__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
'use strict';
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ default: () => __WEBPACK_DEFAULT_EXPORT__,
/* harmony export */
});
/*
ES6 compatible port of CryptoJS - encoding
Source: https://github.com/brix/crypto-js
LICENSE: MIT
*/
const enc = {
Latin1: {
stringify: (wordArray) => {
// Shortcuts
let words = wordArray.words;
let sigBytes = wordArray.sigBytes;
let latin1Chars = [],
i,
bite;
// Convert
for (i = 0; i < sigBytes; i++) {
bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
latin1Chars.push(String.fromCharCode(bite));
}
return latin1Chars.join('');
},
},
_Utf8: {
stringify: (wordArray) => {
try {
return decodeURIComponent(escape(enc.Latin1.stringify(wordArray)));
} catch (err) {
throw new Error('Malformed UTF-8 data', err);
}
},
},
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = enc;
/***/
},
/***/ './src/utils.js':
/*!**********************!*\
!*** ./src/utils.js ***!
\**********************/
/***/ (__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
'use strict';
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ default: () => __WEBPACK_DEFAULT_EXPORT__,
/* harmony export */
});
/* harmony import */ var crypto_js_pbkdf2__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(
/*! crypto-js/pbkdf2 */ './node_modules/crypto-js/pbkdf2.js',
);
/* harmony import */ var crypto_js_pbkdf2__WEBPACK_IMPORTED_MODULE_0___default =
/*#__PURE__*/ __webpack_require__.n(crypto_js_pbkdf2__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(
/*! ./constants */ './src/constants.js',
);
/* harmony import */ var _WordArray__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(
/*! ./WordArray */ './src/WordArray.js',
);
const utils = {
is: (key) => !!key,
warn: (reason = _constants__WEBPACK_IMPORTED_MODULE_1__['default'].WarningEnum.DEFAULT_TEXT) => {
console.warn(_constants__WEBPACK_IMPORTED_MODULE_1__['default'].WarningTypes[reason]);
},
generateSecretKey: () => {
const salt = _WordArray__WEBPACK_IMPORTED_MODULE_2__['default'].random(128 / 8);
const key128Bits = crypto_js_pbkdf2__WEBPACK_IMPORTED_MODULE_0___default()(
_constants__WEBPACK_IMPORTED_MODULE_1__['default'].secretPhrase,
salt,
{
keySize: 128 / 32,
},
);
return key128Bits.toString();
},
getObjectFromKey: (data = [], key) => {
return data.find((item) => item.k === key) || {};
},
extractKeyNames: ({ keys = [] } = {}) => {
return keys.map(({ k }) => k);
},
isKeyPresent: (allKeys = [], key) => {
return allKeys.some((item) => String(item.k) === String(key));
},
removeFromKeysList: (allKeys = [], key) => {
const index = allKeys.findIndex((item) => item.k === key);
if (index !== -1) {
allKeys.splice(index, 1);
}
return index;
},
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = utils;
/***/
},
/***/ './node_modules/crypto-js/aes.js':
/*!***************************************!*\
!*** ./node_modules/crypto-js/aes.js ***!
\***************************************/
/***/ function (module, exports, __webpack_require__) {
(function (root, factory, undef) {
if (true) {
// CommonJS
module.exports = exports = factory(
__webpack_require__(/*! ./core */ './node_modules/crypto-js/core.js'),
__webpack_require__(/*! ./enc-base64 */ './node_modules/crypto-js/enc-base64.js'),
__webpack_require__(/*! ./md5 */ './node_modules/crypto-js/md5.js'),
__webpack_require__(/*! ./evpkdf */ './node_modules/crypto-js/evpkdf.js'),
__webpack_require__(/*! ./cipher-core */ './node_modules/crypto-js/cipher-core.js'),
);
} else {
}
})(this, function (CryptoJS) {
(function () {
// Shortcuts
var C = CryptoJS;
var C_lib = C.lib;
var BlockCipher = C_lib.BlockCipher;
var C_algo = C.algo;
// Lookup tables
var SBOX = [];
var INV_SBOX = [];
var SUB_MIX_0 = [];
var SUB_MIX_1 = [];
var SUB_MIX_2 = [];
var SUB_MIX_3 = [];
var INV_SUB_MIX_0 = [];
var INV_SUB_MIX_1 = [];
var INV_SUB_MIX_2 = [];
var INV_SUB_MIX_3 = [];
// Compute lookup tables
(function () {
// Compute double table
var d = [];
for (var i = 0; i < 256; i++) {
if (i < 128) {
d[i] = i << 1;
} else {
d[i] = (i << 1) ^ 0x11b;
}
}
// Walk GF(2^8)
var x = 0;
var xi = 0;
for (var i = 0; i < 256; i++) {
// Compute sbox
var sx = xi ^ (xi << 1) ^ (xi << 2) ^ (xi << 3) ^ (xi << 4);
sx = (sx >>> 8) ^ (sx & 0xff) ^ 0x63;
SBOX[x] = sx;
INV_SBOX[sx] = x;
// Compute multiplication
var x2 = d[x];
var x4 = d[x2];
var x8 = d[x4];
// Compute sub bytes, mix columns tables
var t = (d[sx] * 0x101) ^ (sx * 0x1010100);
SUB_MIX_0[x] = (t << 24) | (t >>> 8);
SUB_MIX_1[x] = (t << 16) | (t >>> 16);
SUB_MIX_2[x] = (t << 8) | (t >>> 24);
SUB_MIX_3[x] = t;
// Compute inv sub bytes, inv mix columns tables
var t = (x8 * 0x1010101) ^ (x4 * 0x10001) ^ (x2 * 0x101) ^ (x * 0x1010100);
INV_SUB_MIX_0[sx] = (t << 24) | (t >>> 8);
INV_SUB_MIX_1[sx] = (t << 16) | (t >>> 16);
INV_SUB_MIX_2[sx] = (t << 8) | (t >>> 24);
INV_SUB_MIX_3[sx] = t;
// Compute next counter
if (!x) {
x = xi = 1;
} else {
x = x2 ^ d[d[d[x8 ^ x2]]];
xi ^= d[d[xi]];
}
}
})();
// Precomputed Rcon lookup
var RCON = [0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36];
/**
* AES block cipher algorithm.
*/
var AES = (C_algo.AES = BlockCipher.extend({
_doReset: function () {
var t;
// Skip reset of nRounds has been set before and key did not change
if (this._nRounds && this._keyPriorReset === this._key) {
return;
}
// Shortcuts
var key = (this._keyPriorReset = this._key);
var keyWords = key.words;
var keySize = key.sigBytes / 4;
// Compute number of rounds
var nRounds = (this._nRounds = keySize + 6);
// Compute number of key schedule rows
var ksRows = (nRounds + 1) * 4;
// Compute key schedule
var keySchedule = (this._keySchedule = []);
for (var ksRow = 0; ksRow < ksRows; ksRow++) {
if (ksRow < keySize) {
keySchedule[ksRow] = keyWords[ksRow];
} else {
t = keySchedule[ksRow - 1];
if (!(ksRow % keySize)) {
// Rot word
t = (t << 8) | (t >>> 24);
// Sub word
t =
(SBOX[t >>> 24] << 24) |
(SBOX[(t >>> 16) & 0xff] << 16) |
(SBOX[(t >>> 8) & 0xff] << 8) |
SBOX[t & 0xff];
// Mix Rcon
t ^= RCON[(ksRow / keySize) | 0] << 24;
} else if (keySize > 6 && ksRow % keySize == 4) {
// Sub word
t =
(SBOX[t >>> 24] << 24) |
(SBOX[(t >>> 16) & 0xff] << 16) |
(SBOX[(t >>> 8) & 0xff] << 8) |
SBOX[t & 0xff];
}
keySchedule[ksRow] = keySchedule[ksRow - keySize] ^ t;
}
}
// Compute inv key schedule
var invKeySchedule = (this._invKeySchedule = []);
for (var invKsRow = 0; invKsRow < ksRows; invKsRow++) {
var ksRow = ksRows - invKsRow;
if (invKsRow % 4) {
var t = keySchedule[ksRow];
} else {
var t = keySchedule[ksRow - 4];
}
if (invKsRow < 4 || ksRow <= 4) {
invKeySchedule[invKsRow] = t;
} else {
invKeySchedule[invKsRow] =
INV_SUB_MIX_0[SBOX[t >>> 24]] ^
INV_SUB_MIX_1[SBOX[(t >>> 16) & 0xff]] ^
INV_SUB_MIX_2[SBOX[(t >>> 8) & 0xff]] ^
INV_SUB_MIX_3[SBOX[t & 0xff]];
}
}
},
encryptBlock: function (M, offset) {
this._doCryptBlock(M, offset, this._keySchedule, SUB_MIX_0, SUB_MIX_1, SUB_MIX_2, SUB_MIX_3, SBOX);
},
decryptBlock: function (M, offset) {
// Swap 2nd and 4th rows
var t = M[offset + 1];
M[offset + 1] = M[offset + 3];
M[offset + 3] = t;
this._doCryptBlock(
M,
offset,
this._invKeySchedule,
INV_SUB_MIX_0,
INV_SUB_MIX_1,
INV_SUB_MIX_2,
INV_SUB_MIX_3,
INV_SBOX,
);
// Inv swap 2nd and 4th rows
var t = M[offset + 1];
M[offset + 1] = M[offset + 3];
M[offset + 3] = t;
},
_doCryptBlock: function (M, offset, keySchedule, SUB_MIX_0, SUB_MIX_1, SUB_MIX_2, SUB_MIX_3, SBOX) {
// Shortcut
var nRounds = this._nRounds;
// Get input, add round key
var s0 = M[offset] ^ keySchedule[0];
var s1 = M[offset + 1] ^ keySchedule[1];
var s2 = M[offset + 2] ^ keySchedule[2];
var s3 = M[offset + 3] ^ keySchedule[3];
// Key schedule row counter
var ksRow = 4;
// Rounds
for (var round = 1; round < nRounds; round++) {
// Shift rows, sub bytes, mix columns, add round key
var t0 =
SUB_MIX_0[s0 >>> 24] ^
SUB_MIX_1[(s1 >>> 16) & 0xff] ^
SUB_MIX_2[(s2 >>> 8) & 0xff] ^
SUB_MIX_3[s3 & 0xff] ^
keySchedule[ksRow++];
var t1 =
SUB_MIX_0[s1 >>> 24] ^
SUB_MIX_1[(s2 >>> 16) & 0xff] ^
SUB_MIX_2[(s3 >>> 8) & 0xff] ^
SUB_MIX_3[s0 & 0xff] ^
keySchedule[ksRow++];
var t2 =
SUB_MIX_0[s2 >>> 24] ^
SUB_MIX_1[(s3 >>> 16) & 0xff] ^
SUB_MIX_2[(s0 >>> 8) & 0xff] ^
SUB_MIX_3[s1 & 0xff] ^
keySchedule[ksRow++];
var t3 =
SUB_MIX_0[s3 >>> 24] ^
SUB_MIX_1[(s0 >>> 16) & 0xff] ^
SUB_MIX_2[(s1 >>> 8) & 0xff] ^
SUB_MIX_3[s2 & 0xff] ^
keySchedule[ksRow++];
// Update state
s0 = t0;
s1 = t1;
s2 = t2;
s3 = t3;
}
// Shift rows, sub bytes, add round key
var t0 =
((SBOX[s0 >>> 24] << 24) |
(SBOX[(s1 >>> 16) & 0xff] << 16) |
(SBOX[(s2 >>> 8) & 0xff] << 8) |
SBOX[s3 & 0xff]) ^
keySchedule[ksRow++];
var t1 =
((SBOX[s1 >>> 24] << 24) |
(SBOX[(s2 >>> 16) & 0xff] << 16) |
(SBOX[(s3 >>> 8) & 0xff] << 8) |
SBOX[s0 & 0xff]) ^
keySchedule[ksRow++];
var t2 =
((SBOX[s2 >>> 24] << 24) |
(SBOX[(s3 >>> 16) & 0xff] << 16) |
(SBOX[(s0 >>> 8) & 0xff] << 8) |
SBOX[s1 & 0xff]) ^
keySchedule[ksRow++];
var t3 =
((SBOX[s3 >>> 24] << 24) |
(SBOX[(s0 >>> 16) & 0xff] << 16) |
(SBOX[(s1 >>> 8) & 0xff] << 8) |
SBOX[s2 & 0xff]) ^
keySchedule[ksRow++];
// Set output
M[offset] = t0;
M[offset + 1] = t1;
M[offset + 2] = t2;
M[offset + 3] = t3;
},
keySize: 256 / 32,
}));
/**
* Shortcut functions to the cipher's object interface.
*
* @example
*
* var ciphertext = CryptoJS.AES.encrypt(message, key, cfg);
* var plaintext = CryptoJS.AES.decrypt(ciphertext, key, cfg);
*/
C.AES = BlockCipher._createHelper(AES);
})();
return CryptoJS.AES;
});
/***/
},
/***/ './node_modules/crypto-js/cipher-core.js':
/*!***********************************************!*\
!*** ./node_modules/crypto-js/cipher-core.js ***!
\***********************************************/
/***/ function (module, exports, __webpack_require__) {
(function (root, factory, undef) {
if (true) {
// CommonJS
module.exports = exports = factory(
__webpack_require__(/*! ./core */ './node_modules/crypto-js/core.js'),
__webpack_require__(/*! ./evpkdf */ './node_modules/crypto-js/evpkdf.js'),
);
} else {
}
})(this, function (CryptoJS) {
/**
* Cipher core components.
*/
CryptoJS.lib.Cipher ||
(function (undefined) {
// Shortcuts
var C = CryptoJS;
var C_lib = C.lib;
var Base = C_lib.Base;
var WordArray = C_lib.WordArray;
var BufferedBlockAlgorithm = C_lib.BufferedBlockAlgorithm;
var C_enc = C.enc;
var Utf8 = C_enc.Utf8;
var Base64 = C_enc.Base64;
var C_algo = C.algo;
var EvpKDF = C_algo.EvpKDF;
/**
* Abstract base cipher template.
*
* @property {number} keySize This cipher's key size. Default: 4 (128 bits)
* @property {number} ivSize This cipher's IV size. Default: 4 (128 bits)
* @property {number} _ENC_XFORM_MODE A constant representing encryption mode.
* @property {number} _DEC_XFORM_MODE A constant representing decryption mode.
*/
var Cipher = (C_lib.Cipher = BufferedBlockAlgorithm.extend({
/**
* Configuration options.
*
* @property {WordArray} iv The IV to use for this operation.
*/
cfg: Base.extend(),
/**
* Creates this cipher in encryption mode.
*
* @param {WordArray} key The key.
* @param {Object} cfg (Optional) The configuration options to use for this operation.
*
* @return {Cipher} A cipher instance.
*
* @static
*
* @example
*
* var cipher = CryptoJS.algo.AES.createEncryptor(keyWordArray, { iv: ivWordArray });
*/
createEncryptor: function (key, cfg) {
return this.create(this._ENC_XFORM_MODE, key, cfg);
},
/**
* Creates this cipher in decryption mode.
*
* @param {WordArray} key The key.
* @param {Object} cfg (Optional) The configuration options to use for this operation.
*
* @return {Cipher} A cipher instance.
*
* @static
*
* @example
*
* var cipher = CryptoJS.algo.AES.createDecryptor(keyWordArray, { iv: ivWordArray });
*/
createDecryptor: function (key, cfg) {
return this.create(this._DEC_XFORM_MODE, key, cfg);
},
/**
* Initializes a newly created cipher.
*
* @param {number} xformMode Either the encryption or decryption transormation mode constant.
* @param {WordArray} key The key.
* @param {Object} cfg (Optional) The configuration options to use for this operation.
*
* @example
*
* var cipher = CryptoJS.algo.AES.create(CryptoJS.algo.AES._ENC_XFORM_MODE, keyWordArray, { iv: ivWordArray });
*/
init: function (xformMode, key, cfg) {
// Apply config defaults
this.cfg = this.cfg.extend(cfg);
// Store transform mode and key
this._xformMode = xformMode;
this._key = key;
// Set initial values
this.reset();
},
/**
* Resets this cipher to its initial state.
*
* @example
*
* cipher.reset();
*/
reset: function () {
// Reset data buffer
BufferedBlockAlgorithm.reset.call(this);
// Perform concrete-cipher logic
this._doReset();
},
/**
* Adds data to be encrypted or decrypted.
*
* @param {WordArray|string} dataUpdate The data to encrypt or decrypt.
*
* @return {WordArray} The data after processing.
*
* @example
*
* var encrypted = cipher.process('data');
* var encrypted = cipher.process(wordArray);
*/
process: function (dataUpdate) {
// Append
this._append(dataUpdate);
// Process available blocks
return this._process();
},
/**
* Finalizes the encryption or decryption process.
* Note that the finalize operation is effectively a destructive, read-once operation.
*
* @param {WordArray|string} dataUpdate The final data to encrypt or decrypt.
*
* @return {WordArray} The data after final processing.
*
* @example
*
* var encrypted = cipher.finalize();
* var encrypted = cipher.finalize('data');
* var encrypted = cipher.finalize(wordArray);
*/
finalize: function (dataUpdate) {
// Final data update
if (dataUpdate) {
this._append(dataUpdate);
}
// Perform concrete-cipher logic
var finalProcessedData = this._doFinalize();
return finalProcessedData;
},
keySize: 128 / 32,
ivSize: 128 / 32,
_ENC_XFORM_MODE: 1,
_DEC_XFORM_MODE: 2,
/**
* Creates shortcut functions to a cipher's object interface.
*
* @param {Cipher} cipher The cipher to create a helper for.
*
* @return {Object} An object with encrypt and decrypt shortcut functions.
*
* @static
*
* @example
*
* var AES = CryptoJS.lib.Cipher._createHelper(CryptoJS.algo.AES);
*/
_createHelper: (function () {
function selectCipherStrategy(key) {
if (typeof key == 'string') {
return PasswordBasedCipher;
} else {
return SerializableCipher;
}
}
return function (cipher) {
return {
encrypt: function (message, key, cfg) {
return selectCipherStrategy(key).encrypt(cipher, message, key, cfg);
},
decrypt: function (ciphertext, key, cfg) {
return selectCipherStrategy(key).decrypt(cipher, ciphertext, key, cfg);
},
};
};
})(),
}));
/**
* Abstract base stream cipher template.
*
* @property {number} blockSize The number of 32-bit words this cipher operates on. Default: 1 (32 bits)
*/
var StreamCipher = (C_lib.StreamCipher = Cipher.extend({
_doFinalize: function () {
// Process partial blocks
var finalProcessedBlocks = this._process(!!'flush');
return finalProcessedBlocks;
},
blockSize: 1,
}));
/**
* Mode namespace.
*/
var C_mode = (C.mode = {});
/**
* Abstract base block cipher mode template.
*/
var BlockCipherMode = (C_lib.Bloc