Odyssey
admUserMaint.prg
1 <?php
2 
3 /**
4  * @package AdmUsrMaint.prg.v2 -- Contains all the code to save users through the administration screen and through security screens.
5  * This replaces AdmUsrMaint.prg, AdmSecure.prg, AdmSetCfg.prg, AdmSettings.prg, AdmUsrRpt.prg, pwdRules.html
6  */
7 
8 // For GetAuditTime().
9 require_once("$admLibrary/aAudit.i");
10 
11 $self = "$menu_link?ft=$ft";
12 $operation = trim($operation);
13 
14 $string = array("filter" => HCUFILTER_INPUT_STRING);
15 $parameters = array("a" => array("cu" => "", "username" => "", "forceChange" => "", "tab" => "", "password" => "", "message" => "", "status" => "", "usernames" => "", "isSkip" => ""));
16 HCU_ImportVars($parameters, "a", array("cu" => $string, "username" => $string, "forceChange" => $string, "tab" => $string, "password" => $string, "message" => $string, "status" => $string,
17  "usernames" => $string, "authval" => $string, "isSkip" => $string, "page" => $string));
18 extract($parameters["a"]);
19 
20 $cu = isset($cu) ? trim($cu) : "";
21 $username = isset($username) ? trim($username) : "";
22 $forceChange = isset($forceChange) ? trim($forceChange) : "";
23 $tab = isset($tab) ? trim($tab) : "";
24 $password = isset($password) ? trim($password) : "";
25 $message = isset($message) ? trim($message) : "";
26 $status = isset($status) ? trim($status) : "";
27 $usernames = isset($usernames) ? trim($usernames) : "";
28 $authval = isset($authval) ? trim($authval) : "";
29 $isSkip = isset($isSkip) ? trim($isSkip) == "Y" : false;
30 $page = isset($page) ? trim($page) : "";
31 
32 if ($operation != "") {
33  try {
34  switch($operation) {
35  case "deleteUsers":
36  $returnArray = DeleteUsers($dbh, $Cu, $Cn, $usernames);
37  break;
38  case "readUsers":
39  $returnArray = ReadUsers($dbh, $Cu);
40  break;
41  case "readUser":
42  $returnArray = ReadUserNotSecurity($dbh, $Cu, $username, $tab, $SYSENV["logger"]);
43  break;
44  case "readReport":
45  $returnArray = ReadReport($dbh, $Cu);
46  break;
47  case "saveUser":
48  $returnArray = SaveUserNotSecurity($SYSENV, $dbh, $Cu, $Cn, $ft);
49  break;
50  default: $returnArray = array("error" => array("Operation not recognized: $operation."), "record" => array());
51  break;
52  }
53  } catch(exception $e) {
54  $returnArray = array("error" => array($e->getMessage()));
55  }
56 
57  header('Content-type: application/json');
58  print HCU_JsonEncode($returnArray);
59 } else {
60  try {
61  switch($page) {
62  case "report":
63  PrintReport($self, $dbh, $Cu, $authval);
64  break;
65  case "edit":
66  $results = GetAccessToUserMFA($dbh, $Cu, $Cn, $username);
67  extract($results);
68  PrintEditPage($self, $authval, $username, $tab, $accessToMFA, $isMaster, $usersAlign, $Cu, $remoteAccessEnabled);
69  break;
70  default:
71  PrintMainPage($self, $authval, $status, $username);
72  break;
73  }
74  } catch(exception $e) {
75  print $e->getMessage();
76  }
77 }
78 
79 /**
80  * function ReadReport ($dbh, $Cu)
81  * Gets the data for the report
82  *
83  * @param $dbh -- the database connection
84  * @param string $Cu -- the credit union
85  * @return array--
86  * $status -- "000" if successful, otherwise non-zero
87  * $error -- the error message encountered (if there is such a thing)
88  * $programs -- list of programs with descriptions
89  * $userData -- list of what programs each user has
90  */
91 function ReadReport ($dbh, $Cu) {
92  $programs = array();
93  $userData = array();
94 
95  try {
96  $sql = "select program, displaytext, description, sort_order as sort from cuadminprogs order by sort_order";
97  $sth = db_query($sql, $dbh);
98  if (!$sth) {
99  throw new exception("cuadminprogs query failed.", 1);
100  }
101  for($i = 0; $row = db_fetch_assoc($sth, $i); $i++) {
102  $program = trim($row["program"]);
103  $programText = trim($row["displaytext"]);
104  $sort = HCU_array_key_exists("sort_order", $row) ? intval($row["sort_order"]) : 0;
105  $description = HCU_array_key_exists("description", $row) ? trim($row["description"]) : "";
106 
107  $programs[$program] = array("program" => $program, "programText" => $programText, "description" => $description, "sort" => $sort);
108  }
109 
110  $sql = "select u.user_name as username, realname, coalesce(u.userflags, 0) & 4 as hasmasterprivs, a.program from cuadminusers u
111  left join cuadminallow a on u.cu = a.cu and lower(trim(u.user_name)) = lower(trim(a.user_name)) where u.cu= '$Cu'";
112  $sth = db_query($sql, $dbh);
113  if (!$sth) {
114  throw new exception("cuadminusers query failed.", 2);
115  }
116 
117  for($i = 0; $row = db_fetch_assoc($sth, $i); $i++) {
118  $program = HCU_array_key_exists("program", $row) ? trim($row["program"]) : "";
119  $realname = HCU_array_key_exists("realname", $row) ? trim($row["realname"]) : "";
120  $username = HCU_array_key_exists("username", $row) ? trim($row["username"]) : "";
121 
122  if (!isset($userData[$username])) {
123  $userData[$username] = array("username" => $username, "realname" => $realname,
124  "hasmasterprivs" => intval($row["hasmasterprivs"]) != 0 ? "Y" : "N", "programs" => array());
125  }
126  if ($program != "") {
127  $programRow = HCU_array_key_exists($program, $programs) ? $programs[$program] : null;
128  $valid = isset($programRow);
129  $text = $valid ? (HCU_array_key_exists("programText", $programRow) ? $programRow["programText"] : "") : $program;
130  $value = $valid ? (HCU_array_key_exists("program", $programRow) ? $programRow["program"] : "") : $program;
131  $sort = $valid ? (HCU_array_key_exists("sort", $programRow) ? $programRow["sort"] : "") : 0;
132 
133  $userData[$username]["programs"][]= array("text" => $text, "value" => $value, "sort" => $sort, "valid" => $valid);
134  }
135  }
136 
137  $returnArray = array("status" => "000", "error" => "", "programs" => array_values($programs), "userData" => array_values($userData));
138  } catch (exception $e) {
139  $returnArray = array("status" => $e->getCode(), "error" => $e->getMessage());
140  }
141  return $returnArray;
142 }
143 
144 /**
145  * function ReadNew($dbh, $cuCode, $getPrograms = false, $getProviders = false)
146  * Data needed to edit an user minus the user record
147  *
148  * @param integer $dbh -- the database connection
149  * @param string $cuCode -- the credit union
150  * @param boolean $getPrograms -- whether to get the admin programs or not
151  * @param boolean $getProviders -- whether to get the cell phone providers or not
152  *
153  * @return array $returnArray --
154  * array $sql -- List of the sqls used
155  * integer $code -- 0 if no errors, nonzero otherwise
156  * array $error -- array() if no errors, or the first error
157  * array $record -- the CU record
158  * array $privilege -- unused
159  */
160 function ReadNew($dbh, $cuCode, $getPrograms = false) {
161  $records = array();
162  $privilegeRecords = array();
163 
164  try {
165  $sql = "select coalesce(a.retrylimit,5) as retry, coalesce(a.gracelimit,5) as grace, trim(a.pwdconfig) as pwdconfig, a.ip_acl from cuadmin a where a.cu = '$cuCode' limit 1";
166  $sth = db_query($sql, $dbh);
167  if (!$sth) {
168  throw new exception("Read query failed.", 1);
169  }
170  for($i = 0; $array = db_fetch_assoc($sth, $i); $i++) {
171  $pwdconfig = HCU_JsonDecode($array["pwdconfig"]);
172  if (!is_array($pwdconfig)) {
173  throw new exception("Password array is malformed.", 4);
174  }
175  $array["pwdconfig"] = $pwdconfig;
176  $records[] = $array;
177  }
178 
179  if ($getPrograms) {
180  $sql = "select ap.program, ap.displaytext, ap.description from cuadminprogs ap order by ap.sort_order, ap.program";
181  $sth = db_query($sql, $dbh);
182  if (!$sth) {
183  throw new exception("Program query failed.", 2);
184  }
185  $pwdconfig = null;
186  for($i = 0; $array = db_fetch_assoc($sth, $i); $i++) {
187  $array = array("program" => trim($array["program"]), "displaytext" => trim($array["displaytext"]), "description" => trim($array["description"]),
188  "checked" => false, "prevChecked" => false);
189  $privilegeRecords[] = $array;
190  }
191  }
192 
193  $sql = "select user_name from cuadminusers where cu = '$cuCode'";
194  $sth = db_query($sql, $dbh);
195  if (!$sth) {
196  throw new exception("user name query failed.", 5);
197  }
198  $usernamesUsed = array();
199  for($i = 0; $array = db_fetch_row($sth, $i); $i++) {
200  $usernamesUsed[] = trim($array[0]);
201  }
202 
203  $returnArray = array("status" => "000", "error" => "", "record" => $records, "privilege" => $privilegeRecords,
204  "usernamesUsed" => $usernamesUsed);
205 
206  } catch (exception $e) {
207 
208  $returnArray = array("status" => $e->getCode(), "error" => $e->getMessage());
209  }
210  return $returnArray;
211 }
212 
213 /**
214  * function ReadUserNotSecurity($dbh, $cuCode, $username, $tab, $logger)
215  * Read user from admin user admin
216  *
217  * @param integer $dbh -- the database connection
218  * @param string $cuCode -- the credit union code
219  * @param string $username -- the username
220  * @param string $tab -- the particular tab
221  * @param object $logger -- the logger for logging logs
222  *
223  * @return readUser contents
224  */
225 function ReadUserNotSecurity($dbh, $cuCode, $username, $tab, $logger) {
226  if (trim($username) == "") {
227  return ReadNew($dbh, $cuCode);
228  }
229 
230  switch($tab) {
231  case "summary":
232  return ReadUser($dbh, $cuCode, $username, false, false, false, false, $logger);
233  case "events":
234  return ReadUser($dbh, $cuCode, $username, false, false, false, true, $logger);
235  case "settings":
236  case "remote":
237  return ReadUser($dbh, $cuCode, $username, false, true, true, false, $logger);
238  case "permissions":
239  return ReadUser($dbh, $cuCode, $username, true, false, false, false, $logger);
240  }
241 }
242 
243 /**
244  * function GetAccessToUserMFA($dbh, $Cu, $Cn, $username)
245  * Checks if the logged in user has access to the MFA's.
246  *
247  * @param $dbh -- the database connection
248  * @param string $Cu -- the credit union
249  * @param string $Cn -- the logged in user
250  * @param string $username -- the username of the viewed MFA
251  * @return true/false depending on if the user has access or not.
252  */
253 function GetAccessToUserMFA($dbh, $Cu, $Cn, $username) {
254  $accessToMFA = false;
255  $isMaster = false;
256  $usersAlign = false;
257  $remoteAccessEnabled = false;
258  try {
259  $usersAlign = trim($Cn) == trim($username);
260 
261  $sql = "select user_name, ip_acl, (select 'FOUND' from cuadminallow a where a.user_name = '$Cn' and a.cu = '$Cu' and a.program = 'userMFA') as mfa from cuadmin where cu = '$Cu'";
262  $sth = db_query($sql, $dbh);
263  if (!$sth) {
264  throw new exception("cuadmin query failed.", 1);
265  }
266  $row = db_fetch_assoc($sth, 0);
267  $isMaster = trim($row["user_name"]) == trim($username);
268  $remoteAccessEnabled = isset($row["ip_acl"]) && trim($row["ip_acl"]) != "";
269  $accessToMFA = trim($row["user_name"]) == trim($Cn) || (isset($row["mfa"]) && trim($row["mfa"]) == "FOUND");
270 
271  $returnArray = array("accessToMFA" => $accessToMFA, "isMaster" => $isMaster, "usersAlign" => $usersAlign, "remoteAccessEnabled" => $remoteAccessEnabled);
272  } catch(exception $e){
273  $returnArray = array("accessToMFA" => false, "isMaster" => false, "usersAlign" => false, "remoteAccessEnabled" => false);
274  }
275 
276  return $returnArray;
277 }
278 
279 /**
280  * function GetAuditRecords($dbh, $cuCode, $username, $logger)
281  * Gets the audit records
282  *
283  * @param $dbh -- the database connection
284  * @param string $cuCode -- the credit union
285  * @param string $username -- the username
286  * @param object $logger -- for logging unparseable audit entries
287  * @return [date:"", actioncode:"", user:"", script:"", action:"", rown:0, details: [{table:"", label:"", type:"",
288  * rows: [{type: "", values: [{col: "", before: "", after: "", label: "", same: false}, ...]}, ...]}, ... ]]
289  * Type can be "mixed", "add", "delete", or "update" at the table level. It cannot be "mixed" at the column level.
290  */
291 function GetAuditRecords($dbh, $cuCode, $username, $logger) {
292  $sql = "select auditdate as date, auditaction as actioncode, auditsrcuser_name as user, auditrecbefore as before, auditrecafter as after, auditsrccode_context as script,
293  auditfulldesc as action, row_number() over (order by auditdate desc) as rown from cuauditadmin where lower(user_name) = '" . strtolower(prep_save($username, 50))
294  . "' and cu = '$cuCode'";
295  $sth = db_query($sql, $dbh);
296  if (!$sth) {
297  throw new exception("Audit query failed.", 12);
298  }
299  $auditRecords = array();
300  for($i = 0; $row = db_fetch_assoc($sth, $i); $i++) {
301  $results = ParseAuditRow($row, $cuCode, $dbh);
302  if ($results["status"] !== "000") { // Audit row is invalid in the database. DO NOT KILL THE PAGE. Instead DO NOT DISPLAY and log error in Kibana.
303  $logger->error("Admin audit is invalid in the database. CU: $cuCode, Audit Date: " . $row["date"]);
304  continue;
305  } else {
306  $row = $results["row"];
307  }
308  // #820 added and commented out reference. This is more a stage 3 new feature.
309  //addDetailedDescription($row);
310 
311  // Do date stuff
312  $tz = GetCreditUnionTimezone($dbh, $cuCode);
313  $dateTime = new DateTime($row["date"]);
314  $dateTime->setTimezone(new DateTimeZone($tz));
315  $row["date"] = $dateTime->format("Y-m-d H:i:s.u") . "Z";
316 
317  $auditRecords[] = $row;
318  }
319  return $auditRecords;
320 }
321 
322 /**
323  * function ReadUsers($dbh, $cuCode)
324  * Get all available users for the particular CU
325  *
326  * @param integer $dbh -- the database connection
327  * @param string $cuCode -- the credit union
328  *
329  * @return array--
330  * integer $status -- 000 if successful; nonzero otherwise
331  * array $error -- nonempty if error(s)
332  * array $record -- list of user records
333  */
334 function ReadUsers($dbh, $cuCode) {
335  $records = array();
336 
337  try {
338  $sql = "select au.user_name as username, au.realname, au.email, au.user_name = a.user_name as ismaster from cuadminusers au inner join cuadmin a on au.cu = a.cu where au.cu = '$cuCode'";
339  $sth = db_query($sql, $dbh);
340  if (!$sth) {
341  throw new exception("Read query failed.", 1);
342  }
343  for($i = 0; $array = db_fetch_assoc($sth, $i); $i++) {
344  $array["ismaster"] = trim($array["ismaster"]) == "t";
345  $array['checked'] = false;
346  $records[] = $array;
347  }
348 
349  $returnArray = array("status" => "000", "error" => "", "record" => $records);
350  } catch(exception $e) {
351  $returnArray = array("status" => $e->getCode(), "error" => array($e->getMessage()));
352  }
353  return $returnArray;
354 }
355 
356 /**
357  * function DeleteUsers($dbh, $cuCode, $loggedInUser, $usernames)
358  * Deletes an user
359  *
360  * @param integer $dbh -- the database connection
361  * @param string $cuCode -- the credit union code
362  * @param string $loggedInUser -- the logged in user
363  * @param array $usernames -- the usernames to delete
364  *
365  * @return array --
366  * integer $code -- nonzero if error(s)
367  * array $error -- nonempty if error(s)
368  */
369 function DeleteUsers($dbh, $cuCode, $loggedInUser, $usernames) {
370  $pUpdTable = array();
371 
372  try {
373  if ($usernames == "") {
374  throw new exception ("No users found.", 3);
375  }
376  $usernames = HCU_JsonDecode($usernames);
377  if (!is_array($usernames)) {
378  throw new exception ("Users not decoded correctly.", 4);
379  }
380  if (count($usernames) == 0) {
381  throw new exception("No users found.", 5);
382  }
383 
384  $sql = "select user_name from cuadmin where cu = '$cuCode'";
385  $sth = db_query($sql, $dbh);
386  if (!$sth) {
387  throw new exception("cuadmin query failed.", 6);
388  }
389  if (db_num_rows($sth) == 0) {
390  throw new exception("cuadmin query has no records.", 7);
391  }
392  $thyMaster = trim(db_fetch_row($sth, 0)[0]);
393 
394  foreach($usernames as $username) {
395  if ($thyMaster == trim($username)) {
396  // There should be no reason to throw an exception, users can't - or
397  // shouldn't be able to - select master from the front end. There
398  // should never be a match on this condition, but leaving it in,
399  // the continue guards against master deletion.
400  // throw new exception("cannot delete the master record.", 8);
401  continue;
402  }
403  $pUpdTable[] = array("_action" => "delete", "cu" => $cuCode, "user_name" => $username);
404  }
405  $pUpdTable = array("cuadminusers" => $pUpdTable);
406 
407  $sql = "select email from cuadminusers where user_name = '$loggedInUser' and cu = '$cuCode'";
408  $sth = db_query($sql, $dbh);
409  if (!$sth) {
410  throw new exception("Email query failed.", 2);
411  }
412  $email = db_fetch_row($sth)[0];
413 
414  if (DataAdminTableUpdate($dbh, array("cu" => $cuCode), $pUpdTable, $username, "USER_D", "AdmUserMaint.prg", "A", "User(s) Deleted", $loggedInUser, $email,
415  trim($_SERVER["REMOTE_ADDR"])) === false) {
416  throw new exception("Update failed.", 1);
417  }
418 
419  $returnArray = array("status" => "000", "error" => "");
420  } catch(exception $e) {
421  $returnArray = array("code" => $e->getCode(), "error" => array($e->getMessage()));
422  }
423  return $returnArray;
424 }
425 
426 /**
427  * function SaveUserNotSecurity($pSysEnv, $dbh, $Cu, $Cn, $ft)
428  * Saves an user from the admin user admin
429  *
430  * @param array $pSysEnv -- The System Environment variable from main
431  * with the settings for this environment (production/development)
432  * @param integer $dbh -- the database connection
433  * @param string $Cu -- the credit union
434  * @param string $Cn -- the logged in user
435  * @param number $ft -- the number of the script
436  *
437  * @return saveUser contents
438  */
439 function SaveUserNotSecurity($pSysEnv, $dbh, $Cu, $Cn, $ft) {
440  $string = array("filter" => HCUFILTER_INPUT_STRING);
441  $parameters = array("a" => array("isAdd" => "", "forceSecurity" => "", "forcePassword" => "", "lockAccount" => "", "masterIpAddress" => "", "password" => "", "remoteAccessSet" => "",
442  "forceChangesAmount" => "", "username" => "", "emailAddress" => "", "addPermissions" => "", "removePermissions" => "", "realName" => "", "masterPrivileges" => "",
443  "remoteAccess" => "", "ipAddress" => "", "smsNumber" => "", "confidence" => "", "questIds" => "", "questResponses" => "", "tab" => ""));
444 
445  HCU_ImportVars($parameters, "a", array("isAdd" => $string, "forceSecurity" => $string, "forcePassword" => $string, "lockAccount" => $string, "masterIpAddress" => $string,
446  "password" => $string, "forceChangesAmount" => $string, "username" => $string, "emailAddress" => $string, "addPermissions" => $string, "removePermissions" => $string,
447  "realName" => $string, "masterPrivileges" => $string, "remoteAccess" => $string, "ipAddress" => $string, "smsNumber" => $string,
448  "confidence" => $string, "questIds" => $string, "questResponses" => $string, "tab" => $string, "remoteAccessSet" => $string));
449 
450  return SaveUser($pSysEnv, $dbh, $Cu, $parameters["a"], $Cn, $parameters["a"]["tab"] == "security" ? "noneWithConfidence" : "none");
451 }
452 
453 /**
454  * function PrintMainPage($self, $authval, $status, $username)
455  * Prints out the main page to the admin user admin
456  *
457  * @param string $self -- url that points to this script
458  * @param string $authval -- needs to be passed along to verify that there is access to this script
459  * @param string $status -- the status to print
460  * @param string $username -- the username
461  */
462 function PrintMainPage($self, $authval, $status, $username) {
463  switch($status) {
464  case "saved":
465  $status = "$username was saved successfully.";
466  break;
467  case "deleted":
468  $status = "$username was deleted successfully.";
469  break;
470  case "added":
471  $status = "$username was added successfully.";
472  break;
473  default:
474  $status = "";
475  break;
476  }
477  ?>
478  <script type="text/javascript">
479  <?php // Library javascript functions
480  getShowWaitFunctions(); ?>
481 
482  function Init() {
483  var userGrid = $("#userGrid").kendoGrid({
484  dataSource: {
485  transport: {
486  read: {
487  url: "<?php echo $self; ?>&operation=readUsers",
488  dataType: "json",
489  type: "POST"
490  },
491  parameterMap: function(data, type) {
492  showWaitWindow();
493  return {authval: "<?php echo $authval; ?>"};
494  }
495  },
496  schema: {
497  model: {
498  id: "username",
499  fields: {
500  username: {type: "string"},
501  realname: {type: "string"},
502  email: {type: "string"},
503  ismaster: {type: "boolean"},
504  checked: {type: "boolean", defaultValue: false}
505  }
506  },
507  parse: function (data) {
508  hideWaitWindow();
509  if (data.error.length > 0) {
510  $.homecuValidator.displayMessage(data.error, $.homecuValidator.settings.statusError );
511  }
512 
513  return data.record;
514  }
515  },
516  sort: {field: "username", dir: "asc"}
517  },
518  sortable: true,
519  filterable: {
520  extra: false
521  },
522  columns: [
523  {field: "checked", headerTemplate: "<input type='checkbox' class='allCheckbox'>", width: "45px", sortable: false, filterable: false},
524  {field: "username", title: "Name"},
525  {field: "realname", title: "Real Name"},
526  {field: "email", title: "Email"}
527  ],
528  rowTemplate: "<tr data-uid='#: uid #'><td class='checkboxTD'># if (!ismaster) { #\
529  <input type='checkbox' class='rowCheckbox' value='#: username #'>\
530  # } #\
531  <td><a href='\\#' class='editBtn'>#: username #</a></td><td>#: realname #</td><td>#: email #</td></tr>",
532  scrollable: false
533  }).data("kendoGrid");
534 
535  $("#permissionReportBtn").click(function() {
536  $("#redirectForm [name='page']").val("report");
537  $("#redirectForm").submit();
538  return false;
539  })
540  $("#userGrid").on("click", ".editBtn", function() {
541  var userName = userGrid.dataItem($(this).closest("tr")).username;
542  $("#redirectForm").append("<input type='hidden' name='username' value='" + userName + "'>");
543  $("#redirectForm").submit();
544  return false;
545  });
546 
547  $("#userAddBtn").click(function() {
548  $("#redirectForm").submit();
549  return false;
550  });
551 
552  <?php printCheckboxEvents("#userGrid", "#userDeleteBtn");
553 
554  /* When the user clicks on the delete button, no action will be taken if the .k-state-disabled class is on the button. This happens when no checkboxes are checked.
555  * Otherwise, a dialog pops up with two options: 1) Yes and 2) No. No just closes the dialog. Yes will send the usernames selected to the backend to delete them.
556  */
557  ?>
558  $("#userDeleteBtn").click(function() {
559  if (!$(this).hasClass("k-state-disabled") && $("#userGrid .rowCheckbox:checked").length > 0) {
560  var deleteDialog = $("#deleteDialog").data("kendoDialog");
561  if (deleteDialog == null) {
562  deleteDialog = $("<div id='deleteDialog'></div>").appendTo("body").kendoDialog({
563  title: "Delete Users",
564  content: "Are you sure that you want to delete the selected users?",
565  actions: [
566  {text: "Yes", primary: true, action: function() {
567 
568  gridData = userGrid.dataSource.data();
569  var usernames = [];
570  <?php
571  /* The common function .allCheckbox.on('click') in printCheckboxEvents() reads the grid
572  * and has no "awareness" of what is in the dom. The master record has no checkbox and
573  * can't be deleted. Its grid property is still "checked = true." To avoid modifying
574  * the common function, here we ensure the checked property is set to false for any
575  * elements not deleted so the grep below will properly re-populate the dom with
576  * undeleted records. In reality this only affects the master user record as any
577  * others will already be "checked = false."
578  */ ?>
579  for(var i = 0; i != gridData.length; i++) {
580  if ((gridData[i].ismaster === false) && (gridData[i].checked === true)) {
581  usernames.push(gridData[i].username);
582  } else {
583  gridData[i].checked = false;
584  }
585  }
586 
587  var parameters = {authval: "<?php echo $authval; ?>", usernames: kendo.stringify(usernames)};
588  showWaitWindow();
589  $.post("<?php echo $self; ?>&operation=deleteUsers", parameters, function(data) {
590  hideWaitWindow();
591  if (data.error.length > 0) {
592  $.homecuValidator.displayMessage( data.error, $.homecuValidator.settings.statusError );
593  } else {
594  gridData = $.grep(gridData, function(n,i) { return !n.checked; });
595  userGrid.dataSource.data(gridData);
596  }
597  });
598  }},
599  {text: "No"}
600  ],
601  visible: false,
602  open: function() {
603  if (window.activeWindows != null) {
604  window.activeWindows.push(this);
605  }
606  },
607  close: function() {
608  if (window.activeWindows != null) {
609  window.activeWindows.pop();
610  }
611  }
612  }).data("kendoDialog");
613  }
614 
615  deleteDialog.open();
616  }
617  });
618  }
619 
620  var activeWindows = [];
621  $(document).ready(function() {
622  Init();
623  <?php printClickOverlayEvent(); ?>
624  });
625  </script>
626  <form id="redirectForm" action="<?php echo $self; ?>" method="post">
627  <input type="hidden" name="page" value="edit">
628  <input type="hidden" name="authval" value="<?php echo $authval; ?>">
629  </form>
630  <div class="container-fluid"><div>
631  <br>
632  <h2>Admin User Maintenance</h2>
633  <?php if ($status != "") { ?>
634  <div class="k-block k-info-colored formValidateDiv"><?php echo $status; ?></div>
635  <?php } ?>
636  <div id="formValidateDiv" class="k-block k-error-colored" style="display:none;"></div>
637  <div class="form-horizontal form-widgets">
638  <?php printButtons(array(array("id" => "userAddBtn", "text" => "Add User"), array("id" => "userDeleteBtn", "text" => "Delete Users", "disabled" => true),
639  array("id" => "permissionReportBtn", "text" => "Permissions", "isLink" => true)));
640  printGridDiv("userGrid"); ?>
641  </div>
642  </div></div>
643 <?php }
644 
645 
646 /**
647  * function PrintValidateSMS()
648  *
649  * This prints out the validation for phone numbers.
650  */
651 function PrintValidateSMS() { ?>
652  validatesms: function(input) {
653  if (!input.is("[name='smsNumber']")) {
654  return true;
655  }
656  if ($(input).val().trim() != "" && !$(input).val().match(/\([0-9]{3}\) [0-9]{3}-[0-9]{4}/)) {
657  $(input).attr("data-validatesms-msg", "Phone number is invalid.");
658  return false;
659  }
660  return true;
661  }
662 <?php }
663 
664 /**
665  * function PrintMatchOriginalPassword()
666  *
667  * This prints out the validation that the password and the original password do not match. The original password doesn't exist on the page.
668  * Checking if the original password is correct is done totally on the server side so there is a case where this fires but the original password isn't correct.
669  */
670 function PrintMatchOriginalPassword() { ?>
671  matchoriginalpassword: function(input) {
672  if (!input.is("[name='password']") || $(input).val().trim() == "") {
673  return true;
674  }
675  if ($(input).val().trim() == $("[name='oldPassword']").val().trim()) {
676  $(input).attr("data-matchoriginalpassword-msg", "Password cannot be original password.");
677  return false;
678  }
679  return true;
680  }
681 <?php }
682 
683 /**
684  * function printWasRead()
685  * This validates that either the suggested password document was opened or the checkbox was clicked.
686  */
687 function printWasRead() { ?>
688  wasread: function(input) {
689  if (!input.is("[name='showHelp']")) {
690  return true;
691  }
692  if (!$(input).prop("checked")) {
693  $(input).attr("data-wasread-msg", "Please review the recommended password guidelines before saving your new password.");
694  return false;
695  }
696  return true;
697  }
698 <?php }
699 
700 /**
701  * function PrintInitRemoteAccess($isMaster)
702  * Prints the logic to initialize the remote access controls.
703  *
704  * @param boolean $isMaster -- if true, then it is the master user.
705  */
706 function PrintInitRemoteAccess($isMaster) { ?>
707  function InitRemoteAccess(record) {
708 
709  $("[name='remoteAccess']").click(function() {
710  $(this).prop("checked") ? $(".remoteAccessDiv").show() : $(".remoteAccessDiv").hide();
711  });
712 
713  var smsNumber = $("[name='notifySMS']").kendoMaskedTextBox({
714  mask: "(000) 000-0000",
715  clearPromptChar: true
716  }).data("kendoMaskedTextBox");
717 
718 
719  $("#deleteAllowedAccess").click(function() {
720  if ($(this).text().trim() == "Delete") {
721  $("#allowedAccess").addClass("deleted");
722  $(this).text("Cancel Delete");
723  } else {
724  $("#allowedAccess").removeClass("deleted");
725  $(this).text("Delete");
726  }
727  return false;
728  });
729 
730  <?php if ($isMaster) { ?>
731  var toolbarTemplate = "<a href='\\#' class='k-grid-del k-button " + (record.cuIps.length == 0 ? "k-state-disabled" : "") + "'>Delete Selected</a>";
732 
733  var cuIps = [];
734  for(var i = 0; i != record.cuIps.length; i++) {
735  cuIps.push({ip: record.cuIps[i], checked: false});
736  }
737 
738  var cuIpGrid = $("#allowedMasterAddressGrid").kendoGrid({
739  dataSource: {
740  data: cuIps,
741  schema: {
742  id: "ip",
743  fields: {
744  ip: {type: "string"},
745  checked: {type: "boolean"}
746  }
747  }
748  },
749  columns: [
750  {headerTemplate: "<input type='checkbox' class='allCheckbox'>", width: "45px"},
751  {field: "ip", headerTemplate: "IP Address"}
752  ],
753  rowTemplate: "<tr data-uid='#: uid #'><td class='checkboxTD'><input type='checkbox' class='rowCheckbox' value='#: checked #'>\
754  <td>#: ip #</td></tr>",
755  toolbar: toolbarTemplate,
756  noRecords: {
757  template: "<tr class='noRecordsDiv'><td colspan='2'>No Records Found</td></tr>"
758  },
759  scrollable: false
760  }).data("kendoGrid");
761 
762  <?php printCheckboxEvents("#allowedMasterAddressGrid", ".k-grid-del"); ?>
763 
764  $("#allowedMasterAddressGrid").on("click", ".k-grid-del", function() {
765  var data = cuIpGrid.dataSource.data();
766  data = $.grep(data, function(n,i) { return !n.checked; });
767  if (data.length == 0) {
768  $("#allowedMasterAddressGrid .allCheckbox").prop("checked", false);
769  }
770  cuIpGrid.dataSource.data(data);
771 
772  if (data.length == 0 && $(".personalRemoteAccessDiv").length > 0) {
773  $(".personalRemoteAccessDiv").hide();
774  }
775  return false;
776  });
777 
778  $("#addCuIpBtn").click(function() {
779  $.homecuValidator.validate();
780  if ($("[name='addCuIpInput']").val().trim() != "" && !$("[name='addCuIpInput']").hasClass("k-invalid")) {
781  cuIpGrid.dataSource.add({ip: $("[name='addCuIpInput']").val(), checked: false});
782  $("[name='addCuIpInput']").val(null);
783 
784  if ($(".personalRemoteAccessDiv").length > 0) {
785  $(".personalRemoteAccessDiv").show();
786  if ($(".personalRemoteAccessDiv [type='checkbox']").is(":checked")) {
787  $(".remoteAccessDiv").show();
788  }
789  }
790 
791  }
792  return false;
793  });
794  <?php } ?>
795  }
796 <?php }
797 
798 
799 /**
800  * function PrintEditPage($self, $authval, $username, $tab, $displayUserMFA, $isMaster, $usersAlign, $Cu, $remoteAccessEnabled)
801  * This prints the edit page
802  *
803  * @param string $self -- the URL of this script
804  * @param string $authval -- needed if you are not the master user and you have master privileges
805  * @param boolean $displayUserMFA -- if true, can see the user MFA questions
806  * @param string $Cu -- the credit union
807  * @param boolean $remoteAccessEnabled -- tells if the remote access is enabled or not
808  */
809 function PrintEditPage($self, $authval, $username, $tab, $displayUserMFA, $isMaster, $usersAlign, $Cu, $remoteAccessEnabled) {
810  $tab = isset($tab) ? trim($tab) : ""; ?>
811 
812  <style>
813  .custom-padding {
814  padding-left: 0;
815  }
816 
817  .local-fifth {
818  width: 20%;
819  }
820 
821  @media (max-width: 991px) {
822  .custom-padding {
823  padding-right: 0;
824  }
825  }
826  </style>
827  <script type="text/javascript">
828  <?php // Library javascript functions
829  getShowWaitFunctions();
830  printJavascriptHashCode(); ?>
831 
832  var challengeData = [];
833  var challengeMap = {};
834  var activeWindows = [];
835  var ismaster = <?php echo $isMaster ? "true" : "false" ?>;
836  var previousParameters = null;
837  var tabs = {};
838  function Init() {
839  <?php printClickOverlayEvent();
840 
841  // here lies the code for each of the tabs: summary, events, permissions, and settings. Each tab has an init, getSaveParameters, destroy, revertChanges, and postChanges functions.
842  ?>
843  tabs = {
844  <?php
845  /* The summary is one of two things: 1) the initial screen for a new user, or 2) the screen that shows a lot of readonly information for the user.
846  * This is the first screen that the system goes to when coming from the main page.
847  */
848  ?>
849  summary: {
850  name: "summary",
851  template: $("#summaryTemplate").html(),
852  init: function(record) {
853  $.homecuValidator.setup({formValidate:'tabForm', formStatusField: 'formValidateDiv', homecuCustomRules: {
854  validaterealname: function(input) {
855  if (!input.is("[name='realName']") && $(input).val().trim() != "") {
856  return true;
857  }
858  var invalidMatches = $(input).val().match(/['"@;]/g);
859  if (invalidMatches != null && invalidMatches.length > 0) {
860  $(input).attr("data-validaterealname-msg", "Real Name has invalid characters.");
861  return false;
862  }
863  return true;
864  },
865  validateusername: function(input) {
866  if (!input.is("[name='username']") && $(input).val().trim() != "") {
867  return true;
868  }
869 
870  var uname = input.val();
871  uname = uname.trim();
872 
873  var invalidMatches= uname.match(/['";+]/g);
874  if (invalidMatches != null && invalidMatches.length > 0) {
875  $(input).attr("data-validateusername-msg", "Username has invalid characters.");
876  return false;
877  }
878 
879  if (/\s/g.test(uname)) {
880  $(input).attr("data-validateusername-msg", "Username cannot contain spaces.");
881  return false;
882  }
883  return true;
884  },
885  uniqueusername: function(input) {
886  if (!input.is("[name='username']")) {
887  return true;
888  }
889  if ($(input).data("used").indexOf($(input).val().trim()) != -1) {
890  $(input).attr("data-uniqueusername-msg", "Username needs to be unique.");
891  return false;
892  }
893  return true;
894  },
895  <?php if ($username == "") { printValidatePassword(); ?>, <?php printMatchPasswords(); } ?>
896  }});
897 
898  $("[name='username']").data("used", record.usernamesUsed);
899 
900  <?php if ($username == "") { ?>
901  $.homecuValidator.passwordRules = record.pwdconfig;
902 
903  var pwdRequirements = [];
904 
905  var datarp = $.homecuValidator.passwordRules;
906  <?php // set up the messages regarding what is being checked ?>
907  var len = Number(datarp.len);
908  var upper = Number(datarp.upper);
909  var lower = Number(datarp.lower);
910  var letter = Number(datarp.letter);
911  var spec = Number(datarp.spec);
912  var digit = Number(datarp.digit);
913 
914  if (len > 0) {
915  var text = len + " Character" + (len > 1 ? "s" : "");
916  pwdRequirements.push({which: "len", text: text});
917  }
918 
919  if (upper > 0) {
920  var text = upper + " UPPER case letter" + (upper > 1 ? "s" : "");
921  pwdRequirements.push({which: "upper", text: text});
922  }
923  if (lower > 0) {
924  var text = lower + " lower case letter" + (lower > 1 ? "s" : "");
925  pwdRequirements.push({which: "lower", text: text});
926  }
927  if (letter > 0) {
928  var text = letter + " Letter" + (letter > 1 ? "s" : "");
929  pwdRequirements.push({which: "letter", text: text});
930  }
931  if (spec > 0) {
932  var text = spec + " Special character" + (spec > 1 ? "s" : "");
933  pwdRequirements.push({which: "spec", text: text});
934  }
935  if (digit > 0) {
936  var text = digit + " Number" + (digit > 1 ? "s" : "");
937  pwdRequirements.push({which: "digit", text: text});
938  }
939 
940  var template = kendo.template($("#passwordRequirementTemplate").html());
941 
942  $(".passwordReqInsertion").html(template({pwdRequirements: pwdRequirements}));
943 
944  <?php // To mimic hcuProfileRequire, I need to validate on keyup to check the password requirements. ?>
945  $("[name='password']").keyup(function() {
946  $.homecuValidator.homecuKendoValidator.validateInput($(this));
947  });
948  <?php } ?>
949  },
950  getSaveParameters: function() {
951  var parameters= {emailAddress: $("[name='emailAddress']").val()};
952  if ($("[name='realName']").length > 0)
953  parameters.realName = $("[name='realName']").val();
954  <?php if ($username == "") { ?>
955  parameters.username = $("[name='username']").val();
956  parameters.password = $("[name='password']").val();
957  <?php } else { ?>
958  parameters.username = "<?php echo $username; ?>";
959  <?php } ?>
960  return parameters;
961  },
962  destroy: function() {},
963  revertChanges: function() {
964  $("[name='emailAddress']").val(previousParameters.emailAddress);
965  if ($("[name='realName']").length > 0)
966  $("[name='realName']").val(previousParameters.realName);
967  <?php if ($username == "") { ?>
968  $("[name='username']").val(previousParameters.username);
969  $("[name='password']").val(previousParameters.password);
970  <?php } ?>
971  },
972  postChanges: function() {
973  $(".userHeader .realname").html($("[name='realName']").val());
974  }
975  },
976  <?php /* This is the second tab that shows all the settings for the user: remote, password, and whatnot. It also shows a MFA sections for those so privileged. */ ?>
977  settings: {
978  name: "settings",
979  template: $("#settingsTemplate").html(),
980  init: function(record) {
981  $("#securityForm input[type='password']").val(null);
982  $.homecuValidator.setup({formValidate:'tabForm', formStatusField: 'formValidateDiv', homecuCustomRules: {
983  <?php printCheckip(); ?>,
984  <?php printValidatePassword(); ?>,
985  <?php printMatchPasswords(); ?>,
986  <?php printValidateSMS(); ?>
987  }});
988 
989  $.homecuValidator.passwordRules= record.pwdconfig;
990  var forceChanges = $("#forcePasswordChangeNTB").kendoNumericTextBox({
991  decimals: 0,
992  min: 1,
993  format: "n0",
994  max: 99,
995  spinners: false
996  }).data("kendoNumericTextBox");
997 
998  forceChanges.enable($("[name='forcePassword']").prop("checked"));
999 
1000  $("[name='forcePassword']").click(function() {
1001  var isChecked = $(this).prop("checked");
1002  $("[name='forceChangesNTB']").prop("required", isChecked);
1003 
1004  if (isChecked) {
1005  <?php // Business rules: If "Force Password Change" is unchecked, when it is marked checked, the retry box should reset to the default for the credit union. ?>
1006  forceChanges.value(record.grace);
1007  }
1008  forceChanges.enable(isChecked);
1009  });
1010 
1011  <?php if ($displayUserMFA) { ?>
1012  $("#userMFAShowBtn").click(function() {
1013  if ($(this).text().trim() == "Show") {
1014  $(this).text("Hide");
1015  $(".userMFASection").show();
1016  } else {
1017  $(this).text("Show");
1018  $(".userMFASection").hide();
1019  }
1020  });
1021  <?php } ?>
1022 
1023  $(".lockAccount a").click(function() {
1024  var lockAccount = $(".lockAccount");
1025  if ($(lockAccount).hasClass("currentLocked")) {
1026  $(lockAccount).removeClass("currentLocked").addClass("currentUnlocked");
1027  <?php // Business rules: If the admin user is locked out due to forceremain is at zero, when the account is unlocked
1028  // the retry box should be reset to the default for the credit union. ?>
1029  if (forceChanges.value() == null) {
1030  forceChanges.value(record.grace);
1031  }
1032  } else {
1033  $(lockAccount).removeClass("currentUnlocked").addClass("currentLocked");
1034  }
1035  return false;
1036  });
1037 
1038  var pwdRequirements = [];
1039 
1040  var datarp = $.homecuValidator.passwordRules;
1041  <?php // set up the messages regarding what is being checked ?>
1042  var len = Number(datarp.len);
1043  var upper = Number(datarp.upper);
1044  var lower = Number(datarp.lower);
1045  var letter = Number(datarp.letter);
1046  var spec = Number(datarp.spec);
1047  var digit = Number(datarp.digit);
1048 
1049  if (len > 0) {
1050  var text = len + " Character" + (len > 1 ? "s" : "");
1051  pwdRequirements.push({which: "len", text: text});
1052  }
1053 
1054  if (upper > 0) {
1055  var text = upper + " UPPER case letter" + (upper > 1 ? "s" : "");
1056  pwdRequirements.push({which: "upper", text: text});
1057  }
1058  if (lower > 0) {
1059  var text = lower + " lower case letter" + (lower > 1 ? "s" : "");
1060  pwdRequirements.push({which: "lower", text: text});
1061  }
1062  if (letter > 0) {
1063  var text = letter + " Letter" + (letter > 1 ? "s" : "");
1064  pwdRequirements.push({which: "letter", text: text});
1065  }
1066  if (spec > 0) {
1067  var text = spec + " Special character" + (spec > 1 ? "s" : "");
1068  pwdRequirements.push({which: "spec", text: text});
1069  }
1070  if (digit > 0) {
1071  var text = digit + " Number" + (digit > 1 ? "s" : "");
1072  pwdRequirements.push({which: "digit", text: text});
1073  }
1074 
1075  var template = kendo.template($("#passwordRequirementTemplate").html());
1076 
1077  $(".passwordReqInsertion").html(template({pwdRequirements: pwdRequirements}));
1078 
1079  <?php // To mimic hcuProfileRequire, I need to validate on keyup to check the password requirements. ?>
1080  $("[name='password']").keyup(function() {
1081  $.homecuValidator.homecuKendoValidator.validateInput($(this));
1082  });
1083  },
1084  getSaveParameters: function(doStringify, alwaysGetValue) {
1085  var parameters = {};
1086 
1087  var lockAccount = $(".lockAccount").hasClass("currentLocked") ?
1088  ($(".lockAccount").hasClass("originalLocked") ? null : "Y") :
1089  ($(".lockAccount").hasClass("originalUnlocked") ? null : "N");
1090 
1091  if ($("[name='password']").val().trim() != "") {
1092  parameters.password = $("[name='password']").val();
1093  }
1094 
1095  var forceSecurity = $("[name='forceSecurity']").prop("checked") ? "Y" : "N";
1096  var forcePassword = $("[name='forcePassword']").prop("checked") ? "Y" : "N";
1097  var forceChangesAmount = $("[name='forceChangesNTB']").val();
1098  var masterPrivileges = $("[name='masterPrivileges']").prop("checked") ? "Y" : "N";
1099 
1100 
1101  if (alwaysGetValue || lockAccount != previousParameters.lockAccount) {
1102  parameters.lockAccount = lockAccount;
1103  }
1104  if (alwaysGetValue || forceSecurity != previousParameters.forceSecurity) {
1105  parameters.forceSecurity = forceSecurity;
1106  }
1107  if (alwaysGetValue || forcePassword != previousParameters.forcePassword) {
1108  parameters.forcePassword = forcePassword;
1109  }
1110  if (alwaysGetValue || forceChangesAmount != previousParameters.forceChangesAmount) {
1111  parameters.forceChangesAmount = forceChangesAmount;
1112  }
1113  if (alwaysGetValue || masterPrivileges != previousParameters.masterPrivileges) {
1114  parameters.masterPrivileges = masterPrivileges;
1115  }
1116 
1117  return parameters;
1118  },
1119  destroy: function() {
1120  $("#forcePasswordChangeNTB").data("kendoNumericTextBox").destroy();
1121  },
1122  revertChanges: function() {
1123  $("[name='forceSecurity']").prop("checked", previousParameters.forceSecurity == "Y");
1124  $("[name='forcePassword']").prop("checked", previousParameters.forcePassword == "Y");
1125  $("[name='password']").val(previousParameters.password);
1126  $("[name='confirm']").val(null);
1127  $("[name='masterPrivileges']").prop("checked", previousParameters.masterPrivileges == "Y");
1128  var lockAccountListView = $("#lockAccount").data("kendoListView");
1129  lockAccountListView.select($("#lockAccount .default"));
1130  lockAccountListView.value = null;
1131  $("#forcePasswordChangeNTB").data("kendoNumericTextBox").value(previousParameters.forceChangesAmount);
1132 
1133  <?php PrintRestorePreviousChallenge(true); ?>
1134  },
1135  postChanges: function() {
1136  if ($("#allowedAccess.deleted").length > 0) {
1137  $("#allowedAccess.deleted").remove();
1138  }
1139 
1140  if ($(".lockAccount").hasClass("originalUnlocked") && $(".lockAccount").hasClass("currentLocked")) {
1141  $(".lockAccount").removeClass("originalUnlocked").addClass("originalLocked");
1142  } else if ($(".lockAccount").hasClass("originalLocked") && $(".lockAccount").hasClass("currentUnlocked")) {
1143  $(".lockAccount").removeClass("originalLocked").addClass("originalUnlocked");
1144  }
1145 
1146  var unvalued = ($("#forcePasswordChangeNTB").val()+"").trim();
1147  $("#forcePasswordChangeNTB").data("previous", unvalued);
1148  }
1149  },
1150  <?php if ($isMaster || $remoteAccessEnabled) { ?>
1151  remote: {
1152  name: "remote",
1153  template: $("#remoteTemplate").html(),
1154  init: function(record) {
1155  $.homecuValidator.setup({formValidate:'tabForm', formStatusField: 'formValidateDiv'});
1156  InitRemoteAccess(record);
1157  },
1158  getSaveParameters: function(doStringify, alwaysGetValue) {
1159 
1160  var parameters = {};
1161  if ($("[name='remoteAccess']").length > 0) {
1162 
1163  var smsNumber = $("[name='notifySMS']").data("kendoMaskedTextBox").raw();
1164  var remoteAccess = $("[name='remoteAccess']").prop("checked") ? "Y" : "N";
1165  if ($("#allowedAccess").hasClass("deleted")) {
1166  parameters.ipAddress = "NONE";
1167  }
1168 
1169  if (alwaysGetValue || smsNumber != previousParameters.smsNumber ) {
1170  <?php // SMS and phone provider are together. ?>
1171  parameters.smsNumber = smsNumber;
1172  }
1173 
1174 
1175  parameters.remoteAccess = alwaysGetValue || remoteAccess != previousParameters.remoteAccess ? remoteAccess : "U";
1176  if (!alwaysGetValue) {
1177  parameters.remoteAccessSet = remoteAccess; <?php // Need to see if it is set or not even if the value doesn't change. ?>
1178  }
1179  }
1180 
1181  <?php if ($isMaster) { ?>
1182  var masterIpAddress = [];
1183 
1184  if ($("#allowedMasterAddressGrid").length > 0) {
1185  var data = $("#allowedMasterAddressGrid").data("kendoGrid").dataSource.data();
1186 
1187  for(var i = 0; i != data.length; i++) {
1188  masterIpAddress.push(data[i].ip.trim());
1189  }
1190  if (masterIpAddress.length == 0) {
1191  masterIpAddress = "NONE";
1192  } else {
1193  masterIpAddress = masterIpAddress.join(";");
1194  }
1195  }
1196  if (alwaysGetValue || masterIpAddress != previousParameters.masterIpAddress) {
1197  parameters.masterIpAddress = masterIpAddress;
1198  }
1199 
1200  <?php } ?>
1201 
1202  return parameters;
1203  },
1204  destroy: function() {
1205  if ($("[name='remoteAccess']").length > 0) {
1206  $("[name='notifySMS']").data("kendoMaskedTextBox").destroy();
1207  }
1208  },
1209  revertChanges: function() {
1210 
1211  if ($("[name='remoteAccess']").length > 0) {
1212  $("[name='remoteAccess']").prop("checked", previousParameters.remoteAccess == "Y");
1213  $("[name='notifySMS']").data("kendoMaskedTextBox").value(previousParameters.smsNumber);
1214  $("#allowedAccess").removeClass("deleted");
1215  }
1216 
1217  <?php if ($isMaster) { ?>
1218  if ($("#allowedMasterAddressGrid").length > 0) {
1219  $("[name='addCuIpInput']").val(null);
1220  var ips = previousParameters.masterIpAddress.split(";");
1221  var data = [];
1222  if (ips.length > 0 && ips[0] != "") {
1223  for(var i = 0; i = ips.length; i++) {
1224  data.push({checked: false, ip: ips[i]});
1225  }
1226  }
1227  $("#allowedMasterAddressGrid").data("kendoGrid").dataSource.data(data);
1228  }
1229  <?php } ?>
1230  },
1231  postChanges: function() {
1232  if (!$("[name='remoteAccess']").is(":checked")) {
1233  $("[name='notifySMS']").data("kendoMaskedTextBox").value("");
1234  $("#allowedAccess").remove();
1235  }
1236  }
1237  },
1238  <?php } // End see if remote access tab is needed.
1239  /* List of permissions that the user has. Checked means that the user has it. */ ?>
1240  permissions: {
1241  name: "permissions",
1242  template: $("#permissionsTemplate").html(),
1243  init: function(record) {
1244  $.homecuValidator.setup({formValidate:'tabForm', formStatusField: 'formValidateStatusDiv'});
1245 
1246  var userPermissionsGrid = $("#userPermissionsGrid").kendoGrid({
1247  dataSource: {
1248  data: record.programs,
1249  schema: {
1250  model: {
1251  id: "program",
1252  fields: {
1253  program: {type: "string"},
1254  displaytext: {type: "string"},
1255  description: {type: "string"},
1256  checked: {type: "boolean"},
1257  prevChecked: {type: "boolean"}
1258  }
1259  }
1260  }
1261  },
1262  columns: [
1263  {field: "checked", headerTemplate: "<input type='checkbox' class='allCheckbox'>", width: "45px", sortable: false, filterable: false},
1264  {field: "displaytext", title: "Title", width: "33%"},
1265  {field: "description", title: "Description"}
1266  ],
1267  rowTemplate: "<tr data-uid='#: uid #'><td class='checkboxTD'><input type='checkbox' class='rowCheckbox' # if (checked) { # checked # } #></td>\
1268  <td>#: displaytext #</td><td>#: description #</td></tr>",
1269  noRecords: {
1270  template: "<tr class='noRecordsDiv'><td colspan='3'><span class='vsgSecondary'>No Records Found</span></td></tr>"
1271  },
1272  sortable: true,
1273  filterable: {
1274  extra: false
1275  },
1276  scrollable: false
1277  }).data("kendoGrid");
1278 
1279  <?php printCheckboxEvents("#userPermissionsGrid"); ?>
1280 
1281  },
1282  getSaveParameters: function(doStringify) {
1283  var data = $("#userPermissionsGrid").data("kendoGrid").dataSource.data();
1284  var addPermissions = [], removePermissions = [];
1285  for(var i = 0; i != data.length; i++) {
1286  var row = data[i];
1287  if (row.checked != row.prevChecked) {
1288  row.checked ? addPermissions.push(row.program) : removePermissions.push(row.program);
1289  }
1290  }
1291  return doStringify ? {addPermissions: kendo.stringify(addPermissions), removePermissions: kendo.stringify(removePermissions)}
1292  : {addPermissions: addPermissions, removePermissions: removePermissions};
1293  },
1294  destroy: function() {
1295  $("#userPermissionsGrid").data("kendoGrid").destroy();
1296  },
1297  revertChanges: function() {
1298  var data = $("#userPermissionsGrid").data("kendoGrid").dataSource.data();
1299  for(var i = 0; i != data.length; i++) {
1300  data[i].checked = data[i].prevChecked;
1301  }
1302  $("#userPermissionsGrid").data("kendoGrid").dataSource.data(data);
1303  },
1304  postChanges: function() {
1305  var data = $("#userPermissionsGrid").data("kendoGrid").dataSource.data();
1306  for(var i = 0; i != data.length; i++) {
1307  data[i].prevChecked = data[i].checked;
1308  }
1309  $("#userPermissionsGrid").data("kendoGrid").dataSource.data(data);
1310  }
1311  },
1312  <?php /* Shows the audit records for the user. */ ?>
1313  events: {
1314  name: "events",
1315  template: $("#eventTemplate").html(),
1316  init: function(record) {
1317 
1318  var auditData = record.auditRecords;
1319  <?php printAuditInit(); ?>
1320  },
1321  getSaveParameters: function() {return []; },
1322  destroy: function() {
1323  $("#auditGrid").data("kendoGrid").destroy();
1324  $("#auditGrid, #auditGrid *, #previewWindow, #previewWindow *").off();
1325  },
1326  revertChanges: function() {},
1327  postChanges: function() {}
1328  }
1329  };
1330 
1331  $(".tabContents").on("click", "#auditGrid tbody tr td:not(.checkboxTD)", function() {
1332  var dataItem = $("#auditGrid").data("kendoGrid").dataItem($(this).closest("tr"));
1333  auditOpenPopup(dataItem);
1334  return false;
1335  });
1336 
1337  $(".fullTab").on("click", ".tabReturnBtn", function() {
1338  $("#redirectForm").append("<input type='hidden' name='username' value='<?php echo $username; ?>'>");
1339  $("#redirectForm").submit();
1340  return false;
1341  });
1342 
1343  <?php printFullTabClickEvents($username, false, true);
1344  $tab = !in_array($tab, array("settings", "permissions", "events")) ? "summary" : $tab; ?>
1345  loadTab(tabs.<?php echo $tab; ?>);
1346  }
1347 
1348  <?php printPrintAudits("admin"); printAuditOpenPopup();
1349  printTabFunctions($self, $username, $authval);
1350  printInitRemoteAccess($isMaster); ?>
1351  <?php
1352  /**
1353  * function showSuccessMessage(message)
1354  * Shows the success message for a save.
1355  * Redirect to show edit screen for new user
1356  *
1357  * @param message -- the message to display.
1358  */
1359  ?>
1360  function showSuccessMessage(message) {
1361  var user = "<?php echo $username; ?>";
1362  if (user && user.length > 0) {
1363  var notification = $("<div id='accessControlAccountAddNotificationWithALongId'></div>").appendTo("body").kendoNotification({
1364  appendTo: ".notificationRow"
1365  }).data("kendoNotification");
1366  notification.success(message);
1367  } else {
1368  var userName = $("input[name=\"username\"]").val();
1369  $("#redirectForm").append("<input type='hidden' name='page' value='edit'>");
1370  $("#redirectForm").append("<input type='hidden' name='username' value='" + userName + "'>");
1371  $("#redirectForm").submit();
1372 
1373  }
1374  }
1375 
1376  $(document).ready(function() {
1377  Init();
1378  <?php printClickOverlayEvent(); ?>
1379  });
1380  </script>
1381  <script type="text/x-kendo-template" id="summaryTemplate">
1382  <div class="container hcu-all-100 tabMaxWidth"><div class="row">
1383  <form id="tabForm">
1384  <?php if ($username == "") {
1385  loginPrintInputLine("User", "", "username", 50, true, true, "text", "Username is required");
1386  loginPrintInputLine("Real Name", "", "realName", 50, false, true, "text", "Real Name is required");
1387  loginPrintInputLine("Email Address", "", "emailAddress", 50, "data-email-msg='Email is not valid'", true, "email", "Email is required"); ?>
1388 
1389  <div class="row form-group"><div class="col-xs-12"><h4 class="h4 hcuSpacerx">Password</h4></div></div>
1390  <div class="col-xs-12 col-md-8">
1391  <div class="row form-group hcuSpacer">
1392  <label class="col-xs-12 custom-padding">Enter Password&nbsp;</label>
1393  <div class="col-xs-12 custom-padding">
1394  <input name="password" class="hcu-all-100 k-input k-textbox matchPasswords" type="password" maxlength="255" aria-invalid="true">
1395  </div>
1396  </div>
1397  <div class="row form-group hcuSpacer">
1398  <label class="col-xs-12 custom-padding">Confirm&nbsp;</label>
1399  <div class="col-xs-12 custom-padding">
1400  <input name="confirm" class="hcu-all-100 k-input k-textbox matchPasswords" type="password" maxlength="255">
1401  </div>
1402  </div>
1403  </div>
1404  <div class="col-xs-12 col-md-4 passwordReqInsertion"></div>
1405  <?php } else {
1406  $array= array("User" => "#: username #", "Last Successful Login" => "# if (lastlogin != null) { # #= (lastlogin+'').trim() # # } #",
1407  "Last Failed Login" => "# if (failedlogin != null) { # #= (failedlogin+'').trim() # # } #", "Last Failed Reason" => "#: failReason #",
1408  "Login Retries Before Lockout" => "#: textLockout #");
1409  if ($isMaster) {
1410  $array["Real Name"] = "#: realname #";
1411  printAdmUsrMaintLabelBlock($array);
1412  } else {
1413  printAdmUsrMaintLabelBlock($array);
1414  loginPrintInputLine("Real Name", "#: realname #", "realName", 50, true, true, "text", "Real Name is required");
1415  }
1416  loginPrintInputLine("Email Address", "#: email #", "emailAddress", 50, "# if (!ismaster) { # autofocus # } # data-email-msg='Email is not valid'", true, "email",
1417  "Email is required");
1418  } ?>
1419  </form>
1420  </div></div>
1421  </script>
1422  <?php if ($username != "") { ?>
1423  <script type="text/x-kendo-template" id="remoteTemplate">
1424  <div class="container hcu-all-100"><div class="row">
1425  <form id="tabForm">
1426  <?php if ($isMaster) { ?>
1427  <div class="row form-group hcuSpacer">
1428  <h4 class="h4 hcuSpacerx col-xs-12">Credit Union Remote Access</h4>
1429  </div>
1430  <div class="row form-group hcuSpacer hcuSecondary"><div class="vsgSecondary col-xs-12">
1431  Set up one or more IP addresses to enable remote access. To disable access, remove all IP addresses from the list.
1432  <br>You are accessing this page from IP address: <b><?php echo trim( $_SERVER["REMOTE_ADDR"] ); ?></b>.
1433  Please make sure this address is in the list of allowed IP addresses or you will be locked out.
1434  </div></div>
1435  <div class="row form-group hcuSpacer">
1436  <label class="col-xs-12 col-md-8">Add IP&nbsp;</label>
1437  <div class="col-xs-10 col-md-6">
1438  <input name="addCuIpInput" class="hcu-all-100 k-input k-textbox" type="text">
1439  </div>
1440  <div class="col-xs-2">
1441  <a href='\\#' id="addCuIpBtn" class="k-button">Add</a>
1442  </div>
1443  <div class="col-xs-1">
1444  <span data-for='addCuIpInput' class='k-invalid-msg'></span>
1445  </div>
1446 
1447  </div>
1448  <?php loginPrintDivLine("Allowed IP Addresses", "allowedMasterAddressGrid", true, "hcu-all-100 ipGrid");
1449  } ?>
1450 
1451  <div class="personalRemoteAccessDiv" <?php if (!$remoteAccessEnabled) { ?> style="display:none;" <?php } ?>>
1452  <div class="row form-group hcuSpacer">
1453  <h4 class="h4 hcuSpacerx col-xs-12">Admin User Remote Access</h4>
1454  </div>
1455 
1456  <div class="row form-group hcuSpacer checkbox" id="restrictRemoteAccessRow">
1457  <div class="col-xs-12"><label><input name="remoteAccess" type="checkbox" # if (booleanRemotePrivileges) { # checked # } #>Allow Remote Access For This User</label></div>
1458  </div>
1459 
1460  <div class="remoteAccessDiv" # if (!booleanRemotePrivileges) { # style="display:none;" # } #>
1461  <div class="row hcuSecondary hcuSpacer"><div class="vsgSecondary col-xs-12">
1462  If accessing HomeCU Admin from an IP address not configured, you will be prompted for an access code the first time you access from that IP address.
1463  <br>You can get this access code through email and <i>optionally</i> through text message if your SMS information is set.
1464  </div></div>
1465 
1466  <?php loginPrintInputLine("Notify SMS", "#: smsNumber #", "notifySMS", 0, false, true, "text");?>
1467 
1468 
1469  # if (remoteip != "") { #
1470  <div class="row hcuSpacer" id="allowedAccess"><div class="hcuSpacer">
1471  <label class="col-xs-12 col-md-8" >Allowed Access&nbsp;</label></div>
1472  <div class="col-xs-12 col-md-8">
1473  <span>#: remoteip #</span> (<a href='\\#' id="deleteAllowedAccess">Delete</a>)
1474  </div>
1475  </div>
1476  # } #
1477  </div>
1478  </div>
1479  </form></div></div>
1480  </script>
1481  <script type="text/x-kendo-template" id="settingsTemplate">
1482  <div class="container hcu-all-100 tabMaxWidth"><div class="row">
1483  <form id="tabForm" style="max-width:1325px;">
1484  <div class="row form-group"><div class="col-xs-12"><h4 class="h4 hcuSpacerx">Password</h4></div></div>
1485  <div class="col-xs-12 col-md-8">
1486  <div class="row form-group hcuSpacer">
1487  <label class="col-xs-12">Enter Password&nbsp;</label>
1488  <div class="col-xs-12">
1489  <input name="password" class="hcu-all-100 k-input k-textbox matchPasswords" type="password" maxlength="255" aria-invalid="true">
1490  </div>
1491  </div>
1492  <div class="row form-group hcuSpacer">
1493  <label class="col-xs-12">Confirm&nbsp;</label>
1494  <div class="col-xs-12">
1495  <input name="confirm" class="hcu-all-100 k-input k-textbox matchPasswords" type="password" maxlength="255">
1496  </div>
1497  </div>
1498  </div>
1499  <div class="col-xs-12 col-md-4 passwordReqInsertion"></div>
1500  <div class="col-xs-12">&nbsp;</div>
1501 
1502  <div class="row form-group hcuSpacer">
1503  <h4 class="h4 hcuSpacerx col-xs-12">Password Settings</h4>
1504  </div>
1505 
1506  <div class="row col-xs-12 col-sm-6 col-md-5 col-lg-5">
1507  <div class="row form-group hcuSpacer">
1508  <label class="col-xs-10 col-md-10">Force Password Change&nbsp;</label>
1509  <div class="col-xs-1 col-md-1">
1510  <input name="forcePassword" type="checkbox" # if (booleanForceChange) { # checked # } #>
1511  </div>
1512  </div>
1513  <div class="row form-group hcuSpacer">
1514  <label class="col-xs-10 col-md-10">Force Security Change&nbsp;</label>
1515  <div class="col-xs-1 col-md-1">
1516  <input name="forceSecurity" type="checkbox" # if (booleanForceSecurity) { # checked # } #>
1517  </div>
1518  </div>
1519 
1520  <div class="row form-group hcuSpacer">
1521  <label class="col-xs-10 col-md-10">Allow Master Privileges&nbsp;</label>
1522  <div class="col-xs-1 col-md-1">
1523  <input name="masterPrivileges" type="checkbox" # if (booleanMasterPrivileges) { # checked # } #>
1524  </div>
1525  </div>
1526 
1527  </div>
1528  <div class="col-xs-12 col-sm-6 col-md-7">
1529  <div class="col-xs-12 hcu-no-padding">
1530  <div class="row form-group hcuSpacer admAlignBottom">
1531  <label class="col-xs-6 col-md-6">Force Password In</label>
1532  <div class="col-xs-4 col-md-3">
1533  <input id="forcePasswordChangeNTB" name="forceChangesNTB" value="#: numRemaining #" style="width:100%;" data-previous="#: numRemaining #">
1534  </div>
1535  <div class="col-xs-2 col-md-1">Tries</div>
1536  <div class="col-xs-1 col-sm-1">
1537  <span data-for='forceChangesNTB' class='k-invalid-msg'></span>
1538  </div>
1539  </div>
1540  </div>
1541  <div class="col-xs-12">&nbsp;</div>
1542  # var lockMode= booleanLockAccount ? "Locked" : "Unlocked"; #
1543  <div class="col-xs-12 hcu-no-padding">
1544  <div class="row form-group hcuSpacer">
1545  <label class="col-xs-6 col-md-6">Lock Account</label>
1546  <div class="lockAccount original#: lockMode # current#: lockMode # admAlignBottom">
1547  <span class="text col-xs-4 col-md-3"></span> <span class="col-xs-2 col-md-1">(<a href="\\#"></a>)</span>
1548  </div>
1549  </div>
1550  </div>
1551  </div>
1552 
1553  <?php if ($displayUserMFA) { ?>
1554  <div class="col-xs-12">&nbsp;</div>
1555  <?php printHeader("User MFA (<a href='\\#' id='userMFAShowBtn'>Show</a>)"); ?>
1556  <div class="userMFASection" style="display:none;">
1557  # if (mfaquest != null && mfaquest.length == 3) { #
1558  <?php PrintAdmUsrMaintLabelBlock(array("Confidence Word" => "#: confidence #"));
1559  PrintAdmUsrMaintLabelBlock(array("#: mfaquest[0].quest_text #" => "#: mfaquest[0].answer #", "#: mfaquest[1].quest_text #" => "#: mfaquest[1].answer #",
1560  "#: mfaquest[2].quest_text #" => "#: mfaquest[2].answer #")); ?>
1561  # } else { #
1562  <?php printMessage("User needs to set up MFA."); ?>
1563  # } #
1564  <?php } ?>
1565  </form></div></div>
1566  </script>
1567  <script type="text/x-kendo-template" id="permissionsTemplate">
1568  <div class="container hcu-all-100"><div class="row">
1569  <form id="tabForm">
1570  <?php printGridDiv("userPermissionsGrid"); ?>
1571  </form></div></div>
1572  </script>
1573  <script type="text/x-kendo-template" id="eventTemplate">
1574  <div id="auditGrid" class="hcu-all-100 pointerGrid"></div>
1575  </script>
1576  <?php printAuditTemplates();
1577  }
1578  printPasswordRequirementTemplate (); ?>
1579  <script type="text/x-kendo-template" id="tabTemplate">
1580  <?php
1581  if ($username == "") {
1582  $summaryLastChild = "lastChild";
1583  $eventsLastChild = "";
1584  $permissionsLastChild = "";
1585  } else if ($isMaster) {
1586  $summaryLastChild = "";
1587  $eventsLastChild = "lastChild";
1588  $permissionsLastChild = "";
1589  } else {
1590  $summaryLastChild = "";
1591  $eventsLastChild = "";
1592  $permissionsLastChild = "lastChild";
1593  }
1594  $spacing = "col-xs-2 local-fifth";
1595  $clearfix = $username == "" || $isMaster;
1596  ?>
1597  # var summarySelected = ""; var settingsSelected = ""; var eventsSelected = ""; var permissionsSelected = ""; var remoteSelected = ""; switch(tabname) {
1598  case "summary":
1599  summarySelected = "selected";
1600  break;
1601  case "events":
1602  eventsSelected = "selected";
1603  break;
1604  case "permissions":
1605  permissionsSelected = "selected";
1606  break;
1607  case "settings":
1608  settingsSelected = "selected";
1609  break;
1610  case "remote":
1611  remoteSelected = "selected";
1612  } #
1613  <div class="tabSuccessfulDiv"></div>
1614  <h2>Admin User Maintenance</h2>
1615  <span class="hcu-breadcrumb"><a href="\\#" class="tabReturnBtn">Admin User Maintenance</a> / <span class="realname">
1616  <?php if ($username != "") { ?>#: realname #<?php } else { ?>New User<?php } ?></span></span>
1617  <div>&nbsp;</div>
1618  <div class=" tabTitles row adm-no-horz-margin">
1619  <div class="<?php echo "$spacing $summaryLastChild"; ?> #: summarySelected #" data-name="summary"><div><i class="fa fa-info-circle fa-6">
1620  <div class="hidden-xs hidden-sm text">&nbsp;Summary</div></i></div></div>
1621  <?php if ($username != "") { ?>
1622  <div class="<?php echo $spacing; ?> #: settingsSelected #" data-name="settings"><div><i class="fa fa-desktop fa-6">
1623  <div class="hidden-xs hidden-sm text">&nbsp;Settings</div></i></div></div>
1624  <?php if ($isMaster || $remoteAccessEnabled) { ?>
1625  <div class="<?php echo $spacing; ?> #: remoteSelected #" data-name="remote"><div><i class="fa fa-wifi fa-6">
1626  <div class="hidden-xs hidden-sm text">&nbsp;Access</div></i></div></div>
1627  <?php } ?>
1628  <div class="<?php echo "$spacing $eventsLastChild"; ?> #: eventsSelected #" data-name="events"><div><i class="fa fa-calendar fa-6">
1629  <div class="hidden-xs hidden-sm text">&nbsp;Events</div></i></div></div>
1630  <?php if (!$isMaster) { ?>
1631  <div class="<?php echo "$spacing $permissionsLastChild"; ?> #: permissionsSelected #" data-name="permissions"><div><i class="fa fa-check-square fa-6">
1632  <div class="hidden-xs hidden-sm text">&nbsp;Permissions</div></i></i></div></div>
1633  <?php }}
1634  if ($clearfix) { ?>
1635  <div class='clearfix hidden-xs-block'></div>
1636  <?php } ?>
1637  </div>
1638  <div>
1639  <div class="form-group tabContents"></div>
1640  </div>
1641  <div class="hcu-edit-buttons k-state-default row">
1642  <a class="tabCancelBtn" href="\\#">Cancel</a>
1643  &nbsp;&nbsp;&nbsp;
1644  <a class="tabSaveBtn k-button k-primary" href="\\#"><i class="fa fa-check"></i>Save</a>
1645  </div>
1646  </script>
1647  <div class="container-fluid admUserMaintDiv">
1648  <div class="row notificationRow hcuSpacer"></div>
1649  <form id="redirectForm" action="<?php echo $self; ?>" method="post">
1650  <input type="hidden" name="authval" value="<?php echo $authval; ?>">
1651  </form>
1652  <div>
1653  <div id="formValidateDiv" class="k-block k-error-colored formValidateDiv" style="display:none"></div>
1654  </div>
1655  <div class="fullTab hcu-template"></div>
1656  </div>
1657  <form id="auditPrintForm" method="post" action="shell.prg" target="auditPrint">
1658  <input type="hidden" name="shell" value="">
1659  <input type="hidden" name="title" value="">
1660  </form>
1661  <div id="previewWindow"></div>
1662 <?php }
1663 
1664 /**
1665  * function PrintReport($self, $dbh, $cuCode, $authval)
1666  * This prints out the report page.
1667  *
1668  * @param string $self -- the URL of this page
1669  * @param $dbh -- the database connection
1670  * @param string $cuCode -- the credit union
1671  * @param string $authval -- if authenticated
1672  */
1673 function PrintReport($self, $dbh, $cuCode, $authval) { ?>
1674  <script type="text/javascript">
1675  <?php // Library javascript functions
1676  getShowWaitFunctions(); ?>
1677 
1678  <?php
1679  /**
1680  * function Init()
1681  * This initializes the page for the report with the two grids.
1682  */
1683  ?>
1684  function Init() {
1685  var userPermissionsGrid = $("#userPermissionsGrid").kendoGrid({
1686  dataSource: {
1687  data: [],
1688  schema: {
1689  model: {
1690  id: "username",
1691  fields: {
1692  username: {type: "string"},
1693  realname: {type: "string"},
1694  hasmasterprivs: {type: "string"},
1695  programs: {type: "odata"}
1696  }
1697  }
1698  }
1699  },
1700  columns: [
1701  {field: "username", title: "User", width: "10%"},
1702  {field: "hasmasterprivs", title: "Master Privileges", width: "50px", values: [{text: "Yes", value: "Y"}, {text: "No", value: "N"}]},
1703  {field: "realname", title: "Name"},
1704  {field: "programs", title: "Programs", sortable: false, filterable: false}
1705  ],
1706  rowTemplate: "<tr data-uid='#: uid #'><td><a href='\\#' class='editBtn'>#: username #</a></td><td># if(hasmasterprivs == 'Y') { # Yes # } else { # No # } #</td>\
1707  <td>#: realname #</td><td># if (programs.length == 0) { # (No Permissions) # } else { for( var i = 0; i != programs.length; i++) { # #: programs[i].text #<br>\
1708  # }} #</td></tr>",
1709  noRecords: {
1710  template: "<tr class='noRecordsDiv'><td colspan='3'>No Records Found</td></tr>"
1711  },
1712  sortable: true,
1713  filterable: {extra: false,
1714  operators: { <?php // Needed because the enum also has isnull and isnotnull which don't work ?>
1715  enums: {
1716  eq: "Is equal to",
1717  neq: "Is not equal to"
1718  }
1719  }},
1720  scrollable: false
1721  }).data("kendoGrid");
1722 
1723  var allPermissionsGrid = $("#allPermissionsGrid").kendoGrid({
1724  dataSource: {
1725  data: [],
1726  schema: {
1727  model: {
1728  id: "program",
1729  fields: {
1730  program: {type: "string"},
1731  programText: {type: "string"},
1732  description: {type: "string"},
1733  sort: {type: "number"}
1734  }
1735  }
1736  },
1737  sort: {field: "sort", dir: "asc"}
1738  },
1739  columns: [
1740  {field: "programText", title: "Program", width: "20%"},
1741  {field: "description", title: "Description"}
1742  ],
1743  noRecords: {
1744  template: "<tr class='noRecordsDiv'><td colspan='2'>No Records Found</td></tr>"
1745  },
1746  scrollable: false,
1747  sortable: true,
1748  filterable: {extra: false}
1749  }).data("kendoGrid");
1750 
1751  $(".returnBtn").click(function() {
1752  $("#redirectForm").submit();
1753  return false;
1754  });
1755 
1756  $("#userPermissionsGrid").on("click", ".editBtn", function() {
1757  $("#redirectForm").append("<input type='hidden' name='page' value='edit'><input type='hidden' name='username' value='" + $(this).text().trim() + "'>");
1758  $("#redirectForm").submit();
1759  return false;
1760  });
1761 
1762  showWaitWindow();
1763  $.post("<?php echo $self; ?>&operation=readReport", {authval: "<?php echo $authval; ?>"}, function(data) {
1764  hideWaitWindow();
1765  if (data.error.length > 0) {
1766  $.homecuValidator.displayMessage(data.error, $.homecuValidator.settings.statusError );
1767  } else {
1768  userPermissionsGrid.dataSource.data(data.userData);
1769  allPermissionsGrid.dataSource.data(data.programs);
1770  }
1771  });
1772  }
1773 
1774  $(document).ready(function() {
1775  Init();
1776  });
1777  </script>
1778  <div class="container-fluid">
1779  <br>
1780  <h2>Admin User Maintenance</h2>
1781  <form id="redirectForm" action="<?php echo $self; ?>" method="post">
1782  <input type="hidden" name="authval" value="<?php echo $authval; ?>">
1783  </form>
1784  <div>
1785  <div id="formValidateDiv" class="k-block k-error-colored formValidateDiv" style="display:none"></div>
1786  </div>
1787  <div>
1788  <div class="hcuSpacer">
1789  <span class="hcu-breadcrumb"> <a href="#" class="returnBtn">Users</a> / User Permissions</span>
1790  </div>
1791  </div>
1792  <div>&nbsp;</div>
1793  <div>
1794  <?php printGridDiv("userPermissionsGrid"); ?>
1795  </div>
1796  <div>&nbsp;</div>
1797  <div>
1798  <?php printHeader("Permission Descriptions");
1799  printGridDiv("allPermissionsGrid"); ?>
1800  </div>
1801  </div>
1802 <?php }
1803 
1804 /**
1805  * function PrintAdmUsrMaintLabelBlock($labelArray)
1806  * Prints out a label block
1807  *
1808  * @param array $labelArray -- the label block to display
1809  */
1810 function PrintAdmUsrMaintLabelBlock($labelArray) { ?>
1811  <div class="row form-group col-xs-12"><div class="k-block col-xs-12">
1812  <?php foreach($labelArray as $label => $value) { ?>
1813  <div class="col-xs-12 col-sm-6 hcuSpacer">
1814  <label class="col-xs-12"><?php echo $label; ?>&nbsp;</label>
1815  <div class="col-xs-12 admIndent"><?php echo trim(str_replace('\\', '\\\\', $value)); ?></div>
1816  </div>
1817  <?php } ?>
1818  </div></div>
1819 <?php }
1820 
1821 /**
1822  * function PrintRestorePreviousChallenge($fromAdmUser = false)
1823  * @param $fromAdmUser if from admin user or not.
1824  * prints out the contents of the restorePrevious function. For the advanced security page, it is just this. For the setup page, there is a little bit more code.
1825  */
1826 function PrintRestorePreviousChallenge($fromAdmUser = false) {
1827  if (!$fromAdmUser) { ?>
1828  var previousParameters = $("#form, #login-entry").data("previousParameters");
1829  <?php } ?>
1830  $("[name='confidenceWord']").val(previousParameters.confidence);
1831 
1832  for(var i = 0; i < 3; i++) {
1833  var index = i + 1;
1834  $("#challengeQuestDDL" + index).data("kendoDropDownList").value(previousParameters.questIds[i]);
1835  $("[name=challengeResponse" + index + "]").val(previousParameters.questResponses[i]);
1836  }
1837  UpdateDDLs();
1838 <?php }
Definition: User.php:7