summary refs log tree commit diff
path: root/src/api
diff options
context:
space:
mode:
Diffstat (limited to 'src/api')
-rw-r--r--src/api/middlewares/Authentication.ts2
-rw-r--r--src/api/routes/connections/#connection_name/#connection_id/refresh.ts11
-rw-r--r--src/api/routes/connections/#connection_name/authorize.ts35
-rw-r--r--src/api/routes/connections/#connection_name/callback.ts52
-rw-r--r--src/api/routes/users/@me/connections.ts24
5 files changed, 121 insertions, 3 deletions
diff --git a/src/api/middlewares/Authentication.ts b/src/api/middlewares/Authentication.ts
index 771f0de8..55527984 100644
--- a/src/api/middlewares/Authentication.ts
+++ b/src/api/middlewares/Authentication.ts
@@ -52,6 +52,8 @@ export const NO_AUTHORIZATION_ROUTES = [
 	"/oauth2/callback",
 	// Asset delivery
 	/\/guilds\/\d+\/widget\.(json|png)/,
+	// Connections
+	/\/connections\/\w+\/callback/
 ];
 
 export const API_PREFIX = /^\/api(\/v\d+)?/;
diff --git a/src/api/routes/connections/#connection_name/#connection_id/refresh.ts b/src/api/routes/connections/#connection_name/#connection_id/refresh.ts
new file mode 100644
index 00000000..cce50436
--- /dev/null
+++ b/src/api/routes/connections/#connection_name/#connection_id/refresh.ts
@@ -0,0 +1,11 @@
+import { route } from "@fosscord/api";
+import { Request, Response, Router } from "express";
+const router = Router();
+
+router.post("/", route({}), async (req: Request, res: Response) => {
+	// TODO:
+	const { connection_name, connection_id } = req.params;
+	res.sendStatus(204);
+});
+
+export default router;
diff --git a/src/api/routes/connections/#connection_name/authorize.ts b/src/api/routes/connections/#connection_name/authorize.ts
new file mode 100644
index 00000000..8e640a69
--- /dev/null
+++ b/src/api/routes/connections/#connection_name/authorize.ts
@@ -0,0 +1,35 @@
+import { Request, Response, Router } from "express";
+import { FieldErrors } from "../../../../util";
+import { ConnectionStore } from "../../../../util/connections";
+import { route } from "../../../util";
+
+const router = Router();
+
+router.get("/", route({}), async (req: Request, res: Response) => {
+	const { connection_id: connection_name } = req.params;
+	const connection = ConnectionStore.connections.get(connection_name);
+	if (!connection)
+		throw FieldErrors({
+			provider_id: {
+				code: "BASE_TYPE_CHOICES",
+				message: req.t("common:field.BASE_TYPE_CHOICES", {
+					types: Array.from(ConnectionStore.connections.keys()).join(
+						", ",
+					),
+				}),
+			},
+		});
+
+	if (!connection.settings.enabled)
+		throw FieldErrors({
+			provider_id: {
+				message: "This connection has been disabled server-side.",
+			},
+		});
+
+	res.json({
+		url: await connection.getAuthorizationUrl(req.user_id),
+	});
+});
+
+export default router;
diff --git a/src/api/routes/connections/#connection_name/callback.ts b/src/api/routes/connections/#connection_name/callback.ts
new file mode 100644
index 00000000..f158a037
--- /dev/null
+++ b/src/api/routes/connections/#connection_name/callback.ts
@@ -0,0 +1,52 @@
+import { Request, Response, Router } from "express";
+import {
+	ConnectionCallbackSchema,
+	emitEvent,
+	FieldErrors,
+} from "../../../../util";
+import { ConnectionStore } from "../../../../util/connections";
+import { route } from "../../../util";
+
+const router = Router();
+
+router.post(
+	"/",
+	route({ body: "ConnectionCallbackSchema" }),
+	async (req: Request, res: Response) => {
+		const { connection_id: connection_name } = req.params;
+		const connection = ConnectionStore.connections.get(connection_name);
+		if (!connection)
+			throw FieldErrors({
+				provider_id: {
+					code: "BASE_TYPE_CHOICES",
+					message: req.t("common:field.BASE_TYPE_CHOICES", {
+						types: Array.from(
+							ConnectionStore.connections.keys(),
+						).join(", "),
+					}),
+				},
+			});
+
+		if (!connection.settings.enabled)
+			throw FieldErrors({
+				provider_id: {
+					message: "This connection has been disabled server-side.",
+				},
+			});
+
+		const body = req.body as ConnectionCallbackSchema;
+		const userId = connection.getUserId(body.state);
+		const emit = await connection.handleCallback(body);
+
+		// whether we should emit a connections update event, only used when a connection doesnt already exist
+		if (emit)
+			emitEvent({
+				event: "USER_CONNECTIONS_UPDATE",
+				data: {},
+				user_id: userId,
+			});
+		res.sendStatus(204);
+	},
+);
+
+export default router;
diff --git a/src/api/routes/users/@me/connections.ts b/src/api/routes/users/@me/connections.ts
index 74315bfe..a5041be1 100644
--- a/src/api/routes/users/@me/connections.ts
+++ b/src/api/routes/users/@me/connections.ts
@@ -16,14 +16,32 @@
 	along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */
 
-import { Request, Response, Router } from "express";
 import { route } from "@fosscord/api";
+import { ConnectedAccount, ConnectedAccountDTO } from "@fosscord/util";
+import { Request, Response, Router } from "express";
 
 const router: Router = Router();
 
 router.get("/", route({}), async (req: Request, res: Response) => {
-	//TODO
-	res.json([]).status(200);
+	const connections = await ConnectedAccount.find({
+		where: {
+			user_id: req.user_id,
+		},
+		select: [
+			"external_id",
+			"type",
+			"name",
+			"verified",
+			"visibility",
+			"show_activity",
+			"revoked",
+			"access_token",
+			"friend_sync",
+			"integrations",
+		],
+	});
+
+	res.json(connections.map((x) => new ConnectedAccountDTO(x, true)));
 });
 
 export default router;