diff --git a/src/api/routes/users/@me/channels.ts b/src/api/routes/users/@me/channels.ts
index 04db4fe9..8a8fadd9 100644
--- a/src/api/routes/users/@me/channels.ts
+++ b/src/api/routes/users/@me/channels.ts
@@ -16,32 +16,51 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-import { Request, Response, Router } from "express";
+import { route } from "@spacebar/api";
import {
- Recipient,
- DmChannelDTO,
Channel,
DmChannelCreateSchema,
+ DmChannelDTO,
+ Recipient,
} from "@spacebar/util";
-import { route } from "@spacebar/api";
+import { Request, Response, Router } from "express";
const router: Router = Router();
-router.get("/", route({}), async (req: Request, res: Response) => {
- const recipients = await Recipient.find({
- where: { user_id: req.user_id, closed: false },
- relations: ["channel", "channel.recipients"],
- });
- res.json(
- await Promise.all(
- recipients.map((r) => DmChannelDTO.from(r.channel, [req.user_id])),
- ),
- );
-});
+router.get(
+ "/",
+ route({
+ responses: {
+ 200: {
+ body: "APIDMChannelArray",
+ },
+ },
+ }),
+ async (req: Request, res: Response) => {
+ const recipients = await Recipient.find({
+ where: { user_id: req.user_id, closed: false },
+ relations: ["channel", "channel.recipients"],
+ });
+ res.json(
+ await Promise.all(
+ recipients.map((r) =>
+ DmChannelDTO.from(r.channel, [req.user_id]),
+ ),
+ ),
+ );
+ },
+);
router.post(
"/",
- route({ body: "DmChannelCreateSchema" }),
+ route({
+ requestBody: "DmChannelCreateSchema",
+ responses: {
+ 200: {
+ body: "DmChannelDTO",
+ },
+ },
+ }),
async (req: Request, res: Response) => {
const body = req.body as DmChannelCreateSchema;
res.json(
diff --git a/src/api/routes/users/@me/connections/#connection_name/#connection_id/index.ts b/src/api/routes/users/@me/connections/#connection_name/#connection_id/index.ts
index 3a4e5e0a..351ec99a 100644
--- a/src/api/routes/users/@me/connections/#connection_name/#connection_id/index.ts
+++ b/src/api/routes/users/@me/connections/#connection_name/#connection_id/index.ts
@@ -29,7 +29,7 @@ const router = Router();
// TODO: connection update schema
router.patch(
"/",
- route({ body: "ConnectionUpdateSchema" }),
+ route({ requestBody: "ConnectionUpdateSchema" }),
async (req: Request, res: Response) => {
const { connection_name, connection_id } = req.params;
const body = req.body as ConnectionUpdateSchema;
diff --git a/src/api/routes/users/@me/delete.ts b/src/api/routes/users/@me/delete.ts
index dce737fc..e36a1e92 100644
--- a/src/api/routes/users/@me/delete.ts
+++ b/src/api/routes/users/@me/delete.ts
@@ -16,41 +16,58 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-import { Router, Request, Response } from "express";
-import { Member, User } from "@spacebar/util";
import { route } from "@spacebar/api";
+import { Member, User } from "@spacebar/util";
import bcrypt from "bcrypt";
+import { Request, Response, Router } from "express";
import { HTTPError } from "lambert-server";
const router = Router();
-router.post("/", route({}), async (req: Request, res: Response) => {
- const user = await User.findOneOrFail({
- where: { id: req.user_id },
- select: ["data"],
- }); //User object
- let correctpass = true;
-
- if (user.data.hash) {
- // guest accounts can delete accounts without password
- correctpass = await bcrypt.compare(req.body.password, user.data.hash);
- if (!correctpass) {
- throw new HTTPError(req.t("auth:login.INVALID_PASSWORD"));
+router.post(
+ "/",
+ route({
+ responses: {
+ 204: {},
+ 401: {
+ body: "APIErrorResponse",
+ },
+ 404: {
+ body: "APIErrorResponse",
+ },
+ },
+ }),
+ async (req: Request, res: Response) => {
+ const user = await User.findOneOrFail({
+ where: { id: req.user_id },
+ select: ["data"],
+ }); //User object
+ let correctpass = true;
+
+ if (user.data.hash) {
+ // guest accounts can delete accounts without password
+ correctpass = await bcrypt.compare(
+ req.body.password,
+ user.data.hash,
+ );
+ if (!correctpass) {
+ throw new HTTPError(req.t("auth:login.INVALID_PASSWORD"));
+ }
}
- }
- // TODO: decrement guild member count
+ // TODO: decrement guild member count
- if (correctpass) {
- await Promise.all([
- User.delete({ id: req.user_id }),
- Member.delete({ id: req.user_id }),
- ]);
+ if (correctpass) {
+ await Promise.all([
+ User.delete({ id: req.user_id }),
+ Member.delete({ id: req.user_id }),
+ ]);
- res.sendStatus(204);
- } else {
- res.sendStatus(401);
- }
-});
+ res.sendStatus(204);
+ } else {
+ res.sendStatus(401);
+ }
+ },
+);
export default router;
diff --git a/src/api/routes/users/@me/disable.ts b/src/api/routes/users/@me/disable.ts
index d123a6a1..b4d03e62 100644
--- a/src/api/routes/users/@me/disable.ts
+++ b/src/api/routes/users/@me/disable.ts
@@ -16,35 +16,52 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-import { User } from "@spacebar/util";
-import { Router, Response, Request } from "express";
import { route } from "@spacebar/api";
+import { User } from "@spacebar/util";
import bcrypt from "bcrypt";
+import { Request, Response, Router } from "express";
const router = Router();
-router.post("/", route({}), async (req: Request, res: Response) => {
- const user = await User.findOneOrFail({
- where: { id: req.user_id },
- select: ["data"],
- }); //User object
- let correctpass = true;
+router.post(
+ "/",
+ route({
+ responses: {
+ 204: {},
+ 400: {
+ body: "APIErrorResponse",
+ },
+ 404: {
+ body: "APIErrorResponse",
+ },
+ },
+ }),
+ async (req: Request, res: Response) => {
+ const user = await User.findOneOrFail({
+ where: { id: req.user_id },
+ select: ["data"],
+ }); //User object
+ let correctpass = true;
- if (user.data.hash) {
- // guest accounts can delete accounts without password
- correctpass = await bcrypt.compare(req.body.password, user.data.hash); //Not sure if user typed right password :/
- }
+ if (user.data.hash) {
+ // guest accounts can delete accounts without password
+ correctpass = await bcrypt.compare(
+ req.body.password,
+ user.data.hash,
+ ); //Not sure if user typed right password :/
+ }
- if (correctpass) {
- await User.update({ id: req.user_id }, { disabled: true });
+ if (correctpass) {
+ await User.update({ id: req.user_id }, { disabled: true });
- res.sendStatus(204);
- } else {
- res.status(400).json({
- message: "Password does not match",
- code: 50018,
- });
- }
-});
+ res.sendStatus(204);
+ } else {
+ res.status(400).json({
+ message: "Password does not match",
+ code: 50018,
+ });
+ }
+ },
+);
export default router;
diff --git a/src/api/routes/users/@me/guilds.ts b/src/api/routes/users/@me/guilds.ts
index b16b909d..0bce432b 100644
--- a/src/api/routes/users/@me/guilds.ts
+++ b/src/api/routes/users/@me/guilds.ts
@@ -16,79 +16,106 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-import { Router, Request, Response } from "express";
+import { route } from "@spacebar/api";
import {
+ Config,
Guild,
- Member,
- User,
GuildDeleteEvent,
GuildMemberRemoveEvent,
+ Member,
+ User,
emitEvent,
- Config,
} from "@spacebar/util";
+import { Request, Response, Router } from "express";
import { HTTPError } from "lambert-server";
-import { route } from "@spacebar/api";
const router: Router = Router();
-router.get("/", route({}), async (req: Request, res: Response) => {
- const members = await Member.find({
- relations: ["guild"],
- where: { id: req.user_id },
- });
+router.get(
+ "/",
+ route({
+ responses: {
+ 200: {
+ body: "APIGuildArray",
+ },
+ },
+ }),
+ async (req: Request, res: Response) => {
+ const members = await Member.find({
+ relations: ["guild"],
+ where: { id: req.user_id },
+ });
- let guild = members.map((x) => x.guild);
+ let guild = members.map((x) => x.guild);
- if ("with_counts" in req.query && req.query.with_counts == "true") {
- guild = []; // TODO: Load guilds with user role permissions number
- }
+ if ("with_counts" in req.query && req.query.with_counts == "true") {
+ guild = []; // TODO: Load guilds with user role permissions number
+ }
- res.json(guild);
-});
+ res.json(guild);
+ },
+);
// user send to leave a certain guild
-router.delete("/:guild_id", route({}), async (req: Request, res: Response) => {
- const { autoJoin } = Config.get().guild;
- const { guild_id } = req.params;
- const guild = await Guild.findOneOrFail({
- where: { id: guild_id },
- select: ["owner_id"],
- });
+router.delete(
+ "/:guild_id",
+ route({
+ responses: {
+ 204: {},
+ 400: {
+ body: "APIErrorResponse",
+ },
+ 404: {
+ body: "APIErrorResponse",
+ },
+ },
+ }),
+ async (req: Request, res: Response) => {
+ const { autoJoin } = Config.get().guild;
+ const { guild_id } = req.params;
+ const guild = await Guild.findOneOrFail({
+ where: { id: guild_id },
+ select: ["owner_id"],
+ });
- if (!guild) throw new HTTPError("Guild doesn't exist", 404);
- if (guild.owner_id === req.user_id)
- throw new HTTPError("You can't leave your own guild", 400);
- if (
- autoJoin.enabled &&
- autoJoin.guilds.includes(guild_id) &&
- !autoJoin.canLeave
- ) {
- throw new HTTPError("You can't leave instance auto join guilds", 400);
- }
+ if (!guild) throw new HTTPError("Guild doesn't exist", 404);
+ if (guild.owner_id === req.user_id)
+ throw new HTTPError("You can't leave your own guild", 400);
+ if (
+ autoJoin.enabled &&
+ autoJoin.guilds.includes(guild_id) &&
+ !autoJoin.canLeave
+ ) {
+ throw new HTTPError(
+ "You can't leave instance auto join guilds",
+ 400,
+ );
+ }
- await Promise.all([
- Member.delete({ id: req.user_id, guild_id: guild_id }),
- emitEvent({
- event: "GUILD_DELETE",
- data: {
- id: guild_id,
- },
- user_id: req.user_id,
- } as GuildDeleteEvent),
- ]);
+ await Promise.all([
+ Member.delete({ id: req.user_id, guild_id: guild_id }),
+ emitEvent({
+ event: "GUILD_DELETE",
+ data: {
+ id: guild_id,
+ },
+ user_id: req.user_id,
+ } as GuildDeleteEvent),
+ ]);
- const user = await User.getPublicUser(req.user_id);
+ const user = await User.getPublicUser(req.user_id);
- await emitEvent({
- event: "GUILD_MEMBER_REMOVE",
- data: {
+ await emitEvent({
+ event: "GUILD_MEMBER_REMOVE",
+ data: {
+ guild_id: guild_id,
+ user: user,
+ },
guild_id: guild_id,
- user: user,
- },
- guild_id: guild_id,
- } as GuildMemberRemoveEvent);
+ } as GuildMemberRemoveEvent);
- return res.sendStatus(204);
-});
+ return res.sendStatus(204);
+ },
+);
export default router;
diff --git a/src/api/routes/users/@me/guilds/#guild_id/settings.ts b/src/api/routes/users/@me/guilds/#guild_id/settings.ts
index 7e9f2a08..ac6586ce 100644
--- a/src/api/routes/users/@me/guilds/#guild_id/settings.ts
+++ b/src/api/routes/users/@me/guilds/#guild_id/settings.ts
@@ -16,29 +16,49 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-import { Router, Response, Request } from "express";
+import { route } from "@spacebar/api";
import {
Channel,
Member,
OrmUtils,
UserGuildSettingsSchema,
} from "@spacebar/util";
-import { route } from "@spacebar/api";
+import { Request, Response, Router } from "express";
const router = Router();
// GET doesn't exist on discord.com
-router.get("/", route({}), async (req: Request, res: Response) => {
- const user = await Member.findOneOrFail({
- where: { id: req.user_id, guild_id: req.params.guild_id },
- select: ["settings"],
- });
- return res.json(user.settings);
-});
+router.get(
+ "/",
+ route({
+ responses: {
+ 200: {},
+ 404: {},
+ },
+ }),
+ async (req: Request, res: Response) => {
+ const user = await Member.findOneOrFail({
+ where: { id: req.user_id, guild_id: req.params.guild_id },
+ select: ["settings"],
+ });
+ return res.json(user.settings);
+ },
+);
router.patch(
"/",
- route({ body: "UserGuildSettingsSchema" }),
+ route({
+ requestBody: "UserGuildSettingsSchema",
+ responses: {
+ 200: {},
+ 400: {
+ body: "APIErrorResponse",
+ },
+ 404: {
+ body: "APIErrorResponse",
+ },
+ },
+ }),
async (req: Request, res: Response) => {
const body = req.body as UserGuildSettingsSchema;
diff --git a/src/api/routes/users/@me/index.ts b/src/api/routes/users/@me/index.ts
index b3eeb964..8fe86265 100644
--- a/src/api/routes/users/@me/index.ts
+++ b/src/api/routes/users/@me/index.ts
@@ -16,36 +16,59 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-import { Router, Request, Response } from "express";
+import { route } from "@spacebar/api";
import {
- User,
- PrivateUserProjection,
- emitEvent,
- UserUpdateEvent,
- handleFile,
- FieldErrors,
adjustEmail,
Config,
- UserModifySchema,
+ emitEvent,
+ FieldErrors,
generateToken,
+ handleFile,
+ PrivateUserProjection,
+ User,
+ UserModifySchema,
+ UserUpdateEvent,
} from "@spacebar/util";
-import { route } from "@spacebar/api";
import bcrypt from "bcrypt";
+import { Request, Response, Router } from "express";
const router: Router = Router();
-router.get("/", route({}), async (req: Request, res: Response) => {
- res.json(
- await User.findOne({
- select: PrivateUserProjection,
- where: { id: req.user_id },
- }),
- );
-});
+router.get(
+ "/",
+ route({
+ responses: {
+ 200: {
+ body: "APIPrivateUser",
+ },
+ },
+ }),
+ async (req: Request, res: Response) => {
+ res.json(
+ await User.findOne({
+ select: PrivateUserProjection,
+ where: { id: req.user_id },
+ }),
+ );
+ },
+);
router.patch(
"/",
- route({ body: "UserModifySchema" }),
+ route({
+ requestBody: "UserModifySchema",
+ responses: {
+ 200: {
+ body: "UserUpdateResponse",
+ },
+ 400: {
+ body: "APIErrorResponse",
+ },
+ 404: {
+ body: "APIErrorResponse",
+ },
+ },
+ }),
async (req: Request, res: Response) => {
const body = req.body as UserModifySchema;
diff --git a/src/api/routes/users/@me/mfa/codes-verification.ts b/src/api/routes/users/@me/mfa/codes-verification.ts
index 69d45e91..f71704a9 100644
--- a/src/api/routes/users/@me/mfa/codes-verification.ts
+++ b/src/api/routes/users/@me/mfa/codes-verification.ts
@@ -16,21 +16,34 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-import { Router, Request, Response } from "express";
import { route } from "@spacebar/api";
import {
BackupCode,
- generateMfaBackupCodes,
- User,
CodesVerificationSchema,
DiscordApiErrors,
+ User,
+ generateMfaBackupCodes,
} from "@spacebar/util";
+import { Request, Response, Router } from "express";
const router = Router();
router.post(
"/",
- route({ body: "CodesVerificationSchema" }),
+ route({
+ requestBody: "CodesVerificationSchema",
+ responses: {
+ 200: {
+ body: "APIBackupCodeArray",
+ },
+ 400: {
+ body: "APIErrorResponse",
+ },
+ 404: {
+ body: "APIErrorResponse",
+ },
+ },
+ }),
async (req: Request, res: Response) => {
// const { key, nonce, regenerate } = req.body as CodesVerificationSchema;
const { regenerate } = req.body as CodesVerificationSchema;
diff --git a/src/api/routes/users/@me/mfa/codes.ts b/src/api/routes/users/@me/mfa/codes.ts
index 4ddbf78e..f9cfc4c4 100644
--- a/src/api/routes/users/@me/mfa/codes.ts
+++ b/src/api/routes/users/@me/mfa/codes.ts
@@ -16,16 +16,16 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-import { Router, Request, Response } from "express";
import { route } from "@spacebar/api";
import {
BackupCode,
FieldErrors,
generateMfaBackupCodes,
- User,
MfaCodesSchema,
+ User,
} from "@spacebar/util";
import bcrypt from "bcrypt";
+import { Request, Response, Router } from "express";
const router = Router();
@@ -33,7 +33,23 @@ const router = Router();
router.post(
"/",
- route({ body: "MfaCodesSchema" }),
+ route({
+ requestBody: "MfaCodesSchema",
+ deprecated: true,
+ description:
+ "This route is replaced with users/@me/mfa/codes-verification in newer clients",
+ responses: {
+ 200: {
+ body: "APIBackupCodeArray",
+ },
+ 400: {
+ body: "APIErrorResponse",
+ },
+ 404: {
+ body: "APIErrorResponse",
+ },
+ },
+ }),
async (req: Request, res: Response) => {
const { password, regenerate } = req.body as MfaCodesSchema;
diff --git a/src/api/routes/users/@me/mfa/totp/disable.ts b/src/api/routes/users/@me/mfa/totp/disable.ts
index 9f406423..362152d7 100644
--- a/src/api/routes/users/@me/mfa/totp/disable.ts
+++ b/src/api/routes/users/@me/mfa/totp/disable.ts
@@ -16,22 +16,32 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-import { Router, Request, Response } from "express";
import { route } from "@spacebar/api";
-import { verifyToken } from "node-2fa";
-import { HTTPError } from "lambert-server";
import {
- User,
- generateToken,
BackupCode,
TotpDisableSchema,
+ User,
+ generateToken,
} from "@spacebar/util";
+import { Request, Response, Router } from "express";
+import { HTTPError } from "lambert-server";
+import { verifyToken } from "node-2fa";
const router = Router();
router.post(
"/",
- route({ body: "TotpDisableSchema" }),
+ route({
+ requestBody: "TotpDisableSchema",
+ responses: {
+ 200: {
+ body: "TokenOnlyResponse",
+ },
+ 400: {
+ body: "APIErrorResponse",
+ },
+ },
+ }),
async (req: Request, res: Response) => {
const body = req.body as TotpDisableSchema;
diff --git a/src/api/routes/users/@me/mfa/totp/enable.ts b/src/api/routes/users/@me/mfa/totp/enable.ts
index 4d6b2763..19836e4d 100644
--- a/src/api/routes/users/@me/mfa/totp/enable.ts
+++ b/src/api/routes/users/@me/mfa/totp/enable.ts
@@ -16,15 +16,15 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-import { Router, Request, Response } from "express";
+import { route } from "@spacebar/api";
import {
+ TotpEnableSchema,
User,
- generateToken,
generateMfaBackupCodes,
- TotpEnableSchema,
+ generateToken,
} from "@spacebar/util";
-import { route } from "@spacebar/api";
import bcrypt from "bcrypt";
+import { Request, Response, Router } from "express";
import { HTTPError } from "lambert-server";
import { verifyToken } from "node-2fa";
@@ -32,7 +32,20 @@ const router = Router();
router.post(
"/",
- route({ body: "TotpEnableSchema" }),
+ route({
+ requestBody: "TotpEnableSchema",
+ responses: {
+ 200: {
+ body: "TokenWithBackupCodesResponse",
+ },
+ 400: {
+ body: "APIErrorResponse",
+ },
+ 404: {
+ body: "APIErrorResponse",
+ },
+ },
+ }),
async (req: Request, res: Response) => {
const body = req.body as TotpEnableSchema;
diff --git a/src/api/routes/users/@me/mfa/webauthn/credentials/#key_id/index.ts b/src/api/routes/users/@me/mfa/webauthn/credentials/#key_id/index.ts
index 04aca7e4..9cf42def 100644
--- a/src/api/routes/users/@me/mfa/webauthn/credentials/#key_id/index.ts
+++ b/src/api/routes/users/@me/mfa/webauthn/credentials/#key_id/index.ts
@@ -21,21 +21,31 @@ import { SecurityKey, User } from "@spacebar/util";
import { Request, Response, Router } from "express";
const router = Router();
-router.delete("/", route({}), async (req: Request, res: Response) => {
- const { key_id } = req.params;
+router.delete(
+ "/",
+ route({
+ responses: {
+ 204: {},
+ },
+ }),
+ async (req: Request, res: Response) => {
+ const { key_id } = req.params;
- await SecurityKey.delete({
- id: key_id,
- user_id: req.user_id,
- });
+ await SecurityKey.delete({
+ id: key_id,
+ user_id: req.user_id,
+ });
- const keys = await SecurityKey.count({ where: { user_id: req.user_id } });
+ const keys = await SecurityKey.count({
+ where: { user_id: req.user_id },
+ });
- // disable webauthn if there are no keys left
- if (keys === 0)
- await User.update({ id: req.user_id }, { webauthn_enabled: false });
+ // disable webauthn if there are no keys left
+ if (keys === 0)
+ await User.update({ id: req.user_id }, { webauthn_enabled: false });
- res.sendStatus(204);
-});
+ res.sendStatus(204);
+ },
+);
export default router;
diff --git a/src/api/routes/users/@me/mfa/webauthn/credentials/index.ts b/src/api/routes/users/@me/mfa/webauthn/credentials/index.ts
index 29dbb7cf..f383ffb7 100644
--- a/src/api/routes/users/@me/mfa/webauthn/credentials/index.ts
+++ b/src/api/routes/users/@me/mfa/webauthn/credentials/index.ts
@@ -73,7 +73,17 @@ router.get("/", route({}), async (req: Request, res: Response) => {
router.post(
"/",
- route({ body: "WebAuthnPostSchema" }),
+ route({
+ requestBody: "WebAuthnPostSchema",
+ responses: {
+ 200: {
+ body: "WebAuthnCreateResponse",
+ },
+ 400: {
+ body: "APIErrorResponse",
+ },
+ },
+ }),
async (req: Request, res: Response) => {
if (!WebAuthn.fido2) {
// TODO: I did this for typescript and I can't use !
diff --git a/src/api/routes/users/@me/notes.ts b/src/api/routes/users/@me/notes.ts
index d05c799c..248e61f9 100644
--- a/src/api/routes/users/@me/notes.ts
+++ b/src/api/routes/users/@me/notes.ts
@@ -16,71 +16,99 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-import { Request, Response, Router } from "express";
import { route } from "@spacebar/api";
-import { User, Note, emitEvent, Snowflake } from "@spacebar/util";
+import { Note, Snowflake, User, emitEvent } from "@spacebar/util";
+import { Request, Response, Router } from "express";
const router: Router = Router();
-router.get("/:id", route({}), async (req: Request, res: Response) => {
- const { id } = req.params;
-
- const note = await Note.findOneOrFail({
- where: {
- owner: { id: req.user_id },
- target: { id: id },
+router.get(
+ "/:id",
+ route({
+ responses: {
+ 200: {
+ body: "UserNoteResponse",
+ },
+ 404: {
+ body: "APIErrorResponse",
+ },
},
- });
+ }),
+ async (req: Request, res: Response) => {
+ const { id } = req.params;
+
+ const note = await Note.findOneOrFail({
+ where: {
+ owner: { id: req.user_id },
+ target: { id: id },
+ },
+ });
- return res.json({
- note: note?.content,
- note_user_id: id,
- user_id: req.user_id,
- });
-});
+ return res.json({
+ note: note?.content,
+ note_user_id: id,
+ user_id: req.user_id,
+ });
+ },
+);
-router.put("/:id", route({}), async (req: Request, res: Response) => {
- const { id } = req.params;
- const owner = await User.findOneOrFail({ where: { id: req.user_id } });
- const target = await User.findOneOrFail({ where: { id: id } }); //if noted user does not exist throw
- const { note } = req.body;
+router.put(
+ "/:id",
+ route({
+ requestBody: "UserNoteUpdateSchema",
+ responses: {
+ 204: {},
+ 404: {
+ body: "APIErrorResponse",
+ },
+ },
+ }),
+ async (req: Request, res: Response) => {
+ const { id } = req.params;
+ const owner = await User.findOneOrFail({ where: { id: req.user_id } });
+ const target = await User.findOneOrFail({ where: { id: id } }); //if noted user does not exist throw
+ const { note } = req.body;
- if (note && note.length) {
- // upsert a note
- if (
- await Note.findOne({
- where: { owner: { id: owner.id }, target: { id: target.id } },
- })
- ) {
- Note.update(
- { owner: { id: owner.id }, target: { id: target.id } },
- { owner, target, content: note },
- );
+ if (note && note.length) {
+ // upsert a note
+ if (
+ await Note.findOne({
+ where: {
+ owner: { id: owner.id },
+ target: { id: target.id },
+ },
+ })
+ ) {
+ Note.update(
+ { owner: { id: owner.id }, target: { id: target.id } },
+ { owner, target, content: note },
+ );
+ } else {
+ Note.insert({
+ id: Snowflake.generate(),
+ owner,
+ target,
+ content: note,
+ });
+ }
} else {
- Note.insert({
- id: Snowflake.generate(),
- owner,
- target,
- content: note,
+ await Note.delete({
+ owner: { id: owner.id },
+ target: { id: target.id },
});
}
- } else {
- await Note.delete({
- owner: { id: owner.id },
- target: { id: target.id },
- });
- }
- await emitEvent({
- event: "USER_NOTE_UPDATE",
- data: {
- note: note,
- id: target.id,
- },
- user_id: owner.id,
- });
+ await emitEvent({
+ event: "USER_NOTE_UPDATE",
+ data: {
+ note: note,
+ id: target.id,
+ },
+ user_id: owner.id,
+ });
- return res.status(204);
-});
+ return res.status(204);
+ },
+);
export default router;
diff --git a/src/api/routes/users/@me/relationships.ts b/src/api/routes/users/@me/relationships.ts
index e9ea47e6..bce0a654 100644
--- a/src/api/routes/users/@me/relationships.ts
+++ b/src/api/routes/users/@me/relationships.ts
@@ -16,20 +16,20 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
+import { route } from "@spacebar/api";
import {
- RelationshipAddEvent,
- User,
+ Config,
+ DiscordApiErrors,
PublicUserProjection,
- RelationshipType,
+ Relationship,
+ RelationshipAddEvent,
RelationshipRemoveEvent,
+ RelationshipType,
+ User,
emitEvent,
- Relationship,
- Config,
} from "@spacebar/util";
-import { Router, Response, Request } from "express";
+import { Request, Response, Router } from "express";
import { HTTPError } from "lambert-server";
-import { DiscordApiErrors } from "@spacebar/util";
-import { route } from "@spacebar/api";
const router = Router();
@@ -38,29 +38,53 @@ const userProjection: (keyof User)[] = [
...PublicUserProjection,
];
-router.get("/", route({}), async (req: Request, res: Response) => {
- const user = await User.findOneOrFail({
- where: { id: req.user_id },
- relations: ["relationships", "relationships.to"],
- select: ["id", "relationships"],
- });
+router.get(
+ "/",
+ route({
+ responses: {
+ 200: {
+ body: "UserRelationshipsResponse",
+ },
+ 404: {
+ body: "APIErrorResponse",
+ },
+ },
+ }),
+ async (req: Request, res: Response) => {
+ const user = await User.findOneOrFail({
+ where: { id: req.user_id },
+ relations: ["relationships", "relationships.to"],
+ select: ["id", "relationships"],
+ });
- //TODO DTO
- const related_users = user.relationships.map((r) => {
- return {
- id: r.to.id,
- type: r.type,
- nickname: null,
- user: r.to.toPublicUser(),
- };
- });
+ //TODO DTO
+ const related_users = user.relationships.map((r) => {
+ return {
+ id: r.to.id,
+ type: r.type,
+ nickname: null,
+ user: r.to.toPublicUser(),
+ };
+ });
- return res.json(related_users);
-});
+ return res.json(related_users);
+ },
+);
router.put(
"/:id",
- route({ body: "RelationshipPutSchema" }),
+ route({
+ requestBody: "RelationshipPutSchema",
+ responses: {
+ 204: {},
+ 400: {
+ body: "APIErrorResponse",
+ },
+ 404: {
+ body: "APIErrorResponse",
+ },
+ },
+ }),
async (req: Request, res: Response) => {
return await updateRelationship(
req,
@@ -77,7 +101,18 @@ router.put(
router.post(
"/",
- route({ body: "RelationshipPostSchema" }),
+ route({
+ requestBody: "RelationshipPostSchema",
+ responses: {
+ 204: {},
+ 400: {
+ body: "APIErrorResponse",
+ },
+ 404: {
+ body: "APIErrorResponse",
+ },
+ },
+ }),
async (req: Request, res: Response) => {
return await updateRelationship(
req,
@@ -98,64 +133,78 @@ router.post(
},
);
-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");
+router.delete(
+ "/:id",
+ route({
+ responses: {
+ 204: {},
+ 400: {
+ body: "APIErrorResponse",
+ },
+ 404: {
+ body: "APIErrorResponse",
+ },
+ },
+ }),
+ 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({
- where: { id: req.user_id },
- select: userProjection,
- relations: ["relationships"],
- });
- const friend = await User.findOneOrFail({
- where: { id: id },
- select: userProjection,
- relations: ["relationships"],
- });
+ const user = await User.findOneOrFail({
+ where: { id: req.user_id },
+ select: userProjection,
+ relations: ["relationships"],
+ });
+ const friend = await User.findOneOrFail({
+ where: { id: id },
+ select: userProjection,
+ relations: ["relationships"],
+ });
- const relationship = user.relationships.find((x) => x.to_id === id);
- const friendRequest = friend.relationships.find(
- (x) => x.to_id === req.user_id,
- );
+ const relationship = user.relationships.find((x) => x.to_id === id);
+ const friendRequest = friend.relationships.find(
+ (x) => x.to_id === req.user_id,
+ );
- if (!relationship)
- throw new HTTPError("You are not friends with the user", 404);
- if (relationship?.type === RelationshipType.blocked) {
- // unblock user
+ if (!relationship)
+ throw new HTTPError("You are not friends with the user", 404);
+ if (relationship?.type === RelationshipType.blocked) {
+ // unblock user
+
+ await Promise.all([
+ Relationship.delete({ id: relationship.id }),
+ emitEvent({
+ event: "RELATIONSHIP_REMOVE",
+ user_id: req.user_id,
+ data: relationship.toPublicRelationship(),
+ } as RelationshipRemoveEvent),
+ ]);
+ return res.sendStatus(204);
+ }
+ if (friendRequest && friendRequest.type !== RelationshipType.blocked) {
+ await Promise.all([
+ Relationship.delete({ id: friendRequest.id }),
+ await emitEvent({
+ event: "RELATIONSHIP_REMOVE",
+ data: friendRequest.toPublicRelationship(),
+ user_id: id,
+ } as RelationshipRemoveEvent),
+ ]);
+ }
await Promise.all([
Relationship.delete({ id: relationship.id }),
emitEvent({
event: "RELATIONSHIP_REMOVE",
- user_id: req.user_id,
data: relationship.toPublicRelationship(),
+ user_id: req.user_id,
} as RelationshipRemoveEvent),
]);
- return res.sendStatus(204);
- }
- if (friendRequest && friendRequest.type !== RelationshipType.blocked) {
- await Promise.all([
- Relationship.delete({ id: friendRequest.id }),
- await emitEvent({
- event: "RELATIONSHIP_REMOVE",
- data: friendRequest.toPublicRelationship(),
- user_id: id,
- } as RelationshipRemoveEvent),
- ]);
- }
- await Promise.all([
- Relationship.delete({ id: relationship.id }),
- emitEvent({
- event: "RELATIONSHIP_REMOVE",
- data: relationship.toPublicRelationship(),
- user_id: req.user_id,
- } as RelationshipRemoveEvent),
- ]);
-
- return res.sendStatus(204);
-});
+ return res.sendStatus(204);
+ },
+);
export default router;
diff --git a/src/api/routes/users/@me/settings.ts b/src/api/routes/users/@me/settings.ts
index 62cfe904..d22d6de1 100644
--- a/src/api/routes/users/@me/settings.ts
+++ b/src/api/routes/users/@me/settings.ts
@@ -16,23 +16,49 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-import { Router, Response, Request } from "express";
-import { User, UserSettingsSchema } from "@spacebar/util";
import { route } from "@spacebar/api";
+import { User, UserSettingsSchema } from "@spacebar/util";
+import { Request, Response, Router } from "express";
const router = Router();
-router.get("/", route({}), async (req: Request, res: Response) => {
- const user = await User.findOneOrFail({
- where: { id: req.user_id },
- relations: ["settings"],
- });
- return res.json(user.settings);
-});
+router.get(
+ "/",
+ route({
+ responses: {
+ 200: {
+ body: "UserSettings",
+ },
+ 404: {
+ body: "APIErrorResponse",
+ },
+ },
+ }),
+ async (req: Request, res: Response) => {
+ const user = await User.findOneOrFail({
+ where: { id: req.user_id },
+ relations: ["settings"],
+ });
+ return res.json(user.settings);
+ },
+);
router.patch(
"/",
- route({ body: "UserSettingsSchema" }),
+ route({
+ requestBody: "UserSettingsSchema",
+ responses: {
+ 200: {
+ body: "UserSettings",
+ },
+ 400: {
+ body: "APIErrorResponse",
+ },
+ 404: {
+ body: "APIErrorResponse",
+ },
+ },
+ }),
async (req: Request, res: Response) => {
const body = req.body as UserSettingsSchema;
if (body.locale === "en") body.locale = "en-US"; // fix discord client crash on unkown locale
|