226 lines
6.4 KiB
TypeScript
226 lines
6.4 KiB
TypeScript
import { fail, redirect } from '@sveltejs/kit';
|
|
import { getRequestEvent } from '$app/server';
|
|
import type { Actions, PageServerLoad } from './$types';
|
|
import { db } from '$lib/server/db';
|
|
import * as table from '$lib/server/db/schema';
|
|
import { DirectMessageID, FriendRequestID, ServerID } from '$lib';
|
|
import { eq } from 'drizzle-orm';
|
|
import { and } from 'drizzle-orm';
|
|
import { type User } from '$lib/server/db/schema';
|
|
export const load: PageServerLoad = async () => {
|
|
const user = requireLogin();
|
|
return { user };
|
|
};
|
|
|
|
export const actions = {
|
|
addFriend: async ({ request, locals }) => {
|
|
const data = await request.formData();
|
|
const username = data.get('username');
|
|
const userId = data.get('userId');
|
|
|
|
if (username && !userId) {
|
|
if (typeof username !== 'string' || username.length < 3) {
|
|
return fail(400, { error: 'Invalid username' });
|
|
}
|
|
}
|
|
|
|
let user: User[];
|
|
if (username) {
|
|
user = await db
|
|
.select()
|
|
.from(table.user)
|
|
.where(eq(table.user.username, username.toString()))
|
|
.limit(1);
|
|
} else if (userId) {
|
|
user = await db
|
|
.select()
|
|
.from(table.user)
|
|
.where(eq(table.user.id, userId.toString()))
|
|
.limit(1);
|
|
} else {
|
|
return fail(400, { error: 'Missing username or userId' });
|
|
}
|
|
|
|
if (locals.user?.friends.find((z) => z.id == user[0].id)) {
|
|
return fail(400, { error: 'Already friends' });
|
|
}
|
|
|
|
if (user?.length == 0) return fail(400, { error: 'User not found' });
|
|
|
|
const friendRequest = await db
|
|
.select()
|
|
.from(table.friendRequest)
|
|
.where(
|
|
and(
|
|
eq(table.friendRequest.fromUser, user[0].id),
|
|
eq(table.friendRequest.toUser, locals.user!.id)
|
|
)
|
|
)
|
|
.limit(1);
|
|
|
|
// user has already sent a request to us
|
|
// means we want to accept it
|
|
//
|
|
if (friendRequest?.length != 0) {
|
|
await db
|
|
.delete(table.friendRequest)
|
|
.where(
|
|
and(
|
|
eq(table.friendRequest.fromUser, user[0].id),
|
|
eq(table.friendRequest.toUser, locals.user!.id)
|
|
)
|
|
)
|
|
.limit(1);
|
|
|
|
await db.insert(table.directMessage).values({
|
|
id: DirectMessageID.newV4(),
|
|
firstMember: locals.user!.id,
|
|
secondMember: user[0].id,
|
|
messages: []
|
|
});
|
|
|
|
// add other guy to us
|
|
await db.transaction(async (tx) => {
|
|
await tx
|
|
.update(table.user)
|
|
.set({ friends: locals.user?.friends.map((z) => z.id).concat(user[0].id) })
|
|
.where(eq(table.user.id, locals.user!.id));
|
|
|
|
await tx
|
|
.update(table.user)
|
|
.set({ friends: (user[0].friends as string[]).concat(locals.user!.id) })
|
|
.where(eq(table.user.id, user[0].id));
|
|
});
|
|
|
|
return { success: true };
|
|
}
|
|
|
|
// a request from us has already been sent to user
|
|
if (
|
|
locals.user?.friendRequests.find(
|
|
(z) => z.toUser == user[0].id && z.fromUser == locals.user!.id
|
|
)
|
|
)
|
|
return fail(400, { error: 'Already sent request' });
|
|
|
|
await db.insert(table.friendRequest).values({
|
|
id: FriendRequestID.newV4(),
|
|
fromUser: locals.user!.id,
|
|
toUser: user[0].id,
|
|
toUsername: user[0].username,
|
|
fromUsername: locals.user!.username
|
|
});
|
|
|
|
return { success: true };
|
|
},
|
|
cancelFriendRequest: async ({ request, locals }) => {
|
|
const data = await request.formData();
|
|
const requestId = data.get('requestId');
|
|
|
|
if (typeof requestId !== 'string') {
|
|
return fail(400, { error: 'Invalid request ID' });
|
|
}
|
|
|
|
// fetch the friend request
|
|
const friendRequest = await db
|
|
.select()
|
|
.from(table.friendRequest)
|
|
.where(eq(table.friendRequest.id, requestId))
|
|
.limit(1);
|
|
|
|
if (!friendRequest?.length) {
|
|
return fail(404, { error: 'Friend request not found' });
|
|
}
|
|
|
|
const fr = friendRequest[0];
|
|
|
|
// only allow cancelling if it's related to current user
|
|
if (fr.fromUser !== locals.user!.id && fr.toUser !== locals.user!.id) {
|
|
return fail(403, { error: 'Not allowed' });
|
|
}
|
|
|
|
// delete the request
|
|
await db.delete(table.friendRequest).where(eq(table.friendRequest.id, requestId)).limit(1);
|
|
|
|
return { success: true };
|
|
},
|
|
createGroup: async ({ request, locals }) => {
|
|
const data = await request.formData();
|
|
const members = data.getAll('member');
|
|
|
|
if (!members.length) {
|
|
return fail(400, { error: 'No members selected' });
|
|
}
|
|
|
|
return { success: true };
|
|
},
|
|
|
|
joinServer: async ({ request, locals }) => {
|
|
const data = await request.formData();
|
|
const invite = data.get('invite');
|
|
|
|
if (typeof invite !== 'string') {
|
|
return fail(400, { error: 'Invalid invite' });
|
|
}
|
|
|
|
const inv = await db.select().from(table.invite).where(eq(table.invite.code, invite)).limit(1);
|
|
|
|
if (inv?.length == 0) return fail(400, { error: 'Invalid invite' });
|
|
|
|
const server = await db
|
|
.select()
|
|
.from(table.server)
|
|
.where(eq(table.server.id, inv[0].serverId))
|
|
.limit(1);
|
|
|
|
if (server?.length == 0) return fail(400, { error: 'Invalid server' });
|
|
|
|
if (locals.user!.servers.some((z) => z.id == server[0].id))
|
|
return fail(400, { error: 'Already in server' });
|
|
|
|
await db.transaction(async (tx) => {
|
|
await tx
|
|
.update(table.user)
|
|
.set({ servers: locals.user!.servers.map((z) => z.id).concat([server[0].id]) })
|
|
.where(eq(table.user.id, locals.user!.id));
|
|
|
|
await tx
|
|
.update(table.server)
|
|
.set({ members: (server[0].members as string[]).concat([locals.user!.id]) })
|
|
.where(eq(table.server.id, server[0].id));
|
|
});
|
|
|
|
return { success: true };
|
|
},
|
|
|
|
createServer: async ({ request, locals }) => {
|
|
const data = await request.formData();
|
|
const name = data.get('name');
|
|
|
|
if (typeof name !== 'string' || name.length < 3) {
|
|
return fail(400, { error: 'Server name too short' });
|
|
}
|
|
const serverId = ServerID.newV4();
|
|
|
|
await db
|
|
.insert(table.server)
|
|
.values({ id: serverId, name, owner: locals.user!.id, members: [locals.user!.id] });
|
|
|
|
await db
|
|
.update(table.user)
|
|
.set({ servers: locals.user!.servers.map((z) => z.id).concat([serverId]) })
|
|
.where(eq(table.user.id, locals.user!.id));
|
|
|
|
redirect(303, `/app`);
|
|
}
|
|
} satisfies Actions;
|
|
|
|
function requireLogin() {
|
|
const { locals } = getRequestEvent();
|
|
|
|
if (!locals.user) {
|
|
return redirect(302, '/login');
|
|
}
|
|
|
|
return locals.user;
|
|
}
|