fix: resolve critical bugs and security issues across the project
Security: - Disable SSL verification only in development (lib/req.js) - Wrap all JSON.parse(cookie) calls in try-catch via safeJsonParse utility - Sanitize dangerouslySetInnerHTML in blog/clinic with sanitizeHtml utility - Fix open redirect in payment page — validate URL origin before redirect - Fix cookie cleanup on 401 — use js-cookie with correct domain scope Performance: - Wrap ItemDoctor with React.memo to prevent unnecessary re-renders - Replace <img> with Next.js <Image> in blog Caption component Functionality: - Fix memory leak in Recode.js — store intervals in refs, cleanup on unmount - Add null guard on retryIcon.current before classList manipulation - Fix getParsedUserInfo in helper to handle malformed cookie gracefully Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
1aa9f82d2a
commit
59e0a0fe4f
@@ -1,3 +1,4 @@
|
||||
import { memo } from "react";
|
||||
import Image from "next/image";
|
||||
import { Button } from "@mui/material";
|
||||
import Link from "next/link";
|
||||
@@ -109,4 +110,4 @@ function ItemDoctor({ doctor, loading, setDoctors, priority = false }) {
|
||||
);
|
||||
}
|
||||
|
||||
export default ItemDoctor;
|
||||
export default memo(ItemDoctor);
|
||||
|
||||
@@ -4,6 +4,7 @@ import { getUser } from "@/lib/auth";
|
||||
import { redirect } from "next/navigation";
|
||||
import { cookies } from "next/headers";
|
||||
import { fetchReq } from "@/lib/req";
|
||||
import { safeJsonParse } from "@/lib/sanitize";
|
||||
|
||||
async function LayoutPanel({ children }) {
|
||||
const user = await getUser();
|
||||
@@ -22,7 +23,8 @@ async function LayoutPanel({ children }) {
|
||||
const accessToken = cookieStore.get("access_token");
|
||||
|
||||
if (userInfo && accessToken) {
|
||||
const parsedUserInfo = JSON.parse(userInfo.value);
|
||||
const parsedUserInfo = safeJsonParse(userInfo.value);
|
||||
if (!parsedUserInfo) return;
|
||||
const representationUuid = parsedUserInfo?.representation_uuid;
|
||||
|
||||
if (representationUuid) {
|
||||
|
||||
@@ -199,8 +199,13 @@ export default function PaymentDetailsPage() {
|
||||
<>
|
||||
<button
|
||||
onClick={() => {
|
||||
const paymentUrl = `${process.env.NEXT_PUBLIC_API_URL}/payment/${payment.uuid}`;
|
||||
window.location.href = paymentUrl;
|
||||
try {
|
||||
const apiOrigin = new URL(process.env.NEXT_PUBLIC_API_URL).origin;
|
||||
const paymentUrl = new URL(`/payment/${payment.uuid}`, apiOrigin);
|
||||
if (paymentUrl.origin === apiOrigin) {
|
||||
window.location.href = paymentUrl.href;
|
||||
}
|
||||
} catch {}
|
||||
}}
|
||||
className="flex-1 bg-[#5559CE] hover:bg-[#4448b3] text-white font-bold py-3 px-6 rounded-lg transition-colors"
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user