Compare commits
2
Commits
4201a90fd0
...
45f63d1c48
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
45f63d1c48 | ||
|
|
2d3ca28691 |
@@ -72,8 +72,19 @@ export async function updateUser(req: Request, res: Response): Promise<void> {
|
||||
// Whitelist: nur erlaubte Felder aus req.body übernehmen (Mass-Assignment-Schutz)
|
||||
const data = pickUserUpdate(req.body);
|
||||
|
||||
// Vorherigen Stand laden für Audit
|
||||
const before = await prisma.user.findUnique({ where: { id: userId } });
|
||||
// Vorherigen Stand laden für Audit – inkl. Rollen, damit hasGdprAccess /
|
||||
// hasDeveloperAccess (versteckte Rollen) korrekt verglichen werden.
|
||||
const beforeUser = await prisma.user.findUnique({
|
||||
where: { id: userId },
|
||||
include: { roles: { include: { role: true } } },
|
||||
});
|
||||
const before = beforeUser
|
||||
? {
|
||||
...beforeUser,
|
||||
hasGdprAccess: beforeUser.roles.some((ur) => ur.role.name === 'DSGVO'),
|
||||
hasDeveloperAccess: beforeUser.roles.some((ur) => ur.role.name === 'Developer'),
|
||||
}
|
||||
: null;
|
||||
|
||||
const user = await userService.updateUser(userId, data as any);
|
||||
if (user) {
|
||||
@@ -82,6 +93,7 @@ export async function updateUser(req: Request, res: Response): Promise<void> {
|
||||
const changes: Record<string, { von: unknown; nach: unknown }> = {};
|
||||
const fieldLabels: Record<string, string> = {
|
||||
email: 'E-Mail', firstName: 'Vorname', lastName: 'Nachname', isActive: 'Aktiv',
|
||||
hasGdprAccess: 'DSGVO-Zugriff', hasDeveloperAccess: 'Entwicklerzugriff',
|
||||
};
|
||||
for (const [key, newVal] of Object.entries(data)) {
|
||||
if (['id', 'createdAt', 'updatedAt'].includes(key)) continue;
|
||||
|
||||
@@ -110,6 +110,12 @@ const USER_UPDATABLE_FIELDS = [
|
||||
'signalNumber',
|
||||
'roleIds',
|
||||
'password', // nur Admin, wird im Service gehashed
|
||||
// hasGdprAccess + hasDeveloperAccess sind keine User-Spalten – der Service
|
||||
// mappt sie auf die versteckten Rollen DSGVO/Developer (siehe
|
||||
// setUserGdprAccess / setUserDeveloperAccess). Müssen aber auf der Whitelist
|
||||
// stehen, damit pick() sie nicht aus dem Request entfernt.
|
||||
'hasGdprAccess',
|
||||
'hasDeveloperAccess',
|
||||
// Nicht: id, customerId, tokenInvalidatedAt, passwordResetToken, passwordResetExpiresAt
|
||||
] as const;
|
||||
|
||||
|
||||
@@ -97,6 +97,13 @@ isolierte Instanz (keine Multi-Tenancy im Code), Provisioning + Abrechnung
|
||||
|
||||
## ✅ Erledigt
|
||||
|
||||
- [x] **🐛 Benutzer-Verwaltung: DSGVO- + Entwickler-Zugriff zuweisbar**
|
||||
- Mass-Assignment-Whitelist (`pickUserUpdate`) hat `hasGdprAccess` /
|
||||
`hasDeveloperAccess` rausgefiltert → Service erhielt sie nie → Rollen
|
||||
DSGVO/Developer waren in der UI nicht zuweisbar (Checkbox ohne Wirkung).
|
||||
- Beide Felder zur Whitelist hinzugefügt + Audit-Log liest die Pre-Werte
|
||||
jetzt aus den geladenen Rollen (kein False-Positive-Change mehr).
|
||||
|
||||
- [x] **🔒 HTTPS-only-Header per Flag (`HTTPS_ENABLED`)**
|
||||
- HSTS + `upgrade-insecure-requests` (CSP) sperrten den Browser bei
|
||||
direktem `http://ip:port`-Zugriff aus (`ERR_SSL_PROTOCOL_ERROR`).
|
||||
|
||||
Reference in New Issue
Block a user