// The admin's tools for managing people: add someone, choose their tabs, give them a one-time invite code, // sign them out everywhere, turn them off, or delete them and their data. Admin only (enforced by the caller). const users = require('./users'); const auth = require('./auth'); const readBody = req => new Promise((ok, no) => { const c = []; req.on('data', d => c.push(d)); req.on('end', () => ok(Buffer.concat(c).toString())); req.on('error', no); }); const json = (res, code, obj) => { res.writeHead(code, { 'content-type': 'application/json' }); res.end(JSON.stringify(obj)); }; const row = u => ({ ...users.publicView(u), tabsChosen: u.tabs || [], passkeys: auth.passkeyCount(u.id) }); async function handle(req, res, me) { try { const p = new URL(req.url, 'http://x').pathname.replace(/\/$/, ''), parts = p.split('/'); // ['', 'api', 'users', id?, action?] const id = parts[3], action = parts[4]; if (!id && req.method === 'GET') return json(res, 200, { users: users.all().map(row), tabs: users.TABS.map(t => ({ id: t, label: users.TAB_LABELS[t] })), invite: { minutes: auth.INVITE_MINUTES } }); if (!id && req.method === 'POST') { const b = JSON.parse(await readBody(req) || '{}'); const u = users.create({ name: b.name, role: 'user', tabs: b.tabs }); return json(res, 200, { user: row(u), code: auth.newInvite(u.id), minutes: auth.INVITE_MINUTES }); } const u = users.get(id); if (!u) return json(res, 404, { error: 'Person not found' }); if (action === 'invite' && req.method === 'POST') return json(res, 200, { code: auth.newInvite(u.id), minutes: auth.INVITE_MINUTES }); // for a new device or to recover access if (!action && req.method === 'PUT') { const b = JSON.parse(await readBody(req) || '{}'); if (u.id === me.id && b.disabled) return json(res, 400, { error: 'You cannot turn off your own account' }); users.update(id, { name: b.name, tabs: b.tabs, role: b.role, disabled: b.disabled, signOutEverywhere: b.signOutEverywhere }); return json(res, 200, { user: row(users.get(id)) }); } if (!action && req.method === 'DELETE') { if (u.id === me.id) return json(res, 400, { error: 'You cannot delete your own account' }); users.remove(id); auth.removeCredsOf(id); return json(res, 200, { ok: true }); } json(res, 404, { error: 'Not found' }); } catch (e) { json(res, 400, { error: e.message }); } } module.exports = { handle };