diff --git a/app/SyncOnFirstLoad.tsx b/app/SyncOnFirstLoad.tsx index b2afd5db7..f3ff0f9a9 100644 --- a/app/SyncOnFirstLoad.tsx +++ b/app/SyncOnFirstLoad.tsx @@ -1,13 +1,53 @@ "use client"; import { useEffect } from "react"; import { useSyncStore } from "./store/sync"; - +import { showToast } from "./components/ui-lib"; +import { AUTHEN_PAGE } from "./constant"; export default function SyncOnFirstLoad() { const syncStore = useSyncStore(); useEffect(() => { - // Parse cookies using the custom function - // syncStore.sync(); + // Parse cookies using the cookie library + // const cookies = cookie.parse(document.cookie || ""); + // const authToken = cookies["sb-zzgkylsbdgwoohcbompi-auth-token"] || null; + + console.log("[Auth Check] Checking user authentication status"); + + fetch("/api/auth/check") + .then((res) => { + if (res.status === 401) { + console.log("[Auth Check] User is not authenticated"); + // Handle unauthenticated user - redirect or show login modal + + showToast("Please login first"); + + setTimeout(() => { + window.location.href = AUTHEN_PAGE; + }, 500); + return; + } + + return res.json(); + }) + .then((data) => { + if (data) { + console.log("[Auth Check] User is authenticated:", data.user); + + // Assuming data.user contains the user information(user email) + const email = data.user.email || ""; + + // Only update upstash.username, keep other params + syncStore.update((config) => (config.upstash.username = email)); + + // You can now use the user data as needed + // syncStore.sync(); + // console.log("[Sync] User data synced successfully"); + } + }) + .catch((e) => { + console.error("[Auth Check] Error checking authentication:", e); + // Handle error appropriately + }); }, []); return null; diff --git a/app/api/[provider]/[...path]/route.ts b/app/api/[provider]/[...path]/route.ts index 9d5816d82..182862289 100644 --- a/app/api/[provider]/[...path]/route.ts +++ b/app/api/[provider]/[...path]/route.ts @@ -15,7 +15,6 @@ import { handle as siliconflowHandler } from "../../siliconflow"; import { handle as xaiHandler } from "../../xai"; import { handle as chatglmHandler } from "../../glm"; import { handle as proxyHandler } from "../../proxy"; -import { handle as supabaseHandler } from "../../supabase"; async function handle( req: NextRequest, @@ -28,9 +27,6 @@ async function handle( console.log(`[${params.provider} Route] params `, params); switch (apiPath) { - case ApiPath.Supabase: - console.log("[Supabase Route] params ", params); - return supabaseHandler(req, { params }); case ApiPath.Azure: return azureHandler(req, { params }); case ApiPath.Google: diff --git a/app/api/auth/check/route.ts b/app/api/auth/check/route.ts new file mode 100644 index 000000000..63fbfa9bc --- /dev/null +++ b/app/api/auth/check/route.ts @@ -0,0 +1,21 @@ +// /app/api/auth/check/route.ts +import { NextRequest } from "next/server"; +import { checkAuth } from "../../supabase"; + +export async function GET(req: NextRequest) { + const user = await checkAuth(req); + + console.log("[Auth] user ", user); + + if (!user) { + return new Response(JSON.stringify({ authenticated: false }), { + status: 401, + headers: { "Content-Type": "application/json" }, + }); + } + + return new Response(JSON.stringify({ authenticated: true, user }), { + status: 200, + headers: { "Content-Type": "application/json" }, + }); +} diff --git a/app/api/common.ts b/app/api/common.ts index 42d9f4aa7..64f4c9464 100644 --- a/app/api/common.ts +++ b/app/api/common.ts @@ -30,14 +30,17 @@ export async function requestOpenai(req: NextRequest) { authHeaderName = "api-key"; } else { // Nếu là OpenAI thường, giữ nguyên header Authorization + authValue = req.headers.get("Authorization") ?? ""; authHeaderName = "Authorization"; + + console.log("[Auth] ", authValue); } // Xử lý lại đường dẫn endpoint cho phù hợp với OpenAI/Azure let path = `${req.nextUrl.pathname}`.replaceAll("/api/openai/", ""); - console.log("[Proxy] mac dinh ", path); + // console.log("[Proxy] mac dinh ", path); // Lấy baseUrl từ config, ưu tiên Azure nếu là request Azure let baseUrl = diff --git a/app/api/supabase.ts b/app/api/supabase.ts index 28b80829f..3db90034d 100644 --- a/app/api/supabase.ts +++ b/app/api/supabase.ts @@ -1,23 +1,20 @@ import { createClient } from "@supabase/supabase-js"; -import { NextRequest, NextResponse } from "next/server"; -import cookie from "cookie"; +import { NextRequest } from "next/server"; const SUPABASE_URL = process.env.SUPABASE_URL!; const SUPABASE_ANON_KEY = process.env.SUPABASE_ANON_KEY!; -const AUTHEN_PAGE = process.env.AUTHEN_PAGE!; -export async function handle( - req: NextRequest, - { params }: { params: { path: string[] } }, -) { - // Parse cookies using the 'cookie' library - const cookies = cookie.parse(req.headers.get("cookie") || ""); - const authToken = cookies["sb-zzgkylsbdgwoohcbompi-auth-token"]; +export async function checkAuth(req: NextRequest) { + // Use NextRequest.cookies API + const authToken = req.cookies.get("sb-zzgkylsbdgwoohcbompi-auth-token") + ?.value; - console.log("[Supabase] authToken", authToken); + // console.log("[Supabase] authToken", authToken); if (!authToken) { - return NextResponse.redirect(AUTHEN_PAGE, 302); + // Không tìm thấy token xác thực + console.log("[Supabase] No auth token found"); + return null; } const supabase = createClient(SUPABASE_URL, SUPABASE_ANON_KEY, { @@ -31,21 +28,18 @@ export async function handle( try { const { data, error } = await supabase.auth.getUser(); - console.log("[Supabase] user", data?.user); - if (error || !data?.user) { - return NextResponse.json( - { error: error?.message || "Error fetching user data" }, - { status: 401 }, - ); + // Lỗi khi lấy thông tin người dùng + console.error("[Supabase] Error getting user:", error); + return null; } - return NextResponse.json({ user: data.user }, { status: 200 }); + // Đã xác thực thành công, trả về thông tin người dùng + console.log("[Supabase] Authenticated user:", data.user); + return data.user; } catch (err) { - console.error("Error fetching user data from Supabase:", err); - return NextResponse.json( - { error: "Internal server error" }, - { status: 500 }, - ); + // Lỗi khi lấy dữ liệu người dùng + console.error("[Supabase] Error fetching user data:", err); + return null; } } diff --git a/app/chebichatConstant.ts b/app/chebichatConstant.ts index 69593d7d4..b4e1513c8 100644 --- a/app/chebichatConstant.ts +++ b/app/chebichatConstant.ts @@ -5,3 +5,4 @@ export const UPSTASH_ENDPOINT = "https://fine-baboon-52580.upstash.io"; export const UPSTASH_APIKEY = "Ac1kAAIjcDE2YjM4YmY3OGI4YzA0MTU2YjZhNmQyNzc5Yzc3NzEwYnAxMA"; export const STORAGE_KEY = "chebichat-backup"; +export const AUTHEN_PAGE = "https://chinese.giahungtech.com.vn"; diff --git a/app/components/settings.tsx b/app/components/settings.tsx index 3eb47ce9c..38baffa12 100644 --- a/app/components/settings.tsx +++ b/app/components/settings.tsx @@ -529,6 +529,8 @@ function SyncItems() { setShowSyncConfigModal(true); }} /> + + {/* thuc hien dong bo voi cloud */} {couldSync && ( } diff --git a/app/components/sidebar.tsx b/app/components/sidebar.tsx index 2b09bee61..38fbfec73 100644 --- a/app/components/sidebar.tsx +++ b/app/components/sidebar.tsx @@ -29,13 +29,15 @@ import { import { Link, useNavigate } from "react-router-dom"; import { isIOS, useMobileScreen } from "../utils"; import dynamic from "next/dynamic"; -import { Selector, showConfirm } from "./ui-lib"; +import { Selector, showConfirm, showToast } from "./ui-lib"; import clsx from "clsx"; import { isMcpEnabled } from "../mcp/actions"; +import { useSyncStore } from "../store/sync"; const DISCOVERY = [ // { name: Locale.Plugin.Name, path: Path.Plugins }, // { name: "Stable Diffusion", path: Path.Sd }, + { name: Locale.UI.Sync, path: "/sync" }, { name: Locale.SearchChat.Page.Title, path: Path.SearchChat }, ]; @@ -233,6 +235,8 @@ export function SideBar(props: { className?: string }) { const chatStore = useChatStore(); const [mcpEnabled, setMcpEnabled] = useState(false); + const syncStore = useSyncStore(); + useEffect(() => { // 检查 MCP 是否启用 const checkMcpStatus = async () => { @@ -306,9 +310,20 @@ export function SideBar(props: { className?: string }) { }), ]} onClose={() => setshowDiscoverySelector(false)} - onSelection={(s) => { - // Điều hướng đến trang được chọn - navigate(s[0], { state: { fromHome: true } }); + onSelection={async (s) => { + console.log(s[0]); + if (s[0] == "/sync") { + try { + await syncStore.sync(); + console.log("Dong bo thanh cong "); + showToast(Locale.Settings.Sync.Success); + } catch (e) { + showToast(Locale.Settings.Sync.Fail); + console.error("[Sync]", e); + } + } else { + navigate(s[0], { state: { fromHome: true } }); + } }} /> )} diff --git a/app/constant.ts b/app/constant.ts index cf97cb0d3..53bd011bc 100644 --- a/app/constant.ts +++ b/app/constant.ts @@ -57,6 +57,7 @@ export enum Path { Artifacts = "/artifacts", SearchChat = "/search-chat", McpMarket = "/mcp-market", + Sync = "/sync", } export enum ApiPath { diff --git a/app/layout.tsx b/app/layout.tsx index 8f3d66c8c..000b497e8 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -37,7 +37,7 @@ export default function RootLayout({ const serverConfig = getServerSideConfig(); // Log server configuration for debugging - console.log("Server Configuration:"); + // console.log("Server Configuration:"); // console.log(serverConfig); return ( diff --git a/app/utils/chat.ts b/app/utils/chat.ts index 439c69d91..f52416447 100644 --- a/app/utils/chat.ts +++ b/app/utils/chat.ts @@ -35,10 +35,10 @@ export function compressImage(file: Blob, maxSize: number): Promise { if (dataUrl.length < maxSize) break; if (quality > 0.5) { - // Prioritize quality reduction + // Ưu tiên giảm chất lượng quality -= 0.1; } else { - // Then reduce the size + // Sau đó giảm kích thước width *= 0.9; height *= 0.9; } diff --git a/git.sh b/git.sh index ab7970f8f..e9335130e 100644 --- a/git.sh +++ b/git.sh @@ -2,7 +2,7 @@ # git config --global user.name "quangdn-ght" git add . -git commit -m "cap nhat giao dien" +git commit -m "Xu ly dong bo nguoi dung thanh cong" git push # mdZddHXcuzsB0Akk \ No newline at end of file diff --git a/package.json b/package.json index cfc31630b..fe7bdc1ff 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,6 @@ "@hello-pangea/dnd": "^16.5.0", "@modelcontextprotocol/sdk": "^1.0.4", "@next/third-parties": "^14.1.0", - "@supabase/auth-helpers-nextjs": "^0.10.0", "@supabase/ssr": "^0.6.1", "@supabase/supabase-js": "^2.50.1", "@svgr/webpack": "^6.5.1", diff --git a/yarn.lock b/yarn.lock index 0ad8fe446..dba15375c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2169,21 +2169,6 @@ dependencies: "@sinonjs/commons" "^3.0.0" -"@supabase/auth-helpers-nextjs@^0.10.0": - version "0.10.0" - resolved "https://registry.yarnpkg.com/@supabase/auth-helpers-nextjs/-/auth-helpers-nextjs-0.10.0.tgz#e831968f95e1bc44f400825d251a8b2fda97ee9f" - integrity sha512-2dfOGsM4yZt0oS4TPiE7bD4vf7EVz7NRz/IJrV6vLg0GP7sMUx8wndv2euLGq4BjN9lUCpu6DG/uCC8j+ylwPg== - dependencies: - "@supabase/auth-helpers-shared" "0.7.0" - set-cookie-parser "^2.6.0" - -"@supabase/auth-helpers-shared@0.7.0": - version "0.7.0" - resolved "https://registry.yarnpkg.com/@supabase/auth-helpers-shared/-/auth-helpers-shared-0.7.0.tgz#244a6b6ac39a5eb1bc8d69a57c25aa580cd0f669" - integrity sha512-FBFf2ei2R7QC+B/5wWkthMha8Ca2bWHAndN+syfuEUUfufv4mLcAgBCcgNg5nJR8L0gZfyuaxgubtOc9aW3Cpg== - dependencies: - jose "^4.14.4" - "@supabase/auth-js@2.70.0": version "2.70.0" resolved "https://registry.npmjs.org/@supabase/auth-js/-/auth-js-2.70.0.tgz" @@ -6447,11 +6432,6 @@ jest@^29.7.0: import-local "^3.0.2" jest-cli "^29.7.0" -jose@^4.14.4: - version "4.15.9" - resolved "https://registry.yarnpkg.com/jose/-/jose-4.15.9.tgz#9b68eda29e9a0614c042fa29387196c7dd800100" - integrity sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA== - "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz" @@ -8828,11 +8808,6 @@ serialize-javascript@^6.0.1: dependencies: randombytes "^2.1.0" -set-cookie-parser@^2.6.0: - version "2.7.1" - resolved "https://registry.yarnpkg.com/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz#3016f150072202dfbe90fadee053573cc89d2943" - integrity sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ== - setprototypeof@1.2.0: version "1.2.0" resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz"