Exosphere is a set of small, modular, self-hostable community tools built on the AT Protocol. app.exosphere.site
7
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix: update pds on sphere module toggling

Hugo 9ea4cf47 e4936130

+40 -25
+27 -7
packages/core/src/sphere/api/modules.ts
··· 1 + import type { Context } from "hono"; 1 2 import { Hono } from "hono"; 2 3 import { z } from "zod"; 3 4 import { and, eq } from "../../db/drizzle.ts"; 4 5 import { getDb } from "../../db/index.ts"; 5 - import { sphereModules } from "../../db/schema/index.ts"; 6 + import { sphereModules, type spheres } from "../../db/schema/index.ts"; 6 7 import { requireAuth, type AuthEnv } from "../../auth/index.ts"; 7 - import { getActiveMemberRole, isAdminOrOwner } from "../operations.ts"; 8 + import { putPdsRecord } from "../../pds.ts"; 8 9 import { enableModuleSchema } from "../schemas.ts"; 9 10 import { findSphere, getEnabledModules, formatModules } from "./helpers.ts"; 10 11 12 + const SPHERE_COLLECTION = "site.exosphere.sphere" as const; 13 + 14 + type Sphere = typeof spheres.$inferSelect; 15 + 16 + /** Sync the sphere declaration (including modules) to the owner's PDS. */ 17 + async function syncSpherePds(c: Context<AuthEnv>, sphere: Sphere) { 18 + const modules = getEnabledModules(sphere.id).map((m) => m.moduleName); 19 + await putPdsRecord(c.var.session, SPHERE_COLLECTION, "self", { 20 + name: sphere.name, 21 + description: sphere.description ?? undefined, 22 + visibility: sphere.visibility, 23 + writeAccess: sphere.writeAccess, 24 + modules, 25 + createdAt: sphere.createdAt, 26 + }); 27 + } 28 + 11 29 export function createModuleRoutes(availableModules: string[]) { 12 30 const app = new Hono<AuthEnv>(); 13 31 ··· 31 49 return c.json({ error: "Sphere not found" }, 404); 32 50 } 33 51 34 - const role = getActiveMemberRole(sphere.id, c.var.did); 35 - if (!isAdminOrOwner(role)) { 52 + if (c.var.did !== sphere.ownerDid) { 36 53 return c.json({ error: "Forbidden" }, 403); 37 54 } 38 55 ··· 58 75 .onConflictDoNothing() 59 76 .run(); 60 77 78 + await syncSpherePds(c, sphere); 79 + 61 80 return c.json({ 62 81 modules: formatModules(getEnabledModules(sphere.id)), 63 82 }); 64 83 }); 65 84 66 85 // Disable module 67 - app.delete("/:handle/modules/:moduleName", requireAuth, (c) => { 86 + app.delete("/:handle/modules/:moduleName", requireAuth, async (c) => { 68 87 const sphere = findSphere(c.req.param("handle")); 69 88 if (!sphere) { 70 89 return c.json({ error: "Sphere not found" }, 404); 71 90 } 72 91 73 - const role = getActiveMemberRole(sphere.id, c.var.did); 74 - if (!isAdminOrOwner(role)) { 92 + if (c.var.did !== sphere.ownerDid) { 75 93 return c.json({ error: "Forbidden" }, 403); 76 94 } 77 95 ··· 84 102 ), 85 103 ) 86 104 .run(); 105 + 106 + await syncSpherePds(c, sphere); 87 107 88 108 return c.json({ 89 109 modules: formatModules(getEnabledModules(sphere.id)),
+13 -18
packages/core/src/sphere/api/spheres.ts
··· 6 6 import { requireAuth, optionalAuth, type AuthEnv } from "../../auth/index.ts"; 7 7 import { putPdsRecord, generateRkey } from "../../pds.ts"; 8 8 import { createSphereSchema, updateSphereSchema } from "../schemas.ts"; 9 - import { getActiveMemberRole, isAdminOrOwner } from "../operations.ts"; 9 + import { getActiveMemberRole } from "../operations.ts"; 10 10 import { findSphere, getEnabledModules, formatModules } from "./helpers.ts"; 11 11 12 12 const SPHERE_COLLECTION = "site.exosphere.sphere"; ··· 199 199 return c.json({ error: "Sphere not found" }, 404); 200 200 } 201 201 202 - const role = getActiveMemberRole(sphere.id, c.var.did); 203 - if (!isAdminOrOwner(role)) { 202 + if (c.var.did !== sphere.ownerDid) { 204 203 return c.json({ error: "Forbidden" }, 403); 205 204 } 206 205 ··· 221 220 if (updates.writeAccess !== undefined) set.writeAccess = updates.writeAccess; 222 221 223 222 // Sync Sphere declaration to owner's PDS 224 - // Only the owner can update the PDS record (it lives on their repo) 225 - if (c.var.did === sphere.ownerDid) { 226 - const session = c.var.session; 227 - const modules = getEnabledModules(sphere.id).map((m) => m.moduleName); 228 - const pdsUri = await putPdsRecord(session, SPHERE_COLLECTION, "self", { 229 - name: updates.name ?? sphere.name, 230 - description: updates.description ?? sphere.description ?? undefined, 231 - visibility: updates.visibility ?? sphere.visibility, 232 - writeAccess: updates.writeAccess ?? sphere.writeAccess, 233 - modules, 234 - createdAt: sphere.createdAt, 235 - }); 236 - if (pdsUri && !sphere.pdsUri) { 237 - set.pdsUri = pdsUri; 238 - } 223 + const modules = getEnabledModules(sphere.id).map((m) => m.moduleName); 224 + const pdsUri = await putPdsRecord(c.var.session, SPHERE_COLLECTION, "self", { 225 + name: updates.name ?? sphere.name, 226 + description: updates.description ?? sphere.description ?? undefined, 227 + visibility: updates.visibility ?? sphere.visibility, 228 + writeAccess: updates.writeAccess ?? sphere.writeAccess, 229 + modules, 230 + createdAt: sphere.createdAt, 231 + }); 232 + if (pdsUri && !sphere.pdsUri) { 233 + set.pdsUri = pdsUri; 239 234 } 240 235 241 236 getDb().update(spheres).set(set).where(eq(spheres.id, sphere.id)).run();