Working auth (hopefully)

This commit is contained in:
2025-10-13 23:41:54 +02:00
parent a5edc7677c
commit 7f8482dc5a
3 changed files with 37 additions and 43 deletions
+28 -19
View File
@@ -4,24 +4,36 @@ import { supabase } from "../supa";
const SERVER_AUTH_TOKENS = new Map< const SERVER_AUTH_TOKENS = new Map<
string, string,
{ user_id: string; server_ip: string } { user_id: string; server_id: string }
>(); >();
/** /**
* GET /api/auth?token=<relayToken> * GET /api/auth?token=<relayToken>?key=<serverKey>
* Called by a (DM node / Server) to verify a temporary relay token. * Called by a (DM node / Server) to verify a temporary relay token.
*/ */
export async function GET(req: NextRequest) { export async function GET(req: NextRequest) {
const url = new URL(req.url); const url = new URL(req.url);
const token = url.searchParams.get("token"); const token = url.searchParams.get("token");
const key = url.searchParams.get("key");
if (!token) { if (!token || !key) {
return NextResponse.json( return NextResponse.json(
{ message: "There should be a token parameter" }, { message: "There should be a token and a key parameter" },
{ status: StatusCodes.BAD_REQUEST } { status: StatusCodes.BAD_REQUEST }
); );
} }
const { data: server } = await supabase
.from("servers")
.select("id, created_at, owner, address")
.eq("key", key)
.maybeSingle();
if (!server)
return NextResponse.json(
{ message: "Key unauthorized" },
{ status: StatusCodes.UNAUTHORIZED }
);
const auth = SERVER_AUTH_TOKENS.get(token); const auth = SERVER_AUTH_TOKENS.get(token);
if (!auth) { if (!auth) {
return NextResponse.json( return NextResponse.json(
@@ -30,19 +42,11 @@ export async function GET(req: NextRequest) {
); );
} }
const ip = if (auth.server_id !== server.id)
req.headers.get("x-real-ip") ||
req.headers.get("x-forwarded-for")?.split(",")[0] ||
"127.0.0.1";
console.log("Auth request from IP:", ip);
if (auth.server_ip !== ip && ip !== "::1") {
return NextResponse.json( return NextResponse.json(
{ message: "Invalid address" }, { message: "Invalid id" },
{ status: StatusCodes.UNAUTHORIZED } { status: StatusCodes.UNAUTHORIZED }
); );
}
SERVER_AUTH_TOKENS.delete(token); SERVER_AUTH_TOKENS.delete(token);
@@ -53,19 +57,24 @@ export async function GET(req: NextRequest) {
* POST /api/auth * POST /api/auth
* Called by the client to request a temporary relay token for a DM server. * Called by the client to request a temporary relay token for a DM server.
* *
* Body: { server_ip: string } * Body: { server_id: string }
* Header: Authorization: Bearer <supabase_jwt> * Header: Authorization: Bearer <supabase_jwt>
*/ */
export async function POST(req: NextRequest) { export async function POST(req: NextRequest) {
const { server_ip } = await req.json(); const { server_id } = await req.json();
const authHeader = req.cookies.get("token"); const authHeader = req.cookies.get("token");
if (!authHeader) { if (!server_id)
return NextResponse.json(
{ message: "Missing server_id in the json body" },
{ status: StatusCodes.BAD_REQUEST }
);
if (!authHeader)
return NextResponse.json( return NextResponse.json(
{ message: "Missing Supabase Authorization header" }, { message: "Missing Supabase Authorization header" },
{ status: StatusCodes.BAD_REQUEST } { status: StatusCodes.BAD_REQUEST }
); );
}
const supabaseToken = authHeader.value; const supabaseToken = authHeader.value;
@@ -85,7 +94,7 @@ export async function POST(req: NextRequest) {
SERVER_AUTH_TOKENS.set(relayToken, { SERVER_AUTH_TOKENS.set(relayToken, {
user_id: user.id, user_id: user.id,
server_ip: String(server_ip), server_id,
}); });
return NextResponse.json({ message: "ok", token: relayToken }); return NextResponse.json({ message: "ok", token: relayToken });
+1 -3
View File
@@ -5,7 +5,6 @@ import {
MessageCircle, MessageCircle,
Plus, Plus,
Search, Search,
SettingsIcon,
Volume2Icon, Volume2Icon,
} from "lucide-react"; } from "lucide-react";
import { Server, Channel, Message } from "@/types/types"; import { Server, Channel, Message } from "@/types/types";
@@ -27,10 +26,9 @@ import { Button } from "./ui/button";
import { Card } from "./ui/card"; import { Card } from "./ui/card";
import { ScrollArea } from "./ui/scroll-area"; import { ScrollArea } from "./ui/scroll-area";
import { useRouter } from "next/navigation"; import { useRouter } from "next/navigation";
import Link from "next/link";
import useUser, { UserProfile } from "@/hooks/get-user"; import useUser, { UserProfile } from "@/hooks/get-user";
import ProfilePicture from "./ProfilePicture"; import ProfilePicture from "./ProfilePicture";
import auth, { makeAddress } from "@/lib/auth"; import auth from "@/lib/auth";
import { toast } from "sonner"; import { toast } from "sonner";
import { StringMap } from "@/types/typeUtils"; import { StringMap } from "@/types/typeUtils";
import SettingsDialog from "./settings/SettingsDialog"; import SettingsDialog from "./settings/SettingsDialog";
+8 -21
View File
@@ -2,34 +2,21 @@ import { Message, Server } from "@/types/types";
import axios from "axios"; import axios from "axios";
import { Dispatch, RefObject, SetStateAction } from "react"; import { Dispatch, RefObject, SetStateAction } from "react";
async function getIP(domain: string) {
const res = await fetch(`https://dns.google/resolve?name=${domain}&type=A`);
const data = await res.json();
return data.Answer[0]?.data || null;
}
export async function makeAddress(ip: string, defaultPort = 7080) {
// Apparently wss doesn't like ports (or maybe the tunnel I'm using)
// return ip.includes(":") ? `${ip}` : `${ip}:${defaultPort}`;
if (ip.match(/^\d\.\d\.\d\.\d/)) {
return ip;
}
return await getIP(ip);
}
export default async function auth( export default async function auth(
ip: string, id: string,
wsRef: RefObject<WebSocket | null>, wsRef: RefObject<WebSocket | null>,
setServer: Dispatch<SetStateAction<Server | undefined>>, setServer: Dispatch<SetStateAction<Server | undefined>>,
setMessages: Dispatch<SetStateAction<Message[]>>, setMessages: Dispatch<SetStateAction<Message[]>>,
onNewMessage?: (m: Message) => void onNewMessage?: (m: Message) => void
) { ) {
console.log("Authenticating with server id:", id);
const ip = ((await axios.get(`/api/server/${id}`)).data as any)
.address as string;
console.log("Authenticating with server at:", ip); console.log("Authenticating with server at:", ip);
const server_auth = ( const server_auth = ((await axios.post("/api/auth", { id })).data as any)
(await axios.post("/api/auth", { server_ip: await makeAddress(ip) })) .token;
.data as any
).token;
// Open the WebSocket connection // Open the WebSocket connection
const ws = new WebSocket(`wss://${ip}`); const ws = new WebSocket(`wss://${ip}`);