diff --git a/assets/src/css/style.css b/assets/src/css/style.css index 19141ae042..88ab38aaaf 100755 --- a/assets/src/css/style.css +++ b/assets/src/css/style.css @@ -216,6 +216,192 @@ input[type=file] { box-shadow: 0 1px 3px rgba(255, 193, 7, 0.3); } +.login-page .osm-login { + display: flex; + align-items: center; + justify-content: center; + width: 100%; + min-height: 100vh; + padding: 32px 16px; + background: + linear-gradient(135deg, rgba(15, 23, 42, 0.04), rgba(14, 165, 233, 0.08)), + #f5f7fb; +} + +.login-page .osm-login__panel { + width: min(100%, 430px); +} + +.login-page .osm-login__brand { + margin-bottom: 18px; + text-align: center; +} + +.login-page .osm-login__logo { + width: min(100%, 310px); + max-height: 86px; + object-fit: contain; +} + +.login-page .osm-login__locale { + display: flex; + align-items: center; + justify-content: flex-end; + gap: 8px; + margin-bottom: 12px; +} + +.login-page .osm-login__locale-label { + margin-bottom: 0; + color: #4b5563; + font-size: 0.9rem; + font-weight: 600; +} + +.login-page .osm-login__locale-select { + width: auto; + min-width: 180px; +} + +.login-page .osm-login__form { + padding: 32px; + background: #fff; + border: 1px solid #dbe3ef; + border-radius: 8px; + box-shadow: 0 18px 45px rgba(15, 23, 42, 0.12); +} + +.login-page .osm-login__title { + margin: 0; + color: #111827; + font-size: 1.75rem; + font-weight: 700; + letter-spacing: 0; + line-height: 1.2; +} + +.login-page .osm-login__subtitle { + margin: 8px 0 24px; + color: #64748b; +} + +.login-page .osm-login__notice, +.login-page .osm-login__error { + border-radius: 8px; +} + +.login-page .osm-login__brute { + display: block; + margin-top: 8px; +} + +.login-page .osm-login__field { + margin-bottom: 18px; +} + +.login-page .osm-login__field label { + color: #334155; + font-weight: 600; +} + +.login-page .osm-login__field .form-control { + min-height: 46px; + border-color: #cbd5e1; + border-radius: 6px 0 0 6px; +} + +.login-page .osm-login__field .input-group-text, +.login-page .osm-login__password-toggle { + min-width: 46px; + border-color: #cbd5e1; + background: #f8fafc; + color: #475569; +} + +.login-page .osm-login__password-toggle { + border-radius: 0 6px 6px 0; +} + +.login-page .osm-login__submit { + min-height: 48px; + border-radius: 6px; + font-weight: 700; +} + +.login-page .osm-login__links { + margin-top: 18px; + text-align: center; +} + +.login-page .osm-login__links a { + color: #475569; + font-weight: 600; +} + +.login-page .osm-login__links a:hover { + color: #0f766e; +} + +.login-page .osm-login__divider { + display: flex; + align-items: center; + gap: 12px; + margin: 24px 0 16px; + color: #64748b; + font-size: 0.9rem; +} + +.login-page .osm-login__divider::before, +.login-page .osm-login__divider::after { + content: ""; + flex: 1; + height: 1px; + background: #e2e8f0; +} + +.login-page .osm-login__oauth-button { + border-radius: 6px; + font-weight: 700; +} + +.login-page .osm-login :focus-visible { + outline: 3px solid rgba(14, 165, 233, 0.35); + outline-offset: 2px; +} + +@media (max-width: 575.98px) { + .login-page .osm-login { + align-items: flex-start; + padding: 22px 12px; + } + + .login-page .osm-login__brand { + margin-bottom: 14px; + } + + .login-page .osm-login__logo { + width: min(100%, 250px); + max-height: 72px; + } + + .login-page .osm-login__locale { + justify-content: stretch; + } + + .login-page .osm-login__locale-select { + flex: 1; + min-width: 0; + } + + .login-page .osm-login__form { + padding: 24px 18px; + } + + .login-page .osm-login__title { + font-size: 1.45rem; + } +} + /* Disabilita il widget sidebar-search di AdminLTE */ [data-widget-disabled="true"] .sidebar-search-results, .sidebar-search-results, diff --git a/include/login.php b/include/login.php new file mode 100644 index 0000000000..6300b38b07 --- /dev/null +++ b/include/login.php @@ -0,0 +1,211 @@ +. + */ + +$escape = static fn ($value) => htmlspecialchars((string) $value, ENT_QUOTES, 'UTF-8'); + +$username = $username ?? ''; +$error_message = $error_message ?? null; +$available_login_locales = $available_login_locales ?? []; +$selected_login_locale = $selected_login_locale ?? trans_osm()->getCurrentLocale(); +$oauth_providers = $oauth_providers ?? []; + +$provider_icon = static function ($provider_name) { + $provider_name = strtolower((string) $provider_name); + + if (str_contains($provider_name, 'microsoft')) { + return 'fa-windows'; + } + if (str_contains($provider_name, 'keycloak')) { + return 'fa-key'; + } + if (str_contains($provider_name, 'google')) { + return 'fa-google'; + } + + return 'fa-sign-in'; +}; + +echo ' +
+
+ '; + +if (count($available_login_locales) > 1) { + echo ' + '; +} + +if (Update::isBeta()) { + echo ' + '; +} + +if (AuthOSM::isBrute()) { + echo ' + '; +} + +echo ' + +
+
+ +'; diff --git a/index.php b/index.php index 53e55b8088..20b3fa88f6 100755 --- a/index.php +++ b/index.php @@ -27,12 +27,53 @@ $op = filter('op'); $token = filter('token'); -$microsoft = null; -$keycloack = null; -if ($dbo->isConnected()) { +// Lingua pre-login: solo sessione/richiesta corrente, senza modificare l'impostazione globale. +$available_login_locales = []; +$selected_login_locale = trans_osm()->getCurrentLocale(); +if ($dbo->isConnected() && $dbo->isInstalled() && !AuthOSM::check()) { try { - $microsoft = $dbo->selectOne('zz_oauth2', '*', ['name' => 'Microsoft', 'enabled' => 1, 'is_login' => 1]); - $keycloack = $dbo->selectOne('zz_oauth2', '*', ['name' => 'Keycloak', 'enabled' => 1, 'is_login' => 1]); + $catalog_locales = trans_osm()->getAvailableLocales(); + $enabled_locales = $dbo->fetchArray('SELECT `id`, `name`, `iso_code`, `language_code`, `date`, `time`, `timestamp`, `decimals`, `thousands`, `predefined` FROM `zz_langs` WHERE `enabled` = 1 ORDER BY `predefined` DESC, `name` ASC'); + + foreach ($enabled_locales as $enabled_locale) { + if (!empty($enabled_locale['predefined']) || trans_osm()->isLocaleAvailable($enabled_locale['language_code']) || in_array($enabled_locale['language_code'], $catalog_locales)) { + $available_login_locales[] = $enabled_locale; + } + } + + $requested_login_locale = null; + $has_requested_login_locale = array_key_exists('login_locale', $_POST) || array_key_exists('login_locale', $_GET); + if ($has_requested_login_locale) { + $requested_login_locale = post('login_locale') ?: get('login_locale'); + } elseif (!empty($_SESSION['login_locale'])) { + $requested_login_locale = $_SESSION['login_locale']; + } + + $login_locale = null; + foreach ($available_login_locales as $available_login_locale) { + if ($available_login_locale['language_code'] === $requested_login_locale) { + $login_locale = $available_login_locale; + break; + } + } + + if (!empty($login_locale)) { + $_SESSION['login_locale'] = $login_locale['language_code']; + $selected_login_locale = $login_locale['language_code']; + $lang = $selected_login_locale; + + trans_osm()->setLocale($selected_login_locale, [ + 'timestamp' => $login_locale['timestamp'], + 'date' => $login_locale['date'], + 'time' => $login_locale['time'], + 'number' => [ + 'decimals' => $login_locale['decimals'], + 'thousands' => $login_locale['thousands'], + ], + ]); + } elseif ($has_requested_login_locale) { + unset($_SESSION['login_locale']); + } } catch (QueryException $e) { } } @@ -140,80 +181,11 @@ include_once App::filepath('include|custom|', 'top.php'); -// Controllo se è una beta e in caso mostro un warning -if (Update::isBeta()) { - echo ' -
-
- '.tr('Attenzione!').' '.tr('Stai utilizzando una versione non stabile di OSM.').' - -
'; -} - -// Controllo se è una beta e in caso mostro un warning -if (AuthOSM::isBrute()) { - echo ' -
-
-

'.tr('Attenzione').'

-
-
-

'.tr('Sono stati effettuati troppi tentativi di accesso consecutivi!').'

-
-

'.tr('Tempo rimanente').':

-

'.(AuthOSM::getBruteTimeout() + 1).' '.tr('secondi').'

-
-
-
- - '; -} // Recupera il messaggio di errore dalla variabile di sessione $error_message = $_SESSION['login_error'] ?? null; if (!empty($error_message)) { // Rimuovi il messaggio dalla sessione dopo averlo recuperato unset($_SESSION['login_error']); - - echo ' - '; } $login_logo = App::getPaths()['img'].'/logo_completo.png'; @@ -229,100 +201,17 @@ function brute() { } } +$oauth_providers = []; if ($dbo->isInstalled() && $dbo->isConnected() && !Update::isUpdateAvailable()) { - echo ' -
-
-
-
- '.tr('OpenSTAManager, il software gestionale open source per assistenza tecnica e fatturazione elettronica').' -
- -
- -
- fetchArray('SELECT `id`, `name` FROM `zz_oauth2` WHERE `enabled` = 1 AND `is_login` = 1 ORDER BY `name` ASC'); + } catch (QueryException $e) { + $oauth_providers = []; } +} - echo ' required> -
-
- -
-
-
- -
- {[ "type": "password", "name": "password", "autocomplete": "current-password", "placeholder": "'.tr('Password').'", "class": "form-control-lg password-field" ]} -
- - - - '; - if ($microsoft || $keycloack) { - echo ' - '; - } - echo ' -
-
-
-
- - - '; +if ($dbo->isInstalled() && $dbo->isConnected() && !Update::isUpdateAvailable()) { + include_once App::filepath('include|custom|', 'login.php'); } $custom_css = $dbo->isInstalled() ? html_entity_decode(setting('CSS Personalizzato')) : ''; diff --git a/locale/de_DE/de_DE.mo b/locale/de_DE/de_DE.mo index 5e14ef7f7d..1c5803807b 100644 Binary files a/locale/de_DE/de_DE.mo and b/locale/de_DE/de_DE.mo differ diff --git a/locale/de_DE/de_DE.po b/locale/de_DE/de_DE.po index 7dee567392..3afd0c9d50 100644 --- a/locale/de_DE/de_DE.po +++ b/locale/de_DE/de_DE.po @@ -10726,3 +10726,19 @@ msgid "" "Il browser non supporta i contenuti iframe: clicca qui per raggiungere il " "file originale" msgstr "" + +#: include/login.php +msgid "Selezione lingua" +msgstr "Sprachauswahl" + +#: include/login.php +msgid "Lingua" +msgstr "Sprache" + +#: include/login.php +msgid "Accessi alternativi" +msgstr "Alternative Anmeldungen" + +#: include/login.php +msgid "Accedi con" +msgstr "Anmelden mit" diff --git a/locale/en_GB/en_GB.mo b/locale/en_GB/en_GB.mo index d291a6b6ad..6d70f840a8 100755 Binary files a/locale/en_GB/en_GB.mo and b/locale/en_GB/en_GB.mo differ diff --git a/locale/en_GB/en_GB.po b/locale/en_GB/en_GB.po index fb07812f19..a7a3cbda64 100755 --- a/locale/en_GB/en_GB.po +++ b/locale/en_GB/en_GB.po @@ -20181,6 +20181,22 @@ msgid "" "l'amministratore del sistema." msgstr "" +#: include/login.php +msgid "Selezione lingua" +msgstr "Language selection" + +#: include/login.php +msgid "Lingua" +msgstr "Language" + +#: include/login.php +msgid "Accessi alternativi" +msgstr "Alternative sign-ins" + +#: include/login.php +msgid "Accedi con" +msgstr "Sign in with" + #~ msgid "Il gestionale open source per l'assistenza tecnica e la fatturazione" #~ msgstr "" #~ "The open source management software for technical assistance and billing"