diff --git a/h/browser/chrome/lib/install.js b/h/browser/chrome/lib/install.js index 68401702020..76c6c98931f 100644 --- a/h/browser/chrome/lib/install.js +++ b/h/browser/chrome/lib/install.js @@ -19,6 +19,18 @@ chrome.runtime.requestUpdateCheck(function (status) { chrome.runtime.onUpdateAvailable.addListener(onUpdateAvailable); }); +chrome.runtime.onMessage.addListener(function (message, sender, response) { + switch (message.type) { + case 'SIDEBAR_SESSION_STATE_CHANGED': + console.log('Received sidebar session state', message.state); + var stateJSON = JSON.stringify(message.state); + window.localStorage.setItem('sessionState', stateJSON); + break; + default: + break; + } +}); + function onInstalled(installDetails) { if (installDetails.reason === 'install') { browserExtension.firstRun(installDetails); diff --git a/h/browser/chrome/lib/uri-info.js b/h/browser/chrome/lib/uri-info.js index d0fb6e58305..d6799fc8c71 100644 --- a/h/browser/chrome/lib/uri-info.js +++ b/h/browser/chrome/lib/uri-info.js @@ -5,12 +5,27 @@ function encodeUriQuery(val) { return encodeURIComponent(val).replace(/%20/g, '+'); } +function queryHeaders() { + try { + var state = JSON.parse(window.localStorage.getItem("sessionState")); + var headers = {}; + if (state.api_token) { + headers['Authorization'] = 'Bearer ' + state.api_token; + } + return headers; + } catch (err) { + return {}; + } +} + /** * Queries the Hypothesis service that provides * statistics about the annotations for a given URL. */ function query(uri) { - return fetch(settings.apiUrl + '/badge?uri=' + encodeUriQuery(uri)) + return fetch(settings.apiUrl + '/badge?uri=' + encodeUriQuery(uri), { + headers: new Headers(queryHeaders()) + }) .then(function (res) { return res.json(); }).then(function (data) { diff --git a/h/session.py b/h/session.py index dcac6b58713..21466bf1e35 100644 --- a/h/session.py +++ b/h/session.py @@ -17,6 +17,8 @@ def model(request): user = request.authenticated_user if user and not user.sidebar_tutorial_dismissed: session['preferences']['show_sidebar_tutorial'] = True + session['api_token'] = '{}:TOKEN'.format(request.authenticated_userid) + session['extension_ids'] = ['chrome-ext-id', 'chrome-staging-ext-id'] return session diff --git a/h/static/scripts/session.js b/h/static/scripts/session.js index b83b4a2e432..ca0deb5ee65 100644 --- a/h/static/scripts/session.js +++ b/h/static/scripts/session.js @@ -15,6 +15,36 @@ var ACCOUNT_ACTIONS = [ ['disable_user', 'POST'] ]; +function reportSessionStateToExtension(state) { + if (!window.chrome) { + return; + } + + var stateMessage = { + type: 'SIDEBAR_SESSION_STATE_CHANGED', + state: state, + }; + + // when sidebar is served from the extension, + // send the session state to the parent + var currentExtensionID = chrome.runtime.id; + if (currentExtensionID) { + chrome.runtime.sendMessage(stateMessage); + } + + // when sidebar is served from the app, + // send the session state to all registered extensions + if (state.extension_ids) { + state.extension_ids.forEach(function (id) { + if (id === currentExtensionID) { + // we have already notified ourselves earlier + return; + } + chrome.runtime.sendMessage(id, stateMessage); + }); + } +} + function sessionActions(options) { var actions = {}; @@ -125,6 +155,8 @@ function session($http, $resource, $rootScope, flash, raven, settings) { // Copy the model data (including the CSRF token) into `resource.state`. angular.copy(model, resource.state); + reportSessionStateToExtension(model); + // Set up subsequent requests to send the CSRF token in the headers. if (resource.state.csrf) { headers[$http.defaults.xsrfHeaderName] = resource.state.csrf;