From 377e9f2395a7b85cf1a8ec8608183174ae8451be Mon Sep 17 00:00:00 2001 From: Nikiroy78 <35032449+Nikiroy78@users.noreply.github.com> Date: Sun, 29 Oct 2023 15:52:41 +0300 Subject: [PATCH] Add /password-manager page --- assets/clipboard.js | 34 ++ assets/encode-converter.js | 47 +++ assets/main.css | 9 + assets/main.js | 4 + assets/pages/password-manager.js | 18 ++ assets/sha1.js | 489 +++++++++++++++++++++++++++++ fl_dir/password-manager/index.html | 28 ++ password-manager/index.html | 34 ++ 8 files changed, 663 insertions(+) create mode 100644 assets/clipboard.js create mode 100644 assets/encode-converter.js create mode 100644 assets/pages/password-manager.js create mode 100644 assets/sha1.js create mode 100644 fl_dir/password-manager/index.html create mode 100644 password-manager/index.html diff --git a/assets/clipboard.js b/assets/clipboard.js new file mode 100644 index 0000000..5b62bf3 --- /dev/null +++ b/assets/clipboard.js @@ -0,0 +1,34 @@ +function fallbackCopyTextToClipboard(text) { + var textArea = document.createElement("textarea"); + textArea.value = text; + + // Avoid scrolling to bottom + textArea.style.top = "0"; + textArea.style.left = "0"; + textArea.style.position = "fixed"; + + document.body.appendChild(textArea); + textArea.focus(); + textArea.select(); + + try { + var successful = document.execCommand('copy'); + var msg = successful ? 'successful' : 'unsuccessful'; + console.log('Fallback: Copying text command was ' + msg); + } catch (err) { + console.error('Fallback: Oops, unable to copy', err); + } + + document.body.removeChild(textArea); +} +export function copyTextToClipboard(text) { + if (!navigator.clipboard) { + fallbackCopyTextToClipboard(text); + return; + } + navigator.clipboard.writeText(text).then(function() { + console.log('Async: Copying to clipboard was successful!'); + }, function(err) { + console.error('Async: Could not copy text: ', err); + }); +} \ No newline at end of file diff --git a/assets/encode-converter.js b/assets/encode-converter.js new file mode 100644 index 0000000..710d257 --- /dev/null +++ b/assets/encode-converter.js @@ -0,0 +1,47 @@ +if (!window.atob) { + var tableStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + var table = tableStr.split(""); + + window.atob = function (base64) { + if (/(=[^=]+|={3,})$/.test(base64)) throw new Error("String contains an invalid character"); + base64 = base64.replace(/=/g, ""); + var n = base64.length & 3; + if (n === 1) throw new Error("String contains an invalid character"); + for (var i = 0, j = 0, len = base64.length / 4, bin = []; i < len; ++i) { + var a = tableStr.indexOf(base64[j++] || "A"), b = tableStr.indexOf(base64[j++] || "A"); + var c = tableStr.indexOf(base64[j++] || "A"), d = tableStr.indexOf(base64[j++] || "A"); + if ((a | b | c | d) < 0) throw new Error("String contains an invalid character"); + bin[bin.length] = ((a << 2) | (b >> 4)) & 255; + bin[bin.length] = ((b << 4) | (c >> 2)) & 255; + bin[bin.length] = ((c << 6) | d) & 255; + }; + return String.fromCharCode.apply(null, bin).substr(0, bin.length + n - 4); + }; + + window.btoa = function (bin) { + for (var i = 0, j = 0, len = bin.length / 3, base64 = []; i < len; ++i) { + var a = bin.charCodeAt(j++), b = bin.charCodeAt(j++), c = bin.charCodeAt(j++); + if ((a | b | c) > 255) throw new Error("String contains an invalid character"); + base64[base64.length] = table[a >> 2] + table[((a << 4) & 63) | (b >> 4)] + + (isNaN(b) ? "=" : table[((b << 2) & 63) | (c >> 6)]) + + (isNaN(b + c) ? "=" : table[c & 63]); + } + return base64.join(""); + }; + +} + +export function hexToBase64(str) { + return btoa(String.fromCharCode.apply(null, + str.replace(/\r|\n/g, "").replace(/([\da-fA-F]{2}) ?/g, "0x$1 ").replace(/ +$/, "").split(" ")) + ); +} + +export function base64ToHex(str) { + for (var i = 0, bin = atob(str.replace(/[ \r\n]+$/, "")), hex = []; i < bin.length; ++i) { + var tmp = bin.charCodeAt(i).toString(16); + if (tmp.length === 1) tmp = "0" + tmp; + hex[hex.length] = tmp; + } + return hex.join(" "); +} \ No newline at end of file diff --git a/assets/main.css b/assets/main.css index 19669df..0fd8972 100644 --- a/assets/main.css +++ b/assets/main.css @@ -79,6 +79,15 @@ margin: auto; } +.password-manger-form { + margin-left : 30%; + margin-right : 30%; + padding : 10px; + padding-left : 65px; + padding-right : 65px; + border-radius : 15px; +} + /* $accordion-color:green; */ /* $accordion-padding-y:1.3rem; */ /* $accordion-padding-x:2.5rem; */ diff --git a/assets/main.js b/assets/main.js index 031c779..44b89d4 100644 --- a/assets/main.js +++ b/assets/main.js @@ -1,4 +1,5 @@ import { blog } from "./pages/blog.js"; +import { passwordManager } from "./pages/password-manager.js"; /* Альтернативное главное меню */ let altMenuSelectedPage = 1; const altPages = [ @@ -42,6 +43,9 @@ if (isMobile && !document.cookie.includes('warning_showed=true')) { fl.bindLoad('/blog', () => { blog(); }); +fl.bindLoad('/password-manager', () => { + passwordManager(); +}); fl.bindLoad('/main-mobile', () => { document.getElementById('alt-main-prev').onclick = () => setAltMenuPage(altMenuSelectedPage - 1); diff --git a/assets/pages/password-manager.js b/assets/pages/password-manager.js new file mode 100644 index 0000000..0008239 --- /dev/null +++ b/assets/pages/password-manager.js @@ -0,0 +1,18 @@ +import {} from "/assets/sha1.js"; +import { hexToBase64 } from "/assets/encode-converter.js"; +import { copyTextToClipboard } from "/assets/clipboard.js"; + +function generatePassword () { + const generatedPasswordElement = document.getElementById('generated-password'); + const keyword = document.getElementById('keyword').value; + const service = document.getElementById('service').value.toLowerCase();; + const login = document.getElementById('login').value.toLowerCase();; + + const generatedPassword = hexToBase64(sha1(`${keyword}::${service}::${login}`)) + "#"; + generatedPasswordElement.value = generatedPassword; +} + +export function passwordManager () { + document.getElementById('generate-password').onclick = generatePassword; + document.getElementById('copy-password').onclick = () => copyTextToClipboard(document.getElementById('generated-password').value); +} \ No newline at end of file diff --git a/assets/sha1.js b/assets/sha1.js new file mode 100644 index 0000000..79bab00 --- /dev/null +++ b/assets/sha1.js @@ -0,0 +1,489 @@ +/* + * [js-sha1]{@link https://github.com/emn178/js-sha1} + * + * @version 0.6.0 + * @author Chen, Yi-Cyuan [emn178@gmail.com] + * @copyright Chen, Yi-Cyuan 2014-2017 + * @license MIT + */ +!(function () { + "use strict"; + function t(t) { + t + ? ((f[0] = + f[16] = + f[1] = + f[2] = + f[3] = + f[4] = + f[5] = + f[6] = + f[7] = + f[8] = + f[9] = + f[10] = + f[11] = + f[12] = + f[13] = + f[14] = + f[15] = + 0), + (this.blocks = f)) + : (this.blocks = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), + (this.h0 = 1732584193), + (this.h1 = 4023233417), + (this.h2 = 2562383102), + (this.h3 = 271733878), + (this.h4 = 3285377520), + (this.block = this.start = this.bytes = this.hBytes = 0), + (this.finalized = this.hashed = !1), + (this.first = !0); + } + var h = "object" == typeof window ? window : {}, + s = + !h.JS_SHA1_NO_NODE_JS && + "object" == typeof process && + process.versions && + process.versions.node; + s && (h = global); + var i = + !h.JS_SHA1_NO_COMMON_JS && "object" == typeof module && module.exports, + e = "function" == typeof define && define.amd, + r = "0123456789abcdef".split(""), + o = [-2147483648, 8388608, 32768, 128], + n = [24, 16, 8, 0], + a = ["hex", "array", "digest", "arrayBuffer"], + f = [], + u = function (h) { + return function (s) { + return new t(!0).update(s)[h](); + }; + }, + c = function () { + var h = u("hex"); + s && (h = p(h)), + (h.create = function () { + return new t(); + }), + (h.update = function (t) { + return h.create().update(t); + }); + for (var i = 0; i < a.length; ++i) { + var e = a[i]; + h[e] = u(e); + } + return h; + }, + p = function (t) { + var h = eval("require('crypto')"), + s = eval("require('buffer').Buffer"), + i = function (i) { + if ("string" == typeof i) + return h.createHash("sha1").update(i, "utf8").digest("hex"); + if (i.constructor === ArrayBuffer) i = new Uint8Array(i); + else if (void 0 === i.length) return t(i); + return h.createHash("sha1").update(new s(i)).digest("hex"); + }; + return i; + }; + (t.prototype.update = function (t) { + if (!this.finalized) { + var s = "string" != typeof t; + s && t.constructor === h.ArrayBuffer && (t = new Uint8Array(t)); + for (var i, e, r = 0, o = t.length || 0, a = this.blocks; r < o; ) { + if ( + (this.hashed && + ((this.hashed = !1), + (a[0] = this.block), + (a[16] = + a[1] = + a[2] = + a[3] = + a[4] = + a[5] = + a[6] = + a[7] = + a[8] = + a[9] = + a[10] = + a[11] = + a[12] = + a[13] = + a[14] = + a[15] = + 0)), + s) + ) + for (e = this.start; r < o && e < 64; ++r) + a[e >> 2] |= t[r] << n[3 & e++]; + else + for (e = this.start; r < o && e < 64; ++r) + (i = t.charCodeAt(r)) < 128 + ? (a[e >> 2] |= i << n[3 & e++]) + : i < 2048 + ? ((a[e >> 2] |= (192 | (i >> 6)) << n[3 & e++]), + (a[e >> 2] |= (128 | (63 & i)) << n[3 & e++])) + : i < 55296 || i >= 57344 + ? ((a[e >> 2] |= (224 | (i >> 12)) << n[3 & e++]), + (a[e >> 2] |= (128 | ((i >> 6) & 63)) << n[3 & e++]), + (a[e >> 2] |= (128 | (63 & i)) << n[3 & e++])) + : ((i = + 65536 + (((1023 & i) << 10) | (1023 & t.charCodeAt(++r)))), + (a[e >> 2] |= (240 | (i >> 18)) << n[3 & e++]), + (a[e >> 2] |= (128 | ((i >> 12) & 63)) << n[3 & e++]), + (a[e >> 2] |= (128 | ((i >> 6) & 63)) << n[3 & e++]), + (a[e >> 2] |= (128 | (63 & i)) << n[3 & e++])); + (this.lastByteIndex = e), + (this.bytes += e - this.start), + e >= 64 + ? ((this.block = a[16]), + (this.start = e - 64), + this.hash(), + (this.hashed = !0)) + : (this.start = e); + } + return ( + this.bytes > 4294967295 && + ((this.hBytes += (this.bytes / 4294967296) << 0), + (this.bytes = this.bytes % 4294967296)), + this + ); + } + }), + (t.prototype.finalize = function () { + if (!this.finalized) { + this.finalized = !0; + var t = this.blocks, + h = this.lastByteIndex; + (t[16] = this.block), + (t[h >> 2] |= o[3 & h]), + (this.block = t[16]), + h >= 56 && + (this.hashed || this.hash(), + (t[0] = this.block), + (t[16] = + t[1] = + t[2] = + t[3] = + t[4] = + t[5] = + t[6] = + t[7] = + t[8] = + t[9] = + t[10] = + t[11] = + t[12] = + t[13] = + t[14] = + t[15] = + 0)), + (t[14] = (this.hBytes << 3) | (this.bytes >>> 29)), + (t[15] = this.bytes << 3), + this.hash(); + } + }), + (t.prototype.hash = function () { + var t, + h, + s = this.h0, + i = this.h1, + e = this.h2, + r = this.h3, + o = this.h4, + n = this.blocks; + for (t = 16; t < 80; ++t) + (h = n[t - 3] ^ n[t - 8] ^ n[t - 14] ^ n[t - 16]), + (n[t] = (h << 1) | (h >>> 31)); + for (t = 0; t < 20; t += 5) + (s = + ((h = + ((i = + ((h = + ((e = + ((h = + ((r = + ((h = + ((o = + ((h = (s << 5) | (s >>> 27)) + + ((i & e) | (~i & r)) + + o + + 1518500249 + + n[t]) << + 0) << + 5) | + (o >>> 27)) + + ((s & (i = (i << 30) | (i >>> 2))) | (~s & e)) + + r + + 1518500249 + + n[t + 1]) << + 0) << + 5) | + (r >>> 27)) + + ((o & (s = (s << 30) | (s >>> 2))) | (~o & i)) + + e + + 1518500249 + + n[t + 2]) << + 0) << + 5) | + (e >>> 27)) + + ((r & (o = (o << 30) | (o >>> 2))) | (~r & s)) + + i + + 1518500249 + + n[t + 3]) << + 0) << + 5) | + (i >>> 27)) + + ((e & (r = (r << 30) | (r >>> 2))) | (~e & o)) + + s + + 1518500249 + + n[t + 4]) << + 0), + (e = (e << 30) | (e >>> 2)); + for (; t < 40; t += 5) + (s = + ((h = + ((i = + ((h = + ((e = + ((h = + ((r = + ((h = + ((o = + ((h = (s << 5) | (s >>> 27)) + + (i ^ e ^ r) + + o + + 1859775393 + + n[t]) << + 0) << + 5) | + (o >>> 27)) + + (s ^ (i = (i << 30) | (i >>> 2)) ^ e) + + r + + 1859775393 + + n[t + 1]) << + 0) << + 5) | + (r >>> 27)) + + (o ^ (s = (s << 30) | (s >>> 2)) ^ i) + + e + + 1859775393 + + n[t + 2]) << + 0) << + 5) | + (e >>> 27)) + + (r ^ (o = (o << 30) | (o >>> 2)) ^ s) + + i + + 1859775393 + + n[t + 3]) << + 0) << + 5) | + (i >>> 27)) + + (e ^ (r = (r << 30) | (r >>> 2)) ^ o) + + s + + 1859775393 + + n[t + 4]) << + 0), + (e = (e << 30) | (e >>> 2)); + for (; t < 60; t += 5) + (s = + ((h = + ((i = + ((h = + ((e = + ((h = + ((r = + ((h = + ((o = + ((h = (s << 5) | (s >>> 27)) + + ((i & e) | (i & r) | (e & r)) + + o - + 1894007588 + + n[t]) << + 0) << + 5) | + (o >>> 27)) + + ((s & (i = (i << 30) | (i >>> 2))) | + (s & e) | + (i & e)) + + r - + 1894007588 + + n[t + 1]) << + 0) << + 5) | + (r >>> 27)) + + ((o & (s = (s << 30) | (s >>> 2))) | (o & i) | (s & i)) + + e - + 1894007588 + + n[t + 2]) << + 0) << + 5) | + (e >>> 27)) + + ((r & (o = (o << 30) | (o >>> 2))) | (r & s) | (o & s)) + + i - + 1894007588 + + n[t + 3]) << + 0) << + 5) | + (i >>> 27)) + + ((e & (r = (r << 30) | (r >>> 2))) | (e & o) | (r & o)) + + s - + 1894007588 + + n[t + 4]) << + 0), + (e = (e << 30) | (e >>> 2)); + for (; t < 80; t += 5) + (s = + ((h = + ((i = + ((h = + ((e = + ((h = + ((r = + ((h = + ((o = + ((h = (s << 5) | (s >>> 27)) + + (i ^ e ^ r) + + o - + 899497514 + + n[t]) << + 0) << + 5) | + (o >>> 27)) + + (s ^ (i = (i << 30) | (i >>> 2)) ^ e) + + r - + 899497514 + + n[t + 1]) << + 0) << + 5) | + (r >>> 27)) + + (o ^ (s = (s << 30) | (s >>> 2)) ^ i) + + e - + 899497514 + + n[t + 2]) << + 0) << + 5) | + (e >>> 27)) + + (r ^ (o = (o << 30) | (o >>> 2)) ^ s) + + i - + 899497514 + + n[t + 3]) << + 0) << + 5) | + (i >>> 27)) + + (e ^ (r = (r << 30) | (r >>> 2)) ^ o) + + s - + 899497514 + + n[t + 4]) << + 0), + (e = (e << 30) | (e >>> 2)); + (this.h0 = (this.h0 + s) << 0), + (this.h1 = (this.h1 + i) << 0), + (this.h2 = (this.h2 + e) << 0), + (this.h3 = (this.h3 + r) << 0), + (this.h4 = (this.h4 + o) << 0); + }), + (t.prototype.hex = function () { + this.finalize(); + var t = this.h0, + h = this.h1, + s = this.h2, + i = this.h3, + e = this.h4; + return ( + r[(t >> 28) & 15] + + r[(t >> 24) & 15] + + r[(t >> 20) & 15] + + r[(t >> 16) & 15] + + r[(t >> 12) & 15] + + r[(t >> 8) & 15] + + r[(t >> 4) & 15] + + r[15 & t] + + r[(h >> 28) & 15] + + r[(h >> 24) & 15] + + r[(h >> 20) & 15] + + r[(h >> 16) & 15] + + r[(h >> 12) & 15] + + r[(h >> 8) & 15] + + r[(h >> 4) & 15] + + r[15 & h] + + r[(s >> 28) & 15] + + r[(s >> 24) & 15] + + r[(s >> 20) & 15] + + r[(s >> 16) & 15] + + r[(s >> 12) & 15] + + r[(s >> 8) & 15] + + r[(s >> 4) & 15] + + r[15 & s] + + r[(i >> 28) & 15] + + r[(i >> 24) & 15] + + r[(i >> 20) & 15] + + r[(i >> 16) & 15] + + r[(i >> 12) & 15] + + r[(i >> 8) & 15] + + r[(i >> 4) & 15] + + r[15 & i] + + r[(e >> 28) & 15] + + r[(e >> 24) & 15] + + r[(e >> 20) & 15] + + r[(e >> 16) & 15] + + r[(e >> 12) & 15] + + r[(e >> 8) & 15] + + r[(e >> 4) & 15] + + r[15 & e] + ); + }), + (t.prototype.toString = t.prototype.hex), + (t.prototype.digest = function () { + this.finalize(); + var t = this.h0, + h = this.h1, + s = this.h2, + i = this.h3, + e = this.h4; + return [ + (t >> 24) & 255, + (t >> 16) & 255, + (t >> 8) & 255, + 255 & t, + (h >> 24) & 255, + (h >> 16) & 255, + (h >> 8) & 255, + 255 & h, + (s >> 24) & 255, + (s >> 16) & 255, + (s >> 8) & 255, + 255 & s, + (i >> 24) & 255, + (i >> 16) & 255, + (i >> 8) & 255, + 255 & i, + (e >> 24) & 255, + (e >> 16) & 255, + (e >> 8) & 255, + 255 & e, + ]; + }), + (t.prototype.array = t.prototype.digest), + (t.prototype.arrayBuffer = function () { + this.finalize(); + var t = new ArrayBuffer(20), + h = new DataView(t); + return ( + h.setUint32(0, this.h0), + h.setUint32(4, this.h1), + h.setUint32(8, this.h2), + h.setUint32(12, this.h3), + h.setUint32(16, this.h4), + t + ); + }); + var y = c(); + i + ? (module.exports = y) + : ((h.sha1 = y), + e && + define(function () { + return y; + })); +})(); \ No newline at end of file diff --git a/fl_dir/password-manager/index.html b/fl_dir/password-manager/index.html new file mode 100644 index 0000000..45d36d9 --- /dev/null +++ b/fl_dir/password-manager/index.html @@ -0,0 +1,28 @@ +
+

Менеджер паролей онлайн

+
+
+
+
+
+ +
Является "корневым паролем" для генерации паролей
+
+
+
+ +
Желательно использовать следующий приоритет: логин->почта->номер телефона; это поможет вам знать корректный пароль от системы
+
+
+
+ +
Используйте доменные имена без сокращений (vk.com; yandex.ru; mail.yandex.ru; youtube.com; etc.)
+
+
+
+ +
Сгенерированный пароль по формуле: base64(sha1(`${keyword}::${service}::${login}`)) + "#"
+
+
+
+
\ No newline at end of file diff --git a/password-manager/index.html b/password-manager/index.html new file mode 100644 index 0000000..0bd1bfa --- /dev/null +++ b/password-manager/index.html @@ -0,0 +1,34 @@ + + + + + + + + + + + FullGreaM + + + + +
+

Включите поддержку JavaScript!

+

В противном случае, компоненты сайте не смогут быть загружены

+
+ + + + + + + + \ No newline at end of file