diff options
author | lonkaars <loek@pipeframe.xyz> | 2023-05-27 14:21:25 +0200 |
---|---|---|
committer | lonkaars <loek@pipeframe.xyz> | 2023-05-27 14:21:25 +0200 |
commit | 8af23ff155904ba78de61a3cdab33a048a0f5664 (patch) | |
tree | 16a7c1c426f68e3e0289177b1406222f55b6fb0e | |
parent | 05d4f801fa8a519e257993cfa5bf1d72cdb7646f (diff) |
validate register info client-side
-rw-r--r-- | public/global.css | 6 | ||||
-rw-r--r-- | public/login.php | 4 | ||||
-rw-r--r-- | public/register.css | 93 | ||||
-rw-r--r-- | public/register.js | 83 | ||||
-rw-r--r-- | public/register.php | 34 |
5 files changed, 214 insertions, 6 deletions
diff --git a/public/global.css b/public/global.css index a417d10..1683ef5 100644 --- a/public/global.css +++ b/public/global.css @@ -54,6 +54,12 @@ body, html { border-radius: 8px; border: none; background-color: var(--bg-alt); + transition: opacity .3s; +} +.button[disabled], +.buttonstyle[disabled] { + opacity: 0.4; + cursor: not-allowed !important; } .button { diff --git a/public/login.php b/public/login.php index 19d9d17..7b1a254 100644 --- a/public/login.php +++ b/public/login.php @@ -23,9 +23,9 @@ do { <div class="modal"> <form action="/login.php" method="post"> <label for="username">Gebruikersnaam</label> - <input id="username" name="username" type="text" placeholder="gebruikersnaam" class="buttonstyle"> + <input id="username" name="username" type="text" placeholder="gebruikersnaam" class="buttonstyle" autocomplete="username" autofocus> <label for="password">Wachtwoord</label> - <input id="password" name="password" type="password" placeholder="wachtwoord" class="buttonstyle"> + <input id="password" name="password" type="password" placeholder="wachtwoord" class="buttonstyle" autocomplete="current-password"> <input type="submit" value="Inloggen" class="button filled"> </form> <span class="register">Of <a href="/register.php">een nieuw account maken</a></span> diff --git a/public/register.css b/public/register.css new file mode 100644 index 0000000..eef7490 --- /dev/null +++ b/public/register.css @@ -0,0 +1,93 @@ +.check-popup { + transition-property: margin, box-shadow; + transition-duration: .3s; + background-color: var(--bg-alt); + position: relative; + margin-bottom: 16px; + border-radius: 8px; + box-shadow: 0px 8px 32px -16px #0004; +} + +.check-popup::before { + transition: opacity .3s; + content: ""; + position: absolute; + top: 0; + left: 50%; + background-color: var(--bg-alt); + width: 16px; + height: 16px; + transform: translate(-50%, -50%) rotate(-45deg); +} + +.requirements { + display: grid; + list-style: none; +} + +.requirements .requirement { + transition-property: opacity; + transition-duration: .3s; + opacity: calc(100% - 50% * var(--done)); + --done: 0; +} + +.requirements .requirement .inner { + position: relative; +} + +.requirements .requirement .inner::before { + content: "- "; + position: absolute; + left: -0.5em; + transform: translateX(-100%); +} + +.requirements .requirement .inner::after { + transition-property: width; + transition-duration: .3s; + content: ""; + position: absolute; + top: 50%; + left: 0; + width: calc(100% * var(--done)); + background-color: currentColor; + height: 2px; +} + +.requirements.len-3 .requirement.len-3, +.requirements.nosymbol .requirement.nosymbol, +.requirements.nospace .requirement.nospace, +.requirements.valid .requirement.valid, +.requirements.len-8 .requirement.len-8, +.requirements.digit-2 .requirement.digit-2, +.requirements.symbol-2 .requirement.symbol-2, +.requirements.has-uppercase .requirement.has-uppercase, +.requirements.has-lowercase .requirement.has-lowercase +{ --done: 1; } + +#username-requirements { --requirement-count: 3; } +#email-requirements { --requirement-count: 1; } +#password-requirements { --requirement-count: 5; } +.check-popup .requirements { + --requirement-count: 0; /* TODO: this should dynamically change */ + transition-property: margin, opacity, grid-template-rows; + transition-duration: .3s; + grid-template-rows: repeat(var(--requirement-count), 1fr); + overflow: hidden; +} + +.check-popup .requirements .requirement { + min-height: 0; +} + +.check-popup.all .requirements { + margin: 0; + opacity: 0; + grid-template-rows: repeat(var(--requirement-count), 0fr); +} +.check-popup.all { + margin: 0; + box-shadow: none; +} +.check-popup.all::before { opacity: 0; } diff --git a/public/register.js b/public/register.js new file mode 100644 index 0000000..d3b66e1 --- /dev/null +++ b/public/register.js @@ -0,0 +1,83 @@ +function checkUsername() { + var username = document.getElementById("username").value; + var requirements = document.getElementById("username-requirements"); + + var len3 = username.length >= 3; + var nosymbol = username.match(/["'<>/&:;\\|{}[\]()]/) == null; + var nospace = username.match(/[ ]/) == null; + + requirements.classList[len3 ? "add" : "remove"]("len-3"); + requirements.classList[nosymbol ? "add" : "remove"]("nosymbol"); + requirements.classList[nospace ? "add" : "remove"]("nospace"); + + requirements.parentElement.classList.remove("all"); + if (!len3) return false; + if (!nosymbol) return false; + if (!nospace) return false; + requirements.parentElement.classList.add("all"); + return true; +} + +function checkEmail() { + var email = document.getElementById("email").value; + var requirements = document.getElementById("email-requirements"); + + // e-mail addresses can really only be verified by attempting to send a mail + // to them, so this is pretty much useless for client-side anyways + var valid = email.match(/.+?@.+/) != null; + + requirements.classList[valid ? "add" : "remove"]("valid"); + + requirements.parentElement.classList.remove("all"); + if (!valid) return false; + requirements.parentElement.classList.add("all"); + return true; +} + +function checkPassword() { + var password = document.getElementById("password").value; + var requirements = document.getElementById("password-requirements"); + + var len8 = password.length >= 8; + var minnum2 = password.match(/[0-9]/g)?.length >= 2; + var minsym2 = password.match(/[!@#$%^&*()\-=_+[\]{}\\|;:'",<.>/?`~]/g)?.length >= 2; + var uppercase = password.match(/[A-Z]/) != null; + var lowercase = password.match(/[a-z]/) != null; + + requirements.classList[len8 ? "add" : "remove"]("len-8"); + requirements.classList[minnum2 ? "add" : "remove"]("digit-2"); + requirements.classList[minsym2 ? "add" : "remove"]("symbol-2"); + requirements.classList[uppercase ? "add" : "remove"]("has-uppercase"); + requirements.classList[lowercase ? "add" : "remove"]("has-lowercase"); + + requirements.parentElement.classList.remove("all"); + if (!len8) return false; + if (!minnum2) return false; + if (!minsym2) return false; + if (!uppercase) return false; + if (!lowercase) return false; + requirements.parentElement.classList.add("all"); + return true; +} + +function checkAllFields() { + var username = checkUsername(); + var email = checkEmail(); + var password = checkPassword(); + + if (!username) return false; + if (!email) return false; + if (!password) return false; + return true; +} + +function updateRegisterButton() { + document.getElementById("register-submit").disabled = !checkAllFields(); +} + +// update when fields are changed +document.getElementById("username").addEventListener("input", updateRegisterButton); +document.getElementById("email").addEventListener("input", updateRegisterButton); +document.getElementById("password").addEventListener("input", updateRegisterButton); + +updateRegisterButton(); diff --git a/public/register.php b/public/register.php index f0f6596..0ef7e18 100644 --- a/public/register.php +++ b/public/register.php @@ -1,5 +1,6 @@ +<!DOCTYPE html> <?php include "../lib/login.php" ?> -<?php // if_logged_in(true, "/") ?> +<?php if_logged_in(true, "/") ?> <?php do { if ($_SERVER['REQUEST_METHOD'] !== 'POST') break; @@ -17,6 +18,8 @@ do { <?php include 'head.php' ?> <title>registeren</title> <link rel='stylesheet' type='text/css' media='screen' href='login.css'> + <link rel='stylesheet' type='text/css' media='screen' href='register.css'> + <script defer src="register.js"></script> </head> <body> <?php include 'navbar.php' ?> @@ -25,10 +28,33 @@ do { <div class="modal"> <form action="/register.php" method="post"> <label for="username">Gebruikersnaam</label> - <input id="username" name="username" type="text" placeholder="gebruikersnaam" class="buttonstyle"> + <input id="username" name="username" type="text" placeholder="gebruikersnaam" class="buttonstyle" autocomplete="username" autofocus> + <div class="check-popup check-username"> + <ul id="username-requirements" class="requirements"> + <li class="requirement len-3"><span class="inner">Minimaal 3 letters lang</span></li> + <li class="requirement nosymbol"><span class="inner">Geen symbolen</span></li> + <li class="requirement nospace"><span class="inner">Geen spaties</span></li> + </ul> + </div> + <label for="username">E-mail adres</label> + <input id="email" name="email" type="text" placeholder="e-mail" class="buttonstyle" autocomplete="email"> + <div class="check-popup check-email"> + <ul id="email-requirements" class="requirements"> + <li class="requirement valid"><span class="inner">Geldig e-mail adres</span></li> + </ul> + </div> <label for="password">Wachtwoord</label> - <input id="password" name="password" type="password" placeholder="wachtwoord" class="buttonstyle"> - <input type="submit" value="Registreren" class="button filled"> + <input id="password" name="password" type="password" placeholder="wachtwoord" class="buttonstyle" autocomplete="new-password"> + <div class="check-popup check-password"> + <ul id="password-requirements" class="requirements"> + <li class="requirement len-8"><span class="inner">Minimaal 8 tekens lang</span></li> + <li class="requirement digit-2"><span class="inner">Minimaal 2 cijfers</span></li> + <li class="requirement symbol-2"><span class="inner">Minimaal 2 symbolen</span></li> + <li class="requirement has-uppercase"><span class="inner">Bevat hoofdletter(s)</span></li> + <li class="requirement has-lowercase"><span class="inner">Bevat kleine letter(s)</span></li> + </ul> + </div> + <input id="register-submit" type="submit" value="Registreren" class="button filled"> </form> <span class="register">Of <a href="/login.php">inloggen</a></span> </div> |