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 { SplashScreen } from '@ionic-native/splash-screen';
import { CoreEventsProvider } from '../providers/events';
import { CoreLoggerProvider } from '../providers/logger';
import { CoreLoginHelperProvider } from '../core/login/providers/helper';
@Component({
@ -25,9 +26,13 @@ import { CoreLoginHelperProvider } from '../core/login/providers/helper';
export class MyApp implements AfterViewInit {
@ViewChild(Nav) navCtrl;
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) {
this.logger = logger.getInstance('AppComponent');
platform.ready().then(() => {
// Okay, so the platform is ready and our plugins are available.
// Here you can do any higher level native things you might need.
@ -86,8 +91,25 @@ export class MyApp implements AfterViewInit {
}, 1000);
});
// @todo: Register observer to check if the app was launched via URL scheme.
// $mmURLDelegate.register('mmLoginSSO', appLaunchedByURL);
// Handle app launched with a certain URL (custom URL scheme).
(<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.
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.
url = url.replace(ssoScheme, '');
@ -205,6 +205,8 @@ export class CoreLoginHelperProvider {
promise.then(() => {
this.openBrowserForSSOLogin(siteUrl, typeOfLogin, service, launchUrl);
}, () => {
// User cancelled, ignore.
});
}
@ -934,7 +936,7 @@ export class CoreLoginHelperProvider {
return Promise.reject(null);
}
let launchSiteURL = data.siteurl,
let launchSiteURL = data.siteUrl,
passport = data.passport;
// Reset temporary values.

View File

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

View File

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

View File

@ -790,17 +790,27 @@ export class CoreUtilsProvider {
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);
// 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) => {
this.eventsProvider.trigger(CoreEventsProvider.IAB_LOAD_START, event);
});
let exitSubscription = this.iabInstance.on('exit').subscribe((event) => {
loadStartSubscription.unsubscribe();
exitSubscription.unsubscribe();
this.eventsProvider.trigger(CoreEventsProvider.IAB_EXIT, event);
});
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.
let loadStartSubscription = this.iabInstance.on('loadstart').subscribe((event) => {
this.eventsProvider.trigger(CoreEventsProvider.IAB_LOAD_START, event);
});
let exitSubscription = this.iabInstance.on('exit').subscribe((event) => {
loadStartSubscription.unsubscribe();
exitSubscription.unsubscribe();
this.eventsProvider.trigger(CoreEventsProvider.IAB_EXIT, event);
});
}
return this.iabInstance;
}