diff --git a/lam/lib/2factor.inc b/lam/lib/2factor.inc index 9967ceb09..3918ada22 100644 --- a/lam/lib/2factor.inc +++ b/lam/lib/2factor.inc @@ -14,6 +14,7 @@ use Facile\OpenIDClient\Issuer\IssuerBuilder; use GuzzleHttp\Psr7\ServerRequest; use htmlResponsiveRow; use LAM\LOGIN\WEBAUTHN\WebauthnManager; +use LAM_INTERFACE; use SelfServiceLoginHandler; use selfServiceProfile; use LAMConfig; @@ -461,7 +462,7 @@ class DuoProvider extends BaseProvider { * @see BaseProvider::addCustomInput */ public function addCustomInput(&$row, $userDn) { - $pathPrefix = $this->config->isSelfService ? '../' : ''; + $pathPrefix = ($this->config->interface === LAM_INTERFACE::SELF_SERVICE) ? '../' : ''; $row->add(new htmlImage($pathPrefix . '../graphics/duo.png')); if (!empty($_GET['duo_code'])) { // authentication is verified @@ -612,7 +613,7 @@ class OktaProvider extends BaseProvider { return; } - $pathPrefix = $this->config->isSelfService ? '../' : ''; + $pathPrefix = ($this->config->interface === LAM_INTERFACE::SELF_SERVICE) ? '../' : ''; $row->add(new htmlImage($pathPrefix . '../graphics/okta.png')); $_SESSION['okta_state'] = bin2hex(random_bytes(10)); $_SESSION['okta_code_verifier'] = bin2hex(random_bytes(50)); @@ -797,7 +798,7 @@ class OpenIdProvider extends BaseProvider { return; } $content = new htmlResponsiveRow(); - $pathPrefix = $this->config->isSelfService ? '../' : ''; + $pathPrefix = ($this->config->interface === LAM_INTERFACE::SELF_SERVICE) ? '../' : ''; $row->add(new htmlImage($pathPrefix . '../graphics/openid.png')); include_once __DIR__ . '/3rdParty/composer/autoload.php'; try { @@ -976,8 +977,8 @@ class WebauthnProvider extends BaseProvider { $row->add(new htmlStatusMessage('INFO', _('Please register a security device.'))); } $row->addVerticalSpacer('2rem'); - $pathPrefix = $this->config->isSelfService ? '../' : ''; - $selfServiceParam = $this->config->isSelfService ? 'true' : 'false'; + $pathPrefix = ($this->config->interface === LAM_INTERFACE::SELF_SERVICE) ? '../' : ''; + $selfServiceParam = ($this->config->interface === LAM_INTERFACE::SELF_SERVICE) ? 'selfservice=true' : ''; $row->add(new htmlImage($pathPrefix . '../graphics/webauthn.svg', '50%')); $row->addVerticalSpacer('1rem'); $errorMessage = new htmlStatusMessage('ERROR', '', _('This service requires a browser with "WebAuthn" support.')); @@ -995,7 +996,7 @@ class WebauthnProvider extends BaseProvider { $errorMessageDiv->addDataAttribute('button', _('Ok')); $errorMessageDiv->addDataAttribute('title', _('WebAuthn failed')); $row->add($errorMessageDiv); - $row->add(new htmlJavaScript('window.lam.webauthn.start(\'' . $pathPrefix . '\', ' . $selfServiceParam . ',' . + $row->add(new htmlJavaScript('window.lam.webauthn.start(\'' . $pathPrefix . '\', \'' . $selfServiceParam . '\',' . ' \'' . _('Do you want to set a name for this device?') . '\', \'' . _('Name') . '\',' . ' \'' . _('Ok') . '\', \'' . _('Cancel') . '\');'), 0); } @@ -1244,7 +1245,7 @@ class TwoFactorProviderService { */ private function getConfigSelfService(&$profile): TwoFactorConfiguration { $tfConfig = new TwoFactorConfiguration(); - $tfConfig->isSelfService = true; + $tfConfig->interface = LAM_INTERFACE::SELF_SERVICE; $tfConfig->twoFactorAuthentication = $profile->twoFactorAuthentication; $tfConfig->twoFactorAuthenticationInsecure = $profile->twoFactorAuthenticationInsecure; $tfConfig->twoFactorAuthenticationOptional = $profile->twoFactorAuthenticationOptional; @@ -1294,7 +1295,7 @@ class TwoFactorProviderService { */ private function getConfigAdmin($conf): TwoFactorConfiguration { $tfConfig = new TwoFactorConfiguration(); - $tfConfig->isSelfService = false; + $tfConfig->interface = LAM_INTERFACE::ADMIN; $tfConfig->twoFactorAuthentication = $conf->getTwoFactorAuthentication(); $tfConfig->twoFactorAuthenticationInsecure = $conf->getTwoFactorAuthenticationInsecure(); $tfConfig->twoFactorAuthenticationOptional = $conf->getTwoFactorAuthenticationOptional(); @@ -1340,10 +1341,8 @@ class TwoFactorProviderService { */ class TwoFactorConfiguration { - /** - * @var bool is self service - */ - public bool $isSelfService = false; + /** LAM UI */ + public LAM_INTERFACE $interface = LAM_INTERFACE::ADMIN; /** * @var ?string provider id diff --git a/lam/lib/config.inc b/lam/lib/config.inc index 1edd7a6f0..60eba5621 100644 --- a/lam/lib/config.inc +++ b/lam/lib/config.inc @@ -39,6 +39,18 @@ use function LAM\TYPES\getScopeFromTypeId; * @author Thomas Manninger */ +/** + * Defines the possible LAM user interfaces. + */ +enum LAM_INTERFACE { + /** admin pages to manage any type aof entry */ + case ADMIN; + /** user self-service to manage own data */ + case SELF_SERVICE; + /** white-pages to display users */ + case WHITE_PAGES; +} + /** persistence */ include_once __DIR__ . '/persistence.inc'; /** Used to print messages. */ diff --git a/lam/lib/import.inc b/lam/lib/import.inc index 6e280fcbb..db4ffdcea 100644 --- a/lam/lib/import.inc +++ b/lam/lib/import.inc @@ -444,7 +444,7 @@ class AddEntryTask implements ImporterTask { * Constructor * * @param string $dn DN - * @param array[string[]] $attributes list of attributes + * @param array $attributes list of attributes */ public function __construct($dn, $attributes) { $this->dn = $dn; @@ -601,7 +601,7 @@ class AddAttributesTask implements ImporterTask { * Constructor * * @param string $dn DN - * @param array[string[]] $attributes list of attributes + * @param array $attributes list of attributes */ public function __construct($dn, $attributes) { $this->dn = $dn; @@ -657,7 +657,7 @@ class DeleteAttributesTask implements ImporterTask { * * @param string $dn DN * @param string $attributeName attribute name - * @param array[string[]] $attributes list of attributes + * @param array $attributes list of attributes */ public function __construct($dn, $attributeName, $attributes) { $this->dn = $dn; @@ -726,7 +726,7 @@ class ReplaceAttributesTask implements ImporterTask { * Constructor * * @param string $dn DN - * @param array[string[]] $attributes list of attributes + * @param array $attributes list of attributes */ public function __construct($dn, $attributes) { $this->dn = $dn; diff --git a/lam/style/100_lam-responsive.css b/lam/style/100_lam-responsive.css index 15eca8d72..4d77c146e 100644 --- a/lam/style/100_lam-responsive.css +++ b/lam/style/100_lam-responsive.css @@ -1,7 +1,7 @@ /* This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/) - Copyright (C) 2017 - 2019 Roland Gruber + Copyright (C) 2017 - 2025 Roland Gruber This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/lam/style/500_layout.css b/lam/style/500_layout.css index 46b9a9d18..4a8424b4e 100644 --- a/lam/style/500_layout.css +++ b/lam/style/500_layout.css @@ -489,6 +489,10 @@ table.collapse { white-space: nowrap; } +hr { + border: 1px solid var(--lam-border-color); +} + hr.dotted { border-bottom: 1px dotted var(--lam-text-color-default); border-top: none; @@ -534,7 +538,7 @@ td.loginRightBox { } .roundedShadowBox { - border: 2px solid #a0a0a4; + border: 2px solid #ffffff; border-radius: 5px; box-shadow: 2px 2px 5px #a0a0a4; display: inline-block; @@ -566,7 +570,7 @@ a.lamLogo span { } .lam-header { - box-shadow: 0px 3px 2px -2px grey; + box-shadow: 0px 3px 2px -2px #b9b9b9; } .module-list { @@ -1151,7 +1155,7 @@ div.tippy-box { color: var(--lam-text-color-default); background: var(--lam-background-color-default); font-size: 85%; - border: 2px solid #a0a0a4; + border: 2px solid #ffffff; border-radius: var(--lam-default-border-radius); box-shadow: 0px 0px 5px #666666; padding: 0 var(--lam-regular-space) var(--lam-regular-space) var(--lam-regular-space); diff --git a/lam/templates/lib/500_lam.js b/lam/templates/lib/500_lam.js index 5aeb0048d..5afe88fbb 100644 --- a/lam/templates/lib/500_lam.js +++ b/lam/templates/lib/500_lam.js @@ -1863,15 +1863,15 @@ window.lam.webauthn.charAt = function (c) { * Starts the webauthn process. * * @param prefix path prefix for Ajax endpoint - * @param isSelfService runs as part of self service + * @param extraParam additional parameter for request (e.g. "selfservice=true") * @param newDeviceNameTitle title for new device name dialog * @param newDeviceNameLabel label for new device name * @param okText text for Ok button * @param cancelText text for cancelButton */ -window.lam.webauthn.start = function(prefix, isSelfService, newDeviceNameTitle, newDeviceNameLabel, okText, cancelText) { +window.lam.webauthn.start = function(prefix, extraParam, newDeviceNameTitle, newDeviceNameLabel, okText, cancelText) { document.addEventListener("DOMContentLoaded", function(){ - window.lam.webauthn.run(prefix, isSelfService, newDeviceNameTitle, newDeviceNameLabel, okText, cancelText); + window.lam.webauthn.run(prefix, extraParam, newDeviceNameTitle, newDeviceNameLabel, okText, cancelText); }); } @@ -1879,13 +1879,13 @@ window.lam.webauthn.start = function(prefix, isSelfService, newDeviceNameTitle, * Checks if the user is registered and starts login/registration. * * @param prefix path prefix for Ajax endpoint - * @param isSelfService runs as part of self-service + * @param extraParam additional parameter for request (e.g. "selfservice=true") * @param newDeviceNameTitle title for new device name dialog * @param newDeviceNameLabel label for new device name * @param okText text for Ok button * @param cancelText text for cancelButton */ -window.lam.webauthn.run = function(prefix, isSelfService, newDeviceNameTitle, newDeviceNameLabel, okText, cancelText) { +window.lam.webauthn.run = function(prefix, extraParam, newDeviceNameTitle, newDeviceNameLabel, okText, cancelText) { const skipButton = document.getElementById('btn_skip_webauthn'); if (skipButton) { skipButton.onclick = function () { @@ -1908,7 +1908,7 @@ window.lam.webauthn.run = function(prefix, isSelfService, newDeviceNameTitle, ne let data = new FormData(); data.append('sec_token', token); data.append('action', 'status'); - var extraParam = isSelfService ? '&selfservice=true' : ''; + extraParam = (extraParam) ? '&' + extraParam : ''; fetch(prefix + 'misc/ajax.php?function=webauthn' + extraParam, { method: 'POST', body: data diff --git a/phpstan.neon b/phpstan.neon index 5b1fcb6d8..b920f9bfe 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -44,7 +44,6 @@ parameters: - lam/lib/plugins/extendedInvalidCredentials/MitKerberosExtraInvalidCredentialsProvider.inc (?) ignoreErrors: - '#Variable \$helpArray might not be defined.#' - - '#Offset .SID. on array.*in isset\(\) always exists.*#' - '#Offset .preferred_username. does not exist on.*#' - '#Strict comparison using !== between non-empty-list.*will always evaluate to true.*#' - '#Strict comparison using !== between non-empty-array.*will always evaluate to true.*#'