mirror of
https://github.com/ancsemi/Haven.git
synced 2026-11-07 14:36:33 +00:00
- Database, .env, certs, and uploads now stored outside the code directory - Auto-migration moves existing data from old locations on first launch - SSL certs auto-detected in data dir (no .env config needed) - New src/paths.js module as single source of truth for all data paths - HAVEN_DATA_DIR env var for custom data location override - Updated Start Haven.bat, start.sh, README, GUIDE, .env.example - Bumped version to 1.1.0
94 lines
3.0 KiB
JavaScript
94 lines
3.0 KiB
JavaScript
/**
|
|
* Haven — Centralised data-directory resolution
|
|
*
|
|
* All user data (database, .env, certs, uploads) lives OUTSIDE the
|
|
* application folder so the code directory can never accidentally
|
|
* leak personal data — even if someone copies the whole folder,
|
|
* force-adds files, or pushes to a public repo.
|
|
*
|
|
* Locations:
|
|
* Windows : %APPDATA%\Haven\ (e.g. C:\Users\you\AppData\Roaming\Haven)
|
|
* Linux : ~/.haven/
|
|
* macOS : ~/.haven/
|
|
*
|
|
* Override : set HAVEN_DATA_DIR env var to any absolute path.
|
|
*/
|
|
|
|
const path = require('path');
|
|
const fs = require('fs');
|
|
const os = require('os');
|
|
|
|
function getDataDir() {
|
|
// Allow explicit override via environment variable
|
|
if (process.env.HAVEN_DATA_DIR) {
|
|
const custom = path.resolve(process.env.HAVEN_DATA_DIR);
|
|
fs.mkdirSync(custom, { recursive: true });
|
|
return custom;
|
|
}
|
|
|
|
let base;
|
|
if (process.platform === 'win32') {
|
|
// %APPDATA% → C:\Users\<user>\AppData\Roaming
|
|
base = path.join(process.env.APPDATA || path.join(os.homedir(), 'AppData', 'Roaming'), 'Haven');
|
|
} else {
|
|
// Linux / macOS → ~/.haven
|
|
base = path.join(os.homedir(), '.haven');
|
|
}
|
|
|
|
fs.mkdirSync(base, { recursive: true });
|
|
return base;
|
|
}
|
|
|
|
// Pre-computed paths for convenience
|
|
const DATA_DIR = getDataDir();
|
|
const DB_PATH = path.join(DATA_DIR, 'haven.db');
|
|
const ENV_PATH = path.join(DATA_DIR, '.env');
|
|
const CERTS_DIR = path.join(DATA_DIR, 'certs');
|
|
const UPLOADS_DIR = path.join(DATA_DIR, 'uploads');
|
|
|
|
// Ensure sub-directories exist
|
|
fs.mkdirSync(CERTS_DIR, { recursive: true });
|
|
fs.mkdirSync(UPLOADS_DIR, { recursive: true });
|
|
|
|
// ── One-time migration: move data from old project-dir locations ─────
|
|
const PROJECT_ROOT = path.join(__dirname, '..');
|
|
|
|
function migrateFile(oldRel, newAbs) {
|
|
const oldAbs = path.join(PROJECT_ROOT, oldRel);
|
|
if (fs.existsSync(oldAbs) && !fs.existsSync(newAbs)) {
|
|
try {
|
|
fs.copyFileSync(oldAbs, newAbs);
|
|
fs.unlinkSync(oldAbs);
|
|
console.log(`📦 Migrated ${oldRel} → ${newAbs}`);
|
|
} catch { /* silent — might lack permissions */ }
|
|
}
|
|
}
|
|
|
|
function migrateDir(oldRel, newDir) {
|
|
const oldAbs = path.join(PROJECT_ROOT, oldRel);
|
|
if (fs.existsSync(oldAbs)) {
|
|
try {
|
|
const entries = fs.readdirSync(oldAbs);
|
|
for (const entry of entries) {
|
|
if (entry === '.gitkeep') continue;
|
|
const src = path.join(oldAbs, entry);
|
|
const dst = path.join(newDir, entry);
|
|
if (!fs.existsSync(dst) && fs.statSync(src).isFile()) {
|
|
fs.copyFileSync(src, dst);
|
|
fs.unlinkSync(src);
|
|
console.log(`📦 Migrated ${oldRel}/${entry} → ${dst}`);
|
|
}
|
|
}
|
|
} catch { /* silent */ }
|
|
}
|
|
}
|
|
|
|
migrateFile('haven.db', DB_PATH);
|
|
migrateFile('haven.db-shm', DB_PATH + '-shm');
|
|
migrateFile('haven.db-wal', DB_PATH + '-wal');
|
|
migrateFile('.env', ENV_PATH);
|
|
migrateDir('certs', CERTS_DIR);
|
|
migrateDir('public/uploads', UPLOADS_DIR);
|
|
|
|
module.exports = { getDataDir, DATA_DIR, DB_PATH, ENV_PATH, CERTS_DIR, UPLOADS_DIR };
|