Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(login): styles #1767

Merged
merged 1 commit into from
Feb 25, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions www/common.inc
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,27 @@ require_once(__DIR__ . '/util.inc');
use WebPageTest\Util;
use WebPageTest\User;
use WebPageTest\RequestContext;
use WebPageTest\Exception\ClientException;


if (Util::getSetting('cp_auth')) {
// Start session handling for this request
session_start();
}

if (Util::getSetting('cp_auth')) {
set_exception_handler(function($e) {
if(is_a($e, ClientException::class)) {
$route = $e->getRoute();
$message = $e->getMessage();
$_SESSION['error_message'] = $message;
header('HTTP/1.1 302 Found');
header('Location: ' . $route);
exit(0);
}
});
}

// Disable caching by default
header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0", true);

Expand Down
20 changes: 13 additions & 7 deletions www/cpauth/login.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,24 @@
if ($request_method === 'POST') {
$csrf_token = filter_input(INPUT_POST, 'csrf_token');
if ($csrf_token !== $_SESSION['csrf_token']) {
throw new ClientException("You submitted an incorrect CSRF token", 403);
error_log("Incorrect CSRF token");
throw new ClientException("There was an error logging you in. Please try again.", "/login", 403);
exit();
}

try {
$email = filter_input(INPUT_POST, 'email', FILTER_SANITIZE_EMAIL);
$password = filter_input(INPUT_POST, 'password');
} catch (Exception $e) {
throw new ClientException($e->getMessage(), 400);
error_log("Incorrect CSRF token");
throw new ClientException($e->getMessage(), "/login", 400);
}

try {
$auth_token = $request_context->getClient()->login($email, $password);
$request_context->getClient()->authenticate($auth_token->access_token);
} catch (Exception $e) {
throw new ClientException($e->getMessage(), 403);
throw new ClientException($e->getMessage(), "/login", 403);
}

$protocol = getUrlProtocol();
Expand All @@ -43,14 +45,18 @@
exit();
} elseif ($request_method === 'GET') {
$_SESSION['csrf_token'] = bin2hex(random_bytes(35));

$error = $_SESSION['error_message'] ?? "";
unset($_SESSION['error_message']);

$tpl = new Template('account');
$tpl->setLayout('headless');
$args = array(
'csrf_token' => $_SESSION['csrf_token'],
'has_error' => !empty($error)
);
echo $tpl->render(
'login',
array(
'csrf_token' => $_SESSION['csrf_token']
)
$args
);
exit();
}
2 changes: 2 additions & 0 deletions www/nginx.conf
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ rewrite ^/tv$ /tv.php permanent;

rewrite ^/login /cpauth/login.php last;
rewrite ^/logout /cpauth/logout.php last;
rewrite ^/forgot-password /cpauth/forgot_password.php last;
rewrite ^/signup /cpauth/signup.php last;

#result paths
rewrite ^/result/([a-zA-Z0-9_]+)$ /result/$1/ permanent;
Expand Down
179 changes: 179 additions & 0 deletions www/pagestyle2.css
Original file line number Diff line number Diff line change
Expand Up @@ -6509,3 +6509,182 @@ div.bar {
padding-left: 1em;
margin-bottom: 1.5em;
}

.headless {
height: 100%;
}

.headless body, .headless body:not(.home) {
background: initial;
height: 100%;
display: block;
}

.headless * {
box-sizing: border-box;
}

.page.theme-c {
height: 100%;
display: grid;
background-color: #6b25cf;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='100%25' height='100%25' viewBox='0 0 800 400'%3E%3Cdefs%3E%3CradialGradient id='a' cx='396' cy='281' r='514' gradientUnits='userSpaceOnUse'%3E%3Cstop offset='0' stop-color='%237D0688'/%3E%3Cstop offset='1' stop-color='%23150033'/%3E%3C/radialGradient%3E%3ClinearGradient id='b' gradientUnits='userSpaceOnUse' x1='400' y1='148' x2='400' y2='333'%3E%3Cstop offset='0' stop-color='%23D617C5' stop-opacity='0'/%3E%3Cstop offset='1' stop-color='%23D617C5' stop-opacity='0.5'/%3E%3C/linearGradient%3E%3C/defs%3E%3Crect fill='url(%23a)' width='800' height='400'/%3E%3Cg fill-opacity='0.49'%3E%3Ccircle fill='url(%23b)' cx='267.5' cy='61' r='300'/%3E%3Ccircle fill='url(%23b)' cx='532.5' cy='61' r='300'/%3E%3Ccircle fill='url(%23b)' cx='400' cy='30' r='300'/%3E%3C/g%3E%3C/svg%3E");
background-position: bottom 0 left 50%;
background-repeat: no-repeat;
background-size: cover;
color: white;
}

.page.theme-c .container {
margin: auto;
min-width: 320px;
width: 100%;
background: #24334F;
padding: 30px 40px 80px;
font-size: 20px;
font-weight: 300;
border-radius: 10px;
box-shadow: 5px 5px 10px 1px rgb(43 38 51 / 50%);
}

.page.theme-c .container a,
.page.theme-c .container a:hover,
.page.theme-c .container a:visited {
text-decoration: none;
color: #A9C8F1;
}

@media (min-width: 480px) {
.page.theme-c .container {
width: 480px;
}
}

.page.theme-c .subhed {
}

.page.theme-c .subhed h1 {
font-weight: 300;
text-align: center;
font-size: 38px;
margin-top: 0.5em;
margin-bottom: 0.8em;
}

.page.theme-c .subhed .error-text {
text-align: center;
color: #FF8A88;
padding-bottom: 0.5em;
margin-bottom: 1.1em;
}

.page.theme-c .subhed .error-text span {
display: block;
}

.page.theme-c .container .container-signup-link {
text-align: center;
margin-top: 20px;
}


.form-login {
}

.form-login fieldset {
border: 0;
margin: 0;
padding: 0;
margin-inline-start: 0;
margin-inline-end: 0;
padding-block-start: 0;
padding-inline-start: 0;
padding-inline-end: 0;
padding-block-end: 0;
min-inline-size: initial;
}

.form-login .inputs {
margin-bottom: 30px;
}

.form-login .inputs > div:first-child {
margin-bottom: 16px;
}

.form-login .inputs label {
display: block;
}

.form-login .inputs input {
display: block;
width: 100%;
font-size: 20px;
line-height: 1.15em;
padding: 0.7em 8px;
border: 1px #24334F;
border-radius: 2px;
}

.form-login .inputs input:focus {
outline: 1px solid #2F80ED;
}

.form-login .container-password {
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: .5fr 1fr;
gap: 0px 0px;
grid-template-areas:
"label link"
"input input";
}

.form-login .container-password-label {
grid-area: label;
}
.form-login .container-password input[type=password] {
grid-area: input;
}
.form-login .container-password .link-forgot-password {
text-align: right;
grid-area: link;
}

.form-login .container-submit {
}

.form-login .container-submit button {
width: 100%;
appearance: none;
border: 0;
background: #F9D856;
padding: 16px 0;
font-weight: 300;
font-size: 20px;
display: block;
border-radius: 4px;
}

.form-login .container-submit button:hover {
background: #F2CC35;
}

.form-login .container-submit button:focus {
outline: 1px solid #333;
}

.form-login .container-submit button:active {
background: #EABC08;
}

.a11y-hidden {
clip: rect(1px, 1px, 1px, 1px);
clip-path: inset(50%);
height: 1px;
width: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
}
10 changes: 9 additions & 1 deletion www/src/Exception/ClientException.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,16 @@

class ClientException extends \Exception
{
public function __construct($message, $code = 400, \Throwable $previous = null)
private string $route;

public function __construct(string $message, string $route = '/', int $code = 400, \Throwable $previous = null)
{
parent::__construct($message, $code, $previous);
$this->route = $route;
}

public function getRoute(): string
{
return $this->route;
}
}
66 changes: 38 additions & 28 deletions www/templates/account/login.php
Original file line number Diff line number Diff line change
@@ -1,31 +1,41 @@
<div>
<div><a href="https://www.webpagetest.org/">
<!--TODO LOGO --><span>LOGO</span>
</a></div>
</div>
<div>
<form method="POST" action="/login">
<fieldset>
<legend>
WPT Credentials
</legend>
<div class="inputs">
<div>
<label for="email">Email</label>
<input name="email" type="email" class="form-field email" placeholder="Email" />
</div>
<div>
<label for="password">Password</label>
<input name="password" type="password" class="form-field password" placeholder="Password" />
</div>
<input type="hidden" name="csrf_token" value="<?= $csrf_token ?>" />
</div><!-- /.inputs -->
<div>
<button type="submit">Login</button>
<div class="page theme-c">
<div class="container">
<div class="subhed">
<div><a href="https://www.webpagetest.org/"><img src="/images/wpt-logo.svg" alt="WebPageTest, by Catchpoint"></a></div>
<h1>Log in</h1>
<?php if ($has_error): ?>
<div class="error-text">
<span>Incorrect email address or password.</span>
<span>Please try again.</span>
</div>
</fieldset>
</form>
<div>
<button class="forgot-password">Forgot Password</button>
<?php endif; ?>
</div>
<form method="POST" action="/login" class="form-login">
<fieldset>
<legend class="a11y-hidden">
WebPageTest Login Credentials
</legend>
<div class="inputs">
<div>
<label for="email">Email Address</label>
<input name="email" type="email" class="form-field email" required />
</div>
<div class="container-password">
<div class="container-password-label">
<label for="password">Password</label>
</div>
<input name="password" type="password" class="form-field password" required />
<a class="link-forgot-password" href="/forgot-password">Forgot Password?</a>
</div>
<input type="hidden" name="csrf_token" value="<?= $csrf_token ?>" />
</div><!-- /.inputs -->
<div class="container-submit">
<button type="submit">Login</button>
</div>
</fieldset>
</form>
<div class="container-signup-link">
New User? <a href="/signup">Try for Free →</a>
</div>
</div>
</div>
19 changes: 19 additions & 0 deletions www/templates/layouts/headless.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<!DOCTYPE html>
<html class="headless">
<head>
<?php
require_once __DIR__ . '/../../common.inc';

global $USER_EMAIL;
global $supportsAuth;
global $supportsSaml;

$page_title = $page_title ?: 'WebPageTest';
?>
<title><?php echo $page_title; ?></title>
<?php require_once __DIR__ . '/head.inc'; ?>
</head>
<body>
<?php echo $template_output; ?>
</body>
</html>