Canvas: Configure deploy keys on repo owner

Expose Agent compact prop
Implement GitHub repo pagination

Change-Id: Ib444c53f2c7f83d7461e6f1a8e9d86698d320e92
diff --git a/apps/canvas/back/src/index.ts b/apps/canvas/back/src/index.ts
index b6a7098..1fd9b37 100644
--- a/apps/canvas/back/src/index.ts
+++ b/apps/canvas/back/src/index.ts
@@ -809,6 +809,48 @@
 	}
 };
 
+// eslint-disable-next-line @typescript-eslint/no-unused-vars
+const internalEnvSchema = z.object({
+	githubToken: z.string().optional(),
+	networks: z.array(
+		z.object({
+			name: z.string(),
+			domain: z.string(),
+			hasAuth: z.boolean(),
+		}),
+	),
+});
+
+type InternalEnv = z.infer<typeof internalEnvSchema>;
+
+const handleInternalEnv: express.Handler = async (req, resp) => {
+	try {
+		console.log("getting internal env");
+		const project = await db.project.findUnique({
+			where: {
+				id: Number(req.params["projectId"]),
+				userId: resp.locals.userId,
+			},
+			select: {
+				githubToken: true,
+			},
+		});
+		const networks = getNetworks(resp.locals.username);
+		const env: InternalEnv = {
+			networks,
+			githubToken: project?.githubToken ?? undefined,
+		};
+		resp.status(200);
+		resp.write(JSON.stringify(env));
+	} catch (error) {
+		console.error("Error getting env:", error);
+		resp.status(500);
+		resp.write(JSON.stringify({ error: "Internal server error" }));
+	} finally {
+		resp.end();
+	}
+};
+
 const handleServiceLogs: express.Handler = async (req, resp) => {
 	const projectId = Number(req.params["projectId"]);
 	const service = req.params["service"];
@@ -1263,6 +1305,7 @@
 	internalApi.get("/api/project/:projectId/config", handleConfigGet);
 	internalApi.post("/api/project/:projectId/saved", handleSave);
 	internalApi.post("/api/project/:projectId/deploy", handleDeploy);
+	internalApi.get("/api/project/:projectId/env", handleInternalEnv);
 	internalApi.post("/api/validate-config", handleValidateConfig);
 
 	app.listen(env.DODO_PORT_WEB, () => {