LogonController.js

1       
2       
3           var utils = sap.logon.Utils;
4           var TIMEOUT = 2000;
5               
6           var _oLogonCore;
7           var _oLogonView;
8           var _hasLogonSuccessEventFired = false;
9                      
10      	var _providedContext;
11          
12          var init = function (successCallback, errorCallback, applicationId, context, customView) {
13          
14          
15              document.addEventListener("resume", 
16                  function(){
17                      resume(
18                          function() { fireEvent('onSapResumeSuccess', arguments);},
19                          function() { fireEvent('onSapResumeError', arguments);}                    
20                      );
21                  },
22                  false);
23      
24              // The success callback used for the call to _oLogonCore.initLogon(...)
25              var initSuccess = function(){
26                  utils.log('LogonController: LogonCore successfully initialized.');
27      
28                  // Now that Logon is initialized, registerOrUnlock is automatically called.
29                  registerOrUnlock( successCallback, errorCallback );
30              }
31                     
32              var initError = function(error){
33                  // If a parameter describing the error is given, pass it along.
34                  // Otherwise, construct something to call the error callback with.
35                  if( error ) {
36                      errorCallback( error );
37                  } else {
38                      errorCallback( utils.Error('ERR_INIT_FAILED') );
39                  }
40              }
41              
42      		utils.log('LogonController.init enter');
43      		utils.log(applicationId);
44      		module.exports.applicationId = applicationId;
45      			   
46      		// Make note of the context given (if any)
47      		if( context ){
48      			_providedContext = context;
49      		}
50                     
51      		_oLogonView = customView;
52      		if (!_oLogonView) {
53      			_oLogonView = sap.logon.IabUi;
54      		}
55      
56      		//coLogonCore.cordova.require("com.sap.mp.cordova.plugins.logon.LogonCore");
57              _oLogonCore = sap.logon.Core;
58              _oLogonCore.initLogon(initSuccess, initError, applicationId);
59                  
60              //update exports definition
61              module.exports.core = _oLogonCore;
62          }       
63              
64          var fireEvent = function (eventId, args) {
65              if (typeof eventId === 'string') {
66                  //var event = document.createEvent('Events');
67                  //event.initEvent(eventId, false, false);
68                  
69                  if (!window.CustomEvent) {
70                      window.CustomEvent = function(type, eventInitDict) {
71                          var newEvent = document.createEvent('CustomEvent');
72                          newEvent.initCustomEvent(
73                              type,
74                              !!(eventInitDict && eventInitDict.bubbles),
75                              !!(eventInitDict && eventInitDict.cancelable),
76                              (eventInitDict ? eventInitDict.detail : null));
77                          return newEvent;
78                      };
79                  }
80                  
81       			var event = new CustomEvent(eventId, { 'detail':{ 'id': eventId, 'args': args }});
82                  			
83                  setTimeout(function() {
84                      document.dispatchEvent(event);
85                  }, 0);
86              } else {
87                  throw 'Invalid eventId: ' + JSON.stringify(event);
88              }
89          }
90                     
91          var FlowRunner = function(onsuccess, onerror, pLogonView, pLogonCore) {
92                     
93              var onFlowSuccess;
94              var onFlowError;
95              var onFlowCancel;
96                     
97              var logonView;
98              var logonCore;
99              var flow;
100                 
101                 
102                 
103             logonView = pLogonView;
104             logonCore = pLogonCore;
105                    
106             onFlowSuccess = function onFlowSuccess() {
107                 utils.logJSON('onFlowSuccess');
108                 logonView.close();
109                 onsuccess.apply(this, arguments);
110             }
111     
112             onFlowError = function onFlowError() {
113                 utils.logJSON('onFlowError');
114                 logonView.close();
115                 onerror.apply(this, arguments);
116             }
117                    
118             onFlowCancel = function onFlowCancel(){
119                 utils.logJSON('onFlowCancel');
120                 //logonView.close();
121                 onFlowError(new utils.Error('ERR_USER_CANCELLED'));
122             }
123                    
124             var handleCoreStateOnly = function(currentState){
125                 handleCoreResult(null, currentState);
126             }
127             
128             var handleCoreResult = function (currentContext, currentState) {
129                 if (typeof currentContext === undefined) currentContext = null;
130                 
131                 //workaround for defaultPasscodeAllowed
132                 if (currentState) {
133                     if (currentContext && currentContext.policyContext && currentContext.policyContext.defaultAllowed){
134                         currentState.defaultPasscodeAllowed = true;
135                     }
136                     else {
137                         currentState.defaultPasscodeAllowed = false;
138                     }
139                 }
140                 
141                 utils.logJSON(currentContext, 'handleCoreResult currentContext');
142                 utils.logJSON(currentState, 'handleCoreResult currentState');
143     
144                 
145                 utils.logJSON(flow.name);
146                 var matchFound = false;
147                 var rules = flow.stateTransitions;
148                 
149                 
150                 ruleMatching:
151                 for (key in rules){
152                 
153                     var rule = flow.stateTransitions[key];
154                     //utils.logJSON(rule, 'rule');
155                    
156                     //utils.logJSON(rule.condition, 'rule.condition');
157                     if (typeof rule.condition === 'undefined') {
158                     	throw 'undefined condition in state transition rule';
159                     }
160                     
161                     
162                     if (rule.condition.state === null) {
163                     	if (currentState)
164                     	{
165                     		continue ruleMatching; // non-null state (and rule) mismatch
166                     	}
167                     	//else {
168                     	//	// match: 
169                     	//	// rule.condition.state === null &&
170                     	//	// (typeof currentState === 'undefined') // null or undefined
171                     	//}
172                     }
173                     else if (rule.condition.state !== 'undefined' && currentState){
174                     	utils.log('stateMatching');
175     	                
176                     	stateMatching:
177     		            for (field in rule.condition.state) {
178     		                utils.log(field);
179     		                if (rule.condition.state[field] === currentState[field]) 
180     		                {
181     		                    utils.log('field matching ' + field);
182     		                    continue stateMatching; // state field match 
183     		                }
184     		                else {
185     		                    utils.log('field mismatching ' + field);
186     		                    continue ruleMatching; // state field (and rule) mismatch
187     		                };
188     		            }
189                     }
190                    
191                     if (rule.condition.context === null) {
192                         if (currentContext)
193                     	{
194                             continue ruleMatching; // non-null context (and rule) mismatch
195                     	}
196                     	//else {
197                     	//	// match: 
198                     	//	// rule.condition.context === null &&
199                     	//	// (typeof currentContext === 'undefined') // null or undefined
200                     	//}
201                     }
202                     else if (rule.condition.context !== 'undefined' && currentContext){
203                    
204                         utils.log('contextMatching');
205     	                contextMatching:
206     	                for (field in rule.condition.context) {
207     	                    utils.log(field);
208     	                    if (rule.condition.context[field] === currentContext[field])
209     	                    {
210     	                        utils.log('field matching ' + field);
211     	                        continue contextMatching;  // context field match 
212     	                    }
213     	                    else {
214     	                        utils.log('field mismatching ' + field);
215     	                        continue ruleMatching;  // context field (and rule) mismatch
216     	                    };
217     	                }
218                     }
219                     utils.log('match found');
220                     utils.logJSON(rule, 'rule');
221                    
222                     if (typeof rule.action === 'function') {
223                         rule.action(currentContext);
224                     }
225                     else if (typeof rule.action === 'string') {
226                         // the action is a screenId
227                         var screenId = rule.action;
228                         utils.log('handleCoreResult: ' + screenId);
229                         utils.logKeys(flow.screenEvents[screenId]);
230     					if(!currentContext){
231                             currentContext = {};
232                         }
233     					
234                         if( !currentContext.registrationContext && _providedContext ){
235     						// The current registrationContext is null, and we have been given a context when initialized,
236     						// so use the one we were given.
237     						currentContext.registrationContext = _providedContext;
238                         } else if (currentContext.registrationContext && _providedContext && !currentContext.registrationReadOnly){
239                             for (key in _providedContext) {
240                                 //if (!currentContext.registrationContext[key]){
241                                     currentContext.registrationContext[key] = _providedContext[key];
242                                 //}
243                             }
244                         }
245                    
246                         logonView.showScreen(screenId, flow.screenEvents[screenId], currentContext);
247                         
248                     }
249                     else {
250                         onFlowError(new utils.Error('ERR_INVALID_ACTION'));
251                     }
252                    
253                     matchFound = true;
254                     break ruleMatching;
255                 }
256                 
257                 if (!matchFound) {
258                     onFlowError(new utils.Error('ERR_INVALID_STATE'));
259                 }
260             }
261             
262             
263             this.run = function(FlowClass) {
264                 utils.log('FlowRunner.run '  + FlowClass.name);
265                 flow = new FlowClass(logonCore, logonView, handleCoreResult, onFlowSuccess, onFlowError, onFlowCancel);
266                 utils.logKeys(flow , 'new flow ');
267                 logonCore.getState(handleCoreStateOnly, onFlowError);
268             }
269                    
270         }
271     
272         
273             var MockFlow = function MockFlow(logonCore, logonView, onCoreResult, onFlowSuccess, onFlowError, onFlowCancel) {
274             //wrapped into a function to defer evaluation of the references to flow callbacks
275                 //var flow = {};
276                 
277                 this.name = 'mockFlowBuilder';
278                 
279                 this.stateTransitions = [
280                 {
281                 	condition: {
282     	                state: {
283     	                	secureStoreOpen: false,
284     	                }
285                     },
286                     action: 'SCR_MOCKSCREEN'
287                 },
288                 {
289                 	condition: {
290     	                state: {
291     	                	secureStoreOpen: true,
292     	                }
293                     },
294                     action: 'SCR_MOCKSCREEN'
295                 },
296                 
297                 ];
298             
299                 this.screenEvents = {
300                     'SCR_TURN_PASSCODE_ON': {
301                         onsubmit: onFlowSuccess,
302                         oncancel: onFlowCancel,
303                         onerror: onFlowError,
304                     }
305                 };
306                 
307                 utils.log('flow constructor return');
308                 //return flow;
309             }
310             
311             var RegistrationFlow = function RegistrationFlow(logonCore, logonView, onCoreResult, onFlowSuccess, onFlowError, onFlowCancel) {
312             //wrapped into a function to defer evaluation of the references to flow callbacks
313                 
314                 this.name = 'registrationFlowBuilder';
315                 
316                 var registrationInProgress = false;
317                 
318                 var onCancelSSOPin = function() {
319                 	onFlowError(errorWithDomainCodeDescription("MAFLogon","0","SSO Passcode set screen was cancelled"));
320                 }
321                 
322                 var onCancelRegistration = function() {
323                 	onFlowError(errorWithDomainCodeDescription("MAFLogon","1","Registration screen was cancelled"));
324                 }
325                 
326                 // internal methods
327                 var showScreen = function(screenId) {
328                     return function(coreContext) {
329                         logonView.showScreen(screenId, this.screenEvents[screenId], coreContext);
330                     }.bind(this);
331                 }.bind(this);
332                 
333                 var onUnlockSubmit = function(context){
334                     utils.logJSON(context, 'logonCore.unlockSecureStore');
335                     logonCore.unlockSecureStore(onCoreResult, onUnlockError, context)
336                 }
337                 
338                 var onUnlockError = function(error) {
339                     utils.logJSON("onUnlockError: " + JSON.stringify(error));
340                     
341                     // TODO switch case according to the error codes
342                     logonView.showNotification("ERR_UNLOCK_FAILED");
343                 }
344                 
345                 var noOp = function() { }
346                 
347                 var onRegistrationBackButton = function() {
348                 	if (registrationInProgress == true) {
349                 		utils.log('back button pushed, no operation is required as registration is running');
350                 	}
351                 	else {
352                 		onCancelRegistration();
353                 	}
354                 }
355                 
356                 var onUnlockVaultWithDefaultPasscode = function(){
357                 	utils.log('logonCore.unlockSecureStore - default passcode');
358                 	var unlockContext = {"unlockPasscode":null};
359                 	logonCore.unlockSecureStore(onCoreResult, onFlowError, unlockContext)
360                 }
361                 
362                 var onRegSucceeded = function(context, state) {
363                 	onCoreResult(context, state);
364                 	registrationInProgress = false;
365                 }
366                 
367                 var onRegError = function(error){
368                 	utils.logJSON(error, 'registration failed');
369                 	logonView.showNotification(getRegistrationErrorText(error));
370                 	registrationInProgress = false;
371                 }
372                 
373                 var onRegSubmit = function(context){
374                     utils.logJSON(context, 'logonCore.startRegistration');
375                     registrationInProgress = true;
376                     logonCore.startRegistration(onRegSucceeded, onRegError, context)
377                 }
378                 
379                 var onCreatePasscodeSubmit = function(context){
380                     utils.logJSON(context, 'logonCore.persistRegistration');
381                     logonCore.persistRegistration(onCoreResult, onCreatePasscodeError, context);
382                 }
383                 
384                 var onCancelRegistrationError = function(error){
385                 	utils.logJSON("onCancelRegistrationError: " + JSON.stringify(error));            	
386                 	logonView.showNotification(getRegistrationCancelError(error));
387                 }
388     
389                 var onCreatePasscodeError = function(error) {
390                     utils.logJSON("onCreatePasscodeError: " + JSON.stringify(error));
391                     logonView.showNotification(getSecureStoreErrorText(error));
392                 }
393                 
394                 var onSSOPasscodeSetError = function(error) {
395                     utils.logJSON("onSSOPasscodeSetError: " + JSON.stringify(error));
396                    logonView.showNotification(getSSOPasscodeSetErrorText(error));
397                 }
398                 
399                 var callGetContext = function(){
400                     utils.log('logonCore.getContext');
401                     logonCore.getContext(onCoreResult, onFlowError);
402                 }
403                 
404                  var onFullRegistered = function()
405                  {
406                  	var getContextSuccessCallback = function(result){
407                  		
408                  		if(!_hasLogonSuccessEventFired) {
409                             fireEvent("onSapLogonSuccess", arguments);
410      						_hasLogonSuccessEventFired = true;
411                  		}
412                  		
413                  		onFlowSuccess(result);
414                  	}
415                      utils.log('logonCore.getContext');
416                      logonCore.getContext(getContextSuccessCallback, onFlowError);
417                  }
418                 
419                 var onForgotAppPasscode = function(){
420                 	utils.log('logonCore.deleteRegistration');
421                     logonCore.deleteRegistration(onFlowError, onFlowError);
422                 }
423     
424                 var onForgotSsoPin = function(){
425                 	utils.log('forgotSSOPin');
426                 	logonView.showNotification("ERR_FORGOT_SSO_PIN");
427                 }
428                 
429                 var onSkipSsoPin = function(){
430                     utils.logJSON('logonCore.skipClientHub');
431                     logonCore.skipClientHub(onCoreResult, onFlowError);
432                 }
433                 
434                 var callPersistWithDefaultPasscode = function(context){
435                 	utils.logJSON(context, 'logonCore.persistRegistration');
436                 	context.passcode = null;
437                 	logonCore.persistRegistration(
438                             onCoreResult,
439                             onFlowError,
440                             context)
441                 } 
442                 
443                 // exported properties
444                 this.stateTransitions = [
445                 {
446                 	condition: {
447                 		state: {
448                 			secureStoreOpen: false,
449                 			status: 'fullRegistered',
450                 			defaultPasscodeUsed: true
451                 		}
452                 	},
453                 	action: onUnlockVaultWithDefaultPasscode
454                 },
455                 
456                 {
457                 	condition: {
458     	                state: {
459     	                	secureStoreOpen: false,
460                         	status: 'fullRegistered'
461     	                }
462                     },
463                     action: 'SCR_UNLOCK'
464                 },
465     
466                 
467                 {
468                 	condition: {
469     	                state: {
470     	                    //secureStoreOpen: false, //TODO clarify
471     	                    status: 'fullRegistered',
472     	                    stateClientHub: 'availableNoSSOPin'
473     	                }
474                 	},
475                     action: 'SCR_SSOPIN_SET'
476                 },
477                 {
478                 	condition: {
479     	                state: {
480     	                	secureStoreOpen: false,
481     	                	status: 'new'
482     	                },
483     	                context: null
484                     },
485                     action: callGetContext
486                 },
487                 
488                 {
489                 	condition: {
490     	                state: {
491     	                    secureStoreOpen: false,
492     	                    status: 'new',
493     	                    stateClientHub: 'availableNoSSOPin'
494     	                }
495                 	},
496                     action: 'SCR_SSOPIN_SET'
497                 },
498                 
499                 {
500                 	condition: {
501     	                state: {
502     	                    secureStoreOpen: false,
503     	                    status: 'new',
504     	                    stateClientHub: 'availableInvalidSSOPin'
505     	                }
506                 	},
507                     action: 'SCR_SSOPIN_SET'
508                 },
509     
510                 {
511                 	condition: {
512     	                state: {
513     	                    secureStoreOpen: false,
514     	                    status: 'new',
515     	                    stateClientHub: 'availableValidSSOPin'
516     	                },
517                 		context : {
518                 			credentialsByClientHub : true,
519                 			registrationReadOnly : true
520                 		}
521                 	},
522                     action: function(context){
523                         utils.logJSON(context, 'logonCore.startRegistration');
524                         logonCore.startRegistration(onCoreResult, onFlowError, context.registrationContext);
525                     }
526                 },
527                 {
528                 	condition: {
529     	                state: {
530     	                    secureStoreOpen: false,
531     	                    status: 'new',
532     	                    stateClientHub: 'availableValidSSOPin',
533                             stateAfaria: 'initializationSuccessful'
534     	                },
535                 		context : {
536                 			registrationReadOnly : true,
537                             afariaRegistration: 'certificate'
538                 		}
539                 	},
540                     action: function(context){
541                         utils.logJSON(context, 'logonCore.startRegistration');
542                         logonCore.startRegistration(onCoreResult, onFlowError, context.registrationContext);
543                     }
544                 },
545                 {
546                 	condition: {
547     	                state: {
548     	                    secureStoreOpen: false,
549     	                    status: 'new',
550     	                    stateClientHub: 'availableValidSSOPin'
551     	                },
552                 		context : {
553                 			registrationReadOnly :true,
554                 			credentialsByClientHub : false
555                 		}
556                 	},
557                     action: 'SCR_ENTER_CREDENTIALS'
558                 },
559                 
560                 
561                 {
562                 	condition: {
563     	                state: {
564     	                    secureStoreOpen: false,
565     	                    status: 'new',
566     	                    //stateClientHub: 'notAvailable' | 'availableValidSSOPin' | 'skipped' | 'error'
567     	                    stateAfaria: 'initializationFailed'
568     	                }
569                 	},
570                     action: 'SCR_REGISTRATION'
571                 },
572                 
573                 {
574                 	condition: {
575     	                state: {
576     	                    secureStoreOpen: false,
577     	                    status: 'new',
578     	                    //stateClientHub: 'notAvailable' | 'availableValidSSOPin' | 'skipped' | 'error'
579     	                }
580                 	},
581                     action: 'SCR_REGISTRATION'
582                 },
583                 
584                 {
585                 	condition: {
586     	                state: {
587     	                    secureStoreOpen: false,
588     	                    status: 'new',
589     	                    //stateClientHub: 'notAvailable' | 'availableValidSSOPin' | 'skipped' | 'error'
590     	                    stateAfaria: 'initializationFailed'
591     	                }
592                 	},
593                     action: 'SCR_REGISTRATION'
594                 },
595     
596                 {
597                     condition: {
598     	                state: {
599     	                	secureStoreOpen: false,
600                             status: 'registered',
601                             defaultPasscodeUsed: true,
602     //                        defaultPasscodeAllowed: true,
603     	                }
604                     },
605                     action: 'SCR_SET_PASSCODE_OPT_OFF'
606                 },
607                 {
608                 	condition: {
609     	                state: {
610     	                	secureStoreOpen: false,
611                             status: 'registered',
612                             defaultPasscodeUsed: false,
613                             defaultPasscodeAllowed: true,
614     	                }
615                     },
616                     action: 'SCR_SET_PASSCODE_OPT_ON'
617                 },
618                 {
619                 	condition: {
620     	                state: {
621     	                	secureStoreOpen: false,
622                             status: 'registered',
623     //                        defaultPasscodeAllowed: false,
624     	                }
625                     },
626                     action: 'SCR_SET_PASSCODE_MANDATORY'
627                 },
628                 
629                 
630                 {
631                 	condition: {
632     	                state: {
633     	                    //secureStoreOpen: false, //TODO clarify
634     	                    status: 'fullRegistered',
635     	                    stateClientHub: 'availableInvalidSSOPin'
636     	                }
637                 	},
638                     action: 'SCR_SSOPIN_CHANGE'
639                 },
640                 {
641                 	condition: {
642     	                state: {
643     	                	secureStoreOpen: true,
644     	                	status: 'fullRegistered',
645     	                	stateClientHub: 'notAvailable'
646     	                }
647                     },
648                     action: onFullRegistered
649                 },
650                 {
651                 	condition: {
652     	                state: {
653     	                	secureStoreOpen: true,
654     	                	status: 'fullRegistered',
655     	                	stateClientHub: 'availableValidSSOPin'
656     	                }
657                     },
658                     action: onFullRegistered
659                 },
660                 {
661                 	condition: {
662     	                state: {
663     	                	secureStoreOpen: true,
664     	                	status: 'fullRegistered',
665     	                	stateClientHub: 'skipped'
666     	                }
667                     },
668                     action: onFullRegistered
669                 },
670     
671                 
672     
673                 ];
674                 
675                 this.screenEvents = {
676                 	'SCR_SSOPIN_SET': {
677                         onsubmit: function(context){
678                             utils.logJSON(context, 'logonCore.setSSOPasscode');
679                             logonCore.setSSOPasscode(onCoreResult, onSSOPasscodeSetError, context);
680                         },
681                         oncancel: onCancelSSOPin,
682                         onerror: onFlowError,
683                         onforgot: onForgotSsoPin,
684                         onskip: onSkipSsoPin
685                     },
686                     
687                 	'SCR_SSOPIN_CHANGE': {
688                         onsubmit: function(context){
689                             utils.logJSON(context, 'logonCore.setSSOPasscode');
690                             logonCore.setSSOPasscode(onCoreResult, onSSOPasscodeSetError, context);
691                         },
692                         oncancel: onSkipSsoPin,
693                         onerror: onFlowError,
694                         onforgot: onForgotSsoPin
695                     },
696                 		
697                     'SCR_UNLOCK': {
698                         onsubmit: onUnlockSubmit,
699                         oncancel: noOp,
700                         onerror: onFlowError,
701                         onforgot: onForgotAppPasscode,
702                         onerrorack: noOp  
703                     },
704                    
705                     'SCR_REGISTRATION':  {
706                         onsubmit: onRegSubmit,
707                         oncancel: onCancelRegistration,
708                         onerror: onFlowError,
709                         onbackbutton: onRegistrationBackButton
710                     },
711                     
712                     'SCR_ENTER_CREDENTIALS' : {
713                     	onsubmit: onRegSubmit,
714                         oncancel: onCancelRegistration,
715                         onerror: onFlowError
716                     },
717                     'SCR_SET_PASSCODE_OPT_ON': {
718                         onsubmit: onCreatePasscodeSubmit,
719                         oncancel: noOp,
720                         onerror: onFlowError,
721                         ondisable: showScreen('SCR_SET_PASSCODE_OPT_OFF'),
722                         onerrorack: noOp  
723                     },
724                     'SCR_SET_PASSCODE_OPT_OFF': {
725                         onsubmit: callPersistWithDefaultPasscode,
726                         oncancel: noOp,
727                         onerror: onFlowError,
728                         onenable: showScreen('SCR_SET_PASSCODE_OPT_ON'),
729                         onerrorack: noOp  
730                     },
731                     'SCR_SET_PASSCODE_MANDATORY': {
732                         onsubmit: onCreatePasscodeSubmit,
733                         oncancel: noOp,
734                         onerror: onFlowError,
735                         onerrorack: noOp  
736                     },
737                     
738                     
739                    
740                 };
741     
742                 
743                 utils.log('flow constructor return');
744             }
745             
746             
747             
748             var ChangePasswordFlow = function ChangePasswordFlow(logonCore, logonView, onCoreResult, onFlowSuccess, onFlowError, onFlowCancel) {
749             //wrapped into a function to defer evaluation of the references to flow callbacks
750             
751                 this.name = 'changePasswordFlowBuilder';
752                 
753                 
754                 // internal methods      
755     
756                 var callUnlockFlow = function(){
757                         utils.log(this.name + ' triggered unlock');
758                         registerOrUnlock(onCoreResult,onFlowError); 
759                 }
760     
761                 var onChangePasswordSubmit = function(context){
762                     utils.logJSON(context, 'logonCore.changePassword');
763                     // this logonCore call does not return with context
764                     logonCore.changePassword(onPasswordChanged, onFlowError, context);
765                 }
766     
767                 
768                 var onPasswordChanged = function(){
769                     utils.log('onPasswordChanged');
770                     logonCore.getContext(onFlowSuccess, onFlowError);
771                 }
772     
773                 // exported properties
774                 this.stateTransitions = [
775                 {
776                 	condition: {
777     	                state: {
778     	                	secureStoreOpen: false,
779     	                }
780                     },
781                     action: callUnlockFlow,
782                 },
783                 {
784                 	condition: {
785     	                state: {
786     	                	secureStoreOpen: true,
787     	                }
788                     },
789                     action: 'SCR_CHANGE_PASSWORD'
790                 },
791                 
792                 ];
793                 
794                 this.screenEvents = {
795                     'SCR_CHANGE_PASSWORD': {
796                         onsubmit: onChangePasswordSubmit,
797                         oncancel: onFlowCancel,
798                         onerror: onFlowError
799                     }
800                 };
801                 
802                 
803                 utils.log('flow constructor return');
804             }
805             
806             var ManagePasscodeFlow = function ManagePasscodeFlow(logonCore, logonView, onCoreResult, onFlowSuccess, onFlowError, onFlowCancel) {
807             //wrapped into a function to defer evaluation of the references to flow callbacks
808             
809                 this.name = 'managePasscodeFlowBuilder';
810                 
811                 // internal methods
812                 var showScreen = function(screenId) {
813                     return function(coreContext) {
814                         logonView.showScreen(screenId, this.screenEvents[screenId], coreContext);
815                     }.bind(this);
816                 }.bind(this);
817                 
818                 
819                 var callChangePasscode = function(context){
820                         utils.logJSON(context, 'logonCore.changePasscode');
821                         logonCore.changePasscode(
822                             onCoreResult,
823                             onChangePasscodeError,
824                             context)
825                 }
826                 
827                 var onChangePasscodeError = function(error) {
828                     utils.logJSON("onChangePasscodeError: " + JSON.stringify(error));
829                     logonView.showNotification(getSecureStoreErrorText(error));
830                 }           
831     
832                 var noOp = function() { }
833                 
834                 var callDisablePasscode = function(context){
835                 	utils.logJSON(context, 'logonCore.disablePasscode');
836                 	context.passcode = null;
837                 	logonCore.changePasscode(
838                             onCoreResult,
839                             onFlowError,
840                             context)
841                 }
842                             
843                 var callGetContext = function(){
844                     utils.log('logonCore.getContext');
845                     logonCore.getContext(onCoreResult, onFlowError);
846                 }
847                 
848                 var onPasscodeEnable = function(context){
849                     utils.logJSON(context, this.name + ' onPasscodeEnable: ');
850                     //logonCore.changePasscode(onFlowSuccess, onFlowError, context);
851                     onFlowError();
852                 }
853         
854                 // exported properties
855                 this.stateTransitions = [
856                 {
857                 	condition: {
858     	                state: {
859     	                	secureStoreOpen: true,
860     	                },
861     	                context: null
862                     },
863                     action: callGetContext
864                 },
865                 {
866                 	condition: {
867     	                state: {
868     	                	secureStoreOpen: false,
869     	                }
870                     },
871                     action: onFlowError
872                 },
873                 {
874                 	condition: {
875     	                state: {
876     	                	secureStoreOpen: true,
877                             defaultPasscodeUsed: true,
878     //                        defaultPasscodeAllowed: true,
879     	                }
880                     },
881                     action: 'SCR_MANAGE_PASSCODE_OPT_OFF'
882                 },
883                 {
884                 	condition: {
885     	                state: {
886     	                	secureStoreOpen: true,
887                             defaultPasscodeUsed: false,
888                             defaultPasscodeAllowed: true,
889     	                }
890                     },
891                     action: 'SCR_MANAGE_PASSCODE_OPT_ON'
892                 },
893                 {
894                 	condition: {
895     	                state: {
896     	                	secureStoreOpen: true,
897                             //defaultPasscodeUsed: [DONTCARE],
898                             defaultPasscodeAllowed: false,
899     	                }
900                     },
901                     action: 'SCR_MANAGE_PASSCODE_MANDATORY'
902                 },
903     
904                 
905                 ];
906                 
907                 this.screenEvents = {
908                     'SCR_MANAGE_PASSCODE_OPT_ON': {
909                         onsubmit: onFlowSuccess,
910                         oncancel: onFlowSuccess,
911                         onerror: onFlowError,
912                         ondisable: showScreen('SCR_CHANGE_PASSCODE_OPT_OFF'),
913                         onchange: showScreen('SCR_CHANGE_PASSCODE_OPT_ON')
914                     },
915                     'SCR_MANAGE_PASSCODE_OPT_OFF': {
916                         onsubmit: onFlowSuccess,
917                         oncancel: onFlowSuccess,
918                         onerror: onFlowError,
919                         onenable: showScreen('SCR_SET_PASSCODE_OPT_ON')
920                     },
921                     'SCR_MANAGE_PASSCODE_MANDATORY': {
922                         onsubmit: onFlowSuccess,
923                         oncancel: onFlowSuccess,
924                         onerror: onFlowError,
925                         onchange: showScreen('SCR_CHANGE_PASSCODE_MANDATORY')
926                     },
927                    
928                    
929                     'SCR_SET_PASSCODE_OPT_ON': {
930                         onsubmit: callChangePasscode,
931                         oncancel: onFlowCancel,
932                         onerror: onFlowError,
933                         ondisable: showScreen('SCR_SET_PASSCODE_OPT_OFF'),
934                         onerrorack: noOp  
935                     },
936                     'SCR_SET_PASSCODE_OPT_OFF': {
937                         onsubmit: callDisablePasscode,
938                         oncancel: onFlowCancel,
939                         onerror: onFlowError,
940                         onenable: showScreen('SCR_SET_PASSCODE_OPT_ON'),
941                         onerrorack: noOp  
942                     },
943                     'SCR_CHANGE_PASSCODE_OPT_ON': {
944                         onsubmit: callChangePasscode,
945                         oncancel: onFlowCancel,
946                         onerror: onFlowError,
947                         ondisable: showScreen('SCR_CHANGE_PASSCODE_OPT_OFF'),
948                         onerrorack: noOp  
949                     },
950                     'SCR_CHANGE_PASSCODE_OPT_OFF': {
951                         onsubmit: callDisablePasscode,
952                         oncancel: onFlowCancel,
953                         onerror: onFlowError,
954                         onenable: showScreen('SCR_CHANGE_PASSCODE_OPT_ON'),
955                         onerrorack: noOp  
956                     },
957                     'SCR_CHANGE_PASSCODE_MANDATORY': {
958                         onsubmit: callChangePasscode,
959                         oncancel: onFlowCancel,
960                         onerror: onFlowError,
961                         onerrorack: noOp  
962                     },
963                    
964                 };
965     
966                 
967                 utils.log('flow constructor return');
968             }
969             
970             var ShowRegistrationFlow = function ShowRegistrationFlow(logonCore, logonView, onCoreResult, onFlowSuccess, onFlowError, onFlowCancel) {
971             //wrapped into a function to defer evaluation of the references to flow callbacks
972                 
973                 this.name = 'showRegistrationFlowBuilder';
974                 
975                 var showRegistrationInfo = function(context) {
976                 	logonView.showScreen('SCR_SHOW_REGISTRATION', this.screenEvents['SCR_SHOW_REGISTRATION'], context);
977                 }.bind(this);
978                 
979                 var callGetContext = function(){
980                     utils.log('logonCore.getContext');
981                     logonCore.getContext(onCoreResult, onFlowError);
982                 }
983                
984                 // exported properties
985                 this.stateTransitions = [
986                 {
987                 	condition: {
988     	                state: {
989     	                	secureStoreOpen: true,
990     	                	
991     	                },
992     	                context: null
993                     },
994                     action: callGetContext
995                 },
996                 {
997                     condition: {
998                         secureStoreOpen: true,
999                     },
1000                    action: showRegistrationInfo
1001                }
1002                
1003                ];
1004                
1005                this.screenEvents = {
1006                    'SCR_SHOW_REGISTRATION': {
1007                        oncancel: onFlowSuccess,
1008                        onerror: onFlowError
1009                    }
1010                };
1011    
1012    
1013                utils.log('flow constructor return');
1014            }
1015            
1016    // === flow launcher methods =====================================
1017              
1018                
1019            var resume = function (onsuccess, onerror) {
1020            	
1021            	var onUnlockSuccess = function(){
1022            		_oLogonCore.onEvent(onsuccess, onerror, 'RESUME');
1023            	}
1024                
1025                var onGetStateSuccess = function(state) {
1026            	//call registration flow only if the status is fullregistered in case of resume, so logon screen will not loose its input values
1027            		if (state.status == 'fullRegistered') {
1028            			registerOrUnlock(onUnlockSuccess, onerror);
1029            		}
1030                }
1031                
1032                getState(onGetStateSuccess, onerror);
1033            }
1034            
1035    
1036            var get = function (onsuccess, onerror, key) {
1037            	
1038            	var onUnlockSuccess = function(){
1039            		_oLogonCore.getSecureStoreObject(onsuccess, onerror, key);
1040            	}
1041            	
1042            	registerOrUnlock(onUnlockSuccess, onerror);
1043            }
1044    
1045    
1046    
1047            var set = function (onsuccess, onerror, key, value) {
1048            	
1049            	var onUnlockSuccess = function(){
1050            		_oLogonCore.setSecureStoreObject(onsuccess, onerror, key, value);	
1051            	}
1052    
1053            	registerOrUnlock(onUnlockSuccess, onerror);
1054            }
1055            
1056    
1057    
1058            var lock = function (onsuccess, onerror) {
1059                _oLogonCore.lockSecureStore(onsuccess, onerror);
1060            }
1061            
1062            var getState = function (onsuccess, onerror) {
1063            	_oLogonCore.getState(onsuccess, onerror);
1064            }
1065    
1066    
1067            var registerOrUnlock = function(onsuccess, onerror) {
1068                var flowRunner = new FlowRunner(onsuccess, onerror, _oLogonView, _oLogonCore);
1069                flowRunner.run(RegistrationFlow);
1070    		}
1071    
1072            var changePassword = function(onsuccess, onerror) {
1073            	
1074            	var onUnlockSuccess = function(){
1075                    var innerFlowRunner = new FlowRunner(onsuccess, onerror, _oLogonView, _oLogonCore);
1076                    innerFlowRunner.run(ChangePasswordFlow);
1077            	}
1078    
1079            	registerOrUnlock(onUnlockSuccess, onerror);
1080    		}
1081            
1082            
1083            var forgottenPasscode = function(onsuccess, onerror) {
1084            	
1085            	var onUnlockSuccess = function(){
1086                    var innerFlowRunner = new FlowRunner(onsuccess, onerror, _oLogonView, _oLogonCore);
1087                    innerFlowRunner.run(MockFlow);
1088            	}
1089    
1090            	registerOrUnlock(onUnlockSuccess, onerror);
1091    		}
1092            
1093            var managePasscode = function(onsuccess, onerror) {
1094            	
1095            	var onUnlockSuccess = function(){
1096                    var innerFlowRunner = new FlowRunner(onsuccess, onerror, _oLogonView, _oLogonCore);
1097                    innerFlowRunner.run(ManagePasscodeFlow);
1098            	}
1099    
1100            	registerOrUnlock(onUnlockSuccess, onerror);
1101    		}
1102    
1103            var showRegistrationData = function(onsuccess, onerror) {
1104            	var onUnlockSuccess = function(){
1105                    var innerFlowRunner = new FlowRunner(onsuccess, onerror, _oLogonView, _oLogonCore);
1106                    innerFlowRunner.run(ShowRegistrationFlow);
1107            	}
1108    
1109            	registerOrUnlock(onUnlockSuccess, onerror);
1110    		}
1111    
1112            var getSecureStoreErrorText = function(error) {
1113                utils.logJSON('LogonController.getSecureStoreErrorText: ' + JSON.stringify(error));
1114    
1115            	var errorText;
1116            	
1117            	if(error.errorCode === '14' && error.errorDomain === 'MAFSecureStoreManagerErrorDomain')
1118            		errorText = "ERR_PASSCODE_TOO_SHORT";
1119            	else if(error.errorCode === '10' && error.errorDomain === 'MAFSecureStoreManagerErrorDomain')
1120            		errorText = "ERR_PASSCODE_REQUIRES_DIGIT";
1121            	else if(error.errorCode === '13' && error.errorDomain === 'MAFSecureStoreManagerErrorDomain')
1122            		errorText = "ERR_PASSCODE_REQUIRES_UPPER";
1123            	else if(error.errorCode === '11' && error.errorDomain === 'MAFSecureStoreManagerErrorDomain')
1124            		errorText = "ERR_PASSCODE_REQUIRES_LOWER";
1125            	else if(error.errorCode === '12' && error.errorDomain === 'MAFSecureStoreManagerErrorDomain')
1126            		errorText = "ERR_PASSCODE_REQUIRES_SPECIAL";
1127            	else if(error.errorCode === '15' && error.errorDomain === 'MAFSecureStoreManagerErrorDomain')
1128            		errorText = "ERR_PASSCODE_UNDER_MIN_UNIQUE_CHARS";
1129            	else {
1130            		errorText = "ERR_SETPASSCODE_FAILED";
1131            	}
1132            	
1133            	return errorText;
1134            }
1135            
1136            var getSSOPasscodeSetErrorText = function(error) {
1137                utils.logJSON('LogonController.getSSOPasscodeSetErrorText: ' + JSON.stringify(error));
1138                
1139                var errorText;
1140                
1141                if (error.errorDomain === 'MAFLogonCoreErrorDomain') {
1142            		if (error.errorCode === '16') {
1143            			errorText = "ERR_SSO_PASSCODE_SET_ERROR";
1144            		}
1145            	}
1146                
1147                return errorText;
1148            }
1149            
1150            var getRegistrationErrorText = function(error) {
1151            	utils.logJSON('LogonController.getRegistrationErrorText: ' + JSON.stringify(error));
1152            	
1153            	var errorText;
1154            	
1155            	if (error.errorDomain === 'MAFLogonCoreErrorDomain') {
1156            		if (error.errorCode === '80003') {
1157            			errorText = "ERR_REG_FAILED_WRONG_SERVER";
1158            		}
1159            		//in case of wrong application id
1160            		else if (error.errorCode === '404') {
1161            			errorText = "ERR_REG_FAILED";
1162            		}
1163            		else if (error.errorCode === '401') {
1164            			errorText = "ERR_REG_FAILED_UNATHORIZED";
1165            		}
1166            		else {
1167            			errorText = "ERR_REG_FAILED";
1168            		}
1169            	}
1170            	
1171            	return errorText;
1172            }
1173            
1174            var getRegistrationCancelError = function(error) {
1175            	utils.logJSON('LogonController.getRegistrationCancelError: ' + JSON.stringify(error));
1176            	
1177            	var errorText;
1178            	
1179            	errorText = "ERR_REGISTRATION_CANCEL";
1180            	
1181            	return errorText;
1182            }
1183            
1184            var errorWithDomainCodeDescription = function(domain, code, description) {
1185            	var error = {
1186            		errorDomain: domain,
1187            		errorCode: code,
1188            		errorMessage: description
1189            	};
1190            		
1191            	return error;
1192            }
1193            
1194            
1195                   
1196    		
1197    // =================== exported (public) members ====================
1198    
1199    	/**
1200    	 * The Logon plugin provides screen flows to register an app with an SAP Mobile Platform server.<br/>
1201    	 * <br/>
1202    	 * The logon plugin is a component of the SAP Mobile Application Framework (MAF), exposed as a Cordova plugin. The basic
1203    	 * idea is that it provides screen flows where the user can enter the values needed to connect to an SAP Mobile Platform 3.0 server and
1204    	 * stores those values in its own secure data vault. This data vault is separate from the one provided with the
1205    	 * encrypted storage plugin. In an OData based SAP Mobile Platform 3.0 application, a client must onboard or register with the SAP Mobile Platform 3.0
1206    	 * server to receive an application connection ID for a particular app. The application connection ID must be sent
1207    	 * along with each request that is proxied through the SAP Mobile Platform 3.0 server to the OData producer.<br/>
1208    	 * <br/>
1209    	 * <b>Adding and Removing the Logon Plugin</b><br/>
1210    	 * The Logon plugin is added and removed using the
1211    	 * <a href="http://cordova.apache.org/docs/en/edge/guide_cli_index.md.html#The%20Command-line%20Interface">Cordova CLI</a>.<br/>
1212    	 * <br/>
1213    	 * To add the Logon plugin to your project, use the following command:<br/>
1214    	 * cordova plugin add <full path to directory containing Kapsel plugins>\logon<br/>
1215    	 * <br/>
1216    	 * To remove the Logon plugin from your project, use the following command:<br/>
1217    	 * cordova plugin rm com.sap.mp.cordova.plugins.logon
1218    	 *
1219    	 * @namespace
1220     	 * @alias Logon
1221     	 * @memberof sap
1222     	 */
1223        module.exports = {
1224            
1225        /**
1226    	 * Initialization method to set up the Logon plugin.  This will register the application with the SMP server and also authenticate the user
1227    	 * with servers on the network.  This step must be done first prior to any attempt to communicate with the SMP server.
1228    	 *
1229    	 * @method
1230    	 * @param {sap.Logon~successCallback} successCallback The function that is invoked if initialization is successful.  The current
1231    	 * context is passed to this function as the parameter.
1232    	 * @param {sap.Logon~errorCallback} errorCallback The function that is invoked in case of an error.
1233    	 * @param {string} applicationId The unique ID of the application.  Must match the application ID on the SAP Mobile Platform server.
1234    	 * @param {object} [context] The context with default values for application registration.  See {@link sap.Logon~successCallback} for the structure
1235    	 * of the context object.  Note that all properties of the context object are optional, and you only need to specify the properties
1236    	 * for which you want to provide default values for.  The values will be presented to the application users during the registration process and given them
1237    	 * a chance to override these values during runtime.
1238    	 * @param {string} [logonView="com/sap/mp/logon/iabui"] The cordova module ID of a custom renderer for the logon,
1239    	 * implementing the [showScreen(), close()] interface.  Please use the defaul module unless you are absolutely sure that you can provide your own
1240    	 * custom implementation.  Please refer to JavaScript files inside your Kapsel project's plugins\logon\www\common\modules\ folder as example.
1241    	 * @example
1242    	 * // a custom UI can be loaded here
1243    	 * var logonView = sap.logon.IabUi;
1244    	 *
1245    	 * // The app ID
1246    	 * var applicationId = "someAppID";
1247    	 *
1248    	 * // You only need to specify the fields for which you want to set the default.   These values are optional because they will be 
1249    	 * // used to prefill the fields on Logon's UI screen.  
1250    	 * var defaultContext = {
1251    	 *  "serverHost" : "defaultServerHost.com"
1252    	 *	"https" : false,
1253    	 *	"serverPort" : "8080",
1254    	 *	"user" : "user1",
1255    	 *	"password" : "Zzzzzz123",
1256    	 *	"communicatorId" : "REST",
1257    	 *	"securityConfig" : "sec1",
1258    	 *	"passcode" : "Aaaaaa123",
1259    	 *	"unlockPasscode" : "Aaaaaa123"
1260    	 * };
1261    	 *
1262    	 * var app_context;
1263    	 *
1264    	 * var successCallback = function(context){
1265    	 *     app_context = context;
1266    	 * }
1267    	 *
1268    	 * var errorCallback = function(errorInfo){
1269    	 *     alert("error: " + JSON.stringify(errorInfo));
1270    	 * }
1271    	 * sap.Logon.init(successCallback, errorCallback, applicationId, defaultContext, logonView);
1272    	 */
1273    	   init: init,
1274            
1275           /**
1276            * The application ID with which {@link sap.Logon.init} was called.  It is available here so it is easy to access later.
1277    		* @example
1278    		* // After calling the init function
1279    		* alert("The app ID for this app is: " + sap.Logon.applicationId);
1280            */ 
1281           applicationId: null,
1282    	/**
1283    	 * Direct reference to the logon core object used by the Logon plugin.  This is needed to perform more complex operations that
1284    	 * are not generally needed by applications. <br/>
1285    	 * There are several functions that can be accessed on the core object:<br/>
1286    	 * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; getState(successCallback,errorCallback) returns the state object of the application to the success callback in the form of a JavaScript object.<br/>
1287    	 * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; getContext(successCallback,errorCallback) returns the context object of the application to the success callback in the form of a JavaScript object.<br/>
1288    	 * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; deleteRegistration(successCallback,errorCallback) deletes the application's registration from the SAP Mobile Platform server and removes<br/>
1289    	 * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; application data on device.<br/>
1290    	 * @example
1291    	 * var successCallback = function(result){
1292    	 *     alert("Result: " + JSON.stringify(result));
1293    	 * }
1294    	 * var errorCallback = function(errorInfo){
1295    	 *     alert("Error: " + JSON.stringify(errorInfo));
1296    	 * }
1297    	 * sap.Logon.core.getState(successCallback,errorCallback);
1298    	 * sap.Logon.core.getContext(successCallback,errorCallback);
1299    	 * sap.Logon.core.deleteRegistration(successCallback,errorCallback);
1300    	 */
1301                core: _oLogonCore, //Must be updated after init
1302    
1303    	/**
1304    	 * Get an  (JSON serializable) object from the DataVault for a given key.
1305    	 * @method
1306    	 * @param {sap.Logon~getSuccessCallback} onsuccess The function that is invoked
1307    	 * upon success.  It is called with the resulting object as a single parameter.
1308    	 * This can be null or undefined, if no object is defined for the given key.
1309    	 * @param {sap.Logon~errorCallback} onerror The function to invoke in case of error.
1310    	 * @param {string} key The key with which to query the DataVault.
1311    	 * @example
1312    	 * var errorCallback = function(errorInfo){
1313    	 *     alert("Error: " + JSON.stringify(errorInfo));
1314    	 * }
1315    	 * var getSuccess = function(value){
1316    	 *     alert("value retrieved from the store: " + JSON.stringify(value));
1317    	 * }
1318    	 * var setSuccess = function(){
1319    	 *     sap.Logon.get(getSuccess,errorCallback,'someKey');
1320    	 * }
1321    	 * sap.Logon.set(setSuccess,errorCallback,'someKey', 'some string (could also be an object).');
1322    	 */           
1323                get: get,
1324    
1325    	/**
1326    	 * Set an (JSON serializable) object in the DataVault.
1327    	 * @method
1328    	 * @param {sap.Logon~successCallbackNoParameters} onsuccess The function to invoke upon success.
1329    	 * onsuccess will be called without parameters for this method. 
1330    	 * @param {sap.Logon~errorCallback} onerror The function to invoke in case of error.
1331    	 * @param {string} key The key to store the provided object on.
1332    	 * @param {object} value The object to be set on the given key.  Must be JSON serializable (ie:
1333    	 * cannot contain circular references).
1334    	 * @example
1335    	 * var errorCallback = function(errorInfo){
1336    	 *     alert("Error: " + JSON.stringify(errorInfo));
1337    	 * }
1338    	 * var getSuccess = function(value){
1339    	 *     alert("value retrieved from the store: " + JSON.stringify(value));
1340    	 * }
1341    	 * var setSuccess = function(){
1342    	 *     sap.Logon.get(getSuccess,errorCallback,'someKey');
1343    	 * }
1344    	 * sap.Logon.set(setSuccess,errorCallback,'someKey', 'some string (could also be an object).');
1345    	 */
1346                set: set,
1347    
1348    	/**
1349    	 * Locks the Logon plugin's secure data vault.  
1350    	 * @method
1351    	 * @param {sap.Logon~successCallbackNoParameters} onsuccess The function to invoke upon success. 
1352    	 * @param {sap.Logon~errorCallback} onerror The function to invoke in case of error.
1353    	 * @example
1354    	 * var errorCallback = function(errorInfo){
1355    	 *     alert("Error: " + JSON.stringify(errorInfo));
1356    	 * }
1357    	 * var successCallback = function(){
1358    	 *     alert("Locked!");
1359    	 * }
1360    	 * sap.Logon.lock(successCallback,errorCallback);
1361    	 */
1362                lock: lock,
1363    
1364    	/**
1365    	 * Unlock the Logon plugin's secure data vault if it has been locked (due to being inactive, or
1366    	 * {@link sap.Logon.lock} being called), then the user is prompted for the passcode to unlock the
1367    	 * application.<br/>
1368    	 * If the application is already unlocked, then nothing will be done.<br/>
1369    	 * If the application has passcode disabled, then passcode prompt will not be necessary.
1370    	 * In all cases if an error does not occur, the success callback is invoked with the current logon context
1371    	 * as the parameter.
1372    	 * @method
1373    	 * @param {sap.Logon~successCallback} onsuccess - The callback to call if the screen flow succeeds.
1374    	 * onsuccess will be called with the current logon context as a single parameter. 
1375    	 * @param {sap.Logon~errorCallback} onerror - The callback to call if the screen flow fails.
1376    	 * @example
1377    	 * var errorCallback = function(errorInfo){
1378    	 *     alert("Error: " + JSON.stringify(errorInfo));
1379    	 * }
1380    	 * var successCallback = function(context){
1381    	 *     alert("Registered and unlocked.  Context: " + JSON.stringify(context));
1382    	 * }
1383    	 * sap.Logon.unlock(successCallback,errorCallback);
1384    	 */
1385    	    unlock: registerOrUnlock,
1386    
1387    	/**
1388    	 * This is an alias for registerOrUnlock.  Calling this function is equivalent
1389    	 * to calling {@link sap.Logon.unlock} since both of them are alias to registerOrUnlock.
1390    	 * @method
1391    	 * @private
1392    	 */
1393                registerUser: registerOrUnlock,
1394    
1395    	/**
1396    	 * This function registers the user and creates a new unlocked DataVault to store the registration
1397    	 * information.<br/>
1398    	 * If the user has already been registered, but the application is locked (due to being inactive, or
1399    	 * {@link sap.Logon.lock} being called), then the user is prompted for the passcode to unlock the
1400    	 * application.<br/>
1401    	 * If the application is already unlocked, then nothing will be done.<br/>
1402    	 * In all cases if an error does not occur, the success callback is invoked with the current logon context
1403    	 * as the parameter.
1404    	 * @method
1405    	 * @param {sap.Logon~successCallback} onsuccess - The callback to call if the screen flow succeeds.
1406    	 * onsuccess will be called with the current logon context as a single parameter. 
1407    	 * @param {sap.Logon~errorCallback} onerror - The callback to call if the screen flow fails.
1408    	 * @example
1409    	 * var errorCallback = function(errorInfo){
1410    	 *     alert("Error: " + JSON.stringify(errorInfo));
1411    	 * }
1412    	 * var successCallback = function(context){
1413    	 *     alert("Registered and unlocked.  Context: " + JSON.stringify(context));
1414    	 * }
1415    	 * sap.Logon.registerOrUnlock(successCallback,errorCallback);
1416    	 * @private
1417    	 */ 
1418    	    registerOrUnlock: registerOrUnlock,
1419    
1420    	/**
1421    	 * This method will launch the UI screen for application users to manage and update the data vault passcode or, 
1422    	 * if the SMP server's Client Passcode Policy allows it, enable or disable the passcode to the data vault.
1423    	 * 
1424    	 * @method
1425    	 * @param {sap.Logon~successCallbackNoParameters} onsuccess - The function to invoke upon success.  
1426    	 * @param {sap.Logon~errorCallback} onerror - The function to invoke in case of error.
1427    	 * @example
1428    	 * var errorCallback = function(errorInfo){
1429    	 *     alert("Error: " + JSON.stringify(errorInfo));
1430    	 * }
1431    	 * var successCallback = function(context){
1432    	 *     alert("Passcode successfully managed.");
1433    	 * }
1434    	 * sap.Logon.managePasscode(successCallback,errorCallback);
1435    	 */ 
1436    	    managePasscode: managePasscode,
1437    
1438    	/**
1439    	 * This method will launch the UI screen for application users to manage and update the back end passcode that Logon stores in the 
1440    	 * data vault that is used to authenticate the client to the server.
1441    	 * 
1442    	 * @method
1443    	 * @param {sap.Logon~successCallbackNoParameters} onsuccess - The callback to call if the screen flow succeeds.
1444    	 * onsuccess will be called without parameters for this method.
1445    	 * @param {sap.Logon~errorCallback} onerror The function that is invoked in case of an error.
1446    	 * @example
1447    	 * var errorCallback = function(errorInfo){
1448    	 *     alert("Error: " + JSON.stringify(errorInfo));
1449    	 * }
1450    	 * var successCallback = function(context){
1451    	 *     alert("Password successfully changed.");
1452    	 * }
1453    	 * sap.Logon.changePassword(successCallback,errorCallback);
1454    	 */ 
1455                changePassword: changePassword,
1456    
1457    	/**
1458    	 * Calling this method will show a UI screen with values used for registrating application.
1459    	 * @method
1460    	 * @param {sap.Logon~successCallbackNoParameters} onsuccess - The callback to call if the screen flow succeeds.
1461    	 * onsuccess will be called without parameters for this method.
1462    	 * @param {sap.Logon~errorCallback} onerror The function that is invoked in case of an error.
1463    	 * @example
1464    	 * var errorCallback = function(errorInfo){
1465    	 *     alert("Error: " + JSON.stringify(errorInfo));
1466    	 * }
1467    	 * var successCallback = function(context){
1468    	 *     alert("The showRegistrationData screenflow was successful.");
1469    	 * }
1470    	 * sap.Logon.showRegistrationData(successCallback,errorCallback);
1471    	 */
1472                showRegistrationData: showRegistrationData,
1473                
1474            };
1475    
1476    /**
1477     * Callback function that is invoked in case of an error.
1478     *
1479     * @callback sap.Logon~errorCallback
1480     *
1481     * @param {Object} errorObject An object containing properties: 'errorCode', 'errorMessage', and 'errorDomain'.
1482     * The 'errorCode' is just a number uniquely identifying the error.  The 'errorMessage'
1483     * property is a string with more detailed information of what went wrong.  The 'errorDomain' property specifies
1484     * the domain that the error occurred in.
1485     */
1486    
1487    /**
1488     * Callback function that is invoked upon successfully registering or unlocking or retrieving the context.
1489     *
1490     * @callback sap.Logon~successCallback
1491     *
1492     * @param {Object} context An object containing the current logon context.  Two properties of particular importance
1493     * are applicationEndpointURL, and applicationConnectionId.
1494     * The context object contains the following properties:<br/>
1495     * "registrationContext": {<br/>
1496     * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"serverHost": Host of the server.<br/>
1497     * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"domain": Domain for server. Can be used in case of SAP Mobile Platform communication.<br/>
1498     * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"resourcePath": Resource path on the server. The path is used mainly for path based reverse proxy but can contain a custom relay server path as well.<br/>
1499     * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"https": Marks whether the server should be accessed in a secure way.<br/>
1500     * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"serverPort": Port of the server.<br/>
1501     * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"user": Username in the backend.<br/>
1502     * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"password": Password for the backend user.<br/>
1503     * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"farmId": FarmId of the server. Can be nil. Used in case of Relay server or SiteMinder.<br/>
1504     * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"communicatorId": Id of the communicator manager that will be used for performing the logon. Possible values: IMO / GATEWAY / REST<br/>
1505     * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"securityConfig": Security configuration. If nil, the default configuration is used.<br/>
1506     * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"mobileUser": Mobile User. Used in case of IMO manual user creation.<br/>
1507     * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"activationCode": Activation Code. Used in case of IMO manual user creation.<br/>
1508     * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"gatewayClient": The key string that identifies the client on the gateway. Used in Gateway only registration mode. The value will be used as adding the parameter: sap-client=<gateway client><br/>
1509     * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"gatewayPingPath": The custom path of the ping URL on the gateway. Used in case of Gateway only registration mode.<br/>
1510     * }<br/>
1511     * "applicationEndpointURL": Contains the application endpoint URL after a successful registration.<br/>
1512     * "applicationConnectionId": ID to get after a successful SUP REST registration. Needs to be set in the download request header with key X-SUP-APPCID<br/>
1513     * "afariaRegistration": manual / automatic / certificate<br/>
1514     * "policyContext": Contains the password policy for the secure store {<br/>
1515     * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"alwaysOn":<br/>
1516     * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"alwaysOff":<br/>
1517     * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"defaultOn":<br/>
1518     * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"hasDigits":<br/>
1519     * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"hasLowerCaseLetters":<br/>
1520     * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"hasSpecialLetters":<br/>
1521     * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"hasUpperCaseLetters":<br/>
1522     * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"defaultAllowed":<br/>
1523     * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"expirationDays":<br/>
1524     * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"lockTimeout":<br/>
1525     * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"minLength":<br/>
1526     * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"minUniqueChars":<br/>
1527     * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"retryLimit":<br/>
1528     * }<br/>
1529     * "registrationReadOnly": specifies whether context values are coming from clientHub / afaria<br/>
1530     * "policyReadOnly": specifies whether passcode policy is coming from afaria<br/>
1531     * "credentialsByClientHub": specifies whether credentials are coming from clientHub
1532     */
1533     
1534     /**
1535      * Callback function that will be invoked with no parameters.
1536      * 
1537      * @callback sap.Logon~successCallbackNoParameters
1538      */
1539     
1540     /**
1541      * Callback function that is invoked upon successfully retrieving an object from the DataVault.
1542      * 
1543      * @callback sap.Logon~getSuccessCallback
1544      *
1545      * @param {Object} value The object that was stored with the given key.  Can be null or undefined if no object was stored
1546      * with the given key.
1547      */
1548    
1549