backend: llevar tambien bottombar y legacy/export al router del fork

Quedaban tres rutas propias sueltas dentro de la cadena de upstream:
/settings/bottombar (GET y POST, la personalizacion de la barra inferior) y
/legacy/export en GET, que upstream solo tiene en POST.

Con esto backend.js queda sin ninguna ruta de la rama: 8899 lineas frente a las
9067 de partida, y el unico rastro son las 4 lineas del require de fork_routes
en el array de middleware.

Verificado: el router monta las 11 rutas y backend.js no conserva referencias
a identificadores movidos.
This commit is contained in:
SITO 2026-08-18 21:34:09 +02:00
parent e5e8e53374
commit b3986b12a0
2 changed files with 41 additions and 37 deletions

View file

@ -6162,19 +6162,6 @@ router
ctx.redirect(safeReturnTo(ctx, '/forum', ['/forum']));
}
})
.get('/legacy/export', async (ctx) => {
if (!isLoopbackRequest(ctx)) { ctx.status = 403; ctx.body = ''; return; }
const pw = ctx.query && ctx.query.password;
if (!pw || pw.length < 32) return ctx.redirect('/legacy');
try {
const { filename, data } = await legacyModel.exportData({ password: pw });
ctx.set('Content-Type', 'application/octet-stream');
ctx.set('Content-Disposition', `attachment; filename="${filename}"`);
ctx.set('Content-Length', String(data.length));
ctx.body = data;
try { onboardingModel.markStep('backup'); } catch (_) {}
} catch (error) { sendErrorPage(ctx, error.message); }
})
.post('/legacy/import', koaBody({
multipart: true,
formidable: {
@ -7975,28 +7962,6 @@ router
console.log("oasis@version: running install.sh...", shOut, shErr);
safeRefererRedirect(ctx, '/settings');
})
.get("/settings/bottombar", async (ctx) => {
ctx.body = require("../views/main_views").bottomBarPickerView();
})
.post("/settings/bottombar", koaBody(), async (ctx) => {
const cfg = getConfig();
const MAX = 4;
const body = ctx.request.body || {};
const action = String(body.action || '').trim();
const key = String(body.key || '').trim();
const catalog = require("../views/main_views").PINNABLE_MODULES || [];
let pins = Array.isArray(cfg.bottomBarPins) ? cfg.bottomBarPins.slice() : [];
if (action === 'add') {
if (key && catalog.some(m => m.key === key) && !pins.includes(key) && pins.length < MAX) pins.push(key);
} else if (action === 'remove') {
pins = pins.filter(k => k !== key);
} else if (action === 'clear') {
pins = [];
}
cfg.bottomBarPins = pins.slice(0, MAX);
saveConfig(cfg);
ctx.redirect('/settings/bottombar');
})
.post("/settings/theme", koaBody(), async (ctx) => {
const theme = String(ctx.request.body.theme || "").trim(), cfg = getConfig();
cfg.themes.current = theme || "Dark-SNH";
@ -8691,7 +8656,9 @@ const middleware = [
await next();
},
// rutas propias de la rama (Karvan): fuera de la cadena de upstream
require('./fork_routes')({ cooler, pull, pmModel, checkMod, getViewerId }),
require('./fork_routes')({ cooler, pull, pmModel, checkMod, getViewerId,
getConfig, saveConfig, legacyModel, onboardingModel,
isLoopbackRequest, sendErrorPage }),
routes,
];
const app = http({ host, port, middleware, allowHost: config.allowHost });

View file

@ -17,7 +17,9 @@ const { stripDangerousTags } = require("./sanitizeHtml");
const karvanModel = require('../models/karvan_model')({}); // FORK_IA_UX: salas efímeras en RAM (mensajes temporales + señalización WebRTC)
const { karvanView, karvanRoomView } = require("../views/karvan_view");
module.exports = ({ cooler, pull, pmModel, checkMod, getViewerId }) => {
module.exports = ({ cooler, pull, pmModel, checkMod, getViewerId,
getConfig, saveConfig, legacyModel, onboardingModel,
isLoopbackRequest, sendErrorPage }) => {
// FORK_IA_UX Fase 2 (cross-device): relay de MENSAJES de Karvan por privados SSB. Funciona vía un pub
// (el privado se replica al otro móvil); los SIGNAL de WebRTC NO se relayan (serían demasiados/lentos por el log).
// No toca el arranque del SSB. Ingesta por stream EN VIVO (no polling) → eficiente.
@ -155,6 +157,41 @@ async function karvanInviteAuthor(roomId) {
if (!checkMod(ctx, 'karvanMod')) { ctx.status = 403; ctx.body = { error: 'off' }; return; }
const r = karvanModel.getSignals(ctx.params.id, { forId: ctx.query.for || '', since: ctx.query.since || 0 });
ctx.body = r || { signals: [], members: [] };
})
.get("/settings/bottombar", async (ctx) => {
ctx.body = require("../views/main_views").bottomBarPickerView();
})
.post("/settings/bottombar", koaBody(), async (ctx) => {
const cfg = getConfig();
const MAX = 4;
const body = ctx.request.body || {};
const action = String(body.action || '').trim();
const key = String(body.key || '').trim();
const catalog = require("../views/main_views").PINNABLE_MODULES || [];
let pins = Array.isArray(cfg.bottomBarPins) ? cfg.bottomBarPins.slice() : [];
if (action === 'add') {
if (key && catalog.some(m => m.key === key) && !pins.includes(key) && pins.length < MAX) pins.push(key);
} else if (action === 'remove') {
pins = pins.filter(k => k !== key);
} else if (action === 'clear') {
pins = [];
}
cfg.bottomBarPins = pins.slice(0, MAX);
saveConfig(cfg);
ctx.redirect('/settings/bottombar');
})
.get('/legacy/export', async (ctx) => {
if (!isLoopbackRequest(ctx)) { ctx.status = 403; ctx.body = ''; return; }
const pw = ctx.query && ctx.query.password;
if (!pw || pw.length < 32) return ctx.redirect('/legacy');
try {
const { filename, data } = await legacyModel.exportData({ password: pw });
ctx.set('Content-Type', 'application/octet-stream');
ctx.set('Content-Disposition', `attachment; filename="${filename}"`);
ctx.set('Content-Length', String(data.length));
ctx.body = data;
try { onboardingModel.markStep('backup'); } catch (_) {}
} catch (error) { sendErrorPage(ctx, error.message); }
});
return forkRouter.routes();