fix: security hardening — block self-registration, SSE auth, audit logging fixes
Some checks failed
Build and Push Docker Image / build (push) Has been cancelled
Some checks failed
Build and Push Docker Image / build (push) Has been cancelled
Security fixes: - Block self-registration via magic link (PrismaAdapter createUser throws) - Magic links only sent to existing ACTIVE users (prevents enumeration) - signIn callback rejects non-existent users (defense-in-depth) - Change schema default role from JURY_MEMBER to APPLICANT - Add authentication to live-voting SSE stream endpoint - Fix false FILE_OPENED/FILE_DOWNLOADED audit events on page load (remove purpose from eagerly pre-fetched URL queries) Bug fixes: - Fix impersonation skeleton screen on applicant dashboard - Fix onboarding redirect loop in auth layout Observer dashboard redesign (Steps 1-6): - Clickable round pipeline with selected round highlighting - Round-type-specific dashboard panels (intake, filtering, evaluation, submission, mentoring, live final, deliberation) - Enhanced activity feed with server-side humanization - Previous round comparison section - New backend queries for round-specific analytics Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -2,6 +2,7 @@ import { z } from 'zod'
|
||||
import { TRPCError } from '@trpc/server'
|
||||
import { Prisma } from '@prisma/client'
|
||||
import { router, protectedProcedure, adminProcedure } from '../trpc'
|
||||
import { getUserAvatarUrl } from '../utils/avatar-url'
|
||||
import { logAudit } from '../utils/audit'
|
||||
import { processEligibilityJob } from '../services/award-eligibility-job'
|
||||
import { getAwardSelectionNotificationTemplate } from '@/lib/email'
|
||||
@@ -481,7 +482,7 @@ export const specialAwardRouter = router({
|
||||
listJurors: protectedProcedure
|
||||
.input(z.object({ awardId: z.string() }))
|
||||
.query(async ({ ctx, input }) => {
|
||||
return ctx.prisma.awardJuror.findMany({
|
||||
const jurors = await ctx.prisma.awardJuror.findMany({
|
||||
where: { awardId: input.awardId },
|
||||
include: {
|
||||
user: {
|
||||
@@ -496,6 +497,15 @@ export const specialAwardRouter = router({
|
||||
},
|
||||
},
|
||||
})
|
||||
return Promise.all(
|
||||
jurors.map(async (j) => ({
|
||||
...j,
|
||||
user: {
|
||||
...j.user,
|
||||
avatarUrl: await getUserAvatarUrl(j.user.profileImageKey, j.user.profileImageProvider),
|
||||
},
|
||||
}))
|
||||
)
|
||||
}),
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user