58 lines
1.9 KiB
TypeScript
58 lines
1.9 KiB
TypeScript
|
|
import type { FastifyInstance } from 'fastify';
|
||
|
|
import { z } from 'zod';
|
||
|
|
import { auditLog, createDb, desc, eq, memberships, organizations, users } from '@bmm/db';
|
||
|
|
import { requireAuth } from '../plugins/session.js';
|
||
|
|
|
||
|
|
const db = createDb();
|
||
|
|
|
||
|
|
export async function settingsRoutes(app: FastifyInstance): Promise<void> {
|
||
|
|
app.get('/v1/me/org', { preHandler: requireAuth }, async (req, reply) => {
|
||
|
|
const user = req.user!;
|
||
|
|
const [org] = await db.select().from(organizations).where(eq(organizations.id, user.orgId)).limit(1);
|
||
|
|
if (!org) return reply.code(404).send({ error: 'not_found' });
|
||
|
|
|
||
|
|
const members = await db
|
||
|
|
.select({
|
||
|
|
id: memberships.id,
|
||
|
|
userId: users.id,
|
||
|
|
email: users.email,
|
||
|
|
name: users.name,
|
||
|
|
role: memberships.role,
|
||
|
|
createdAt: memberships.createdAt,
|
||
|
|
})
|
||
|
|
.from(memberships)
|
||
|
|
.innerJoin(users, eq(users.id, memberships.userId))
|
||
|
|
.where(eq(memberships.orgId, org.id))
|
||
|
|
.orderBy(memberships.createdAt);
|
||
|
|
|
||
|
|
return reply.send({ org, members });
|
||
|
|
});
|
||
|
|
|
||
|
|
app.get('/v1/audit', { preHandler: requireAuth }, async (req, reply) => {
|
||
|
|
const user = req.user!;
|
||
|
|
const Query = z.object({
|
||
|
|
limit: z.coerce.number().min(1).max(500).default(100),
|
||
|
|
action: z.string().optional(),
|
||
|
|
resourceType: z.string().optional(),
|
||
|
|
});
|
||
|
|
const parsed = Query.safeParse(req.query);
|
||
|
|
if (!parsed.success) return reply.code(400).send({ error: 'invalid_query' });
|
||
|
|
|
||
|
|
let rows = await db
|
||
|
|
.select()
|
||
|
|
.from(auditLog)
|
||
|
|
.where(eq(auditLog.orgId, user.orgId))
|
||
|
|
.orderBy(desc(auditLog.createdAt))
|
||
|
|
.limit(parsed.data.limit);
|
||
|
|
|
||
|
|
if (parsed.data.action) {
|
||
|
|
rows = rows.filter((r) => r.action === parsed.data.action);
|
||
|
|
}
|
||
|
|
if (parsed.data.resourceType) {
|
||
|
|
rows = rows.filter((r) => r.resourceType === parsed.data.resourceType);
|
||
|
|
}
|
||
|
|
|
||
|
|
return reply.send({ entries: rows });
|
||
|
|
});
|
||
|
|
}
|