@@ -65,6 +65,8 @@ const DIST_FOLDER = join(process.cwd(), 'dist/browser');
6565// Set path fir IIIF viewer.
6666const IIIF_VIEWER = join ( process . cwd ( ) , 'dist/iiif' ) ;
6767
68+ const miradorHtml = join ( IIIF_VIEWER , '/mirador/index.html' ) ;
69+
6870const indexHtml = join ( DIST_FOLDER , 'index.html' ) ;
6971
7072const cookieParser = require ( 'cookie-parser' ) ;
@@ -86,8 +88,10 @@ const _window = domino.createWindow(indexHtml);
8688// The REST server base URL
8789const REST_BASE_URL = environment . rest . ssrBaseUrl || environment . rest . baseUrl ;
8890
91+ const IIIF_ALLOWED_ORIGINS = environment . rest . allowedOrigins || [ ] ;
92+
8993// Assign the DOM window and document objects to the global object
90- ( _window as any ) . screen = { deviceXDPI : 0 , logicalXDPI : 0 } ;
94+ ( _window as any ) . screen = { deviceXDPI : 0 , logicalXDPI : 0 } ;
9195( global as any ) . window = _window ;
9296( global as any ) . document = _window . document ;
9397( global as any ) . navigator = _window . navigator ;
@@ -231,6 +235,35 @@ export function app() {
231235 */
232236 router . use ( '/iiif' , express . static ( IIIF_VIEWER , { index : false } ) ) ;
233237
238+ /*
239+ * Adapt headers to allow embedding of IIIF viewer in authorized pages
240+ */
241+ server . get ( '/iiif/mirador/index.html' , ( req , res ) => {
242+ const referer = req . headers . referer ;
243+
244+ if ( referer && ! referer . startsWith ( '/' ) ) {
245+ try {
246+ const origin = new URL ( referer ) . origin ;
247+ if ( IIIF_ALLOWED_ORIGINS . includes ( origin ) ) {
248+ console . info ( 'Found allowed origin, setting headers for IIIF viewer' ) ;
249+ // CORS header
250+ res . setHeader ( 'Access-Control-Allow-Origin' , origin ) ;
251+ // CSP for iframe embedding
252+ res . setHeader ( 'Content-Security-Policy' , `frame-ancestors ${ origin } ;` ) ;
253+ console . info ( 'Headers have been set ' , res . getHeader ( 'Access-Control-Allow-Origin' ) , res . getHeader ( 'Content-Security-Policy' ) ) ;
254+ }
255+ } catch ( error ) {
256+ console . error ( 'An error occurred setting security headers in response:' , error . message ) ;
257+ }
258+ }
259+
260+ res . sendFile ( miradorHtml , ( err ) => {
261+ if ( err ) {
262+ res . status ( 500 ) . send ( 'Internal Server Error' ) ;
263+ }
264+ } ) ;
265+ } ) ;
266+
234267 /**
235268 * Checking server status
236269 */
@@ -286,6 +319,11 @@ function serverSideRender(req, res, sendToUser: boolean = true) {
286319 originUrl : environment . ui . baseUrl ,
287320 requestUrl : req . originalUrl ,
288321 } , ( err , data ) => {
322+
323+ if ( res . writableEnded || res . headersSent || res . finished ) {
324+ return ;
325+ }
326+
289327 if ( hasNoValue ( err ) && hasValue ( data ) ) {
290328 // Replace REST URL with UI URL
291329 if ( environment . universal . replaceRestUrl && REST_BASE_URL !== environment . rest . baseUrl ) {
@@ -644,10 +682,10 @@ function start() {
644682 * The callback function to serve client health check requests
645683 */
646684function clientHealthCheck ( req , res ) {
647- const isServerHealthy = true ;
648- if ( isServerHealthy ) {
649- res . status ( 200 ) . json ( { status : 'UP' } ) ;
650- }
685+ const isServerHealthy = true ;
686+ if ( isServerHealthy ) {
687+ res . status ( 200 ) . json ( { status : 'UP' } ) ;
688+ }
651689}
652690
653691/*
@@ -665,6 +703,8 @@ function healthCheck(req, res) {
665703 } ) ;
666704 } ) ;
667705}
706+
707+
668708// Webpack will replace 'require' with '__webpack_require__'
669709// '__non_webpack_require__' is a proxy to Node 'require'
670710// The below code is to ensure that the server is run only when not requiring the bundle.
0 commit comments