new style, add redirect support
Before (image error) Size: 367 KiB |
BIN
src/public/bg/0001.jpg
Normal file
After (image error) Size: 285 KiB |
BIN
src/public/bg/0002.jpg
Normal file
After (image error) Size: 950 KiB |
BIN
src/public/bg/0003.jpg
Normal file
After (image error) Size: 685 KiB |
BIN
src/public/bg/0004.jpg
Normal file
After (image error) Size: 3.1 MiB |
BIN
src/public/bg/0005.jpg
Normal file
After (image error) Size: 681 KiB |
BIN
src/public/bg/0006.jpg
Normal file
After (image error) Size: 2.1 MiB |
BIN
src/public/bg/0007.jpg
Normal file
After (image error) Size: 554 KiB |
BIN
src/public/bg/0008.jpg
Normal file
After (image error) Size: 568 KiB |
BIN
src/public/bg/0009.jpg
Normal file
After (image error) Size: 322 KiB |
BIN
src/public/bg/0010.jpg
Normal file
After (image error) Size: 856 KiB |
BIN
src/public/bg/0011.jpg
Normal file
After (image error) Size: 807 KiB |
BIN
src/public/bg/0012.jpg
Normal file
After (image error) Size: 1.6 MiB |
BIN
src/public/bg/0013.jpg
Normal file
After (image error) Size: 374 KiB |
BIN
src/public/bg/0014.jpg
Normal file
After (image error) Size: 833 KiB |
BIN
src/public/bg/0015.jpg
Normal file
After (image error) Size: 1 MiB |
BIN
src/public/bg/0016.jpg
Normal file
After (image error) Size: 291 KiB |
BIN
src/public/bg/0017.jpg
Normal file
After (image error) Size: 172 KiB |
BIN
src/public/bg/0018.jpg
Normal file
After (image error) Size: 197 KiB |
BIN
src/public/bg/0019.jpg
Normal file
After (image error) Size: 1.8 MiB |
BIN
src/public/bg/0020.jpg
Normal file
After (image error) Size: 425 KiB |
BIN
src/public/bg/0021.jpg
Normal file
After (image error) Size: 1.3 MiB |
BIN
src/public/bg/0022.jpg
Normal file
After (image error) Size: 185 KiB |
BIN
src/public/bg/0023.jpg
Normal file
After (image error) Size: 157 KiB |
BIN
src/public/bg/0024.jpg
Normal file
After (image error) Size: 182 KiB |
BIN
src/public/bg/0025.jpg
Normal file
After (image error) Size: 183 KiB |
BIN
src/public/bg/0026.jpg
Normal file
After (image error) Size: 558 KiB |
BIN
src/public/bg/0027.jpg
Normal file
After (image error) Size: 395 KiB |
BIN
src/public/bg/0028.jpg
Normal file
After (image error) Size: 772 KiB |
BIN
src/public/bg/0029.jpg
Normal file
After (image error) Size: 1.2 MiB |
BIN
src/public/bg/0030.jpg
Normal file
After (image error) Size: 770 KiB |
BIN
src/public/bg/0031.jpg
Normal file
After (image error) Size: 1.3 MiB |
BIN
src/public/bg/0032.jpg
Normal file
After (image error) Size: 854 KiB |
BIN
src/public/bg/0033.jpg
Normal file
After (image error) Size: 570 KiB |
BIN
src/public/bg/0034.jpg
Normal file
After (image error) Size: 441 KiB |
BIN
src/public/bg/0035.jpg
Normal file
After (image error) Size: 177 KiB |
BIN
src/public/bg/0036.jpg
Normal file
After (image error) Size: 155 KiB |
BIN
src/public/bg/0037.jpg
Normal file
After (image error) Size: 401 KiB |
BIN
src/public/bg/0038.jpg
Normal file
After (image error) Size: 439 KiB |
BIN
src/public/bg/0039.jpg
Normal file
After (image error) Size: 743 KiB |
BIN
src/public/bg/0040.jpg
Normal file
After (image error) Size: 568 KiB |
BIN
src/public/bg/0041.jpg
Normal file
After (image error) Size: 505 KiB |
BIN
src/public/bg/0042.jpg
Normal file
After (image error) Size: 710 KiB |
BIN
src/public/bg/0043.jpg
Normal file
After (image error) Size: 735 KiB |
BIN
src/public/bg/0044.jpg
Normal file
After (image error) Size: 313 KiB |
BIN
src/public/bg/0045.jpg
Normal file
After (image error) Size: 218 KiB |
BIN
src/public/bg/0046.jpg
Normal file
After (image error) Size: 964 KiB |
BIN
src/public/bg/0047.jpg
Normal file
After (image error) Size: 255 KiB |
BIN
src/public/bg/0048.jpg
Normal file
After (image error) Size: 412 KiB |
BIN
src/public/bg/0049.jpg
Normal file
After (image error) Size: 118 KiB |
BIN
src/public/bg/0050.jpg
Normal file
After (image error) Size: 244 KiB |
BIN
src/public/bg/0051.jpg
Normal file
After (image error) Size: 157 KiB |
BIN
src/public/bg/0052.jpg
Normal file
After (image error) Size: 565 KiB |
BIN
src/public/bg/0053.jpg
Normal file
After (image error) Size: 542 KiB |
BIN
src/public/bg/0054.jpg
Normal file
After (image error) Size: 429 KiB |
BIN
src/public/bg/0055.jpg
Normal file
After (image error) Size: 1.6 MiB |
BIN
src/public/bg/0056.jpg
Normal file
After (image error) Size: 603 KiB |
BIN
src/public/bg/0057.jpg
Normal file
After (image error) Size: 349 KiB |
BIN
src/public/bg/0058.jpg
Normal file
After (image error) Size: 1.3 MiB |
BIN
src/public/bg/0059.jpg
Normal file
After (image error) Size: 188 KiB |
BIN
src/public/bg/0060.jpg
Normal file
After (image error) Size: 214 KiB |
BIN
src/public/bg/0061.jpg
Normal file
After (image error) Size: 410 KiB |
BIN
src/public/bg/0062.jpg
Normal file
After (image error) Size: 168 KiB |
BIN
src/public/bg/0063.jpg
Normal file
After (image error) Size: 350 KiB |
BIN
src/public/bg/0064.jpg
Normal file
After (image error) Size: 1.3 MiB |
BIN
src/public/bg/0065.jpg
Normal file
After (image error) Size: 552 KiB |
BIN
src/public/bg/0066.jpg
Normal file
After (image error) Size: 260 KiB |
BIN
src/public/bg/0067.jpg
Normal file
After (image error) Size: 388 KiB |
BIN
src/public/bg/0068.jpg
Normal file
After (image error) Size: 1.3 MiB |
BIN
src/public/bg/0069.jpg
Normal file
After (image error) Size: 406 KiB |
BIN
src/public/bg/0070.jpg
Normal file
After (image error) Size: 437 KiB |
|
@ -1,68 +1,150 @@
|
|||
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
src: url('opensans.ttf');
|
||||
}
|
||||
|
||||
:root {
|
||||
--white: #fff;
|
||||
--grey: #F5F5F5;
|
||||
--black: #2D2D2F;
|
||||
|
||||
--text: var(--black);
|
||||
--font: 'Playfair Display';
|
||||
--blue: rgb(0, 102, 204);
|
||||
|
||||
--font-size: 140%;
|
||||
--font-small: 60%;
|
||||
|
||||
--radius: 7px;
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
html, body {
|
||||
html,
|
||||
body,
|
||||
main {
|
||||
min-height: 100vh;
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
background: var(--white);
|
||||
color: var(--text);
|
||||
font-family: 'Open Sans', Helvetica, Arial, sans-serif;
|
||||
font-size: var(--font-size);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.row {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.col {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
justify-content: center;
|
||||
background: url('./bg.jpg')
|
||||
50% 50%/cover no-repeat fixed;
|
||||
color: #fff;
|
||||
font-family: "Open Sans", Helvetica, Arial, sans-serif;
|
||||
font-weight: 100;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
main {
|
||||
margin-top: 20vh;
|
||||
height: fit-content;
|
||||
width: 400px;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background: #fff;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
main .heading {
|
||||
border-top: 5px solid var(--blue);
|
||||
font-size: 1.5rem;
|
||||
text-align: center;
|
||||
padding: 10px;
|
||||
main .content-box {
|
||||
margin: auto 0;
|
||||
height: 100%;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
main .content {
|
||||
padding: 10px;
|
||||
padding: 40px;
|
||||
min-width: 400px;
|
||||
}
|
||||
|
||||
main .content, form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
main label,
|
||||
main #submit {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
main input {
|
||||
border: 1px solid #ddd;
|
||||
outline: none;
|
||||
padding: 7px;
|
||||
font-size: 14px;
|
||||
border-bottom-color: black;
|
||||
}
|
||||
|
||||
main #submit {
|
||||
background: var(--blue);
|
||||
color: white;
|
||||
.btn {
|
||||
background: var(--grey);
|
||||
color: var(--black);
|
||||
text-decoration: none;
|
||||
font-size: var(--font-small);
|
||||
padding: 10px 60px;
|
||||
border-radius: var(--radius);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
outline: 1px solid var(--black);
|
||||
transition: all 0.2s ease-out;
|
||||
}
|
||||
|
||||
main .banner {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
main .banner img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
border-radius: 30px 0 0 30px;
|
||||
}
|
||||
|
||||
input {
|
||||
outline: none;
|
||||
border: none;
|
||||
}
|
||||
|
||||
form input:not(.btn) {
|
||||
display: block;
|
||||
outline: 2px solid var(--grey);
|
||||
margin-bottom: 10px;
|
||||
padding: 10px;
|
||||
min-width: 350px;
|
||||
border-radius: var(--radius);
|
||||
font-size: var(--font-small);
|
||||
}
|
||||
|
||||
form input:not(.btn):focus {
|
||||
outline-color: var(--blue);
|
||||
}
|
||||
|
||||
form > div {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
form label {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
font-size: var(--font-small);
|
||||
transform: translate(10px, -50%);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
input:focus + label,
|
||||
input:not(:placeholder-shown) + label {
|
||||
top: 0;
|
||||
padding: 2px;
|
||||
background-color: var(--white);
|
||||
transition: all 0.2s ease-out;
|
||||
}
|
||||
|
||||
@media (max-width: 1200px) {
|
||||
.row {
|
||||
flex-direction: column !important;
|
||||
}
|
||||
|
||||
main .banner {
|
||||
height: 50% !important;
|
||||
}
|
||||
|
||||
main .banner img {
|
||||
border-radius: 30px 30px 0 0;
|
||||
}
|
||||
}
|
||||
|
|
BIN
src/public/opensans.ttf
Normal file
21
src/web/helpers/html.php
Normal file
|
@ -0,0 +1,21 @@
|
|||
<?php /* Copyright (c) 2024 Freya Murphy */
|
||||
|
||||
function is_base64(string $data): bool {
|
||||
return base64_encode(base64_decode($data, true)) === $data;
|
||||
}
|
||||
|
||||
function maybe_base64_encode(string $data): string {
|
||||
if (is_base64($data)) {
|
||||
return $data;
|
||||
} else {
|
||||
return base64_encode($data);
|
||||
}
|
||||
}
|
||||
|
||||
function esc(string $data): string {
|
||||
$data = trim(preg_replace('/\s\s+/', ' ', $data));
|
||||
$data = str_replace('&', '&', $data);
|
||||
$data = str_replace('<', '<', $data);
|
||||
$data = str_replace('>', '>', $data);
|
||||
return $data;
|
||||
}
|
|
@ -6,6 +6,7 @@ $webroot = dirname(__FILE__);
|
|||
$publicroot = realpath(dirname(__FILE__) . '/../public');
|
||||
|
||||
// load stuff
|
||||
require($webroot . '/helpers/html.php');
|
||||
require($webroot . '/helpers/schema.php');
|
||||
require($webroot . '/helpers/ldap.php');
|
||||
require($webroot . '/helpers/auth.php');
|
||||
|
|
|
@ -17,12 +17,13 @@ class Router {
|
|||
/**
|
||||
* Displays a page to the user
|
||||
* @param string $file
|
||||
* @param array<string,mixed> $data
|
||||
*/
|
||||
private function send_page(
|
||||
* @param array<string,mixed> $data
|
||||
*/
|
||||
private function send_page(
|
||||
string $file,
|
||||
array $data = array()
|
||||
): void {
|
||||
$data['bg'] = random_int(1, 70);
|
||||
extract($data);
|
||||
$webroot = $GLOBALS['webroot'];
|
||||
require($webroot . '/views/header.php');
|
||||
|
@ -35,7 +36,7 @@ class Router {
|
|||
* @param string $title
|
||||
* @param string $msg
|
||||
* @param int $code
|
||||
*/
|
||||
*/
|
||||
private function send_message(
|
||||
string $title,
|
||||
string $msg
|
||||
|
@ -50,15 +51,16 @@ class Router {
|
|||
* Gets the HTTP request information
|
||||
*/
|
||||
private function get_req(): array {
|
||||
$path = $_SERVER['REQUEST_URI'];
|
||||
$uri = $_SERVER['REQUEST_URI'];
|
||||
$path = parse_url($uri)['path'];
|
||||
$method = $_SERVER['REQUEST_METHOD'];
|
||||
return [$method, $path];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string> $fields
|
||||
*/
|
||||
private function get_post_info(
|
||||
/**
|
||||
* @param array<string> $fields
|
||||
*/
|
||||
private function get_post_info(
|
||||
string ...$fields
|
||||
): ?array {
|
||||
$values = array();
|
||||
|
@ -88,10 +90,18 @@ class Router {
|
|||
return;
|
||||
}
|
||||
|
||||
$redirect = $this->get_post_info('redirect') ?? '';
|
||||
if (is_array($redirect)) {
|
||||
$redirect = $redirect['redirect'];
|
||||
$redirect = base64_decode($redirect);
|
||||
}
|
||||
|
||||
$user = $this->ldap->search($info['username']);
|
||||
if ($user == NULL || !count($user)) {
|
||||
http_response_code(400);
|
||||
$this->send_message('Error', 'User does not exist');
|
||||
$this->send_page('error', array(
|
||||
'title' => 'Error',
|
||||
'redirect' => $redirect));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -108,9 +118,18 @@ class Router {
|
|||
|
||||
$session = $this->auth->create_session($user);
|
||||
|
||||
http_response_code(200);
|
||||
$session->write_headers();
|
||||
$this->send_message('Success', 'Authenticated. You can now go back to your content');
|
||||
if ($redirect == '') {
|
||||
http_response_code(200);
|
||||
$session->write_headers();
|
||||
$this->send_message('Success', 'Authenticated. You can now go back to your content');
|
||||
} else {
|
||||
if (!str_starts_with($redirect, 'http')) {
|
||||
$redirect = 'http://' . $redirect;
|
||||
}
|
||||
http_response_code(303);
|
||||
$session->write_headers();
|
||||
header("Location: $redirect");
|
||||
}
|
||||
}
|
||||
|
||||
private function handle_logout(): void {
|
||||
|
@ -131,7 +150,7 @@ class Router {
|
|||
'You have been logged out successfully.');
|
||||
}
|
||||
|
||||
private function handle_auth(): void {
|
||||
private function handle_auth(): void {
|
||||
$session = $this->auth->get_session();
|
||||
if ($session == NULL) {
|
||||
// redirect them to login
|
||||
|
@ -145,14 +164,15 @@ class Router {
|
|||
http_response_code(200);
|
||||
$session->write_headers();
|
||||
$this->send_message('Authenticated',
|
||||
'You are already logged in.<br><br><a href="logout">Log Out</a>');
|
||||
'<a class="btn" href="logout">Log Out</a>');
|
||||
}
|
||||
}
|
||||
|
||||
private function page_login(): void {
|
||||
http_response_code(200);
|
||||
$this->send_page('login', array(
|
||||
'title' => 'Login'
|
||||
'title' => 'Login',
|
||||
'redirect' => $_GET['redirect'] ?? ''
|
||||
));
|
||||
}
|
||||
|
||||
|
|
10
src/web/views/error.php
Normal file
|
@ -0,0 +1,10 @@
|
|||
<?php /* Copyright (c) 2024 Freya Murphy */ ?>
|
||||
<form method="post" autocomplete="off">
|
||||
<span>Authentication failed</span>
|
||||
<br>
|
||||
<br>
|
||||
<a
|
||||
class="btn"
|
||||
href="/login?redirect=<?=maybe_base64_encode(esc($redirect))?>">
|
||||
Go Back
|
||||
</a>
|
|
@ -1,4 +1,9 @@
|
|||
<?php /* Copyright (c) 2024 Freya Murphy */ ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="banner col">
|
||||
<img src="/public/bg/<?=sprintf("%04d", $bg)?>.jpg">
|
||||
</div>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -4,13 +4,11 @@
|
|||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link href="//fonts.googleapis.com/css?family=Open+Sans:300,400,600,700&subset=latin" rel="stylesheet">
|
||||
<link rel="stylesheet" href="/public/main.css">
|
||||
<title><?=$title?></title>
|
||||
</head>
|
||||
<body>
|
||||
<main id="main" role="main">
|
||||
<div class="heading">
|
||||
<span><?=$title?></span>
|
||||
</div>
|
||||
<main id="main" role="main" class="row">
|
||||
<div class="content-box col">
|
||||
<div class="content">
|
||||
<h1><?=$title?></h1>
|
||||
|
|
|
@ -1,22 +1,33 @@
|
|||
<?php /* Copyright (c) 2024 Freya Murphy */ ?>
|
||||
<form method="post">
|
||||
<label for="username">Username</label>
|
||||
<input
|
||||
type="text"
|
||||
id="username"
|
||||
name="username"
|
||||
autofocus="true"
|
||||
>
|
||||
<label fot="password">Password</label>
|
||||
<input
|
||||
type="password"
|
||||
id="password"
|
||||
name="password"
|
||||
>
|
||||
<form method="post" autocomplete="off">
|
||||
<div>
|
||||
<input
|
||||
type="text"
|
||||
id="username"
|
||||
name="username"
|
||||
autofocus="true"
|
||||
autocomplete="off"
|
||||
placeholder=" ">
|
||||
<label for="username">Username</label>
|
||||
</div>
|
||||
<div>
|
||||
<input
|
||||
type="password"
|
||||
id="password"
|
||||
name="password"
|
||||
autocomplete="off"
|
||||
placeholder=" ">
|
||||
<label fot="password">Password</label>
|
||||
</div>
|
||||
<input
|
||||
type="submit"
|
||||
role="button"
|
||||
id="submit"
|
||||
value="Sign In"
|
||||
class="btn"
|
||||
>
|
||||
<input
|
||||
type="hidden"
|
||||
name="redirect"
|
||||
value="<?=maybe_base64_encode(esc($redirect))?>">
|
||||
<form>
|
||||
|
|
|
@ -1 +1 @@
|
|||
<center><?=$msg?></center>
|
||||
<div class="inner"><?=$msg?></div>
|
||||
|
|