Browse Source

Add automatic role assignment for new and existing users

- Implemented auto-assignment of the 'private' role for new users upon first login, ensuring they have access to products.
- Added a safety check to assign the 'private' role to existing users without roles during login.
- Updated relevant documentation to reflect these changes in role management and visibility patterns.
main
Bastian Masanek 2 months ago
parent
commit
cb4810893c
  1. 44
      CLAUDE.md
  2. 5
      docs/ARCHITECTURE.md
  3. 9
      docs/PRD.md
  4. 13
      server/api/auth/login.post.ts

44
CLAUDE.md

@ -499,6 +499,50 @@ export async function submitOrderToXAPI(payload: XAPIOrderPayload) {
## Role-based Product Visibility Patterns (MVP) ## Role-based Product Visibility Patterns (MVP)
### Auto-Assignment of 'private' Role (MVP)
**Requirement**: All users must have at least one role to see products. New users automatically receive the `private` role on first login.
**Implementation** in `server/api/auth/login.post.ts`:
```typescript
if (!user) {
// First time login - create user profile
const [newUser] = await db.insert(users).values({
experimentaId: cidaasUser.sub,
email: cidaasUser.email,
firstName: cidaasUser.given_name || '',
lastName: cidaasUser.family_name || '',
}).returning()
user = newUser
// Auto-assign 'private' role on first login
await assignRoleToUser(newUser.id, 'private', {
adminNotes: 'Auto-assigned on first login',
})
} else {
// Update last login timestamp
await db.update(users)
.set({ updatedAt: new Date() })
.where(eq(users.id, user.id))
// Safety check: If existing user has no roles, assign 'private' role
const userRoleCodes = await getUserApprovedRoleCodes(user.id)
if (userRoleCodes.length === 0) {
await assignRoleToUser(user.id, 'private', {
adminNotes: 'Auto-assigned for existing user without roles',
})
}
}
```
**Key Points:**
- ✅ New users → `private` role automatically assigned
- ✅ Existing users without roles → `private` role assigned (safety check)
- ✅ Status always `approved` (no approval workflow in MVP)
- ✅ Admin notes track auto-assignment source
### Role-based Filtering Pattern ### Role-based Filtering Pattern
```typescript ```typescript

5
docs/ARCHITECTURE.md

@ -1544,6 +1544,11 @@ try {
- **user_roles**: Many-to-Many User ↔ Rollen mit Antrags-Workflow (vorbereitet für Phase 2/3) - **user_roles**: Many-to-Many User ↔ Rollen mit Antrags-Workflow (vorbereitet für Phase 2/3)
- **product_role_visibility**: Many-to-Many Produkt ↔ Rollen (Sichtbarkeitssteuerung) - **product_role_visibility**: Many-to-Many Produkt ↔ Rollen (Sichtbarkeitssteuerung)
**Automatische Rollen-Zuweisung (MVP):**
- Neue User erhalten bei erster Anmeldung automatisch die Rolle `private` (Status: `approved`)
- Implementierung in `server/api/auth/login.post.ts` nach User-Profile-Erstellung
- Safety-Check: Bestehende User ohne Rollen erhalten ebenfalls `private` Rolle
**Opt-in Sichtbarkeit:** **Opt-in Sichtbarkeit:**
- Produkte OHNE `product_role_visibility` Einträge sind für NIEMANDEN sichtbar - Produkte OHNE `product_role_visibility` Einträge sind für NIEMANDEN sichtbar
- Produkte MIT Einträgen sind nur für User mit passender `approved` Rolle sichtbar - Produkte MIT Einträgen sind nur für User mit passender `approved` Rolle sichtbar

9
docs/PRD.md

@ -143,10 +143,14 @@ Das System nutzt ein rollenbasiertes Modell zur Steuerung der Produktsichtbarkei
#### 3.3.3 Rollenzuweisung (MVP) #### 3.3.3 Rollenzuweisung (MVP)
**Automatische Rollen-Zuweisung (MVP):**
- Neue User erhalten bei erster Anmeldung automatisch die Rolle `private` (Status: `approved`)
- Implementierung in `server/api/auth/login.post.ts`
- Falls ein bestehender User keine Rolle hat (z.B. Legacy-Daten), wird ebenfalls `private` zugewiesen
**Manuelle Zuweisung via Datenbank:** **Manuelle Zuweisung via Datenbank:**
- Rollen werden manuell via Drizzle Studio zugewiesen - Weitere Rollen werden manuell via Drizzle Studio zugewiesen
- Status immer `approved` (keine Anträge im MVP) - Status immer `approved` (keine Anträge im MVP)
- Standard: Neue User erhalten automatisch Rolle `private`
**Automatische Produkt-Rollen-Zuweisung (ERP-Import):** **Automatische Produkt-Rollen-Zuweisung (ERP-Import):**
@ -202,6 +206,7 @@ Beim Import von Produkten aus dem NAV ERP werden Rollen basierend auf der Katego
- Bestätigungs-E-Mail wird von Cidaas versendet - Bestätigungs-E-Mail wird von Cidaas versendet
- E-Mail muss bestätigt werden bevor Login möglich ist - E-Mail muss bestätigt werden bevor Login möglich ist
- Nach erster Anmeldung wird User-Profil in lokaler DB angelegt (über OAuth2 Callback) - Nach erster Anmeldung wird User-Profil in lokaler DB angelegt (über OAuth2 Callback)
- **Automatische Rollen-Zuweisung**: Bei Erstellung des User-Profils wird automatisch die Rolle "Privatperson" (`private`) zugewiesen
- User erhält Fehlermeldung wenn E-Mail bereits registriert - User erhält Fehlermeldung wenn E-Mail bereits registriert
- Validierung: Client-seitig (UX) + Server-seitig (Sicherheit) - Validierung: Client-seitig (UX) + Server-seitig (Sicherheit)
- Übersetzung in Deutsch und Englisch - Übersetzung in Deutsch und Englisch

13
server/api/auth/login.post.ts

@ -63,6 +63,11 @@ export default defineEventHandler(async (event) => {
.returning() .returning()
user = newUser user = newUser
// Auto-assign 'private' role on first login
await assignRoleToUser(newUser.id, 'private', {
adminNotes: 'Auto-assigned on first login',
})
} else { } else {
// Update last login timestamp // Update last login timestamp
await db await db
@ -71,6 +76,14 @@ export default defineEventHandler(async (event) => {
updatedAt: new Date(), updatedAt: new Date(),
}) })
.where(eq(users.id, user.id)) .where(eq(users.id, user.id))
// Safety check: If existing user has no roles, assign 'private' role
const userRoleCodes = await getUserApprovedRoleCodes(user.id)
if (userRoleCodes.length === 0) {
await assignRoleToUser(user.id, 'private', {
adminNotes: 'Auto-assigned for existing user without roles',
})
}
} }
// 6. Create encrypted session // 6. Create encrypted session

Loading…
Cancel
Save