Update user routing, added user authorization with JWT cookie management

This commit is contained in:
Hannah dagemark 2026-09-14 23:09:11 +02:00
commit f055e77eea
7 changed files with 97 additions and 10 deletions

View file

@ -1,7 +1,12 @@
const BACKEND_URL = process.env.BACKEND_URL; const BACKEND_URL = process.env.BACKEND_URL;
export async function POST(request: Request) { export async function POST(request: Request) {
const response = await fetch(`${BACKEND_URL}/users/auth`, request); const response = await fetch(`${BACKEND_URL}/users/auth`, {
method: "POST",
headers: request.headers,
body: request.body,
duplex: "half",
});
const data = await response.json(); const data = await response.json();

View file

@ -15,7 +15,12 @@ export async function GET() {
} }
export async function POST(request: Request) { export async function POST(request: Request) {
const response = await fetch(`${BACKEND_URL}/users`, request); const response = await fetch(`${BACKEND_URL}/users`, {
method: "POST",
headers: request.headers,
body: request.body,
duplex: "half",
});
const data = await response.json(); const data = await response.json();

View file

@ -1,7 +1,13 @@
const BACKEND_URL = process.env.BACKEND_URL; const BACKEND_URL = process.env.BACKEND_URL;
export async function GET() { export async function GET(request: Request) {
const response = await fetch(`${BACKEND_URL}/users/user`); const authorization = request.headers.get("authorization");
const response = await fetch(`${BACKEND_URL}/users/user`, {
headers: {
Authorization: authorization ?? "",
},
});
if (!response.ok) { if (!response.ok) {
return new Response("Request failed in backend", { return new Response("Request failed in backend", {

View file

@ -14,3 +14,18 @@ export async function cmFetch<T>(
return response.json(); return response.json();
} }
export async function cmFetchRaw(
bffUrl: string | URL,
options?: RequestInit,
ignoreStatuses?: number[],
): Promise<Response> {
const response = await fetch(`${FRONTEND_URL}/${bffUrl}`, options);
if (!response.ok && !ignoreStatuses?.includes(response.status)) {
throw new Error("Request failed");
}
console.log(response);
return response;
}

View file

@ -1,24 +1,49 @@
import { cmFetch } from "../cmFetch"; import { getSessionToken } from "@/lib/server_functions/userAuth";
import { cmFetch, cmFetchRaw } from "../cmFetch";
import { Token, User } from "../types"; import { Token, User } from "../types";
export async function getUsers() { export async function getUsers() {
return cmFetch<User[]>(`/api/users`); return cmFetch<User[]>(`/api/users`);
} }
export async function getCurrentUser() {
return cmFetchRaw(
`/api/users/user`,
{ headers: { Authorization: `Bearer ${await getSessionToken()}` } },
[401],
);
}
export async function getUser(id: number) { export async function getUser(id: number) {
return cmFetch<User>(`/api/users/${id}`); return cmFetch<User>(`/api/users/${id}`);
} }
export async function loginUser(user: FormData) { export async function loginUser(user: FormData) {
const body = {
username: user.get("username"),
password: user.get("password"),
};
return cmFetch<Token>(`/api/users/login`, { return cmFetch<Token>(`/api/users/login`, {
method: "POST", method: "POST",
body: user, headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(body),
}); });
} }
export async function createUser(user: FormData) { export async function createUser(user: FormData) {
const body = {
username: user.get("username"),
password: user.get("password"),
authority: 0,
};
return cmFetch<Token>(`/api/users`, { return cmFetch<Token>(`/api/users`, {
method: "POST", method: "POST",
body: user, headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(body),
}); });
} }

View file

@ -0,0 +1,23 @@
import { cookies } from "next/headers";
import { cache } from "react";
import "server-only";
import { getCurrentUser } from "../api/helpers/users";
import { User } from "../api/types";
export const verifySession = cache(async () => {
const cookie = (await cookies()).get("access_token")?.value;
if (!cookie) {
return { isAuthed: false };
}
const response = await getCurrentUser();
if (response.status == 401) {
return { isAuthed: false };
}
const user = (await response.json()) as User;
return {
isAuthed: true,
surface_auth_level: user.authority,
username: user.username,
};
});

View file

@ -9,7 +9,7 @@ export async function login(formData: FormData) {
"use server"; "use server";
const token = await loginUser(formData); const token = await loginUser(formData);
await createSession(token); await createSession(token);
redirect("/admin/overview"); redirect("/Admin/Overview");
} }
export async function signup(formData: FormData) { export async function signup(formData: FormData) {
@ -17,7 +17,7 @@ export async function signup(formData: FormData) {
"use server"; "use server";
const token = await createUser(formData); const token = await createUser(formData);
await createSession(token); await createSession(token);
redirect("/admin/overview"); redirect("/Admin/Overview");
} }
export async function createSession(token: Token) { export async function createSession(token: Token) {
@ -26,8 +26,16 @@ export async function createSession(token: Token) {
cookieStore.set("access_token", access_token, { cookieStore.set("access_token", access_token, {
httpOnly: true, httpOnly: true,
secure: true, secure: process.env.NODE_ENV === "production",
sameSite: "lax", sameSite: "lax",
path: "/", path: "/",
}); });
} }
export async function getSessionToken() {
const cookieStore = await cookies();
console.log(cookieStore.getAll());
const token = cookieStore.get("access_token")?.value;
return token ? token : null;
}