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
@@ -0,0 +1,173 @@
|
||||
import { test, after } from 'node:test'
|
||||
import assert from 'node:assert/strict'
|
||||
import { startAppwriteMock } from './support/appwriteMock.js'
|
||||
import { startFakeStripe } from './support/fakeStripe.js'
|
||||
import { useTestEnv } from './support/testEnv.js'
|
||||
|
||||
// Zugang zum Ticketsystem nur mit Label (scripts/mitarbeiter-zugang.mjs, employeeAdmin.js)
|
||||
const aw = await startAppwriteMock()
|
||||
const st = await startFakeStripe()
|
||||
useTestEnv({ appwriteUrl: aw.url, stripeUrl: st.url })
|
||||
const {
|
||||
applyPermissionChanges,
|
||||
grantStaffLabel,
|
||||
planPermissionChanges,
|
||||
removeEmployeeEntry,
|
||||
staffAccessStatus,
|
||||
staffOnlyPermissions,
|
||||
} = await import('../server/services/staffAccessAdmin.js')
|
||||
const { isStaffAccount, isAdminAccount } = await import('../server/services/staffLabels.js')
|
||||
const { createEmployeeWithLogin, updateEmployeeWithLogin } = await import('../server/services/employeeAdmin.js')
|
||||
after(() => Promise.all([aw.close(), st.close()]))
|
||||
|
||||
const STAFF = ['label:mitarbeiter', 'label:admin']
|
||||
|
||||
test('isStaffAccount: nur Label mitarbeiter oder admin, nie ohne Konto', () => {
|
||||
assert.equal(isStaffAccount({ labels: ['mitarbeiter'] }), true)
|
||||
assert.equal(isStaffAccount({ labels: ['admin'] }), true)
|
||||
assert.equal(isStaffAccount({ labels: [] }), false)
|
||||
assert.equal(isStaffAccount({ labels: ['kunde'] }), false)
|
||||
assert.equal(isStaffAccount(null), false)
|
||||
assert.equal(isAdminAccount({ labels: ['mitarbeiter'] }), false)
|
||||
})
|
||||
|
||||
test('staffOnlyPermissions: any/guests/users -> Mitarbeiter-Labels, andere Rollen bleiben, keine Doppel', () => {
|
||||
assert.deepEqual(
|
||||
staffOnlyPermissions(['read("users")', 'create("users")', 'read("any")', 'update("guests")', 'read("user:abc")', 'delete("users/verified")']),
|
||||
[
|
||||
...STAFF.map((r) => `read("${r}")`),
|
||||
...STAFF.map((r) => `create("${r}")`),
|
||||
...STAFF.map((r) => `update("${r}")`),
|
||||
'read("user:abc")',
|
||||
...STAFF.map((r) => `delete("${r}")`),
|
||||
]
|
||||
)
|
||||
assert.deepEqual(staffOnlyPermissions(['read("label:mitarbeiter")', 'read("team:x")']), ['read("label:mitarbeiter")', 'read("team:x")'])
|
||||
assert.deepEqual(staffOnlyPermissions([]), [])
|
||||
})
|
||||
|
||||
// Nachbau der Appwrite-Verwaltungs-API fuer Rechte (Datenbanken, Collections, Dokumente, Buckets, Dateien)
|
||||
function fakeAdminApi() {
|
||||
const collections = {
|
||||
tickets: { $id: 'workorders', name: 'Work Orders', documentSecurity: false, enabled: true, $permissions: ['read("users")', 'update("users")'] },
|
||||
portal: { $id: 'chatMessages', name: 'Chat', documentSecurity: false, enabled: true, $permissions: [] },
|
||||
docs: { $id: 'notes', name: 'Notes', documentSecurity: true, enabled: true, $permissions: ['read("label:mitarbeiter")'] },
|
||||
}
|
||||
const documents = [
|
||||
{ $id: 'n1', $permissions: ['read("user:u1")'] },
|
||||
{ $id: 'n2', $permissions: ['read("any")'] },
|
||||
]
|
||||
const bucket = {
|
||||
$id: 'legal-files', name: 'Legal', fileSecurity: false, enabled: true, maximumFileSize: 30000000,
|
||||
allowedFileExtensions: ['pdf'], compression: 'none', encryption: true, antivirus: true, $permissions: ['read("users")', 'create("users")'],
|
||||
}
|
||||
const writes = []
|
||||
const request = async (path, { method = 'GET', body } = {}) => {
|
||||
if (method !== 'GET') {
|
||||
if (path.endsWith('/collections/workorders') && body.name === undefined) throw new Error('name fehlt')
|
||||
if (path.startsWith('/storage/') && method === 'PUT' && path.endsWith('/broken')) throw new Error('missing scope (buckets.write)')
|
||||
writes.push({ method, path, body })
|
||||
return {}
|
||||
}
|
||||
if (path === '/databases') return { databases: [{ $id: 'woms-database' }] }
|
||||
if (path === '/databases/woms-database/collections') return { collections: Object.values(collections) }
|
||||
if (path === '/databases/woms-database/collections/notes/documents') return { documents }
|
||||
if (path === '/storage/buckets') return { buckets: [bucket, { ...bucket, $id: 'broken', name: 'Kaputt' }] }
|
||||
throw new Error(`unerwartet ${path}`)
|
||||
}
|
||||
return { request, writes }
|
||||
}
|
||||
|
||||
test('planPermissionChanges: offene Collections, Dokumente und Buckets, geschlossene nicht', async () => {
|
||||
const api = fakeAdminApi()
|
||||
const changes = await planPermissionChanges(api.request)
|
||||
assert.deepEqual(changes.map((c) => `${c.kind}:${c.id}`), ['collection:workorders', 'document:n2', 'bucket:legal-files', 'bucket:broken'])
|
||||
const tickets = changes[0]
|
||||
assert.deepEqual(tickets.before, ['read("users")', 'update("users")'])
|
||||
assert.deepEqual(tickets.after, [...STAFF.map((r) => `read("${r}")`), ...STAFF.map((r) => `update("${r}")`)])
|
||||
assert.deepEqual(tickets.settings, { name: 'Work Orders', documentSecurity: false, enabled: true })
|
||||
})
|
||||
|
||||
test('applyPermissionChanges: schreibt mit allen Einstellungen, meldet Fehler je Stelle, Ruecknahme schreibt before', async () => {
|
||||
const api = fakeAdminApi()
|
||||
const changes = await planPermissionChanges(api.request)
|
||||
const results = await applyPermissionChanges(changes, { request: api.request })
|
||||
assert.deepEqual(results.map((r) => r.ok), [true, true, true, false])
|
||||
assert.match(results[3].error, /buckets\.write/)
|
||||
|
||||
const [collection, document, bucket] = api.writes
|
||||
assert.deepEqual(collection, {
|
||||
method: 'PUT',
|
||||
path: '/databases/woms-database/collections/workorders',
|
||||
body: { name: 'Work Orders', documentSecurity: false, enabled: true, permissions: changes[0].after },
|
||||
})
|
||||
assert.deepEqual(document, { method: 'PATCH', path: '/databases/woms-database/collections/notes/documents/n2', body: { permissions: changes[1].after } })
|
||||
assert.equal(bucket.path, '/storage/buckets/legal-files')
|
||||
assert.equal(bucket.body.maximumFileSize, 30000000)
|
||||
assert.deepEqual(bucket.body.allowedFileExtensions, ['pdf'])
|
||||
assert.equal(bucket.body.antivirus, true)
|
||||
|
||||
api.writes.length = 0
|
||||
await applyPermissionChanges(changes.slice(0, 1), { direction: 'before', request: api.request })
|
||||
assert.deepEqual(api.writes[0].body.permissions, ['read("users")', 'update("users")'])
|
||||
})
|
||||
|
||||
test('Status: markiert Eintraege von Kunden und Eintraege ohne Label, listet Label-Konten ohne Eintrag', async () => {
|
||||
aw.addUser({ $id: 'u_kenso', email: 'kenso@webklar.com', name: 'Kenso', labels: ['admin', 'mitarbeiter'] })
|
||||
aw.addUser({ $id: 'u_andrej', email: 'andrej@webklar.com', name: 'Andrej' })
|
||||
aw.addUser({ $id: 'u_kunde', email: 'kunde@example.invalid', name: 'Kunde' })
|
||||
aw.addUser({ $id: 'u_nur_label', email: 'nico@webklar.com', name: 'Nico', labels: ['mitarbeiter'] })
|
||||
aw.seed('employees', { $id: 'e_kenso', userId: 'u_kenso', displayName: 'Kenso', email: 'kenso@webklar.com' })
|
||||
aw.seed('employees', { $id: 'e_andrej', userId: 'u_andrej', displayName: 'Andrej', email: 'andrej@webklar.com' })
|
||||
aw.seed('employees', { $id: 'e_kunde', userId: 'u_kunde', displayName: 'Kunde', email: 'kunde@example.invalid' })
|
||||
aw.seed('customers', { $id: 'c1', appwriteUserId: 'u_kunde', name: 'Kunde GmbH' })
|
||||
|
||||
const users = [...['u_kenso', 'u_andrej', 'u_kunde', 'u_nur_label']].map((id) => aw.user(id))
|
||||
const request = async (path, options) => (path === '/users' ? { users } : (await import('../server/services/appwriteAdmin.js')).appwriteAdminRequest(path, options))
|
||||
const { rows, labelOnly } = await staffAccessStatus(request)
|
||||
const byId = Object.fromEntries(rows.map((r) => [r.employeeId, r]))
|
||||
assert.equal(byId.e_kenso.staff, true)
|
||||
assert.equal(byId.e_andrej.staff, false)
|
||||
assert.equal(byId.e_andrej.customer, '')
|
||||
assert.equal(byId.e_kunde.staff, false)
|
||||
assert.equal(byId.e_kunde.customer, 'Kunde GmbH')
|
||||
assert.deepEqual(labelOnly.map((u) => u.userId), ['u_nur_label'])
|
||||
})
|
||||
|
||||
test('grantStaffLabel: haengt mitarbeiter an, vorhandene Labels bleiben', async () => {
|
||||
aw.addUser({ $id: 'u_justin', email: 'justin@webklar.com', name: 'Justin', labels: ['vip'] })
|
||||
const r = await grantStaffLabel('u_justin')
|
||||
assert.deepEqual(r.labels, ['vip', 'mitarbeiter'])
|
||||
assert.deepEqual(aw.user('u_justin').labels, ['vip', 'mitarbeiter'])
|
||||
})
|
||||
|
||||
test('removeEmployeeEntry: loescht nur den Eintrag eines Kunden, nie das Konto; Mitarbeiter bleiben', async () => {
|
||||
aw.addUser({ $id: 'u_k2', email: 'k2@example.invalid', name: 'K2' })
|
||||
aw.addUser({ $id: 'u_m2', email: 'm2@webklar.com', name: 'M2', labels: ['mitarbeiter'] })
|
||||
aw.seed('employees', { $id: 'e_k2', userId: 'u_k2', displayName: 'K2' })
|
||||
aw.seed('employees', { $id: 'e_m2', userId: 'u_m2', displayName: 'M2' })
|
||||
|
||||
await removeEmployeeEntry('e_k2')
|
||||
assert.equal(aw.docs('employees').has('e_k2'), false)
|
||||
assert.ok(aw.user('u_k2'), 'Konto des Kunden bleibt')
|
||||
|
||||
await assert.rejects(removeEmployeeEntry('e_m2'), /Mitarbeiter-Label/)
|
||||
assert.equal(aw.docs('employees').has('e_m2'), true)
|
||||
})
|
||||
|
||||
test('Mitarbeiter anlegen: Label mitarbeiter (+ admin), Bearbeiten ergaenzt es und laesst admin ohne Angabe stehen', async () => {
|
||||
const { employee } = await createEmployeeWithLogin({ displayName: 'Neu', email: 'neu@webklar.com', password: 'neu-neu-neu', isAdmin: false })
|
||||
assert.deepEqual(aw.user(employee.userId).labels, ['mitarbeiter'])
|
||||
|
||||
const { employee: chef } = await createEmployeeWithLogin({ displayName: 'Chef', email: 'chef@webklar.com', password: 'chef-chef-chef', isAdmin: true })
|
||||
assert.deepEqual(aw.user(chef.userId).labels.sort(), ['admin', 'mitarbeiter'])
|
||||
assert.equal(chef.isAdmin, true)
|
||||
|
||||
// Altbestand ohne Label: jede Bearbeitung holt es nach, admin bleibt ohne Angabe unveraendert
|
||||
aw.addUser({ $id: 'u_alt', email: 'alt@webklar.com', name: 'Alt', labels: ['admin'] })
|
||||
aw.seed('employees', { $id: 'e_alt', userId: 'u_alt', displayName: 'Alt', email: 'alt@webklar.com' })
|
||||
await updateEmployeeWithLogin('e_alt', { shortcode: 'ALT' }, 'u_kenso')
|
||||
assert.deepEqual(aw.user('u_alt').labels.sort(), ['admin', 'mitarbeiter'])
|
||||
await updateEmployeeWithLogin('e_alt', { isAdmin: false }, 'u_kenso')
|
||||
assert.deepEqual(aw.user('u_alt').labels, ['mitarbeiter'])
|
||||
})
|
||||
+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)
|
||||
}
|
||||
|
||||
@@ -229,6 +229,21 @@ export async function startAppwriteMock({ schema = {}, datetimes = {}, defaultLi
|
||||
return [200, { $id: `s-${user.$id}`, userId: user.$id, factors: session.factors }]
|
||||
}
|
||||
}
|
||||
// Konto anlegen und Labels setzen (Mitarbeiter-Verwaltung, employeeAdmin.js)
|
||||
if (url.pathname === '/v1/users' && req.method === 'POST') {
|
||||
const { userId, email, password, name } = await readBody(req)
|
||||
users.set(userId, { $id: userId, email, password, name, labels: [], mfa: false, emailVerification: false })
|
||||
userCalls.push(`create:${userId}`)
|
||||
return [201, publicUser(users.get(userId))]
|
||||
}
|
||||
const labelsPath = url.pathname.match(/^\/v1\/users\/([^/]+)\/labels$/)
|
||||
if (labelsPath && req.method === 'PUT') {
|
||||
const user = users.get(labelsPath[1])
|
||||
if (!user) return [404, { message: 'User not found', code: 404, type: 'user_not_found' }]
|
||||
user.labels = (await readBody(req)).labels
|
||||
userCalls.push(`labels:${labelsPath[1]}`)
|
||||
return [200, publicUser(user)]
|
||||
}
|
||||
const mfaPath = url.pathname.match(/^\/v1\/users\/([^/]+)\/(mfa|verification)$/)
|
||||
if (mfaPath && req.method === 'PATCH') {
|
||||
const user = users.get(mfaPath[1])
|
||||
@@ -286,7 +301,9 @@ export async function startAppwriteMock({ schema = {}, datetimes = {}, defaultLi
|
||||
if (jwt === 'jwt-admin') return [200, { $id: 'u_admin', email: 'kenso@webklar.com', labels: ['admin'] }]
|
||||
if (jwt === 'jwt-kunde') return [200, { $id: 'u_admin', email: 'kenso@webklar.com', labels: [] }]
|
||||
// jwt-staff = Mitarbeiter ohne Label admin, jwt-halb = JWT aus einer Sitzung ohne zweiten Faktor
|
||||
if (jwt === 'jwt-staff') return [200, { $id: 'u_staff2', email: 'andrej@webklar.com', name: 'Andrej', labels: [] }]
|
||||
if (jwt === 'jwt-staff') return [200, { $id: 'u_staff2', email: 'andrej@webklar.com', name: 'Andrej', labels: ['mitarbeiter'] }]
|
||||
// jwt-kunde-eintrag = Kunde ohne Label, dessen Konto-ID ein (selbst angelegter) employees-Eintrag traegt
|
||||
if (jwt === 'jwt-kunde-eintrag') return [200, { $id: 'u_kunde_e', email: 'kunde@example.invalid', name: 'Kunde', labels: [] }]
|
||||
if (jwt === 'jwt-halb') return moreFactors
|
||||
// Team-Eingang: Konto-Mail gleicht einem Mitarbeiter, ist aber unbestaetigt bzw. bestaetigt (ohne userId-Treffer)
|
||||
if (jwt === 'jwt-mail-ungeprueft') return [200, { $id: 'u_fremd', email: 'andrej@webklar.com', emailVerification: false, labels: [] }]
|
||||
|
||||
+12
-10
@@ -5,7 +5,7 @@ import { startAppwriteMock } from './support/appwriteMock.js'
|
||||
import { startFakeStripe } from './support/fakeStripe.js'
|
||||
import { useTestEnv } from './support/testEnv.js'
|
||||
|
||||
// Team-Eingang /api/team: Appwrite-JWT aus dem Ticketsystem, jeder Mitarbeiter (nicht nur Label admin)
|
||||
// Team-Eingang /api/team: Appwrite-JWT aus dem Ticketsystem, jedes Konto mit Label mitarbeiter oder admin
|
||||
const aw = await startAppwriteMock()
|
||||
const st = await startFakeStripe()
|
||||
useTestEnv({ appwriteUrl: aw.url, stripeUrl: st.url })
|
||||
@@ -25,6 +25,8 @@ after(() => Promise.all([app.close(), aw.close(), st.close()]))
|
||||
|
||||
aw.seed('employees', { $id: 'e_staff2', userId: 'u_staff2', displayName: 'Andrej', email: 'andrej@webklar.com' })
|
||||
aw.seed('employees', { $id: 'e_nico', userId: '', displayName: 'Nico', email: 'nico@webklar.com' })
|
||||
// Beim Login eines Kunden ins Ticketsystem entstand frueher automatisch ein employees-Eintrag
|
||||
aw.seed('employees', { $id: 'e_kunde', userId: 'u_kunde_e', displayName: 'Kunde', email: 'kunde@example.invalid' })
|
||||
|
||||
const probe = (jwt) => rawGet('/probe', jwt ? { headers: { authorization: `Bearer ${jwt}` } } : {})
|
||||
|
||||
@@ -38,18 +40,18 @@ test('Kunde (kein Mitarbeiter, kein Label) -> 403', async () => {
|
||||
assert.equal(res.body.error, 'Kein Mitarbeiterkonto.')
|
||||
})
|
||||
|
||||
test('Mail gleicht Mitarbeiter, ist aber unbestaetigt -> 403', async () => {
|
||||
test('Kunde mit employees-Eintrag, aber ohne Label -> 403', async () => {
|
||||
const res = await probe('jwt-kunde-eintrag')
|
||||
assert.equal(res.status, 403)
|
||||
assert.equal(res.body.error, 'Kein Mitarbeiterkonto.')
|
||||
})
|
||||
|
||||
test('Mail gleicht einem Mitarbeiter (bestaetigt oder nicht), kein Label -> 403', async () => {
|
||||
assert.equal((await probe('jwt-mail-ungeprueft')).status, 403)
|
||||
assert.equal((await probe('jwt-mail-geprueft')).status, 403)
|
||||
})
|
||||
|
||||
test('bestaetigte Mail eines Mitarbeiters ohne userId -> erlaubt', async () => {
|
||||
const res = await probe('jwt-mail-geprueft')
|
||||
assert.equal(res.status, 200)
|
||||
assert.equal(res.body.name, 'Nico')
|
||||
assert.equal(res.body.appwriteUserId, 'u_neu')
|
||||
})
|
||||
|
||||
test('Mitarbeiter ohne Admin-Label -> erlaubt, Sitzung in Admin-Form', async () => {
|
||||
test('Label mitarbeiter (ohne admin) -> erlaubt, Name aus employees, Sitzung in Admin-Form', async () => {
|
||||
const res = await probe('jwt-staff')
|
||||
assert.equal(res.status, 200)
|
||||
assert.deepEqual(res.body, { role: 'admin', isAdmin: false, appwriteUserId: 'u_staff2', name: 'Andrej', email: 'andrej@webklar.com' })
|
||||
|
||||
Reference in new issue
Block a user