#36 CRITICAL: add .max(128) to all password Zod schemas to prevent Argon2-based DoS from unbounded password strings. #46 HIGH: configure pino redact paths so passwords/tokens/cookies/TOTP secrets are never serialized in logs. #58 MEDIUM: upgrade dompurify to ^3.4.0 and add pnpm overrides for brace-expansion (>=5.0.5) and esbuild (>=0.25.0) to patch known CVEs. Vite moderate (path traversal, dev-only) remains — requires vitest 3.x major upgrade, deferred. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -99,8 +99,10 @@ export const inviteRouter = createTRPCRouter({
|
||||
select: { email: true, role: true, expiresAt: true, usedAt: true },
|
||||
});
|
||||
if (!invite) throw new TRPCError({ code: "NOT_FOUND", message: "Invite not found." });
|
||||
if (invite.usedAt) throw new TRPCError({ code: "BAD_REQUEST", message: "This invite has already been used." });
|
||||
if (invite.expiresAt < new Date()) throw new TRPCError({ code: "BAD_REQUEST", message: "This invite has expired." });
|
||||
if (invite.usedAt)
|
||||
throw new TRPCError({ code: "BAD_REQUEST", message: "This invite has already been used." });
|
||||
if (invite.expiresAt < new Date())
|
||||
throw new TRPCError({ code: "BAD_REQUEST", message: "This invite has expired." });
|
||||
return { email: invite.email, role: invite.role };
|
||||
}),
|
||||
|
||||
@@ -109,7 +111,7 @@ export const inviteRouter = createTRPCRouter({
|
||||
.input(
|
||||
z.object({
|
||||
token: z.string(),
|
||||
password: z.string().min(12, "Password must be at least 12 characters."),
|
||||
password: z.string().min(12, "Password must be at least 12 characters.").max(128),
|
||||
}),
|
||||
)
|
||||
.mutation(async ({ ctx, input }) => {
|
||||
@@ -125,13 +127,18 @@ export const inviteRouter = createTRPCRouter({
|
||||
where: { token: input.token },
|
||||
});
|
||||
if (!invite) throw new TRPCError({ code: "NOT_FOUND", message: "Invite not found." });
|
||||
if (invite.usedAt) throw new TRPCError({ code: "BAD_REQUEST", message: "This invite has already been used." });
|
||||
if (invite.expiresAt < new Date()) throw new TRPCError({ code: "BAD_REQUEST", message: "This invite has expired." });
|
||||
if (invite.usedAt)
|
||||
throw new TRPCError({ code: "BAD_REQUEST", message: "This invite has already been used." });
|
||||
if (invite.expiresAt < new Date())
|
||||
throw new TRPCError({ code: "BAD_REQUEST", message: "This invite has expired." });
|
||||
|
||||
// Check if user already exists
|
||||
const existing = await ctx.db.user.findUnique({ where: { email: invite.email } });
|
||||
if (existing) {
|
||||
throw new TRPCError({ code: "CONFLICT", message: "An account with this email already exists." });
|
||||
throw new TRPCError({
|
||||
code: "CONFLICT",
|
||||
message: "An account with this email already exists.",
|
||||
});
|
||||
}
|
||||
|
||||
const { hash } = await import("@node-rs/argon2");
|
||||
|
||||
Reference in New Issue
Block a user