fix(spaces): use correct EncryptID internal URL for member operations

The spaces module was defaulting to http://localhost:3000 for EncryptID
API calls, which resolves to the rspace container itself (both run on
port 3000). Changed to http://encryptid:3000 matching server/index.ts.
Also improved error surfacing in /members/add endpoint.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Jeff Emmett 2026-03-16 20:50:13 -07:00
parent d999c98b98
commit 97636235bf
1 changed files with 11 additions and 5 deletions

View File

@ -70,6 +70,8 @@ import { syncServer } from "./sync-instance";
import { seedTemplateShapes } from "./seed-template"; import { seedTemplateShapes } from "./seed-template";
import { notify, notifySpaceAdmins } from "./notification-service"; import { notify, notifySpaceAdmins } from "./notification-service";
const ENCRYPTID_URL = process.env.ENCRYPTID_INTERNAL_URL || "http://encryptid:3000";
// ── Role types and helpers ── // ── Role types and helpers ──
export type SpaceRoleString = 'viewer' | 'member' | 'moderator' | 'admin'; export type SpaceRoleString = 'viewer' | 'member' | 'moderator' | 'admin';
@ -2122,7 +2124,7 @@ spaces.post("/:slug/invite", async (c) => {
const expiresAt = Date.now() + 7 * 24 * 60 * 60 * 1000; // 7 days const expiresAt = Date.now() + 7 * 24 * 60 * 60 * 1000; // 7 days
// Store invite (call EncryptID API internally) // Store invite (call EncryptID API internally)
const ENCRYPTID_URL = process.env.ENCRYPTID_INTERNAL_URL || "http://localhost:3000";
try { try {
await fetch(`${ENCRYPTID_URL}/api/spaces/${slug}/invites`, { await fetch(`${ENCRYPTID_URL}/api/spaces/${slug}/invites`, {
method: "POST", method: "POST",
@ -2192,12 +2194,16 @@ spaces.post("/:slug/members/add", async (c) => {
} }
// Look up user via EncryptID // Look up user via EncryptID
const ENCRYPTID_URL = process.env.ENCRYPTID_INTERNAL_URL || "http://localhost:3000";
const lookupRes = await fetch(`${ENCRYPTID_URL}/api/users/lookup?username=${encodeURIComponent(body.username)}`, { const lookupRes = await fetch(`${ENCRYPTID_URL}/api/users/lookup?username=${encodeURIComponent(body.username)}`, {
headers: { "Authorization": `Bearer ${token}` }, headers: { "Authorization": `Bearer ${token}` },
}); });
if (!lookupRes.ok) { if (!lookupRes.ok) {
return c.json({ error: "User not found" }, 404); const errBody = await lookupRes.json().catch(() => ({})) as Record<string, unknown>;
if (lookupRes.status === 404) {
return c.json({ error: `User "${body.username}" not found` }, 404);
}
return c.json({ error: (errBody.error as string) || "User lookup failed" }, lookupRes.status as any);
} }
const user = await lookupRes.json() as { did: string; username: string; displayName: string }; const user = await lookupRes.json() as { did: string; username: string; displayName: string };
@ -2251,7 +2257,7 @@ spaces.post("/:slug/invite/accept", async (c) => {
if (!body.inviteToken) return c.json({ error: "inviteToken is required" }, 400); if (!body.inviteToken) return c.json({ error: "inviteToken is required" }, 400);
// Accept via EncryptID API // Accept via EncryptID API
const ENCRYPTID_URL = process.env.ENCRYPTID_INTERNAL_URL || "http://localhost:3000";
const acceptRes = await fetch(`${ENCRYPTID_URL}/api/invites/${body.inviteToken}/accept`, { const acceptRes = await fetch(`${ENCRYPTID_URL}/api/invites/${body.inviteToken}/accept`, {
method: "POST", method: "POST",
headers: { "Authorization": `Bearer ${token}` }, headers: { "Authorization": `Bearer ${token}` },
@ -2292,7 +2298,7 @@ spaces.get("/:slug/invites", async (c) => {
} }
// Fetch from EncryptID // Fetch from EncryptID
const ENCRYPTID_URL = process.env.ENCRYPTID_INTERNAL_URL || "http://localhost:3000";
try { try {
const res = await fetch(`${ENCRYPTID_URL}/api/spaces/${slug}/invites`, { const res = await fetch(`${ENCRYPTID_URL}/api/spaces/${slug}/invites`, {
headers: { "Authorization": `Bearer ${token}` }, headers: { "Authorization": `Bearer ${token}` },