-
{{ data.data }}
+
+
+
+
+
+ {{ presetUser.preset.name }}
+ Default
+
+ Created by {{ presetUser.preset.createdBy }}
+
+
+
+ {{ presetUser.preset.iceServers.length }} ICE Server{{
+ presetUser.preset.iceServers.length === 1 ? "" : "s"
+ }}
+ configured
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/pages/presets/new.vue b/app/pages/presets/new.vue
index b3e4478..06e03db 100644
--- a/app/pages/presets/new.vue
+++ b/app/pages/presets/new.vue
@@ -1,157 +1,11 @@
-
-
- Ice Servers (JSON)
-
-
-
-
-
-
-
-
-
-
- Set as default preset
-
-
- This preset will be selected by default on the preset selector.
-
-
-
-
-
-
-
-
-
-
+
diff --git a/server/api/presets/[id].delete.ts b/server/api/presets/[id].delete.ts
new file mode 100644
index 0000000..4becd40
--- /dev/null
+++ b/server/api/presets/[id].delete.ts
@@ -0,0 +1,34 @@
+import { eq, and } from "drizzle-orm";
+import { db } from "~/lib/db";
+import { presets, presetUsers } from "~/lib/db/schema";
+
+export default defineEventHandler(async (event) => {
+ const { isAuthenticated, userId } = event.context.auth();
+
+ if (!isAuthenticated || !userId) {
+ throw createError({ statusCode: 401, statusMessage: "Unauthorized" });
+ }
+
+ const id = getRouterParam(event, "id");
+ if (!id) {
+ throw createError({ statusCode: 400, statusMessage: "Missing preset ID" });
+ }
+
+ // Check if the user is the creator of the preset
+ const preset = await db.query.presets.findFirst({
+ where: eq(presets.id, id),
+ });
+
+ if (!preset) {
+ throw createError({ statusCode: 404, statusMessage: "Preset not found" });
+ }
+
+ if (preset.createdBy !== userId) {
+ throw createError({ statusCode: 403, statusMessage: "Forbidden: You can only delete your own presets" });
+ }
+
+ // Delete the preset (cascades to presetUsers)
+ await db.delete(presets).where(eq(presets.id, id));
+
+ return { success: true };
+});
diff --git a/server/api/presets/[id].get.ts b/server/api/presets/[id].get.ts
new file mode 100644
index 0000000..496cf2d
--- /dev/null
+++ b/server/api/presets/[id].get.ts
@@ -0,0 +1,39 @@
+import { eq } from "drizzle-orm";
+import { db } from "~/lib/db";
+import { presets, presetUsers } from "~/lib/db/schema";
+
+export default defineEventHandler(async (event) => {
+ const { isAuthenticated, userId } = event.context.auth();
+
+ if (!isAuthenticated || !userId) {
+ throw createError({ statusCode: 401, statusMessage: "Unauthorized" });
+ }
+
+ const id = getRouterParam(event, "id");
+ if (!id) {
+ throw createError({ statusCode: 400, statusMessage: "Missing preset ID" });
+ }
+
+ // Fetch the preset
+ const preset = await db.query.presets.findFirst({
+ where: eq(presets.id, id),
+ });
+
+ if (!preset) {
+ throw createError({ statusCode: 404, statusMessage: "Preset not found" });
+ }
+
+ // Check if user has access (either creator or has it in their presetUsers)
+ const userPreset = await db.query.presetUsers.findFirst({
+ where: eq(presetUsers.presetId, id),
+ });
+
+ if (preset.createdBy !== userId && (!userPreset || userPreset.userId !== userId)) {
+ throw createError({ statusCode: 403, statusMessage: "Forbidden" });
+ }
+
+ return {
+ success: true,
+ data: preset,
+ };
+});
diff --git a/server/api/presets/[id].put.ts b/server/api/presets/[id].put.ts
new file mode 100644
index 0000000..2e4e39b
--- /dev/null
+++ b/server/api/presets/[id].put.ts
@@ -0,0 +1,59 @@
+import { eq, and } from "drizzle-orm";
+import { db } from "~/lib/db";
+import { presets, presetUsers } from "~/lib/db/schema";
+
+export default defineEventHandler(async (event) => {
+ const { isAuthenticated, userId } = event.context.auth();
+
+ if (!isAuthenticated || !userId) {
+ throw createError({ statusCode: 401, statusMessage: "Unauthorized" });
+ }
+
+ const id = getRouterParam(event, "id");
+ if (!id) {
+ throw createError({ statusCode: 400, statusMessage: "Missing preset ID" });
+ }
+
+ const body = await readBody(event);
+
+ // Verify ownership
+ const preset = await db.query.presets.findFirst({
+ where: eq(presets.id, id),
+ });
+
+ if (!preset) {
+ throw createError({ statusCode: 404, statusMessage: "Preset not found" });
+ }
+
+ if (preset.createdBy !== userId) {
+ throw createError({ statusCode: 403, statusMessage: "Forbidden: You can only edit your own presets" });
+ }
+
+ // Update preset
+ await db.update(presets)
+ .set({
+ name: body.name,
+ iceServers: JSON.stringify(body.iceServers),
+ })
+ .where(eq(presets.id, id));
+
+ // Update default status in presetUsers
+ if (body.default !== undefined) {
+ // If setting as default, first unset all other defaults for this user
+ if (body.default) {
+ await db.update(presetUsers)
+ .set({ isDefault: false })
+ .where(eq(presetUsers.userId, userId));
+ }
+
+ // Update the default status for this preset
+ await db.update(presetUsers)
+ .set({ isDefault: body.default })
+ .where(and(
+ eq(presetUsers.presetId, id),
+ eq(presetUsers.userId, userId)
+ ));
+ }
+
+ return { success: true };
+});