diff --git a/README.md b/README.md index fec86ec..75dc884 100644 --- a/README.md +++ b/README.md @@ -26,10 +26,11 @@ Prerequisite: golang installed Prerequisite: bun installed -The environment variable `API_HOST` will need to be set for the middleware. +The environment variables `API_HOST` and `AUTH_HOST` will need to be set for the middleware. Example `.env` in web's root: ``` API_HOST="http://localhost:8082/v1/" +AUTH_HOST="http://localhost:8083/" ``` 1. `cd web` diff --git a/compose.yaml b/compose.yaml index 4445c1d..e4ddfac 100644 --- a/compose.yaml +++ b/compose.yaml @@ -50,6 +50,7 @@ services: - "3000:3000" environment: - API_HOST=http://submissions:8082/v1 + - AUTH_HOST=http://localhost:8080/ validation: image: diff --git a/web/src/app/_components/header.tsx b/web/src/app/_components/header.tsx index c2274aa..b611533 100644 --- a/web/src/app/_components/header.tsx +++ b/web/src/app/_components/header.tsx @@ -1,6 +1,11 @@ +"use client" + import Link from "next/link" +import Image from "next/image"; import "./styles/header.scss" +import { UserInfo } from "@/app/ts/User"; +import { useState, useEffect } from "react"; interface HeaderButton { name: string, @@ -15,6 +20,25 @@ function HeaderButton(header: HeaderButton) { } export default function Header() { + const handleLoginClick = () => { + window.location.href = "/auth/oauth2/login?redirect=" + window.location.href; + }; + + const [valid, setValid] = useState(false) + const [user, setUser] = useState(null) + + useEffect(() => { + async function getLoginInfo() { + const [validateData, userData] = await Promise.all([ + fetch("/api/session/validate").then(validateResponse => validateResponse.json()), + fetch("/api/session/user").then(userResponse => userResponse.json()) + ]); + setValid(validateData) + setUser(userData) + } + getLoginInfo() + }, []) + return (
) diff --git a/web/src/app/_components/webpage.tsx b/web/src/app/_components/webpage.tsx index 2c64aba..fc386fd 100644 --- a/web/src/app/_components/webpage.tsx +++ b/web/src/app/_components/webpage.tsx @@ -1,25 +1,8 @@ "use client" -import { redirect } from "next/navigation"; -import { useEffect } from "react"; - import Header from "./header"; -async function login_check() { - const response = await fetch("/api/session/validate") - if (response.ok) { - const logged_in = await response.json() - if (!logged_in) { - redirect("https://auth.staging.strafes.net/oauth2/login?redirect=" + window.location.href) - } - } else { - console.error("No response from /api/session/validate") - } -} - export default function Webpage({children}: Readonly<{children?: React.ReactNode}>) { - useEffect(() => { login_check() }, []) - return <>
{children} diff --git a/web/src/app/mapfixes/page.tsx b/web/src/app/mapfixes/page.tsx index 2945e1e..98b31e2 100644 --- a/web/src/app/mapfixes/page.tsx +++ b/web/src/app/mapfixes/page.tsx @@ -1,6 +1,6 @@ 'use client' -import React, { useState, useEffect } from "react"; +import { useState, useEffect } from "react"; import { MapfixList } from "../ts/Mapfix"; import { MapfixCard } from "../_components/mapCard"; import Webpage from "@/app/_components/webpage"; diff --git a/web/src/app/submissions/page.tsx b/web/src/app/submissions/page.tsx index 2ae27dd..8a7c017 100644 --- a/web/src/app/submissions/page.tsx +++ b/web/src/app/submissions/page.tsx @@ -1,6 +1,6 @@ 'use client' -import React, { useState, useEffect } from "react"; +import { useState, useEffect } from "react"; import { SubmissionList } from "../ts/Submission"; import { SubmissionCard } from "../_components/mapCard"; import Webpage from "@/app/_components/webpage"; diff --git a/web/src/app/ts/User.ts b/web/src/app/ts/User.ts new file mode 100644 index 0000000..98ffb12 --- /dev/null +++ b/web/src/app/ts/User.ts @@ -0,0 +1,5 @@ +export interface UserInfo { + readonly UserID: number, + readonly Username: string, + readonly AvatarURL: string, +} diff --git a/web/src/middleware.ts b/web/src/middleware.ts index ce20731..0a25a76 100644 --- a/web/src/middleware.ts +++ b/web/src/middleware.ts @@ -1,13 +1,29 @@ import { NextRequest, NextResponse } from "next/server" export const config = { - matcher: ["/api/:path*"], + matcher: ["/api/:path*", "/auth/:path*"], } export function middleware(request: NextRequest) { - if (!process.env.API_HOST) { - throw new Error("env variable \"API_HOST\" is not set") - } - const url = new URL(process.env.API_HOST + request.nextUrl.pathname.replace(/^\/api/, '') + request.nextUrl.search) - return NextResponse.rewrite(url, { request }) + const { pathname, search } = request.nextUrl + + if (pathname.startsWith("/api")) { + if (!process.env.API_HOST) { + throw new Error('env variable "API_HOST" is not set') + } + const apiUrl = new URL(process.env.API_HOST + pathname.replace(/^\/api/, '') + search) + return NextResponse.rewrite(apiUrl, { request }) + } else if (pathname.startsWith("/auth")) { + if (!process.env.AUTH_HOST) { + throw new Error('env variable "AUTH_HOST" is not set') + } + + const authHost = process.env.AUTH_HOST.replace(/\/$/, "") + const path = pathname.replace(/^\/auth/, "") + const redirectUrl = new URL(authHost + path + search) + + return NextResponse.redirect(redirectUrl, 302) + } + + return NextResponse.next() } \ No newline at end of file