diff --git a/README.md b/README.md index aa0be88..aec14bb 100644 --- a/README.md +++ b/README.md @@ -386,6 +386,17 @@ In order to run this project you need: +
  • +
    +Password Generator +

    The Password Generator App is a web application that allows users to create secure, customizable passwords based on user-defined criteria such as length and character types. It offers a simple interface for generating and copying passwords to the clipboard. This tool enhances online security by providing strong, random passwords.

    + +
    +
  • +

    (back to top)

    diff --git a/Source-Code/PasswordGenerator/index.html b/Source-Code/PasswordGenerator/index.html new file mode 100644 index 0000000..67d0781 --- /dev/null +++ b/Source-Code/PasswordGenerator/index.html @@ -0,0 +1,55 @@ + + + + + + + + + Password Generator + + +
    +
    +

    Password Generator

    +
    + + +
    +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    + +
    + + + + + diff --git a/Source-Code/PasswordGenerator/script.js b/Source-Code/PasswordGenerator/script.js new file mode 100644 index 0000000..3af8d1c --- /dev/null +++ b/Source-Code/PasswordGenerator/script.js @@ -0,0 +1,80 @@ +/* eslint-disable no-loop-func */ +const resultEl = document.getElementById('result'); +const lengthEl = document.getElementById('length'); +const uppercaseEl = document.getElementById('uppercase'); +const lowercaseEl = document.getElementById('lowercase'); +const numbersEl = document.getElementById('numbers'); +const symbolsEl = document.getElementById('symbols'); +const generateEl = document.getElementById('generate'); +const clipboardEl = document.getElementById('clipboard'); + +clipboardEl.addEventListener('click', () => { + const textarea = document.createElement('textarea'); + const password = resultEl.innerText; + + if (!password) { + return; + } + + textarea.value = password; + document.body.appendChild(textarea); + textarea.select(); + document.execCommand('copy'); + textarea.remove(); + alert('Password copied to clipboard!'); +}); + +const getRandomLower = () => String.fromCharCode(Math.floor(Math.random() * 26) + 97); + +const getRandomUpper = () => String.fromCharCode(Math.floor(Math.random() * 26) + 65); + +const getRandomNumber = () => String.fromCharCode(Math.floor(Math.random() * 10) + 48); + +const getRandomSymbol = () => { + const symbols = '!@#$%^&*(){}[]=<>/,.'; + return symbols[Math.floor(Math.random() * symbols.length)]; +}; + +const randomFunc = { + lower: getRandomLower, + upper: getRandomUpper, + number: getRandomNumber, + symbol: getRandomSymbol, +}; +const generatePassword = (lower, upper, number, symbol, length) => { + let generatedPassword = ''; + const typesCount = lower + upper + number + symbol; + const typesArr = [{ lower }, { upper }, { number }, { symbol }].filter( + (item) => Object.values(item)[0], + ); + + if (typesCount === 0) { + return ''; + } + + for (let i = 0; i < length; i += typesCount) { + typesArr.forEach((type) => { + const funcName = Object.keys(type)[0]; + generatedPassword += randomFunc[funcName](); + }); + } + + const finalPassword = generatedPassword.slice(0, length); + + return finalPassword; +}; +generateEl.addEventListener('click', () => { + const length = +lengthEl.value; + const hasLower = lowercaseEl.checked; + const hasUpper = uppercaseEl.checked; + const hasNumber = numbersEl.checked; + const hasSymbol = symbolsEl.checked; + + resultEl.innerText = generatePassword( + hasLower, + hasUpper, + hasNumber, + hasSymbol, + length, + ); +}); diff --git a/Source-Code/PasswordGenerator/style.css b/Source-Code/PasswordGenerator/style.css new file mode 100644 index 0000000..304d22d --- /dev/null +++ b/Source-Code/PasswordGenerator/style.css @@ -0,0 +1,83 @@ +@import url('https://fonts.googleapis.com/css?family=Muli&display=swap'); + +* { + box-sizing: border-box; +} + +body { + background: linear-gradient(to right, #e762ea, #b3f4f0); + color: rgb(255, 255, 255); + font-family: 'Courier New', Courier, monospace; + font-weight: 500; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + height: 100vh; + overflow: hidden; + padding: 10px; + margin: 0; +} + +h2 { + margin: 10px 0 20px; + text-align: center; + font-weight: 1000; +} + +.container { + background-color: #2bd3df; + box-shadow: 0 2px 10px rgba(255, 255, 255, 0.2); + padding: 20px; + width: 350px; + max-width: 100%; +} + +.result-container { + background-color: rgba(0, 0, 0, 0.247); + display: flex; + justify-content: flex-start; + align-items: center; + position: relative; + font-size: 18px; + font-weight: bold; + letter-spacing: 1px; + padding: 12px 10px; + height: 50px; + width: 100%; +} + +.result-container #result { + word-wrap: break-word; + max-width: calc(100% - 40px); +} + +.btn { + border: none; + background-color: #2c085c; + color: #fff; + font-size: 16px; + padding: 8px 12px; + cursor: pointer; +} + +.result-container .btn { + position: absolute; + top: 5px; + right: 5px; + width: 40px; + height: 40px; + font-size: 20px; +} + +.btn-large { + display: block; + width: 100%; +} + +.setting { + display: flex; + justify-content: space-between; + align-items: center; + margin: 15px 0; +}