Add CSP compliance to plugins
Change-Id: Ia13082bbad5348c8cbb5f5cb976bfe32c9fe0a27
diff --git a/Changes b/Changes
index 98225df..80b1bc0 100755
--- a/Changes
+++ b/Changes
@@ -15,6 +15,8 @@
- Introduce X-Frame-Options header.
- Introduce X-XSS-Protection header.
- Support CSP in notifications framework.
+ - Fetch plugin configs from JSON file to be
+ CSP compliant.
0.40 2020-12-17
- Modernize ES and fix in-loops.
diff --git a/dev/js/src/api.js b/dev/js/src/api.js
index 75a4e68..cfc0625 100644
--- a/dev/js/src/api.js
+++ b/dev/js/src/api.js
@@ -107,7 +107,15 @@
let url = KorAP.URL + "/corpus?cq=" + encodeURIComponent(cq);
KorAP.API.getJSON(url, cb, "CorpusInfo: " + cq);
};
-
+
+
+ /**
+ * Retrieve a list of all plugin objects to
+ * establish in the frontend.
+ */
+ KorAP.API.getPluginList = function (url, cb) {
+ KorAP.API.getJSON(url, cb, "Plugin-List")
+ };
/**
* General method to retrieve JSON information
diff --git a/dev/js/src/init.js b/dev/js/src/init.js
index ef6dfcf..4f6074f 100644
--- a/dev/js/src/init.js
+++ b/dev/js/src/init.js
@@ -436,28 +436,35 @@
/**
* Initialize Plugin registry.
*/
- let p = KorAP.Plugins;
- if (p && p.length > 0) {
- // Load Plugin Server first
- KorAP.Plugin = pluginClass.create();
+ let pe;
+ if (pe = d.getElementById("kalamar-plugins")) {
+ let url = pe.getAttribute('data-plugins');
+ if (url !== undefined) {
+ KorAP.API.getPluginList(url, function (json) {
+ if (json && json.length > 0) {
+ // Load Plugin Server first
+ KorAP.Plugin = pluginClass.create();
- // Add services container to head
- d.head.appendChild(KorAP.Plugin.element());
+ // Add services container to head
+ d.head.appendChild(KorAP.Plugin.element());
- // Add pipe form
- KorAP.Pipe = pipeClass.create();
- d.getElementById("searchform").appendChild(KorAP.Pipe.element());
-
- try {
-
- // Register all plugins
- p.forEach(i => KorAP.Plugin.register(i));
- }
- catch (e) {
- KorAP.log(0, e);
- }
+ // Add pipe form
+ KorAP.Pipe = pipeClass.create();
+ d.getElementById("searchform").appendChild(KorAP.Pipe.element());
+
+ try {
+
+ // Register all plugins
+ json.forEach(i => KorAP.Plugin.register(i));
+ }
+ catch (e) {
+ KorAP.log(0, e);
+ }
+ }
+ });
+ };
};
-
+
return obj;
});
diff --git a/lib/Kalamar/Plugin/Plugins.pm b/lib/Kalamar/Plugin/Plugins.pm
index 5e2e4a0..73dcdbe 100644
--- a/lib/Kalamar/Plugin/Plugins.pm
+++ b/lib/Kalamar/Plugin/Plugins.pm
@@ -1,5 +1,6 @@
package Kalamar::Plugin::Plugins;
use Mojo::Base 'Mojolicious::Plugin';
+use Mojo::JSON qw'decode_json';
# Register the plugin
sub register {
@@ -15,25 +16,36 @@
# Read default plugins file
my $default = Mojo::File->new($param->{default_plugins});
- my $json_array = $default->slurp;
+ my $json_array = decode_json $default->slurp;
# If any scripts are defined
if ($json_array) {
# TODO:
- # Make this CSP (#72) compliant.
+ # Add user registered plugins as a path
+
+ # TODO:
+ # Add sources to CORS.
# Add default plugins, if exist
+ $app->routes->get('/settings/plugin/list.json')->to(
+ cb => sub {
+ my $c = shift;
+ $c->res->headers->cache_control('no-cache');
+ $c->render(
+ json => $json_array
+ );
+ }
+ )->name('plugin_list');
+
$app->content_block(
scripts => {
- inline => "<script>//<![CDATA[\nKorAP.Plugins=" . $json_array . "\n//]]></script>"
+ inline => q!<span id="kalamar-plugins" ! .
+ q!data-plugins="<%== url_for 'plugin_list' %>"></span>!
}
);
};
};
-
- # TODO:
- # Add user registered plugins as a path
};
@@ -73,7 +85,7 @@
=head2 COPYRIGHT AND LICENSE
-Copyright (C) 2020, L<IDS Mannheim|http://www.ids-mannheim.de/>
+Copyright (C) 2021, L<IDS Mannheim|http://www.ids-mannheim.de/>
Author: L<Nils Diewald|http://nils-diewald.de/>
Kalamar is developed as part of the L<KorAP|http://korap.ids-mannheim.de/>
diff --git a/package.json b/package.json
index 0678630..838d8b6 100755
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
"name": "Kalamar",
"description": "Mojolicious-based Frontend for KorAP",
"license": "BSD-2-Clause",
- "version": "0.41.0",
+ "version": "0.41.1",
"pluginVersion": "0.2.2",
"engines": {
"node": ">=6.0.0"
diff --git a/t/plugin/plugins.t b/t/plugin/plugins.t
index fa5ae91..eb8b2a2 100644
--- a/t/plugin/plugins.t
+++ b/t/plugin/plugins.t
@@ -10,16 +10,16 @@
$temp->spurt(<<SCRIPT);
[{
- 'name' : 'Export',
- 'desc' : 'Exports Kalamar results',
- 'embed' : [{
- 'panel' : 'result',
- 'title' : 'exports KWICs and snippets',
- 'icon' : "\uf019",
- 'classes' : ['button-icon','plugin'],
- 'onClick' : {
- 'action' : 'addWidget',
- 'template' : 'http://localhost:7777/res/export.html'
+ "name" : "Export",
+ "desc" : "Exports Kalamar results",
+ "embed" : [{
+ "panel" : "result",
+ "title" : "exports KWICs and snippets",
+ "icon" : "\uf019",
+ "classes" : ["button-icon","plugin"],
+ "onClick" : {
+ "action" : "addWidget",
+ "template" : "http://localhost:7777/res/export.html"
}
}]
}]
@@ -31,8 +31,17 @@
$t->get_ok('/')
->text_is('h1 span', 'KorAP - Corpus Analysis Platform')
- ->content_like(qr!KorAP\.Plugins\s*=\s*\[!)
- ->content_like(qr!<script>\/\/<\!\[CDATA\[!)
+ ->content_unlike(qr!KorAP\.Plugins\s*=\s*\[!)
+ ->content_unlike(qr!<script>\/\/<\!\[CDATA\[!)
+ ->content_like(qr!<span id="kalamar-plugins" data-plugins="/settings/plugin/list\.json"></span>!)
+ ;
+
+$t->get_ok('/settings/plugin/list.json')
+ ->status_is(200)
+ ->header_is('Content-Type','application/json;charset=UTF-8')
+ ->content_unlike(qr!KorAP\.Plugins=!)
+ ->content_like(qr!button-icon!)
+ ->json_is('/0/embed/0/title','exports KWICs and snippets')
;
done_testing;