diff --git a/src/servers/api/email/email-db.ts b/src/servers/api/email/email-db.ts index 1b0256d9..cf911946 100644 --- a/src/servers/api/email/email-db.ts +++ b/src/servers/api/email/email-db.ts @@ -82,7 +82,12 @@ export function openEmailDb(email: string): Database { db.exec(SCHEMA_TABLES); migrate(db); db.exec(SCHEMA_INDEXES); - chmodSync(dbPath, 0o666); + // Try to chmod, but don't crash if permission denied (e.g., file owned by different user) + try { + chmodSync(dbPath, 0o666); + } catch (err) { + // File exists with correct permissions, or owned by another user - that's fine + } return db; } diff --git a/src/servers/api/users/provision.ts b/src/servers/api/users/provision.ts index 507c5576..e62f1398 100644 --- a/src/servers/api/users/provision.ts +++ b/src/servers/api/users/provision.ts @@ -48,9 +48,10 @@ export async function provisionLinuxUser(email: string, username: string): Promi } // Set ownership and permissions on user data directory - // chmod 770 so the service user (in the user's group) can read/write for background jobs + // chmod 775 so the service user (in the user's group) can read/write for background jobs + // The service user is added to the group below, so group permissions (rwx) are needed run(['sudo', 'chown', '-R', `${shellUsername}:${shellUsername}`, userRoot]); - run(['sudo', 'chmod', '770', userRoot]); + run(['sudo', 'chmod', '-R', '775', userRoot]); // Recursive chmod to fix all subdirectories // Add the service user to the new user's group so server jobs can access user data const serviceUser = process.env.USER ?? ''; @@ -74,8 +75,9 @@ export async function provisionLinuxUser(email: string, username: string): Promi const settingsContent = await Bun.file(settingsFile).text(); await Bun.write(join(claudeDir, 'settings.json'), settingsContent); - // Fix ownership after seeding + // Fix ownership and permissions after seeding run(['sudo', 'chown', '-R', `${shellUsername}:${shellUsername}`, userRoot]); + run(['sudo', 'chmod', '-R', '775', userRoot]); console.log(`[provision] provisioning complete for ${shellUsername}`); return true;