Dienstkonto-Kennzeichen in der Benutzerverwaltung setzbar machen
Nachgezogen: Das Feld isServiceAccount lag in der Datenbank, war aber nirgends setzbar - weder im Formular noch ueber die API. Der Betreiber haette es nicht aktivieren koennen, damit waere die R182-Einstufung wirkungslos geblieben. Jetzt Ankreuzfeld "Dienstkonto" im Benutzerformular mit Erklaerung im Klartext, Feld in der Mass-Assignment-Whitelist (gilt damit auch beim Anlegen), im Service-Typ und in allen drei select-Bloecken, damit es beim Bearbeiten vorbelegt wird. Verifiziert: Whitelist laesst das Feld durch und blockt Fremdfelder weiterhin, Wert ueber Prisma lesbar, tsc und vite build gruen. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -44,6 +44,7 @@ export async function getAllUsers(filters: UserFilters) {
|
|||||||
firstName: true,
|
firstName: true,
|
||||||
lastName: true,
|
lastName: true,
|
||||||
isActive: true,
|
isActive: true,
|
||||||
|
isServiceAccount: true,
|
||||||
customerId: true,
|
customerId: true,
|
||||||
whatsappNumber: true,
|
whatsappNumber: true,
|
||||||
telegramUsername: true,
|
telegramUsername: true,
|
||||||
@@ -97,6 +98,7 @@ export async function getUserById(id: number) {
|
|||||||
firstName: true,
|
firstName: true,
|
||||||
lastName: true,
|
lastName: true,
|
||||||
isActive: true,
|
isActive: true,
|
||||||
|
isServiceAccount: true,
|
||||||
customerId: true,
|
customerId: true,
|
||||||
whatsappNumber: true,
|
whatsappNumber: true,
|
||||||
telegramUsername: true,
|
telegramUsername: true,
|
||||||
@@ -170,6 +172,7 @@ export async function createUser(data: {
|
|||||||
firstName: true,
|
firstName: true,
|
||||||
lastName: true,
|
lastName: true,
|
||||||
isActive: true,
|
isActive: true,
|
||||||
|
isServiceAccount: true,
|
||||||
customerId: true,
|
customerId: true,
|
||||||
roles: {
|
roles: {
|
||||||
include: { role: true },
|
include: { role: true },
|
||||||
@@ -198,6 +201,7 @@ export async function updateUser(
|
|||||||
firstName?: string;
|
firstName?: string;
|
||||||
lastName?: string;
|
lastName?: string;
|
||||||
isActive?: boolean;
|
isActive?: boolean;
|
||||||
|
isServiceAccount?: boolean;
|
||||||
roleIds?: number[];
|
roleIds?: number[];
|
||||||
customerId?: number;
|
customerId?: number;
|
||||||
hasDeveloperAccess?: boolean;
|
hasDeveloperAccess?: boolean;
|
||||||
|
|||||||
@@ -640,6 +640,10 @@ const USER_UPDATABLE_FIELDS = [
|
|||||||
'firstName',
|
'firstName',
|
||||||
'lastName',
|
'lastName',
|
||||||
'isActive',
|
'isActive',
|
||||||
|
// Kennzeichnet planmaessig arbeitende Konten (z. B. das Gegenbuch). Ihre
|
||||||
|
// Anmeldungen werden als Routine statt CRITICAL gefuehrt, dafuer wacht der
|
||||||
|
// Heartbeat-Monitor ueber ihr AUSBLEIBEN (Pentest R182/R183).
|
||||||
|
'isServiceAccount',
|
||||||
'whatsappNumber',
|
'whatsappNumber',
|
||||||
'telegramUsername',
|
'telegramUsername',
|
||||||
'signalNumber',
|
'signalNumber',
|
||||||
|
|||||||
@@ -97,6 +97,20 @@ isolierte Instanz (keine Multi-Tenancy im Code), Provisioning + Abrechnung
|
|||||||
|
|
||||||
## ✅ Erledigt
|
## ✅ Erledigt
|
||||||
|
|
||||||
|
- [x] **🖱️ Dienstkonto-Kennzeichen in der Benutzerverwaltung** (2026-08-24)
|
||||||
|
- Nachgezogen: Das Feld `isServiceAccount` lag zwar in der Datenbank, war
|
||||||
|
aber **nirgends setzbar** – weder im Formular noch ueber die API. Der
|
||||||
|
Betreiber haette es nicht aktivieren koennen, damit waere die
|
||||||
|
R182-Einstufung wirkungslos geblieben.
|
||||||
|
- Jetzt: Ankreuzfeld „Dienstkonto“ im Benutzerformular unter den
|
||||||
|
zusaetzlichen Berechtigungen, mit Erklaerung im Klartext (planmaessige
|
||||||
|
Anmeldungen als Routine, dafuer Meldung bei AUSBLEIBEN). Feld in der
|
||||||
|
Whitelist (`USER_UPDATABLE_FIELDS`, damit auch beim Anlegen), im
|
||||||
|
Service-Typ und in allen drei `select`-Bloecken, damit es beim Bearbeiten
|
||||||
|
vorbelegt wird.
|
||||||
|
- Verifiziert: Whitelist laesst das Feld durch und blockt Fremdfelder
|
||||||
|
weiterhin; Wert ueber Prisma lesbar; `tsc` und `vite build` gruen.
|
||||||
|
|
||||||
- [x] **🚨 Retention-Governance + Heartbeat-Wachhund (Pentest R183, R182-Rest)** (2026-08-24)
|
- [x] **🚨 Retention-Governance + Heartbeat-Wachhund (Pentest R183, R182-Rest)** (2026-08-24)
|
||||||
- **R183-01 (HIGH)** – Die geladene Waffe war ungegatet, der Abzug gegatet:
|
- **R183-01 (HIGH)** – Die geladene Waffe war ungegatet, der Abzug gegatet:
|
||||||
`PUT /retention-policies/{id}` nahm `retentionDays: 0` **ohne
|
`PUT /retention-policies/{id}` nahm `retentionDays: 0` **ohne
|
||||||
|
|||||||
@@ -247,6 +247,7 @@ function UserModal({
|
|||||||
isActive: true,
|
isActive: true,
|
||||||
hasDeveloperAccess: false,
|
hasDeveloperAccess: false,
|
||||||
hasGdprAccess: false,
|
hasGdprAccess: false,
|
||||||
|
isServiceAccount: false,
|
||||||
whatsappNumber: '',
|
whatsappNumber: '',
|
||||||
telegramUsername: '',
|
telegramUsername: '',
|
||||||
signalNumber: '',
|
signalNumber: '',
|
||||||
@@ -267,6 +268,7 @@ function UserModal({
|
|||||||
isActive: (user as any).isActive ?? true,
|
isActive: (user as any).isActive ?? true,
|
||||||
hasDeveloperAccess: (user as any).hasDeveloperAccess ?? false,
|
hasDeveloperAccess: (user as any).hasDeveloperAccess ?? false,
|
||||||
hasGdprAccess: (user as any).hasGdprAccess ?? false,
|
hasGdprAccess: (user as any).hasGdprAccess ?? false,
|
||||||
|
isServiceAccount: (user as any).isServiceAccount ?? false,
|
||||||
whatsappNumber: (user as any).whatsappNumber || '',
|
whatsappNumber: (user as any).whatsappNumber || '',
|
||||||
telegramUsername: (user as any).telegramUsername || '',
|
telegramUsername: (user as any).telegramUsername || '',
|
||||||
signalNumber: (user as any).signalNumber || '',
|
signalNumber: (user as any).signalNumber || '',
|
||||||
@@ -324,6 +326,7 @@ function UserModal({
|
|||||||
isActive: formData.isActive,
|
isActive: formData.isActive,
|
||||||
hasDeveloperAccess: formData.hasDeveloperAccess,
|
hasDeveloperAccess: formData.hasDeveloperAccess,
|
||||||
hasGdprAccess: formData.hasGdprAccess,
|
hasGdprAccess: formData.hasGdprAccess,
|
||||||
|
isServiceAccount: formData.isServiceAccount,
|
||||||
whatsappNumber: formData.whatsappNumber || undefined,
|
whatsappNumber: formData.whatsappNumber || undefined,
|
||||||
telegramUsername: formData.telegramUsername || undefined,
|
telegramUsername: formData.telegramUsername || undefined,
|
||||||
signalNumber: formData.signalNumber || undefined,
|
signalNumber: formData.signalNumber || undefined,
|
||||||
@@ -359,6 +362,7 @@ function UserModal({
|
|||||||
roleIds: formData.roleIds,
|
roleIds: formData.roleIds,
|
||||||
hasDeveloperAccess: formData.hasDeveloperAccess,
|
hasDeveloperAccess: formData.hasDeveloperAccess,
|
||||||
hasGdprAccess: formData.hasGdprAccess,
|
hasGdprAccess: formData.hasGdprAccess,
|
||||||
|
isServiceAccount: formData.isServiceAccount,
|
||||||
whatsappNumber: formData.whatsappNumber || undefined,
|
whatsappNumber: formData.whatsappNumber || undefined,
|
||||||
telegramUsername: formData.telegramUsername || undefined,
|
telegramUsername: formData.telegramUsername || undefined,
|
||||||
signalNumber: formData.signalNumber || undefined,
|
signalNumber: formData.signalNumber || undefined,
|
||||||
@@ -487,6 +491,22 @@ function UserModal({
|
|||||||
</div>
|
</div>
|
||||||
<label className="block text-sm font-medium text-gray-700 mt-4 mb-2">Zusätzliche Berechtigungen</label>
|
<label className="block text-sm font-medium text-gray-700 mt-4 mb-2">Zusätzliche Berechtigungen</label>
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
|
<label className="flex items-start gap-2">
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
checked={formData.isServiceAccount}
|
||||||
|
onChange={(e) => setFormData({ ...formData, isServiceAccount: e.target.checked })}
|
||||||
|
className="mt-1 rounded border-blue-300 text-blue-600 focus:ring-blue-500"
|
||||||
|
/>
|
||||||
|
<span>
|
||||||
|
<span className="font-medium">Dienstkonto</span>
|
||||||
|
<span className="block text-sm text-gray-500">
|
||||||
|
Für Konten, die sich planmäßig und regelmäßig anmelden – etwa das Gegenbuch.
|
||||||
|
Ihre Anmeldungen erscheinen im Audit-Log als Routine statt als kritisches
|
||||||
|
Ereignis. Dafür wird gemeldet, wenn ein solches Konto <em>ausbleibt</em>.
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
<label className="flex items-center gap-2">
|
<label className="flex items-center gap-2">
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
|
|||||||
Reference in New Issue
Block a user