Mitarbeiter nur noch per Label: Kunden-Konten bekommen keinen Team-Zugang
Kunden haben Konten im selben Appwrite-Projekt wie das Ticketsystem. Bisher galt als Mitarbeiter, wer einen employees-Eintrag hatte - den legte das Ticketsystem beim Login jedes Kontos automatisch an, und jedes angemeldete Konto konnte ihn auch selbst anlegen. Damit kam ein Kunde ueber /api/team an Chats, Kundenansicht, Angebote und Finanzen. - staffLabels.js: Mitarbeiter = Label "mitarbeiter" oder "admin" (setzt nur der Server-Key) - Team-Eingang (requireStaffJwt) und Portal-Login-Sperre nur noch per Label; kein Abgleich ueber employees-Eintrag oder Mail mehr - Portal-Login: Konto-Abruf gestoert -> 503 fuer alle (fail closed) - Mitarbeiter anlegen/bearbeiten setzt das Label "mitarbeiter" - scripts/mitarbeiter-zugang.mjs: --status (markiert employees-Eintraege von Kunden), --label, --eintrag-loeschen (nur Eintrag, nie das Konto), --rechte (Probelauf, --anwenden mit Sicherung, --zurueck): any/guests/users -> label:mitarbeiter + label:admin in Collections, Buckets und bei Dokument-/ Datei-Sicherheit auch einzelnen Dokumenten und Dateien Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
be7f9b1aa3
commit
2659385205
12 files changed
+602
-65
No files matched your search
+22
-7
@@ -16,11 +16,16 @@ const app = await startTestApp({ '/api/auth': authRoutes })
|
||||
after(() => Promise.all([app.close(), aw.close(), st.close()]))
|
||||
|
||||
aw.addUser({ $id: 'u_kunde', email: 'kunde@example.invalid', password: 'kunde-kunde' })
|
||||
aw.addUser({ $id: 'u_ohne', email: 'justin@webklar.com', password: 'ohne-ohne-ohne' })
|
||||
aw.addUser({ $id: 'u_mfa', email: 'kenso@webklar.com', password: 'mit-mit-mit', mfa: true, emailVerification: true, labels: ['admin'] })
|
||||
aw.addUser({ $id: 'u_ohne', email: 'justin@webklar.com', password: 'ohne-ohne-ohne', labels: ['mitarbeiter'] })
|
||||
aw.addUser({ $id: 'u_mfa', email: 'kenso@webklar.com', password: 'mit-mit-mit', mfa: true, emailVerification: true, labels: ['admin', 'mitarbeiter'] })
|
||||
// Kunde, fuer den beim Login ins Ticketsystem automatisch ein employees-Eintrag entstand (kein Label)
|
||||
aw.addUser({ $id: 'u_kunde_e', email: 'kunde2@example.invalid', password: 'kunde2-kunde2' })
|
||||
aw.addUser({ $id: 'u_label', email: 'label@webklar.com', password: 'label-label', labels: ['admin'] })
|
||||
aw.seed('customers', { $id: 'c1', appwriteUserId: 'u_kunde', email: 'kunde@example.invalid', name: 'Kunde', customerStatus: 'active', portalAccessEnabled: true })
|
||||
aw.seed('customerPortalAccess', { $id: 'pa1', customerId: 'c1', enabled: true })
|
||||
aw.seed('customers', { $id: 'c2', appwriteUserId: 'u_kunde_e', email: 'kunde2@example.invalid', name: 'Kunde Zwei', customerStatus: 'active', portalAccessEnabled: true })
|
||||
aw.seed('customerPortalAccess', { $id: 'pa2', customerId: 'c2', enabled: true })
|
||||
aw.seed('employees', { $id: 'e3', userId: 'u_kunde_e', displayName: 'Kunde Zwei', email: 'kunde2@example.invalid' })
|
||||
aw.seed('employees', { $id: 'e1', userId: 'u_ohne', displayName: 'Justin', email: 'justin@webklar.com' })
|
||||
aw.seed('employees', { $id: 'e2', userId: 'u_mfa', displayName: 'Kenso', email: 'kenso@webklar.com' })
|
||||
|
||||
@@ -41,6 +46,13 @@ test('Kunde meldet sich weiter normal an', async () => {
|
||||
assert.equal(aw.sessionDeletes(), before)
|
||||
})
|
||||
|
||||
test('Kunde mit employees-Eintrag ohne Label meldet sich normal an (Eintrag macht niemanden zum Mitarbeiter)', async () => {
|
||||
const res = await login('kunde2@example.invalid', 'kunde2-kunde2')
|
||||
assert.equal(res.status, 200)
|
||||
assert.equal(res.body.role, 'customer')
|
||||
assert.equal(liveCookies(res, SESSION).length, 1)
|
||||
})
|
||||
|
||||
test('Mitarbeiter ohne 2FA: 403 mit Link ins Ticketsystem, keine Sitzung, Appwrite-Sitzung beendet', async () => {
|
||||
const before = aw.sessionDeletes()
|
||||
const res = await login('justin@webklar.com', 'ohne-ohne-ohne')
|
||||
@@ -68,13 +80,16 @@ test('Nur Label admin (ohne employees-Eintrag): ebenfalls gesperrt', async () =>
|
||||
assert.equal(liveCookies(res, SESSION).length, 0)
|
||||
})
|
||||
|
||||
test('Konto-Abruf gestoert: Mitarbeiter bleibt gesperrt (employees-Treffer)', async () => {
|
||||
test('Konto-Abruf gestoert: niemand bekommt eine Sitzung (503), Appwrite-Sitzung beendet', async () => {
|
||||
aw.failUserLookups(true)
|
||||
try {
|
||||
const res = await login('kenso@webklar.com', 'mit-mit-mit')
|
||||
assert.equal(res.status, 403)
|
||||
assert.deepEqual(res.body, STAFF_BLOCKED)
|
||||
assert.equal(liveCookies(res, SESSION).length, 0)
|
||||
for (const [email, password] of [['kenso@webklar.com', 'mit-mit-mit'], ['kunde@example.invalid', 'kunde-kunde']]) {
|
||||
const before = aw.sessionDeletes()
|
||||
const res = await login(email, password)
|
||||
assert.equal(res.status, 503, email)
|
||||
assert.equal(liveCookies(res, SESSION).length, 0)
|
||||
assert.equal(aw.sessionDeletes(), before + 1)
|
||||
}
|
||||
} finally {
|
||||
aw.failUserLookups(false)
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user