diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 0000000..bf1d0a6 --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,5 @@ +{ + "tabWidth": 2, + "useTabs": true, + "printWidth": 160 +} diff --git a/build.ts b/build.ts index 52c6fe6..6a23c62 100644 --- a/build.ts +++ b/build.ts @@ -1,43 +1,41 @@ -import dts from 'bun-plugin-dts'; -import Logger from '@rabbit-company/logger'; -import fs from 'fs/promises'; +import dts from "bun-plugin-dts"; +import Logger from "@rabbit-company/logger"; +import fs from "fs/promises"; -await fs.rm('./module', {recursive: true, force: true}); -await fs.rm('./dist', {recursive: true, force: true}); +await fs.rm("./module", { recursive: true, force: true }); +await fs.rm("./dist", { recursive: true, force: true }); -Logger.info('Start bulding module...'); +Logger.info("Start bulding module..."); let moduleBuild = await Bun.build({ - entrypoints: ['./src/password-entropy.ts'], - outdir: './module', - target: 'browser', - format: 'esm', - plugins: [ - dts({output: {noBanner: true}}) - ], + entrypoints: ["./src/password-entropy.ts"], + outdir: "./module", + target: "browser", + format: "esm", + plugins: [dts({ output: { noBanner: true } })], }); -if(moduleBuild.success){ - Logger.info('Bulding module complete'); -}else{ - Logger.error('Bulding module failed'); +if (moduleBuild.success) { + Logger.info("Bulding module complete"); +} else { + Logger.error("Bulding module failed"); } -fs.cp('./src/index.html', './dist/index.html', {recursive: true, force: true}); +fs.cp("./src/index.html", "./dist/index.html", { recursive: true, force: true }); -Logger.info('Start bundling dist...'); +Logger.info("Start bundling dist..."); let distBuild = await Bun.build({ - entrypoints: ['./src/index.ts'], - outdir: './dist', - target: 'browser', - format: 'esm', + entrypoints: ["./src/index.ts"], + outdir: "./dist", + target: "browser", + format: "esm", minify: true, - sourcemap: 'none', // Bun still generates incorrect sourcemaps - plugins: [], + sourcemap: "none", // Bun still generates incorrect sourcemaps + plugins: [], }); -if(distBuild.success){ - Logger.info('Bundling dist complete'); -}else{ - Logger.error('Bundling dist failed'); +if (distBuild.success) { + Logger.info("Bundling dist complete"); +} else { + Logger.error("Bundling dist failed"); Logger.error(distBuild.logs); -} \ No newline at end of file +} diff --git a/bun.lockb b/bun.lockb index 5575bdd..f965f9f 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/dist/index.html b/dist/index.html index 0b05ff2..c8709b1 100644 --- a/dist/index.html +++ b/dist/index.html @@ -1,22 +1,22 @@ - - PasswordEntropy-JS - - -

PasswordEntropy-JS

+ + PasswordEntropy-JS + + +

PasswordEntropy-JS

- -

Your password entropy is 0.

+ +

Your password entropy is 0.

-

Performance Test

-
- - - -
-

+

Performance Test

+
+ + + +
+

- - - \ No newline at end of file + + + diff --git a/dist/index.js b/dist/index.js index 2b8175a..45ecf44 100644 --- a/dist/index.js +++ b/dist/index.js @@ -1 +1 @@ -class G{static lcase="abcdefghijklmnopqrstuvwxyz";static ucase="ABCDEFGHIJKLMNOPQRSTUVWXYZ";static numb="1234567890";static symbol="!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~ ";static _includesChar(g,v){for(let z=0;z{J.innerText=G.calculate(L.value).toString()});document.getElementById("btn-start")?.addEventListener("click",()=>{const g=document.getElementById("amount"),v=document.getElementById("perf");if(!g||!v)return;let z=parseInt(g.value,10);if(z<1)z=1;if(z>1e5)z=1e5;let q=[],A="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~ ",K=Date.now();v.innerText="1. Performance test has started.\n";let H=Date.now();for(let B=0;B{e.lcase="abcdefghijklmnopqrstuvwxyz",e.ucase="ABCDEFGHIJKLMNOPQRSTUVWXYZ",e.numb="1234567890",e.symbol="!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~ ";function f(n,t){for(let u=0;u{c.innerText=I.calculate(T.value).toString()});document.getElementById("btn-start")?.addEventListener("click",()=>{const i=document.getElementById("amount"),l=document.getElementById("perf");if(!i||!l)return;let m=parseInt(i.value,10);if(m<1)m=1;if(m>1e5)m=1e5;let E=[],f="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~ ",L=Date.now();l.innerText="1. Performance test has started.\n";let n=Date.now();for(let t=0;t?@[\\]^_`{|}~ ". - * @type {string} - */ - static symbol: string; + * Symbols used in password entropy calculation. Developers can customize this string. + * Default: "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~ ". + * @type {string} + */ + let symbol: string; /** - * Checks if the given text includes any character from the provided character list. - * - * @private - * @param {string} text - The text to check. - * @param {string} charlist - The character list to check against. - * @returns {boolean} True if the text includes any character from the character list, false otherwise. - */ - private static _includesChar; - /** - * Calculates the entropy of a given password. - * - * @param {string} password - The password for which to calculate entropy. - * @returns {number} The calculated password entropy. - */ - static calculate(password: string): number; + * Calculates the entropy of a given password. + * + * @param {string} password - The password for which to calculate entropy. + * @returns {number} The calculated password entropy. + * + * @example + * const entropy = PasswordEntropy.calculate("P@ssw0rd"); + * console.log(entropy); // Outputs the entropy value for the given password + */ + function calculate(password: string): number; } +export { + PasswordEntropy as default, +}; + export {}; diff --git a/module/password-entropy.js b/module/password-entropy.js index 13c47f9..bd93667 100644 --- a/module/password-entropy.js +++ b/module/password-entropy.js @@ -1,35 +1,38 @@ // src/password-entropy.ts -class PasswordEntropy { - static lcase = "abcdefghijklmnopqrstuvwxyz"; - static ucase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - static numb = "1234567890"; - static symbol = "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~ "; - static _includesChar(text, charlist) { +var PasswordEntropy; +((PasswordEntropy) => { + PasswordEntropy.lcase = "abcdefghijklmnopqrstuvwxyz"; + PasswordEntropy.ucase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + PasswordEntropy.numb = "1234567890"; + PasswordEntropy.symbol = "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~ "; + function _includesChar(text, charlist) { for (let i = 0;i < text.length; i++) { if (charlist.includes(text[i])) return true; } return false; } - static calculate(password) { + function calculate(password) { if (typeof password !== "string") return 0; let pool = 0; - if (this._includesChar(password, this.lcase)) - pool += 26; - if (this._includesChar(password, this.ucase)) - pool += 26; - if (this._includesChar(password, this.numb)) - pool += 10; - if (this._includesChar(password, this.symbol)) - pool += 33; - if (!this._includesChar(password, this.lcase + this.ucase + this.numb + this.symbol)) + if (_includesChar(password, PasswordEntropy.lcase)) + pool += PasswordEntropy.lcase.length; + if (_includesChar(password, PasswordEntropy.ucase)) + pool += PasswordEntropy.ucase.length; + if (_includesChar(password, PasswordEntropy.numb)) + pool += PasswordEntropy.numb.length; + if (_includesChar(password, PasswordEntropy.symbol)) + pool += PasswordEntropy.symbol.length; + if (!_includesChar(password, PasswordEntropy.lcase + PasswordEntropy.ucase + PasswordEntropy.numb + PasswordEntropy.symbol)) pool += 100; if (pool == 0) return 0; return Math.round(password.length * Math.log(pool) / Math.LN2); } -} + PasswordEntropy.calculate = calculate; +})(PasswordEntropy ||= {}); +var password_entropy_default = PasswordEntropy; export { - PasswordEntropy as default + password_entropy_default as default }; diff --git a/package.json b/package.json index e697194..de48df0 100644 --- a/package.json +++ b/package.json @@ -1,45 +1,45 @@ { - "name": "@rabbit-company/password-entropy", - "version": "2.0.1", - "description": "Password entropy calculator", - "main": "./module/password-entropy.js", + "name": "@rabbit-company/password-entropy", + "version": "2.1.0", + "description": "Password entropy calculator", + "main": "./module/password-entropy.js", "browser": "./module/password-entropy.js", - "type": "module", - "homepage": "https://github.com/Rabbit-Company/PasswordEntropy-JS", - "funding": "https://rabbit-company.com/donation", - "author": "Rabbit Company ", - "license": "MIT", - "private": false, - "scripts": { - "build": "bun run build.ts" - }, - "files": [ + "type": "module", + "homepage": "https://github.com/Rabbit-Company/PasswordEntropy-JS", + "funding": "https://rabbit-company.com/donation", + "author": "Rabbit Company ", + "license": "MIT", + "private": false, + "scripts": { + "build": "bun run build.ts" + }, + "files": [ "module/password-entropy.js", "module/password-entropy.d.ts" - ], - "repository": { - "type": "git", - "url": "git+https://github.com/Rabbit-Company/PasswordEntropy-JS.git" - }, - "contributors": [ - "Rabbit Company (https://github.com/Rabbit-Company)" - ], - "bugs": { - "url": "https://github.com/Rabbit-Company/PasswordEntropy-JS/issues", - "email": "info@rabbit-company.com" - }, - "keywords": [ - "password", - "entropy", - "security", - "strength" - ], - "devDependencies": { - "@types/bun": "latest", - "bun-plugin-dts": "^0.2.1", - "@rabbit-company/logger": "^2.1.1" - }, - "peerDependencies": { - "typescript": "^5.0.0" - } -} \ No newline at end of file + ], + "repository": { + "type": "git", + "url": "git+https://github.com/Rabbit-Company/PasswordEntropy-JS.git" + }, + "contributors": [ + "Rabbit Company (https://github.com/Rabbit-Company)" + ], + "bugs": { + "url": "https://github.com/Rabbit-Company/PasswordEntropy-JS/issues", + "email": "info@rabbit-company.com" + }, + "keywords": [ + "password", + "entropy", + "security", + "strength" + ], + "devDependencies": { + "@types/bun": "latest", + "bun-plugin-dts": "^0.2.3", + "@rabbit-company/logger": "^3.1.0" + }, + "peerDependencies": { + "typescript": "^5.0.0" + } +} diff --git a/src/index.html b/src/index.html index 0b05ff2..c8709b1 100644 --- a/src/index.html +++ b/src/index.html @@ -1,22 +1,22 @@ - - PasswordEntropy-JS - - -

PasswordEntropy-JS

+ + PasswordEntropy-JS + + +

PasswordEntropy-JS

- -

Your password entropy is 0.

+ +

Your password entropy is 0.

-

Performance Test

-
- - - -
-

+

Performance Test

+
+ + + +
+

- - - \ No newline at end of file + + + diff --git a/src/index.ts b/src/index.ts index 4bb02ba..d11072b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -3,21 +3,21 @@ import PasswordEntropy from "./password-entropy"; const passwordInput = document.getElementById("password") as HTMLInputElement | null; const resultElement = document.getElementById("result") as HTMLElement | null; -if(passwordInput && resultElement){ - passwordInput.addEventListener('input', () => { +if (passwordInput && resultElement) { + passwordInput.addEventListener("input", () => { resultElement.innerText = PasswordEntropy.calculate(passwordInput.value).toString(); }); } -document.getElementById("btn-start")?.addEventListener('click', () => { +document.getElementById("btn-start")?.addEventListener("click", () => { const amountInput = document.getElementById("amount") as HTMLInputElement | null; const perfElement = document.getElementById("perf") as HTMLElement | null; - if(!amountInput || !perfElement) return; + if (!amountInput || !perfElement) return; let amount = parseInt(amountInput.value, 10); - if(amount < 1) amount = 1; - if(amount > 100000) amount = 100000; + if (amount < 1) amount = 1; + if (amount > 100000) amount = 100000; let passwords: string[] = []; let chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~ "; @@ -26,18 +26,18 @@ document.getElementById("btn-start")?.addEventListener('click', () => { perfElement.innerText = "1. Performance test has started.\n"; let timer = Date.now(); - for(let i = 0; i < amount; i++){ + for (let i = 0; i < amount; i++) { let password = ""; for (let j = 0; j <= 10; j++) { let randomNumber = Math.floor(Math.random() * chars.length); password += chars.substring(randomNumber, randomNumber + 1); } - passwords[i] = password; - } - perfElement.innerText += "2. " + amount + " random passwords generated in " + calcT(timer) + " milliseconds.\n"; + passwords[i] = password; + } + perfElement.innerText += "2. " + amount + " random passwords generated in " + calcT(timer) + " milliseconds.\n"; timer = Date.now(); - for(let i = 0; i < amount; i++){ + for (let i = 0; i < amount; i++) { PasswordEntropy.calculate(passwords[i]); } perfElement.innerText += "3. Entropy has been calculated for " + amount + " passwords in " + calcT(timer) + " milliseconds.\n"; @@ -45,6 +45,6 @@ document.getElementById("btn-start")?.addEventListener('click', () => { perfElement.innerText += "4. Performance test has completed in " + calcT(timerStart) + " milliseconds.\n"; }); -function calcT(timer: number){ - return Date.now() - timer; -} \ No newline at end of file +function calcT(timer: number) { + return Date.now() - timer; +} diff --git a/src/password-entropy.ts b/src/password-entropy.ts index 2e7a2f7..61f5f3d 100644 --- a/src/password-entropy.ts +++ b/src/password-entropy.ts @@ -1,61 +1,73 @@ /** - * PasswordEntropy class provides methods for calculating password entropy. -*/ -export default class PasswordEntropy{ - + * The `PasswordEntropy` namespace provides methods for calculating the entropy of a password. + * + * Developers can customize the character sets used for entropy calculation by modifying + * the properties `lcase`, `ucase`, `numb`, and `symbol`. + */ +namespace PasswordEntropy { /** - * Lowercase letters: "abcdefghijklmnopqrstuvwxyz". - * @type {string} - */ - static lcase: string = "abcdefghijklmnopqrstuvwxyz"; + * Lowercase letters used in password entropy calculation. Developers can customize this string. + * Default: "abcdefghijklmnopqrstuvwxyz". + * @type {string} + */ + export let lcase: string = "abcdefghijklmnopqrstuvwxyz"; /** - * Uppercase letters: "ABCDEFGHIJKLMNOPQRSTUVWXYZ". - * @type {string} - */ - static ucase: string = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + * Uppercase letters used in password entropy calculation. Developers can customize this string. + * Default: "ABCDEFGHIJKLMNOPQRSTUVWXYZ". + * @type {string} + */ + export let ucase: string = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; /** - * Numbers: "1234567890". - * @type {string} - */ - static numb: string = "1234567890"; + * Numbers used in password entropy calculation. Developers can customize this string. + * Default: "1234567890". + * @type {string} + */ + export let numb: string = "1234567890"; /** - * Symbols: "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~ ". - * @type {string} - */ - static symbol: string = "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~ "; + * Symbols used in password entropy calculation. Developers can customize this string. + * Default: "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~ ". + * @type {string} + */ + export let symbol: string = "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~ "; /** - * Checks if the given text includes any character from the provided character list. - * - * @private - * @param {string} text - The text to check. + * Checks if the given text includes any character from the provided character list. + * + * @private + * @param {string} text - The text to check. * @param {string} charlist - The character list to check against. * @returns {boolean} True if the text includes any character from the character list, false otherwise. - */ - private static _includesChar(text: string, charlist: string): boolean{ - for(let i = 0; i < text.length; i++){ - if(charlist.includes(text[i])) return true; + */ + function _includesChar(text: string, charlist: string): boolean { + for (let i = 0; i < text.length; i++) { + if (charlist.includes(text[i])) return true; } return false; } /** - * Calculates the entropy of a given password. - * - * @param {string} password - The password for which to calculate entropy. - * @returns {number} The calculated password entropy. - */ - static calculate(password: string): number{ - if(typeof(password) !== 'string') return 0; + * Calculates the entropy of a given password. + * + * @param {string} password - The password for which to calculate entropy. + * @returns {number} The calculated password entropy. + * + * @example + * const entropy = PasswordEntropy.calculate("P@ssw0rd"); + * console.log(entropy); // Outputs the entropy value for the given password + */ + export function calculate(password: string): number { + if (typeof password !== "string") return 0; let pool = 0; - if(this._includesChar(password, this.lcase)) pool += 26; - if(this._includesChar(password, this.ucase)) pool += 26; - if(this._includesChar(password, this.numb)) pool += 10; - if(this._includesChar(password, this.symbol)) pool += 33; - if(!this._includesChar(password, this.lcase + this.ucase + this.numb + this.symbol)) pool += 100; - if(pool == 0) return 0; + if (_includesChar(password, lcase)) pool += lcase.length; + if (_includesChar(password, ucase)) pool += ucase.length; + if (_includesChar(password, numb)) pool += numb.length; + if (_includesChar(password, symbol)) pool += symbol.length; + if (!_includesChar(password, lcase + ucase + numb + symbol)) pool += 100; + if (pool == 0) return 0; - return Math.round(password.length * Math.log(pool) / Math.LN2); + return Math.round((password.length * Math.log(pool)) / Math.LN2); } -} \ No newline at end of file +} + +export default PasswordEntropy;