From 1ffa1641607821c543deb2292e5a7dd1d88eca2d Mon Sep 17 00:00:00 2001 From: djpbessems Date: Mon, 25 Feb 2019 15:00:32 +0100 Subject: [PATCH 1/7] Added placeholder management page (usermanagement, dbmanagement) --- README.md | 2 +- include/lucidAuth.template.php | 3 +-- public/lucidAuth.login.php | 22 +++++++++++++++------- public/lucidAuth.manage.php | 19 +++++++++++++++++++ public/misc/script.manage.js | 0 5 files changed, 36 insertions(+), 10 deletions(-) create mode 100644 public/lucidAuth.manage.php create mode 100644 public/misc/script.manage.js diff --git a/README.md b/README.md index c8c5c49..18d6b8f 100644 --- a/README.md +++ b/README.md @@ -29,4 +29,4 @@ Forward Authentication for use with proxies (caddy, nginx, traefik, etc) The domainname of the website made in step 3, needs to match the domainname (*ignoring subdomains, if any*) of the resource utilizing this authentication proxy. ## Questions or bugs -Feel free to open issues in this repository (or in its mirror on [GitHub](#)). \ No newline at end of file +Feel free to open issues in this repository. \ No newline at end of file diff --git a/include/lucidAuth.template.php b/include/lucidAuth.template.php index f0ce42a..cedb154 100644 --- a/include/lucidAuth.template.php +++ b/include/lucidAuth.template.php @@ -81,7 +81,7 @@ $contentLayout['login'] = << LOGIN; -$contentLayout['manage'] = << Ingelogd als {$_SESSION['fullname']} --- [Browser plugin
Select browser:[v0.2.122.4]
] [EN NL] [Log uit]
-MANAGE; - -$contentLayout['dialog'] = << -
  • - -
  • -
  • - -
  • - -DIALOG; - + + + + + lucidAuth + + + + + + + + + + + + + +
    +
    + +
    + %1$s +
    +
    +
    + + +FULL; + +$pageLayout['bare'] = <<<'BARE' + + + + + lucidAuth + + + + + + %1$s + + +BARE; + +$contentLayout['login'] = <<<'LOGIN' + +
    + Login Details +
      +
    • + + + +
    • +
    • + + +
    • +
    • + + +
    • +
    • +   +
    • +
    • + Inloggegevens verkrijgbaar op aanvraag! +
    • +
    +
    + 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/lucidAuth.config.php.example b/lucidAuth.config.php.example index 6a2abb5..167797b 100644 --- a/lucidAuth.config.php.example +++ b/lucidAuth.config.php.example @@ -1,53 +1,53 @@ - [ - 'Server' => 'server.domain.tld', - // FQDN of the LDAP-server - 'Port' => 389, - // Port of the LDAP-server; default port is 389 - 'BaseDN' => 'OU=Users,DC=domain,DC=tld', - // Location of your useraccounts - // Syntax: - // 'OU=container,DC=domain,DC=tld' - 'Domain' => 'domain' - // Specify the NetBios name of the domain; to allow users to log on with just their usernames. - ], - - 'Sqlite' => [ - 'Path' => '../data/lucidAuth.sqlite.db' - // Relative path to the location where the database should be stored - ], - - 'JWT' => [ - 'PrivateKey_base64' => '', - // A base64-encoded random (preferably long) string (see https://www.base64encode.org/) - 'Algorithm' => [ - 'HS256', - ] - ], - - 'Session' => [ - 'Duration' => 2592000, - // In seconds (2592000 is equivalent to 30 days) - 'CrossDomainLogin' => False, - // Set this to True if SingleSignOn (albeit rudementary) is desired - // (cookies are inheritently unaware of each other; clearing cookies for one domain does not affect other domains) - 'CookieDomains' => [ - 'domain1.tld' #, 'domain2.tld', 'subdomain.domain3.tld' - ] - // Domain(s) that will be used to set cookie-domains to - // (multiple domains are allowed; remove the '#' above) - ], - - 'Debug' => [ - 'Verbose' => False, - 'LogToFile' => False - ] -); - + [ + 'Server' => 'server.domain.tld', + // FQDN of the LDAP-server + 'Port' => 389, + // Port of the LDAP-server; default port is 389 + 'BaseDN' => 'OU=Users,DC=domain,DC=tld', + // Location of your useraccounts + // Syntax: + // 'OU=container,DC=domain,DC=tld' + 'Domain' => 'domain' + // Specify the NetBios name of the domain; to allow users to log on with just their usernames. + ], + + 'Sqlite' => [ + 'Path' => '../data/lucidAuth.sqlite.db' + // Relative path to the location where the database should be stored + ], + + 'JWT' => [ + 'PrivateKey_base64' => '', + // A base64-encoded random (preferably long) string (see https://www.base64encode.org/) + 'Algorithm' => [ + 'HS256', + ] + ], + + 'Session' => [ + 'Duration' => 2592000, + // In seconds (2592000 is equivalent to 30 days) + 'CrossDomainLogin' => False, + // Set this to True if SingleSignOn (albeit rudementary) is desired + // (cookies are inheritently unaware of each other; clearing cookies for one domain does not affect other domains) + 'CookieDomains' => [ + 'domain1.tld' #, 'domain2.tld', 'subdomain.domain3.tld' + ] + // Domain(s) that will be used to set cookie-domains to + // (multiple domains are allowed; remove the '#' above) + ], + + 'Debug' => [ + 'Verbose' => False, + 'LogToFile' => False + ] +); + ?> \ No newline at end of file diff --git a/public/example.php b/public/example.php new file mode 100644 index 0000000..c31adb3 --- /dev/null +++ b/public/example.php @@ -0,0 +1,27 @@ + '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.login.php b/public/lucidAuth.login.php index 005013a..cf55df8 100644 --- a/public/lucidAuth.login.php +++ b/public/lucidAuth.login.php @@ -1,61 +1,73 @@ -LDAP['Domain'] . '\\' . $_POST['username'], $_SERVER['HTTP_HOST'])['status'] !== 'Success') { - // Since this action is only ever called through an AJAX-request; return JSON object - echo '{"Result":"Fail","Reason":"Failed storing authentication token in database and/or cookie"}' . PHP_EOL; - exit; - } - - // Convert base64 encoded string back from JSON; - // forcing it into an associative array (instead of javascript's default StdClass object) - try { - $proxyHeaders = json_decode(base64_decode($_POST['ref']), JSON_OBJECT_AS_ARRAY); - } - catch (Exception $e) { - // Since this action is only ever called through an AJAX-request; return JSON object - echo '{"Result":"Fail","Reason":"Original request URI lost in transition"}' . PHP_EOL; - exit; - } - $originalUri = !empty($proxyHeaders) ? $proxyHeaders['XForwardedProto'] . '://' . $proxyHeaders['XForwardedHost'] . $proxyHeaders['XForwardedUri'] : 'lucidAuth.manage.php'; - - // Since this request is only ever called through an AJAX-request; return JSON object - header('Content-Type: application/json'); - echo json_encode([ - "Result" => "Success", - "Location" => $originalUri, - "CrossDomainLogin" => $settings->Session['CrossDomainLogin'] - ]); - } else { - switch ($result['reason']) { - case '1': - header('Content-Type: application/json'); - echo json_encode([ - "Result" => "Failure", - "Reason" => "Invalid username and/or password" - ]); -# echo '{"Result":"Fail","Reason":"Invalid username and/or password"}' . PHP_EOL; - break; - default: - header('Content-Type: application/json'); - echo json_encode([ - "Result" => "Failure", - "Reason" => "Uncaught error" - ]); -# echo '{"Result":"Fail","Reason":"Uncaught error"}' . PHP_EOL; - break; - } - } - } else { - include_once('../include/lucidAuth.template.php'); - - echo sprintf($pageLayout['full'], $contentLayout['login']); - } - +LDAP['Domain'] . '\\' . $_POST['username'], $_SERVER['HTTP_HOST'])['status'] !== 'Success') { + // Return JSON object + header('Content-Type: application/json'); + echo json_encode([ + "Result" => "Failure", + "Reason" => "Failed storing authentication token in database and/or cookie" + ]); +# echo '{"Result":"Fail","Reason":"Failed storing authentication token in database and/or cookie"}' . PHP_EOL; + exit; + } + + // Convert base64 encoded string back from JSON; + // forcing it into an associative array (instead of javascript's default StdClass object) + try { + $proxyHeaders = json_decode(base64_decode($_POST['ref']), JSON_OBJECT_AS_ARRAY); + } + catch (Exception $e) { + // Return JSON object + header('Content-Type: application/json'); + echo json_encode([ + "Result" => "Failure", + "Reason" => "Original request-URI lost in transition" + ]); +# echo '{"Result":"Fail","Reason":"Original request URI lost in transition"}' . PHP_EOL; + exit; + } + $originalUri = !empty($proxyHeaders) ? $proxyHeaders['XForwardedProto'] . '://' . $proxyHeaders['XForwardedHost'] . $proxyHeaders['XForwardedUri'] : 'lucidAuth.manage.php'; + + // Return JSON object + header('Content-Type: application/json'); + echo json_encode([ + "Result" => "Success", + "Location" => $originalUri, + "CrossDomainLogin" => $settings->Session['CrossDomainLogin'] + ]); + } else { + switch ($result['reason']) { + case '1': + header('Content-Type: application/json'); + echo json_encode([ + "Result" => "Failure", + "Reason" => "Invalid username and/or password" + ]); + break; + default: + header('Content-Type: application/json'); + echo json_encode([ + "Result" => "Failure", + "Reason" => "Uncaught error" + ]); + break; + } + } + } else { + include_once('../include/lucidAuth.template.php'); + + echo sprintf($pageLayout['full'], + sprintf($contentLayout['login'], + $_GET['ref'] + ) + ); + } + ?> \ No newline at end of file diff --git a/public/lucidAuth.manage.php b/public/lucidAuth.manage.php index 4d82869..3a052c4 100644 --- a/public/lucidAuth.manage.php +++ b/public/lucidAuth.manage.php @@ -1,19 +1,27 @@ - \ No newline at end of file diff --git a/public/lucidAuth.setXDomainCookie.php b/public/lucidAuth.setXDomainCookie.php index ba423c0..c3ab1f8 100644 --- a/public/lucidAuth.setXDomainCookie.php +++ b/public/lucidAuth.setXDomainCookie.php @@ -1,24 +1,24 @@ -Session['CookieDomains'] and iterate through the remaining domains, serving them in one page (which contains iframes already) - // this might be slower because it means one additional roundtrip between client and server - - // approach 2: - // let the client setup multiple iframes for all domains other than origin domains - // this requires passing an array of domains to the client in asynchronous reply; which feels insecure - - include_once('../include/lucidAuth.template.php'); - - echo sprintf($pageLayout['bare', - '// iFrames go here' - ); +Session['CookieDomains'] and iterate through the remaining domains, serving them in one page (which contains iframes already) + // this might be slower because it means one additional roundtrip between client and server + + // approach 2: + // let the client setup multiple iframes for all domains other than origin domains + // this requires passing an array of domains to the client in asynchronous reply; which feels insecure + + include_once('../include/lucidAuth.template.php'); + + echo sprintf($pageLayout['bare'], + '// iFrames go here' + ); ?> \ No newline at end of file diff --git a/public/lucidAuth.validateRequest.php b/public/lucidAuth.validateRequest.php index 0075d4d..289561d 100644 --- a/public/lucidAuth.validateRequest.php +++ b/public/lucidAuth.validateRequest.php @@ -1,42 +1,42 @@ - $value) { - if (strpos($key, 'HTTP_') === 0) { - // Trim and then convert all headers to camelCase - $proxyHeaders[str_replace(' ', '', ucwords(str_replace('_', ' ', strtolower(substr($key, 5)))))] = $value; - } - } - // Keep only headers relevant for proxying - $proxyHeaders = array_filter($proxyHeaders, function ($key) { - return substr($key, 0, 10) === 'XForwarded'; - }, ARRAY_FILTER_USE_KEY); - - // For debugging purposes - enable it in ../lucidAuth.config.php - if ($settings->Debug['LogToFile']) { - file_put_contents('../requestHeaders.log', (new DateTime())->format('Y-m-d\TH:i:s.u') . ' --- ' . (json_encode($proxyHeaders, JSON_FORCE_OBJECT)) . PHP_EOL, FILE_APPEND); - } - - if (sizeof($proxyHeaders) === 0) { - // Non-proxied request; this is senseless, go fetch! - header("HTTP/1.1 403 Forbidden"); - exit; - } - - if (!empty($_COOKIE['JWT']) && validateToken($_COOKIE['JWT'])['status'] === "Success") { - // Valid authentication token found - header("HTTP/1.1 202 Accepted"); - exit; - } else { - // No cookie containing valid authentication token found; - // explicitly deleting any remaining cookie, then redirecting to loginpage - setcookie('JWT', FALSE); - - header("HTTP/1.1 401 Unauthorized"); - header("Location: lucidAuth.login.php?ref=" . base64_encode(json_encode($proxyHeaders))); - } - + $value) { + if (strpos($key, 'HTTP_') === 0) { + // Trim and then convert all headers to camelCase + $proxyHeaders[str_replace(' ', '', ucwords(str_replace('_', ' ', strtolower(substr($key, 5)))))] = $value; + } + } + // Keep only headers relevant for proxying + $proxyHeaders = array_filter($proxyHeaders, function ($key) { + return substr($key, 0, 10) === 'XForwarded'; + }, ARRAY_FILTER_USE_KEY); + + // For debugging purposes - enable it in ../lucidAuth.config.php + if ($settings->Debug['LogToFile']) { + file_put_contents('../requestHeaders.log', (new DateTime())->format('Y-m-d\TH:i:s.u') . ' --- ' . (json_encode($proxyHeaders, JSON_FORCE_OBJECT)) . PHP_EOL, FILE_APPEND); + } + + if (sizeof($proxyHeaders) === 0) { + // Non-proxied request; this is senseless, go fetch! + header("HTTP/1.1 403 Forbidden"); + exit; + } + + if (!empty($_COOKIE['JWT']) && validateToken($_COOKIE['JWT'])['status'] === "Success") { + // Valid authentication token found + header("HTTP/1.1 202 Accepted"); + exit; + } else { + // No cookie containing valid authentication token found; + // explicitly deleting any remaining cookie, then redirecting to loginpage + setcookie('JWT', FALSE); + + header("HTTP/1.1 401 Unauthorized"); + header("Location: lucidAuth.login.php?ref=" . base64_encode(json_encode($proxyHeaders))); + } + ?> \ No newline at end of file diff --git a/public/misc/script.index.js b/public/misc/script.index.js index 782dcd2..5da41bd 100644 --- a/public/misc/script.index.js +++ b/public/misc/script.index.js @@ -1,57 +1,57 @@ -$(document).ready(function(){ - // Allow user to press enter to submit credentials - $('#username, #password').keypress(function(event) { - if (event.which === 13) { - $('#btnlogin').trigger('click'); - } - }); - - $('#btnlogin').click(function() { - // Give feedback that request has been submitted (and prevent repeated requests) - $('#btnlogin').prop('disabled', true).css({ - 'background': '#999 url(data:image/gif;base64,R0lGODlhEAAQAPIAAJmZmf///7CwsOPj4////9fX18rKysPDwyH+GkNyZWF0ZWQgd2l0aCBhamF4bG9hZC5pbmZvACH5BAAKAAAAIf8LTkVUU0NBUEUyLjADAQAAACwAAAAAEAAQAAADMwi63P4wyklrE2MIOggZnAdOmGYJRbExwroUmcG2LmDEwnHQLVsYOd2mBzkYDAdKa+dIAAAh+QQACgABACwAAAAAEAAQAAADNAi63P5OjCEgG4QMu7DmikRxQlFUYDEZIGBMRVsaqHwctXXf7WEYB4Ag1xjihkMZsiUkKhIAIfkEAAoAAgAsAAAAABAAEAAAAzYIujIjK8pByJDMlFYvBoVjHA70GU7xSUJhmKtwHPAKzLO9HMaoKwJZ7Rf8AYPDDzKpZBqfvwQAIfkEAAoAAwAsAAAAABAAEAAAAzMIumIlK8oyhpHsnFZfhYumCYUhDAQxRIdhHBGqRoKw0R8DYlJd8z0fMDgsGo/IpHI5TAAAIfkEAAoABAAsAAAAABAAEAAAAzIIunInK0rnZBTwGPNMgQwmdsNgXGJUlIWEuR5oWUIpz8pAEAMe6TwfwyYsGo/IpFKSAAAh+QQACgAFACwAAAAAEAAQAAADMwi6IMKQORfjdOe82p4wGccc4CEuQradylesojEMBgsUc2G7sDX3lQGBMLAJibufbSlKAAAh+QQACgAGACwAAAAAEAAQAAADMgi63P7wCRHZnFVdmgHu2nFwlWCI3WGc3TSWhUFGxTAUkGCbtgENBMJAEJsxgMLWzpEAACH5BAAKAAcALAAAAAAQABAAAAMyCLrc/jDKSatlQtScKdceCAjDII7HcQ4EMTCpyrCuUBjCYRgHVtqlAiB1YhiCnlsRkAAAOwAAAAAAAAAAAA==) no-repeat center', - 'color': 'transparent', - 'transform': 'rotateX(180deg)' - }); - $.post("lucidAuth.login.php", { - do: "login", - username: $('#username').val(), - password: $('#password').val(), - ref: $('#ref').val() - }) - .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', - 'transform': 'rotateX(0deg)' - }); - setTimeout(function() { - $('#btnlogin').prop('disabled', false).css({ - 'background': '#003399 linear-gradient(0deg, rgba(255,255,255,0) 0%, rgba(255,255,255,0) 50%, rgba(255,255,255,0.25) 51%) no-repeat center', - 'color': '#FFF' - }); - if (data.CrossDomainLogin) { - // Create iframes for other domains -console.log('CrossDomainLogin initiated'); - } -console.log("Navigating to :" + data.Location); - window.location.replace(data.Location); - }, 2250); - } else { - $('#btnlogin').css({ - 'background': 'red url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAv0lEQVQ4jaWT0Q3CMAxELwh1BEag87AJ6hcLlE/KBLABrNEV2h26QaXHj4NMGgpS7sfJJXd24kQqRMiRQC3pIKk2apD0DCEMq25ABZyBmSVmW6vWxH1GmKLPmph7xJQReq5dnNmVPQE7oHOCzrhoMts9vQ1OSbYOCBb92OPkDe6ZkqMwJwa4SdJmtS1/YGsx7e9VUiPpYvPG4tHtGUsvcf+RkpI2mkHZQ3ImLd+fcpuKf32meM5R0iOEMOb2F+EF33vgCePVr8UAAAAASUVORK5CYII=) no-repeat center', - 'transform': 'rotateX(0deg)' - }); - setTimeout(function() { - $('#btnlogin').prop('disabled', false).css({ - 'background': '#003399 linear-gradient(0deg, rgba(255,255,255,0) 0%, rgba(255,255,255,0) 50%, rgba(255,255,255,0.25) 51%) no-repeat center', - 'color': '#FFF' - }); - // TODO: Add feedback (based on data.Reason) - // Is the redirect needed? - window.location.replace('lucidAuth.login.php'/*+ '?reason=' + data.Reason*/); - }, 2250); - } - }); - }); +$(document).ready(function(){ + // Allow user to press enter to submit credentials + $('#username, #password').keypress(function(event) { + if (event.which === 13) { + $('#btnlogin').trigger('click'); + } + }); + + $('#btnlogin').click(function() { + // Give feedback that request has been submitted (and prevent repeated requests) + $('#btnlogin').prop('disabled', true).css({ + 'background': '#999 url(data:image/gif;base64,R0lGODlhEAAQAPIAAJmZmf///7CwsOPj4////9fX18rKysPDwyH+GkNyZWF0ZWQgd2l0aCBhamF4bG9hZC5pbmZvACH5BAAKAAAAIf8LTkVUU0NBUEUyLjADAQAAACwAAAAAEAAQAAADMwi63P4wyklrE2MIOggZnAdOmGYJRbExwroUmcG2LmDEwnHQLVsYOd2mBzkYDAdKa+dIAAAh+QQACgABACwAAAAAEAAQAAADNAi63P5OjCEgG4QMu7DmikRxQlFUYDEZIGBMRVsaqHwctXXf7WEYB4Ag1xjihkMZsiUkKhIAIfkEAAoAAgAsAAAAABAAEAAAAzYIujIjK8pByJDMlFYvBoVjHA70GU7xSUJhmKtwHPAKzLO9HMaoKwJZ7Rf8AYPDDzKpZBqfvwQAIfkEAAoAAwAsAAAAABAAEAAAAzMIumIlK8oyhpHsnFZfhYumCYUhDAQxRIdhHBGqRoKw0R8DYlJd8z0fMDgsGo/IpHI5TAAAIfkEAAoABAAsAAAAABAAEAAAAzIIunInK0rnZBTwGPNMgQwmdsNgXGJUlIWEuR5oWUIpz8pAEAMe6TwfwyYsGo/IpFKSAAAh+QQACgAFACwAAAAAEAAQAAADMwi6IMKQORfjdOe82p4wGccc4CEuQradylesojEMBgsUc2G7sDX3lQGBMLAJibufbSlKAAAh+QQACgAGACwAAAAAEAAQAAADMgi63P7wCRHZnFVdmgHu2nFwlWCI3WGc3TSWhUFGxTAUkGCbtgENBMJAEJsxgMLWzpEAACH5BAAKAAcALAAAAAAQABAAAAMyCLrc/jDKSatlQtScKdceCAjDII7HcQ4EMTCpyrCuUBjCYRgHVtqlAiB1YhiCnlsRkAAAOwAAAAAAAAAAAA==) no-repeat center', + 'color': 'transparent', + 'transform': 'rotateX(180deg)' + }); + $.post("lucidAuth.login.php", { + do: "login", + username: $('#username').val(), + password: $('#password').val(), + ref: $('#ref').val() + }) + .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', + 'transform': 'rotateX(0deg)' + }); + setTimeout(function() { + $('#btnlogin').prop('disabled', false).css({ + 'background': '#003399 linear-gradient(0deg, rgba(255,255,255,0) 0%, rgba(255,255,255,0) 50%, rgba(255,255,255,0.25) 51%) no-repeat center', + 'color': '#FFF' + }); + if (data.CrossDomainLogin) { + // Create iframes for other domains +console.log('CrossDomainLogin initiated'); + } +console.log("Navigating to :" + data.Location); + window.location.replace(data.Location); + }, 2250); + } else { + $('#btnlogin').css({ + 'background': 'red url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAv0lEQVQ4jaWT0Q3CMAxELwh1BEag87AJ6hcLlE/KBLABrNEV2h26QaXHj4NMGgpS7sfJJXd24kQqRMiRQC3pIKk2apD0DCEMq25ABZyBmSVmW6vWxH1GmKLPmph7xJQReq5dnNmVPQE7oHOCzrhoMts9vQ1OSbYOCBb92OPkDe6ZkqMwJwa4SdJmtS1/YGsx7e9VUiPpYvPG4tHtGUsvcf+RkpI2mkHZQ3ImLd+fcpuKf32meM5R0iOEMOb2F+EF33vgCePVr8UAAAAASUVORK5CYII=) no-repeat center', + 'transform': 'rotateX(0deg)' + }); + setTimeout(function() { + $('#btnlogin').prop('disabled', false).css({ + 'background': '#003399 linear-gradient(0deg, rgba(255,255,255,0) 0%, rgba(255,255,255,0) 50%, rgba(255,255,255,0.25) 51%) no-repeat center', + 'color': '#FFF' + }); + // TODO: Add feedback (based on data.Reason) + // Is the redirect needed? + window.location.replace('lucidAuth.login.php'/*+ '?reason=' + data.Reason*/); + }, 2250); + } + }); + }); }); \ No newline at end of file diff --git a/public/misc/script.table.min.js b/public/misc/script.table.min.js new file mode 100644 index 0000000..2d4b259 --- /dev/null +++ b/public/misc/script.table.min.js @@ -0,0 +1,6 @@ +/*! + * 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.theme.js b/public/misc/script.theme.js index 7ebde0b..5532021 100644 --- a/public/misc/script.theme.js +++ b/public/misc/script.theme.js @@ -1,19 +1,19 @@ -$(document).ready(function() { - if (localStorage.getItem('theme') != '') { - $('html').addClass(localStorage.getItem('theme')); - } - - $('.logo .sub').on('click', function(event) { - if (event.ctrlKey) { - var classes = ["tablecloth", "weave", "madras", "tartan", "seigaiha"]; - var selectedTheme = classes[~~(Math.random()*classes.length)]; - - $('html').removeClass().addClass(selectedTheme); - localStorage.setItem('theme', selectedTheme); - } - if (event.altKey) { - $('html').removeClass(); - localStorage.removeItem('theme'); - } - }); +$(document).ready(function() { + if (localStorage.getItem('theme') != '') { + $('html').addClass(localStorage.getItem('theme')); + } + + $('.logo .sub').on('click', function(event) { + if (event.ctrlKey) { + var classes = ["tablecloth", "weave", "madras", "tartan", "seigaiha"]; + var selectedTheme = classes[~~(Math.random()*classes.length)]; + + $('html').removeClass().addClass(selectedTheme); + localStorage.setItem('theme', selectedTheme); + } + if (event.altKey) { + $('html').removeClass(); + localStorage.removeItem('theme'); + } + }); }); \ No newline at end of file diff --git a/public/misc/script.translation.js b/public/misc/script.translation.js index ee56a89..7566134 100644 --- a/public/misc/script.translation.js +++ b/public/misc/script.translation.js @@ -8,13 +8,9 @@ var locales = { heading_error: "ERROR!", label_password: "Password:", label_username: "Username:", - label_selectbrowser: "Select browser:", - link_install: "Install!", link_logout: "Logout", - link_plugin: "Browser plugin", span_credentialsavailable: "Login credentials available upon request!", - span_loggedinas: "Logged in as", - span_plugin: "Browser plugin?" + span_loggedinas: "Logged in as" }, nl: { button_add: "voeg toe", @@ -25,13 +21,9 @@ var locales = { heading_error: "FOUT!", label_password: "Wachtwoord:", label_username: "Gebruikersnaam:", - label_selectbrowser: "Selecteer browser:", - link_install: "Installeer!", link_logout: "Log uit", - link_plugin: "Browser plugin", span_credentialsavailable: "Inloggegevens verkrijgbaar op aanvraag!", - span_loggedinas: "Ingelogd als", - span_plugin: "Browser plugin?" + span_loggedinas: "Ingelogd als" } // ... etc. }; diff --git a/public/misc/style.button.css b/public/misc/style.button.css index 89ea54a..1708c25 100644 --- a/public/misc/style.button.css +++ b/public/misc/style.button.css @@ -1,139 +1,139 @@ -@charset "UTF-8"; -/*! - * - * bttn.css - https://ganapativs.github.io/bttn.css - * Version - 0.2.4 - * Demo: https://bttn.surge.sh - * - * Licensed under the MIT license - http://opensource.org/licenses/MIT - * - * Copyright (c) 2016 Ganapati V S (@ganapativs) - * - */ -/* standalone - .bttn-simple */ -.bttn-default { - color: #fff; -} -.bttn-primary, -.bttn, -.bttn-lg, -.bttn-md, -.bttn-sm, -.bttn-xs { - color: #1d89ff; -} -.bttn-warning { - color: #feab3a; -} -.bttn-danger { - color: #ff5964; -} -.bttn-success { - color: #28b78d; -} -.bttn-royal { - color: #bd2df5; -} -.bttn, -.bttn-lg, -.bttn-md, -.bttn-sm, -.bttn-xs { - margin: 0; - padding: 0; - border-width: 0; - border-color: transparent; - background: transparent; - font-weight: 400; - cursor: pointer; - position: relative; -} -.bttn-lg { - padding: 8px 15px; - font-size: 24px; - font-family: inherit; -} -.bttn-md { - font-size: 20px; - font-family: inherit; - padding: 5px 12px; -} -.bttn-sm { - padding: 4px 10px; - font-size: 16px; - font-family: inherit; -} -.bttn-xs { - padding: 3px 8px; - font-size: 12px; - font-family: inherit; -} -.bttn-simple { - margin: 0; - padding: 0; - border-width: 0; - border-color: transparent; - border-radius: 4px; - background: transparent; - font-weight: 400; - cursor: pointer; - position: relative; - font-size: 20px; - font-family: inherit; - padding: 5px 12px; - overflow: hidden; - background: rgba(255,255,255,0.4); - color: #fff; - -webkit-transition: all 0.3s cubic-bezier(0.02, 0.01, 0.47, 1); - transition: all 0.3s cubic-bezier(0.02, 0.01, 0.47, 1); -} -.bttn-simple:hover, -.bttn-simple:focus { - opacity: 0.75; -} -.bttn-simple.bttn-xs { - padding: 3px 8px; - font-size: 12px; - font-family: inherit; -} -.bttn-simple.bttn-sm { - padding: 4px 10px; - font-size: 16px; - font-family: inherit; -} -.bttn-simple.bttn-md { - font-size: 20px; - font-family: inherit; - padding: 5px 12px; -} -.bttn-simple.bttn-lg { - padding: 8px 15px; - font-size: 24px; - font-family: inherit; -} -.bttn-simple.bttn-default { - background: rgba(255,255,255,0.4); -} -.bttn-simple.bttn-primary { - background: #003399; - background-image: linear-gradient(0deg, rgba(255,255,255,0) 0%, rgba(255,255,255,0) 50%, rgba(255,255,255,0.25) 51%); -} -.bttn-simple.bttn-warning { - background: #feab3a; -} -.bttn-simple.bttn-danger { - background: #ff5964; -} -.bttn-simple.bttn-success { - background: #28b78d; -} -.bttn-simple.bttn-royal { - background: #bd2df5; -} -.bttn-simple.disabled { - background: #999 !important; - color: rgba(255,255,255,0.625); - cursor: default; - text-shadow: 0.375px 0.375px 0 rgba(140,140,140,0.6), -0.375px -0.375px 0.375px rgba(0,0,0,0.67); - opacity: 1; -} +@charset "UTF-8"; +/*! + * + * bttn.css - https://ganapativs.github.io/bttn.css + * Version - 0.2.4 + * Demo: https://bttn.surge.sh + * + * Licensed under the MIT license - http://opensource.org/licenses/MIT + * + * Copyright (c) 2016 Ganapati V S (@ganapativs) + * + */ +/* standalone - .bttn-simple */ +.bttn-default { + color: #fff; +} +.bttn-primary, +.bttn, +.bttn-lg, +.bttn-md, +.bttn-sm, +.bttn-xs { + color: #1d89ff; +} +.bttn-warning { + color: #feab3a; +} +.bttn-danger { + color: #ff5964; +} +.bttn-success { + color: #28b78d; +} +.bttn-royal { + color: #bd2df5; +} +.bttn, +.bttn-lg, +.bttn-md, +.bttn-sm, +.bttn-xs { + margin: 0; + padding: 0; + border-width: 0; + border-color: transparent; + background: transparent; + font-weight: 400; + cursor: pointer; + position: relative; +} +.bttn-lg { + padding: 8px 15px; + font-size: 24px; + font-family: inherit; +} +.bttn-md { + font-size: 20px; + font-family: inherit; + padding: 5px 12px; +} +.bttn-sm { + padding: 4px 10px; + font-size: 16px; + font-family: inherit; +} +.bttn-xs { + padding: 3px 8px; + font-size: 12px; + font-family: inherit; +} +.bttn-simple { + margin: 0; + padding: 0; + border-width: 0; + border-color: transparent; + border-radius: 4px; + background: transparent; + font-weight: 400; + cursor: pointer; + position: relative; + font-size: 20px; + font-family: inherit; + padding: 5px 12px; + overflow: hidden; + background: rgba(255,255,255,0.4); + color: #fff; + -webkit-transition: all 0.3s cubic-bezier(0.02, 0.01, 0.47, 1); + transition: all 0.3s cubic-bezier(0.02, 0.01, 0.47, 1); +} +.bttn-simple:hover, +.bttn-simple:focus { + opacity: 0.75; +} +.bttn-simple.bttn-xs { + padding: 3px 8px; + font-size: 12px; + font-family: inherit; +} +.bttn-simple.bttn-sm { + padding: 4px 10px; + font-size: 16px; + font-family: inherit; +} +.bttn-simple.bttn-md { + font-size: 20px; + font-family: inherit; + padding: 5px 12px; +} +.bttn-simple.bttn-lg { + padding: 8px 15px; + font-size: 24px; + font-family: inherit; +} +.bttn-simple.bttn-default { + background: rgba(255,255,255,0.4); +} +.bttn-simple.bttn-primary { + background: #003399; + background-image: linear-gradient(0deg, rgba(255,255,255,0) 0%, rgba(255,255,255,0) 50%, rgba(255,255,255,0.25) 51%); +} +.bttn-simple.bttn-warning { + background: #feab3a; +} +.bttn-simple.bttn-danger { + background: #ff5964; +} +.bttn-simple.bttn-success { + background: #28b78d; +} +.bttn-simple.bttn-royal { + background: #bd2df5; +} +.bttn-simple.disabled { + background: #999 !important; + color: rgba(255,255,255,0.625); + cursor: default; + text-shadow: 0.375px 0.375px 0 rgba(140,140,140,0.6), -0.375px -0.375px 0.375px rgba(0,0,0,0.67); + opacity: 1; +} diff --git a/public/misc/style.css b/public/misc/style.css index 186b31d..1a60e11 100644 --- a/public/misc/style.css +++ b/public/misc/style.css @@ -1,238 +1,238 @@ -* { - font-family: Tahoma, sans-serif; - font-size: 16px; - margin: 0; - padding: 0; -} -body { - color: #000000; - background-color: #333333; - margin: 0px; -} -#horizon { - text-align: center; - position: absolute; - top: 50%; - left: 0px; - width: 100%; - height: 1px; - overflow: visible; - visibility: visible; - display: block; -} -#content { - background: url(/images/bg_main_bottom.gif) repeat-x bottom left; - font-family: Tahoma, sans-serif; - border: 3px solid #CCCCCC; - background-color: #FFFFFF; - position: absolute; - left: 50%; - visibility: visible; - border-radius: 5px; - top: -125px; - margin-left: -225px; - height: 220px; - width: 450px; -} - #error .main { - padding: 0 10px; - } - #error ol { - margin: 10px 0; - } - #error span { - margin: 0; - } - #error button { - text-transform: uppercase; - } -.logo { - background: url(/images/bg_header.gif) repeat-x top left; - height: 45px; - z-index: 50; - border-radius: 5px 5px 0 0; -} - .logo .left { - background: url(/images/bg_header_l.gif) no-repeat top left; - position: relative; - top: 4px; - left: 5px; - height: 49px; - float: left; - z-index: 48; - } - .logo .middle { - background: url(/images/bg_header_m.gif) no-repeat 25px 0; - margin: 0 5px; - padding: 5px 10px 0; - height: 49px; - float: left; - z-index: 49; - display: inline; - font-size: 18px; - font-weight: bold; - color: #FFFFFF; - } - .logo .right { - background: url(/images/bg_header_r.gif) no-repeat top left; - position: relative; - top: 4px; - height: 49px; - width: 5px; - float: left; - } - .logo .sub { - margin-top: 12px; - margin-left: 20px; - float: left; - display: inline; - font-size: 13px; - font-weight: bold; - color: #FFFFFF; - } - .logo .sub em { - font-size: 13px; - } -.main { - clear: both; -} - .main fieldset { - border: 0; - } - .main fieldset legend { - visibility: hidden; - } - .main fieldset 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 { - border: 1px solid #003399; - padding: 2px; - width: 100px; - } - .main fieldset input[type=radio] { - border: none; - margin-top: 7px; - width: 20px; - } - .main fieldset 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 li { - list-style: none; - padding: 5px; - text-align: left; - } - .main li.misc { - padding: 0 5px; - } - .main span, - .main strong, - .main a { - font-size: 12px; - } - .main span.indent { - color: #666666; - margin-left: 160px; - } - .main span.dialogdesc { - margin-left: 10px; - } - .main a:link, .main a:visited { - color: #003399; - text-decoration: none; - } - .main a:hover, .main a:active { - text-decoration: underline; - } - .main span#user { - color: #666666; - float: right; - margin: 0 5px 0 0; - } - .main span#user, - .main span#user a { - font-size: 12px; - } - .main span#user a:link, .main span#user a:visited { - color: #001177; - text-decoration: none; - } - .main span#user a:hover, .main span#user a:active { - text-decoration: underline; - } - .main span#user a.current { - text-decoration: none; - font-weight: 900; - cursor: default; - color: #666666; - } - .main span#user a.current:before { - content: '\00bb'; - font-weight: 100; - } - .main span#user a.current:after { - content: '\00ab'; - font-weight: 100; - } - .main span#user nav { - display: inline; - } - .main span#user #pluginlogos { - display: none; - position: absolute; - top: 72px; - right: 10px; - height: 112px; - width: 250px; - border: 1px solid rgb(0, 51, 153); - box-shadow: black 0px 0px 20px; - box-sizing: border-box; - padding-top: 5px; - background: white; - font-size: inherit; - font-weight: bold; - } - .main span#user #pluginlogos img { - width: 75px; - height: 75px; - filter: saturate(500%) contrast(200%) grayscale(100%) opacity(50%); - transition: all 375ms; - cursor: pointer; - } +* { + font-family: Tahoma, sans-serif; + font-size: 16px; + margin: 0; + padding: 0; +} +body { + color: #000000; + background-color: #333333; + margin: 0px; +} +#horizon { + text-align: center; + position: absolute; + top: 50%; + left: 0px; + width: 100%; + height: 1px; + overflow: visible; + visibility: visible; + display: block; +} +#content { + background: url(/images/bg_main_bottom.gif) repeat-x bottom left; + font-family: Tahoma, sans-serif; + border: 3px solid #CCCCCC; + background-color: #FFFFFF; + position: absolute; + left: 50%; + visibility: visible; + border-radius: 5px; + top: -125px; + margin-left: -225px; + height: 220px; + width: 450px; +} + #error .main { + padding: 0 10px; + } + #error ol { + margin: 10px 0; + } + #error span { + margin: 0; + } + #error button { + text-transform: uppercase; + } +.logo { + background: url(/images/bg_header.gif) repeat-x top left; + height: 45px; + z-index: 50; + border-radius: 5px 5px 0 0; +} + .logo .left { + background: url(/images/bg_header_l.gif) no-repeat top left; + position: relative; + top: 4px; + left: 5px; + height: 49px; + float: left; + z-index: 48; + } + .logo .middle { + background: url(/images/bg_header_m.gif) no-repeat 25px 0; + margin: 0 5px; + padding: 5px 10px 0; + height: 49px; + float: left; + z-index: 49; + display: inline; + font-size: 18px; + font-weight: bold; + color: #FFFFFF; + } + .logo .right { + background: url(/images/bg_header_r.gif) no-repeat top left; + position: relative; + top: 4px; + height: 49px; + width: 5px; + float: left; + } + .logo .sub { + margin-top: 12px; + margin-left: 20px; + float: left; + display: inline; + font-size: 13px; + font-weight: bold; + color: #FFFFFF; + } + .logo .sub em { + font-size: 13px; + } +.main { + clear: both; +} + .main fieldset { + border: 0; + } + .main fieldset legend { + visibility: hidden; + } + .main fieldset 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 { + border: 1px solid #003399; + padding: 2px; + width: 100px; + } + .main fieldset input[type=radio] { + border: none; + margin-top: 7px; + width: 20px; + } + .main fieldset 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 li { + list-style: none; + padding: 5px; + text-align: left; + } + .main li.misc { + padding: 0 5px; + } + .main span, + .main strong, + .main a { + font-size: 12px; + } + .main span.indent { + color: #666666; + margin-left: 160px; + } + .main span.dialogdesc { + margin-left: 10px; + } + .main a:link, .main a:visited { + color: #003399; + text-decoration: none; + } + .main a:hover, .main a:active { + text-decoration: underline; + } + .main span#user { + color: #666666; + float: right; + margin: 0 5px 0 0; + } + .main span#user, + .main span#user a { + font-size: 12px; + } + .main span#user a:link, .main span#user a:visited { + color: #001177; + text-decoration: none; + } + .main span#user a:hover, .main span#user a:active { + text-decoration: underline; + } + .main span#user a.current { + text-decoration: none; + font-weight: 900; + cursor: default; + color: #666666; + } + .main span#user a.current:before { + content: '\00bb'; + font-weight: 100; + } + .main span#user a.current:after { + content: '\00ab'; + font-weight: 100; + } + .main span#user nav { + display: inline; + } + .main span#user #pluginlogos { + display: none; + position: absolute; + top: 72px; + right: 10px; + height: 112px; + width: 250px; + border: 1px solid rgb(0, 51, 153); + box-shadow: black 0px 0px 20px; + box-sizing: border-box; + padding-top: 5px; + background: white; + font-size: inherit; + font-weight: bold; + } + .main span#user #pluginlogos img { + width: 75px; + height: 75px; + filter: saturate(500%) contrast(200%) grayscale(100%) opacity(50%); + transition: all 375ms; + cursor: pointer; + } diff --git a/public/misc/style.theme.css b/public/misc/style.theme.css index e446051..382eb0a 100644 --- a/public/misc/style.theme.css +++ b/public/misc/style.theme.css @@ -1,39 +1,39 @@ -html.tablecloth { - height: 100%; - background: repeating-linear-gradient(-45deg, transparent, transparent 1em, rgba(136, 136, 136, 0.4) 0, rgba(136, 136, 136, 0.1) 2em, transparent 0, transparent 1em, rgba(136, 136, 136, 0.3) 0, rgba(136, 136, 136, 0.2) 4em, transparent 0, transparent 1em, rgba(68, 68, 68, 0.6) 0, rgba(68, 68, 68, 0.2) 2em), - repeating-linear-gradient(45deg, transparent, transparent 1em, rgba(136, 136, 136, 0.4) 0, rgba(136, 136, 136, 0.1) 2em, transparent 0, transparent 1em, rgba(136, 136, 136, 0.3) 0, rgba(136, 136, 136, 0.2) 4em, transparent 0, transparent 1em, rgba(68, 68, 68, 0.4) 0, rgba(68, 68, 68, 0.1) 2em), #666; - background-blend-mode: multiply; -} - -html.weave { - background: linear-gradient(45deg, #666 12%, transparent 0, transparent 88%, #666 0), - linear-gradient(135deg, transparent 37%, #888 0, #888 63%, transparent 0), - linear-gradient(45deg, transparent 37%, #666 0, #666 63%, transparent 0), - #444; - background-size: 40px 40px; -} - -html.madras { - height: 100%; - background-color: #e9d4b9; - background-image: repeating-linear-gradient(45deg, transparent 5px, rgba(11, 36, 45, 0.5) 5px, rgba(11, 36, 45, 0.5) 10px, rgba(211, 119, 111, 0) 10px, rgba(211, 119, 111, 0) 35px, rgba(211, 119, 111, 0.5) 35px, rgba(211, 119, 111, 0.5) 40px, rgba(11, 36, 45, 0.5) 40px, rgba(11, 36, 45, 0.5) 50px, rgba(11, 36, 45, 0) 50px, rgba(11, 36, 45, 0) 60px, rgba(211, 119, 111, 0.5) 60px, rgba(211, 119, 111, 0.5) 70px, rgba(247, 179, 85, 0.5) 70px, rgba(247, 179, 85, 0.5) 80px, rgba(247, 179, 85, 0) 80px, rgba(247, 179, 85, 0) 90px, rgba(211, 119, 111, 0.5) 90px, rgba(211, 119, 111, 0.5) 110px, rgba(211, 119, 111, 0) 110px, rgba(211, 119, 111, 0) 120px, rgba(11, 36, 45, 0.5) 120px, rgba(11, 36, 45, 0.5) 140px), - repeating-linear-gradient(135deg, transparent 5px, rgba(11, 36, 45, 0.5) 5px, rgba(11, 36, 45, 0.5) 10px, rgba(211, 119, 111, 0) 10px, rgba(211, 119, 111, 0) 35px, rgba(211, 119, 111, 0.5) 35px, rgba(211, 119, 111, 0.5) 40px, rgba(11, 36, 45, 0.5) 40px, rgba(11, 36, 45, 0.5) 50px, rgba(11, 36, 45, 0) 50px, rgba(11, 36, 45, 0) 60px, rgba(211, 119, 111, 0.5) 60px, rgba(211, 119, 111, 0.5) 70px, rgba(247, 179, 85, 0.5) 70px, rgba(247, 179, 85, 0.5) 80px, rgba(247, 179, 85, 0) 80px, rgba(247, 179, 85, 0) 90px, rgba(211, 119, 111, 0.5) 90px, rgba(211, 119, 111, 0.5) 110px, rgba(211, 119, 111, 0) 110px, rgba(211, 119, 111, 0) 140px, rgba(11, 36, 45, 0.5) 140px, rgba(11, 36, 45, 0.5) 160px); -} - -html.tartan { - height: 100%; - background-color: #a0302c; - background-image: repeating-linear-gradient(20deg, transparent, transparent 50px, rgba(0, 0, 0, 0.4) 50px, rgba(0, 0, 0, 0.4) 53px, transparent 53px, transparent 63px, rgba(0, 0, 0, 0.4) 63px, rgba(0, 0, 0, 0.4) 66px, transparent 66px, transparent 116px, rgba(0, 0, 0, 0.5) 116px, rgba(0, 0, 0, 0.5) 166px, rgba(255, 255, 255, 0.2) 166px, rgba(255, 255, 255, 0.2) 169px, rgba(0, 0, 0, 0.5) 169px, rgba(0, 0, 0, 0.5) 179px, rgba(255, 255, 255, 0.2) 179px, rgba(255, 255, 255, 0.2) 182px, rgba(0, 0, 0, 0.5) 182px, rgba(0, 0, 0, 0.5) 232px, transparent 232px), - repeating-linear-gradient(290deg, transparent, transparent 50px, rgba(0, 0, 0, 0.4) 50px, rgba(0, 0, 0, 0.4) 53px, transparent 53px, transparent 63px, rgba(0, 0, 0, 0.4) 63px, rgba(0, 0, 0, 0.4) 66px, transparent 66px, transparent 116px, rgba(0, 0, 0, 0.5) 116px, rgba(0, 0, 0, 0.5) 166px, rgba(255, 255, 255, 0.2) 166px, rgba(255, 255, 255, 0.2) 169px, rgba(0, 0, 0, 0.5) 169px, rgba(0, 0, 0, 0.5) 179px, rgba(255, 255, 255, 0.2) 179px, rgba(255, 255, 255, 0.2) 182px, rgba(0, 0, 0, 0.5) 182px, rgba(0, 0, 0, 0.5) 232px, transparent 232px), - repeating-linear-gradient(145deg, transparent, transparent 2px, rgba(0, 0, 0, 0.2) 2px, rgba(0, 0, 0, 0.2) 3px, transparent 3px, transparent 5px, rgba(0, 0, 0, 0.2) 5px); -} - -html.seigaiha { - background-color: grey; - background-image: radial-gradient(circle at 100% 150%, grey 24%, silver 25%, silver 28%, grey 29%, grey 36%, silver 36%, silver 40%, rgba(0, 0, 0, 0) 40%, rgba(0, 0, 0, 0)), - radial-gradient(circle at 0 150%, grey 24%, silver 25%, silver 28%, grey 29%, grey 36%, silver 36%, silver 40%, rgba(0, 0, 0, 0) 40%, rgba(0, 0, 0, 0)), - radial-gradient(circle at 50% 100%, silver 10%, grey 11%, grey 23%, silver 24%, silver 30%, grey 31%, grey 43%, silver 44%, silver 50%, grey 51%, grey 63%, silver 64%, silver 71%, rgba(0, 0, 0, 0) 71%, rgba(0, 0, 0, 0)), - radial-gradient(circle at 100% 50%, silver 5%, grey 6%, grey 15%, silver 16%, silver 20%, grey 21%, grey 30%, silver 31%, silver 35%, grey 36%, grey 45%, silver 46%, silver 49%, rgba(0, 0, 0, 0) 50%, rgba(0, 0, 0, 0)), - radial-gradient(circle at 0 50%, silver 5%, grey 6%, grey 15%, silver 16%, silver 20%, grey 21%, grey 30%, silver 31%, silver 35%, grey 36%, grey 45%, silver 46%, silver 49%, rgba(0, 0, 0, 0) 50%, rgba(0, 0, 0, 0)); - background-size: 100px 50px; +html.tablecloth { + height: 100%; + background: repeating-linear-gradient(-45deg, transparent, transparent 1em, rgba(136, 136, 136, 0.4) 0, rgba(136, 136, 136, 0.1) 2em, transparent 0, transparent 1em, rgba(136, 136, 136, 0.3) 0, rgba(136, 136, 136, 0.2) 4em, transparent 0, transparent 1em, rgba(68, 68, 68, 0.6) 0, rgba(68, 68, 68, 0.2) 2em), + repeating-linear-gradient(45deg, transparent, transparent 1em, rgba(136, 136, 136, 0.4) 0, rgba(136, 136, 136, 0.1) 2em, transparent 0, transparent 1em, rgba(136, 136, 136, 0.3) 0, rgba(136, 136, 136, 0.2) 4em, transparent 0, transparent 1em, rgba(68, 68, 68, 0.4) 0, rgba(68, 68, 68, 0.1) 2em), #666; + background-blend-mode: multiply; +} + +html.weave { + background: linear-gradient(45deg, #666 12%, transparent 0, transparent 88%, #666 0), + linear-gradient(135deg, transparent 37%, #888 0, #888 63%, transparent 0), + linear-gradient(45deg, transparent 37%, #666 0, #666 63%, transparent 0), + #444; + background-size: 40px 40px; +} + +html.madras { + height: 100%; + background-color: #e9d4b9; + background-image: repeating-linear-gradient(45deg, transparent 5px, rgba(11, 36, 45, 0.5) 5px, rgba(11, 36, 45, 0.5) 10px, rgba(211, 119, 111, 0) 10px, rgba(211, 119, 111, 0) 35px, rgba(211, 119, 111, 0.5) 35px, rgba(211, 119, 111, 0.5) 40px, rgba(11, 36, 45, 0.5) 40px, rgba(11, 36, 45, 0.5) 50px, rgba(11, 36, 45, 0) 50px, rgba(11, 36, 45, 0) 60px, rgba(211, 119, 111, 0.5) 60px, rgba(211, 119, 111, 0.5) 70px, rgba(247, 179, 85, 0.5) 70px, rgba(247, 179, 85, 0.5) 80px, rgba(247, 179, 85, 0) 80px, rgba(247, 179, 85, 0) 90px, rgba(211, 119, 111, 0.5) 90px, rgba(211, 119, 111, 0.5) 110px, rgba(211, 119, 111, 0) 110px, rgba(211, 119, 111, 0) 120px, rgba(11, 36, 45, 0.5) 120px, rgba(11, 36, 45, 0.5) 140px), + repeating-linear-gradient(135deg, transparent 5px, rgba(11, 36, 45, 0.5) 5px, rgba(11, 36, 45, 0.5) 10px, rgba(211, 119, 111, 0) 10px, rgba(211, 119, 111, 0) 35px, rgba(211, 119, 111, 0.5) 35px, rgba(211, 119, 111, 0.5) 40px, rgba(11, 36, 45, 0.5) 40px, rgba(11, 36, 45, 0.5) 50px, rgba(11, 36, 45, 0) 50px, rgba(11, 36, 45, 0) 60px, rgba(211, 119, 111, 0.5) 60px, rgba(211, 119, 111, 0.5) 70px, rgba(247, 179, 85, 0.5) 70px, rgba(247, 179, 85, 0.5) 80px, rgba(247, 179, 85, 0) 80px, rgba(247, 179, 85, 0) 90px, rgba(211, 119, 111, 0.5) 90px, rgba(211, 119, 111, 0.5) 110px, rgba(211, 119, 111, 0) 110px, rgba(211, 119, 111, 0) 140px, rgba(11, 36, 45, 0.5) 140px, rgba(11, 36, 45, 0.5) 160px); +} + +html.tartan { + height: 100%; + background-color: #a0302c; + background-image: repeating-linear-gradient(20deg, transparent, transparent 50px, rgba(0, 0, 0, 0.4) 50px, rgba(0, 0, 0, 0.4) 53px, transparent 53px, transparent 63px, rgba(0, 0, 0, 0.4) 63px, rgba(0, 0, 0, 0.4) 66px, transparent 66px, transparent 116px, rgba(0, 0, 0, 0.5) 116px, rgba(0, 0, 0, 0.5) 166px, rgba(255, 255, 255, 0.2) 166px, rgba(255, 255, 255, 0.2) 169px, rgba(0, 0, 0, 0.5) 169px, rgba(0, 0, 0, 0.5) 179px, rgba(255, 255, 255, 0.2) 179px, rgba(255, 255, 255, 0.2) 182px, rgba(0, 0, 0, 0.5) 182px, rgba(0, 0, 0, 0.5) 232px, transparent 232px), + repeating-linear-gradient(290deg, transparent, transparent 50px, rgba(0, 0, 0, 0.4) 50px, rgba(0, 0, 0, 0.4) 53px, transparent 53px, transparent 63px, rgba(0, 0, 0, 0.4) 63px, rgba(0, 0, 0, 0.4) 66px, transparent 66px, transparent 116px, rgba(0, 0, 0, 0.5) 116px, rgba(0, 0, 0, 0.5) 166px, rgba(255, 255, 255, 0.2) 166px, rgba(255, 255, 255, 0.2) 169px, rgba(0, 0, 0, 0.5) 169px, rgba(0, 0, 0, 0.5) 179px, rgba(255, 255, 255, 0.2) 179px, rgba(255, 255, 255, 0.2) 182px, rgba(0, 0, 0, 0.5) 182px, rgba(0, 0, 0, 0.5) 232px, transparent 232px), + repeating-linear-gradient(145deg, transparent, transparent 2px, rgba(0, 0, 0, 0.2) 2px, rgba(0, 0, 0, 0.2) 3px, transparent 3px, transparent 5px, rgba(0, 0, 0, 0.2) 5px); +} + +html.seigaiha { + background-color: grey; + background-image: radial-gradient(circle at 100% 150%, grey 24%, silver 25%, silver 28%, grey 29%, grey 36%, silver 36%, silver 40%, rgba(0, 0, 0, 0) 40%, rgba(0, 0, 0, 0)), + radial-gradient(circle at 0 150%, grey 24%, silver 25%, silver 28%, grey 29%, grey 36%, silver 36%, silver 40%, rgba(0, 0, 0, 0) 40%, rgba(0, 0, 0, 0)), + radial-gradient(circle at 50% 100%, silver 10%, grey 11%, grey 23%, silver 24%, silver 30%, grey 31%, grey 43%, silver 44%, silver 50%, grey 51%, grey 63%, silver 64%, silver 71%, rgba(0, 0, 0, 0) 71%, rgba(0, 0, 0, 0)), + radial-gradient(circle at 100% 50%, silver 5%, grey 6%, grey 15%, silver 16%, silver 20%, grey 21%, grey 30%, silver 31%, silver 35%, grey 36%, grey 45%, silver 46%, silver 49%, rgba(0, 0, 0, 0) 50%, rgba(0, 0, 0, 0)), + radial-gradient(circle at 0 50%, silver 5%, grey 6%, grey 15%, silver 16%, silver 20%, grey 21%, grey 30%, silver 31%, silver 35%, grey 36%, grey 45%, silver 46%, silver 49%, rgba(0, 0, 0, 0) 50%, rgba(0, 0, 0, 0)); + background-size: 100px 50px; } \ No newline at end of file From b5df9543229b4d856bce077e52ad87ce9139051d Mon Sep 17 00:00:00 2001 From: Danny Bessems Date: Sun, 3 Mar 2019 17:06:41 +0100 Subject: [PATCH 3/7] Managementinterface retrieves data from database; Table on interface is editable; replaced library. --- include/lucidAuth.template.php | 51 ++++++----- public/example.php | 27 ------ public/lucidAuth.manage.php | 29 +++++- public/misc/script.editable.table.js | 131 +++++++++++++++++++++++++++ public/misc/script.index.js | 2 +- public/misc/script.manage.js | 7 ++ public/misc/script.table.min.js | 6 -- public/misc/script.translation.js | 14 +-- public/misc/style.css | 68 ++++++-------- 9 files changed, 226 insertions(+), 109 deletions(-) delete mode 100644 public/example.php create mode 100644 public/misc/script.editable.table.js delete mode 100644 public/misc/script.table.min.js 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 +
      +
    • +   +
    • @@ -70,41 +69,45 @@ $contentLayout['login'] = <<<'LOGIN'
    • -
    • -   -
    • Inloggegevens verkrijgbaar op aanvraag!
    -
    + Secure! LOGIN; $contentLayout['manage'] = <<<'MANAGE' + Ingelogd als %1$s --- [EN NL] [Log uit] -
    - Beheer Gebruikers +
    • + + + + + + + + + + %2$s + +
      UsernameRoleSessions
    • -
    • - +
    • + + +
    • -
    • - [--] - -
    • -
    • - -
    • -
    • - +
    • + +
    -
    + 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..65be88b --- /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..ba18028 100644 --- a/public/misc/script.manage.js +++ b/public/misc/script.manage.js @@ -0,0 +1,7 @@ +$(document).ready(function(){ + $('#usertable').editableTableWidget(); + + $('#btnnewuser').click(function() { + $('#usertable tbody').append($('<username>User0')); + }); +}); \ 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; From 1548cd4bb6bebfabd150f0836b0a97cf24afa407 Mon Sep 17 00:00:00 2001 From: Danny Bessems Date: Mon, 4 Mar 2019 10:43:08 +0100 Subject: [PATCH 4/7] Managementinterface retrieves data from database; Table on interface is editable; replaced library. --- include/lucidAuth.template.php | 51 ++++++----- public/example.php | 27 ------ public/lucidAuth.manage.php | 29 +++++- public/misc/script.editable.table.js | 131 +++++++++++++++++++++++++++ public/misc/script.index.js | 2 +- public/misc/script.manage.js | 13 +++ public/misc/script.table.min.js | 6 -- public/misc/script.translation.js | 14 +-- public/misc/style.css | 68 ++++++-------- 9 files changed, 232 insertions(+), 109 deletions(-) delete mode 100644 public/example.php create mode 100644 public/misc/script.editable.table.js delete mode 100644 public/misc/script.table.min.js 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 +
      +
    • +   +
    • @@ -70,41 +69,45 @@ $contentLayout['login'] = <<<'LOGIN'
    • -
    • -   -
    • Inloggegevens verkrijgbaar op aanvraag!
    -
    + Secure! LOGIN; $contentLayout['manage'] = <<<'MANAGE' + Ingelogd als %1$s --- [EN NL] [Log uit] -
    - Beheer Gebruikers +
    • + + + + + + + + + + %2$s + +
      UsernameRoleSessions
    • -
    • - +
    • + + +
    • -
    • - [--] - -
    • -
    • - -
    • -
    • - +
    • + +
    -
    + 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; From a049bdbd24ad0661a94b90664fd3353b00029f18 Mon Sep 17 00:00:00 2001 From: Danny Bessems Date: Tue, 5 Mar 2019 11:14:17 +0100 Subject: [PATCH 5/7] Refactored template; make main content scrollable without overflow Switched to Flexbox CSS based layout Retargeted HTML-elements for theming --- include/lucidAuth.template.php | 71 ++++++++++++++++++++++++------- public/lucidAuth.manage.php | 17 ++++---- public/misc/script.manage.js | 22 +++++++++- public/misc/script.theme.js | 19 --------- public/misc/style.css | 29 +++---------- public/misc/style.panes.css | 50 ++++++++++++++++++++++ public/misc/style.theme.css | 76 +++++++++++++++++----------------- 7 files changed, 181 insertions(+), 103 deletions(-) delete mode 100644 public/misc/script.theme.js create mode 100644 public/misc/style.panes.css diff --git a/include/lucidAuth.template.php b/include/lucidAuth.template.php index bbbd26a..9dc8689 100644 --- a/include/lucidAuth.template.php +++ b/include/lucidAuth.template.php @@ -33,6 +33,47 @@ $pageLayout['full'] = <<<'FULL' FULL; +$pageLayout['full2'] = <<<'FULL2' + + + + + lucidAuth + + + + + + + + + + + +
    +
    +
    +
    +
    + + %1$s +
    +
    + %2$s +
    +
    + + +
    +
    +
    + + +FULL2; + $pageLayout['bare'] = <<<'BARE' @@ -77,11 +118,23 @@ $contentLayout['login'] = <<<'LOGIN' Secure! LOGIN; -$contentLayout['manage'] = <<<'MANAGE' +$contentLayout['manage']['header'] = <<<'MANAGE_HEADER' Ingelogd als %1$s --- [EN NL] [Log uit] -
    +
      +
    • + + + +
    • +
    • + + +
    • +
    +MANAGE_HEADER; +$contentLayout['manage']['section'] = <<<'MANAGE_SECTION'
    • @@ -93,21 +146,11 @@ $contentLayout['manage'] = <<<'MANAGE' - %2$s + %1$s
    • -
    • - - - -
    • -
    • - - -
    -
    -MANAGE; +MANAGE_SECTION; ?> \ No newline at end of file diff --git a/public/lucidAuth.manage.php b/public/lucidAuth.manage.php index 0ad71a9..9075744 100644 --- a/public/lucidAuth.manage.php +++ b/public/lucidAuth.manage.php @@ -12,7 +12,7 @@ try { $allUsers = $pdoDB->query(' - SELECT User.Username, Role.Rolename, COUNT(DISTINCT SecureToken.Value) AS Sessions + SELECT User.Id, User.Username, Role.Rolename, COUNT(DISTINCT SecureToken.Value) AS Sessions FROM User LEFT JOIN Role ON (User.RoleId=Role.Id) @@ -25,19 +25,22 @@ } foreach($allUsers as $row) { - $tableRows[] = sprintf('%1$s%2$s%3$s', + $tableRows[] = sprintf('%2$s%3$s%4$s', + $row['Id'], explode('\\', $row['Username'])[1], $row['Rolename'], $row['Sessions'] ); } - echo sprintf($pageLayout['full'], - sprintf($contentLayout['manage'], - $validateTokenResult['name'], + echo sprintf($pageLayout['full2'], + sprintf($contentLayout['manage']['header'], + $validateTokenResult['name'] + ), + sprintf($contentLayout['manage']['section'], implode($tableRows) - ) - ); + ) + ); } else { // No cookie containing valid authentication token found; // explicitly deleting any remaining cookie, then redirecting to loginpage diff --git a/public/misc/script.manage.js b/public/misc/script.manage.js index f7e6c98..1766e5b 100644 --- a/public/misc/script.manage.js +++ b/public/misc/script.manage.js @@ -5,9 +5,29 @@ $(document).ready(function(){ $('#btnnewuser').click(function() { var newUser = 'User' + String(Math.floor(Math.random() * Math.floor(9999))).padStart(4, '0'); - $('#usertable tbody').append($('' + newUser + 'User0')); + $('#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')}); }); + + if (localStorage.getItem('theme') !== null) { + $('#theme').addClass(localStorage.getItem('theme')); + } + + $('.logo .sub').click(function(event) { + var classes = ["tablecloth", "weave", "madras", "tartan", "seigaiha"]; + + if (event.ctrlKey) { + var selectedTheme = classes[~~(Math.random()*classes.length)]; + + $('#theme').removeClass(classes.join(' ')).addClass(selectedTheme); + localStorage.setItem('theme', selectedTheme); + } + if (event.altKey) { + $('#theme').removeClass(classes.join(' ')); + localStorage.removeItem('theme'); + } + }); + }); \ No newline at end of file diff --git a/public/misc/script.theme.js b/public/misc/script.theme.js deleted file mode 100644 index 5532021..0000000 --- a/public/misc/script.theme.js +++ /dev/null @@ -1,19 +0,0 @@ -$(document).ready(function() { - if (localStorage.getItem('theme') != '') { - $('html').addClass(localStorage.getItem('theme')); - } - - $('.logo .sub').on('click', function(event) { - if (event.ctrlKey) { - var classes = ["tablecloth", "weave", "madras", "tartan", "seigaiha"]; - var selectedTheme = classes[~~(Math.random()*classes.length)]; - - $('html').removeClass().addClass(selectedTheme); - localStorage.setItem('theme', selectedTheme); - } - if (event.altKey) { - $('html').removeClass(); - localStorage.removeItem('theme'); - } - }); -}); \ No newline at end of file diff --git a/public/misc/style.css b/public/misc/style.css index 1bf0cd9..8abf93a 100644 --- a/public/misc/style.css +++ b/public/misc/style.css @@ -116,13 +116,16 @@ body { margin-top: 7px; width: 20px; } + .main header button, .main section button { margin-left: 160px; text-transform: uppercase; } + .main header .buttons, .main section .buttons { text-align: center; } + .main header .buttons button, .main section .buttons button { margin-left: inherit; } @@ -130,7 +133,7 @@ body { width: 100%; } .main section table * { - font-size: 12px; + font-size: 14px; padding: 2px; margin: 0; } @@ -199,26 +202,4 @@ body { } .main span#user nav { display: inline; - } - .main span#user #pluginlogos { - display: none; - position: absolute; - top: 72px; - right: 10px; - height: 112px; - width: 250px; - border: 1px solid rgb(0, 51, 153); - box-shadow: black 0px 0px 20px; - box-sizing: border-box; - padding-top: 5px; - background: white; - font-size: inherit; - font-weight: bold; - } - .main span#user #pluginlogos img { - width: 75px; - height: 75px; - filter: saturate(500%) contrast(200%) grayscale(100%) opacity(50%); - transition: all 375ms; - cursor: pointer; - } + } \ No newline at end of file diff --git a/public/misc/style.panes.css b/public/misc/style.panes.css new file mode 100644 index 0000000..f060c14 --- /dev/null +++ b/public/misc/style.panes.css @@ -0,0 +1,50 @@ +body{ + margin: 0; +} +.wrapper{ + min-height: 100vh; + background: #FFFFFF; + display: flex; + flex-direction: column; +} +.header { + height: 125px; + background: #FFFFFF; + color: #000000; +} +.content { + display: flex; + flex: 1; + background: #333333; + color: #000; + min-height: 0px; + max-height: 100vh; +} +.columns{ + display: flex; + flex:1; +} +.main{ + flex: 1; + order: 2; + background: #fff; + border: 3px solid #CCCCCC; + border-radius: 5px; + height: 400px; + margin-top: auto; + margin-bottom: auto; +} +.main section { + overflow-y: scroll; + height: calc(100% - 125px); +} +.sidebar-first{ + width: 25%; + background: transparent; + order: 1; +} +.sidebar-second{ + width: 25%; + order: 3; + background: transparent; +} \ No newline at end of file diff --git a/public/misc/style.theme.css b/public/misc/style.theme.css index 382eb0a..1d78ca5 100644 --- a/public/misc/style.theme.css +++ b/public/misc/style.theme.css @@ -1,39 +1,39 @@ -html.tablecloth { - height: 100%; - background: repeating-linear-gradient(-45deg, transparent, transparent 1em, rgba(136, 136, 136, 0.4) 0, rgba(136, 136, 136, 0.1) 2em, transparent 0, transparent 1em, rgba(136, 136, 136, 0.3) 0, rgba(136, 136, 136, 0.2) 4em, transparent 0, transparent 1em, rgba(68, 68, 68, 0.6) 0, rgba(68, 68, 68, 0.2) 2em), - repeating-linear-gradient(45deg, transparent, transparent 1em, rgba(136, 136, 136, 0.4) 0, rgba(136, 136, 136, 0.1) 2em, transparent 0, transparent 1em, rgba(136, 136, 136, 0.3) 0, rgba(136, 136, 136, 0.2) 4em, transparent 0, transparent 1em, rgba(68, 68, 68, 0.4) 0, rgba(68, 68, 68, 0.1) 2em), #666; - background-blend-mode: multiply; -} - -html.weave { - background: linear-gradient(45deg, #666 12%, transparent 0, transparent 88%, #666 0), - linear-gradient(135deg, transparent 37%, #888 0, #888 63%, transparent 0), - linear-gradient(45deg, transparent 37%, #666 0, #666 63%, transparent 0), - #444; - background-size: 40px 40px; -} - -html.madras { - height: 100%; - background-color: #e9d4b9; - background-image: repeating-linear-gradient(45deg, transparent 5px, rgba(11, 36, 45, 0.5) 5px, rgba(11, 36, 45, 0.5) 10px, rgba(211, 119, 111, 0) 10px, rgba(211, 119, 111, 0) 35px, rgba(211, 119, 111, 0.5) 35px, rgba(211, 119, 111, 0.5) 40px, rgba(11, 36, 45, 0.5) 40px, rgba(11, 36, 45, 0.5) 50px, rgba(11, 36, 45, 0) 50px, rgba(11, 36, 45, 0) 60px, rgba(211, 119, 111, 0.5) 60px, rgba(211, 119, 111, 0.5) 70px, rgba(247, 179, 85, 0.5) 70px, rgba(247, 179, 85, 0.5) 80px, rgba(247, 179, 85, 0) 80px, rgba(247, 179, 85, 0) 90px, rgba(211, 119, 111, 0.5) 90px, rgba(211, 119, 111, 0.5) 110px, rgba(211, 119, 111, 0) 110px, rgba(211, 119, 111, 0) 120px, rgba(11, 36, 45, 0.5) 120px, rgba(11, 36, 45, 0.5) 140px), - repeating-linear-gradient(135deg, transparent 5px, rgba(11, 36, 45, 0.5) 5px, rgba(11, 36, 45, 0.5) 10px, rgba(211, 119, 111, 0) 10px, rgba(211, 119, 111, 0) 35px, rgba(211, 119, 111, 0.5) 35px, rgba(211, 119, 111, 0.5) 40px, rgba(11, 36, 45, 0.5) 40px, rgba(11, 36, 45, 0.5) 50px, rgba(11, 36, 45, 0) 50px, rgba(11, 36, 45, 0) 60px, rgba(211, 119, 111, 0.5) 60px, rgba(211, 119, 111, 0.5) 70px, rgba(247, 179, 85, 0.5) 70px, rgba(247, 179, 85, 0.5) 80px, rgba(247, 179, 85, 0) 80px, rgba(247, 179, 85, 0) 90px, rgba(211, 119, 111, 0.5) 90px, rgba(211, 119, 111, 0.5) 110px, rgba(211, 119, 111, 0) 110px, rgba(211, 119, 111, 0) 140px, rgba(11, 36, 45, 0.5) 140px, rgba(11, 36, 45, 0.5) 160px); -} - -html.tartan { - height: 100%; - background-color: #a0302c; - background-image: repeating-linear-gradient(20deg, transparent, transparent 50px, rgba(0, 0, 0, 0.4) 50px, rgba(0, 0, 0, 0.4) 53px, transparent 53px, transparent 63px, rgba(0, 0, 0, 0.4) 63px, rgba(0, 0, 0, 0.4) 66px, transparent 66px, transparent 116px, rgba(0, 0, 0, 0.5) 116px, rgba(0, 0, 0, 0.5) 166px, rgba(255, 255, 255, 0.2) 166px, rgba(255, 255, 255, 0.2) 169px, rgba(0, 0, 0, 0.5) 169px, rgba(0, 0, 0, 0.5) 179px, rgba(255, 255, 255, 0.2) 179px, rgba(255, 255, 255, 0.2) 182px, rgba(0, 0, 0, 0.5) 182px, rgba(0, 0, 0, 0.5) 232px, transparent 232px), - repeating-linear-gradient(290deg, transparent, transparent 50px, rgba(0, 0, 0, 0.4) 50px, rgba(0, 0, 0, 0.4) 53px, transparent 53px, transparent 63px, rgba(0, 0, 0, 0.4) 63px, rgba(0, 0, 0, 0.4) 66px, transparent 66px, transparent 116px, rgba(0, 0, 0, 0.5) 116px, rgba(0, 0, 0, 0.5) 166px, rgba(255, 255, 255, 0.2) 166px, rgba(255, 255, 255, 0.2) 169px, rgba(0, 0, 0, 0.5) 169px, rgba(0, 0, 0, 0.5) 179px, rgba(255, 255, 255, 0.2) 179px, rgba(255, 255, 255, 0.2) 182px, rgba(0, 0, 0, 0.5) 182px, rgba(0, 0, 0, 0.5) 232px, transparent 232px), - repeating-linear-gradient(145deg, transparent, transparent 2px, rgba(0, 0, 0, 0.2) 2px, rgba(0, 0, 0, 0.2) 3px, transparent 3px, transparent 5px, rgba(0, 0, 0, 0.2) 5px); -} - -html.seigaiha { - background-color: grey; - background-image: radial-gradient(circle at 100% 150%, grey 24%, silver 25%, silver 28%, grey 29%, grey 36%, silver 36%, silver 40%, rgba(0, 0, 0, 0) 40%, rgba(0, 0, 0, 0)), - radial-gradient(circle at 0 150%, grey 24%, silver 25%, silver 28%, grey 29%, grey 36%, silver 36%, silver 40%, rgba(0, 0, 0, 0) 40%, rgba(0, 0, 0, 0)), - radial-gradient(circle at 50% 100%, silver 10%, grey 11%, grey 23%, silver 24%, silver 30%, grey 31%, grey 43%, silver 44%, silver 50%, grey 51%, grey 63%, silver 64%, silver 71%, rgba(0, 0, 0, 0) 71%, rgba(0, 0, 0, 0)), - radial-gradient(circle at 100% 50%, silver 5%, grey 6%, grey 15%, silver 16%, silver 20%, grey 21%, grey 30%, silver 31%, silver 35%, grey 36%, grey 45%, silver 46%, silver 49%, rgba(0, 0, 0, 0) 50%, rgba(0, 0, 0, 0)), - radial-gradient(circle at 0 50%, silver 5%, grey 6%, grey 15%, silver 16%, silver 20%, grey 21%, grey 30%, silver 31%, silver 35%, grey 36%, grey 45%, silver 46%, silver 49%, rgba(0, 0, 0, 0) 50%, rgba(0, 0, 0, 0)); - background-size: 100px 50px; +#theme.tablecloth { + height: 100%; + background: repeating-linear-gradient(-45deg, transparent, transparent 1em, rgba(136, 136, 136, 0.4) 0, rgba(136, 136, 136, 0.1) 2em, transparent 0, transparent 1em, rgba(136, 136, 136, 0.3) 0, rgba(136, 136, 136, 0.2) 4em, transparent 0, transparent 1em, rgba(68, 68, 68, 0.6) 0, rgba(68, 68, 68, 0.2) 2em), + repeating-linear-gradient(45deg, transparent, transparent 1em, rgba(136, 136, 136, 0.4) 0, rgba(136, 136, 136, 0.1) 2em, transparent 0, transparent 1em, rgba(136, 136, 136, 0.3) 0, rgba(136, 136, 136, 0.2) 4em, transparent 0, transparent 1em, rgba(68, 68, 68, 0.4) 0, rgba(68, 68, 68, 0.1) 2em), #666; + background-blend-mode: multiply; +} + +#theme.weave { + background: linear-gradient(45deg, #666 12%, transparent 0, transparent 88%, #666 0), + linear-gradient(135deg, transparent 37%, #888 0, #888 63%, transparent 0), + linear-gradient(45deg, transparent 37%, #666 0, #666 63%, transparent 0), + #444; + background-size: 40px 40px; +} + +#theme.madras { + height: 100%; + background-color: #e9d4b9; + background-image: repeating-linear-gradient(45deg, transparent 5px, rgba(11, 36, 45, 0.5) 5px, rgba(11, 36, 45, 0.5) 10px, rgba(211, 119, 111, 0) 10px, rgba(211, 119, 111, 0) 35px, rgba(211, 119, 111, 0.5) 35px, rgba(211, 119, 111, 0.5) 40px, rgba(11, 36, 45, 0.5) 40px, rgba(11, 36, 45, 0.5) 50px, rgba(11, 36, 45, 0) 50px, rgba(11, 36, 45, 0) 60px, rgba(211, 119, 111, 0.5) 60px, rgba(211, 119, 111, 0.5) 70px, rgba(247, 179, 85, 0.5) 70px, rgba(247, 179, 85, 0.5) 80px, rgba(247, 179, 85, 0) 80px, rgba(247, 179, 85, 0) 90px, rgba(211, 119, 111, 0.5) 90px, rgba(211, 119, 111, 0.5) 110px, rgba(211, 119, 111, 0) 110px, rgba(211, 119, 111, 0) 120px, rgba(11, 36, 45, 0.5) 120px, rgba(11, 36, 45, 0.5) 140px), + repeating-linear-gradient(135deg, transparent 5px, rgba(11, 36, 45, 0.5) 5px, rgba(11, 36, 45, 0.5) 10px, rgba(211, 119, 111, 0) 10px, rgba(211, 119, 111, 0) 35px, rgba(211, 119, 111, 0.5) 35px, rgba(211, 119, 111, 0.5) 40px, rgba(11, 36, 45, 0.5) 40px, rgba(11, 36, 45, 0.5) 50px, rgba(11, 36, 45, 0) 50px, rgba(11, 36, 45, 0) 60px, rgba(211, 119, 111, 0.5) 60px, rgba(211, 119, 111, 0.5) 70px, rgba(247, 179, 85, 0.5) 70px, rgba(247, 179, 85, 0.5) 80px, rgba(247, 179, 85, 0) 80px, rgba(247, 179, 85, 0) 90px, rgba(211, 119, 111, 0.5) 90px, rgba(211, 119, 111, 0.5) 110px, rgba(211, 119, 111, 0) 110px, rgba(211, 119, 111, 0) 140px, rgba(11, 36, 45, 0.5) 140px, rgba(11, 36, 45, 0.5) 160px); +} + +#theme.tartan { + height: 100%; + background-color: #a0302c; + background-image: repeating-linear-gradient(20deg, transparent, transparent 50px, rgba(0, 0, 0, 0.4) 50px, rgba(0, 0, 0, 0.4) 53px, transparent 53px, transparent 63px, rgba(0, 0, 0, 0.4) 63px, rgba(0, 0, 0, 0.4) 66px, transparent 66px, transparent 116px, rgba(0, 0, 0, 0.5) 116px, rgba(0, 0, 0, 0.5) 166px, rgba(255, 255, 255, 0.2) 166px, rgba(255, 255, 255, 0.2) 169px, rgba(0, 0, 0, 0.5) 169px, rgba(0, 0, 0, 0.5) 179px, rgba(255, 255, 255, 0.2) 179px, rgba(255, 255, 255, 0.2) 182px, rgba(0, 0, 0, 0.5) 182px, rgba(0, 0, 0, 0.5) 232px, transparent 232px), + repeating-linear-gradient(290deg, transparent, transparent 50px, rgba(0, 0, 0, 0.4) 50px, rgba(0, 0, 0, 0.4) 53px, transparent 53px, transparent 63px, rgba(0, 0, 0, 0.4) 63px, rgba(0, 0, 0, 0.4) 66px, transparent 66px, transparent 116px, rgba(0, 0, 0, 0.5) 116px, rgba(0, 0, 0, 0.5) 166px, rgba(255, 255, 255, 0.2) 166px, rgba(255, 255, 255, 0.2) 169px, rgba(0, 0, 0, 0.5) 169px, rgba(0, 0, 0, 0.5) 179px, rgba(255, 255, 255, 0.2) 179px, rgba(255, 255, 255, 0.2) 182px, rgba(0, 0, 0, 0.5) 182px, rgba(0, 0, 0, 0.5) 232px, transparent 232px), + repeating-linear-gradient(145deg, transparent, transparent 2px, rgba(0, 0, 0, 0.2) 2px, rgba(0, 0, 0, 0.2) 3px, transparent 3px, transparent 5px, rgba(0, 0, 0, 0.2) 5px); +} + +#theme.seigaiha { + background-color: grey; + background-image: radial-gradient(circle at 100% 150%, grey 24%, silver 25%, silver 28%, grey 29%, grey 36%, silver 36%, silver 40%, rgba(0, 0, 0, 0) 40%, rgba(0, 0, 0, 0)), + radial-gradient(circle at 0 150%, grey 24%, silver 25%, silver 28%, grey 29%, grey 36%, silver 36%, silver 40%, rgba(0, 0, 0, 0) 40%, rgba(0, 0, 0, 0)), + radial-gradient(circle at 50% 100%, silver 10%, grey 11%, grey 23%, silver 24%, silver 30%, grey 31%, grey 43%, silver 44%, silver 50%, grey 51%, grey 63%, silver 64%, silver 71%, rgba(0, 0, 0, 0) 71%, rgba(0, 0, 0, 0)), + radial-gradient(circle at 100% 50%, silver 5%, grey 6%, grey 15%, silver 16%, silver 20%, grey 21%, grey 30%, silver 31%, silver 35%, grey 36%, grey 45%, silver 46%, silver 49%, rgba(0, 0, 0, 0) 50%, rgba(0, 0, 0, 0)), + radial-gradient(circle at 0 50%, silver 5%, grey 6%, grey 15%, silver 16%, silver 20%, grey 21%, grey 30%, silver 31%, silver 35%, grey 36%, grey 45%, silver 46%, silver 49%, rgba(0, 0, 0, 0) 50%, rgba(0, 0, 0, 0)); + background-size: 100px 50px; } \ No newline at end of file From 3dbb6b99326476b534e4ae8affb6c90b92fc1dc0 Mon Sep 17 00:00:00 2001 From: Danny Bessems Date: Wed, 6 Mar 2019 14:21:47 +0100 Subject: [PATCH 6/7] Implemented GUI aspect of usermanagement page TODO: add ajax-call that will update database --- include/lucidAuth.functions.php | 10 +++--- include/lucidAuth.template.php | 29 +++++++-------- public/lucidAuth.manage.php | 16 ++++----- public/misc/script.manage.js | 60 ++++++++++++++++++++++++++++++- public/misc/script.translation.js | 16 ++++++--- public/misc/style.css | 7 ++++ public/misc/style.panes.css | 4 +-- 7 files changed, 106 insertions(+), 36 deletions(-) diff --git a/include/lucidAuth.functions.php b/include/lucidAuth.functions.php index cc56ef6..11352c9 100644 --- a/include/lucidAuth.functions.php +++ b/include/lucidAuth.functions.php @@ -76,7 +76,7 @@ function storeToken (string $secureToken, string $qualifiedUsername, string $htt catch (Exception $e) { return ['status' => 'Fail', 'reason' => $e]; } - + // Save authentication token in cookie clientside $cookieDomain = array_values(array_filter($settings->Session['CookieDomains'], function ($value) use ($httpHost) { // Check if $_SERVER['HTTP_HOST'] matches any of the configured domains (either explicitly or as a subdomain) @@ -114,9 +114,9 @@ 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 + LEFT JOIN User ON (User.Id=SecureToken.UserId) WHERE User.Username = :username '); @@ -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']) { diff --git a/include/lucidAuth.template.php b/include/lucidAuth.template.php index 9dc8689..4572173 100644 --- a/include/lucidAuth.template.php +++ b/include/lucidAuth.template.php @@ -33,7 +33,7 @@ $pageLayout['full'] = <<<'FULL' FULL; -$pageLayout['full2'] = <<<'FULL2' +$pageLayout['full_alt'] = <<<'FULL_ALT' @@ -72,7 +72,7 @@ $pageLayout['full2'] = <<<'FULL2' -FULL2; +FULL_ALT; $pageLayout['bare'] = <<<'BARE' @@ -98,12 +98,12 @@ $contentLayout['login'] = <<<'LOGIN'  
  • - +
  • - +
  • @@ -111,7 +111,7 @@ $contentLayout['login'] = <<<'LOGIN'
  • - Inloggegevens verkrijgbaar op aanvraag! + Login credentials available upon request!
  • @@ -121,16 +121,13 @@ LOGIN; $contentLayout['manage']['header'] = <<<'MANAGE_HEADER' - Ingelogd als %1$s --- [EN NL] [Log uit] + Logged in as %1$s --- [EN NL] [Logout]
    • - - - -
    • -
    • - - + +   + +
    MANAGE_HEADER; @@ -140,9 +137,9 @@ $contentLayout['manage']['section'] = <<<'MANAGE_SECTION' - - - + + + diff --git a/public/lucidAuth.manage.php b/public/lucidAuth.manage.php index 9075744..7488b9d 100644 --- a/public/lucidAuth.manage.php +++ b/public/lucidAuth.manage.php @@ -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) + LEFT JOIN Role + 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('', + $tableRows[] = sprintf('', + $validateTokenResult['uid'] === $row['Id'] ? 'class="currentuser"': null, $row['Id'], explode('\\', $row['Username'])[1], $row['Rolename'], - $row['Sessions'] + '' . ($validateTokenResult['uid'] === $row['Id'] ? null : ' ') ); } - echo sprintf($pageLayout['full2'], + echo sprintf($pageLayout['full_alt'], sprintf($contentLayout['manage']['header'], $validateTokenResult['name'] ), diff --git a/public/misc/script.manage.js b/public/misc/script.manage.js index 1766e5b..ecb4d31 100644 --- a/public/misc/script.manage.js +++ b/public/misc/script.manage.js @@ -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($('')); + // Add new user to the interface + // (new `` in `
    UsernameRoleSessionsUsernameRoleManage
    %2$s%3$s%4$s
    %3$s%4$s%5$s
    ' + newUser + 'User0
    `) + $('#usertable tbody').append($('', {class: 'new'}) + .append($('` // To prevent recreating multiple new editors; reference the already existing `` $('#usertable').editableTableWidget({editor: $('#editor')}); + // Add eventhandlers to buttons of newly added `` + $('#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) { diff --git a/public/misc/script.translation.js b/public/misc/script.translation.js index 1c1de54..9b002cd 100644 --- a/public/misc/script.translation.js +++ b/public/misc/script.translation.js @@ -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'); diff --git a/public/misc/style.css b/public/misc/style.css index 8abf93a..b1dd04a 100644 --- a/public/misc/style.css +++ b/public/misc/style.css @@ -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); } diff --git a/public/misc/style.panes.css b/public/misc/style.panes.css index f060c14..ac9fa89 100644 --- a/public/misc/style.panes.css +++ b/public/misc/style.panes.css @@ -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%; From a20f13ab7c96ef52a7b23d515e188fa3af4505ed Mon Sep 17 00:00:00 2001 From: Danny Bessems Date: Wed, 13 Mar 2019 09:59:12 +0000 Subject: [PATCH 7/7] Babysteps towards cross-domain-cookies-in-iframes --- include/lucidAuth.template.php | 6 +++--- public/lucidAuth.setXDomainCookie.php | 21 +++++++++++++++++++-- public/misc/script.manage.js | 8 ++++++-- 3 files changed, 28 insertions(+), 7 deletions(-) diff --git a/include/lucidAuth.template.php b/include/lucidAuth.template.php index 7ee36c0..e1b45b6 100644 --- a/include/lucidAuth.template.php +++ b/include/lucidAuth.template.php @@ -13,7 +13,7 @@ $pageLayout['full'] = <<<'FULL' - + @@ -79,7 +79,7 @@ $pageLayout['bare'] = <<<'BARE' lucidAuth - + @@ -119,7 +119,7 @@ LOGIN; $contentLayout['manage']['header'] = <<<'MANAGE_HEADER' - Logged in as %1$s --- [EN NL] [Logout] + Logged in as %1$s --- [EN NL] [Logout]
    • diff --git a/public/lucidAuth.setXDomainCookie.php b/public/lucidAuth.setXDomainCookie.php index c3ab1f8..0d20746 100644 --- a/public/lucidAuth.setXDomainCookie.php +++ b/public/lucidAuth.setXDomainCookie.php @@ -3,8 +3,7 @@ include_once('../include/lucidAuth.functions.php'); - - // Start with checking $_REQUEST['ref'] + // Start with checking $_REQUEST['ref'] // What do we need? // token again? @@ -16,6 +15,24 @@ // let the client setup multiple iframes for all domains other than origin domains // this requires passing an array of domains to the client in asynchronous reply; which feels insecure + if (!empty($_REQUEST['ref'])) { + try { + $queryString = json_decode(base64_decode($_REQUEST['ref']), JSON_OBJECT_AS_ARRAY); + } + catch (Exception $e) { + // Silently fail, unless explicitly specified otherwise + if ($settings->Debug['Verbose']) throw new Exception($e); + exit; + } + + switch ($queryString['action']) { + case 'login': + break; + default: + break; + } + } + include_once('../include/lucidAuth.template.php'); echo sprintf($pageLayout['bare'], diff --git a/public/misc/script.manage.js b/public/misc/script.manage.js index ecb4d31..2048dda 100644 --- a/public/misc/script.manage.js +++ b/public/misc/script.manage.js @@ -22,9 +22,9 @@ $(document).ready(function(){ .append($('
    ', { + text: newUser + })) + .append($('', { + text: 'User' + })) + .append($('', { + class: 'immutable', + html: ' ' + + '' + })) + ); // Call `editableTableWidget()` again to include the newly added `
    ', { class: 'immutable', html: ' ' + + locales[(localStorage.getItem('language') !== null ? localStorage.getItem('language') : 'en')]['button_sessions'] + ' ' + '' })) ); @@ -69,6 +69,10 @@ console.log({'new': newEntries, 'removed': removedEntries}); window.location.reload(); }); + $('#linklogout').click(function() { + console.log('Logging out!'); + }); + if (localStorage.getItem('theme') !== null) { $('#theme').addClass(localStorage.getItem('theme')); }