MOBILE-2253 emulator: Support SSO authentication

main
Dani Palou 2017-12-08 15:15:27 +01:00
parent 4a423f9cd3
commit a1c80fb311
5 changed files with 61 additions and 21 deletions

View File

@ -17,6 +17,7 @@ import { Platform, Nav } from 'ionic-angular';
import { StatusBar } from '@ionic-native/status-bar'; import { StatusBar } from '@ionic-native/status-bar';
import { SplashScreen } from '@ionic-native/splash-screen'; import { SplashScreen } from '@ionic-native/splash-screen';
import { CoreEventsProvider } from '../providers/events'; import { CoreEventsProvider } from '../providers/events';
import { CoreLoggerProvider } from '../providers/logger';
import { CoreLoginHelperProvider } from '../core/login/providers/helper'; import { CoreLoginHelperProvider } from '../core/login/providers/helper';
@Component({ @Component({
@ -25,9 +26,13 @@ import { CoreLoginHelperProvider } from '../core/login/providers/helper';
export class MyApp implements AfterViewInit { export class MyApp implements AfterViewInit {
@ViewChild(Nav) navCtrl; @ViewChild(Nav) navCtrl;
rootPage:any = 'CoreLoginInitPage'; rootPage:any = 'CoreLoginInitPage';
protected logger;
protected lastUrls = {};
constructor(private platform: Platform, statusBar: StatusBar, splashScreen: SplashScreen, constructor(private platform: Platform, statusBar: StatusBar, splashScreen: SplashScreen, logger: CoreLoggerProvider,
private eventsProvider: CoreEventsProvider, private loginHelper: CoreLoginHelperProvider) { private eventsProvider: CoreEventsProvider, private loginHelper: CoreLoginHelperProvider) {
this.logger = logger.getInstance('AppComponent');
platform.ready().then(() => { platform.ready().then(() => {
// Okay, so the platform is ready and our plugins are available. // Okay, so the platform is ready and our plugins are available.
// Here you can do any higher level native things you might need. // Here you can do any higher level native things you might need.
@ -86,8 +91,25 @@ export class MyApp implements AfterViewInit {
}, 1000); }, 1000);
}); });
// @todo: Register observer to check if the app was launched via URL scheme. // Handle app launched with a certain URL (custom URL scheme).
// $mmURLDelegate.register('mmLoginSSO', appLaunchedByURL); (<any>window).handleOpenURL = (url: string) => {
// First check that the URL hasn't been treated a few seconds ago. Sometimes this function is called more than once.
if (this.lastUrls[url] && Date.now() - this.lastUrls[url] < 3000) {
// Function called more than once, stop.
return;
}
this.logger.debug('App launched by URL ', url);
this.lastUrls[url] = Date.now();
this.eventsProvider.trigger(CoreEventsProvider.APP_LAUNCHED_URL, url);
};
// Listen for app launched URLs. If we receive one, check if it's a SSO authentication.
this.eventsProvider.on(CoreEventsProvider.APP_LAUNCHED_URL, (url) => {
this.loginHelper.appLaunchedByURL(url);
});
} }
} }

View File

@ -112,7 +112,7 @@ export class CoreLoginHelperProvider {
// App opened using custom URL scheme. Probably an SSO authentication. // App opened using custom URL scheme. Probably an SSO authentication.
this.appProvider.startSSOAuthentication(); this.appProvider.startSSOAuthentication();
this.logger.debug('App launched by URL'); this.logger.debug('App launched by URL with an SSO');
// Delete the sso scheme from the URL. // Delete the sso scheme from the URL.
url = url.replace(ssoScheme, ''); url = url.replace(ssoScheme, '');
@ -205,6 +205,8 @@ export class CoreLoginHelperProvider {
promise.then(() => { promise.then(() => {
this.openBrowserForSSOLogin(siteUrl, typeOfLogin, service, launchUrl); this.openBrowserForSSOLogin(siteUrl, typeOfLogin, service, launchUrl);
}, () => {
// User cancelled, ignore.
}); });
} }
@ -934,7 +936,7 @@ export class CoreLoginHelperProvider {
return Promise.reject(null); return Promise.reject(null);
} }
let launchSiteURL = data.siteurl, let launchSiteURL = data.siteUrl,
passport = data.passport; passport = data.passport;
// Reset temporary values. // Reset temporary values.

View File

@ -224,19 +224,24 @@ export class CoreAppProvider {
* NOT when the browser is opened. * NOT when the browser is opened.
*/ */
startSSOAuthentication() : void { startSSOAuthentication() : void {
let cancelTimeout,
resolvePromise;
this.ssoAuthenticationPromise = new Promise((resolve, reject) => { this.ssoAuthenticationPromise = new Promise((resolve, reject) => {
// Store the resolve function in the promise itself. resolvePromise = resolve;
(<any>this.ssoAuthenticationPromise).resolve = resolve;
// Resolve it automatically after 10 seconds (it should never take that long). // Resolve it automatically after 10 seconds (it should never take that long).
let cancel = setTimeout(() => { cancelTimeout = setTimeout(() => {
this.finishSSOAuthentication(); this.finishSSOAuthentication();
}, 10000); }, 10000);
});
// Store the resolve function in the promise itself.
(<any>this.ssoAuthenticationPromise).resolve = resolvePromise;
// If the promise is resolved because finishSSOAuthentication is called, stop the cancel promise. // If the promise is resolved because finishSSOAuthentication is called, stop the cancel promise.
this.ssoAuthenticationPromise.then(() => { this.ssoAuthenticationPromise.then(() => {
clearTimeout(cancel); clearTimeout(cancelTimeout);
});
}); });
}; };

View File

@ -45,6 +45,7 @@ export class CoreEventsProvider {
public static LOGIN_SITE_UNCHECKED = 'login_site_unchecked'; public static LOGIN_SITE_UNCHECKED = 'login_site_unchecked';
public static IAB_LOAD_START = 'inappbrowser_load_start'; public static IAB_LOAD_START = 'inappbrowser_load_start';
public static IAB_EXIT = 'inappbrowser_exit'; public static IAB_EXIT = 'inappbrowser_exit';
public static APP_LAUNCHED_URL = 'app_launched_url'; // App opened with a certain URL (custom URL scheme).
logger; logger;
observables = {}; observables = {};

View File

@ -790,8 +790,17 @@ export class CoreUtilsProvider {
options.location = 'no'; options.location = 'no';
} }
// Convert the options to a string.
let optionsArray = [],
optionsString;
for (let name in options) {
optionsArray.push(`${name}=${options[name]}`)
}
optionsString = optionsArray.join(',');
this.iabInstance = this.iab.create(url, '_blank', options); this.iabInstance = this.iab.create(url, '_blank', options);
if (this.appProvider.isDesktop() || this.appProvider.isMobile()) {
// Trigger global events when a url is loaded or the window is closed. This is to make it work like in Ionic 1. // Trigger global events when a url is loaded or the window is closed. This is to make it work like in Ionic 1.
let loadStartSubscription = this.iabInstance.on('loadstart').subscribe((event) => { let loadStartSubscription = this.iabInstance.on('loadstart').subscribe((event) => {
this.eventsProvider.trigger(CoreEventsProvider.IAB_LOAD_START, event); this.eventsProvider.trigger(CoreEventsProvider.IAB_LOAD_START, event);
@ -801,6 +810,7 @@ export class CoreUtilsProvider {
exitSubscription.unsubscribe(); exitSubscription.unsubscribe();
this.eventsProvider.trigger(CoreEventsProvider.IAB_EXIT, event); this.eventsProvider.trigger(CoreEventsProvider.IAB_EXIT, event);
}); });
}
return this.iabInstance; return this.iabInstance;
} }