summary refs log tree commit diff
path: root/api/src
diff options
context:
space:
mode:
Diffstat (limited to 'api/src')
-rw-r--r--api/src/middlewares/Authentication.ts4
-rw-r--r--api/src/routes/applications/#id/entitlements.ts12
-rw-r--r--api/src/routes/auth/register.ts10
-rw-r--r--api/src/routes/channels/#channel_id/messages/#message_id/crosspost.ts26
-rw-r--r--api/src/routes/channels/#channel_id/messages/#message_id/reactions.ts4
-rw-r--r--api/src/routes/discoverable-guilds.ts8
-rw-r--r--api/src/routes/discovery.ts12
-rw-r--r--api/src/routes/stage-instances.ts (renamed from api/src/routes/store/skus.ts)3
-rw-r--r--api/src/routes/store/published-listings/applications.ts79
-rw-r--r--api/src/routes/store/published-listings/applications/#id/subscription-plans.ts24
-rw-r--r--api/src/routes/store/published-listings/skus.ts79
-rw-r--r--api/src/routes/store/published-listings/skus/#sku_id/subscription-plans.ts25
-rw-r--r--api/src/routes/users/@me/activities/statistics/applications.ts11
-rw-r--r--api/src/routes/users/@me/billing/payment-sources.ts11
-rw-r--r--api/src/routes/users/@me/email-settings.ts19
-rw-r--r--api/src/routes/users/@me/entitlements.ts11
-rw-r--r--api/src/routes/users/@me/guilds/premium/subscription-slots.ts11
-rw-r--r--api/src/routes/users/@me/notes.ts (renamed from api/src/routes/store/applications.ts)8
-rw-r--r--api/src/util/route.ts21
19 files changed, 364 insertions, 14 deletions
diff --git a/api/src/middlewares/Authentication.ts b/api/src/middlewares/Authentication.ts
index a300c786..5a082751 100644
--- a/api/src/middlewares/Authentication.ts
+++ b/api/src/middlewares/Authentication.ts
@@ -1,6 +1,6 @@
 import { NextFunction, Request, Response } from "express";
 import { HTTPError } from "lambert-server";
-import { checkToken, Config } from "@fosscord/util";
+import { checkToken, Config, Rights } from "@fosscord/util";
 
 export const NO_AUTHORIZATION_ROUTES = [
 	"/auth/login",
@@ -21,6 +21,7 @@ declare global {
 			user_id: string;
 			user_bot: boolean;
 			token: string;
+			rights: Rights;
 		}
 	}
 }
@@ -46,6 +47,7 @@ export async function Authentication(req: Request, res: Response, next: NextFunc
 		req.token = decoded;
 		req.user_id = decoded.id;
 		req.user_bot = user.bot;
+		req.rights = new Rights(Number(user.rights));
 		return next();
 	} catch (error: any) {
 		return next(new HTTPError(error?.toString(), 400));
diff --git a/api/src/routes/applications/#id/entitlements.ts b/api/src/routes/applications/#id/entitlements.ts
new file mode 100644
index 00000000..1152e500
--- /dev/null
+++ b/api/src/routes/applications/#id/entitlements.ts
@@ -0,0 +1,12 @@
+import { Router, Response, Request } from "express";
+import { route } from "@fosscord/api";
+
+const router = Router();
+
+router.get("/", route({}), (req: Request, res: Response) => {
+	// TODO:
+    //const { exclude_consumed } = req.query;
+	res.status(200).send([]);
+});
+
+export default router;
diff --git a/api/src/routes/auth/register.ts b/api/src/routes/auth/register.ts
index 9c058399..1344c994 100644
--- a/api/src/routes/auth/register.ts
+++ b/api/src/routes/auth/register.ts
@@ -50,6 +50,15 @@ router.post("/", route({ body: "RegisterSchema" }), async (req: Request, res: Re
 	const { register, security } = Config.get();
 	const ip = getIpAdress(req);
 
+	if (register.disabled) {
+		throw FieldErrors({
+			email: {
+				code: "DISABLED",
+				message: "registration is disabled on this instance"
+			}
+		});
+	}
+
 	if (register.blockProxies) {
 		if (isProxy(await IPAnalysis(ip))) {
 			console.log(`proxy ${ip} blocked from registration`);
@@ -202,6 +211,7 @@ router.post("/", route({ body: "RegisterSchema" }), async (req: Request, res: Re
 		disabled: false,
 		deleted: false,
 		email: email,
+		rights: "0",
 		nsfw_allowed: true, // TODO: depending on age
 		public_flags: "0",
 		flags: "0", // TODO: generate
diff --git a/api/src/routes/channels/#channel_id/messages/#message_id/crosspost.ts b/api/src/routes/channels/#channel_id/messages/#message_id/crosspost.ts
index 6753e832..de0c01f1 100644
--- a/api/src/routes/channels/#channel_id/messages/#message_id/crosspost.ts
+++ b/api/src/routes/channels/#channel_id/messages/#message_id/crosspost.ts
@@ -1,8 +1,30 @@
 import { Router, Response, Request } from "express";
+import { route } from "@fosscord/api";
 
 const router = Router();
 
-// TODO:
-// router.post("/", (req: Request, res: Response) => {});
+router.post("/", route({ permission: "MANAGE_MESSAGES" }), (req: Request, res: Response) => {
+	// TODO:
+	res.json({
+        id: "", 
+        type: 0, 
+        content: "", 
+        channel_id: "", 
+        author: {id: "", 
+        username: "", 
+        avatar: "", 
+        discriminator: "", public_flags: 64}, 
+        attachments: [], 
+        embeds: [], 
+        mentions: [], 
+        mention_roles: [], 
+        pinned: false, 
+        mention_everyone: false, 
+        tts: false, 
+        timestamp: "", 
+        edited_timestamp: null, 
+        flags: 1, components: []}).status(200);
+});
 
 export default router;
+
diff --git a/api/src/routes/channels/#channel_id/messages/#message_id/reactions.ts b/api/src/routes/channels/#channel_id/messages/#message_id/reactions.ts
index f2b83d40..6b6a66b2 100644
--- a/api/src/routes/channels/#channel_id/messages/#message_id/reactions.ts
+++ b/api/src/routes/channels/#channel_id/messages/#message_id/reactions.ts
@@ -124,7 +124,7 @@ router.put("/:emoji/:user_id", route({ permission: "READ_MESSAGE_HISTORY" }), as
 		already_added.count++;
 	} else message.reactions.push({ count: 1, emoji, user_ids: [req.user_id] });
 
-	await Message.update({ id: message_id, channel_id }, message);
+	await message.save();
 
 	const member = channel.guild_id && (await Member.findOneOrFail({ id: req.user_id }));
 
@@ -165,7 +165,7 @@ router.delete("/:emoji/:user_id", route({}), async (req: Request, res: Response)
 
 	if (already_added.count <= 0) message.reactions.remove(already_added);
 
-	await Message.update({ id: message_id, channel_id }, message);
+	await message.save();
 
 	await emitEvent({
 		event: "MESSAGE_REACTION_REMOVE",
diff --git a/api/src/routes/discoverable-guilds.ts b/api/src/routes/discoverable-guilds.ts
index f667eb2a..b626b084 100644
--- a/api/src/routes/discoverable-guilds.ts
+++ b/api/src/routes/discoverable-guilds.ts
@@ -1,16 +1,18 @@
-import { Guild } from "@fosscord/util";
+import { Guild, Config } from "@fosscord/util";
+
 import { Router, Request, Response } from "express";
 import { route } from "@fosscord/api";
 
+
 const router = Router();
 
 router.get("/", route({}), async (req: Request, res: Response) => {
 	const { limit } = req.params;
-
+	var showAllGuilds = Config.get().guild.showAllGuildsInDiscovery;
 	// ! this only works using SQL querys
 	// TODO: implement this with default typeorm query
 	// const guilds = await Guild.find({ where: { features: "DISCOVERABLE" } }); //, take: Math.abs(Number(limit)) });
-	const guilds = await Guild.find({ where: `"features" LIKE 'COMMUNITY'`, take: Math.abs(Number(limit)) });
+	const guilds = showAllGuilds ? await Guild.find({take: Math.abs(Number(limit || 20))}) : await Guild.find({ where: `"features" LIKE '%COMMUNITY%'`, take: Math.abs(Number(limit || 20)) });
 	res.send({ guilds: guilds });
 });
 
diff --git a/api/src/routes/discovery.ts b/api/src/routes/discovery.ts
new file mode 100644
index 00000000..9e6e0164
--- /dev/null
+++ b/api/src/routes/discovery.ts
@@ -0,0 +1,12 @@
+import { Router, Response, Request } from "express";
+import { route } from "@fosscord/api";
+
+const router = Router();
+
+router.get("/categories", route({}), (req: Request, res: Response) => {
+	// TODO:
+    //const { locale, primary_only } = req.query;
+	res.json([]).status(200);
+});
+
+export default router;
diff --git a/api/src/routes/store/skus.ts b/api/src/routes/stage-instances.ts
index 7d0e12eb..411e95bf 100644
--- a/api/src/routes/store/skus.ts
+++ b/api/src/routes/stage-instances.ts
@@ -3,9 +3,8 @@ import { route } from "@fosscord/api";
 
 const router: Router = Router();
 
-router.get("/skus/:id", route({}), async (req: Request, res: Response) => {
+router.get("/", route({}), async (req: Request, res: Response) => {
 	//TODO
-	const { id } = req.params;
 	res.json([]).status(200);
 });
 
diff --git a/api/src/routes/store/published-listings/applications.ts b/api/src/routes/store/published-listings/applications.ts
new file mode 100644
index 00000000..f06a01e4
--- /dev/null
+++ b/api/src/routes/store/published-listings/applications.ts
@@ -0,0 +1,79 @@
+import { Request, Response, Router } from "express";
+import { route } from "@fosscord/api";
+
+const router: Router = Router();
+
+router.get("/:id", route({}), async (req: Request, res: Response) => {
+	//TODO
+	const id = req.params.id;
+	res.json({
+		id: "",
+		summary: "",
+		sku: {
+			id: "",
+			type: 1,
+			dependent_sku_id: null,
+			application_id: "",
+			manifets_labels: [],
+			access_type: 2,
+			name: "",
+			features: [],
+			relase_date: "",
+			premium: false,
+			slug: "",
+			flags: 4,
+			genres: [],
+			legal_notice: "",
+			application: {
+				id: "",
+				name: "",
+				icon: "",
+				description: "",
+				summary: "",
+				cover_image: "",
+				primary_sku_id: "",
+				hook: true,
+				slug: "",
+				guild_id: "",
+				bot_public: "",
+				bot_require_code_grant: false,
+				verify_key: "",
+				publishers: [
+					{
+						id: "",
+						name: ""
+					}
+				],
+				developers: [
+					{
+						id: "",
+						name: ""
+					}
+				],
+				system_requirements: {},
+				show_age_gate: false,
+				price: {
+					amount: 0,
+					currency: "EUR"
+				},
+				locales: []
+			},
+			tagline: "",
+			description: "",
+			carousel_items: [
+				{
+					asset_id: ""
+				}
+			],
+			header_logo_dark_theme: {}, //{id: "", size: 4665, mime_type: "image/gif", width 160, height: 160}
+			header_logo_light_theme: {},
+			box_art: {},
+			thumbnail: {},
+			header_background: {},
+			hero_background: {},
+			assets: []
+		}
+	}).status(200);
+});
+
+export default router;
diff --git a/api/src/routes/store/published-listings/applications/#id/subscription-plans.ts b/api/src/routes/store/published-listings/applications/#id/subscription-plans.ts
new file mode 100644
index 00000000..77f949d9
--- /dev/null
+++ b/api/src/routes/store/published-listings/applications/#id/subscription-plans.ts
@@ -0,0 +1,24 @@
+import { Request, Response, Router } from "express";
+import { route } from "@fosscord/api";
+
+const router: Router = Router();
+
+router.get("/", route({}), async (req: Request, res: Response) => {
+	//TODO
+	res.json([
+        {
+            id: "",
+            name: "",
+            interval: 1,
+            interval_count: 1,
+            tax_inclusive: true,
+            sku_id: "",
+            fallback_price: 499,
+            fallback_currency: "eur",
+            currency: "eur",
+            price: 4199,
+            price_tier: null
+        }]).status(200);
+});
+
+export default router;
diff --git a/api/src/routes/store/published-listings/skus.ts b/api/src/routes/store/published-listings/skus.ts
new file mode 100644
index 00000000..f06a01e4
--- /dev/null
+++ b/api/src/routes/store/published-listings/skus.ts
@@ -0,0 +1,79 @@
+import { Request, Response, Router } from "express";
+import { route } from "@fosscord/api";
+
+const router: Router = Router();
+
+router.get("/:id", route({}), async (req: Request, res: Response) => {
+	//TODO
+	const id = req.params.id;
+	res.json({
+		id: "",
+		summary: "",
+		sku: {
+			id: "",
+			type: 1,
+			dependent_sku_id: null,
+			application_id: "",
+			manifets_labels: [],
+			access_type: 2,
+			name: "",
+			features: [],
+			relase_date: "",
+			premium: false,
+			slug: "",
+			flags: 4,
+			genres: [],
+			legal_notice: "",
+			application: {
+				id: "",
+				name: "",
+				icon: "",
+				description: "",
+				summary: "",
+				cover_image: "",
+				primary_sku_id: "",
+				hook: true,
+				slug: "",
+				guild_id: "",
+				bot_public: "",
+				bot_require_code_grant: false,
+				verify_key: "",
+				publishers: [
+					{
+						id: "",
+						name: ""
+					}
+				],
+				developers: [
+					{
+						id: "",
+						name: ""
+					}
+				],
+				system_requirements: {},
+				show_age_gate: false,
+				price: {
+					amount: 0,
+					currency: "EUR"
+				},
+				locales: []
+			},
+			tagline: "",
+			description: "",
+			carousel_items: [
+				{
+					asset_id: ""
+				}
+			],
+			header_logo_dark_theme: {}, //{id: "", size: 4665, mime_type: "image/gif", width 160, height: 160}
+			header_logo_light_theme: {},
+			box_art: {},
+			thumbnail: {},
+			header_background: {},
+			hero_background: {},
+			assets: []
+		}
+	}).status(200);
+});
+
+export default router;
diff --git a/api/src/routes/store/published-listings/skus/#sku_id/subscription-plans.ts b/api/src/routes/store/published-listings/skus/#sku_id/subscription-plans.ts
new file mode 100644
index 00000000..54c01607
--- /dev/null
+++ b/api/src/routes/store/published-listings/skus/#sku_id/subscription-plans.ts
@@ -0,0 +1,25 @@
+import { Request, Response, Router } from "express";
+import { route } from "@fosscord/api";
+
+const router: Router = Router();
+
+const skus = new Map([
+	["521842865731534868", [{"id": "511651856145973248", "name": "Premium Monthly (Legacy)", "interval": 1, "interval_count": 1, "tax_inclusive": true, "sku_id": "521842865731534868", "currency": "usd", "price": 0, "price_tier": null}, {"id": "511651860671627264", "name": "Premium Yearly (Legacy)", "interval": 2, "interval_count": 1, "tax_inclusive": true, "sku_id": "521842865731534868", "currency": "usd", "price": 0, "price_tier": null}]],
+	["521846918637420545", [{"id": "511651871736201216", "name": "Premium Classic Monthly", "interval": 1, "interval_count": 1, "tax_inclusive": true, "sku_id": "521846918637420545", "currency": "usd", "price": 0, "price_tier": null}, {"id": "511651876987469824", "name": "Premium Classic Yearly", "interval": 2, "interval_count": 1, "tax_inclusive": true, "sku_id": "521846918637420545", "currency": "usd", "price": 0, "price_tier": null}]],
+	["521847234246082599", [{"id": "642251038925127690", "name": "Premium Quarterly", "interval": 1, "interval_count": 3, "tax_inclusive": true, "sku_id": "521847234246082599", "currency": "usd", "price": 0, "price_tier": null}, {"id": "511651880837840896", "name": "Premium Monthly", "interval": 1, "interval_count": 1, "tax_inclusive": true, "sku_id": "521847234246082599", "currency": "usd", "price": 0, "price_tier": null}, {"id": "511651885459963904", "name": "Premium Yearly", "interval": 2, "interval_count": 1, "tax_inclusive": true, "sku_id": "521847234246082599", "currency": "usd", "price": 0, "price_tier": null}]],
+	["590663762298667008", [{"id": "590665532894740483", "name": "Server Boost Monthly", "interval": 1, "interval_count": 1, "tax_inclusive": true, "sku_id": "590663762298667008", "discount_price": 0, "currency": "usd", "price": 0, "price_tier": null}, {"id": "590665538238152709", "name": "Server Boost Yearly", "interval": 2, "interval_count": 1, "tax_inclusive": true, "sku_id": "590663762298667008", "discount_price": 0, "currency": "usd", "price": 0, "price_tier": null}]],
+]);
+
+router.get("/", route({}), async (req: Request, res: Response) => {
+	// TODO: add the ability to add custom
+	const { sku_id } = req.params;
+	
+	if(!skus.has(sku_id)) {
+		console.log(`Request for invalid SKU ${sku_id}! Please report this!`);
+		res.sendStatus(404);
+	} else {
+		res.json(skus.get(sku_id)).status(200);
+	}
+});
+
+export default router;
diff --git a/api/src/routes/users/@me/activities/statistics/applications.ts b/api/src/routes/users/@me/activities/statistics/applications.ts
new file mode 100644
index 00000000..834be35c
--- /dev/null
+++ b/api/src/routes/users/@me/activities/statistics/applications.ts
@@ -0,0 +1,11 @@
+import { Router, Response, Request } from "express";
+import { route } from "@fosscord/api";
+
+const router = Router();
+
+router.get("/", route({}), (req: Request, res: Response) => {
+	// TODO:
+	res.json([]).status(200)
+});
+
+export default router;
diff --git a/api/src/routes/users/@me/billing/payment-sources.ts b/api/src/routes/users/@me/billing/payment-sources.ts
new file mode 100644
index 00000000..834be35c
--- /dev/null
+++ b/api/src/routes/users/@me/billing/payment-sources.ts
@@ -0,0 +1,11 @@
+import { Router, Response, Request } from "express";
+import { route } from "@fosscord/api";
+
+const router = Router();
+
+router.get("/", route({}), (req: Request, res: Response) => {
+	// TODO:
+	res.json([]).status(200)
+});
+
+export default router;
diff --git a/api/src/routes/users/@me/email-settings.ts b/api/src/routes/users/@me/email-settings.ts
new file mode 100644
index 00000000..2d961a0e
--- /dev/null
+++ b/api/src/routes/users/@me/email-settings.ts
@@ -0,0 +1,19 @@
+import { Router, Response, Request } from "express";
+import { route } from "@fosscord/api";
+
+const router = Router();
+
+router.get("/", route({}), (req: Request, res: Response) => {
+	// TODO:    
+	res.json({
+		categories: { 
+        social: true,
+        communication: true,
+        tips: false,
+        updates_and_announcements: false,
+        recommendations_and_events: false },
+		initialized: false
+	}).status(200);
+});
+
+export default router;
diff --git a/api/src/routes/users/@me/entitlements.ts b/api/src/routes/users/@me/entitlements.ts
new file mode 100644
index 00000000..341e2b4c
--- /dev/null
+++ b/api/src/routes/users/@me/entitlements.ts
@@ -0,0 +1,11 @@
+import { Router, Response, Request } from "express";
+import { route } from "@fosscord/api";
+
+const router = Router();
+
+router.get("/gifts", route({}), (req: Request, res: Response) => {
+	// TODO:
+	res.json([]).status(200);
+});
+
+export default router;
diff --git a/api/src/routes/users/@me/guilds/premium/subscription-slots.ts b/api/src/routes/users/@me/guilds/premium/subscription-slots.ts
new file mode 100644
index 00000000..014df8af
--- /dev/null
+++ b/api/src/routes/users/@me/guilds/premium/subscription-slots.ts
@@ -0,0 +1,11 @@
+import { Router, Response, Request } from "express";
+import { route } from "@fosscord/api";
+
+const router = Router();
+
+router.get("/", route({}), (req: Request, res: Response) => {
+	// TODO:
+	res.json([]).status(200);
+});
+
+export default router;
diff --git a/api/src/routes/store/applications.ts b/api/src/routes/users/@me/notes.ts
index 352c1752..2ef27bc0 100644
--- a/api/src/routes/store/applications.ts
+++ b/api/src/routes/users/@me/notes.ts
@@ -3,10 +3,12 @@ import { route } from "@fosscord/api";
 
 const router: Router = Router();
 
-router.get("/applications/:id", route({}), async (req: Request, res: Response) => {
+router.put("/:id", route({}), async (req: Request, res: Response) => {
 	//TODO
-	const { id } = req.params;
-	res.json([]).status(200);
+	res.json({
+		message: "400: Bad Request",
+		code: 0
+	}).status(400);
 });
 
 export default router;
diff --git a/api/src/util/route.ts b/api/src/util/route.ts
index 45882d8a..3e967e2a 100644
--- a/api/src/util/route.ts
+++ b/api/src/util/route.ts
@@ -1,4 +1,15 @@
-import { DiscordApiErrors, EVENT, Event, EventData, getPermission, PermissionResolvable, Permissions } from "@fosscord/util";
+import {
+	DiscordApiErrors,
+	EVENT,
+	Event,
+	EventData,
+	FosscordApiErrors,
+	getPermission,
+	PermissionResolvable,
+	Permissions,
+	RightResolvable,
+	Rights
+} from "@fosscord/util";
 import { NextFunction, Request, Response } from "express";
 import fs from "fs";
 import path from "path";
@@ -33,6 +44,7 @@ export type RouteResponse = { status?: number; body?: `${string}Response`; heade
 
 export interface RouteOptions {
 	permission?: PermissionResolvable;
+	right?: RightResolvable;
 	body?: `${string}Schema`; // typescript interface name
 	test?: {
 		response?: RouteResponse;
@@ -89,6 +101,13 @@ export function route(opts: RouteOptions) {
 			}
 		}
 
+		if (opts.right) {
+			const required = new Rights(opts.right);
+			if (!req.rights || !req.rights.has(required)) {
+				throw FosscordApiErrors.MISSING_RIGHTS.withParams(opts.right as string);
+			}
+		}
+
 		if (validate) {
 			const valid = validate(normalizeBody(req.body));
 			if (!valid) {