Commit 1f022e9a authored by Robert Knight's avatar Robert Knight

Enable third-party authorities to globally disable annotation share links

In the context of the LMS app, the client is embedded inside a Via iframe, which
is inside an LMS app iframe, which is inside Canvas. There is currently no
mechanism in place to propagate the focused annotation down the frame hierarchy.
As a result, share links show up but do not work.

As a simple way to resolve that for an initial version of the LMS app, provide
it with a way to globally disable annotation share links.

In future we may move this responsibility to the "h" service, so that the
availability (or not) of share links is correctly reflected in h API responses.

Part of https://github.com/hypothesis/product-backlog/issues/843
parent 8ed3c575
...@@ -156,7 +156,9 @@ loads. ...@@ -156,7 +156,9 @@ loads.
items in the array are ignored. items in the array are ignored.
Each item in the :option:`services` array should be an object describing an Each item in the :option:`services` array should be an object describing an
annotation service, with the following keys: annotation service.
Required keys:
.. option:: apiUrl .. option:: apiUrl
...@@ -179,12 +181,12 @@ loads. ...@@ -179,12 +181,12 @@ loads.
:ref:`Generating authorization grant tokens` for how to generate grant :ref:`Generating authorization grant tokens` for how to generate grant
tokens for the `hypothes.is <https://hypothes.is/>`_ service. tokens for the `hypothes.is <https://hypothes.is/>`_ service.
.. option:: icon Optional keys:
``String|null``. The URL to an image for the annotation service. This .. option:: enableShareLinks
image will appear to the left of the name of the currently selected
group. The image should be suitable for display at 16x16px and the ``boolean``. A flag indicating whether annotation cards should show links
recommended format is SVG. that take the user to see an annotation in context. (Default: ``true``).
.. option:: groups .. option:: groups
...@@ -195,6 +197,13 @@ loads. ...@@ -195,6 +197,13 @@ loads.
This can be useful in contexts where it is important that annotations This can be useful in contexts where it is important that annotations
are made in a particular group. are made in a particular group.
.. option:: icon
``String|null``. The URL to an image for the annotation service. This
image will appear to the left of the name of the currently selected
group. The image should be suitable for display at 16x16px and the
recommended format is SVG.
.. option:: onLoginRequest .. option:: onLoginRequest
``function``. A JavaScript function that the Hypothesis client will ``function``. A JavaScript function that the Hypothesis client will
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
const annotationMetadata = require('../annotation-metadata'); const annotationMetadata = require('../annotation-metadata');
const events = require('../events'); const events = require('../events');
const { isThirdPartyUser } = require('../util/account-id'); const { isThirdPartyUser } = require('../util/account-id');
const serviceConfig = require('../service-config');
const isNew = annotationMetadata.isNew; const isNew = annotationMetadata.isNew;
const isReply = annotationMetadata.isReply; const isReply = annotationMetadata.isReply;
...@@ -23,6 +24,23 @@ function updateModel(annotation, changes, permissions) { ...@@ -23,6 +24,23 @@ function updateModel(annotation, changes, permissions) {
}); });
} }
/**
* Return true if share links are globally enabled.
*
* Share links will only be shown on annotation cards if this is true and if
* these links are included in API responses.
*/
function shouldEnableShareLinks(settings) {
const serviceConfig_ = serviceConfig(settings);
if (serviceConfig_ === null) {
return true;
}
if (typeof serviceConfig_.enableShareLinks !== 'boolean') {
return true;
}
return serviceConfig_.enableShareLinks;
}
// @ngInject // @ngInject
function AnnotationController( function AnnotationController(
$document, $rootScope, $scope, $timeout, $window, analytics, store, $document, $rootScope, $scope, $timeout, $window, analytics, store,
...@@ -32,6 +50,8 @@ function AnnotationController( ...@@ -32,6 +50,8 @@ function AnnotationController(
const self = this; const self = this;
let newlyCreatedByHighlightButton; let newlyCreatedByHighlightButton;
const enableShareLinks = shouldEnableShareLinks(settings);
/** Save an annotation to the server. */ /** Save an annotation to the server. */
function save(annot) { function save(annot) {
let saved; let saved;
...@@ -487,7 +507,7 @@ function AnnotationController( ...@@ -487,7 +507,7 @@ function AnnotationController(
}; };
this.incontextLink = function () { this.incontextLink = function () {
if (self.annotation.links) { if (enableShareLinks && self.annotation.links) {
return self.annotation.links.incontext || return self.annotation.links.incontext ||
self.annotation.links.html || self.annotation.links.html ||
''; '';
......
...@@ -1164,6 +1164,22 @@ describe('annotation', function() { ...@@ -1164,6 +1164,22 @@ describe('annotation', function() {
const controller = createDirective(annotation).controller; const controller = createDirective(annotation).controller;
assert.equal(controller.incontextLink(), ''); assert.equal(controller.incontextLink(), '');
}); });
[true, false].forEach(enableShareLinks => {
it('does not render links if share links are globally disabled', () => {
const annotation = Object.assign({}, fixtures.defaultAnnotation(), {
links: {
incontext: 'https://hpt.is/deadbeef',
},
});
fakeSettings.services = [{
enableShareLinks,
}];
const controller = createDirective(annotation).controller;
const hasIncontextLink = controller.incontextLink() === annotation.links.incontext;
assert.equal(hasIncontextLink, enableShareLinks);
});
});
}); });
it('renders quotes as plain text', function () { it('renders quotes as plain text', function () {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment