• v1.0.0 1126d96271

    ADconsole v1.0.0
    CI / PHP 8.2 (push) Failing after 2m46s
    CI / PHP 8.3 (push) Failing after 59s
    CI / PHP 8.4 (push) Failing after 1m7s
    Stable

    kzbkowski released this 2026-09-08 23:14:56 +02:00 | 3 commits to main since this release

    First public release. Consolidates the prior internal builds (0.1.0) into a
    tagged, documented release published at
    https://gitea.kzbikowski.pl/kzbkowski/ADconsle.

    Added

    • Audit log (/audit, AuditController): read-only, filterable record of
      every change the panel makes to AD — actor, action slug, target, optional
      reason, a changes diff and a context blob. New panel_audit table, written
      only through App\Services\AuditLogger (best-effort; a log failure never
      aborts the AD operation). Viewing a LAPS / BitLocker secret is audited too.
    • User offboarding (/users/{sam}/offboard + /users/bulk/offboard):
      one action that disables the account and randomises its password, strips group
      memberships (optionally keeping the primary group), moves the object to a
      chosen OU and sets an expiry date + description note — run in a safe order
      (attribute changes → group removal → OU move last, since the move changes the
      DN).
    • Settings → Audit log: a "require a reason for destructive actions"
      switch (panel_settings → audit.require_reason) that makes the reason field
      mandatory for disable / delete / move / offboard.
    • Users: CSV export of the current (filtered) list — GET /users/export,
      streamed, UTF-8 with a BOM for Excel, one column per configured attribute.
    • Dashboard: tiles are now links to the matching filtered user list;
      problem tiles (locked / expired password / expired account) are highlighted
      when non-zero; relative "recalculated N ago" indicator that turns amber when
      the cache is stale; global empty state when AD returns nothing; password-age
      histogram (<30 / 30–60 / 60–90 / >90 days).
    • Users: filter= query parameter for the dashboard drill-downs
      (locked, pwd_never, pwd_expiring, pwd_expired, inactive,
      account_expired) with a clearable filter chip.
    • Collapsible OU-tree sidebar (narrow rail with hover-to-expand, or pinned),
      remembered per browser.
    • LDAP_SSL, LDAP_TLS_VERIFY, APP_DOMAIN environment keys.
    • Docker: self-bootstrapping entrypoint (deps, key, migrate, cache),
      docker/compose.override.yaml.template for running without Traefik, opcache
      in the image, .dockerignore.
    • Full docs/ set (installation, configuration, Active Directory, architecture,
      deployment, development, troubleshooting, upgrading, publishing), plus
      LICENSE, CONTRIBUTING.md, CODE_OF_CONDUCT.md, SECURITY.md, GitHub
      issue/PR templates, a CI workflow (Pint + PHPUnit on PHP 8.2–8.4), and this
      changelog.

    Changed

    • URL segments are now English (route names were already): /dashboard,
      /users, /computers, /groups, /organisation, /gpo, /settings,
      /login, /logout, /language/{locale}, /about; sub-paths too
      (/users/search, /users/bulk/…, /users/{sam}/reset-password,
      /computers/{cn}/reset-trust, /groups/{cn}/members, /settings/attributes,
      …). Bookmarks to the old Polish paths (/pulpit, /uzytkownicy, …) now 404.
      Blade route() calls were unaffected; hardcoded fetch/url() paths in the
      module JS (/users/{sam}/template, .../photo, .../groups,
      /groups/{cn}/members, single-action templates in the bulk modals) and the
      settings-page tab anchors (#attributes) were updated to match.
    • manager attribute relabelled to Kierownik; in the user edit dialog it
      is now a name search only — the raw DN field is hidden (still submitted), with
      a clear button to unset the manager.
    • Panel configuration moved out of storage/app/panel_settings.json into the
      database:
      • general settings (password policy & generator, reset-dialog defaults,
        encryption key) → panel_settings table (App\Models\PanelSetting);
      • AD attribute / column definitions → dedicated panel_attributes table with
        real columns (key, label, ldap, category, type, is_column,
        position) and one row per attribute (App\Models\PanelAttribute).
        Two automatic migrations: the first imports the legacy JSON file (renaming it
        *.migrated), the second moves the attribute list into its own table and
        drops the now-unused attributes / domains / users_table keys from the
        panel_settings row. PanelSettingsService is still the only entry point.
    • Dashboard aggregation streams every account with chunk() instead of one
      paginate(500) page — lower memory, and unambiguously counts the whole
      domain.
    • Search inputs, the "search" buttons and the account-status filter restyled as
      borderless / outline controls; the navbar search matches. Removed the static
      "Domain: …" label from the navbar.
    • config/ldap.php: LDAP_SSL (LDAPS) / LDAP_TLS (STARTTLS) now map to the
      correct LdapRecord v4 options, plus a LDAP_TLS_VERIFY cert-check switch and
      tidied comments.
    • README rewritten; .env.example fully documented with production-safe
      defaults (APP_ENV=production, APP_DEBUG=false).
    • composer.json package renamed to adconsole/adconsole; added test /
      lint / format scripts.

    Fixed

    • Dashboard report links used a dead scope=all parameter (the list reads
      all_ou), so drilling into a user from another OU found nothing.
    Downloads