text: var debugvar = "";
  
  var AuthenticablePrincipal = {
  
      SelectedUser: {
          name : "",
          enabled : false,
          localLogonEnabled: false,
          id: "",
          alternativeNames: []
      },
  
      ResetUserModalValues: function ()
      {
          $('#authPrincipalUpn').val('');
          $('#authPrincipalEnabled').val('');
          $('#localLogonEnabled').val('');
          AuthenticablePrincipal.AlternativeUpnActionModalSelect2.val(null).trigger("change");
      },
  
      GetUpdatedUserData: function ()
      {
          return {
              id: AuthenticablePrincipal.TargetUserId.val(),
              name: $('#principalName.modal-input').val(),
              enabled: $("#userEnabled.modal-input").is(":checked"),
              localLogonEnabled: $("#userLocalLogonEnabled.modal-input").is(":checked"),
              alternativeNames: UiGlobal.GetSelectedOptions(AuthenticablePrincipal.AlternativeUpnActionModalSelect2)
          }
      },
  
      ShowAddUserModal: function ()
      {
          AuthenticablePrincipal.ResetUserModalValues();
          AuthenticablePrincipal.TargetUserId.val("");
          AuthenticablePrincipal.InitializeAlternativeUpnActionModalSelect2();
          AuthenticablePrincipal.SetCommitOnClick("Add");
          AuthenticablePrincipal.UserModal.modal("show");
      },
  
      ShowEditUserModal: function (data)
      {
          AuthenticablePrincipal.ResetUserModalValues();
          AuthenticablePrincipal.LoadEditAuthPrincipalModalData(data);
          AuthenticablePrincipal.SetCommitOnClick("Edit");
          AuthenticablePrincipal.UserModal.modal("show");
      },
  
      SetCommitOnClick(eventType)
      {
          switch (eventType) {
              case "Add":
                  AuthenticablePrincipal.CommitUserButton.attr("onclick", "AuthenticablePrincipal.AddAuthPrincipal();");
                  break;
              case "Edit":
                  AuthenticablePrincipal.CommitUserButton.attr("onclick", "AuthenticablePrincipal.EditAuthPrincipal();");
                  break;
              default:
                  AuthenticablePrincipal.CommitUserButton.attr("onclick", "AuthenticablePrincipal.AddAuthPrincipal();");
          }
      },
  
      LoadEditAuthPrincipalModalData: function (data)
      {
          AuthenticablePrincipal.TargetUserId.val(data.id);
          $('#principalName').val(data.name);
          $('#userEnabled.modal-input').attr("checked", data.enabled);
          $('#userLocalLogonEnabled.modal-input').attr("checked", data.localLogonEnabled);
          AuthenticablePrincipal.InitializeAlternativeUpnActionModalSelect2(data);
      },
  
      EditAuthPrincipal: function ()
      {
          var data = AuthenticablePrincipal.GetUpdatedUserData();
          //$.extend(client, {
          //    name: $("#authPrincipalUpn").val(),
          //    enabled: $("#authPrincipalEnabled").is(":checked"),
          //    localLogonEnabled: $("#localLogonEnabled").is(":checked"),
          //    alternativeNames: UiGlobal.GetSelectedOptions(AuthenticablePrincipal.AlternativeUpnActionModalSelect2)        
          //});
  
          //debugvar = client;
  
          AuthenticablePrincipal.Grid.jsGrid("updateItem", data);
  
          //$("#authenticablePrincipalActionModal").modal("hide");
      },
  
      AddAuthPrincipal: function () {
  
          var data = AuthenticablePrincipal.GetUpdatedUserData();
  
          //$.extend(client, {
          //    name: $("#authPrincipalUpn").val(),
          //    enabled: $("#authPrincipalEnabled").is(":checked"),
          //    localLogonEnabled: $("#localLogonEnabled").is(":checked"),
          //    alternativeNames: UiGlobal.GetSelectedOptions(AuthenticablePrincipal.AlternativeUpnActionModalSelect2)    
          //});
  
          AuthenticablePrincipal.Grid.jsGrid("insertItem", data);
  
          //$("#authenticablePrincipalActionModal").modal("hide");
      },
  
      InitializeGrid: function ()
      {
          AuthenticablePrincipal.Grid = $("#authenticablePrincipalTable");
  
          AuthenticablePrincipal.Grid.jsGrid({
              height: "auto",
              width: "100%",
  
              rowClick: function (args) {
                  AuthenticablePrincipal.ShowEditUserModal(args.item);
                  //AuthenticablePrincipal.ShowAuthenticablePrincipalActionModal("Edit", args.item);
              },
  
              editing: false,
              sorting: true,
              paging: true,
              autoload: true,
  
              pageSize: 15,
              pageButtonCount: 5,
  
              deleteConfirm: "Do you really want to delete this external identity source?",
  
              controller: AuthenticablePrincipal.Controller,
  
              //rowClick: function (args) {
              //    AuthenticablePrincipal.ShowAuthenticablePrincipalActionModal("Edit", args.item);
              //},
  
              fields: [
                  { name: "name", type: "text", title: "Name" },
                  {
                      name: "alternativeNames",
                      title: "Alternative UPN",
                      itemTemplate: function (value, item) {
  
                          var altUpnSelect = $("<select style='width:100%' class='alternativeupn-select2' multiple='multiple'>");
  
  
                          if (item.alternativeNames != null)
                          {
                              item.alternativeNames.forEach(function (option) {
                                  altUpnSelect.append($('<option>', {
                                      value: option,
                                      text: option
                                  }).attr('selected', true));
                              });
                          }
                          
  
                          altUpnSelect = altUpnSelect.attr('disabled', true);
                          return altUpnSelect;
  
                      }
                  },
                  { name: "localLogonEnabled", type: "checkbox", title: "LocalLogonEnabled", width: 40 },
                  { name: "enabled", type: "checkbox", title: "Enabled", sorting: false, width: 25 },
                  {
                      title: "Action",
                      width: 15,
                      itemTemplate: function (value, item) {
                          var btn = $("<i>");
                          btn.addClass("fa fa-key");
                          btn.attr('cm-id', item.id);
                          btn.attr('cm-upn', item.name);
                          
                          return btn.on("click", function (event) {
                              var id = event.target.attributes["cm-id"].value
                              var upn = event.target.attributes["cm-upn"].value
                              AuthenticablePrincipal.ResetPasswordButtonClick(id, upn);
                              return false;
                          });
                      }
  
                  },
                  {
                      width: 25,
                      type: "control",
                      editButton: false,
                      headerTemplate: function () {
                          return $("<button>").attr("type", "button").text("Add")
                              .on("click", function () {
                                  AuthenticablePrincipal.ShowAddUserModal();
                              });
                      }
                  }
              ],
              onRefreshed: function (args) { AuthenticablePrincipal.InitializeAlternativeUpnSelect2(); },
              onItemUpdated: function (args) { AuthenticablePrincipal.Grid.jsGrid("render"); AuthenticablePrincipal.InitializeAlternativeUpnSelect2(); },
              onItemEditing: function (args) { AuthenticablePrincipal.InitializeAlternativeUpnSelect2(); },
              onItemInserting: function (args) { UiGlobal.ResetAlertState(); },
              onItemUpdating: function (args) { UiGlobal.ResetAlertState(); AuthenticablePrincipal.InitializeAlternativeUpnSelect2(); },
              onItemDeleting: function (args) { UiGlobal.ResetAlertState(); },
              onDataLoading: function (args) { AuthenticablePrincipal.InitializeAlternativeUpnSelect2(); },
              onDataLoaded: function (args) { AuthenticablePrincipal.InitializeAlternativeUpnSelect2(); }
              
          });
  
          AuthenticablePrincipal.InitializeAlternativeUpnSelect2();
      },
  
      Controller: {
          loadData: function (filter) {
              var d = $.Deferred();
              $.ajax({
                  type: "GET",
                  url: "/security/authenticable-principals",
                  dataType: "json"
              }).done(function (response) {
                  d.resolve(response.payload);
              });
              return d.promise();
          },
          insertItem: function (item) {
              $.ajax({
                  type: "POST",
                  url: "/security/authenticable-principal",
                  data: item
              }).fail(function (xhr, ajaxOptions, thrownError) {
                  AuthenticablePrincipal.HandleError(xhr.responseJSON.message, AuthenticablePrincipal.Grid);
              });
          },
  
          updateItem: function (item) {
  
              var d = $.Deferred();
              $.ajax({
                  type: "PUT",
                  url: "/security/authenticable-principal",
                  dataType: "json",
                  data: item
              }).fail(function (xhr, ajaxOptions, thrownError) {
                  AuthenticablePrincipal.HandleError(xhr.responseJSON.message, AuthenticablePrincipal.Grid);
              }).done(function (response) {
                  d.resolve(response.payload);
              });
              return d.promise();
  
          },
  
          deleteItem: function (item) {
              $.ajax({
                  type: "DELETE",
                  url: "/security/authenticable-principal",
                  data: item
              }).fail(function (xhr, ajaxOptions, thrownError) {
                  AuthenticablePrincipal.HandleError(xhr.responseJSON.message, AuthenticablePrincipal.Grid);
              });
          },
  
          onItemInserting: function (args) { AuthenticablePrincipal.ResetErrorState(); },
          onItemUpdating: function (args) { AuthenticablePrincipal.ResetErrorState(); },
          onItemDeleting: function (args) { AuthenticablePrincipal.ResetErrorState(); }
      },
  
      ResetErrorState: function () {
          UiGlobal.HideError();
      },
  
      HandleError: function (msg, grid) {
          grid.jsGrid("render");
          UiGlobal.ShowError(msg);
      },
  
      InitializeSelect: function () {
          CmOptions.ActiveDirectoryMetadataType.forEach(function (item) {
              $('#eisType').append($('<option>', {
                  value: item.Name,
                  text: item.Name
              }));
          });
      },
  
      ImportUserSelections: [],
  
      InitializeUserSearchSelect: function () {
  
          $('.idp-select').select2({ data: CmOptions.ActiveDirectoryMetadatas });
  
          AuthenticablePrincipal.ImportUserSelect = $(".user-search-select");
  
          AuthenticablePrincipal.ImportUserSelect.select2({
              dropdownAutoWidth: true,
              placeholder: 'search for an ad object',
              ajax: {
  
                  url: ("/identity-source/external/query/users"),
                  dataType: 'json',
                  type: 'get',
                  delay: 30,
                  data: function (params) {
                      return {
                          query: params.term, // search term
                          page: params.page
                      };
                  },
                  processResults: function (data, params) {
                      // parse the results into the format expected by Select2
                      // since we are using custom formatting functions we do not need to
                      // alter the remote JSON data, except to indicate that infinite
                      // scrolling can be used
                      params.page = params.page || 1;
  
                      return {
                          results: data.payload,
                          //pagination: {
                          //    more: (params.page * 30) < data.total_count
                          //}
                      };
                  },
                  cache: true
              },
              escapeMarkup: function (markup) { return markup; }, // let our custom formatter work
              minimumInputLength: 2,
              templateResult: AuthenticablePrincipal.formatRepo, // omitted for brevity, see the source of this page
              templateSelection: AuthenticablePrincipal.formatRepoSelection // omitted for brevity, see the source of this page
          });
  
          AuthenticablePrincipal.ImportUserSelect.on("select2:selecting", function (e) {
              AuthenticablePrincipal.ImportUserSelections.push(e.params.args.data);
          });
      },
  
      formatRepo: function (repo) {
  
          var markup = '<div class="user-select-container">'
          markup = markup + '<div class="user-select-title">' + repo.samAccountName + ' ; ' + repo.name + ' ; ' + repo.displayName + '</div>';
          markup = markup + '<div class="user-select-details">UserPrincipalName: <span class="user-select-details-value">' + repo.name + '</span></div>';
          markup = markup + '<div class="user-select-details">Domain: <span class="user-select-details-value">' + repo.domain + '</span></div>';
          markup = markup + '</div>';
          //var markup = repo.text;
          return markup;
      },
  
      formatRepoSelection: function (repo) {
          return repo.samAccountName;
          //return repo.name || repo.text;
          //return repo.text;
      },
  
      FormatExistingUserMergeRepository: function (repo)
      {
          return repo.name;
      },
  
      FormatExistingUserMergeSelection: function (repo)
      {
          return repo.name;
      },
  
      ImportSelectedUsers: function ()
      {
          UiGlobal.ResetAlertState();
  
          
          if (AuthenticablePrincipal.MergeOnImport)
          {
              var data = {
                  users: AuthenticablePrincipal.ImportUserSelections,
                  mergeWith: AuthenticablePrincipal.ExistingUserMergeSelect2().val(),
                  merge: AuthenticablePrincipal.MergeOnImport
              };
          }
          else
          {
              var data = {
                  users: AuthenticablePrincipal.ImportUserSelections,
                  merge: AuthenticablePrincipal.MergeOnImport
              };
          }
          
  
  
          Services.ImportUsersFromActiveDirectoryMetadata(data, AuthenticablePrincipal.ImportSelectedUsersSuccessCallback, AuthenticablePrincipal.ImportSelectedUsersErrorCallback);
  
  
      },
  
      ImportSelectedUsersSuccessCallback: function ()
      {
          AuthenticablePrincipal.ImportUserSelections = [];
          AuthenticablePrincipal.ResetUserSelect();
          UiGlobal.RefreshGrid(AuthenticablePrincipal.Grid);
          UiGlobal.ShowSuccess("Successfully imported the selected users");
  
      },
  
      ImportSelectedUsersErrorCallback: function (e) {
          AuthenticablePrincipal.ImportUserSelections = [];
          AuthenticablePrincipal.ResetUserSelect();
          UiGlobal.ShowError("Error while importing users: " + e.responseJSON.message);
      },
  
      ResetUserSelect: function ()
      {
          AuthenticablePrincipal.ImportUserSelect.select2('val', 'All');
      },
  
      AlternativeUpnSelect2: function () {
          return $('.alternativeupn-select2');
      },
  
      InitializeAlternativeUpnActionModalSelect2: function (client)
      {
          AuthenticablePrincipal.ResetUserModalValues();
  
          if (client != null)
          {
              if (client.alternativeNames != null) {
                  client.alternativeNames.forEach(function (option) {
  
                      if (!AuthenticablePrincipal.AlternativeUpnActionModalSelect2.val().includes(option)) {
                          AuthenticablePrincipal.AlternativeUpnActionModalSelect2.append($('<option>', {
                              value: option,
                              text: option
                          }).attr('selected', true));
                      }
  
                  });
              }
          }
          
          AuthenticablePrincipal.AlternativeUpnActionModalSelect2.select2({ width: '100%', tags: true });
      },
  
      InitializeAlternativeUpnSelect2: function ()
      {
          AuthenticablePrincipal.AlternativeUpnSelect2().select2({ width: '100%' });
      },
  
      RegisterModalCloseEvent: function ()
      {
          $('#authenticablePrincipalActionModal').on('hidden.bs.modal', function () {
              AuthenticablePrincipal.ResetUserModalValues();
          });
      },
  
      RegisterImportUserModalCloseEvent: function ()
      {
          $('#importUsersModal').on('hidden.bs.modal', function () {
              $('#authPrincipalUpn').val('');
              $('#authPrincipalEnabled').val('');
              $('#localLogonEnabled').val('');
              AuthenticablePrincipal.AlternativeUpnActionModalSelect2ClearOptions();
          });
      },
  
      PageLoad: function ()
      {
          AuthenticablePrincipal.InitializeGrid();
          AuthenticablePrincipal.InitializeUserSearchSelect();
          //AuthenticablePrincipal.RegisterModalCloseEvent();
          AuthenticablePrincipal.RegisterMergeCheckboxEvent();
          AuthenticablePrincipal.InitializeExistingUserMergeSelect2();
          AuthenticablePrincipal.CommitUserButton = $('#commitAuthenticablePrincipalButton');
          AuthenticablePrincipal.UserModal = $("#authenticablePrincipalActionModal");
          AuthenticablePrincipal.TargetUserId = $('#targetUserId');
          AuthenticablePrincipal.AlternativeUpnActionModalSelect2 = $('#alternativeUpn');
      },
  
      MergeOnImport: false,
  
      ShowMergeExistingUserSelect: function ()
      {
          $('.existingUserSelect').show();
      },
  
      HideMergeExistingUserSelect: function ()
      {
          $('.existingUserSelect').hide();
      },
  
      RegisterMergeCheckboxEvent: function () {
          $('#mergeCheckbox').change(function () {
              if ($(this).is(":checked")) {
                  AuthenticablePrincipal.MergeOnImport = true;
                  AuthenticablePrincipal.ShowMergeExistingUserSelect();
              }
              else
              {
                  AuthenticablePrincipal.MergeOnImport = false;
                  AuthenticablePrincipal.HideMergeExistingUserSelect();
              }
          });
      },
  
      ExistingUserMergeSelect2: function ()
      {
          return $('#existingUserSelect');
      },
  
      InitializeExistingUserMergeSelect2: function ()
      {
          AuthenticablePrincipal.ExistingUserMergeSelect2().select2({
              dropdownAutoWidth: true,
              width: '100%',
              placeholder: 'Search for a Certificate Manager user',
              ajax: {
                  url: ("/security/authenticable-principals"),
                  dataType: 'json',
                  type: 'get',
                  delay: 30,
                  //data: function (params) {
                  //    return {
                  //        query: params.term, // search term
                  //        page: params.page
                  //    };
                  //},
                  processResults: function (data, params) {
                      params.page = params.page || 1;
  
                      return {
                          results: data.payload,
                      };
                  },
                  cache: true
              },
              escapeMarkup: function (markup) { return markup; },
              //minimumInputLength: 2,
              templateResult: AuthenticablePrincipal.FormatExistingUserMergeRepository,
              templateSelection: AuthenticablePrincipal.FormatExistingUserMergeSelection
  
          });
      },
  
      ResetPasswordButtonClick: function (id, upn)
      {
          //console.log('reset password button click');
          //console.log(id);
          //console.log(upn);
  
  
          $('#reset-pwd-id').val(id)
          $('#reset-pwd-upn').val(upn);
  
          $("#resetUserPasswordModal").modal("show");
  
          
          return false;
      },
  
      ResetUserPassword: function ()
      {
          var id = $('#reset-pwd-id').val();
          var newPassword = $('#reset-pwd-password').val();
  
          var data = {
              id: id,
              newPassword: newPassword
          };
  
          $('#reset-pwd-password').val('');
  
          Services.ResetUserPassword(data, UiGlobal.ShowSuccess, UiGlobal.ShowError);
      },
  
      CommitUserButton: null,
  
      UserModal: null,
  
      Grid: null,
  
      ImportUserSelect: null,
  
      TargetUserId: null,
  
      AlternativeUpnActionModalSelect2: null
  
  }
  var CmOptions = {
      hashAlgorithmOptions: [
          { Name: "SHA1", Id: 0, Display: "SHA1 (Insecure)" },
          { Name: "SHA256", Id: 1, Display: "SHA256 (Recommended)", Primary: true },
          { Name: "SHA512", Id: 2, Display: "SHA512 (Most Secure)" }
      ],
      cipherOptions: [
          { Name: "RSA", Id: 0, Display: "RSA (TLS / More Support)", Primary: true },
          { Name: "ECDH", Id: 1, Display: "ECDH (TLS / Most Secure)" },
          { Name: "ECDSA", Id: 2, Display: "ECDSA (Uncommon)" }
      ],
  
      keyUsageOptions: [
          { Name: "None", Id: 0, Primitive: true, Display: "None" },
          { Name: "ServerAuthentication", Id: 1, Primitive: true, Display: "ServerAuthentication", Primary: true },
          { Name: "ClientAuthentication", Id: 2, Primitive: true, Display: "ClientAuthentication" },
          { Name: "ServerAuthentication, ClientAuthentication", Id: 3, Primitive: false, Display: "ServerAuthentication, ClientAuthentication" },
          { Name: "DocumentEncryption", Id: 4, Primitive: true, Display: "DocumentEncryption" },
          { Name: "CodeSigning", Id: 8, Primitive: true, Display: "CodeSigning" },
          { Name: "CertificateAuthority", Id: 16, Primitive: true, Display: "CertificateAuthority" },
          { Name: "Undetermined", Id: 32, Primitive: true, Display: "Undetermined" }
  
      ],
      windowsApiOptions: [
          { Name: "Cng", Id: 1, Display: "CryptoApi Next Generation (Most Secure)", Primary: true },
          { Name: "CryptoApi", Id: 0, Display: "CryptoApi (More Support)" }
      ],
      //windowsApiOptions: ["Cng", "CryptoApi"],
      authenticationTypeOptions: [
          { Name: "UsernamePassword", Id: 0, Display: "basic", Primary: true },
          { Name: "WindowsKerberos", Id: 1, Display: "kerberos" }
      ],
      ActiveDirectoryMetadataType: [
          { Name: "ActiveDirectoryIwa", Id: 0, Display: "ActiveDirectoryIwa" },
          { Name: "ActiveDirectoryBasic", Id: 1, Display: "ActiveDirectoryBasic" },
      ],
  
      LocalIdentityProviderId: "02abeb4c-e0b6-4231-b836-268aa40c3f1c"
  }
  var Nodes = {
  
      PageLoad: function () {
          Nodes.Grid = $('#nodeTable');
          Nodes.Modal = $('#addNodeModal');
          Nodes.CommitButton = $('#addButton');
          Nodes.CredentialSelect = $('#credential');
          Nodes.InitializeGrid();
          Nodes.InitializeIdpSelect();
      },
  
      InitializeIdpSelect: function () {
          Services.GetActiveDirectoryIdentityProviders(Nodes.InitializeIdpSelectSuccessCallback, null);
      },
  
      InitializeIdpSelectSuccessCallback: function (data) {
  
          var primarySet = false;
  
          var appendData = {};
  
          data.forEach(function (item) {
  
            
              if (primarySet) {
                  appendData = {
                      value: item.id,
                      text: item.name
                  };
              }
              else {
                  appendData = {
                      value: item.id,
                      text: item.name,
                      selected: "selected"
                  };
                  primarySet = true;
              }
  
              Nodes.CredentialSelect.append($('<option>', appendData));        
          });
      },
  
      CredentialSelect: null,
  
      Grid: null,
  
      Modal: null,
  
      ShowAddModal: function () {
          Nodes.ResetModalState();
          Nodes.Modal.modal("show");
          Nodes.SetCommitOnClick("Add");
      },
  
      CommitButton: null,
  
      ResetModalState: function () {
          $('#hostname').val('');
          $('#credential').val('');
      },
  
      Add: function () {
          Nodes.Grid.jsGrid("insertItem", Nodes.GetData());
      },
  
      Edit: function () {
  
      },
  
  
      GetData: function () {
          return {
              hostName: $('#hostname').val(),
              credentialId: $('#credential').val()
          };
      },
  
  
      SetCommitOnClick: function(eventType) {
          switch (eventType) {
              case "Add":
                  Nodes.CommitButton.attr("onclick", "Nodes.Add();");
                  break;
              case "Edit":
                  Nodes.CommitButton.attr("onclick", "Nodes.Edit();");
                  break;
              default:
                  Nodes.CommitButton.attr("onclick", "Nodes.Add();");
          }
      },
  
      ViewNode: function (item) {
          document.location = "/view/node/" + item.id;
      },
  
      InitializeGrid: function ()
      {
          Nodes.Grid.jsGrid({
              height: "auto",
              width: "100%",
  
              
              editing: false,
              sorting: true,
              paging: true,
              autoload: true,
  
              pageSize: 15,
              pageButtonCount: 5,
  
              rowClick: function (args) {
                  Nodes.ViewNode(args.item);
              },
  
              deleteConfirm: "Do you really want to delete this node?",
  
              controller: Nodes.Controller,
  
              fields: [
  
                  { name: "hostname", type: "text", title: "Hostname" },
  
                  { name: "credential", type: "text", title: "Credential" },
  
                  { name: "lastCommunication", type: "text", title: "LastCommunication" },
                  
                  { name: "communicationSuccess", type: "text", title: "CommunicationSuccess" },
  
                  {
                      name: "details",
                      title: "Action", 
                      width: 50,
                      itemTemplate: function (value, item) {
                          var $link = $("<a>").attr("href", '/view/node/' + item.id).text("View");
                          return $("<div>").append($link);
                      }
                  },
                  {
                      type: "control",
                      
                      headerTemplate: function () {
                          return $("<button>").attr("type", "button").text("Add")
                              .on("click", function () {
                                  Nodes.ShowAddModal();
                              });
                      }
                  }
              ],
  
              onItemInserting: function (args) { Nodes.ResetErrorState(); },
              onItemUpdating: function (args) { Nodes.ResetErrorState(); },
              onItemDeleting: function (args) { Nodes.ResetErrorState(); }
  
          });
      },
  
      Controller: {
          loadData: function (filter) {
              var d = $.Deferred();
              $.ajax({
                  type: "GET",
                  url: "/nodes",
                  dataType: "json"
              }).done(function (response) {
                  d.resolve(response.payload);
              });
              return d.promise();
          },
          insertItem: function (item) {
              var d = $.Deferred();
              $.ajax({
                  type: "POST",
                  url: "/node",
                  data: item
              }).done(function (response) {
                  d.resolve(response.payload);
              }).fail(function (xhr, ajaxOptions, thrownError) {
                  Nodes.HandleError(xhr.responseJSON.message, Nodes.Table);
              });
              return d.promise();
          },
  
          updateItem: function (item) {
  
              $.ajax({
                  type: "PUT",
                  url: "/node",
                  data: item
              }).fail(function (xhr, ajaxOptions, thrownError) {
                  Nodes.HandleError(xhr.responseJSON.message, Nodes.Table);
              });
          },
  
          deleteItem: function (item) {
              $.ajax({
                  type: "DELETE",
                  url: "/node",
                  data: item
              }).fail(function (xhr, ajaxOptions, thrownError) {
                  Nodes.HandleError(xhr.responseJSON.message, Nodes.Table);
              });
          }
      },
  
      ResetErrorState: function () {
          UiGlobal.HideError();
      },
  
      HandleError: function (textStatus, grid) {
          grid.jsGrid("render");
          UiGlobal.ShowError(textStatus.responseJSON.message);
      },
  
      InitializeSelect: function () {
          CmOptions.ActiveDirectoryMetadataType.forEach(function (item) {
              $('#eisType').append($('<option>', {
                  value: item.Name,
                  text: item.Name
              }));
          });
      }
  
  
  }
  function openTab(evt, tabName) {
      // Declare all variables
      var i, tabcontent, tablinks;
  
      location.hash = tabName;
      // Get all elements with class="tabcontent" and hide them
      tabcontent = document.getElementsByClassName("tabcontent");
      for (i = 0; i < tabcontent.length; i++) {
          tabcontent[i].style.display = "none";
      }
  
      // Get all elements with class="tablinks" and remove the class "active"
      tablinks = document.getElementsByClassName("tablinks");
      for (i = 0; i < tablinks.length; i++) {
          tablinks[i].className = tablinks[i].className.replace(" active", "");
      }
  
      // Show the current tab, and add an "active" class to the button that opened the tab
      document.getElementById(tabName).style.display = "block";
      $('.' + tabName).addClass("active");
  };
  
  
  var UIDefaults = {
      GetEnumMap: function () {
          if (localStorage.getItem("uiEnumMap") === null) {
              Services.GetEnumMapping();
  
              while (localStorage.getItem("uiEnumMap") === null)
              {
  
              }
              return JSON.parse(localStorage.getItem("uiEnumMap"));
          }
          else {
              return JSON.parse(localStorage.getItem("uiEnumMap"));
          }
      }
  };
  
  
  var UiGlobal = {
  
      GetRowClass: function (item, itemIndex) {
  
          if (item.eventCategory == "CertificateIssuance" && item.eventResult == "Success" ) {
              return 'event-primary';
          }
          if (item.eventCategory == "LogCleared") {
              return 'warning';
          }
  
          if (item.eventResult == "Error") {
              return 'error';
          }
      },
  
      GetWindowsApiDisplay: function (name)
      {
          var displayName = "unknown";
  
          CmOptions.windowsApiOptions.forEach(function (item) {
  
              if (item.Name == name)
              {
                  displayName = item.Display;
              }
          });
  
          return displayName;
      },
  
      GetShortDateTime: function (value, item) {
          var date = new Date(value)
          return date.toDateString();
      },
      RefreshGrid: function (grid)
      {
          grid.jsGrid("render");
      },
      ResetAlertState: function ()
      {
          UiGlobal.HideError();
          UiGlobal.HideSuccess();
          UiGlobal.HideWarning();
      },
      ShowSuccess: function (msg)
      {
          $('#success-alert').text(msg)
          $('#success-alert').show();
      },
      HideSuccess: function (msg)
      {
          $('#success-alert').hide();
      },
      ShowError: function (msg)
      {
          $('#error-alert').text(msg)
          $('#error-alert').show();
      },
      ShowWarning: function (msg)
      {
          $('#warning-alert').text(msg);
          $('#warning-alert').show();
      },
      HideError: function ()
      {
          $('#error-alert').hide();
      },
      HideWarning: function ()
      {
          $('#warning-alert').hide();
      },
      ShowCurrentTab: function ()
      {
          if (location.hash === "" || location.hash === null) {
              $('#defaultOpen').click();
          }
          else
          {
              var currentTab = location.hash.replace("#", "");
              $("." + currentTab).click();
          }
      },
  
      ShowModal: function (id) {
          $("#" + id).modal("show");
      },
      GetSelectedOptions: function (obj)
      {
          var selectedArray = [];
  
          var selected = obj.find(":selected");
  
          for (i = 0; i < selected.length; i++) {
              selectedArray.push(selected[i].value);
          }
  
          return selectedArray;
      },
  
      GetDateString(arg) {
          return (new Date(arg)).toDateString();
      },
  
  
      GetFormRowDiv: function ()
      {
          return $('<div>').addClass('form-group row');
      },
  
      GetFormColLabel: function (displayText)
      {
          return $('<div>').addClass('col-sm-6').text(displayText);
      },
  
      GetFormCheckbox: function (inputId, isChecked)
      {
          var input = $('<input>').addClass('form-check-input scope').attr('type', 'checkbox').attr('id', inputId).attr("checked", isChecked);
          var label = $('<label>').addClass('form-check-label');
          var inputDiv = $('<div>').addClass('form-check');
          var inputCol = $('<div>').addClass('col-sm-4');
  
          return inputCol.append(inputDiv.append(label.append(input)));
      },
  
      GetButton: function (onclick)
      {
          return $('<button>')
              .attr('type', 'button')
              .addClass('btn btn-primary')
              .attr('onclick', onclick)
              .text('Save');
      }
  }
  var CmScripts = {
  
      PageLoad: function () {
          CmScripts.Grid = $('#table');
          CmScripts.Modal = $('#addModal');
          CmScripts.CommitButton = $('#addButton');
          //CmScripts.CredentialSelect = $('#credential');
          CmScripts.InitializeGrid();
          //CmScripts.InitializeIdpSelect();
      },
  
      InitializeIdpSelect: function () {
          Services.GetActiveDirectoryIdentityProviders(CmScripts.InitializeIdpSelectSuccessCallback, null);
      },
  
      InitializeIdpSelectSuccessCallback: function (data) {
  
          var primarySet = false;
  
          var appendData = {};
  
          data.forEach(function (item) {
  
            
              if (primarySet) {
                  appendData = {
                      value: item.id,
                      text: item.name
                  };
              }
              else {
                  appendData = {
                      value: item.id,
                      text: item.name,
                      selected: "selected"
                  };
                  primarySet = true;
              }
  
              CmScripts.CredentialSelect.append($('<option>', appendData));        
          });
      },
  
      CredentialSelect: null,
  
      Grid: null,
  
      Modal: null,
  
      ShowAddModal: function () {
          CmScripts.ResetModalState();
          CmScripts.Modal.modal("show");
          CmScripts.SetCommitOnClick("Add");
      },
  
      CommitButton: null,
  
      ResetModalState: function () {
          $('#name').val('');
          $('#code').val('');
      },
  
      Add: function () {
          CmScripts.Grid.jsGrid("insertItem", CmScripts.GetData());
      },
  
      Edit: function () {
  
      },
  
  
      GetData: function () {
          return {
              name: $('#name').val(),
              code: $('#code').val()
          };
      },
  
  
      SetCommitOnClick: function(eventType) {
          switch (eventType) {
              case "Add":
                  CmScripts.CommitButton.attr("onclick", "CmScripts.Add();");
                  break;
              case "Edit":
                  CmScripts.CommitButton.attr("onclick", "CmScripts.Edit();");
                  break;
              default:
                  CmScripts.CommitButton.attr("onclick", "CmScripts.Add();");
          }
      },
  
      InitializeGrid: function ()
      {
          CmScripts.Grid.jsGrid({
              height: "auto",
              width: "100%",
  
              editing: true,
              sorting: true,
              paging: true,
              autoload: true,
  
              pageSize: 15,
              pageButtonCount: 5,
  
              deleteConfirm: "Do you really want to delete this script?",
  
              controller: CmScripts.Controller,
  
              fields: [
  
                  { name: "name", type: "text", title: "name" },
  
                  { name: "id", type: "text", title: "id" },
  
                  {
                      name: "details",
                      title: "Action", 
                      width: 50,
                      itemTemplate: function (value, item) {
                          var $link = $("<a>").attr("href", '/view/script/' + item.id).text("View");
                          return $("<div>").append($link);
                      }
                  },
                  {
                      type: "control",
                      
                      headerTemplate: function () {
                          return $("<button>").attr("type", "button").text("Add")
                              .on("click", function () {
                                  CmScripts.ShowAddModal();
                              });
                      }
                  }
              ],
  
              onItemInserting: function (args) { CmScripts.ResetErrorState(); },
              onItemUpdating: function (args) { CmScripts.ResetErrorState(); },
              onItemDeleting: function (args) { CmScripts.ResetErrorState(); }
  
          });
      },
  
      Controller: {
          loadData: function (filter) {
              var d = $.Deferred();
              $.ajax({
                  type: "GET",
                  url: "/scripts",
                  dataType: "json"
              }).done(function (response) {
                  d.resolve(response.payload);
              });
              return d.promise();
          },
          insertItem: function (item) {
              var d = $.Deferred();
              $.ajax({
                  type: "POST",
                  url: "/script",
                  data: item
              }).done(function (response) {
                  d.resolve(response.payload);
              }).fail(function (xhr, ajaxOptions, thrownError) {
                  CmScripts.HandleError(xhr.responseJSON.message, CmScripts.Table);
              });
              return d.promise();
          },
  
          updateItem: function (item) {
  
              $.ajax({
                  type: "PUT",
                  url: "/script",
                  data: item
              }).fail(function (xhr, ajaxOptions, thrownError) {
                  CmScripts.HandleError(xhr.responseJSON.message, CmScripts.Table);
              });
          },
  
          deleteItem: function (item) {
              $.ajax({
                  type: "DELETE",
                  url: "/script",
                  data: item
              }).fail(function (xhr, ajaxOptions, thrownError) {
                  CmScripts.HandleError(xhr.responseJSON.message, CmScripts.Table);
              });
          }
      },
  
      ResetErrorState: function () {
          UiGlobal.HideError();
      },
  
      HandleError: function (textStatus, grid) {
          grid.jsGrid("render");
          UiGlobal.ShowError(textStatus.responseJSON.message);
      },
  
      InitializeSelect: function () {
          CmOptions.ActiveDirectoryMetadataType.forEach(function (item) {
              $('#eisType').append($('<option>', {
                  value: item.Name,
                  text: item.Name
              }));
          });
      }
  
  
  }
  
  var certSearchResult = null;
  
  var Services = {
  
      Post: function (uri, data, successCallback, errorCallback) {
          $.ajax({
              url: uri,
              type: 'post',
              data: data,
              cache: false,
              async: true,
              dataType: "json",
              success: function (data) {
                  successCallback(data.payload);
              },
              error: function (x, t, m) {
                  errorCallback(x, t, m);
              }
          });
      },
  
      Put: function (uri, data, successCallback, errorCallback) {
          $.ajax({
              url: uri,
              type: 'put',
              data: data,
              cache: false,
              async: true,
              dataType: "json",
              success: function (data) {
                  successCallback(data.payload);
              },
              error: function (x, t, m) {
                  errorCallback(x, t, m);
              }
          });
      },
  
      Get: function (uri, successCallback, errorCallback) {
          $.ajax({
              url: uri,
              type: 'get',
              cache: false,
              async: true,
              dataType: "json",
              success: function (data) {
                  successCallback(data.payload);
              },
              error: function (x, t, m) {
                  errorCallback('Error while retrieving data');
              }
          });
      },
  
      Delete: function (uri, successCallback, errorCallback) {
          $.ajax({
              url: uri,
              type: 'delete',
              cache: false,
              async: true,
              dataType: "json",
              success: function (data) {
                  successCallback(data);
              },
              error: function (x, t, m) {
                  errorCallback('Error while retrieving data');
              }
          });
      },
  
      GetNode: function (id, successCallback, errorCallback) {
          $.ajax({
              url: "/node/" + id,
              type: 'get',
              cache: false,
              async: true,
              dataType: "json",
              success: function (data) {
                  successCallback(data.payload);
              },
              error: function (x, t, m) {
                  errorCallback(x, t, m);
              }
          });
      },
  
      SaveSettings: function (requestData, successCallback, errorCallback) {
          $.ajax({
              url: "/general-config/settings",
              type: 'put',
              data: requestData,
              cache: false,
              async: true,
              dataType: "json",
              success: function (data) {
                  successCallback(data.payload);
              },
              error: function (x, t, m) {
                  errorCallback(x, t, m);
              }
          });
      },
  
      GetActiveDirectoryIdentityProviders: function (successCallback, errorCallback)
      {
          $.ajax({
              url: "/cm-config/external-identity-sources",
              type: 'get',
              cache: false,
              async: true,
              dataType: "json",
              success: function (data) {
                  successCallback(data);
              },
              error: function (x, t, m) {
                  errorCallback(x, t, m);
              }
          });
      },
  
      GetSettings: function (successCallback, errorCallback) {
          $.ajax({
              url: "/app-config",
              type: 'get',
              cache: false,
              async: true,
              dataType: "json",
              success: function (data) {
                  successCallback(data.payload);
              },
              error: function (x, t, m) {
                  errorCallback(x, t, m);
              }
          });
      },
  
      SetAuditConfig: function (requestData, successCallback, errorCallback)
      {
          $.ajax({
              url: "/general-config/audit-config",
              type: 'put',
              data: requestData,
              cache: false,
              async: true,
              dataType: "json",
              success: function (data) {
                  successCallback(data.payload);
              },
              error: function (x, t, m) {
                  errorCallback(x, t, m);
              }
          });
      },
  
      CreateCertificate: function (request, successCallback, errorCallback) {
          $.ajax({
              url: "/ca/private/certificate/request/includeprivatekey",
              type: 'post',
              data: {
                  SubjectCommonName: request.SubjectCommonName,
                  SubjectDepartment: request.SubjectDepartment,
                  SubjectOrganization: request.SubjectOrganization,
                  SubjectCity: request.SubjectCity,
                  SubjectState: request.SubjectState,
                  SubjectCountry: request.SubjectCountry,
                  SubjectAlternativeNamesRaw: request.SubjectAlternativeNamesRaw,
                  CipherAlgorithm: request.CipherAlgorithm,
                  Provider: request.Provider,
                  HashAlgorithm: request.HashAlgorithm,
                  KeySize: request.KeySize,
                  KeyUsage: request.KeyUsage
              },
              cache: false,
              async: true,
              dataType: "json",
              success: function (data) {
                  successCallback(data.payload);
              },
              error: function (x, t, m) {
                  errorCallback(x, t, m);
              }
          });
      },
  
      ResetCertificatePassword: function (id, successCallback, errorCallback) {
          $.ajax({
              url: "/certificate/" + id + "/password",
              type: 'put',
              cache: false,
              async: true,
              success: function (data) {
                  successCallback();
              },
              error: function (x, t, m) {
                  errorCallback();
              }
          });
      },
  
      GetCertificatePassword: function (id, successCallback, errorCallback) {
          $.ajax({
              url: "/certificate/" + id + "/password",
              type: 'get',
              cache: false,
              async: true,
              dataType: "json",
              success: function (data) {
                  successCallback(data.payload);
              },
              error: function (x, t, m) {
                  errorCallback(x, t, m);
              }
          });
      },
  
      IssuePendingCertificate: function (id, successCallback, errorCallback) {
          $.ajax({
              url: "/ca/private/certificate/request/issue-pending/" + id,
              type: 'post',
              cache: false,
              async: true,
              dataType: "json",
              success: function (data) {
                  successCallback(data.payload);
              },
              error: function (x, t, m) {
                  errorCallback(x, t, m);
              }
          });
      },
  
      GetCertificateDetails: function (id, successCallback, errorCallback) {
          $.ajax({
              url: "/certificate/" + id,
              type: 'get',
              cache: false,
              async: true,
              dataType: "json",
              success: function (data) {
                  successCallback(data.payload);
              },
              error: function (x, t, m) {
                  errorCallback(x, t, m);
              }
          });
      },
  
      SearchCertificates: function (query, successCallback, errorCallback)
      {
          $.ajax({
              url: "/certificates/search",
              type: 'get',
              cache: false,
              async: true,
              dataType: "json",
              success: function (data) {
                  certSearchResult = data;
                  //successCallback(data);
              },
              error: function (x, t, m) {
                  //errorCallback(x, t, m);
              }
          });
      },
  
      GetAdcsTemplates: function (successCallback, errorCallback) {
          $.ajax({
              url: "/pki-config/templates",
              type: 'get',
              cache: false,
              async: true,
              dataType: "json",
              success: function (data) {
                  successCallback(data);
              },
              error: function (x, t, m) {
              }
          });
      },
  
      GetPendingCertificates: function (successCallback, errorCallback) {
          $.ajax({
              url: "/certificate/request/pending",
              type: 'get',
              cache: false,
              async: true,
              dataType: "json",
              success: function (data) {
                  successCallback(data.payload);
              },
              error: function (x, t, m) {
              }
          });
      },
  
      GetEnumMapping: async function () {
          const response = await axios.get("/view/enum-mapping");
          localStorage.setItem("uiEnumMap", JSON.stringify(response.data));
  
      },
  
      GetSecurityRoleDetails: function (id, successCallback, errorCallback)
      {
          $.ajax({
              url: "/security/role/" + id,
              type: 'get',
              cache: false,
              async: true,
              dataType: "json",
              success: function (data) {
                  successCallback(data);
              },
              error: function (x, t, m) {
                  errorCallback(x, t, m);
              }
          });
      },
  
      ImportUsersFromActiveDirectoryMetadata: function (data, successCallback, errorCallback)
      {
          $.ajax({
              url: "/security/authenticable-principal/import",
              type: 'post',
              cache: false,
              async: true,
              dataType: "json",
              data: data,
              success: function (data) {
                  successCallback(data);
              },
              error: function (x, t, m) {
                  errorCallback(x, t, m);
              }
          });
      },
  
      GetAppConfig: function (successCallback, errorCallback)
      {
          $.ajax({
              url: "/config",
              type: 'get',
              cache: false,
              async: true,
              dataType: "json",
              success: function (data) {
                  successCallback(data);
              },
              error: function (x, t, m) {
                  errorCallback(x, t, m);
              }
          });
      },
  
      SetAppConfig: function (data, successCallback, errorCallback)
      {
          $.ajax({
              url: "/config",
              type: 'put',
              cache: false,
              async: true,
              data: data,
              dataType: "json",
              success: function (data) {
                  successCallback();
              },
              error: function (x, t, m) {
                  errorCallback(x, t, m);
              }
          });
      },
  
      ResetUserPassword: function (data, successCallback, errorCallback) {
          $.ajax({
              url: "/security/authenticable-principal/password",
              type: 'put',
              cache: false,
              async: true,
              data: data,
              dataType: "json",
              success: function (response) {
                  successCallback("Successfully reset password");
              },
              error: function (x, t, m) {
                  errorCallback(x, t, m);
              }
          });
      },
  
      SetLocalAppConfig: function (data, successCallback, errorCallback) {
          $.ajax({
              url: "/config/local",
              type: 'put',
              cache: false,
              async: true,
              data: data,
              dataType: "json",
              success: function (data) {
                  successCallback();
              },
              error: function (x, t, m) {
                  errorCallback(x, t, m);
              }
          });
      },
  
      SetRoleScopes: function (roleId, scopes, successCallback, errorCallback) {
  
          UiGlobal.ResetAlertState();
  
          $.ajax({
              url: "/security/role/" + roleId + "/scopes",
              type: 'put',
              cache: false,
              async: true,
              data: JSON.stringify( { scopes: scopes } ),
              dataType: "json",
              contentType: "application/json",
              success: function (data) {
                  successCallback();
              },
              error: function (x, t, m) {
                  errorCallback(x.responseJSON.message);
                  //errorCallback(x, t, m);
              }
          });
      }
  }
  
  var ActiveDirectoryMetadatas = {
  
      ShowAuthApiActionModal: function (dialogType, client) {
  
          if (dialogType === "Add")
          {
              $('#commitAuthApiEntity').click(function () {
  
                  ActiveDirectoryMetadatas.AddAuthApiCertificate(client);
              });
          }
          else
          {
  
          }
          
  
          $("#authApiActionModal").modal("show");
      },
  
      ShowAddActiveDirectoryMetadataModal: function (dialogType, client) {
  
          $('#commitAuthApiEntity').click(function () {
  
              ActiveDirectoryMetadatas.AddEis(client, "Add");
          });
  
          $("#addActiveDirectoryMetadataModal").modal("show");
      },
  
      AddEis: function (client, isNew) {
          $.extend(client, {
              name: $("#eisName").val(),
              domain: $("#eisDomain").val(),
              username: $("#eisUsername").val(),
              password: $("#eisPassword").val(),
              enabled: $("#eisEnabled").val(),
              searchBase: $("#eisSearchBase").val(),
          });
  
          $("#ActiveDirectoryMetadatasTable").jsGrid(isNew ? "insertItem" : "updateItem", client);
  
          $("#addActiveDirectoryMetadataModal").modal("hide");
      },
  
      AddAuthApiCertificate: function (client) {
          $.extend(client, {
              id: $("#thumbprint").val(),
              primary: $("#primary").is(":checked")
          });
  
          $("#authApiSigningCertificatesTable").jsGrid("insertItem", client);
  
          $("#authApiActionModal").modal("hide");
      },
  
      InitializeAuthApiGrid: function ()
      {
          $('#authApiSigningCertificatesTable').jsGrid({
              height: "auto",
              width: "100%",
  
              //filtering: true,
              editing: false,
              sorting: true,
              paging: true,
              autoload: true,
  
              pageSize: 15,
              pageButtonCount: 5,
  
              deleteConfirm: "Do you really want to delete this external identity source?",
  
              controller: ActiveDirectoryMetadatas.AuthApiController,
  
              fields: [
                  { name: "displayName", type: "text", title: "DisplayName" },
                  { name: "thumbprint", type: "text", title: "Thumbprint" },
                  { name: "hasPrivateKey", type: "checkbox", title: "HasPrivateKey", sorting: false },
                  { name: "primary", type: "checkbox", title: "Primary", sorting: false },
                  {
                      type: "control",
                      editButton: false,
                      headerTemplate: function () {
                          return $("<button>").attr("type", "button").text("Add")
                              .on("click", function () {
                                  ActiveDirectoryMetadatas.ShowAuthApiActionModal("Add", {});
                              });
                      }
                  }
              ]
          });
      },
  
      InitializeGrid: function ()
      {
          $("#ActiveDirectoryMetadatasTable").jsGrid({
              height: "auto",
              width: "100%",
  
              //filtering: true,
              editing: true,
              sorting: true,
              paging: true,
              autoload: true,
  
              pageSize: 15,
              pageButtonCount: 5,
  
              deleteConfirm: "Do you really want to delete this external identity source?",
  
              controller: ActiveDirectoryMetadatas.Controller,
  
              fields: [
                  { name: "name", type: "text", title: "Name" },
                  { name: "domain", type: "text", title: "Domain" },
                  { name: "searchBase", type: "text", title: "SearchBase" },
                  { name: "activeDirectoryMetadataType", type: "select", items: CmOptions.ActiveDirectoryMetadataType, valueType: "string", valueField: "Name", textField: "Name", title: "Type" },
                  { name: "username", type: "text", title: "Username" },
                  { name: "password", type: "text", readOnly: true, title: "password" },
                  { name: "enabled", type: "checkbox", title: "Enabled", sorting: false },
                  {
                      type: "control",
                      headerTemplate: function () {
                          return $("<button>").attr("type", "button").text("Add")
                              .on("click", function () {
                                  ActiveDirectoryMetadatas.ShowAddActiveDirectoryMetadataModal("Add", {});
                              });
                      }
                  }
              ]
          });
      },
  
      Controller: {
          loadData: function (filter) {
              var d = $.Deferred();
              $.ajax({
                  type: "GET",
                  url: "/cm-config/external-identity-sources",
                  dataType: "json"
              }).done(function (response) {
                  d.resolve(response);
              });
              return d.promise();
          },
          insertItem: function (item) {
              $.ajax({
                  type: "POST",
                  url: "/cm-config/external-identity-source",
                  data: item
              }).fail(function (xhr, ajaxOptions, thrownError) {
                  ActiveDirectoryMetadatas.HandleError(xhr.responseJSON.message, $("#ActiveDirectoryMetadatasTable"));
              });
          },
  
          updateItem: function (item) {
  
              $.ajax({
                  type: "PUT",
                  url: "/cm-config/external-identity-source",
                  data: item
              }).fail(function (xhr, ajaxOptions, thrownError) {
                  ActiveDirectoryMetadatas.HandleError(xhr.responseJSON.message, $("#ActiveDirectoryMetadatasTable"));
              });
          },
  
          deleteItem: function (item) {
              $.ajax({
                  type: "DELETE",
                  url: "/cm-config/external-identity-source",
                  data: item
              }).fail(function (xhr, ajaxOptions, thrownError) {
                  ActiveDirectoryMetadatas.HandleError(xhr.responseJSON.message, $("#ActiveDirectoryMetadatasTable"));
              });
          },
  
          onItemInserting: function (args) { ActiveDirectoryMetadatas.ResetErrorState(); },
          onItemUpdating: function (args) { ActiveDirectoryMetadatas.ResetErrorState(); },
          onItemDeleting: function (args) { ActiveDirectoryMetadatas.ResetErrorState(); }
      },
  
      AuthApiController: {
          loadData: function (filter) {
              var d = $.Deferred();
              $.ajax({
                  type: "GET",
                  url: "/identity-sources/local-authapi/trustedcertificates",
                  dataType: "json"
              }).done(function (response) {
                  d.resolve(response.payload);
              });
              return d.promise();
          },
          insertItem: function (item) {
              $.ajax({
                  type: "POST",
                  url: "/identity-sources/local-authapi/trustedcertificate",
                  data: item
              }).fail(function (xhr, ajaxOptions, thrownError) {
                  ActiveDirectoryMetadatas.HandleError(xhr.responseJSON.message, $("#authApiSigningCertificatesTable"));
              });
          },
  
          updateItem: function (item) {
  
              $.ajax({
                  type: "PUT",
                  url: "/identity-sources/local-authapi/trustedcertificate",
                  data: item
              }).fail(function (xhr, ajaxOptions, thrownError) {
                  ActiveDirectoryMetadatas.HandleError(xhr.responseJSON.message, $("#authApiSigningCertificatesTable"));
              });
          },
  
          deleteItem: function (item) {
              $.ajax({
                  type: "DELETE",
                  url: "/identity-sources/local-authapi/trustedcertificate",
                  data: item
              }).fail(function (xhr, ajaxOptions, thrownError) {
                  ActiveDirectoryMetadatas.HandleError(xhr.responseJSON.message, $("#authApiSigningCertificatesTable"));
              });
          },
  
          onItemInserting: function (args) { ActiveDirectoryMetadatas.ResetErrorState(); },
          onItemUpdating: function (args) { ActiveDirectoryMetadatas.ResetErrorState(); },
          onItemDeleting: function (args) { ActiveDirectoryMetadatas.ResetErrorState(); }
      },
  
      ResetErrorState: function () {
          UiGlobal.HideError();
      },
  
      HandleError: function (textStatus, grid) {
          grid.jsGrid("render");
          UiGlobal.ShowError(textStatus.responseJSON.message);
      },
  
      InitializeSelect: function () {
          CmOptions.ActiveDirectoryMetadataType.forEach(function (item) {
              $('#eisType').append($('<option>', {
                  value: item.Name,
                  text: item.Name
              }));
          });
      },
  
      CertificateSelect2: null,
  
      InitializeCertificateSelect2: function ()
      {
          ActiveDirectoryMetadatas.CertificateSelect2.select2({
              width: '100%',
              placeholder: 'Search for a certificate',
              ajax: {
                  url: ("/certificates/search/summary"),
                  dataType: 'json',
                  type: 'get',
                  delay: 30,
                  //data: function (params) {
                  //    return {
                  //        query: params.term
                  //    };
                  //},
                  processResults: function (data, params) {
                      //params.page = params.page || 1;
  
                      return {
                          results: data.payload,
                      };
                  },
                  cache: false
              },
              escapeMarkup: function (markup) { return markup; },
              templateResult: ActiveDirectoryMetadatas.FormatCertificate,
              templateSelection: ActiveDirectoryMetadatas.FormatCertificateSelection,
  
          });
      },
  
      FormatCertificate: function (repo) {
  
          var markup = '<div class="user-select-container">'
          markup = markup + '<div class="cert-select-title"><b>' + repo.displayName + '</b></div>';
          markup = markup + '<div class="cert-select-details">Thumbprint: <span class="cert-select-details-value">' + repo.thumbprint + '</span></div>';
          markup = markup + '<div class="cert-select-details">Expires: <span class="cert-select-details-value">' + UiGlobal.GetDateString(repo.expiry) + '</span></div>';
          //markup = markup + '<div class="user-select-details">Domain: <span class="user-select-details-value">' + repo.domain + '</span></div>';
          markup = markup + '</div>';
          //var markup = repo.text;
          return markup;
      },
  
      FormatCertificateSelection: function (repo) {
          return repo.thumbprint;
      },
  
      GetAppConfigSuccessCallback: function (data)
      {
          $('#jwtValidityPeriod').val(data.payload.jwtValidityPeriod);
          $('#localIdpIdentifier').val(data.payload.localIdpIdentifier);
          $('#allowWindowsAuth').prop('checked', data.payload.windowsAuthEnabled);
          $('#allowLocalAuthentication').prop('checked', data.payload.localLogonEnabled);
          $('#allowEmergencyAccess').prop('checked', data.payload.emergencyAccessEnabled);
      },
  
      SaveAppConfigSuccessCallback: function ()
      {
          UiGlobal.ShowSuccess("Successfully saved app configuration");
      },
  
      PageLoad: function ()
      {
          ActiveDirectoryMetadatas.InitializeSelect();
          ActiveDirectoryMetadatas.InitializeGrid();
          ActiveDirectoryMetadatas.CertificateSelect2 = $('#thumbprint');
          ActiveDirectoryMetadatas.InitializeCertificateSelect2();
          ActiveDirectoryMetadatas.InitializeAuthApiGrid();
          Services.GetAppConfig(ActiveDirectoryMetadatas.GetAppConfigSuccessCallback, null);
          UiGlobal.ShowCurrentTab();
      },
  
      SetAppConfig: function()
      {
          UiGlobal.ResetAlertState();
  
          var data = {
              jwtValidityPeriod: $('#jwtValidityPeriod').val(),
              localIdpIdentifier: $('#localIdpIdentifier').val()
          }
  
          Services.SetAppConfig(data, ActiveDirectoryMetadatas.SaveAppConfigSuccessCallback, null);
      },
  
      SetLocalAppConfig: function ()
      {
  
          UiGlobal.ResetAlertState();
  
          var data = {
              localLogonEnabled: $('#allowLocalAuthentication').prop('checked'),
              emergencyAccessEnabled: $('#allowEmergencyAccess').prop('checked'),
              windowsAuthEnabled: $('#allowWindowsAuth').prop('checked')
          }
  
          Services.SetLocalAppConfig(data, ActiveDirectoryMetadatas.SaveAppConfigSuccessCallback, null);
      }
  }
  var GeneralConfig = {
  
      SecurityAuditingRadio: null,
  
      OperationsLoggingRadio: null,
  
      ClearAuditConfigCurrentState: function () {
          $('input:radio[name="securityAuditingState"]').removeAttr('checked');
          $('input:radio[name="operationsLoggingState"]').removeAttr('checked');
      },
  
      GetAuditConfigCurrentState: function ()
      {
          return {
              securityAuditingState: $('input:radio[name="securityAuditingState"]:checked').val(),
              operationsLoggingState: $('input:radio[name="operationsLoggingState"]:checked').val()
          }
      },
  
      GetSettingsCurrentState: function ()
      {
          return {
              cachePeriod: $('#cachePeriod').val()
          };
      },
  
      GetSettings: function ()
      {
          GeneralConfig.ClearAuditConfigCurrentState();
  
          Services.GetSettings(GeneralConfig.GetSettingsSuccessCallback, GeneralConfig.ErrorCallback)
      },
  
      SaveSettings: function ()
      {
          UiGlobal.ResetAlertState();
          var data = GeneralConfig.GetSettingsCurrentState();
          Services.SaveSettings(data, GeneralConfig.SaveSettingsSuccessCallback, GeneralConfig.ErrorCallback);
      },
  
      SaveAuditConfig: function ()
      {
          UiGlobal.ResetAlertState();
          var data = GeneralConfig.GetAuditConfigCurrentState();
          Services.SetAuditConfig(data, GeneralConfig.SaveAuditConfigSuccessCallback, GeneralConfig.ErrorCallback);
      },
  
      SaveSettingsSuccessCallback: function () {
          UiGlobal.ShowSuccess("Settings were saved successfully");
      },
  
      ErrorCallback: function (x) {
          UiGlobal.ShowError(x.message);
      },
  
      GetSettingsSuccessCallback: function (data) {
          $("input[name=operationsLoggingState][value=" + data.operationsLoggingState + "]").attr('checked', 'checked');
          $("input[name=securityAuditingState][value=" + data.securityAuditingState + "]").attr('checked', 'checked');
          $('#cachePeriod').val(data.cachePeriod);
      },
  
      SaveAuditConfigSuccessCallback: function ()
      {
          UiGlobal.ShowSuccess("Auditing configuration was saved successfully");
      },
  
      PageLoad: function ()
      {
          //GeneralConfig.SecurityAuditingRadio = $('input[name=securityAuditingRadio]:checked');
          //GeneralConfig.OperationsLoggingRadio = $('input[name=operationsLoggingRadio]:checked');
  
          GeneralConfig.GetSettings();
          UiGlobal.ShowCurrentTab();
  
      }
  }
  
  
  var Login = {
  
      PageLoad: function ()
      {
          Login.ShowErrorIfUnsuccessful();
          Login.InitializeAlternativeLoginOptions();
          Login.ConfigureAuthBypass();
          Login.InitializeDomainSelect();   
      },
  
      ShowErrorIfUnsuccessful: function ()
      {
          if (Login.IsAuthFailure())
          {
              UiGlobal.ShowError();
          }
      },
  
      ConfigureAuthBypass: function ()
      {
          //controlled by form post
      },
  
      InitializeAlternativeLoginOptions: function ()
      {
          $('#altLoginMethodCheckbox').change(function () {
              if ($(this).is(":checked")) {
                  $('.alt-login-btn').show();
              }
              else {
                  $('.alt-login-btn').hide();
              }
          });
      },
  
      InitializeDomainSelect: function ()
      {
          CmOptions.ActiveDirectoryMetadatas.forEach(function (item) {
              if (item.enabled) {
                  var element = $('#domain');
  
                  element.append($('<option>', {
                      value: item.id,
                      text: item.name
                  }));
              }
          });
  
          if (CmOptions.LocalAuthenticationEnabled)
          {
              var element = $('#domain');
  
              element.append($('<option>', {
                  value: CmOptions.LocalIdentityProviderId,
                  text: 'Local'
              }));
          }
      },
  
      IsAuthFailure: function ()
      {
          if (document.URL.indexOf("authentication_failure") > -1)
          {
              return true;
          }
          else
          {
              return false;
          }
      }
  
  }
  var Logs = {
  
  
      Grid: null,
  
      Controller: {
          loadData: function (filter) {
              var d = $.Deferred();
              $.ajax({
                  type: "GET",
                  url: "/logs",
                  dataType: "json"
              }).done(function (response) {
                  d.resolve(response.payload);
              });
              return d.promise();
          }
      },
  
      ShowDetailsModal: function (data)
      {
          $('#eventTime').val(data.time);
          $('#eventResult').val(data.eventResult);
          $('#eventCategory').val(data.eventCategory);
          $('#contextUserId').val(data.userId);
          $('#contextUser').val(data.userDisplay);
          $('#targetId').val(data.target);
          $('#message').text(data.message);
  
          UiGlobal.ShowModal('LogDetailsModal');
      },
  
      InitializeGrid: function ()
      {
          Logs.Grid.jsGrid({
              height: "auto",
              width: "100%",
  
              rowClick: function (args) {
                  Logs.ShowDetailsModal(args.item);
              },
  
              rowClass: function (item, itemIndex) {
                  return UiGlobal.GetRowClass(item, itemIndex);
              },
  
              editing: false,
              sorting: true,
              paging: true,
              autoload: true,
  
              pageSize: 30,
              pageButtonCount: 5,
  
              deleteConfirm: "Do you really want to delete this log?",
  
              controller: Logs.Controller,
  
              fields: [
                  { name: "target", type: "text", title: "Target" },
                  //{ name: "targetDescription", type: "text", title: "Description" },
                  { name: "userDisplay", type: "text", title: "UserDisplay" },
                  { name: "userId", type: "text", title: "UserId" },
                  { name: "eventResult", type: "text", title: "EventResult" },
                  { name: "eventCategory", type: "text", title: "EventCategory" },
                  { name: "time", type: "text", title: "Time" }
              ]
  
          });
      },
  
      PageLoad: function ()
      {
          Logs.Grid = $('#logsTable');
          Logs.InitializeGrid();
      },
  
      Clear: function () {
          Services.Delete('/logs', Logs.ClearLogsCallbackSuccess, null);
      },
  
      ClearLogsCallbackSuccess: function (data) {
          location.reload();
      }
  }
  
  
  var NodeDetails = {
  
      Id: null,
  
      CredentialId: null,
  
      Credential: null,
  
      Hostname: null,
  
      Node: null,
  
      ManagedCertificatesTable: null,
  
      PageLoad: function () {
  
          UiGlobal.ShowCurrentTab();
          NodeDetails.Id = $('#id');
          NodeDetails.Credential = $('#credential');
          NodeDetails.CredentialId = $('#credentialId');
          NodeDetails.Hostname = $('#hostname');
          NodeDetails.ManagedCertificatesTable = $('#managedCertificatesTable');
          NodeDetails.GetNode(NodeDetails.Id.val());
      },
  
      ShowSelectedTable: function () {
  
      },
  
      GetNode: function (id) {
          Services.GetNode(id, NodeDetails.GetNodeSuccessCallback, null);
      },
  
      InitManagedCertificatesTable: function () {
          NodeDetails.ManagedCertificatesTable.bootstrapTable({
              data: NodeDetails.Node.managedCertificates
          });
      },
  
      GetNodeSuccessCallback: function (data) {
          NodeDetails.Node = data;
          NodeDetails.CredentialId.val(data.credentialId);
          NodeDetails.Hostname.val(data.hostname);
          NodeDetails.Credential.val(data.credentialDisplayName);
          NodeDetails.InitManagedCertificatesTable();
      },
  
      InvokeCertificateDiscovery: function () {
          UiGlobal.ResetAlertState();
          Services.Post("/node/" + NodeDetails.Id.val() + "/discovery/iis", null, NodeDetails.InvokeCertificateDiscoverySuccessCallback, NodeDetails.InvokeCertificateDiscoveryErrorCallback);
      },
  
      InvokeCertificateDiscoverySuccessCallback: function () {
          UiGlobal.ShowSuccess("Certificate discovery has started for this node. Reviews logs for results.");
      },
  
      InvokeCertificateDiscoveryErrorCallback: function () {
          UiGlobal.ShowError("Failed to start certificate discovery");
      }
  }
  var OidcIdentityProvider = {
      PageLoad: function () {
          OidcIdentityProvider.InitGrid();
  
          OidcIdentityProvider.OidcIdpModal = $('#oidcIdpModal');
          OidcIdentityProvider.CommitOidcIdpButton = $('#commitOidcIdpButton');
      },
  
      InitModal: function () {
          OidcIdentityProvider.CommitOidcIdpButton('#commitOidcIdpButton');
      },
  
      InitGrid: function () {
          OidcIdentityProvider.Grid = $("#openIdConfigTable");
  
          $("#openIdConfigTable").jsGrid({
              height: "auto",
              width: "100%",
  
              editing: true,
              sorting: true,
              paging: true,
              autoload: true,
  
              pageSize: 15,
              pageButtonCount: 5,
  
              deleteConfirm: "Do you really want to delete this identity provider?",
  
              controller: OidcIdentityProvider.Controller,
  
              fields: [
                  { name: "name", type: "text", title: "Name" },
                  { name: "authority", type: "text", title: "Authority" },
                  { name: "clientId", type: "text", title: "ClientId" },
  
                  {
                      type: "control",
                      headerTemplate: function () {
                          return $("<button>").attr("type", "button").text("Add")
                              .on("click", function () {
                                  OidcIdentityProvider.ShowAddOidcIdpModal();
                              });
                      }
                  }
              ]
          });
      },
  
      GetOidcIdpData: function () {
          return {
              name: $('#oidcIdpName').val(),
              clientId: $('#oidcIdpClientId').val(),
              authority: $('#oidcIdpAuthority').val()
          };
      },
  
      AddOidcIdp: function () {
          OidcIdentityProvider.Grid.jsGrid("insertItem", OidcIdentityProvider.GetOidcIdpData());
      },
  
      ShowAddOidcIdpModal: function () {
          OidcIdentityProvider.ResetAddOidcModalState();
          OidcIdentityProvider.OidcIdpModal.modal("show");
          OidcIdentityProvider.SetCommitOnClick("Add");
      },
  
      SetCommitOnClick(eventType) {
          switch (eventType) {
              case "Add":
                  OidcIdentityProvider.CommitOidcIdpButton.attr("onclick", "OidcIdentityProvider.AddOidcIdp();");
                  break;
              case "Edit":
                  OidcIdentityProvider.CommitOidcIdpButton.attr("onclick", "OidcIdentityProvider.EditOidcIdp();");
                  break;
              default:
                  OidcIdentityProvider.CommitOidcIdpButton.attr("onclick", "OidcIdentityProvider.AddOidcIdp();");
          }
      },
  
      ResetAddOidcModalState: function () {
          $('#oidcIdpName').val('');
          $('#oidcIdpAuthority').val('');
          $('#oidcIdpClientId').val('');
      },
  
      Controller: {
          loadData: function (filter) {
              var d = $.Deferred();
              $.ajax({
                  type: "GET",
                  url: "/cm-config/oidc-idp",
                  dataType: "json"
              }).done(function (response) {
                  d.resolve(response.payload);
              });
              return d.promise();
          },
          insertItem: function (item) {
              $.ajax({
                  type: "POST",
                  url: "/cm-config/oidc-idp",
                  data: item
              }).fail(function (xhr, ajaxOptions, thrownError) {
                  OidcIdentityProvider.HandleError(xhr.responseJSON.message);
              });
          },
  
          updateItem: function (item) {
  
              $.ajax({
                  type: "PUT",
                  url: "/cm-config/oidc-idp",
                  data: item
              }).fail(function (xhr, ajaxOptions, thrownError) {
                  OidcIdentityProvider.HandleError(xhr.responseJSON.message);
              });
          },
  
          deleteItem: function (item) {
              $.ajax({
                  type: "DELETE",
                  url: "/cm-config/oidc-idp",
                  data: item
              }).fail(function (xhr, ajaxOptions, thrownError) {
                  OidcIdentityProvider.HandleError(xhr.responseJSON.message);
              });
          },
  
          onItemInserting: function (args) { OidcIdentityProvider.ResetErrorState(); },
          onItemUpdating: function (args) { OidcIdentityProvider.ResetErrorState(); },
          onItemDeleting: function (args) { OidcIdentityProvider.ResetErrorState(); }
      },
  
      HandleError: function (msg) {
          OidcIdentityProvider.Grid.jsGrid("render");
          UiGlobal.ShowError(msg);
      },
  
      ResetErrorState: function () {
          UiGlobal.HideError();
      },
  
      OidcIdpModal: null,
  
      CommitOidcIdpButton: null,
  
      Grid: null
  
  }
  var PendingCertificates = {
  
      PageLoad: function ()
      {
          PendingCertificates.Grid = $('#allPendingCertificates');
          PendingCertificates.InitializeGrid();
      },
  
      Grid: null,
      
      Controller:
      {
          loadData: function (filter)
          {
              var d = $.Deferred();
              $.ajax({
                  type: "GET",
                  url: "/certificate/request/pending",
                  dataType: "json"
              }).done(function (response) {
                  d.resolve(response.payload);
              });
              return d.promise();
          },
          deleteItem: function (item) {
              $.ajax({
                  type: "DELETE",
                  url: "/certificate/request/pending/" + item.id
                  //data: item
              }).fail(function (xhr, ajaxOptions, thrownError) {
                  ViewAllCertificates.HandleError(xhr.responseJSON.message, ViewAllCertificates.Grid);
              });
          }
      },
  
      InitializeGrid: function ()
      {
          PendingCertificates.Grid.jsGrid({
              height: "auto",
              width: "100%",
  
              //filtering: true,
              editing: false,
              sorting: true,
              paging: true,
              autoload: true,
  
              pageSize: 15,
              pageButtonCount: 5,
  
              deleteConfirm: "Do you want to deny this certificate request?",
  
              controller: PendingCertificates.Controller,
  
              fields: [
                  { title: "CommonName", name: "subjectCommonName", type: "text" },
                  { title: "RequestDate", name: "requestDate", type: "text"  },
                  { title: "Cipher", name: "cipherAlgorithm", type: "text" },
                  { title: "Hash", name: "hashAlgorithm", type: "text" },
                  { title: "RequestType", name: "pendingCertificateRequestType", type: "text" },
                  { title: "KeyUsage", name: "keyUsage", type: "text" },
                  {
                      title: "Action",
                      width: 15,
                      itemTemplate: function (value, item) {
                          var btn = $("<i>");
                          btn.addClass("fa fa-check");
                          btn.attr('req-id', item.id);
  
                          btn.on('click', function (event) {
                              UiGlobal.ShowWarning("Please wait, the certificate request is processing");
                              var id = event.target.attributes["req-id"].value;
                              Services.IssuePendingCertificate(id, PendingCertificates.IssueCertificateSuccessCallback, PendingCertificates.IssueCertificateErrorCallback);
                              return false;
                          });
  
                          return btn;
                      }
  
                  },
                  {
                      type: "control",
                      editButton: false,
                      width: 10
                  }
              ]
  
              //onItemInserting: function (args) { SecurityRoles.ResetErrorState(); },
              //onItemUpdating: function (args) { SecurityRoles.ResetErrorState(); },
              //onItemDeleting: function (args) { SecurityRoles.ResetErrorState(); }
  
          });
      },
  
      IssueCertificateSuccessCallback: function (data)
      {
          UiGlobal.HideWarning();
          window.location.replace("/view/certificate/" + data.id);
      },
  
      IssueCertificateErrorCallback: function (x, t, m)
      {
          UiGlobal.HideWarning();
          UiGlobal.ShowError("Could not issue the pending certificate.");
      }
  }
  var debugData = "";
  
  var PkiConfig = {
  
      ResolveIdpName: function (value, item)
      {
          var idpDisplayName = "";
  
          CmOptions.ActiveDirectoryMetadatas.forEach(function (idp) {
  
  
              if (idp.id == item.identityProviderId) {
                  idpDisplayName = idp.name
              }
  
  
          });
  
          if (idpDisplayName === "") {
              idpDisplayName = "none";
          }
  
          return idpDisplayName;
      },
  
      InitializeSelect: function ()
      {
          CmOptions.hashAlgorithmOptions.forEach(function (item) {
  
              var caHash = $('#caHash');
  
              var element = $('#adcsTemplateHash');
  
              element.append($('<option>', {
                  value: item.Name,
                  text: item.Name
              }));
  
  
              caHash.append($('<option>', {
                  value: item.Name,
                  text: item.Name
              }));
  
              if (item.Primary === true)
              {
                  caHash.val(item.Name);
                  element.val(item.Name);
              }   
          });
  
          CmOptions.cipherOptions.forEach(function (item) {
              $('#adcsTemplateCipher').append($('<option>', {
                  value: item.Name,
                  text: item.Name,
              }));
          });
          
          CmOptions.keyUsageOptions.forEach(function (item) {
              $('#adcsTemplateKeyUsage').append($('<option>', {
                  value: item.Name,
                  text: item.Name
              }));
          });
  
          CmOptions.windowsApiOptions.forEach(function (item) {
              $('#adcsTemplateWindowsApi').append($('<option>', {
                  value: item.Name,
                  text: item.Name
              }));
          });
      },
  
      ResetErrorState: function () {
          UiGlobal.HideError();
      },
  
      HandleError: function (textStatus, grid) {
          grid.jsGrid("render");
          UiGlobal.ShowError(textStatus);
      },
  
      GetUpdatedTemplateData: function ()
      {
          var allowedToIssueList = "";
          $('#adcsTemplateAllowedToIssue').val().forEach(function (item) {
  
              if (allowedToIssueList === "") {
                  allowedToIssueList = item;
              }
              else {
                  allowedToIssueList = allowedToIssueList + ';' + item;
              }
  
          });
  
          return {
              id: $('#selected-template-id').val(),
              name: $('#adcsTemplateName').val(),
              cipher: $("#adcsTemplateCipher").val(),
              keyUsage: $("#adcsTemplateKeyUsage").val(),
              windowsApi: $("#adcsTemplateWindowsApi").val(),
              rolesAllowedToIssue: allowedToIssueList
          }
      },
  
      EditTemplate: function ()
      {
          var data = PkiConfig.GetUpdatedTemplateData();
  
          $("#adcsTemplatesTable").jsGrid("updateItem", data);
  
      },
  
      LoadEditTemplateModalData: function (data)
      {
          var roleIds = new Array();
  
          for (var key in data.rolesAllowedToIssueSelectView) {
              roleIds.push(data.rolesAllowedToIssueSelectView[key].id);
          }
  
          $('#selected-template-id').val(data.id);
          $("#adcsTemplateName").val(data.name);
          $("#adcsTemplateCipher").val(data.cipher);
          $("#adcsTemplateKeyUsage").val(data.keyUsage);
          $("#adcsTemplateWindowsApi").val(data.windowsApi);
  
          var roleSelect = document.getElementById('adcsTemplateAllowedToIssue');
  
          for (i = 0; i < roleSelect.children.length; i++) {
  
              var option = roleSelect.children[i];
  
              if (roleIds.includes(option.value)) {
                  option.selected = true;
              }
              else {
                  option.selected = false;
              }
          }
      },
  
      AddTemplate: function ()
      {
          var data = PkiConfig.GetUpdatedTemplateData();
  
          $("#adcsTemplatesTable").jsGrid("insertItem", data);
      },
  
      ShowAddTemplateModal: function ()
      {
          PkiConfig.ResetErrorState();
  
          PkiConfig.SetCommitOnClick("Add");
  
          PkiConfig.InitializeSelect2();
  
          UiGlobal.ShowModal("addAdcsTemplateModal");
      },
  
      ShowEditTemplateModal: function (data)
      {
          PkiConfig.ResetErrorState();
  
          PkiConfig.LoadEditTemplateModalData(data);
          
          PkiConfig.InitializeSelect2();
  
          PkiConfig.SetCommitOnClick("Edit");
  
          UiGlobal.ShowModal("addAdcsTemplateModal");
      },
  
      ShowAddPrivateCaModal: function (client) {
  
          PkiConfig.InitializePrivateCaIdentityProviderSelect2();
  
          $('#commitPrivateCaButton').click(function () {
  
              PkiConfig.AddPrivateCa(client);
          });
  
          $("#privateCaActionModal").modal("show");
      },
  
      ShowEditPrivateCaModal: function (client)
      {
          debugData = client;
          $('#privateCaId').val(client.id);
          $('#caServerName').val(client.serverName);
          $('#caCommonName').val(client.commonName);
          $('#caHash').val(client.hashAlgorithm);
          
          
          PkiConfig.InitializePrivateCaIdentityProviderSelect2();
  
          $('#commitPrivateCaButton').click(function () {
  
              PkiConfig.ChangePrivateCa(client);
          });
  
          $("#privateCaActionModal").modal("show");
      },
  
      AddPrivateCa: function (client, isNew) {
          $.extend(client, {
              serverName: $("#caServerName").val(),
              commonName: $("#caCommonName").val(),
              hashAlgorithm: $("#caHash").val(),
              authenticationRealm: $("#caAuthenticationRealm").val(),
              authenticationType: $("#caAuthenticationType").val(),
              username: $("#caUsername").val(),
              password: $("#caPassword").val()
          });
  
          $("#privateCaTable").jsGrid("insertItem", client);
  
          $("#privateCaActionModal").modal("hide");
      },
  
      ChangePrivateCa: function (client) {
          $.extend(client, {
              id: $('#privateCaId').val(),
              serverName: $("#caServerName").val(),
              commonName: $("#caCommonName").val(),
              hashAlgorithm: $("#caHash").val(),
              identityProviderId: $('#caIdentityProvider').val()
          });
  
          $("#privateCaTable").jsGrid("updateItem", client);
  
          $("#privateCaActionModal").modal("hide");
      },
  
      PrivateCertificateAuthoritiesController: {
          loadData: function (filter) {
              var d = $.Deferred();
              $.ajax({
                  type: "GET",
                  url: "/pki-config/certificate-authorities/private",
                  dataType: "json"
              }).done(function (response) {
                  d.resolve(response.payload);
              });
              return d.promise();
          },
          insertItem: function (item) {
              $.ajax({
                  type: "POST",
                  url: "/pki-config/certificate-authority/private",
                  data: item
              }).fail(function (xhr, ajaxOptions, thrownError) {
                  PkiConfig.HandleError(xhr.responseJSON.message, $("#privateCaTable"));
              });
          },
  
          updateItem: function (item) {
              var d = $.Deferred();
              $.ajax({
                  type: "PUT",
                  url: "/pki-config/certificate-authority/private",
                  data: item
              }).done(function (response) {
                  d.resolve(response.payload);
              }).fail(function (xhr, ajaxOptions, thrownError) {
                  PkiConfig.HandleError(xhr.responseJSON.message, $("#privateCaTable"));
                  });
              return d.promise();
          },
  
          deleteItem: function (item) {
              $.ajax({
                  type: "DELETE",
                  url: "/pki-config/certificate-authority/private",
                  data: item
              }).fail(function (xhr, ajaxOptions, thrownError) {
                  PkiConfig.HandleError(xhr.responseJSON.message, $("#privateCaTable"));
              });
          }  
      },
  
      AdcsTemplateController: {
          loadData: function (filter) {
              var d = $.Deferred();
              $.ajax({
                  type: "GET",
                  url: "/pki-config/templates",
                  //data: filter,
                  dataType: "json"
              }).done(function (response) {
                  d.resolve(response.payload);
              });
              return d.promise();
          },
  
          insertItem: function (item) {
              var d = $.Deferred();
              $.ajax({
                  type: "POST",
                  url: "/pki-config/template",
                  data: item
              }).done(function (response) {
                  d.resolve(response.payload);
              }).fail(function (xhr, ajaxOptions, thrownError) {
                  PkiConfig.HandleError(xhr.responseJSON.message, $("#adcsTemplatesTable"));
              });
              return d.promise();
  
              //$.ajax({
              //    type: "POST",
              //    url: "/pki-config/template",
              //    data: item
              //}).fail(function (xhr, ajaxOptions, thrownError) {
              //    PkiConfig.HandleError(xhr.responseJSON.message, $("#adcsTemplatesTable"));
              //});
          },
  
          updateItem: function (item) {
              var d = $.Deferred();
              $.ajax({
                  type: "PUT",
                  url: "/pki-config/template",
                  data: item
              }).done(function (response) {
                  d.resolve(response.payload);
              }).fail(function (xhr, ajaxOptions, thrownError) {
                  PkiConfig.HandleError(xhr.responseJSON.message, $("#adcsTemplatesTable"));
                  });
              return d.promise();
  
  
              //var d = $.Deferred();
              //$.ajax({
              //    type: "PUT",
              //    url: "/pki-config/template",
              //    data: item
              //}).fail(function (xhr, ajaxOptions, thrownError) {
              //    PkiConfig.HandleError(xhr.responseJSON.message, $("#adcsTemplatesTable"));
              //});
              //return d.promise();
          },
  
          deleteItem: function (item) {
              $.ajax({
                  type: "DELETE",
                  url: "/pki-config/template",
                  data: item
              }).fail(function (xhr, ajaxOptions, thrownError) {
                  PkiConfig.HandleError(xhr.responseJSON.message, $("#adcsTemplatesTable"));
                  });
  
          }
      },
  
      InitializePkiConfigGrids: function () {
  
          PkiConfig.TemplateGrid = $("#adcsTemplatesTable");
  
  
          PkiConfig.TemplateGrid.jsGrid({
              height: "auto",
              width: "100%",
  
              //filtering: true,
              editing: false,
              sorting: true,
              paging: true,
              autoload: true,
  
              pageSize: 15,
              pageButtonCount: 5,
  
              deleteConfirm: "Do you really want to delete this template?",
  
              controller: PkiConfig.AdcsTemplateController,
  
              rowClick: function (args) {
                  PkiConfig.ShowEditTemplateModal(args.item);
              },
              
              fields: [
                  { title: "Template Name", name: "name", type: "text", validate: { validator: "rangeLength", param: [1, 100] }, width: 80 },
                  //{ title: "Server Name", name: "hash", type: "select", items: CmOptions.hashAlgorithmOptions, valueType: "string", valueField: "Name", textField: "Name", width: 30 },
                  { title: "Cipher", name: "cipher", type: "select", items: CmOptions.cipherOptions, valueField: "Name", textField: "Name", width: 30 },
                  { title: "Key Usage", name: "keyUsage", type: "select", items: CmOptions.keyUsageOptions, valueField: "Name", textField: "Name" },
                  { title: "WindowsApi", name: "windowsApi", type: "select", items: CmOptions.windowsApiOptions, valueField: "Name", textField: "Name", width: 40 },
                  {
                      title: "Roles Allowed To Issue This Template",
                      name: "rolesAllowedToIssue",
                      itemTemplate: function (value, item) {
  
                          var roleSelect = $("<select style='width:100%' class='security-roles-adcs-select2' multiple='multiple'>");
  
                          item.rolesAllowedToIssueSelectView.forEach(function (option) {
                              roleSelect.append($('<option>', {
                                  value: option.id,
                                  text: option.name
                              }).attr('selected', true));
                          });
  
                          roleSelect = roleSelect.attr('disabled', true);
                          return roleSelect;
                          //return $("<div>").append(roleSelect);
                      }
                  },
                  {
                      width:25,
                      editButton: false,
                      type: "control",
                      headerTemplate: function () {
                          return $("<button>").attr("type", "button").text("Add")
                              .on("click", function () {
                                  PkiConfig.ShowAddTemplateModal();
                              });
                      }
                  }
              ],
              onItemInserted: function (args) { PkiConfig.TemplateGrid.jsGrid("render"); },
              onRefreshed: function (args) { PkiConfig.InitializeSelect2(); },
              onItemUpdated: function (args) { PkiConfig.TemplateGrid.jsGrid("render"); PkiConfig.InitializeSelect2(); },
              onItemEditing: function (args) { PkiConfig.InitializeSelect2(); },
              onItemInserting: function (args) { PkiConfig.ResetErrorState(); },
              onItemUpdating: function (args) { PkiConfig.ResetErrorState(); PkiConfig.InitializeSelect2(); },
              onItemDeleting: function (args) { PkiConfig.ResetErrorState(); },
              onDataLoading: function (args) { PkiConfig.InitializeSelect2();}, 
              onDataLoaded: function (args) { PkiConfig.InitializeSelect2();}
  
  
          });
  
          $("#privateCaTable").jsGrid({
              height: "auto",
              width: "100%",
  
              //filtering: true,
              editing: false,
              sorting: true,
              paging: true,
              autoload: true,
  
              pageSize: 15,
              pageButtonCount: 5,
  
              deleteConfirm: "Do you really want to delete this certificate authority?",
  
              controller: PkiConfig.PrivateCertificateAuthoritiesController,
  
              rowClick: function (args) {
                  PkiConfig.ShowEditPrivateCaModal(args.item);
              },
  
              fields: [
                  { title: "Server Name", name: "serverName", type: "text" },
                  { title: "Common Name", name: "commonName", type: "text" },
                  { title: "Hash", name: "hashAlgorithm", type: "select", items: CmOptions.hashAlgorithmOptions, valueType: "string", valueField: "Name", textField: "Name" },
                  { title: "Identity Provider", name: "identityProviderId", itemTemplate: function (value, item) { return PkiConfig.ResolveIdpName(value, item); }  },
                  {
                      type: "control",
                      editButton: false,
                      headerTemplate: function () {
                          return $("<button>").attr("type", "button").text("Add")
                              .on("click", function () {
                                  PkiConfig.ShowAddPrivateCaModal({});
                              });
                      }
                  }
              ],
              onItemInserting: function (args) { PkiConfig.ResetErrorState(); },
              onItemUpdating: function (args) { PkiConfig.ResetErrorState(); },
              onItemDeleting: function (args) { PkiConfig.ResetErrorState(); }
          });
  
          var editableAllowedToIssue = $('.security-roles-adcs-select2-editable');
  
          CmOptions.SecurityRoles.forEach(function (option) {
              editableAllowedToIssue.append($('<option>', {
                  //value: item.Name,
                  //text: item.Name,
                  value: option.Id,
                  text: option.Name
              }))
          });
      },
  
      InitializePrivateCaIdentityProviderSelect2: function ()
      {
          $('#caIdentityProvider').select2({ data: CmOptions.ActiveDirectoryMetadatas, width: '100%' });
      },
  
      InitializeSelect2: function ()
      {
          $('.security-roles-adcs-select2').select2({ width: '100%' });
      },
  
      SetCommitOnClick(eventType) {
          switch (eventType) {
              case "Add":
                  PkiConfig.CommitTemplateButton.attr("onclick", "PkiConfig.AddTemplate();");
                  break;
              case "Edit":
                  PkiConfig.CommitTemplateButton.attr("onclick", "PkiConfig.EditTemplate();");
                  break;
              default:
                  PkiConfig.CommitTemplateButton.attr("onclick", "PkiConfig.AddTemplate();");
          }
      },
  
      CommitTemplateButton: null,
  
      TemplateGrid: null,
  
      PageLoad: function ()
      {
          PkiConfig.CommitTemplateButton = $('#addAdcsTemplateButton');
          PkiConfig.InitializeSelect();
          UiGlobal.ShowCurrentTab();
          PkiConfig.InitializePkiConfigGrids();
      }
  }
  
  
  function WriteError(msg) {
      $('#error-alert').text(msg);
      $('#error-alert').show();
  }
  
  function DisplayCertificateDetails(data) {
      $("#displayName").text(data.displayName);
      $('#hashAlgorithm').text(data.hashAlgorithm);
      $('#thumbprint').text(data.thumbprint);
      $('#certificate-id').text(data.id);
      $('#cipherAlgorithm').text(data.cipherAlgorithm);
      $('#hasPrivateKey').text(data.hasPrivateKey);
      $('#expires').text(data.validTo);
      $('#keySize').text(data.keySize);
      $('#storageFormat').text(data.certificateStorageFormat);
      $('#windowsApi').text(data.windowsApi);
  }
  
  function GetPrivateCertificateRequestData() {
      var request = {
          SubjectCommonName: $('#commonName').val(),
          SubjectDepartment: $('#department').val(),
          SubjectOrganization: $('#organization').val(),
          SubjectCity: $('#city').val(),
          SubjectState: $('#state').val(),
          SubjectCountry: $('#country').val(),
          SubjectAlternativeNamesRaw: $('#sancsv').val(),
          CipherAlgorithm: $('#cipherAlgorithm').val(),
          Provider: $('#windowsApi').val(),
          HashAlgorithm: $('#hashAlgorithm').val(),
          KeySize: $('#keySize').val(),
          KeyUsage: $('#keyUsage').val()
      }
  
      return request;
  }
  
  function ValidateNewPrivateCertificate(request) {
  
      //var spinner = StartSpinner();
      var keysize = request.KeySize;
      var provider = request.Provider;
      var cipheralg = request.CipherAlgorithm;
      var validRsaKeySizes = ["2048", "4096", "8192", "16384"]
      var keyusage = request.KeyUsage;
      //var role = $('#role').val();
  
  
      //0 is RSA
      if (cipheralg == "0") {
          if (validRsaKeySizes.indexOf(keysize) != 0) {
              var msg = "Rsa keysize is invalid. Rsa only supports 2048, 4096, 8192, or 16384. Choose 2048 if you are unsure.";
              WriteError(msg)
              return false;
          }
      }
  
      //1 is EC
      if (cipheralg == "1") {
          if (provider != "1") {
              var msg = "Elliptic Curve only supports the provider Cng (CryptoApi Next Generation)";
              WriteError(msg);
              return false;
          }
  
          if (keysize != 256) {
              var msg = "Elliptic Curve only supports a keysize of 256bits";
              WriteError(msg);
              return false;
          }
      }
  
  
      if ($("#SubjectCommonName").val() != "") {
          var result = Services.ValidateDnsName($("#SubjectCommonName").val())
          if (result["Status"] != "valid") {
              WriteError("Invalid subject common name provided")
              return false;
          }
      }
      else {
          WriteError("You must specify a subject common name");
          return false;
      }
  
      if ($("#SubjectAlternativeNamesRaw").val() != "") {
          var result = Services.ValidateDnsSan($("#SubjectAlternativeNamesRaw").val())
          if (result["Status"] != "valid") {
              WriteError("Invalid subject alternative name. Either remove the subject alternative name, or specify the san with correct comma separated format. ")
              return false;
          }
      }
  
  
      if (keyusage == null) {
          WriteError("Key Usage must be specified. If you're not an Admin, you won't be able to select anything except 'Server'")
          return false;
      }
  
      if (!keyusage.constructor == Array) {
          WriteError("Key Usage must be specified. If you're not an Admin, you won't be able to select anything except 'Server'")
          return false;
      }
  
      if (keyusage.length < 1 || keyusage.length > 3) {
          WriteError("Key Usage must be specified. If you're not an Admin, you won't be able to select anything except 'Server'")
          return false;
      }
  
      //if (role != "Admin" && keyusage != 1) {
      //    $(".modal-body").text("Key Usage must be specified. If you're not an Admin, you won't be able to select anything except 'Server'");
      //    $('#msgModal').modal('show');
      //    return false;
      //}
  
      return true;
      //$('#formSubmitButtonHidden').click();
  
  
  }
  
  
  
  var PrivateCertificateAuthority = {
  
      CreateCertificateSuccessCallback: function (data) {
  
          if (data.status == "Success")
          {
              window.sessionStorage.setItem("certificateId", data.id);
              $('#create-private-certificate-btn').prop('disabled', false);
              window.location.replace("/view/certificate/" + data.id);
          }
          else if(data.status == "Pending")
          {
              window.location.replace('/view/certificate/request/pending');
          }
          else
          {
              //error thing
          }
   
      },
  
      CreateCertificateErrorCallback: function (x, t, m) {
  
          WriteError(x.responseJSON.message);
  
          $('#create-private-certificate-btn').prop('disabled', false);
  
      },
  
      GetCertificateErrorCallback: function (x, t, m) {
  
          //WriteError(x.responseJSON.message);
  
          //$('#create-private-certificate-btn').prop('disabled', false);
  
      },
  
      GetCertificateSuccessCallback: function (data) {
          DisplayCertificateDetails(data);
      },
  
      GetCertificateDetails: function () {
          //var id = window.location.pathname.replace('/views/certificate/', '');
          var id = window.sessionStorage.getItem("certificateId");
          Services.GetCertificateDetails(id, this.GetCertificateSuccessCallback, this.GetCertificateErrorCallback);
      },
  
      RegisterCreateCertificateButtonEvent: function () {
          $('#create-private-certificate-btn').click(function () {
  
              $('#error-alert').hide();
              $('#success-alert').hide();
              $('#create-private-certificate-btn').prop('disabled', true);
  
              var request = GetPrivateCertificateRequestData();
  
              //if (!ValidateNewPrivateCertificate(request))
              //{
              //    $('#create-private-certificate-btn').prop('disabled', false);
              //    return false;
              //}
  
              Services.CreateCertificate(request, PrivateCertificateAuthority.CreateCertificateSuccessCallback, PrivateCertificateAuthority.CreateCertificateErrorCallback);
  
          });
  
      },
  
      InitializeUi: function () {
  
          CmOptions.hashAlgorithmOptions.forEach(function (item) {
  
              var element = $('#hashAlgorithm');
  
              element.append($('<option>', {
                  value: item.Name,
                  text: item.Name
              }));
  
              if (item.Primary) {
                  element.val(item.Name);
              }
          });
  
          CmOptions.cipherOptions.forEach(function (item) {
              $('#cipherAlgorithm').append($('<option>', {
                  value: item.Name,
                  text: item.Display
              }));
          });
  
          CmOptions.keyUsageOptions.forEach(function (item) {
              if (item.Primitive) {
  
                  if (item.Primary)
                  {
                      $('#keyUsage').append($('<option>', {
                          value: item.Name,
                          text: item.Display,
                          selected: "selected"
                      }));
                  }
                  else
                  {
                      $('#keyUsage').append($('<option>', {
                          value: item.Name,
                          text: item.Display
                      }));
                  }
                  
              }
          });
  
          $('#keyUsage').select2({ width: '100%' });
  
          CmOptions.windowsApiOptions.forEach(function (item) {
              $('#windowsApi').append($('<option>', {
                  value: item.Name,
                  text: item.Display
              }));
          });
      },
  
      PageLoad: function () {
          PrivateCertificateAuthority.InitializeUi();
          PrivateCertificateAuthority.RegisterCreateCertificateButtonEvent();
      }
  };
  var ScriptDetails = {
  
      Uri: '/script',
  
      Id: null,
  
      Name: null,
  
      Code: null,
  
      PageLoad: function () {
          ScriptDetails.Id = $('#id');
          ScriptDetails.Name = $('#name');
          ScriptDetails.Code = $('#code');
          ScriptDetails.Get(ScriptDetails.Id.val());
      },
  
      Get: function (id) {
          var uri = ScriptDetails.Uri + '/' + ScriptDetails.Id.val();
          Services.Get(uri, ScriptDetails.GetSuccessCallback, ScriptDetails.ErrorCallback)
      },
  
      GetSuccessCallback: function (data) {
          ScriptDetails.Name.val(data.name);
          ScriptDetails.Code.val(data.code);
      },
  
      GetSaveData: function () {
          data = {
              id: ScriptDetails.Id.val(),
              name: ScriptDetails.Name.val(),
              code: ScriptDetails.Code.val()
          }
  
          return data;
      },
  
      SaveSuccessCallback: function () {
          UiGlobal.ResetAlertState();
          UiGlobal.ShowSuccess();
      },
  
      ErrorCallback: function (msg) {
          UiGlobal.ResetAlertState();
          UiGlobal.ShowError('Error while parsing the script');
      },
  
      Save: function () {
          UiGlobal.ResetAlertState();
          Services.Put(ScriptDetails.Uri, ScriptDetails.GetSaveData(), ScriptDetails.SaveSuccessCallback, ScriptDetails.ErrorCallback);
      }
  }
  var debugvar = "";
  
  var SecurityRoleDetails = {
  
      GetScopesForRole: function ()
      {
          var selectedScopes = [];
  
          CmOptions.Scopes.forEach(function (item) {
  
              var selector = "#" + item.Id + ".scope";
  
              if ($(selector).is(":checked"))
              {
                  selectedScopes.push(item.Id);
              }
          });
  
          return selectedScopes;
  
      },
  
      SaveScopes: function ()
      {
          var selectedScopes = SecurityRoleDetails.GetScopesForRole();
          Services.SetRoleScopes(SecurityRoleDetails.Role.id, selectedScopes, UiGlobal.ShowSuccess, UiGlobal.ShowError);
      },
  
      ShowAddRoleMemberModal: function (dialogType, client) {
  
          $('#addSecurityRoleMemberButton').click(function () {
  
              SecurityRoleDetails.AddSecurityRoleMember(client, dialogType === "Add");
          });
  
          $("#addSecurityRoleMemberModal").modal("show");
      },
  
      AddSecurityRoleMember: function (client, isNew) {
          $.extend(client, {
              memberId: SecurityRoleDetails.UserAddRoleMemberSelect.val(),
              roleId: $('#roleId').text()
          });
  
          $("#roleMembersTable").jsGrid(isNew ? "insertItem" : "updateItem", client);
  
          $("#addSecurityRoleMemberModal").modal("hide");
      },
  
      RenderScopes: function ()
      {
          CmOptions.Scopes.forEach(function (item) {
  
              var formRow = UiGlobal.GetFormRowDiv();
  
              formRow.append(UiGlobal.GetFormColLabel(item.Name));
  
              if (SecurityRoleDetails.Role.scopes == null)
              {
                  var checked = false;
              }
              else
              {
                  var checked = SecurityRoleDetails.Role.scopes.indexOf(item.Id) >= 0;
              }
  
              
  
              formRow.append(UiGlobal.GetFormCheckbox(item.Id, checked));
  
              SecurityRoleDetails.ScopesTab.append(formRow);
  
          });
  
          SecurityRoleDetails.ScopesTab.append(UiGlobal.GetButton('SecurityRoleDetails.SaveScopes()'));
  
      },
  
      RenderViewData: function (data)
      {
          SecurityRoleDetails.Role = data.payload;
          $('#roleName').text(data.payload.name);
          SecurityRoleDetails.RenderScopes();
      },
  
      InitializeGrid: function () {
          $("#roleMembersTable").jsGrid({
              height: "auto",
              width: "100%",
              sorting: true,
              paging: true,
              autoload: true,
              pageSize: 15,
              pageButtonCount: 5,
  
              deleteConfirm: "Do you really want to delete this external identity source?",
  
              controller: SecurityRoleDetails.MembersController,
  
              fields: [
                  { name: "name", type: "text", title: "Name", editing: false },
                  { name: "enabled", type: "checkbox", title: "Enabled", sorting: false, editing: false },
                  {
                      type: "control",
                      headerTemplate: function () {
                          return $("<button>").attr("type", "button").text("Add")
                              .on("click", function () {
                                  SecurityRoleDetails.ShowAddRoleMemberModal("Add", {});
                              });
                      }
                  }
              ],
  
              onItemInserting: function (args) { SecurityRoleDetails.ResetErrorState(); },
              onItemUpdating: function (args) { SecurityRoleDetails.ResetErrorState(); },
              onItemDeleting: function (args) { SecurityRoleDetails.ResetErrorState(); }
          });
      },
  
      UserAddRoleMemberSelect: null,
  
      InitializeUserAddRoleMemberSelect: function ()
      {
          SecurityRoleDetails.UserAddRoleMemberSelect = $("#user-select");
  
          SecurityRoleDetails.UserAddRoleMemberSelect.select2({
              placeholder: 'search for a certificate manager user',
              ajax: {
  
                  url: ("/security/authenticable-principals/search"),
                  dataType: 'json',
                  type: 'get',
                  delay: 30,
                  data: function (params) {
                      return {
                          query: params.term, // search term
                          page: params.page
                      };
                  },
                  processResults: function (data, params) {
                      params.page = params.page || 1;
  
                      return {
                          results: data.payload,
                      };
                  },
                  cache: true
              },
              escapeMarkup: function (markup) { return markup; }, // let our custom formatter work
              minimumInputLength: 2,
              templateResult: SecurityRoleDetails.UserSelectFormatRepo, // omitted for brevity, see the source of this page
              templateSelection: SecurityRoleDetails.UserSelectFormatRepoSelection // omitted for brevity, see the source of this page
          });
      },
  
      UserSelectFormatRepo: function (repo)
      {
          return repo.name;
      },
  
      UserSelectFormatRepoSelection: function (repo)
      {
          return repo.name;
      },
  
      MembersController: {
          loadData: function (filter) {
              var d = $.Deferred();
              $.ajax({
                  type: "GET",
                  url: "/security/role/" + $('#roleId').text() + "/members",
                  dataType: "json"
              }).done(function (response) {
                  d.resolve(response.payload);
              });
              return d.promise();
          },
          insertItem: function (item) {
              //MembersController.onItemInserting();
              var d = $.Deferred();
              $.ajax({
                  type: "POST",
                  url: "/security/role/" + $('#roleId').text() + "/member/" + SecurityRoleDetails.UserAddRoleMemberSelect.val()
              }).done(function (response) {
                  d.resolve(response.payload);
              }).fail(function (xhr, ajaxOptions, thrownError) {
                  SecurityRoleDetails.HandleError(xhr.responseJSON.message, $("#roleMembersTable"));
              });
              return d.promise();
          },
  
          deleteItem: function (item) {
              $.ajax({
                  type: "DELETE",
                  url: "/security/role/" + $('#roleId').text() + "/member/" + item.id
              }).fail(function (xhr, ajaxOptions, thrownError) {
                  SecurityRoleDetails.HandleError(xhr.responseJSON.message, $("#roleMembersTable"));
              });
          }
      },
  
      ResetErrorState: function () {
          UiGlobal.HideError();
      },
  
      HandleError: function (textStatus, grid) {
          grid.jsGrid("render");
          UiGlobal.ShowError(textStatus);
      },
  
      PageLoad: function ()
      {
          UiGlobal.ShowCurrentTab();
          SecurityRoleDetails.ScopesTab = $('#roleScopes.tabcontent');
          Services.GetSecurityRoleDetails($('#roleId').text(), SecurityRoleDetails.RenderViewData, null);
          SecurityRoleDetails.InitializeGrid();
          SecurityRoleDetails.InitializeUserAddRoleMemberSelect();
          //SecurityRoleDetails.RegisterAddRoleMemberSelectHandler();
      },
  
      Role: null,
  
      ScopesTab: null
  }
  var SecurityRoles = {
  
      ShowAddSecurityRoleModal: function (dialogType, client) {
  
          //$("#eisName").val(client.name);
          //$("#eisDomain").val(client.hash);
          //$("#eis").val(client.cipher);
          //$("#adcsTemplateKeyUsage").val(client.keyUsage);
          //$("#adcsTemplateWindowsApi").val(client.windowsApi);
  
          $('#AddSecurityRoleButton').click(function () {
  
              SecurityRoles.AddRole(client, dialogType === "Add");
          });
  
          $("#addSecurityRoleModal").modal("show");
      },
  
      AddRole: function (client, isNew) {
          $.extend(client, {
              name: $("#secRoleName").val(),
              enabled: $("#secRoleEnabled").is(":checked")
          });
  
          $("#securityRolesTable").jsGrid(isNew ? "insertItem" : "updateItem", client);
  
          $("#addSecurityRoleModal").modal("hide");
      },
  
      InitializeGrid: function ()
      {
          $("#securityRolesTable").jsGrid({
              height: "auto",
              width: "100%",
  
              //filtering: true,
              editing: true,
              sorting: true,
              paging: true,
              autoload: true,
  
              pageSize: 15,
              pageButtonCount: 5,
  
              deleteConfirm: "Do you really want to delete this external identity source?",
  
              controller: SecurityRoles.Controller,
  
              fields: [
                  { name: "name", type: "text", title: "name" },
                  //{ name: "domain", type: "text", title: "Domain" },
                  //{ name: "searchBase", type: "text", title: "SearchBase" },
                  //{ name: "ActiveDirectoryMetadataType", type: "select", items: CmOptions.ActiveDirectoryMetadataType, valueType: "string", valueField: "Name", textField: "Name", title: "Type" },
                  //{ name: "username", type: "text", title: "Username" },
                  //{ name: "password", type: "text", readOnly: true, title: "password" },
                  { name: "enabled", type: "checkbox", title: "Enabled", sorting: false },
                  {
                      //css: "security-roles-select2",
                      name: "details",
                      title: "Action", 
                      width: 50,
                      itemTemplate: function (value, item) {
                          //var $text = $("<p>").text(item.MyField);
                          var $link = $("<a>").attr("href", '/view/security/role/' + item.id).text("View");
                          return $("<div>").append($link);
                      }
                  },
                  {
                      type: "control",
                      
                      headerTemplate: function () {
                          return $("<button>").attr("type", "button").text("Add")
                              .on("click", function () {
                                  SecurityRoles.ShowAddSecurityRoleModal("Add", {});
                              });
                      }
                  }
              ],
  
              onItemInserting: function (args) { SecurityRoles.ResetErrorState(); },
              onItemUpdating: function (args) { SecurityRoles.ResetErrorState(); },
              onItemDeleting: function (args) { SecurityRoles.ResetErrorState(); }
  
          });
      },
  
      Controller: {
          loadData: function (filter) {
              var d = $.Deferred();
              $.ajax({
                  type: "GET",
                  url: "/security/roles",
                  dataType: "json"
              }).done(function (response) {
                  d.resolve(response.payload);
              });
              return d.promise();
          },
          insertItem: function (item) {
              var d = $.Deferred();
              $.ajax({
                  type: "POST",
                  url: "/security/role",
                  data: item
              }).done(function (response) {
                  d.resolve(response.payload);
              }).fail(function (xhr, ajaxOptions, thrownError) {
                  SecurityRoles.HandleError(xhr.responseJSON.message, $("#securityRolesTable"));
              });
              return d.promise();
          },
  
          updateItem: function (item) {
  
              $.ajax({
                  type: "PUT",
                  url: "/security/role",
                  data: item
              }).fail(function (xhr, ajaxOptions, thrownError) {
                  SecurityRoles.HandleError(xhr.responseJSON.message, $("#securityRolesTable"));
              });
          },
  
          deleteItem: function (item) {
              $.ajax({
                  type: "DELETE",
                  url: "/security/role",
                  data: item
              }).fail(function (xhr, ajaxOptions, thrownError) {
                  SecurityRoles.HandleError(xhr.responseJSON.message, $("#securityRolesTable"));
              });
          }
      },
  
      ResetErrorState: function () {
          UiGlobal.HideError();
      },
  
      HandleError: function (textStatus, grid) {
          grid.jsGrid("render");
          UiGlobal.ShowError(textStatus.responseJSON.message);
      },
  
      InitializeSelect: function () {
          CmOptions.ActiveDirectoryMetadataType.forEach(function (item) {
              $('#eisType').append($('<option>', {
                  value: item.Name,
                  text: item.Name
              }));
          });
      }
  
  
  }
  
  var ViewAllCertificates = {
  
      PageLoad: function ()
      {
          ViewAllCertificates.Grid = $('#allCertificatesTable');
  
          ViewAllCertificates.InitializeGrid();
      },
  
      Grid: null,
  
      Controller: {
          loadData: function (filter) {
              var d = $.Deferred();
              $.ajax({
                  type: "GET",
                  url: "/certificates",
                  dataType: "json"
              }).done(function (response) {
                  d.resolve(response.payload);
              });
              return d.promise();
          },
          deleteItem: function (item) {
              $.ajax({
                  type: "DELETE",
                  url: "/certificate",
                  data: item
              }).fail(function (xhr, ajaxOptions, thrownError) {
                  ViewAllCertificates.HandleError(xhr.responseJSON.message, ViewAllCertificates.Grid);
              });
          }
      },
  
      ViewCertificate: function (item) {
          document.location = "/view/certificate/" + item.id;
      },
  
      InitializeGrid: function ()
      {
          ViewAllCertificates.Grid.jsGrid({
              height: "auto",
              width: "100%",
  
              //filtering: true,
              editing: false,
              sorting: true,
              paging: true,
              autoload: true,
  
              pageSize: 15,
              pageButtonCount: 5,
  
              rowClick: function (args) {
                  ViewAllCertificates.ViewCertificate(args.item);
              },
  
              deleteConfirm: "Do you really want to delete this certificate?",
  
              controller: ViewAllCertificates.Controller,
  
              fields: [
                  { title: "Display Name", name: "displayName", type: "text" },
                  { title: "Hash", name: "hashAlgorithm", type: "text", width: 25 },
                  { title: "Cipher", name: "cipherAlgorithm", type: "text", width: 25 },
                  {
                      title: "Expires", name: "validTo", type: "text", width: 40,
                      itemTemplate: function (value, item) {
                          return UiGlobal.GetDateString(value);
                      } },
                  { title: "Thumbprint", name: "thumbprint", type: "text" },
                  //{
                  //    name: "details",
                  //    title: "Action",
                  //    width: 20,
                  //    itemTemplate: function (value, item) {
                  //        //var $text = $("<p>").text(item.MyField);
                  //        var $link = $("<a>").attr("href", '/view/certificate/' + item.id).text("View");
                  //        return $("<div>").append($link);
                  //    }
                  //},
                  {
                      type: "control",
                      editButton: false,
                      width: 10
                  }
              ]
  
          });
      }
  }
  ViewCertificate = {
  
      PageLoad: function ()
      {
          document.getElementById("defaultOpen").click();
  
          UiGlobal.ShowCurrentTab();
  
          ViewCertificate.SubjectAlternativeNameTable = $('#subjectAlternativeNameTable');
          ViewCertificate.AclTable = $('#certificateAclTable');
          ViewCertificate.InitialzeAclTable();
          ViewCertificate.CertificateAceModal = $('#addCertificateAceModal');
          Services.GetCertificateDetails(ViewCertificate.GetCertificateId(), ViewCertificate.GetCertificateSuccessCallback, ViewCertificate.GetCertificateErrorCallback);
          ViewCertificate.InitializeDownloadUx();
          ViewCertificate.InitializeShowPassword();
          ViewCertificate.InitializeResetPassword();
          ViewCertificate.InitializeSelects();
  
          ViewCertificate.NodeSelect = $("#nodeSelect");
          ViewCertificate.InitializeNodeSelect();
  
          ViewCertificate.InitializeNodeSelect();
      },
  
      ShowDeployCertificateModal: function () {
          UiGlobal.ShowModal('deployCertificateModal');
      },
  
      DeployToNode: function () {
  
      },
  
      GetCertificateId: function ()
      {
          return $('#certificate-id-hidden').val();
      },
  
      InitializeSelects: function ()
      {
          ViewCertificate.AceTypeChangeAceSelect = $('#aceType');
          ViewCertificate.IdentityTypeChangeAceSelect = $('#aceIdentityType');
          ViewCertificate.AceIdentitySelect = $('#identity-select');
  
          CmOptions.AceTypes.forEach(function (item) {
              ViewCertificate.AceTypeChangeAceSelect.append(
                  $('<option>', { value: item, text: item })
              );
          });
  
          CmOptions.IdentityTypes.forEach(function (item) {
              ViewCertificate.IdentityTypeChangeAceSelect.append(
                  $('<option>', { value: item, text: item })
              );
          });
  
  
          ViewCertificate.AceIdentitySelect.select2({
              width: 'resolve',
              dropdownAutoWidth: true,
              placeholder: 'search for a certificate manager security principal',
              ajax: {
                  url: ("/security/principals"),
                  dataType: 'json',
                  type: 'get',
                  delay: 30,
                  data: function (params) {
                      return {
                          query: params.term, // search term
                          page: params.page
                      };
                  },
                  processResults: function (data, params) {
                      params.page = params.page || 1;
  
                      return {
                          results: data.payload,
                      };
                  },
                  cache: true
              },
              escapeMarkup: function (markup) { return markup; }, // let our custom formatter work
              minimumInputLength: 2,
              templateResult: ViewCertificate.FormatSelectResults, // omitted for brevity, see the source of this page
              templateSelection: ViewCertificate.FormatSelection // omitted for brevity, see the source of this page
          });
          
      },
  
      FormatSelectResults: function (repo) {
  
          var markup = '<div class="user-select-container">'
          markup = markup + '<div class="user-select-title">' + repo.name + '</div>';
          markup = markup + '<div class="user-select-details">Type: <span class="user-select-details-value">' + repo.identityType + '</span></div>';
          markup = markup + '</div>';
          return markup;
      },
  
      FormatSelection: function (repo)
      {
          return repo.name;
      },
  
      AceIdentitySelect: null,
  
      AceTypeChangeAceSelect: null,
  
      IdentityTypeChangeAceSelect: null,
  
      CertificateData: null,
  
      SubjectAlternativeNameTable: null,
  
      AclTable: null,
  
      CertificateAceModal: null,
  
      NodeSelect: null,
  
      GetCertificateSuccessCallback: function (data)
      {
          CertificateData = data;
  
          $('#displayName').text(data.displayName);
          $('#thumbprint').text(data.thumbprint);
          $('#hashAlgorithm').text(data.hashAlgorithm);
          $('#cipherAlgorithm').text(data.cipherAlgorithm);
          $('#hasPrivateKey').text(data.hasPrivateKey);
          $('#expires').text(UiGlobal.GetDateString(data.expires));
          $('#windowsApi').text(UiGlobal.GetWindowsApiDisplay(data.windowsApi));
          $('#keySize').text(data.keySize);
          $('#storageFormat').text(data.certificateStorageFormat);
  
          ViewCertificate.InitializeSubjectAlternativeNamesTable(ViewCertificate.SubjectAlternativeNameTable, data.subject.subjectAlternativeName);
  
          //ViewCertificate.InitialzeAclTable(ViewCertificate.AclTable, data.acl);
      },
  
      GetCertificateErrorCallback: function ()
      {
          UiGlobal.ShowError();
      },
  
      ShowAddCertificateAceModal: function ()
      {
          ViewCertificate.CertificateAceModal.modal("show");
      },
  
      InitializeDownloadUx: function ()
      {
          $('#showCertificateDownloadOptionsButton').click(function () {
  
              $('#certificateDownloadOptionsModal').modal('show');
  
          });
  
  
          $('#cer-radio').change(function () {
              $("#download-certificate-button").prop('disabled', false);
              $("#download-cer-option-der").prop('disabled', false);
              $("#download-cer-option-b64").prop('disabled', false);
              $("#download-cer-option-b64").prop('checked', true);
              $("#cer-background").css("background-color", "#b0c4de");
              $("#pfx-background").css("background-color", "#f5f5f5");
          });
  
          $('#pfx-radio').change(function () {
              $("#download-certificate-button").prop('disabled', false);
              $("#download-pfx-includechain").prop('disabled', false);
              $("#download-cer-option-b64").prop('disabled', true);
              $("#download-cer-option-der").prop('disabled', true);
              $("#pfx-background").css("background-color", "#b0c4de");
              $("#cer-background").css("background-color", "#f5f5f5");
          });
  
  
          $('#download-certificate-button').click(function (e) {
              var type;
              var encoding;
              if ($("#cer-radio").prop("checked")) {
                  if ($("#download-cer-option-b64").prop('checked')) {
                      type = "certb64";
                  }
                  else {
                      type = "certbinary";
                  }
                  type = "certbinary";
              }
              else if ($("#pfx-radio").prop("checked")) {
                  type = "pfx";
              }
              else {
                  type = "";
              }
  
              if ($('#include-chain-checkbox').prop('checked')) {
                  type = type + "chain"
              }
  
              var downloadUri = "/certificate/" + $('#certificate-id').text();
  
              switch (type) {
                  case "certbinarychain":
                      downloadUri = downloadUri + "/download/cer/binary/includechain";
                      break;
                  case "certbinary":
                      downloadUri = downloadUri + "/download/cer/binary/nochain";
                      break;
                  case "certb64chain":
                      downloadUri = downloadUri + "/download/cer/base64/includechain";
                      break;
                  case "certb64":
                      downloadUri = downloadUri + "/download/cer/base64/nochain";
                      break;
                  case "pfxchain":
                      downloadUri = downloadUri + "/download/pfx/includechain";
                      break;
                  case "pfx":
                      downloadUri = downloadUri + "/download/pfx/nochain";
                      break;
                  default:
                      downloadUri = downloadUri + "/download/cer/binary/nochain";
              }
  
              e.preventDefault();
              window.location.href = downloadUri;
  
          });
      },
  
      InitializeSubjectAlternativeNamesTable: function (table, sanList) {
          table.jsGrid({
              width: "100%",
              paging: true,
              autoload: true,
              pageLoading: true,
  
              controller: {
                  loadData: function () {
                      return { data: sanList }
                  }
              },
  
              fields: [
                  {
                      title: "Subject Alternative Name",
                      itemTemplate: function (value, item) {
                          return item;
                      }
                  }
              ]
          });
      },
  
      ChangeList: function ()
      {
  
      },
  
  
      InitialzeAclTable: function (table)
      {
          ViewCertificate.AclTable.jsGrid({
              width: "100%",
              paging: true,
              autoload: true,
              //pageLoading: true,
              deleteConfirm: "Are you sure you want to remove this ACE from the Access Control List?",
              //"certificate/{certId:guid}/acl/{aceId:guid}"
              controller: {
  
                  loadData: function (filter) {
                      var d = $.Deferred();
                      $.ajax({
                          type: "GET",
                          url: "/certificate/" + ViewCertificate.GetCertificateId(),
                          dataType: "json"
                      }).done(function (response) {
                          d.resolve(response.payload.acl);
                      });
                      return d.promise();
                  },
                  //loadData: function () {
                  //    return { data: acl }
                  //},
  
                  insertItem: function (item) {
                      var d = $.Deferred();
                      $.ajax({
                          type: "PUT",
                          url: "/certificate/" + item.id + "/acl",
                          dataType: "json",
                          contentType: 'application/json; charset=UTF-8',
                          data: JSON.stringify({
                              identityType: item.identityType,
                              aceType: item.aceType,
                              identity: item.identity
                          })
                      }).done(function (response) {
                          d.resolve(response.payload);
                      });
                      return d.promise();
  
                  },
  
                  deleteItem: function (item) {
                      $.ajax({
                          type: "DELETE",
                          url: "/certificate/" + ViewCertificate.GetCertificateId() + "/acl/" + item.id
                      }).fail(function (xhr, ajaxOptions, thrownError) {
                          ViewCertificate.HandleError(xhr.responseJSON.message, AuthenticablePrincipal.Grid);
                      });
                  }
              },
  
              fields: [
                  { title: "Identity", name: "identityDisplayName", type: "text" },
                  { title: "IdentityType", name: "identityType", type: "text" },
                  { title: "AceType", name: "aceType", type: "text" },
                  {
                      width: 25,
                      editButton: false,
                      type: "control",
                      headerTemplate: function () {
                          return $("<button>").attr("type", "button").text("Add")
                              .on("click", function () {
                                  ViewCertificate.ShowAddCertificateAceModal("Add", {});
                              });
                      }
                  }
              ]
          });
      },
  
      InitializeShowPassword: function ()
      {
          $('#showPasswordButton').click(function () {
              $('#password').empty();
              Services.GetCertificatePassword(ViewCertificate.GetCertificateId(), ViewCertificate.GetCertificatePasswordSuccessCallback, ViewCertificate.GetCertificatePasswordErrorCallback);
          });
      },
  
      InitializeResetPassword: function ()
      {
          $('#resetPasswordButton').click(function () {
              UiGlobal.ResetAlertState();
              Services.ResetCertificatePassword(ViewCertificate.GetCertificateId(), ViewCertificate.ResetCertificatePasswordSuccessCallback, ViewCertificate.ResetCertificatePasswordErrorCallback);
          });
      },
  
      ResetCertificatePasswordSuccessCallback: function ()
      {
          UiGlobal.ShowSuccess("Certificate password was reset successfully");
      },
  
      ResetCertificatePasswordErrorCallback: function ()
      {
          UiGlobal.ShowError("Could not process certificate password reset request");
      },
  
      GetCertificatePasswordSuccessCallback: function (data)
      {
          $('#password').text(data.decryptedPassword);
      },
  
      GetCertificatePasswordErrorCallback: function (x, t, m) {
          $('#password').text("Could not retrieved password, access denied.");
          $('#password').css("color", "red");
      },
  
      AddCertificateAce: function () {
          var data = {
              id: ViewCertificate.GetCertificateId(),
              identity: ViewCertificate.AceIdentitySelect.val(),
              identityType: $('#aceIdentityType').val(),
              aceType: $('#aceType').val()
          };
  
          ViewCertificate.AclTable.jsGrid("insertItem", data);
      },
  
      InitializeNodeSelect: function () {
          
  
          ViewCertificate.NodeSelect.select2({
              placeholder: 'search for a certificate manager user',
              ajax: {
  
                  url: ("/nodes"),
                  dataType: 'json',
                  type: 'get',
                  delay: 30,
                  data: function (params) {
                      return {
                          query: params.term, // search term
                          page: params.page
                      };
                  },
                  processResults: function (data, params) {
                      params.page = params.page || 1;
  
                      return {
                          results: data.payload,
                      };
                  },
                  cache: true
              },
              escapeMarkup: function (markup) { return markup; }, // let our custom formatter work
              minimumInputLength: 2,
              templateResult: ViewCertificate.NodeSelectFormatRepo, // omitted for brevity, see the source of this page
              templateSelection: ViewCertificate.NodeSelectFormatRepoSelection // omitted for brevity, see the source of this page
          });
      },
  
      NodeSelectFormatRepo: function (repo) {
          return repo.hostname;
      },
  
      NodeSelectFormatRepoSelection: function (repo) {
          return repo.hostname;
      },
  
      DeployToNode: function () {
  
          var uri = '/node/' + ViewCertificate.NodeSelect.val() + '/deploy/' + ViewCertificate.GetCertificateId();
  
          Services.Post(uri, null, ViewCertificate.DeployCertSuccessCallback, null);
  
      },
  
      DeployCertSuccessCallback: function (payload) {
          UiGlobal.ShowSuccess('Certificate successfully deployed to node');
      }
  }