diff --git a/api/src/routes/users/#id/index.ts b/api/src/routes/users/#id/index.ts
index 3841756b..bdb1060f 100644
--- a/api/src/routes/users/#id/index.ts
+++ b/api/src/routes/users/#id/index.ts
@@ -1,9 +1,10 @@
import { Router, Request, Response } from "express";
-import { User } from "../../../../../util/dist";
+import { User } from "@fosscord/util";
+import { route } from "@fosscord/api";
const router: Router = Router();
-router.get("/", async (req: Request, res: Response) => {
+router.get("/", route({}), async (req: Request, res: Response) => {
const { id } = req.params;
res.json(await User.getPublicUser(id));
diff --git a/api/src/routes/users/#id/profile.ts b/api/src/routes/users/#id/profile.ts
index 8be03b47..d60c4f86 100644
--- a/api/src/routes/users/#id/profile.ts
+++ b/api/src/routes/users/#id/profile.ts
@@ -1,9 +1,17 @@
import { Router, Request, Response } from "express";
-import { PublicConnectedAccount, PublicUser, User, UserPublic } from "../../../../../util/dist";
+import { PublicConnectedAccount, PublicUser, User, UserPublic } from "@fosscord/util";
+import { route } from "@fosscord/api";
const router: Router = Router();
-router.get("/", async (req: Request, res: Response) => {
+export interface UserProfileResponse {
+ user: UserPublic;
+ connected_accounts: PublicConnectedAccount;
+ premium_guild_since?: Date;
+ premium_since?: Date;
+}
+
+router.get("/", route({ response: { body: "UserProfileResponse" } }), async (req: Request, res: Response) => {
if (req.params.id === "@me") req.params.id = req.user_id;
const user = await User.getPublicUser(req.params.id, { relations: ["connected_accounts"] });
@@ -25,11 +33,4 @@ router.get("/", async (req: Request, res: Response) => {
});
});
-export interface UserProfileResponse {
- user: UserPublic;
- connected_accounts: PublicConnectedAccount;
- premium_guild_since?: Date;
- premium_since?: Date;
-}
-
export default router;
diff --git a/api/src/routes/users/@me/affinities/guilds.ts b/api/src/routes/users/@me/affinities/guilds.ts
index fa6be0e7..8d744744 100644
--- a/api/src/routes/users/@me/affinities/guilds.ts
+++ b/api/src/routes/users/@me/affinities/guilds.ts
@@ -1,8 +1,9 @@
import { Router, Response, Request } from "express";
+import { route } from "@fosscord/api";
const router = Router();
-router.get("/", (req: Request, res: Response) => {
+router.get("/", route({}), (req: Request, res: Response) => {
// TODO:
res.status(200).send({ guild_affinities: [] });
});
diff --git a/api/src/routes/users/@me/affinities/users.ts b/api/src/routes/users/@me/affinities/users.ts
index db67ab71..6d4e4991 100644
--- a/api/src/routes/users/@me/affinities/users.ts
+++ b/api/src/routes/users/@me/affinities/users.ts
@@ -1,9 +1,10 @@
import { Router, Response, Request } from "express";
+import { route } from "@fosscord/api";
const router = Router();
-router.get("/", (req: Request, res: Response) => {
- //TODO
+router.get("/", route({}), (req: Request, res: Response) => {
+ // TODO:
res.status(200).send({ user_affinities: [], inverse_user_affinities: [] });
});
diff --git a/api/src/routes/users/@me/channels.ts b/api/src/routes/users/@me/channels.ts
index 6fd396b8..5515a217 100644
--- a/api/src/routes/users/@me/channels.ts
+++ b/api/src/routes/users/@me/channels.ts
@@ -1,21 +1,23 @@
import { Router, Request, Response } from "express";
-import { Channel, ChannelCreateEvent, ChannelType, Snowflake, trimSpecial, User, emitEvent } from "@fosscord/util";
+import { Channel, ChannelCreateEvent, ChannelType, Snowflake, trimSpecial, User, emitEvent, Recipient } from "@fosscord/util";
import { HTTPError } from "lambert-server";
-
-import { DmChannelCreateSchema } from "../../../schema/Channel";
-import { check } from "../../../util/instanceOf";
+import { route } from "@fosscord/api";
import { In } from "typeorm";
-import { Recipient } from "../../../../../util/dist/entities/Recipient";
+
+export interface DmChannelCreateSchema {
+ name?: string;
+ recipients: string[];
+}
const router: Router = Router();
-router.get("/", async (req: Request, res: Response) => {
+router.get("/", route({}), async (req: Request, res: Response) => {
const recipients = await Recipient.find({ where: { user_id: req.user_id }, relations: ["channel"] });
res.json(recipients.map((x) => x.channel));
});
-router.post("/", check(DmChannelCreateSchema), async (req: Request, res: Response) => {
+router.post("/", route({ body: "DmChannelCreateSchema" }), async (req: Request, res: Response) => {
const body = req.body as DmChannelCreateSchema;
body.recipients = body.recipients.filter((x) => x !== req.user_id).unique();
diff --git a/api/src/routes/users/@me/delete.ts b/api/src/routes/users/@me/delete.ts
index e5fda948..39ceefd9 100644
--- a/api/src/routes/users/@me/delete.ts
+++ b/api/src/routes/users/@me/delete.ts
@@ -1,10 +1,12 @@
import { Router, Request, Response } from "express";
import { Guild, Member, User } from "@fosscord/util";
+import { route } from "@fosscord/api";
import bcrypt from "bcrypt";
import { HTTPError } from "lambert-server";
+
const router = Router();
-router.post("/", async (req: Request, res: Response) => {
+router.post("/", route({}), async (req: Request, res: Response) => {
const user = await User.findOneOrFail({ id: req.user_id }); //User object
let correctpass = true;
diff --git a/api/src/routes/users/@me/devices.ts b/api/src/routes/users/@me/devices.ts
index b16ef783..8556a3ad 100644
--- a/api/src/routes/users/@me/devices.ts
+++ b/api/src/routes/users/@me/devices.ts
@@ -1,8 +1,9 @@
import { Router, Response, Request } from "express";
+import { route } from "@fosscord/api";
const router = Router();
-router.post("/", (req: Request, res: Response) => {
+router.post("/", route({}), (req: Request, res: Response) => {
// TODO:
res.sendStatus(204);
});
diff --git a/api/src/routes/users/@me/disable.ts b/api/src/routes/users/@me/disable.ts
index 7b8a130c..259ced96 100644
--- a/api/src/routes/users/@me/disable.ts
+++ b/api/src/routes/users/@me/disable.ts
@@ -1,10 +1,11 @@
import { User } from "@fosscord/util";
import { Router, Response, Request } from "express";
+import { route } from "@fosscord/api";
import bcrypt from "bcrypt";
const router = Router();
-router.post("/", async (req: Request, res: Response) => {
+router.post("/", route({}), async (req: Request, res: Response) => {
const user = await User.findOneOrFail({ id: req.user_id }); //User object
let correctpass = true;
diff --git a/api/src/routes/users/@me/guilds.ts b/api/src/routes/users/@me/guilds.ts
index fb88281b..4ba03cec 100644
--- a/api/src/routes/users/@me/guilds.ts
+++ b/api/src/routes/users/@me/guilds.ts
@@ -1,18 +1,18 @@
import { Router, Request, Response } from "express";
import { Guild, Member, User, GuildDeleteEvent, GuildMemberRemoveEvent, emitEvent } from "@fosscord/util";
import { HTTPError } from "lambert-server";
-import { In } from "typeorm";
+import { route } from "@fosscord/api";
const router: Router = Router();
-router.get("/", async (req: Request, res: Response) => {
+router.get("/", route({}), async (req: Request, res: Response) => {
const members = await Member.find({ relations: ["guild"], where: { id: req.user_id } });
res.json(members.map((x) => x.guild));
});
// user send to leave a certain guild
-router.delete("/:id", async (req: Request, res: Response) => {
+router.delete("/:id", route({}), async (req: Request, res: Response) => {
const guild_id = req.params.id;
const guild = await Guild.findOneOrFail({ where: { id: guild_id }, select: ["owner_id"] });
diff --git a/api/src/routes/users/@me/index.ts b/api/src/routes/users/@me/index.ts
index 68649215..68723374 100644
--- a/api/src/routes/users/@me/index.ts
+++ b/api/src/routes/users/@me/index.ts
@@ -1,16 +1,33 @@
import { Router, Request, Response } from "express";
import { User, PrivateUserProjection } from "@fosscord/util";
-import { UserModifySchema } from "../../../schema/User";
-import { check } from "../../../util/instanceOf";
-import { handleFile } from "../../../util/cdn";
+import { check, route } from "@fosscord/api";
+import { handleFile } from "@fosscord/api";
const router: Router = Router();
+export interface UserModifySchema {
+ /**
+ * @minLength 1
+ * @maxLength 100
+ */
+ username?: string;
+ avatar?: string | null;
+ /**
+ * @maxLength 1024
+ */
+ bio?: string;
+ accent_color?: number | null;
+ banner?: string | null;
+ password?: string;
+ new_password?: string;
+ code?: string;
+}
+
router.get("/", async (req: Request, res: Response) => {
- res.json(await User.getPublicUser(req.user_id, { select: PrivateUserProjection }));
+ res.json(await User.findOne({ select: PrivateUserProjection, where: { id: req.user_id } }));
});
-router.patch("/", check(UserModifySchema), async (req: Request, res: Response) => {
+router.patch("/", route({ body: "UserModifySchema" }), async (req: Request, res: Response) => {
const body = req.body as UserModifySchema;
if (body.avatar) body.avatar = await handleFile(`/avatars/${req.user_id}`, body.avatar as string);
diff --git a/api/src/routes/users/@me/library.ts b/api/src/routes/users/@me/library.ts
index d771cb5e..7ac13bae 100644
--- a/api/src/routes/users/@me/library.ts
+++ b/api/src/routes/users/@me/library.ts
@@ -1,8 +1,9 @@
import { Router, Response, Request } from "express";
+import { route } from "@fosscord/api";
const router = Router();
-router.get("/", (req: Request, res: Response) => {
+router.get("/", route({}), (req: Request, res: Response) => {
// TODO:
res.status(200).send([]);
});
diff --git a/api/src/routes/users/@me/relationships.ts b/api/src/routes/users/@me/relationships.ts
index 995b0244..cc264f3f 100644
--- a/api/src/routes/users/@me/relationships.ts
+++ b/api/src/routes/users/@me/relationships.ts
@@ -11,19 +11,95 @@ import {
import { Router, Response, Request } from "express";
import { HTTPError } from "lambert-server";
import { DiscordApiErrors } from "@fosscord/util";
-
-import { check, Length } from "../../../util/instanceOf";
+import { route } from "@fosscord/api";
const router = Router();
const userProjection: (keyof User)[] = ["relationships", ...PublicUserProjection];
-router.get("/", async (req: Request, res: Response) => {
+router.get("/", route({}), async (req: Request, res: Response) => {
const user = await User.findOneOrFail({ where: { id: req.user_id }, relations: ["relationships"] });
return res.json(user.relationships);
});
+export interface RelationshipPutSchema {
+ type: RelationshipType;
+}
+
+router.put("/:id", route({ body: "RelationshipPutSchema" }), async (req: Request, res: Response) => {
+ return await updateRelationship(
+ req,
+ res,
+ await User.findOneOrFail({ id: req.params.id }, { relations: ["relationships"], select: userProjection }),
+ req.body.type
+ );
+});
+
+export interface RelationshipPostSchema {
+ discriminator: string;
+ username: string;
+}
+
+router.post("/", route({ body: "RelationshipPostSchema" }), async (req: Request, res: Response) => {
+ return await updateRelationship(
+ req,
+ res,
+ await User.findOneOrFail({
+ relations: ["relationships"],
+ select: userProjection,
+ where: req.body as { discriminator: string; username: string }
+ }),
+ req.body.type
+ );
+});
+
+router.delete("/:id", route({}), async (req: Request, res: Response) => {
+ const { id } = req.params;
+ if (id === req.user_id) throw new HTTPError("You can't remove yourself as a friend");
+
+ const user = await User.findOneOrFail({ id: req.user_id }, { select: userProjection, relations: ["relationships"] });
+ const friend = await User.findOneOrFail({ id: id }, { select: userProjection, relations: ["relationships"] });
+
+ const relationship = user.relationships.find((x) => x.id === id);
+ const friendRequest = friend.relationships.find((x) => x.id === req.user_id);
+
+ if (relationship?.type === RelationshipType.blocked) {
+ // unblock user
+ user.relationships.remove(relationship);
+
+ await Promise.all([
+ user.save(),
+ emitEvent({ event: "RELATIONSHIP_REMOVE", user_id: req.user_id, data: relationship } as RelationshipRemoveEvent)
+ ]);
+ return res.sendStatus(204);
+ }
+ 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.relationships.remove(relationship);
+ friend.relationships.remove(friendRequest);
+
+ await Promise.all([
+ user.save(),
+ friend.save(),
+ emitEvent({
+ event: "RELATIONSHIP_REMOVE",
+ data: relationship,
+ user_id: req.user_id
+ } as RelationshipRemoveEvent),
+ emitEvent({
+ event: "RELATIONSHIP_REMOVE",
+ data: friendRequest,
+ user_id: id
+ } as RelationshipRemoveEvent)
+ ]);
+
+ return res.sendStatus(204);
+});
+
+export default router;
+
async function updateRelationship(req: Request, res: Response, friend: User, type: RelationshipType) {
const id = friend.id;
if (id === req.user_id) throw new HTTPError("You can't add yourself as a friend");
@@ -114,71 +190,3 @@ async function updateRelationship(req: Request, res: Response, friend: User, typ
return res.sendStatus(204);
}
-
-router.put("/:id", check({ $type: new Length(Number, 1, 4) }), async (req: Request, res: Response) => {
- return await updateRelationship(
- req,
- res,
- await User.findOneOrFail({ id: req.params.id }, { relations: ["relationships"], select: userProjection }),
- req.body.type
- );
-});
-
-router.post("/", check({ discriminator: String, username: String }), async (req: Request, res: Response) => {
- return await updateRelationship(
- req,
- res,
- await User.findOneOrFail({
- relations: ["relationships"],
- select: userProjection,
- where: req.body as { discriminator: string; username: string }
- }),
- req.body.type
- );
-});
-
-router.delete("/:id", async (req: Request, res: Response) => {
- const { id } = req.params;
- if (id === req.user_id) throw new HTTPError("You can't remove yourself as a friend");
-
- const user = await User.findOneOrFail({ id: req.user_id }, { select: userProjection, relations: ["relationships"] });
- const friend = await User.findOneOrFail({ id: id }, { select: userProjection, relations: ["relationships"] });
-
- const relationship = user.relationships.find((x) => x.id === id);
- const friendRequest = friend.relationships.find((x) => x.id === req.user_id);
-
- if (relationship?.type === RelationshipType.blocked) {
- // unblock user
- user.relationships.remove(relationship);
-
- await Promise.all([
- user.save(),
- emitEvent({ event: "RELATIONSHIP_REMOVE", user_id: req.user_id, data: relationship } as RelationshipRemoveEvent)
- ]);
- return res.sendStatus(204);
- }
- 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.relationships.remove(relationship);
- friend.relationships.remove(friendRequest);
-
- await Promise.all([
- user.save(),
- friend.save(),
- emitEvent({
- event: "RELATIONSHIP_REMOVE",
- data: relationship,
- user_id: req.user_id
- } as RelationshipRemoveEvent),
- emitEvent({
- event: "RELATIONSHIP_REMOVE",
- data: friendRequest,
- user_id: id
- } as RelationshipRemoveEvent)
- ]);
-
- return res.sendStatus(204);
-});
-
-export default router;
diff --git a/api/src/routes/users/@me/settings.ts b/api/src/routes/users/@me/settings.ts
index 90ee6372..9d7a2545 100644
--- a/api/src/routes/users/@me/settings.ts
+++ b/api/src/routes/users/@me/settings.ts
@@ -1,11 +1,12 @@
import { Router, Response, Request } from "express";
import { User, UserSettings } from "@fosscord/util";
-import { check } from "../../../util/instanceOf";
-import { UserSettingsSchema } from "../../../schema/User";
+import { route } from "@fosscord/api";
const router = Router();
-router.patch("/", check(UserSettingsSchema), async (req: Request, res: Response) => {
+export interface UserSettingsSchema extends UserSettings {}
+
+router.patch("/", route({ body: "UserSettingsSchema" }), async (req: Request, res: Response) => {
const body = req.body as UserSettings;
// only users can update user settings
|