Commit b017a5bc authored by Robert Knight's avatar Robert Knight Committed by GitHub

Merge pull request #279 from hypothesis/reorganise-docs

Reorganise docs
parents d28669cc bd33075d
build/
node_modules/
coverage/
docs/_build/
......@@ -19,6 +19,10 @@ test: node_modules/.uptodate
lint: node_modules/.uptodate
npm run lint
.PHONY: docs
docs:
cd docs && make livehtml
################################################################################
build/manifest.json: node_modules/.uptodate
......
# Minimal makefile for Sphinx documentation
#
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build
SPHINXPROJ = HypothesisClient
SOURCEDIR = .
BUILDDIR = _build
# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
.PHONY: help Makefile
livehtml:
sphinx-autobuild -b dirhtml -p 8888 "$(SOURCEDIR)" "$(BUILDDIR)/dirhtml" $(SPHINXOPTS) $(O)
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
../../images/screenshot.png
\ No newline at end of file
# -*- coding: utf-8 -*-
#
# Hypothesis Client documentation build configuration file, created by
# sphinx-quickstart on Thu Mar 9 18:01:59 2017.
#
# This file is execfile()d with the current directory set to its
# containing dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.
import os
# import sys
from recommonmark.parser import CommonMarkParser
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
# sys.path.insert(0, os.path.abspath('.'))
# on_rtd is whether the docs are being built on readthedocs.org (or whether
# someone is building them locally), this line of code grabbed from
# docs.readthedocs.org
on_rtd = os.environ.get('READTHEDOCS', None) == 'True'
# -- General configuration ------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
#
# needs_sphinx = '1.0'
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = ['sphinx.ext.todo', 'sphinx.ext.intersphinx']
intersphinx_mapping = {'h': ('https://h.readthedocs.io/en/latest/', None)}
# Add any paths that contain tempates here, relative to this directory.
templates_path = ['_templates']
source_parsers = {
'.md': CommonMarkParser, # Add Markdown support to Sphinx.
}
# The suffix(es) of source filenames.
# You can specify multiple suffix as a list of string:
#
# source_suffix = ['.rst', '.md']
source_suffix = ['.rst', '.md']
# The master toctree document.
master_doc = 'index'
# General information about the project.
project = u'Hypothesis Client'
copyright = u'2017, Hypothesis Project Contributors'
author = u'Hypothesis Project Contributors'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = u'1.0.0'
# The full version, including alpha/beta/rc tags.
release = u'1.0.0'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language = None
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This patterns also effect to html_static_path and html_extra_path
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
# If true, `todo` and `todoList` produce output, else they produce nothing.
todo_include_todos = True
numfig = True
# -- Options for HTML output ----------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
if not on_rtd: # only import and set the theme if we're building docs locally
import sphinx_rtd_theme
html_theme = 'sphinx_rtd_theme'
html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
# otherwise, readthedocs.org uses their theme by default, so no need to specify it
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#
html_theme_options = {
'display_version': False,
}
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
# -- Options for HTMLHelp output ------------------------------------------
# Output file base name for HTML help builder.
htmlhelp_basename = 'HypothesisClientdoc'
# -- Options for LaTeX output ---------------------------------------------
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
#
# 'papersize': 'letterpaper',
# The font size ('10pt', '11pt' or '12pt').
#
# 'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
#
# 'preamble': '',
# Latex figure (float) alignment
#
# 'figure_align': 'htbp',
}
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
(master_doc, 'HypothesisClient.tex', u'Hypothesis Client Documentation',
u'Hypothesis Project Contributors', 'manual'),
]
# -- Options for manual page output ---------------------------------------
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
(master_doc, 'hypothesisclient', u'Hypothesis Client Documentation',
[author], 1)
]
# -- Options for Texinfo output -------------------------------------------
# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
(master_doc, 'HypothesisClient', u'Hypothesis Client Documentation',
author, 'HypothesisClient', 'One line description of project.',
'Miscellaneous'),
]
Configuring the client
======================
### Configuring the client using JSON
The Hypothesis client can be configured by providing a JSON config object in
the body of the hosting page:
```html
<script type="application/json" class="js-hypothesis-config">
{
"openSidebar": true
}
</script>
<script async src="https://hypothes.is/embed.js"></script>
```
Not all configuration settings can be set in this way, some must be
[set using JavaScript](#configuring-the-client-using-javascript) (see below).
**N.B.** The body of the `.js-hypothesis-config` tag must be [valid
JSON](http://jsonlint.com/) -- invalid JSON will cause the entire config object
to be ignored.
### Configuring the client using JavaScript
Alternatively, the Hypothesis client can be configured from the hosting page by
providing a JavaScript function named `window.hypothesisConfig` that returns
a configuration object. Some configuration settings (for example settings that
register callback or event handler functions) can _only_ be set from
JavaScript:
```html
window.hypothesisConfig = function () {
return {
"openSidebar": true
};
};
```
Config settings
---------------
### Client behavior
These settings configure the behavior and initial state of the client when it
loads.
#### `openLoginForm`
_Boolean_. Controls whether the login panel is automatically opened on startup,
as if the user had clicked "Log in" themselves. (Default: _false_.)
#### `openSidebar`
_Boolean_. Controls whether the sidebar opens automatically on startup.
(Default: _false_.)
#### `showHighlights`
_Boolean_. Controls whether the in-document highlights are shown by default.
(Default: _true_.)
### Annotation services
The `services` setting configures which annotation services the client
connects to (for example to login, retrieve annotations, and save annotations).
By default, if no `services` setting is given, the client connects to the
public Hypothesis service at [hypothes.is](https://hypothes.is).
#### `services`
_Array_. A list of alternative annotation services which the client should
connect to instead of connecting the the public Hypothesis service at
[hypothes.is](https://hypothes.is/).
May optionally include information (in the form of a grant token) about the
identity of the user accounts that the client is logged in to on those
services.
**N.B.** These settings are currently still experimental and may change without
warning.
**N.B.** Currently only one alternative annotation service at a time is
supported - only the first item in this `services` array is used, and any
further items in the array are ignored.
Each item in the `services` array should be an object describing an annotation
service, with the following keys:
* `authority` _String_. The domain name which the annotation service is
associated with.
* `grantToken` _String|null_. An OAuth 2 grant token which the client can
exchange for an access token in order to make authenticated requests to the
service. If _null_, the user will be able to read but not create or modify
annotations. (Default: _null_)
* `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.
* `onLoginRequest` _function_. A JavaScript function that the client will
call in order to login (for example, when the user clicks a login button in
the Hypothesis client's sidebar).
This setting can only be [set using window.hypothesisConfig](#configuring-the-client-using-javascript).
If the hosting page provides an `onLoginRequest` function then the Hypothesis
client will call this function instead of doing its usual procedure for
logging in to the public service at [hypothes.is](https://hypothes.is/).
No arguments are passed to the `onLoginRequest` function.
The `onLoginRequest` function should cause a login procedure for the hosting page
to be performed - for example by redirecting to a login page, or by opening
a popup login window. After a successful login the hosting page should
reload the original page with a non-null `grantToken` for the logged-in user
in the `services` configuration setting.
### Asset and sidebar app location
These settings configure where the client's assets are loaded from.
**N.B.** These settings are currently still experimental and may change without
warning.
#### `assetRoot`
_String_. The root URL from which assets are loaded. This should be set to the
URL where the contents of the `hypothesis` package are hosted, including the
trailing slash. (Default: For production builds:
_https://cdn.hypothes.is/hypothesis/X.Y.Z/_, for development builds:
_http://localhost:3001/hypothesis/X.Y.Z/_. _X.Y.Z_ is the package version from
`package.json`)
#### `sidebarAppUrl`
_String_. The URL for the sidebar application which displays annotations
(Default: _https://hypothes.is/app.html_ . If the `H_SERVICE_URL` env var is
set, defaults to `${H_SERVICE_URL}/app.html`)
# Developing the client
Developing the Client
=====================
Hypothesis is comprised of several components:
This section documents how to setup a development environment for the client,
how to run the client and its tests in a development environment,
client coding standards and how to contribute code to the client.
- A browser-based web app for annotating web pages (this repository)
- A service which stores annotations, user accounts and other data. By default
the client uses the public service at [hypothes.is](https://hypothes.is).
- A browser extension which can add the client to web pages.
Setting up a Client Development Environment
-------------------------------------------
## Prerequisites
Prerequisites
#############
You will need:
* [git](https://git-scm.com/)
* [Node.js](https://nodejs.org/en/) v6+
* `git <https://git-scm.com/>`_
* `Node.js <https://nodejs.org/en/>`_ v6+
## Building
Building
########
To build the client for development:
```sh
git clone 'https://github.com/hypothesis/client.git'
cd client
npm install -g gulp-cli # Tip: if you get a "permission denied" error try
.. code-block:: sh
git clone 'https://github.com/hypothesis/client.git'
cd client
npm install -g gulp-cli # Tip: if you get a "permission denied" error try
# `sudo npm install -g gulp-cli` instead.
make
```
make
You now have a development client built. To run your development client in
a browser you'll need a local copy of either the Hypothesis Chrome extension or
the Hypothesis web service. Follow either the instructions for
[Running the client from the browser extension](#running-the-client-from-the-browser-extension)
or for
[Running the client from the web service](#running-the-client-from-the-web-service)
below.
the Hypothesis web service. Follow either
:ref:`running-from-browser-ext` or :ref:`running-from-web-service` below.
If you're only interested in making changes to the client (and not to the web
service) then running the client from the browser extension is easiest.
## Running the client from the browser extension
.. _running-from-browser-ext:
Running the Client from the Browser Extension
---------------------------------------------
This is the currently easiest way to get your development client running in a
browser. It sets you up to make changes to the client and to the Chrome
extension itself, but not to the web service.
1. Check out the [browser
extension](https://github.com/hypothesis/browser-extension) and follow the
steps in the
[README](https://github.com/hypothesis/browser-extension/blob/master/README.md)
to make it use your local version of the client and the [production
Hypothesis
service](https://github.com/hypothesis/browser-extension/blob/master/docs/building.md).
#. Check out the
`browser extension <https://github.com/hypothesis/browser-extension>`_
and follow the steps in the browser extension's documentation to build the
extension and configure it to use your local version of the client and the
production Hypothesis service.
1. Start the client's development server to rebuild the client whenever it
#. Start the client's development server to rebuild the client whenever it
changes:
```
.. code-block:: sh
gulp watch
```
1. After making changes to the client, you will need to run `make` in the
#. After making changes to the client, you will need to run ``make`` in the
browser extension repo and reload the extension in Chrome to see changes.
You can use [Extensions
Reloader](https://chrome.google.com/webstore/detail/extensions-reloader/fimgfedafeadlieiabdeeaodndnlbhid?hl=en)
You can use
`Extensions Reloader <https://chrome.google.com/webstore/detail/extensions-reloader/fimgfedafeadlieiabdeeaodndnlbhid?hl=en>`_
to make this easier.
## Running the client from the web service
.. _running-from-web-service:
Running the Client From the Web Service
---------------------------------------
This takes longer to setup than
[Running the client from the browser extension](#running-the-client-from-the-browser-extension).
This takes longer to setup than :ref:`running-from-browser-ext`.
You should follow these steps if you want to make changes to the Hypothesis
web service as well as to the client.
First follow the [instructions for setting up a development install of the web
service](http://h.readthedocs.io/en/latest/developing/).
First follow the
`instructions for setting up a development install of the web service <http://h.readthedocs.io/en/latest/developing/>`_.
Once you have a development install of the Hypothesis service set up, you can
configure it to use a local build of the client. **In the client repository**,
run:
```sh
export H_SERVICE_URL=http://localhost:5000
gulp watch
```
.. code-block:: sh
The `H_SERVICE_URL` env var sets the URL of the service which hosts the HTML
entry point for the client's sidebar application.
export H_SERVICE_URL=http://localhost:5000
gulp watch
**In the `hypothesis/h` repository**, set the `CLIENT_URL` env var to tell the
service where to load the client from, before running `make dev`:
**In the `hypothesis/h` repository**, set the :envvar:`CLIENT_URL` env var to
tell the service where to load the client from, before running ``make dev``:
```sh
export CLIENT_URL=http://localhost:3001/hypothesis
make dev
```
.. code-block:: sh
export CLIENT_URL=http://localhost:3001/hypothesis
make dev
Once the client and service are running, you can test it out by visiting:
[http://localhost:3000](http://localhost:3000) or [the Help
page](http://localhost:5000/docs/help) in your browser.
http://localhost:3000 or http://localhost:5000/docs/help in your browser.
You can also load the client into your own web pages by adding:
```html
<script async src="http://localhost:5000/embed.js"></script>
```
.. code-block:: html
<script async src="http://localhost:5000/embed.js"></script>
to the page's HTML. Note that this will only work in pages served via plain
HTTP. If you want to test out the client on pages served via HTTPS then building
the client into a browser extension is the easiest option.
## Running tests
Running the Tests
-----------------
Hypothesis uses Karma and mocha for testing. To run all the tests once, run:
```sh
gulp test
```
.. code-block:: sh
gulp test
To run tests and automatically re-run them whenever any source files change, run:
```sh
gulp test-watch
```
.. code-block:: sh
You can filter the tests which are run by passing `--grep <pattern>` as an
argument to `gulp test`. See the documentation for Mocha's
[grep](https://mochajs.org/#g---grep-pattern) option.
gulp test-watch
You can filter the tests which are run by passing ``--grep <pattern>`` as an
argument to ``gulp test``. See the documentation for Mocha's
`grep <https://mochajs.org/#g---grep-pattern>`_ option.
## Code style
Code Style
----------
### JavaScript
JavaScript
##########
Hypothesis uses ESLint to help maintain style consistency. You can check your
changes for conformance using:
```
make lint
```
.. code-block:: sh
make lint
Many lint errors can be fixed automatically using:
```
./node_modules/.bin/eslint --fix
```
.. code-block:: sh
./node_modules/.bin/eslint --fix
### CSS
CSS
###
Styling is authored in SASS. For guidance on writing CSS for Hypothesis
projects, please see our [CSS
Guide](https://github.com/hypothesis/frontend-toolkit/blob/master/docs/css-style-guide.md).
projects, please see our
`CSS Guide <https://github.com/hypothesis/frontend-toolkit/blob/master/docs/css-style-guide.md>`_.
## Submitting pull requests
Submitting Pull Requests
------------------------
For general guidance on submitting pull requests to Hypothesis projects, please
see the [Contributor's Guide](https://h.readthedocs.io/en/latest/developing/).
see the `Contributor's Guide <https://h.readthedocs.io/en/latest/developing/>`_.
Environment Variables
=====================
This section documents all the environment variables supported by the client's
build tasks.
.. envvar:: H_SERVICE_URL
The URL of the service which hosts the HTML entry point for the client's
sidebar application.
For Developers
==============
This section contains documentation for **developers** contributing code to
the Hypothesis client.
.. toctree::
:maxdepth: 3
developing
security
envvars
# Client security
Client Security
===============
This document is intended to give an overview of the security considerations
which must be kept in mind when working on the Hypothesis client. It outlines
......@@ -6,32 +7,24 @@ the overall security goals for the client, names some risks and attack vectors,
and identifies ways in which code in the client attempts to mitigate those
risks.
### Table of Contents
.. environment-overview:
- [Environment overview](#environment-overview)
- [Threat model](#threat-model)
- [Potential attack vectors](#potential-attack-vectors)
- [Design considerations and defenses](#design-considerations-and-defenses)
- [Same-origin policy protections](#same-origin-policy-protections)
- [Input sanitisation](#input-sanitisation)
- [Transport Layer Security](#transport-layer-security)
- [Clickjacking protections](#clickjacking-protections)
- [Phishing/imitation](#phishingimitation)
Environment Overview
--------------------
## Environment overview
The Hypothesis client is a [single-page web
application](https://en.wikipedia.org/wiki/Single-page_application) which runs
in a browser. Typically, it interacts with some annotated content (the page on
which annotations are made) and an annotation service running on a remote
server.
The Hypothesis client is a
`single-page web application <https://en.wikipedia.org/wiki/Single-page_application>`_
which runs in a browser. Typically, it interacts with some annotated content
(the page on which annotations are made) and an annotation service running on a
remote server.
At different times, users interact directly with the client, with the annotated
content, and with the annotation service. Data can flow in both directions: from
the annotated content to the client and vice versa. Communication with the
annotation service is also bidirectional, making use of an HTTP API and a
WebSocket connection.
WebSocket connection:
.. code::
.─.
( )
......@@ -50,7 +43,6 @@ WebSocket connection.
│ │ * ║ ║ WS │ │
│ │ * ║ ║ │ │
└────────────┘ * ╚════════════╝ └────────────┘
*Figure 1: Hypothesis client environment*
There are two important trust boundaries in this system:
......@@ -58,10 +50,11 @@ There are two important trust boundaries in this system:
on a remote server.
2. Between the annotated content (which may be an HTML page or a PDF rendered as
an HTML page) and the client application. This boundary is marked with
asterisks (\*) in Figure 1.
asterisks (``*``) in the ASCII art above.
## Threat model
Threat Model
------------
We are principally interested in ensuring that untrusted parties cannot gain
access to data that is intended to be confidential, or tamper with such data
......@@ -92,108 +85,127 @@ and all of the following:
- members of the public who don't use the annotation service
- active attackers
We aim to defend confidential user data against any possibility of unauthorised access.
We aim to defend confidential user data against any possibility of unauthorised
access.
## Potential attack vectors
Potential Attack Vectors
------------------------
The mechanisms of directed attack we are aiming to defend against are common to
many web applications, namely:
- execution of untrusted code in a trusted context (principally by
[XSS](https://en.wikipedia.org/wiki/Cross-site_scripting))
- [clickjacking](https://en.wikipedia.org/wiki/Clickjacking)
`XSS <https://en.wikipedia.org/wiki/Cross-site_scripting>`_)
- `clickjacking <https://en.wikipedia.org/wiki/Clickjacking>`_
- phishing/imitation attacks
- eavesdropping of unencrypted network traffic by an untrusted party
- to a limited extent, [cross-site request
forgery](https://en.wikipedia.org/wiki/Cross-site_request_forgery), although
this is mostly a concern for the annotation service
- to a limited extent,
`cross-site request forgery <https://en.wikipedia.org/wiki/Cross-site_request_forgery>`_,
although this is mostly a concern for the annotation service
## Design considerations and defenses
Design Considerations and Defenses
----------------------------------
### Same-origin policy protections
Same-Origin Policy Protections
##############################
The starting point for understanding many of the client-side security mechanisms
is the web platform's [same-origin
policy](https://en.wikipedia.org/wiki/Same-origin_policy) (SOP), which ensures
that any document on origin[^1] "A" has very limited access to the execution
context or DOM tree of any document on a different origin "B".
is the web platform's
`same-origin policy <https://en.wikipedia.org/wiki/Same-origin_policy>`_ (SOP),
which ensures that any document on origin [#f1]_ "A" has very limited access to
the execution context or DOM tree of any document on a different origin "B".
.. _security-sop:
[^1]: An origin is the tuple of (scheme, host, port) for a given web document.
.. figure:: security-sop.png
![](security-sop.png)
*Figure 2: Distinct origins for annotated content and client application*
Distinct origins for annotated content and client application
As shown in Figure 2, the bulk of the Hypothesis client application executes
within an `<iframe>` injected into the annotated content. This `<iframe>` has an
origin distinct from that of the hosting page, which means that most of the
protections of the SOP apply. Most importantly, code executing in the context of
the annotated page cannot inspect the DOM of the client frame. The red border in
the image is a visual representation of the trust boundary between the
inherently untrusted execution context of the annotated page, and the trusted
execution context of the client frame.
As shown in :numref:`security-sop`, the bulk of the Hypothesis client application
executes within an ``<iframe>`` injected into the annotated content. This
``<iframe>`` has an origin distinct from that of the hosting page, which means
that most of the protections of the SOP apply. Most importantly, code executing
in the context of the annotated page cannot inspect the DOM of the client
frame. The red border in the image is a visual representation of the trust
boundary between the inherently untrusted execution context of the annotated
page, and the trusted execution context of the client frame.
Instead, the components of the client which execute in the annotated page must
communicate with the client frame using [cross-document
messaging](https://en.wikipedia.org/wiki/Web_Messaging). It is important that
such **cross-document messaging should expose only the minimum information
necessary about user data** to code executing in the annotated page. For
example: in order to draw highlights, the annotated page needs to know the
location of annotations, but it does not ever need to know the body text of an
an annotation, and so it should not be possible to expose this over the
messaging interface.
_TODO 2017-03-08: currently the client shares an origin with the annotation
service when delivered by any mechanism other than the Chrome extension. This
makes any XSS vulnerability in the client a problem for the service and vice
versa. We need to move the client to its own origin to better isolate the client
from the service and minimise the risk posed by XSS._
### Input sanitisation
communicate with the client frame using
`cross-document messaging <https://en.wikipedia.org/wiki/Web_Messaging>`_.
It is important that such **cross-document messaging should expose only the
minimum information necessary about user data** to code executing in the
annotated page. For example: in order to draw highlights, the annotated page
needs to know the location of annotations, but it does not ever need to know
the body text of an an annotation, and so it should not be possible to expose
this over the messaging interface.
.. todo:: 2017-03-08
Currently the client shares an origin with the annotation service when
delivered by any mechanism other than the Chrome extension. This makes any
XSS vulnerability in the client a problem for the service and vice versa. We
need to move the client to its own origin to better isolate the client from
the service and minimise the risk posed by XSS.
Input Sanitization
##################
As alluded to above, the client frame is a trusted execution context. Any code
running there has full access to everything the user has access to, which may
constitute a major security flaw if that code was provided by another user (say,
as a `<script>` tag in the body of an annotation).
as a ``<script>`` tag in the body of an annotation).
This is an example of a cross-site scripting attack (XSS) and must be mediated
by ensuring that **any and all user content displayed in the client frame is
appropriately escaped and/or sanitised**.
### Transport Layer Security
Transport Layer Security
########################
We ensure that it is hard to eavesdrop on traffic between the client and the
annotation service by communicating with the annotation service over encrypted
channels (`https://` and `wss://`).
channels (``https://`` and ``wss://``).
_TODO 2017-03-08: This is not currently enforced by the client. Perhaps
production builds of the client should refuse to communicate with annotation
services over insecure channels?_
.. todo:: 2017-03-08
### Clickjacking protections
This is not currently enforced by the client. Perhaps production builds of
the client should refuse to communicate with annotation services over
insecure channels?
Clickjacking Protections
########################
The most straightforward way to protect an application from most kinds of
clickjacking is the [`frame-ancestors` Content-Security-Policy
directive](https://w3c.github.io/webappsec-csp/#directive-frame-ancestors) or
the older [`X-Frame-Options` HTTP
Header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options).
clickjacking is the
`frame-ancestors Content-Security-Policy directive <https://w3c.github.io/webappsec-csp/#directive-frame-ancestors>`_
or the older
`X-Frame-Options HTTP Header <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options>`_.
Unfortunately, the client runs in a framed context (and on arbitrary origins) by
default, so simply applying `X-Frame-Options: DENY` would break the client
default, so simply applying ``X-Frame-Options: DENY`` would break the client
entirely.
_TODO 2017-03-08: The Hypothesis client would appear to have very little
protection against clickjacking attacks that allow arbitrary websites to trick
Hypothesis users into performing actions they did not intend to perform. It's
not immediately clear what tools we have at our disposal to solve this problem._
.. todo:: 2017-03-08
The Hypothesis client would appear to have very little protection against
clickjacking attacks that allow arbitrary websites to trick Hypothesis users
into performing actions they did not intend to perform. It's not immediately
clear what tools we have at our disposal to solve this problem.
### Phishing/imitation
Phishing/Imitation
##################
At the moment there is little that would stop a website embedding a replica of
the Hypothesis client in a frame and using it to harvest Hypothesis users'
usernames and passwords.
_TODO 2017-03-08: Direct credential input must move to a first-party interaction
(i.e. a popup window) where the user has the benefit of the browser toolbar to
help them identify phishing attacks._
.. todo:: 2017-03-08
Direct credential input must move to a first-party interaction (i.e. a popup
window) where the user has the benefit of the browser toolbar to help them
identify phishing attacks.
.. rubric:: Footnotes
.. [#f1] An origin is the tuple of (scheme, host, port) for a given web document.
Building the Docs Locally
=========================
You will need:
#. Git
#. Python and Virtualenv
#. Make
To build the docs:
#. ``git clone https://github.com/hypothesis/client.git``
#. ``cd client``
#. Create and activate a Python virtual environment.
#. ``pip install -r requirements-dev.in``
#. ``make docs``
Now open http://localhost:8888 to view your local build of the docs.
The built docs will automatically update when you save changes to the source
files.
For Documenters
===============
This section contains documentation for **documenters** who want to contribute
documentation to the Hypothesis client.
.. toctree::
:maxdepth: 3
buildthedocs
# Interacting with the sidebar
## Show the sidebar:
If you need to have a custom trigger on your third party page to bring up the embedded Hypothesis
sidebar, add the `data-hypothesis-trigger` attribute to the element that you want to enable.
Clicking that element will cause the sidebar to open.
Note, however, subsequent clicks do not hide the sidebar.
Example:
To add a `button` on a page to open the sidebar, simply
add the `data-hypothesis-trigger` attribute.
```html
<button data-hypothesis-trigger>
Open sidebar
</button>
```
## Show the public annotation count:
If you need to show the total number of public annotations, page notes and orphaned annotations
on your third party page where the Hypothesis sidebar is embedded, add the `data-hypothesis-annotation-count`
attribute to the element that you want to enable.
The contents of the enabled element will be replaced with the count of public annotations and if there are no
public annotations, with 0.
Example:
To display the annotation count in a `div` element, simply
add the `data-hypothesis-annotation-count` attribute to the `div`:
```html
<div data-hypothesis-annotation-count>
Annotation count will appear here
</div>
```
Welcome to Hypothesis Client's documentation!
=============================================
The `Hypothesis client <https://github.com/hypothesis/client>`_ is a browser-based tool for making annotations on web
pages. It's a client for the `Hypothesis web annotation service <http://h.readthedocs.io/>`_.
It's used by the
`Hypothesis browser extension <https://chrome.google.com/webstore/detail/hypothesis-web-pdf-annota/bjfhmglciegochdpefhhlphglcehbmek>`_, and can also be
:doc:`embedded directly into web pages <publishers/embedding>`.
.. image:: /_static/screenshot.png
.. toctree::
:maxdepth: 2
:caption: Contents
publishers/index
developers/index
documenters/index
Configuring the Client
======================
This page documents the configuration settings that you can use to configure
the Hypothesis client once it's embedded in your website.
Configuring the Client Using JSON
---------------------------------
The Hypothesis client can be configured by providing a JSON config object in
the body of the hosting page:
.. code-block:: html
<script type="application/json" class="js-hypothesis-config">
{
"openSidebar": true
}
</script>
<script async src="https://hypothes.is/embed.js"></script>
Not all configuration settings can be set in this way, some must be
:ref:`set using JavaScript <configuring-with-js>` (see below).
.. note::
The body of the ``.js-hypothesis-config`` tag must be
`valid JSON <http://jsonlint.com/>`_, invalid JSON will cause the entire
config object to be ignored.
.. _configuring-with-js:
Configuring the Client Using JavaScript
---------------------------------------
.. js:function:: window.hypothesisConfig()
Alternatively, the Hypothesis client can be configured from the hosting page
by providing a JavaScript function named :js:func:`window.hypothesisConfig`
that returns a configuration object. Some configuration settings (for
example settings that register callback or event handler functions) can
*only* be set from JavaScript:
.. code-block:: javascript
window.hypothesisConfig = function () {
return {
"openSidebar": true
};
};
Config Settings
---------------
Client Behavior
###############
These settings configure the behavior and initial state of the client when it
loads.
.. option:: openLoginForm
``Boolean``. Controls whether the login panel is automatically opened on
startup, as if the user had clicked "Log in" themselves.
(Default: ``false``.)
.. option:: openSidebar
``Boolean``. Controls whether the sidebar opens automatically on startup.
(Default: ``false``.)
.. option:: showHighlights
``Boolean``. Controls whether the in-document highlights are shown by default.
(Default: ``true``.)
.. option:: services
``Array``. A list of alternative annotation services which the client should
connect to instead of connecting to the public Hypothesis service at
`hypothes.is <https://hypothes.is/>`_. May optionally include information
(in the form of grant tokens) about user accounts that the client is logged
in to on those services.
For example:
.. code-block:: javascript
window.hypothesisConfig = function () {
return {
services: [{
authority: 'partner.org',
grantToken: '***',
icon: 'https://openclipart.org/download/272629/sihouette-animaux-10.svg'
}],
};
};
By default, if no :option:`services` setting is given, the client connects
to the public Hypothesis service at `hypothes.is <https://hypothes.is/>`_.
.. warning::
The :option:`services` setting is currently still experimental and may
change in the future.
.. note::
Currently only one additional annotation service is supported - only the
first item in this :option:`services` array is used, and any further
items in the array are ignored.
Each item in the :option:`services` array should be an object describing an
annotation service, with the following keys:
.. option:: authority
``String``. The domain name which the annotation service is associated with.
.. option:: grantToken
``String|null``. An OAuth 2 grant token which the client can send to the
service in order to get an access token for making authenticated requests
to the service. If ``null``, the user will not be logged in and will only
be able to read rather than create or modify annotations. (Default:
``null``)
.. seealso::
:ref:`Generating authorization grant tokens` for how to generate grant
tokens for the `hypothes.is <https://hypothes.is/>`_ service.
.. 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
``function``. A JavaScript function that the Hypothesis client will
call in order to login (for example, when the user clicks a login button in
the Hypothesis client's sidebar).
This setting can only be set using :js:func:`window.hypothesisConfig`.
If the hosting page provides an :option:`onLoginRequest` function then the
Hypothesis client will call this function instead of doing its usual
procedure for logging in to the public service at `hypothes.is
<https://hypothes.is/>`_.
No arguments are passed to the :option:`onLoginRequest` function.
The :option:`onLoginRequest` function should cause a login procedure for
the hosting page to be performed - for example by redirecting to a login
page, or by opening a popup login window. After a successful login the
hosting page should reload the original page with a non-null
:option:`grantToken` for the logged-in user in the :option:`services`
configuration setting.
Asset and Sidebar App Location
##############################
These settings configure where the client's assets are loaded from.
.. warning::
These settings are currently still experimental and may change in the future.
.. option:: assetRoot
``String``. The root URL from which assets are loaded. This should be set to
the URL where the contents of the hypothesis package are hosted, including
the trailing slash. (Default: for production builds:
``"https://cdn.hypothes.is/hypothesis/X.Y.Z/"``, for development builds:
``"http://localhost:3001/hypothesis/X.Y.Z/""`.
``X.Y.Z`` is the package version from ``package.json``).
.. option:: sidebarAppUrl
``String``. The URL for the sidebar application which displays annotations
(Default: ``"https://hypothes.is/app.html"``).
How to Add Hypothesis to Your Website
=====================================
.. If you update this page, please ensure you update the "For Publishers" page
on the Hypothesis website, or coordinate with someone who can
(https://hypothes.is/for-publishers/).
To add Hypothesis to your website, just add this one line to the HTML source of
each page that you want to have the Hypothesis client on:
.. code-block:: html
<script src="https://hypothes.is/embed.js" async></script>
Interacting with the Client
===========================
This page documents the ways in which your website can interact with the
Hypothesis client, once the client is embedded in your site.
.. option:: data-hypothesis-trigger
You can add a button to your page that opens the Hypothesis sidebar.
If you need to have a custom trigger on your third party page to bring up
the embedded Hypothesis sidebar, add the :option:`data-hypothesis-trigger`
attribute to the element that you want to enable. Clicking that element
will cause the sidebar to open. Note, however, subsequent clicks do not
hide the sidebar.
For example to add a ``<button>`` on a page to open the sidebar, simply
add the :option:`data-hypothesis-trigger` attribute:
.. code-block:: html
<button data-hypothesis-trigger>
Open sidebar
</button>
.. option:: data-hypothesis-annotation-count
You can add a count of the number of annotations to your page.
If you need to show the total number of public annotations, page notes and
orphaned annotations on your third party page where the Hypothesis client
is embedded, add the :option:`data-hypothesis-annotation-count` attribute to
the element that you want to enable. The contents of the enabled element
will be replaced with the count of public annotations and if there are no
public annotations, with 0.
For example to display the annotation count in a ``<div>`` element, simply
add the :option:`data-hypothesis-annotation-count` attribute to the
``<div>``:
.. code-block:: html
<div data-hypothesis-annotation-count>
Annotation count will appear here
</div>
For Content Publishers
======================
This section is for **content publishers** who publish content to the web and
want to integrate the Hypothesis client into their web pages. If you want to
add the Hypothesis client to your web pages so that visitors can annotate the
pages without having to install their own Hypothesis browser extension, these
pages will help you get started.
.. toctree::
:maxdepth: 3
embedding
config
host-page-integration
# Python requirements needed to run the `make docs` command.
recommonmark
sphinx
sphinx-autobuild
sphinx_rtd_theme
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