diff --git a/src/api/Server.ts b/src/api/Server.ts
index 0f5df490..bea75d7e 100644
--- a/src/api/Server.ts
+++ b/src/api/Server.ts
@@ -18,15 +18,15 @@
import {
Config,
+ ConnectionConfig,
+ ConnectionLoader,
Email,
- initDatabase,
- initEvent,
JSONReplacer,
- registerRoutes,
Sentry,
WebAuthn,
- ConnectionConfig,
- ConnectionLoader,
+ initDatabase,
+ initEvent,
+ registerRoutes,
} from "@spacebar/util";
import { Request, Response, Router } from "express";
import { Server, ServerOptions } from "lambert-server";
@@ -143,6 +143,10 @@ export class SpacebarServer extends Server {
res.sendFile(path.join(PUBLIC_ASSETS_FOLDER, "index.html")),
);
+ app.get("/verify", (req, res) =>
+ res.sendFile(path.join(PUBLIC_ASSETS_FOLDER, "verify.html")),
+ );
+
this.app.use(ErrorHandler);
Sentry.errorHandler(this.app);
diff --git a/src/api/routes/auth/verify/index.ts b/src/api/routes/auth/verify/index.ts
index 49f74277..32c3f305 100644
--- a/src/api/routes/auth/verify/index.ts
+++ b/src/api/routes/auth/verify/index.ts
@@ -85,7 +85,7 @@ router.post(
user = userTokenData.user;
} catch {
throw FieldErrors({
- password: {
+ token: {
message: req.t("auth:password_reset.INVALID_TOKEN"),
code: "INVALID_TOKEN",
},
diff --git a/src/api/routes/channels/#channel_id/index.ts b/src/api/routes/channels/#channel_id/index.ts
index 99f9a647..291b6472 100644
--- a/src/api/routes/channels/#channel_id/index.ts
+++ b/src/api/routes/channels/#channel_id/index.ts
@@ -50,7 +50,13 @@ router.get(
const channel = await Channel.findOneOrFail({
where: { id: channel_id },
});
+ if (!channel.guild_id) return res.send(channel);
+ channel.position = await Channel.calculatePosition(
+ channel_id,
+ channel.guild_id,
+ channel.guild,
+ );
return res.send(channel);
},
);
diff --git a/src/api/routes/channels/#channel_id/messages/#message_id/crosspost.ts b/src/api/routes/channels/#channel_id/messages/#message_id/crosspost.ts
index 5ca645c0..6362941c 100644
--- a/src/api/routes/channels/#channel_id/messages/#message_id/crosspost.ts
+++ b/src/api/routes/channels/#channel_id/messages/#message_id/crosspost.ts
@@ -1,17 +1,17 @@
/*
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
Copyright (C) 2023 Spacebar and Spacebar Contributors
-
+
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
-
+
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
@@ -56,6 +56,7 @@ router.post(
edited_timestamp: null,
flags: 1,
components: [],
+ poll: {},
}).status(200);
},
);
diff --git a/src/api/routes/channels/#channel_id/messages/#message_id/index.ts b/src/api/routes/channels/#channel_id/messages/#message_id/index.ts
index c4d2e1e8..211cf997 100644
--- a/src/api/routes/channels/#channel_id/messages/#message_id/index.ts
+++ b/src/api/routes/channels/#channel_id/messages/#message_id/index.ts
@@ -1,17 +1,17 @@
/*
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
Copyright (C) 2023 Spacebar and Spacebar Contributors
-
+
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
-
+
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
@@ -91,11 +91,10 @@ router.patch(
}
} else rights.hasThrow("SELF_EDIT_MESSAGES");
+ // @ts-expect-error Something is wrong with message_reference here, TS complains since "channel_id" is optional in MessageCreateSchema
const new_message = await handleMessage({
...message,
// TODO: should message_reference be overridable?
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
- // @ts-ignore
message_reference: message.message_reference,
...body,
author_id: message.author_id,
diff --git a/src/api/routes/channels/#channel_id/messages/index.ts b/src/api/routes/channels/#channel_id/messages/index.ts
index a5bfcfd7..645c6db2 100644
--- a/src/api/routes/channels/#channel_id/messages/index.ts
+++ b/src/api/routes/channels/#channel_id/messages/index.ts
@@ -1,17 +1,17 @@
/*
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
Copyright (C) 2023 Spacebar and Spacebar Contributors
-
+
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
-
+
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
@@ -183,9 +183,17 @@ router.get(
const uri = y.proxy_url.startsWith("http")
? y.proxy_url
: `https://example.org${y.proxy_url}`;
- y.proxy_url = `${endpoint == null ? "" : endpoint}${
- new URL(uri).pathname
- }`;
+
+ let pathname = new URL(uri).pathname;
+ while (
+ pathname.split("/")[0] != "attachments" &&
+ pathname.length > 30
+ ) {
+ pathname = pathname.split("/").slice(1).join("/");
+ }
+ if (!endpoint?.endsWith("/")) pathname = "/" + pathname;
+
+ y.proxy_url = `${endpoint == null ? "" : endpoint}${pathname}`;
});
/**
diff --git a/src/api/routes/channels/#channel_id/permissions.ts b/src/api/routes/channels/#channel_id/permissions.ts
index d3edb0fa..fe289f23 100644
--- a/src/api/routes/channels/#channel_id/permissions.ts
+++ b/src/api/routes/channels/#channel_id/permissions.ts
@@ -1,17 +1,17 @@
/*
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
Copyright (C) 2023 Spacebar and Spacebar Contributors
-
+
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
-
+
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
@@ -53,6 +53,11 @@ router.put(
where: { id: channel_id },
});
if (!channel.guild_id) throw new HTTPError("Channel not found", 404);
+ channel.position = await Channel.calculatePosition(
+ channel_id,
+ channel.guild_id,
+ channel.guild,
+ );
if (body.type === 0) {
if (!(await Role.count({ where: { id: overwrite_id } })))
diff --git a/src/api/routes/connections/index.ts b/src/api/routes/connections/index.ts
new file mode 100644
index 00000000..37c20a37
--- /dev/null
+++ b/src/api/routes/connections/index.ts
@@ -0,0 +1,45 @@
+/*
+ Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
+ Copyright (C) 2023 Spacebar and Spacebar Contributors
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
+*/
+
+import { route } from "@spacebar/api";
+import { ConnectionConfig } from "@spacebar/util";
+import { Request, Response, Router } from "express";
+const router = Router();
+
+router.get(
+ "/",
+ route({
+ responses: {
+ 200: {
+ body: "APIConnectionsConfiguration",
+ },
+ },
+ }),
+ async (req: Request, res: Response) => {
+ const config = ConnectionConfig.get();
+
+ Object.keys(config).forEach((key) => {
+ delete config[key].clientId;
+ delete config[key].clientSecret;
+ });
+
+ res.json(config);
+ },
+);
+
+export default router;
diff --git a/src/api/routes/guilds/#guild_id/channels.ts b/src/api/routes/guilds/#guild_id/channels.ts
index 68208fee..3488b64d 100644
--- a/src/api/routes/guilds/#guild_id/channels.ts
+++ b/src/api/routes/guilds/#guild_id/channels.ts
@@ -1,17 +1,17 @@
/*
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
Copyright (C) 2023 Spacebar and Spacebar Contributors
-
+
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
-
+
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
@@ -41,6 +41,15 @@ router.get(
const { guild_id } = req.params;
const channels = await Channel.find({ where: { guild_id } });
+ for await (const channel of channels) {
+ channel.position = await Channel.calculatePosition(
+ channel.id,
+ guild_id,
+ channel.guild,
+ );
+ }
+ channels.sort((a, b) => a.position - b.position);
+
res.json(channels);
},
);
@@ -71,6 +80,11 @@ router.post(
{ ...body, guild_id },
req.user_id,
);
+ channel.position = await Channel.calculatePosition(
+ channel.id,
+ guild_id,
+ channel.guild,
+ );
res.status(201).json(channel);
},
diff --git a/src/api/routes/guilds/#guild_id/emojis.ts b/src/api/routes/guilds/#guild_id/emojis.ts
index ef28f989..f3f0fd8b 100644
--- a/src/api/routes/guilds/#guild_id/emojis.ts
+++ b/src/api/routes/guilds/#guild_id/emojis.ts
@@ -1,17 +1,17 @@
/*
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
Copyright (C) 2023 Spacebar and Spacebar Contributors
-
+
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
-
+
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
@@ -125,6 +125,7 @@ router.post(
const user = await User.findOneOrFail({ where: { id: req.user_id } });
body.image = (await handleFile(`/emojis/${id}`, body.image)) as string;
+ const mimeType = body.image.split(":")[1].split(";")[0];
const emoji = await Emoji.create({
id: id,
guild_id: guild_id,
@@ -132,7 +133,10 @@ router.post(
require_colons: body.require_colons ?? undefined, // schema allows nulls, db does not
user: user,
managed: false,
- animated: false, // TODO: Add support animated emojis
+ animated:
+ mimeType == "image/gif" ||
+ mimeType == "image/apng" ||
+ mimeType == "video/webm",
available: true,
roles: [],
}).save();
diff --git a/src/api/routes/guilds/#guild_id/messages/search.ts b/src/api/routes/guilds/#guild_id/messages/search.ts
index 637d1e43..94adf9c6 100644
--- a/src/api/routes/guilds/#guild_id/messages/search.ts
+++ b/src/api/routes/guilds/#guild_id/messages/search.ts
@@ -1,17 +1,17 @@
/*
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
Copyright (C) 2023 Spacebar and Spacebar Contributors
-
+
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
-
+
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
@@ -162,6 +162,7 @@ router.get(
edited_timestamp: x.edited_timestamp,
flags: x.flags,
components: x.components,
+ poll: x.poll,
hit: true,
},
]);
diff --git a/src/api/routes/users/#id/profile.ts b/src/api/routes/users/#id/profile.ts
index eecec0f3..db0922d6 100644
--- a/src/api/routes/users/#id/profile.ts
+++ b/src/api/routes/users/#id/profile.ts
@@ -18,6 +18,7 @@
import { route } from "@spacebar/api";
import {
+ Badge,
Member,
PrivateUserProjection,
User,
@@ -98,6 +99,9 @@ router.get(
bio: guild_member?.bio || "",
guild_id,
};
+
+ const badges = await Badge.find();
+
res.json({
connected_accounts: user.connected_accounts.filter(
(x) => x.visibility != 0,
@@ -111,6 +115,7 @@ router.get(
user_profile: userProfile,
guild_member: guild_member?.toPublicMember(),
guild_member_profile: guild_id && guildMemberProfile,
+ badges: badges.filter((x) => user.badge_ids?.includes(x.id)),
});
},
);
diff --git a/src/api/util/handlers/Message.ts b/src/api/util/handlers/Message.ts
index 6172a3d0..c3658668 100644
--- a/src/api/util/handlers/Message.ts
+++ b/src/api/util/handlers/Message.ts
@@ -1,57 +1,57 @@
/*
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
Copyright (C) 2023 Spacebar and Spacebar Contributors
-
+
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
-
+
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
+import * as Sentry from "@sentry/node";
+import { EmbedHandlers } from "@spacebar/api";
import {
+ Application,
+ Attachment,
Channel,
+ Config,
Embed,
+ EmbedCache,
emitEvent,
+ EVERYONE_MENTION,
+ getPermission,
+ getRights,
Guild,
+ HERE_MENTION,
Message,
MessageCreateEvent,
+ MessageCreateSchema,
+ MessageType,
MessageUpdateEvent,
- getPermission,
- getRights,
- //CHANNEL_MENTION,
- USER_MENTION,
- ROLE_MENTION,
Role,
- EVERYONE_MENTION,
- HERE_MENTION,
- MessageType,
+ ROLE_MENTION,
+ Sticker,
User,
- Application,
+ //CHANNEL_MENTION,
+ USER_MENTION,
Webhook,
- Attachment,
- Config,
- Sticker,
- MessageCreateSchema,
- EmbedCache,
} from "@spacebar/util";
import { HTTPError } from "lambert-server";
import { In } from "typeorm";
-import { EmbedHandlers } from "@spacebar/api";
-import * as Sentry from "@sentry/node";
const allow_empty = false;
// TODO: check webhook, application, system author, stickers
// TODO: embed gifs/videos/images
const LINK_REGEX =
- /https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)/g;
+ /<?https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)>?/g;
export async function handleMessage(opts: MessageOptions): Promise<Message> {
const channel = await Channel.findOneOrFail({
@@ -66,6 +66,7 @@ export async function handleMessage(opts: MessageOptions): Promise<Message> {
: undefined;
const message = Message.create({
...opts,
+ poll: opts.poll,
sticker_items: stickers,
guild_id: channel.guild_id,
channel_id: opts.channel_id,
@@ -116,6 +117,12 @@ export async function handleMessage(opts: MessageOptions): Promise<Message> {
const guild = await Guild.findOneOrFail({
where: { id: channel.guild_id },
});
+
+ if (!opts.message_reference.guild_id)
+ opts.message_reference.guild_id = channel.guild_id;
+ if (!opts.message_reference.channel_id)
+ opts.message_reference.channel_id = opts.channel_id;
+
if (!guild.features.includes("CROSS_CHANNEL_REPLIES")) {
if (opts.message_reference.guild_id !== channel.guild_id)
throw new HTTPError(
@@ -126,6 +133,8 @@ export async function handleMessage(opts: MessageOptions): Promise<Message> {
"You can only reference messages from this channel",
);
}
+
+ message.message_reference = opts.message_reference;
}
/** Q: should be checked if the referenced message exists? ANSWER: NO
otherwise backfilling won't work **/
@@ -138,7 +147,9 @@ export async function handleMessage(opts: MessageOptions): Promise<Message> {
!opts.content &&
!opts.embeds?.length &&
!opts.attachments?.length &&
- !opts.sticker_ids?.length
+ !opts.sticker_ids?.length &&
+ !opts.poll &&
+ !opts.components?.length
) {
throw new HTTPError("Empty messages are not allowed", 50006);
}
@@ -213,6 +224,9 @@ export async function postHandleMessage(message: Message) {
const cachePromises = [];
for (const link of links) {
+ // Don't embed links in <>
+ if (link.startsWith("<") && link.endsWith(">")) continue;
+
const url = new URL(link);
const cached = await EmbedCache.findOne({ where: { url: link } });
diff --git a/src/cdn/routes/badge-icons.ts b/src/cdn/routes/badge-icons.ts
new file mode 100644
index 00000000..04e96f2f
--- /dev/null
+++ b/src/cdn/routes/badge-icons.ts
@@ -0,0 +1,40 @@
+/*
+ Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
+ Copyright (C) 2023 Spacebar and Spacebar Contributors
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
+*/
+
+import { Router, Response, Request } from "express";
+import { storage } from "../util/Storage";
+import FileType from "file-type";
+import { HTTPError } from "lambert-server";
+
+const router = Router();
+
+router.get("/:badge_id", async (req: Request, res: Response) => {
+ const { badge_id } = req.params;
+ const path = `badge-icons/${badge_id}`;
+
+ const file = await storage.get(path);
+ if (!file) throw new HTTPError("not found", 404);
+ const type = await FileType.fromBuffer(file);
+
+ res.set("Content-Type", type?.mime);
+ res.set("Cache-Control", "public, max-age=31536000, must-revalidate");
+
+ return res.send(file);
+});
+
+export default router;
diff --git a/src/cdn/routes/embed.ts b/src/cdn/routes/embed.ts
index b99396eb..95ac720d 100644
--- a/src/cdn/routes/embed.ts
+++ b/src/cdn/routes/embed.ts
@@ -23,12 +23,12 @@ import { HTTPError } from "lambert-server";
import { join } from "path";
const defaultAvatarHashMap = new Map([
- ["0", "823a3de61c4dc2415cc4dbc38fca4299"],
- ["1", "e56a89224be0b2b1f7c04eca975be468"],
- ["2", "0c8138dcc0dfe2689cdd73f7952c2475"],
- ["3", "5ac2728593bb455250d11b848a0c36c6"],
- ["4", "addd2f3268df46459e1d6012ad8e75bd"],
- ["5", "c4e0c8300fa491d94acfd2a1fb26cea8"],
+ ["0", "4a8562cf00887030c416d3ec2d46385a"],
+ ["1", "9b0bb198936784c45c72833cc426cc55"],
+ ["2", "22341bdb500c7b63a93bbce957d1601e"],
+ ["3", "d9977836b82058bf2f74eebd50edc095"],
+ ["4", "9d6ddb4e4d899a533a8cc617011351c9"],
+ ["5", "7213ab6677377974697dfdfbaf5f6a6f"],
]);
const defaultGroupDMAvatarHashMap = new Map([
diff --git a/src/connections/BattleNet/index.ts b/src/connections/BattleNet/index.ts
index 4fdfccb1..8f44944c 100644
--- a/src/connections/BattleNet/index.ts
+++ b/src/connections/BattleNet/index.ts
@@ -1,17 +1,17 @@
/*
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
Copyright (C) 2023 Spacebar and Spacebar Contributors
-
+
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
-
+
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
@@ -47,13 +47,15 @@ export default class BattleNetConnection extends Connection {
settings: BattleNetSettings = new BattleNetSettings();
init(): void {
- const settings =
- ConnectionLoader.getConnectionConfig<BattleNetSettings>(
- this.id,
- this.settings,
- );
+ this.settings = ConnectionLoader.getConnectionConfig<BattleNetSettings>(
+ this.id,
+ this.settings,
+ );
- if (settings.enabled && (!settings.clientId || !settings.clientSecret))
+ if (
+ this.settings.enabled &&
+ (!this.settings.clientId || !this.settings.clientSecret)
+ )
throw new Error(`Invalid settings for connection ${this.id}`);
}
diff --git a/src/connections/Discord/index.ts b/src/connections/Discord/index.ts
index 731086f1..e5508f48 100644
--- a/src/connections/Discord/index.ts
+++ b/src/connections/Discord/index.ts
@@ -1,17 +1,17 @@
/*
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
Copyright (C) 2023 Spacebar and Spacebar Contributors
-
+
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
-
+
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
@@ -43,12 +43,15 @@ export default class DiscordConnection extends Connection {
settings: DiscordSettings = new DiscordSettings();
init(): void {
- const settings = ConnectionLoader.getConnectionConfig<DiscordSettings>(
+ this.settings = ConnectionLoader.getConnectionConfig<DiscordSettings>(
this.id,
this.settings,
);
- if (settings.enabled && (!settings.clientId || !settings.clientSecret))
+ if (
+ this.settings.enabled &&
+ (!this.settings.clientId || !this.settings.clientSecret)
+ )
throw new Error(`Invalid settings for connection ${this.id}`);
}
diff --git a/src/connections/EpicGames/index.ts b/src/connections/EpicGames/index.ts
index e5b2d336..cedfcd0a 100644
--- a/src/connections/EpicGames/index.ts
+++ b/src/connections/EpicGames/index.ts
@@ -1,17 +1,17 @@
/*
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
Copyright (C) 2023 Spacebar and Spacebar Contributors
-
+
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
-
+
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
@@ -53,13 +53,15 @@ export default class EpicGamesConnection extends Connection {
settings: EpicGamesSettings = new EpicGamesSettings();
init(): void {
- const settings =
- ConnectionLoader.getConnectionConfig<EpicGamesSettings>(
- this.id,
- this.settings,
- );
+ this.settings = ConnectionLoader.getConnectionConfig<EpicGamesSettings>(
+ this.id,
+ this.settings,
+ );
- if (settings.enabled && (!settings.clientId || !settings.clientSecret))
+ if (
+ this.settings.enabled &&
+ (!this.settings.clientId || !this.settings.clientSecret)
+ )
throw new Error(`Invalid settings for connection ${this.id}`);
}
diff --git a/src/connections/Facebook/index.ts b/src/connections/Facebook/index.ts
index 2bf26f34..bcb90b4c 100644
--- a/src/connections/Facebook/index.ts
+++ b/src/connections/Facebook/index.ts
@@ -1,17 +1,17 @@
/*
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
Copyright (C) 2023 Spacebar and Spacebar Contributors
-
+
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
-
+
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
@@ -52,12 +52,15 @@ export default class FacebookConnection extends Connection {
settings: FacebookSettings = new FacebookSettings();
init(): void {
- const settings = ConnectionLoader.getConnectionConfig<FacebookSettings>(
+ this.settings = ConnectionLoader.getConnectionConfig<FacebookSettings>(
this.id,
this.settings,
);
- if (settings.enabled && (!settings.clientId || !settings.clientSecret))
+ if (
+ this.settings.enabled &&
+ (!this.settings.clientId || !this.settings.clientSecret)
+ )
throw new Error(`Invalid settings for connection ${this.id}`);
}
diff --git a/src/connections/GitHub/index.ts b/src/connections/GitHub/index.ts
index 25e5f89f..78bf510e 100644
--- a/src/connections/GitHub/index.ts
+++ b/src/connections/GitHub/index.ts
@@ -1,17 +1,17 @@
/*
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
Copyright (C) 2023 Spacebar and Spacebar Contributors
-
+
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
-
+
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
@@ -42,12 +42,15 @@ export default class GitHubConnection extends Connection {
settings: GitHubSettings = new GitHubSettings();
init(): void {
- const settings = ConnectionLoader.getConnectionConfig<GitHubSettings>(
+ this.settings = ConnectionLoader.getConnectionConfig<GitHubSettings>(
this.id,
this.settings,
);
- if (settings.enabled && (!settings.clientId || !settings.clientSecret))
+ if (
+ this.settings.enabled &&
+ (!this.settings.clientId || !this.settings.clientSecret)
+ )
throw new Error(`Invalid settings for connection ${this.id}`);
}
diff --git a/src/connections/Reddit/index.ts b/src/connections/Reddit/index.ts
index 149cce02..0db23731 100644
--- a/src/connections/Reddit/index.ts
+++ b/src/connections/Reddit/index.ts
@@ -1,17 +1,17 @@
/*
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
Copyright (C) 2023 Spacebar and Spacebar Contributors
-
+
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
-
+
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
@@ -54,12 +54,15 @@ export default class RedditConnection extends Connection {
settings: RedditSettings = new RedditSettings();
init(): void {
- const settings = ConnectionLoader.getConnectionConfig<RedditSettings>(
+ this.settings = ConnectionLoader.getConnectionConfig<RedditSettings>(
this.id,
this.settings,
);
- if (settings.enabled && (!settings.clientId || !settings.clientSecret))
+ if (
+ this.settings.enabled &&
+ (!this.settings.clientId || !this.settings.clientSecret)
+ )
throw new Error(`Invalid settings for connection ${this.id}`);
}
diff --git a/src/connections/Spotify/index.ts b/src/connections/Spotify/index.ts
index ece404d8..4eb12602 100644
--- a/src/connections/Spotify/index.ts
+++ b/src/connections/Spotify/index.ts
@@ -1,17 +1,17 @@
/*
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
Copyright (C) 2023 Spacebar and Spacebar Contributors
-
+
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
-
+
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
@@ -63,12 +63,16 @@ export default class SpotifyConnection extends RefreshableConnection {
* So to prevent spamming the spotify api we disable the ability to refresh.
*/
this.refreshEnabled = false;
- const settings = ConnectionLoader.getConnectionConfig<SpotifySettings>(
+
+ this.settings = ConnectionLoader.getConnectionConfig<SpotifySettings>(
this.id,
this.settings,
);
- if (settings.enabled && (!settings.clientId || !settings.clientSecret))
+ if (
+ this.settings.enabled &&
+ (!this.settings.clientId || !this.settings.clientSecret)
+ )
throw new Error(`Invalid settings for connection ${this.id}`);
}
diff --git a/src/connections/Twitch/index.ts b/src/connections/Twitch/index.ts
index 9a6cea35..953669a1 100644
--- a/src/connections/Twitch/index.ts
+++ b/src/connections/Twitch/index.ts
@@ -1,17 +1,17 @@
/*
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
Copyright (C) 2023 Spacebar and Spacebar Contributors
-
+
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
-
+
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
@@ -55,12 +55,15 @@ export default class TwitchConnection extends RefreshableConnection {
settings: TwitchSettings = new TwitchSettings();
init(): void {
- const settings = ConnectionLoader.getConnectionConfig<TwitchSettings>(
+ this.settings = ConnectionLoader.getConnectionConfig<TwitchSettings>(
this.id,
this.settings,
);
- if (settings.enabled && (!settings.clientId || !settings.clientSecret))
+ if (
+ this.settings.enabled &&
+ (!this.settings.clientId || !this.settings.clientSecret)
+ )
throw new Error(`Invalid settings for connection ${this.id}`);
}
diff --git a/src/connections/Twitter/index.ts b/src/connections/Twitter/index.ts
index 62fd7da1..eba8ceb5 100644
--- a/src/connections/Twitter/index.ts
+++ b/src/connections/Twitter/index.ts
@@ -1,17 +1,17 @@
/*
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
Copyright (C) 2023 Spacebar and Spacebar Contributors
-
+
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
-
+
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
@@ -55,12 +55,15 @@ export default class TwitterConnection extends RefreshableConnection {
settings: TwitterSettings = new TwitterSettings();
init(): void {
- const settings = ConnectionLoader.getConnectionConfig<TwitterSettings>(
+ this.settings = ConnectionLoader.getConnectionConfig<TwitterSettings>(
this.id,
this.settings,
);
- if (settings.enabled && (!settings.clientId || !settings.clientSecret))
+ if (
+ this.settings.enabled &&
+ (!this.settings.clientId || !this.settings.clientSecret)
+ )
throw new Error(`Invalid settings for connection ${this.id}`);
}
diff --git a/src/connections/Xbox/index.ts b/src/connections/Xbox/index.ts
index 935ff7ab..84066def 100644
--- a/src/connections/Xbox/index.ts
+++ b/src/connections/Xbox/index.ts
@@ -1,17 +1,17 @@
/*
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
Copyright (C) 2023 Spacebar and Spacebar Contributors
-
+
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
-
+
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
@@ -62,12 +62,15 @@ export default class XboxConnection extends Connection {
settings: XboxSettings = new XboxSettings();
init(): void {
- const settings = ConnectionLoader.getConnectionConfig<XboxSettings>(
+ this.settings = ConnectionLoader.getConnectionConfig<XboxSettings>(
this.id,
this.settings,
);
- if (settings.enabled && (!settings.clientId || !settings.clientSecret))
+ if (
+ this.settings.enabled &&
+ (!this.settings.clientId || !this.settings.clientSecret)
+ )
throw new Error(`Invalid settings for connection ${this.id}`);
}
diff --git a/src/connections/Youtube/index.ts b/src/connections/Youtube/index.ts
index 844803cf..38edbb0d 100644
--- a/src/connections/Youtube/index.ts
+++ b/src/connections/Youtube/index.ts
@@ -1,17 +1,17 @@
/*
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
Copyright (C) 2023 Spacebar and Spacebar Contributors
-
+
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
-
+
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
@@ -62,12 +62,15 @@ export default class YoutubeConnection extends Connection {
settings: YoutubeSettings = new YoutubeSettings();
init(): void {
- const settings = ConnectionLoader.getConnectionConfig<YoutubeSettings>(
+ this.settings = ConnectionLoader.getConnectionConfig<YoutubeSettings>(
this.id,
this.settings,
);
- if (settings.enabled && (!settings.clientId || !settings.clientSecret))
+ if (
+ this.settings.enabled &&
+ (!this.settings.clientId || !this.settings.clientSecret)
+ )
throw new Error(`Invalid settings for connection ${this.id}`);
}
diff --git a/src/util/config/types/EmailConfiguration.ts b/src/util/config/types/EmailConfiguration.ts
index ae9d53ba..62305d10 100644
--- a/src/util/config/types/EmailConfiguration.ts
+++ b/src/util/config/types/EmailConfiguration.ts
@@ -25,6 +25,7 @@ import { SendGridConfiguration } from "./subconfigurations/email/SendGrid";
export class EmailConfiguration {
provider: string | null = null;
+ senderAddress: string | null = null;
smtp: SMTPConfiguration = new SMTPConfiguration();
mailgun: MailGunConfiguration = new MailGunConfiguration();
mailjet: MailJetConfiguration = new MailJetConfiguration();
diff --git a/src/util/connections/Connection.ts b/src/util/connections/Connection.ts
index 5bdebd47..638dde2c 100644
--- a/src/util/connections/Connection.ts
+++ b/src/util/connections/Connection.ts
@@ -1,17 +1,17 @@
/*
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
Copyright (C) 2023 Spacebar and Spacebar Contributors
-
+
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
-
+
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
@@ -43,7 +43,7 @@ export abstract class Connection {
*/
getRedirectUri() {
const endpointPublic =
- Config.get().api.endpointPublic ?? "http://localhost:3001";
+ Config.get().general.frontPage ?? "http://localhost:3001";
return `${endpointPublic}/connections/${this.id}/callback`;
}
diff --git a/src/util/dtos/UserDTO.ts b/src/util/dtos/UserDTO.ts
index a24c8d96..17e4435f 100644
--- a/src/util/dtos/UserDTO.ts
+++ b/src/util/dtos/UserDTO.ts
@@ -24,6 +24,7 @@ export class MinimalPublicUserDTO {
id: string;
public_flags: number;
username: string;
+ badge_ids?: string[] | null;
constructor(user: User) {
this.avatar = user.avatar;
@@ -31,5 +32,6 @@ export class MinimalPublicUserDTO {
this.id = user.id;
this.public_flags = user.public_flags;
this.username = user.username;
+ this.badge_ids = user.badge_ids;
}
}
diff --git a/src/util/entities/Badge.ts b/src/util/entities/Badge.ts
new file mode 100644
index 00000000..9535e207
--- /dev/null
+++ b/src/util/entities/Badge.ts
@@ -0,0 +1,35 @@
+/*
+ Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
+ Copyright (C) 2023 Spacebar and Spacebar Contributors
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
+*/
+
+import { Column, Entity } from "typeorm";
+import { BaseClassWithoutId } from "./BaseClass";
+
+@Entity("badges")
+export class Badge extends BaseClassWithoutId {
+ @Column({ primary: true })
+ id: string;
+
+ @Column()
+ description: string;
+
+ @Column()
+ icon: string;
+
+ @Column({ nullable: true })
+ link?: string;
+}
diff --git a/src/util/entities/Member.ts b/src/util/entities/Member.ts
index 65942816..3ef778ac 100644
--- a/src/util/entities/Member.ts
+++ b/src/util/entities/Member.ts
@@ -1,17 +1,17 @@
/*
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
Copyright (C) 2023 Spacebar and Spacebar Contributors
-
+
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
-
+
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
@@ -31,7 +31,7 @@ import {
PrimaryGeneratedColumn,
RelationId,
} from "typeorm";
-import { Ban, PublicGuildRelations } from ".";
+import { Ban, Channel, PublicGuildRelations } from ".";
import { ReadyGuildDTO } from "../dtos";
import {
GuildCreateEvent,
@@ -330,6 +330,13 @@ export class Member extends BaseClassWithoutId {
relationLoadStrategy: "query",
});
+ for await (const channel of guild.channels) {
+ channel.position = await Channel.calculatePosition(
+ channel.id,
+ guild_id,
+ );
+ }
+
const memberCount = await Member.count({ where: { guild_id } });
const memberPreview = (
diff --git a/src/util/entities/Message.ts b/src/util/entities/Message.ts
index 4a9cff4a..d28c8c29 100644
--- a/src/util/entities/Message.ts
+++ b/src/util/entities/Message.ts
@@ -1,17 +1,17 @@
/*
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
Copyright (C) 2023 Spacebar and Spacebar Contributors
-
+
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
-
+
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
@@ -218,6 +218,9 @@ export class Message extends BaseClass {
@Column({ type: "simple-json", nullable: true })
components?: MessageComponent[];
+ @Column({ type: "simple-json", nullable: true })
+ poll?: Poll;
+
toJSON(): Message {
return {
...this,
@@ -238,6 +241,7 @@ export class Message extends BaseClass {
activity: this.activity ?? undefined,
application: this.application ?? undefined,
components: this.components ?? undefined,
+ poll: this.poll ?? undefined,
content: this.content ?? "",
};
}
@@ -249,6 +253,7 @@ export interface MessageComponent {
label?: string;
emoji?: PartialEmoji;
custom_id?: string;
+ sku_id?: string;
url?: string;
disabled?: boolean;
components: MessageComponent[];
@@ -327,3 +332,32 @@ export interface AllowedMentions {
users?: string[];
replied_user?: boolean;
}
+
+export interface Poll {
+ question: PollMedia;
+ answers: PollAnswer[];
+ expiry: Date;
+ allow_multiselect: boolean;
+ results?: PollResult;
+}
+
+export interface PollMedia {
+ text?: string;
+ emoji?: PartialEmoji;
+}
+
+export interface PollAnswer {
+ answer_id?: string;
+ poll_media: PollMedia;
+}
+
+export interface PollResult {
+ is_finalized: boolean;
+ answer_counts: PollAnswerCount[];
+}
+
+export interface PollAnswerCount {
+ id: string;
+ count: number;
+ me_voted: boolean;
+}
diff --git a/src/util/entities/User.ts b/src/util/entities/User.ts
index c6582b00..c929039e 100644
--- a/src/util/entities/User.ts
+++ b/src/util/entities/User.ts
@@ -49,6 +49,7 @@ export enum PublicUserEnum {
premium_type,
theme_colors,
pronouns,
+ badge_ids,
}
export type PublicUserKeys = keyof typeof PublicUserEnum;
@@ -231,6 +232,9 @@ export class User extends BaseClass {
@OneToMany(() => SecurityKey, (key: SecurityKey) => key.user)
security_keys: SecurityKey[];
+ @Column({ type: "simple-array", nullable: true })
+ badge_ids?: string[];
+
// TODO: I don't like this method?
validate() {
if (this.discriminator) {
diff --git a/src/util/entities/index.ts b/src/util/entities/index.ts
index aa943dca..b2356aa7 100644
--- a/src/util/entities/index.ts
+++ b/src/util/entities/index.ts
@@ -20,6 +20,7 @@ export * from "./Application";
export * from "./Attachment";
export * from "./AuditLog";
export * from "./BackupCodes";
+export * from "./Badge";
export * from "./Ban";
export * from "./BaseClass";
export * from "./Categories";
diff --git a/src/util/migration/mariadb/1719776735000-newUserSettings.ts b/src/util/migration/mariadb/1719776735000-newUserSettings.ts
new file mode 100644
index 00000000..f7c37ca9
--- /dev/null
+++ b/src/util/migration/mariadb/1719776735000-newUserSettings.ts
@@ -0,0 +1,23 @@
+import { MigrationInterface, QueryRunner } from "typeorm";
+
+export class NewUserSettings1719776735000 implements MigrationInterface {
+ name = "NewUserSettings1719776735000";
+
+ public async up(queryRunner: QueryRunner): Promise<void> {
+ await queryRunner.query(
+ "ALTER TABLE `user_settings` ADD friend_discovery_flags integer NULL DEFAULT 0;",
+ );
+ await queryRunner.query(
+ "ALTER TABLE `user_settings` ADD view_nsfw_guilds tinyint NULL DEFAULT 1;",
+ );
+ }
+
+ public async down(queryRunner: QueryRunner): Promise<void> {
+ await queryRunner.query(
+ "ALTER TABLE `user_settings` DROP COLUMN friend_discovery_flags;",
+ );
+ await queryRunner.query(
+ "ALTER TABLE `user_settings` DROP COLUMN view_nsfw_guilds;",
+ );
+ }
+}
diff --git a/src/util/migration/mariadb/1720157926878-messagePollObject.ts b/src/util/migration/mariadb/1720157926878-messagePollObject.ts
new file mode 100644
index 00000000..c0866426
--- /dev/null
+++ b/src/util/migration/mariadb/1720157926878-messagePollObject.ts
@@ -0,0 +1,13 @@
+import { MigrationInterface, QueryRunner } from "typeorm";
+
+export class MessagePollObject1720157926878 implements MigrationInterface {
+ name = "MessagePollObject1720157926878";
+
+ public async up(queryRunner: QueryRunner): Promise<void> {
+ await queryRunner.query("ALTER TABLE `messages` ADD `poll` text NULL");
+ }
+
+ public async down(queryRunner: QueryRunner): Promise<void> {
+ await queryRunner.query("ALTER TABLE `messages` DROP COLUMN `poll`");
+ }
+}
diff --git a/src/util/migration/mariadb/1720628601997-badges.ts b/src/util/migration/mariadb/1720628601997-badges.ts
new file mode 100644
index 00000000..af298e42
--- /dev/null
+++ b/src/util/migration/mariadb/1720628601997-badges.ts
@@ -0,0 +1,21 @@
+import { MigrationInterface, QueryRunner } from "typeorm";
+
+export class Badges1720628601997 implements MigrationInterface {
+ name = "Badges1720628601997";
+
+ public async up(queryRunner: QueryRunner): Promise<void> {
+ await queryRunner.query(
+ `CREATE TABLE \`badges\` (\`id\` varchar(255) NOT NULL, \`description\` varchar(255) NOT NULL, \`icon\` varchar(255) NOT NULL, \`link\` varchar(255) NULL, PRIMARY KEY (\`id\`)) ENGINE=InnoDB`,
+ );
+ await queryRunner.query(
+ `ALTER TABLE \`users\` ADD \`badge_ids\` text NULL`,
+ );
+ }
+
+ public async down(queryRunner: QueryRunner): Promise<void> {
+ await queryRunner.query(
+ `ALTER TABLE \`users\` DROP COLUMN \`badge_ids\``,
+ );
+ await queryRunner.query(`DROP TABLE \`badges\``);
+ }
+}
diff --git a/src/util/migration/mysql/1719776735000-newUserSettings.ts b/src/util/migration/mysql/1719776735000-newUserSettings.ts
new file mode 100644
index 00000000..f7c37ca9
--- /dev/null
+++ b/src/util/migration/mysql/1719776735000-newUserSettings.ts
@@ -0,0 +1,23 @@
+import { MigrationInterface, QueryRunner } from "typeorm";
+
+export class NewUserSettings1719776735000 implements MigrationInterface {
+ name = "NewUserSettings1719776735000";
+
+ public async up(queryRunner: QueryRunner): Promise<void> {
+ await queryRunner.query(
+ "ALTER TABLE `user_settings` ADD friend_discovery_flags integer NULL DEFAULT 0;",
+ );
+ await queryRunner.query(
+ "ALTER TABLE `user_settings` ADD view_nsfw_guilds tinyint NULL DEFAULT 1;",
+ );
+ }
+
+ public async down(queryRunner: QueryRunner): Promise<void> {
+ await queryRunner.query(
+ "ALTER TABLE `user_settings` DROP COLUMN friend_discovery_flags;",
+ );
+ await queryRunner.query(
+ "ALTER TABLE `user_settings` DROP COLUMN view_nsfw_guilds;",
+ );
+ }
+}
diff --git a/src/util/migration/mysql/1720157926878-messagePollObject.ts b/src/util/migration/mysql/1720157926878-messagePollObject.ts
new file mode 100644
index 00000000..c0866426
--- /dev/null
+++ b/src/util/migration/mysql/1720157926878-messagePollObject.ts
@@ -0,0 +1,13 @@
+import { MigrationInterface, QueryRunner } from "typeorm";
+
+export class MessagePollObject1720157926878 implements MigrationInterface {
+ name = "MessagePollObject1720157926878";
+
+ public async up(queryRunner: QueryRunner): Promise<void> {
+ await queryRunner.query("ALTER TABLE `messages` ADD `poll` text NULL");
+ }
+
+ public async down(queryRunner: QueryRunner): Promise<void> {
+ await queryRunner.query("ALTER TABLE `messages` DROP COLUMN `poll`");
+ }
+}
diff --git a/src/util/migration/mysql/1720628601997-badges.ts b/src/util/migration/mysql/1720628601997-badges.ts
new file mode 100644
index 00000000..af298e42
--- /dev/null
+++ b/src/util/migration/mysql/1720628601997-badges.ts
@@ -0,0 +1,21 @@
+import { MigrationInterface, QueryRunner } from "typeorm";
+
+export class Badges1720628601997 implements MigrationInterface {
+ name = "Badges1720628601997";
+
+ public async up(queryRunner: QueryRunner): Promise<void> {
+ await queryRunner.query(
+ `CREATE TABLE \`badges\` (\`id\` varchar(255) NOT NULL, \`description\` varchar(255) NOT NULL, \`icon\` varchar(255) NOT NULL, \`link\` varchar(255) NULL, PRIMARY KEY (\`id\`)) ENGINE=InnoDB`,
+ );
+ await queryRunner.query(
+ `ALTER TABLE \`users\` ADD \`badge_ids\` text NULL`,
+ );
+ }
+
+ public async down(queryRunner: QueryRunner): Promise<void> {
+ await queryRunner.query(
+ `ALTER TABLE \`users\` DROP COLUMN \`badge_ids\``,
+ );
+ await queryRunner.query(`DROP TABLE \`badges\``);
+ }
+}
diff --git a/src/util/migration/postgres/1719776735000-newUserSettings.ts b/src/util/migration/postgres/1719776735000-newUserSettings.ts
new file mode 100644
index 00000000..dbee0b0d
--- /dev/null
+++ b/src/util/migration/postgres/1719776735000-newUserSettings.ts
@@ -0,0 +1,23 @@
+import { MigrationInterface, QueryRunner } from "typeorm";
+
+export class NewUserSettings1719776735000 implements MigrationInterface {
+ name = "NewUserSettings1719776735000";
+
+ public async up(queryRunner: QueryRunner): Promise<void> {
+ await queryRunner.query(
+ "ALTER TABLE user_settings ADD COLUMN friend_discovery_flags integer DEFAULT 0;",
+ );
+ await queryRunner.query(
+ "ALTER TABLE user_settings ADD COLUMN view_nsfw_guilds boolean DEFAULT true;",
+ );
+ }
+
+ public async down(queryRunner: QueryRunner): Promise<void> {
+ await queryRunner.query(
+ "ALTER TABLE user_settings DROP COLUMN friend_discovery_flags;",
+ );
+ await queryRunner.query(
+ "ALTER TABLE user_settings DROP COLUMN view_nsfw_guilds;",
+ );
+ }
+}
diff --git a/src/util/migration/postgres/1720157926878-messagePollObject.ts b/src/util/migration/postgres/1720157926878-messagePollObject.ts
new file mode 100644
index 00000000..7c3c95a0
--- /dev/null
+++ b/src/util/migration/postgres/1720157926878-messagePollObject.ts
@@ -0,0 +1,13 @@
+import { MigrationInterface, QueryRunner } from "typeorm";
+
+export class MessagePollObject1720157926878 implements MigrationInterface {
+ name = "MessagePollObject1720157926878";
+
+ public async up(queryRunner: QueryRunner): Promise<void> {
+ await queryRunner.query("ALTER TABLE messages ADD poll text NULL");
+ }
+
+ public async down(queryRunner: QueryRunner): Promise<void> {
+ await queryRunner.query("ALTER TABLE messages DROP COLUMN poll");
+ }
+}
diff --git a/src/util/migration/postgres/1720628601997-badges.ts b/src/util/migration/postgres/1720628601997-badges.ts
new file mode 100644
index 00000000..f7b9958b
--- /dev/null
+++ b/src/util/migration/postgres/1720628601997-badges.ts
@@ -0,0 +1,16 @@
+import { MigrationInterface, QueryRunner } from "typeorm";
+
+export class Badges1720628601997 implements MigrationInterface {
+ name = "Badges1720628601997";
+
+ public async up(queryRunner: QueryRunner): Promise<void> {
+ await queryRunner.query(
+ `CREATE TABLE "badges" ("id" character varying NOT NULL, "description" character varying NOT NULL, "icon" character varying NOT NULL, "link" character varying, CONSTRAINT "PK_8a651318b8de577e8e217676466" PRIMARY KEY ("id"))`,
+ );
+ await queryRunner.query(`ALTER TABLE "users" ADD "badge_ids" text`);
+ }
+
+ public async down(queryRunner: QueryRunner): Promise<void> {
+ await queryRunner.query(`ALTER TABLE "users" DROP COLUMN "badge_ids"`);
+ }
+}
diff --git a/src/util/schemas/MessageCreateSchema.ts b/src/util/schemas/MessageCreateSchema.ts
index 57abf62f..014f6c87 100644
--- a/src/util/schemas/MessageCreateSchema.ts
+++ b/src/util/schemas/MessageCreateSchema.ts
@@ -1,22 +1,22 @@
/*
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
Copyright (C) 2023 Spacebar and Spacebar Contributors
-
+
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
-
+
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-import { Embed } from "@spacebar/util";
+import { Embed, MessageComponent, PollAnswer, PollMedia } from "@spacebar/util";
type Attachment = {
id: string;
@@ -42,7 +42,7 @@ export interface MessageCreateSchema {
};
message_reference?: {
message_id: string;
- channel_id: string;
+ channel_id?: string;
guild_id?: string;
fail_if_not_exists?: boolean;
};
@@ -54,6 +54,21 @@ export interface MessageCreateSchema {
**/
attachments?: Attachment[];
sticker_ids?: string[];
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- components?: any[];
+ components?: MessageComponent[];
+ // TODO: Fix TypeScript errors in src\api\util\handlers\Message.ts once this is enabled
+ poll?: PollCreationSchema;
+ enforce_nonce?: boolean; // For Discord compatibility, it's the default behavior here
+ applied_tags?: string[]; // Not implemented yet, for webhooks in forums
+ thread_name?: string; // Not implemented yet, for webhooks
+ avatar_url?: string; // Not implemented yet, for webhooks
+}
+
+// TypeScript complains once this is used above
+// eslint-disable-next-line @typescript-eslint/no-unused-vars
+interface PollCreationSchema {
+ question: PollMedia;
+ answers: PollAnswer[];
+ duration?: number;
+ allow_multiselect?: boolean;
+ layout_type?: number;
}
diff --git a/src/util/schemas/responses/GuildMessagesSearchResponse.ts b/src/util/schemas/responses/GuildMessagesSearchResponse.ts
index b42aafd3..6121983e 100644
--- a/src/util/schemas/responses/GuildMessagesSearchResponse.ts
+++ b/src/util/schemas/responses/GuildMessagesSearchResponse.ts
@@ -1,17 +1,17 @@
/*
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
Copyright (C) 2023 Spacebar and Spacebar Contributors
-
+
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
-
+
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
@@ -19,7 +19,9 @@
import {
Attachment,
Embed,
+ MessageComponent,
MessageType,
+ Poll,
PublicUser,
Role,
} from "../../entities";
@@ -40,7 +42,8 @@ export interface GuildMessagesSearchMessage {
timestamp: string;
edited_timestamp: string | null;
flags: number;
- components: unknown[];
+ components: MessageComponent[];
+ poll: Poll;
hit: true;
}
diff --git a/src/util/schemas/responses/TypedResponses.ts b/src/util/schemas/responses/TypedResponses.ts
index fa169c25..8214ff7b 100644
--- a/src/util/schemas/responses/TypedResponses.ts
+++ b/src/util/schemas/responses/TypedResponses.ts
@@ -1,17 +1,17 @@
/*
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
Copyright (C) 2023 Spacebar and Spacebar Contributors
-
+
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
-
+
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
@@ -104,3 +104,10 @@ export type APIGuildVoiceRegion = GuildVoiceRegion[];
export type APILimitsConfiguration = LimitsConfiguration;
export type APIStickerPackArray = StickerPack[];
+
+export type APIConnectionsConfiguration = Record<
+ string,
+ {
+ enabled: boolean;
+ }
+>;
diff --git a/src/util/schemas/responses/UserProfileResponse.ts b/src/util/schemas/responses/UserProfileResponse.ts
index 26e7e3bc..7b63542e 100644
--- a/src/util/schemas/responses/UserProfileResponse.ts
+++ b/src/util/schemas/responses/UserProfileResponse.ts
@@ -17,6 +17,7 @@
*/
import {
+ Badge,
Member,
PublicConnectedAccount,
PublicMember,
@@ -52,4 +53,5 @@ export interface UserProfileResponse {
user_profile: UserProfile;
guild_member?: PublicMember;
guild_member_profile?: PublicMemberProfile;
+ badges: Badge[];
}
diff --git a/src/util/util/email/index.ts b/src/util/util/email/index.ts
index 619cc5c3..e3382794 100644
--- a/src/util/util/email/index.ts
+++ b/src/util/util/email/index.ts
@@ -141,8 +141,9 @@ export const Email: {
*/
generateLink: async function (type, id, email) {
const token = (await generateToken(id, email)) as string;
+ // puyodead1: this is set to api endpoint because the verification page is on the server since no clients have one, and not all 3rd party clients will have one
const instanceUrl =
- Config.get().general.frontPage || "http://localhost:3001";
+ Config.get().api.endpointPublic || "http://localhost:3001";
const link = `${instanceUrl}/${type}#token=${token}`;
return link;
},
@@ -187,7 +188,9 @@ export const Email: {
const message = {
from:
- Config.get().general.correspondenceEmail || "noreply@localhost",
+ Config.get().email.senderAddress ||
+ Config.get().general.correspondenceEmail ||
+ "noreply@localhost",
to: email,
subject,
html,
diff --git a/src/util/util/email/transports/SMTP.ts b/src/util/util/email/transports/SMTP.ts
index 5b43a870..e3031943 100644
--- a/src/util/util/email/transports/SMTP.ts
+++ b/src/util/util/email/transports/SMTP.ts
@@ -27,9 +27,12 @@ export default async function () {
if (!host || !port || secure === null || !username || !password)
return console.error("[Email] SMTP has not been configured correctly.");
- if (!Config.get().general.correspondenceEmail)
+ if (
+ !Config.get().email.senderAddress &&
+ !Config.get().general.correspondenceEmail
+ )
return console.error(
- "[Email] Correspondence email has not been configured! This is used as the sender email address.",
+ '[Email] You have to configure either "email_senderAddress" or "general_correspondenceEmail" for emails to work. The configured value is used as the sender address.',
);
// construct the transporter
|