diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 00000000..ee4d8ed1 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,7 @@ +{ + "recommendations": [ + "EthanSK.restore-terminals", + "dbaeumer.vscode-eslint", + "VisualStudioExptTeam.vscodeintellicode" + ] +} diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 00000000..c68c8a56 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,18 @@ +{ + // Verwendet IntelliSense zum Ermitteln möglicher Attribute. + // Zeigen Sie auf vorhandene Attribute, um die zugehörigen Beschreibungen anzuzeigen. + // Weitere Informationen finden Sie unter https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "node", + "request": "launch", + "name": "Debug Server", + "skipFiles": ["/**"], + "program": "${workspaceFolder}\\server\\index.ts", + "cwd": "${workspaceFolder}\\server", + "runtimeArgs": ["-r", "ts-node/register"], + "console": "integratedTerminal" + } + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..a8c108c3 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,18 @@ +{ + "editor.formatOnSave": true, + "files.autoSave": "off", + "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.codeActionsOnSave": ["source.formatDocument", "source.fixAll.eslint"], + "eslint.workingDirectories": ["./client", "./server"], + "eslint.lintTask.enable": true, + "restoreTerminals.terminals": [ + { + "splitTerminals": [ + { + "name": "Monorepo", + "commands": ["npm run dev"] + } + ] + } + ] +} diff --git a/apps/dispatch/app/api/auth/[...nextauth]/auth.ts b/apps/dispatch/app/api/auth/[...nextauth]/auth.ts index 9b9d5db2..17636942 100644 --- a/apps/dispatch/app/api/auth/[...nextauth]/auth.ts +++ b/apps/dispatch/app/api/auth/[...nextauth]/auth.ts @@ -26,7 +26,6 @@ export const options: AuthOptions = { id: code.userId, }, }); - console.log(code, user); if (!user) return null; @@ -43,7 +42,7 @@ export const options: AuthOptions = { maxAge: 30 * 24 * 60 * 60, }, - adapter: PrismaAdapter(prisma), + adapter: PrismaAdapter(prisma as any), callbacks: { jwt: async ({ token, user }) => { if (user && 'firstname' in user) { diff --git a/apps/hub/app/(auth)/oauth/_components/Authorize.tsx b/apps/hub/app/(auth)/oauth/_components/Authorize.tsx index 239fab5d..b97979ad 100644 --- a/apps/hub/app/(auth)/oauth/_components/Authorize.tsx +++ b/apps/hub/app/(auth)/oauth/_components/Authorize.tsx @@ -17,7 +17,7 @@ export const Authorize = ({ service }: { service: Service }) => { return (

Unerlaubter Zugriff

-

Du greifst von einem ncith genehmigtem Server auf diese URL zu

+

Du greifst von einem nicht genehmigtem Server auf diese URL zu

); diff --git a/apps/hub/app/(auth)/oauth/page.tsx b/apps/hub/app/(auth)/oauth/page.tsx index f14951cb..8786f86c 100644 --- a/apps/hub/app/(auth)/oauth/page.tsx +++ b/apps/hub/app/(auth)/oauth/page.tsx @@ -7,6 +7,12 @@ export const services = [ name: 'Leitstellendisposition', approvedUrls: ['http://localhost:3001'], }, + { + id: '789456', + service: 'desktop', + name: 'Desktop client', + approvedUrls: ['var'], + }, ]; export type Service = (typeof services)[number]; diff --git a/apps/hub/app/_components/ui/Header.tsx b/apps/hub/app/_components/ui/Header.tsx new file mode 100644 index 00000000..e6f88a3f --- /dev/null +++ b/apps/hub/app/_components/ui/Header.tsx @@ -0,0 +1,23 @@ +'use client'; + +import { useSession } from 'next-auth/react'; +import Link from 'next/link'; + +export const Header = () => { + const session = useSession(); + console.log(session); + return ( +
+

Hub

+
+ {session.status === 'authenticated' ? ( +

{session.data?.user.firstname}

+ ) : ( + + + + )} +
+
+ ); +}; diff --git a/apps/hub/app/admin/page.tsx b/apps/hub/app/admin/page.tsx new file mode 100644 index 00000000..cb20f8f8 --- /dev/null +++ b/apps/hub/app/admin/page.tsx @@ -0,0 +1,3 @@ +export default () => { + return
Admin Page
; +}; diff --git a/apps/hub/app/api/auth/accessToken/route.ts b/apps/hub/app/api/auth/accessToken/route.ts new file mode 100644 index 00000000..966b678c --- /dev/null +++ b/apps/hub/app/api/auth/accessToken/route.ts @@ -0,0 +1,28 @@ +import { 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 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/page.tsx b/apps/hub/app/page.tsx index 0e93079a..ad80c330 100644 --- a/apps/hub/app/page.tsx +++ b/apps/hub/app/page.tsx @@ -1,16 +1,11 @@ import Link from 'next/link'; -import { PrismaClient } from '@repo/db'; import { PaginatedTable } from './_components/PaginatedTable'; +import { Header } from './_components/ui/Header'; export default async function Home() { - const prisma = new PrismaClient(); - return (
-

Hub

- - - +
=12", + "npm": ">=6" + } + }, "node_modules/jsx-ast-utils": { "version": "3.3.5", "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", @@ -5567,6 +5619,25 @@ "node": ">=4.0" } }, + "node_modules/jwa": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", + "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "dependencies": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jws": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "dependencies": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", @@ -5884,12 +5955,47 @@ "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", "dev": true }, + "node_modules/lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==" + }, + "node_modules/lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" + }, + "node_modules/lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==" + }, + "node_modules/lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==" + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==" + }, + "node_modules/lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==" + }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, + "node_modules/lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" + }, "node_modules/log-symbols": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", @@ -6046,8 +6152,7 @@ "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, "node_modules/mute-stream": { "version": "0.0.8", @@ -7524,7 +7629,6 @@ "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, "funding": [ { "type": "github", @@ -7588,7 +7692,6 @@ "version": "7.6.3", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", - "devOptional": true, "bin": { "semver": "bin/semver.js" }, diff --git a/packages/database/prisma/migrations/20250213210756_/migration.sql b/packages/database/prisma/migrations/20250213210756_/migration.sql new file mode 100644 index 00000000..18857811 --- /dev/null +++ b/packages/database/prisma/migrations/20250213210756_/migration.sql @@ -0,0 +1,2 @@ +-- AddForeignKey +ALTER TABLE "oauth_tokens" ADD CONSTRAINT "oauth_tokens_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE; diff --git a/packages/database/prisma/schema/auth.prisma b/packages/database/prisma/schema/auth.prisma index e5503b18..1b748ab4 100644 --- a/packages/database/prisma/schema/auth.prisma +++ b/packages/database/prisma/schema/auth.prisma @@ -21,6 +21,9 @@ model User { createdAt DateTime @default(now()) @map(name: "created_at") updatedAt DateTime @default(now()) @map(name: "updated_at") + // relations: + oauthTokens OAuthToken[] + @@map(name: "users") } @@ -43,5 +46,8 @@ model OAuthToken { createdAt DateTime @default(now()) @map(name: "created_at") updatedAt DateTime @default(now()) @map(name: "updated_at") + // relations: + user User @relation(fields: [userId], references: [id]) // Beziehung zu User + @@map(name: "oauth_tokens") }