fix: resolve email database permission errors for multi-user setups

Issues:
1. User directories created with chmod 770 (too restrictive)
   - Prevents service user from reading/writing even though in group
   - Changed to chmod 775 (recursive) to allow group access

2. openEmailDb tries to chmod file it may not own
   - If file owned by different user (e.g., andrepadez), chmod fails
   - Wrapped chmodSync in try/catch to gracefully skip

Changes:
- src/servers/api/users/provision.ts:
  * Changed chmod 770 → 775 (owner/group rwx, others rx)
  * Applied recursively to all subdirectories
  * Added chmod after seeding files to ensure consistency

- src/servers/api/email/email-db.ts:
  * Wrapped chmodSync in try/catch
  * Logs silently skip if file not owned by current process
  * Database still works even if chmod fails

Fixes /email endpoint 500 errors for users with email data.
This commit is contained in:
2026-03-04 02:56:35 +00:00
parent 698c1ff297
commit cd1bce5a8a
2 changed files with 11 additions and 4 deletions
+6 -1
View File
@@ -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;
}
+5 -3
View File
@@ -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;