Added socket

This commit is contained in:
sianida26 2024-02-16 20:50:19 +07:00
parent da678fd487
commit f16e356555
7 changed files with 115 additions and 3 deletions

2
.env.development Normal file
View File

@ -0,0 +1,2 @@
WS_PORT=4001
WS_HOST=ws://localhost:$WS_PORT

BIN
bun.lockb

Binary file not shown.

101
server/socket.ts Normal file
View File

@ -0,0 +1,101 @@
import getUserFromToken from "@/modules/auth/utils/getUserFromToken";
import { User } from "@prisma/client";
import prisma from "@/core/db";
import Bun from "bun";
const intents = {
listenMyWaitingLinkRequest: "listenMyWaitingLinkRequest",
} as const;
const waitingLinkRequestConnections: Map<
string,
Bun.ServerWebSocket<{
channel: string;
user: User;
intent: string;
}>
> = new Map();
export const server = Bun.serve<{
channel: string;
user: User;
intent: string;
}>({
async fetch(req, server) {
const url = new URL(req.url);
req.headers.getSetCookie();
const pathname = url.pathname;
const cookies = req.headers.get("Cookie");
// Extract the Authorization header
const authHeader = req.headers.get("Authorization");
const token = authHeader?.startsWith("Bearer ")
? authHeader.substring(7, authHeader.length)
: null;
const user = token ? await getUserFromToken(token) : null;
const intent = pathname.substring(1);
switch (intent) {
case `/${intents.listenMyWaitingLinkRequest}`: {
if (!user) {
return new Response("Unauthorized", { status: 401 });
}
const channel = `mwrl-${user.id}`;
const success = server.upgrade(req, {
data: { user, channel, intent },
});
if (success) return undefined;
break;
}
default: {
return new Response("");
}
}
},
websocket: {
async open(ws) {
switch (ws.data.intent) {
case intents.listenMyWaitingLinkRequest: {
ws.subscribe(ws.data.channel);
//retrieve user's link requests with status of waiting
const result = await prisma.office365LinkRequest.findMany({
where: {
createdBy: ws.data.user.id,
status: "WAITING",
},
select: {
id: true,
},
});
server.publish(ws.data.channel, JSON.stringify(result));
waitingLinkRequestConnections.set(ws.data.channel, ws);
}
}
},
message(ws, message) {
// the server re-broadcasts incoming messages to everyone
// server.publish("the-group-chat", `: ${message}`);
},
close(ws) {
// const msg = ` has left the chat`;
// server.publish("the-group-chat", msg);
// ws.unsubscribe("the-group-chat");
switch (ws.data.intent) {
case intents.listenMyWaitingLinkRequest: {
ws.unsubscribe(ws.data.channel);
waitingLinkRequestConnections.delete(ws.data.channel);
}
}
},
},
port: 3001,
});
console.log(`Listening on ${server.hostname}:${server.port}`);

View File

@ -0,0 +1,6 @@
import { cache } from "react";
import getUserFromToken from "./getUserFromToken";
const cachedGetUserFromToken = cache(getUserFromToken);
export default cachedGetUserFromToken;

View File

@ -12,7 +12,7 @@ import prisma from "@/core/db";
* @returns The user's data if the user exists, or null if no user is found.
* Throws an error if the token is invalid or the database query fails.
*/
const getUserFromToken = cache(async (token: string) => {
const getUserFromToken = async (token: string) => {
// Decode the JWT token to extract the user ID
const decodedToken = decodeJwtToken(token) as { id: string; iat: number };
@ -32,6 +32,6 @@ const getUserFromToken = cache(async (token: string) => {
});
return user;
});
};
export default getUserFromToken;

View File

@ -10,6 +10,7 @@ import mapObjectToFirstValue from "@/utils/mapObjectToFirstValue";
import db from "@/core/db";
import getCurrentUser from "@/modules/auth/utils/getCurrentUser";
import { revalidatePath } from "next/cache";
import {server} from "../../../../server/socket";
export default async function createLinkRequest(
formData: RequestLinkForm
@ -54,6 +55,8 @@ export default async function createLinkRequest(
revalidatePath(".")
server.publish(`mwrl-${currentUser.id}`, "update")
return {
success: true,
message: