diff --git a/lib/Auth/Source/Campusidp.php b/lib/Auth/Source/Campusidp.php index 0d513f5e3cd7405325f0df888656d6153cdda26d..a8880d9e9fa31238412cba82569e34ef42f54e8c 100644 --- a/lib/Auth/Source/Campusidp.php +++ b/lib/Auth/Source/Campusidp.php @@ -25,6 +25,7 @@ class Campusidp extends Source public const COOKIE_IDP_ENTITY_ID = 'idpentityid'; public const COOKIE_INSTITUTION_NAME = 'institution_name'; public const COOKIE_INSTITUTION_IMG = 'institution_img'; + public const COOKIE_COMPONENT_INDEX = 'component_index'; public const COOKIE_USERNAME = 'username'; public const COOKIE_PASSWORD = 'password'; @@ -140,6 +141,33 @@ class Campusidp extends Source Utils\HTTP::setCookie($prefixedName, $value, $params, false); } + public static function getMostSquareLikeImg($idpentry) + { + if (!empty($idpentry['UIInfo']['Logo'])) { + if (1 === count($idpentry['UIInfo']['Logo'])) { + $item['image'] = $idpentry['UIInfo']['Logo'][0]['url']; + } else { + $logoSizeRatio = 1; // impossible value + $candidateLogoUrl = null; + + foreach ($idpentry['UIInfo']['Logo'] as $logo) { + $ratio = abs($logo['height'] - $logo['width']) / ($logo['height'] + $logo['width']); + + if ($ratio < $logoSizeRatio) { // then we found more square-like logo + $logoSizeRatio = $ratio; + $candidateLogoUrl = $logo['url']; + } + } + + $item['image'] = $candidateLogoUrl; + } + + return $item['image']; + } else { + return ''; + } + } + public function logout(&$state) { assert(is_array($state)); diff --git a/locales/cs/LC_MESSAGES/campusMultiauth.po b/locales/cs/LC_MESSAGES/campusMultiauth.po index faca531b00cc281a2f6bc5b063fa252c5d919e96..b5cc4da620cc2834922f1f020c8ac6c20efb8f69 100644 --- a/locales/cs/LC_MESSAGES/campusMultiauth.po +++ b/locales/cs/LC_MESSAGES/campusMultiauth.po @@ -54,3 +54,6 @@ msgstr "Více možností" msgid "{campusMultiauth:wrong_username_or_password}" msgstr "Špatné uživatelské jméno nebo heslo." + +msgid "{campusMultiauth:search_button}" +msgstr "Vyhledat" diff --git a/locales/en/LC_MESSAGES/campusMultiauth.po b/locales/en/LC_MESSAGES/campusMultiauth.po index 9f642fe525875d9f4b1bf0a20df8950ef1627540..ec4783f4e7073abb57bd505b4c9c7bba93bc4ce0 100644 --- a/locales/en/LC_MESSAGES/campusMultiauth.po +++ b/locales/en/LC_MESSAGES/campusMultiauth.po @@ -54,3 +54,6 @@ msgstr "More options" msgid "{campusMultiauth:wrong_username_or_password}" msgstr "Wrong username or password." + +msgid "{campusMultiauth:search_button}" +msgstr "Search" diff --git a/themes/campusThemes/default/_header.twig b/themes/campusThemes/default/_header.twig index 0ac978e6ee05e0264e2c162fe5fde4c5707d123d..a261764b759a882182c82fec50ddb3e2e0fe292f 100644 --- a/themes/campusThemes/default/_header.twig +++ b/themes/campusThemes/default/_header.twig @@ -16,6 +16,16 @@ </a> {% endif %} </p> + <p class="menu-lang__popup"> + {% for langKey, langName in wayf_config.languages %} + {% if langKey != currentLanguage and currentUrl ~ "&language=" ~ langKey %} + <a href="{{ currentUrl ~ "?language=" ~ langKey }}{%- for name, value in queryParams %}{{ "&" ~ name ~ "=" ~ value }}{%- endfor %}" + rel="alternate" hreflang="{{ langKey }}" lang="{{ langKey }}" class="menu-lang__popup__link"> + {{ langName }} + </a> + {% endif %} + {% endfor %} + </p> </nav> {% else %} <nav class="menu-lang" aria-label="{{ '{campusMultiauth:lang_selection}'|trans }}"> @@ -61,10 +71,10 @@ <div class="header-container"> {% if wayf_config.languages | length > 2 %} <div class="dropdown mobile-language language-bar-margin"> - <a id="dropdown-language" class="btn btn-secondary dropdown-toggle text-primary" href="#" role="button"> + <a id="dropdown-language-mobile" class="btn btn-secondary dropdown-toggle text-primary bg-white border-0" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false"> {{ currentLanguage | upper }} </a> - <ul class="dropdown-menu" aria-labelledby="dropdown-language"> + <ul class="dropdown-menu" aria-labelledby="dropdown-language-mobile"> {% for langKey, langName in wayf_config.languages %} {% if langKey != currentLanguage %} <li> @@ -77,14 +87,14 @@ </ul> </div> <div class="dropdown desktop-language language-bar-margin"> - <a id="dropdown-language" class="btn btn-secondary dropdown-toggle text-primary" href="#" role="button"> + <a id="dropdown-language-desktop" class="btn btn-secondary dropdown-toggle text-primary bg-white border-0" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false"> {% if attribute(wayf_config.languages, currentLanguage) is defined %} {{ attribute(wayf_config.languages, currentLanguage) }} {% else %} {{ currentLanguage | upper }} {% endif %} </a> - <ul class="dropdown-menu" aria-labelledby="dropdown-language"> + <ul class="dropdown-menu" aria-labelledby="dropdown-language-desktop"> {% for langKey, langName in wayf_config.languages %} {% if langKey != currentLanguage %} <li> diff --git a/themes/campusThemes/default/base.twig b/themes/campusThemes/default/base.twig index 804c9454c23bb062f6185ab85eed57b5d1a45bff..a7d544693331e2e946a8fcc533b4b57ee10aadc2 100644 --- a/themes/campusThemes/default/base.twig +++ b/themes/campusThemes/default/base.twig @@ -16,8 +16,10 @@ {% if wayf_config.css_framework is defined and wayf_config.css_framework == 'muni_jvs' %} <link rel="stylesheet" type="text/css" href="/{{baseurlpath}}module.php/campusMultiauth/resources/MuniWeb/css/style{% if wayf_config.muni_faculty is defined%}-{{ wayf_config.muni_faculty }}{% endif %}.css" /> + <script src="/{{baseurlpath}}module.php/campusMultiauth/resources/MuniWeb/js/app.js"></script> {% else %} <link href="/{{baseurlpath}}module.php/campusMultiauth/resources/bootstrap-5.0.2-dist/css/bootstrap.css" rel="stylesheet"> + <script src="/{{baseurlpath}}module.php/campusMultiauth/resources/bootstrap-5.0.2-dist/js/bootstrap.bundle.js"></script> {% endif %} <link rel="stylesheet" type="text/css" href="/{{baseurlpath}}module.php/campusMultiauth/resources/campus_idp.css" /> @@ -26,7 +28,7 @@ </head> <body id="{{ templateId }}"> {% block header %}{% include "_header.twig" %}{% endblock %} - <div style="width: 100%; text-align: center"> + <div class="layout"> {% if wayf_config.css_framework is defined and wayf_config.css_framework == 'muni_jvs' %} <div class="window-jvs"> {% else %} diff --git a/themes/campusThemes/default/individual-identities.twig b/themes/campusThemes/default/individual-identities.twig index 98f6b66e77bc1a911dc010ee8d653e596b3a5ccc..73f1f978c70da9d6707214166a2e5d47c6012b29 100644 --- a/themes/campusThemes/default/individual-identities.twig +++ b/themes/campusThemes/default/individual-identities.twig @@ -36,7 +36,7 @@ </button> </div> {% else %} - <button class="btn btn-{{ configuration.priority }} btn-lg btn-individual-identity {% if loop.index0 >= configuration.number_shown %}idp-hidden vhide{% endif %}" type="submit" name="idpentityid" value="{{ idp.upstream_idp }}"> + <button class="btn btn-{{ configuration.priority }} btn-lg btn-individual-identity {% if loop.index0 >= configuration.number_shown %}idp-hidden d-none{% endif %}" type="submit" name="idpentityid" value="{{ idp.upstream_idp }}"> <img class="individual-identity-logo" {% if idp.background_color is defined %}style="background-color: {{ idp.background_color }}{% endif %}" src="{{ idp.logo }}" alt=""/> <span class="idp-text">{{ '{campusMultiauth:sign_in_with}'|trans }}{{ " " }}{% if attribute(idp.name, currentLanguage) is defined %}{{ attribute(idp.name, currentLanguage) }} {% elseif idp.name is defined and idp.name is iterable and idp.name is not empty %}{{ idp.name | first }} @@ -51,17 +51,23 @@ </form> {% if configuration.identities|length > configuration.number_shown %} - <div style="text-align: center;"> - <button id="more-options" class="btn btn-primary btn-s btn-white btn-more-options hover-none-primary" onclick="show()"> - <span class="no-uppercase padding-zero">{{ '{campusMultiauth:more_options}'|trans }} <span class="btn-icon icon icon-angle-down"></span></span> - </button> + <div class="text-center"> + {% if wayf_config.css_framework is defined and wayf_config.css_framework == 'muni_jvs' %} + <button id="more-options" class="btn btn-primary btn-s btn-white hover-none-primary" onclick="show()"> + <span class="no-uppercase padding-zero">{{ '{campusMultiauth:more_options}'|trans }}<span class="btn-icon icon icon-angle-down"></span></span> + </button> + {% else %} + <button id="more-options" class="btn btn-outline-{{ configuration.priority }} btn-lg btn-individual-identity btn-more-options text-center border-0 text-decoration-underline" type="button" onclick="show()"> + <span class="no-uppercase padding-zero">{{ '{campusMultiauth:more_options}'|trans }} <i class="fas fa-arrow-down"></i></span> + </button> + {% endif %} </div> {% endif %} <script> function show() { - document.querySelectorAll('.idp-hidden').forEach( function(element) {element.classList.remove('vhide')}); - document.getElementById('more-options').classList.add('vhide'); + document.querySelectorAll('.idp-hidden').forEach( function(element) {element.classList.remove({% if wayf_config.css_framework is defined and wayf_config.css_framework == 'muni_jvs' %}'vhide'{% else %}'d-none'{% endif %})}); + document.getElementById('more-options').classList.add({% if wayf_config.css_framework is defined and wayf_config.css_framework == 'muni_jvs' %}'vhide'{% else %}'d-none'{% endif %}); } </script> diff --git a/themes/campusThemes/default/searchbox.twig b/themes/campusThemes/default/searchbox.twig index fe7da09670a96e155e81ede4d9e74cf61aab780b..3f3156c3ea8a2a26bca850987332931ae43e03a9 100644 --- a/themes/campusThemes/default/searchbox.twig +++ b/themes/campusThemes/default/searchbox.twig @@ -2,8 +2,8 @@ {% set configuration = configuration|merge({'priority': 'secondary'}) %} {% endif %} -<div id="idps-form-div" class="list-group text-left"> - <form id="idps-form" action="{{ currentUrl }}" method="post"> +<div class="list-group text-left idps-form-div"> + <form id="idps-form-{{ component_index }}" action="{{ currentUrl }}" method="post"> <label for="searchbox" {% if wayf_config.css_framework is defined and wayf_config.css_framework == 'muni_jvs' %} class="color-{{ configuration.priority }} text-bold" @@ -18,7 +18,7 @@ {% elseif configuration.title is defined and configuration.title is not iterable %}{{ configuration.title }} {% else %}{{ '{campusMultiauth:searchbox_title}'|trans }} {% endif %}</label> - <input type="text" name="suggest" id="searchbox" value="" + <input type="text" name="searchbox" id="searchbox-{{ component_index }}" value="" {% if wayf_config.css_framework is defined and wayf_config.css_framework == 'muni_jvs' %} class="inp-text js-suggest searchbox-input input-height selectized color-border-{{ configuration.priority }}" {% else %} @@ -29,13 +29,13 @@ {% endif %} {% endif %}> - {% if cookie_idpentityid is not null %} + {% if cookie_idpentityid is not null and cookie_component_index == component_index %} {% if wayf_config.css_framework is defined and wayf_config.css_framework == 'muni_jvs' %} <div class="box-vcards-list__item box-vcard--compact searchbox-result side-padding-zero"> <button class="preferred-idp" type="submit"> <div class="box-vcards-list__inner side-padding-zero"> <p class="box-vcards-list__img center"> - <img src="{{ cookie_institution_img }}" style="height: 50px; width: 50px; object-fit: cover; object-position: left"/> + <img src="{{ cookie_institution_img }}" class="img-searchbox"/> </p> <div class="box-vcards-list__content u-pb-0 u-pt-0 u-pr-0 u-pl-10"> {% if attribute(cookie_institution_name, currentLanguage) is defined %}{{ attribute(cookie_institution_name, currentLanguage) }}{% else %}{{ cookie_institution_name.en}}{% endif %} @@ -45,63 +45,97 @@ </div> {% else %} <button class="list-group-item list-group-item-action d-flex align-items-center"> - <span style="margin-bottom: 0"> - <img src="{{ cookie_institution_img }}" style="height: 50px; width: 50px; object-fit: cover; object-position: left" alt=""/> + <span class="mb-0"> + <img src="{{ cookie_institution_img }}" class="img-searchbox" alt=""/> </span> - <span style="margin-left: 24px"> + <span class="margin-left-24"> {% if attribute(cookie_institution_name, currentLanguage) is defined %}{{ attribute(cookie_institution_name, currentLanguage) }}{% else %}{{ cookie_institution_name.en}}{% endif %} </span> </button> {% endif %} {% endif %} - <input type="hidden" id="idpentityid-searchbox" name="idpentityid-searchbox"{% if cookie_idpentityid is defined%} value="{{ cookie_idpentityid }}" {% endif %}/> - <input type="hidden" id="institution-name" name="institution-name"{% if cookie_institution_name is defined%} value="{{ cookie_institution_name | json_encode }}" {% endif %}/> - <input type="hidden" id="institution-img" name="institution-img"{% if cookie_institution_img is defined%} value="{{ cookie_institution_img }}" {% endif %}/> - + <input type="hidden" id="componentIndex" name="componentIndex" value="{{ component_index }}" /> <input type="hidden" id="authstate" name="authstate" value="{{ authstate }}" /> <input type="hidden" id="source" name="source" value="default-sp" /> </form> </div> -{% if idps == null %} - -<div id="idps-form-nojs-div" class="list-group"> - <form id="idps-form-nojs" action="{{ currentUrl }}" method="post"> - <label for="q" class="color-{{ configuration.priority }}">{% if attribute(configuration.title, currentLanguage) is defined %}{{ attribute(configuration.title, currentLanguage) }} - {% elseif configuration.title is defined and configuration.title is iterable and configuration.title is not empty %}{{ configuration.title | first }} - {% elseif configuration.title is defined and configuration.title is not iterable %}{{ configuration.title }} - {% else %}{{ '{campusMultiauth:searchbox_title}'|trans }} - {% endif %}</label> - <span class="inp-fix inp-icon inp-icon--after"> - <input id="q" name="q" class="inp-text" type="text" placeholder="{% if attribute(configuration.placeholder, currentLanguage) is defined %}{{ attribute(configuration.placeholder, currentLanguage) }}{% elseif configuration.placeholder is defined and configuration.placeholder is iterable and configuration.placeholder is not empty %}{{ configuration.placeholder | first }}{% elseif configuration.placeholder is defined and configuration.placeholder is not iterable %}{{ configuration.placeholder }}{% else %}{{ '{campusMultiauth:searchbox_placeholder}'|trans }}{% endif %}"> - <span class="icon icon-search"></span> - </span> - - <input type="hidden" id="authstate" name="authstate" value="{{ authstate }}" /> - </form> -</div> +{% if idps == null or component_index != no_js_display_index %} + <div class="idps-form-nojs-div list-group text-left"> + {% if wayf_config.css_framework is defined and wayf_config.css_framework == 'muni_jvs' %} + <label for="idps-form-nojs" class="color-{{ configuration.priority }}">{% if attribute(configuration.title, currentLanguage) is defined %}{{ attribute(configuration.title, currentLanguage) }} + {% elseif configuration.title is defined and configuration.title is iterable and configuration.title is not empty %}{{ configuration.title | first }} + {% elseif configuration.title is defined and configuration.title is not iterable %}{{ configuration.title }} + {% else %}{{ '{campusMultiauth:searchbox_title}'|trans }} + {% endif %}</label> + <form id="idps-form-nojs" class="form-inline" action="{{ currentUrl }}" method="post"> + <p class="size--m--4-4 size--l--10-12"> + <span class="inp-fix"> + <input id="q" class="inp-text" type="text" name="q" placeholder="{% if attribute(configuration.placeholder, currentLanguage) is defined %}{{ attribute(configuration.placeholder, currentLanguage) }}{% elseif configuration.placeholder is defined and configuration.placeholder is iterable and configuration.placeholder is not empty %}{{ configuration.placeholder | first }}{% elseif configuration.placeholder is defined and configuration.placeholder is not iterable %}{{ configuration.placeholder }}{% else %}{{ '{campusMultiauth:searchbox_placeholder}'|trans }}{% endif %}"> + </span> + </p> + <p> + <button class="btn btn-primary btn-s nowrap full-width" type="submit"> + <span>{{ '{campusMultiauth:search_button}'|trans }}</span> + </button> + </p> + {% else %} + <form id="idps-form-nojs" action="{{ currentUrl }}" method="post"> + <label for="q" + {% if configuration.priority == 'primary' %} + class="form-label text-dark" + {% else %} + class="form-label text-muted" + {% endif %}>{% if attribute(configuration.title, currentLanguage) is defined %}{{ attribute(configuration.title, currentLanguage) }} + {% elseif configuration.title is defined and configuration.title is iterable and configuration.title is not empty %}{{ configuration.title | first }} + {% elseif configuration.title is defined and configuration.title is not iterable %}{{ configuration.title }} + {% else %}{{ '{campusMultiauth:searchbox_title}'|trans }} + {% endif %}</label> + <div class="input-group"> + <input id="q" name="q" type="text" placeholder="{% if attribute(configuration.placeholder, currentLanguage) is defined %}{{ attribute(configuration.placeholder, currentLanguage) }}{% elseif configuration.placeholder is defined and configuration.placeholder is iterable and configuration.placeholder is not empty %}{{ configuration.placeholder | first }}{% elseif configuration.placeholder is defined and configuration.placeholder is not iterable %}{{ configuration.placeholder }}{% else %}{{ '{campusMultiauth:searchbox_placeholder}'|trans }}{% endif %}" + {% if configuration.priority == 'primary' %} + class="form-control border border-2 border-dark input-height" aria-describedby="submit-search"> + <button id="submit-search" class="btn btn-primary" type="submit">Button</button> + {% else %} + class="form-control border border-2 border-muted input-height" aria-describedby="submit-search"> + <button id="submit-search" class="btn btn-secondary" type="submit">{{ '{campusMultiauth:search_button}'|trans }}</button> + {% endif %} + </div> + {% endif %} + <input type="hidden" id="componentIndex" name="componentIndex" value="{{ component_index }}" /> + <input type="hidden" id="currentLanguage" name="currentLanguage" value="{{ currentLanguage }}" /> + <input type="hidden" id="authstate" name="authstate" value="{{ authstate }}" /> + </form> + </div> {% else %} - <div id="idps-form-nojs-div" class="list-group div-nojs"> - <form id="idps" action="{{ currentUrl }}" method="post"> + <div class="idps-form-nojs-div list-group div-nojs"> + <form id="idps-{{ component_index }}" action="{{ currentUrl }}" method="post"> {% for idp in idps.items %} - <button class="metaentry list-group-item" type="submit" name="idpentityid" value="{{ idp.idpentityid }}"> - <div class="box-vcards-list__item box-vcard--compact searchbox-result side-padding-zero"> - <div class="box-vcards-list__inner side-padding-zero"> - <p class="box-vcards-list__img center"> - <img src="{{ idp.image }}" style="height: 50px; width: 50px; object-fit: cover; object-position: left"> - </p> - <div class="box-vcards-list__content u-pb-0 u-pt-0 u-pr-0 u-pl-10"> - {% if attribute(idp.text, currentLanguage) is defined %} - {{ attribute(idp.text, currentLanguage) }} - {% else %} - {{ idp.text.en }} - {% endif %} + {% if wayf_config.css_framework is defined and wayf_config.css_framework == 'muni_jvs' %} + <button class="metaentry list-group-item" type="submit" name="idpentityid" value="{{ idp.idpentityid }}"> + <div class="box-vcards-list__item box-vcard--compact searchbox-result side-padding-zero"> + <div class="box-vcards-list__inner side-padding-zero"> + <p class="box-vcards-list__img center"> + <img src="{{ idp.image }}" class="img-searchbox"> + </p> + <div class="box-vcards-list__content u-pb-0 u-pt-0 u-pr-0 u-pl-10"> + {{ idp.text }} + </div> </div> </div> - </div> - </button> + </button> + {% else %} + <button class="list-group-item list-group-item-action d-flex align-items-center text-left" type="submit" name="idpentityid" value="{{ idp.idpentityid }}"> + <span class="mb-0"> + <img src="{{ idp.image }}" class="img-searchbox" alt=""/> + </span> + <span class="margin-left-24"> + {{ idp.text }} + </span> + </button> + {% endif %} {% endfor %} <input type="hidden" id="authstate" name="authstate" value="{{ authstate }}" /> @@ -113,7 +147,13 @@ <script type="text/javascript" src="/{{baseurlpath}}module.php/campusMultiauth/resources/searchbox.js"></script> <script> - let placeholderText = {% if attribute(configuration.placeholder, currentLanguage) is defined %} + if (typeof indexes === 'undefined') { + var indexes = [{{ component_index }}]; + } else { + indexes.push({{ component_index }}); + } + + var placeholderText = {% if attribute(configuration.placeholder, currentLanguage) is defined %} '{{ attribute(configuration.placeholder, currentLanguage) }}' {% elseif configuration.placeholder is defined and configuration.placeholder is iterable and configuration.placeholder is not empty %} '{{ configuration.placeholder | first }}' @@ -123,12 +163,19 @@ '{{ '{campusMultiauth:searchbox_placeholder}'|trans }}' {% endif %}; - let framework = {% if wayf_config.css_framework is defined and wayf_config.css_framework == 'muni_jvs' %} - 'muni_jvs' - {% else %} - 'bootstrap' - {% endif %} + if (typeof placeholderTexts === 'undefined') { + var placeholderTexts = [placeholderText]; + } else { + placeholderTexts.push(placeholderText); + } + + + var framework = {% if wayf_config.css_framework is defined and wayf_config.css_framework == 'muni_jvs' %} + 'muni_jvs' + {% else %} + 'bootstrap' + {% endif %} - let language = '{{ currentLanguage }}'; - let componentIndex = '{{ component_index }}'; + var language = '{{ currentLanguage }}'; + var baseUrl = '/' + '{{ baseurlpath }}'; </script> diff --git a/www/idpSearch.php b/www/idpSearch.php index 92cbceec7d5225c0d620c638ca48b66517f4ed44..20ed92efa77207c2e3cba0a4867f527a2fedad2b 100644 --- a/www/idpSearch.php +++ b/www/idpSearch.php @@ -3,6 +3,7 @@ use SimpleSAML\Configuration; use SimpleSAML\Logger; use SimpleSAML\Metadata\MetaDataStorageHandler; +use SimpleSAML\Module\campusMultiauth\Auth\Source\Campusidp; header('Content-type: application/json'); @@ -91,7 +92,7 @@ foreach ($metadata as $entityid => $idpentry) { $filteredData = []; foreach ($metadata as $entityid => $idpentry) { - if (is_array($idpentry['name'])) { + if (!empty($idpentry['name']) && is_array($idpentry['name'])) { foreach ($idpentry['name'] as $key => $value) { if (str_contains($transliterator->transliterate($value), $transliterator->transliterate($searchTerm))) { $filteredData[$entityid] = $idpentry; @@ -100,7 +101,7 @@ foreach ($metadata as $entityid => $idpentry) { } } - if (!in_array($idpentry, $filteredData) && is_array($idpentry['description'])) { + if (!in_array($idpentry, $filteredData) && !empty($idpentry['description']) && is_array($idpentry['description'])) { foreach ($idpentry['description'] as $key => $value) { if (str_contains($transliterator->transliterate($value), $transliterator->transliterate($searchTerm))) { $filteredData[$entityid] = $idpentry; @@ -109,7 +110,7 @@ foreach ($metadata as $entityid => $idpentry) { } } - if (!in_array($idpentry, $filteredData) && is_array($idpentry['url'])) { + if (!in_array($idpentry, $filteredData) && !empty($idpentry['url']) && is_array($idpentry['url'])) { foreach ($idpentry['url'] as $key => $value) { if (str_contains(strtolower($value), strtolower($searchTerm))) { $filteredData[$entityid] = $idpentry; @@ -123,26 +124,12 @@ $data['items'] = []; foreach ($filteredData as $entityid => $idpentry) { $item['idpentityid'] = $entityid; - $item['text'] = $idpentry['name']; + $item['image'] = Campusidp::getMostSquareLikeImg($idpentry); - if (!empty($idpentry['UIInfo']['Logo'])) { - if (1 === count($idpentry['UIInfo']['Logo'])) { - $item['image'] = $idpentry['UIInfo']['Logo'][0]['url']; - } else { - $logoSizeRatio = 1; // impossible value - $candidateLogoUrl = null; - - foreach ($idpentry['UIInfo']['Logo'] as $logo) { - $ratio = abs($logo['height'] - $logo['width']) / ($logo['height'] + $logo['width']); - - if ($ratio < $logoSizeRatio) { // then we found more square-like logo - $logoSizeRatio = $ratio; - $candidateLogoUrl = $logo['url']; - } - } - - $item['image'] = $candidateLogoUrl; - } + if (!empty($idpentry['name'][$_GET['language']])) { + $item['text'] = $idpentry['name'][$_GET['language']]; + } else { + $item['text'] = $idpentry['name']['en']; } $data['items'][] = $item; diff --git a/www/resources/campus_idp.css b/www/resources/campus_idp.css index 50d6e4deae7d4d101ebbd514d274a7dc66b7595d..b29e5eb4e17040016b2a7fd1310473f533d8df0b 100644 --- a/www/resources/campus_idp.css +++ b/www/resources/campus_idp.css @@ -18,6 +18,10 @@ html, body { padding-right: 5%; } +.full-width { + width: 100%; +} + .input { width: 100%; } @@ -36,7 +40,7 @@ html, body { background-color: rgba(0, 0, 0, 0.05); } -.preferred-item-button { +.text-center { text-align: center; } @@ -52,6 +56,11 @@ html, body { width: 100%; } +.btn-more-options { + width: 160px; + margin-top: -24px; +} + .btn-individual-identity { width: 100%; text-align: left; @@ -136,6 +145,15 @@ html, body { margin-left: 25px; } +.margin-left-24 { + margin-left: 24px; +} + +.layout { + width: 100%; + text-align: center; +} + .local-password-btn-wrap { text-align: right; padding: 0; @@ -246,19 +264,27 @@ html, body { line-height: 3.3; display: block; position: absolute; - top: 0; - right: 0; + top: 0px; + right: 10px; padding-right: 11px; text-rendering: auto; font-variant: normal; font-style: normal; -webkit-font-smoothing: antialiased; + border-color: rgba(0, 0, 0, 0); } .input-height { line-height: 28px; } +.img-searchbox { + height: 50px; + width: 50px; + object-fit: cover; + object-position: left; +} + .preferred-idp { text-align: left; width: 100%; @@ -274,6 +300,10 @@ html, body { text-align: right; } +.footer { + padding: 0 18px 0 36px; +} + .footer-jvs { padding: 0 12px 0 6px; } @@ -331,7 +361,7 @@ html, body { width: 100%; } -#idps-form-div { +.idps-form-div { display: none; margin-top: 0; margin-bottom: 24px; @@ -343,10 +373,6 @@ html, body { margin-bottom: 24px; } -#q { - width: 100%; -} - #more-options { border-bottom: 1px solid #0000dc; margin-bottom: 24px; diff --git a/www/resources/searchbox.js b/www/resources/searchbox.js index 11918f8bfc2d38e3852a108aa1706f06c3997e54..178b8bc3668f97290c74264075512526a2bbb682 100644 --- a/www/resources/searchbox.js +++ b/www/resources/searchbox.js @@ -1,2 +1,9 @@ -document.getElementById('idps-form-nojs-div').style.display = 'none'; -document.getElementById('idps-form-div').style.display = 'block'; +var noJsElements =Array.from(document.getElementsByClassName('idps-form-nojs-div')); +for (let i = 0; i < noJsElements.length; i++) { + noJsElements[i].style.display = "none"; +} + +var jsElements =Array.from(document.getElementsByClassName('idps-form-div')); +for (let i = 0; i < jsElements.length; i++) { + jsElements[i].style.display = "block"; +} diff --git a/www/resources/selectize_conf.js b/www/resources/selectize_conf.js index d79abbe7b15af5d1e6359144e47dd528ffadfcb6..723ddeca4e93cc92feb155a3ccffd778e7280b71 100644 --- a/www/resources/selectize_conf.js +++ b/www/resources/selectize_conf.js @@ -1,88 +1,84 @@ $(function () { - $("#searchbox").selectize({ - valueField: "idpentityid", - labelField: "text", - options: [], - create: false, - loadThrottle: 250, - placeholder: placeholderText, - render: { - option: function (item) { - let text; + for (var i = 0; i < indexes.length; i++) { + $("#searchbox-" + indexes[i]).selectize({ + valueField: "idpentityid", + labelField: "text", + options: [], + create: false, + maxItems: 1, + myIndex: indexes[i], + loadThrottle: 250, + placeholder: placeholderTexts[i], + render: { + option: function (item, escape) { + item.text = escape(item.text); + item.image = escape(item.image); - if (typeof item.text[language] !== 'undefined') { - text = item.text[language]; - } else { - text = item.text['en']; - } - - if (framework === 'muni_jvs') { - return ( - '<div class="box-vcards-list__item box-vcard--compact searchbox-result side-padding-zero">' + + if (framework === 'muni_jvs') { + return ( + '<div class="box-vcards-list__item box-vcard--compact searchbox-result side-padding-zero">' + '<div class="box-vcards-list__inner side-padding-zero">' + - '<p class="box-vcards-list__img center">' + - '<img src="' + item.image + '" style="height: 50px; width: 50px; object-fit: cover; object-position: left" alt=""/>' + - '</p>' + - '<div class="box-vcards-list__content u-pb-0 u-pt-0 u-pr-0 u-pl-10">' + - text + - '</div>' + + '<p class="box-vcards-list__img center">' + + '<img src="' + item.image + '" class="img-searchbox" alt=""/>' + + '</p>' + + '<div class="box-vcards-list__content u-pb-0 u-pt-0 u-pr-0 u-pl-10">' + + item.text + + '</div>' + '</div>' + - '</div>' - ); - } else { - return ( - '<div class="list-group-item list-group-item-action d-flex align-items-center">' + - '<p style="margin-bottom: 0">' + - '<img src="' + item.image + '" style="height: 50px; width: 50px; object-fit: cover; object-position: left" alt=""/>' + + '</div>' + ); + } else { + return ( + '<div class="list-group-item list-group-item-action d-flex align-items-center">' + + '<p class="mb-0">' + + '<img src="' + item.image + '" class="img-searchbox" alt=""/>' + '</p>' + - '<div style="margin-left: 24px">' + - text + + '<div class="margin-left-24">' + + item.text + '</div>' + - '</div>' - ); - } + '</div>' + ); + } + }, }, - }, - onItemAdd: function (value, $item) { - let data = this.options[value]; + onChange: function (value) { + $(this['$input']).closest('form').trigger('submit'); + }, - $('#idpentityid-searchbox').val(data.idpentityid); - $('#institution-img').val(data.image); - $('#institution-name').val(JSON.stringify(data.text)); + score: function () { + return function () { + return 1; + }; + }, - $('#idps-form').submit(); - }, + load: function (query, callback) { + if (!query.length) { + return callback(); + } - score: function () { - return function () { - return 1; - }; - }, + this.clearCache('option'); + this.clearOptions(); + this.refreshOptions(true); - load: function (query, callback) { - if (!query.length) { - return callback(); - } - this.clearCache('option'); - this.clearOptions(); - this.refreshOptions(true); - $.ajax({ - url: "https://ip-147-251-124-162.flt.cloud.muni.cz/campus-idp/module.php/campusMultiauth/idpSearch.php", - type: "GET", - dataType: "json", - data: { - q: query, - index: componentIndex, - page_limit: 10, - }, - error: function () { - callback(); - }, - success: function (res) { - callback(res.items); - }, - }); - }, - }) + $.ajax({ + url: baseUrl + "module.php/campusMultiauth/idpSearch.php", + type: "GET", + dataType: "json", + data: { + q: query, + index: this.settings.myIndex, + language: language, + page_limit: 10, + }, + error: function () { + callback(); + }, + success: function (res) { + callback(res.items); + }, + }); + }, + }); + } }); diff --git a/www/selectsource.php b/www/selectsource.php index 3ff8c7b681cf2c54d805f163f3088fa7fa69b114..bfaeb1370761bc3a3c5772b2a9be7f34970615b6 100644 --- a/www/selectsource.php +++ b/www/selectsource.php @@ -4,6 +4,7 @@ use SimpleSAML\Auth\State; use SimpleSAML\Configuration; use SimpleSAML\Error\BadRequest; use SimpleSAML\Logger; +use SimpleSAML\Metadata\MetaDataStorageHandler; use SimpleSAML\Module; use SimpleSAML\Module\campusMultiauth\Auth\Source\Campusidp; use SimpleSAML\XHTML\Template; @@ -17,12 +18,16 @@ empty($_REQUEST['AuthState']) ? $authStateId = $_POST['authstate'] : $authStateI $state = State::loadState($authStateId, Campusidp::STAGEID_USERPASS); if (array_key_exists('source', $_POST)) { - if (array_key_exists('idpentityid-searchbox', $_POST)) { - $state['saml:idp'] = $_POST['idpentityid-searchbox']; + if (array_key_exists('searchbox', $_POST)) { + $state['saml:idp'] = $_POST['searchbox']; - Campusidp::setCookie(Campusidp::COOKIE_IDP_ENTITY_ID, $_POST['idpentityid-searchbox']); - Campusidp::setCookie(Campusidp::COOKIE_INSTITUTION_NAME, $_POST['institution-name']); - Campusidp::setCookie(Campusidp::COOKIE_INSTITUTION_IMG, $_POST['institution-img']); + $metadataStorageHandler = MetaDataStorageHandler::getMetadataHandler(); + $metadata = $metadataStorageHandler->getList(); + + Campusidp::setCookie(Campusidp::COOKIE_IDP_ENTITY_ID, $_POST['searchbox']); + Campusidp::setCookie(Campusidp::COOKIE_INSTITUTION_NAME, json_encode($metadata[$_POST['searchbox']]['name'])); + Campusidp::setCookie(Campusidp::COOKIE_INSTITUTION_IMG, Campusidp::getMostSquareLikeImg($metadata[$_POST['searchbox']])); + Campusidp::setCookie(Campusidp::COOKIE_COMPONENT_INDEX, $_POST['componentIndex']); Campusidp::delegateAuthentication($_POST['source'], $state); } elseif (array_key_exists('idpentityid', $_POST)) { @@ -62,7 +67,7 @@ $idps = null; if (!empty($_POST['q'])) { $ch = curl_init(); - curl_setopt($ch, CURLOPT_URL, Module::getModuleURL('campusMultiauth/idpSearch.php?q=' . $_POST['q'])); + curl_setopt($ch, CURLOPT_URL, Module::getModuleURL('campusMultiauth/idpSearch.php?q=' . $_POST['q'] . '&index=' . $_POST['componentIndex'] . '&language=' . $_POST['currentLanguage'])); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $idps = json_decode(curl_exec($ch)); @@ -77,9 +82,11 @@ $t->data['authstate'] = $authStateId; $t->data['currentUrl'] = htmlentities($_SERVER['PHP_SELF']); $t->data['wayf_config'] = $wayfConfig; $t->data['idps'] = $idps; +$t->data['no_js_display_index'] = $_POST['componentIndex']; $t->data['cookie_idpentityid'] = Campusidp::getCookie(Campusidp::COOKIE_IDP_ENTITY_ID); $t->data['cookie_institution_name'] = json_decode(Campusidp::getCookie(Campusidp::COOKIE_INSTITUTION_NAME), true); $t->data['cookie_institution_img'] = Campusidp::getCookie(Campusidp::COOKIE_INSTITUTION_IMG); +$t->data['cookie_component_index'] = Campusidp::getCookie(Campusidp::COOKIE_COMPONENT_INDEX); $t->data['cookie_username'] = Campusidp::getCookie(Campusidp::COOKIE_USERNAME); $t->data['cookie_password'] = Campusidp::getCookie(Campusidp::COOKIE_PASSWORD);