mirror of
https://github.com/XFox111/PasswordGeneratorExtension.git
synced 2026-04-22 08:08:01 +03:00
3ecb6c4a31
- Migrated to WXT - Migrated to NPM - Added Insert & copy action - Added ESLint
129 lines
3.6 KiB
TypeScript
129 lines
3.6 KiB
TypeScript
import { GeneratorOptions } from "./storage";
|
|
|
|
const Characters =
|
|
{
|
|
Uppercase: "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
|
|
Lowercase: "abcdefghijklmnopqrstuvwxyz",
|
|
Numeric: "1234567890",
|
|
Special: "!#$%&*+-=?@^_"
|
|
};
|
|
|
|
const Similar: string = "iIl1Lo0O";
|
|
const Ambiguous: string = "{}[]()/\\'\"`~,;:.<>";
|
|
|
|
export const CharacterHints = { ...Characters, Similar, Ambiguous };
|
|
|
|
/**
|
|
* Generates a random password
|
|
* @param options Options for password generation
|
|
* @returns Randomly generated password
|
|
* @throws Error if options are invalid
|
|
*/
|
|
export function GeneratePassword(options: GeneratorOptions): string
|
|
{
|
|
ValidateOptions(options);
|
|
|
|
let password: string = GetRequiredCharacters(options);
|
|
const availableCharacters: string = GetAvailableCharacters(options);
|
|
|
|
for (let i = password.length; i < options.Length; i++)
|
|
{
|
|
const character: string = PickRandomFromArray(availableCharacters);
|
|
|
|
if (options.ExcludeRepeating && password.includes(character))
|
|
i--;
|
|
else
|
|
password += character;
|
|
}
|
|
|
|
password = ShuffleString(password);
|
|
return password;
|
|
}
|
|
|
|
/**
|
|
* Validates options for password generation
|
|
* @param options Options for password generation
|
|
* @throws Error if options are invalid
|
|
*/
|
|
export function ValidateOptions(options: GeneratorOptions): void
|
|
{
|
|
if (options.Length < 4)
|
|
throw new Error(i18n.t("errors.too_short"));
|
|
|
|
const availableCharacters: string = GetAvailableCharacters(options);
|
|
|
|
if (availableCharacters.length < 1)
|
|
throw new Error(i18n.t("errors.no_characters"));
|
|
|
|
if (options.ExcludeRepeating && options.Length > availableCharacters.length)
|
|
throw new Error(i18n.t("errors.too_long"));
|
|
}
|
|
|
|
// Returns a string containing all characters that are available for password generation
|
|
function GetAvailableCharacters(options: GeneratorOptions): string
|
|
{
|
|
let availableCharacters: string = "";
|
|
|
|
for (const [key, value] of Object.entries(Characters))
|
|
if (options[key as keyof GeneratorOptions])
|
|
availableCharacters += value;
|
|
|
|
if (options.ExcludeSimilar)
|
|
availableCharacters = availableCharacters.replace(new RegExp(`[${Similar}]`, "g"), "");
|
|
|
|
if (options.Special && !options.ExcludeAmbiguous)
|
|
availableCharacters += Ambiguous;
|
|
|
|
return availableCharacters;
|
|
}
|
|
|
|
// Returns a string containing all characters from every available set that are required for password generation
|
|
function GetRequiredCharacters(options: GeneratorOptions): string
|
|
{
|
|
let result: string = "";
|
|
const characters: Record<string, string> = Object.assign({}, Characters);
|
|
|
|
if (!options.ExcludeAmbiguous)
|
|
characters.Special += Ambiguous;
|
|
|
|
if (options.ExcludeSimilar)
|
|
for (const key of Object.keys(characters))
|
|
characters[key] = characters[key].replace(new RegExp(`[${Similar}]`, "g"), "");
|
|
|
|
for (const [key, value] of Object.entries(characters))
|
|
if (options[key as keyof GeneratorOptions])
|
|
result += PickRandomFromArray(value);
|
|
|
|
return result;
|
|
}
|
|
|
|
// Picks a random character from a string
|
|
function PickRandomFromArray(array: string): string
|
|
{
|
|
return array[GetRandomInt(0, array.length)];
|
|
}
|
|
|
|
// See https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Math/random
|
|
// min is inclusive, max is exclusive
|
|
function GetRandomInt(min: number, max: number): number
|
|
{
|
|
const arr = new Uint16Array(1);
|
|
crypto.getRandomValues(arr); // Using crypto instead of Math.random() as a CSPRNG
|
|
return Math.floor((arr[0] / 65_536) * (max - min)) + min;
|
|
}
|
|
|
|
// Shuffles a string using Fisher-Yates algorithm and CSPRNG
|
|
// See https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle
|
|
function ShuffleString(str: string): string
|
|
{
|
|
const arr = str.split("");
|
|
|
|
for (let i = arr.length - 1; i > 0; i--)
|
|
{
|
|
const j = GetRandomInt(0, i + 1);
|
|
[arr[i], arr[j]] = [arr[j], arr[i]];
|
|
}
|
|
|
|
return arr.join("");
|
|
}
|