Skip to content

Commit ea509c0

Browse files
feat: remove mashlib-local and solidos-ui coupling
- Remove local mashlib serving (--mashlib local mode) - Remove --solidos-ui option and all solidosUiEnabled references - Keep --mashlib-cdn and --mashlib-module as supported modes - JSS no longer bundles or distributes mashlib Fixes JavaScriptSolidServer#220
1 parent 7444cdd commit ea509c0

5 files changed

Lines changed: 24 additions & 105 deletions

File tree

bin/jss.js

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,10 @@ program
5353
.option('--subdomains', 'Enable subdomain-based pods (XSS protection)')
5454
.option('--no-subdomains', 'Disable subdomain-based pods')
5555
.option('--base-domain <domain>', 'Base domain for subdomain pods (e.g., "example.com")')
56-
.option('--mashlib', 'Enable Mashlib data browser (local mode, requires mashlib in node_modules)')
57-
.option('--mashlib-cdn', 'Enable Mashlib data browser (CDN mode, no local files needed)')
56+
.option('--mashlib-cdn', 'Enable Mashlib data browser (CDN mode)')
5857
.option('--mashlib-module <url>', 'Enable ES module data browser from a URL')
5958
.option('--no-mashlib', 'Disable Mashlib data browser')
6059
.option('--mashlib-version <version>', 'Mashlib version for CDN mode (default: 2.0.0)')
61-
.option('--solidos-ui', 'Enable modern Nextcloud-style UI (requires --mashlib)')
6260
.option('--git', 'Enable Git HTTP backend (clone/push support)')
6361
.option('--no-git', 'Disable Git HTTP backend')
6462
.option('--nostr', 'Enable Nostr relay')
@@ -143,7 +141,6 @@ program
143141
mashlibCdn: config.mashlibCdn,
144142
mashlibVersion: config.mashlibVersion,
145143
mashlibModule: config.mashlibModule,
146-
solidosUi: config.solidosUi,
147144
git: config.git,
148145
nostr: config.nostr,
149146
nostrPath: config.nostrPath,
@@ -193,7 +190,6 @@ program
193190
console.log(` Mashlib: local (data browser enabled)`);
194191
}
195192
if (config.mashlibModule) console.log(` Mashlib module: ${config.mashlibModule}`);
196-
if (config.solidosUi) console.log(' SolidOS UI: enabled (modern interface)');
197193
if (config.git) console.log(' Git: enabled (clone/push support)');
198194
if (config.nostr) console.log(` Nostr: enabled (${config.nostrPath})`);
199195
if (config.webrtc) console.log(` WebRTC: enabled (${config.webrtcPath || '/.webrtc'})`);

src/auth/middleware.js

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { checkAccess, getRequiredMode } from '../wac/checker.js';
99
import { AccessMode } from '../wac/parser.js';
1010
import * as storage from '../storage/filesystem.js';
1111
import { getEffectiveUrlPath } from '../utils/url.js';
12-
import { generateDatabrowserHtml, generateModuleDatabrowserHtml, generateSolidosUiHtml } from '../mashlib/index.js';
12+
import { generateDatabrowserHtml, generateModuleDatabrowserHtml } from '../mashlib/index.js';
1313

1414
/**
1515
* Build a resource URL for WAC checking, normalizing path-based pod access
@@ -148,12 +148,9 @@ export function handleUnauthorized(request, reply, isAuthenticated, wacAllow, au
148148
// If mashlib is enabled, serve mashlib instead of static error page
149149
// Mashlib has built-in login functionality via panes.runDataBrowser()
150150
if (request.mashlibEnabled) {
151-
// Use SolidOS UI if enabled, ES module if configured, otherwise classic mashlib
152-
const html = request.solidosUiEnabled
153-
? generateSolidosUiHtml()
154-
: request.mashlibModule
155-
? generateModuleDatabrowserHtml(request.mashlibModule)
156-
: generateDatabrowserHtml(request.url, request.mashlibCdn ? request.mashlibVersion : null);
151+
const html = request.mashlibModule
152+
? generateModuleDatabrowserHtml(request.mashlibModule)
153+
: generateDatabrowserHtml(request.url, request.mashlibCdn ? request.mashlibVersion : null);
157154
return reply.code(statusCode).type('text/html').send(html);
158155
}
159156
return reply.code(statusCode).type('text/html').send(getErrorPage(statusCode, isAuthenticated, request));

src/config.js

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,6 @@ export const defaults = {
4343
mashlibVersion: '2.0.0',
4444
mashlibModule: false,
4545

46-
// SolidOS UI (modern Nextcloud-style interface)
47-
solidosUi: false,
48-
4946
// Git HTTP backend
5047
git: false,
5148

@@ -137,7 +134,6 @@ const envMap = {
137134
JSS_MASHLIB_CDN: 'mashlibCdn',
138135
JSS_MASHLIB_VERSION: 'mashlibVersion',
139136
JSS_MASHLIB_MODULE: 'mashlibModule',
140-
JSS_SOLIDOS_UI: 'solidosUi',
141137
JSS_GIT: 'git',
142138
JSS_NOSTR: 'nostr',
143139
JSS_NOSTR_PATH: 'nostrPath',
@@ -331,8 +327,7 @@ export function printConfig(config) {
331327
console.log(` Notifications: ${config.notifications}`);
332328
console.log(` IdP: ${config.idp ? (config.idpIssuer || 'enabled') : 'disabled'}`);
333329
console.log(` Subdomains: ${config.subdomains ? (config.baseDomain || 'enabled') : 'disabled'}`);
334-
console.log(` Mashlib: ${config.mashlibModule ? `module (${config.mashlibModule})` : config.mashlibCdn ? `CDN v${config.mashlibVersion}` : config.mashlib ? 'local' : 'disabled'}`);
335-
console.log(` SolidOS UI: ${config.solidosUi ? 'enabled' : 'disabled'}`);
330+
console.log(` Mashlib: ${config.mashlibModule ? `module (${config.mashlibModule})` : config.mashlibCdn ? `CDN v${config.mashlibVersion}` : 'disabled'}`);
336331
if (config.pay) {
337332
console.log(` Pay: ${config.payCost} sat/req`);
338333
if (config.payToken) console.log(` Token: ${config.payToken} @ ${config.payRate} sat/token`);

src/handlers/resource.js

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import {
1515
} from '../rdf/conneg.js';
1616
import { emitChange } from '../notifications/events.js';
1717
import { checkIfMatch, checkIfNoneMatchForGet, checkIfNoneMatchForWrite } from '../utils/conditional.js';
18-
import { generateDatabrowserHtml, generateModuleDatabrowserHtml, generateSolidosUiHtml, shouldServeMashlib } from '../mashlib/index.js';
18+
import { generateDatabrowserHtml, generateModuleDatabrowserHtml, shouldServeMashlib } from '../mashlib/index.js';
1919

2020
/**
2121
* Live reload script - injected into HTML when --live-reload is enabled
@@ -230,12 +230,9 @@ export async function handleGet(request, reply) {
230230

231231
// Check if we should serve Mashlib data browser for containers
232232
if (shouldServeMashlib(request, request.mashlibEnabled, 'application/ld+json')) {
233-
// Use SolidOS UI if enabled, ES module if configured, otherwise classic mashlib
234-
const html = request.solidosUiEnabled
235-
? generateSolidosUiHtml()
236-
: request.mashlibModule
237-
? generateModuleDatabrowserHtml(request.mashlibModule)
238-
: generateDatabrowserHtml(resourceUrl, request.mashlibCdn ? request.mashlibVersion : null);
233+
const html = request.mashlibModule
234+
? generateModuleDatabrowserHtml(request.mashlibModule)
235+
: generateDatabrowserHtml(resourceUrl, request.mashlibCdn ? request.mashlibVersion : null);
239236
const headers = getAllHeaders({
240237
isContainer: true,
241238
etag: stats.etag,
@@ -309,12 +306,9 @@ export async function handleGet(request, reply) {
309306
// Check if we should serve Mashlib data browser
310307
// Only for RDF resources when Accept: text/html is requested
311308
if (shouldServeMashlib(request, request.mashlibEnabled, storedContentType)) {
312-
// Use SolidOS UI if enabled, ES module if configured, otherwise classic mashlib
313-
const html = request.solidosUiEnabled
314-
? generateSolidosUiHtml()
315-
: request.mashlibModule
316-
? generateModuleDatabrowserHtml(request.mashlibModule)
317-
: generateDatabrowserHtml(resourceUrl, request.mashlibCdn ? request.mashlibVersion : null);
309+
const html = request.mashlibModule
310+
? generateModuleDatabrowserHtml(request.mashlibModule)
311+
: generateDatabrowserHtml(resourceUrl, request.mashlibCdn ? request.mashlibVersion : null);
318312
const headers = getAllHeaders({
319313
isContainer: false,
320314
etag: stats.etag,

src/server.js

Lines changed: 11 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -62,14 +62,11 @@ export function createServer(options = {}) {
6262
const subdomainsEnabled = options.subdomains ?? false;
6363
const baseDomain = options.baseDomain || null;
6464
// Mashlib data browser is OFF by default
65-
// mashlibCdn: if true, load from CDN; if false, serve locally
66-
// mashlibModule: URL to ES module entry point (alternative to classic mashlib)
65+
// mashlibCdn: load from CDN; mashlibModule: URL to ES module entry point
6766
const mashlibModule = options.mashlibModule ?? false;
68-
const mashlibEnabled = options.mashlib || !!mashlibModule;
6967
const mashlibCdn = options.mashlibCdn ?? false;
68+
const mashlibEnabled = mashlibCdn || !!mashlibModule;
7069
const mashlibVersion = options.mashlibVersion ?? '2.0.0';
71-
// SolidOS UI (modern Nextcloud-style interface) - requires mashlib
72-
const solidosUiEnabled = options.solidosUi ?? false;
7370
// Git HTTP backend is OFF by default - enables clone/push via git protocol
7471
const gitEnabled = options.git ?? false;
7572
// Nostr relay is OFF by default
@@ -179,7 +176,6 @@ export function createServer(options = {}) {
179176
fastify.decorateRequest('mashlibCdn', null);
180177
fastify.decorateRequest('mashlibVersion', null);
181178
fastify.decorateRequest('mashlibModule', null);
182-
fastify.decorateRequest('solidosUiEnabled', null);
183179
fastify.decorateRequest('defaultQuota', null);
184180
fastify.decorateRequest('config', null);
185181
fastify.decorateRequest('liveReloadEnabled', null);
@@ -193,7 +189,6 @@ export function createServer(options = {}) {
193189
request.mashlibCdn = mashlibCdn;
194190
request.mashlibVersion = mashlibVersion;
195191
request.mashlibModule = mashlibModule;
196-
request.solidosUiEnabled = solidosUiEnabled;
197192
request.defaultQuota = defaultQuota;
198193
request.config = { public: options.public, readOnly: options.readOnly };
199194
request.liveReloadEnabled = liveReloadEnabled;
@@ -410,7 +405,7 @@ export function createServer(options = {}) {
410405
// Authorization hook - check WAC permissions
411406
// Skip for pod creation endpoint (needs special handling)
412407
fastify.addHook('preHandler', async (request, reply) => {
413-
// Skip auth for pod creation, OPTIONS, IdP routes, mashlib, solidos-ui, well-known, notifications, nostr, git, and AP
408+
// Skip auth for pod creation, OPTIONS, IdP routes, mashlib, well-known, notifications, nostr, git, and AP
414409
const mashlibPaths = ['/mashlib.min.js', '/mash.css', '/841.mashlib.min.js'];
415410
const apPaths = ['/inbox', '/profile/card/inbox', '/profile/card/outbox', '/profile/card/followers', '/profile/card/following',
416411
'/api/v1/apps', '/api/v1/instance', '/api/v1/accounts/verify_credentials',
@@ -424,7 +419,6 @@ export function createServer(options = {}) {
424419
request.method === 'OPTIONS' ||
425420
request.url.startsWith('/idp/') ||
426421
request.url.startsWith('/.well-known/') ||
427-
request.url.startsWith('/solidos-ui/') ||
428422
(nostrEnabled && request.url.startsWith(nostrPath)) ||
429423
(gitEnabled && isGitRequest(request.url)) ||
430424
(activitypubEnabled && apPaths.some(p => request.url === p || request.url.startsWith(p + '?'))) ||
@@ -464,72 +458,15 @@ export function createServer(options = {}) {
464458
}
465459
}, handleCreatePod);
466460

467-
// Mashlib static files (served from root like NSS does)
468-
if (mashlibEnabled) {
469-
if (mashlibCdn) {
470-
// CDN mode: redirect chunk requests to CDN
471-
// Mashlib uses code splitting, so it loads chunks like 789.mashlib.min.js
472-
const cdnBase = `https://unpkg.com/mashlib@${mashlibVersion}/dist`;
473-
const chunkPattern = /^\/\d+\.mashlib\.min\.js(\.map)?$/;
474-
475-
fastify.addHook('onRequest', async (request, reply) => {
476-
if (chunkPattern.test(request.url)) {
477-
const filename = request.url.split('/').pop();
478-
return reply.redirect(302, `${cdnBase}/${filename}`);
479-
}
480-
});
481-
} else {
482-
// Local mode: serve from local files
483-
const mashlibDir = join(__dirname, 'mashlib-local', 'dist');
484-
const mashlibFiles = {
485-
'/mashlib.min.js': { file: 'mashlib.min.js', type: 'application/javascript' },
486-
'/mashlib.min.js.map': { file: 'mashlib.min.js.map', type: 'application/json' },
487-
'/mash.css': { file: 'mash.css', type: 'text/css' },
488-
'/mash.css.map': { file: 'mash.css.map', type: 'application/json' },
489-
'/841.mashlib.min.js': { file: '841.mashlib.min.js', type: 'application/javascript' },
490-
'/841.mashlib.min.js.map': { file: '841.mashlib.min.js.map', type: 'application/json' }
491-
};
492-
493-
for (const [path, config] of Object.entries(mashlibFiles)) {
494-
fastify.get(path, async (request, reply) => {
495-
try {
496-
const content = await readFile(join(mashlibDir, config.file));
497-
return reply.type(config.type).send(content);
498-
} catch {
499-
return reply.code(404).send({ error: 'Not Found' });
500-
}
501-
});
502-
}
503-
}
504-
}
461+
// Mashlib CDN mode: redirect chunk requests to CDN
462+
if (mashlibEnabled && mashlibCdn) {
463+
const cdnBase = `https://unpkg.com/mashlib@${mashlibVersion}/dist`;
464+
const chunkPattern = /^\/\d+\.mashlib\.min\.js(\.map)?$/;
505465

506-
// SolidOS UI static files (modern Nextcloud-style interface)
507-
// Serves from /solidos-ui/* - requires mashlib to be enabled as well
508-
if (solidosUiEnabled && mashlibEnabled) {
509-
const solidosUiDir = join(__dirname, 'mashlib-local', 'dist', 'solidos-ui');
510-
511-
// Serve all files under /solidos-ui/* path
512-
fastify.get('/solidos-ui/*', async (request, reply) => {
513-
try {
514-
// Get the path after /solidos-ui/
515-
const filePath = request.url.replace('/solidos-ui/', '').split('?')[0];
516-
const fullPath = join(solidosUiDir, filePath);
517-
518-
// Determine content type based on extension
519-
const ext = filePath.split('.').pop()?.toLowerCase();
520-
const contentTypes = {
521-
'js': 'application/javascript',
522-
'css': 'text/css',
523-
'map': 'application/json',
524-
'html': 'text/html'
525-
};
526-
const contentType = contentTypes[ext] || 'application/octet-stream';
527-
528-
const content = await readFile(fullPath);
529-
return reply.type(contentType).send(content);
530-
} catch (err) {
531-
request.log.error(err, 'Failed to serve solidos-ui file');
532-
return reply.code(404).send({ error: 'Not Found' });
466+
fastify.addHook('onRequest', async (request, reply) => {
467+
if (chunkPattern.test(request.url)) {
468+
const filename = request.url.split('/').pop();
469+
return reply.redirect(302, `${cdnBase}/${filename}`);
533470
}
534471
});
535472
}

0 commit comments

Comments
 (0)