/
Alex_Ural
/
opencode
Обзор
Документация
Войти
/
Alex_Ural
/
opencode
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
dev
packages/enterprise/src/routes/api/[...path].ts
171 строка
5 KB
vimtor
fix(enterprise): use delete for remove share
24 июн 2026, 13:43
24 июн 2026, 13:43
bd149f0
Код
Авторство
О чём код?
import type { APIEvent } from "@solidjs/start/server" import { Hono } from "hono" import { describeRoute, openAPIRouteHandler, resolver } from "hono-openapi" import { validator } from "hono-openapi" import z from "zod" import { cors } from "hono/cors" import { Share } from "~/core/share" import { Resource } from "sst" import { timingSafeEqual } from "node:crypto" const app = new Hono() app .basePath("/api") .use(cors()) .get( "/doc", openAPIRouteHandler(app, { documentation: { info: { title: "Opencode Enterprise API", version: "1.0.0", description: "Opencode Enterprise API endpoints", }, openapi: "3.1.1", }, }), ) .post( "/share", describeRoute({ description: "Create a share", operationId: "share.create", responses: { 200: { description: "Success", content: { "application/json": { schema: resolver( z .object({ id: z.string(), url: z.string(), secret: z.string(), }) .meta({ ref: "Share" }), ), }, }, }, }, }), validator("json", z.object({ sessionID: z.string() })), async (c) => { const body = c.req.valid("json") const share = await Share.create({ sessionID: body.sessionID }) const protocol = c.req.header("x-forwarded-proto") ?? c.req.header("x-forwarded-protocol") ?? "https" const host = c.req.header("x-forwarded-host") ?? c.req.header("host") return c.json({ id: share.id, secret: share.secret, url: `${protocol}://${host}/share/${share.id}`, }) }, ) .post( "/share/:shareID/sync", describeRoute({ description: "Sync share data", operationId: "share.sync", responses: { 200: { description: "Success", content: { "application/json": { schema: resolver(z.object({})), }, }, }, }, }), validator("param", z.object({ shareID: z.string() })), validator("json", z.object({ secret: z.string(), data: Share.Data.array() })), async (c) => { const { shareID } = c.req.valid("param") const body = c.req.valid("json") await Share.sync({ share: { id: shareID, secret: body.secret }, data: body.data, }) return c.json({}) }, ) .get( "/share/:shareID/data", describeRoute({ description: "Get share data", operationId: "share.data", responses: { 200: { description: "Success", content: { "application/json": { schema: resolver(z.array(Share.Data)), }, }, }, }, }), validator("param", z.object({ shareID: z.string() })), async (c) => { const { shareID } = c.req.valid("param") c.header("Cache-Control", "public, max-age=30, s-maxage=300, stale-while-revalidate=86400") return c.json(await Share.data(shareID)) }, ) .delete( "/share/:shareID", describeRoute({ description: "Remove a share", operationId: "share.remove", responses: { 200: { description: "Success", content: { "application/json": { schema: resolver(z.object({})), }, }, }, }, }), validator("param", z.object({ shareID: z.string() })), validator("json", z.object({ secret: z.string() })), async (c) => { const { shareID } = c.req.valid("param") const body = c.req.valid("json") await Share.remove({ id: shareID, secret: body.secret }) return c.json({}) }, ) .delete("/support/actions/remove-share", async (c) => { const authorization = c.req.header("authorization") const expected = `Bearer ${(Resource as unknown as Record<string, { value: string }>).SUPPORT_API_KEY.value}` const actual = Buffer.from(authorization ?? "") const secret = Buffer.from(expected) if (actual.length !== secret.length || !timingSafeEqual(actual, secret)) return c.json({ error: "Unauthorized" }, 401) const body = z.object({ shareID: z.string().min(1) }).safeParse(await c.req.json().catch(() => undefined)) if (!body.success) return c.json({ error: "Invalid request", issues: body.error.issues }, 400) return Share.removeAdmin({ id: body.data.shareID }) .then(() => c.json({ success: true, message: "Share removed" })) .catch((error) => c.json({ error: error instanceof Error ? error.message : String(error) }, 400)) }) export function GET(event: APIEvent) { return app.fetch(event.request) } export function POST(event: APIEvent) { return app.fetch(event.request) } export function PUT(event: APIEvent) { return app.fetch(event.request) } export async function DELETE(event: APIEvent) { return app.fetch(event.request) }