fix(security): raise password minimum to 12 chars, hide raw error messages, add audit script
- Password validation: min(8) → min(12) across auth.ts, user-procedure-support.ts, and invite.ts (aligns with NIST SP 800-63B modern recommendations) - Error boundary: stop rendering raw error.message which could leak internal details; always show the generic fallback text - Add `pnpm audit` script (--audit-level=high) for dependency vulnerability scanning Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -34,7 +34,7 @@ export default function AppError({
|
|||||||
Something went wrong
|
Something went wrong
|
||||||
</h2>
|
</h2>
|
||||||
<p className="text-sm text-gray-500 dark:text-gray-400 mb-6 max-w-sm">
|
<p className="text-sm text-gray-500 dark:text-gray-400 mb-6 max-w-sm">
|
||||||
{error.message || "An unexpected error occurred. The team has been notified."}
|
{"An unexpected error occurred. The team has been notified."}
|
||||||
</p>
|
</p>
|
||||||
{error.digest && (
|
{error.digest && (
|
||||||
<p className="text-xs text-gray-400 dark:text-gray-500 mb-4 font-mono">
|
<p className="text-xs text-gray-400 dark:text-gray-500 mb-4 font-mono">
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
"test:e2e": "node ./scripts/run-from-workspace-root.mjs turbo test:e2e",
|
"test:e2e": "node ./scripts/run-from-workspace-root.mjs turbo test:e2e",
|
||||||
"test:e2e:email": "pnpm --filter @capakraken/web test:e2e:email",
|
"test:e2e:email": "pnpm --filter @capakraken/web test:e2e:email",
|
||||||
"test:scripts": "node --test scripts/*.test.mjs",
|
"test:scripts": "node --test scripts/*.test.mjs",
|
||||||
|
"audit": "pnpm audit --audit-level=high",
|
||||||
"check:architecture": "node ./scripts/check-architecture-guardrails.mjs",
|
"check:architecture": "node ./scripts/check-architecture-guardrails.mjs",
|
||||||
"check:exports": "node ./scripts/check-workspace-exports.mjs",
|
"check:exports": "node ./scripts/check-workspace-exports.mjs",
|
||||||
"check:imports": "node ./scripts/check-workspace-imports.mjs",
|
"check:imports": "node ./scripts/check-workspace-imports.mjs",
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ export const authRouter = createTRPCRouter({
|
|||||||
.input(
|
.input(
|
||||||
z.object({
|
z.object({
|
||||||
token: z.string().min(1),
|
token: z.string().min(1),
|
||||||
password: z.string().min(8, "Password must be at least 8 characters."),
|
password: z.string().min(12, "Password must be at least 12 characters."),
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.mutation(async ({ ctx, input }) => {
|
.mutation(async ({ ctx, input }) => {
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ export const inviteRouter = createTRPCRouter({
|
|||||||
.input(
|
.input(
|
||||||
z.object({
|
z.object({
|
||||||
token: z.string(),
|
token: z.string(),
|
||||||
password: z.string().min(8, "Password must be at least 8 characters."),
|
password: z.string().min(12, "Password must be at least 12 characters."),
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.mutation(async ({ ctx, input }) => {
|
.mutation(async ({ ctx, input }) => {
|
||||||
|
|||||||
@@ -10,12 +10,12 @@ export const CreateUserInputSchema = z.object({
|
|||||||
email: z.string().email(),
|
email: z.string().email(),
|
||||||
name: z.string().min(1),
|
name: z.string().min(1),
|
||||||
systemRole: z.nativeEnum(SystemRole).default(SystemRole.USER),
|
systemRole: z.nativeEnum(SystemRole).default(SystemRole.USER),
|
||||||
password: z.string().min(8),
|
password: z.string().min(12),
|
||||||
});
|
});
|
||||||
|
|
||||||
export const SetUserPasswordInputSchema = z.object({
|
export const SetUserPasswordInputSchema = z.object({
|
||||||
userId: z.string(),
|
userId: z.string(),
|
||||||
password: z.string().min(8, "Password must be at least 8 characters"),
|
password: z.string().min(12, "Password must be at least 12 characters"),
|
||||||
});
|
});
|
||||||
|
|
||||||
export const UpdateUserRoleInputSchema = z.object({
|
export const UpdateUserRoleInputSchema = z.object({
|
||||||
|
|||||||
Reference in New Issue
Block a user