Added Connection Component, Store, JWT logic
This commit is contained in:
@@ -1,10 +1,9 @@
|
|||||||
import "dotenv/config";
|
import "dotenv/config";
|
||||||
import express from "express";
|
import express from "express";
|
||||||
import { createServer } from "http";
|
import { createServer } from "http";
|
||||||
import { handle } from "socket-events/connect-dispatch";
|
|
||||||
import { Server } from "socket.io";
|
import { Server } from "socket.io";
|
||||||
import { createAdapter } from "@socket.io/redis-adapter";
|
import { createAdapter } from "@socket.io/redis-adapter";
|
||||||
import { jwtMiddleware } from "modules/socketJWT";
|
import { jwtMiddleware } from "modules/socketJWTmiddleware";
|
||||||
import { pubClient, subClient } from "modules/redis";
|
import { pubClient, subClient } from "modules/redis";
|
||||||
|
|
||||||
const app = express();
|
const app = express();
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
import { ExtendedError, Server, Socket } from "socket.io";
|
import { ExtendedError, Server, Socket } from "socket.io";
|
||||||
import jwt from "jsonwebtoken";
|
import { prisma } from "@repo/db";
|
||||||
import { pubClient } from "modules/redis";
|
|
||||||
|
|
||||||
if (!process.env.DISPATCH_APP_TOKEN)
|
if (!process.env.DISPATCH_APP_TOKEN)
|
||||||
throw new Error("DISPATCH_APP_TOKEN is not defined");
|
throw new Error("DISPATCH_APP_TOKEN is not defined");
|
||||||
|
|
||||||
@@ -10,17 +8,19 @@ export const jwtMiddleware = async (
|
|||||||
next: (err?: ExtendedError) => void,
|
next: (err?: ExtendedError) => void,
|
||||||
) => {
|
) => {
|
||||||
try {
|
try {
|
||||||
const token = socket.handshake.auth?.token;
|
const { uid } = socket.handshake.auth;
|
||||||
console.log(socket.handshake);
|
if (!uid) return new Error("Authentication error");
|
||||||
|
/* const token = socket.handshake.auth?.token;
|
||||||
if (!token) return new Error("Authentication error");
|
if (!token) return new Error("Authentication error");
|
||||||
const decoded = jwt.verify(token, process.env.DISPATCH_APP_TOKEN!);
|
const decoded = jwt.verify(token, process.env.DISPATCH_APP_TOKEN!); */
|
||||||
// socket.data.userId = decoded.; // User ID lokal speichern
|
// socket.data.userId = decoded.; // User ID lokal speichern
|
||||||
|
const user = await prisma.user.findUniqueOrThrow({
|
||||||
|
where: { id: uid },
|
||||||
|
});
|
||||||
|
|
||||||
// Prüfen, ob der Nutzer ein Disponent ist
|
socket.data.user = user;
|
||||||
const userId: any = decoded;
|
|
||||||
socket.data.user = decoded; // Lokal speichern
|
|
||||||
|
|
||||||
// In Redis speichern: Key = 'connected_dispatchers', Feld = socket.id, Wert = JSON-String des Users
|
next();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
next(new Error("Authentication error"));
|
next(new Error("Authentication error"));
|
||||||
17
apps/dispatch/app/(dispatch)/_components/Connection.tsx
Normal file
17
apps/dispatch/app/(dispatch)/_components/Connection.tsx
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
import { useSession } from "next-auth/react";
|
||||||
|
import { connectionStore } from "../../_store/connectionStore";
|
||||||
|
import { useEffect } from "react";
|
||||||
|
|
||||||
|
export const Connection = () => {
|
||||||
|
const session = useSession();
|
||||||
|
const cStore = connectionStore((state) => state);
|
||||||
|
const uid = session.data?.user?.id;
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (uid) {
|
||||||
|
cStore.connect(uid);
|
||||||
|
}
|
||||||
|
}, [uid]);
|
||||||
|
|
||||||
|
return <div>{cStore.isConnected ? "Connected" : "Not Connected"}</div>;
|
||||||
|
};
|
||||||
@@ -6,10 +6,10 @@ import Link from "next/link";
|
|||||||
import { connectionStore } from "../../_store/connectionStore";
|
import { connectionStore } from "../../_store/connectionStore";
|
||||||
import { useEffect } from "react";
|
import { useEffect } from "react";
|
||||||
import { socket } from "../socket";
|
import { socket } from "../socket";
|
||||||
|
import { useSession } from "next-auth/react";
|
||||||
|
import { Connection } from "./Connection";
|
||||||
|
|
||||||
export default function Navbar() {
|
export default function Navbar() {
|
||||||
const connected = connectionStore((state) => state);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="navbar bg-base-100 shadow-sm">
|
<div className="navbar bg-base-100 shadow-sm">
|
||||||
<div className="flex-1">
|
<div className="flex-1">
|
||||||
@@ -51,6 +51,9 @@ export default function Navbar() {
|
|||||||
<path d="M21.64,13a1,1,0,0,0-1.05-.14,8.05,8.05,0,0,1-3.37.73A8.15,8.15,0,0,1,9.08,5.49a8.59,8.59,0,0,1,.25-2A1,1,0,0,0,8,2.36,10.14,10.14,0,1,0,22,14.05,1,1,0,0,0,21.64,13Zm-9.5,6.69A8.14,8.14,0,0,1,7.08,5.22v.27A10.15,10.15,0,0,0,17.22,15.63a9.79,9.79,0,0,0,2.1-.22A8.11,8.11,0,0,1,12.14,19.73Z" />
|
<path d="M21.64,13a1,1,0,0,0-1.05-.14,8.05,8.05,0,0,1-3.37.73A8.15,8.15,0,0,1,9.08,5.49a8.59,8.59,0,0,1,.25-2A1,1,0,0,0,8,2.36,10.14,10.14,0,1,0,22,14.05,1,1,0,0,0,21.64,13Zm-9.5,6.69A8.14,8.14,0,0,1,7.08,5.22v.27A10.15,10.15,0,0,0,17.22,15.63a9.79,9.79,0,0,0,2.1-.22A8.11,8.11,0,0,1,12.14,19.73Z" />
|
||||||
</svg>
|
</svg>
|
||||||
</label>
|
</label>
|
||||||
|
<div>
|
||||||
|
<Connection />
|
||||||
|
</div>
|
||||||
<div className="dropdown dropdown-end">
|
<div className="dropdown dropdown-end">
|
||||||
<div tabIndex={0} role="button" className="btn btn-ghost">
|
<div tabIndex={0} role="button" className="btn btn-ghost">
|
||||||
...
|
...
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ export default async function RootLayout({
|
|||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
}>) {
|
}>) {
|
||||||
const session = await getServerSession();
|
const session = await getServerSession();
|
||||||
|
console.log(session);
|
||||||
if (!session) {
|
if (!session) {
|
||||||
redirect("/login");
|
redirect("/login");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
import { io } from "socket.io-client";
|
import { io } from "socket.io-client";
|
||||||
|
|
||||||
export const socket = io(process.env.NEXT_PUBLIC_DISPATCH_SERVER_URL, {
|
export const socket = io(process.env.NEXT_PUBLIC_DISPATCH_SERVER_URL, {
|
||||||
auth: (cb) => {
|
autoConnect: false,
|
||||||
cb({ token: "jwt" });
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -3,10 +3,15 @@ import { socket } from "../(dispatch)/socket";
|
|||||||
|
|
||||||
console.log("connectionStore");
|
console.log("connectionStore");
|
||||||
|
|
||||||
export const connectionStore = create((set) => ({
|
interface ConnectionStore {
|
||||||
|
isConnected: boolean;
|
||||||
|
connect: (uid: string) => Promise<void>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const connectionStore = create<ConnectionStore>((set) => ({
|
||||||
isConnected: false,
|
isConnected: false,
|
||||||
connect: async (jwt: string) => {
|
connect: async (uid: string) => {
|
||||||
socket.auth = { token: "jwt" };
|
socket.auth = { uid };
|
||||||
socket.connect();
|
socket.connect();
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ export const options: AuthOptions = {
|
|||||||
|
|
||||||
adapter: PrismaAdapter(prisma as any),
|
adapter: PrismaAdapter(prisma as any),
|
||||||
callbacks: {
|
callbacks: {
|
||||||
jwt: async ({ token, user }) => {
|
jwt: async ({ token, user, ...rest }) => {
|
||||||
if (user && "firstname" in user) {
|
if (user && "firstname" in user) {
|
||||||
return {
|
return {
|
||||||
...token,
|
...token,
|
||||||
|
|||||||
21
apps/dispatch/types/next-auth.d.ts
vendored
Normal file
21
apps/dispatch/types/next-auth.d.ts
vendored
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
import NextAuth from "next-auth";
|
||||||
|
import { User as IUser } from "@repo/db";
|
||||||
|
|
||||||
|
declare module "next-auth" {
|
||||||
|
/**
|
||||||
|
* Returned by `useSession`, `getSession` and received as a prop on the `SessionProvider` React Context
|
||||||
|
*/
|
||||||
|
interface Session {
|
||||||
|
user: IUser;
|
||||||
|
}
|
||||||
|
type User = IUser;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module "next-auth/jwt" {
|
||||||
|
interface JWT {
|
||||||
|
uid: string;
|
||||||
|
firstname: string;
|
||||||
|
lastname: string;
|
||||||
|
email: string;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user