chore: harden deps, env validation, admin errors, and redis warnings
Deploy / release (push) Skipped
Deploy / deploy (push) Successful in 1m39s

Align nodemailer with Auth.js peers, bump patch deps, validate env on deploy builds, add admin error boundary, and warn when Redis is missing in production.

Co-authored-by: Cursor <[email protected]>
This commit is contained in:
SimoandCursor committed 2026-07-21 20:19:05 +02:00
1 parent c865e6f699
commit c46dadeda4
10 files changed
+876 -461

No files matched your search

+2 -1
View File
@@ -13,7 +13,8 @@ describe("production deploy workflow", () => {
expect(workflow).not.toMatch(/rm\s+-rf\s+\.next(?:\s|$)/);
expect(workflow).toContain("rm -rf .output dist .next/types .next/dev");
expect(workflow).toContain("pnpm install --frozen-lockfile");
expect(workflow).toContain("SKIP_ENV_VALIDATION=1");
// Production builds must validate env (AUTH_SECRET, DATABASE_URL, …).
expect(workflow).not.toContain("SKIP_ENV_VALIDATION=1");
});
it("reclaims ownership before git reset so www-data files can be overwritten", () => {
+7
View File
@@ -13,6 +13,7 @@ const CLEANUP_INTERVAL_MS = 300_000;
const MAX_BUCKETS = 10_000;
let lastCleanup = Date.now();
let redisFailWarned = false;
function cleanup(): void {
const now = Date.now();
@@ -54,6 +55,12 @@ export async function rateLimit(
return { ok: true, retryAfter: 0 };
} catch {
// Redis unavailable — fall through to in-memory
if (process.env.NODE_ENV === "production" && !redisFailWarned) {
redisFailWarned = true;
console.error(
"[rate-limit] Redis error — falling back to in-process buckets. Limits are not shared across instances until Redis recovers.",
);
}
}
}
+16 -2
View File
@@ -2,11 +2,25 @@ import "server-only";
import Redis from "ioredis";
const globalForRedis = globalThis as unknown as { redis?: Redis | null };
const globalForRedis = globalThis as unknown as {
redis?: Redis | null;
redisMissingWarned?: boolean;
};
function createRedis(): Redis | null {
const url = process.env.REDIS_URL;
if (!url) return null;
if (!url) {
if (
process.env.NODE_ENV === "production" &&
!globalForRedis.redisMissingWarned
) {
globalForRedis.redisMissingWarned = true;
console.error(
"[redis] REDIS_URL is unset in production. Rate limits and shared caches fall back to in-process memory and will not work correctly across multiple instances.",
);
}
return null;
}
try {
const client = new Redis(url, {
maxRetriesPerRequest: 3,