Commit graph

14308 commits

Author SHA1 Message Date
Johannes Meyer
21ef5900ab modal.js: Do not wobble if ESC has been handled otherwise
Some checks failed
L10n Update / update (push) Has been cancelled
CI / PHP (push) Has been cancelled
2026-05-21 17:03:00 +02:00
jrauh01
40114d90e4
Fix navigation path in authentication configuration docs (#5508)
Some checks failed
L10n Update / update (push) Has been cancelled
CI / PHP (push) Has been cancelled
`"Authentication"` was renamed to `"Access Control Backends"` in the UI.
2026-05-20 09:03:27 +02:00
Eric Lippmann
0b266cd831
Modernize login (#5500)
This PR replaces the legacy Zend-based login form and authentication
controller with their ipl equivalents, and extracts the login page view
script markup into a reusable widget.

### Convert `LoginForm` to `CompatForm`
`LoginForm` now extends `CompatForm`, replacing
`init()`/`createElements()` with `__construct()`/`assemble()` and Zend
decorator arrays with inline ipl decorator objects. The
`CsrfCounterMeasure` and `FormUid` traits are added.

`getRedirectUrl()` is renamed to `createRedirectUrl()` to avoid
overriding `CompatForm::getRedirectUrl()`, using `hasBeenAssembled`
instead of `$this->created` and `str_contains()` instead of `strpos()`.
`onSuccess()` is rewritten for the CompatForm lifecycle: void return,
explicit `setRedirectUrl()` call, `Icinga::app()->getResponse()` instead
of `$this->getResponse()`, and `addMessage()` instead of `addError()`.

### New `LoginPage` widget to replace view script
Extracts the login page structure (logo, footer, social links,
decorative orbs) from `login.phtml` into a new `LoginPage` widget
extending `HtmlDocument`, so the markup is defined in one place and no
longer lives in a view script. Additional login buttons provided by
`LoginButtonHook` are now grouped in a `div.login-buttons` flex
container, rendered only when buttons are actually present.

### Convert `AuthenticationController` to `CompatController`
`AuthenticationController` now extends `CompatController`, dropping
`login.phtml` in favour of `LoginPage` and `addContent()`. The form is
built with an `ON_SUBMIT` handler for the redirect and an `ON_REQUEST`
handler delegating to `LoginForm::onRequest()`. Uses
`$this->getServerRequest()` instead of `ServerRequest::fromGlobals()`.

### CSS / JS fixes
- `login.less`: 
- `height: 100%` -> `100vh` on `#login` (now a grandchild of `#layout`
via `.content`)
- `.login-buttons` styled as a flex column with a row gap and top margin
  - per-`li` error styling, including spacing inside `.login-buttons`
  - `.icinga-form` width and control-group spacing
  - `align-items: center` on `.remember-me-box`
  - label `margin-right` reset for the disabled-state description
- `history.js`: `#layout > #login` -> `#layout #login` (direct-child
selector broke with the new nesting)
- `login-orbs.less`: fixes long-standing typo `#orb-notifactions` ->
`#orb-notifications`
2026-05-20 09:02:30 +02:00
Johannes Rauh
059073a5db Add rel="noopener noreferrer" to external links in LoginPage
Prevents the linked page from accessing `window.opener` and stops the
referring URL from being sent in the `Referer` header.
2026-05-18 12:14:13 +02:00
Johannes Rauh
8dff2712a1 Use Form::ON_SUBMIT instead of ON_SUCCESS for login buttons 2026-05-18 12:14:13 +02:00
Johannes Rauh
b6fd551413 Fix error message spacing inside login-buttons container
Ensure `.errors` inside `.login-buttons` has no extra padding and that
the last error item retains a bottom margin, matching the layout used
for the primary login form errors.
2026-05-18 12:14:13 +02:00
Johannes Rauh
77d4c618ab Fix login page CSS for ipl CompatForm rendering
Adjust login.less to match the HTML structure emitted by CompatForm:

- Add width: unset and margin on `.icinga-form` inside `.login-form` so the ipl
  form does not overflow its container and control groups have spacing
- Restyle `.errors` at the li level rather than the container level, giving each
  error message its own red box with margin between them
- Remove the padding from `.errors`/`.form-errors` that was set at the container
  level (now on each li)
- Change `.remember-me-box` align-items from `flex-start` to `center` so the
  toggle switch and label sit at the same baseline

Also fix a pre-existing typo in `login-orbs.less`: `#orb-notifactions` ->
`#orb-notifications`
2026-05-18 12:14:13 +02:00
Johannes Rauh
650ea2b597 Migrate AuthenticationController to CompatController
Convert `AuthenticationController` from the legacy Zend Controller to
`CompatController`, dropping `login.phtml` in favour of the new `LoginPage`
widget and `addContent()`. The view variable assignments are replaced by
`setTitle()` and `addContent(new LoginPage(...))`. Improve `httpBadRequest()`
message for external redirect attempts.

In `CompatController`, `$this->controls` is the tab bar area rendered
above the page content. When no tabs are added it still emits an empty
`<div class="controls">` wrapper. Setting `$this->view->compact = true`
suppresses that wrapper entirely, keeping the login page markup clean.

Handle the redirect on success in an `ON_SUBMIT` event handler. Delegate
the external-backend-only check to `LoginForm::onRequest()` via `ON_REQUEST`.
Use `$this->getServerRequest()` instead of `ServerRequest::fromGlobals()`.

Two structural fixes required by the changed DOM nesting:
- `login.less`: height `100%` -> `100vh` (`#login` is now inside `.content`
  which has no explicit height, so percentage inheritance breaks)
- `history.js`: `#layout > #login` -> `#layout #login` (direct-child selector
  breaks because `#login` is now a grandchild of `#layout` through `.content`)
2026-05-18 12:14:13 +02:00
Johannes Rauh
1dd503e9af Add LoginPage widget to centralize login page and modernize to ipl
Extract the login page structure (logo, footer, social links, decorative orbs)
from `login.phtml` into a reusable ipl-html widget. Extending `HtmlDocument`
rather than `BaseHtmlElement` lets it emit `#login` and the seven `.orb` sibling
divs without a wrapping root tag.

Both the login action and the upcoming 2FA challenge action can now share the
same visual scaffolding without duplicating markup and without using view
scripts anymore.
2026-05-18 12:14:13 +02:00
Johannes Rauh
fe282a304e Rewrite authentication login form to ipl CompatForm
Replace the legacy Zend-based `LoginForm` with an ipl `CompatForm`-based form:

- Add `CsrfCounterMeasure` and `FormUid` traits
- Replace `init()`/`createElements()` with `__construct()´/`assemble()` using
  inline ipl decorator objects instead of Zend decorator arrays
- Replace `getRedirectUrl()` with `createRedirectUrl()` because
  `getRedirectUrl()` would override `ipl\Html\Form::getRedirectUrl()`
    - use `hasBeenAssembled()` instead of `$this->created`
    - use `str_contains()` instead of `strpos()`
- Rewrite `onSuccess()` for `CompatForm`:
    - change visibility from `public` to `protected`
    - void return type
    - use `Icinga::app()->getResponse()` instead of `$this->getResponse()`
    - use `addMessage()` instead of `addError()`
    - call `setRedirectUrl()` explicitly
2026-05-18 12:14:07 +02:00
Johannes Meyer
845792b364 modal.js: Prevent unintentional closing
Some checks failed
L10n Update / update (push) Has been cancelled
CI / PHP (push) Has been cancelled
This tracks the user's interactions by observing the events
`keydown`, `paste` and `change` to detect changes to forms
inside a modal. Upon any change, the modal cannot be closed
anymore by pushing Escape or clicking outside the modal.
Instead, the modal will *wobble* for a short period.

resolves #5307
2026-05-12 15:56:57 +02:00
Johannes Meyer
ca4a561d63
Fix focus on login password (#5504)
Some checks failed
L10n Update / update (push) Has been cancelled
CI / PHP (push) Has been cancelled
The native attribute `autofocus` is nowadays the better alternative to
our legacy `.autofocus` implementation. Also this was seldomly used
elsewhere. Except in the director, which [handles it
manually](5fc103ffc3/public/js/module.js (L713))
anyway. It is now gone for good.

In case we ever need something similar, we should re-introduce it but
properly integrate it with the default focus handling. But now it's not
the time and no real need for this.

A small bonus of this change is that error messages are now copyable to
clipboard with a single click.

The related issue is fixed because our default focus preservation now
doesn't kick in because the login form uses the native attribute on the
username field.

fixes #5503
2026-05-11 14:25:23 +02:00
Johannes Meyer
688593311e history.js: Do not try to move errors to the right 2026-05-11 14:23:19 +02:00
Johannes Meyer
441d580f16 js: Do not force focus in forms that seem to apply it automatically
If a form uses the native autofocus, it seems it wants to guide
the user. So the first visit respects the autofocus, so the
element is either still focused upon submit or another one.
Either way, the default focus preservation ensures that whatever
is in focus will retain it if necessary and if not, the content
will probably fundamentally change and no force focus is required.
With the only remaining cases, login and setup, this is true.
Another upcoming case is the 2FA flow, where it is true as well.
2026-05-11 14:23:19 +02:00
Johannes Meyer
e8f8033d02 js: Drop autofocus behavior
It didn't work anyway and is now obsolete given that there's
a `autofocus` attribute widely supported by browsers. The catch
however is, that this only works upon page load. But all still
relevant cases where autofocus is suited are in fact page loads.

In case we ever need something similar, we should re-introduce
it but properly integrate it with the default focus handling.
But now it's not the time and no real need for this.
2026-05-11 14:23:19 +02:00
Johannes Meyer
876f065f31 form.js: Do not ignore autofocus elements
There are none anymore and the implementation is going
to be removed from the framework until we have a better
idea how or whether to still support autofocusing.
2026-05-11 14:23:19 +02:00
Johannes Meyer
132d19d98e FilterEditor: Don't replace autosubmit with autofocus
Didn't notice that was working as intended now, but it makes
zero sense anyway as both functions are distinct and either
cannot replace the other -.-
2026-05-11 14:23:19 +02:00
Johannes Meyer
ca1c5625e1 error.phtml: Allow to copy errors to clipboard
Hopefully users will now always include the first message
in reports and not only the stacktrace

Hopefully users will now always include the first message
in reports and not only the stacktrace……
2026-05-11 14:23:19 +02:00
Johannes Meyer
0488bebd8c ConfirmRemovalForm: Drop autofocus entirely
Besides that this is a destructive operation which shouldn't
get automatic focus… our native way to adhere to WCAG standards
is by focusing the newly rendered container which suffices.
2026-05-08 11:45:22 +02:00
Johannes Meyer
acc0259464 login/setup: Use native autofocus on form inputs 2026-05-08 11:45:22 +02:00
Sukhwinder Dhillon
6409782e02 menu.less: Apply same bg-color to the caret in the .nav-item-header
- Change the css specificity so it matches the existing level (hovered menu)
2026-05-05 13:39:50 +02:00
Johannes Meyer
c07389bfad
Remove .action-link and button-link css (#5370)
### Requires:

- https://github.com/Icinga/ipl-web/pull/284 (ipl-web v0.12.0)
2026-05-05 13:30:23 +02:00
Sukhwinder Dhillon
51aa75160f mixins.less: Remove user-select() mixin
This has been moved to ipl-web
2026-05-05 13:28:30 +02:00
Sukhwinder Dhillon
3187251306 Remove .action-link and button-link css
This has been moved to ipl-web
2026-05-05 13:28:30 +02:00
Johannes Meyer
0a639dbb0a StaticController: Allow to access a lib's js/css assets
Some checks failed
L10n Update / update (push) Has been cancelled
CI / PHP (push) Has been cancelled
2026-05-04 16:47:51 +02:00
Johannes Meyer
48f6617d34 JavaScript: Enhance dependency optimization 2026-05-04 16:17:20 +02:00
Johannes Meyer
570cc5f771 Revert "Provide Icinga to ipl/web behaviors (#5238)"
This reverts commit 1ee08d6180.
2026-04-30 13:18:02 +02:00
Eric Lippmann
229ff3b057
Migrate Less compilation to ipl\Web\Less (#5492)
Because the in-tree Less visitor requires `wikimedia/less.php`, that
dependency has to live in `icinga-php-thirdparty`. `icinga-php-library`
already carries Less-related code with the same dependency, so this PR
consolidates everything into `icinga-php-library` and removes the
duplicate in-tree implementation.

- Remove the in-tree `Icinga\Less\` visitor layer in favor of the shared
`ipl\Web\Less` library, which maintains modernized equivalent CSS var
replacement and light-mode functionality.

- Strip unused variable-export support from `LessCompiler`. The feature
was never used by any our modules or community modules.

- Update `LessCompiler` to delegate to `ipl\Web\Less`, assembling
sources via `@import (less)` directives; pass the `$minify` flag
directly to `render()` instead of via a separate `compress()` call.

- Modernize `LessCompiler` with PHP type declarations, short array
syntax, and tightened PHPDoc.

Here is the test summary:

The stylesheets are nearly identical. Most changes are normalization
noise introduced by the new version of the wikimedia Less parser:

- Decimal canonicalization: `.5` → `0.5`, `2.0em` → `2em`
- Hex color shortening: `#dddddd` → `#ddd`
- Hex color case kept as is: `#535353` → `#535353`, `#c4c4c4` → `#c4c4c4`
- `calc()` math preserved: `calc(14.28571429%)` → `calc(100% / 7)`

Starting with Less.php 5.0, arithmetic is no longer evaluated inside
`calc()`. This required changing one occurrence in our Less files
directly; no other changes were necessary, and no known publicly
available Icinga Web module is affected by similar changes in this
regard.

There is one functional difference: the light-mode background color
gains an extra level of indirection via a new CSS var call (because it
uses `@light-body-bg-color`):

```diff
-  --body-bg-color: #f5f9fa;
+  --body-bg-color: var(--light-body-bg-color, #f5f9fa);
```

The new CSS var replacement visitor from `ipl\Web` runs independently
from the light mode call visitor, and therefore also adds var overrides
to such detached rulesets. Everything else is normalization noise.
2026-04-30 10:58:47 +02:00
Eric Lippmann
a268c46602 Unify file validation in LessCompiler via resolveReadableFile()
Previously, `addLessFile` and `addModuleLessFile` called `realpath()` but
skipped the readability check, silently appending `false` when a path did
not resolve. `setTheme` and `setThemeMode` checked readability but stored
the unresolved path and swallowed errors via `Logger::error`.

`resolveReadableFile()` centralizes both steps: it calls `realpath()` and
verifies the result is a readable file, throwing a `RuntimeException` on
failure so no invalid path can be registered silently.
2026-04-27 16:44:51 +02:00
Sukhwinder Dhillon
4246e4e546 configmenu.less: Fix invalid calc() param
Starting with Less.php version 5.0, arithmetic is no longer evaluated
inside `calc()` the way this code relied on[^1]. Compute the division in
a Less variable first, then use that value in `calc()` and drop the
unnecessary escaping.

[^1]: https://gerrit.wikimedia.org/r/c/mediawiki/libs/less.php/+/1049149
2026-04-27 16:24:51 +02:00
Eric Lippmann
bbaa812835 Modernize LessCompiler with typed properties and method signatures
Add missing PHP type declarations to properties and methods, replace long-form
`array()` syntax with short `[]` syntax, tighten PHPDoc comments, and correct
"LESS" to "Less".
2026-04-27 16:24:51 +02:00
Eric Lippmann
80308bbd75 Migrate Less compilation to ipl\Web\Less
Replace the in-tree `Icinga\Less\` visitor layer with its equivalents
from `ipl\Web\Less`, where the same color-variable and light-mode
functionality is maintained as a shared library.

`LessCompiler` is updated to delegate to `WikimediaLessCompiler`,
assembling source via `@import (less)` directives and accepting a
`$minify` flag directly on `render()` rather than through a separate
`compress()` call.
2026-04-27 16:24:51 +02:00
Eric Lippmann
7ef376df0f Revert "LessCompiler: Add support for variable exports by modules"
This reverts commit 7c58b3ced1.

Remove variable exports as they were never used in our modules or community
modules, and using this feature is discouraged.
2026-04-27 16:24:51 +02:00
Eric Lippmann
a1c67a3913 Evaluate the light mode rules immediately
This is a preparation for using the new Less utils from `ipl\Web` to simplify
the comparison of the old and new stylesheets.
2026-04-27 16:24:51 +02:00
Sukhwinder Dhillon
821f6a4775 doc: Remove monitoring module references
Some checks failed
L10n Update / update (push) Has been cancelled
CI / PHP (push) Has been cancelled
The `monitoring` module was removed in v2.13.0 and its references
remained in the docs. Remove these references and replace them with
`icingadb` where appropriate.
2026-04-24 10:00:09 +02:00
Johannes Meyer
49ed0ac0ac
Move relative time js behavior to ipl-web (#5461)
Some checks failed
L10n Update / update (push) Has been cancelled
CI / PHP (push) Has been cancelled
This PR removes the Javascript function that updates relative times.

refs: https://github.com/Icinga/ipl-web/issues/341

Depends on:
- https://github.com/Icinga/ipl-web/pull/350
(ipl-web handles the time refreshing via javascript now)
2026-04-21 15:52:58 +02:00
Johannes Meyer
d75a83e013 doc: Mention relative time changes in the upgrading section 2026-04-21 10:01:39 +02:00
Johannes Meyer
6cab713031 helpers/format.php: Let time helpers return updated markup
This still doesn't cover other implementations generating
the markup on their own but still using the CSS classes,
but it's a start.
2026-04-21 10:00:20 +02:00
Johannes Meyer
cd426e88f7 ui.js: Remove remaining time counter references 2026-04-21 10:00:00 +02:00
Johannes Meyer
b7e01023ab Update required icinga-php-library version 2026-04-17 15:40:21 +02:00
Jan Schuppik
1df38fd3e3 Revert: creation of the relative-time-behavior
Revert "Fix: add stop method"

This reverts commit 7605c655fd.

Revert "Adjust onRendered method"

This reverts commit ab868e15f8.

Revert "Adjust: html-attribute 'datetime' as update source"

This reverts commit 8bf1b1746d.

Revert "Init: js relative-time behavior"

This reverts commit f17bf24def.
2026-04-17 15:36:36 +02:00
Jan Schuppik
09a004fec1 Fix: add stop method 2026-04-17 15:36:36 +02:00
Jan Schuppik
78f6f5715a Adjust onRendered method 2026-04-17 15:36:36 +02:00
Jan Schuppik
589ee57e32 Remove previous code 2026-04-17 15:36:36 +02:00
Jan Schuppik
d6994dbb58 Adjust: html-attribute 'datetime' as update source 2026-04-17 15:36:36 +02:00
Jan Schuppik
136b5853ab Init: js relative-time behavior 2026-04-17 15:36:36 +02:00
Sukhwinder Dhillon
1ee08d6180
Provide Icinga to ipl/web behaviors (#5238)
Some checks are pending
L10n Update / update (push) Waiting to run
CI / PHP (push) Waiting to run
2026-04-17 15:35:31 +02:00
Johannes Meyer
1d6fa0aabd doc: Mention monitoring removal in upgrading section
Some checks failed
L10n Update / update (push) Has been cancelled
CI / PHP (push) Has been cancelled
2026-04-02 14:41:02 +02:00
Eric Lippmann
67b6c01978
Release version 2.13.0 (#5485)
Some checks failed
L10n Update / update (push) Has been cancelled
CI / PHP (push) Has been cancelled
2026-03-27 01:29:40 +01:00
Eric Lippmann
36fa5377e7 Remove badges from README 2026-03-26 21:31:28 +01:00