rootdo/content/pg/app.js
2024-10-04 12:44:59 +00:00

98 lines
2.3 KiB
JavaScript

const crypto = window.crypto || window.msCrypto;
function getRandomNumber(ceiling) {
return Math.floor(crypto.getRandomValues(new Uint32Array(1))[0] / (0xffffffff + 1) * ceiling);
}
function getEntropy(length, numPossibleSymbols) {
if (!length || !numPossibleSymbols) {
return null;
}
return Math.round(Math.log2(Math.pow(numPossibleSymbols, length)) * 100) / 100;
}
const characterSets = [
{ name: 'a-z', value: 'abcdefghijklmnopqrstuvwxyz' },
{ name: 'A-Z', value: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' },
{ name: '0-9', value: '0123456789' },
{ name: 'Symbols', value: '~!@#$%^&*-_=+' },
{ name: 'Special', value: ':;|/,.?()[]{}<>' },
];
const app = Vue.createApp({
data() {
return {
charSets: characterSets,
selectedCharSets: [],
extraCharacters: '',
passwordLength: 25,
password: '',
clipboardButton: null,
isToastVisible: false,
};
},
mounted: function () {
this.clipboardButton = new ClipboardJS('#clipboard-button');
this.clipboardButton.on('success', this.showToast);
this.initializeCharacterSelection();
},
methods: {
generatePassword: function () {
let password = '';
for (let i = 0; i < this.passwordLength; i++) {
password += this.characters.charAt(getRandomNumber(this.characters.length));
}
this.password = password;
},
initializeCharacterSelection: function () {
this.selectedCharSets = characterSets.slice(0, 4);
this.extraCharacters = '';
},
clearCharacterSelection: function () {
this.selectedCharSets = [];
this.extraCharacters = '';
},
showToast: function () {
this.isToastVisible = true;
setTimeout(this.hideToast, 5500);
},
hideToast: function () {
this.isToastVisible = false;
}
},
watch: {
characters: function () {
this.generatePassword();
},
passwordLength: function () {
this.generatePassword();
},
},
computed: {
characters: function () {
return this.selectedCharSets
.map(item => item.value)
.flat()
.join('') + this.extraCharacters;
},
entropy: function () {
const uniqueCharacters = new Set(this.characters);
return getEntropy(this.passwordLength, uniqueCharacters.size);
},
},
});
app.mount('#app');