various improvements

This commit is contained in:
Zoe
2023-04-20 21:19:22 -05:00
parent b6d3b045aa
commit 3ea8167569
60 changed files with 12369 additions and 7625 deletions

16
server/middleware/auth.ts Normal file → Executable file
View File

@@ -1,11 +1,11 @@
import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();
export default defineEventHandler(async (event) => {
const cookies = parseCookies(event)
const cookies = parseCookies(event);
if (!cookies.sessionToken) {
event.context.user = { authenticated: false }
event.context.user = { authenticated: false };
return;
}
@@ -13,12 +13,12 @@ export default defineEventHandler(async (event) => {
where: {
token: cookies.sessionToken
}
})
});
if (!session) {
event.context.user = { authenticated: false }
event.context.user = { authenticated: false };
return;
}
event.context.user = { authenticated: true, id: session.userId };
})
});

View File

@@ -0,0 +1,28 @@
import Redis from 'ioredis';
const redis = new Redis();
const INCREMENT_LIMIT = 5;
const LIMIT_TIME = 700; // milliseconds
export default defineEventHandler(async (event) => {
if (event.node.req.method === 'HEAD' || event.node.req.method === 'OPTIONS' || event.node.req.method === 'GET') return;
const cookies = parseCookies(event);
// if there is no session token in the cookie the request doesn't need a cookie or they just don't have a session token and it will error appropriately.
if (!cookies.sessionToken) return;
const date = new Date().getTime();
const lastRequestData = await redis.get(`request-${cookies.sessionToken}`);
redis.set(`request-${cookies.sessionToken}`, `${new Date().getTime()} ${(parseInt(lastRequestData?.split(' ')[1] || '0') + 1)}`);
if (!lastRequestData) return;
const [lastRequestDate, increment] = lastRequestData.split(' ');
if (lastRequestDate && +lastRequestDate + LIMIT_TIME >= date) {
if (increment && +increment < INCREMENT_LIMIT) return;
throw createError({
statusCode: 429,
});
} else {
redis.set(`request-${cookies.sessionToken}`, `${new Date().getTime()} 0`);
}
});

210
server/middleware/socket.ts Normal file → Executable file
View File

@@ -1,117 +1,113 @@
import { Server } from 'socket.io'
import { PrismaClient } from '@prisma/client'
import { IChannel, IServer, IUser, SafeUser } from '~~/types'
const prisma = new PrismaClient()
declare global {
let io: Server | undefined
}
import { Server } from 'socket.io';
import { PrismaClient } from '@prisma/client';
import { IChannel, IServer, IUser, SafeUser } from '~~/types';
const prisma = new PrismaClient();
export default defineEventHandler(({ node }) => {
if (!global.io) {
global.io = new Server(node.res.socket?.server);
if (!global.io) {
global.io = new Server(node.res.socket?.server);
global.io.on('connection', async (socket) => {
const token = socket.handshake.auth.token;
if (!token) {
return;
}
global.io.on('connection', async (socket) => {
const token = socket.handshake.auth.token;
if (!token) {
return;
}
const { user } = await prisma.session.findFirst({
where: {
token
},
select: {
user: {
select: {
id: true,
username: true,
servers: {
select: {
id: true,
name: true,
participants: {
select: {
id: true,
username: true,
roles: {
select: {
id: true,
administrator: true,
owner: true
}
}
}
},
channels: {
select: {
id: true,
DM: true,
server: {
select: {
id: true,
name: true,
participants: {
select: {
id: true,
username: true,
roles: {
select: {
id: true,
administrator: true,
owner: true
}
}
}
},
}
}
}
}
}
},
channels: {
select: {
id: true,
DM: true,
dmParticipants: {
select: {
id: true,
username: true
}
},
}
}
}
}
}
}) as { user: IUser } | null;
const { user } = await prisma.session.findFirst({
where: {
token
},
select: {
user: {
select: {
id: true,
username: true,
servers: {
select: {
id: true,
name: true,
participants: {
select: {
id: true,
username: true,
roles: {
select: {
id: true,
administrator: true,
owner: true
}
}
}
},
channels: {
select: {
id: true,
DM: true,
server: {
select: {
id: true,
name: true,
participants: {
select: {
id: true,
username: true,
roles: {
select: {
id: true,
administrator: true,
owner: true
}
}
}
},
}
}
}
}
}
},
channels: {
select: {
id: true,
DM: true,
dmParticipants: {
select: {
id: true,
username: true
}
},
}
}
}
}
}
}) as unknown as { user: IUser };
if (!user) {
return;
}
if (!user) {
return;
}
socket.on('typing', async (ev) => {
if (!ev) {
return;
}
socket.on('typing', async (ev) => {
if (!ev) {
return;
}
let channel = user.channels.find((c: IChannel) => c.id === ev) || user.servers.find((s: IServer) => s.channels.some((c: IChannel) => c.id === ev))
if (channel.DM === undefined) {
// assume its a server
channel = channel.channels.find((c: IChannel) => c.id === ev)
}
let channel = user.channels?.find((c: IChannel) => c.id === ev) || user.servers?.find((s: IServer) => s.channels.some((c: IChannel) => c.id === ev));
if (channel?.DM === undefined) {
// assume its a server
channel = channel?.channels.find((c: IChannel) => c.id === ev);
}
if (!channel) return;
if (!channel) return;
if (!channel.dmParticipants?.find((e: SafeUser) => e.id === user.id)) {
if (!channel.server || !channel.server.participants.find((e: SafeUser) => e.id === user.id)) {
return
}
}
if (!channel.dmParticipants?.find((e: SafeUser) => e.id === user.id)) {
if (!channel.server || !channel.server.participants.find((e: SafeUser) => e.id === user.id)) {
return;
}
}
global.io.emit(`typing-${channel.id}`, user.username)
})
})
}
})
global.io.emit(`typing-${channel.id}`, user.username);
});
});
}
});