This commit is contained in:
PxlLoewe
2025-02-15 18:06:21 +01:00
parent 1fba206dbf
commit bb9feaa1cc
14 changed files with 224 additions and 14 deletions

7
.vscode/extensions.json vendored Normal file
View File

@@ -0,0 +1,7 @@
{
"recommendations": [
"EthanSK.restore-terminals",
"dbaeumer.vscode-eslint",
"VisualStudioExptTeam.vscodeintellicode"
]
}

18
.vscode/launch.json vendored Normal file
View File

@@ -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": ["<node_internals>/**"],
"program": "${workspaceFolder}\\server\\index.ts",
"cwd": "${workspaceFolder}\\server",
"runtimeArgs": ["-r", "ts-node/register"],
"console": "integratedTerminal"
}
]
}

18
.vscode/settings.json vendored Normal file
View File

@@ -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"]
}
]
}
]
}

View File

@@ -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) {

View File

@@ -17,7 +17,7 @@ export const Authorize = ({ service }: { service: Service }) => {
return (
<div className="card-body">
<h1 className="text-4xl font-bold">Unerlaubter Zugriff</h1>
<p>Du greifst von einem ncith genehmigtem Server auf diese URL zu</p>
<p>Du greifst von einem nicht genehmigtem Server auf diese URL zu</p>
</div>
);

View File

@@ -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];

View File

@@ -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 (
<header className="flex justify-between items-center p-4">
<h1 className="text-2xl font-bold">Hub</h1>
<div>
{session.status === 'authenticated' ? (
<p>{session.data?.user.firstname}</p>
) : (
<Link href="/login">
<button className="btn">Login</button>
</Link>
)}
</div>
</header>
);
};

View File

@@ -0,0 +1,3 @@
export default () => {
return <div>Admin Page</div>;
};

View File

@@ -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,
});
};

View File

@@ -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 (
<div>
<h1 className="text-5xl">Hub</h1>
<Link href="/logout">
<button className="btn">Logout</button>
</Link>
<Header />
<PaginatedTable
rowsPerPage={10}
prismaModel={'user'}

View File

@@ -15,6 +15,7 @@
"@tanstack/react-table": "^8.20.6",
"bcryptjs": "^2.4.3",
"clsx": "^2.1.1",
"jsonwebtoken": "^9.0.2",
"lodash": "^4.17.21",
"lucide-react": "^0.474.0",
"next": "15.1.4",
@@ -29,6 +30,7 @@
"devDependencies": {
"@eslint/eslintrc": "^3",
"@types/bcryptjs": "^2.4.6",
"@types/jsonwebtoken": "^9.0.8",
"@types/node": "^20",
"@types/react": "^19",
"@types/react-dom": "^19",

111
package-lock.json generated
View File

@@ -111,6 +111,7 @@
"@tanstack/react-table": "^8.20.6",
"bcryptjs": "^2.4.3",
"clsx": "^2.1.1",
"jsonwebtoken": "^9.0.2",
"lodash": "^4.17.21",
"lucide-react": "^0.474.0",
"next": "15.1.4",
@@ -125,6 +126,7 @@
"devDependencies": {
"@eslint/eslintrc": "^3",
"@types/bcryptjs": "^2.4.6",
"@types/jsonwebtoken": "^9.0.8",
"@types/node": "^20",
"@types/react": "^19",
"@types/react-dom": "^19",
@@ -1649,6 +1651,16 @@
"integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==",
"dev": true
},
"node_modules/@types/jsonwebtoken": {
"version": "9.0.8",
"resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.8.tgz",
"integrity": "sha512-7fx54m60nLFUVYlxAB1xpe9CBWX2vSrk50Y6ogRJ1v5xxtba7qXTg5BgYDN5dq+yuQQ9HaVlHJyAAt1/mxryFg==",
"dev": true,
"dependencies": {
"@types/ms": "*",
"@types/node": "*"
}
},
"node_modules/@types/leaflet": {
"version": "1.9.16",
"resolved": "https://registry.npmjs.org/@types/leaflet/-/leaflet-1.9.16.tgz",
@@ -1664,6 +1676,12 @@
"integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==",
"dev": true
},
"node_modules/@types/ms": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz",
"integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==",
"dev": true
},
"node_modules/@types/node": {
"version": "20.17.13",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.13.tgz",
@@ -2377,6 +2395,11 @@
"ieee754": "^1.1.13"
}
},
"node_modules/buffer-equal-constant-time": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
"integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA=="
},
"node_modules/busboy": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz",
@@ -3080,6 +3103,14 @@
"integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
"dev": true
},
"node_modules/ecdsa-sig-formatter": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
"integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
"dependencies": {
"safe-buffer": "^5.0.1"
}
},
"node_modules/emoji-regex": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
@@ -5552,6 +5583,27 @@
"graceful-fs": "^4.1.6"
}
},
"node_modules/jsonwebtoken": {
"version": "9.0.2",
"resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz",
"integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==",
"dependencies": {
"jws": "^3.2.2",
"lodash.includes": "^4.3.0",
"lodash.isboolean": "^3.0.3",
"lodash.isinteger": "^4.0.4",
"lodash.isnumber": "^3.0.3",
"lodash.isplainobject": "^4.0.6",
"lodash.isstring": "^4.0.1",
"lodash.once": "^4.0.0",
"ms": "^2.1.1",
"semver": "^7.5.4"
},
"engines": {
"node": ">=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"
},

View File

@@ -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;

View File

@@ -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")
}