summary refs log tree commit diff
path: root/api/src
diff options
context:
space:
mode:
authorFlam3rboy <34555296+Flam3rboy@users.noreply.github.com>2021-08-27 11:10:42 +0200
committerFlam3rboy <34555296+Flam3rboy@users.noreply.github.com>2021-08-27 11:10:42 +0200
commit0ecc5d8c0e353676e9f5bdbc724bb33572d3b572 (patch)
tree75040e26406762efea9daf7e8475e3834495c462 /api/src
parent:sparkles: use RelationId (diff)
downloadserver-0ecc5d8c0e353676e9f5bdbc724bb33572d3b572.tar.xz
:construction: api
Diffstat (limited to 'api/src')
-rw-r--r--api/src/middlewares/ErrorHandler.ts1
-rw-r--r--api/src/routes/auth/login.ts12
-rw-r--r--api/src/routes/auth/register.ts59
-rw-r--r--api/src/routes/guilds/#guild_id/channels.ts12
-rw-r--r--api/src/routes/guilds/#guild_id/templates.ts60
-rw-r--r--api/src/routes/guilds/templates/index.ts7
-rw-r--r--api/src/routes/invites/index.ts4
-rw-r--r--api/src/routes/users/#id/profile.ts2
-rw-r--r--api/src/routes/users/@me/relationships.ts36
-rw-r--r--api/src/util/Channel.ts2
-rw-r--r--api/src/util/User.ts16
11 files changed, 89 insertions, 122 deletions
diff --git a/api/src/middlewares/ErrorHandler.ts b/api/src/middlewares/ErrorHandler.ts

index d080e498..8e2cd923 100644 --- a/api/src/middlewares/ErrorHandler.ts +++ b/api/src/middlewares/ErrorHandler.ts
@@ -2,6 +2,7 @@ import { NextFunction, Request, Response } from "express"; import { HTTPError } from "lambert-server"; import { FieldError } from "../util/instanceOf"; +// TODO: update with new body/typorm validation export function ErrorHandler(error: Error, req: Request, res: Response, next: NextFunction) { if (!error) next(); diff --git a/api/src/routes/auth/login.ts b/api/src/routes/auth/login.ts
index 579a097e..c0acad4e 100644 --- a/api/src/routes/auth/login.ts +++ b/api/src/routes/auth/login.ts
@@ -21,9 +21,6 @@ router.post( async (req: Request, res: Response) => { const { login, password, captcha_key, undelete } = req.body; const email = adjustEmail(login); - const query: any[] = [{ phone: login }]; - if (email) query.push({ email }); - console.log(req.body, email); const config = Config.get(); @@ -41,11 +38,10 @@ router.post( // TODO: check captcha } - const user = await User.findOneOrFail( - { $or: query }, - { "data.hash": true, id: true, disabled: true, deleted: true, "settings.locale": true, "settings.theme": true } - ).catch((e) => { - console.log(e, query); + const user = await User.findOneOrFail({ + where: [{ phone: login }, { email: login }], + select: ["data", "id", "disabled", "deleted", "settings"] + }).catch((e) => { throw FieldErrors({ login: { message: req.t("auth:login.INVALID_LOGIN"), code: "INVALID_LOGIN" } }); }); diff --git a/api/src/routes/auth/register.ts b/api/src/routes/auth/register.ts
index 1405e219..62b039d5 100644 --- a/api/src/routes/auth/register.ts +++ b/api/src/routes/auth/register.ts
@@ -1,12 +1,12 @@ import { Request, Response, Router } from "express"; -import { trimSpecial, User, Snowflake, User, Config } from "@fosscord/util"; +import { trimSpecial, User, Snowflake, Config } from "@fosscord/util"; import bcrypt from "bcrypt"; import { check, Email, EMAIL_REGEX, FieldErrors, Length } from "../../util/instanceOf"; import "missing-native-js-functions"; import { generateToken } from "./login"; import { getIpAdress, IPAnalysis, isProxy } from "../../util/ipAddress"; import { HTTPError } from "lambert-server"; -import RateLimit from "../../middlewares/RateLimit"; +import { In } from "typeorm"; const router: Router = Router(); @@ -55,13 +55,13 @@ router.post( // TODO: check password strength // adjusted_email will be slightly modified version of the user supplied email -> e.g. protection against GMail Trick - let adjusted_email: string | null = adjustEmail(email); + let adjusted_email = adjustEmail(email); // adjusted_password will be the hash of the password - let adjusted_password: string = ""; + let adjusted_password = ""; // trim special uf8 control characters -> Backspace, Newline, ... - let adjusted_username: string = trimSpecial(username); + let adjusted_username = trimSpecial(username); // discriminator will be randomly generated let discriminator = ""; @@ -129,7 +129,7 @@ router.post( if (!register.allowMultipleAccounts) { // TODO: check if fingerprint was eligible generated - const exists = await User.findOneOrFail({ fingerprints: fingerprint }).catch((e) => {}); + const exists = await User.findOne({ where: { fingerprints: In(fingerprint) } }); if (exists) { throw FieldErrors({ @@ -164,12 +164,8 @@ router.post( // TODO: is there any better way to generate a random discriminator only once, without checking if it already exists in the mongodb database? for (let tries = 0; tries < 5; tries++) { discriminator = Math.randomIntBetween(1, 9999).toString().padStart(4, "0"); - try { - exists = await User.findOneOrFail({ discriminator, username: adjusted_username }, "id"); - } catch (error) { - // doesn't exist -> break - break; - } + exists = await User.findOne({ where: { discriminator, username: adjusted_username }, select: ["id"] }); + if (!exists) break; } if (exists) { @@ -185,35 +181,26 @@ router.post( // appearently discord doesn't save the date of birth and just calculate if nsfw is allowed // if nsfw_allowed is null/undefined it'll require date_of_birth to set it to true/false - const user: User = { + const user = await new User({ id: Snowflake.generate(), created_at: new Date(), username: adjusted_username, discriminator, - avatar: null, - accent_color: null, - banner: null, + avatar: undefined, + accent_color: undefined, + banner: undefined, bot: false, system: false, desktop: false, mobile: false, premium: true, premium_type: 2, - phone: null, + phone: undefined, bio: "", mfa_enabled: false, verified: false, disabled: false, deleted: false, - presence: { - activities: [], - client_status: { - desktop: undefined, - mobile: undefined, - web: undefined - }, - status: "offline" - }, email: adjusted_email, nsfw_allowed: true, // TODO: depending on age public_flags: 0n, @@ -221,10 +208,7 @@ router.post( guilds: [], data: { hash: adjusted_password, - valid_tokens_since: new Date(), - relationships: [], - connected_accounts: [], - fingerprints: [] + valid_tokens_since: new Date() }, settings: { afk_timeout: 300, @@ -234,10 +218,10 @@ router.post( contact_sync_enabled: false, convert_emoticons: false, custom_status: { - emoji_id: null, - emoji_name: null, - expires_at: null, - text: null + emoji_id: undefined, + emoji_name: undefined, + expires_at: undefined, + text: undefined }, default_guilds_restricted: false, detect_platform_accounts: true, @@ -265,16 +249,13 @@ router.post( timezone_offset: 0 // timezone_offset: // TODO: timezone from request } - }; - - // insert user into database - await new User(user).save(); + }).save(); return res.json({ token: await generateToken(user.id) }); } ); -export function adjustEmail(email: string): string | null { +export function adjustEmail(email: string): string | undefined { // body parser already checked if it is a valid email const parts = <RegExpMatchArray>email.match(EMAIL_REGEX); // @ts-ignore diff --git a/api/src/routes/guilds/#guild_id/channels.ts b/api/src/routes/guilds/#guild_id/channels.ts
index b53c9a5a..7b0e94b6 100644 --- a/api/src/routes/guilds/#guild_id/channels.ts +++ b/api/src/routes/guilds/#guild_id/channels.ts
@@ -1,5 +1,5 @@ import { Router, Response, Request } from "express"; -import { Channel, toObject, ChannelUpdateEvent, getPermission, emitEvent } from "@fosscord/util"; +import { Channel, ChannelUpdateEvent, getPermission, emitEvent } from "@fosscord/util"; import { HTTPError } from "lambert-server"; import { ChannelModifySchema } from "../../../schema/Channel"; @@ -48,15 +48,19 @@ router.patch( if (x.parent_id) { opts.parent_id = x.parent_id; - const parent_channel = await Channel.findOneOrFail({ id: x.parent_id, guild_id }, { permission_overwrites: true }); + const parent_channel = await Channel.findOneOrFail({ + where: { id: x.parent_id, guild_id }, + select: ["permission_overwrites"] + }); if (x.lock_permissions) { opts.permission_overwrites = parent_channel.permission_overwrites; } } - const channel = await Channel.findOneOrFailAndUpdate({ id: x.id, guild_id }, opts, { new: true }); + await Channel.update({ guild_id, id: x.id }, opts); + const channel = await Channel.findOneOrFail({ guild_id, id: x.id }); - await emitEvent({ event: "CHANNEL_UPDATE", data: channel), channel_id: x.id, guild_id } as ChannelUpdateEvent; + await emitEvent({ event: "CHANNEL_UPDATE", data: channel, channel_id: x.id, guild_id } as ChannelUpdateEvent); }) ]); diff --git a/api/src/routes/guilds/#guild_id/templates.ts b/api/src/routes/guilds/#guild_id/templates.ts
index 13917dbd..e1d2f5fd 100644 --- a/api/src/routes/guilds/#guild_id/templates.ts +++ b/api/src/routes/guilds/#guild_id/templates.ts
@@ -1,5 +1,5 @@ import { Request, Response, Router } from "express"; -import { TemplateModel, Guild, getPermission, toObject, User, Snowflake } from "@fosscord/util"; +import { Guild, getPermission, Template } from "@fosscord/util"; import { HTTPError } from "lambert-server"; import { TemplateCreateSchema, TemplateModifySchema } from "../../../schema/Template"; import { check } from "../../../util/instanceOf"; @@ -7,22 +7,22 @@ import { generateCode } from "../../../util/String"; const router: Router = Router(); -const TemplateGuildProjection = { - name: true, - description: true, - region: true, - verification_level: true, - default_message_notifications: true, - explicit_content_filter: true, - preferred_locale: true, - afk_timeout: true, - roles: true, - channels: true, - afk_channel_id: true, - system_channel_id: true, - system_channel_flags: true, - icon_hash: true -}; +const TemplateGuildProjection: (keyof Guild)[] = [ + "name", + "description", + "region", + "verification_level", + "default_message_notifications", + "explicit_content_filter", + "preferred_locale", + "afk_timeout", + "roles", + "channels", + "afk_channel_id", + "system_channel_id", + "system_channel_flags", + "icon" +]; router.get("/", async (req: Request, res: Response) => { const { guild_id } = req.params; @@ -34,14 +34,14 @@ router.get("/", async (req: Request, res: Response) => { router.post("/", check(TemplateCreateSchema), async (req: Request, res: Response) => { const { guild_id } = req.params; - const guild = await Guild.findOneOrFail({ id: guild_id }, TemplateGuildProjection); + const guild = await Guild.findOneOrFail({ where: { id: guild_id }, select: TemplateGuildProjection }); const perms = await getPermission(req.user_id, guild_id); perms.hasThrow("MANAGE_GUILD"); const exists = await Template.findOneOrFail({ id: guild_id }).catch((e) => {}); if (exists) throw new HTTPError("Template already exists", 400); - const template = await new TemplateModel({ + const template = await new Template({ ...req.body, code: generateCode(), creator_id: req.user_id, @@ -51,7 +51,7 @@ router.post("/", check(TemplateCreateSchema), async (req: Request, res: Response serialized_source_guild: guild }).save(); - res.json(template)).send(; + res.json(template); }); router.delete("/:code", async (req: Request, res: Response) => { @@ -61,37 +61,39 @@ router.delete("/:code", async (req: Request, res: Response) => { const perms = await getPermission(req.user_id, guild_id); perms.hasThrow("MANAGE_GUILD"); - const template = await Template.findOneOrFailAndDelete({ + const template = await Template.delete({ code }); - res.send(template); + res.json(template); }); router.put("/:code", async (req: Request, res: Response) => { - const guild_id = req.params.guild_id; - const { code } = req.params; + // synchronizes the template + const { code, guild_id } = req.params; - const guild = await Guild.findOneOrFail({ id: guild_id }, TemplateGuildProjection); + const guild = await Guild.findOneOrFail({ where: { id: guild_id }, select: TemplateGuildProjection }); const perms = await getPermission(req.user_id, guild_id); perms.hasThrow("MANAGE_GUILD"); - const template = await Template.findOneOrFailAndUpdate({ code }, { serialized_source_guild: guild }, { new: true }); + const template = await new Template({ code, serialized_source_guild: guild }).save(); - res.json(template)).send(; + res.json(template); }); router.patch("/:code", check(TemplateModifySchema), async (req: Request, res: Response) => { + // updates the template description const { guild_id } = req.params; const { code } = req.params; + const { name, description } = req.body; const perms = await getPermission(req.user_id, guild_id); perms.hasThrow("MANAGE_GUILD"); - const template = await Template.findOneOrFailAndUpdate({ code }, { name: req.body.name, description: req.body.description }, { new: true }); + const template = await new Template({ code, name: name, description: description }).save(); - res.json(template)).send(; + res.json(template); }); export default router; diff --git a/api/src/routes/guilds/templates/index.ts b/api/src/routes/guilds/templates/index.ts
index ad8b676b..b8c1012d 100644 --- a/api/src/routes/guilds/templates/index.ts +++ b/api/src/routes/guilds/templates/index.ts
@@ -1,9 +1,8 @@ import { Request, Response, Router } from "express"; const router: Router = Router(); -import { TemplateModel, Guild, toObject, User, Role, Snowflake, Guild, Config } from "@fosscord/util"; +import { Template, Guild, Role, Snowflake, Config, User } from "@fosscord/util"; import { HTTPError } from "lambert-server"; import { GuildTemplateCreateSchema } from "../../../schema/Guild"; -import { getPublicUser } from "../../../util/User"; import { check } from "../../../util/instanceOf"; import { addMember } from "../../../util/Member"; @@ -12,7 +11,7 @@ router.get("/:code", async (req: Request, res: Response) => { const template = await Template.findOneOrFail({ code: code }); - res.json(template)).send(; + res.json(template); }); router.post("/:code", check(GuildTemplateCreateSchema), async (req: Request, res: Response) => { @@ -20,7 +19,7 @@ router.post("/:code", check(GuildTemplateCreateSchema), async (req: Request, res const body = req.body as GuildTemplateCreateSchema; const { maxGuilds } = Config.get().limits.user; - const user = await getPublicUser(req.user_id, { guilds: true }); + const user = await User.getPublicUser(req.user_id, { guilds: true }); if (user.guilds.length >= maxGuilds) { throw new HTTPError(`Maximum number of guilds reached ${maxGuilds}`, 403); diff --git a/api/src/routes/invites/index.ts b/api/src/routes/invites/index.ts
index e871af86..a488c44b 100644 --- a/api/src/routes/invites/index.ts +++ b/api/src/routes/invites/index.ts
@@ -1,5 +1,5 @@ import { Router, Request, Response } from "express"; -import { getPermission, Guild, InviteModel, toObject } from "@fosscord/util"; +import { getPermission, Guild, Invite } from "@fosscord/util"; import { HTTPError } from "lambert-server"; import { addMember } from "../../util/Member"; const router: Router = Router(); @@ -40,7 +40,7 @@ router.delete("/:code", async (req: Request, res: Response) => { await Guild.update({ vanity_url_code: code }, { $unset: { vanity_url_code: 1 } }).catch((e) => {}); - res.status(200).send({ invite: invite) }; + res.json({ invite: invite }); }); export default router; diff --git a/api/src/routes/users/#id/profile.ts b/api/src/routes/users/#id/profile.ts
index 46c96698..9b2e2d5e 100644 --- a/api/src/routes/users/#id/profile.ts +++ b/api/src/routes/users/#id/profile.ts
@@ -7,7 +7,7 @@ router.get("/", async (req: Request, res: Response) => { const user = await getPublicUser(req.params.id, { data: true }); res.json({ - connected_accounts: user.data.connected_accounts, + connected_accounts: user.connected_accounts, premium_guild_since: null, // TODO premium_since: null, // TODO user: { diff --git a/api/src/routes/users/@me/relationships.ts b/api/src/routes/users/@me/relationships.ts
index 9b8d6199..8c7469ed 100644 --- a/api/src/routes/users/@me/relationships.ts +++ b/api/src/routes/users/@me/relationships.ts
@@ -15,14 +15,14 @@ import { check, Length } from "../../../util/instanceOf"; const router = Router(); -const userProjection = { "user_data.relationships": true, ...PublicUserProjection }; +const userProjection = { "data.relationships": true, ...PublicUserProjection }; router.get("/", async (req: Request, res: Response) => { - const user = await User.findOneOrFail({ id: req.user_id }, { user_data: { relationships: true } }).populate({ - path: "user_data.relationships.id", + const user = await User.findOneOrFail({ id: req.user_id }, { data: { relationships: true } }).populate({ + path: "data.relationships.id", model: User }); - return res.json(user.user_data.relationships); + return res.json(user.data.relationships); }); async function addRelationship(req: Request, res: Response, friend: UserDocument, type: RelationshipType) { @@ -30,8 +30,8 @@ async function addRelationship(req: Request, res: Response, friend: UserDocument if (id === req.user_id) throw new HTTPError("You can't add yourself as a friend"); const user = await User.findOneOrFail({ id: req.user_id }, userProjection); - const newUserRelationships = [...user.user_data.relationships]; - const newFriendRelationships = [...friend.user_data.relationships]; + const newUserRelationships = [...user.data.relationships]; + const newFriendRelationships = [...friend.data.relationships]; var relationship = newUserRelationships.find((x) => x.id === id); const friendRequest = newFriendRelationships.find((x) => x.id === req.user_id); @@ -48,7 +48,7 @@ async function addRelationship(req: Request, res: Response, friend: UserDocument if (friendRequest && friendRequest.type !== RelationshipType.blocked) { newFriendRelationships.remove(friendRequest); await Promise.all([ - User.update({ id: friend.id }, { "user_data.relationships": newFriendRelationships }), + User.update({ id: friend.id }, { "data.relationships": newFriendRelationships }), emitEvent({ event: "RELATIONSHIP_REMOVE", data: friendRequest, @@ -58,12 +58,12 @@ async function addRelationship(req: Request, res: Response, friend: UserDocument } await Promise.all([ - User.update({ id: req.user_id }, { "user_data.relationships": newUserRelationships }), + User.update({ id: req.user_id }, { "data.relationships": newUserRelationships }), emitEvent({ event: "RELATIONSHIP_ADD", data: { ...relationship, - user: { ...friend, user_data: undefined } + user: { ...friend, data: undefined } }, user_id: req.user_id } as RelationshipAddEvent) @@ -91,13 +91,13 @@ async function addRelationship(req: Request, res: Response, friend: UserDocument } else newUserRelationships.push(outgoing_relationship); await Promise.all([ - User.update({ id: req.user_id }, { "user_data.relationships": newUserRelationships }), - User.update({ id: friend.id }, { "user_data.relationships": newFriendRelationships }), + User.update({ id: req.user_id }, { "data.relationships": newUserRelationships }), + User.update({ id: friend.id }, { "data.relationships": newFriendRelationships }), emitEvent({ event: "RELATIONSHIP_ADD", data: { ...outgoing_relationship, - user: { ...friend, user_data: undefined } + user: { ...friend, data: undefined } }, user_id: req.user_id } as RelationshipAddEvent), @@ -106,7 +106,7 @@ async function addRelationship(req: Request, res: Response, friend: UserDocument data: { ...incoming_relationship, should_notify: true, - user: { ...user, user_data: undefined } + user: { ...user, data: undefined } }, user_id: id } as RelationshipAddEvent) @@ -138,11 +138,11 @@ router.delete("/:id", async (req: Request, res: Response) => { const friend = await User.findOneOrFail({ id }, userProjection); if (!friend) throw new HTTPError("User not found", 404); - const relationship = user.user_data.relationships.find((x) => x.id === id); - const friendRequest = friend.user_data.relationships.find((x) => x.id === req.user_id); + const relationship = user.data.relationships.find((x) => x.id === id); + const friendRequest = friend.data.relationships.find((x) => x.id === req.user_id); if (relationship?.type === RelationshipType.blocked) { // unblock user - user.user_data.relationships.remove(relationship); + user.data.relationships.remove(relationship); await Promise.all([ user.save(), @@ -153,8 +153,8 @@ router.delete("/:id", async (req: Request, res: Response) => { if (!relationship || !friendRequest) throw new HTTPError("You are not friends with the user", 404); if (friendRequest.type === RelationshipType.blocked) throw new HTTPError("The user blocked you"); - user.user_data.relationships.remove(relationship); - friend.user_data.relationships.remove(friendRequest); + user.data.relationships.remove(relationship); + friend.data.relationships.remove(friendRequest); await Promise.all([ user.save(), diff --git a/api/src/util/Channel.ts b/api/src/util/Channel.ts
index a618d2df..f518aefd 100644 --- a/api/src/util/Channel.ts +++ b/api/src/util/Channel.ts
@@ -57,7 +57,7 @@ export async function createChannel( recipient_ids: null }).save(); - await emitEvent({ event: "CHANNEL_CREATE", data: channel), guild_id: channel.guild_id } as ChannelCreateEvent; + await emitEvent({ event: "CHANNEL_CREATE", data: channel, guild_id: channel.guild_id } as ChannelCreateEvent); return channel; } diff --git a/api/src/util/User.ts b/api/src/util/User.ts deleted file mode 100644
index 4d9065c4..00000000 --- a/api/src/util/User.ts +++ /dev/null
@@ -1,16 +0,0 @@ -import { toObject, User, PublicUserProjection } from "@fosscord/util"; -import { HTTPError } from "lambert-server"; - -export { PublicUserProjection }; - -export async function getPublicUser(user_id: string, additional_fields?: any) { - const user = await User.findOneOrFail( - { id: user_id }, - { - ...PublicUserProjection, - ...additional_fields - } - ); - if (!user) throw new HTTPError("User not found", 404); - return user; -}