Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@
"drizzle-kit": "0.31.10",
"eslint": "10.1.0",
"eslint-config-next": "16.2.1",
"puppeteer": "^24.40.0",
Copy link

Copilot AI Mar 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

puppeteer is added to devDependencies, but there are no in-repo imports or scripts referencing it (Playwright is already present, and LHCI typically uses puppeteer-core). If this isn’t immediately required, consider removing it (or documenting/adding the script that uses it) to avoid extra install time and the Chromium download footprint in CI/dev.

Suggested change
"puppeteer": "^24.40.0",

Copilot uses AI. Check for mistakes.
"tailwindcss": "^4.2.2",
"tsx": "4.21.0",
"typescript": "5.9.3",
Expand Down
119 changes: 119 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/components/ArticleCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export default function ArticleCard({ post }: { post: ArticleCardPost }) {
)}
<div className="p-5">
<div className="flex items-center gap-3 text-xs text-muted mb-1">
{date && <span>{date}</span>}
{date && <span suppressHydrationWarning>{date}</span>}
{post.viewsTotal !== undefined && post.viewsTotal > 0 && (
<span>• {formatViewCount(post.viewsTotal)} views</span>
)}
Expand Down
2 changes: 1 addition & 1 deletion src/components/admin/ModerationQueue.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -566,7 +566,7 @@ function CommentCard({
<span className="font-medium">User ID:</span> <code className="text-xs">{comment.userId || "—"}</code>
</div>
<div>
<span className="font-medium">Created:</span> {new Date(comment.createdAt).toLocaleString()}
<span className="font-medium">Created:</span> <span suppressHydrationWarning>{new Date(comment.createdAt).toLocaleString()}</span>
</div>
</div>
</div>
Expand Down
20 changes: 0 additions & 20 deletions src/components/auth/TwoFactorGuard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,48 +16,28 @@ export function TwoFactorGuard({ children }: { children: React.ReactNode }) {
const router = useRouter();

useEffect(() => {
console.log("[2FA GUARD] Effect triggered:", {
pathname,
status,
hasSession: !!session,
mfaPending: session?.mfaPending,
mfa: session?.mfa,
});

// Skip check if loading or not authenticated
if (status === "loading" || status === "unauthenticated") {
console.log("[2FA GUARD] Skipping - status is loading or unauthenticated");
return;
}

// Skip if no session (belt and suspenders)
if (!session) {
console.log("[2FA GUARD] Skipping - no session object");
return;
}

// Skip if already on 2FA page
if (pathname === "/login/2fa") {
console.log("[2FA GUARD] Skipping - already on 2FA page");
return;
}

// Skip for auth-related pages
if (pathname.startsWith("/login") || pathname.startsWith("/api")) {
console.log("[2FA GUARD] Skipping - auth/api page");
return;
}

console.log("[2FA GUARD] Checking if redirect needed:", {
pathname,
status,
mfaPending: session?.mfaPending,
mfa: session?.mfa,
});

// Check if 2FA is required
if (session?.mfaPending === true) {
console.log("[2FA GUARD] Redirecting to /login/2fa");
router.push("/login/2fa");
}
}, [session, status, pathname, router]);
Expand Down
Loading
Loading