11import Fastify from 'fastify' ;
2+ import { readFile } from 'fs/promises' ;
3+ import { join , dirname } from 'path' ;
4+ import { fileURLToPath } from 'url' ;
25import { handleGet , handleHead , handlePut , handleDelete , handleOptions , handlePatch } from './handlers/resource.js' ;
36import { handlePost , handleCreatePod } from './handlers/container.js' ;
47import { getCorsHeaders } from './ldp/headers.js' ;
58import { authorize , handleUnauthorized } from './auth/middleware.js' ;
69import { notificationsPlugin } from './notifications/index.js' ;
710import { idpPlugin } from './idp/index.js' ;
811
12+ const __dirname = dirname ( fileURLToPath ( import . meta. url ) ) ;
13+
914/**
1015 * Create and configure Fastify server
1116 * @param {object } options - Server options
@@ -31,7 +36,9 @@ export function createServer(options = {}) {
3136 const subdomainsEnabled = options . subdomains ?? false ;
3237 const baseDomain = options . baseDomain || null ;
3338 // Mashlib data browser is OFF by default
39+ // mashlibCdn: if true, load from CDN; if false, serve locally
3440 const mashlibEnabled = options . mashlib ?? false ;
41+ const mashlibCdn = options . mashlibCdn ?? false ;
3542 const mashlibVersion = options . mashlibVersion ?? '2.0.0' ;
3643
3744 // Set data root via environment variable if provided
@@ -70,6 +77,7 @@ export function createServer(options = {}) {
7077 fastify . decorateRequest ( 'baseDomain' , null ) ;
7178 fastify . decorateRequest ( 'podName' , null ) ;
7279 fastify . decorateRequest ( 'mashlibEnabled' , null ) ;
80+ fastify . decorateRequest ( 'mashlibCdn' , null ) ;
7381 fastify . decorateRequest ( 'mashlibVersion' , null ) ;
7482 fastify . addHook ( 'onRequest' , async ( request ) => {
7583 request . connegEnabled = connegEnabled ;
@@ -78,6 +86,7 @@ export function createServer(options = {}) {
7886 request . subdomainsEnabled = subdomainsEnabled ;
7987 request . baseDomain = baseDomain ;
8088 request . mashlibEnabled = mashlibEnabled ;
89+ request . mashlibCdn = mashlibCdn ;
8190 request . mashlibVersion = mashlibVersion ;
8291
8392 // Extract pod name from subdomain if enabled
@@ -122,11 +131,13 @@ export function createServer(options = {}) {
122131 // Authorization hook - check WAC permissions
123132 // Skip for pod creation endpoint (needs special handling)
124133 fastify . addHook ( 'preHandler' , async ( request , reply ) => {
125- // Skip auth for pod creation, OPTIONS, IdP routes, and well-known endpoints
134+ // Skip auth for pod creation, OPTIONS, IdP routes, mashlib, and well-known endpoints
135+ const mashlibPaths = [ '/mashlib.min.js' , '/mash.css' , '/841.mashlib.min.js' ] ;
126136 if ( request . url === '/.pods' ||
127137 request . method === 'OPTIONS' ||
128138 request . url . startsWith ( '/idp/' ) ||
129- request . url . startsWith ( '/.well-known/' ) ) {
139+ request . url . startsWith ( '/.well-known/' ) ||
140+ mashlibPaths . some ( p => request . url === p || request . url . startsWith ( p + '.' ) ) ) {
130141 return ;
131142 }
132143
@@ -144,6 +155,30 @@ export function createServer(options = {}) {
144155 // Pod creation endpoint
145156 fastify . post ( '/.pods' , handleCreatePod ) ;
146157
158+ // Mashlib static files (served from root like NSS does)
159+ if ( mashlibEnabled ) {
160+ const mashlibDir = join ( __dirname , 'mashlib-local' , 'dist' ) ;
161+ const mashlibFiles = {
162+ '/mashlib.min.js' : { file : 'mashlib.min.js' , type : 'application/javascript' } ,
163+ '/mashlib.min.js.map' : { file : 'mashlib.min.js.map' , type : 'application/json' } ,
164+ '/mash.css' : { file : 'mash.css' , type : 'text/css' } ,
165+ '/mash.css.map' : { file : 'mash.css.map' , type : 'application/json' } ,
166+ '/841.mashlib.min.js' : { file : '841.mashlib.min.js' , type : 'application/javascript' } ,
167+ '/841.mashlib.min.js.map' : { file : '841.mashlib.min.js.map' , type : 'application/json' }
168+ } ;
169+
170+ for ( const [ path , config ] of Object . entries ( mashlibFiles ) ) {
171+ fastify . get ( path , async ( request , reply ) => {
172+ try {
173+ const content = await readFile ( join ( mashlibDir , config . file ) ) ;
174+ return reply . type ( config . type ) . send ( content ) ;
175+ } catch {
176+ return reply . code ( 404 ) . send ( { error : 'Not Found' } ) ;
177+ }
178+ } ) ;
179+ }
180+ }
181+
147182 // LDP routes - using wildcard routing
148183 fastify . get ( '/*' , handleGet ) ;
149184 fastify . head ( '/*' , handleHead ) ;
0 commit comments