ssb: base de multicuenta y arreglo de las rutas fijas a ~/.ssb
ssb_config pasa a derivar la cuenta de OASIS_ACCOUNT. Como ssb-config construye la
ruta desde el appname y gui.js saca el socket de config.path, cambiar ese literal
arrastra de forma coherente el almacen, la base de datos, los blobs, el secret y el
socket. Sin la variable se usa 'ssb', asi que las instalaciones existentes siguen en
~/.ssb y no notan nada.
El nombre se valida contra [a-zA-Z0-9][a-zA-Z0-9_-]{0,31} y cae a 'ssb' si no encaja.
No es de adorno: acaba en rutas de fichero y hay operaciones destructivas detras.
Comprobado que OASIS_ACCOUNT=../../etc no sale de sitio.
statePath separa tambien por cuenta cuando se usa OASIS_STATE_DIR. Sin eso, dos
identidades compartirian el estado que 0.9.5 empezo a guardar ahi, que es justo el
camino a partir el registro.
Y el arreglo que importa: doce sitios construian la ruta como os.homedir() + '/.ssb'
en vez de usar la de la cuenta. El peor era panicmode_model, que con varias
identidades habria borrado la equivocada; tambien exportmode y legacy_model, que
habrian exportado o restaurado la identidad de otra cuenta. Los de lectura
—main_models, stats_model y backend.js con gossip.json y ebt— habrian mirado siempre
la cuenta por defecto.
Falta la parte visible: el selector de identidad y el reinicio del proceso al
cambiar. Esta base es la que hacia falta para que eso no sea peligroso.
Verificado: con OASIS_ACCOUNT sin definir la ruta sigue siendo ~/.ssb; con 'trabajo'
pasa a ~/.trabajo; con un valor con .. o espacios se rechaza. Diez rutas OK con la
app en marcha, incluidas /peers y /stats, que son las que leen esos ficheros.
This commit is contained in:
parent
f80b2e04f0
commit
f354069af7
7 changed files with 39 additions and 21 deletions
|
|
@ -3507,7 +3507,7 @@ router
|
|||
});
|
||||
};
|
||||
try {
|
||||
const gossipPathLocal = path.join(os.homedir(), '.ssb', 'gossip.json');
|
||||
const gossipPathLocal = path.join(require('../server/ssb_config').path, 'gossip.json');
|
||||
let gossip = [];
|
||||
try { gossip = JSON.parse(await promisesFs.readFile(gossipPathLocal, 'utf8')); } catch (_) {}
|
||||
if (Array.isArray(gossip)) {
|
||||
|
|
@ -8770,9 +8770,9 @@ router
|
|||
if (pubKey) {
|
||||
try {
|
||||
const os = require('os'), fsx = require('fs'), px = require('path');
|
||||
const gossip = JSON.parse(fsx.readFileSync(px.join(os.homedir(), '.ssb', 'gossip.json'), 'utf8') || '[]');
|
||||
const gossip = JSON.parse(fsx.readFileSync(px.join(require('../server/ssb_config').path, 'gossip.json'), 'utf8') || '[]');
|
||||
let unfollowed = [];
|
||||
try { unfollowed = JSON.parse(fsx.readFileSync(px.join(os.homedir(), '.ssb', 'gossip_unfollowed.json'), 'utf8') || '[]'); } catch (_) {}
|
||||
try { unfollowed = JSON.parse(fsx.readFileSync(px.join(require('../server/ssb_config').path, 'gossip_unfollowed.json'), 'utf8') || '[]'); } catch (_) {}
|
||||
const activePub = Array.isArray(gossip) && gossip.some(p => p && p.key === pubKey) && !unfollowed.some(u => u && u.key === pubKey);
|
||||
if (activePub) { ctx.redirect('/invites?flash=alreadyFederated'); return; }
|
||||
} catch (_) {}
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@ const archiver = require('../server/node_modules/archiver');
|
|||
module.exports = {
|
||||
exportSSB: async (outputPath) => {
|
||||
try {
|
||||
const homeDir = os.homedir();
|
||||
const ssbPath = path.join(homeDir, '.ssb');
|
||||
// se exporta la cuenta activa, no siempre la de por defecto
|
||||
const ssbPath = require('../server/ssb_config').path;
|
||||
const output = fs.createWriteStream(outputPath);
|
||||
const archive = archiver('zip', {
|
||||
zlib: { level: 9 }
|
||||
|
|
|
|||
|
|
@ -49,8 +49,8 @@ module.exports = {
|
|||
exportData: async (password) => {
|
||||
try {
|
||||
const pw = normalizePassword(password);
|
||||
const homeDir = os.homedir();
|
||||
const secretFilePath = path.join(homeDir, '.ssb', 'secret');
|
||||
// identidad de la cuenta activa
|
||||
const secretFilePath = path.join(require('../server/ssb_config').path, 'secret');
|
||||
if (!fs.existsSync(secretFilePath)) {
|
||||
throw new Error(".ssb/secret file doesn't exist");
|
||||
}
|
||||
|
|
@ -78,8 +78,8 @@ module.exports = {
|
|||
} catch (_) {
|
||||
throw new Error('Wrong password or corrupt backup file.');
|
||||
}
|
||||
const homeDir = os.homedir();
|
||||
const ssbDir = path.join(homeDir, '.ssb');
|
||||
// identidad de la cuenta activa
|
||||
const ssbDir = require('../server/ssb_config').path;
|
||||
fs.mkdirSync(ssbDir, { recursive: true });
|
||||
const secretPath = path.join(ssbDir, 'secret');
|
||||
if (fs.existsSync(secretPath)) {
|
||||
|
|
|
|||
|
|
@ -66,8 +66,8 @@ const configure = (...customOptions) =>
|
|||
Object.assign({}, defaultOptions, ...customOptions);
|
||||
|
||||
// PEERS
|
||||
const ebtDir = path.join(os.homedir(), '.ssb', 'ebt');
|
||||
const unfollowedPath = path.join(os.homedir(), '.ssb', 'gossip_unfollowed.json');
|
||||
const ebtDir = path.join(require('../server/ssb_config').path, 'ebt');
|
||||
const unfollowedPath = path.join(require('../server/ssb_config').path, 'gossip_unfollowed.json');
|
||||
|
||||
async function loadPeersFromEbt() {
|
||||
let result = [];
|
||||
|
|
@ -789,7 +789,7 @@ models.meta = {
|
|||
discovered: async () => {
|
||||
const ssb = await cooler.open();
|
||||
const snapshot = await ssb.conn.dbPeers();
|
||||
const gossipPath = path.join(os.homedir(), '.ssb', 'gossip.json');
|
||||
const gossipPath = path.join(require('../server/ssb_config').path, 'gossip.json');
|
||||
let gossipMap = new Map();
|
||||
try {
|
||||
const gossipData = JSON.parse(await fs.readFile(gossipPath, 'utf8'));
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@ const path = require('path');
|
|||
module.exports = {
|
||||
removeSSB: async () => {
|
||||
try {
|
||||
const homeDir = os.homedir();
|
||||
const ssbPath = path.join(homeDir, '.ssb');
|
||||
// ruta de la cuenta activa: con varias identidades, ~/.ssb fijo borraria otra
|
||||
const ssbPath = require('../server/ssb_config').path;
|
||||
await fs.promises.rm(ssbPath, { recursive: true, force: true });
|
||||
} catch (error) {
|
||||
throw new Error("Error deleting data: " + error.message);
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ function readAddrMap() {
|
|||
|
||||
const listPubsFromEbt = () => {
|
||||
try {
|
||||
const ebtDir = path.join(os.homedir(), '.ssb', 'ebt');
|
||||
const ebtDir = path.join(require('../server/ssb_config').path, 'ebt');
|
||||
const files = fs.readdirSync(ebtDir);
|
||||
return files.filter(f => f.endsWith('.ed25519'));
|
||||
} catch {
|
||||
|
|
@ -428,12 +428,12 @@ module.exports = ({ cooler, tribeCrypto, tribesModel }) => {
|
|||
|
||||
const inhabitants = new Set(allMsgs.map(m => m.value.author)).size;
|
||||
|
||||
const secretStat = fs.statSync(`${os.homedir()}/.ssb/secret`);
|
||||
const secretStat = fs.statSync((require('../server/ssb_config').path + '/secret'));
|
||||
const createdAt = secretStat.birthtime.toLocaleString();
|
||||
|
||||
const folderSize = getFolderSize(`${os.homedir()}/.ssb`);
|
||||
const flumeSize = getFolderSize(`${os.homedir()}/.ssb/flume`);
|
||||
const blobsSize = getFolderSize(`${os.homedir()}/.ssb/blobs`);
|
||||
const folderSize = getFolderSize((require('../server/ssb_config').path + ''));
|
||||
const flumeSize = getFolderSize((require('../server/ssb_config').path + '/flume'));
|
||||
const blobsSize = getFolderSize((require('../server/ssb_config').path + '/blobs'));
|
||||
|
||||
const allTs = scopedMsgs.map(m => m.value.timestamp || 0).filter(Boolean);
|
||||
const lastTs = allTs.length ? Math.max(...allTs) : 0;
|
||||
|
|
|
|||
|
|
@ -11,7 +11,21 @@ const i = argv.indexOf('--');
|
|||
const conf = argv.slice(i + 1);
|
||||
const cliArgs = ~i ? argv.slice(0, i) : argv;
|
||||
|
||||
let config = Config('ssb', minimist(conf));
|
||||
// Nombre de la cuenta: define donde vive todo (~/.<cuenta>) y de ahi cuelgan el
|
||||
// secret, la base de datos, los blobs y el socket. Sin la variable se usa 'ssb',
|
||||
// que es lo de siempre, asi que las instalaciones existentes no notan nada.
|
||||
//
|
||||
// Se valida a proposito: este nombre acaba en rutas de fichero y hay operaciones
|
||||
// destructivas (el modo panico borra el directorio de la cuenta) que no deben poder
|
||||
// apuntar fuera de sitio.
|
||||
const ACCOUNT_RE = /^[a-zA-Z0-9][a-zA-Z0-9_-]{0,31}$/;
|
||||
const rawAccount = process.env.OASIS_ACCOUNT || 'ssb';
|
||||
const account = ACCOUNT_RE.test(rawAccount) ? rawAccount : 'ssb';
|
||||
if (account !== rawAccount) {
|
||||
console.error(`[oasis] OASIS_ACCOUNT no valido (${rawAccount}); se usa 'ssb'`);
|
||||
}
|
||||
|
||||
let config = Config(account, minimist(conf));
|
||||
config = { ...config, ...configData };
|
||||
|
||||
const debug = process.argv.includes('--debug') || process.env.OASIS_DEBUG === '1' || process.env.OASIS_DEBUG === 'true';
|
||||
|
|
@ -23,8 +37,12 @@ const megabyte = Math.pow(2, 20);
|
|||
config.blobs = config.blobs || {};
|
||||
config.blobs.max = 50 * megabyte;
|
||||
|
||||
config.account = account;
|
||||
|
||||
config.statePath = (name) => {
|
||||
if (process.env.OASIS_STATE_DIR) return path.join(process.env.OASIS_STATE_DIR, name);
|
||||
// El directorio externo se separa por cuenta: sin esto dos identidades
|
||||
// compartirian estado, que es justo lo que hay que evitar.
|
||||
if (process.env.OASIS_STATE_DIR) return path.join(process.env.OASIS_STATE_DIR, account, name);
|
||||
return config.path ? path.join(config.path, name) : null;
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue