Skip to content

Commit

Permalink
Make oauth state cookie work
Browse files Browse the repository at this point in the history
  • Loading branch information
Oscariremma committed Oct 24, 2024
1 parent ac92620 commit cf1b27e
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 41 deletions.
13 changes: 5 additions & 8 deletions frontend/src/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,14 @@ import { redirect } from "next/navigation";
import { getSuggestions } from "../lib/goldapps/get-suggestions";
import { createGoldappsServerClient } from "../lib/goldapps/client-server";

async function fetchSuggestions() {
const goldappsClient = createGoldappsServerClient();
const redirectUri = await checkLogin();
if (redirectUri) {
return redirect(redirectUri);
}

return getSuggestions(goldappsClient);
}

export default async function IndexPage() {
const fetchSuggestions = async () => {
const goldappsClient = createGoldappsServerClient();
return getSuggestions(goldappsClient);
}

const suggestions = await fetchSuggestions();
return <Suggestions suggestions={suggestions} />;
}
8 changes: 6 additions & 2 deletions frontend/src/app/unauthorized/page.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
export default function UnauthorizedPage() {
import { checkLogin } from "../../lib/goldapps/auth";

export default async function UnauthorizedPage() {

await checkLogin();
return (
<div className="flex flex-col items-center justify-center">
<h2>Unauthorized!</h2>
<p>You are not authorized to use this website</p>
<p>
For more information, please contact IT responsible at the IT student
division or digIT
division.
</p>
</div>
);
Expand Down
60 changes: 36 additions & 24 deletions frontend/src/lib/goldapps/auth.ts
Original file line number Diff line number Diff line change
@@ -1,42 +1,54 @@
'use server';

import { AxiosResponse } from "axios";
import { AxiosHeaders, AxiosResponse, RawAxiosResponseHeaders } from "axios";
import { cookies } from "next/headers";
import { createGoldappsServerClient } from "./client-server";
import { ResponseCookie } from "next/dist/compiled/@edge-runtime/cookies";

function extractOauthStateCookie(headers: RawAxiosResponseHeaders | (RawAxiosResponseHeaders & AxiosHeaders)): ResponseCookie | null {
if (headers === null || headers === undefined) {
return null;
}
const setCookieHeader = headers["set-cookie"] || null;
const serverCookies = (Array.isArray(setCookieHeader) ? setCookieHeader : [setCookieHeader]).map((cookie) => {
if (typeof cookie === "string") {
const [nameValue, ...rest] = cookie.split(";");
const [name, value] = nameValue.split("=");
return { name, value, attributes: rest.join(";") };
}
return null;
}).filter(cookie => cookie !== null) || [];

const oauthStateCookie = serverCookies.find((cookie: any) => cookie.name === "oauth_state");

if (oauthStateCookie) {
return {
name: "oauth_state",
value: oauthStateCookie.value,
maxAge: 3600, // 1 hour
httpOnly: true,
secure: true,
sameSite: "none",
};
}
return null
}

// Returns login uri if not logged in
export async function checkLogin() {
export async function checkLogin() : Promise<{data: string, cookie: (ResponseCookie | null)} | null> {
try {

const client = createGoldappsServerClient();
const { status: checkLoginStatus, data, headers } = await client.get<string>(
"/api/checkLogin",
"/api/checkLogin"
);
if (checkLoginStatus !== 200) {
const serverCookies = headers["set-cookie"]?.map((cookie) => {
const [nameValue, ...rest] = cookie.split(';');
const [name, value] = nameValue.split('=');
return { name, value, attributes: rest.join(';') };
}) || [];

const oauthStateCookie = serverCookies.find((cookie) => cookie.name === "oauth_state");

if (oauthStateCookie) {
cookies().set({
name: "oauth_state",
value: oauthStateCookie.value,
maxAge: 3600, // 1 hour
httpOnly: true,
secure: true,
sameSite: "none"
});
}

return data;
return {data, cookie: extractOauthStateCookie(headers)};
}

return null;
} catch (e) {
const response = (e as any).response as AxiosResponse<string>;
return response.data;
return {data: response.data, cookie: extractOauthStateCookie(response.headers)};
}
}
32 changes: 25 additions & 7 deletions frontend/src/middleware.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,31 @@
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";
import { createGoldappsServerClient } from "./lib/goldapps/client-server";
import { checkLogin } from "./lib/goldapps/auth";

export async function middleware(request: NextRequest) {

export function middleware(request: NextRequest) {
const GOLDAPPS_URL = process.env.GOLDAPPS_URL || "http://localhost:8080";
return NextResponse.rewrite(
GOLDAPPS_URL + request.nextUrl.pathname + request.nextUrl.search,
);
if (request.nextUrl.pathname === "/") {
const loginStatus = await checkLogin();
if (loginStatus?.data){
const redirectResponse = NextResponse.redirect(loginStatus.data);

if (loginStatus.cookie)
redirectResponse.cookies.set(loginStatus.cookie);

return redirectResponse;
}
}

if (request.nextUrl.pathname.startsWith("/api/")) {
return NextResponse.rewrite(
GOLDAPPS_URL + request.nextUrl.pathname + request.nextUrl.search,
);
}
return NextResponse.next();
}

export const config = {
matcher: "/api/:path*",
};
//export const config = {
// matcher: "/api/:path*",
//};

0 comments on commit cf1b27e

Please sign in to comment.