composer.lock already pins packages that need PHP >= 8.4.1 (symfony/* v8, nesbot/carbon 3, laravel/pint), so `composer install` on the 8.2 / 8.3 CI legs has been failing since v1.0.0. Bump composer.json to "php": "^8.4", regenerate the lock platform block, drop 8.2 / 8.3 from the ci.yml matrix, and update the "PHP 8.2+" references in the docs. The Docker image was already php:8.4-apache. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JKT9p3bfP8RZesExdYCS52
8.4 KiB
Changelog
All notable changes to ADconsole. Format follows Keep a Changelog.
Versioning (from v1.0.0 on) is semantic: MAJOR for
incompatible changes to configuration, the database schema or AD-permission
requirements; MINOR for backwards-compatible features; PATCH for
backwards-compatible fixes. Each release is a git tag vX.Y.Z; the latest tag on
main is the supported version. Upgrade notes live in
upgrading.md.
Unreleased
Nothing yet.
1.1.0 - 2026-09-10
Added
- Configuration backup.
/settings→ General tab can now export the whole panel configuration (general settings + attribute definitions) to a JSON file and import it back. Export can optionally leave out the attribute-encryption key. Both actions are recorded in the audit log (config.export,config.import). No Active Directory data is included. docker/compose.dev.yaml— a live-reload development stack that bind-mounts the working tree;docker/php/Dockerfileis now multi-stage withdev/prodtargets. Each stack has a no-Traefik override template.- Release image.
.github/workflows/release.ymlbuilds theprodimage on everyvX.Y.Ztag and pushes it to the Gitea container registry asgitea.kzbikowski.pl/kzbkowski/adconsole:{X.Y.Z, X.Y, latest}.docker/compose.yamlnow defaults to that image (ADCONSOLE_VERSIONpins a tag,ADCONSOLE_IMAGEreplaces the reference);docker compose … up -dpulls it,… --buildstill rebuilds locally.
Changed
-
Docker: the production image is now self-contained.
docker/compose.yamlbuildsdocker/php/Dockerfiletargetprod, whichCOPYs the app in and runscomposer install --no-devat build time — the working tree is no longer bind-mounted (only.env). Persistent state moved from Docker named volumes todocker/data/app_storageanddocker/data/dbbind mounts. Apache now honours Laravel'spublic/.htaccess(AllowOverride All).Run Compose from the repo root with
--env-file .env, e.g.docker compose --env-file .env -f docker/compose.yaml up -d.Upgrading an existing Docker deployment: copy the old named volumes into
docker/data/before the firstupwith the new file, e.g.docker run --rm -v adconsole_db_data:/from -v "$PWD/docker/data/db":/to alpine cp -a /from/. /to/(same foradconsole_app_storage→docker/data/app_storage). See upgrading.md. -
Minimum PHP is now 8.4 (
composer.json"php": "^8.4"). Thecomposer.lockalready pinned packages needing 8.4.1+ (symfony/*v8,nesbot/carbon3,laravel/pint), so 8.2 / 8.3composer installwas already failing.ci.ymltests 8.4 only now; the Docker image was alreadyphp:8.4-apache.
1.0.0 - 2026-09-08
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, achangesdiff and acontextblob. Newpanel_audittable, written only throughApp\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_DOMAINenvironment keys.- Docker: self-bootstrapping entrypoint (deps, key, migrate, cache),
docker/compose.override.yaml.templatefor running without Traefik, opcache in the image,.dockerignore. - Full
docs/set (installation, configuration, Active Directory, architecture, deployment, development, troubleshooting, upgrading, publishing), plusLICENSE,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. Bladeroute()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. managerattribute 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.jsoninto the database:- general settings (password policy & generator, reset-dialog defaults,
encryption key) →
panel_settingstable (App\Models\PanelSetting); - AD attribute / column definitions → dedicated
panel_attributestable 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-unusedattributes/domains/users_tablekeys from thepanel_settingsrow.PanelSettingsServiceis still the only entry point.
- general settings (password policy & generator, reset-dialog defaults,
encryption key) →
- Dashboard aggregation streams every account with
chunk()instead of onepaginate(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 aLDAP_TLS_VERIFYcert-check switch and tidied comments.- README rewritten;
.env.examplefully documented with production-safe defaults (APP_ENV=production,APP_DEBUG=false). composer.jsonpackage renamed toadconsole/adconsole; addedtest/lint/formatscripts.
Fixed
- Dashboard report links used a dead
scope=allparameter (the list readsall_ou), so drilling into a user from another OU found nothing.
[0.1.0] - internal
Initial internal release: users, computers, groups, read-only GPO, org chart,
dashboard, panel configuration, PL/EN UI, LDAP-group login. Never tagged or
published; superseded by 1.0.0.