diff --git a/kbase-extension/static/kbase/js/api/auth.js b/kbase-extension/static/kbase/js/api/auth.js index 264b9bfcaa..adbee6bfb9 100644 --- a/kbase-extension/static/kbase/js/api/auth.js +++ b/kbase-extension/static/kbase/js/api/auth.js @@ -1,14 +1,14 @@ define([ 'bluebird', 'jquery', - 'util/string', 'jqueryCookie' -], function(Promise, $, StringUtil) { +], function(Promise, $) { 'use strict'; function factory(config) { - var url = config.url; - var cookieName = 'kbase_session'; + const url = config.url, + cookieName = 'kbase_session', + cookieRegex = new RegExp('(^| )' + cookieName + '=([^;]+)'); /** * Does a GET request to get the profile of the currently logged in user. @@ -42,14 +42,19 @@ define([ return null; } + function getTokenCookie() { + let match = document.cookie.match(cookieRegex); + if (match) { + return match[2]; + } + return null; + } + /* Returns the current auth token that's stuffed in a cookie. * Returns null if not logged in. */ function getAuthToken() { - if (!$.cookie(cookieName)) { - return null; - } - return $.cookie(cookieName); + return getTokenCookie(); } /* Sets the given auth token into the browser's cookie. diff --git a/kbase-extension/static/kbase/js/kbaseNarrative.js b/kbase-extension/static/kbase/js/kbaseNarrative.js index f8d9bd740f..225aff2fb4 100644 --- a/kbase-extension/static/kbase/js/kbaseNarrative.js +++ b/kbase-extension/static/kbase/js/kbaseNarrative.js @@ -635,6 +635,9 @@ define([ } else { errorText = 'An unknown error occurred!'; } + errorText += '
This may occur because you have recently lost a connection to the ' + + 'Narrative server. Please try restarting the kernel by navigating to the Kernel ' + + 'menu -> Restart. If this problem persists, contact KBase through the Help menu.'; Jupyter.dialog.modal({ title: 'Narrative save failed!', @@ -715,17 +718,17 @@ define([ } }; - $([Jupyter.events]).on('notebook_loaded.Notebook', function () { + $([Jupyter.events]).on('notebook_loaded.Notebook', () => { this.loadingWidget.updateProgress('narrative', true); $('#notification_area').find('div#notification_trusted').hide(); - $(document).one('dataUpdated.Narrative', function () { + $(document).one('dataUpdated.Narrative', () => { this.loadingWidget.updateProgress('data', true); - }.bind(this)); + }); - $(document).one('appListUpdated.Narrative', function () { + $(document).one('appListUpdated.Narrative', () => { this.loadingWidget.updateProgress('apps', true); - }.bind(this)); + }); // Tricky with inter/intra-dependencies between kbaseNarrative and kbaseNarrativeWorkspace... this.sidePanel = new KBaseNarrativeSidePanel($('#kb-side-panel'), { autorender: false }); @@ -753,34 +756,36 @@ define([ } this.initSharePanel(); this.updateDocumentVersion() - .then(function() { + .then(() => { // init the controller return this.narrController.render(); - }.bind(this)) - .finally(function () { + }) + .finally(() => { this.sidePanel.render(); - }.bind(this)); + }); - $([Jupyter.events]).trigger('loaded.Narrative'); - $([Jupyter.events]).on('kernel_ready.Kernel', - function () { - console.log('Kernel Ready! Initializing Job Channel...'); - this.loadingWidget.updateProgress('kernel', true); - // TODO: This should be an event "kernel-ready", perhaps broadcast - // on the default bus channel. - this.sidePanel.$jobsWidget.initCommChannel() - .then(function () { - this.loadingWidget.updateProgress('jobs', true); - }.bind(this)) - .catch(function (err) { - // TODO: put the narrative into a terminal state - console.error('ERROR initializing kbase comm channel', err); - KBFatal('Narrative.ini', 'KBase communication channel could not be initiated with the back end. TODO'); - // this.loadingWidget.remove(); - }.bind(this)); - }.bind(this) - ); - }.bind(this)); + $([Jupyter.events]).on('kernel_ready.Kernel', () => { + NarrativeLogin.restartSession(); + Jupyter.notebook.kernel.execute( + 'import os;' + + 'os.environ["KB_AUTH_TOKEN"]="' + this.getAuthToken() + '";' + + 'os.environ["KB_WORKSPACE_ID"]="' + Jupyter.notebook.metadata.ws_name + '"' + ); + + console.log('Kernel Ready! Initializing Job Channel...'); + this.loadingWidget.updateProgress('kernel', true); + // TODO: This should be an event "kernel-ready", perhaps broadcast + // on the default bus channel. + this.sidePanel.$jobsWidget.initCommChannel() + .then(() => { + this.loadingWidget.updateProgress('jobs', true); + }) + .catch((err) => { + console.error('ERROR initializing kbase comm channel', err); + KBFatal('Narrative.ini', 'KBase communication channel could not be initiated with the back end.'); + }); + }); + }); }; /** diff --git a/kbase-extension/static/kbase/js/kbaseNarrativePrestart.js b/kbase-extension/static/kbase/js/kbaseNarrativePrestart.js index 37da13bf6a..04a03ba08a 100644 --- a/kbase-extension/static/kbase/js/kbaseNarrativePrestart.js +++ b/kbase-extension/static/kbase/js/kbaseNarrativePrestart.js @@ -1,308 +1,305 @@ /*global define,Jupyter,window*/ /*jslint white: true,browser:true*/ // Bind all page buttons right at startup. -define( - [ - 'kbwidget', - 'bootstrap', - 'jquery', - 'narrativeConfig', - 'common/runtime', - 'api/auth' - ], - function( - KBWidget, - bootstrap, - $, - Config, - Runtime, - Auth - ) { - 'use strict'; +define([ + 'jquery', + 'narrativeConfig', + 'common/runtime', + 'api/auth', + 'narrativeLogin' +], function( + $, + Config, + Runtime, + Auth, + NarrativeLogin +) { + 'use strict'; - function loadDomEvents() { + function loadDomEvents() { - // bind menubar buttons - $('#kb-save-btn').click(function() { - if (Jupyter && Jupyter.notebook) { - var narrName = Jupyter.notebook.notebook_name; - // we do not allow users to leave their narratives untitled - if (narrName.trim().toLowerCase() === 'untitled' || narrName.trim().length === 0) { - Jupyter.save_widget.rename_notebook({ notebook: Jupyter.notebook }); //"Please name your Narrative before saving.", false); - } else { - Jupyter.narrative.saveNarrative(); - } - } - }); - $('#kb-kernel-int-btn').click(function() { - if (Jupyter && Jupyter.notebook && Jupyter.notebook.kernel) { - Jupyter.notebook.kernel.interrupt(); - } - }); - $('#kb-kernel-ref-btn').click(function() { - if (Jupyter && Jupyter.notebook && Jupyter.notebook.kernel) { - Jupyter.notebook.kernel.restart(); + // bind menubar buttons + $('#kb-save-btn').click(function() { + if (Jupyter && Jupyter.notebook) { + var narrName = Jupyter.notebook.notebook_name; + // we do not allow users to leave their narratives untitled + if (narrName.trim().toLowerCase() === 'untitled' || narrName.trim().length === 0) { + Jupyter.save_widget.rename_notebook({ notebook: Jupyter.notebook }); //"Please name your Narrative before saving.", false); + } else { + Jupyter.narrative.saveNarrative(); } - }); - $('#kb-kernel-rec-btn').click(function() { - if (Jupyter && Jupyter.notebook && Jupyter.notebook.kernel) { - Jupyter.notebook.kernel.reconnect(); + } + }); + $('#kb-kernel-int-btn').click(function() { + if (Jupyter && Jupyter.notebook && Jupyter.notebook.kernel) { + Jupyter.notebook.kernel.interrupt(); + } + }); + $('#kb-kernel-ref-btn').click(function() { + if (Jupyter && Jupyter.notebook && Jupyter.notebook.kernel) { + Jupyter.notebook.kernel.restart(); + } + }); + $('#kb-kernel-rec-btn').click(function() { + if (Jupyter && Jupyter.notebook && Jupyter.notebook.kernel) { + Jupyter.notebook.kernel.reconnect(); + } + }); + $('#kb-del-btn').click(function() { + if (Jupyter && Jupyter.notebook) { + Jupyter.notebook.delete_cell(); + } + }); + $('#kb-jira-btn').attr('href', Config.url('submit_jira_ticket') + '%20' + Config.get('version')); + $('#kb-status-btn').attr('href', Config.url('status_page')); + + $('#kb-add-code-cell').click(function() { + var data = { + type: 'code', + language: 'python' + }; + Jupyter.narrative.insertAndSelectCellBelow('code', null, data); + }) + .tooltip({ + delay: { + show: Config.get('tooltip').showDelay, + hide: Config.get('tooltip').hideDelay } }); - $('#kb-del-btn').click(function() { - if (Jupyter && Jupyter.notebook) { - Jupyter.notebook.delete_cell(); + + $('#kb-add-md-cell').click(function() { + Jupyter.narrative.insertAndSelectCellBelow('markdown'); + }) + .tooltip({ + delay: { + show: Config.get('tooltip').showDelay, + hide: Config.get('tooltip').hideDelay } }); - $('#kb-jira-btn').attr('href', Config.url('submit_jira_ticket') + '%20' + Config.get('version')); - $('#kb-status-btn').attr('href', Config.url('status_page')); - - $('#kb-add-code-cell').click(function() { - var data = { - type: 'code', - language: 'python' - }; - Jupyter.narrative.insertAndSelectCellBelow('code', null, data); - }) - .tooltip({ - delay: { - show: Config.get('tooltip').showDelay, - hide: Config.get('tooltip').hideDelay - } - }); - - $('#kb-add-md-cell').click(function() { - Jupyter.narrative.insertAndSelectCellBelow('markdown'); - }) - .tooltip({ - delay: { - show: Config.get('tooltip').showDelay, - hide: Config.get('tooltip').hideDelay - } - }); - $('#kb-side-toggle-in').click(function() { - Jupyter.narrative.toggleSidePanel(); - }); - } + $('#kb-side-toggle-in').click(function() { + Jupyter.narrative.toggleSidePanel(); + }); + } - function loadGlobals() { - /** - * Error logging for detectable failure conditions. - * Logs go through the kernel and thus are sent to the - * main KBase logging facility (Splunk, as of this writing). - * - * Usage: - * KBFail(, "what you were doing", "what happened"); - * Returns: false if Jupyter not initialized yet, true otherwise - */ - window._kb_failed_once = false; - window.KBFail = function(is_fatal, where, what) { - if (!Jupyter || !Jupyter.notebook || !Jupyter.notebook.kernel) { - return false; - } - var code = ""; - if (window._kb_failed_once === false) { - code += "from biokbase.narrative.common import kblogging\n"; - window._kb_failed_once = true; - } - code += "kblogging.NarrativeUIError("; - if (is_fatal) { - code += "True,"; - } else { - code += "False,"; - } + function loadGlobals() { + /** + * Error logging for detectable failure conditions. + * Logs go through the kernel and thus are sent to the + * main KBase logging facility (Splunk, as of this writing). + * + * Usage: + * KBFail(, "what you were doing", "what happened"); + * Returns: false if Jupyter not initialized yet, true otherwise + */ + window._kb_failed_once = false; + window.KBFail = function(is_fatal, where, what) { + if (!Jupyter || !Jupyter.notebook || !Jupyter.notebook.kernel) { + return false; + } + var code = ""; + if (window._kb_failed_once === false) { + code += "from biokbase.narrative.common import kblogging\n"; + window._kb_failed_once = true; + } + code += "kblogging.NarrativeUIError("; + if (is_fatal) { + code += "True,"; + } else { + code += "False,"; + } + if (where) { + code += 'where="' + where + '"'; + } + if (what) { if (where) { - code += 'where="' + where + '"'; - } - if (what) { - if (where) { - code += ", "; - } - code += 'what="' + what + '"'; + code += ", "; } - code += ")\n"; - // Log the failure - if (Jupyter.notebook.kernel.is_connected()) { - Jupyter.notebook.kernel.execute(code, null, { store_history: false }); - } - return true; - }; - /** - * Syntactic sugar for logging error vs. fatal error. - * - * Same as KBFail() with boolean flag replaced by different names - * for the function. - */ - window.KBError = function(where, what) { - return KBFail(false, where, what); - }; + code += 'what="' + what + '"'; + } + code += ")\n"; + // Log the failure + if (Jupyter.notebook.kernel.is_connected()) { + Jupyter.notebook.kernel.execute(code, null, { store_history: false }); + } + return true; + }; + /** + * Syntactic sugar for logging error vs. fatal error. + * + * Same as KBFail() with boolean flag replaced by different names + * for the function. + */ + window.KBError = function(where, what) { + return KBFail(false, where, what); + }; - /** - * KBFatal will, in addition to calling KBFail(), - * put up a modal dialog showing the error - * and providing some advice to users on what to do next. - * - * @param where (string) Where the error occurred - * @param what (string) What happened - */ - window.KBFatal = function(where, what) { - var res = KBFail(true, where, what); + /** + * KBFatal will, in addition to calling KBFail(), + * put up a modal dialog showing the error + * and providing some advice to users on what to do next. + * + * @param where (string) Where the error occurred + * @param what (string) What happened + */ + window.KBFatal = function(where, what) { + var res = KBFail(true, where, what); - var version = Config.get('version') || 'unknown'; - var hash = Config.get('git_commit_hash') || 'unknown'; - var full_version = 'unknown'; - if (version !== 'unknown') { - if (hash === 'unknown') { - full_version = version; - } else { - full_version = version + ' (hash=' + hash + ')'; - } + var version = Config.get('version') || 'unknown'; + var hash = Config.get('git_commit_hash') || 'unknown'; + var full_version = 'unknown'; + if (version !== 'unknown') { + if (hash === 'unknown') { + full_version = version; + } else { + full_version = version + ' (hash=' + hash + ')'; } - var $fatal = - $('