| <h1>Sign up for |
| <?php echo $SERVICE_NAME;?> |
| </h1> |
| |
| <form class="needs-validation" novalidate action="" method="POST"> |
| <!-- Username input --> |
| <div class="form-outline mb-3"> |
| <label class="form-label font-weight-bold" for="form3Example3">Username*</label> |
| <input pattern="[^\s]{<?php echo $VAL_USER->min_username.','.$VAL_USER->max_username;?>}" required |
| title="At least 5 not whitespace characters" name="username" type="text" id="form3Example0" |
| class="form-control <?php if(isset($error) && $error && !isset($_POST['username'])){echo 'border-danger';}?>" |
| placeholder="johndoe" |
| value="<?php echo isset($_POST['username']) ? htmlspecialchars($_POST['username']) : '' ?>" /> |
| <div class="invalid-feedback"> |
| Please choose a username with at least 5 not whitespace characters. |
| </div> |
| </div> |
| <!-- 2 column grid layout with text inputs for the first and last names --> |
| <div class="row mb-3"> |
| <div class="col"> |
| <div class="form-outline"> |
| <label class="form-label font-weight-bold" for="form3Example1">First name*</label> |
| <input pattern="[^\s]{<?php echo $VAL_USER->min_first_name.','.$VAL_USER->max_first_name;?>}" required |
| title="At least 2 not whitespace characters" name="name" type="text" id="form3Example1" |
| class="form-control <?php if(isset($error) && $error && !isset($_POST['name'])){echo 'border-danger';}?>" |
| placeholder="John" |
| value="<?php echo isset($_POST['name']) ? htmlspecialchars($_POST['name']) : '' ?>" /> |
| </div> |
| <div class="invalid-feedback"> |
| Please provide a first name with at least 2 not whitespace characters. |
| </div> |
| </div> |
| <div class="col"> |
| <div class="form-outline"> |
| <label class="form-label font-weight-bold" for="form3Example2">Last name*</label> |
| <input pattern="[^\s]{<?php echo $VAL_USER->min_last_name.','.$VAL_USER->max_last_name;?>}" required |
| title="At least 2 not whitespace characters" name="last_name" type="text" id="form3Example2" |
| class="form-control <?php if(isset($error) && $error && !isset($_POST['last_name'])){echo 'border-danger';}?>" |
| placeholder="Doe" |
| value="<?php echo isset($_POST['last_name']) ? htmlspecialchars($_POST['last_name']) : '' ?>" /> |
| </div> |
| <div class="invalid-feedback"> |
| Please provide a last name with at least 2 not whitespace characters. |
| </div> |
| </div> |
| </div> |
| |
| <!-- Email input --> |
| <div class="form-outline mb-3"> |
| <label class="form-label font-weight-bold" for="form3Example3">Email address*</label> |
| <input required name="email" type="email" id="form3Example3" |
| class="form-control <?php if(isset($error) && $error && !isset($_POST['email'])){echo 'border-danger';}?>" |
| placeholder="myemail@example.com" |
| value="<?php echo isset($_POST['email']) ? htmlspecialchars($_POST['email']) : '' ?>" /> |
| <div class="invalid-feedback"> |
| Please provide a valid email address. |
| </div> |
| </div> |
| |
| <!-- Password input --> |
| <div class="form-outline mb-3"> |
| <label class="form-label font-weight-bold" for="pw1">Password*</label> |
| <input pattern="[^\s]{<?php echo $VAL_USER->min_password.','.$VAL_USER->max_password;?>}" required |
| title="At least 8 not whitespace characters" name="password" type="password" id="pw1" |
| class="form-control <?php if(isset($error) && $error && !isset($_POST['password'])){echo 'border-danger';}?>" |
| placeholder="********" oninput="passUpdated()" |
| value="<?php echo isset($_POST['password']) ? htmlspecialchars($_POST['password']) : '' ?>" /> |
| <div class="progress mt-2"> |
| <div class="progress-bar bg-danger" role="progressbar" id="pwqbar" aria-valuenow="0" aria-valuemin="0" |
| aria-valuemax="100"></div> |
| </div> |
| </div> |
| <!-- |
| <div class="form-group"> |
| <label for="pwqinfo">Password rating</label> |
| <input class="form-control" type="text" name="pwqinfo" id="pwqinfo" readonly> |
| <div class="progress mt-2"> |
| <div class="progress-bar bg-danger" role="progressbar" id="pwqbar2" aria-valuenow="0" aria-valuemin="0" |
| aria-valuemax="100"></div> |
| </div> |
| </div> |
| --> |
| <!-- Password input --> |
| <div class="form-outline mb-3"> |
| <label class="form-label font-weight-bold" for="pw2">Confirm your Password*</label> |
| <input pattern="[^\s]{<?php echo $VAL_USER->min_password.','.$VAL_USER->max_password;?>}" required |
| title="At least 8 not whitespace characters" name="password_confirm" type="password" id="pw2" |
| class="form-control <?php if(isset($error) && $error && !isset($_POST['password_confirm'])){echo 'border-danger';}?>" |
| placeholder="********" oninput="validate_pw2(this)" /> |
| </div> <hr class="mt-2 mb-3" /> |
| <div class="form-outline mb-3"> |
| <label class="form-label font-weight-bold" for="eula">End User License Agreement*</label> |
| <div class="form-group form-check"> |
| <input type="checkbox" class="form-check-input" id="eula" required |
| title="You need to agree to the EULA in order to proceed"> |
| <label class="form-check-label" for="eula">I have read and agree to to the |
| <?php echo $SERVICE_NAME; ?> <a |
| href="https://www2.ids-mannheim.de/cosmas2/projekt/register/license_agreement.html">End User License |
| Agreement</a> and will use |
| <?php echo $SERVICE_NAME; ?> only for academic and non-commercial purposes. |
| </label> |
| <div class="invalid-feedback"> |
| You need to agree to the EULA in order to proceed. |
| </div> |
| </div> |
| </div> |
| <hr class="mt-2 mb-3" /> |
| <div class="form-outline mb-3"> |
| <label class="form-label font-weight-bold" for="privacy_policy">Privacy Policy*</label> |
| <div class="form-group form-check"> |
| <input type="checkbox" class="form-check-input" name="privacy_policy" id="privacy_policy" required |
| title="You need to agree to the privacy policy in order to proceed"> |
| <label class="form-check-label" for="privacy_policy">I have read and agree |
| to to the |
| <?php echo $SERVICE_NAME; ?> <a |
| href="https://www2.ids-mannheim.de/cosmas2/web-app/datenschutz.html">Privacy Policy</a>. |
| </label> |
| <div class="invalid-feedback"> |
| You need to agree to the privacy policy in order to proceed. |
| </div> |
| </div> |
| </div> |
| |
| <hr class="mt-2 mb-3" /> |
| <!--captcha here--> |
| <div class="form-outline mb-3"> |
| |
| <label class="form-label font-weight-bold" for="form3Example4">Captcha:</label> |
| <div class="container mb-2 offset-md-2"> |
| <img id="captcha" src="<?php echo $BASE_URL.'/captcha.php?token='.$_SESSION['captcha_token']; ?>" /> |
| <div id="reload_captcha"> |
| <button id="reload" class="btn btn-outline-info" type="button"> <span |
| class="glyphicon glyphicon-refresh" aria-hidden="true"></span></button> |
| </div> |
| </div> |
| <input pattern="[^\s]{<?php echo $CAPTCHA_LENGTH; ?>,}" required |
| title="Please fill the captcha. It has 5 characters" name="captcha" type="text" id="form3Example6" |
| class="form-control" placeholder="Type what you see on the image above" /> |
| </div> |
| |
| <!-- Submit button --> |
| <button name="type" value="register" type="submit" class="btn btn-primary float-right btn-md">Sign up</button> |
| |
| </form> |
| </div> |
| |
| <script> |
| // Example starter JavaScript for disabling form submissions if there are invalid fields |
| (function () { |
| 'use strict'; |
| window.addEventListener('load', function () { |
| // Fetch all the forms we want to apply custom Bootstrap validation styles to |
| var forms = document.getElementsByClassName('needs-validation'); |
| // Loop over them and prevent submission |
| var validation = Array.prototype.filter.call(forms, function (form) { |
| form.addEventListener('submit', function (event) { |
| if (form.checkValidity() === false) { |
| event.preventDefault(); |
| event.stopPropagation(); |
| } |
| form.classList.add('was-validated'); |
| }, false); |
| }); |
| }, false); |
| })(); |
| function validate_pw2(pw2) { |
| if (pw2.value !== $("#pw1").val()) { |
| pw2.setCustomValidity("Passwords do not match"); |
| } else { |
| pw2.setCustomValidity(""); // is valid |
| } |
| } |
| |
| TOO_SHORT ='Password too short, still %% characters needed'; |
| TOO_LONG ='Password too long, please remove %% characters'; |
| INVALID_CHARS ='Password contains invalid characters'; |
| QUAL_NONE ='Password is very weak' |
| QUAL_LOW ='Password is weak'; |
| QUAL_MEDIUM ='Password is average' |
| QUAL_GOOD ='Password is good'; |
| QUAL_STRONG ='Password is strong'; |
| REP_OK ='Repetition ok'; |
| REP_NE ='Passwords not identical'; |
| PWNED ='Password found in public password list'; |
| |
| String.prototype.strReverse=function() { |
| var newstring=''; |
| for (var s=0; s < this.length; s++) |
| newstring=this.charAt(s)+newstring; |
| return newstring; |
| }; |
| |
| //var checkTimer; |
| |
| function passUpdated() { |
| var nScore=0; |
| var message=''; |
| |
| var pass=$('#pw1').val(); |
| var pass2=$('#pw2').val(); |
| |
| //clearTimeout(checkTimer); |
| |
| try { |
| if (!pass) |
| throw ''; |
| |
| if (pass.match(/[^a-zA-Z0-9!@#$%()_+=:;",.?/-]/)) |
| throw INVALID_CHARS; |
| |
| var nLength=pass.length; |
| if (nLength < 8) |
| throw TOO_SHORT.replace('%%', 8-nLength); |
| if (nLength > 20) |
| throw TOO_LONG.replace('%%', nLength-20); |
| |
| nScore=4*nLength; |
| |
| // check for upper-/lowercase, numeric and special chars pattern matches |
| var nAlphaUC=0, nAlphaLC=0, nNumber=0, nSpecial=0; |
| var nMidChar=0, nRepChar=0, nRepInc=0; |
| var nConsecAlphaUC=0, nConsecAlphaLC=0, nConsecNumber=0; |
| var nTmpAlphaUC='', nTmpAlphaLC='', nTmpNumber=''; |
| for (var i=0; i < nLength; i++) { |
| if (pass[i].match(/[A-Z]/g)) { // uppercase characters |
| if (nTmpAlphaUC !== '' && (nTmpAlphaUC+1) == i) { |
| nConsecAlphaUC++; |
| } |
| nTmpAlphaUC=i; |
| nAlphaUC++; |
| } else if (pass[i].match(/[a-z]/g)) { // lowercase characters |
| if (nTmpAlphaLC !== '' && (nTmpAlphaLC+1) == i) { |
| nConsecAlphaLC++; |
| } |
| nTmpAlphaLC=i; |
| nAlphaLC++; |
| } else if (pass[i].match(/[0-9]/g)) { // numbers |
| if (i > 0 && i < (nLength-1)) { |
| nMidChar++; |
| } |
| if (nTmpNumber !== '' && (nTmpNumber+1) == i) { |
| nConsecNumber++; |
| } |
| nTmpNumber=i; |
| nNumber++; |
| } else { // special characters |
| if (i > 0 && i < (nLength-1)) { |
| nMidChar++; |
| } |
| nSpecial++; |
| } |
| |
| // check for repeated characters |
| var bCharExists=false; |
| for (var j=0; j < nLength; j++) { |
| if (pass[i] == pass[j] && i != j) { |
| bCharExists=true; |
| nRepInc+=Math.abs(nLength/(j-i)); |
| } |
| } |
| if (bCharExists) { |
| nRepChar++; |
| var nUnqChar=nLength-nRepChar; |
| nRepInc=(nUnqChar) ? Math.ceil(nRepInc/nUnqChar) : Math.ceil(nRepInc); |
| } |
| } |
| |
| // check for sequential alpha string patterns (forward and reverse) |
| var sAlphas="abcdefghijklmnopqrstuvwxyz"; |
| var nSeqAlpha=0; |
| for (var i=0; i < 23; i++) { |
| var sFwd=sAlphas.substring(i, i+3); |
| var sRev=sFwd.strReverse(); |
| if (pass.toLowerCase().indexOf(sFwd) != -1 |
| || pass.toLowerCase().indexOf(sRev) != -1) |
| nSeqAlpha++; |
| } |
| |
| // check for sequential numeric string patterns (forward and reverse) |
| var sNumerics="01234567890"; |
| var nSeqNumber=0; |
| for (var i=0; i < 8; i++) { |
| var sFwd=sNumerics.substring(i, i+3); |
| var sRev=sFwd.strReverse(); |
| if (pass.toLowerCase().indexOf(sFwd) != -1 |
| || pass.toLowerCase().indexOf(sRev) != -1) |
| nSeqNumber++; |
| } |
| |
| // general point assignment |
| if (nAlphaUC > 0 && nAlphaUC < nLength) // uppercase characters |
| nScore+=2*(nLength-nAlphaUC); |
| if (nAlphaLC > 0 && nAlphaLC < nLength) // lowercase characters |
| nScore+=2*(nLength-nAlphaLC); |
| if (nNumber > 0 && nNumber < nLength) // numbers |
| nScore+=2*nNumber; |
| if (nSpecial > 0) // special characters |
| nScore+=4*nSpecial; |
| if (nMidChar > 0) // mid numbers/special characters |
| nScore+=2*nMidChar; |
| |
| // point deductions for poor practices |
| if ((nAlphaLC > 0 || nAlphaUC > 0) |
| && nSpecial === 0 && nNumber === 0) // characters only |
| nScore-=nLength; |
| if (nAlphaLC === 0 && nAlphaUC === 0 |
| && nSpecial === 0 && nNumber > 0) // numbers only |
| nScore-=nLength; |
| if (nRepChar > 0) // same character exists more than once |
| nScore-=nRepInc; |
| if (nConsecAlphaUC > 0) // consecutive uppercase letters exist |
| nScore-=2*nConsecAlphaUC; |
| if (nConsecAlphaLC > 0) // consecutive lowercase letters exist |
| nScore-=2*nConsecAlphaLC; |
| if (nConsecNumber > 0) // consecutive numbers exist |
| nScore-=2*nConsecNumber; |
| if (nSeqAlpha > 0) // sequential alpha strings exist (3 chars or more) |
| nScore-=3*nSeqAlpha; |
| if (nSeqNumber > 0) // sequential numeric strings exist (3 chars or more) |
| nScore-=3*nSeqNumber; |
| |
| // determine if mandatory requirements have been met |
| var arrChars=[nAlphaUC, nAlphaLC, nNumber, nSpecial]; |
| var nReqChar=0; |
| for (var i=0; i < arrChars.length; i++) { |
| if (arrChars[i]) { |
| nReqChar++; |
| } |
| } |
| if (nReqChar >= arrChars.length) |
| nScore+=2*nReqChar; |
| else if (nReqChar < arrChars.length-1) |
| nScore-=2*nReqChar; |
| |
| // limit points to 3..100 |
| nScore=Math.max(3, Math.min(nScore, 100)); |
| |
| // set message according to points |
| if (nScore >= 80) |
| message=QUAL_STRONG; |
| else if (nScore >= 60) |
| message=QUAL_GOOD; |
| else if (nScore >= 40) |
| message=QUAL_MEDIUM; |
| else if (nScore >= 20) |
| message=QUAL_LOW; |
| else |
| message=QUAL_NONE; |
| } catch (error) { |
| nScore=3; |
| message=error; |
| } |
| /* |
| if (pass.length > 0 && pass2.length > 0) { |
| message+=' / '; |
| message+=(pass == pass2) ? REP_OK : REP_NE; |
| } |
| */ |
| $('#pwqinfo').val(message); |
| |
| var progress=$('#pwqbar'); |
| progress.width(nScore + '%'); |
| progress.attr('aria-valuenow', nScore); |
| if (nScore >= 60) |
| progress.removeClass('bg-danger bg-warning').addClass('bg-success'); |
| else if (nScore >= 40) |
| progress.removeClass('bg-danger bg-success').addClass('bg-warning'); |
| else |
| progress.removeClass('bg-warning bg-success').addClass('bg-danger'); |
| |
| if (nScore > 60) { |
| $('#btn_change').prop('disabled', pass !== pass2); |
| } else { |
| $('#btn_change').prop('disabled', 1); |
| } |
| /* |
| if (nScore >= 60) { |
| checkTimer=setTimeout(function() { |
| $.post('checkpass.php', 'pass='+pass, function(ret) { |
| if (ret !== 'PWNED') { |
| $('#btn_change').prop('disabled', pass !== pass2); |
| return; |
| } |
| $('#pwqinfo').val(PWNED); |
| progress.removeClass().addClass('low'); |
| progress.val(3); |
| }); |
| }, 300); |
| } |
| */ |
| } |
| </script> |