various improvements
This commit is contained in:
16
server/middleware/auth.ts
Normal file → Executable file
16
server/middleware/auth.ts
Normal file → Executable 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 };
|
||||
})
|
||||
});
|
||||
28
server/middleware/ratelimit.ts
Normal file
28
server/middleware/ratelimit.ts
Normal 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
210
server/middleware/socket.ts
Normal file → Executable 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);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user