From b629b9a6e283cad53b9bdf3fa3a033354cc78819 Mon Sep 17 00:00:00 2001 From: Leo dev Date: Tue, 23 Dec 2025 15:01:26 +0100 Subject: [PATCH] Testing new supabase structure --- package-lock.json | 155 ++++++++++++++++++++---------------- package.json | 3 +- src/actions/get-profile.ts | 19 +++++ src/actions/get-session.ts | 14 ++++ src/actions/login-server.ts | 18 +++++ src/app/auth/Login.tsx | 17 ++-- src/hooks/get-user.ts | 23 +++--- src/lib/supa.ts | 24 ++++++ 8 files changed, 179 insertions(+), 94 deletions(-) create mode 100644 src/actions/get-profile.ts create mode 100644 src/actions/get-session.ts create mode 100644 src/actions/login-server.ts create mode 100644 src/lib/supa.ts diff --git a/package-lock.json b/package-lock.json index 6a01c88..1bea6d6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,6 +22,7 @@ "@radix-ui/react-slot": "^1.2.3", "@radix-ui/react-tabs": "^1.1.13", "@radix-ui/react-tooltip": "^1.2.8", + "@supabase/ssr": "^0.8.0", "@supabase/supabase-js": "^2.75.0", "@types/axios": "^0.9.36", "@types/date-fns": "^2.5.3", @@ -53,7 +54,7 @@ }, "devDependencies": { "@tailwindcss/postcss": "^4", - "@types/node": "^20.19.21", + "@types/node": "^20.19.27", "@types/pg": "^8.15.5", "@types/react": "^19", "@types/react-dom": "^19", @@ -1918,77 +1919,95 @@ "license": "MIT" }, "node_modules/@supabase/auth-js": { - "version": "2.75.0", - "resolved": "https://registry.npmjs.org/@supabase/auth-js/-/auth-js-2.75.0.tgz", - "integrity": "sha512-J8TkeqCOMCV4KwGKVoxmEBuDdHRwoInML2vJilthOo7awVCro2SM+tOcpljORwuBQ1vHUtV62Leit+5wlxrNtw==", + "version": "2.89.0", + "resolved": "https://registry.npmjs.org/@supabase/auth-js/-/auth-js-2.89.0.tgz", + "integrity": "sha512-wiWZdz8WMad8LQdJMWYDZ2SJtZP5MwMqzQq3ehtW2ngiI3UTgbKiFrvMUUS3KADiVlk4LiGfODB2mrYx7w2f8w==", "license": "MIT", "dependencies": { - "@supabase/node-fetch": "2.6.15" + "tslib": "2.8.1" + }, + "engines": { + "node": ">=20.0.0" } }, "node_modules/@supabase/functions-js": { - "version": "2.75.0", - "resolved": "https://registry.npmjs.org/@supabase/functions-js/-/functions-js-2.75.0.tgz", - "integrity": "sha512-18yk07Moj/xtQ28zkqswxDavXC3vbOwt1hDuYM3/7xPnwwpKnsmPyZ7bQ5th4uqiJzQ135t74La9tuaxBR6e7w==", + "version": "2.89.0", + "resolved": "https://registry.npmjs.org/@supabase/functions-js/-/functions-js-2.89.0.tgz", + "integrity": "sha512-XEueaC5gMe5NufNYfBh9kPwJlP5M2f+Ogr8rvhmRDAZNHgY6mI35RCkYDijd92pMcNM7g8pUUJov93UGUnqfyw==", "license": "MIT", "dependencies": { - "@supabase/node-fetch": "2.6.15" - } - }, - "node_modules/@supabase/node-fetch": { - "version": "2.6.15", - "resolved": "https://registry.npmjs.org/@supabase/node-fetch/-/node-fetch-2.6.15.tgz", - "integrity": "sha512-1ibVeYUacxWYi9i0cf5efil6adJ9WRyZBLivgjs+AUpewx1F3xPi7gLgaASI2SmIQxPoCEjAsLAzKPgMJVgOUQ==", - "license": "MIT", - "dependencies": { - "whatwg-url": "^5.0.0" + "tslib": "2.8.1" }, "engines": { - "node": "4.x || >=6.0.0" + "node": ">=20.0.0" } }, "node_modules/@supabase/postgrest-js": { - "version": "2.75.0", - "resolved": "https://registry.npmjs.org/@supabase/postgrest-js/-/postgrest-js-2.75.0.tgz", - "integrity": "sha512-YfBz4W/z7eYCFyuvHhfjOTTzRrQIvsMG2bVwJAKEVVUqGdzqfvyidXssLBG0Fqlql1zJFgtsPpK1n4meHrI7tg==", + "version": "2.89.0", + "resolved": "https://registry.npmjs.org/@supabase/postgrest-js/-/postgrest-js-2.89.0.tgz", + "integrity": "sha512-/b0fKrxV9i7RNOEXMno/I1862RsYhuUo+Q6m6z3ar1f4ulTMXnDfv0y4YYxK2POcgrOXQOgKYQx1eArybyNvtg==", "license": "MIT", "dependencies": { - "@supabase/node-fetch": "2.6.15" + "tslib": "2.8.1" + }, + "engines": { + "node": ">=20.0.0" } }, "node_modules/@supabase/realtime-js": { - "version": "2.75.0", - "resolved": "https://registry.npmjs.org/@supabase/realtime-js/-/realtime-js-2.75.0.tgz", - "integrity": "sha512-B4Xxsf2NHd5cEnM6MGswOSPSsZKljkYXpvzKKmNxoUmNQOfB7D8HOa6NwHcUBSlxcjV+vIrYKcYXtavGJqeGrw==", + "version": "2.89.0", + "resolved": "https://registry.npmjs.org/@supabase/realtime-js/-/realtime-js-2.89.0.tgz", + "integrity": "sha512-aMOvfDb2a52u6PX6jrrjvACHXGV3zsOlWRzZsTIOAJa0hOVvRp01AwC1+nLTGUzxzezejrYeCX+KnnM1xHdl+w==", "license": "MIT", "dependencies": { - "@supabase/node-fetch": "2.6.15", "@types/phoenix": "^1.6.6", "@types/ws": "^8.18.1", + "tslib": "2.8.1", "ws": "^8.18.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@supabase/ssr": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@supabase/ssr/-/ssr-0.8.0.tgz", + "integrity": "sha512-/PKk8kNFSs8QvvJ2vOww1mF5/c5W8y42duYtXvkOSe+yZKRgTTZywYG2l41pjhNomqESZCpZtXuWmYjFRMV+dw==", + "license": "MIT", + "dependencies": { + "cookie": "^1.0.2" + }, + "peerDependencies": { + "@supabase/supabase-js": "^2.76.1" } }, "node_modules/@supabase/storage-js": { - "version": "2.75.0", - "resolved": "https://registry.npmjs.org/@supabase/storage-js/-/storage-js-2.75.0.tgz", - "integrity": "sha512-wpJMYdfFDckDiHQaTpK+Ib14N/O2o0AAWWhguKvmmMurB6Unx17GGmYp5rrrqCTf8S1qq4IfIxTXxS4hzrUySg==", + "version": "2.89.0", + "resolved": "https://registry.npmjs.org/@supabase/storage-js/-/storage-js-2.89.0.tgz", + "integrity": "sha512-6zKcXofk/M/4Eato7iqpRh+B+vnxeiTumCIP+Tz26xEqIiywzD9JxHq+udRrDuv6hXE+pmetvJd8n5wcf4MFRQ==", "license": "MIT", "dependencies": { - "@supabase/node-fetch": "2.6.15" + "iceberg-js": "^0.8.1", + "tslib": "2.8.1" + }, + "engines": { + "node": ">=20.0.0" } }, "node_modules/@supabase/supabase-js": { - "version": "2.75.0", - "resolved": "https://registry.npmjs.org/@supabase/supabase-js/-/supabase-js-2.75.0.tgz", - "integrity": "sha512-8UN/vATSgS2JFuJlMVr51L3eUDz+j1m7Ww63wlvHLKULzCDaVWYzvacCjBTLW/lX/vedI2LBI4Vg+01G9ufsJQ==", + "version": "2.89.0", + "resolved": "https://registry.npmjs.org/@supabase/supabase-js/-/supabase-js-2.89.0.tgz", + "integrity": "sha512-KlaRwSfFA0fD73PYVMHj5/iXFtQGCcX7PSx0FdQwYEEw9b2wqM7GxadY+5YwcmuEhalmjFB/YvqaoNVF+sWUlg==", "license": "MIT", "dependencies": { - "@supabase/auth-js": "2.75.0", - "@supabase/functions-js": "2.75.0", - "@supabase/node-fetch": "2.6.15", - "@supabase/postgrest-js": "2.75.0", - "@supabase/realtime-js": "2.75.0", - "@supabase/storage-js": "2.75.0" + "@supabase/auth-js": "2.89.0", + "@supabase/functions-js": "2.89.0", + "@supabase/postgrest-js": "2.89.0", + "@supabase/realtime-js": "2.89.0", + "@supabase/storage-js": "2.89.0" + }, + "engines": { + "node": ">=20.0.0" } }, "node_modules/@swc/helpers": { @@ -2353,9 +2372,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "20.19.21", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.21.tgz", - "integrity": "sha512-CsGG2P3I5y48RPMfprQGfy4JPRZ6csfC3ltBZSRItG3ngggmNY/qs2uZKp4p9VbrpqNNSMzUZNFZKzgOGnd/VA==", + "version": "20.19.27", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.27.tgz", + "integrity": "sha512-N2clP5pJhB2YnZJ3PIHFk5RkygRX5WO/5f0WC08tp0wd+sv0rsJk3MqWn3CbNmT2J505a5336jaQj4ph1AdMug==", "license": "MIT", "dependencies": { "undici-types": "~6.21.0" @@ -2374,9 +2393,9 @@ } }, "node_modules/@types/phoenix": { - "version": "1.6.6", - "resolved": "https://registry.npmjs.org/@types/phoenix/-/phoenix-1.6.6.tgz", - "integrity": "sha512-PIzZZlEppgrpoT2QgbnDU+MMzuR6BbCjllj0bM70lWoejMeNJAxCchxnv7J3XFkI8MpygtRpzXrIlmWUBclP5A==", + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/@types/phoenix/-/phoenix-1.6.7.tgz", + "integrity": "sha512-oN9ive//QSBkf19rfDv45M7eZPi0eEXylht2OLEXicu5b4KoQ1OzXIw+xDSGWxSxe1JmepRR/ZH283vsu518/Q==", "license": "MIT" }, "node_modules/@types/react": { @@ -2687,6 +2706,19 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/cookie": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz", + "integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, "node_modules/csstype": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", @@ -3140,6 +3172,15 @@ "integrity": "sha512-RJ8XvFvpPM/Dmc5SV+dC4y5PCeOhT3x1Hq0NU3rjGeg5a/CqlhZ7uudknPwZFz4aeAXDcbAyaeP7GAo9lvngtA==", "license": "MIT" }, + "node_modules/iceberg-js": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/iceberg-js/-/iceberg-js-0.8.1.tgz", + "integrity": "sha512-1dhVQZXhcHje7798IVM+xoo/1ZdVfzOMIc8/rgVSijRK38EDqOJoGula9N/8ZI5RD8QTxNQtK/Gozpr+qUqRRA==", + "license": "MIT", + "engines": { + "node": ">=20.0.0" + } + }, "node_modules/inline-style-parser": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.4.tgz", @@ -5221,12 +5262,6 @@ "node": ">=18" } }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "license": "MIT" - }, "node_modules/trim-lines": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", @@ -5463,22 +5498,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "license": "BSD-2-Clause" - }, - "node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "license": "MIT", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, "node_modules/ws": { "version": "8.18.3", "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", diff --git a/package.json b/package.json index 8909f37..d89a45b 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "@radix-ui/react-slot": "^1.2.3", "@radix-ui/react-tabs": "^1.1.13", "@radix-ui/react-tooltip": "^1.2.8", + "@supabase/ssr": "^0.8.0", "@supabase/supabase-js": "^2.75.0", "@types/axios": "^0.9.36", "@types/date-fns": "^2.5.3", @@ -56,7 +57,7 @@ }, "devDependencies": { "@tailwindcss/postcss": "^4", - "@types/node": "^20.19.21", + "@types/node": "^20.19.27", "@types/pg": "^8.15.5", "@types/react": "^19", "@types/react-dom": "^19", diff --git a/src/actions/get-profile.ts b/src/actions/get-profile.ts new file mode 100644 index 0000000..168878d --- /dev/null +++ b/src/actions/get-profile.ts @@ -0,0 +1,19 @@ +"use server"; + +import createClient from "@/lib/supa"; + +export async function getProfileById(id: string) { + const supabase = await createClient(); + + const { error, data } = await supabase + .from("profiles") + .select("id, username, display_name, avatar_url, node_address") + .eq("id", id) + .maybeSingle(); + + if (error) { + throw error; + } + + return data; +} diff --git a/src/actions/get-session.ts b/src/actions/get-session.ts new file mode 100644 index 0000000..6b2bc78 --- /dev/null +++ b/src/actions/get-session.ts @@ -0,0 +1,14 @@ +"use server"; + +import createClient from "@/lib/supa"; + +export default async function getSession() { + const supabase = await createClient(); + const { error, data } = await supabase.auth.getSession(); + + if (error) { + throw error; + } + + return data.session?.user.id; +} diff --git a/src/actions/login-server.ts b/src/actions/login-server.ts new file mode 100644 index 0000000..c0d2063 --- /dev/null +++ b/src/actions/login-server.ts @@ -0,0 +1,18 @@ +"use server"; + +import createClient from "@/lib/supa"; + +export default async function loginServer(email: string, password: string) { + const supabase = await createClient(); + + const { data, error } = await supabase.auth.signInWithPassword({ + email, + password, + }); + + if (error) { + throw new Error(error.message); + } + + return data.user; +} diff --git a/src/app/auth/Login.tsx b/src/app/auth/Login.tsx index b5419d9..fb20e6c 100644 --- a/src/app/auth/Login.tsx +++ b/src/app/auth/Login.tsx @@ -2,32 +2,25 @@ import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; -import axios from "axios"; import { useState } from "react"; -import Cookies from "js-cookie"; import { useRouter } from "next/navigation"; import { CardContent, CardHeader, CardTitle } from "@/components/ui/card"; +import loginServer from "@/actions/login-server"; + +type Feedback = { kind: "error" | "info"; message: string }; export default function Login() { const [email, setEmail] = useState(""); const [password, setPassword] = useState(""); - const [feedback, setFeedback] = useState< - undefined | { kind: "error" | "info"; message: string } - >(); + const [feedback, setFeedback] = useState(); const router = useRouter(); const login = async () => { - localStorage.removeItem("chat-messages"); - localStorage.removeItem("server-messages"); setFeedback(undefined); try { - const res = await axios.get("/api/user", { - params: { email, password }, - }); + const res = await loginServer(email, password); - Cookies.set("token", (res.data as any).token); - Cookies.set("refresh_token", (res.data as any).refresh_token); setFeedback({ kind: "info", message: "Login successful! Redirecting...", diff --git a/src/hooks/get-user.ts b/src/hooks/get-user.ts index 71f990f..98fe782 100644 --- a/src/hooks/get-user.ts +++ b/src/hooks/get-user.ts @@ -7,6 +7,8 @@ import { useEffect, useState } from "react"; import { get } from "@/lib/request"; import { toast } from "sonner"; import axios from "axios"; +import getSession from "@/actions/get-session"; +import { getProfileById } from "@/actions/get-profile"; export interface UserProfile extends ProfileSettings { id: string; @@ -19,20 +21,15 @@ export default function useUser() { useEffect(() => { async function fetchUser() { try { - setUser((await get("/api/profile", (r) => setUser(r.data))).data); - } catch (e: any) { - try { - console.log("Failed to obtain current user, refreshing token.."); - const refresh = await axios.put("/api/auth/"); - const { access_token, refresh_token } = refresh.data as any; - Cookies.set("token", access_token); - Cookies.set("refresh_token", refresh_token); - - setUser((await get("/api/profile", (r) => setUser(r.data))).data); - } catch (e: any) { - router.push("/auth?t=login"); - toast.error(`Error: ${e}`); + const user_id = await getSession(); + if (!user_id) { + throw new Error("Session user id is not valid"); } + + setUser(await getProfileById(user_id)); + } catch (e: any) { + router.push("/auth?t=login"); + toast.error(`Error: ${e}`); } } diff --git a/src/lib/supa.ts b/src/lib/supa.ts new file mode 100644 index 0000000..5c7f41e --- /dev/null +++ b/src/lib/supa.ts @@ -0,0 +1,24 @@ +import { cookies } from "next/headers"; +import { createServerClient } from "@supabase/ssr"; + +export default async function createClient() { + const cookieStore = await cookies(); + + return createServerClient( + process.env.NEXT_PUBLIC_SUPABASE_URL!, + process.env.SUPABASE_SERVICE_ROLE_KEY!, + { + cookies: { + get(name) { + return cookieStore.get(name)?.value; + }, + set(name, value) { + cookieStore.set(name, value); + }, + remove(name) { + cookieStore.delete(name); + }, + }, + } + ); +}