mirror of
https://github.com/spacebarchat/server.git
synced 2026-10-22 15:22:43 +00:00
Merge branch 'master' into feat/local-image-proxy
This commit is contained in:
69 files changed
+929
-282
No files matched your search
+11
-7
@@ -18,15 +18,15 @@
|
||||
|
||||
import {
|
||||
Config,
|
||||
Email,
|
||||
initDatabase,
|
||||
initEvent,
|
||||
JSONReplacer,
|
||||
registerRoutes,
|
||||
Sentry,
|
||||
WebAuthn,
|
||||
ConnectionConfig,
|
||||
ConnectionLoader,
|
||||
Email,
|
||||
JSONReplacer,
|
||||
Sentry,
|
||||
WebAuthn,
|
||||
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);
|
||||
|
||||
@@ -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",
|
||||
},
|
||||
|
||||
@@ -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);
|
||||
},
|
||||
);
|
||||
|
||||
@@ -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);
|
||||
},
|
||||
);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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}`;
|
||||
});
|
||||
|
||||
/**
|
||||
|
||||
@@ -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 } })))
|
||||
|
||||
@@ -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;
|
||||
@@ -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);
|
||||
},
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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,
|
||||
},
|
||||
]);
|
||||
|
||||
@@ -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)),
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
@@ -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,
|
||||
Guild,
|
||||
Message,
|
||||
MessageCreateEvent,
|
||||
MessageUpdateEvent,
|
||||
EVERYONE_MENTION,
|
||||
getPermission,
|
||||
getRights,
|
||||
Guild,
|
||||
HERE_MENTION,
|
||||
Message,
|
||||
MessageCreateEvent,
|
||||
MessageCreateSchema,
|
||||
MessageType,
|
||||
MessageUpdateEvent,
|
||||
Role,
|
||||
ROLE_MENTION,
|
||||
Sticker,
|
||||
User,
|
||||
//CHANNEL_MENTION,
|
||||
USER_MENTION,
|
||||
ROLE_MENTION,
|
||||
Role,
|
||||
EVERYONE_MENTION,
|
||||
HERE_MENTION,
|
||||
MessageType,
|
||||
User,
|
||||
Application,
|
||||
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 } });
|
||||
|
||||
Reference in new issue
Block a user