mirror of
https://github.com/spacebarchat/server.git
synced 2026-10-25 01:52:51 +00:00
Merge branch 'typescript-interface-body-parser+autogenerate-unit-tests+documentation'
This commit is contained in:
commit
33533fc183
118 files changed
+9131
-1496
No files matched your search
@@ -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));
|
||||
|
||||
@@ -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;
|
||||
@@ -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: [] });
|
||||
});
|
||||
|
||||
@@ -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: [] });
|
||||
});
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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"] });
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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([]);
|
||||
});
|
||||
|
||||
@@ -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;
|
||||
@@ -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
|
||||
|
||||
Reference in new issue
Block a user