diff --git a/www/core/components/contentlinks/services/helper.js b/www/core/components/contentlinks/services/helper.js index e5a059179bd..dc669d8036d 100644 --- a/www/core/components/contentlinks/services/helper.js +++ b/www/core/components/contentlinks/services/helper.js @@ -208,7 +208,7 @@ angular.module('mm.core.contentlinks') return promise.then(function() { if (ssoNeeded) { - $mmLoginHelper.openBrowserForSSOLogin(result.siteurl); + $mmLoginHelper.openBrowserForSSOLogin(result.siteurl, result.code); } else { $state.go('mm_login.credentials', { siteurl: result.siteurl, diff --git a/www/core/components/login/controllers/credentials.js b/www/core/components/login/controllers/credentials.js index e08b293fb99..49f394ec10c 100644 --- a/www/core/components/login/controllers/credentials.js +++ b/www/core/components/login/controllers/credentials.js @@ -52,7 +52,7 @@ angular.module('mm.core.login') // Check that there's no SSO authentication ongoing and the view hasn't changed. if (!$mmLoginHelper.isSSOLoginOngoing() && !$scope.$$destroyed) { $mmUtil.showConfirm($translate('mm.login.logininsiterequired')).then(function() { - $mmLoginHelper.openBrowserForSSOLogin(result.siteurl); + $mmLoginHelper.openBrowserForSSOLogin(result.siteurl, result.code); }); } } else { diff --git a/www/core/components/login/controllers/site.js b/www/core/components/login/controllers/site.js index 0a38d0c2248..c14f3639f6f 100644 --- a/www/core/components/login/controllers/site.js +++ b/www/core/components/login/controllers/site.js @@ -65,7 +65,7 @@ angular.module('mm.core.login') if ($mmLoginHelper.isSSOLoginNeeded(result.code)) { // SSO. User needs to authenticate in a browser. $mmUtil.showConfirm($translate('mm.login.logininsiterequired')).then(function() { - $mmLoginHelper.openBrowserForSSOLogin(result.siteurl); + $mmLoginHelper.openBrowserForSSOLogin(result.siteurl, result.code); }); } else { $state.go('mm_login.credentials', {siteurl: result.siteurl}); diff --git a/www/core/components/login/main.js b/www/core/components/login/main.js index 7d57014bb17..327b906127b 100644 --- a/www/core/components/login/main.js +++ b/www/core/components/login/main.js @@ -104,6 +104,16 @@ angular.module('mm.core.login', []) // Register observer to check if the app was launched via URL scheme. $mmURLDelegate.register('mmLoginSSO', appLaunchedByURL); + // Observe loaded pages in the InAppBrowser to handle SSO URLs. + $rootScope.$on('$cordovaInAppBrowser:loadstart', function(e, event) { + // URLs with a custom scheme are prefixed with "http://", we need to remove this. + var url = event.url.replace(/^http:\/\//, ''); + if (appLaunchedByURL(url)) { + // Close the browser if it's a valid SSO URL. + $mmUtil.closeInAppBrowser(); + } + }); + // Redirect depending on user session. $rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams) { @@ -162,7 +172,7 @@ angular.module('mm.core.login', []) if ($mmLoginHelper.isSSOLoginNeeded(result.code)) { // SSO. User needs to authenticate in a browser. $mmUtil.showConfirm($translate('mm.login.reconnectssodescription')).then(function() { - $mmLoginHelper.openBrowserForSSOLogin(result.siteurl); + $mmLoginHelper.openBrowserForSSOLogin(result.siteurl, result.code); }); } else { var info = $mmSite.getInfo(); diff --git a/www/core/components/login/services/helper.js b/www/core/components/login/services/helper.js index 55cab35c281..8c290200b13 100644 --- a/www/core/components/login/services/helper.js +++ b/www/core/components/login/services/helper.js @@ -15,6 +15,7 @@ angular.module('mm.core.login') .constant('mmLoginSSOCode', 2) // This code is returned by local_mobile Moodle plugin if SSO in browser is required. +.constant('mmLoginSSOInAppCode', 3) .constant('mmLoginLaunchSiteURL', 'mmLoginLaunchSiteURL') .constant('mmLoginLaunchPassport', 'mmLoginLaunchPassport') @@ -25,8 +26,9 @@ angular.module('mm.core.login') * @ngdoc service * @name $mmLoginHelper */ -.factory('$mmLoginHelper', function($q, $log, $mmConfig, mmLoginSSOCode, mmLoginLaunchSiteURL, mmLoginLaunchPassport, - md5, $mmSite, $mmSitesManager, $mmLang, $mmUtil, $state, $mmAddonManager, mmCoreConfigConstants) { +.factory('$mmLoginHelper', function($q, $log, $mmConfig, mmLoginSSOCode, mmLoginSSOInAppCode, mmLoginLaunchSiteURL, + mmLoginLaunchPassport, md5, $mmSite, $mmSitesManager, $mmLang, $mmUtil, $state, $mmAddonManager, + $translate, mmCoreConfigConstants) { $log = $log.getInstance('$mmLoginHelper'); @@ -93,7 +95,7 @@ angular.module('mm.core.login') * @return {Boolean} True if SSO login is needed, false othwerise. */ self.isSSOLoginNeeded = function(code) { - return code == mmLoginSSOCode; + return code == mmLoginSSOCode || code == mmLoginSSOInAppCode; }; /** @@ -116,8 +118,9 @@ angular.module('mm.core.login') * @ngdoc method * @name $mmLoginHelper#openBrowserForSSOLogin * @param {String} siteurl URL of the site where the SSO login will be performed. + * @param {Number} typeOfLogin mmLoginSSOCode or mmLoginSSOInAppCode */ - self.openBrowserForSSOLogin = function(siteurl) { + self.openBrowserForSSOLogin = function(siteurl, typeOfLogin) { var passport = Math.random() * 1000; var loginurl = siteurl + "/local/mobile/launch.php?service=" + mmCoreConfigConstants.wsextservice; loginurl += "&passport=" + passport; @@ -128,9 +131,19 @@ angular.module('mm.core.login') $mmConfig.set(mmLoginLaunchSiteURL, siteurl); $mmConfig.set(mmLoginLaunchPassport, passport); - $mmUtil.openInBrowser(loginurl); - if (navigator.app) { - navigator.app.exitApp(); + if (typeOfLogin == mmLoginSSOInAppCode) { + $translate('mm.login.cancel').then(function(cancelStr) { + var options = { + clearsessioncache: 'yes', // Clear the session cache to allow for multiple logins. + closebuttoncaption: cancelStr, + }; + $mmUtil.openInApp(loginurl, options); + }); + } else { + $mmUtil.openInBrowser(loginurl); + if (navigator.app) { + navigator.app.exitApp(); + } } }; diff --git a/www/core/lib/util.js b/www/core/lib/util.js index 6d895b017be..8115b2c8e78 100644 --- a/www/core/lib/util.js +++ b/www/core/lib/util.js @@ -66,7 +66,7 @@ angular.module('mm.core') }; this.$get = function($ionicLoading, $ionicPopup, $injector, $translate, $http, $log, $q, $mmLang, $mmFS, $timeout, $mmApp, - $mmText, mmCoreWifiDownloadThreshold, mmCoreDownloadThreshold, $ionicScrollDelegate) { + $mmText, mmCoreWifiDownloadThreshold, mmCoreDownloadThreshold, $ionicScrollDelegate, $cordovaInAppBrowser) { $log = $log.getInstance('$mmUtil'); @@ -388,20 +388,39 @@ angular.module('mm.core') * @ngdoc method * @name $mmUtil#openInApp * @param {String} url The URL to open. + * @param {Object} options Override default options passed to $cordovaInAppBrowser#open * @return {Void} */ - self.openInApp = function(url) { + self.openInApp = function(url, options) { if (!url) { return; } - var options = 'enableViewPortScale=yes'; // Enable zoom on iOS. - if (ionic.Platform.isIOS() && url.indexOf('file://') === 0) { + options = options || {}; + + if (!options.enableViewPortScale) { + options.enableViewPortScale = 'yes'; // Enable zoom on iOS. + } + + if (!options.location && ionic.Platform.isIOS() && url.indexOf('file://') === 0) { // The URL uses file protocol, don't show it on iOS. // In Android we keep it because otherwise we lose the whole toolbar. - options += ',location=no'; + options.location = 'no'; } - window.open(url, '_blank', options); + + $cordovaInAppBrowser.open(url, '_blank', options); + }; + + /** + * Close the InAppBrowser window. + * + * @module mm.core + * @ngdoc method + * @name $mmUtil#closeInAppBrowser + * @return {Void} + */ + self.closeInAppBrowser = function() { + $cordovaInAppBrowser.close(); }; /**