diff --git a/apps/server/AliasVault.Client/Services/CredentialService.cs b/apps/server/AliasVault.Client/Services/CredentialService.cs
index 435b414cf..a39923538 100644
--- a/apps/server/AliasVault.Client/Services/CredentialService.cs
+++ b/apps/server/AliasVault.Client/Services/CredentialService.cs
@@ -14,15 +14,13 @@ using System.Net.Http;
using System.Net.Http.Json;
using System.Threading.Tasks;
using AliasClientDb;
-using AliasVault.Generators.Identity.Implementations.Factories;
-using AliasVault.Generators.Identity.Models;
using AliasVault.Shared.Models.WebApi.Favicon;
using Microsoft.EntityFrameworkCore;
///
/// Service class for credential operations.
///
-public sealed class CredentialService(HttpClient httpClient, DbService dbService, Config config)
+public sealed class CredentialService(HttpClient httpClient, DbService dbService, Config config, JsInteropService jsInteropService)
{
///
/// The default service URL used as placeholder in forms. When this value is set, the URL field is considered empty
@@ -73,15 +71,15 @@ public sealed class CredentialService(HttpClient httpClient, DbService dbService
do
{
- // Generate a random identity using the IIdentityGenerator implementation
- var identity = await IdentityGeneratorFactory.CreateIdentityGenerator(dbService.Settings.DefaultIdentityLanguage).GenerateRandomIdentityAsync();
+ // Generate a random identity using the TypeScript library
+ var identity = await jsInteropService.GenerateRandomIdentityAsync(dbService.Settings.DefaultIdentityLanguage);
// Generate random values for the Identity properties
credential.Username = identity.NickName;
credential.Alias.FirstName = identity.FirstName;
credential.Alias.LastName = identity.LastName;
credential.Alias.NickName = identity.NickName;
- credential.Alias.Gender = identity.Gender == Gender.Male ? "Male" : "Female";
+ credential.Alias.Gender = identity.Gender;
credential.Alias.BirthDate = identity.BirthDate;
// Set the email
@@ -105,9 +103,9 @@ public sealed class CredentialService(HttpClient httpClient, DbService dbService
}
while (isEmailTaken && attempts < MaxAttempts);
- // Generate password
+ // Generate password using the TypeScript library
var passwordSettings = dbService.Settings.PasswordSettings;
- credential.Passwords.First().Value = GenerateRandomPassword(passwordSettings);
+ credential.Passwords.First().Value = await jsInteropService.GenerateRandomPasswordAsync(passwordSettings);
return credential;
}
diff --git a/apps/server/AliasVault.Client/Services/JsInteropService.cs b/apps/server/AliasVault.Client/Services/JsInteropService.cs
index 3deadb579..2bbecfeed 100644
--- a/apps/server/AliasVault.Client/Services/JsInteropService.cs
+++ b/apps/server/AliasVault.Client/Services/JsInteropService.cs
@@ -9,7 +9,6 @@ namespace AliasVault.Client.Services;
using System.Security.Cryptography;
using System.Text.Json;
-using Microsoft.EntityFrameworkCore.Metadata.Internal;
using Microsoft.JSInterop;
///
@@ -18,6 +17,19 @@ using Microsoft.JSInterop;
/// IJSRuntime.
public sealed class JsInteropService(IJSRuntime jsRuntime)
{
+ private IJSObjectReference? _identityGeneratorModule;
+ private IJSObjectReference? _passwordGeneratorModule;
+
+ ///
+ /// Initialize the identity generator module.
+ ///
+ /// A task representing the asynchronous operation.
+ public async Task InitializeAsync()
+ {
+ _identityGeneratorModule = await jsRuntime.InvokeAsync("import", "./js/shared/identity-generator/index.mjs");
+ _passwordGeneratorModule = await jsRuntime.InvokeAsync("import", "./js/shared/password-generator/index.mjs");
+ }
+
///
/// Symmetrically encrypts a string using the provided encryption key.
///
@@ -275,6 +287,73 @@ public sealed class JsInteropService(IJSRuntime jsRuntime)
return await jsRuntime.InvokeAsync("cryptoInterop.decryptBytes", base64Ciphertext, encryptionKey);
}
+ ///
+ /// Generates a random identity using the specified language.
+ ///
+ /// The language to use for generating the identity (e.g. "en", "nl").
+ /// A tuple containing the generated identity information.
+ public async Task<(string FirstName, string LastName, string NickName, string EmailPrefix, string Gender, DateTime BirthDate)> GenerateRandomIdentityAsync(string language)
+ {
+ try
+ {
+ if (_identityGeneratorModule == null)
+ {
+ await InitializeAsync();
+ if (_identityGeneratorModule == null)
+ {
+ throw new InvalidOperationException("Failed to initialize identity generator module");
+ }
+ }
+
+ var generatorInstance = await _identityGeneratorModule.InvokeAsync("createGenerator", language);
+ var result = await generatorInstance.InvokeAsync("generateRandomIdentity");
+
+ return (
+ result.GetProperty("firstName").GetString()!,
+ result.GetProperty("lastName").GetString()!,
+ result.GetProperty("nickName").GetString()!,
+ result.GetProperty("emailPrefix").GetString()!,
+ result.GetProperty("gender").GetString()!,
+ result.GetProperty("birthDate").GetDateTime());
+ }
+ catch (JSException ex)
+ {
+ await Console.Error.WriteLineAsync($"JavaScript error generating identity: {ex.Message}");
+ throw new InvalidOperationException("Failed to generate random identity", ex);
+ }
+ }
+
+ ///
+ /// Generates a random password using the specified settings.
+ ///
+ /// The password settings to use.
+ /// The generated password.
+ public async Task GenerateRandomPasswordAsync(PasswordSettings settings)
+ {
+ try
+ {
+ if (_passwordGeneratorModule == null)
+ {
+ await InitializeAsync();
+ if (_passwordGeneratorModule == null)
+ {
+ throw new InvalidOperationException("Failed to initialize password generator module");
+ }
+ }
+
+ var generatorInstance = await _passwordGeneratorModule.InvokeAsync("createPasswordGenerator", settings);
+
+ var result = await generatorInstance.InvokeAsync("generateRandomPassword");
+
+ return result;
+ }
+ catch (JSException ex)
+ {
+ await Console.Error.WriteLineAsync($"JavaScript error generating password: {ex.Message}");
+ throw new InvalidOperationException("Failed to generate random password", ex);
+ }
+ }
+
///
/// Represents the result of a WebAuthn get credential operation.
///
diff --git a/apps/server/AliasVault.Client/wwwroot/js/shared/identity-generator/README.md b/apps/server/AliasVault.Client/wwwroot/js/shared/identity-generator/README.md
new file mode 100644
index 000000000..b46a10238
--- /dev/null
+++ b/apps/server/AliasVault.Client/wwwroot/js/shared/identity-generator/README.md
@@ -0,0 +1,9 @@
+# ⚠️ Auto-Generated Files
+
+This folder contains the output of the shared `identity-generator` module from the `/shared` directory in the AliasVault project.
+
+**Do not edit any of these files manually.**
+
+To make changes:
+1. Update the source files in `packages/identity-generator/src`
+2. Run the `build-and-distribute.sh` script at the root of the project to regenerate the outputs and copy them here.
diff --git a/apps/server/AliasVault.Client/wwwroot/js/shared/identity-generator/index.d.ts b/apps/server/AliasVault.Client/wwwroot/js/shared/identity-generator/index.d.ts
new file mode 100644
index 000000000..f3d21e979
--- /dev/null
+++ b/apps/server/AliasVault.Client/wwwroot/js/shared/identity-generator/index.d.ts
@@ -0,0 +1,142 @@
+declare enum Gender {
+ Male = "Male",
+ Female = "Female",
+ Other = "Other"
+}
+
+/**
+ * Identity.
+ */
+type Identity = {
+ firstName: string;
+ lastName: string;
+ gender: Gender;
+ birthDate: Date;
+ emailPrefix: string;
+ nickName: string;
+};
+
+/**
+ * Generate a username or email prefix.
+ */
+declare class UsernameEmailGenerator {
+ private static readonly MIN_LENGTH;
+ private static readonly MAX_LENGTH;
+ private readonly symbols;
+ /**
+ * Generate a username based on an identity.
+ */
+ generateUsername(identity: Identity): string;
+ /**
+ * Generate an email prefix based on an identity.
+ */
+ generateEmailPrefix(identity: Identity): string;
+ /**
+ * Sanitize an email prefix.
+ */
+ private sanitizeEmailPrefix;
+ /**
+ * Get a random symbol.
+ */
+ private getRandomSymbol;
+ /**
+ * Generate a random string.
+ */
+ private generateRandomString;
+ /**
+ * Generate a secure random integer between 0 (inclusive) and max (exclusive)
+ */
+ private getSecureRandom;
+}
+
+interface IIdentityGenerator {
+ generateRandomIdentity(): Identity;
+}
+
+/**
+ * Base identity generator.
+ */
+declare abstract class BaseIdentityGenerator implements IIdentityGenerator {
+ protected firstNamesMale: string[];
+ protected firstNamesFemale: string[];
+ protected lastNames: string[];
+ private readonly random;
+ /**
+ * Constructor.
+ */
+ constructor();
+ protected abstract getFirstNamesMaleJson(): string[];
+ protected abstract getFirstNamesFemaleJson(): string[];
+ protected abstract getLastNamesJson(): string[];
+ /**
+ * Generate a random date of birth.
+ */
+ protected generateRandomDateOfBirth(): Date;
+ /**
+ * Generate a random identity.
+ */
+ generateRandomIdentity(): Identity;
+}
+
+/**
+ * Identity generator for English language using English word dictionaries.
+ */
+declare class IdentityGeneratorEn extends BaseIdentityGenerator {
+ /**
+ * Get the male first names.
+ */
+ protected getFirstNamesMaleJson(): string[];
+ /**
+ * Get the female first names.
+ */
+ protected getFirstNamesFemaleJson(): string[];
+ /**
+ * Get the last names.
+ */
+ protected getLastNamesJson(): string[];
+}
+
+/**
+ * Identity generator for Dutch language using Dutch word dictionaries.
+ */
+declare class IdentityGeneratorNl extends BaseIdentityGenerator {
+ /**
+ * Get the male first names.
+ */
+ protected getFirstNamesMaleJson(): string[];
+ /**
+ * Get the female first names.
+ */
+ protected getFirstNamesFemaleJson(): string[];
+ /**
+ * Get the last names.
+ */
+ protected getLastNamesJson(): string[];
+}
+
+/**
+ * Helper utilities for identity generation that can be used by multiple client applications.
+ */
+declare class IdentityHelperUtils {
+ /**
+ * Normalize a birth date for display.
+ */
+ static normalizeBirthDateForDisplay(birthDate: string | undefined): string;
+ /**
+ * Normalize a birth date for database.
+ */
+ static normalizeBirthDateForDb(input: string | undefined): string;
+ /**
+ * Check if a birth date is valid.
+ */
+ static isValidBirthDate(input: string | undefined): boolean;
+}
+
+/**
+ * Creates a new identity generator based on the language.
+ * @param language - The language to use for generating the identity (e.g. "en", "nl").
+ * @returns A new identity generator instance.
+ */
+declare const createGenerator: (language: string) => IIdentityGenerator;
+
+export { BaseIdentityGenerator, Gender, type Identity, IdentityGeneratorEn, IdentityGeneratorNl, IdentityHelperUtils, UsernameEmailGenerator, createGenerator };
diff --git a/apps/server/AliasVault.Client/wwwroot/js/shared/identity-generator/index.js b/apps/server/AliasVault.Client/wwwroot/js/shared/identity-generator/index.js
new file mode 100644
index 000000000..d94ec7124
--- /dev/null
+++ b/apps/server/AliasVault.Client/wwwroot/js/shared/identity-generator/index.js
@@ -0,0 +1,1737 @@
+"use strict";
+var __defProp = Object.defineProperty;
+var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
+var __getOwnPropNames = Object.getOwnPropertyNames;
+var __hasOwnProp = Object.prototype.hasOwnProperty;
+var __export = (target, all) => {
+ for (var name in all)
+ __defProp(target, name, { get: all[name], enumerable: true });
+};
+var __copyProps = (to, from, except, desc) => {
+ if (from && typeof from === "object" || typeof from === "function") {
+ for (let key of __getOwnPropNames(from))
+ if (!__hasOwnProp.call(to, key) && key !== except)
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
+ }
+ return to;
+};
+var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
+
+// src/index.ts
+var index_exports = {};
+__export(index_exports, {
+ BaseIdentityGenerator: () => BaseIdentityGenerator,
+ Gender: () => Gender,
+ IdentityGeneratorEn: () => IdentityGeneratorEn,
+ IdentityGeneratorNl: () => IdentityGeneratorNl,
+ IdentityHelperUtils: () => IdentityHelperUtils,
+ UsernameEmailGenerator: () => UsernameEmailGenerator,
+ createGenerator: () => createGenerator
+});
+module.exports = __toCommonJS(index_exports);
+
+// src/utils/UsernameEmailGenerator.ts
+var _UsernameEmailGenerator = class _UsernameEmailGenerator {
+ constructor() {
+ this.symbols = [".", "-"];
+ }
+ /**
+ * Generate a username based on an identity.
+ */
+ generateUsername(identity) {
+ let username = this.generateEmailPrefix(identity);
+ username = username.replace(/[^a-zA-Z0-9]/g, "");
+ if (username.length < _UsernameEmailGenerator.MIN_LENGTH) {
+ username += this.generateRandomString(_UsernameEmailGenerator.MIN_LENGTH - username.length);
+ } else if (username.length > _UsernameEmailGenerator.MAX_LENGTH) {
+ username = username.substring(0, _UsernameEmailGenerator.MAX_LENGTH);
+ }
+ return username;
+ }
+ /**
+ * Generate an email prefix based on an identity.
+ */
+ generateEmailPrefix(identity) {
+ const parts = [];
+ switch (this.getSecureRandom(4)) {
+ case 0:
+ parts.push(identity.firstName.substring(0, 1).toLowerCase() + identity.lastName.toLowerCase());
+ break;
+ case 1:
+ parts.push((identity.firstName + identity.lastName).toLowerCase());
+ break;
+ case 2:
+ parts.push(identity.firstName.toLowerCase() + identity.lastName.substring(0, 1).toLowerCase());
+ break;
+ case 3:
+ parts.push(identity.firstName.substring(0, Math.min(3, identity.firstName.length)).toLowerCase() + identity.lastName.toLowerCase());
+ break;
+ }
+ if (this.getSecureRandom(3) !== 0) {
+ switch (this.getSecureRandom(2)) {
+ case 0:
+ parts.push(identity.birthDate.getFullYear().toString().substring(2));
+ break;
+ case 1:
+ parts.push(identity.birthDate.getFullYear().toString());
+ break;
+ }
+ } else if (this.getSecureRandom(2) === 0) {
+ parts.push((this.getSecureRandom(990) + 10).toString());
+ }
+ let emailPrefix = parts.join(this.getRandomSymbol());
+ if (this.getSecureRandom(2) === 0) {
+ const position = this.getSecureRandom(emailPrefix.length);
+ emailPrefix = emailPrefix.slice(0, position) + this.getRandomSymbol() + emailPrefix.slice(position);
+ }
+ emailPrefix = this.sanitizeEmailPrefix(emailPrefix);
+ if (emailPrefix.length < _UsernameEmailGenerator.MIN_LENGTH) {
+ emailPrefix += this.generateRandomString(_UsernameEmailGenerator.MIN_LENGTH - emailPrefix.length);
+ } else if (emailPrefix.length > _UsernameEmailGenerator.MAX_LENGTH) {
+ emailPrefix = emailPrefix.substring(0, _UsernameEmailGenerator.MAX_LENGTH);
+ }
+ return emailPrefix;
+ }
+ /**
+ * Sanitize an email prefix.
+ */
+ sanitizeEmailPrefix(input) {
+ let sanitized = input.replace(/[^a-zA-Z0-9._-]/g, "");
+ sanitized = sanitized.replace(/[-_.]{2,}/g, (match) => match[0]);
+ sanitized = sanitized.replace(/^[-._]+/, "");
+ sanitized = sanitized.replace(/[-._]*$/, "");
+ return sanitized;
+ }
+ /**
+ * Get a random symbol.
+ */
+ getRandomSymbol() {
+ return this.getSecureRandom(3) === 0 ? this.symbols[this.getSecureRandom(this.symbols.length)] : "";
+ }
+ /**
+ * Generate a random string.
+ */
+ generateRandomString(length) {
+ const chars = "abcdefghijklmnopqrstuvwxyz0123456789";
+ return Array.from({ length }, () => chars.charAt(this.getSecureRandom(chars.length))).join("");
+ }
+ /**
+ * Generate a secure random integer between 0 (inclusive) and max (exclusive)
+ */
+ getSecureRandom(max) {
+ const array = new Uint32Array(1);
+ crypto.getRandomValues(array);
+ return array[0] % max;
+ }
+};
+_UsernameEmailGenerator.MIN_LENGTH = 6;
+_UsernameEmailGenerator.MAX_LENGTH = 20;
+var UsernameEmailGenerator = _UsernameEmailGenerator;
+
+// src/types/Gender.ts
+var Gender = /* @__PURE__ */ ((Gender2) => {
+ Gender2["Male"] = "Male";
+ Gender2["Female"] = "Female";
+ Gender2["Other"] = "Other";
+ return Gender2;
+})(Gender || {});
+
+// src/implementations/base/BaseIdentityGenerator.ts
+var BaseIdentityGenerator = class {
+ /**
+ * Constructor.
+ */
+ constructor() {
+ this.firstNamesMale = [];
+ this.firstNamesFemale = [];
+ this.lastNames = [];
+ this.random = Math.random;
+ this.firstNamesMale = this.getFirstNamesMaleJson();
+ this.firstNamesFemale = this.getFirstNamesFemaleJson();
+ this.lastNames = this.getLastNamesJson();
+ }
+ /**
+ * Generate a random date of birth.
+ */
+ generateRandomDateOfBirth() {
+ const today = /* @__PURE__ */ new Date();
+ const minAge = 21;
+ const maxAge = 65;
+ const minDate = new Date(today.getFullYear() - maxAge, today.getMonth(), today.getDate());
+ const maxDate = new Date(today.getFullYear() - minAge, today.getMonth(), today.getDate());
+ const timestamp = minDate.getTime() + this.random() * (maxDate.getTime() - minDate.getTime());
+ return new Date(timestamp);
+ }
+ /**
+ * Generate a random identity.
+ */
+ generateRandomIdentity() {
+ const identity = {
+ firstName: "",
+ lastName: "",
+ gender: "Male" /* Male */,
+ birthDate: /* @__PURE__ */ new Date(),
+ emailPrefix: "",
+ nickName: ""
+ };
+ if (this.random() < 0.5) {
+ identity.firstName = this.firstNamesMale[Math.floor(this.random() * this.firstNamesMale.length)];
+ identity.gender = "Male" /* Male */;
+ } else {
+ identity.firstName = this.firstNamesFemale[Math.floor(this.random() * this.firstNamesFemale.length)];
+ identity.gender = "Female" /* Female */;
+ }
+ identity.lastName = this.lastNames[Math.floor(this.random() * this.lastNames.length)];
+ identity.birthDate = this.generateRandomDateOfBirth();
+ const generator = new UsernameEmailGenerator();
+ identity.emailPrefix = generator.generateEmailPrefix(identity);
+ identity.nickName = generator.generateUsername(identity);
+ return identity;
+ }
+};
+
+// src/dictionaries/en/firstnames_male.ts
+var firstnames_male_default = [
+ "Michael",
+ "Christopher",
+ "Matthew",
+ "Joshua",
+ "Daniel",
+ "David",
+ "Andrew",
+ "Joseph",
+ "James",
+ "John",
+ "Robert",
+ "William",
+ "Ryan",
+ "Jason",
+ "Nicholas",
+ "Jonathan",
+ "Jacob",
+ "Brandon",
+ "Tyler",
+ "Zachary",
+ "Kevin",
+ "Justin",
+ "Benjamin",
+ "Anthony",
+ "Samuel",
+ "Thomas",
+ "Alexander",
+ "Ethan",
+ "Noah",
+ "Dylan",
+ "Nathan",
+ "Christian",
+ "Austin",
+ "Adam",
+ "Caleb",
+ "Cody",
+ "Jordan",
+ "Logan",
+ "Aaron",
+ "Kyle",
+ "Jose",
+ "Brian",
+ "Gabriel",
+ "Timothy",
+ "Luke",
+ "Jared",
+ "Connor",
+ "Sean",
+ "Evan",
+ "Isaac",
+ "Jack",
+ "Cameron",
+ "Hunter",
+ "Jackson",
+ "Charles",
+ "Devin",
+ "Stephen",
+ "Patrick",
+ "Steven",
+ "Elijah",
+ "Scott",
+ "Mark",
+ "Jeffrey",
+ "Corey",
+ "Juan",
+ "Luis",
+ "Derek",
+ "Chase",
+ "Travis",
+ "Alex",
+ "Spencer",
+ "Ian",
+ "Trevor",
+ "Bryan",
+ "Tanner",
+ "Marcus",
+ "Jeremy",
+ "Eric",
+ "Jaden",
+ "Garrett",
+ "Isaiah",
+ "Dustin",
+ "Jesse",
+ "Seth",
+ "Blake",
+ "Nathaniel",
+ "Mason",
+ "Liam",
+ "Paul",
+ "Carlos",
+ "Mitchell",
+ "Parker",
+ "Lucas",
+ "Richard",
+ "Cole",
+ "Adrian",
+ "Colin",
+ "Bradley",
+ "Jesus",
+ "Peter",
+ "Kenneth",
+ "Joel",
+ "Victor",
+ "Bryce",
+ "Casey",
+ "Vincent",
+ "Edward",
+ "Henry",
+ "Dominic",
+ "Riley",
+ "Shane",
+ "Dalton",
+ "Grant",
+ "Shawn",
+ "Braden",
+ "Caden",
+ "Max",
+ "Hayden",
+ "Owen",
+ "Brett",
+ "Trevor",
+ "Philip",
+ "Brendan",
+ "Wesley",
+ "Aidan",
+ "Brady",
+ "Colton",
+ "Tristan",
+ "George",
+ "Gavin",
+ "Dawson",
+ "Miguel",
+ "Antonio",
+ "Nolan",
+ "Dakota",
+ "Jace",
+ "Collin",
+ "Preston",
+ "Levi",
+ "Alan",
+ "Jorge",
+ "Carson",
+ "Felix",
+ "Oliver",
+ "Theodore",
+ "Harrison",
+ "Maxwell",
+ "Sebastian",
+ "Xavier",
+ "Dominick",
+ "Lincoln",
+ "Elliott",
+ "Walter",
+ "Simon",
+ "Dean",
+ "Hugo",
+ "Malcolm",
+ "Leon",
+ "Oscar",
+ "Calvin",
+ "Raymond",
+ "Edgar",
+ "Franklin",
+ "Arthur",
+ "Lawrence",
+ "Dennis",
+ "Russell",
+ "Douglas",
+ "Leonard",
+ "Gregory",
+ "Harold",
+ "Frederick",
+ "Martin",
+ "Curtis",
+ "Stanley",
+ "Gilbert",
+ "Harvey",
+ "Francis",
+ "Eugene",
+ "Ralph",
+ "Roy",
+ "Albert",
+ "Bruce",
+ "Ronald",
+ "Keith",
+ "Craig",
+ "Roger",
+ "Randy",
+ "Gary",
+ "Dennis",
+ "Edwin",
+ "Don",
+ "Glen",
+ "Gordon",
+ "Howard",
+ "Earl",
+ "Leo",
+ "Lloyd",
+ "Milton",
+ "Norman",
+ "Roland",
+ "Vernon",
+ "Warren",
+ "Alfred",
+ "Bernard",
+ "Chester",
+ "Clarence",
+ "Clifford",
+ "Clyde",
+ "Dale",
+ "Dan",
+ "Darrell",
+ "Floyd",
+ "Herman",
+ "Jerome",
+ "Maurice",
+ "Neil",
+ "Ray",
+ "Rodney",
+ "Roland",
+ "Stuart",
+ "Wallace",
+ "Wayne",
+ "Wendell",
+ "Barry",
+ "Cecil",
+ "Claude",
+ "Daryl",
+ "Edmund",
+ "Everett",
+ "Ferdinand",
+ "Forrest",
+ "Gerald",
+ "Hugh",
+ "Irving",
+ "Leslie",
+ "Marvin",
+ "Morris",
+ "Nelson",
+ "Perry",
+ "Phillip",
+ "Roderick",
+ "Ross",
+ "Terrence",
+ "Wade",
+ "Winston",
+ "Zachariah"
+];
+
+// src/dictionaries/en/firstnames_female.ts
+var firstnames_female_default = [
+ "Emily",
+ "Emma",
+ "Olivia",
+ "Ava",
+ "Sophia",
+ "Isabella",
+ "Mia",
+ "Charlotte",
+ "Amelia",
+ "Harper",
+ "Evelyn",
+ "Abigail",
+ "Elizabeth",
+ "Sofia",
+ "Avery",
+ "Ella",
+ "Madison",
+ "Scarlett",
+ "Victoria",
+ "Aria",
+ "Grace",
+ "Chloe",
+ "Camila",
+ "Penelope",
+ "Riley",
+ "Layla",
+ "Zoey",
+ "Nora",
+ "Lily",
+ "Eleanor",
+ "Hannah",
+ "Lillian",
+ "Addison",
+ "Aubrey",
+ "Ellie",
+ "Stella",
+ "Natalie",
+ "Zoe",
+ "Leah",
+ "Hazel",
+ "Violet",
+ "Aurora",
+ "Savannah",
+ "Audrey",
+ "Brooklyn",
+ "Bella",
+ "Claire",
+ "Skylar",
+ "Lucy",
+ "Paisley",
+ "Everly",
+ "Anna",
+ "Caroline",
+ "Nova",
+ "Genesis",
+ "Emilia",
+ "Kennedy",
+ "Samantha",
+ "Maya",
+ "Willow",
+ "Kinsley",
+ "Naomi",
+ "Aaliyah",
+ "Elena",
+ "Sarah",
+ "Ariana",
+ "Allison",
+ "Gabriella",
+ "Alice",
+ "Madelyn",
+ "Cora",
+ "Ruby",
+ "Eva",
+ "Serenity",
+ "Autumn",
+ "Adeline",
+ "Hailey",
+ "Gianna",
+ "Valentina",
+ "Isla",
+ "Eliana",
+ "Quinn",
+ "Nevaeh",
+ "Ivy",
+ "Sadie",
+ "Piper",
+ "Lydia",
+ "Alexa",
+ "Josephine",
+ "Emery",
+ "Julia",
+ "Delilah",
+ "Arianna",
+ "Vivian",
+ "Kaylee",
+ "Sophie",
+ "Brielle",
+ "Madeline",
+ "Peyton",
+ "Rylee",
+ "Clara",
+ "Hadley",
+ "Melanie",
+ "Mackenzie",
+ "Reagan",
+ "Adalyn",
+ "Liliana",
+ "Aubree",
+ "Jade",
+ "Katherine",
+ "Isabelle",
+ "Natalia",
+ "Raelynn",
+ "Maria",
+ "Athena",
+ "Ximena",
+ "Arya",
+ "Leilani",
+ "Taylor",
+ "Faith",
+ "Rose",
+ "Kylie",
+ "Alexandra",
+ "Mary",
+ "Margaret",
+ "Lyla",
+ "Ashley",
+ "Amaya",
+ "Eliza",
+ "Brianna",
+ "Bailey",
+ "Andrea",
+ "Khloe",
+ "Jasmine",
+ "Melody",
+ "Iris",
+ "Isabel",
+ "Norah",
+ "Annabelle",
+ "Valeria",
+ "Emerson",
+ "Adalynn",
+ "Ryleigh",
+ "Eden",
+ "Emersyn",
+ "Anastasia",
+ "Kayla",
+ "Alyssa",
+ "Anna",
+ "Juliana",
+ "Charlie",
+ "Lucia",
+ "Stella",
+ "Adriana",
+ "Beatrice",
+ "Bianca",
+ "Calliope",
+ "Carmen",
+ "Celeste",
+ "Dakota",
+ "Diana",
+ "Esther",
+ "Florence",
+ "Francesca",
+ "Georgia",
+ "Harlow",
+ "Haven",
+ "Holly",
+ "Hope",
+ "India",
+ "Indie",
+ "Iris",
+ "Juniper",
+ "Kaia",
+ "Keira",
+ "Lara",
+ "Laura",
+ "Laurel",
+ "Luna",
+ "Magnolia",
+ "Maeve",
+ "Marina",
+ "Marlowe",
+ "Nina",
+ "Noelle",
+ "Octavia",
+ "Olive",
+ "Ophelia",
+ "Phoenix",
+ "Poppy",
+ "Primrose",
+ "Ramona",
+ "River",
+ "Rosalie",
+ "Rosemary",
+ "Sage",
+ "Salem",
+ "Selena",
+ "Sienna",
+ "Summer",
+ "Sylvie",
+ "Thea",
+ "Tessa",
+ "Wren",
+ "Winter",
+ "Willa",
+ "Ada",
+ "Aspen",
+ "Blair",
+ "Brynn",
+ "Cassidy",
+ "Cecilia",
+ "Daisy",
+ "Dawn",
+ "Daphne",
+ "Ember",
+ "Fiona",
+ "Flora",
+ "Freya",
+ "Gemma",
+ "Giselle",
+ "Harmony",
+ "Heidi",
+ "Imogen",
+ "Indie",
+ "Jessie",
+ "June",
+ "Kaia",
+ "Lena",
+ "Lola",
+ "Mabel",
+ "Maisie",
+ "Margot",
+ "Matilda",
+ "Mira",
+ "Morgan",
+ "Nell",
+ "Nadia",
+ "Odette",
+ "Opal",
+ "Pearl",
+ "Phoebe",
+ "Raven",
+ "Reese",
+ "Robin",
+ "Rowan",
+ "Ruth",
+ "Sabrina",
+ "Sasha",
+ "Sierra",
+ "Skye",
+ "Sloane",
+ "Talia",
+ "Thora",
+ "Vera",
+ "Willa",
+ "Winnie",
+ "Yara",
+ "Zara"
+];
+
+// src/dictionaries/en/lastnames.ts
+var lastnames_default = [
+ "Smith",
+ "Johnson",
+ "Williams",
+ "Brown",
+ "Jones",
+ "Garcia",
+ "Miller",
+ "Davis",
+ "Rodriguez",
+ "Martinez",
+ "Hernandez",
+ "Lopez",
+ "Gonzalez",
+ "Wilson",
+ "Anderson",
+ "Thomas",
+ "Taylor",
+ "Moore",
+ "Jackson",
+ "Martin",
+ "Lee",
+ "Perez",
+ "Thompson",
+ "White",
+ "Harris",
+ "Sanchez",
+ "Clark",
+ "Ramirez",
+ "Lewis",
+ "Robinson",
+ "Walker",
+ "Young",
+ "Allen",
+ "King",
+ "Wright",
+ "Scott",
+ "Torres",
+ "Nguyen",
+ "Hill",
+ "Flores",
+ "Green",
+ "Adams",
+ "Nelson",
+ "Baker",
+ "Hall",
+ "Rivera",
+ "Campbell",
+ "Mitchell",
+ "Carter",
+ "Roberts",
+ "Gomez",
+ "Phillips",
+ "Evans",
+ "Turner",
+ "Diaz",
+ "Parker",
+ "Cruz",
+ "Edwards",
+ "Collins",
+ "Reyes",
+ "Stewart",
+ "Morris",
+ "Morales",
+ "Murphy",
+ "Cook",
+ "Rogers",
+ "Gutierrez",
+ "Ortiz",
+ "Morgan",
+ "Cooper",
+ "Peterson",
+ "Bailey",
+ "Reed",
+ "Kelly",
+ "Howard",
+ "Ramos",
+ "Kim",
+ "Cox",
+ "Ward",
+ "Richardson",
+ "Watson",
+ "Brooks",
+ "Chavez",
+ "Wood",
+ "James",
+ "Bennett",
+ "Gray",
+ "Mendoza",
+ "Ruiz",
+ "Hughes",
+ "Price",
+ "Alvarez",
+ "Castillo",
+ "Sanders",
+ "Patel",
+ "Myers",
+ "Long",
+ "Ross",
+ "Foster",
+ "Jimenez",
+ "Powell",
+ "Jenkins",
+ "Perry",
+ "Russell",
+ "Sullivan",
+ "Bell",
+ "Coleman",
+ "Butler",
+ "Henderson",
+ "Barnes",
+ "Gonzales",
+ "Fisher",
+ "Vasquez",
+ "Simmons",
+ "Romero",
+ "Jordan",
+ "Patterson",
+ "Alexander",
+ "Hamilton",
+ "Graham",
+ "Reynolds",
+ "Griffin",
+ "Wallace",
+ "Moreno",
+ "West",
+ "Cole",
+ "Hayes",
+ "Bryant",
+ "Herrera",
+ "Gibson",
+ "Ellis",
+ "Tran",
+ "Medina",
+ "Aguilar",
+ "Stevens",
+ "Murray",
+ "Ford",
+ "Castro",
+ "Marshall",
+ "Owens",
+ "Harrison",
+ "Fernandez",
+ "McDonald",
+ "Woods",
+ "Washington",
+ "Kennedy",
+ "Wells",
+ "Vargas",
+ "Henry",
+ "Chen",
+ "Freeman",
+ "Webb",
+ "Tucker",
+ "Guzman",
+ "Burns",
+ "Crawford",
+ "Olson",
+ "Simpson",
+ "Porter",
+ "Hunter",
+ "Gordon",
+ "Mendez",
+ "Silva",
+ "Shaw",
+ "Snyder",
+ "Mason",
+ "Dixon",
+ "Blackwood",
+ "Shepherd",
+ "Frost",
+ "Hawkins",
+ "Pearson",
+ "Fleming",
+ "Dawson",
+ "Palmer",
+ "Nash",
+ "Barker",
+ "Thornton",
+ "Fitzgerald",
+ "Winters",
+ "Mckenzie",
+ "Chandler",
+ "Griffith",
+ "Cunningham",
+ "Doyle",
+ "Fletcher",
+ "Hicks",
+ "Walton",
+ "Briggs",
+ "Pearce",
+ "Nichols",
+ "Blake",
+ "Hodges",
+ "Benson",
+ "Marsh",
+ "Whitaker",
+ "Skinner",
+ "Robbins",
+ "Goodwin",
+ "Kirby",
+ "Savage",
+ "Hensley",
+ "Hancock",
+ "Pratt",
+ "Gallagher",
+ "Yates",
+ "Dennis",
+ "Swanson",
+ "Steele",
+ "Bauer",
+ "Holt",
+ "Barber",
+ "Schultz",
+ "Foley",
+ "Fowler",
+ "Wise",
+ "Malone",
+ "Cannon",
+ "Tate",
+ "Stark",
+ "Welch",
+ "Dyer",
+ "Booth",
+ "Payne",
+ "Shannon",
+ "Harmon",
+ "Woodward",
+ "Morse",
+ "Jacobson",
+ "Knowles",
+ "Blanchard",
+ "Dillon",
+ "Stokes",
+ "Buckley",
+ "Dickerson",
+ "Middleton",
+ "Sellers",
+ "Cobb",
+ "Stephenson",
+ "Roach",
+ "Moody",
+ "Beard",
+ "Mccarthy",
+ "Garner",
+ "Mcguire",
+ "Sloan",
+ "Ballard",
+ "Shields",
+ "Orr",
+ "Savage",
+ "Graves",
+ "Dempsey",
+ "Weeks",
+ "Mckay",
+ "Cooke",
+ "Riddle",
+ "Gates",
+ "Atkins",
+ "Farrell",
+ "Lowery",
+ "Huffman",
+ "Livingston",
+ "Davenport",
+ "Hendricks",
+ "Kerr",
+ "Pollard",
+ "Hoover",
+ "Wolfe",
+ "Bowman",
+ "Underwood",
+ "Frazier"
+];
+
+// src/implementations/IdentityGeneratorEn.ts
+var IdentityGeneratorEn = class extends BaseIdentityGenerator {
+ /**
+ * Get the male first names.
+ */
+ getFirstNamesMaleJson() {
+ return firstnames_male_default;
+ }
+ /**
+ * Get the female first names.
+ */
+ getFirstNamesFemaleJson() {
+ return firstnames_female_default;
+ }
+ /**
+ * Get the last names.
+ */
+ getLastNamesJson() {
+ return lastnames_default;
+ }
+};
+
+// src/dictionaries/nl/firstnames_male.ts
+var firstnames_male_default2 = [
+ "Daan",
+ "Luuk",
+ "Sem",
+ "Finn",
+ "Milan",
+ "Levi",
+ "Noah",
+ "Lucas",
+ "Jesse",
+ "Thijs",
+ "Jayden",
+ "Bram",
+ "Lars",
+ "Ruben",
+ "Thomas",
+ "Tim",
+ "Sam",
+ "Liam",
+ "Julian",
+ "Mees",
+ "Ties",
+ "Sven",
+ "Max",
+ "Gijs",
+ "David",
+ "Stijn",
+ "Jasper",
+ "Niels",
+ "Jens",
+ "Timo",
+ "Cas",
+ "Joep",
+ "Roan",
+ "Tom",
+ "Tygo",
+ "Teun",
+ "Siem",
+ "Mats",
+ "Thijmen",
+ "Rens",
+ "Niek",
+ "Tobias",
+ "Dex",
+ "Hugo",
+ "Robin",
+ "Nick",
+ "Floris",
+ "Pepijn",
+ "Boaz",
+ "Olivier",
+ "Luca",
+ "Jurre",
+ "Jelle",
+ "Guus",
+ "Koen",
+ "Bart",
+ "Olaf",
+ "Wessel",
+ "Dani\xEBl",
+ "Job",
+ "Sander",
+ "Tijmen",
+ "Kai",
+ "Quinten",
+ "Owen",
+ "Morris",
+ "Fedde",
+ "Joris",
+ "Jesper",
+ "Mick",
+ "Ryan",
+ "Milo",
+ "Stan",
+ "Benjamin",
+ "Melle",
+ "Jip",
+ "Dylan",
+ "Brent",
+ "Mick",
+ "Dean",
+ "Otis",
+ "Abel",
+ "Luc",
+ "Sepp",
+ "Vince",
+ "Rayan",
+ "Noud",
+ "Hidde",
+ "Fabian",
+ "Jort",
+ "Damian",
+ "Boris",
+ "Sil",
+ "Moos",
+ "Aiden",
+ "Sep",
+ "Mika",
+ "Mijs",
+ "Mika",
+ "Felix",
+ "Merlijn",
+ "Alexander",
+ "Aron",
+ "Arthur",
+ "Axel",
+ "Bas",
+ "Bastiaan",
+ "Berend",
+ "Bj\xF6rn",
+ "Casper",
+ "Cees",
+ "Chris",
+ "Christian",
+ "Christiaan",
+ "Colin",
+ "Cornelis",
+ "Dani",
+ "Dennis",
+ "Dirk",
+ "Dominic",
+ "Eduard",
+ "Eelco",
+ "Erik",
+ "Erwin",
+ "Ezra",
+ "Faas",
+ "Filip",
+ "Florian",
+ "Frank",
+ "Frederik",
+ "Freek",
+ "Gerard",
+ "Gerrit",
+ "Giel",
+ "Gijs",
+ "Glenn",
+ "Govert",
+ "Harm",
+ "Harold",
+ "Hendrik",
+ "Henrik",
+ "Huub",
+ "Ian",
+ "Ivo",
+ "Jacob",
+ "Jake",
+ "Jan",
+ "Jarno",
+ "Jason",
+ "Jeffrey",
+ "Jeremy",
+ "Jim",
+ "Jimmy",
+ "Johan",
+ "Johannes",
+ "Jonas",
+ "Jonathan",
+ "Jos",
+ "Joshua",
+ "Justin",
+ "Kay",
+ "Kevin",
+ "Kjeld",
+ "Klaas",
+ "Lennard",
+ "Lennart",
+ "Leon",
+ "Lex",
+ "Liam",
+ "Loek",
+ "Lorenzo",
+ "Louis",
+ "Lowie",
+ "Maarten",
+ "Magnus",
+ "Maikel",
+ "Marc",
+ "Marcel",
+ "Marco",
+ "Martijn",
+ "Mathias",
+ "Matthijs",
+ "Maurits",
+ "Menno",
+ "Michiel",
+ "Nathan",
+ "Nico",
+ "Oscar",
+ "Pascal",
+ "Patrick",
+ "Paul",
+ "Peter",
+ "Philip",
+ "Pieter",
+ "Pim",
+ "Quincy",
+ "Remco",
+ "Rick",
+ "Rik",
+ "Robert",
+ "Rogier",
+ "Rowan",
+ "Ruud",
+ "Simon",
+ "Stefan",
+ "Steven",
+ "Thom",
+ "Victor",
+ "Vincent",
+ "Willem",
+ "Wouter",
+ "Yannick"
+];
+
+// src/dictionaries/nl/firstnames_female.ts
+var firstnames_female_default2 = [
+ "Emma",
+ "Sophie",
+ "Julia",
+ "Mila",
+ "Tess",
+ "Sara",
+ "Anna",
+ "Noor",
+ "Lotte",
+ "Liv",
+ "Eva",
+ "Nora",
+ "Zo\xEB",
+ "Evi",
+ "Yara",
+ "Saar",
+ "Nina",
+ "Fenna",
+ "Lieke",
+ "Fleur",
+ "Isa",
+ "Roos",
+ "Lynn",
+ "Sofie",
+ "Sarah",
+ "Milou",
+ "Olivia",
+ "Maud",
+ "Lisa",
+ "Vera",
+ "Luna",
+ "Lina",
+ "Noa",
+ "Feline",
+ "Lo\xEFs",
+ "Lena",
+ "Floor",
+ "Charlotte",
+ "Esmee",
+ "Julie",
+ "Iris",
+ "Lara",
+ "Amber",
+ "Hailey",
+ "Mia",
+ "Lize",
+ "Isabelle",
+ "Cato",
+ "Fenne",
+ "Sanne",
+ "Norah",
+ "Sophia",
+ "Ella",
+ "Nova",
+ "Elin",
+ "Femke",
+ "Lizzy",
+ "Linde",
+ "Lauren",
+ "Rosalie",
+ "Lana",
+ "Emily",
+ "Elise",
+ "Esm\xE9e",
+ "Anne",
+ "Isabelle",
+ "Demi",
+ "Hannah",
+ "Liva",
+ "Suze",
+ "Fay",
+ "Isabel",
+ "Benthe",
+ "Evi",
+ "Amy",
+ "Jasmijn",
+ "Niene",
+ "Sterre",
+ "Fenna",
+ "Fiene",
+ "Liz",
+ "Ise",
+ "Mara",
+ "Nienke",
+ "Indy",
+ "Romy",
+ "Lola",
+ "Puck",
+ "Nora",
+ "Merel",
+ "Bente",
+ "Eline",
+ "Lily",
+ "Leah",
+ "Naomi",
+ "Mirthe",
+ "Valerie",
+ "Noor",
+ "Liva",
+ "Jade",
+ "Juul",
+ "Lise",
+ "Myrthe",
+ "Veerle",
+ "Aafke",
+ "Alicia",
+ "Amira",
+ "Aniek",
+ "Annabel",
+ "Annelies",
+ "Anouk",
+ "Astrid",
+ "Babette",
+ "Bianca",
+ "Britt",
+ "Carlijn",
+ "Chantal",
+ "Claire",
+ "Dagmar",
+ "Danique",
+ "Daphne",
+ "Denise",
+ "Dominique",
+ "Doris",
+ "Eefje",
+ "Elena",
+ "Eline",
+ "Elisa",
+ "Elisabeth",
+ "Ellen",
+ "Esther",
+ "Eveline",
+ "Fabienne",
+ "Felice",
+ "Fleur",
+ "Frederique",
+ "Gwen",
+ "Hanna",
+ "Heleen",
+ "Helena",
+ "Ilona",
+ "Imke",
+ "Inge",
+ "Irene",
+ "Iris",
+ "Janna",
+ "Janneke",
+ "Jasmine",
+ "Jennifer",
+ "Jessica",
+ "Joelle",
+ "Judith",
+ "Julia",
+ "Karin",
+ "Karlijn",
+ "Kim",
+ "Kirsten",
+ "Kyra",
+ "Laura",
+ "Lena",
+ "Lianne",
+ "Liesbeth",
+ "Linda",
+ "Lisanne",
+ "Lisette",
+ "Louise",
+ "Maartje",
+ "Manon",
+ "Margot",
+ "Marieke",
+ "Marijke",
+ "Marlies",
+ "Marloes",
+ "Marthe",
+ "Melissa",
+ "Michelle",
+ "Nadine",
+ "Natalie",
+ "Nicole",
+ "Nina",
+ "Noortje",
+ "Paulien",
+ "Petra",
+ "Rachel",
+ "Renee",
+ "Robin",
+ "Rosa",
+ "Roxanne",
+ "Sabine",
+ "Sandra",
+ "Saskia",
+ "Silke",
+ "Simone",
+ "Suzanne",
+ "Sylvie",
+ "Tamara",
+ "Tanja",
+ "Tara",
+ "Thea",
+ "Thirza",
+ "Tina",
+ "Tineke",
+ "Ursula",
+ "Victoria",
+ "Wendy",
+ "Wilma",
+ "Xandra",
+ "Yasmin",
+ "Yvette",
+ "Yvonne",
+ "Zara"
+];
+
+// src/dictionaries/nl/lastnames.ts
+var lastnames_default2 = [
+ "de Jong",
+ "Jansen",
+ "de Vries",
+ "van den Berg",
+ "van Dijk",
+ "Bakker",
+ "Janssen",
+ "Visser",
+ "Smit",
+ "Meijer",
+ "de Boer",
+ "Mulder",
+ "de Groot",
+ "Bos",
+ "Vos",
+ "Peters",
+ "Hendriks",
+ "van Leeuwen",
+ "Dekker",
+ "Brouwer",
+ "de Wit",
+ "Dijkstra",
+ "Smits",
+ "de Graaf",
+ "van der Meer",
+ "van der Linden",
+ "Kok",
+ "Jacobs",
+ "de Haan",
+ "Vermeulen",
+ "van den Heuvel",
+ "van der Veen",
+ "van den Broek",
+ "de Bruijn",
+ "de Bruin",
+ "van der Heijden",
+ "Schouten",
+ "van Beek",
+ "Willems",
+ "van Vliet",
+ "van de Ven",
+ "Hoekstra",
+ "Maas",
+ "Verhoeven",
+ "Koster",
+ "van Dam",
+ "van der Wal",
+ "Prins",
+ "Blom",
+ "Huisman",
+ "Peeters",
+ "Kuipers",
+ "van Veen",
+ "van Dongen",
+ "Veenstra",
+ "Kramer",
+ "van den Bosch",
+ "van der Meulen",
+ "Mol",
+ "Zwart",
+ "van der Laan",
+ "Martens",
+ "van de Pol",
+ "Postma",
+ "Tromp",
+ "Borst",
+ "Boon",
+ "van Doorn",
+ "Jonker",
+ "van der Velden",
+ "Willemsen",
+ "van Wijk",
+ "Groen",
+ "Gerritsen",
+ "Bosch",
+ "van Loon",
+ "van der Ploeg",
+ "de Ruiter",
+ "Molenaar",
+ "Boer",
+ "Klein",
+ "de Koning",
+ "van de Kamp",
+ "van der Horst",
+ "Verbeek",
+ "Vink",
+ "Goossens",
+ "Scholten",
+ "Hartman",
+ "van Dalen",
+ "van Elst",
+ "Brink",
+ "Boekel",
+ "van de Berg",
+ "Berends",
+ "van der Hoek",
+ "Kuiper",
+ "Kooijman",
+ "de Lange",
+ "van der Sluis",
+ "van Gelder",
+ "Martens",
+ "van Asselt",
+ "Timmermans",
+ "van Vliet",
+ "van Rijn",
+ "van Schaik",
+ "Bosman",
+ "Wolters",
+ "van Hout",
+ "Hermans",
+ "van Rooij",
+ "de Vos",
+ "van Donselaar",
+ "Evers",
+ "van den Brink",
+ "Verkerk",
+ "Groeneveld",
+ "van Duijn",
+ "Schuurman",
+ "Hoogendoorn",
+ "van Zanten",
+ "Koopman",
+ "Cornelissen",
+ "van Driel",
+ "Teunissen",
+ "Versteeg",
+ "van Deursen",
+ "Schipper",
+ "van Kempen",
+ "Bouwman",
+ "van der Valk",
+ "Nijhuis",
+ "van der Werf",
+ "van den Akker",
+ "Verhoef",
+ "Wessels",
+ "van der Poel",
+ "Driessen",
+ "van Oosten",
+ "Lambrechts",
+ "van der Vlist",
+ "Hoogeveen",
+ "van Gils",
+ "Rietveld",
+ "Barendrecht",
+ "van der Spek",
+ "Stam",
+ "van der Linde",
+ "Boersma",
+ "van Dijk",
+ "Schepers",
+ "van der Kolk",
+ "Roelofs",
+ "van der Velden",
+ "van den Burg",
+ "Westra",
+ "van der Steen",
+ "Pronk",
+ "van der Veer",
+ "Rozendaal",
+ "van den Bos",
+ "Konings",
+ "van der Wiel",
+ "Noordam",
+ "van der Laan",
+ "Schut",
+ "van der Vlugt",
+ "Witteveen",
+ "van der Zwan",
+ "Boogaard",
+ "van der Waal",
+ "Stolk",
+ "van der Windt",
+ "Rutten",
+ "van der Zanden",
+ "Spaans",
+ "van der Zwaan",
+ "Roos",
+ "van der Zijl",
+ "Schoenmaker",
+ "van Diepen",
+ "Romeijn",
+ "van Doesburg",
+ "Schippers",
+ "van Eck",
+ "Rijken",
+ "van Egmond",
+ "Schrama",
+ "van Eijk",
+ "Ruijter",
+ "van Engelen",
+ "Sanders",
+ "van Es",
+ "Schenk",
+ "van Essen",
+ "van Gaal",
+ "van Geenen",
+ "van Gent",
+ "van Gestel",
+ "van Gool",
+ "van Grinsven",
+ "van Gurp",
+ "van Haaften",
+ "van Haren",
+ "van Hattem",
+ "van Hees"
+];
+
+// src/implementations/IdentityGeneratorNl.ts
+var IdentityGeneratorNl = class extends BaseIdentityGenerator {
+ /**
+ * Get the male first names.
+ */
+ getFirstNamesMaleJson() {
+ return firstnames_male_default2;
+ }
+ /**
+ * Get the female first names.
+ */
+ getFirstNamesFemaleJson() {
+ return firstnames_female_default2;
+ }
+ /**
+ * Get the last names.
+ */
+ getLastNamesJson() {
+ return lastnames_default2;
+ }
+};
+
+// src/utils/IdentityHelperUtils.ts
+var IdentityHelperUtils = class {
+ /**
+ * Normalize a birth date for display.
+ */
+ static normalizeBirthDateForDisplay(birthDate) {
+ if (!birthDate || birthDate.startsWith("0001-01-01")) {
+ return "";
+ }
+ return birthDate.split(/[T ]/)[0];
+ }
+ /**
+ * Normalize a birth date for database.
+ */
+ static normalizeBirthDateForDb(input) {
+ if (!input || input.trim() === "") {
+ return "0001-01-01T00:00:00.000Z";
+ }
+ const trimmed = input.trim().replace(" ", "T");
+ const match = trimmed.match(/^(\d{4})-(\d{2})-(\d{2})[T ]?(\d{2}):?(\d{2}):?(\d{2})?$/);
+ if (match) {
+ const [_, y, m, d, h = "00", mi = "00", s = "00"] = match;
+ return `${y}-${m}-${d}T${h}:${mi}:${s}.000Z`;
+ }
+ const parsedDate = new Date(trimmed);
+ if (!isNaN(parsedDate.getTime())) {
+ return parsedDate.toISOString();
+ }
+ return "0001-01-01T00:00:00.000Z";
+ }
+ /**
+ * Check if a birth date is valid.
+ */
+ static isValidBirthDate(input) {
+ if (!input || input.trim() === "") {
+ return false;
+ }
+ if (input.startsWith("0001-01-01")) {
+ return false;
+ }
+ const date = new Date(input);
+ if (isNaN(date.getTime())) {
+ return false;
+ }
+ const yearValid = date.getFullYear() > 1 && date.getFullYear() < 9999;
+ return yearValid;
+ }
+};
+
+// src/factories/IdentityGeneratorFactory.ts
+var createGenerator = (language) => {
+ switch (language) {
+ case "en":
+ return new IdentityGeneratorEn();
+ case "nl":
+ return new IdentityGeneratorNl();
+ }
+ throw new Error(`Unsupported language: ${language}`);
+};
+// Annotate the CommonJS export names for ESM import in node:
+0 && (module.exports = {
+ BaseIdentityGenerator,
+ Gender,
+ IdentityGeneratorEn,
+ IdentityGeneratorNl,
+ IdentityHelperUtils,
+ UsernameEmailGenerator,
+ createGenerator
+});
+//# sourceMappingURL=index.js.map
\ No newline at end of file
diff --git a/apps/server/AliasVault.Client/wwwroot/js/shared/identity-generator/index.mjs b/apps/server/AliasVault.Client/wwwroot/js/shared/identity-generator/index.mjs
new file mode 100644
index 000000000..5ac1c0697
--- /dev/null
+++ b/apps/server/AliasVault.Client/wwwroot/js/shared/identity-generator/index.mjs
@@ -0,0 +1,1704 @@
+// src/utils/UsernameEmailGenerator.ts
+var _UsernameEmailGenerator = class _UsernameEmailGenerator {
+ constructor() {
+ this.symbols = [".", "-"];
+ }
+ /**
+ * Generate a username based on an identity.
+ */
+ generateUsername(identity) {
+ let username = this.generateEmailPrefix(identity);
+ username = username.replace(/[^a-zA-Z0-9]/g, "");
+ if (username.length < _UsernameEmailGenerator.MIN_LENGTH) {
+ username += this.generateRandomString(_UsernameEmailGenerator.MIN_LENGTH - username.length);
+ } else if (username.length > _UsernameEmailGenerator.MAX_LENGTH) {
+ username = username.substring(0, _UsernameEmailGenerator.MAX_LENGTH);
+ }
+ return username;
+ }
+ /**
+ * Generate an email prefix based on an identity.
+ */
+ generateEmailPrefix(identity) {
+ const parts = [];
+ switch (this.getSecureRandom(4)) {
+ case 0:
+ parts.push(identity.firstName.substring(0, 1).toLowerCase() + identity.lastName.toLowerCase());
+ break;
+ case 1:
+ parts.push((identity.firstName + identity.lastName).toLowerCase());
+ break;
+ case 2:
+ parts.push(identity.firstName.toLowerCase() + identity.lastName.substring(0, 1).toLowerCase());
+ break;
+ case 3:
+ parts.push(identity.firstName.substring(0, Math.min(3, identity.firstName.length)).toLowerCase() + identity.lastName.toLowerCase());
+ break;
+ }
+ if (this.getSecureRandom(3) !== 0) {
+ switch (this.getSecureRandom(2)) {
+ case 0:
+ parts.push(identity.birthDate.getFullYear().toString().substring(2));
+ break;
+ case 1:
+ parts.push(identity.birthDate.getFullYear().toString());
+ break;
+ }
+ } else if (this.getSecureRandom(2) === 0) {
+ parts.push((this.getSecureRandom(990) + 10).toString());
+ }
+ let emailPrefix = parts.join(this.getRandomSymbol());
+ if (this.getSecureRandom(2) === 0) {
+ const position = this.getSecureRandom(emailPrefix.length);
+ emailPrefix = emailPrefix.slice(0, position) + this.getRandomSymbol() + emailPrefix.slice(position);
+ }
+ emailPrefix = this.sanitizeEmailPrefix(emailPrefix);
+ if (emailPrefix.length < _UsernameEmailGenerator.MIN_LENGTH) {
+ emailPrefix += this.generateRandomString(_UsernameEmailGenerator.MIN_LENGTH - emailPrefix.length);
+ } else if (emailPrefix.length > _UsernameEmailGenerator.MAX_LENGTH) {
+ emailPrefix = emailPrefix.substring(0, _UsernameEmailGenerator.MAX_LENGTH);
+ }
+ return emailPrefix;
+ }
+ /**
+ * Sanitize an email prefix.
+ */
+ sanitizeEmailPrefix(input) {
+ let sanitized = input.replace(/[^a-zA-Z0-9._-]/g, "");
+ sanitized = sanitized.replace(/[-_.]{2,}/g, (match) => match[0]);
+ sanitized = sanitized.replace(/^[-._]+/, "");
+ sanitized = sanitized.replace(/[-._]*$/, "");
+ return sanitized;
+ }
+ /**
+ * Get a random symbol.
+ */
+ getRandomSymbol() {
+ return this.getSecureRandom(3) === 0 ? this.symbols[this.getSecureRandom(this.symbols.length)] : "";
+ }
+ /**
+ * Generate a random string.
+ */
+ generateRandomString(length) {
+ const chars = "abcdefghijklmnopqrstuvwxyz0123456789";
+ return Array.from({ length }, () => chars.charAt(this.getSecureRandom(chars.length))).join("");
+ }
+ /**
+ * Generate a secure random integer between 0 (inclusive) and max (exclusive)
+ */
+ getSecureRandom(max) {
+ const array = new Uint32Array(1);
+ crypto.getRandomValues(array);
+ return array[0] % max;
+ }
+};
+_UsernameEmailGenerator.MIN_LENGTH = 6;
+_UsernameEmailGenerator.MAX_LENGTH = 20;
+var UsernameEmailGenerator = _UsernameEmailGenerator;
+
+// src/types/Gender.ts
+var Gender = /* @__PURE__ */ ((Gender2) => {
+ Gender2["Male"] = "Male";
+ Gender2["Female"] = "Female";
+ Gender2["Other"] = "Other";
+ return Gender2;
+})(Gender || {});
+
+// src/implementations/base/BaseIdentityGenerator.ts
+var BaseIdentityGenerator = class {
+ /**
+ * Constructor.
+ */
+ constructor() {
+ this.firstNamesMale = [];
+ this.firstNamesFemale = [];
+ this.lastNames = [];
+ this.random = Math.random;
+ this.firstNamesMale = this.getFirstNamesMaleJson();
+ this.firstNamesFemale = this.getFirstNamesFemaleJson();
+ this.lastNames = this.getLastNamesJson();
+ }
+ /**
+ * Generate a random date of birth.
+ */
+ generateRandomDateOfBirth() {
+ const today = /* @__PURE__ */ new Date();
+ const minAge = 21;
+ const maxAge = 65;
+ const minDate = new Date(today.getFullYear() - maxAge, today.getMonth(), today.getDate());
+ const maxDate = new Date(today.getFullYear() - minAge, today.getMonth(), today.getDate());
+ const timestamp = minDate.getTime() + this.random() * (maxDate.getTime() - minDate.getTime());
+ return new Date(timestamp);
+ }
+ /**
+ * Generate a random identity.
+ */
+ generateRandomIdentity() {
+ const identity = {
+ firstName: "",
+ lastName: "",
+ gender: "Male" /* Male */,
+ birthDate: /* @__PURE__ */ new Date(),
+ emailPrefix: "",
+ nickName: ""
+ };
+ if (this.random() < 0.5) {
+ identity.firstName = this.firstNamesMale[Math.floor(this.random() * this.firstNamesMale.length)];
+ identity.gender = "Male" /* Male */;
+ } else {
+ identity.firstName = this.firstNamesFemale[Math.floor(this.random() * this.firstNamesFemale.length)];
+ identity.gender = "Female" /* Female */;
+ }
+ identity.lastName = this.lastNames[Math.floor(this.random() * this.lastNames.length)];
+ identity.birthDate = this.generateRandomDateOfBirth();
+ const generator = new UsernameEmailGenerator();
+ identity.emailPrefix = generator.generateEmailPrefix(identity);
+ identity.nickName = generator.generateUsername(identity);
+ return identity;
+ }
+};
+
+// src/dictionaries/en/firstnames_male.ts
+var firstnames_male_default = [
+ "Michael",
+ "Christopher",
+ "Matthew",
+ "Joshua",
+ "Daniel",
+ "David",
+ "Andrew",
+ "Joseph",
+ "James",
+ "John",
+ "Robert",
+ "William",
+ "Ryan",
+ "Jason",
+ "Nicholas",
+ "Jonathan",
+ "Jacob",
+ "Brandon",
+ "Tyler",
+ "Zachary",
+ "Kevin",
+ "Justin",
+ "Benjamin",
+ "Anthony",
+ "Samuel",
+ "Thomas",
+ "Alexander",
+ "Ethan",
+ "Noah",
+ "Dylan",
+ "Nathan",
+ "Christian",
+ "Austin",
+ "Adam",
+ "Caleb",
+ "Cody",
+ "Jordan",
+ "Logan",
+ "Aaron",
+ "Kyle",
+ "Jose",
+ "Brian",
+ "Gabriel",
+ "Timothy",
+ "Luke",
+ "Jared",
+ "Connor",
+ "Sean",
+ "Evan",
+ "Isaac",
+ "Jack",
+ "Cameron",
+ "Hunter",
+ "Jackson",
+ "Charles",
+ "Devin",
+ "Stephen",
+ "Patrick",
+ "Steven",
+ "Elijah",
+ "Scott",
+ "Mark",
+ "Jeffrey",
+ "Corey",
+ "Juan",
+ "Luis",
+ "Derek",
+ "Chase",
+ "Travis",
+ "Alex",
+ "Spencer",
+ "Ian",
+ "Trevor",
+ "Bryan",
+ "Tanner",
+ "Marcus",
+ "Jeremy",
+ "Eric",
+ "Jaden",
+ "Garrett",
+ "Isaiah",
+ "Dustin",
+ "Jesse",
+ "Seth",
+ "Blake",
+ "Nathaniel",
+ "Mason",
+ "Liam",
+ "Paul",
+ "Carlos",
+ "Mitchell",
+ "Parker",
+ "Lucas",
+ "Richard",
+ "Cole",
+ "Adrian",
+ "Colin",
+ "Bradley",
+ "Jesus",
+ "Peter",
+ "Kenneth",
+ "Joel",
+ "Victor",
+ "Bryce",
+ "Casey",
+ "Vincent",
+ "Edward",
+ "Henry",
+ "Dominic",
+ "Riley",
+ "Shane",
+ "Dalton",
+ "Grant",
+ "Shawn",
+ "Braden",
+ "Caden",
+ "Max",
+ "Hayden",
+ "Owen",
+ "Brett",
+ "Trevor",
+ "Philip",
+ "Brendan",
+ "Wesley",
+ "Aidan",
+ "Brady",
+ "Colton",
+ "Tristan",
+ "George",
+ "Gavin",
+ "Dawson",
+ "Miguel",
+ "Antonio",
+ "Nolan",
+ "Dakota",
+ "Jace",
+ "Collin",
+ "Preston",
+ "Levi",
+ "Alan",
+ "Jorge",
+ "Carson",
+ "Felix",
+ "Oliver",
+ "Theodore",
+ "Harrison",
+ "Maxwell",
+ "Sebastian",
+ "Xavier",
+ "Dominick",
+ "Lincoln",
+ "Elliott",
+ "Walter",
+ "Simon",
+ "Dean",
+ "Hugo",
+ "Malcolm",
+ "Leon",
+ "Oscar",
+ "Calvin",
+ "Raymond",
+ "Edgar",
+ "Franklin",
+ "Arthur",
+ "Lawrence",
+ "Dennis",
+ "Russell",
+ "Douglas",
+ "Leonard",
+ "Gregory",
+ "Harold",
+ "Frederick",
+ "Martin",
+ "Curtis",
+ "Stanley",
+ "Gilbert",
+ "Harvey",
+ "Francis",
+ "Eugene",
+ "Ralph",
+ "Roy",
+ "Albert",
+ "Bruce",
+ "Ronald",
+ "Keith",
+ "Craig",
+ "Roger",
+ "Randy",
+ "Gary",
+ "Dennis",
+ "Edwin",
+ "Don",
+ "Glen",
+ "Gordon",
+ "Howard",
+ "Earl",
+ "Leo",
+ "Lloyd",
+ "Milton",
+ "Norman",
+ "Roland",
+ "Vernon",
+ "Warren",
+ "Alfred",
+ "Bernard",
+ "Chester",
+ "Clarence",
+ "Clifford",
+ "Clyde",
+ "Dale",
+ "Dan",
+ "Darrell",
+ "Floyd",
+ "Herman",
+ "Jerome",
+ "Maurice",
+ "Neil",
+ "Ray",
+ "Rodney",
+ "Roland",
+ "Stuart",
+ "Wallace",
+ "Wayne",
+ "Wendell",
+ "Barry",
+ "Cecil",
+ "Claude",
+ "Daryl",
+ "Edmund",
+ "Everett",
+ "Ferdinand",
+ "Forrest",
+ "Gerald",
+ "Hugh",
+ "Irving",
+ "Leslie",
+ "Marvin",
+ "Morris",
+ "Nelson",
+ "Perry",
+ "Phillip",
+ "Roderick",
+ "Ross",
+ "Terrence",
+ "Wade",
+ "Winston",
+ "Zachariah"
+];
+
+// src/dictionaries/en/firstnames_female.ts
+var firstnames_female_default = [
+ "Emily",
+ "Emma",
+ "Olivia",
+ "Ava",
+ "Sophia",
+ "Isabella",
+ "Mia",
+ "Charlotte",
+ "Amelia",
+ "Harper",
+ "Evelyn",
+ "Abigail",
+ "Elizabeth",
+ "Sofia",
+ "Avery",
+ "Ella",
+ "Madison",
+ "Scarlett",
+ "Victoria",
+ "Aria",
+ "Grace",
+ "Chloe",
+ "Camila",
+ "Penelope",
+ "Riley",
+ "Layla",
+ "Zoey",
+ "Nora",
+ "Lily",
+ "Eleanor",
+ "Hannah",
+ "Lillian",
+ "Addison",
+ "Aubrey",
+ "Ellie",
+ "Stella",
+ "Natalie",
+ "Zoe",
+ "Leah",
+ "Hazel",
+ "Violet",
+ "Aurora",
+ "Savannah",
+ "Audrey",
+ "Brooklyn",
+ "Bella",
+ "Claire",
+ "Skylar",
+ "Lucy",
+ "Paisley",
+ "Everly",
+ "Anna",
+ "Caroline",
+ "Nova",
+ "Genesis",
+ "Emilia",
+ "Kennedy",
+ "Samantha",
+ "Maya",
+ "Willow",
+ "Kinsley",
+ "Naomi",
+ "Aaliyah",
+ "Elena",
+ "Sarah",
+ "Ariana",
+ "Allison",
+ "Gabriella",
+ "Alice",
+ "Madelyn",
+ "Cora",
+ "Ruby",
+ "Eva",
+ "Serenity",
+ "Autumn",
+ "Adeline",
+ "Hailey",
+ "Gianna",
+ "Valentina",
+ "Isla",
+ "Eliana",
+ "Quinn",
+ "Nevaeh",
+ "Ivy",
+ "Sadie",
+ "Piper",
+ "Lydia",
+ "Alexa",
+ "Josephine",
+ "Emery",
+ "Julia",
+ "Delilah",
+ "Arianna",
+ "Vivian",
+ "Kaylee",
+ "Sophie",
+ "Brielle",
+ "Madeline",
+ "Peyton",
+ "Rylee",
+ "Clara",
+ "Hadley",
+ "Melanie",
+ "Mackenzie",
+ "Reagan",
+ "Adalyn",
+ "Liliana",
+ "Aubree",
+ "Jade",
+ "Katherine",
+ "Isabelle",
+ "Natalia",
+ "Raelynn",
+ "Maria",
+ "Athena",
+ "Ximena",
+ "Arya",
+ "Leilani",
+ "Taylor",
+ "Faith",
+ "Rose",
+ "Kylie",
+ "Alexandra",
+ "Mary",
+ "Margaret",
+ "Lyla",
+ "Ashley",
+ "Amaya",
+ "Eliza",
+ "Brianna",
+ "Bailey",
+ "Andrea",
+ "Khloe",
+ "Jasmine",
+ "Melody",
+ "Iris",
+ "Isabel",
+ "Norah",
+ "Annabelle",
+ "Valeria",
+ "Emerson",
+ "Adalynn",
+ "Ryleigh",
+ "Eden",
+ "Emersyn",
+ "Anastasia",
+ "Kayla",
+ "Alyssa",
+ "Anna",
+ "Juliana",
+ "Charlie",
+ "Lucia",
+ "Stella",
+ "Adriana",
+ "Beatrice",
+ "Bianca",
+ "Calliope",
+ "Carmen",
+ "Celeste",
+ "Dakota",
+ "Diana",
+ "Esther",
+ "Florence",
+ "Francesca",
+ "Georgia",
+ "Harlow",
+ "Haven",
+ "Holly",
+ "Hope",
+ "India",
+ "Indie",
+ "Iris",
+ "Juniper",
+ "Kaia",
+ "Keira",
+ "Lara",
+ "Laura",
+ "Laurel",
+ "Luna",
+ "Magnolia",
+ "Maeve",
+ "Marina",
+ "Marlowe",
+ "Nina",
+ "Noelle",
+ "Octavia",
+ "Olive",
+ "Ophelia",
+ "Phoenix",
+ "Poppy",
+ "Primrose",
+ "Ramona",
+ "River",
+ "Rosalie",
+ "Rosemary",
+ "Sage",
+ "Salem",
+ "Selena",
+ "Sienna",
+ "Summer",
+ "Sylvie",
+ "Thea",
+ "Tessa",
+ "Wren",
+ "Winter",
+ "Willa",
+ "Ada",
+ "Aspen",
+ "Blair",
+ "Brynn",
+ "Cassidy",
+ "Cecilia",
+ "Daisy",
+ "Dawn",
+ "Daphne",
+ "Ember",
+ "Fiona",
+ "Flora",
+ "Freya",
+ "Gemma",
+ "Giselle",
+ "Harmony",
+ "Heidi",
+ "Imogen",
+ "Indie",
+ "Jessie",
+ "June",
+ "Kaia",
+ "Lena",
+ "Lola",
+ "Mabel",
+ "Maisie",
+ "Margot",
+ "Matilda",
+ "Mira",
+ "Morgan",
+ "Nell",
+ "Nadia",
+ "Odette",
+ "Opal",
+ "Pearl",
+ "Phoebe",
+ "Raven",
+ "Reese",
+ "Robin",
+ "Rowan",
+ "Ruth",
+ "Sabrina",
+ "Sasha",
+ "Sierra",
+ "Skye",
+ "Sloane",
+ "Talia",
+ "Thora",
+ "Vera",
+ "Willa",
+ "Winnie",
+ "Yara",
+ "Zara"
+];
+
+// src/dictionaries/en/lastnames.ts
+var lastnames_default = [
+ "Smith",
+ "Johnson",
+ "Williams",
+ "Brown",
+ "Jones",
+ "Garcia",
+ "Miller",
+ "Davis",
+ "Rodriguez",
+ "Martinez",
+ "Hernandez",
+ "Lopez",
+ "Gonzalez",
+ "Wilson",
+ "Anderson",
+ "Thomas",
+ "Taylor",
+ "Moore",
+ "Jackson",
+ "Martin",
+ "Lee",
+ "Perez",
+ "Thompson",
+ "White",
+ "Harris",
+ "Sanchez",
+ "Clark",
+ "Ramirez",
+ "Lewis",
+ "Robinson",
+ "Walker",
+ "Young",
+ "Allen",
+ "King",
+ "Wright",
+ "Scott",
+ "Torres",
+ "Nguyen",
+ "Hill",
+ "Flores",
+ "Green",
+ "Adams",
+ "Nelson",
+ "Baker",
+ "Hall",
+ "Rivera",
+ "Campbell",
+ "Mitchell",
+ "Carter",
+ "Roberts",
+ "Gomez",
+ "Phillips",
+ "Evans",
+ "Turner",
+ "Diaz",
+ "Parker",
+ "Cruz",
+ "Edwards",
+ "Collins",
+ "Reyes",
+ "Stewart",
+ "Morris",
+ "Morales",
+ "Murphy",
+ "Cook",
+ "Rogers",
+ "Gutierrez",
+ "Ortiz",
+ "Morgan",
+ "Cooper",
+ "Peterson",
+ "Bailey",
+ "Reed",
+ "Kelly",
+ "Howard",
+ "Ramos",
+ "Kim",
+ "Cox",
+ "Ward",
+ "Richardson",
+ "Watson",
+ "Brooks",
+ "Chavez",
+ "Wood",
+ "James",
+ "Bennett",
+ "Gray",
+ "Mendoza",
+ "Ruiz",
+ "Hughes",
+ "Price",
+ "Alvarez",
+ "Castillo",
+ "Sanders",
+ "Patel",
+ "Myers",
+ "Long",
+ "Ross",
+ "Foster",
+ "Jimenez",
+ "Powell",
+ "Jenkins",
+ "Perry",
+ "Russell",
+ "Sullivan",
+ "Bell",
+ "Coleman",
+ "Butler",
+ "Henderson",
+ "Barnes",
+ "Gonzales",
+ "Fisher",
+ "Vasquez",
+ "Simmons",
+ "Romero",
+ "Jordan",
+ "Patterson",
+ "Alexander",
+ "Hamilton",
+ "Graham",
+ "Reynolds",
+ "Griffin",
+ "Wallace",
+ "Moreno",
+ "West",
+ "Cole",
+ "Hayes",
+ "Bryant",
+ "Herrera",
+ "Gibson",
+ "Ellis",
+ "Tran",
+ "Medina",
+ "Aguilar",
+ "Stevens",
+ "Murray",
+ "Ford",
+ "Castro",
+ "Marshall",
+ "Owens",
+ "Harrison",
+ "Fernandez",
+ "McDonald",
+ "Woods",
+ "Washington",
+ "Kennedy",
+ "Wells",
+ "Vargas",
+ "Henry",
+ "Chen",
+ "Freeman",
+ "Webb",
+ "Tucker",
+ "Guzman",
+ "Burns",
+ "Crawford",
+ "Olson",
+ "Simpson",
+ "Porter",
+ "Hunter",
+ "Gordon",
+ "Mendez",
+ "Silva",
+ "Shaw",
+ "Snyder",
+ "Mason",
+ "Dixon",
+ "Blackwood",
+ "Shepherd",
+ "Frost",
+ "Hawkins",
+ "Pearson",
+ "Fleming",
+ "Dawson",
+ "Palmer",
+ "Nash",
+ "Barker",
+ "Thornton",
+ "Fitzgerald",
+ "Winters",
+ "Mckenzie",
+ "Chandler",
+ "Griffith",
+ "Cunningham",
+ "Doyle",
+ "Fletcher",
+ "Hicks",
+ "Walton",
+ "Briggs",
+ "Pearce",
+ "Nichols",
+ "Blake",
+ "Hodges",
+ "Benson",
+ "Marsh",
+ "Whitaker",
+ "Skinner",
+ "Robbins",
+ "Goodwin",
+ "Kirby",
+ "Savage",
+ "Hensley",
+ "Hancock",
+ "Pratt",
+ "Gallagher",
+ "Yates",
+ "Dennis",
+ "Swanson",
+ "Steele",
+ "Bauer",
+ "Holt",
+ "Barber",
+ "Schultz",
+ "Foley",
+ "Fowler",
+ "Wise",
+ "Malone",
+ "Cannon",
+ "Tate",
+ "Stark",
+ "Welch",
+ "Dyer",
+ "Booth",
+ "Payne",
+ "Shannon",
+ "Harmon",
+ "Woodward",
+ "Morse",
+ "Jacobson",
+ "Knowles",
+ "Blanchard",
+ "Dillon",
+ "Stokes",
+ "Buckley",
+ "Dickerson",
+ "Middleton",
+ "Sellers",
+ "Cobb",
+ "Stephenson",
+ "Roach",
+ "Moody",
+ "Beard",
+ "Mccarthy",
+ "Garner",
+ "Mcguire",
+ "Sloan",
+ "Ballard",
+ "Shields",
+ "Orr",
+ "Savage",
+ "Graves",
+ "Dempsey",
+ "Weeks",
+ "Mckay",
+ "Cooke",
+ "Riddle",
+ "Gates",
+ "Atkins",
+ "Farrell",
+ "Lowery",
+ "Huffman",
+ "Livingston",
+ "Davenport",
+ "Hendricks",
+ "Kerr",
+ "Pollard",
+ "Hoover",
+ "Wolfe",
+ "Bowman",
+ "Underwood",
+ "Frazier"
+];
+
+// src/implementations/IdentityGeneratorEn.ts
+var IdentityGeneratorEn = class extends BaseIdentityGenerator {
+ /**
+ * Get the male first names.
+ */
+ getFirstNamesMaleJson() {
+ return firstnames_male_default;
+ }
+ /**
+ * Get the female first names.
+ */
+ getFirstNamesFemaleJson() {
+ return firstnames_female_default;
+ }
+ /**
+ * Get the last names.
+ */
+ getLastNamesJson() {
+ return lastnames_default;
+ }
+};
+
+// src/dictionaries/nl/firstnames_male.ts
+var firstnames_male_default2 = [
+ "Daan",
+ "Luuk",
+ "Sem",
+ "Finn",
+ "Milan",
+ "Levi",
+ "Noah",
+ "Lucas",
+ "Jesse",
+ "Thijs",
+ "Jayden",
+ "Bram",
+ "Lars",
+ "Ruben",
+ "Thomas",
+ "Tim",
+ "Sam",
+ "Liam",
+ "Julian",
+ "Mees",
+ "Ties",
+ "Sven",
+ "Max",
+ "Gijs",
+ "David",
+ "Stijn",
+ "Jasper",
+ "Niels",
+ "Jens",
+ "Timo",
+ "Cas",
+ "Joep",
+ "Roan",
+ "Tom",
+ "Tygo",
+ "Teun",
+ "Siem",
+ "Mats",
+ "Thijmen",
+ "Rens",
+ "Niek",
+ "Tobias",
+ "Dex",
+ "Hugo",
+ "Robin",
+ "Nick",
+ "Floris",
+ "Pepijn",
+ "Boaz",
+ "Olivier",
+ "Luca",
+ "Jurre",
+ "Jelle",
+ "Guus",
+ "Koen",
+ "Bart",
+ "Olaf",
+ "Wessel",
+ "Dani\xEBl",
+ "Job",
+ "Sander",
+ "Tijmen",
+ "Kai",
+ "Quinten",
+ "Owen",
+ "Morris",
+ "Fedde",
+ "Joris",
+ "Jesper",
+ "Mick",
+ "Ryan",
+ "Milo",
+ "Stan",
+ "Benjamin",
+ "Melle",
+ "Jip",
+ "Dylan",
+ "Brent",
+ "Mick",
+ "Dean",
+ "Otis",
+ "Abel",
+ "Luc",
+ "Sepp",
+ "Vince",
+ "Rayan",
+ "Noud",
+ "Hidde",
+ "Fabian",
+ "Jort",
+ "Damian",
+ "Boris",
+ "Sil",
+ "Moos",
+ "Aiden",
+ "Sep",
+ "Mika",
+ "Mijs",
+ "Mika",
+ "Felix",
+ "Merlijn",
+ "Alexander",
+ "Aron",
+ "Arthur",
+ "Axel",
+ "Bas",
+ "Bastiaan",
+ "Berend",
+ "Bj\xF6rn",
+ "Casper",
+ "Cees",
+ "Chris",
+ "Christian",
+ "Christiaan",
+ "Colin",
+ "Cornelis",
+ "Dani",
+ "Dennis",
+ "Dirk",
+ "Dominic",
+ "Eduard",
+ "Eelco",
+ "Erik",
+ "Erwin",
+ "Ezra",
+ "Faas",
+ "Filip",
+ "Florian",
+ "Frank",
+ "Frederik",
+ "Freek",
+ "Gerard",
+ "Gerrit",
+ "Giel",
+ "Gijs",
+ "Glenn",
+ "Govert",
+ "Harm",
+ "Harold",
+ "Hendrik",
+ "Henrik",
+ "Huub",
+ "Ian",
+ "Ivo",
+ "Jacob",
+ "Jake",
+ "Jan",
+ "Jarno",
+ "Jason",
+ "Jeffrey",
+ "Jeremy",
+ "Jim",
+ "Jimmy",
+ "Johan",
+ "Johannes",
+ "Jonas",
+ "Jonathan",
+ "Jos",
+ "Joshua",
+ "Justin",
+ "Kay",
+ "Kevin",
+ "Kjeld",
+ "Klaas",
+ "Lennard",
+ "Lennart",
+ "Leon",
+ "Lex",
+ "Liam",
+ "Loek",
+ "Lorenzo",
+ "Louis",
+ "Lowie",
+ "Maarten",
+ "Magnus",
+ "Maikel",
+ "Marc",
+ "Marcel",
+ "Marco",
+ "Martijn",
+ "Mathias",
+ "Matthijs",
+ "Maurits",
+ "Menno",
+ "Michiel",
+ "Nathan",
+ "Nico",
+ "Oscar",
+ "Pascal",
+ "Patrick",
+ "Paul",
+ "Peter",
+ "Philip",
+ "Pieter",
+ "Pim",
+ "Quincy",
+ "Remco",
+ "Rick",
+ "Rik",
+ "Robert",
+ "Rogier",
+ "Rowan",
+ "Ruud",
+ "Simon",
+ "Stefan",
+ "Steven",
+ "Thom",
+ "Victor",
+ "Vincent",
+ "Willem",
+ "Wouter",
+ "Yannick"
+];
+
+// src/dictionaries/nl/firstnames_female.ts
+var firstnames_female_default2 = [
+ "Emma",
+ "Sophie",
+ "Julia",
+ "Mila",
+ "Tess",
+ "Sara",
+ "Anna",
+ "Noor",
+ "Lotte",
+ "Liv",
+ "Eva",
+ "Nora",
+ "Zo\xEB",
+ "Evi",
+ "Yara",
+ "Saar",
+ "Nina",
+ "Fenna",
+ "Lieke",
+ "Fleur",
+ "Isa",
+ "Roos",
+ "Lynn",
+ "Sofie",
+ "Sarah",
+ "Milou",
+ "Olivia",
+ "Maud",
+ "Lisa",
+ "Vera",
+ "Luna",
+ "Lina",
+ "Noa",
+ "Feline",
+ "Lo\xEFs",
+ "Lena",
+ "Floor",
+ "Charlotte",
+ "Esmee",
+ "Julie",
+ "Iris",
+ "Lara",
+ "Amber",
+ "Hailey",
+ "Mia",
+ "Lize",
+ "Isabelle",
+ "Cato",
+ "Fenne",
+ "Sanne",
+ "Norah",
+ "Sophia",
+ "Ella",
+ "Nova",
+ "Elin",
+ "Femke",
+ "Lizzy",
+ "Linde",
+ "Lauren",
+ "Rosalie",
+ "Lana",
+ "Emily",
+ "Elise",
+ "Esm\xE9e",
+ "Anne",
+ "Isabelle",
+ "Demi",
+ "Hannah",
+ "Liva",
+ "Suze",
+ "Fay",
+ "Isabel",
+ "Benthe",
+ "Evi",
+ "Amy",
+ "Jasmijn",
+ "Niene",
+ "Sterre",
+ "Fenna",
+ "Fiene",
+ "Liz",
+ "Ise",
+ "Mara",
+ "Nienke",
+ "Indy",
+ "Romy",
+ "Lola",
+ "Puck",
+ "Nora",
+ "Merel",
+ "Bente",
+ "Eline",
+ "Lily",
+ "Leah",
+ "Naomi",
+ "Mirthe",
+ "Valerie",
+ "Noor",
+ "Liva",
+ "Jade",
+ "Juul",
+ "Lise",
+ "Myrthe",
+ "Veerle",
+ "Aafke",
+ "Alicia",
+ "Amira",
+ "Aniek",
+ "Annabel",
+ "Annelies",
+ "Anouk",
+ "Astrid",
+ "Babette",
+ "Bianca",
+ "Britt",
+ "Carlijn",
+ "Chantal",
+ "Claire",
+ "Dagmar",
+ "Danique",
+ "Daphne",
+ "Denise",
+ "Dominique",
+ "Doris",
+ "Eefje",
+ "Elena",
+ "Eline",
+ "Elisa",
+ "Elisabeth",
+ "Ellen",
+ "Esther",
+ "Eveline",
+ "Fabienne",
+ "Felice",
+ "Fleur",
+ "Frederique",
+ "Gwen",
+ "Hanna",
+ "Heleen",
+ "Helena",
+ "Ilona",
+ "Imke",
+ "Inge",
+ "Irene",
+ "Iris",
+ "Janna",
+ "Janneke",
+ "Jasmine",
+ "Jennifer",
+ "Jessica",
+ "Joelle",
+ "Judith",
+ "Julia",
+ "Karin",
+ "Karlijn",
+ "Kim",
+ "Kirsten",
+ "Kyra",
+ "Laura",
+ "Lena",
+ "Lianne",
+ "Liesbeth",
+ "Linda",
+ "Lisanne",
+ "Lisette",
+ "Louise",
+ "Maartje",
+ "Manon",
+ "Margot",
+ "Marieke",
+ "Marijke",
+ "Marlies",
+ "Marloes",
+ "Marthe",
+ "Melissa",
+ "Michelle",
+ "Nadine",
+ "Natalie",
+ "Nicole",
+ "Nina",
+ "Noortje",
+ "Paulien",
+ "Petra",
+ "Rachel",
+ "Renee",
+ "Robin",
+ "Rosa",
+ "Roxanne",
+ "Sabine",
+ "Sandra",
+ "Saskia",
+ "Silke",
+ "Simone",
+ "Suzanne",
+ "Sylvie",
+ "Tamara",
+ "Tanja",
+ "Tara",
+ "Thea",
+ "Thirza",
+ "Tina",
+ "Tineke",
+ "Ursula",
+ "Victoria",
+ "Wendy",
+ "Wilma",
+ "Xandra",
+ "Yasmin",
+ "Yvette",
+ "Yvonne",
+ "Zara"
+];
+
+// src/dictionaries/nl/lastnames.ts
+var lastnames_default2 = [
+ "de Jong",
+ "Jansen",
+ "de Vries",
+ "van den Berg",
+ "van Dijk",
+ "Bakker",
+ "Janssen",
+ "Visser",
+ "Smit",
+ "Meijer",
+ "de Boer",
+ "Mulder",
+ "de Groot",
+ "Bos",
+ "Vos",
+ "Peters",
+ "Hendriks",
+ "van Leeuwen",
+ "Dekker",
+ "Brouwer",
+ "de Wit",
+ "Dijkstra",
+ "Smits",
+ "de Graaf",
+ "van der Meer",
+ "van der Linden",
+ "Kok",
+ "Jacobs",
+ "de Haan",
+ "Vermeulen",
+ "van den Heuvel",
+ "van der Veen",
+ "van den Broek",
+ "de Bruijn",
+ "de Bruin",
+ "van der Heijden",
+ "Schouten",
+ "van Beek",
+ "Willems",
+ "van Vliet",
+ "van de Ven",
+ "Hoekstra",
+ "Maas",
+ "Verhoeven",
+ "Koster",
+ "van Dam",
+ "van der Wal",
+ "Prins",
+ "Blom",
+ "Huisman",
+ "Peeters",
+ "Kuipers",
+ "van Veen",
+ "van Dongen",
+ "Veenstra",
+ "Kramer",
+ "van den Bosch",
+ "van der Meulen",
+ "Mol",
+ "Zwart",
+ "van der Laan",
+ "Martens",
+ "van de Pol",
+ "Postma",
+ "Tromp",
+ "Borst",
+ "Boon",
+ "van Doorn",
+ "Jonker",
+ "van der Velden",
+ "Willemsen",
+ "van Wijk",
+ "Groen",
+ "Gerritsen",
+ "Bosch",
+ "van Loon",
+ "van der Ploeg",
+ "de Ruiter",
+ "Molenaar",
+ "Boer",
+ "Klein",
+ "de Koning",
+ "van de Kamp",
+ "van der Horst",
+ "Verbeek",
+ "Vink",
+ "Goossens",
+ "Scholten",
+ "Hartman",
+ "van Dalen",
+ "van Elst",
+ "Brink",
+ "Boekel",
+ "van de Berg",
+ "Berends",
+ "van der Hoek",
+ "Kuiper",
+ "Kooijman",
+ "de Lange",
+ "van der Sluis",
+ "van Gelder",
+ "Martens",
+ "van Asselt",
+ "Timmermans",
+ "van Vliet",
+ "van Rijn",
+ "van Schaik",
+ "Bosman",
+ "Wolters",
+ "van Hout",
+ "Hermans",
+ "van Rooij",
+ "de Vos",
+ "van Donselaar",
+ "Evers",
+ "van den Brink",
+ "Verkerk",
+ "Groeneveld",
+ "van Duijn",
+ "Schuurman",
+ "Hoogendoorn",
+ "van Zanten",
+ "Koopman",
+ "Cornelissen",
+ "van Driel",
+ "Teunissen",
+ "Versteeg",
+ "van Deursen",
+ "Schipper",
+ "van Kempen",
+ "Bouwman",
+ "van der Valk",
+ "Nijhuis",
+ "van der Werf",
+ "van den Akker",
+ "Verhoef",
+ "Wessels",
+ "van der Poel",
+ "Driessen",
+ "van Oosten",
+ "Lambrechts",
+ "van der Vlist",
+ "Hoogeveen",
+ "van Gils",
+ "Rietveld",
+ "Barendrecht",
+ "van der Spek",
+ "Stam",
+ "van der Linde",
+ "Boersma",
+ "van Dijk",
+ "Schepers",
+ "van der Kolk",
+ "Roelofs",
+ "van der Velden",
+ "van den Burg",
+ "Westra",
+ "van der Steen",
+ "Pronk",
+ "van der Veer",
+ "Rozendaal",
+ "van den Bos",
+ "Konings",
+ "van der Wiel",
+ "Noordam",
+ "van der Laan",
+ "Schut",
+ "van der Vlugt",
+ "Witteveen",
+ "van der Zwan",
+ "Boogaard",
+ "van der Waal",
+ "Stolk",
+ "van der Windt",
+ "Rutten",
+ "van der Zanden",
+ "Spaans",
+ "van der Zwaan",
+ "Roos",
+ "van der Zijl",
+ "Schoenmaker",
+ "van Diepen",
+ "Romeijn",
+ "van Doesburg",
+ "Schippers",
+ "van Eck",
+ "Rijken",
+ "van Egmond",
+ "Schrama",
+ "van Eijk",
+ "Ruijter",
+ "van Engelen",
+ "Sanders",
+ "van Es",
+ "Schenk",
+ "van Essen",
+ "van Gaal",
+ "van Geenen",
+ "van Gent",
+ "van Gestel",
+ "van Gool",
+ "van Grinsven",
+ "van Gurp",
+ "van Haaften",
+ "van Haren",
+ "van Hattem",
+ "van Hees"
+];
+
+// src/implementations/IdentityGeneratorNl.ts
+var IdentityGeneratorNl = class extends BaseIdentityGenerator {
+ /**
+ * Get the male first names.
+ */
+ getFirstNamesMaleJson() {
+ return firstnames_male_default2;
+ }
+ /**
+ * Get the female first names.
+ */
+ getFirstNamesFemaleJson() {
+ return firstnames_female_default2;
+ }
+ /**
+ * Get the last names.
+ */
+ getLastNamesJson() {
+ return lastnames_default2;
+ }
+};
+
+// src/utils/IdentityHelperUtils.ts
+var IdentityHelperUtils = class {
+ /**
+ * Normalize a birth date for display.
+ */
+ static normalizeBirthDateForDisplay(birthDate) {
+ if (!birthDate || birthDate.startsWith("0001-01-01")) {
+ return "";
+ }
+ return birthDate.split(/[T ]/)[0];
+ }
+ /**
+ * Normalize a birth date for database.
+ */
+ static normalizeBirthDateForDb(input) {
+ if (!input || input.trim() === "") {
+ return "0001-01-01T00:00:00.000Z";
+ }
+ const trimmed = input.trim().replace(" ", "T");
+ const match = trimmed.match(/^(\d{4})-(\d{2})-(\d{2})[T ]?(\d{2}):?(\d{2}):?(\d{2})?$/);
+ if (match) {
+ const [_, y, m, d, h = "00", mi = "00", s = "00"] = match;
+ return `${y}-${m}-${d}T${h}:${mi}:${s}.000Z`;
+ }
+ const parsedDate = new Date(trimmed);
+ if (!isNaN(parsedDate.getTime())) {
+ return parsedDate.toISOString();
+ }
+ return "0001-01-01T00:00:00.000Z";
+ }
+ /**
+ * Check if a birth date is valid.
+ */
+ static isValidBirthDate(input) {
+ if (!input || input.trim() === "") {
+ return false;
+ }
+ if (input.startsWith("0001-01-01")) {
+ return false;
+ }
+ const date = new Date(input);
+ if (isNaN(date.getTime())) {
+ return false;
+ }
+ const yearValid = date.getFullYear() > 1 && date.getFullYear() < 9999;
+ return yearValid;
+ }
+};
+
+// src/factories/IdentityGeneratorFactory.ts
+var createGenerator = (language) => {
+ switch (language) {
+ case "en":
+ return new IdentityGeneratorEn();
+ case "nl":
+ return new IdentityGeneratorNl();
+ }
+ throw new Error(`Unsupported language: ${language}`);
+};
+export {
+ BaseIdentityGenerator,
+ Gender,
+ IdentityGeneratorEn,
+ IdentityGeneratorNl,
+ IdentityHelperUtils,
+ UsernameEmailGenerator,
+ createGenerator
+};
+//# sourceMappingURL=index.mjs.map
\ No newline at end of file
diff --git a/apps/server/AliasVault.Client/wwwroot/js/shared/password-generator/README.md b/apps/server/AliasVault.Client/wwwroot/js/shared/password-generator/README.md
new file mode 100644
index 000000000..1124b2255
--- /dev/null
+++ b/apps/server/AliasVault.Client/wwwroot/js/shared/password-generator/README.md
@@ -0,0 +1,9 @@
+# ⚠️ Auto-Generated Files
+
+This folder contains the output of the shared `password-generator` module from the `/shared` directory in the AliasVault project.
+
+**Do not edit any of these files manually.**
+
+To make changes:
+1. Update the source files in `packages/password-generator/src`
+2. Run the `build-and-distribute.sh` script at the root of the project to regenerate the outputs and copy them here.
diff --git a/apps/server/AliasVault.Client/wwwroot/js/shared/password-generator/index.d.ts b/apps/server/AliasVault.Client/wwwroot/js/shared/password-generator/index.d.ts
new file mode 100644
index 000000000..373c840bf
--- /dev/null
+++ b/apps/server/AliasVault.Client/wwwroot/js/shared/password-generator/index.d.ts
@@ -0,0 +1,119 @@
+/**
+ * Settings for password generation stored in SQLite database settings table as string.
+ */
+type PasswordSettings = {
+ /**
+ * The length of the password.
+ */
+ Length: number;
+ /**
+ * Whether to use lowercase letters.
+ */
+ UseLowercase: boolean;
+ /**
+ * Whether to use uppercase letters.
+ */
+ UseUppercase: boolean;
+ /**
+ * Whether to use numbers.
+ */
+ UseNumbers: boolean;
+ /**
+ * Whether to use special characters.
+ */
+ UseSpecialChars: boolean;
+ /**
+ * Whether to use non-ambiguous characters.
+ */
+ UseNonAmbiguousChars: boolean;
+};
+
+/**
+ * Generate a random password.
+ */
+declare class PasswordGenerator {
+ private readonly lowercaseChars;
+ private readonly uppercaseChars;
+ private readonly numberChars;
+ private readonly specialChars;
+ private readonly ambiguousChars;
+ private length;
+ private useLowercase;
+ private useUppercase;
+ private useNumbers;
+ private useSpecial;
+ private useNonAmbiguous;
+ /**
+ * Create a new instance of PasswordGenerator.
+ * @param settings Optional password settings to initialize with.
+ */
+ constructor(settings?: PasswordSettings);
+ /**
+ * Apply password settings to this generator.
+ */
+ applySettings(settings: PasswordSettings): this;
+ /**
+ * Set the length of the password.
+ */
+ setLength(length: number): this;
+ /**
+ * Set if lowercase letters should be used.
+ */
+ useLowercaseLetters(use: boolean): this;
+ /**
+ * Set if uppercase letters should be used.
+ */
+ useUppercaseLetters(use: boolean): this;
+ /**
+ * Set if numeric characters should be used.
+ */
+ useNumericCharacters(use: boolean): this;
+ /**
+ * Set if special characters should be used.
+ */
+ useSpecialCharacters(use: boolean): this;
+ /**
+ * Set if only non-ambiguous characters should be used.
+ */
+ useNonAmbiguousCharacters(use: boolean): this;
+ /**
+ * Get a random index from the crypto module.
+ */
+ private getUnbiasedRandomIndex;
+ /**
+ * Generate a random password.
+ */
+ generateRandomPassword(): string;
+ /**
+ * Build character set based on selected options.
+ */
+ private buildCharacterSet;
+ /**
+ * Remove ambiguous characters from a character set.
+ */
+ private removeAmbiguousCharacters;
+ /**
+ * Generate initial random password.
+ */
+ private generateInitialPassword;
+ /**
+ * Ensure the generated password meets all specified requirements.
+ */
+ private ensureRequirements;
+ /**
+ * Get a character set with ambiguous characters removed if needed.
+ */
+ private getSafeCharacterSet;
+ /**
+ * Add a character from the given set at a random position in the password.
+ */
+ private addCharacterFromSet;
+}
+
+/**
+ * Creates a new password generator.
+ * @returns A new password generator instance.
+ */
+declare const createPasswordGenerator: () => PasswordGenerator;
+
+export { PasswordGenerator, type PasswordSettings, createPasswordGenerator };
diff --git a/apps/server/AliasVault.Client/wwwroot/js/shared/password-generator/index.js b/apps/server/AliasVault.Client/wwwroot/js/shared/password-generator/index.js
new file mode 100644
index 000000000..f155250ad
--- /dev/null
+++ b/apps/server/AliasVault.Client/wwwroot/js/shared/password-generator/index.js
@@ -0,0 +1,244 @@
+"use strict";
+var __defProp = Object.defineProperty;
+var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
+var __getOwnPropNames = Object.getOwnPropertyNames;
+var __hasOwnProp = Object.prototype.hasOwnProperty;
+var __export = (target, all) => {
+ for (var name in all)
+ __defProp(target, name, { get: all[name], enumerable: true });
+};
+var __copyProps = (to, from, except, desc) => {
+ if (from && typeof from === "object" || typeof from === "function") {
+ for (let key of __getOwnPropNames(from))
+ if (!__hasOwnProp.call(to, key) && key !== except)
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
+ }
+ return to;
+};
+var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
+
+// src/index.ts
+var index_exports = {};
+__export(index_exports, {
+ PasswordGenerator: () => PasswordGenerator,
+ createPasswordGenerator: () => createPasswordGenerator
+});
+module.exports = __toCommonJS(index_exports);
+
+// src/utils/PasswordGenerator.ts
+var PasswordGenerator = class {
+ /**
+ * Create a new instance of PasswordGenerator.
+ * @param settings Optional password settings to initialize with.
+ */
+ constructor(settings) {
+ this.lowercaseChars = "abcdefghijklmnopqrstuvwxyz";
+ this.uppercaseChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+ this.numberChars = "0123456789";
+ this.specialChars = "!@#$%^&*()_+-=[]{}|;:,.<>?";
+ this.ambiguousChars = "Il1O0";
+ this.length = 18;
+ this.useLowercase = true;
+ this.useUppercase = true;
+ this.useNumbers = true;
+ this.useSpecial = true;
+ this.useNonAmbiguous = false;
+ if (settings) {
+ this.applySettings(settings);
+ }
+ }
+ /**
+ * Apply password settings to this generator.
+ */
+ applySettings(settings) {
+ this.length = settings.Length;
+ this.useLowercase = settings.UseLowercase;
+ this.useUppercase = settings.UseUppercase;
+ this.useNumbers = settings.UseNumbers;
+ this.useSpecial = settings.UseSpecialChars;
+ this.useNonAmbiguous = settings.UseNonAmbiguousChars;
+ return this;
+ }
+ /**
+ * Set the length of the password.
+ */
+ setLength(length) {
+ this.length = length;
+ return this;
+ }
+ /**
+ * Set if lowercase letters should be used.
+ */
+ useLowercaseLetters(use) {
+ this.useLowercase = use;
+ return this;
+ }
+ /**
+ * Set if uppercase letters should be used.
+ */
+ useUppercaseLetters(use) {
+ this.useUppercase = use;
+ return this;
+ }
+ /**
+ * Set if numeric characters should be used.
+ */
+ useNumericCharacters(use) {
+ this.useNumbers = use;
+ return this;
+ }
+ /**
+ * Set if special characters should be used.
+ */
+ useSpecialCharacters(use) {
+ this.useSpecial = use;
+ return this;
+ }
+ /**
+ * Set if only non-ambiguous characters should be used.
+ */
+ useNonAmbiguousCharacters(use) {
+ this.useNonAmbiguous = use;
+ return this;
+ }
+ /**
+ * Get a random index from the crypto module.
+ */
+ getUnbiasedRandomIndex(max) {
+ const limit = Math.floor(2 ** 32 / max) * max;
+ while (true) {
+ const array = new Uint32Array(1);
+ crypto.getRandomValues(array);
+ const value = array[0];
+ if (value < limit) {
+ return value % max;
+ }
+ }
+ }
+ /**
+ * Generate a random password.
+ */
+ generateRandomPassword() {
+ const chars = this.buildCharacterSet();
+ let password = this.generateInitialPassword(chars);
+ password = this.ensureRequirements(password);
+ return password;
+ }
+ /**
+ * Build character set based on selected options.
+ */
+ buildCharacterSet() {
+ let chars = "";
+ if (this.useLowercase) {
+ chars += this.lowercaseChars;
+ }
+ if (this.useUppercase) {
+ chars += this.uppercaseChars;
+ }
+ if (this.useNumbers) {
+ chars += this.numberChars;
+ }
+ if (this.useSpecial) {
+ chars += this.specialChars;
+ }
+ if (chars.length === 0) {
+ chars = this.lowercaseChars;
+ }
+ if (this.useNonAmbiguous) {
+ chars = this.removeAmbiguousCharacters(chars);
+ }
+ return chars;
+ }
+ /**
+ * Remove ambiguous characters from a character set.
+ */
+ removeAmbiguousCharacters(chars) {
+ for (const ambChar of this.ambiguousChars) {
+ chars = chars.replace(ambChar, "");
+ }
+ return chars;
+ }
+ /**
+ * Generate initial random password.
+ */
+ generateInitialPassword(chars) {
+ let password = "";
+ for (let i = 0; i < this.length; i++) {
+ password += chars[this.getUnbiasedRandomIndex(chars.length)];
+ }
+ return password;
+ }
+ /**
+ * Ensure the generated password meets all specified requirements.
+ */
+ ensureRequirements(password) {
+ if (this.useLowercase && !/[a-z]/.exec(password)) {
+ password = this.addCharacterFromSet(
+ password,
+ this.getSafeCharacterSet(this.lowercaseChars, true)
+ );
+ }
+ if (this.useUppercase && !/[A-Z]/.exec(password)) {
+ password = this.addCharacterFromSet(
+ password,
+ this.getSafeCharacterSet(this.uppercaseChars, true)
+ );
+ }
+ if (this.useNumbers && !/\d/.exec(password)) {
+ password = this.addCharacterFromSet(
+ password,
+ this.getSafeCharacterSet(this.numberChars, false)
+ );
+ }
+ if (this.useSpecial && !/[!@#$%^&*()_+\-=[\]{}|;:,.<>?]/.exec(password)) {
+ password = this.addCharacterFromSet(
+ password,
+ this.specialChars
+ );
+ }
+ return password;
+ }
+ /**
+ * Get a character set with ambiguous characters removed if needed.
+ */
+ getSafeCharacterSet(charSet, isAlpha) {
+ if (!this.useNonAmbiguous) {
+ return charSet;
+ }
+ let safeSet = charSet;
+ for (const ambChar of this.ambiguousChars) {
+ if (!isAlpha && !/\d/.test(ambChar)) {
+ continue;
+ }
+ let charToRemove = ambChar;
+ if (isAlpha) {
+ if (charSet === this.lowercaseChars) {
+ charToRemove = ambChar.toLowerCase();
+ } else {
+ charToRemove = ambChar.toUpperCase();
+ }
+ }
+ safeSet = safeSet.replace(charToRemove, "");
+ }
+ return safeSet;
+ }
+ /**
+ * Add a character from the given set at a random position in the password.
+ */
+ addCharacterFromSet(password, charSet) {
+ const pos = this.getUnbiasedRandomIndex(this.length);
+ const char = charSet[this.getUnbiasedRandomIndex(charSet.length)];
+ return password.substring(0, pos) + char + password.substring(pos + 1);
+ }
+};
+
+// src/factories/PasswordGeneratorFactory.ts
+var createPasswordGenerator = () => {
+ return new PasswordGenerator();
+};
+// Annotate the CommonJS export names for ESM import in node:
+0 && (module.exports = {
+ PasswordGenerator,
+ createPasswordGenerator
+});
+//# sourceMappingURL=index.js.map
\ No newline at end of file
diff --git a/apps/server/AliasVault.Client/wwwroot/js/shared/password-generator/index.mjs b/apps/server/AliasVault.Client/wwwroot/js/shared/password-generator/index.mjs
new file mode 100644
index 000000000..8d845caa4
--- /dev/null
+++ b/apps/server/AliasVault.Client/wwwroot/js/shared/password-generator/index.mjs
@@ -0,0 +1,216 @@
+// src/utils/PasswordGenerator.ts
+var PasswordGenerator = class {
+ /**
+ * Create a new instance of PasswordGenerator.
+ * @param settings Optional password settings to initialize with.
+ */
+ constructor(settings) {
+ this.lowercaseChars = "abcdefghijklmnopqrstuvwxyz";
+ this.uppercaseChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+ this.numberChars = "0123456789";
+ this.specialChars = "!@#$%^&*()_+-=[]{}|;:,.<>?";
+ this.ambiguousChars = "Il1O0";
+ this.length = 18;
+ this.useLowercase = true;
+ this.useUppercase = true;
+ this.useNumbers = true;
+ this.useSpecial = true;
+ this.useNonAmbiguous = false;
+ if (settings) {
+ this.applySettings(settings);
+ }
+ }
+ /**
+ * Apply password settings to this generator.
+ */
+ applySettings(settings) {
+ this.length = settings.Length;
+ this.useLowercase = settings.UseLowercase;
+ this.useUppercase = settings.UseUppercase;
+ this.useNumbers = settings.UseNumbers;
+ this.useSpecial = settings.UseSpecialChars;
+ this.useNonAmbiguous = settings.UseNonAmbiguousChars;
+ return this;
+ }
+ /**
+ * Set the length of the password.
+ */
+ setLength(length) {
+ this.length = length;
+ return this;
+ }
+ /**
+ * Set if lowercase letters should be used.
+ */
+ useLowercaseLetters(use) {
+ this.useLowercase = use;
+ return this;
+ }
+ /**
+ * Set if uppercase letters should be used.
+ */
+ useUppercaseLetters(use) {
+ this.useUppercase = use;
+ return this;
+ }
+ /**
+ * Set if numeric characters should be used.
+ */
+ useNumericCharacters(use) {
+ this.useNumbers = use;
+ return this;
+ }
+ /**
+ * Set if special characters should be used.
+ */
+ useSpecialCharacters(use) {
+ this.useSpecial = use;
+ return this;
+ }
+ /**
+ * Set if only non-ambiguous characters should be used.
+ */
+ useNonAmbiguousCharacters(use) {
+ this.useNonAmbiguous = use;
+ return this;
+ }
+ /**
+ * Get a random index from the crypto module.
+ */
+ getUnbiasedRandomIndex(max) {
+ const limit = Math.floor(2 ** 32 / max) * max;
+ while (true) {
+ const array = new Uint32Array(1);
+ crypto.getRandomValues(array);
+ const value = array[0];
+ if (value < limit) {
+ return value % max;
+ }
+ }
+ }
+ /**
+ * Generate a random password.
+ */
+ generateRandomPassword() {
+ const chars = this.buildCharacterSet();
+ let password = this.generateInitialPassword(chars);
+ password = this.ensureRequirements(password);
+ return password;
+ }
+ /**
+ * Build character set based on selected options.
+ */
+ buildCharacterSet() {
+ let chars = "";
+ if (this.useLowercase) {
+ chars += this.lowercaseChars;
+ }
+ if (this.useUppercase) {
+ chars += this.uppercaseChars;
+ }
+ if (this.useNumbers) {
+ chars += this.numberChars;
+ }
+ if (this.useSpecial) {
+ chars += this.specialChars;
+ }
+ if (chars.length === 0) {
+ chars = this.lowercaseChars;
+ }
+ if (this.useNonAmbiguous) {
+ chars = this.removeAmbiguousCharacters(chars);
+ }
+ return chars;
+ }
+ /**
+ * Remove ambiguous characters from a character set.
+ */
+ removeAmbiguousCharacters(chars) {
+ for (const ambChar of this.ambiguousChars) {
+ chars = chars.replace(ambChar, "");
+ }
+ return chars;
+ }
+ /**
+ * Generate initial random password.
+ */
+ generateInitialPassword(chars) {
+ let password = "";
+ for (let i = 0; i < this.length; i++) {
+ password += chars[this.getUnbiasedRandomIndex(chars.length)];
+ }
+ return password;
+ }
+ /**
+ * Ensure the generated password meets all specified requirements.
+ */
+ ensureRequirements(password) {
+ if (this.useLowercase && !/[a-z]/.exec(password)) {
+ password = this.addCharacterFromSet(
+ password,
+ this.getSafeCharacterSet(this.lowercaseChars, true)
+ );
+ }
+ if (this.useUppercase && !/[A-Z]/.exec(password)) {
+ password = this.addCharacterFromSet(
+ password,
+ this.getSafeCharacterSet(this.uppercaseChars, true)
+ );
+ }
+ if (this.useNumbers && !/\d/.exec(password)) {
+ password = this.addCharacterFromSet(
+ password,
+ this.getSafeCharacterSet(this.numberChars, false)
+ );
+ }
+ if (this.useSpecial && !/[!@#$%^&*()_+\-=[\]{}|;:,.<>?]/.exec(password)) {
+ password = this.addCharacterFromSet(
+ password,
+ this.specialChars
+ );
+ }
+ return password;
+ }
+ /**
+ * Get a character set with ambiguous characters removed if needed.
+ */
+ getSafeCharacterSet(charSet, isAlpha) {
+ if (!this.useNonAmbiguous) {
+ return charSet;
+ }
+ let safeSet = charSet;
+ for (const ambChar of this.ambiguousChars) {
+ if (!isAlpha && !/\d/.test(ambChar)) {
+ continue;
+ }
+ let charToRemove = ambChar;
+ if (isAlpha) {
+ if (charSet === this.lowercaseChars) {
+ charToRemove = ambChar.toLowerCase();
+ } else {
+ charToRemove = ambChar.toUpperCase();
+ }
+ }
+ safeSet = safeSet.replace(charToRemove, "");
+ }
+ return safeSet;
+ }
+ /**
+ * Add a character from the given set at a random position in the password.
+ */
+ addCharacterFromSet(password, charSet) {
+ const pos = this.getUnbiasedRandomIndex(this.length);
+ const char = charSet[this.getUnbiasedRandomIndex(charSet.length)];
+ return password.substring(0, pos) + char + password.substring(pos + 1);
+ }
+};
+
+// src/factories/PasswordGeneratorFactory.ts
+var createPasswordGenerator = () => {
+ return new PasswordGenerator();
+};
+export {
+ PasswordGenerator,
+ createPasswordGenerator
+};
+//# sourceMappingURL=index.mjs.map
\ No newline at end of file