diff --git a/package-lock.json b/package-lock.json
index faec7c3..122d218 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -18,6 +18,7 @@
"@types/axios": "^0.9.36",
"@types/date-fns": "^2.5.3",
"@types/http-status-codes": "^1.2.0",
+ "@types/js-cookie": "^3.0.6",
"axios": "^1.12.2",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
@@ -25,6 +26,7 @@
"date-fns": "^4.1.0",
"emoji-picker-react": "^4.13.2",
"http-status-codes": "^2.3.0",
+ "js-cookie": "^3.0.5",
"lexical": "^0.34.0",
"lucide-react": "^0.541.0",
"next": "15.5.0",
@@ -1990,6 +1992,12 @@
"http-status-codes": "*"
}
},
+ "node_modules/@types/js-cookie": {
+ "version": "3.0.6",
+ "resolved": "https://registry.npmjs.org/@types/js-cookie/-/js-cookie-3.0.6.tgz",
+ "integrity": "sha512-wkw9yd1kEXOPnvEeEV1Go1MmxtBJL0RR79aOTAApecWFVu7w0NNXNqhcWgvw2YgZDYadliXkl14pa3WXw5jlCQ==",
+ "license": "MIT"
+ },
"node_modules/@types/mdast": {
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz",
@@ -2810,6 +2818,15 @@
"jiti": "lib/jiti-cli.mjs"
}
},
+ "node_modules/js-cookie": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.5.tgz",
+ "integrity": "sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=14"
+ }
+ },
"node_modules/lexical": {
"version": "0.34.0",
"resolved": "https://registry.npmjs.org/lexical/-/lexical-0.34.0.tgz",
diff --git a/package.json b/package.json
index c515807..c8216fb 100644
--- a/package.json
+++ b/package.json
@@ -21,6 +21,7 @@
"@types/axios": "^0.9.36",
"@types/date-fns": "^2.5.3",
"@types/http-status-codes": "^1.2.0",
+ "@types/js-cookie": "^3.0.6",
"axios": "^1.12.2",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
@@ -28,6 +29,7 @@
"date-fns": "^4.1.0",
"emoji-picker-react": "^4.13.2",
"http-status-codes": "^2.3.0",
+ "js-cookie": "^3.0.5",
"lexical": "^0.34.0",
"lucide-react": "^0.541.0",
"next": "15.5.0",
diff --git a/src/app/api/user/route.ts b/src/app/api/user/route.ts
index 219739b..dbbfc46 100644
--- a/src/app/api/user/route.ts
+++ b/src/app/api/user/route.ts
@@ -33,14 +33,36 @@ export async function POST(req: NextRequest) {
return NextResponse.json({ message: "ok", token, user_id: result.rows[0].id });
}
+export async function GET(req: NextRequest) {
+ const url = new URL(req.url);
+ let query_id = url.searchParams.get("id");
+ const token = url.searchParams.get("token");
+
+ if (!query_id && !token)
+ return NextResponse.json({ message: "Query arg should be token or id" }, { status: StatusCodes.BAD_REQUEST });
+ else {
+ const id = query_id ? query_id : token ? CLIENT_AUTH_TOKENS[token] : null;
+
+ if (!id)
+ return NextResponse.json({ message: "Invalid token" }, { status: StatusCodes.NOT_FOUND });
+
+ const user = await pool.query(
+ "SELECT id, username, email FROM users WHERE id = $1;",
+ [id]
+ );
+
+ return NextResponse.json({ message: "ok", ...user.rows[0] });
+ }
+}
+
export async function DELETE(req: NextRequest) {
let { username } = await req.json();
-
+
await pool.query(
"DELETE FROM users WHERE username = $1;",
[username]
);
-
+
return NextResponse.json({ message: "ok" });
}
diff --git a/src/app/login/page.tsx b/src/app/login/page.tsx
new file mode 100644
index 0000000..95e3ac5
--- /dev/null
+++ b/src/app/login/page.tsx
@@ -0,0 +1,7 @@
+import { Input } from "@/components/ui/input";
+
+export default function Login() {
+ return
+
+
+}
\ No newline at end of file
diff --git a/src/app/server/[id]/page.tsx b/src/app/server/[id]/page.tsx
index b935e0b..a93b503 100644
--- a/src/app/server/[id]/page.tsx
+++ b/src/app/server/[id]/page.tsx
@@ -4,62 +4,69 @@ import { useEffect, useRef, useState } from "react";
import { useParams } from "next/navigation";
import MessageBox from "@/components/MessageBox";
import AppSidebar from "@/components/Sidebar";
-import { getUser } from '@/test/user';
-import { auth } from '@/test/auth';
import Message from "@/types/message";
+import getUser from "@/hooks/get-user";
+import Cookies from "js-cookie";
+import axios from "axios";
export default function Server() {
- const { id } = useParams<{ id: string }>();
+ const { id: ip } = useParams<{ id: string }>();
const wsRef = useRef(null);
const [messages, setMessages] = useState([]);
+ const user = getUser();
useEffect(() => {
- if (!id) return;
+ if (!ip || !user) return;
- getUser().then(session_token => {
- auth(session_token, id === 'localhost' ? '127.0.0.1' : id).then(server_auth => {
- // Open the WebSocket connection
- const ws = new WebSocket(`ws://${id}:7080`);
- wsRef.current = ws;
-
- ws.onopen = () => {
- console.log("Connected to WebSocket:", id);
- ws.send(JSON.stringify({
- version: '0.0.1',
- auth_token: server_auth,
- last_message: 0
- }))
- };
-
- ws.onmessage = (m) => {
- const data = JSON.parse(m.data);
- console.log("Message received:", data);
+ async function auth() {
+ const server_auth = ((await axios.post('http://localhost:3000/api/auth', {
+ server_ip: ip === 'localhost' ? '127.0.0.1' : ip,
+ session_token: Cookies.get('token'),
+ })).data as any).token;
- switch (data.type) {
- case 'authenticated':
- setMessages(data.params.messages);
-
- case 'message_create':
- // setMessages([...messages, data.params]);
- setMessages((prev) => [...prev, data.params]);
- }
- };
-
- ws.onerror = (err) => {
- console.error("WebSocket error:", err);
- };
-
- ws.onclose = () => {
- console.log("WebSocket closed:", id);
- };
-
- // Cleanup on unmount or id change
- return () => {
- ws.close();
- };
- });
- })
- }, [id]);
+ // Open the WebSocket connection
+ const ws = new WebSocket(`ws://${ip}:7080`);
+ wsRef.current = ws;
+
+ ws.onopen = () => {
+ console.log("Connected to WebSocket:", ip);
+ ws.send(JSON.stringify({
+ version: '0.0.1',
+ auth_token: server_auth,
+ last_message: 0
+ }))
+ };
+
+ ws.onmessage = (m) => {
+ const data = JSON.parse(m.data);
+ console.log("Message received:", data);
+
+ switch (data.type) {
+ case 'authenticated':
+ setMessages(data.params.messages);
+
+ case 'message_create':
+ // setMessages([...messages, data.params]);
+ setMessages((prev) => [...prev, data.params]);
+ }
+ };
+
+ ws.onerror = (err) => {
+ console.error("WebSocket error:", err);
+ };
+
+ ws.onclose = () => {
+ console.log("WebSocket closed:", ip);
+ };
+
+ // Cleanup on unmount or id change
+ return () => {
+ ws.close();
+ };
+ }
+
+ auth();
+ }, [ip]);
return (
();
+
+ useEffect(() => {
+ async function fetchUser() {
+ const token = Cookies.get("token");
+
+ if (!token) {
+ redirect('/login')
+ }
+
+ const res = (await axios.get('http://localhost:3000/api/user', {
+ params: { token }
+ })).data as User;
+
+ setUser(res);
+ }
+
+ fetchUser();
+ });
+
+ return user;
+}
diff --git a/src/lib/api-wrapper/auth.ts b/src/lib/api-wrapper/auth.ts
new file mode 100644
index 0000000..733b931
--- /dev/null
+++ b/src/lib/api-wrapper/auth.ts
@@ -0,0 +1,10 @@
+import axios from "axios";
+
+export async function auth(session_token: string, server_ip: string) {
+ const res = (await axios.post('http://localhost:3000/api/auth', {
+ server_ip,
+ session_token,
+ })).data;
+
+ return (res as any).token;
+}
diff --git a/src/test/user.js b/src/lib/api-wrapper/user.ts
similarity index 100%
rename from src/test/user.js
rename to src/lib/api-wrapper/user.ts
diff --git a/src/test/auth.js b/src/test/auth.js
deleted file mode 100644
index b5539bc..0000000
--- a/src/test/auth.js
+++ /dev/null
@@ -1,19 +0,0 @@
-import axios from "axios";
-import { getUser } from "./user.js";
-
-export async function auth(session_token, server_ip) {
- const res = (await axios.post('http://localhost:3000/api/auth', {
- server_ip,
- session_token,
- })).data;
-
- return res.token;
-}
-
-// const session_token = await getUser();
-
-// const token = await auth(session_token);
-
-// const output = (await axios.get('http://localhost:3000/api/auth?intents=server&token='+token)).data;
-
-// console.log(output);
\ No newline at end of file