passbolt-styleguide
Version:
Passbolt styleguide contains common styling assets used by the different sites, plugin, etc.
153 lines (139 loc) • 3.88 kB
JavaScript
/**
* Passbolt ~ Open source password manager for teams
* Copyright (c) Passbolt SA (https://www.passbolt.com)
*
* Licensed under GNU Affero General Public License version 3 of the or any later version.
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Passbolt SA (https://www.passbolt.com)
* @license https://opensource.org/licenses/AGPL-3.0 AGPL License
* @link https://www.passbolt.com Passbolt(tm)
* @since 2.14.0
*/
import { SecretGeneratorComplexity } from "../SecretGenerator/SecretGeneratorComplexity";
import PwnedPasswords from "./PwnedPasswords";
const STRENGTH = [
{
id: "not_available",
label: "n/a",
strength: 0,
},
{
id: "very-weak",
label: "very weak",
strength: 1,
},
{
id: "weak",
label: "weak",
strength: 60,
},
{
id: "fair",
label: "fair",
strength: 80,
},
{
id: "strong",
label: "strong",
strength: 112,
},
{
id: "very-strong",
label: "very strong",
strength: 128,
},
];
const MASKS = {
alpha: {
size: 26,
data: "abcdefghijklmnopqrstuvwxyz",
pattern: /[a-z]/,
},
uppercase: {
size: 26,
data: "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
pattern: /[A-Z]/,
},
digit: {
size: 10,
data: "0123456789",
pattern: /\d/,
},
special: {
size: 32,
// ASCII Code = 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 58, 59, 60, 61, 62, 63, 64, 91, 92, 93, 94, 95, 96, 123, 124, 125, 126
data: "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",
pattern: /[!-/:;-@[-`{-~]/,
},
};
export default class SecretComplexity {
/**
* Generate a random number in the given range.
* @param min {int} The min limit
* @param max {int} The mas limit
* @returns {int}
*/
static randomRange(min, max) {
const arr = new Uint32Array(1);
window.crypto.getRandomValues(arr);
const random = arr[0] / (0xffffffff + 1);
return Math.floor(random * (max - min + 1)) + min;
}
/**
* Get the entropy level regarding the mesure of the entropy.
* @param txt {string} The text to work on
* @return {Object} The text strength, an element of the STRENGTH array.
*/
static getStrength(txt) {
txt = txt || "";
const entropy = SecretGeneratorComplexity.entropyPassword(txt);
const strength = STRENGTH.reduce((accumulator, item) => {
if (!accumulator) {
return item;
}
if (item.strength > accumulator.strength && entropy >= item.strength) {
return item;
}
return accumulator;
});
return strength;
}
/**
* Generate a password following the system settings.
* @param {int} [length] (optional) The password length. Default 18.
* @param {array} [masks] (optional) The list of masks to use. Default all.
* @return {string}
*/
static generate(length, masks) {
let secret = "";
let mask = [];
length = length || 18;
masks = masks || ["alpha", "uppercase", "digit", "special"];
// Build the mask to use to generate a secret.
for (const i in masks) {
mask = [...mask, ...MASKS[masks[i]].data];
}
/*
* Generate a password which should fit the expected entropy.
* Try maximum 10 times.
*/
let j = 0;
const expectedEntropy = SecretGeneratorComplexity.calculEntropy(length, mask.length);
do {
secret = "";
for (let i = 0; i < length; i++) {
secret += mask[this.randomRange(0, mask.length - 1)];
}
} while (SecretGeneratorComplexity.entropyPassword(secret) < expectedEntropy && j++ < 10);
return secret;
}
/**
* Dictionary check
*/
static async ispwned(password) {
const count = await PwnedPasswords.pwnedPasswords(password);
return count > 0;
}
}