# ID-Hashing System

## Übersicht

Das TimeClock Backend verwendet ein automatisches ID-Hashing-System, das alle numerischen IDs in API-Responses verschlüsselt und eingehende Hash-IDs automatisch entschlüsselt.

## Warum ID-Hashing?

- **Sicherheit**: Verhindert, dass Angreifer die Anzahl der Datensätze erraten können
- **Obfuscation**: Versteckt die interne Datenbankstruktur
- **Schutz vor ID-Enumeration**: Verhindert systematisches Durchlaufen von Ressourcen

## Funktionsweise

### Automatisches Hashing (Backend → Frontend)

Alle numerischen ID-Felder in API-Responses werden automatisch in Hashes konvertiert:

```javascript
// Datenbank-Daten:
{
  id: 123,
  user_id: 456,
  full_name: "Max Mustermann"
}

// API-Response:
{
  id: "xY9kL2mP3qR5.aB7cD8eF9gH0",
  user_id: "tU6vW7xY8zZ9.iJ1kL2mN3oP4",
  full_name: "Max Mustermann"
}
```

### Automatisches Enthashen (Frontend → Backend)

Alle Hash-IDs in eingehenden Requests werden automatisch zurück in numerische IDs konvertiert:

```javascript
// Frontend sendet:
{
  user_id: "xY9kL2mP3qR5.aB7cD8eF9gH0"
}

// Backend erhält:
{
  user_id: 123
}
```

## Implementierung

### Backend

Das System besteht aus drei Komponenten:

1. **`utils/hashId.js`**: Utility-Klasse für Encoding/Decoding
2. **`middleware/hashResponse.js`**: Middleware für ausgehende Responses
3. **`middleware/unhashRequest.js`**: Middleware für eingehende Requests

### Konfiguration

In der `.env`-Datei:

```env
HASH_ID_SECRET=your-hash-id-secret-change-in-production
```

⚠️ **Wichtig**: Das Secret sollte in Produktion geändert werden und geheim bleiben!

### Erkannte ID-Felder

Folgende Feldnamen werden automatisch als IDs erkannt und gehashed:

- `id`, `_id`
- `user_id`, `userId`
- `auth_info_id`, `authInfoId`
- `auth_token_id`, `authTokenId`
- `worklog_id`, `worklogId`
- `vacation_id`, `vacationId`
- `sick_id`, `sickId`
- `holiday_id`, `holidayId`
- `state_id`, `stateId`
- `sick_type_id`, `sickTypeId`
- `weekly_worktime_id`, `weeklyWorktimeId`

## Frontend-Integration

Das Frontend muss keine Änderungen vornehmen - es arbeitet einfach mit den empfangenen Hash-IDs:

```javascript
// GET /api/auth/me
const response = await fetch('/api/auth/me')
const data = await response.json()

console.log(data.user.id) // "xY9kL2mP3qR5.aB7cD8eF9gH0"

// POST /api/some-endpoint
await fetch('/api/some-endpoint', {
  method: 'POST',
  body: JSON.stringify({
    user_id: data.user.id // Hash wird automatisch entschlüsselt
  })
})
```

## Manuelle Verwendung

Falls manuelles Encoding/Decoding nötig ist:

```javascript
const hashId = require('./utils/hashId');

// Einzelne ID hashen
const hash = hashId.encode(123); // "xY9kL2mP3qR5.aB7cD8eF9gH0"

// Hash dekodieren
const id = hashId.decode(hash); // 123

// Objekt hashen
const obj = { id: 123, name: "Test" };
const hashed = hashId.encodeObject(obj); // { id: "xY9...", name: "Test" }

// Array hashen
const array = [{ id: 1 }, { id: 2 }];
const hashedArray = hashId.encodeArray(array);
```

## Sicherheitshinweise

1. **Secret ändern**: Ändern Sie `HASH_ID_SECRET` in der Produktion
2. **Secret sicher aufbewahren**: Das Secret sollte niemals im Code oder in der Versionskontrolle erscheinen
3. **Keine zusätzliche Sicherheit**: ID-Hashing ersetzt keine echte Autorisierung - prüfen Sie immer die Zugriffsrechte!

## Hash-Format

Das Hash-Format: `{encrypted_id}.{hash_prefix}`

- **encrypted_id**: AES-256-CBC verschlüsselte ID
- **hash_prefix**: HMAC-SHA256 Hash (erste 12 Zeichen) zur Verifizierung
- **Encoding**: base64url (URL-sicher)

Beispiel: `xY9kL2mP3qR5.aB7cD8eF9gH0`

## Fehlerbehandlung

Ungültige Hash-IDs werden zu `null` dekodiert. Services/Controller sollten dies behandeln:

```javascript
const userId = req.params.id; // Könnte null sein wenn Hash ungültig

if (!userId) {
  return res.status(400).json({ error: 'Ungültige ID' });
}
```

## Performance

- **Encoding**: ~0.1ms pro ID
- **Decoding**: ~0.2ms pro ID
- **Overhead**: Minimal, da deterministisch und ohne Datenbank-Zugriff



