{"version":3,"file":"SecurityUtils.mjs","sources":["../src/SecurityUtils.ts"],"sourcesContent":["/**\n * @module SecurityUtils\n * @description A collection of utility functions for security operations including hashing, encryption, and validation.\n * @example\n * ```typescript\n * import { SecurityUtils } from 'houser-js-utils';\n *\n * // Generate secure hash\n * const hash = await SecurityUtils.hashString('password123');\n *\n * // Generate random token\n * const token = SecurityUtils.generateRandomToken(32);\n *\n * // Sanitize user input\n * const clean = SecurityUtils.sanitizeInput('<script>alert(\"xss\")</script>');\n * ```\n */\n\nexport const SecurityUtils = {\n  /**\n   * Decrypts a string using AES-GCM\n   * @param encryptedData - Data to decrypt\n   * @param key - Decryption key\n   * @returns Decrypted data\n   */\n  async decrypt(encryptedData: string, key: string): Promise<string> {\n    const decoder = new TextDecoder();\n    const keyBuffer = new TextEncoder().encode(key);\n\n    const cryptoKey = await crypto.subtle.importKey(\n      \"raw\",\n      keyBuffer,\n      { name: \"AES-GCM\" },\n      false,\n      [\"decrypt\"]\n    );\n\n    const data = Uint8Array.from(atob(encryptedData), (c) => c.charCodeAt(0));\n    const iv = data.slice(0, 12);\n    const encrypted = data.slice(12);\n\n    const decrypted = await crypto.subtle.decrypt(\n      { name: \"AES-GCM\", iv },\n      cryptoKey,\n      encrypted\n    );\n\n    return decoder.decode(decrypted);\n  },\n\n  /**\n   * Encrypts a string using AES-GCM\n   * @param data - Data to encrypt\n   * @param key - Encryption key\n   * @returns Encrypted data\n   */\n  async encrypt(data: string, key: string): Promise<string> {\n    const encoder = new TextEncoder();\n    const dataBuffer = encoder.encode(data);\n    const keyBuffer = encoder.encode(key);\n\n    const cryptoKey = await crypto.subtle.importKey(\n      \"raw\",\n      keyBuffer,\n      { name: \"AES-GCM\" },\n      false,\n      [\"encrypt\"]\n    );\n\n    const iv = crypto.getRandomValues(new Uint8Array(12));\n    const encrypted = await crypto.subtle.encrypt(\n      { name: \"AES-GCM\", iv },\n      cryptoKey,\n      dataBuffer\n    );\n\n    const result = new Uint8Array(iv.length + encrypted.byteLength);\n    result.set(iv);\n    result.set(new Uint8Array(encrypted), iv.length);\n\n    return btoa(String.fromCharCode(...result));\n  },\n\n  /**\n   * Generates a CSRF token\n   * @returns CSRF token\n   */\n  async generateCsrfToken(): Promise<string> {\n    return this.generateRandomString(32);\n  },\n\n  /**\n   * Generates a random number between min and max\n   * @param min - Minimum value (inclusive)\n   * @param max - Maximum value (inclusive)\n   * @returns Random number\n   */\n  async generateRandomNumber(min: number, max: number): Promise<number> {\n    const range = max - min + 1;\n    const bytesNeeded = Math.ceil(Math.log2(range) / 8);\n    const maxNum = Math.pow(256, bytesNeeded);\n    const maxRange = maxNum - (maxNum % range);\n\n    let value;\n    do {\n      const buffer = new Uint8Array(bytesNeeded);\n      crypto.getRandomValues(buffer);\n      value = buffer.reduce((acc, byte) => (acc << 8) + byte, 0);\n    } while (value >= maxRange);\n\n    return min + (value % range);\n  },\n\n  /**\n   * Generates a random string of specified length\n   * @param length - Length of the random string\n   * @returns Random string\n   */\n  async generateRandomString(length: number): Promise<string> {\n    const chars =\n      \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\";\n    let result = \"\";\n    const array = new Uint32Array(length);\n    crypto.getRandomValues(array);\n    for (let i = 0; i < length; i++) {\n      result += chars[array[i] % chars.length];\n    }\n    return result;\n  },\n\n  /**\n   * Generates a secure password\n   * @param length - Length of the password\n   * @returns Generated password\n   */\n  async generateSecurePassword(length = 16): Promise<string> {\n    const upperChars = \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\";\n    const lowerChars = \"abcdefghijklmnopqrstuvwxyz\";\n    const numberChars = \"0123456789\";\n    const specialChars = '!@#$%^&*(),.?\":{}|<>';\n    const allChars = upperChars + lowerChars + numberChars + specialChars;\n\n    let password = \"\";\n    password +=\n      upperChars[await this.generateRandomNumber(0, upperChars.length - 1)];\n    password +=\n      lowerChars[await this.generateRandomNumber(0, lowerChars.length - 1)];\n    password +=\n      numberChars[await this.generateRandomNumber(0, numberChars.length - 1)];\n    password +=\n      specialChars[await this.generateRandomNumber(0, specialChars.length - 1)];\n\n    for (let i = password.length; i < length; i++) {\n      password +=\n        allChars[await this.generateRandomNumber(0, allChars.length - 1)];\n    }\n\n    return password\n      .split(\"\")\n      .sort(() => Math.random() - 0.5)\n      .join(\"\");\n  },\n\n  /**\n   * Hashes a string using SHA-256\n   * @param input - String to hash\n   * @returns Hashed string\n   */\n  async hashString(input: string): Promise<string> {\n    const encoder = new TextEncoder();\n    const data = encoder.encode(input);\n    const hash = await crypto.subtle.digest(\"SHA-256\", data);\n    return Array.from(new Uint8Array(hash))\n      .map((b) => b.toString(16).padStart(2, \"0\"))\n      .join(\"\");\n  },\n\n  /**\n   * Sanitizes HTML input to prevent XSS attacks\n   * @param input - Input string to sanitize\n   * @returns Sanitized string\n   */\n  sanitizeHtml: (input: string): string => {\n    return input\n      .replace(/&/g, \"&amp;\")\n      .replace(/</g, \"&lt;\")\n      .replace(/>/g, \"&gt;\")\n      .replace(/\"/g, \"&quot;\")\n      .replace(/'/g, \"&#039;\");\n  },\n\n  /**\n   * Validates a CSRF token\n   * @param token - Token to validate\n   * @param storedToken - Stored token to compare against\n   * @returns True if tokens match\n   */\n  validateCsrfToken: (token: string, storedToken: string): boolean => {\n    return token === storedToken;\n  },\n\n  /**\n   * Checks if a password meets security requirements\n   * @param password - Password to check\n   * @returns Object containing validation results\n   */\n  validatePassword: (password: string) => {\n    const minLength = 8;\n    const hasUpperCase = /[A-Z]/.test(password);\n    const hasLowerCase = /[a-z]/.test(password);\n    const hasNumbers = /\\d/.test(password);\n    const hasSpecialChar = /[!@#$%^&*(),.?\":{}|<>]/.test(password);\n    const isLongEnough = password.length >= minLength;\n\n    return {\n      isValid:\n        isLongEnough &&\n        hasUpperCase &&\n        hasLowerCase &&\n        hasNumbers &&\n        hasSpecialChar,\n      requirements: {\n        minLength: isLongEnough,\n        hasUpperCase,\n        hasLowerCase,\n        hasNumbers,\n        hasSpecialChar,\n      },\n    };\n  },\n};\n"],"names":[],"mappings":"AAkBO,MAAM,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAO3B,MAAM,QAAQ,eAAuB,KAA8B;AACjE,UAAM,UAAU,IAAI,YAAA;AACpB,UAAM,YAAY,IAAI,cAAc,OAAO,GAAG;AAE9C,UAAM,YAAY,MAAM,OAAO,OAAO;AAAA,MACpC;AAAA,MACA;AAAA,MACA,EAAE,MAAM,UAAA;AAAA,MACR;AAAA,MACA,CAAC,SAAS;AAAA,IAAA;AAGZ,UAAM,OAAO,WAAW,KAAK,KAAK,aAAa,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;AACxE,UAAM,KAAK,KAAK,MAAM,GAAG,EAAE;AAC3B,UAAM,YAAY,KAAK,MAAM,EAAE;AAE/B,UAAM,YAAY,MAAM,OAAO,OAAO;AAAA,MACpC,EAAE,MAAM,WAAW,GAAA;AAAA,MACnB;AAAA,MACA;AAAA,IAAA;AAGF,WAAO,QAAQ,OAAO,SAAS;AAAA,EACjC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,QAAQ,MAAc,KAA8B;AACxD,UAAM,UAAU,IAAI,YAAA;AACpB,UAAM,aAAa,QAAQ,OAAO,IAAI;AACtC,UAAM,YAAY,QAAQ,OAAO,GAAG;AAEpC,UAAM,YAAY,MAAM,OAAO,OAAO;AAAA,MACpC;AAAA,MACA;AAAA,MACA,EAAE,MAAM,UAAA;AAAA,MACR;AAAA,MACA,CAAC,SAAS;AAAA,IAAA;AAGZ,UAAM,KAAK,OAAO,gBAAgB,IAAI,WAAW,EAAE,CAAC;AACpD,UAAM,YAAY,MAAM,OAAO,OAAO;AAAA,MACpC,EAAE,MAAM,WAAW,GAAA;AAAA,MACnB;AAAA,MACA;AAAA,IAAA;AAGF,UAAM,SAAS,IAAI,WAAW,GAAG,SAAS,UAAU,UAAU;AAC9D,WAAO,IAAI,EAAE;AACb,WAAO,IAAI,IAAI,WAAW,SAAS,GAAG,GAAG,MAAM;AAE/C,WAAO,KAAK,OAAO,aAAa,GAAG,MAAM,CAAC;AAAA,EAC5C;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,oBAAqC;AACzC,WAAO,KAAK,qBAAqB,EAAE;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,qBAAqB,KAAa,KAA8B;AACpE,UAAM,QAAQ,MAAM,MAAM;AAC1B,UAAM,cAAc,KAAK,KAAK,KAAK,KAAK,KAAK,IAAI,CAAC;AAClD,UAAM,SAAS,KAAK,IAAI,KAAK,WAAW;AACxC,UAAM,WAAW,SAAU,SAAS;AAEpC,QAAI;AACJ,OAAG;AACD,YAAM,SAAS,IAAI,WAAW,WAAW;AACzC,aAAO,gBAAgB,MAAM;AAC7B,cAAQ,OAAO,OAAO,CAAC,KAAK,UAAU,OAAO,KAAK,MAAM,CAAC;AAAA,IAC3D,SAAS,SAAS;AAElB,WAAO,MAAO,QAAQ;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,qBAAqB,QAAiC;AAC1D,UAAM,QACJ;AACF,QAAI,SAAS;AACb,UAAM,QAAQ,IAAI,YAAY,MAAM;AACpC,WAAO,gBAAgB,KAAK;AAC5B,aAAS,IAAI,GAAG,IAAI,QAAQ,KAAK;AAC/B,gBAAU,MAAM,MAAM,CAAC,IAAI,MAAM,MAAM;AAAA,IACzC;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,uBAAuB,SAAS,IAAqB;AACzD,UAAM,aAAa;AACnB,UAAM,aAAa;AACnB,UAAM,cAAc;AACpB,UAAM,eAAe;AACrB,UAAM,WAAW,aAAa,aAAa,cAAc;AAEzD,QAAI,WAAW;AACf,gBACE,WAAW,MAAM,KAAK,qBAAqB,GAAG,WAAW,SAAS,CAAC,CAAC;AACtE,gBACE,WAAW,MAAM,KAAK,qBAAqB,GAAG,WAAW,SAAS,CAAC,CAAC;AACtE,gBACE,YAAY,MAAM,KAAK,qBAAqB,GAAG,YAAY,SAAS,CAAC,CAAC;AACxE,gBACE,aAAa,MAAM,KAAK,qBAAqB,GAAG,aAAa,SAAS,CAAC,CAAC;AAE1E,aAAS,IAAI,SAAS,QAAQ,IAAI,QAAQ,KAAK;AAC7C,kBACE,SAAS,MAAM,KAAK,qBAAqB,GAAG,SAAS,SAAS,CAAC,CAAC;AAAA,IACpE;AAEA,WAAO,SACJ,MAAM,EAAE,EACR,KAAK,MAAM,KAAK,WAAW,GAAG,EAC9B,KAAK,EAAE;AAAA,EACZ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,WAAW,OAAgC;AAC/C,UAAM,UAAU,IAAI,YAAA;AACpB,UAAM,OAAO,QAAQ,OAAO,KAAK;AACjC,UAAM,OAAO,MAAM,OAAO,OAAO,OAAO,WAAW,IAAI;AACvD,WAAO,MAAM,KAAK,IAAI,WAAW,IAAI,CAAC,EACnC,IAAI,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,CAAC,EAC1C,KAAK,EAAE;AAAA,EACZ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,cAAc,CAAC,UAA0B;AACvC,WAAO,MACJ,QAAQ,MAAM,OAAO,EACrB,QAAQ,MAAM,MAAM,EACpB,QAAQ,MAAM,MAAM,EACpB,QAAQ,MAAM,QAAQ,EACtB,QAAQ,MAAM,QAAQ;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,mBAAmB,CAAC,OAAe,gBAAiC;AAClE,WAAO,UAAU;AAAA,EACnB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,kBAAkB,CAAC,aAAqB;AACtC,UAAM,YAAY;AAClB,UAAM,eAAe,QAAQ,KAAK,QAAQ;AAC1C,UAAM,eAAe,QAAQ,KAAK,QAAQ;AAC1C,UAAM,aAAa,KAAK,KAAK,QAAQ;AACrC,UAAM,iBAAiB,yBAAyB,KAAK,QAAQ;AAC7D,UAAM,eAAe,SAAS,UAAU;AAExC,WAAO;AAAA,MACL,SACE,gBACA,gBACA,gBACA,cACA;AAAA,MACF,cAAc;AAAA,QACZ,WAAW;AAAA,QACX;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MAAA;AAAA,IACF;AAAA,EAEJ;AACF;"}