diff --git a/include/lucidAuth.template.php b/include/lucidAuth.template.php index efc9edd..bbbd26a 100644 --- a/include/lucidAuth.template.php +++ b/include/lucidAuth.template.php @@ -10,9 +10,6 @@ $pageLayout['full'] = <<<'FULL' lucidAuth - - - @@ -54,9 +51,11 @@ BARE; $contentLayout['login'] = <<<'LOGIN' -
- Login Details +
-
+ Secure! LOGIN; $contentLayout['manage'] = <<<'MANAGE' + Ingelogd als %1$s --- [EN NL] [Log uit] -
- Beheer Gebruikers +
-
+ MANAGE; ?> \ No newline at end of file diff --git a/public/example.php b/public/example.php deleted file mode 100644 index c31adb3..0000000 --- a/public/example.php +++ /dev/null @@ -1,27 +0,0 @@ - 'Failed to connect to MySQL: ' . mysqli_connect_error())); - exit; -} - -if ($input['action'] === 'edit') { - $mysqli->query("UPDATE users SET username='" . $input['username'] . "', email='" . $input['email'] . "', avatar='" . $input['avatar'] . "' WHERE id='" . $input['id'] . "'"); -} else if ($input['action'] === 'delete') { - $mysqli->query("UPDATE users SET deleted=1 WHERE id='" . $input['id'] . "'"); -} else if ($input['action'] === 'restore') { - $mysqli->query("UPDATE users SET deleted=0 WHERE id='" . $input['id'] . "'"); -} - -mysqli_close($mysqli); - -echo json_encode($input); diff --git a/public/lucidAuth.manage.php b/public/lucidAuth.manage.php index 3a052c4..0ad71a9 100644 --- a/public/lucidAuth.manage.php +++ b/public/lucidAuth.manage.php @@ -2,7 +2,7 @@ error_reporting(E_ALL ^ E_NOTICE); include_once('../include/lucidAuth.functions.php'); - + if (!empty($_COOKIE['JWT'])) { $validateTokenResult = validateToken($_COOKIE['JWT']); } @@ -10,9 +10,32 @@ if ($validateTokenResult['status'] === "Success") { include_once('../include/lucidAuth.template.php'); - echo sprintf($pageLayout['full'], + try { + $allUsers = $pdoDB->query(' + SELECT User.Username, Role.Rolename, COUNT(DISTINCT SecureToken.Value) AS Sessions + FROM User + LEFT JOIN Role + ON (User.RoleId=Role.Id) + LEFT JOIN SecureToken + ON (User.Id=SecureToken.UserId) + ')->fetchAll(PDO::FETCH_ASSOC); + } catch (Exception $e) { +// Should really do some actual errorhandling here + throw new Exception($e); + } + + foreach($allUsers as $row) { + $tableRows[] = sprintf('%1$s%2$s%3$s', + explode('\\', $row['Username'])[1], + $row['Rolename'], + $row['Sessions'] + ); + } + + echo sprintf($pageLayout['full'], sprintf($contentLayout['manage'], - $validateTokenResult['name'] + $validateTokenResult['name'], + implode($tableRows) ) ); } else { diff --git a/public/misc/script.editable.table.js b/public/misc/script.editable.table.js new file mode 100644 index 0000000..66984b6 --- /dev/null +++ b/public/misc/script.editable.table.js @@ -0,0 +1,131 @@ +/*global $, window*/ +$.fn.editableTableWidget = function (options) { + 'use strict'; + return $(this).each(function () { + var buildDefaultOptions = function () { + var opts = $.extend({}, $.fn.editableTableWidget.defaultOptions); + opts.editor = opts.editor.clone(); + return opts; + }, + activeOptions = $.extend(buildDefaultOptions(), options), + ARROW_LEFT = 37, ARROW_UP = 38, ARROW_RIGHT = 39, ARROW_DOWN = 40, ENTER = 13, ESC = 27, TAB = 9, + element = $(this), + editor = activeOptions.editor.css('position', 'absolute').hide().appendTo(element.parent()), + active, + showEditor = function (select) { + active = element.find('td:focus:not(".immutable")'); + if (active.length) { + editor.val(active.text()) + .removeClass('error') + .show() + .offset(active.offset()) + .css(active.css(activeOptions.cloneProperties)) + .width(active.width()) + .height(active.height()) + .focus(); + if (select) { + editor.select(); + } + } + }, + setActiveText = function () { + var text = editor.val(), + evt = $.Event('change'), + originalContent; + if (active.text() === text || editor.hasClass('error')) { + return true; + } + originalContent = active.html(); + active.text(text).trigger(evt, text); + if (evt.result === false) { + active.html(originalContent); + } + }, + movement = function (element, keycode) { + if (keycode === ARROW_RIGHT) { + return element.next('td'); + } else if (keycode === ARROW_LEFT) { + return element.prev('td'); + } else if (keycode === ARROW_UP) { + return element.parent().prev().children().eq(element.index()); + } else if (keycode === ARROW_DOWN) { + return element.parent().next().children().eq(element.index()); + } + return []; + }; + editor.blur(function () { + setActiveText(); + editor.hide(); + }).keydown(function (e) { + if (e.which === ENTER) { + setActiveText(); + editor.hide(); + active.focus(); + e.preventDefault(); + e.stopPropagation(); + } else if (e.which === ESC) { + editor.val(active.text()); + e.preventDefault(); + e.stopPropagation(); + editor.hide(); + active.focus(); + } else if (e.which === TAB) { + active.focus(); + } else if (this.selectionEnd - this.selectionStart === this.value.length) { + var possibleMove = movement(active, e.which); + if (possibleMove.length > 0) { + possibleMove.focus(); + e.preventDefault(); + e.stopPropagation(); + } + } + }) + .on('input paste', function () { + var evt = $.Event('validate'); + active.trigger(evt, editor.val()); + if (evt.result === false) { + editor.addClass('error'); + } else { + editor.removeClass('error'); + } + }); + element.on('click keypress dblclick', showEditor) + .css('cursor', 'pointer') + .keydown(function (e) { + var prevent = true, + possibleMove = movement($(e.target), e.which); + if (possibleMove.length > 0) { + possibleMove.focus(); + } else if (e.which === ENTER) { + showEditor(false); + } else if (e.which === 17 || e.which === 91 || e.which === 93) { + showEditor(true); + prevent = false; + } else { + prevent = false; + } + if (prevent) { + e.stopPropagation(); + e.preventDefault(); + } + }); + + element.find('td').prop('tabindex', 1); + + $(window).on('resize', function () { + if (editor.is(':visible')) { + editor.offset(active.offset()) + .width(active.width()) + .height(active.height()); + } + }); + }); + +}; +$.fn.editableTableWidget.defaultOptions = { + cloneProperties: ['padding', 'padding-top', 'padding-bottom', 'padding-left', 'padding-right', + 'text-align', 'font', 'font-size', 'font-family', 'font-weight', + 'border', 'border-top', 'border-bottom', 'border-left', 'border-right'], + editor: $('') +}; + diff --git a/public/misc/script.index.js b/public/misc/script.index.js index 5da41bd..746d489 100644 --- a/public/misc/script.index.js +++ b/public/misc/script.index.js @@ -19,7 +19,7 @@ $(document).ready(function(){ password: $('#password').val(), ref: $('#ref').val() }) - .done(function(data,status) { + .done(function(data,_status) { if (data.Result === 'Success') { $('#btnlogin').css({ 'background': 'green url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAaklEQVQ4jeXOMQ5AQBBG4T2BC4i76EWich7ncAKbqCRuodTqnMNTkFgJs3ZU4tXz/Rlj/hUQv8EpMAClFk9sjUAiHVcCnoFMwhZYgPYG575Xe46aIOyMdJx7ji9GwrEzUgOFCu8DkRp/qxU2BKCUyZR6ygAAAABJRU5ErkJggg==) no-repeat center', diff --git a/public/misc/script.manage.js b/public/misc/script.manage.js index e69de29..f7e6c98 100644 --- a/public/misc/script.manage.js +++ b/public/misc/script.manage.js @@ -0,0 +1,13 @@ +$(document).ready(function(){ + // Initialize the editable-table functionality + $('#usertable').editableTableWidget(); + + $('#btnnewuser').click(function() { + var newUser = 'User' + String(Math.floor(Math.random() * Math.floor(9999))).padStart(4, '0'); + + $('#usertable tbody').append($('' + newUser + 'User0')); + // Call `editableTableWidget()` again to include the newly added `` + // To prevent recreating multiple new editors; reference the already existing `` + $('#usertable').editableTableWidget({editor: $('#editor')}); + }); +}); \ No newline at end of file diff --git a/public/misc/script.table.min.js b/public/misc/script.table.min.js deleted file mode 100644 index 2d4b259..0000000 --- a/public/misc/script.table.min.js +++ /dev/null @@ -1,6 +0,0 @@ -/*! - * Tabledit v1.2.3 (https://github.com/markcell/jQuery-Tabledit) - * Copyright (c) 2015 Celso Marques - * Licensed under MIT (https://github.com/markcell/jQuery-Tabledit/blob/master/LICENSE) - */ -if("undefined"==typeof jQuery)throw new Error("Tabledit requires jQuery library.");!function(t){"use strict";t.fn.Tabledit=function(e){function n(e){var n=i.find(".tabledit-input").serialize()+"&action="+e,a=d.onAjax(e,n);if(a===!1)return!1;var l=t.post(d.url,n,function(t,n,a){e===d.buttons.edit.action&&(s.removeClass(d.dangerClass).addClass(d.warningClass),setTimeout(function(){i.find("tr."+d.warningClass).removeClass(d.warningClass)},1400)),d.onSuccess(t,n,a)},"json");return l.fail(function(t,n,i){e===d.buttons["delete"].action?(o.removeClass(d.mutedClass).addClass(d.dangerClass),o.find(".tabledit-toolbar button").attr("disabled",!1),o.find(".tabledit-toolbar .tabledit-restore-button").hide()):e===d.buttons.edit.action&&s.addClass(d.dangerClass),d.onFail(t,n,i)}),l.always(function(){d.onAlways()}),l}if(!this.is("table"))throw new Error("Tabledit only works when applied to a table.");var i=this,a={url:window.location.href,inputClass:"form-control input-sm",toolbarClass:"btn-toolbar",groupClass:"btn-group btn-group-sm",dangerClass:"danger",warningClass:"warning",mutedClass:"text-muted",eventType:"click",rowIdentifier:"id",hideIdentifier:!1,autoFocus:!0,editButton:!0,deleteButton:!0,saveButton:!0,restoreButton:!0,buttons:{edit:{"class":"btn btn-sm btn-default",html:'',action:"edit"},"delete":{"class":"btn btn-sm btn-default",html:'',action:"delete"},save:{"class":"btn btn-sm btn-success",html:"Save"},restore:{"class":"btn btn-sm btn-warning",html:"Restore",action:"restore"},confirm:{"class":"btn btn-sm btn-danger",html:"Confirm"}},onDraw:function(){},onSuccess:function(){},onFail:function(){},onAlways:function(){},onAjax:function(){}},d=t.extend(!0,a,e),s="undefined",o="undefined",l="undefined",r={columns:{identifier:function(){d.hideIdentifier&&i.find("th:nth-child("+parseInt(d.columns.identifier[0])+"1), tbody td:nth-child("+parseInt(d.columns.identifier[0])+"1)").hide();var e=i.find("tbody td:nth-child("+(parseInt(d.columns.identifier[0])+1)+")");e.each(function(){var e=''+t(this).text()+"",n='';t(this).html(e+n),t(this).parent("tr").attr(d.rowIdentifier,t(this).text())})},editable:function(){for(var e=0;e";if("undefined"!=typeof d.columns.editable[e][2]){var a='"}else var a='';t(this).html(i+a),t(this).addClass("tabledit-view-mode")})}},toolbar:function(){if(d.editButton||d.deleteButton){var t="",e="",n="",a="",s="";0===i.find("th.tabledit-toolbar-column").length&&i.find("tr:first").append(''),d.editButton&&(t='"),d.deleteButton&&(e='",s='"),d.editButton&&d.saveButton&&(n='"),d.deleteButton&&d.restoreButton&&(a='");var o='
\n
'+t+e+"
\n "+n+"\n "+s+"\n "+a+"\n
";i.find("tr:gt(0)").append(''+o+"")}}}},u={view:function(e){var n=t(e).parent("tr");t(e).parent("tr").find(".tabledit-input.tabledit-identifier").prop("disabled",!0),t(e).find(".tabledit-input").blur().hide().prop("disabled",!0),t(e).find(".tabledit-span").show(),t(e).addClass("tabledit-view-mode").removeClass("tabledit-edit-mode"),d.editButton&&(n.find("button.tabledit-save-button").hide(),n.find("button.tabledit-edit-button").removeClass("active").blur())},edit:function(e){c.reset(e);var n=t(e).parent("tr");n.find(".tabledit-input.tabledit-identifier").prop("disabled",!1),t(e).find(".tabledit-span").hide();var i=t(e).find(".tabledit-input");i.prop("disabled",!1).show(),d.autoFocus&&i.focus(),t(e).addClass("tabledit-edit-mode").removeClass("tabledit-view-mode"),d.editButton&&(n.find("button.tabledit-edit-button").addClass("active"),n.find("button.tabledit-save-button").show())}},b={reset:function(e){t(e).each(function(){var e=t(this).find(".tabledit-input"),n=t(this).find(".tabledit-span").text();e.is("select")?e.find("option").filter(function(){return t.trim(t(this).text())===n}).attr("selected",!0):e.val(n),u.view(this)})},submit:function(e){var i=n(d.buttons.edit.action);i!==!1&&(t(e).each(function(){var e=t(this).find(".tabledit-input");t(this).find(".tabledit-span").text(e.is("select")?e.find("option:selected").text():e.val()),u.view(this)}),s=t(e).parent("tr"))}},c={reset:function(t){i.find(".tabledit-confirm-button").hide(),i.find(".tabledit-delete-button").removeClass("active").blur()},submit:function(e){c.reset(e),t(e).parent("tr").find("input.tabledit-identifier").attr("disabled",!1);var i=n(d.buttons["delete"].action);t(e).parents("tr").find("input.tabledit-identifier").attr("disabled",!0),i!==!1&&(t(e).parent("tr").addClass("tabledit-deleted-row"),t(e).parent("tr").addClass(d.mutedClass).find(".tabledit-toolbar button:not(.tabledit-restore-button)").attr("disabled",!0),t(e).find(".tabledit-restore-button").show(),o=t(e).parent("tr"))},confirm:function(e){i.find("td.tabledit-edit-mode").each(function(){b.reset(this)}),t(e).find(".tabledit-delete-button").addClass("active"),t(e).find(".tabledit-confirm-button").show()},restore:function(e){t(e).parent("tr").find("input.tabledit-identifier").attr("disabled",!1);var i=n(d.buttons.restore.action);t(e).parents("tr").find("input.tabledit-identifier").attr("disabled",!0),i!==!1&&(t(e).parent("tr").removeClass("tabledit-deleted-row"),t(e).parent("tr").removeClass(d.mutedClass).find(".tabledit-toolbar button").attr("disabled",!1),t(e).find(".tabledit-restore-button").hide(),l=t(e).parent("tr"))}};return r.columns.identifier(),r.columns.editable(),r.columns.toolbar(),d.onDraw(),d.deleteButton&&(i.on("click","button.tabledit-delete-button",function(e){if(e.handled!==!0){e.preventDefault();var n=t(this).hasClass("active"),i=t(this).parents("td");c.reset(i),n||c.confirm(i),e.handled=!0}}),i.on("click","button.tabledit-confirm-button",function(e){if(e.handled!==!0){e.preventDefault();var n=t(this).parents("td");c.submit(n),e.handled=!0}})),d.restoreButton&&i.on("click","button.tabledit-restore-button",function(e){e.handled!==!0&&(e.preventDefault(),c.restore(t(this).parents("td")),e.handled=!0)}),d.editButton?(i.on("click","button.tabledit-edit-button",function(e){if(e.handled!==!0){e.preventDefault();var n=t(this),a=n.hasClass("active");b.reset(i.find("td.tabledit-edit-mode")),a||t(n.parents("tr").find("td.tabledit-view-mode").get().reverse()).each(function(){u.edit(this)}),e.handled=!0}}),i.on("click","button.tabledit-save-button",function(e){e.handled!==!0&&(e.preventDefault(),b.submit(t(this).parents("tr").find("td.tabledit-edit-mode")),e.handled=!0)})):(i.on(d.eventType,"tr:not(.tabledit-deleted-row) td.tabledit-view-mode",function(t){t.handled!==!0&&(t.preventDefault(),b.reset(i.find("td.tabledit-edit-mode")),u.edit(this),t.handled=!0)}),i.on("change","select.tabledit-input:visible",function(){event.handled!==!0&&(b.submit(t(this).parent("td")),event.handled=!0)}),t(document).on("click",function(t){var e=i.find(".tabledit-edit-mode");e.is(t.target)||0!==e.has(t.target).length||b.reset(i.find(".tabledit-input:visible").parent("td"))})),t(document).on("keyup",function(t){var e=i.find(".tabledit-input:visible"),n=i.find(".tabledit-confirm-button");if(e.length>0)var a=e.parents("td");else{if(!(n.length>0))return;var a=n.parents("td")}switch(t.keyCode){case 9:d.editButton||(b.submit(a),u.edit(a.closest("td").next()));break;case 13:b.submit(a);break;case 27:b.reset(a),c.reset(a)}}),this}}(jQuery); \ No newline at end of file diff --git a/public/misc/script.translation.js b/public/misc/script.translation.js index 7566134..1c1de54 100644 --- a/public/misc/script.translation.js +++ b/public/misc/script.translation.js @@ -1,8 +1,8 @@ var locales = { en: { - button_add: "add", + button_new: "new", + button_save: "save", button_cancel: "cancel", - button_continue: "continue", button_delete: "delete", button_login: "login", heading_error: "ERROR!", @@ -13,9 +13,9 @@ var locales = { span_loggedinas: "Logged in as" }, nl: { - button_add: "voeg toe", - button_cancel: "annuleer", - button_continue: "doorgaan", + button_new: "nieuw", + button_save: "opslaan", + button_cancel: "annuleren", button_delete: "verwijder", button_login: "log in", heading_error: "FOUT!", @@ -37,11 +37,11 @@ $(document).ready(function(){ // Enable/disable (toggle) anchors $('span#user a.current').removeClass('current'); $(this).addClass('current'); - + // Store current languagesetting in persistent localstorage localStorage.setItem('language', selectedlang); }); - + if (localStorage.getItem('language') !== null) { $('[data-translation]').each(function(index) { $(this).text(locales[localStorage.getItem('language')][$(this).data('translation')]); diff --git a/public/misc/style.css b/public/misc/style.css index 1a60e11..1bf0cd9 100644 --- a/public/misc/style.css +++ b/public/misc/style.css @@ -96,64 +96,50 @@ body { .main { clear: both; } - .main fieldset { - border: 0; - } - .main fieldset legend { - visibility: hidden; - } - .main fieldset label.pre { + .main section { + clear: both; + } + .main section label.pre { display: inline-block; width: 155px; text-align: right; vertical-align: top; margin-top: 3px; } - .main fieldset label#labelallaliases { - float: left; - } - .main fieldset output#aliasstats { - float: left; - clear: left; - width: 160px; - text-align: right; - font-size: 12px; - } - .main fieldset output#aliasstats:after { - margin-left: 7px; - content: ' '; - } - .main fieldset input { + .main section input { border: 1px solid #003399; padding: 2px; width: 100px; } - .main fieldset input[type=radio] { + .main section input[type=radio] { border: none; margin-top: 7px; width: 20px; } - .main fieldset button { + .main section button { margin-left: 160px; text-transform: uppercase; } - .main fieldset select { - border: 1px solid #003399; - padding: 2px; - width: 375px; - } - .main fieldset select .new { - font-weight: bold; - } - .main fieldset select .deleted { - text-decoration: line-through; - } - .main fieldset#signup label.pre { - width: 205px; - } - .main fieldset#signup span.indent, .main fieldset#signup input.button { - margin-left: 210px; - } + .main section .buttons { + text-align: center; + } + .main section .buttons button { + margin-left: inherit; + } + .main section table { + width: 100%; + } + .main section table * { + font-size: 12px; + padding: 2px; + margin: 0; + } + .main section table tbody tr:nth-child(odd) { + background-color: rgb(215, 215, 215); + } + .main section table .immutable { + cursor: default !important; + } .main li { list-style: none; padding: 5px;