first commit

This commit is contained in:
DIVISIONSolar 2022-07-08 18:48:34 -04:00
commit 4e4455f44c
3 changed files with 514 additions and 0 deletions

206
app.js Normal file
View file

@ -0,0 +1,206 @@
function minmax(value, min, max)
{
if (value.indexOf('.') > -1)
{
if (value === ".") return;
return value.split('.')[0];
}
if (value.length < 2) return value;
const parsedInput = parseInt(value);
if (parsedInput >= min && parsedInput <= max)
return value;
else if(parsedInput < min)
return min;
else if(parsedInput > max)
return max;
return value;
}
var passwordLength = document.getElementById("password-length");
var repeatCharacters = document.getElementById("repeat-characters");
var specialCharacters = document.getElementById("special-characters");
var ambiguousCharacters = document.getElementById("ambiguous-characters");
var includeNumbers = document.getElementById("include-numbers");
var includeLetters = document.getElementById("include-letters");
var randomPassword = document.getElementById("random-password");
var errorMessage = document.getElementById("error-message");
var defaultCharacters = ["@", "!", "#", "$", "?", ".", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z","A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", 0,1,2,3,4,5,6,7,8,9]
var characters = [];
var passwordArray = [];
const MIN = 4;
const MAX = 256;
function generatePassword() {
randomPassword.innerHTML = "";
passwordArray=[];
characters = defaultCharacters;
const pwLength = parseInt(passwordLength.value);
if (!specialCharacters.checked) {
characters = characters.join("").replace(/[@!#$?.]/g,'').split('')
}
if (!includeNumbers.checked) {
characters = characters.join("").replace(/[0-9]/g,'').split('')
}
if (!includeLetters.checked) {
characters = characters.join("").replace(/[a-zA-Z]/g,'').split('')
}
if (!ambiguousCharacters.checked) {
characters = characters.join("").replace(/[1Ilo0]/g,'').split('')
}
if (pwLength < MIN || pwLength > MAX) {
errorMessage.innerHTML = "You must pick a password between " + MIN + " and " + MAX;
return;
}
if (!specialCharacters.checked && !includeNumbers.checked && !includeLetters.checked) {
errorMessage.innerHTML = "Alas, blank passwords aren't a thing yet."
return;
}
if (!repeatCharacters.checked) {
if (passwordLength.value > characters.length) {
errorMessage.innerHTML = "There are only so many characters, we're going to have to repeat something"
return;
} else {
errorMessage.innerHTML = ""
while (passwordArray.length < passwordLength.value) {
var randomIndex = Math.floor(Math.random()*characters.length);
var newChar = characters[randomIndex];
newChar = isNaN(newChar) ? newChar.toLowerCase() : newChar;
if (passwordArray.indexOf(newChar) === -1) {
passwordArray.push(characters[randomIndex]);
}
}
}
} else {
errorMessage.innerHTML = ""
for (var i = 0; i < passwordLength.value; i++) {
var randomIndex = Math.floor(Math.random()*characters.length);
passwordArray.push(characters[randomIndex])
}
}
randomPassword.innerHTML = passwordArray.join("");
}
function copyToClip() {
var value = document.getElementById("random-password").innerHTML;
var input_temp = document.createElement("input");
input_temp.value = value;
document.body.appendChild(input_temp);
input_temp.select();
document.execCommand("copy");
document.body.removeChild(input_temp);
alert("Password copied!");
}
function getMin() {return MIN;}
function getMax () {return MAX;}
let openInstructions = document.getElementById('instructions__header');
let arrow = document.querySelector('.fas');
openInstructions.addEventListener('click', () => {
openInstructions.parentNode.classList.contains('active') ?
(openInstructions.parentNode.classList.remove('active'), arrow.classList.remove('fa-angle-up'), arrow.classList.add('fa-angle-down') ) :
(openInstructions.parentNode.classList.add('active'), arrow.classList.remove('fa-angle-down'), arrow.classList.add('fa-angle-up'))
});
var passwordTest = document.getElementById("password-test");
passwordTest.addEventListener("change", indicator);
function passwordScore() {
var value = passwordTest.value.trim();
var score = 0;
if (value.length < 8 ) {
score = 0;
} else {
if (value.length > 8) {
score++
}
if (/\d/.test(value)) {
score++
}
if (/[!@#$%^&*()_+\-=\[\]{};':"\|\,.<>\?]/.test(value)) {
score++
}
if (/[A-Z]/.test(value)) {
score++
}
if (value.length > 24) {
score++
}
}
return score;
}
var passwordIndicator = document.getElementById("password-indicator");
var passwordStrength = document.getElementById("password-strength");
function indicator() {
if (passwordTest.value.trim().length < 1) {
passwordIndicator.className="";
passwordStrength.innerHTML = "";
} else {
var score = passwordScore();
switch (score) {
case 0:
passwordIndicator.className="weak";
passwordStrength.innerHTML = "Weak";
break;
case 1:
passwordIndicator.className="average";
passwordStrength.innerHTML = "Average";
break;
case 2:
passwordIndicator.className="good";
passwordStrength.innerHTML = "Good";
break;
case 3:
passwordIndicator.className="strong";
passwordStrength.innerHTML = "Strong";
break;
case 4:
passwordIndicator.className="strong";
passwordStrength.innerHTML = "Strong";
break;
default:
passwordIndicator.className="";
passwordStrength.innerHTML = "";
break;
}
}
}
passwordTest.onkeyup = function() {
indicator();
}
var passwordToggle = document.getElementById("password-toggle");
function togglePassword() {
if (passwordTest.value.trim().length < 1 ) {
return
} else {
if (passwordTest.type === "text") {
passwordToggle.innerHTML="show";
passwordTest.type = "password";
} else if (passwordTest.type === "password") {
passwordToggle.innerHTML="hide";
passwordTest.type = "text";
}
}
}
passwordToggle.onclick = function() {
togglePassword();
}

86
index.html Normal file
View file

@ -0,0 +1,86 @@
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Header -->
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Password Generator App</title>
<link
rel="stylesheet"
href="styles.css"
/>
<!-- Header -->
</head>
<body>
<!-- Body -->
<h1 id="title">Random Password Generator | <span>Made by: <a href="https://divisionsolar.xyz">Josh S.</a></span></h1>
<div id="wrapper">
<aside id="sidebar">
<div id="instructions">
<div id="instructions__header">
<h4 id="how">How To Use: (Click me)</h4>
<i class="fas fa-angle-down"></i>
</div>
<div id="instructions__content">
<ul>
<li>Type in password length.</li>
<li>Select type of password required by checking the appropriate boxes.<br>(Only select 'Include numbers' to generate a PIN number)</li>
<li>Click 'Generate password'</li>
</ul>
<p>All passwords are generated on your browser, so nothing is stored online.</p>
<p>You're the only one who has knowledge of the generated password.</p>
</div>
</div>
</aside>
<main>
<div id="random-password-container">
<div id="error-message"></div>
<div class="input-container">
<label for="password-length">Length of password: </label>
<input type="number" value="8" min="4" max="256" maxlength="3" id="password-length" step="1" onkeyup="this.value = minmax(this.value, getMin(), getMax())">
</div>
<div class="input-container">
<label for="repeat-characters">Repeat characters</label>
<input type="checkbox" checked id="repeat-characters">
</div>
<div class="input-container">
<label for="special-characters">Use special characters</label>
<input type="checkbox" checked id="special-characters">
</div>
<div class="input-container">
<label for="ambiguous-characters">Include ambiguous characters</label>
<input type="checkbox" checked id="ambiguous-characters">
</div>
<div class="input-container">
<label for="include-numbers">Include numbers</label>
<input type="checkbox" checked id="include-numbers">
</div>
<div class="input-container">
<label for="include-letters">Include letters</label>
<input type="checkbox" checked id="include-letters">
</div>
<button class="generate button" type="button" onclick="generatePassword()">Generate password</button>
<div class="input-container">
Random password:
<div id="random-password"></div>
</div>
<button class="copy button" type ="button" onClick="copyToClip()"> Copy to Clipboard </button>
</div>
</main>
</div>
<!-- Body -->
<!-- Scripts -->
<script src="app.js"></script>
<!-- Scripts -->
</body>
</html>

222
styles.css Normal file
View file

@ -0,0 +1,222 @@
* {
box-sizing: border-box;
}
body {
background-color: #fa8096;
font-family: 'Trebuchet MS', 'Lucida Sans Unicode', 'Lucida Grande', 'Lucida Sans', Arial, sans-serif
}
#title {
font-size: 28px;
color: #2f3542;
border: 3px solid #fa8096;
padding: .2em;
border-radius: 5px;
background-color: #68ffb6;
text-align: center;
margin-top: 0;
}
#wrapper {
position: relative;
}
aside {
width: 33.5%;
position: absolute;
height: 85vh;
right: 0;
}
#instructions {
border: 2px solid rgb(60, 255, 118);
margin-bottom: 15px;
border-radius: 5px;
color: #2f3542;
background-color: #68ffb6;
max-height: 55px;
overflow: hidden;
transition: max-height 0.3s ease-out
}
#instructions.active {
height: auto;
max-height: 500px;
}
#instructions__header {
padding: 1em;
cursor: pointer;
border-bottom: 1px solid #2f3542;
display: flex;
justify-content: space-between;
}
#instructions__content {
padding: 0 2em 1em 2em;
}
#instructions__content ul {
padding: 0;
}
#how {
margin: 0;
}
#instructions li {
margin-bottom: 1em
}
main {
width: 65%;
}
main div {
margin: 0.5em 0;
}
#password-length {
width: 5em;
padding: .2rem;
text-align: center;
font-size: .8em;
border: none;
border-radius: 5px;
}
.button{
font-size: 1rem;
border: none;
padding: 5px 15px;
border-radius: 4px;
cursor: pointer;
-webkit-transition: 0.2s;
-o-transition: 0.2s;
transition: 0.2s;
}
.button.generate {
background-color: #70A1FF;
color: #fff;
}
.button.generate:hover{
background-color: #91b6fb;
}
.button.copy {
background-color: powderblue;
color: black;
}
.button.copy:hover{
background-color: #b6e4eb;
}
#random-password-container {
border: 2px solid #68ffb6;
border-radius: 5px;
background-color: #68ffb6;
padding: 1em;
}
#random-password {
background-color: powderblue;
padding: 1em;
word-break: break-all;
}
input[type="number"]::-webkit-outer-spin-button, input[type="number"]::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
input[type="number"] {
-moz-appearance: textfield;
}
#error-message{
opacity: 0;
animation: fadeIn 1s forwards;
color: #D8000C;
}
#password-strength-container {
border: 2px solid #68ffb6;
border-radius: 5px;
background-color: #dfe4ea;
padding: 1em;
}
#password-strength-container .input-container {
position: relative;
}
#password-test {
width: 100%;
border-radius: 5px;
border: 2px solid #68ffb6;
padding: 0.5em;
outline: none;
}
#password-indicator {
width: 100%;
padding: 2px;
border-radius: 5px;
background: white;
}
#password-indicator.weak {
background: linear-gradient(to right, #ff0000 25%, #fff 25%);
}
#password-indicator.average {
background: linear-gradient(to right,#ff9900 50%,#fff 50%);
}
#password-indicator.good {
background: linear-gradient(to right,#70A1FF 75%, #fff 75%);
}
#password-indicator.strong {
background: linear-gradient(to right, #43f04c 100%, #43f04c 100%);
}
#password-toggle {
font-size: .8em;
float: right;
position: absolute;
right: 0.5em;
top: 0.75em;
color: #70A1FF;
cursor: pointer;
}
@keyframes octocat-wave {
0%, 100% {
transform:rotate(0)
}
20%, 60% {
transform:rotate(-25deg)
}
40%, 80% {
transform:rotate(10deg)
}
}
@keyframes fadeIn {
from { opacity: 0 }
to { opacity: 1 }
}
@media only screen and (max-width: 768px) {
aside {
position: relative;
height: auto;
width: 100%;
}
main {
width: 100%;
}
}