Skip to content

Commit

Permalink
Issue #31: Port @kylehuynh205 work to pass auth token to Cantaloupe.
Browse files Browse the repository at this point in the history
  • Loading branch information
alxp committed Sep 15, 2023
1 parent 48b42ab commit e971a6e
Show file tree
Hide file tree
Showing 5 changed files with 138 additions and 1 deletion.
5 changes: 5 additions & 0 deletions islandora_mirador.module
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ function islandora_mirador_theme() {
function template_preprocess_mirador(&$variables) {
$variables['mirador_view_id'] = Html::getUniqueId($variables['mirador_view_id']);

if (!empty(\Drupal::hasService('jwt.authentication.jwt'))) {
$variables['#attached']['drupalSettings']['token'] = \Drupal::service('jwt.authentication.jwt')->generateToken();
}


/**
* @var \Drupal\islandora_mirador\IslandoraMiradorPluginManager
*/
Expand Down
6 changes: 6 additions & 0 deletions islandora_mirador.routing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,9 @@ islandora_mirador.miradorconfig:
_title: 'Mirador Settings'
requirements:
_permission: 'administer site configuration'
islandora_mirador.service_worker:
path: '/islandora_mirador_service_worker'
defaults:
_controller: '\Drupal\islandora_mirador\Controller\ServiceWorkerController::serve'
requirements:
_permission: 'access content'
49 changes: 48 additions & 1 deletion js/mirador_viewer.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,57 @@
attach: function (context, settings) {
Object.entries(settings.mirador.viewers).forEach(entry => {
const [base, values] = entry;
once('mirador-viewer', base, context).forEach(() =>
once('mirador-viewer', base, context, settings).forEach(() => {
if (settings.token !== undefined) {
values["resourceHeaders"] = {
'Authorization': 'Bearer '+ settings.token,
'token': settings.token
};
values["requestPipeline"] = [
(url, options) => ({ ...options, headers: {
"Accept": 'application/ld+json;profile="http://iiif.io/api/presentation/3/context.json"',
'Authorization': 'Bearer '+ settings.token,
'token': settings.token
}})
];
values["osdConfig"] = {
"loadTilesWithAjax": true,
"ajaxHeaders": {
'Authorization': 'Bearer '+ settings.token,
'token': settings.token
}
};
values["requests"] = {
preprocessors: [ // Functions that receive HTTP requests and manipulate them (e.g. to add headers)
// rewrite all info.json requests to add the text/json request header
(url, options) => (url.match('info.json') && { ...options, headers: {
'Authorization': 'Bearer '+ settings.token,
'token': settings.token
}})
],
};

}
Mirador.viewer(values, window.miradorPlugins || {})
}
);
});
if (settings.token !== undefined) {
if ('serviceWorker' in navigator) {
// The Mirador viewer uses img tags for thumbnails so thumbnail image requests
// do not have authorization or token headers. Attach them using a service worker.
window.addEventListener('load', () => {
navigator.serviceWorker
.register('/islandora_mirador_service_worker?token=' + settings.token, { scope: '/' })
.then(registration => {
console.log('ServiceWorker registration successful with scope: ', registration.scope);
})
.catch(err => {
console.log('ServiceWorker registration failed: ', err);
});
});
}
}
},
detach: function (context, settings) {
Object.entries(settings.mirador.viewers).forEach(entry => {
Expand Down
21 changes: 21 additions & 0 deletions js/service_worker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
self.addEventListener('activate', function (event) {
console.log('Service Worker: claiming control...');
return self.clients.claim();
});

self.addEventListener('fetch', function (event) {
if (event.request.destination === "image" && new URL(event.request.url).pathname.startsWith('/cantaloupe/iiif/') && new URL(location).searchParams.has('token')) {
console.log('Service Worker: fetching...');
var token = new URL(location).searchParams.get('token');
event.respondWith(
fetch(event.request, {
headers: {
'Authorization': 'Bearer ' + token,
'token': token
},
mode: "cors",
credentials: "include"
})
);
}
});
58 changes: 58 additions & 0 deletions src/Controller/ServiceWorkerController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php

namespace Drupal\islandora_mirador\Controller;

use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Extension\ExtensionPathResolver;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\BinaryFileResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

/**
* A controller for the Service Worker.
*/
class ServiceWorkerController extends ControllerBase {

/**
* The extension path resolver service.
*
* @var \Drupal\Core\Extension\ExtensionPathResolver
*/
protected $extensionPathResolver;

/**
* Constructs a ServiceWorkerController object.
*
* @param \Drupal\Core\Extension\ExtensionPathResolver $extension_path_resolver
* The extension path resolver service.
*/
public function __construct(ExtensionPathResolver $extension_path_resolver) {
$this->extensionPathResolver = $extension_path_resolver;
}

/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('extension.path.resolver')
);
}

/**
* Adds headers to the HTTP response.
*/
public function serve(Request $request) {
$file_str = $this->extensionPathResolver->getPath('module', 'islandora_mirador') . '/js/service_worker.js';
if (file_exists($file_str)) {
$response = new BinaryFileResponse($file_str, 200);
$response->headers->set('Content-Type', 'application/javascript');
// Allow same origin service worker.
$response->headers->set('Service-Worker-Allowed', '/');
return $response;
}
throw new NotFoundHttpException();
}

}

0 comments on commit e971a6e

Please sign in to comment.