feat: router.back() navigation, read-only evaluation view, auth audit logging
All checks were successful
Build and Push Docker Image / build (push) Successful in 7m53s

- Convert all Back buttons platform-wide (38 files) to use router.back()
  for natural browser-back behavior regardless of entry point
- Add read-only view for submitted evaluations in closed rounds with
  blue banner, disabled inputs, and contextual back navigation
- Add auth audit logs: MAGIC_LINK_SENT, PASSWORD_RESET_LINK_CLICKED,
  PASSWORD_RESET_LINK_EXPIRED, PASSWORD_RESET_LINK_INVALID
- Learning Hub links navigate in same window for all roles
- Update settings descriptions to reflect all-user scope

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-06 14:25:56 +01:00
parent a556732b46
commit a1e758bc39
44 changed files with 398 additions and 384 deletions

View File

@@ -64,7 +64,7 @@ export const { handlers, auth, signIn, signOut } = NextAuth({
// (status NONE) who have no password yet.
const existingUser = await prisma.user.findUnique({
where: { email: email.toLowerCase().trim() },
select: { status: true },
select: { id: true, status: true },
})
if (!existingUser || existingUser.status === 'SUSPENDED') {
// Silently skip — don't reveal whether the email exists (prevents enumeration)
@@ -72,6 +72,17 @@ export const { handlers, auth, signIn, signOut } = NextAuth({
return
}
await sendMagicLinkEmail(email, url)
// Audit: magic link sent
await prisma.auditLog.create({
data: {
userId: existingUser.id,
action: 'MAGIC_LINK_SENT',
entityType: 'User',
entityId: existingUser.id,
detailsJson: { email, timestamp: new Date().toISOString() },
},
}).catch(() => {})
},
}),
// Credentials provider for email/password login and invite token auth