diff --git a/upgrade.txt b/upgrade.txt index 836226bd62c..ed4281c4bfb 100644 --- a/upgrade.txt +++ b/upgrade.txt @@ -1,6 +1,10 @@ This files describes API changes in the Moodle Mobile app, information provided here is intended especially for developers. +=== 3.2 === + + * Now the app supports auto-login with the site if it's a Moodle 3.2 or higher. The mm-link directive already handles it automatically, but it also includes a new attribute to force or disable auto-login in links. To manually open a link with auto-login you can use any of the new functions in $mmSite: openInBrowserWithAutoLogin, openInAppWithAutoLogin, ... + === 3.1.3 === * The module object received by addons in course contents no longer has the "contents" array in Moodle 2.9 or higher. Please use the new function $mmCourse#loadModuleContents to load the contents. diff --git a/www/addons/grades/controllers/grade.js b/www/addons/grades/controllers/grade.js index ef186873cb9..20e6d207f8d 100644 --- a/www/addons/grades/controllers/grade.js +++ b/www/addons/grades/controllers/grade.js @@ -21,8 +21,7 @@ angular.module('mm.addons.grades') * @ngdoc controller * @name mmaGradesGradeCtrl */ -.controller('mmaGradesGradeCtrl', function($scope, $stateParams, $mmUtil, $mmaGrades, $mmSite, $mmaGradesHelper, $log, - $mmContentLinksHelper) { +.controller('mmaGradesGradeCtrl', function($scope, $stateParams, $mmUtil, $mmaGrades, $mmSite, $mmaGradesHelper, $log) { $log = $log.getInstance('mmaGradesGradeCtrl'); @@ -49,17 +48,6 @@ angular.module('mm.addons.grades') }); }; - $scope.gotoActivity = function() { - if ($scope.grade.link) { - $mmContentLinksHelper.handleLink($scope.grade.link).then(function(treated) { - if (!treated) { - $log.debug('Link not being handled ' + $scope.grade.link + ' opening in browser...'); - $mmUtil.openInBrowser($scope.grade.link); - } - }); - } - }; - $scope.refreshGrade = function() { $mmaGrades.invalidateGradesTableData(courseId, userId).finally(function() { fetchGrade().finally(function() { diff --git a/www/addons/grades/templates/grade.html b/www/addons/grades/templates/grade.html index 85d0b1d7a86..5ec4b4ad28a 100644 --- a/www/addons/grades/templates/grade.html +++ b/www/addons/grades/templates/grade.html @@ -5,9 +5,9 @@
- +

{{ 'mma.grades.weight' | translate}}

diff --git a/www/addons/messages/services/handlers.js b/www/addons/messages/services/handlers.js index 0736d6564d4..3190b79773a 100644 --- a/www/addons/messages/services/handlers.js +++ b/www/addons/messages/services/handlers.js @@ -23,7 +23,8 @@ angular.module('mm.addons.messages') * @ngdoc service * @name $mmaMessagesHandlers */ -.factory('$mmaMessagesHandlers', function($log, $mmaMessages, $mmSite, $state, $mmUtil, $mmContentLinksHelper, $mmaMessagesSync) { +.factory('$mmaMessagesHandlers', function($log, $mmaMessages, $mmSite, $state, $mmUtil, $mmContentLinksHelper, $mmaMessagesSync, + $mmSitesManager) { $log = $log.getInstance('$mmaMessagesHandlers'); var self = {}; @@ -343,7 +344,12 @@ angular.module('mm.addons.messages') stateParams = {userId: parseInt(params.user1, 10)}; } else { // He isn't, open in browser. - $mmUtil.openInBrowser(url); + var modal = $mmUtil.showModalLoading(); + $mmSitesManager.getSite(siteId).then(function(site) { + return site.openInBrowserWithAutoLogin(url); + }).finally(function() { + modal.dismiss(); + }); return; } } else if (typeof params.id != 'undefined') { diff --git a/www/addons/mod/assign/templates/edit.html b/www/addons/mod/assign/templates/edit.html index 3595dde32bc..02a596ac080 100644 --- a/www/addons/mod/assign/templates/edit.html +++ b/www/addons/mod/assign/templates/edit.html @@ -1,7 +1,7 @@ {{ title }} - {{ 'mm.core.save' | translate }} + {{ 'mm.core.save' | translate }} diff --git a/www/addons/mod/url/services/url.js b/www/addons/mod/url/services/url.js index f1fe95f71d6..fe6b7a62ef1 100644 --- a/www/addons/mod/url/services/url.js +++ b/www/addons/mod/url/services/url.js @@ -55,7 +55,7 @@ angular.module('mm.addons.mod_url') var modal = $mmUtil.showModalLoading(); $mmContentLinksHelper.handleLink(url).then(function(treated) { if (!treated) { - $mmUtil.openInBrowser(url); + return $mmSite.openInBrowserWithAutoLoginIfSameSite(url); } }).finally(function() { modal.dismiss(); diff --git a/www/addons/mod/wiki/templates/edit.html b/www/addons/mod/wiki/templates/edit.html index 726407d083e..2b4dabf4d4e 100644 --- a/www/addons/mod/wiki/templates/edit.html +++ b/www/addons/mod/wiki/templates/edit.html @@ -1,7 +1,7 @@ {{ title }} - {{ 'mm.core.save' | translate }} + {{ 'mm.core.save' | translate }} diff --git a/www/addons/mod/wiki/templates/index.html b/www/addons/mod/wiki/templates/index.html index ee817e80511..b5d1d824b30 100644 --- a/www/addons/mod/wiki/templates/index.html +++ b/www/addons/mod/wiki/templates/index.html @@ -2,7 +2,7 @@ {{ title }} - + diff --git a/www/core/components/contentlinks/services/helper.js b/www/core/components/contentlinks/services/helper.js index d69562cdb66..f990a2aceb9 100644 --- a/www/core/components/contentlinks/services/helper.js +++ b/www/core/components/contentlinks/services/helper.js @@ -309,7 +309,7 @@ angular.module('mm.core.contentlinks') gotoReview(url, params, courseId, siteId); } else { // Not current user and no gotoReview function specified, open it in browser. - $mmUtil.openInBrowser(url); + return site.openInBrowserWithAutoLogin(url); } }).finally(function() { modal.dismiss(); diff --git a/www/core/components/course/services/content_handler.js b/www/core/components/course/services/content_handler.js index a4ae2a05198..81acd3b6759 100644 --- a/www/core/components/course/services/content_handler.js +++ b/www/core/components/course/services/content_handler.js @@ -21,7 +21,7 @@ angular.module('mm.core.course') * @ngdoc service * @name $mmCourseContentHandler */ -.factory('$mmCourseContentHandler', function($mmCourse, $mmUtil) { +.factory('$mmCourseContentHandler', function($mmCourse, $mmSite) { return { getController: function(module) { return function($scope, $state) { @@ -40,9 +40,9 @@ angular.module('mm.core.course') icon: 'ion-share', label: 'mm.core.openinbrowser', action: function(e) { - $mmUtil.openInBrowser(module.url); e.preventDefault(); e.stopPropagation(); + $mmSite.openInBrowserWithAutoLoginIfSameSite(module.url); } }]; } diff --git a/www/core/components/courses/services/handlers.js b/www/core/components/courses/services/handlers.js index 53b48d5dd31..1f793a6c9eb 100644 --- a/www/core/components/courses/services/handlers.js +++ b/www/core/components/courses/services/handlers.js @@ -87,7 +87,7 @@ angular.module('mm.core.courses') var body = $translate('mm.core.twoparagraphs', {p1: error, p2: $translate.instant('mm.core.confirmopeninbrowser')}); $mmUtil.showConfirm(body).then(function() { - $mmUtil.openInBrowser(url); + $mmSite.openInBrowserWithAutoLogin(url); }); return $q.reject(); }); diff --git a/www/core/components/login/controllers/credentials.js b/www/core/components/login/controllers/credentials.js index f4dbab75a15..a52adefc8ac 100644 --- a/www/core/components/login/controllers/credentials.js +++ b/www/core/components/login/controllers/credentials.js @@ -121,7 +121,7 @@ angular.module('mm.core.login') // Start the authentication process. return $mmSitesManager.getUserToken(siteurl, username, password).then(function(data) { - return $mmSitesManager.newSite(data.siteurl, data.token).then(function() { + return $mmSitesManager.newSite(data.siteurl, data.token, data.privatetoken).then(function() { delete $scope.credentials; // Delete username and password from the scope. $ionicHistory.nextViewOptions({disableBack: true}); diff --git a/www/core/components/login/controllers/reconnect.js b/www/core/components/login/controllers/reconnect.js index d283d083d39..39c80c40594 100644 --- a/www/core/components/login/controllers/reconnect.js +++ b/www/core/components/login/controllers/reconnect.js @@ -70,7 +70,7 @@ angular.module('mm.core.login') // Start the authentication process. $mmSitesManager.getUserToken(siteurl, username, password).then(function(data) { - $mmSitesManager.updateSiteToken(infositeurl, username, data.token).then(function() { + $mmSitesManager.updateSiteToken(infositeurl, username, data.token, data.privatetoken).then(function() { // Update site info too because functions might have changed (e.g. unisntall local_mobile). $mmSitesManager.updateSiteInfoByUrl(infositeurl, username).finally(function() { delete $scope.credentials; // Delete password from the scope. diff --git a/www/core/components/login/controllers/site.js b/www/core/components/login/controllers/site.js index 5d653e029c0..6a0334d53e1 100644 --- a/www/core/components/login/controllers/site.js +++ b/www/core/components/login/controllers/site.js @@ -41,7 +41,7 @@ angular.module('mm.core.login') if (sitedata) { // It's a demo site. $mmSitesManager.getUserToken(sitedata.url, sitedata.username, sitedata.password).then(function(data) { - $mmSitesManager.newSite(data.siteurl, data.token).then(function() { + $mmSitesManager.newSite(data.siteurl, data.token, data.privatetoken).then(function() { $ionicHistory.nextViewOptions({disableBack: true}); return $mmLoginHelper.goToSiteInitialPage(); }, function(error) { diff --git a/www/core/components/settings/templates/about.html b/www/core/components/settings/templates/about.html index 541b6bdc054..d788eddea8b 100644 --- a/www/core/components/settings/templates/about.html +++ b/www/core/components/settings/templates/about.html @@ -9,7 +9,7 @@

{{appname}} {{versionname}}

  • Apache 2.0

    -

    http://www.apache.org/licenses/LICENSE-2.0

    +

    http://www.apache.org/licenses/LICENSE-2.0

  • {{ 'mm.settings.deviceinfo' | translate }}

    @@ -24,7 +24,7 @@

    Apache 2.0

  • {{ 'mm.settings.filesystemroot' | translate}}

    - {{ filesystemroot }} + {{ filesystemroot }}

    {{ filesystemroot }}

  • diff --git a/www/core/components/sidemenu/templates/menu.html b/www/core/components/sidemenu/templates/menu.html index 69b2c0b82df..0bc3fd04764 100644 --- a/www/core/components/sidemenu/templates/menu.html +++ b/www/core/components/sidemenu/templates/menu.html @@ -43,12 +43,12 @@

    {{siteinfo.fullname}}

  • - + {{ 'mm.sidemenu.website' | translate}}
  • - + {{ 'mm.sidemenu.help' | translate}}
  • diff --git a/www/core/components/user/templates/profile.html b/www/core/components/user/templates/profile.html index a9d31363585..0338219a68c 100644 --- a/www/core/components/user/templates/profile.html +++ b/www/core/components/user/templates/profile.html @@ -19,7 +19,7 @@

    {{ 'mm.user.contact' | translate}}

    {{ 'mm.user.email' | translate}}

    - + {{user.email}}

    @@ -27,7 +27,7 @@

    {{ 'mm.user.contact' | translate}}

    {{ 'mm.user.phone1' | translate}}

    - + {{user.phone1}}

    @@ -35,7 +35,7 @@

    {{ 'mm.user.contact' | translate}}

    {{ 'mm.user.phone2' | translate}}

    - + {{user.phone2}}

    @@ -43,10 +43,10 @@

    {{ 'mm.user.contact' | translate}}

    {{ 'mm.user.address' | translate}}

    - + {{user.address}} - + {{user.address}}

    diff --git a/www/core/directives/contextmenu.js b/www/core/directives/contextmenu.js index f3e7b39b32b..591e1ea7591 100644 --- a/www/core/directives/contextmenu.js +++ b/www/core/directives/contextmenu.js @@ -171,6 +171,7 @@ angular.module('mm.core') * @param {Function} [action] Javascript action to be taken on click. Only works if iconAction is set and is not an spinner. * @param {String} [href] Link to go if no action provided. * @param {Boolean} [captureLink=false] If the link needs to be captured by the app. + * @param {Boolean} [autoLogin=check] If the link needs to be opened using auto-login. See mmLink. * @param {Boolean} [closeOnClick=true] If close the popover when clicked. Only works if action or href is provided. * @param {Boolean} [closeWhenDone=false] Close popover when action is done. Only if action is supplied and closeOnClick=false. * @param {Number} [priority] Used to sort items. The highest priority, the highest position. @@ -226,6 +227,7 @@ angular.module('mm.core') action: '&?', href: '=?', captureLink: '=?', + autoLogin: '=?', closeOnClick: '=?', closeWhenDone: '=?', priority: '=?', @@ -248,6 +250,7 @@ angular.module('mm.core') // Navigation help if href provided. scope.captureLink = scope.href && scope.captureLink ? scope.captureLink : "false"; + scope.autoLogin = scope.autoLogin || 'check'; if (CtxtMenuCtrl.shouldMerge() && $ionicPlatform.isTablet()) { // Item should be merged with an outer context-menu in tablet view. diff --git a/www/core/directives/iframe.js b/www/core/directives/iframe.js index 034ea726d98..eec2d5a9bda 100644 --- a/www/core/directives/iframe.js +++ b/www/core/directives/iframe.js @@ -27,7 +27,7 @@ angular.module('mm.core') * @param {Mixed} [width=100%] Width of the iframe. If not defined, use 100%. * @param {Mixed} [height=100%] Height of the iframe. If not defined, use 100%. */ -.directive('mmIframe', function($mmUtil, $mmText) { +.directive('mmIframe', function($mmUtil, $mmText, $mmSite) { var errorShownTime = 0, tags = ['iframe', 'frame', 'object', 'embed']; @@ -130,7 +130,11 @@ angular.module('mm.core') // If the link's already prevented by SCORM JS then we won't open it in browser. if (!e.defaultPrevented) { e.preventDefault(); - $mmUtil.openInBrowser(href); + if (!$mmSite.isLoggedIn()) { + $mmUtil.openInBrowser(href); + } else { + $mmSite.openInBrowserWithAutoLoginIfSameSite(href); + } } }); } else if (el.target == '_parent' || el.target == '_top' || el.target == '_blank') { @@ -139,7 +143,11 @@ angular.module('mm.core') // If the link's already prevented by SCORM JS then we won't open it in InAppBrowser. if (!e.defaultPrevented) { e.preventDefault(); - $mmUtil.openInApp(href); + if (!$mmSite.isLoggedIn()) { + $mmUtil.openInApp(href); + } else { + $mmSite.openInAppWithAutoLoginIfSameSite(href); + } } }); } else if (ionic.Platform.isIOS() && (!el.target || el.target == '_self')) { diff --git a/www/core/directives/link.js b/www/core/directives/link.js index 7145435a868..6a0e66d2f1d 100644 --- a/www/core/directives/link.js +++ b/www/core/directives/link.js @@ -22,15 +22,22 @@ angular.module('mm.core') * @name mmLink * * @param {Boolean} [captureLink=false] If the link needs to be captured by the app. + * @param {String} [autoLogin=check] If the link should be open with auto-login. Accepts the following values: + * "yes" -> Always auto-login. + * "no" -> Never auto-login. + * "check" -> Auto-login only if it points to the current site. Default value. */ -.directive('mmLink', function($mmUtil, $mmContentLinksHelper, $location) { +.directive('mmLink', function($mmUtil, $mmContentLinksHelper, $location, $mmSite) { /** * Convenience function to correctly navigate, open file or url in the browser. * - * @param {String} href HREF to be opened + * @param {String} href HREF to be opened. + * @param {String} [autoLogin=check] Whether to auto-login. "yes", "no" or "check". */ - function navigate(href) { + function navigate(href, autoLogin) { + autoLogin = autoLogin || 'check'; + if (href.indexOf('cdvfile://') === 0 || href.indexOf('file://') === 0) { // We have a local file. $mmUtil.openFile(href).catch(function(error) { @@ -46,8 +53,17 @@ angular.module('mm.core') $mmUtil.scrollToElement(document, "#" + href + ", [name='" + href + "']"); } } else { - // It's an external link, we will open with browser. - $mmUtil.openInBrowser(href); + // It's an external link, we will open with browser. Check if we need to auto-login. + if (!$mmSite.isLoggedIn()) { + // Not logged in, cannot auto-login. + $mmUtil.openInBrowser(href); + } else if (autoLogin == 'yes') { + $mmSite.openInBrowserWithAutoLogin(href); + } else if (autoLogin == 'no') { + $mmUtil.openInBrowser(href); + } else { + $mmSite.openInBrowserWithAutoLoginIfSameSite(href); + } } } @@ -66,11 +82,11 @@ angular.module('mm.core') if (attrs.captureLink && attrs.captureLink !== 'false') { $mmContentLinksHelper.handleLink(href).then(function(treated) { if (!treated) { - navigate(href); + navigate(href, attrs.autoLogin); } }); } else { - navigate(href); + navigate(href, attrs.autoLogin); } } } diff --git a/www/core/lib/sitesfactory.js b/www/core/lib/sitesfactory.js index d2bd72a4e11..c5484f5e49f 100644 --- a/www/core/lib/sitesfactory.js +++ b/www/core/lib/sitesfactory.js @@ -118,7 +118,7 @@ angular.module('mm.core') this.$get = function($http, $q, $mmWS, $mmDB, $log, md5, $mmApp, $mmLang, $mmUtil, $mmFS, mmCoreWSCacheStore, mmCoreWSPrefix, mmCoreSessionExpired, $mmEvents, mmCoreEventSessionExpired, mmCoreUserDeleted, mmCoreEventUserDeleted, $mmText, $translate, mmCoreConfigConstants, mmCoreUserPasswordChangeForced, mmCoreEventPasswordChangeForced, - mmCoreLoginTokenChangePassword) { + mmCoreLoginTokenChangePassword, mmCoreSecondsMinute) { $log = $log.getInstance('$mmSite'); @@ -162,16 +162,19 @@ angular.module('mm.core') /** * Site object to store site data. * - * @param {String} id Site ID. - * @param {String} siteurl Site URL. - * @param {String} token User's token in the site. - * @param {Object} infos Site's info. + * @param {String} id Site ID. + * @param {String} siteurl Site URL. + * @param {String} token User's token in the site. + * @param {Object} infos Site's info. + * @param {String} [privateToken] User's private token. + * @return {Void} */ - function Site(id, siteurl, token, infos) { + function Site(id, siteurl, token, infos, privateToken) { this.id = id; this.siteurl = siteurl; this.token = token; this.infos = infos; + this.privateToken = privateToken; if (this.id) { this.db = $mmDB.getDB('Site-' + this.id, siteSchema, dboptions); @@ -214,6 +217,15 @@ angular.module('mm.core') return this.infos; }; + /** + * Get site private token. + * + * @return {String} Current site private token. + */ + Site.prototype.getPrivateToken = function() { + return this.privateToken; + }; + /** * Get site DB. * @@ -255,6 +267,15 @@ angular.module('mm.core') this.token = token; }; + /** + * Set site private token. + * + * @param {String} privateToken New private token. + */ + Site.prototype.setPrivateToken = function(privateToken) { + this.privateToken = privateToken; + }; + /** * Check if token is already expired using local data. * @@ -835,6 +856,118 @@ angular.module('mm.core') }); }; + /** + * Open a URL in browser using auto-login in the Moodle site if available. + * + * @param {String} url The URL to open. + * @return {Promise} Promise resolved when done, rejected otherwise. + */ + Site.prototype.openInBrowserWithAutoLogin = function(url) { + return this.openWithAutoLogin(false, url); + }; + + /** + * Open a URL in browser using auto-login in the Moodle site if available and the URL belongs to the site. + * + * @param {String} url The URL to open. + * @return {Promise} Promise resolved when done, rejected otherwise. + */ + Site.prototype.openInBrowserWithAutoLoginIfSameSite = function(url) { + return this.openWithAutoLoginIfSameSite(false, url); + }; + + /** + * Open a URL in inappbrowser using auto-login in the Moodle site if available. + * + * @param {String} url The URL to open. + * @param {Object} options Override default options passed to $cordovaInAppBrowser#open + * @return {Promise} Promise resolved when done, rejected otherwise. + */ + Site.prototype.openInAppWithAutoLogin = function(url, options) { + return this.openWithAutoLogin(true, url, options); + }; + + /** + * Open a URL in inappbrowser using auto-login in the Moodle site if available and the URL belongs to the site. + * + * @param {String} url The URL to open. + * @param {Object} options Override default options passed to $cordovaInAppBrowser#open + * @return {Promise} Promise resolved when done, rejected otherwise. + */ + Site.prototype.openInAppWithAutoLoginIfSameSite = function(url, options) { + return this.openWithAutoLoginIfSameSite(true, url, options); + }; + + /** + * Open a URL in browser or InAppBrowser using auto-login in the Moodle site if available. + * + * @param {Boolean} inApp True to open it in InAppBrowser, false to open in browser. + * @param {String} url The URL to open. + * @param {Object} options Override default options passed to $cordovaInAppBrowser#open. + * @return {Promise} Promise resolved when done, rejected otherwise. + */ + Site.prototype.openWithAutoLogin = function(inApp, url, options) { + if (!this.privateToken || !this.wsAvailable('tool_mobile_get_autologin_key') || + (this.lastAutoLogin && $mmUtil.timestamp() - this.lastAutoLogin < 6 * mmCoreSecondsMinute)) { + // No private token, WS not available or last auto-login was less than 6 minutes ago. + // Open the final URL without auto-login. + open(url); + return $q.when(); + } + + var that = this, + userId = that.getUserId(), + params = { + privatetoken: that.privateToken + }, + modal = $mmUtil.showModalLoading(); + + // Use write to not use cache. + return that.write('tool_mobile_get_autologin_key', params).then(function(data) { + if (!data.autologinurl || !data.key) { + // Not valid data, open the final URL without auto-login. + open(url); + return; + } + + that.lastAutoLogin = $mmUtil.timestamp(); + + open(data.autologinurl + '?userid=' + userId + '&key=' + data.key + '&urltogo=' + url); + }).catch(function() { + // Couldn't get autologin key, open the final URL without auto-login. + open(url); + }).finally(function() { + modal.dismiss(); + }); + + function open(url) { + if (inApp) { + $mmUtil.openInApp(url, options); + } else { + $mmUtil.openInBrowser(url); + } + } + }; + + /** + * Open a URL in browser or InAppBrowser using auto-login in the Moodle site if available and the URL belongs to the site. + * + * @param {String} url The URL to open. + * @return {Promise} Promise resolved when done, rejected otherwise. + */ + Site.prototype.openWithAutoLoginIfSameSite = function(inApp, url, options) { + if (this.containsUrl(url)) { + return this.openWithAutoLogin(inApp, url, options); + } else { + if (inApp) { + $mmUtil.openInApp(url, options); + } else { + $mmUtil.openInBrowser(url); + } + return $q.when(); + } + }; + /** * Invalidate entries from the cache. * @@ -994,16 +1127,17 @@ angular.module('mm.core') * @module mm.core * @ngdoc method * @name $mmSitesFactory#makeSite - * @param {String} id Site ID. - * @param {String} siteurl Site URL. - * @param {String} token User's token in the site. - * @param {Object} infos Site's info. - * @return {Object} The current site object. + * @param {String} id Site ID. + * @param {String} siteurl Site URL. + * @param {String} token User's token in the site. + * @param {Object} infos Site's info. + * @param {String} [privateToken] User's private token. + * @return {Object} The current site object. * @description * This returns a site object. */ - self.makeSite = function(id, siteurl, token, infos) { - return new Site(id, siteurl, token, infos); + self.makeSite = function(id, siteurl, token, infos, privateToken) { + return new Site(id, siteurl, token, infos, privateToken); }; /** diff --git a/www/core/lib/sitesmanager.js b/www/core/lib/sitesmanager.js index cde7ff526c0..cd61d854f86 100644 --- a/www/core/lib/sitesmanager.js +++ b/www/core/lib/sitesmanager.js @@ -251,7 +251,7 @@ angular.module('mm.core') * @param {String} [service] Service to use. If not defined, it will be searched in memory. * @param {Boolean} retry We are retrying with a prefixed URL. * @return {Promise} A promise to be resolved when the token is retrieved. If success, returns an object - * with the token and the siteurl to use. + * with the token, private token and the siteurl to use. */ self.getUserToken = function(siteurl, username, password, service, retry) { retry = retry || false; @@ -278,7 +278,7 @@ angular.module('mm.core') return $mmLang.translateAndReject('mm.core.cannotconnect'); } else { if (typeof data.token != 'undefined') { - return {token: data.token, siteurl: siteurl}; + return {token: data.token, siteurl: siteurl, privatetoken: data.privatetoken}; } else { if (typeof data.error != 'undefined') { // We only allow one retry (to avoid loops). @@ -306,13 +306,15 @@ angular.module('mm.core') * @module mm.core * @ngdoc method * @name $mmSitesManager#newSite - * @param {String} siteurl The site url. - * @param {String} token User's token. - * @return {Promise} A promise to be resolved when the site is added and the user is authenticated. + * @param {String} siteurl The site url. + * @param {String} token User's token. + * @param {String} [privateToken] User's private token. + * @return {Promise} A promise to be resolved when the site is added and the user is authenticated. */ - self.newSite = function(siteurl, token) { + self.newSite = function(siteurl, token, privateToken) { + privateToken = privateToken || ''; - var candidateSite = $mmSitesFactory.makeSite(undefined, siteurl, token); + var candidateSite = $mmSitesFactory.makeSite(undefined, siteurl, token, undefined, privateToken); return candidateSite.fetchSiteInfo().then(function(infos) { if (isValidMoodleVersion(infos)) { @@ -320,7 +322,7 @@ angular.module('mm.core') if (validation === true) { var siteid = self.createSiteID(infos.siteurl, infos.username); // Add site to sites list. - self.addSite(siteid, siteurl, token, infos); + self.addSite(siteid, siteurl, token, infos, privateToken); // Turn candidate site into current site. candidateSite.setId(siteid); candidateSite.setInfo(infos); @@ -439,17 +441,21 @@ angular.module('mm.core') * @module mm.core * @ngdoc method * @name $mmSitesManager#addSite - * @param {String} id Site ID. - * @param {String} siteurl Site URL. - * @param {String} token User's token in the site. - * @param {Object} infos Site's info. + * @param {String} id Site ID. + * @param {String} siteurl Site URL. + * @param {String} token User's token in the site. + * @param {Object} infos Site's info. + * @param {String} [privateToken] User's private token. + * @return {Promise} Promise resolved when done. */ - self.addSite = function(id, siteurl, token, infos) { + self.addSite = function(id, siteurl, token, infos, privateToken) { + privateToken = privateToken || ''; return $mmApp.getDB().insert(mmCoreSitesStore, { id: id, siteurl: siteurl, token: token, - infos: infos + infos: infos, + privatetoken: privateToken }); }; @@ -590,7 +596,7 @@ angular.module('mm.core') return $q.when(sites[siteId]); } else { return $mmApp.getDB().get(mmCoreSitesStore, siteId).then(function(data) { - var site = $mmSitesFactory.makeSite(siteId, data.siteurl, data.token, data.infos); + var site = $mmSitesFactory.makeSite(siteId, data.siteurl, data.token, data.infos, data.privatetoken); sites[siteId] = site; return site; }); @@ -740,14 +746,15 @@ angular.module('mm.core') * @module mm.core * @ngdoc method * @name $mmSitesManager#updateSiteToken - * @param {String} siteUrl Site's URL. - * @param {String} username Username. - * @param {String} token User's new token. - * @return {Promise} A promise to be resolved when the site is updated. + * @param {String} siteUrl Site's URL. + * @param {String} username Username. + * @param {String} token User's new token. + * @param {String} [privateToken] User's private token. + * @return {Promise} A promise to be resolved when the site is updated. */ - self.updateSiteToken = function(siteUrl, username, token) { + self.updateSiteToken = function(siteUrl, username, token, privateToken) { var siteId = self.createSiteID(siteUrl, username); - return self.updateSiteTokenBySiteId(siteId, token); + return self.updateSiteTokenBySiteId(siteId, token, privateToken); }; /** @@ -756,19 +763,23 @@ angular.module('mm.core') * @module mm.core * @ngdoc method * @name $mmSitesManager#updateSiteTokenBySiteId - * @param {String} siteId Site Id. - * @param {String} token User's new token. - * @return {Promise} A promise to be resolved when the site is updated. + * @param {String} siteId Site Id. + * @param {String} token User's new token. + * @param {String} [privateToken] User's private token. + * @return {Promise} A promise to be resolved when the site is updated. */ - self.updateSiteTokenBySiteId = function(siteId, token) { + self.updateSiteTokenBySiteId = function(siteId, token, privateToken) { + privateToken = privateToken || ''; return self.getSite(siteId).then(function(site) { site.token = token; + site.privatetoken = privateToken; return $mmApp.getDB().insert(mmCoreSitesStore, { id: siteId, siteurl: site.getURL(), token: token, - infos: site.getInfo() + infos: site.getInfo(), + privatetoken: privateToken }); }); }; @@ -790,7 +801,8 @@ angular.module('mm.core') id: siteid, siteurl: site.getURL(), token: site.getToken(), - infos: infos + infos: infos, + privatetoken: site.getPrivateToken() }).finally(function() { $mmEvents.trigger(mmCoreEventSiteUpdated, siteid); }); @@ -854,7 +866,7 @@ angular.module('mm.core') var ids = []; angular.forEach(sites, function(site) { if (!sites[site.id]) { - sites[site.id] = $mmSitesFactory.makeSite(site.id, site.siteurl, site.token, site.infos); + sites[site.id] = $mmSitesFactory.makeSite(site.id, site.siteurl, site.token, site.infos, site.privatetoken); } if (sites[site.id].containsUrl(url)) { if (!username || sites[site.id].getInfo().username == username) { diff --git a/www/core/templates/contextmenu.html b/www/core/templates/contextmenu.html index 0aa2f3de89c..d4af8f450f6 100644 --- a/www/core/templates/contextmenu.html +++ b/www/core/templates/contextmenu.html @@ -5,7 +5,7 @@ + ng-show="item.ngShow" auto-login="{{item.autoLogin}}"> {{ item.content }}