diff --git a/assets/js/fixit-decryptor.js b/assets/js/fixit-decryptor.js index 94f1fe69..aac75485 100644 --- a/assets/js/fixit-decryptor.js +++ b/assets/js/fixit-decryptor.js @@ -1,13 +1,15 @@ /** * FixIt decryptor for encrypted pages * @param {Object} options - * @param {Function} options.decrypted handler after decrypting + * @param {Function} [options.decrypted] handler after decrypting + * @param {Number} [options.duration] number of seconds to cache decryption statistics. unit: s * @author @Lruihao https://lruihao.cn * @since v0.2.15 */ FixItDecryptor = function (options = {}) { var _proto = FixItDecryptor.prototype; this.options = options || {}; + this.options.duration = this.options.duration || 7 * 24 * 60 * 60; // Default cache 7 days this.decryptedEventSet = new Set(); /** @@ -17,7 +19,7 @@ FixItDecryptor = function (options = {}) { const _decryptor = this; this.options.decrypted && this.addEventListener('decrypted', this.options.decrypted); - this.validateLocalStorage(); + this.validateCache(); document.querySelector('#fixit-decryptor')?.addEventListener('keydown', function (e) { if (e.key === 'Enter') { @@ -28,7 +30,6 @@ FixItDecryptor = function (options = {}) { const saltLen = input.length % 2 ? input.length : input.length + 1; const inputMd5 = CryptoJS.MD5(input).toString(); const inputSha256 = CryptoJS.SHA256(input).toString(); - const base64EncodeContent = $content.getAttribute('data-content').replace(inputSha256.slice(saltLen), ''); if (inputMd5 !== password) { alert(`Password error: ${input} not the correct password!`); @@ -38,11 +39,15 @@ FixItDecryptor = function (options = {}) { try { document.querySelector('.fixit-decryptor-container').classList.add('d-none'); - $content.insertAdjacentHTML('afterbegin', CryptoJS.enc.Base64.parse(base64EncodeContent).toString(CryptoJS.enc.Utf8)); - // remember stat + $content.insertAdjacentHTML( + 'afterbegin', + CryptoJS.enc.Base64.parse($content.getAttribute('data-content').replace(inputSha256.slice(saltLen), '')).toString(CryptoJS.enc.Utf8) + ); + // cache decryption statistics window.localStorage.setItem( `fixit-decryptor/#${location.pathname}`, JSON.stringify({ + expiration: Math.ceil(Date.now() / 1000) + _decryptor.options.duration, md5: inputMd5, sha256: inputSha256.slice(saltLen) }) @@ -60,23 +65,27 @@ FixItDecryptor = function (options = {}) { }; /** - * validate remembered stat in localStorage + * validate the cached decryption statistics in localStorage * // TODO 简化代码 */ - _proto.validateLocalStorage = () => { + _proto.validateCache = () => { const $content = document.querySelector('#content'); const password = $content.getAttribute('data-password'); - const rememberStat = JSON.parse(window.localStorage.getItem(`fixit-decryptor/#${location.pathname}`)); + const cachedStat = JSON.parse(window.localStorage.getItem(`fixit-decryptor/#${location.pathname}`)); - if (rememberStat?.md5 && rememberStat?.sha256) { - const base64EncodeContent = $content.getAttribute('data-content').replace(rememberStat.sha256, ''); - if (rememberStat.md5 !== password) { + if (cachedStat?.md5 && cachedStat?.sha256 && cachedStat?.expiration) { + if (cachedStat.md5 !== password || cachedStat.expiration < Math.ceil(Date.now() / 1000)) { + document.querySelector('.fixit-decryptor-container').classList.remove('d-none'); window.localStorage.removeItem(`fixit-decryptor/#${location.pathname}`); return console.warn('The password has expired, please re-enter!'); } + try { document.querySelector('.fixit-decryptor-container').classList.add('d-none'); - $content.insertAdjacentHTML('afterbegin', CryptoJS.enc.Base64.parse(base64EncodeContent).toString(CryptoJS.enc.Utf8)); + $content.insertAdjacentHTML( + 'afterbegin', + CryptoJS.enc.Base64.parse($content.getAttribute('data-content').replace(cachedStat.sha256, '')).toString(CryptoJS.enc.Utf8) + ); // decrypted hook for (let event of this.decryptedEventSet) { event();