diff --git a/components/pages/inspector/ServerActions.tsx b/components/pages/inspector/ServerActions.tsx index 79c8614..618663e 100644 --- a/components/pages/inspector/ServerActions.tsx +++ b/components/pages/inspector/ServerActions.tsx @@ -14,18 +14,21 @@ import { import { Check, ChevronsUpDown } from "lucide-react"; import { cn } from "@/lib/utils"; import { useState } from "react"; -import { updateServerDiscoverability, updateServerFlags, updateServerOwner } from "@/lib/actions"; +import { addServerMember, updateServerDiscoverability, updateServerFlags, updateServerOwner } from "@/lib/actions"; import { useToast } from "../../ui/use-toast"; import Link from "next/link"; import { DropdownMenu, DropdownMenuContent } from "@/components/ui/dropdown-menu"; import { DropdownMenuTrigger } from "@radix-ui/react-dropdown-menu"; import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger } from "@/components/ui/alert-dialog"; import { Input } from "@/components/ui/input"; +import { Checkbox } from "@/components/ui/checkbox"; export function ServerActions({ server }: { server: Server }) { const [selectBadges, setSelectBadges] = useState(false); const [serverDraft, setDraft] = useState(server); const [newOwner, setNewOwner] = useState(""); + const [newMember, setNewMember] = useState(""); + const [newMemberEvent, setNewMemberEvent] = useState(true); const { toast } = useToast(); return ( @@ -194,6 +197,51 @@ export function ServerActions({ server }: { server: Server }) { + + + + + + + + + Add member to server + + + Enter the ID of the user you want to add. + setNewMember(e.currentTarget.value)} + /> + setNewMemberEvent(state === true)}>Publish join event + + + + Cancel + { + try { + await addServerMember(server._id, newMember, newMemberEvent); + setNewMember(""); + toast({ title: "User added to server" }); + } catch(e) { + toast({ + title: "Failed to add user", + description: String(e), + variant: "destructive", + }); + } + }} + > + Update + + + + diff --git a/lib/accessPermissions.ts b/lib/accessPermissions.ts index c5a7cda..5922c5b 100644 --- a/lib/accessPermissions.ts +++ b/lib/accessPermissions.ts @@ -37,7 +37,7 @@ type Permission = | `servers${ | "" | `/fetch${"" | "/by-id"}` - | `/update${"" | "/flags" | "/discoverability" | "/owner"}`}` + | `/update${"" | "/flags" | "/discoverability" | "/owner" | "/add-member"}`}` | `users${ | "" | `/fetch${ @@ -113,6 +113,7 @@ const PermissionSets = { "users/update/badges", "servers/update/owner", + "servers/update/add-member", "accounts/fetch/by-id", "accounts/fetch/by-email", diff --git a/lib/actions.ts b/lib/actions.ts index b698244..9a30a58 100644 --- a/lib/actions.ts +++ b/lib/actions.ts @@ -25,6 +25,7 @@ import { User, } from "revolt-api"; import { checkPermission } from "./accessPermissions"; +import { Long } from "mongodb"; export async function sendAlert(userId: string, content: string) { await checkPermission("users/create/alert", userId, { content }); @@ -609,6 +610,44 @@ export async function updateServerOwner(serverId: string, userId: string) { }); } +export async function addServerMember(serverId: string, userId: string, withEvent: boolean) { + const server = await mongo() + .db("revolt") + .collection("servers") + .findOne({ _id: serverId }); + + const channels = await mongo() + .db("revolt") + .collection("channels") + .find({ server: serverId }) + .toArray(); + + if (!server) throw new Error("server doesn't exist"); + + await mongo() + .db("revolt") + .collection("server_members") + .insertOne({ + _id: { server: serverId, user: userId }, + joined_at: Long.fromNumber(Date.now()) as unknown as string, + }); + + await publishMessage(userId, { + type: "ServerCreate", + id: serverId, + channels: channels, + server: server, + }); + + if (withEvent) { + await publishMessage(serverId, { + type: "ServerMemberJoin", + id: serverId, + user: userId, + }); + } +} + export async function deleteInvite(invite: string) { await checkPermission("channels/update/invites", invite);