Add read-only Noya admin panel with assignments and UX polish.
Ship admin auth, user overview, assessments, chats, assignment filters/export, security hardening, and a separate desktop admin shell with clearer assessment answers. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -14,6 +14,9 @@ import {
|
||||
toPublicUser,
|
||||
} from './auth.service.js';
|
||||
import { prisma } from '../../lib/prisma.js';
|
||||
import { AUDIT_ACTIONS } from '../admin/auditActions.js';
|
||||
import { recordAuditBestEffort } from '../admin/audit.service.js';
|
||||
import { UserRole } from '@prisma/client';
|
||||
|
||||
const authAbuseLimiter = rateLimiter({
|
||||
windowMs: env.RATE_LIMIT_WINDOW_MS,
|
||||
@@ -49,6 +52,22 @@ export function createAuthRoutes() {
|
||||
routes.post('/login', authAbuseLimiter, jsonValidator(loginSchema), async (c) => {
|
||||
const { email, password } = c.req.valid('json');
|
||||
const result = await login(email, password);
|
||||
|
||||
if (result.user.role === UserRole.admin) {
|
||||
const user = await prisma.user.findUnique({
|
||||
where: { externalId: result.user.id },
|
||||
select: { id: true },
|
||||
});
|
||||
|
||||
await recordAuditBestEffort({
|
||||
actorUserId: user?.id ?? null,
|
||||
action: AUDIT_ACTIONS.ADMIN_LOGIN,
|
||||
metadata: { source: 'password_login' },
|
||||
ipAddress: getClientIp(c),
|
||||
userAgent: c.req.header('user-agent') ?? null,
|
||||
});
|
||||
}
|
||||
|
||||
return success(c, result);
|
||||
});
|
||||
|
||||
@@ -70,6 +89,7 @@ export function createAuthRoutes() {
|
||||
email: authUser.email,
|
||||
isGuest: authUser.isGuest,
|
||||
profileComplete: false,
|
||||
role: authUser.role,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user