mirror of
https://github.com/DeveloLongScript/MHSF.git
synced 2026-05-07 15:05:02 -05:00
feat: reporting
This commit is contained in:
parent
79cef04e48
commit
7c2d7c61d0
@ -22,6 +22,7 @@
|
||||
"@unocss/postcss": "^0.61.5",
|
||||
"@unocss/transformer-directives": "^0.61.5",
|
||||
"@unocss/webpack": "^0.61.5",
|
||||
"discord.js": "^14.15.3",
|
||||
"inngest": "^3.21.2",
|
||||
"input-otp": "^1.2.4",
|
||||
"json-beautify": "^1.1.1",
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
import ClientFadeIn from "@/components/ClientFadeIn";
|
||||
|
||||
export default function ECA() {
|
||||
return (
|
||||
<main>
|
||||
<div className="pt-[100px] pr-8 pl-8">
|
||||
<div className="pt-[100px] p-[300px]">
|
||||
<strong className="text-2xl">External Content Agreement (ECA)</strong>
|
||||
<br />
|
||||
By making external content available for anyone to see, there needs to
|
||||
@ -16,62 +18,96 @@ export default function ECA() {
|
||||
uploaded onto the platform are.
|
||||
<br />
|
||||
<br />
|
||||
<strong className="text-xl">Source Code</strong>
|
||||
<ClientFadeIn>
|
||||
<div>
|
||||
<strong className="text-xl">Source Code</strong>
|
||||
<br />
|
||||
The source code for MHSF is defined by the{" "}
|
||||
<a href="https://github.com/DeveloLongScript/MHSF/blob/main/LICENSE">
|
||||
MIT License
|
||||
</a>
|
||||
. You are free to use MHSF for commercial use, and you may modify
|
||||
the software however you'd like. Taking copies of the software (aka
|
||||
<i>"forking"</i>) is also freely allowed.
|
||||
<br />
|
||||
</div>
|
||||
</ClientFadeIn>
|
||||
<br />
|
||||
The source code for MHSF is defined by the{" "}
|
||||
<a href="https://github.com/DeveloLongScript/MHSF/blob/main/LICENSE">
|
||||
MIT License
|
||||
</a>
|
||||
. You are free to use MHSF for commercial use, and you may modify the
|
||||
software however you'd like. Taking copies of the software (aka
|
||||
<i>"forking"</i>) is also freely allowed.
|
||||
<ClientFadeIn delay={200}>
|
||||
<div>
|
||||
<strong className="text-xl">What your limits are</strong>
|
||||
<br />
|
||||
When creating content, if its a matter of making a profile picture,
|
||||
or editing the description for a server, (and more), you must follow
|
||||
the underlying agreements below.
|
||||
<br />
|
||||
For making banners & descriptions, you must follow{" "}
|
||||
<a href="https://minehut.wiki.gg/wiki/Rules">
|
||||
Minehuts Terms of Service
|
||||
</a>{" "}
|
||||
<i>
|
||||
as all content made is associated to Minehut (as the server is
|
||||
mostly on a community for Minehut).
|
||||
</i>{" "}
|
||||
<br />
|
||||
For making Discord server embeds, you must follow{" "}
|
||||
<a href="https://discord.com/terms/">
|
||||
Discords Terms of Service
|
||||
</a>{" "}
|
||||
<i>as all content made is associated to Discord.</i> <br />
|
||||
<strong>
|
||||
For all other content, they must follow the following: <br />
|
||||
</strong>
|
||||
- No inappropriate/adult images <br />
|
||||
- No swear words of any kind or slurs <br />- Endorsing unethical
|
||||
client modifications (aka cheating or hacking)
|
||||
<br />
|
||||
</div>
|
||||
</ClientFadeIn>
|
||||
<br />
|
||||
<ClientFadeIn delay={400}>
|
||||
<div>
|
||||
<strong className="text-xl">When you agree to the ECA</strong>
|
||||
<br />
|
||||
When you add customization to your server, or add a profile picture
|
||||
(linking an account is included), you must follow the ECA.
|
||||
<br />
|
||||
</div>
|
||||
</ClientFadeIn>
|
||||
<br />
|
||||
<strong className="text-xl">What your limits are</strong>
|
||||
<ClientFadeIn delay={600}>
|
||||
<div>
|
||||
<strong className="text-xl">When linking an account</strong>
|
||||
<br />
|
||||
When linking an account, you must follow the privacy policy and
|
||||
terms of service to the associated service that you linked your MHSF
|
||||
account to. Additionally, if you link an external account{" "}
|
||||
<i>after</i> account creation, everything said before is still true.
|
||||
<br />
|
||||
</div>
|
||||
</ClientFadeIn>
|
||||
<br />
|
||||
When creating content, if its a matter of making a profile picture, or
|
||||
editing the description for a server, (and more), you must follow the
|
||||
underlying agreements below.
|
||||
<ClientFadeIn delay={800}>
|
||||
<div>
|
||||
<strong className="text-xl">Violations</strong>
|
||||
<br />
|
||||
Violations from above have 1 warning. Your first interaction is a
|
||||
warning by removing the content from MHSF, and your 2nd is
|
||||
banning/deleting your account. (some violations are an instant
|
||||
delete)
|
||||
</div>
|
||||
</ClientFadeIn>
|
||||
<br />
|
||||
For making banners & descriptions, you must follow{" "}
|
||||
<a href="https://minehut.wiki.gg/wiki/Rules">
|
||||
Minehuts Terms of Service
|
||||
</a>{" "}
|
||||
<i>
|
||||
as all content made is associated to Minehut (as the server is mostly
|
||||
on a community for Minehut).
|
||||
</i>{" "}
|
||||
<br />
|
||||
For making Discord server embeds, you must follow{" "}
|
||||
<a href="https://discord.com/terms/">Discords Terms of Service</a>{" "}
|
||||
<i>as all content made is associated to Discord.</i> <br />
|
||||
<strong>
|
||||
For all other content, they must follow the following: <br />
|
||||
</strong>
|
||||
- No inappropriate/adult images <br />
|
||||
- No swear words of any kind or slurs <br />- Endorsing unethical client
|
||||
modifications (aka cheating or hacking)
|
||||
<br />
|
||||
<br />
|
||||
<strong className="text-xl">When you agree to the ECA</strong>
|
||||
<br />
|
||||
When you add customization to your server, or add a profile picture
|
||||
(linking an account is included), you must follow the ECA.
|
||||
<br />
|
||||
<br />
|
||||
<strong className="text-xl">When linking an account</strong>
|
||||
<br />
|
||||
When linking an account, you must follow the privacy policy and terms of
|
||||
service to the associated service that you linked your MHSF account to.
|
||||
Additionally, if you link an external account <i>after</i> account
|
||||
creation, everything said before is still true.
|
||||
<br />
|
||||
<br />
|
||||
<strong className="text-xl">Violations</strong>
|
||||
<br />
|
||||
Violations from above have 1 warning. Your first interaction is a
|
||||
warning by removing the content from MHSF, and your 2nd is
|
||||
banning/deleting your account.
|
||||
<ClientFadeIn delay={1000}>
|
||||
<div>
|
||||
<strong className="text-xl">Reporting</strong>
|
||||
<br />
|
||||
If you personally see a violation of the ECA, you can report it by
|
||||
clicking the customization tab on a server, and hitting the Report
|
||||
button (it doesn't appear when the server was never owned). If you
|
||||
misuse this feature, you may get your account deleted.
|
||||
</div>
|
||||
</ClientFadeIn>
|
||||
</div>
|
||||
</main>
|
||||
);
|
||||
|
||||
@ -6,6 +6,7 @@ import { Dispatch, SetStateAction, useEffect, useState } from "react";
|
||||
import {
|
||||
getCustomization,
|
||||
ownServer,
|
||||
reportServer,
|
||||
setCustomization,
|
||||
serverOwned as sOFunc,
|
||||
unownServer,
|
||||
@ -43,6 +44,14 @@ import { useTheme } from "next-themes";
|
||||
import { DiscordPopover } from "./misc/DiscordPopover";
|
||||
import { Spinner } from "./ui/spinner";
|
||||
import { BannerPopover } from "./misc/BannerPopover";
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogDescription,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
DialogTrigger,
|
||||
} from "./ui/dialog";
|
||||
|
||||
const formSchema = z.object({
|
||||
description: z
|
||||
@ -67,6 +76,7 @@ export default function ServerCustomize({
|
||||
const [serverOwned, setServerOwned] = useState(false);
|
||||
const [userOwned, setUserOwned] = useState(false);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [reason, setReason] = useState("");
|
||||
const [description, setDescription] = useState("");
|
||||
const [get, setGet] = useState<any>({});
|
||||
const [author, setAuthor] = useState<string | undefined>("");
|
||||
@ -134,6 +144,74 @@ export default function ServerCustomize({
|
||||
customize it.
|
||||
</div>
|
||||
)}
|
||||
{serverOwned && !userOwned && (
|
||||
<div>
|
||||
<div className="font-bold">
|
||||
Is this server in violation of the ECA?
|
||||
</div>
|
||||
Is this server in violation of the{" "}
|
||||
<Link href="/legal/external-content-agreement">
|
||||
External Content Agreement (aka ECA)
|
||||
</Link>
|
||||
? You can report the server to remove the customizations from the
|
||||
server.
|
||||
<Dialog>
|
||||
<DialogTrigger>
|
||||
<Button className="h-[30px] ml-2">Report</Button>
|
||||
</DialogTrigger>
|
||||
<DialogContent>
|
||||
<DialogHeader>
|
||||
<DialogTitle>Report Server</DialogTitle>
|
||||
<DialogDescription>
|
||||
This will send a notification to MHSF maintainers. This
|
||||
server must be in violation of the{" "}
|
||||
<Link href="/legal/external-content-agreement">ECA</Link> to
|
||||
be a valid report. Typical response times include 1 hour to
|
||||
1 day, and you will not be notified if your report is
|
||||
successful or not.{" "}
|
||||
<b>
|
||||
Please do not spam this form with mindless reports. If you
|
||||
do, your account will be banned. We are not Minehut
|
||||
support, we cannot help you with a problem within the
|
||||
Minehut platform or within the server, we can only
|
||||
moderate the customization of the server.
|
||||
</b>{" "}
|
||||
(if the problem is within the server,{" "}
|
||||
<Link href="https://support.minehut.com/hc/en-us/requests/new?tf_subject=Reporting%20Server&tf_27062997154195=reports_appeals&tf_27063229498259=report_server">
|
||||
report it on Minehut
|
||||
</Link>
|
||||
)<br />
|
||||
<br />
|
||||
<b>Reason:</b>
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
<Textarea
|
||||
value={reason}
|
||||
onChange={(e) => setReason(e.target.value)}
|
||||
/>
|
||||
<div className="grid grid-flow-row gap-2">
|
||||
<Button
|
||||
onClick={async () => {
|
||||
await toast.promise(
|
||||
new Promise(async (g, b) => {
|
||||
(await reportServer(server, reason)) ? g("") : b();
|
||||
}),
|
||||
{
|
||||
success: "Report sent!",
|
||||
loading: "Sending report...",
|
||||
error: "Error while sending report",
|
||||
}
|
||||
);
|
||||
}}
|
||||
>
|
||||
Report Server
|
||||
</Button>
|
||||
</div>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
<br />
|
||||
</div>
|
||||
)}
|
||||
</SignedIn>
|
||||
|
||||
{!serverOwned && minehutOwned && (
|
||||
|
||||
@ -379,3 +379,26 @@ export async function sortedFavorites(): Promise<
|
||||
throw Error("Error while running API");
|
||||
}
|
||||
}
|
||||
|
||||
export async function reportServer(
|
||||
server: string,
|
||||
reason: string
|
||||
): Promise<boolean> {
|
||||
try {
|
||||
const response = await fetch(connector(`/report-server`, { version: 1 }), {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({ server, reason }),
|
||||
});
|
||||
|
||||
if (response.status == 400) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
} catch {
|
||||
throw Error("Error while running API");
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,8 +1,119 @@
|
||||
import { OnlineServer } from "@/lib/types/mh-server";
|
||||
import { Inngest } from "inngest";
|
||||
import { serve } from "inngest/next";
|
||||
import { MongoClient } from "mongodb";
|
||||
import { Document, MongoClient, ObjectId, WithId } from "mongodb";
|
||||
import {
|
||||
ActionRowBuilder,
|
||||
ButtonBuilder,
|
||||
ButtonStyle,
|
||||
Client,
|
||||
EmbedBuilder,
|
||||
GatewayIntentBits,
|
||||
ModalBuilder,
|
||||
REST,
|
||||
Routes,
|
||||
SlashCommandBuilder,
|
||||
SlashCommandStringOption,
|
||||
TextChannel,
|
||||
TextInputBuilder,
|
||||
TextInputStyle,
|
||||
} from "discord.js";
|
||||
|
||||
let reporting = true;
|
||||
let initalizedYet = false;
|
||||
const commands = [
|
||||
new SlashCommandBuilder()
|
||||
.setName("realive")
|
||||
.setDescription("Re-alive an existing report that was glitched")
|
||||
.addStringOption(
|
||||
new SlashCommandStringOption()
|
||||
.setName("id")
|
||||
.setRequired(true)
|
||||
.setDescription("Report ID")
|
||||
),
|
||||
];
|
||||
|
||||
let client: Client;
|
||||
|
||||
// this isn't entirely necessary, to run each time the server starts
|
||||
async function init() {
|
||||
try {
|
||||
const rest = new REST({ version: "10" }).setToken(
|
||||
process.env.DISCORD_TOKEN as string
|
||||
);
|
||||
|
||||
try {
|
||||
console.log("[REPORTING] Started refreshing application (/) commands.");
|
||||
|
||||
await rest.put(
|
||||
Routes.applicationCommands(process.env.DISCORD_APP_ID as string),
|
||||
{ body: commands }
|
||||
);
|
||||
|
||||
console.log(
|
||||
"[REPORTING] Successfully reloaded application (/) commands."
|
||||
);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
} catch {
|
||||
console.log(
|
||||
"[REPORTING] Discord API token not found, skipping reporting..."
|
||||
);
|
||||
reporting = false;
|
||||
}
|
||||
client = new Client({
|
||||
intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages],
|
||||
});
|
||||
client.on("interactionCreate", async (interaction) => {
|
||||
if (!interaction.isChatInputCommand()) return;
|
||||
if (interaction.commandName === "realive") {
|
||||
await interaction.reply({
|
||||
embeds: [
|
||||
new EmbedBuilder()
|
||||
.setTitle("Re-creating report")
|
||||
.setColor("Blurple")
|
||||
.setDescription("This may take a few seconds.."),
|
||||
],
|
||||
ephemeral: true,
|
||||
});
|
||||
const mongo = new MongoClient(process.env.MONGO_DB as string);
|
||||
const db = mongo.db("mhsf");
|
||||
const collection = db.collection("reports");
|
||||
let reportDoc: WithId<Document> | null;
|
||||
try {
|
||||
reportDoc = await collection.findOne({
|
||||
_id: new ObjectId(interaction.options.getString("id") as string),
|
||||
});
|
||||
} catch {
|
||||
await interaction.editReply({
|
||||
embeds: [
|
||||
new EmbedBuilder()
|
||||
.setTitle("Report ID not valid")
|
||||
.setColor("Red")
|
||||
.setDescription("This report could not be found."),
|
||||
],
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (reportDoc === null) {
|
||||
await interaction.editReply({
|
||||
embeds: [
|
||||
new EmbedBuilder()
|
||||
.setTitle("Report not found")
|
||||
.setColor("Red")
|
||||
.setDescription("This report could not be found."),
|
||||
],
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
report({ data: { ...reportDoc, id: reportDoc._id.toString() } });
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
// Create a client to send and receive events
|
||||
export const inngest = new Inngest({ id: "mhsf" });
|
||||
|
||||
@ -10,6 +121,33 @@ export const inngest = new Inngest({ id: "mhsf" });
|
||||
export default serve({
|
||||
client: inngest,
|
||||
functions: [
|
||||
inngest.createFunction(
|
||||
{ id: "report" },
|
||||
{ event: "report-server" },
|
||||
async ({ event, step }) => {
|
||||
if (!reporting) {
|
||||
throw new Error("Cannot report server: Discord API token not found");
|
||||
}
|
||||
|
||||
if (!initalizedYet) {
|
||||
await init();
|
||||
initalizedYet = true;
|
||||
client.login(process.env.DISCORD_TOKEN);
|
||||
|
||||
console.log(`[REPORTING] Waiting for bot to be ready`);
|
||||
|
||||
client.on("ready", () => {
|
||||
console.log(
|
||||
`[REPORTING] Bot logged in as ${client.user?.displayName}`
|
||||
);
|
||||
report(event);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
report(event);
|
||||
}
|
||||
),
|
||||
inngest.createFunction(
|
||||
{ id: "short-term-data" },
|
||||
[{ cron: "*/30 * * * *" }, { event: "test/30-min" }],
|
||||
@ -80,3 +218,238 @@ export default serve({
|
||||
),
|
||||
],
|
||||
});
|
||||
|
||||
async function report(event: any) {
|
||||
const isTextBased = client.channels.cache.get(
|
||||
process.env.REPORTS_CHANNEL as string
|
||||
)?.isTextBased;
|
||||
|
||||
if (!isTextBased) {
|
||||
throw new Error(
|
||||
"Cannot report server: Report channel not found or not a text channel."
|
||||
);
|
||||
}
|
||||
const channel = client.channels.cache.get(
|
||||
process.env.REPORTS_CHANNEL as string
|
||||
) as TextChannel;
|
||||
|
||||
const goToServer = new ButtonBuilder()
|
||||
.setLabel("Go to server")
|
||||
.setStyle(ButtonStyle.Link)
|
||||
.setURL("https://list.mlnehut.com/server/" + event.data.server);
|
||||
|
||||
const confirm = new ButtonBuilder()
|
||||
.setCustomId("resolve")
|
||||
.setLabel("Resolve")
|
||||
.setStyle(ButtonStyle.Primary);
|
||||
const typed = (name: string) =>
|
||||
new ButtonBuilder()
|
||||
.setCustomId("typed")
|
||||
.setLabel(name + " is typing")
|
||||
.setStyle(ButtonStyle.Secondary)
|
||||
.setDisabled(true);
|
||||
|
||||
const cancel = new ButtonBuilder()
|
||||
.setCustomId("cancel")
|
||||
.setLabel("Cancel")
|
||||
.setStyle(ButtonStyle.Secondary);
|
||||
|
||||
const undo = new ButtonBuilder()
|
||||
.setCustomId("undo")
|
||||
.setLabel("Undo")
|
||||
.setStyle(ButtonStyle.Danger);
|
||||
|
||||
const undor = new ActionRowBuilder<ButtonBuilder>().addComponents(
|
||||
undo,
|
||||
goToServer
|
||||
);
|
||||
|
||||
const rowN = new ActionRowBuilder<ButtonBuilder>().addComponents(
|
||||
confirm,
|
||||
cancel,
|
||||
goToServer
|
||||
);
|
||||
|
||||
const message = await channel.send({
|
||||
embeds: [
|
||||
new EmbedBuilder()
|
||||
.setColor("Orange")
|
||||
.setTitle("New report to server")
|
||||
.setTimestamp()
|
||||
.setDescription(
|
||||
"A server has been reported by a player. \n Reason: " +
|
||||
event.data.reason +
|
||||
(event.data.reason == "" ? "*<empty>*" : "")
|
||||
)
|
||||
.setFields([
|
||||
{ name: "User ID", value: `\`${event.data.userId}\`` },
|
||||
{ name: "Server", value: `${event.data.server}` },
|
||||
])
|
||||
.setFooter({
|
||||
text:
|
||||
"Is this report glitched? Use the command /realive id:" +
|
||||
event.data._id +
|
||||
" to do actions on this report.",
|
||||
}),
|
||||
],
|
||||
components: [rowN],
|
||||
});
|
||||
setTimeout(async () => {
|
||||
await messageLoop();
|
||||
|
||||
async function messageLoop() {
|
||||
const confirmation = await message.awaitMessageComponent({});
|
||||
if (confirmation.customId == "undo") {
|
||||
(await confirmation.reply({ content: "Done!" })).delete();
|
||||
await message.edit({
|
||||
embeds: [
|
||||
new EmbedBuilder()
|
||||
.setColor("Orange")
|
||||
.setTitle("New report to server")
|
||||
.setTimestamp()
|
||||
.setDescription(
|
||||
"A server has been reported by a player. \n Reason: " +
|
||||
event.data.reason +
|
||||
(event.data.reason == "" ? "*<empty>*" : "")
|
||||
)
|
||||
.setFields([
|
||||
{ name: "User ID", value: `\`${event.data.userId}\`` },
|
||||
{ name: "Server", value: `${event.data.server}` },
|
||||
])
|
||||
.setFooter({
|
||||
text:
|
||||
"Is this report glitched? Use the command /realive id:" +
|
||||
event.data._id +
|
||||
" to do actions on this report.",
|
||||
}),
|
||||
],
|
||||
components: [rowN],
|
||||
});
|
||||
}
|
||||
if (confirmation.customId == "resolve") {
|
||||
await message.edit({
|
||||
embeds: [
|
||||
new EmbedBuilder()
|
||||
.setColor("Green")
|
||||
.setTitle("Server report resolved")
|
||||
.setTimestamp()
|
||||
.setDescription(
|
||||
"The server report has been resolved by <@" +
|
||||
confirmation.user.id +
|
||||
"> \n Reason: " +
|
||||
event.data.reason +
|
||||
(event.data.reason == "" ? "*<empty>*" : "")
|
||||
)
|
||||
.setFields([
|
||||
{ name: "User ID", value: `\`${event.data.userId}\`` },
|
||||
{ name: "Server", value: `${event.data.server}` },
|
||||
])
|
||||
.setFooter({
|
||||
text:
|
||||
"Is this report glitched? Use the command /realive id:" +
|
||||
event.data._id +
|
||||
" to do actions on this report.",
|
||||
}),
|
||||
],
|
||||
components: [undor],
|
||||
});
|
||||
(
|
||||
await confirmation.reply({ content: "Done!", ephemeral: true })
|
||||
).delete();
|
||||
}
|
||||
|
||||
if (confirmation.customId == "cancel") {
|
||||
const modal = new ModalBuilder().setCustomId("why").setTitle("MHSF");
|
||||
const favoriteColorInput = new TextInputBuilder()
|
||||
.setCustomId("whyToCancel")
|
||||
.setLabel("Cancelation reason")
|
||||
.setStyle(TextInputStyle.Short);
|
||||
|
||||
const row = new ActionRowBuilder<TextInputBuilder>().addComponents(
|
||||
favoriteColorInput
|
||||
);
|
||||
modal.addComponents(row);
|
||||
confirmation.showModal(modal);
|
||||
|
||||
try {
|
||||
let reportedYet = false;
|
||||
await message.edit({
|
||||
components: [
|
||||
new ActionRowBuilder<ButtonBuilder>().addComponents(
|
||||
typed(
|
||||
confirmation.user.globalName || confirmation.user.username
|
||||
)
|
||||
),
|
||||
],
|
||||
});
|
||||
setTimeout(async () => {
|
||||
if (reportedYet == false) {
|
||||
await message.edit({
|
||||
components: [rowN],
|
||||
});
|
||||
|
||||
await messageLoop();
|
||||
}
|
||||
|
||||
return;
|
||||
}, 60_000);
|
||||
const submission = await confirmation.awaitModalSubmit({
|
||||
time: 60_000,
|
||||
});
|
||||
const text = submission.fields.getTextInputValue("whyToCancel");
|
||||
|
||||
if (text == "") {
|
||||
await submission.reply({ content: "Done!", ephemeral: true });
|
||||
await messageLoop();
|
||||
}
|
||||
|
||||
reportedYet = true;
|
||||
|
||||
await message.edit({
|
||||
embeds: [
|
||||
new EmbedBuilder()
|
||||
.setColor("Red")
|
||||
.setTitle("Server report cancelled")
|
||||
.setTimestamp()
|
||||
.setDescription(
|
||||
"The server report has been cancelled by <@" +
|
||||
confirmation.user.id +
|
||||
"> \n Reason of cancelation: " +
|
||||
text +
|
||||
"\nReason of report: " +
|
||||
event.data.reason +
|
||||
(event.data.reason == "" ? "*<empty>*" : "")
|
||||
)
|
||||
.setFields([
|
||||
{ name: "User ID", value: `\`${event.data.userId}\`` },
|
||||
{ name: "Server", value: `${event.data.server}` },
|
||||
])
|
||||
.setFooter({
|
||||
text:
|
||||
"Is this report glitched? Use the command /realive id:" +
|
||||
event.data._id +
|
||||
" to do actions on this report.",
|
||||
}),
|
||||
],
|
||||
components: [undor],
|
||||
});
|
||||
await submission.reply({ content: "Done!", ephemeral: true });
|
||||
} catch (e) {
|
||||
await message.edit({
|
||||
components: [rowN],
|
||||
});
|
||||
await confirmation.reply({
|
||||
embeds: [
|
||||
new EmbedBuilder()
|
||||
.setTitle("You took too long!")
|
||||
.setDescription("Please try again.")
|
||||
.setColor("Red"),
|
||||
],
|
||||
ephemeral: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
await messageLoop();
|
||||
}
|
||||
}, 0);
|
||||
}
|
||||
|
||||
50
src/pages/api/v1/report-server.ts
Normal file
50
src/pages/api/v1/report-server.ts
Normal file
@ -0,0 +1,50 @@
|
||||
import { NextApiRequest, NextApiResponse } from "next";
|
||||
import { getAuth } from "@clerk/nextjs/server";
|
||||
import { MongoClient } from "mongodb";
|
||||
import { inngest } from "../inngest";
|
||||
|
||||
export default async function handler(
|
||||
req: NextApiRequest,
|
||||
res: NextApiResponse
|
||||
) {
|
||||
const { userId } = getAuth(req);
|
||||
const { server } = req.body;
|
||||
|
||||
if (server == null) {
|
||||
res.status(400).send({ message: "Couldn't find data" });
|
||||
return;
|
||||
}
|
||||
const { reason } = req.body;
|
||||
|
||||
if (reason == null) {
|
||||
res.status(400).send({ message: "Couldn't find data" });
|
||||
return;
|
||||
}
|
||||
|
||||
if (!userId) {
|
||||
return res.status(401).json({ error: "Unauthorized" });
|
||||
}
|
||||
const client = new MongoClient(process.env.MONGO_DB as string);
|
||||
await client.connect();
|
||||
|
||||
const db = client.db("mhsf");
|
||||
const collection = db.collection("reports");
|
||||
const entry = await collection.insertOne({
|
||||
server: server,
|
||||
reason: reason,
|
||||
userId: userId,
|
||||
});
|
||||
// Don't wait for this to finish, just continue anyway
|
||||
inngest.send({
|
||||
name: "report-server",
|
||||
data: {
|
||||
_id: entry.insertedId.toString(),
|
||||
server,
|
||||
reason,
|
||||
userId,
|
||||
},
|
||||
});
|
||||
|
||||
client.close();
|
||||
res.send({ msg: "Successfully reported server!" });
|
||||
}
|
||||
162
yarn.lock
162
yarn.lock
@ -209,6 +209,71 @@
|
||||
dependencies:
|
||||
csstype "3.1.1"
|
||||
|
||||
"@discordjs/builders@^1.8.2":
|
||||
version "1.8.2"
|
||||
resolved "https://registry.yarnpkg.com/@discordjs/builders/-/builders-1.8.2.tgz#535d970331ee40f20dec9ef8079e43092f323ce9"
|
||||
integrity sha512-6wvG3QaCjtMu0xnle4SoOIeFB4y6fKMN6WZfy3BMKJdQQtPLik8KGzDwBVL/+wTtcE/ZlFjgEk74GublyEVZ7g==
|
||||
dependencies:
|
||||
"@discordjs/formatters" "^0.4.0"
|
||||
"@discordjs/util" "^1.1.0"
|
||||
"@sapphire/shapeshift" "^3.9.7"
|
||||
discord-api-types "0.37.83"
|
||||
fast-deep-equal "^3.1.3"
|
||||
ts-mixer "^6.0.4"
|
||||
tslib "^2.6.2"
|
||||
|
||||
"@discordjs/collection@1.5.3":
|
||||
version "1.5.3"
|
||||
resolved "https://registry.yarnpkg.com/@discordjs/collection/-/collection-1.5.3.tgz#5a1250159ebfff9efa4f963cfa7e97f1b291be18"
|
||||
integrity sha512-SVb428OMd3WO1paV3rm6tSjM4wC+Kecaa1EUGX7vc6/fddvw/6lg90z4QtCqm21zvVe92vMMDt9+DkIvjXImQQ==
|
||||
|
||||
"@discordjs/collection@^2.1.0":
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@discordjs/collection/-/collection-2.1.0.tgz#f327d944ab2dcf9a1f674470a481f78a120a5e3b"
|
||||
integrity sha512-mLcTACtXUuVgutoznkh6hS3UFqYirDYAg5Dc1m8xn6OvPjetnUlf/xjtqnnc47OwWdaoCQnHmHh9KofhD6uRqw==
|
||||
|
||||
"@discordjs/formatters@^0.4.0":
|
||||
version "0.4.0"
|
||||
resolved "https://registry.yarnpkg.com/@discordjs/formatters/-/formatters-0.4.0.tgz#066a2c2163b26ac066e6f621f17445be9690c6a9"
|
||||
integrity sha512-fJ06TLC1NiruF35470q3Nr1bi95BdvKFAF+T5bNfZJ4bNdqZ3VZ+Ttg6SThqTxm6qumSG3choxLBHMC69WXNXQ==
|
||||
dependencies:
|
||||
discord-api-types "0.37.83"
|
||||
|
||||
"@discordjs/rest@^2.3.0":
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/@discordjs/rest/-/rest-2.3.0.tgz#06d37c7fb54a9be61134b5bbb201abd760343472"
|
||||
integrity sha512-C1kAJK8aSYRv3ZwMG8cvrrW4GN0g5eMdP8AuN8ODH5DyOCbHgJspze1my3xHOAgwLJdKUbWNVyAeJ9cEdduqIg==
|
||||
dependencies:
|
||||
"@discordjs/collection" "^2.1.0"
|
||||
"@discordjs/util" "^1.1.0"
|
||||
"@sapphire/async-queue" "^1.5.2"
|
||||
"@sapphire/snowflake" "^3.5.3"
|
||||
"@vladfrangu/async_event_emitter" "^2.2.4"
|
||||
discord-api-types "0.37.83"
|
||||
magic-bytes.js "^1.10.0"
|
||||
tslib "^2.6.2"
|
||||
undici "6.13.0"
|
||||
|
||||
"@discordjs/util@^1.1.0":
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@discordjs/util/-/util-1.1.0.tgz#dcffd2b61aab8eadd66bea67811bc34fc769bb2a"
|
||||
integrity sha512-IndcI5hzlNZ7GS96RV3Xw1R2kaDuXEp7tRIy/KlhidpN/BQ1qh1NZt3377dMLTa44xDUNKT7hnXkA/oUAzD/lg==
|
||||
|
||||
"@discordjs/ws@^1.1.1":
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@discordjs/ws/-/ws-1.1.1.tgz#bffbfd46838258ab09054ed98ddef1a36f6507a3"
|
||||
integrity sha512-PZ+vLpxGCRtmr2RMkqh8Zp+BenUaJqlS6xhgWKEZcgC/vfHLEzpHtKkB0sl3nZWpwtcKk6YWy+pU3okL2I97FA==
|
||||
dependencies:
|
||||
"@discordjs/collection" "^2.1.0"
|
||||
"@discordjs/rest" "^2.3.0"
|
||||
"@discordjs/util" "^1.1.0"
|
||||
"@sapphire/async-queue" "^1.5.2"
|
||||
"@types/ws" "^8.5.10"
|
||||
"@vladfrangu/async_event_emitter" "^2.2.4"
|
||||
discord-api-types "0.37.83"
|
||||
tslib "^2.6.2"
|
||||
ws "^8.16.0"
|
||||
|
||||
"@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0":
|
||||
version "4.4.0"
|
||||
resolved "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz"
|
||||
@ -1135,6 +1200,24 @@
|
||||
resolved "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.10.3.tgz"
|
||||
integrity sha512-qC/xYId4NMebE6w/V33Fh9gWxLgURiNYgVNObbJl2LZv0GUUItCcCqC5axQSwRaAgaxl2mELq1rMzlswaQ0Zxg==
|
||||
|
||||
"@sapphire/async-queue@^1.5.2":
|
||||
version "1.5.3"
|
||||
resolved "https://registry.yarnpkg.com/@sapphire/async-queue/-/async-queue-1.5.3.tgz#03cd2a2f3665068f314736bdc56eee2025352422"
|
||||
integrity sha512-x7zadcfJGxFka1Q3f8gCts1F0xMwCKbZweM85xECGI0hBTeIZJGGCrHgLggihBoprlQ/hBmDR5LKfIPqnmHM3w==
|
||||
|
||||
"@sapphire/shapeshift@^3.9.7":
|
||||
version "3.9.7"
|
||||
resolved "https://registry.yarnpkg.com/@sapphire/shapeshift/-/shapeshift-3.9.7.tgz#43e23243cac8a0c046bf1e73baf3dbf407d33a0c"
|
||||
integrity sha512-4It2mxPSr4OGn4HSQWGmhFMsNFGfFVhWeRPCRwbH972Ek2pzfGRZtb0pJ4Ze6oIzcyh2jw7nUDa6qGlWofgd9g==
|
||||
dependencies:
|
||||
fast-deep-equal "^3.1.3"
|
||||
lodash "^4.17.21"
|
||||
|
||||
"@sapphire/snowflake@3.5.3", "@sapphire/snowflake@^3.5.3":
|
||||
version "3.5.3"
|
||||
resolved "https://registry.yarnpkg.com/@sapphire/snowflake/-/snowflake-3.5.3.tgz#0c102aa2ec5b34f806e9bc8625fc6a5e1d0a0c6a"
|
||||
integrity sha512-jjmJywLAFoWeBi1W7994zZyiNWPIiqRRNAmSERxyg93xRGzNYvGjlZ0gR6x0F4gPRi2+0O6S71kOZYyr3cxaIQ==
|
||||
|
||||
"@swc/counter@^0.1.3":
|
||||
version "0.1.3"
|
||||
resolved "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz"
|
||||
@ -1288,6 +1371,13 @@
|
||||
resolved "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz"
|
||||
integrity sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==
|
||||
|
||||
"@types/node@*":
|
||||
version "22.4.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-22.4.1.tgz#9b595d292c65b94c20923159e2ce947731b6fdce"
|
||||
integrity sha512-1tbpb9325+gPnKK0dMm+/LMriX0vKxf6RnB0SZUqfyVkQ4fMgUSySqhxE/y8Jvs4NyF1yHzTfG9KlnkIODxPKg==
|
||||
dependencies:
|
||||
undici-types "~6.19.2"
|
||||
|
||||
"@types/node@^20":
|
||||
version "20.13.0"
|
||||
resolved "https://registry.npmjs.org/@types/node/-/node-20.13.0.tgz"
|
||||
@ -1349,6 +1439,13 @@
|
||||
dependencies:
|
||||
"@types/webidl-conversions" "*"
|
||||
|
||||
"@types/ws@^8.5.10":
|
||||
version "8.5.12"
|
||||
resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.12.tgz#619475fe98f35ccca2a2f6c137702d85ec247b7e"
|
||||
integrity sha512-3tPRkv1EtkDpzlgyKyI8pGsGZAGPEaXeu0DOj5DI25Ja91bdAYddYHbADRYVrZMRbfW+1l5YwXVDKohDJNQxkQ==
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@typescript-eslint/parser@^5.4.2 || ^6.0.0 || 7.0.0 - 7.2.0":
|
||||
version "7.2.0"
|
||||
resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.2.0.tgz"
|
||||
@ -1575,6 +1672,11 @@
|
||||
resolved "https://registry.yarnpkg.com/@vercel/speed-insights/-/speed-insights-1.0.12.tgz#71c2edffdedae98d34e306d7b0a573e6816898b4"
|
||||
integrity sha512-ZGQ+a7bcfWJD2VYEp2R1LHvRAMyyaFBYytZXsfnbOMkeOvzGNVxUL7aVUvisIrTZjXTSsxG45DKX7yiw6nq2Jw==
|
||||
|
||||
"@vladfrangu/async_event_emitter@^2.2.4":
|
||||
version "2.4.5"
|
||||
resolved "https://registry.yarnpkg.com/@vladfrangu/async_event_emitter/-/async_event_emitter-2.4.5.tgz#7bc35026fdc3398a5e1aac801edd21b28cdf4cfa"
|
||||
integrity sha512-J7T3gUr3Wz0l7Ni1f9upgBZ7+J22/Q1B7dl0X6fG+fTsD+H+31DIosMHj4Um1dWQwqbcQ3oQf+YS2foYkDc9cQ==
|
||||
|
||||
acorn-jsx@^5.3.2:
|
||||
version "5.3.2"
|
||||
resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz"
|
||||
@ -2331,6 +2433,29 @@ dir-glob@^3.0.1:
|
||||
dependencies:
|
||||
path-type "^4.0.0"
|
||||
|
||||
discord-api-types@0.37.83:
|
||||
version "0.37.83"
|
||||
resolved "https://registry.yarnpkg.com/discord-api-types/-/discord-api-types-0.37.83.tgz#a22a799729ceded8176ea747157837ddf4708b1f"
|
||||
integrity sha512-urGGYeWtWNYMKnYlZnOnDHm8fVRffQs3U0SpE8RHeiuLKb/u92APS8HoQnPTFbnXmY1vVnXjXO4dOxcAn3J+DA==
|
||||
|
||||
discord.js@^14.15.3:
|
||||
version "14.15.3"
|
||||
resolved "https://registry.yarnpkg.com/discord.js/-/discord.js-14.15.3.tgz#b2a67a1a4ef192be498fb8b6784224a42906f1be"
|
||||
integrity sha512-/UJDQO10VuU6wQPglA4kz2bw2ngeeSbogiIPx/TsnctfzV/tNf+q+i1HlgtX1OGpeOBpJH9erZQNO5oRM2uAtQ==
|
||||
dependencies:
|
||||
"@discordjs/builders" "^1.8.2"
|
||||
"@discordjs/collection" "1.5.3"
|
||||
"@discordjs/formatters" "^0.4.0"
|
||||
"@discordjs/rest" "^2.3.0"
|
||||
"@discordjs/util" "^1.1.0"
|
||||
"@discordjs/ws" "^1.1.1"
|
||||
"@sapphire/snowflake" "3.5.3"
|
||||
discord-api-types "0.37.83"
|
||||
fast-deep-equal "3.1.3"
|
||||
lodash.snakecase "4.1.1"
|
||||
tslib "2.6.2"
|
||||
undici "6.13.0"
|
||||
|
||||
dlv@^1.1.3:
|
||||
version "1.1.3"
|
||||
resolved "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz"
|
||||
@ -2808,7 +2933,7 @@ extend@^3.0.0, extend@^3.0.1:
|
||||
resolved "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz"
|
||||
integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==
|
||||
|
||||
fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3:
|
||||
fast-deep-equal@3.1.3, fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3:
|
||||
version "3.1.3"
|
||||
resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz"
|
||||
integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
|
||||
@ -3715,6 +3840,11 @@ lodash.merge@^4.6.2:
|
||||
resolved "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz"
|
||||
integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==
|
||||
|
||||
lodash.snakecase@4.1.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz#39d714a35357147837aefd64b5dcbb16becd8f8d"
|
||||
integrity sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==
|
||||
|
||||
lodash@^4.17.21:
|
||||
version "4.17.21"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
|
||||
@ -3749,6 +3879,11 @@ lucide-react@^0.416.0:
|
||||
resolved "https://registry.yarnpkg.com/lucide-react/-/lucide-react-0.416.0.tgz#657da248f9b862703d7d80aafb912e79ad886313"
|
||||
integrity sha512-wPWxTzdss1CTz2aqcNWNlbh4YSnH9neJWP3RaeXepxpLCTW+pmu7WcT/wxJe+Q7Y7DqGOxAqakJv0pIK3431Ag==
|
||||
|
||||
magic-bytes.js@^1.10.0:
|
||||
version "1.10.0"
|
||||
resolved "https://registry.yarnpkg.com/magic-bytes.js/-/magic-bytes.js-1.10.0.tgz#c41cf4bc2f802992b05e64962411c9dd44fdef92"
|
||||
integrity sha512-/k20Lg2q8LE5xiaaSkMXk4sfvI+9EGEykFS4b0CHHGWqDYU0bGUFSwchNOMA56D7TCs9GwVTkqe9als1/ns8UQ==
|
||||
|
||||
magic-string@^0.30.10:
|
||||
version "0.30.10"
|
||||
resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.10.tgz#123d9c41a0cb5640c892b041d4cfb3bd0aa4b39e"
|
||||
@ -5685,6 +5820,11 @@ ts-interface-checker@^0.1.9:
|
||||
resolved "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz"
|
||||
integrity sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==
|
||||
|
||||
ts-mixer@^6.0.4:
|
||||
version "6.0.4"
|
||||
resolved "https://registry.yarnpkg.com/ts-mixer/-/ts-mixer-6.0.4.tgz#1da39ceabc09d947a82140d9f09db0f84919ca28"
|
||||
integrity sha512-ufKpbmrugz5Aou4wcr5Wc1UUFWOLhq+Fm6qa6P0w0K5Qw2yhaUoiWszhCVuNQyNwrlGiscHOmqYoAox1PtvgjA==
|
||||
|
||||
tsconfig-paths@^3.15.0:
|
||||
version "3.15.0"
|
||||
resolved "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz"
|
||||
@ -5700,6 +5840,11 @@ tslib@2.4.1:
|
||||
resolved "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz"
|
||||
integrity sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==
|
||||
|
||||
tslib@2.6.2:
|
||||
version "2.6.2"
|
||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae"
|
||||
integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==
|
||||
|
||||
tslib@^2.0.0, tslib@^2.0.3, tslib@^2.1.0, tslib@^2.4.0, tslib@^2.6.2:
|
||||
version "2.6.3"
|
||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.3.tgz#0438f810ad7a9edcde7a241c3d80db693c8cbfe0"
|
||||
@ -5851,6 +5996,16 @@ undici-types@~5.26.4:
|
||||
resolved "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz"
|
||||
integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==
|
||||
|
||||
undici-types@~6.19.2:
|
||||
version "6.19.8"
|
||||
resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.19.8.tgz#35111c9d1437ab83a7cdc0abae2f26d88eda0a02"
|
||||
integrity sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==
|
||||
|
||||
undici@6.13.0:
|
||||
version "6.13.0"
|
||||
resolved "https://registry.yarnpkg.com/undici/-/undici-6.13.0.tgz#7edbf4b7f3aac5f8a681d515151bf55cb3589d72"
|
||||
integrity sha512-Q2rtqmZWrbP8nePMq7mOJIN98M0fYvSgV89vwl/BQRT4mDOeY2GXZngfGpcBBhtky3woM7G24wZV3Q304Bv6cw==
|
||||
|
||||
unified@^11.0.0:
|
||||
version "11.0.4"
|
||||
resolved "https://registry.npmjs.org/unified/-/unified-11.0.4.tgz"
|
||||
@ -6149,6 +6304,11 @@ wrappy@1:
|
||||
resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz"
|
||||
integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==
|
||||
|
||||
ws@^8.16.0:
|
||||
version "8.18.0"
|
||||
resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.0.tgz#0d7505a6eafe2b0e712d232b42279f53bc289bbc"
|
||||
integrity sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==
|
||||
|
||||
y18n@^5.0.5:
|
||||
version "5.0.8"
|
||||
resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user