upd
This commit is contained in:
@@ -1,9 +1,11 @@
|
||||
import { Elysia, t } from "elysia";
|
||||
import { authMiddleware } from "../middlewares/auth";
|
||||
import { optionalAuthMiddleware } from "../middlewares/optionalAuth";
|
||||
import { eq } from "drizzle-orm";
|
||||
import db from "../db";
|
||||
import { apps } from "../db/schema/apps";
|
||||
import { serverSessionService } from "../services/serverSession";
|
||||
import { serverService } from "../services/server";
|
||||
|
||||
export const sessionController = new Elysia({ prefix: "/sessions" })
|
||||
// PATCH /sessions/:id/status - обновить статус сессии (публичный endpoint для сессионного сервера)
|
||||
@@ -78,45 +80,17 @@ export const sessionController = new Elysia({ prefix: "/sessions" })
|
||||
}),
|
||||
}
|
||||
)
|
||||
// Все роуты требуют авторизации
|
||||
.use(authMiddleware)
|
||||
// GET /sessions - получить список сессий пользователя
|
||||
.get("/", async ({ currentUser, query }) => {
|
||||
const { status, mode } = query as {
|
||||
status?: "starting" | "started" | "ending" | "ended";
|
||||
mode?: "stream" | "local";
|
||||
};
|
||||
|
||||
const sessions = await serverSessionService.findByUserId(currentUser.id, {
|
||||
status,
|
||||
mode,
|
||||
});
|
||||
|
||||
return { sessions };
|
||||
})
|
||||
// GET /sessions/:id - получить информацию о конкретной сессии
|
||||
.get("/:id", async ({ params, currentUser, status }) => {
|
||||
const { id } = params;
|
||||
|
||||
const session = await serverSessionService.findByIdForUser(
|
||||
id,
|
||||
currentUser.id
|
||||
);
|
||||
|
||||
if (!session) {
|
||||
return status(404, "Session not found");
|
||||
}
|
||||
|
||||
return { session };
|
||||
})
|
||||
// POST /sessions - создать новую сессию
|
||||
// Endpoints с optional auth (доступны для неавторизованных пользователей)
|
||||
.use(optionalAuthMiddleware)
|
||||
// POST /sessions - создать новую сессию (с optional auth для demo серверов)
|
||||
.post(
|
||||
"/",
|
||||
async ({ body, currentUser, status }) => {
|
||||
const { appId, mode, serverId } = body as {
|
||||
const { appId, mode, serverId, tier } = body as {
|
||||
appId: string;
|
||||
mode: "stream" | "local";
|
||||
serverId?: string;
|
||||
tier?: "demo" | "prod";
|
||||
};
|
||||
|
||||
// Проверить, что приложение существует
|
||||
@@ -128,6 +102,53 @@ export const sessionController = new Elysia({ prefix: "/sessions" })
|
||||
return status(404, "App not found");
|
||||
}
|
||||
|
||||
// Если пользователь не авторизован
|
||||
if (!currentUser) {
|
||||
// Проверяем, что режим - stream (только stream поддерживает demo)
|
||||
if (mode !== "stream") {
|
||||
return status(401, "Authorization required for local sessions");
|
||||
}
|
||||
|
||||
// Неавторизованные пользователи могут использовать только demo-серверы
|
||||
if (tier && tier !== "demo") {
|
||||
return status(
|
||||
403,
|
||||
"Unauthorized users can only use demo tier servers"
|
||||
);
|
||||
}
|
||||
|
||||
// Проверяем, что есть доступные demo-серверы
|
||||
const demoServers = await serverService.findAvailableStreamServers(
|
||||
"demo"
|
||||
);
|
||||
|
||||
if (demoServers.length === 0) {
|
||||
return status(
|
||||
503,
|
||||
"No available demo servers. Please login to use production servers."
|
||||
);
|
||||
}
|
||||
|
||||
// Создаем сессию без userId (для неавторизованных пользователей)
|
||||
try {
|
||||
const newSession = await serverSessionService.create({
|
||||
appId,
|
||||
// userId не передаем - будет undefined для неавторизованных пользователей
|
||||
mode,
|
||||
serverId,
|
||||
tier: "demo", // Всегда demo для неавторизованных
|
||||
});
|
||||
|
||||
return { session: newSession };
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
return status(503, error.message);
|
||||
}
|
||||
return status(500, "Failed to create session");
|
||||
}
|
||||
}
|
||||
|
||||
// Если пользователь авторизован - используем стандартную логику
|
||||
// Проверить, что пользователь не имеет активных сессий этого приложения
|
||||
const hasActive = await serverSessionService.hasActiveSession(
|
||||
currentUser.id,
|
||||
@@ -138,6 +159,16 @@ export const sessionController = new Elysia({ prefix: "/sessions" })
|
||||
return status(409, "User already has an active session for this app");
|
||||
}
|
||||
|
||||
// Для режима stream - проверяем наличие серверов нужного tier
|
||||
if (mode === "stream" && tier) {
|
||||
const availableServers = await serverService.findAvailableStreamServers(
|
||||
tier
|
||||
);
|
||||
if (availableServers.length === 0) {
|
||||
return status(503, `No available ${tier} servers`);
|
||||
}
|
||||
}
|
||||
|
||||
// Создать сессию
|
||||
try {
|
||||
const newSession = await serverSessionService.create({
|
||||
@@ -145,6 +176,7 @@ export const sessionController = new Elysia({ prefix: "/sessions" })
|
||||
userId: currentUser.id,
|
||||
mode,
|
||||
serverId,
|
||||
tier,
|
||||
});
|
||||
|
||||
return { session: newSession };
|
||||
@@ -160,9 +192,58 @@ export const sessionController = new Elysia({ prefix: "/sessions" })
|
||||
appId: t.String({ format: "uuid" }),
|
||||
mode: t.Union([t.Literal("stream"), t.Literal("local")]),
|
||||
serverId: t.Optional(t.String({ format: "uuid" })),
|
||||
tier: t.Optional(t.Union([t.Literal("demo"), t.Literal("prod")])),
|
||||
}),
|
||||
}
|
||||
)
|
||||
// GET /sessions/:id - получить информацию о конкретной сессии (optional auth)
|
||||
.get("/:id", async ({ params, currentUser, status }) => {
|
||||
const { id } = params;
|
||||
|
||||
// Для авторизованных пользователей - проверяем ownership
|
||||
if (currentUser) {
|
||||
const session = await serverSessionService.findByIdForUser(
|
||||
id,
|
||||
currentUser.id
|
||||
);
|
||||
|
||||
if (!session) {
|
||||
return status(404, "Session not found");
|
||||
}
|
||||
|
||||
return { session };
|
||||
}
|
||||
|
||||
// Для неавторизованных - просто находим сессию по ID
|
||||
const session = await serverSessionService.findById(id);
|
||||
|
||||
if (!session) {
|
||||
return status(404, "Session not found");
|
||||
}
|
||||
|
||||
// Проверяем, что это сессия без userId (неавторизованная)
|
||||
if (session.userId) {
|
||||
return status(403, "This session belongs to an authenticated user");
|
||||
}
|
||||
|
||||
return { session };
|
||||
})
|
||||
// Все остальные роуты требуют авторизации
|
||||
.use(authMiddleware)
|
||||
// GET /sessions - получить список сессий пользователя
|
||||
.get("/", async ({ currentUser, query }) => {
|
||||
const { status, mode } = query as {
|
||||
status?: "starting" | "started" | "ending" | "ended";
|
||||
mode?: "stream" | "local";
|
||||
};
|
||||
|
||||
const sessions = await serverSessionService.findByUserId(currentUser.id, {
|
||||
status,
|
||||
mode,
|
||||
});
|
||||
|
||||
return { sessions };
|
||||
})
|
||||
// PATCH /sessions/:id - обновить статус сессии
|
||||
.patch(
|
||||
"/:id",
|
||||
|
||||
Reference in New Issue
Block a user