Login Page

The Login Page series and page are created automatically as part of all new app designs. Every business app created using Evoke needs a login Page Series so that users can log into the deployed app.
You can change the login page (or Page Series) to be whatever look and feel you would like. This help section will describe the default login page and how to change the various components of this.




Definitions of the Login Page
The App Startup section allows the App designer to define the following, each of these settings is provided as a fully operational default in a new app:
  • The name of the login Page Series

  • The name of the button widget being used for the login

  • The name of the selection being used to authenticate a login attempt

  • If a Page Series is to be shown after login or if only the menu is to be shown

  • The name of the Page Series to be shown after login (can be redefined is user access control)

  • Any data/records that are related to the user loging in that you may want to load at the time of login

Full explanations of the valid options for changing these definitions and the authentication are available in the App Startup section.



Redesigning the Login Page
The default login page includes a number of segments and templates that you can reorganise, modify or add to. Explanations of changing, adding or deleting segments, templates, buttons, etc are available in the Pages section of this user guide.
In addition to blank segments, that are just spacer segments, there is a segment for adding your app logo. Instructions for re-using this segment (or defining a separate segment) to hold a company or app logo are in the Static Images section.
The segment holding the login ID and Password Entry fields and the "remember" checkboxes is actually multiple segments and templates. You do not need to include "remember" checkboxes but if you do then Evoke will create a cookie on the users computer that remembers and pre-fills the Login ID and Password fields when the app is loaded/run again. The remember functions and other data fields (properties) used on this login page are defined in the Reserved Entity AppUser.
Finally, there is a segment holding "login" button. In the template for this segment, the WidgetID is set to "LoginButton" as is defined in the App Startup setting described above. This is a special button and does not need definition of which selection to run or what authentication to perform as these are defined in the App Startup settings.
You can move the segments around, choose to include things like the remember checkboxes, include a page background at app level or page level, etc just as you would building any app page, however, the login button and the login id/password entry boxes muct remain on this page.

Changing the user authentication used on the Login Page
It is expected that your App will use a number of Selections, however, the SelectByName Selection is included as a default selection and as it is used by the App Login process to initially authenticate the user logging into the app. This default selection can be changed or a new authentication added and used.
Changing the standard SelectByName Database Selection
First, this does not have to be called SelectByName, this is the default name and can be changed in the App Startup section of Evoke for each App. In its simplest form, this selection will access an AppUser File/Table in the backend database and run a simple selection e.g. SELECT WITH LOGINNAME = "[{LoginName}]", where LoginName is the filter argument defined in the Entity Selection definition and passed in from the LoginName datafield entered on the default login page. If the entered LoginName matches the LoginName field in a record in the AppUser file and a record is returned to the app then the password entered is matched against the password in the AppUser record and if matched then the user is authenticated and is logged into the app. As described in the Selections section you can change the function of this selection, for example adding another parameter (field entered on the login screen) to validate

Using Windows Active Directory to login
You can use the Windows Active Directory as an alternative login authentication option. To switch to Windows AD, you will need to access one of the custom code files that Evoke has added to your App Visual Studio Solution. In the "Repository Access" project, under Repositories you will find the file AppUser.cs.
A small piece of code needs to be added in the SelectCustom function. There is a sample below - note the id of the selection that validates the login details has been defined as being "SelectByName"
public async Task <ViewEntities.AppUser[]> SelectCustom(CustomInvokePosition InvokePosition, SqlCommand DatabaseCommand, Dictionary<string, string[]> ContextData, DataSelectionControl DataSelectionControl, DataRetrievalControl DataRetrievalControl, List<ViewEntities.AppUser> ViewAppUsers, List<RepositoryItem> RepositoryDataItems = null, RelatedDataContext RelatedDataContext = null)
{
   if (RelatedDataContext == null)
   {
      switch (InvokePosition)
      {
         case CustomInvokePosition.Start:
            break;
         case CustomInvokePosition.Middle:
            break;
         case CustomInvokePosition.Finish:
**** Add the following code ****
            if (DataSelectionControl.SelectionID == "SelectByName")
            {
               if (ViewAppUsers.Count > 0)
               {
                  string userName = ContextData["UserName"][0];
                  string password = ContextData["Password"][0];
                  if (UserAuthenticatedAgainstAD(userName, password))
                     ViewAppUsers[0].Password = password;
                  else
                     ViewAppUsers.Clear();
                  }
               }
               break;
            default:
               if (String.Empty == Boolean.FalseString) await Task.Delay(0); // suppress intellisense "no await" warning
**** end of additional code ****
               break;
            }
               return null;
         }
else
{
   switch (RelatedDataContext.EntityName)
   {
      case "":
         switch (RelatedDataContext.PropertyName)
         {
            case "":
               switch (InvokePosition)
               {
                   case CustomInvokePosition.Start:
                     // set RelatedDataContext.SupportingData to any required supporting data for the actual related data retrieval process
                     break;
                  case CustomInvokePosition.Finish:
                     // return the related data
                     break;
               }
               break;
            }
         break;
      }
      return null;
   }
}
You'll need to create the function "UserAuthenticatedAgainstAD" to access AD and return true or false depending on whether the supplied login credentials are valid. Note how the ViewAppUsers list is cleared if the AD validation fails - this triggers the standard "user details not recognized" error within the app login page.
There's lots of sample code on the Web that illustrates how to authenticate against AD using C#. An example can be found at:

https://www.codemag.com/Article/1312041/Using-Active-Directory-in-.NET

private bool AuthenticateUser(string domainName, string userName, string password)
{
   bool ret = false;
    try
    {
      DirectoryEntry de = new DirectoryEntry("LDAP://" + domainName, userName, password);
      DirectorySearcher dsearch = new DirectorySearcher(de);
      SearchResult results = null;
      results = dsearch.FindOne();
      ret = true;
   }
   catch
   {
      ret = false;
   }
    return ret;
}


Adding custom user authentication
Some developers building apps will want to have custom user authentication, this is accomodated within Evoke but, by its very nature, will require some custom code to be added.
This user guide will be updated to incorporate descriptions for this, in the meantime please contact evoke support.



Password Reminder on the Login Page
The Evoke Example app provides an example of using the "remind password" option for users.
It suggests having a user enter their login name and then requesting a password reminder that is sent to their registered email address.
In the example the request for a password reminder is performed on a button click and this button is intercepted in the custom code file for the login page (found at Web\scripts\pages\Pages.Login.js). You will need to have incorporated an emailer system/email client into your app, in the example we use mailjet.
Add a small piece of custom code in the widgetEvents of this page, similar to...
   // click of resend password button - create new appuser record (for security) - calls AppUser.view.cs to prep and send email
   ResendForgottonPasswordbyEmail: function (eventInfo, widget, pageSeries) {
      switch (eventInfo.Id) {
         case "click":
            var appUser = App.Entity.AppUser.createSync();
            appUser.LoginName = pageSeries.viewModel.ResendPassword.LoginName;
            if (!App.utility.varHasContent(appUser.LoginName)) {
               App.PageSystem.showError("Please enter a login name to use for the password resend action");
               return;
            }
            appUser.CurrentAuthToken = "ResendPassword|ByLoginName|" + appUser.NewUserEmailFrom;
            appUser.update()
               .done(function (data) {
                  if (data.CurrentAuthToken) {
                     App.PageSystem.showError("Problem encountered during password resend action: " + data.CurrentAuthToken);
                  } else {
                     App.PageSystem.showMsg("Your existing password has been sent to the email associated with the supplied login name");
                  }
               })
               .fail(function (err) {
                  App.PageSystem.showError("Problem encountered during password resend: " + err);
               });
            break;
      }
   },