Implemented GUI aspect of usermanagement page
TODO: add ajax-call that will update database
This commit is contained in:
		| @@ -114,7 +114,7 @@ function validateToken (string $secureToken) { | ||||
|  | ||||
| 	// Retrieve all authentication tokens from database matching username | ||||
| 	$pdoQuery = $pdoDB->prepare(' | ||||
| 		SELECT SecureToken.Value | ||||
| 		SELECT User.Id, SecureToken.Value | ||||
| 		FROM SecureToken | ||||
| 		LEFT JOIN User | ||||
| 			ON (User.Id=SecureToken.UserId) | ||||
| @@ -126,6 +126,7 @@ function validateToken (string $secureToken) { | ||||
| 	foreach($pdoQuery->fetchAll(PDO::FETCH_ASSOC) as $row) { | ||||
| 		try { | ||||
| 			$storedTokens[] = JWT::decode($row['Value'], base64_decode($settings->JWT['PrivateKey_base64']), $settings->JWT['Algorithm']); | ||||
|             $currentUserId = $row['Id']; | ||||
| 		} catch (Exception $e) { | ||||
| 			continue; | ||||
| 		} | ||||
| @@ -137,7 +138,8 @@ function validateToken (string $secureToken) { | ||||
| 	})) === 1) { | ||||
| 		return [ | ||||
| 			'status'	=> 'Success', | ||||
| 			'name'		=> $jwtPayload->name | ||||
| 			'name'		=> $jwtPayload->name, | ||||
|             'uid'       => $currentUserId | ||||
| 		]; | ||||
| 	} else { | ||||
| 		if ($settings->Debug['LogToFile']) { | ||||
|   | ||||
| @@ -33,7 +33,7 @@ $pageLayout['full'] = <<<'FULL' | ||||
| </html> | ||||
| FULL; | ||||
|  | ||||
| $pageLayout['full2'] = <<<'FULL2' | ||||
| $pageLayout['full_alt'] = <<<'FULL_ALT' | ||||
| <!DOCTYPE html> | ||||
| <html lang="nl"> | ||||
|   <head> | ||||
| @@ -72,7 +72,7 @@ $pageLayout['full2'] = <<<'FULL2' | ||||
|    	</div> | ||||
|   </body> | ||||
| </html> | ||||
| FULL2; | ||||
| FULL_ALT; | ||||
|  | ||||
| $pageLayout['bare'] = <<<'BARE' | ||||
| <!DOCTYPE html> | ||||
| @@ -98,12 +98,12 @@ $contentLayout['login'] = <<<'LOGIN' | ||||
|                 <span class="indent"> </span> | ||||
|               </li> | ||||
|               <li> | ||||
|                 <label class="pre" for="username" data-translation="label_username">Gebruikersnaam:</label> | ||||
|                 <label class="pre" for="username" data-translation="label_username">Username:</label> | ||||
|                 <input type="text" id="username" name="username" tabindex="100" /> | ||||
|                 <label for="username">@lucidAuth</label> | ||||
|               </li> | ||||
|               <li> | ||||
|                 <label class="pre" for="password" data-translation="label_password">Wachtwoord:</label> | ||||
|                 <label class="pre" for="password" data-translation="label_password">Password:</label> | ||||
|                 <input type="password" id="password" name="password" tabindex="200" /> | ||||
|               </li> | ||||
|               <li> | ||||
| @@ -111,7 +111,7 @@ $contentLayout['login'] = <<<'LOGIN' | ||||
| 				<button id="btnlogin" class="bttn-simple bttn-xs bttn-primary" tabindex="300" data-translation="button_login">login</button> | ||||
|               </li> | ||||
|               <li class="misc"> | ||||
|                 <span class="indent" data-translation="span_credentialsavailable">Inloggegevens verkrijgbaar op aanvraag!</span> | ||||
|                 <span class="indent" data-translation="span_credentialsavailable">Login credentials available upon request!</span> | ||||
|               </li> | ||||
|             </ul> | ||||
|           </section> | ||||
| @@ -121,16 +121,13 @@ LOGIN; | ||||
| $contentLayout['manage']['header'] = <<<'MANAGE_HEADER' | ||||
| 		  <script src="misc/script.editable.table.js"></script> | ||||
| 		  <script src="misc/script.manage.js"></script> | ||||
|           <span id="user"><span data-translation="span_loggedinas">Ingelogd als</span> %1$s --- [<a id="linklanguage-en" href="#" tabindex="700">EN</a> <a id="linklanguage-nl" class="current" href="#" tabindex="700">NL</a>] [<a href="#" tabindex="800" data-translation="link_logout">Log uit</a>]</span> | ||||
|           <span id="user"><span data-translation="span_loggedinas">Logged in as</span> %1$s --- [<a id="linklanguage-en" href="#" tabindex="700">EN</a> <a id="linklanguage-nl" class="current" href="#" tabindex="700">NL</a>] [<a href="#" tabindex="800" data-translation="link_logout">Logout</a>]</span> | ||||
|           <ul style="clear: both; margin-top: 20px;"> | ||||
|             <li class="buttons"> | ||||
| 		        <button id="btnnewuser" class="bttn-simple bttn-xs bttn-primary" data-translation="button_new">nieuw</button> | ||||
| 		        <button id="btnfoo" class="bttn-simple bttn-xs bttn-primary" data-translation="button_foo">foo</button> | ||||
| 				<button id="btnbar" class="bttn-simple bttn-xs bttn-primary" data-translation="button_bar">bar</button> | ||||
|             </li> | ||||
|             <li class="buttons"> | ||||
| 		      <button id="btnsync" class="bttn-simple bttn-xs bttn-primary" data-translation="button_save">opslaan</button> | ||||
|               <button id="btncancel" class="bttn-simple bttn-xs bttn-primary" data-translation="button_cancel">annuleren</button> | ||||
| 		      <button id="btnnewuser" class="bttn-simple bttn-xs bttn-primary" data-translation="button_new">new</button> | ||||
|                   | ||||
| 		      <button id="btnsave" class="bttn-simple bttn-xs bttn-primary" data-translation="button_save">save</button> | ||||
|               <button id="btncancel" class="bttn-simple bttn-xs bttn-primary" data-translation="button_cancel">cancel</button> | ||||
|             </li> | ||||
|           </ul> | ||||
| MANAGE_HEADER; | ||||
| @@ -140,9 +137,9 @@ $contentLayout['manage']['section'] = <<<'MANAGE_SECTION' | ||||
|                 <table id="usertable"> | ||||
|                   <thead> | ||||
|                     <tr> | ||||
|                       <th class="immutable">Username</th> | ||||
|                       <th class="immutable">Role</th> | ||||
|                       <th class="immutable">Sessions</th> | ||||
|                       <th class="immutable" data-translation="th_username">Username</th> | ||||
|                       <th class="immutable" data-translation="th_role">Role</th> | ||||
|                       <th class="immutable" data-translation="th_manage">Manage</th> | ||||
|                     </tr> | ||||
|                   </thead> | ||||
|                   <tbody> | ||||
|   | ||||
| @@ -12,28 +12,26 @@ | ||||
|  | ||||
|         try { | ||||
|         	$allUsers = $pdoDB->query(' | ||||
|                 SELECT User.Id, User.Username, Role.Rolename, COUNT(DISTINCT SecureToken.Value) AS Sessions | ||||
|                 SELECT User.Id, User.Username, Role.Rolename | ||||
| 		        FROM User | ||||
| 	            LEFT JOIN Role | ||||
| 	    		    ON (User.RoleId=Role.Id) | ||||
|                 LEFT JOIN SecureToken | ||||
|                     ON (User.Id=SecureToken.UserId) | ||||
|                     ON (Role.Id = User.RoleId) | ||||
|     	    ')->fetchAll(PDO::FETCH_ASSOC); | ||||
|         } catch (Exception $e) { | ||||
| // Should really do some actual errorhandling here | ||||
|             throw new Exception($e); | ||||
|         } | ||||
|  | ||||
|     	foreach($allUsers as $row) { | ||||
|             $tableRows[] = sprintf('<tr><td data-userid="%1$s">%2$s</td><td>%3$s</td><td class="immutable"><a href="?">%4$s</a></td></tr>', | ||||
|             $tableRows[] = sprintf('<tr %1$s><td data-userid="%2$s">%3$s</td><td>%4$s</td><td class="immutable">%5$s</td></tr>', | ||||
|                 $validateTokenResult['uid'] === $row['Id'] ? 'class="currentuser"': null, | ||||
|                 $row['Id'], | ||||
|                 explode('\\', $row['Username'])[1], | ||||
|                 $row['Rolename'], | ||||
|                 $row['Sessions'] | ||||
|                 $validateTokenResult['uid'] === $row['Id'] ? '<button class="bttn-simple bttn-xs bttn-primary" data-translation="button_sessions">Sessions</button>' : '<button class="bttn-simple bttn-xs bttn-primary" data-translation="button_sessions">Sessions</button> <button class="bttn-simple bttn-xs bttn-primary delete" data-translation="button_delete">Delete</button>' | ||||
|             ); | ||||
|     	} | ||||
|  | ||||
|         echo sprintf($pageLayout['full2'], | ||||
|         echo sprintf($pageLayout['full_alt'], | ||||
|             sprintf($contentLayout['manage']['header'], | ||||
|                 $validateTokenResult['name'] | ||||
|             ), | ||||
|   | ||||
| @@ -2,13 +2,71 @@ $(document).ready(function(){ | ||||
|     // Initialize the editable-table functionality | ||||
|     $('#usertable').editableTableWidget(); | ||||
|  | ||||
|     $('#usertable button.delete').click(function() { | ||||
|         $(this).closest('tr').addClass('removed'); | ||||
|     }); | ||||
|  | ||||
|     $('#btnnewuser').click(function() { | ||||
|         // Create a new user; generate pseudo-random username | ||||
|         var newUser = 'User' + String(Math.floor(Math.random() * Math.floor(9999))).padStart(4, '0'); | ||||
|  | ||||
|         $('#usertable tbody').append($('<tr class="new"><td>' + newUser + '</td><td>User</td><td class="immutable"><a href="?">0</a></td></tr>')); | ||||
|         // Add new user to the interface | ||||
|         //   (new `<tr>` in `<table id="usertable">`) | ||||
|         $('#usertable tbody').append($('<tr>', {class: 'new'}) | ||||
|             .append($('<td>', { | ||||
|                 text: newUser | ||||
|             })) | ||||
|             .append($('<td>', { | ||||
|                 text: 'User' | ||||
|             })) | ||||
|             .append($('<td>', { | ||||
|                 class: 'immutable', | ||||
|                 html: '<button class="bttn-simple bttn-xs bttn-primary disabled" data-translation="button_sessions" disabled="true">' + | ||||
|                     locales[(localStorage.getItem('language') !== null ? localStorage.getItem('language') : 'nl')]['button_sessions'] + '</button> ' + | ||||
|                     '<button class="bttn-simple bttn-xs bttn-primary delete" data-translation="button_delete">' + | ||||
|                     locales[(localStorage.getItem('language') !== null ? localStorage.getItem('language') : 'nl')]['button_delete'] + | ||||
|                     '</button>' | ||||
|             })) | ||||
|         ); | ||||
|         // Call `editableTableWidget()` again to include the newly added `<tr>` | ||||
|         //   To prevent recreating multiple new editors; reference the already existing `<input>` | ||||
|         $('#usertable').editableTableWidget({editor: $('#editor')}); | ||||
|         // Add eventhandlers to buttons of newly added `<tr>` | ||||
|         $('#usertable .new button.delete').unbind().click(function() { | ||||
|             $(this).closest('tr').remove(); | ||||
|         }); | ||||
|     }); | ||||
|  | ||||
|     $('#btnsave').click(function() { | ||||
|         var newEntries = []; | ||||
|         $('#usertable .new').each(function() { | ||||
|             newEntries.push({ | ||||
|                 'userName': $(this).find('td:nth-child(1)').text(), | ||||
|                 'roleName': $(this).find('td:nth-child(2)').text() | ||||
|             }); | ||||
|         }); | ||||
|         var removedEntries = []; | ||||
|         $('#usertable .removed').each(function() { | ||||
|             removedEntries.push({ | ||||
|                 'userId':   $(this).find('td:nth-child(1)').data('userid'), | ||||
|                 'userName': $(this).find('td:nth-child(1)').text(), | ||||
|                 'roleName': $(this).find('td:nth-child(2)').text() | ||||
|             }); | ||||
|         }); | ||||
|  | ||||
| console.log({'new': newEntries, 'removed': removedEntries}); | ||||
|  | ||||
| /*        $.get("psworker.php", { | ||||
| 			do: "mutate", | ||||
| 			mutations: { | ||||
| 				new: newEntries, | ||||
| 				removed: removedEntries | ||||
| 			} | ||||
| 		})*/ | ||||
|     }); | ||||
|  | ||||
|     $('#btncancel').click(function() { | ||||
|         window.location.reload(); | ||||
|     }); | ||||
|  | ||||
|    	if (localStorage.getItem('theme') !== null) { | ||||
|   | ||||
| @@ -3,6 +3,7 @@ var locales = { | ||||
| 		button_new:					"new", | ||||
|         button_save:                "save", | ||||
| 		button_cancel:				"cancel", | ||||
|         button_sessions:            "sessions", | ||||
| 		button_delete:				"delete", | ||||
| 		button_login:				"login", | ||||
| 		heading_error:				"ERROR!", | ||||
| @@ -10,12 +11,16 @@ var locales = { | ||||
| 		label_username:				"Username:", | ||||
| 		link_logout:				"Logout", | ||||
| 		span_credentialsavailable:	"Login credentials available upon request!", | ||||
| 		span_loggedinas:			"Logged in as" | ||||
| 		span_loggedinas:			"Logged in as", | ||||
|         th_username:                "Username", | ||||
|         th_role:                    "Role", | ||||
|         th_manage:                  "Manage" | ||||
| 	}, | ||||
| 	nl: { | ||||
| 		button_new:					"nieuw", | ||||
|         button_save:                "opslaan", | ||||
| 		button_cancel:				"annuleren", | ||||
|         button_sessions:            "sessies", | ||||
| 		button_delete:				"verwijder", | ||||
| 		button_login:				"log in", | ||||
| 		heading_error:				"FOUT!", | ||||
| @@ -23,7 +28,10 @@ var locales = { | ||||
| 		label_username:				"Gebruikersnaam:", | ||||
| 		link_logout:				"Log uit", | ||||
| 		span_credentialsavailable:	"Inloggegevens verkrijgbaar op aanvraag!", | ||||
| 		span_loggedinas:			"Ingelogd als" | ||||
| 		span_loggedinas:			"Ingelogd als", | ||||
|         th_username:                "Gebruikersnaam", | ||||
|         th_role:                    "Rol", | ||||
|         th_manage:                  "Beheer" | ||||
| 	} // ... etc. | ||||
| }; | ||||
|  | ||||
| @@ -31,7 +39,7 @@ $(document).ready(function(){ | ||||
| 	$('[id^=linklanguage-]').click(function() { | ||||
| 		var selectedlang = $(this).attr('id').split('-')[1]; | ||||
| 		// Replace text of each element with translated value | ||||
| 		$('[data-translation]').each(function(index) { | ||||
| 		$('[data-translation]').each(function() { | ||||
| 			$(this).text(locales[selectedlang][$(this).data('translation')]); | ||||
| 		}); | ||||
| 		// Enable/disable (toggle) anchors | ||||
| @@ -43,7 +51,7 @@ $(document).ready(function(){ | ||||
| 	}); | ||||
|  | ||||
| 	if (localStorage.getItem('language') !== null) { | ||||
| 		$('[data-translation]').each(function(index) { | ||||
| 		$('[data-translation]').each(function() { | ||||
| 			$(this).text(locales[localStorage.getItem('language')][$(this).data('translation')]); | ||||
| 		}); | ||||
| 		$('span#user a.current').removeClass('current'); | ||||
|   | ||||
| @@ -137,6 +137,13 @@ body { | ||||
|             padding: 2px; | ||||
|             margin: 0; | ||||
|         } | ||||
|         .main section table .new { | ||||
|             font-weight: bold; | ||||
|         } | ||||
|         .main section table .removed td:nth-child(-n+2) { | ||||
|             text-decoration: line-through; | ||||
|             color: grey; | ||||
|         } | ||||
|         .main section table tbody tr:nth-child(odd) { | ||||
|             background-color: rgb(215, 215, 215); | ||||
|         } | ||||
|   | ||||
| @@ -8,7 +8,7 @@ body{ | ||||
|   flex-direction: column; | ||||
| } | ||||
| .header { | ||||
|   height: 125px; | ||||
|   height: 100px; | ||||
|   background: #FFFFFF; | ||||
|   color: #000000; | ||||
| } | ||||
| @@ -36,7 +36,7 @@ body{ | ||||
| } | ||||
| .main section { | ||||
| 	overflow-y: scroll; | ||||
| 	height: calc(100% - 125px); | ||||
| 	height: calc(100% - 100px); | ||||
| } | ||||
| .sidebar-first{ | ||||
|   width: 25%; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user