From 33d33bdd17734c24a0a930af37119da40078fbca Mon Sep 17 00:00:00 2001 From: Leendert de Borst Date: Fri, 26 Jun 2026 16:53:53 +0200 Subject: [PATCH] Remove TS password generator from web app (#776) --- .../Services/JsInterop/JsInteropService.cs | 34 --- .../js/dist/core/password-generator/README.md | 9 - .../dist/core/password-generator/index.d.ts | 134 ---------- .../js/dist/core/password-generator/index.js | 245 ------------------ .../js/dist/core/password-generator/index.mjs | 218 ---------------- core/typescript/password-generator/build.sh | 1 - 6 files changed, 641 deletions(-) delete mode 100644 apps/server/AliasVault.Client/wwwroot/js/dist/core/password-generator/README.md delete mode 100644 apps/server/AliasVault.Client/wwwroot/js/dist/core/password-generator/index.d.ts delete mode 100644 apps/server/AliasVault.Client/wwwroot/js/dist/core/password-generator/index.js delete mode 100644 apps/server/AliasVault.Client/wwwroot/js/dist/core/password-generator/index.mjs diff --git a/apps/server/AliasVault.Client/Services/JsInterop/JsInteropService.cs b/apps/server/AliasVault.Client/Services/JsInterop/JsInteropService.cs index 53ed88e78..3511a15c7 100644 --- a/apps/server/AliasVault.Client/Services/JsInterop/JsInteropService.cs +++ b/apps/server/AliasVault.Client/Services/JsInterop/JsInteropService.cs @@ -26,7 +26,6 @@ public sealed class JsInteropService(IJSRuntime jsRuntime) private readonly string _cacheBuster = AppInfo.GetFullVersion(); private IJSObjectReference? _identityGeneratorModule; - private IJSObjectReference? _passwordGeneratorModule; private IJSObjectReference? _vaultSqlInteropModule; /// @@ -41,12 +40,6 @@ public sealed class JsInteropService(IJSRuntime jsRuntime) throw new InvalidOperationException("Failed to initialize identity generator module"); } - _passwordGeneratorModule = await jsRuntime.InvokeAsync("import", $"./js/dist/core/password-generator/index.mjs?v={_cacheBuster}"); - if (_passwordGeneratorModule == null) - { - throw new InvalidOperationException("Failed to initialize password generator module"); - } - _vaultSqlInteropModule = await jsRuntime.InvokeAsync("import", $"./js/dist/core/vault/index.mjs?v={_cacheBuster}"); if (_vaultSqlInteropModule == null) { @@ -642,33 +635,6 @@ public sealed class JsInteropService(IJSRuntime jsRuntime) } } - /// - /// 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(); - } - - 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); - } - } - /// /// Gets SQL commands to create a new vault with the latest schema. /// diff --git a/apps/server/AliasVault.Client/wwwroot/js/dist/core/password-generator/README.md b/apps/server/AliasVault.Client/wwwroot/js/dist/core/password-generator/README.md deleted file mode 100644 index ed0527c64..000000000 --- a/apps/server/AliasVault.Client/wwwroot/js/dist/core/password-generator/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# ⚠️ Auto-Generated Files - -This folder contains the output of the core `password-generator` module from the `/core` directory in the AliasVault project. - -**Do not edit any of these files manually.** - -To make changes: -1. Update the source files in the `/core/typescript/password-generator/src` directory -2. Run the `build.sh` script in the module directory to regenerate the outputs and copy them here. diff --git a/apps/server/AliasVault.Client/wwwroot/js/dist/core/password-generator/index.d.ts b/apps/server/AliasVault.Client/wwwroot/js/dist/core/password-generator/index.d.ts deleted file mode 100644 index ebfe93c7b..000000000 --- a/apps/server/AliasVault.Client/wwwroot/js/dist/core/password-generator/index.d.ts +++ /dev/null @@ -1,134 +0,0 @@ -/** - * 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; - /** - * Ambiguous characters that look similar and are easy to confuse when typing: - * - I, l, 1, | (pipe) - all look like vertical lines - * - O, 0, o - all look like circles - * - Z, 2 - similar appearance - * - S, 5 - similar appearance - * - B, 8 - similar appearance - * - G, 6 - similar appearance - * - Brackets, braces, parentheses: [], {}, () - * - Quotes: ', ", ` - * - Punctuation pairs: ;:, ., - * - Dashes: -, _ - * - Angle brackets: <> - */ - 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. - * @param settings - The settings for the password generator. - * @returns A new password generator instance. - */ -declare const CreatePasswordGenerator: (settings: PasswordSettings) => PasswordGenerator; - -export { CreatePasswordGenerator, PasswordGenerator, type PasswordSettings }; diff --git a/apps/server/AliasVault.Client/wwwroot/js/dist/core/password-generator/index.js b/apps/server/AliasVault.Client/wwwroot/js/dist/core/password-generator/index.js deleted file mode 100644 index 757060daa..000000000 --- a/apps/server/AliasVault.Client/wwwroot/js/dist/core/password-generator/index.js +++ /dev/null @@ -1,245 +0,0 @@ -// -// This file was automatically generated. Do not edit manually. - -"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, { - CreatePasswordGenerator: () => CreatePasswordGenerator, - PasswordGenerator: () => PasswordGenerator -}); -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 = "!@#$%^&*()_+-=[]{}|;:,.<>?"; - /** - * Ambiguous characters that look similar and are easy to confuse when typing: - * - I, l, 1, | (pipe) - all look like vertical lines - * - O, 0, o - all look like circles - * - Z, 2 - similar appearance - * - S, 5 - similar appearance - * - B, 8 - similar appearance - * - G, 6 - similar appearance - * - Brackets, braces, parentheses: [], {}, () - * - Quotes: ', ", ` - * - Punctuation pairs: ;:, ., - * - Dashes: -, _ - * - Angle brackets: <> - */ - this.ambiguousChars = "Il1O0oZzSsBbGg2568|[]{}()<>;:,.`'\"_-"; - 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) - ); - } - if (this.useUppercase && !/[A-Z]/.exec(password)) { - password = this.addCharacterFromSet( - password, - this.getSafeCharacterSet(this.uppercaseChars) - ); - } - if (this.useNumbers && !/\d/.exec(password)) { - password = this.addCharacterFromSet( - password, - this.getSafeCharacterSet(this.numberChars) - ); - } - if (this.useSpecial && !/[!@#$%^&*()_+\-=[\]{}|;:,.<>?]/.exec(password)) { - password = this.addCharacterFromSet( - password, - this.getSafeCharacterSet(this.specialChars) - ); - } - return password; - } - /** - * Get a character set with ambiguous characters removed if needed. - */ - getSafeCharacterSet(charSet) { - if (!this.useNonAmbiguous) { - return charSet; - } - return this.removeAmbiguousCharacters(charSet); - } - /** - * 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 = (settings) => { - return new PasswordGenerator(settings); -}; -// Annotate the CommonJS export names for ESM import in node: -0 && (module.exports = { - CreatePasswordGenerator, - PasswordGenerator -}); diff --git a/apps/server/AliasVault.Client/wwwroot/js/dist/core/password-generator/index.mjs b/apps/server/AliasVault.Client/wwwroot/js/dist/core/password-generator/index.mjs deleted file mode 100644 index 60016fcf9..000000000 --- a/apps/server/AliasVault.Client/wwwroot/js/dist/core/password-generator/index.mjs +++ /dev/null @@ -1,218 +0,0 @@ -// -// This file was automatically generated. Do not edit manually. - - -// 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 = "!@#$%^&*()_+-=[]{}|;:,.<>?"; - /** - * Ambiguous characters that look similar and are easy to confuse when typing: - * - I, l, 1, | (pipe) - all look like vertical lines - * - O, 0, o - all look like circles - * - Z, 2 - similar appearance - * - S, 5 - similar appearance - * - B, 8 - similar appearance - * - G, 6 - similar appearance - * - Brackets, braces, parentheses: [], {}, () - * - Quotes: ', ", ` - * - Punctuation pairs: ;:, ., - * - Dashes: -, _ - * - Angle brackets: <> - */ - this.ambiguousChars = "Il1O0oZzSsBbGg2568|[]{}()<>;:,.`'\"_-"; - 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) - ); - } - if (this.useUppercase && !/[A-Z]/.exec(password)) { - password = this.addCharacterFromSet( - password, - this.getSafeCharacterSet(this.uppercaseChars) - ); - } - if (this.useNumbers && !/\d/.exec(password)) { - password = this.addCharacterFromSet( - password, - this.getSafeCharacterSet(this.numberChars) - ); - } - if (this.useSpecial && !/[!@#$%^&*()_+\-=[\]{}|;:,.<>?]/.exec(password)) { - password = this.addCharacterFromSet( - password, - this.getSafeCharacterSet(this.specialChars) - ); - } - return password; - } - /** - * Get a character set with ambiguous characters removed if needed. - */ - getSafeCharacterSet(charSet) { - if (!this.useNonAmbiguous) { - return charSet; - } - return this.removeAmbiguousCharacters(charSet); - } - /** - * 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 = (settings) => { - return new PasswordGenerator(settings); -}; -export { - CreatePasswordGenerator, - PasswordGenerator -}; diff --git a/core/typescript/password-generator/build.sh b/core/typescript/password-generator/build.sh index 34f589d64..db5254e1f 100755 --- a/core/typescript/password-generator/build.sh +++ b/core/typescript/password-generator/build.sh @@ -6,7 +6,6 @@ set -u # Treat unset variables as errors # Define output targets for password-generator TARGETS=( "../../../apps/mobile-app/utils/dist/core/password-generator" - "../../../apps/server/AliasVault.Client/wwwroot/js/dist/core/password-generator" ) # Build and distribute password-generator