Periodic merge upstream #2
@ -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.
|
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
|
## Questions or bugs
|
||||||
Feel free to open issues in this repository (or in its mirror on [GitHub](#)).
|
Feel free to open issues in this repository.
|
@ -66,11 +66,11 @@ function storeToken (string $secureToken, string $qualifiedUsername, string $htt
|
|||||||
INSERT INTO SecureToken (UserId, Value)
|
INSERT INTO SecureToken (UserId, Value)
|
||||||
SELECT User.Id, :securetoken
|
SELECT User.Id, :securetoken
|
||||||
FROM User
|
FROM User
|
||||||
WHERE User.Username = :qualifiedusername
|
WHERE LOWER(User.Username) = :qualifiedusername
|
||||||
');
|
');
|
||||||
$pdoQuery->execute([
|
$pdoQuery->execute([
|
||||||
':securetoken' => $secureToken,
|
':securetoken' => $secureToken,
|
||||||
':qualifiedusername' => $qualifiedUsername
|
':qualifiedusername' => strtolower($qualifiedUsername)
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
catch (Exception $e) {
|
catch (Exception $e) {
|
||||||
@ -114,18 +114,19 @@ function validateToken (string $secureToken) {
|
|||||||
|
|
||||||
// Retrieve all authentication tokens from database matching username
|
// Retrieve all authentication tokens from database matching username
|
||||||
$pdoQuery = $pdoDB->prepare('
|
$pdoQuery = $pdoDB->prepare('
|
||||||
SELECT SecureToken.Value
|
SELECT User.Id, SecureToken.Value
|
||||||
FROM SecureToken
|
FROM SecureToken
|
||||||
LEFT JOIN User
|
LEFT JOIN User
|
||||||
ON (User.Id=SecureToken.UserId)
|
ON (User.Id=SecureToken.UserId)
|
||||||
WHERE User.Username = :username
|
WHERE LOWER(User.Username) = :username
|
||||||
');
|
');
|
||||||
$pdoQuery->execute([
|
$pdoQuery->execute([
|
||||||
':username' => (string)$jwtPayload->sub
|
':username' => (string) strtolower($jwtPayload->sub)
|
||||||
]);
|
]);
|
||||||
foreach($pdoQuery->fetchAll(PDO::FETCH_ASSOC) as $row) {
|
foreach($pdoQuery->fetchAll(PDO::FETCH_ASSOC) as $row) {
|
||||||
try {
|
try {
|
||||||
$storedTokens[] = JWT::decode($row['Value'], base64_decode($settings->JWT['PrivateKey_base64']), $settings->JWT['Algorithm']);
|
$storedTokens[] = JWT::decode($row['Value'], base64_decode($settings->JWT['PrivateKey_base64']), $settings->JWT['Algorithm']);
|
||||||
|
$currentUserId = $row['Id'];
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -135,10 +136,14 @@ function validateToken (string $secureToken) {
|
|||||||
if (!empty($storedTokens) && sizeof(array_filter($storedTokens, function ($value) use ($jwtPayload) {
|
if (!empty($storedTokens) && sizeof(array_filter($storedTokens, function ($value) use ($jwtPayload) {
|
||||||
return $value->iat === $jwtPayload->iat;
|
return $value->iat === $jwtPayload->iat;
|
||||||
})) === 1) {
|
})) === 1) {
|
||||||
return ['status' => 'Success'];
|
return [
|
||||||
|
'status' => 'Success',
|
||||||
|
'name' => $jwtPayload->name,
|
||||||
|
'uid' => $currentUserId
|
||||||
|
];
|
||||||
} else {
|
} else {
|
||||||
if ($settings->Debug['LogToFile']) {
|
if ($settings->Debug['LogToFile']) {
|
||||||
file_put_contents('../validateToken.log', (new DateTime())->format('Y-m-d\TH:i:s.u') . ' --- No matching token in database' . PHP_EOL, FILE_APPEND);
|
file_put_contents('../validateToken.log', (new DateTime())->format('Y-m-d\TH:i:s.u') . ' --- Either no matching token or multiple matching tokens found in database' . PHP_EOL, FILE_APPEND);
|
||||||
}
|
}
|
||||||
return ['status' => 'Fail', 'reason' => '2'];
|
return ['status' => 'Fail', 'reason' => '2'];
|
||||||
}
|
}
|
||||||
|
@ -9,15 +9,11 @@ $pageLayout['full'] = <<<'FULL'
|
|||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<title>lucidAuth</title>
|
<title>lucidAuth</title>
|
||||||
<meta name="application-name" content="lucidAuth" />
|
<meta name="application-name" content="lucidAuth" />
|
||||||
<meta name="theme-color" content="#B50000" />
|
<meta name="theme-color" content="#003399" />
|
||||||
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" />
|
|
||||||
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png" />
|
|
||||||
<link rel="manifest" href="/manifest.json" />
|
|
||||||
<link href="misc/style.css" rel="stylesheet" />
|
<link href="misc/style.css" rel="stylesheet" />
|
||||||
<link href="misc/style.theme.css" rel="stylesheet" />
|
<link href="misc/style.theme.css" rel="stylesheet" />
|
||||||
<link href="misc/style.button.css" rel="stylesheet" />
|
<link href="misc/style.button.css" rel="stylesheet" />
|
||||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.js"></script>
|
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.js"></script>
|
||||||
<script src="misc/script.theme.js"></script>
|
|
||||||
<script src="misc/script.translation.js"></script>
|
<script src="misc/script.translation.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@ -36,6 +32,46 @@ $pageLayout['full'] = <<<'FULL'
|
|||||||
</html>
|
</html>
|
||||||
FULL;
|
FULL;
|
||||||
|
|
||||||
|
$pageLayout['full_alt'] = <<<'FULL_ALT'
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="nl">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<title>lucidAuth</title>
|
||||||
|
<meta name="application-name" content="lucidAuth" />
|
||||||
|
<meta name="theme-color" content="#003399" />
|
||||||
|
<link href="misc/style.css" rel="stylesheet" />
|
||||||
|
<link href="misc/style.panes.css" rel="stylesheet" />
|
||||||
|
<link href="misc/style.button.css" rel="stylesheet" />
|
||||||
|
<link href="misc/style.theme.css" rel="stylesheet" />
|
||||||
|
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.js"></script>
|
||||||
|
<script src="misc/script.translation.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="wrapper">
|
||||||
|
<section id="theme" class="content">
|
||||||
|
<div class="columns">
|
||||||
|
<main class="main">
|
||||||
|
<header class="header">
|
||||||
|
<div class="logo">
|
||||||
|
<div class="left"><div class="middle">lucidAuth</div></div><div class="right"></div>
|
||||||
|
<div class="sub"><em>Respect</em> the unexpected; mitigate your risks</div>
|
||||||
|
</div>
|
||||||
|
%1$s
|
||||||
|
</header>
|
||||||
|
<section>
|
||||||
|
%2$s
|
||||||
|
</section>
|
||||||
|
</main>
|
||||||
|
<aside class="sidebar-first"></aside>
|
||||||
|
<aside class="sidebar-second"></aside>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
FULL_ALT;
|
||||||
|
|
||||||
$pageLayout['bare'] = <<<'BARE'
|
$pageLayout['bare'] = <<<'BARE'
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="nl">
|
<html lang="nl">
|
||||||
@ -52,72 +88,64 @@ $pageLayout['bare'] = <<<'BARE'
|
|||||||
</html>
|
</html>
|
||||||
BARE;
|
BARE;
|
||||||
|
|
||||||
$contentLayout['login'] = <<<LOGIN
|
$contentLayout['login'] = <<<'LOGIN'
|
||||||
<script src="misc/script.index.js"></script>
|
<script src="misc/script.index.js"></script>
|
||||||
<fieldset>
|
<section>
|
||||||
<legend>Login Details</legend>
|
|
||||||
<ul>
|
<ul>
|
||||||
|
<li class="misc">
|
||||||
|
<span class="indent"> </span>
|
||||||
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<label class="pre" for="username" data-translation="label_username">Gebruikersnaam:</label>
|
<label class="pre" for="username" data-translation="label_username">Username:</label>
|
||||||
<input type="text" id="username" name="username" tabindex="100" />
|
<input type="text" id="username" name="username" tabindex="100" />
|
||||||
<label for="username">@lucidAuth</label>
|
<label for="username">@lucidAuth</label>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<label class="pre" for="password" data-translation="label_password">Wachtwoord:</label>
|
<label class="pre" for="password" data-translation="label_password">Password:</label>
|
||||||
<input type="password" id="password" name="password" tabindex="200" />
|
<input type="password" id="password" name="password" tabindex="200" />
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<input type="hidden" id="ref" name="ref" value="{$_GET['ref']}" />
|
<input type="hidden" id="ref" name="ref" value="%1$s" />
|
||||||
<button id="btnlogin" class="bttn-simple bttn-xs bttn-primary" tabindex="300" data-translation="button_login">login</button>
|
<button id="btnlogin" class="bttn-simple bttn-xs bttn-primary" tabindex="300" data-translation="button_login">login</button>
|
||||||
</li>
|
</li>
|
||||||
<li class="misc">
|
<li class="misc">
|
||||||
<span class="indent"> </span>
|
<span class="indent" data-translation="span_credentialsavailable">Login credentials available upon request!</span>
|
||||||
</li>
|
|
||||||
<li class="misc">
|
|
||||||
<span class="indent" data-translation="span_credentialsavailable">Inloggegevens verkrijgbaar op aanvraag!</span>
|
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</fieldset>
|
</section>
|
||||||
<img src="/images/tag_lock.png" style="position: absolute; top: 175px; left: 20px;" alt="Secure!" />
|
<img src="/images/tag_lock.png" style="position: absolute; top: 175px; left: 20px;" alt="Secure!" />
|
||||||
LOGIN;
|
LOGIN;
|
||||||
|
|
||||||
$contentLayout['manage'] = <<<MANAGE
|
$contentLayout['manage']['header'] = <<<'MANAGE_HEADER'
|
||||||
|
<script src="misc/script.editable.table.js"></script>
|
||||||
<script src="misc/script.manage.js"></script>
|
<script src="misc/script.manage.js"></script>
|
||||||
<span id="user"><span data-translation="span_loggedinas">Ingelogd als</span> {$_SESSION['fullname']} --- [<a id="linkplugindialog" tabindex="600" data-translation="link_plugin">Browser plugin</a><div id="pluginlogos"><span data-translation="label_selectbrowser" style="float: left; margin-left: 5px;">Select browser:</span><span style="font-size: 8px; float: right; margin-right: 5px; margin-top: 2px;">[v0.2.122.4]</span><br /><img id="linkpluginchrome" src="images/chrome_256x256.png" /><img id="linkpluginfirefox" src="images/firefox_256x256.png" /><img id="linkpluginopera" src="images/opera_256x256.png" /></div>] [<a id="linklanguage-en" href="#" tabindex="700">EN</a> <a id="linklanguage-nl" class="current" href="#" tabindex="700">NL</a>] [<a href="index.php?do=logout" tabindex="800" data-translation="link_logout">Log uit</a>]</span>
|
<span id="user"><span data-translation="span_loggedinas">Logged in as</span> %1$s --- [<a id="linklanguage-en" href="#" tabindex="700">EN</a> <a id="linklanguage-nl" class="current" href="#" tabindex="700">NL</a>] [<a href="#" tabindex="800" data-translation="link_logout">Logout</a>]</span>
|
||||||
<!-- <fieldset style="clear: both;">
|
<ul style="clear: both; margin-top: 20px;">
|
||||||
<legend>Beheer Account</legend>
|
<li class="buttons">
|
||||||
|
<button id="btnnewuser" class="bttn-simple bttn-xs bttn-primary" data-translation="button_new">new</button>
|
||||||
|
|
||||||
|
<button id="btnsave" class="bttn-simple bttn-xs bttn-primary" data-translation="button_save">save</button>
|
||||||
|
<button id="btncancel" class="bttn-simple bttn-xs bttn-primary" data-translation="button_cancel">cancel</button>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
MANAGE_HEADER;
|
||||||
|
$contentLayout['manage']['section'] = <<<'MANAGE_SECTION'
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
</li>
|
<table id="usertable">
|
||||||
<li>
|
<thead>
|
||||||
<button id="btnaliasadd" class="bttn-simple bttn-xs bttn-primary" tabindex="200" data-translation="button_add">voeg toe</button>
|
<tr>
|
||||||
</li>
|
<th class="immutable" data-translation="th_username">Username</th>
|
||||||
<li>
|
<th class="immutable" data-translation="th_role">Role</th>
|
||||||
<label id="labelallaliases" class="pre" for="allaliases" data-translation="label_allaliases">Alle aliassen:</label><output id="aliasstats">[--]</output>
|
<th class="immutable" data-translation="th_manage">Manage</th>
|
||||||
<select id="allaliases" size="10" multiple="multiple" tabindex="300">
|
</tr>
|
||||||
</select>
|
</thead>
|
||||||
</li>
|
<tbody>
|
||||||
<li>
|
%1$s
|
||||||
<button id="btnaliasdelete" class="bttn-simple bttn-xs bttn-primary" tabindex="400" data-translation="button_delete">verwijder</button>
|
</tbody>
|
||||||
</li>
|
</table>
|
||||||
<li>
|
|
||||||
<button id="btnsync" class="bttn-simple bttn-xs bttn-primary" style="background-position: center;" tabindex="500" data-translation="button_sync">synchroniseer</button>
|
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</fieldset>
|
MANAGE_SECTION;
|
||||||
-->
|
|
||||||
MANAGE;
|
|
||||||
|
|
||||||
$contentLayout['dialog'] = <<<DIALOG
|
|
||||||
<ul class="dialog">
|
|
||||||
<li>
|
|
||||||
<!--REPL_DIALOGDESC-->
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<button id="btnhome" class="bttn-simple bttn-xs bttn-primary" tabindex="400" data-translation="button_home">ga naar startpagina</button>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
DIALOG;
|
|
||||||
|
|
||||||
|
|
||||||
?>
|
?>
|
@ -3,15 +3,18 @@
|
|||||||
|
|
||||||
include_once('../include/lucidAuth.functions.php');
|
include_once('../include/lucidAuth.functions.php');
|
||||||
|
|
||||||
echo $settings->Debug['Verbose'];
|
|
||||||
|
|
||||||
if ($_POST['do'] == 'login') {
|
if ($_POST['do'] == 'login') {
|
||||||
$result = authenticateLDAP($_POST['username'], $_POST['password']);
|
$result = authenticateLDAP($_POST['username'], $_POST['password']);
|
||||||
if ($result['status'] == 'Success') {
|
if ($result['status'] === 'Success') {
|
||||||
// Store authentication token; in database serverside & in cookie clientside
|
// Store authentication token; in database serverside & in cookie clientside
|
||||||
if (storeToken($result['token'], $settings->LDAP['Domain'] . '\\' . $_POST['username'], $_SERVER['HTTP_HOST'])['status'] !== 'Success') {
|
if (storeToken($result['token'], $settings->LDAP['Domain'] . '\\' . $_POST['username'], $_SERVER['HTTP_HOST'])['status'] !== 'Success') {
|
||||||
// Since this action is only ever called through an AJAX-request; return JSON object
|
// Return JSON object
|
||||||
echo '{"Result":"Fail","Reason":"Failed storing authentication token in database and/or cookie"}' . PHP_EOL;
|
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;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -21,33 +24,50 @@
|
|||||||
$proxyHeaders = json_decode(base64_decode($_POST['ref']), JSON_OBJECT_AS_ARRAY);
|
$proxyHeaders = json_decode(base64_decode($_POST['ref']), JSON_OBJECT_AS_ARRAY);
|
||||||
}
|
}
|
||||||
catch (Exception $e) {
|
catch (Exception $e) {
|
||||||
// Since this action is only ever called through an AJAX-request; return JSON object
|
// Return JSON object
|
||||||
echo '{"Result":"Fail","Reason":"Original request URI lost in transition"}' . PHP_EOL;
|
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;
|
exit;
|
||||||
}
|
}
|
||||||
$originalUri = !empty($proxyHeaders) ? $proxyHeaders['XForwardedProto'] . '://' . $proxyHeaders['XForwardedHost'] . $proxyHeaders['XForwardedUri'] : 'lucidAuth.manage.php';
|
$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
|
// Return JSON object
|
||||||
header('Content-Type: application/json');
|
header('Content-Type: application/json');
|
||||||
echo json_encode([
|
echo json_encode([
|
||||||
"Result" => "Success",
|
"Result" => "Success",
|
||||||
"Location" => $originalUri,
|
"Location" => $originalUri,
|
||||||
"CrossDomainLogin" => $settings->Session['CrossDomainLogin']
|
"CrossDomainLogin" => $settings->Session['CrossDomainLogin']
|
||||||
]);
|
]);
|
||||||
# echo sprintf('{"Result":"Success","Location":"%1$s","CrossDomainLogin":%2$s}', $originalUri, $settings->Session['CrossDomainLogin'] ? 'True' : 'False') . PHP_EOL;
|
|
||||||
} else {
|
} else {
|
||||||
switch ($result['reason']) {
|
switch ($result['reason']) {
|
||||||
case '1':
|
case '1':
|
||||||
echo '{"Result":"Fail","Reason":"Invalid username and/or password"}' . PHP_EOL;
|
header('Content-Type: application/json');
|
||||||
|
echo json_encode([
|
||||||
|
"Result" => "Failure",
|
||||||
|
"Reason" => "Invalid username and/or password"
|
||||||
|
]);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
echo '{"Result":"Fail","Reason":"Uncaught error"}' . PHP_EOL;
|
header('Content-Type: application/json');
|
||||||
|
echo json_encode([
|
||||||
|
"Result" => "Failure",
|
||||||
|
"Reason" => "Uncaught error"
|
||||||
|
]);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
include_once('../include/lucidAuth.template.php');
|
include_once('../include/lucidAuth.template.php');
|
||||||
|
|
||||||
echo sprintf($pageLayout['full'], $contentLayout['login']);
|
echo sprintf($pageLayout['full'],
|
||||||
|
sprintf($contentLayout['login'],
|
||||||
|
$_GET['ref']
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
?>
|
51
public/lucidAuth.manage.php
Normal file
51
public/lucidAuth.manage.php
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
<?php
|
||||||
|
error_reporting(E_ALL ^ E_NOTICE);
|
||||||
|
|
||||||
|
include_once('../include/lucidAuth.functions.php');
|
||||||
|
|
||||||
|
if (!empty($_COOKIE['JWT'])) {
|
||||||
|
$validateTokenResult = validateToken($_COOKIE['JWT']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($validateTokenResult['status'] === "Success") {
|
||||||
|
include_once('../include/lucidAuth.template.php');
|
||||||
|
|
||||||
|
try {
|
||||||
|
$allUsers = $pdoDB->query('
|
||||||
|
SELECT User.Id, User.Username, Role.Rolename
|
||||||
|
FROM User
|
||||||
|
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('<tr%1$s><td data-userid="%2$s">%3$s</td><td>%4$s</td><td class="immutable">%5$s</td></tr>',
|
||||||
|
$validateTokenResult['uid'] === $row['Id'] ? ' class="currentuser"': null,
|
||||||
|
$row['Id'],
|
||||||
|
explode('\\', $row['Username'])[1],
|
||||||
|
$row['Rolename'],
|
||||||
|
'<button class="bttn-simple bttn-xs bttn-primary" data-translation="button_sessions">Sessions</button>' . ($validateTokenResult['uid'] === $row['Id'] ? null : ' <button class="bttn-simple bttn-xs bttn-primary delete" data-translation="button_delete">Delete</button>')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
echo sprintf($pageLayout['full_alt'],
|
||||||
|
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
|
||||||
|
setcookie('JWT', FALSE);
|
||||||
|
|
||||||
|
header("HTTP/1.1 401 Unauthorized");
|
||||||
|
header("Location: lucidAuth.login.php");
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
include_once('../include/lucidAuth.template.php');
|
include_once('../include/lucidAuth.template.php');
|
||||||
|
|
||||||
echo sprintf($pageLayout['bare',
|
echo sprintf($pageLayout['bare'],
|
||||||
'// iFrames go here'
|
'// iFrames go here'
|
||||||
);
|
);
|
||||||
?>
|
?>
|
131
public/misc/script.editable.table.js
Normal file
131
public/misc/script.editable.table.js
Normal file
@ -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: $('<input id="editor">')
|
||||||
|
};
|
||||||
|
|
@ -19,7 +19,7 @@ $(document).ready(function(){
|
|||||||
password: $('#password').val(),
|
password: $('#password').val(),
|
||||||
ref: $('#ref').val()
|
ref: $('#ref').val()
|
||||||
})
|
})
|
||||||
.done(function(data,status) {
|
.done(function(data,_status) {
|
||||||
if (data.Result === 'Success') {
|
if (data.Result === 'Success') {
|
||||||
$('#btnlogin').css({
|
$('#btnlogin').css({
|
||||||
'background': 'green url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAaklEQVQ4jeXOMQ5AQBBG4T2BC4i76EWich7ncAKbqCRuodTqnMNTkFgJs3ZU4tXz/Rlj/hUQv8EpMAClFk9sjUAiHVcCnoFMwhZYgPYG575Xe46aIOyMdJx7ji9GwrEzUgOFCu8DkRp/qxU2BKCUyZR6ygAAAABJRU5ErkJggg==) no-repeat center',
|
'background': 'green url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAaklEQVQ4jeXOMQ5AQBBG4T2BC4i76EWich7ncAKbqCRuodTqnMNTkFgJs3ZU4tXz/Rlj/hUQv8EpMAClFk9sjUAiHVcCnoFMwhZYgPYG575Xe46aIOyMdJx7ji9GwrEzUgOFCu8DkRp/qxU2BKCUyZR6ygAAAABJRU5ErkJggg==) no-repeat center',
|
||||||
|
91
public/misc/script.manage.js
Normal file
91
public/misc/script.manage.js
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
$(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');
|
||||||
|
|
||||||
|
// Add new user to the interface
|
||||||
|
// (new `<tr>` in `<table id="usertable">`)
|
||||||
|
$('#usertable tbody').append($('<tr>', {class: 'new'})
|
||||||
|
.append($('<td>', {
|
||||||
|
text: newUser
|
||||||
|
}))
|
||||||
|
.append($('<td>', {
|
||||||
|
text: 'User'
|
||||||
|
}))
|
||||||
|
.append($('<td>', {
|
||||||
|
class: 'immutable',
|
||||||
|
html: '<button class="bttn-simple bttn-xs bttn-primary disabled" data-translation="button_sessions" disabled="true">' +
|
||||||
|
locales[(localStorage.getItem('language') !== null ? localStorage.getItem('language') : 'nl')]['button_sessions'] + '</button> ' +
|
||||||
|
'<button class="bttn-simple bttn-xs bttn-primary delete" data-translation="button_delete">' +
|
||||||
|
locales[(localStorage.getItem('language') !== null ? localStorage.getItem('language') : 'nl')]['button_delete'] +
|
||||||
|
'</button>'
|
||||||
|
}))
|
||||||
|
);
|
||||||
|
// Call `editableTableWidget()` again to include the newly added `<tr>`
|
||||||
|
// To prevent recreating multiple new editors; reference the already existing `<input>`
|
||||||
|
$('#usertable').editableTableWidget({editor: $('#editor')});
|
||||||
|
// Add eventhandlers to buttons of newly added `<tr>`
|
||||||
|
$('#usertable .new button.delete').unbind().click(function() {
|
||||||
|
$(this).closest('tr').remove();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#btnsave').click(function() {
|
||||||
|
var newEntries = [];
|
||||||
|
$('#usertable .new').each(function() {
|
||||||
|
newEntries.push({
|
||||||
|
'userName': $(this).find('td:nth-child(1)').text(),
|
||||||
|
'roleName': $(this).find('td:nth-child(2)').text()
|
||||||
|
});
|
||||||
|
});
|
||||||
|
var removedEntries = [];
|
||||||
|
$('#usertable .removed').each(function() {
|
||||||
|
removedEntries.push({
|
||||||
|
'userId': $(this).find('td:nth-child(1)').data('userid'),
|
||||||
|
'userName': $(this).find('td:nth-child(1)').text(),
|
||||||
|
'roleName': $(this).find('td:nth-child(2)').text()
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log({'new': newEntries, 'removed': removedEntries});
|
||||||
|
|
||||||
|
/* $.get("psworker.php", {
|
||||||
|
do: "mutate",
|
||||||
|
mutations: {
|
||||||
|
new: newEntries,
|
||||||
|
removed: removedEntries
|
||||||
|
}
|
||||||
|
})*/
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#btncancel').click(function() {
|
||||||
|
window.location.reload();
|
||||||
|
});
|
||||||
|
|
||||||
|
if (localStorage.getItem('theme') !== null) {
|
||||||
|
$('#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');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
@ -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');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,37 +1,37 @@
|
|||||||
var locales = {
|
var locales = {
|
||||||
en: {
|
en: {
|
||||||
button_add: "add",
|
button_new: "new",
|
||||||
|
button_save: "save",
|
||||||
button_cancel: "cancel",
|
button_cancel: "cancel",
|
||||||
button_continue: "continue",
|
button_sessions: "sessions",
|
||||||
button_delete: "delete",
|
button_delete: "delete",
|
||||||
button_login: "login",
|
button_login: "login",
|
||||||
heading_error: "ERROR!",
|
heading_error: "ERROR!",
|
||||||
label_password: "Password:",
|
label_password: "Password:",
|
||||||
label_username: "Username:",
|
label_username: "Username:",
|
||||||
label_selectbrowser: "Select browser:",
|
|
||||||
link_install: "Install!",
|
|
||||||
link_logout: "Logout",
|
link_logout: "Logout",
|
||||||
link_plugin: "Browser plugin",
|
|
||||||
span_credentialsavailable: "Login credentials available upon request!",
|
span_credentialsavailable: "Login credentials available upon request!",
|
||||||
span_loggedinas: "Logged in as",
|
span_loggedinas: "Logged in as",
|
||||||
span_plugin: "Browser plugin?"
|
th_username: "Username",
|
||||||
|
th_role: "Role",
|
||||||
|
th_manage: "Manage"
|
||||||
},
|
},
|
||||||
nl: {
|
nl: {
|
||||||
button_add: "voeg toe",
|
button_new: "nieuw",
|
||||||
button_cancel: "annuleer",
|
button_save: "opslaan",
|
||||||
button_continue: "doorgaan",
|
button_cancel: "annuleren",
|
||||||
|
button_sessions: "sessies",
|
||||||
button_delete: "verwijder",
|
button_delete: "verwijder",
|
||||||
button_login: "log in",
|
button_login: "log in",
|
||||||
heading_error: "FOUT!",
|
heading_error: "FOUT!",
|
||||||
label_password: "Wachtwoord:",
|
label_password: "Wachtwoord:",
|
||||||
label_username: "Gebruikersnaam:",
|
label_username: "Gebruikersnaam:",
|
||||||
label_selectbrowser: "Selecteer browser:",
|
|
||||||
link_install: "Installeer!",
|
|
||||||
link_logout: "Log uit",
|
link_logout: "Log uit",
|
||||||
link_plugin: "Browser plugin",
|
|
||||||
span_credentialsavailable: "Inloggegevens verkrijgbaar op aanvraag!",
|
span_credentialsavailable: "Inloggegevens verkrijgbaar op aanvraag!",
|
||||||
span_loggedinas: "Ingelogd als",
|
span_loggedinas: "Ingelogd als",
|
||||||
span_plugin: "Browser plugin?"
|
th_username: "Gebruikersnaam",
|
||||||
|
th_role: "Rol",
|
||||||
|
th_manage: "Beheer"
|
||||||
} // ... etc.
|
} // ... etc.
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -39,7 +39,7 @@ $(document).ready(function(){
|
|||||||
$('[id^=linklanguage-]').click(function() {
|
$('[id^=linklanguage-]').click(function() {
|
||||||
var selectedlang = $(this).attr('id').split('-')[1];
|
var selectedlang = $(this).attr('id').split('-')[1];
|
||||||
// Replace text of each element with translated value
|
// Replace text of each element with translated value
|
||||||
$('[data-translation]').each(function(index) {
|
$('[data-translation]').each(function() {
|
||||||
$(this).text(locales[selectedlang][$(this).data('translation')]);
|
$(this).text(locales[selectedlang][$(this).data('translation')]);
|
||||||
});
|
});
|
||||||
// Enable/disable (toggle) anchors
|
// Enable/disable (toggle) anchors
|
||||||
@ -51,7 +51,7 @@ $(document).ready(function(){
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (localStorage.getItem('language') !== null) {
|
if (localStorage.getItem('language') !== null) {
|
||||||
$('[data-translation]').each(function(index) {
|
$('[data-translation]').each(function() {
|
||||||
$(this).text(locales[localStorage.getItem('language')][$(this).data('translation')]);
|
$(this).text(locales[localStorage.getItem('language')][$(this).data('translation')]);
|
||||||
});
|
});
|
||||||
$('span#user a.current').removeClass('current');
|
$('span#user a.current').removeClass('current');
|
||||||
|
@ -96,63 +96,59 @@ body {
|
|||||||
.main {
|
.main {
|
||||||
clear: both;
|
clear: both;
|
||||||
}
|
}
|
||||||
.main fieldset {
|
.main section {
|
||||||
border: 0;
|
clear: both;
|
||||||
}
|
}
|
||||||
.main fieldset legend {
|
.main section label.pre {
|
||||||
visibility: hidden;
|
|
||||||
}
|
|
||||||
.main fieldset label.pre {
|
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
width: 155px;
|
width: 155px;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
vertical-align: top;
|
vertical-align: top;
|
||||||
margin-top: 3px;
|
margin-top: 3px;
|
||||||
}
|
}
|
||||||
.main fieldset label#labelallaliases {
|
.main section input {
|
||||||
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;
|
border: 1px solid #003399;
|
||||||
padding: 2px;
|
padding: 2px;
|
||||||
width: 100px;
|
width: 100px;
|
||||||
}
|
}
|
||||||
.main fieldset input[type=radio] {
|
.main section input[type=radio] {
|
||||||
border: none;
|
border: none;
|
||||||
margin-top: 7px;
|
margin-top: 7px;
|
||||||
width: 20px;
|
width: 20px;
|
||||||
}
|
}
|
||||||
.main fieldset button {
|
.main header button,
|
||||||
|
.main section button {
|
||||||
margin-left: 160px;
|
margin-left: 160px;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
}
|
}
|
||||||
.main fieldset select {
|
.main header .buttons,
|
||||||
border: 1px solid #003399;
|
.main section .buttons {
|
||||||
padding: 2px;
|
text-align: center;
|
||||||
width: 375px;
|
|
||||||
}
|
}
|
||||||
.main fieldset select .new {
|
.main header .buttons button,
|
||||||
|
.main section .buttons button {
|
||||||
|
margin-left: inherit;
|
||||||
|
}
|
||||||
|
.main section table {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.main section table * {
|
||||||
|
font-size: 14px;
|
||||||
|
padding: 2px;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
.main section table .new {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
.main fieldset select .deleted {
|
.main section table .removed td:nth-child(-n+2) {
|
||||||
text-decoration: line-through;
|
text-decoration: line-through;
|
||||||
|
color: grey;
|
||||||
}
|
}
|
||||||
.main fieldset#signup label.pre {
|
.main section table tbody tr:nth-child(odd) {
|
||||||
width: 205px;
|
background-color: rgb(215, 215, 215);
|
||||||
}
|
}
|
||||||
.main fieldset#signup span.indent, .main fieldset#signup input.button {
|
.main section table .immutable {
|
||||||
margin-left: 210px;
|
cursor: default !important;
|
||||||
}
|
}
|
||||||
.main li {
|
.main li {
|
||||||
list-style: none;
|
list-style: none;
|
||||||
@ -214,25 +210,3 @@ body {
|
|||||||
.main span#user nav {
|
.main span#user nav {
|
||||||
display: inline;
|
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;
|
|
||||||
}
|
|
||||||
|
50
public/misc/style.panes.css
Normal file
50
public/misc/style.panes.css
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
body{
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
.wrapper{
|
||||||
|
min-height: 100vh;
|
||||||
|
background: #FFFFFF;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
.header {
|
||||||
|
height: 100px;
|
||||||
|
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% - 100px);
|
||||||
|
}
|
||||||
|
.sidebar-first{
|
||||||
|
width: 25%;
|
||||||
|
background: transparent;
|
||||||
|
order: 1;
|
||||||
|
}
|
||||||
|
.sidebar-second{
|
||||||
|
width: 25%;
|
||||||
|
order: 3;
|
||||||
|
background: transparent;
|
||||||
|
}
|
@ -1,11 +1,11 @@
|
|||||||
html.tablecloth {
|
#theme.tablecloth {
|
||||||
height: 100%;
|
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),
|
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;
|
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;
|
background-blend-mode: multiply;
|
||||||
}
|
}
|
||||||
|
|
||||||
html.weave {
|
#theme.weave {
|
||||||
background: linear-gradient(45deg, #666 12%, transparent 0, transparent 88%, #666 0),
|
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(135deg, transparent 37%, #888 0, #888 63%, transparent 0),
|
||||||
linear-gradient(45deg, transparent 37%, #666 0, #666 63%, transparent 0),
|
linear-gradient(45deg, transparent 37%, #666 0, #666 63%, transparent 0),
|
||||||
@ -13,14 +13,14 @@ html.weave {
|
|||||||
background-size: 40px 40px;
|
background-size: 40px 40px;
|
||||||
}
|
}
|
||||||
|
|
||||||
html.madras {
|
#theme.madras {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background-color: #e9d4b9;
|
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),
|
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);
|
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 {
|
#theme.tartan {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background-color: #a0302c;
|
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),
|
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),
|
||||||
@ -28,7 +28,7 @@ html.tartan {
|
|||||||
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);
|
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 {
|
#theme.seigaiha {
|
||||||
background-color: grey;
|
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)),
|
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 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)),
|
||||||
|
Loading…
Reference in New Issue
Block a user