start kv
This commit is contained in:
parent
a16b530b56
commit
a90c09200d
@ -1,4 +1,4 @@
|
|||||||
import type { DrizzleD1Database } from "drizzle-orm/d1";
|
// import type { DrizzleD1Database } from "drizzle-orm/d1";
|
||||||
import { drizzle } from "drizzle-orm/d1";
|
import { drizzle } from "drizzle-orm/d1";
|
||||||
import { json } from "itty-router-extras";
|
import { json } from "itty-router-extras";
|
||||||
import { ZodError, z } from "zod";
|
import { ZodError, z } from "zod";
|
||||||
@ -10,6 +10,7 @@ import { and, eq, sql } from "drizzle-orm";
|
|||||||
export interface Env {
|
export interface Env {
|
||||||
DB: D1Database;
|
DB: D1Database;
|
||||||
STORAGE: any;
|
STORAGE: any;
|
||||||
|
KV: KVNamespace;
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://github.com/drizzle-team/drizzle-orm/tree/main/examples/cloudflare-d1
|
// https://github.com/drizzle-team/drizzle-orm/tree/main/examples/cloudflare-d1
|
||||||
@ -30,7 +31,35 @@ export default {
|
|||||||
|
|
||||||
const db = drizzle(env.DB, { schema });
|
const db = drizzle(env.DB, { schema });
|
||||||
|
|
||||||
if (path === "/api/sandbox") {
|
if (path === "/api/session") {
|
||||||
|
if (method === "PUT") {
|
||||||
|
const body = await request.json();
|
||||||
|
const schema = z.object({
|
||||||
|
userId: z.string(),
|
||||||
|
sandboxId: z.string(),
|
||||||
|
});
|
||||||
|
|
||||||
|
const { userId, sandboxId } = schema.parse(body);
|
||||||
|
|
||||||
|
await env.KV.put(userId, sandboxId);
|
||||||
|
|
||||||
|
return success;
|
||||||
|
} else if (method === "GET") {
|
||||||
|
const params = url.searchParams;
|
||||||
|
if (params.has("id")) {
|
||||||
|
const id = params.get("id") as string;
|
||||||
|
const sandboxId = await env.KV.get(id);
|
||||||
|
return json({ sandboxId });
|
||||||
|
} else return invalidRequest;
|
||||||
|
} else if (method === "DELETE") {
|
||||||
|
const params = url.searchParams;
|
||||||
|
if (params.has("id")) {
|
||||||
|
const id = params.get("id") as string;
|
||||||
|
await env.KV.delete(id);
|
||||||
|
return success;
|
||||||
|
} else return invalidRequest;
|
||||||
|
} else return methodNotAllowed;
|
||||||
|
} else if (path === "/api/sandbox") {
|
||||||
if (method === "GET") {
|
if (method === "GET") {
|
||||||
const params = url.searchParams;
|
const params = url.searchParams;
|
||||||
if (params.has("id")) {
|
if (params.has("id")) {
|
||||||
@ -65,14 +94,14 @@ export default {
|
|||||||
return invalidRequest;
|
return invalidRequest;
|
||||||
}
|
}
|
||||||
} else if (method === "POST") {
|
} else if (method === "POST") {
|
||||||
const initSchema = z.object({
|
const postSchema = z.object({
|
||||||
id: z.string(),
|
id: z.string(),
|
||||||
name: z.string().optional(),
|
name: z.string().optional(),
|
||||||
visibility: z.enum(["public", "private"]).optional(),
|
visibility: z.enum(["public", "private"]).optional(),
|
||||||
});
|
});
|
||||||
|
|
||||||
const body = await request.json();
|
const body = await request.json();
|
||||||
const { id, name, visibility } = initSchema.parse(body);
|
const { id, name, visibility } = postSchema.parse(body);
|
||||||
const sb = await db.update(sandbox).set({ name, visibility }).where(eq(sandbox.id, id)).returning().get();
|
const sb = await db.update(sandbox).set({ name, visibility }).where(eq(sandbox.id, id)).returning().get();
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
@ -99,9 +128,8 @@ export default {
|
|||||||
body: JSON.stringify({ sandboxId: sb.id, type }),
|
body: JSON.stringify({ sandboxId: sb.id, type }),
|
||||||
headers: { "Content-Type": "application/json" },
|
headers: { "Content-Type": "application/json" },
|
||||||
});
|
});
|
||||||
const initStorageRes = await env.STORAGE.fetch(initStorageRequest);
|
|
||||||
|
|
||||||
// const initStorage = await initStorageRes.text();
|
await env.STORAGE.fetch(initStorageRequest);
|
||||||
|
|
||||||
return new Response(sb.id, { status: 200 });
|
return new Response(sb.id, { status: 200 });
|
||||||
} else {
|
} else {
|
||||||
|
@ -2,8 +2,8 @@ FROM node:20
|
|||||||
|
|
||||||
# Security: Drop all capabilities
|
# Security: Drop all capabilities
|
||||||
USER root
|
USER root
|
||||||
RUN apt-get update && apt-get install -y libcap2-bin && \
|
RUN apt-get update && apt-get install -y libcap2-bin
|
||||||
setcap cap_net_bind_service=+ep /usr/local/bin/node
|
RUN setcap cap_net_bind_service=+ep /usr/local/bin/node
|
||||||
|
|
||||||
WORKDIR /code
|
WORKDIR /code
|
||||||
|
|
||||||
@ -15,21 +15,14 @@ COPY . .
|
|||||||
|
|
||||||
RUN npm run build
|
RUN npm run build
|
||||||
|
|
||||||
|
# Security: Create non-root user and assign ownership
|
||||||
RUN useradd -m sboxuser
|
RUN useradd -m sboxuser
|
||||||
RUN mkdir projects && chown -R sboxuser:sboxuser projects
|
RUN mkdir projects && chown -R sboxuser:sboxuser projects
|
||||||
|
|
||||||
# todo user namespace mapping
|
|
||||||
|
|
||||||
RUN apt-get install -y firejail
|
|
||||||
# RUN echo "noblacklist /code/projects\nprivate-bin node\nwhitelist /code/projects\n" > /etc/firejail/sboxuser.profile
|
|
||||||
|
|
||||||
# RUN echo '#!/bin/bash\nexec firejail --private=/projects --noprofile node dist/index.js' > /start.sh
|
|
||||||
RUN echo '#!/bin/bash\nexec firejail --private=/code/projects --noprofile --net=none --whitelist=/code/projects node dist/index.js' > /start.sh
|
|
||||||
RUN chmod +x /start.sh
|
|
||||||
|
|
||||||
USER sboxuser
|
USER sboxuser
|
||||||
|
|
||||||
EXPOSE 8000
|
# user namespace mapping
|
||||||
EXPOSE 4000
|
|
||||||
|
|
||||||
CMD ["/start.sh"]
|
EXPOSE 8000
|
||||||
|
EXPOSE 5173
|
||||||
|
|
||||||
|
CMD [ "node", "dist/index.js" ]
|
@ -34,50 +34,55 @@ export default function Editor({
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
startServer(sandboxData.id).then((response) => {
|
// startServer(sandboxData.id).then((response) => {
|
||||||
if (!response.success) {
|
// if (!response.success) {
|
||||||
toast.error(response.message);
|
// toast.error(response.message);
|
||||||
setDidFail(true);
|
// setDidFail(true);
|
||||||
} else {
|
// } else {
|
||||||
setIsServiceRunning(true);
|
// setIsServiceRunning(true);
|
||||||
|
|
||||||
checkServiceStatus(sandboxData.id)
|
// checkServiceStatus(sandboxData.id)
|
||||||
.then(() => {
|
// .then(() => {
|
||||||
setIsDeploymentActive(true);
|
// setIsDeploymentActive(true);
|
||||||
|
|
||||||
getTaskIp(sandboxData.id)
|
// getTaskIp(sandboxData.id)
|
||||||
.then((ip) => {
|
// .then((ip) => {
|
||||||
setTaskIp(ip);
|
// setTaskIp(ip);
|
||||||
})
|
// })
|
||||||
.catch(() => {
|
// .catch(() => {
|
||||||
setDidFail(true);
|
// setDidFail(true);
|
||||||
toast.error("An error occurred while getting your server IP.");
|
// toast.error("An error occurred while getting your server IP.");
|
||||||
});
|
// });
|
||||||
})
|
// })
|
||||||
.catch(() => {
|
// .catch(() => {
|
||||||
toast.error("An error occurred while initializing your server.");
|
// toast.error("An error occurred while initializing your server.");
|
||||||
setDidFail(true);
|
// setDidFail(true);
|
||||||
});
|
// });
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
if (didFail) return <Loading didFail={didFail} />;
|
// if (didFail) return <Loading didFail={didFail} />;
|
||||||
if (!isServiceRunning || !isDeploymentActive || !taskIp)
|
// if (!isServiceRunning || !isDeploymentActive || !taskIp)
|
||||||
return (
|
// return (
|
||||||
<Loading
|
// <Loading
|
||||||
text="Creating sandbox resources"
|
// text="Creating sandbox resources"
|
||||||
description={
|
// description={
|
||||||
isDeploymentActive
|
// isDeploymentActive
|
||||||
? "Preparing server networking..."
|
// ? "Preparing server networking..."
|
||||||
: isServiceRunning
|
// : isServiceRunning
|
||||||
? "Initializing server, this could take a minute..."
|
// ? "Initializing server, this could take a minute..."
|
||||||
: "Requesting your server creation..."
|
// : "Requesting your server creation..."
|
||||||
}
|
// }
|
||||||
/>
|
// />
|
||||||
);
|
// );
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<CodeEditor ip={taskIp} userData={userData} sandboxData={sandboxData} />
|
<CodeEditor
|
||||||
|
ip={"localhost"}
|
||||||
|
// ip={taskIp}
|
||||||
|
userData={userData}
|
||||||
|
sandboxData={sandboxData}
|
||||||
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user