mirror of
https://github.com/spacebarchat/server.git
synced 2026-03-30 18:15:41 +00:00
Prettier u3
This commit is contained in:
@@ -41,14 +41,8 @@ export function BodyParser(opts?: OptionsJson) {
|
||||
|
||||
jsonParser(req, res, (err) => {
|
||||
if (err) {
|
||||
const [message, status] = errorMessages[err.type] || [
|
||||
"Invalid Body",
|
||||
400,
|
||||
];
|
||||
const errorMessage =
|
||||
message.includes("charset") || message.includes("encoding")
|
||||
? `${message} "${err.charset || err.encoding}"`
|
||||
: message;
|
||||
const [message, status] = errorMessages[err.type] || ["Invalid Body", 400];
|
||||
const errorMessage = message.includes("charset") || message.includes("encoding") ? `${message} "${err.charset || err.encoding}"` : message;
|
||||
return next(new HTTPError(errorMessage, status));
|
||||
}
|
||||
next();
|
||||
|
||||
@@ -46,22 +46,15 @@ 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,
|
||||
);
|
||||
channel.position = await Channel.calculatePosition(channel_id, channel.guild_id, channel.guild);
|
||||
|
||||
if (body.type === ChannelPermissionOverwriteType.role) {
|
||||
if (!(await Role.count({ where: { id: overwrite_id } })))
|
||||
throw new HTTPError("role not found", 404);
|
||||
if (!(await Role.count({ where: { id: overwrite_id } }))) throw new HTTPError("role not found", 404);
|
||||
} else if (body.type === ChannelPermissionOverwriteType.member) {
|
||||
if (!(await Member.count({ where: { id: overwrite_id } })))
|
||||
throw new HTTPError("user not found", 404);
|
||||
if (!(await Member.count({ where: { id: overwrite_id } }))) throw new HTTPError("user not found", 404);
|
||||
} else throw new HTTPError("type not supported", 501);
|
||||
|
||||
let overwrite: ChannelPermissionOverwrite | undefined =
|
||||
channel.permission_overwrites?.find((x) => x.id === overwrite_id);
|
||||
let overwrite: ChannelPermissionOverwrite | undefined = channel.permission_overwrites?.find((x) => x.id === overwrite_id);
|
||||
if (!overwrite) {
|
||||
overwrite = {
|
||||
id: overwrite_id,
|
||||
@@ -71,14 +64,8 @@ router.put(
|
||||
};
|
||||
channel.permission_overwrites?.push(overwrite);
|
||||
}
|
||||
overwrite.allow = String(
|
||||
(req.permission?.bitfield || 0n) &
|
||||
(BigInt(body.allow) || BigInt("0")),
|
||||
);
|
||||
overwrite.deny = String(
|
||||
(req.permission?.bitfield || 0n) &
|
||||
(BigInt(body.deny) || BigInt("0")),
|
||||
);
|
||||
overwrite.allow = String((req.permission?.bitfield || 0n) & (BigInt(body.allow) || BigInt("0")));
|
||||
overwrite.deny = String((req.permission?.bitfield || 0n) & (BigInt(body.deny) || BigInt("0")));
|
||||
|
||||
await Promise.all([
|
||||
channel.save(),
|
||||
@@ -94,32 +81,26 @@ router.put(
|
||||
);
|
||||
|
||||
// TODO: check permission hierarchy
|
||||
router.delete(
|
||||
"/:overwrite_id",
|
||||
route({ permission: "MANAGE_ROLES", responses: { 204: {}, 404: {} } }),
|
||||
async (req: Request, res: Response) => {
|
||||
const { channel_id, overwrite_id } = req.params;
|
||||
router.delete("/:overwrite_id", route({ permission: "MANAGE_ROLES", responses: { 204: {}, 404: {} } }), async (req: Request, res: Response) => {
|
||||
const { channel_id, overwrite_id } = req.params;
|
||||
|
||||
const channel = await Channel.findOneOrFail({
|
||||
where: { id: channel_id },
|
||||
});
|
||||
if (!channel.guild_id) throw new HTTPError("Channel not found", 404);
|
||||
const channel = await Channel.findOneOrFail({
|
||||
where: { id: channel_id },
|
||||
});
|
||||
if (!channel.guild_id) throw new HTTPError("Channel not found", 404);
|
||||
|
||||
channel.permission_overwrites = channel.permission_overwrites?.filter(
|
||||
(x) => x.id !== overwrite_id,
|
||||
);
|
||||
channel.permission_overwrites = channel.permission_overwrites?.filter((x) => x.id !== overwrite_id);
|
||||
|
||||
await Promise.all([
|
||||
channel.save(),
|
||||
emitEvent({
|
||||
event: "CHANNEL_UPDATE",
|
||||
channel_id,
|
||||
data: channel,
|
||||
} as ChannelUpdateEvent),
|
||||
]);
|
||||
await Promise.all([
|
||||
channel.save(),
|
||||
emitEvent({
|
||||
event: "CHANNEL_UPDATE",
|
||||
channel_id,
|
||||
data: channel,
|
||||
} as ChannelUpdateEvent),
|
||||
]);
|
||||
|
||||
return res.sendStatus(204);
|
||||
},
|
||||
);
|
||||
return res.sendStatus(204);
|
||||
});
|
||||
|
||||
export default router;
|
||||
|
||||
@@ -17,55 +17,45 @@
|
||||
*/
|
||||
|
||||
import { route } from "@spacebar/api";
|
||||
import {
|
||||
ConnectionStore,
|
||||
emitEvent,
|
||||
FieldErrors,
|
||||
} from "@spacebar/util";
|
||||
import { ConnectionStore, emitEvent, FieldErrors } from "@spacebar/util";
|
||||
import { Request, Response, Router } from "express";
|
||||
import { ConnectionCallbackSchema } from "@spacebar/schemas"
|
||||
import { ConnectionCallbackSchema } from "@spacebar/schemas";
|
||||
|
||||
const router = Router({ mergeParams: true });
|
||||
|
||||
router.post(
|
||||
"/",
|
||||
route({ requestBody: "ConnectionCallbackSchema" }),
|
||||
async (req: Request, res: Response) => {
|
||||
const { connection_name } = req.params;
|
||||
const connection = ConnectionStore.connections.get(connection_name);
|
||||
if (!connection)
|
||||
throw FieldErrors({
|
||||
provider_id: {
|
||||
code: "BASE_TYPE_CHOICES",
|
||||
message: req.t("common:field.BASE_TYPE_CHOICES", {
|
||||
types: Array.from(
|
||||
ConnectionStore.connections.keys(),
|
||||
).join(", "),
|
||||
}),
|
||||
},
|
||||
});
|
||||
router.post("/", route({ requestBody: "ConnectionCallbackSchema" }), async (req: Request, res: Response) => {
|
||||
const { connection_name } = req.params;
|
||||
const connection = ConnectionStore.connections.get(connection_name);
|
||||
if (!connection)
|
||||
throw FieldErrors({
|
||||
provider_id: {
|
||||
code: "BASE_TYPE_CHOICES",
|
||||
message: req.t("common:field.BASE_TYPE_CHOICES", {
|
||||
types: Array.from(ConnectionStore.connections.keys()).join(", "),
|
||||
}),
|
||||
},
|
||||
});
|
||||
|
||||
if (!connection.settings.enabled)
|
||||
throw FieldErrors({
|
||||
provider_id: {
|
||||
message: "This connection has been disabled server-side.",
|
||||
},
|
||||
});
|
||||
if (!connection.settings.enabled)
|
||||
throw FieldErrors({
|
||||
provider_id: {
|
||||
message: "This connection has been disabled server-side.",
|
||||
},
|
||||
});
|
||||
|
||||
const body = req.body as ConnectionCallbackSchema;
|
||||
const userId = connection.getUserId(body.state);
|
||||
const connectedAccnt = await connection.handleCallback(body);
|
||||
const body = req.body as ConnectionCallbackSchema;
|
||||
const userId = connection.getUserId(body.state);
|
||||
const connectedAccnt = await connection.handleCallback(body);
|
||||
|
||||
// whether we should emit a connections update event, only used when a connection doesnt already exist
|
||||
if (connectedAccnt)
|
||||
emitEvent({
|
||||
event: "USER_CONNECTIONS_UPDATE",
|
||||
data: { ...connectedAccnt, token_data: undefined },
|
||||
user_id: userId,
|
||||
});
|
||||
// whether we should emit a connections update event, only used when a connection doesnt already exist
|
||||
if (connectedAccnt)
|
||||
emitEvent({
|
||||
event: "USER_CONNECTIONS_UPDATE",
|
||||
data: { ...connectedAccnt, token_data: undefined },
|
||||
user_id: userId,
|
||||
});
|
||||
|
||||
res.sendStatus(204);
|
||||
},
|
||||
);
|
||||
res.sendStatus(204);
|
||||
});
|
||||
|
||||
export default router;
|
||||
|
||||
@@ -17,14 +17,9 @@
|
||||
*/
|
||||
|
||||
import { route } from "@spacebar/api";
|
||||
import {
|
||||
Emoji,
|
||||
DiscordApiErrors,
|
||||
Guild,
|
||||
Member,
|
||||
} from "@spacebar/util";
|
||||
import { Emoji, DiscordApiErrors, Guild, Member } from "@spacebar/util";
|
||||
import { Request, Response, Router } from "express";
|
||||
import { APIErrorResponse, EmojiGuild, EmojiSourceResponse } from "@spacebar/schemas"
|
||||
import { APIErrorResponse, EmojiGuild, EmojiSourceResponse } from "@spacebar/schemas";
|
||||
|
||||
const router = Router({ mergeParams: true });
|
||||
|
||||
|
||||
@@ -17,13 +17,10 @@
|
||||
*/
|
||||
|
||||
import { route } from "@spacebar/api";
|
||||
import {
|
||||
getGifApiKey,
|
||||
parseGifResult,
|
||||
} from "@spacebar/util";
|
||||
import { getGifApiKey, parseGifResult } from "@spacebar/util";
|
||||
import { Request, Response, Router } from "express";
|
||||
import http from "http";
|
||||
import { TenorGif, TenorMediaTypes } from "@spacebar/schemas"
|
||||
import { TenorGif, TenorMediaTypes } from "@spacebar/schemas";
|
||||
|
||||
const router = Router({ mergeParams: true });
|
||||
|
||||
@@ -39,9 +36,7 @@ router.get(
|
||||
media_format: {
|
||||
type: "string",
|
||||
description: "Media format",
|
||||
values: Object.keys(TenorMediaTypes).filter((key) =>
|
||||
isNaN(Number(key)),
|
||||
),
|
||||
values: Object.keys(TenorMediaTypes).filter((key) => isNaN(Number(key))),
|
||||
},
|
||||
locale: {
|
||||
type: "string",
|
||||
@@ -60,13 +55,10 @@ router.get(
|
||||
|
||||
const apiKey = getGifApiKey();
|
||||
|
||||
const response = await fetch(
|
||||
`https://g.tenor.com/v1/search?q=${q}&media_format=${media_format}&locale=${locale}&key=${apiKey}`,
|
||||
{
|
||||
method: "get",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
},
|
||||
);
|
||||
const response = await fetch(`https://g.tenor.com/v1/search?q=${q}&media_format=${media_format}&locale=${locale}&key=${apiKey}`, {
|
||||
method: "get",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
});
|
||||
|
||||
const { results } = (await response.json()) as { results: TenorGif[] };
|
||||
|
||||
|
||||
@@ -17,12 +17,9 @@
|
||||
*/
|
||||
|
||||
import { route } from "@spacebar/api";
|
||||
import {
|
||||
getGifApiKey,
|
||||
parseGifResult,
|
||||
} from "@spacebar/util";
|
||||
import { getGifApiKey, parseGifResult } from "@spacebar/util";
|
||||
import { Request, Response, Router } from "express";
|
||||
import { TenorGif, TenorMediaTypes } from "@spacebar/schemas"
|
||||
import { TenorGif, TenorMediaTypes } from "@spacebar/schemas";
|
||||
|
||||
const router = Router({ mergeParams: true });
|
||||
|
||||
@@ -33,9 +30,7 @@ router.get(
|
||||
media_format: {
|
||||
type: "string",
|
||||
description: "Media format",
|
||||
values: Object.keys(TenorMediaTypes).filter((key) =>
|
||||
isNaN(Number(key)),
|
||||
),
|
||||
values: Object.keys(TenorMediaTypes).filter((key) => isNaN(Number(key))),
|
||||
},
|
||||
locale: {
|
||||
type: "string",
|
||||
@@ -54,13 +49,10 @@ router.get(
|
||||
|
||||
const apiKey = getGifApiKey();
|
||||
|
||||
const response = await fetch(
|
||||
`https://g.tenor.com/v1/trending?media_format=${media_format}&locale=${locale}&key=${apiKey}`,
|
||||
{
|
||||
method: "get",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
},
|
||||
);
|
||||
const response = await fetch(`https://g.tenor.com/v1/trending?media_format=${media_format}&locale=${locale}&key=${apiKey}`, {
|
||||
method: "get",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
});
|
||||
|
||||
const { results } = (await response.json()) as { results: TenorGif[] };
|
||||
|
||||
|
||||
@@ -17,12 +17,9 @@
|
||||
*/
|
||||
|
||||
import { route } from "@spacebar/api";
|
||||
import {
|
||||
getGifApiKey,
|
||||
parseGifResult,
|
||||
} from "@spacebar/util";
|
||||
import { getGifApiKey, parseGifResult } from "@spacebar/util";
|
||||
import { Request, Response, Router } from "express";
|
||||
import { TenorCategoriesResults, TenorTrendingResults } from "@spacebar/schemas"
|
||||
import { TenorCategoriesResults, TenorTrendingResults } from "@spacebar/schemas";
|
||||
|
||||
const router = Router({ mergeParams: true });
|
||||
|
||||
@@ -50,26 +47,18 @@ router.get(
|
||||
const apiKey = getGifApiKey();
|
||||
|
||||
const [responseSource, trendGifSource] = await Promise.all([
|
||||
fetch(
|
||||
`https://g.tenor.com/v1/categories?locale=${locale}&key=${apiKey}`,
|
||||
{
|
||||
method: "get",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
},
|
||||
),
|
||||
fetch(
|
||||
`https://g.tenor.com/v1/trending?locale=${locale}&key=${apiKey}`,
|
||||
{
|
||||
method: "get",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
},
|
||||
),
|
||||
fetch(`https://g.tenor.com/v1/categories?locale=${locale}&key=${apiKey}`, {
|
||||
method: "get",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
}),
|
||||
fetch(`https://g.tenor.com/v1/trending?locale=${locale}&key=${apiKey}`, {
|
||||
method: "get",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
}),
|
||||
]);
|
||||
|
||||
const { tags } =
|
||||
(await responseSource.json()) as TenorCategoriesResults;
|
||||
const { results } =
|
||||
(await trendGifSource.json()) as TenorTrendingResults;
|
||||
const { tags } = (await responseSource.json()) as TenorCategoriesResults;
|
||||
const { results } = (await trendGifSource.json()) as TenorTrendingResults;
|
||||
|
||||
res.json({
|
||||
categories: tags.map((x) => ({
|
||||
|
||||
@@ -20,7 +20,7 @@ import { route } from "@spacebar/api";
|
||||
import { User, AutomodRule } from "@spacebar/util";
|
||||
import { Request, Response, Router } from "express";
|
||||
import { HTTPError } from "lambert-server";
|
||||
import { AutomodRuleSchema } from "@spacebar/schemas"
|
||||
import { AutomodRuleSchema } from "@spacebar/schemas";
|
||||
|
||||
const router: Router = Router({ mergeParams: true });
|
||||
|
||||
@@ -63,17 +63,9 @@ router.post(
|
||||
}),
|
||||
async (req: Request, res: Response) => {
|
||||
const { guild_id } = req.params;
|
||||
if (req.user_id !== req.body.creator_id)
|
||||
throw new HTTPError(
|
||||
"You can't create a rule for someone else",
|
||||
403,
|
||||
);
|
||||
if (req.user_id !== req.body.creator_id) throw new HTTPError("You can't create a rule for someone else", 403);
|
||||
|
||||
if (guild_id !== req.body.guild_id)
|
||||
throw new HTTPError(
|
||||
"You can't create a rule for another guild",
|
||||
403,
|
||||
);
|
||||
if (guild_id !== req.body.guild_id) throw new HTTPError("You can't create a rule for another guild", 403);
|
||||
|
||||
if (req.body.id) {
|
||||
throw new HTTPError("You can't specify an ID for a new rule", 400);
|
||||
|
||||
@@ -17,16 +17,7 @@
|
||||
*/
|
||||
|
||||
import { route } from "@spacebar/api";
|
||||
import {
|
||||
GuildStickersUpdateEvent,
|
||||
Member,
|
||||
Snowflake,
|
||||
Sticker,
|
||||
emitEvent,
|
||||
uploadFile,
|
||||
Config,
|
||||
DiscordApiErrors,
|
||||
} from "@spacebar/util";
|
||||
import { GuildStickersUpdateEvent, Member, Snowflake, Sticker, emitEvent, uploadFile, Config, DiscordApiErrors } from "@spacebar/util";
|
||||
import { Request, Response, Router } from "express";
|
||||
import { HTTPError } from "lambert-server";
|
||||
import multer from "multer";
|
||||
@@ -92,10 +83,7 @@ router.post(
|
||||
});
|
||||
const { maxStickers } = Config.get().limits.guild;
|
||||
|
||||
if (sticker_count >= maxStickers)
|
||||
throw DiscordApiErrors.MAXIMUM_STICKERS.withParams(
|
||||
maxStickers,
|
||||
);
|
||||
if (sticker_count >= maxStickers) throw DiscordApiErrors.MAXIMUM_STICKERS.withParams(maxStickers);
|
||||
|
||||
const [sticker] = await Promise.all([
|
||||
Sticker.create({
|
||||
@@ -126,9 +114,7 @@ function getStickerFormat(mime_type: string) {
|
||||
case "image/gif":
|
||||
return StickerFormatType.GIF;
|
||||
default:
|
||||
throw new HTTPError(
|
||||
"invalid sticker format: must be png, apng or lottie",
|
||||
);
|
||||
throw new HTTPError("invalid sticker format: must be png, apng or lottie");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,11 +17,7 @@
|
||||
*/
|
||||
|
||||
import { route } from "@spacebar/api";
|
||||
import {
|
||||
Channel,
|
||||
Guild,
|
||||
Invite,
|
||||
} from "@spacebar/util";
|
||||
import { Channel, Guild, Invite } from "@spacebar/util";
|
||||
import { Request, Response, Router } from "express";
|
||||
import { HTTPError } from "lambert-server";
|
||||
import { ChannelType, VanityUrlSchema } from "@spacebar/schemas";
|
||||
@@ -63,9 +59,7 @@ router.get(
|
||||
});
|
||||
if (!invite || invite.length == 0) return res.json({ code: null });
|
||||
|
||||
return res.json(
|
||||
invite.map((x) => ({ code: x.code, uses: x.uses })),
|
||||
);
|
||||
return res.json(invite.map((x) => ({ code: x.code, uses: x.uses })));
|
||||
}
|
||||
},
|
||||
);
|
||||
@@ -93,11 +87,9 @@ router.patch(
|
||||
const code = body.code?.replace(InviteRegex, "");
|
||||
|
||||
const guild = await Guild.findOneOrFail({ where: { id: guild_id } });
|
||||
if (!guild.features.includes("VANITY_URL"))
|
||||
throw new HTTPError("Your guild doesn't support vanity urls");
|
||||
if (!guild.features.includes("VANITY_URL")) throw new HTTPError("Your guild doesn't support vanity urls");
|
||||
|
||||
if (!code || code.length === 0)
|
||||
throw new HTTPError("Code cannot be null or empty");
|
||||
if (!code || code.length === 0) throw new HTTPError("Code cannot be null or empty");
|
||||
|
||||
const invite = await Invite.findOne({ where: { code } });
|
||||
if (invite) throw new HTTPError("Invite already exists");
|
||||
|
||||
@@ -24,8 +24,7 @@ const router = Router({ mergeParams: true });
|
||||
router.get(
|
||||
"/",
|
||||
route({
|
||||
description:
|
||||
"Returns a list of guild webhook objects. Requires the MANAGE_WEBHOOKS permission.",
|
||||
description: "Returns a list of guild webhook objects. Requires the MANAGE_WEBHOOKS permission.",
|
||||
permission: "MANAGE_WEBHOOKS",
|
||||
responses: {
|
||||
200: {
|
||||
@@ -37,30 +36,17 @@ router.get(
|
||||
const { guild_id } = req.params;
|
||||
const webhooks = await Webhook.find({
|
||||
where: { guild_id },
|
||||
relations: [
|
||||
"user",
|
||||
"channel",
|
||||
"source_channel",
|
||||
"guild",
|
||||
"source_guild",
|
||||
"application",
|
||||
],
|
||||
relations: ["user", "channel", "source_channel", "guild", "source_guild", "application"],
|
||||
});
|
||||
|
||||
const instanceUrl =
|
||||
Config.get().api.endpointPublic || "http://localhost:3001";
|
||||
const instanceUrl = Config.get().api.endpointPublic;
|
||||
return res.json(
|
||||
webhooks.map((webhook) => ({
|
||||
...webhook,
|
||||
url:
|
||||
instanceUrl +
|
||||
"/webhooks/" +
|
||||
webhook.id +
|
||||
"/" +
|
||||
webhook.token,
|
||||
url: instanceUrl + "/webhooks/" + webhook.id + "/" + webhook.token,
|
||||
})),
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
export default router;
|
||||
export default router;
|
||||
@@ -17,13 +17,9 @@
|
||||
*/
|
||||
|
||||
import { route } from "@spacebar/api";
|
||||
import {
|
||||
Channel,
|
||||
Guild,
|
||||
Member,
|
||||
} from "@spacebar/util";
|
||||
import { Channel, Guild, Member } from "@spacebar/util";
|
||||
import { Request, Response, Router } from "express";
|
||||
import { GuildUpdateWelcomeScreenSchema } from "@spacebar/schemas"
|
||||
import { GuildUpdateWelcomeScreenSchema } from "@spacebar/schemas";
|
||||
|
||||
const router: Router = Router({ mergeParams: true });
|
||||
|
||||
@@ -70,11 +66,9 @@ router.patch(
|
||||
|
||||
const guild = await Guild.findOneOrFail({ where: { id: guild_id } });
|
||||
|
||||
if (body.enabled != undefined)
|
||||
guild.welcome_screen.enabled = body.enabled;
|
||||
if (body.enabled != undefined) guild.welcome_screen.enabled = body.enabled;
|
||||
|
||||
if (body.description != undefined)
|
||||
guild.welcome_screen.description = body.description;
|
||||
if (body.description != undefined) guild.welcome_screen.description = body.description;
|
||||
|
||||
if (body.welcome_channels != undefined) {
|
||||
// Ensure channels exist within the guild
|
||||
|
||||
@@ -17,14 +17,7 @@
|
||||
*/
|
||||
|
||||
import { randomString, route } from "@spacebar/api";
|
||||
import {
|
||||
Channel,
|
||||
DiscordApiErrors,
|
||||
Guild,
|
||||
Invite,
|
||||
Member,
|
||||
Permissions,
|
||||
} from "@spacebar/util";
|
||||
import { Channel, DiscordApiErrors, Guild, Invite, Member, Permissions } from "@spacebar/util";
|
||||
import { Request, Response, Router } from "express";
|
||||
|
||||
const router: Router = Router({ mergeParams: true });
|
||||
@@ -95,13 +88,7 @@ router.get(
|
||||
|
||||
(await Channel.getOrderedChannels(guild.id, guild)).filter((doc) => {
|
||||
// Only return channels where @everyone has the CONNECT permission
|
||||
if (
|
||||
doc.permission_overwrites === undefined ||
|
||||
Permissions.channelPermission(
|
||||
doc.permission_overwrites,
|
||||
Permissions.FLAGS.CONNECT,
|
||||
) === Permissions.FLAGS.CONNECT
|
||||
) {
|
||||
if (doc.permission_overwrites === undefined || Permissions.channelPermission(doc.permission_overwrites, Permissions.FLAGS.CONNECT) === Permissions.FLAGS.CONNECT) {
|
||||
channels.push({
|
||||
id: doc.id,
|
||||
name: doc.name ?? "Unknown channel",
|
||||
|
||||
@@ -58,15 +58,8 @@ router.get(
|
||||
|
||||
// Fetch parameter
|
||||
const style = req.query.style?.toString() || "shield";
|
||||
if (
|
||||
!["shield", "banner1", "banner2", "banner3", "banner4"].includes(
|
||||
style,
|
||||
)
|
||||
) {
|
||||
throw new HTTPError(
|
||||
"Value must be one of ('shield', 'banner1', 'banner2', 'banner3', 'banner4').",
|
||||
400,
|
||||
);
|
||||
if (!["shield", "banner1", "banner2", "banner3", "banner4"].includes(style)) {
|
||||
throw new HTTPError("Value must be one of ('shield', 'banner1', 'banner2', 'banner3', 'banner4').", 400);
|
||||
}
|
||||
|
||||
// Setup canvas
|
||||
@@ -74,17 +67,7 @@ router.get(
|
||||
const sizeOf = require("image-size");
|
||||
|
||||
// TODO: Widget style templates need Spacebar branding
|
||||
const source = path.join(
|
||||
__dirname,
|
||||
"..",
|
||||
"..",
|
||||
"..",
|
||||
"..",
|
||||
"..",
|
||||
"assets",
|
||||
"widget",
|
||||
`${style}.png`,
|
||||
);
|
||||
const source = path.join(__dirname, "..", "..", "..", "..", "..", "assets", "widget", `${style}.png`);
|
||||
if (!fs.existsSync(source)) {
|
||||
throw new HTTPError("Widget template does not exist.", 400);
|
||||
}
|
||||
@@ -100,100 +83,30 @@ router.get(
|
||||
switch (style) {
|
||||
case "shield":
|
||||
ctx.textAlign = "center";
|
||||
await drawText(
|
||||
ctx,
|
||||
73,
|
||||
13,
|
||||
"#FFFFFF",
|
||||
"thin 10px Verdana",
|
||||
presence,
|
||||
);
|
||||
await drawText(ctx, 73, 13, "#FFFFFF", "thin 10px Verdana", presence);
|
||||
break;
|
||||
case "banner1":
|
||||
if (icon) await drawIcon(ctx, 20, 27, 50, icon);
|
||||
await drawText(
|
||||
ctx,
|
||||
83,
|
||||
51,
|
||||
"#FFFFFF",
|
||||
"12px Verdana",
|
||||
name,
|
||||
22,
|
||||
);
|
||||
await drawText(
|
||||
ctx,
|
||||
83,
|
||||
66,
|
||||
"#C9D2F0FF",
|
||||
"thin 11px Verdana",
|
||||
presence,
|
||||
);
|
||||
await drawText(ctx, 83, 51, "#FFFFFF", "12px Verdana", name, 22);
|
||||
await drawText(ctx, 83, 66, "#C9D2F0FF", "thin 11px Verdana", presence);
|
||||
break;
|
||||
case "banner2":
|
||||
if (icon) await drawIcon(ctx, 13, 19, 36, icon);
|
||||
await drawText(
|
||||
ctx,
|
||||
62,
|
||||
34,
|
||||
"#FFFFFF",
|
||||
"12px Verdana",
|
||||
name,
|
||||
15,
|
||||
);
|
||||
await drawText(
|
||||
ctx,
|
||||
62,
|
||||
49,
|
||||
"#C9D2F0FF",
|
||||
"thin 11px Verdana",
|
||||
presence,
|
||||
);
|
||||
await drawText(ctx, 62, 34, "#FFFFFF", "12px Verdana", name, 15);
|
||||
await drawText(ctx, 62, 49, "#C9D2F0FF", "thin 11px Verdana", presence);
|
||||
break;
|
||||
case "banner3":
|
||||
if (icon) await drawIcon(ctx, 20, 20, 50, icon);
|
||||
await drawText(
|
||||
ctx,
|
||||
83,
|
||||
44,
|
||||
"#FFFFFF",
|
||||
"12px Verdana",
|
||||
name,
|
||||
27,
|
||||
);
|
||||
await drawText(
|
||||
ctx,
|
||||
83,
|
||||
58,
|
||||
"#C9D2F0FF",
|
||||
"thin 11px Verdana",
|
||||
presence,
|
||||
);
|
||||
await drawText(ctx, 83, 44, "#FFFFFF", "12px Verdana", name, 27);
|
||||
await drawText(ctx, 83, 58, "#C9D2F0FF", "thin 11px Verdana", presence);
|
||||
break;
|
||||
case "banner4":
|
||||
if (icon) await drawIcon(ctx, 21, 136, 50, icon);
|
||||
await drawText(
|
||||
ctx,
|
||||
84,
|
||||
156,
|
||||
"#FFFFFF",
|
||||
"13px Verdana",
|
||||
name,
|
||||
27,
|
||||
);
|
||||
await drawText(
|
||||
ctx,
|
||||
84,
|
||||
171,
|
||||
"#C9D2F0FF",
|
||||
"thin 12px Verdana",
|
||||
presence,
|
||||
);
|
||||
await drawText(ctx, 84, 156, "#FFFFFF", "13px Verdana", name, 27);
|
||||
await drawText(ctx, 84, 171, "#C9D2F0FF", "thin 12px Verdana", presence);
|
||||
break;
|
||||
default:
|
||||
throw new HTTPError(
|
||||
"Value must be one of ('shield', 'banner1', 'banner2', 'banner3', 'banner4').",
|
||||
400,
|
||||
);
|
||||
throw new HTTPError("Value must be one of ('shield', 'banner1', 'banner2', 'banner3', 'banner4').", 400);
|
||||
}
|
||||
|
||||
// Return final image
|
||||
@@ -204,13 +117,7 @@ router.get(
|
||||
},
|
||||
);
|
||||
|
||||
async function drawIcon(
|
||||
canvas: any,
|
||||
x: number,
|
||||
y: number,
|
||||
scale: number,
|
||||
icon: string,
|
||||
) {
|
||||
async function drawIcon(canvas: any, x: number, y: number, scale: number, icon: string) {
|
||||
const { loadImage } = require("canvas");
|
||||
const img = await loadImage(await storage.get(icon));
|
||||
|
||||
@@ -227,19 +134,10 @@ async function drawIcon(
|
||||
canvas.restore();
|
||||
}
|
||||
|
||||
async function drawText(
|
||||
canvas: any,
|
||||
x: number,
|
||||
y: number,
|
||||
color: string,
|
||||
font: string,
|
||||
text: string,
|
||||
maxcharacters?: number,
|
||||
) {
|
||||
async function drawText(canvas: any, x: number, y: number, color: string, font: string, text: string, maxcharacters?: number) {
|
||||
canvas.fillStyle = color;
|
||||
canvas.font = font;
|
||||
if (text.length > (maxcharacters || 0) && maxcharacters)
|
||||
text = text.slice(0, maxcharacters) + "...";
|
||||
if (text.length > (maxcharacters || 0) && maxcharacters) text = text.slice(0, maxcharacters) + "...";
|
||||
canvas.fillText(text, x, y);
|
||||
}
|
||||
|
||||
|
||||
@@ -17,13 +17,11 @@
|
||||
*/
|
||||
|
||||
import { route } from "@spacebar/api";
|
||||
import {
|
||||
FieldErrors,
|
||||
} from "@spacebar/util";
|
||||
import { FieldErrors } from "@spacebar/util";
|
||||
import emailProviders from "email-providers/all.json";
|
||||
import { Request, Response, Router } from "express";
|
||||
import { HTTPError } from "lambert-server";
|
||||
import { EmailDomainLookupResponse, EmailDomainLookupSchema, EmailDomainLookupVerifyCodeSchema } from "@spacebar/schemas"
|
||||
import { EmailDomainLookupResponse, EmailDomainLookupSchema, EmailDomainLookupVerifyCodeSchema } from "@spacebar/schemas";
|
||||
|
||||
const router = Router({ mergeParams: true });
|
||||
|
||||
@@ -48,8 +46,7 @@ router.post(
|
||||
if (emailProviders.includes(tld.toLowerCase())) {
|
||||
throw FieldErrors({
|
||||
name: {
|
||||
message:
|
||||
"That looks like a personal email address. Please use your official student email.",
|
||||
message: "That looks like a personal email address. Please use your official student email.",
|
||||
code: "EMAIL_IS_UNOFFICIAL",
|
||||
},
|
||||
});
|
||||
@@ -84,8 +81,7 @@ router.post(
|
||||
if (emailProviders.includes(tld.toLowerCase())) {
|
||||
throw FieldErrors({
|
||||
name: {
|
||||
message:
|
||||
"That looks like a personal email address. Please use your official student email.",
|
||||
message: "That looks like a personal email address. Please use your official student email.",
|
||||
code: "EMAIL_IS_UNOFFICIAL",
|
||||
},
|
||||
});
|
||||
|
||||
@@ -17,15 +17,9 @@
|
||||
*/
|
||||
|
||||
import { route } from "@spacebar/api";
|
||||
import {
|
||||
Config,
|
||||
DiscordApiErrors,
|
||||
Guild,
|
||||
Member,
|
||||
getRights,
|
||||
} from "@spacebar/util";
|
||||
import { Config, DiscordApiErrors, Guild, Member, getRights } from "@spacebar/util";
|
||||
import { Request, Response, Router } from "express";
|
||||
import { GuildCreateSchema } from "@spacebar/schemas"
|
||||
import { GuildCreateSchema } from "@spacebar/schemas";
|
||||
|
||||
const router: Router = Router({ mergeParams: true });
|
||||
|
||||
|
||||
@@ -17,10 +17,7 @@
|
||||
*/
|
||||
|
||||
import { route } from "@spacebar/api";
|
||||
import {
|
||||
Application,
|
||||
DiscordApiErrors,
|
||||
} from "@spacebar/util";
|
||||
import { Application, DiscordApiErrors } from "@spacebar/util";
|
||||
import { Request, Response, Router } from "express";
|
||||
import { PublicUserProjection } from "@spacebar/schemas";
|
||||
|
||||
@@ -40,9 +37,7 @@ router.get(
|
||||
where: { id: req.params.id }, // ...huh? there's no ID in the path...
|
||||
relations: ["bot", "owner"],
|
||||
select: {
|
||||
owner: Object.fromEntries(
|
||||
PublicUserProjection.map((x) => [x, true]),
|
||||
),
|
||||
owner: Object.fromEntries(PublicUserProjection.map((x) => [x, true])),
|
||||
},
|
||||
});
|
||||
|
||||
@@ -51,8 +46,7 @@ router.get(
|
||||
res.json({
|
||||
...app,
|
||||
owner: app.owner.toPublicUser(),
|
||||
install_params:
|
||||
app.install_params !== null ? app.install_params : undefined,
|
||||
install_params: app.install_params !== null ? app.install_params : undefined,
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
@@ -18,11 +18,7 @@
|
||||
|
||||
import { Request, Response, Router } from "express";
|
||||
import { route } from "@spacebar/api";
|
||||
import {
|
||||
Team,
|
||||
TeamMember,
|
||||
User,
|
||||
} from "@spacebar/util";
|
||||
import { Team, TeamMember, User } from "@spacebar/util";
|
||||
import { HTTPError } from "lambert-server";
|
||||
import { TeamCreateSchema, TeamMemberRole, TeamMemberState } from "@spacebar/schemas";
|
||||
|
||||
@@ -34,8 +30,7 @@ router.get(
|
||||
query: {
|
||||
include_payout_account_status: {
|
||||
type: "boolean",
|
||||
description:
|
||||
"Whether to include team payout account status in the response (default false)",
|
||||
description: "Whether to include team payout account status in the response (default false)",
|
||||
},
|
||||
},
|
||||
responses: {
|
||||
@@ -71,8 +66,7 @@ router.post(
|
||||
where: [{ id: req.user_id }],
|
||||
select: ["mfa_enabled"],
|
||||
});
|
||||
if (!user.mfa_enabled)
|
||||
throw new HTTPError("You must enable MFA to create a team");
|
||||
if (!user.mfa_enabled) throw new HTTPError("You must enable MFA to create a team");
|
||||
|
||||
const body = req.body as TeamCreateSchema;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user