From bacf77b506a25a13221cada7966957aac8334423 Mon Sep 17 00:00:00 2001 From: Zan1456 <62830223+Zan1456@users.noreply.github.com> Date: Wed, 4 Jun 2025 16:56:54 +0200 Subject: [PATCH] 2fa support --- login/twofactor.css | 326 ++++++++++++++++++++++++++++++++++++++++++++ login/twofactor.js | 171 +++++++++++++++++++++++ manifest.json | 7 +- 3 files changed, 503 insertions(+), 1 deletion(-) create mode 100644 login/twofactor.css create mode 100644 login/twofactor.js diff --git a/login/twofactor.css b/login/twofactor.css new file mode 100644 index 0000000..0ecf58f --- /dev/null +++ b/login/twofactor.css @@ -0,0 +1,326 @@ +@font-face { + font-family: 'Montserrat'; + src: url('chrome-extension://__MSG_@@extension_id__/fonts/Montserrat-Regular.woff2') format('woff2'); + font-weight: 400; + font-style: normal; +} +@font-face { + font-family: 'Montserrat'; + src: url('chrome-extension://__MSG_@@extension_id__/fonts/Montserrat-Medium.woff2') format('woff2'); + font-weight: 500; + font-style: normal; +} +@font-face { + font-family: 'Montserrat'; + src: url('chrome-extension://__MSG_@@extension_id__/fonts/Montserrat-SemiBold.woff2') format('woff2'); + font-weight: 600; + font-style: normal; +} +@font-face { + font-family: 'Figtree'; + src: url('chrome-extension://__MSG_@@extension_id__/fonts/Figtree-Regular.woff2') format('woff2'); + font-weight: 400; + font-style: normal; +} + +:root { + --icon-invert: 0.1; + --icon-sepia: 0.1; + --icon-saturate: 0.1; + --icon-hue-rotate: 0deg; + --icon-brightness: 0.1; +} + +:root[data-theme="light-green"] { + --icon-invert: 0.1; + --icon-sepia: 0.1; + --icon-saturate: 0.1; + --icon-hue-rotate: 0deg; + --icon-brightness: 0.1; +} + +:root[data-theme="dark-blue"] { + --icon-invert: 0.9; + --icon-sepia: 0.1; + --icon-saturate: 0.1; + --icon-hue-rotate: 0deg; + --icon-brightness: 1; +} + +:root[data-theme="dark-green"] { + --icon-invert: 0.9; + --icon-sepia: 0.1; + --icon-saturate: 0.1; + --icon-hue-rotate: 0deg; + --icon-brightness: 1; +} + +* { + box-sizing: border-box; + margin: 0; + padding: 0; +} + +body { + margin: 0; + padding: 0; + color: var(--text-primary); + background-color: var(--background) !important; + font-family: "Montserrat", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif !important; + min-height: 100vh; + font-size: 16px; + display: flex; + align-items: center; + justify-content: center; +} + +.login-container { + width: 90%; + max-width: 500px; + padding: 20px; + margin: 0 auto; +} + +.login-card { + background: var(--card-card); + padding: 24px; + margin-bottom: 16px; + border-radius: 24px; + box-shadow: 0px 1px var(--shadow-blur) 0px var(--accent-shadow); +} + +.card-header { + display: flex; + flex-direction: column; + align-items: center; + gap: 8px; + margin: 16px 0; + background: var(--card-card) !important; + border-bottom: 1px solid rgba(0, 0, 0, 0) !important; +} + +.logo-text { + color: var(--text-primary); + text-align: center; + font-family: Montserrat; + font-size: 20px; + font-style: normal; + font-weight: 700; + line-height: normal; +} + +.logo { + width: 48px; + height: 48px; + border-radius: 12px; +} + +.twofactor-title { + color: var(--text-primary); + text-align: center; + font-family: Montserrat; + font-size: 24px; + font-style: normal; + font-weight: 600; + line-height: 130%; + margin-bottom: 16px; +} + +.twofactor-form { + width: 100%; +} + +.form-group { + margin-bottom: 16px; +} + +.form-control { + display: flex; + height: 48px; + padding: 0px 14px; + align-items: center; + gap: 10px; + align-self: stretch; + border-radius: 12px; + background: var(--accent-15) !important; + border: 0px solid var(--accent-15) !important; + color: var(--text-primary) !important; +} + +.form-control:focus { + outline: none; + border-color: var(--accent-accent) !important; +} + +.form-control::placeholder { + color: var(--text-secondary) !important; +} + +.password-group { + position: relative; +} + +.show-password { + position: absolute; + right: 12px; + top: 50%; + transform: translateY(-50%); + background: none; + border: none; + padding: 4px; + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; +} + +.icon-eye { + width: 20px; + height: 20px; + opacity: 0.6; + transition: opacity 0.2s ease; + filter: invert(var(--icon-invert)) sepia(var(--icon-sepia)) saturate(var(--icon-saturate)) hue-rotate(var(--icon-hue-rotate)) brightness(var(--icon-brightness)); +} + +.show-password:hover .icon-eye { + opacity: 1; +} + +.form-check { + display: flex; + align-items: center; + margin-top: 16px; + margin-bottom: 16px; +} + +.form-check-input { + width: 20px; + height: 20px; + margin-right: 8px; + border-radius: 6px; + border: 2px solid var(--accent-accent); + background-color: var(--card-card); + cursor: pointer; +} + +.form-check-input:checked { + background-color: var(--accent-accent); + border-color: var(--accent-accent); +} + +.form-check-label { + color: var(--text-primary); + font-family: Figtree; + font-size: 14px; + font-style: normal; + font-weight: 400; + line-height: 130%; + cursor: pointer; +} + +.btn-kreta { + display: flex; + height: 48px; + padding: 0px 24px; + justify-content: center; + align-items: center; + gap: 8px; + border-radius: 12px; + background: var(--accent-accent); + color: white; + font-family: Montserrat; + font-size: 16px; + font-style: normal; + font-weight: 600; + line-height: normal; + border: none; + cursor: pointer; + transition: background-color 0.2s ease; +} + +.btn-kreta:hover { + background-color: var(--accent-secondary); +} + +.btn-link { + background: none; + border: none; + color: var(--accent-accent); + font-family: Figtree; + font-size: 14px; + font-style: normal; + font-weight: 400; + line-height: 130%; + text-decoration: underline; + cursor: pointer; + padding: 0; +} + +.btn-link:hover { + color: var(--accent-secondary); +} + +.subtext { + color: var(--text-primary); + font-family: Figtree; + font-size: 14px; + font-style: normal; + font-weight: 400; + line-height: 130%; + text-align: center; +} + +.login-footer { + margin-top: 24px; + text-align: center; +} + +.privacy-link { + color: var(--text-secondary); + font-family: Figtree; + font-size: 14px; + font-style: normal; + font-weight: 400; + line-height: 130%; + text-decoration: none; +} + +.privacy-link:hover { + text-decoration: underline; +} + +.error-message { + display: none; + color: var(--error-text); + font-family: Figtree; + font-size: 12px; + font-style: normal; + font-weight: 400; + line-height: 130%; + margin-top: 4px; +} + +.error-message.show { + display: block; +} + +.form-control.error { + border: 1px solid var(--error-accent) !important; +} + +/* Hide original elements */ +header, main > .container-fluid, footer { + display: none !important; +} + +/* Responsive adjustments */ +@media (max-width: 576px) { + .login-container { + width: 100%; + padding: 16px; + } + + .login-card { + padding: 16px; + } +} \ No newline at end of file diff --git a/login/twofactor.js b/login/twofactor.js new file mode 100644 index 0000000..2fc2609 --- /dev/null +++ b/login/twofactor.js @@ -0,0 +1,171 @@ +async function transformTwoFactorPage() { + try { + if (document.readyState !== 'complete') { + await new Promise(resolve => { + window.addEventListener('load', resolve); + }); + } + + if (typeof loadingScreen !== 'undefined') { + loadingScreen.show(); + } + + const existingForm = document.querySelector('form'); + const formData = { + action: existingForm?.getAttribute('action') || '', + clientId: document.querySelector('#ClientId')?.value || '', + rememberLogin: document.querySelector('#RememberLogin')?.value || 'False', + returnUrl: document.querySelector('#ReturnUrl')?.value || '', + isRecoveryCode: document.querySelector('#IsRecoveryCode')?.value || 'False', + requestToken: document.querySelector('input[name="__RequestVerificationToken"]')?.value || '', + trustDeviceValue: document.querySelector('input[name="TrustDevice"][type="hidden"]')?.value || 'false' + }; + + const newHTML = ` +
+
+
+

+ + Firka +

+

Kétfaktoros azonosítás

+
+ +
+ + + + + + +
+ + +
Kérjük, add meg az egyszeri jelszót.
+
+ +
+ + + +
+ +
+ +
+ +
+ + Nem fér hozzá eszközéhez? Lépjen be + + +
+
+
+ + +
+ `; + + document.body.innerHTML = newHTML; + applyTheme(); + setupEventListeners(); + if (typeof loadingScreen !== 'undefined') { + loadingScreen.hide(); + } + + } catch (error) { + console.error('Error transforming two-factor page:', error); + if (typeof loadingScreen !== 'undefined') { + loadingScreen.hide(); + } + } +} + +function applyTheme() { + try { + if (typeof getCookie === 'function') { + const theme = getCookie('theme') || 'light-blue'; + document.documentElement.setAttribute('data-theme', theme); + } + } catch (error) { + console.error('Error applying theme:', error); + } +} + +function setupEventListeners() { + const twoFactorForm = document.getElementById('twoFactorForm'); + const verificationInput = document.getElementById('VerificationCode'); + const togglePasswordBtn = document.querySelector('.show-password'); + const formInputs = document.querySelectorAll('.form-control'); + + if (togglePasswordBtn && verificationInput) { + togglePasswordBtn.addEventListener('click', () => { + const isPassword = verificationInput.type === 'password'; + verificationInput.type = isPassword ? 'text' : 'password'; + const icon = togglePasswordBtn.querySelector('.icon-eye'); + icon.src = chrome.runtime.getURL(`icons/${isPassword ? 'eye-on' : 'eye-off'}.svg`); + }); + } + formInputs.forEach(input => { + input.addEventListener('input', () => { + validateInput(input); + }); + + input.addEventListener('blur', () => { + validateInput(input, true); + }); + }); + if (twoFactorForm) { + twoFactorForm.addEventListener('submit', handleSubmit); + } +} + +function validateInput(input, showError = false) { + const isValid = input.value.trim().length > 0; + const errorElement = input.nextElementSibling?.nextElementSibling; + + if (!isValid && showError) { + input.classList.add('error'); + errorElement?.classList.add('show'); + } else { + input.classList.remove('error'); + errorElement?.classList.remove('show'); + } + + return isValid; +} + +function handleSubmit(event) { + event.preventDefault(); + + const form = event.target; + const inputs = form.querySelectorAll('.form-control[required]'); + let isValid = true; + inputs.forEach(input => { + if (!validateInput(input, true)) { + isValid = false; + } + }); + if (isValid) { + const submitButton = form.querySelector('.btn-kreta'); + if (submitButton) { + submitButton.disabled = true; + submitButton.innerHTML = 'Ellenőrzés...'; + } + + form.submit(); + } +} +transformTwoFactorPage(); \ No newline at end of file diff --git a/manifest.json b/manifest.json index 1052048..3d6c5fa 100644 --- a/manifest.json +++ b/manifest.json @@ -20,7 +20,7 @@ "icons/*.svg", "grades/chart.js" ], - "matches": ["https://*.e-kreta.hu/*"] + "matches": ["https://*.e-kreta.hu/*", "https://idp.e-kreta.hu/*"] }], "content_scripts": [ { @@ -44,6 +44,11 @@ "js": ["login/login.js"], "css": ["login/login.css"] }, + { + "matches": ["https://idp.e-kreta.hu/account/loginwithtwofactor*"], + "js": ["login/twofactor.js"], + "css": ["login/twofactor.css"] + }, { "matches": [ "https://*.e-kreta.hu/Hianyzas/Hianyzasok*"