diff --git a/apps/dispatch/app/(auth)/oauth/_components/Authorize.tsx b/apps/dispatch/app/(auth)/oauth/_components/Authorize.tsx deleted file mode 100644 index 22b5085b..00000000 --- a/apps/dispatch/app/(auth)/oauth/_components/Authorize.tsx +++ /dev/null @@ -1,43 +0,0 @@ -'use client'; -import { useSearchParams } from 'next/navigation'; -import { Service } from '../page'; -import { generateToken } from './action'; - -export const Authorize = ({ service }: { service: Service }) => { - const searchParams = useSearchParams(); - const legitimeUrl = service.approvedUrls.some((url) => - searchParams.get('redirect_uri')?.startsWith(url) - ); - if (!legitimeUrl) - return ( -
-

Unerlaubter Zugriff

-

Du greifst von einem ncith genehmigtem Server auf diese URL zu

-
- ); - - return ( -
e.preventDefault()}> -

Zugriff zulassen

-

- Die Anwendung {service.name} möchte auf deine Daten - zugreifen. -

-
- - -
-
- ); -}; diff --git a/apps/dispatch/app/(auth)/oauth/_components/action.ts b/apps/dispatch/app/(auth)/oauth/_components/action.ts deleted file mode 100644 index 52204e89..00000000 --- a/apps/dispatch/app/(auth)/oauth/_components/action.ts +++ /dev/null @@ -1,24 +0,0 @@ -'use server'; -import { getServerSession } from '../../../api/auth/[...nextauth]/auth'; -import { Service } from '../page'; -import { PrismaClient } from '@repo/db'; - -const prisma = new PrismaClient(); - -export const generateToken = async (service: Service) => { - const session = await getServerSession(); - if (!session) return null; - - const accessToken = Array.from({ length: 10 }, () => - Math.floor(Math.random() * 10) - ).join(''); - - const code = await prisma.oAuthToken.create({ - data: { - clientId: service.id, - userId: session.user.id, - accessToken: accessToken, - }, - }); - return code; -}; diff --git a/apps/dispatch/app/(auth)/oauth/page.tsx b/apps/dispatch/app/(auth)/oauth/page.tsx deleted file mode 100644 index e5506c5a..00000000 --- a/apps/dispatch/app/(auth)/oauth/page.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import { Authorize } from "./_components/Authorize"; - -export const services = [ - { - id: "123456", - service: "dispatch", - name: "Leitstellendisposition", - approvedUrls: ["http://localhost:3001"], - }, -]; -export type Service = (typeof services)[number]; - -export default async ({ - searchParams, -}: { - searchParams: Promise<{ [key: string]: string | string[] | undefined }>; -}) => { - const { service: serviceId } = await searchParams; - const service = services.find((service) => service.id === serviceId); - - if (!service) { - return
Service not found
; - } - - return ; -}; diff --git a/apps/hub/app/(auth)/oauth/_components/Authorize.tsx b/apps/hub/app/(auth)/oauth/_components/Authorize.tsx index b97979ad..7e25305a 100644 --- a/apps/hub/app/(auth)/oauth/_components/Authorize.tsx +++ b/apps/hub/app/(auth)/oauth/_components/Authorize.tsx @@ -1,48 +1,48 @@ -'use client'; -import { redirect, useSearchParams } from 'next/navigation'; -import { Service } from '../page'; -import { generateToken } from './action'; -import { useSession } from 'next-auth/react'; +"use client"; +import { redirect, useSearchParams } from "next/navigation"; +import { Service } from "../page"; +import { generateToken } from "./action"; +import { useSession } from "next-auth/react"; export const Authorize = ({ service }: { service: Service }) => { - const searchParams = useSearchParams(); - const legitimeUrl = service.approvedUrls.some((url) => - searchParams.get('redirect_uri')?.startsWith(url) - ); - const { data: session } = useSession(); - console.log(session); - if (!session) - redirect('/login?redirect=' + encodeURIComponent(window.location.href)); - if (!legitimeUrl) - return ( -
-

Unerlaubter Zugriff

-

Du greifst von einem nicht genehmigtem Server auf diese URL zu

-
- ); + const searchParams = useSearchParams(); + const legitimeUrl = service.approvedUrls.some((url) => + searchParams.get("redirect_uri")?.startsWith(url), + ); + const { data: session } = useSession(); + console.log(session); + if (!session) + redirect("/login?redirect=" + encodeURIComponent(window.location.href)); + if (!legitimeUrl) + return ( +
+

Unerlaubter Zugriff

+

Du greifst von einem nicht genehmigtem Server auf diese URL zu

+
+ ); - return ( -
e.preventDefault()}> -

Zugriff zulassen

-

- Die Anwendung {service.name} möchte auf deine Daten - zugreifen. -

-
- - -
-
- ); + return ( +
e.preventDefault()}> +

Zugriff zulassen

+

+ Die Anwendung {service.name} möchte auf deine Daten + zugreifen. +

+
+ + +
+
+ ); }; diff --git a/apps/hub/app/(auth)/oauth/page.tsx b/apps/hub/app/(auth)/oauth/page.tsx index 8786f86c..8da61cde 100644 --- a/apps/hub/app/(auth)/oauth/page.tsx +++ b/apps/hub/app/(auth)/oauth/page.tsx @@ -1,32 +1,39 @@ -import { Authorize } from './_components/Authorize'; +import { Authorize } from "./_components/Authorize"; export const services = [ - { - id: '123456', - service: 'dispatch', - name: 'Leitstellendisposition', - approvedUrls: ['http://localhost:3001'], - }, - { - id: '789456', - service: 'desktop', - name: 'Desktop client', - approvedUrls: ['var'], - }, + { + id: "1", + service: "dispatch", + name: "Leitstellendisposition", + approvedUrls: ["http://localhost:3001"], + }, + { + id: "2", + service: "desktop", + name: "Desktop client", + approvedUrls: ["var"], + }, + { + id: "3", + secret: "d0f3e4e4", + service: "moodle", + name: "Moodle", + approvedUrls: ["https://moodle.virtualairrescue.com"], + }, ]; export type Service = (typeof services)[number]; export default async ({ - searchParams, + searchParams, }: { - searchParams: Promise<{ [key: string]: string | string[] | undefined }>; + searchParams: Promise<{ [key: string]: string | string[] | undefined }>; }) => { - const { service: serviceId } = await searchParams; - const service = services.find((service) => service.id === serviceId); + const { service: serviceId } = await searchParams; + const service = services.find((service) => service.id === serviceId); - if (!service) { - return
Service not found
; - } + if (!service) { + return
Service not found
; + } - return ; + return ; }; diff --git a/apps/hub/app/api/auth/accessToken/route.ts b/apps/hub/app/api/auth/accessToken/route.ts index 966b678c..0f3cf795 100644 --- a/apps/hub/app/api/auth/accessToken/route.ts +++ b/apps/hub/app/api/auth/accessToken/route.ts @@ -1,28 +1,48 @@ -import { PrismaClient } from '@repo/db'; -import { NextRequest, NextResponse } from 'next/server'; -import { sign } from 'jsonwebtoken'; +import { prisma, PrismaClient } from "@repo/db"; +import { NextRequest, NextResponse } from "next/server"; +import { sign } from "jsonwebtoken"; export const GET = async (req: NextRequest) => { - const client = new PrismaClient(); - const accessToken = req.nextUrl.searchParams.get('token'); - if (!accessToken) - return new Response('No access token provided', { status: 400 }); - const accessRequest = await client.oAuthToken.findFirst({ - where: { - accessToken: accessToken, - }, - include: { - user: true, - }, - }); - if (!accessRequest) - return new Response('Access token not found', { status: 404 }); + const client = new PrismaClient(); + const accessToken = + req.nextUrl.searchParams.get("token") || + req.nextUrl.searchParams.get("code"); + const client_id = req.nextUrl.searchParams.get("client_id"); + const client_secret = req.nextUrl.searchParams.get("client_secret"); - const jwt = sign(accessRequest.user, process.env.NEXTAUTH_SECRET as string, { - expiresIn: '30d', - }); - return Response.json({ - user: accessRequest.user, - jwt, - }); + if (!accessToken) + return new Response("No access token provided", { status: 400 }); + + if (!client_id) + return new Response("No client ID token provided", { status: 400 }); + + const accessRequest = await client.oAuthToken.findFirst({ + where: { + accessToken: accessToken, + clientId: client_id, + }, + include: { + user: true, + }, + }); + if (!accessRequest) + return new Response("Access token not found", { status: 404 }); + + if (new Date().getTime() - accessRequest?.createdAt.getTime() > 60 * 1000) { + await prisma.oAuthToken.delete({ + where: { + id: accessRequest.id, + }, + }); + return new Response("Code expired", { status: 400 }); + } + + const jwt = sign(accessRequest.user, process.env.NEXTAUTH_SECRET as string, { + expiresIn: "30d", + }); + + return Response.json({ + user: accessRequest.user, + jwt, + }); }; diff --git a/apps/hub/app/api/user/route.ts b/apps/hub/app/api/user/route.ts new file mode 100644 index 00000000..bc7ff663 --- /dev/null +++ b/apps/hub/app/api/user/route.ts @@ -0,0 +1,21 @@ +import { NextRequest, NextResponse } from "next/server"; +import { getServerSession } from "../auth/[...nextauth]/auth"; +import { prisma } from "@repo/db"; + +export const GET = async (req: NextRequest) => { + const session = await getServerSession(); + if (!session) { + return { + status: 401, + body: "Unauthorized", + }; + } + + const user = await prisma.user.findUnique({ + where: { + id: session.user.id, + }, + }); + + return NextResponse.json(user); +};