Split Admin module into Status and User Management under one sidemenu dropdown
Playwright Tests / test (push) Canceled after 0s
Playwright Tests / test (push) Canceled after 0s
Splits fn=admin into two independent modules: the original status dashboard stays at fn=admin, user management moves to a new fn=usr (IntranetController.AdminUsers.cs, fis.usr.js). Both are now reached through a single "Administration" sidemenu dropdown (Systemüberwachung / Benutzerverwaltung) gated by one shared fds_sys > 4 check, per ADR 0015 (supersedes 0014's "fold into one module" choice). Also fixes the password-reset validation to check only a plain 6-char minimum instead of silently also requiring ValidatePassword's default 2-uppercase/2-lowercase/2-digit composition, which contradicted the "mind. 6 Zeichen" message shown to the admin. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -9,11 +9,9 @@ applyTo:
|
||||
- "Fuchs/js/intranet/modules/fis.admin*.js"
|
||||
- "Fuchs/js/intranet/modules/fis.admin.scss"
|
||||
- "Fuchs/js/intranet/fis_main_menu.js"
|
||||
- "Fuchs_Database/dbo/Functions/fis_admin_*.sql"
|
||||
- "Fuchs_Database/dbo/Stored Procedures/fis_admin_*.sql"
|
||||
relatedDecisions:
|
||||
- "0011-admin-module-system-status.md"
|
||||
- "0014-admin-user-management.md"
|
||||
- "0015-split-admin-user-management-module.md"
|
||||
---
|
||||
|
||||
# Admin / System-Status module
|
||||
@@ -28,10 +26,13 @@ Access is restricted to users whose `fds_sys` module authorization is greater th
|
||||
## How it works
|
||||
|
||||
### Authorization (two layers)
|
||||
1. **Menu visibility** — at page load `fis_main_menu.js#addAdminMenuIfAuthorized` calls
|
||||
`$fis.getAuth('fds_sys')`; only when the level is > 4 does it push the `init:admin`
|
||||
button into `$ocms.ocmsmenu` and re-render `#mainmenu`. Users below the threshold never
|
||||
see the button and never fetch the module script.
|
||||
1. **Menu visibility** — at page load `fis_main_menu.js#addAdminMenuButtonsIfAuthorized` calls
|
||||
`$fis.getAuth('fds_sys')` once (shared with the separate `usr` user-management module, see
|
||||
[0015](../Decisions/0015-split-admin-user-management-module.md)); only when the level is > 4
|
||||
does it push a single "Administration" dropdown entry into `$ocms.ocmsmenu` — containing this
|
||||
module's "Systemüberwachung" (`init:admin`) item alongside `usr`'s "Benutzerverwaltung"
|
||||
(`init:usr`) item — and re-render `#mainmenu`. Users below the threshold never see the
|
||||
dropdown and never fetch either module's script.
|
||||
2. **Server-side gate** — every `/do/admin/*` endpoint resolves
|
||||
`fis_getModuleAuth('fds_sys', authuser)` and returns 401 unless it is > 4. The only
|
||||
exception is `admin/auth`, which returns `{ manage: 0 }` for unauthorized users so the
|
||||
@@ -87,46 +88,18 @@ refresh button, the email card carries the test-email dialog. The topbar has an
|
||||
button that reloads the whole snapshot. Admin responses are serialized **camelCase** (the DTOs are
|
||||
PascalCase) so the JS reads `probe.status`, `info.database.server`, etc.
|
||||
|
||||
## User management (`users`/`userpwdreset`/`useremail`/`usergroups`/`usergroupset`)
|
||||
See [0014](../Decisions/0014-admin-user-management.md) for why this lives here and for the
|
||||
dual-authorization caveat (`fds_sys > 4` gates the endpoints; the SQL layer separately requires
|
||||
the caller's `intranet_admin` setting to be `> 1`).
|
||||
|
||||
A card below the status grid (`$adm.usersCard`) renders a table of every non-deleted user
|
||||
account (name, email, active/disabled) via `POST admin/users` →
|
||||
`fis_admin_getUserAccountList(@authaccount, NULL, NULL, NULL)`. Clicking a row toggles a
|
||||
per-row ribbon (`$adm.uMn`, replacing the topbar exactly like Banking's `iMn`/`eM` swap) with
|
||||
three actions:
|
||||
|
||||
- **Passwort zurücksetzen** — a dialog with one optional password field ("leave blank to
|
||||
auto-generate"). `POST admin/userpwdreset` calls `fis_admin_resetUserPassword` (now takes an
|
||||
optional `@newpassword`; `NULL` ⇒ the proc auto-generates one as before). On success the
|
||||
controller re-fetches the target's row (server-trusted email — never client-supplied) and
|
||||
emails the plaintext password via `IComService.SendEmailAsync` — the admin never sees it. The
|
||||
email subject/body is built by `IntranetController.BuildPasswordResetEmail` (pure, unit-tested
|
||||
in `Fuchs.Tests/AdminUserManagementTests.cs`). Failure to reset, or to deliver the email, calls
|
||||
`IEventService.UserIssueAsync` so the admin gets a visible notification either way.
|
||||
- **E-Mail ändern** — a dialog with the email field prefilled. `POST admin/useremail` fetches
|
||||
the current row and calls `fis_admin_setUserAccount` with only the email changed (other fields
|
||||
passed through unchanged, `@password = NULL` so the update path leaves the password alone). A
|
||||
duplicate email (`THROW 60001` in the proc) surfaces as an HTTP 409 `{ error: "duplicate_email" }`.
|
||||
- **Gruppenzugehörigkeit** — a dialog (`$adm.groupsDlg`) listing every group as a checkbox,
|
||||
populated via `POST admin/usergroups` → the new `fis_admin_getUserGroupMembership` function.
|
||||
Each checkbox toggle immediately posts `admin/usergroupset`, which calls
|
||||
`fis_admin_addGroupMember`/`remGroupMember` depending on the new state — no separate save step.
|
||||
|
||||
## Key files
|
||||
- `Fuchs/Controllers/IntranetController.Admin.cs` — `Do_Process_Admin` dispatch + auth gate + camelCase JSON helper + user-management endpoints.
|
||||
- `Fuchs/Controllers/IntranetController.Admin.cs` — `Do_Process_Admin` dispatch + shared auth gate/camelCase JSON helper (also used by the separate `usr` module, see [0015](../Decisions/0015-split-admin-user-management-module.md)).
|
||||
- `Fuchs/Services/ISystemStatusService.cs`, `SystemStatusService.cs`, `SystemStatusModels.cs` — diagnostics service + DTOs.
|
||||
- `Fuchs/Services/StartupCheckReport.cs` (`StartupCheckReporter` singleton) + `StartupSelfTestService.cs` — boot self-test result captured for the non-refreshable widget.
|
||||
- `Fuchs/Services/IBlobStorageService.cs` / `AzureBlobStorageService.cs` — `CheckConnectivityAsync` + `BlobConnectivity`.
|
||||
- `Fuchs/js/intranet/modules/fis.admin*.js`, `fis.admin.scss` — the module, texts, styles (bundled via `bdlconfig.json`).
|
||||
- `Fuchs/js/intranet/fis_main_menu.js` (`addAdminMenuIfAuthorized`) + `fis_main_go.js` — conditional menu button.
|
||||
- `Fuchs_Database/dbo/Functions/fis_admin_getUserAccountList.sql`, `fis_admin_getUserGroupList.sql`, `fis_admin_getUserGroupMembership.sql` — read-side user/group queries.
|
||||
- `Fuchs_Database/dbo/Stored Procedures/fis_admin_resetUserPassword.sql`, `fis_admin_setUserAccount.sql`, `fis_admin_addGroupMember.sql`, `fis_admin_remGroupMember.sql` — write-side user/group procs.
|
||||
- `Fuchs/js/intranet/fis_main_menu.js` (`addAdminMenuButtonsIfAuthorized`) + `fis_main_go.js` — conditional menu buttons (this module and `usr`).
|
||||
- `Fuchs.Tests/SystemStatusServiceTests.cs` — service tests.
|
||||
- `Fuchs.Tests/AdminUserManagementTests.cs` — password-reset email content tests.
|
||||
|
||||
User account/group management moved to its own module and concept doc — see
|
||||
[admin-user-management.md](admin-user-management.md).
|
||||
|
||||
## Related decisions
|
||||
- [0011 — Admin module gated on `fds_sys` > 4](../Decisions/0011-admin-module-system-status.md)
|
||||
- [0014 — Admin user management: folded into the `admin` module, dual auth axis, password always emailed](../Decisions/0014-admin-user-management.md)
|
||||
- [0015 — Split Admin into separate Status/User-Management modules](../Decisions/0015-split-admin-user-management-module.md)
|
||||
|
||||
Reference in New Issue
Block a user