Upload files to "js"
This commit is contained in:
parent
4b2507b7c5
commit
c8c7fa0422
452
js/password-om.js
Normal file
452
js/password-om.js
Normal file
@ -0,0 +1,452 @@
|
||||
/**
|
||||
* POMjs 1.1.4
|
||||
*
|
||||
* password-om.js
|
||||
*
|
||||
* Plain vanilla javascript for the "Öppet Moln" ("Open Cloud") random password
|
||||
* generator site (password.oppetmoln.se). For the sake of having a name, it
|
||||
* shall be POMjs. There's really nothing fancy going on here :-)
|
||||
*
|
||||
* Copyright 2022, 2023 Joaquim Homrighausen; All rights reserved.
|
||||
* Development sponsored by WebbPlatsen i Sverige AB
|
||||
* https://www.webbplatsen.se
|
||||
*
|
||||
* This file is part of POMjs. POMjs is free software.
|
||||
*
|
||||
* You may redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License version 2, as published by the Free Software
|
||||
* Foundation.
|
||||
*
|
||||
* POMjs is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with the POMjs package. If not, write to:
|
||||
* The Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/* Some globals, to be filled by script */
|
||||
|
||||
var POM_cfgLanguage = 'noLang?';
|
||||
var POM_cfgTitle = 'noTitle?';
|
||||
var POM_cfgSlogan = 'noSlogan?';
|
||||
var POM_cfgGenPasswordHint = 'noHint?';
|
||||
const POM_strUppercase = POM_genAlphabet(true);
|
||||
const POM_strLowercase = POM_genAlphabet(false);
|
||||
const POM_strDigits = POM_genDigits();
|
||||
const POM_strSpecialOne = '-._#$@%!';
|
||||
const POM_strSpecialTwo = '"+(){}[]?&,*<>|:;^';
|
||||
|
||||
/* Easy customization of defaults, etc */
|
||||
const POM_strUppercase_Default = true;
|
||||
const POM_strLowercase_Default = true;
|
||||
const POM_strDigits_Default = true;
|
||||
const POM_strSpecialOne_Default = true;
|
||||
const POM_strSpecialTwo_Default = false;
|
||||
const POM_mkPasswordOnLoad = true;
|
||||
const POM_changeIsClick = true;
|
||||
const POM_minLength = 8;
|
||||
const POM_maxLength = 24;
|
||||
const POM_sliderStep = 1;
|
||||
const POM_debug = false;
|
||||
|
||||
/* Generate some strings */
|
||||
function POM_genAlphabet(isUpper = false) {
|
||||
return [...Array(26)].map((_, i) => String.fromCharCode(i + (isUpper ? 65 : 97))).join('');
|
||||
}
|
||||
function POM_genDigits() {
|
||||
return [...Array(10)].map((_, i) => String.fromCharCode(i + 48)).join('');
|
||||
}
|
||||
/* Distill string down to unique characters by using a set */
|
||||
function POM_distillString(s) {
|
||||
s = s.split('');
|
||||
s = new Set(s);
|
||||
s = [...s].join('+');
|
||||
return(s);
|
||||
}
|
||||
/* Escape special regex characters in string, from MDN */
|
||||
function POM_escapeRegExp(s) {
|
||||
return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
|
||||
}
|
||||
/* Validate "manual input" */
|
||||
function POM_validateNumInput() {
|
||||
let mkLengthSlider = document.getElementById('mk-password-len-slider');
|
||||
if (mkLengthSlider) {
|
||||
if (this.value === '') {
|
||||
this.value = POM_minLength;
|
||||
}
|
||||
mkLengthSlider.value = this.value;
|
||||
if (mkLengthSlider.value < POM_minLength) {
|
||||
mkLengthSlider.value = POM_minLength;
|
||||
} else if (mkLengthSlider.value > POM_maxLength) {
|
||||
mkLengthSlider.value = POM_maxLength;
|
||||
}
|
||||
this.value = mkLengthSlider.value;
|
||||
}
|
||||
if (POM_changeIsClick) {
|
||||
document.getElementById('mk-password-btn').click();
|
||||
}
|
||||
}
|
||||
/* Validate "manual input" */
|
||||
function POM_generatePassword() {
|
||||
let strengthP = document.getElementById('mk-password-strength');
|
||||
strengthP.style.background = 'inherit';
|
||||
strengthP.style.width = '0';
|
||||
strengthP.style.transition = 'none';
|
||||
let passwordField = document.getElementById('mk-password-field');
|
||||
passwordField.value = '';
|
||||
passwordField.classList.remove('mk-password-field-focus');
|
||||
let mkLengthField = document.getElementById('mk-length-field');
|
||||
if (POM_debug) {
|
||||
console.clear();
|
||||
}
|
||||
if (mkLengthField) {
|
||||
if (mkLengthField.value >= POM_minLength && mkLengthField.value <= POM_maxLength) {
|
||||
let passwordSource = '';
|
||||
if (document.getElementById('mk-uppercase-select').checked) {
|
||||
passwordSource += POM_strUppercase;
|
||||
}
|
||||
if (document.getElementById('mk-special-one-select').checked) {
|
||||
passwordSource += (POM_strSpecialOne + POM_strSpecialOne);
|
||||
}
|
||||
if (document.getElementById('mk-digits-select').checked) {
|
||||
passwordSource += POM_strDigits;
|
||||
}
|
||||
if (document.getElementById('mk-lowercase-select').checked) {
|
||||
passwordSource += POM_strLowercase;
|
||||
}
|
||||
if (document.getElementById('mk-digits-select').checked) {
|
||||
passwordSource += POM_strDigits;
|
||||
}
|
||||
if (document.getElementById('mk-special-two-select').checked) {
|
||||
passwordSource += (POM_strSpecialTwo + POM_strSpecialTwo);
|
||||
}
|
||||
if (passwordSource.length>0) {
|
||||
let passwordGen = '';
|
||||
let theChar = '';
|
||||
for (let i = 0; i < mkLengthField.value; i++) {
|
||||
const charPos = Math.floor(Math.random() * passwordSource.length);
|
||||
theChar = passwordSource[charPos];
|
||||
passwordGen += theChar;
|
||||
}
|
||||
passwordField.value = passwordGen;
|
||||
|
||||
let scoreP = 0;/* Password strength score, max is 8 */
|
||||
let searchStr;
|
||||
let re;
|
||||
|
||||
/* See if password contains uppercase characters */
|
||||
searchStr = '[' + POM_escapeRegExp(POM_strUppercase) + ']';
|
||||
if (POM_debug) {
|
||||
console.log('Using ' + searchStr + ' to scan password');
|
||||
}
|
||||
re = new RegExp(searchStr);
|
||||
if (re.test(passwordGen)) {
|
||||
scoreP++;
|
||||
if (POM_debug) {
|
||||
console.log('Password contains UPPERCASE');
|
||||
}
|
||||
} else {
|
||||
if (POM_debug) {
|
||||
console.log('Password does NOT contain UPPERCASE');
|
||||
}
|
||||
}
|
||||
/* See if password contains lowercase characters */
|
||||
searchStr = '[' + POM_escapeRegExp(POM_strLowercase) + ']';
|
||||
if (POM_debug) {
|
||||
console.log('Using ' + searchStr + ' to scan password');
|
||||
}
|
||||
re = new RegExp(searchStr);
|
||||
if (re.test(passwordGen)) {
|
||||
scoreP++;
|
||||
if (POM_debug) {
|
||||
console.log('Password contains lowercase');
|
||||
}
|
||||
} else {
|
||||
if (POM_debug) {
|
||||
console.log('Password does NOT contain lowercase');
|
||||
}
|
||||
}
|
||||
/* See if password contains digits characters */
|
||||
searchStr = '[' + POM_escapeRegExp(POM_strDigits) + ']';
|
||||
if (POM_debug) {
|
||||
console.log('Using ' + searchStr + ' to scan password');
|
||||
}
|
||||
re = new RegExp(searchStr);
|
||||
if (re.test(passwordGen)) {
|
||||
scoreP++;
|
||||
if (POM_debug) {
|
||||
console.log('Password contains digits');
|
||||
}
|
||||
} else {
|
||||
if (POM_debug) {
|
||||
console.log('Password does NOT contain digits');
|
||||
}
|
||||
}
|
||||
/* See if password contains specialOne characters */
|
||||
searchStr = '[' + POM_escapeRegExp(POM_strSpecialOne) + ']';
|
||||
if (POM_debug) {
|
||||
console.log('Using ' + searchStr + ' to scan password');
|
||||
}
|
||||
re = new RegExp(searchStr);
|
||||
if (re.test(passwordGen)) {
|
||||
scoreP++;
|
||||
if (POM_debug) {
|
||||
console.log('Password contains specialOne');
|
||||
}
|
||||
} else {
|
||||
if (POM_debug) {
|
||||
console.log('Password does NOT contain specialOne');
|
||||
}
|
||||
}
|
||||
/* See if password contains specialtwo characters */
|
||||
searchStr = '[' + POM_escapeRegExp(POM_strSpecialTwo) + ']';
|
||||
if (POM_debug) {
|
||||
console.log('Using ' + searchStr + ' to scan password');
|
||||
}
|
||||
re = new RegExp(searchStr);
|
||||
if (re.test(passwordGen)) {
|
||||
scoreP++;
|
||||
if (POM_debug) {
|
||||
console.log('Password contains specialTwo');
|
||||
}
|
||||
} else {
|
||||
if (POM_debug) {
|
||||
console.log('Password does NOT contain specialTwo');
|
||||
}
|
||||
}
|
||||
/* Bump score if password is > 7 characters */
|
||||
if (passwordGen.length > 7) {
|
||||
scoreP++;
|
||||
if (POM_debug) {
|
||||
console.log('Password >7 characters, buping score');
|
||||
}
|
||||
}
|
||||
/* Bump score if password is > 15 characters */
|
||||
if (passwordGen.length > 15) {
|
||||
scoreP++;
|
||||
if (POM_debug) {
|
||||
console.log('Password >15 characters, buping score');
|
||||
}
|
||||
}
|
||||
/* Bump score if password is > 31 characters */
|
||||
if (passwordGen.length > 31) {
|
||||
scoreP += 2;
|
||||
if (POM_debug) {
|
||||
console.log('Password >31 characters, buping score');
|
||||
}
|
||||
}
|
||||
/* Bump score if password is > 63 characters */
|
||||
if (passwordGen.length > 63) {
|
||||
scoreP += 4;
|
||||
if (POM_debug) {
|
||||
console.log('Password >63 characters, buping score');
|
||||
}
|
||||
}
|
||||
/* Let's not overflooooow */
|
||||
if (scoreP > 8) {
|
||||
scoreP = 8;
|
||||
}
|
||||
if (scoreP > 6) {
|
||||
strengthP.style.background = '#27ce60';
|
||||
} else if (scoreP > 5) {
|
||||
strengthP.style.background = '#27ae60';
|
||||
} else if (scoreP > 3) {
|
||||
strengthP.style.background = '#FFC300';
|
||||
} else {
|
||||
strengthP.style.background = '#C0392B';
|
||||
}
|
||||
strengthP.style.width = (scoreP * 12.5) + '%';
|
||||
strengthP.style.transition = 'width 0.3s ease-in';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Copy content of generated password field, if any, to clipboard */
|
||||
function POM_copyPassword() {
|
||||
let passwordField = document.getElementById('mk-password-field');
|
||||
if (passwordField && passwordField.value.length > 0) {
|
||||
if (navigator && navigator.clipboard && navigator.clipboard.writeText) {
|
||||
/* Use "modern" method */
|
||||
navigator.clipboard.writeText(passwordField.value).then(function() {
|
||||
passwordField.classList.add('mk-password-field-focus');
|
||||
}, function(e) {
|
||||
alert("Could not copy text: " + e);
|
||||
});
|
||||
} else {
|
||||
/* Use legacy method */
|
||||
var theText = document.createElement('textarea');
|
||||
theText.value = passwordField.value;
|
||||
theText.setAttribute('readonly', '');
|
||||
theText.style.position = 'absolute';
|
||||
theText.style.top = '-6969px';
|
||||
theText.style.left = '-6969px';
|
||||
document.body.appendChild(theText);
|
||||
theText.focus();
|
||||
theText.select();
|
||||
try {
|
||||
var goodCopy = document.execCommand('copy');
|
||||
if (goodCopy) {
|
||||
passwordField.classList.add('mk-password-field-focus');
|
||||
} else {
|
||||
alert('That did not work');
|
||||
}
|
||||
} catch(e) {
|
||||
alert('Could not copy text: ' + e.message);
|
||||
}
|
||||
document.body.removeChild(theText);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Initialize */
|
||||
function POM_initialSetup() {
|
||||
/* Setup, language strings, etc. Ugly, but it works :-) */
|
||||
if (navigator.language) {
|
||||
POM_cfgLanguage = navigator.language;
|
||||
if (POM_debug) {
|
||||
console.log("Language: " + POM_cfgLanguage);
|
||||
}
|
||||
let dashPos = POM_cfgLanguage.indexOf('-');
|
||||
if (dashPos && dashPos>0) {
|
||||
POM_cfgLanguage = POM_cfgLanguage.substring(0, dashPos);
|
||||
}
|
||||
POM_cfgLanguage = POM_cfgLanguage.toLowerCase();
|
||||
} else {
|
||||
POM_cfgLanguage = '???';
|
||||
}
|
||||
/* Add your translation here */
|
||||
switch(POM_cfgLanguage) {
|
||||
case 'sv':
|
||||
case 'se':
|
||||
POM_cfgTitle = 'Slumpmässigt Lösenord';
|
||||
POM_cfgSlogan = 'Inga kakor, <span tyle="display:inline-block">ingen spårning.</span><br/>Bara lösenord.';
|
||||
POM_cfgGenPasswordHint = 'Generera lösenord';
|
||||
break;
|
||||
case 'de':
|
||||
/* Thank you Peter Hampf */
|
||||
POM_cfgTitle = 'Zufallsgenerator für Passwörter';
|
||||
POM_cfgSlogan = 'Keine Cookies, <span style="display:inline-block">keine Tracker.</span><br/>Nur Passwörter.';
|
||||
POM_cfgGenPasswordHint = 'Passwort generieren';
|
||||
break;
|
||||
case 'hu':
|
||||
/* Thank you Mihaly Balassy */
|
||||
POM_cfgTitle = 'Véletlenszerű jelszógenerátor';
|
||||
POM_cfgSlogan = 'Cookie-k nélkül, <span style="display:inline-block">nyomkövetők nélkül.</span><br/>Csak jelszavak.';
|
||||
POM_cfgGenPasswordHint = 'Jelszó generálása';
|
||||
break;
|
||||
case 'nl':
|
||||
/* Thank you Jeroen van de Leur */
|
||||
POM_cfgTitle = 'Willekeurig Wachtwoord Generator';
|
||||
POM_cfgSlogan = 'Geen cookies, <span style="display:inline-block">geen trackers.</span><br/>Uitsluitend wachtwoorden.';
|
||||
POM_cfgGenPasswordHint = 'Genereer wachtwoord';
|
||||
break;
|
||||
case 'lb':
|
||||
/* Thank you Alain Fontaine */
|
||||
POM_cfgTitle = 'Zoufallspasswuertgenerator';
|
||||
POM_cfgSlogan = 'Keng Cookien, <span style="display:inline-block">keng Trackeren.</span><br/>Nemme Passwierder.';
|
||||
POM_cfgGenPasswordHint = 'Passwuert genereieren';
|
||||
break;
|
||||
case 'fr':
|
||||
/* Thank you Alain Fontaine */
|
||||
POM_cfgTitle = 'Générateur de mot de passe au hazard';
|
||||
POM_cfgSlogan = 'Pas de cookies, <span style="display:inline-block">pas de traceurs.</span><br/>Juste des mots de passe.';
|
||||
POM_cfgGenPasswordHint = 'Générer mot de passe';
|
||||
break;
|
||||
case 'fi':
|
||||
/* Thank you Thomas Raehalme */
|
||||
POM_cfgTitle = 'Salasanageneraattori';
|
||||
POM_cfgSlogan = 'Ei evästeitä, <span style="display:inline-block">ei seurantaa.</span><br/>Vain salasanoja.';
|
||||
POM_cfgGenPasswordHint = 'Generoi salasana';
|
||||
break;
|
||||
case 'sl':
|
||||
/* Thank you Gregor Godler */
|
||||
POM_cfgTitle = 'Generator Naključnih Gesel';
|
||||
POM_cfgSlogan = 'Brez piškotkov, <span style="display:inline-block">nič sledilnikov.</span><br/>Samo geslo.';
|
||||
POM_cfgGenPasswordHint = 'Generiraj geslo';
|
||||
break;
|
||||
default:
|
||||
POM_cfgTitle = 'Random Password Generator';
|
||||
POM_cfgSlogan = 'No cookies, <span style="display:inline-block">no trackers.</span><br/>Just passwords.';
|
||||
POM_cfgGenPasswordHint = 'Generate password';
|
||||
break;
|
||||
}
|
||||
/* Paint "HTML" with language strings */
|
||||
document.getElementById('cfg-page-title').innerHTML = POM_cfgTitle;
|
||||
document.getElementById('cfg-page-slogan').innerHTML = POM_cfgSlogan;
|
||||
document.getElementById('cfg-page-lang').innerHTML = '[' + POM_cfgLanguage + ']';
|
||||
document.getElementById('mk-password-btn').title = POM_cfgGenPasswordHint;
|
||||
/* Set reasonable defaults */
|
||||
document.getElementById('mk-uppercase-select').checked = POM_strUppercase_Default;
|
||||
document.getElementById('mk-lowercase-select').checked = POM_strLowercase_Default;
|
||||
document.getElementById('mk-digits-select').checked = POM_strDigits_Default;
|
||||
document.getElementById('mk-special-one-select').checked = POM_strSpecialOne_Default;
|
||||
document.getElementById('mk-special-two-select').checked = POM_strSpecialTwo_Default;
|
||||
|
||||
document.getElementById('mk-password-field').value = '';
|
||||
let mkPasswordSlider = document.getElementById('mk-password-len-slider');
|
||||
if (mkPasswordSlider) {
|
||||
mkPasswordSlider.value = POM_minLength;
|
||||
mkPasswordSlider.setAttribute("min", POM_minLength);
|
||||
mkPasswordSlider.setAttribute("max", POM_maxLength);
|
||||
mkPasswordSlider.step = POM_sliderStep;
|
||||
}
|
||||
document.getElementById('mk-length-field').value = POM_minLength;
|
||||
/* Paint "HTML" with password source */
|
||||
document.getElementById("gen-uppercase").innerText = POM_strUppercase;
|
||||
document.getElementById("gen-lowercase").innerText = POM_strLowercase;
|
||||
document.getElementById("gen-digits").innerText = POM_strDigits;
|
||||
document.getElementById("gen-special-one").innerText = POM_strSpecialOne;
|
||||
document.getElementById("gen-special-two").innerText = POM_strSpecialTwo;
|
||||
/* Add timestamp, for no good reason :) */
|
||||
document.getElementById("gen-timestamp").innerText = Date.now();
|
||||
/* Add some event handlers */
|
||||
document.getElementById('mk-password-len-slider').addEventListener('input', function() {
|
||||
let mkLengthField = document.getElementById('mk-length-field');
|
||||
if (mkLengthField) {
|
||||
mkLengthField.value = this.value;
|
||||
if (mkLengthField.value < POM_minLength) {
|
||||
mkLengthField.value = POM_minLength;
|
||||
} else if (mkLengthField.value > POM_maxLength) {
|
||||
mkLengthField.value = POM_maxLength;
|
||||
}
|
||||
this.value = mkLengthField.value;
|
||||
}
|
||||
});
|
||||
document.getElementById('mk-length-field').addEventListener('click', function() {
|
||||
this.select();
|
||||
});
|
||||
document.getElementById('mk-length-field').addEventListener('blur', POM_validateNumInput);
|
||||
document.getElementById('mk-length-field').addEventListener('change', POM_validateNumInput);
|
||||
document.getElementById('mk-password-btn').addEventListener('click', POM_generatePassword);
|
||||
document.getElementById('mk-password-field').addEventListener('click', POM_copyPassword);
|
||||
/* Possibly generate password on load */
|
||||
if (POM_mkPasswordOnLoad) {
|
||||
document.getElementById('mk-password-btn').click();
|
||||
}
|
||||
/* Possibly generate password on configuration changes */
|
||||
if (POM_changeIsClick) {
|
||||
document.getElementById('mk-uppercase-select').addEventListener('click', POM_generatePassword);
|
||||
document.getElementById('mk-special-one-select').addEventListener('click', POM_generatePassword);
|
||||
document.getElementById('mk-digits-select').addEventListener('click', POM_generatePassword);
|
||||
document.getElementById('mk-lowercase-select').addEventListener('click', POM_generatePassword);
|
||||
document.getElementById('mk-digits-select').addEventListener('click', POM_generatePassword);
|
||||
document.getElementById('mk-special-two-select').addEventListener('click', POM_generatePassword);
|
||||
document.getElementById('mk-password-len-slider').addEventListener('change', POM_generatePassword);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Wait for things to be loaded */
|
||||
if (document.readyState === "complete" ||
|
||||
(document.readyState !== "loading" && !document.documentElement.doScroll)) {
|
||||
POM_initialSetup();
|
||||
} else {
|
||||
document.addEventListener("DOMContentLoaded", POM_initialSetup);
|
||||
}
|
||||
|
||||
/* end of file "password-om.js" */
|
Loading…
x
Reference in New Issue
Block a user