@frank-auth/react
Version:
Flexible and customizable React UI components for Frank Authentication
1 lines • 25.7 kB
Source Map (JSON)
{"version":3,"file":"crypto.cjs","sources":["../../../src/utils/crypto.ts"],"sourcesContent":["// Cryptographic utilities for Frank Auth React library\n// These are client-side utilities for non-sensitive operations\n\n// Base64 utilities\nexport const base64Encode = (data: string): string => {\n if (typeof btoa !== 'undefined') {\n return btoa(data);\n }\n\n // Fallback for environments without btoa\n return Buffer.from(data, 'utf-8').toString('base64');\n};\n\nexport const base64Decode = (encoded: string): string => {\n if (typeof atob !== 'undefined') {\n return atob(encoded);\n }\n\n // Fallback for environments without atob\n return Buffer.from(encoded, 'base64').toString('utf-8');\n};\n\nexport const base64UrlEncode = (data: string): string => {\n return base64Encode(data)\n .replace(/\\+/g, '-')\n .replace(/\\//g, '_')\n .replace(/=/g, '');\n};\n\nexport const base64UrlDecode = (encoded: string): string => {\n // Add padding if needed\n let padded = encoded;\n while (padded.length % 4) {\n padded += '=';\n }\n\n return base64Decode(\n padded\n .replace(/-/g, '+')\n .replace(/_/g, '/')\n );\n};\n\n// Random generation utilities\nexport const generateRandomBytes = (length: number): Uint8Array => {\n if (typeof crypto !== 'undefined' && crypto.getRandomValues) {\n return crypto.getRandomValues(new Uint8Array(length));\n }\n\n // Fallback for environments without crypto.getRandomValues\n const array = new Uint8Array(length);\n for (let i = 0; i < length; i++) {\n array[i] = Math.floor(Math.random() * 256);\n }\n return array;\n};\n\nexport const generateRandomString = (length: number, charset?: string): string => {\n const defaultCharset = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\n const chars = charset || defaultCharset;\n const randomBytes = generateRandomBytes(length);\n\n let result = '';\n for (let i = 0; i < length; i++) {\n result += chars[randomBytes[i] % chars.length];\n }\n\n return result;\n};\n\nexport const generateSecureId = (): string => {\n const timestamp = Date.now().toString(36);\n const randomPart = generateRandomString(8);\n return `${timestamp}${randomPart}`;\n};\n\nexport const generateNonce = (): string => {\n return generateRandomString(32);\n};\n\nexport const generateState = (): string => {\n return generateRandomString(32);\n};\n\nexport const generateCodeVerifier = (): string => {\n return generateRandomString(128, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~');\n};\n\n// PKCE (Proof Key for Code Exchange) utilities\nexport const generateCodeChallenge = async (verifier: string): Promise<string> => {\n if (typeof crypto !== 'undefined' && crypto.subtle) {\n const encoder = new TextEncoder();\n const data = encoder.encode(verifier);\n const digest = await crypto.subtle.digest('SHA-256', data);\n const array = new Uint8Array(digest);\n\n return base64UrlEncode(String.fromCharCode(...array));\n }\n\n // Fallback: return verifier as-is (not recommended for production)\n console.warn('WebCrypto API not available, using plain code verifier');\n return verifier;\n};\n\nexport const generatePKCEPair = async (): Promise<{\n codeVerifier: string;\n codeChallenge: string;\n codeChallengeMethod: 'S256' | 'plain';\n}> => {\n const codeVerifier = generateCodeVerifier();\n\n if (typeof crypto !== 'undefined' && crypto.subtle) {\n const codeChallenge = await generateCodeChallenge(codeVerifier);\n return {\n codeVerifier,\n codeChallenge,\n codeChallengeMethod: 'S256',\n };\n }\n\n return {\n codeVerifier,\n codeChallenge: codeVerifier,\n codeChallengeMethod: 'plain',\n };\n};\n\n// Hash utilities\nexport const sha256 = async (data: string): Promise<string> => {\n if (typeof crypto !== 'undefined' && crypto.subtle) {\n const encoder = new TextEncoder();\n const dataBuffer = encoder.encode(data);\n const hashBuffer = await crypto.subtle.digest('SHA-256', dataBuffer);\n const hashArray = new Uint8Array(hashBuffer);\n\n return Array.from(hashArray)\n .map(b => b.toString(16).padStart(2, '0'))\n .join('');\n }\n\n // Fallback: simple hash (not cryptographically secure)\n let hash = 0;\n for (let i = 0; i < data.length; i++) {\n const char = data.charCodeAt(i);\n hash = ((hash << 5) - hash) + char;\n hash = hash & hash; // Convert to 32-bit integer\n }\n\n return Math.abs(hash).toString(16);\n};\n\nexport const md5 = (data: string): string => {\n // Simple MD5 implementation (not cryptographically secure, for compatibility only)\n // In production, you should use a proper crypto library\n let hash = 0;\n for (let i = 0; i < data.length; i++) {\n const char = data.charCodeAt(i);\n hash = ((hash << 5) - hash) + char;\n hash = hash & hash;\n }\n return Math.abs(hash).toString(16);\n};\n\n// Simple encryption/decryption (for client-side storage only)\n// NOTE: This is NOT secure encryption and should only be used for obfuscation\nexport const simpleEncrypt = (data: string, key: string): string => {\n let encrypted = '';\n for (let i = 0; i < data.length; i++) {\n const dataChar = data.charCodeAt(i);\n const keyChar = key.charCodeAt(i % key.length);\n encrypted += String.fromCharCode(dataChar ^ keyChar);\n }\n return base64Encode(encrypted);\n};\n\nexport const simpleDecrypt = (encrypted: string, key: string): string => {\n try {\n const data = base64Decode(encrypted);\n let decrypted = '';\n for (let i = 0; i < data.length; i++) {\n const dataChar = data.charCodeAt(i);\n const keyChar = key.charCodeAt(i % key.length);\n decrypted += String.fromCharCode(dataChar ^ keyChar);\n }\n return decrypted;\n } catch {\n return '';\n }\n};\n\n// JWT utilities (for parsing only, NOT for verification)\nexport interface JWTHeader {\n alg: string;\n typ: string;\n kid?: string;\n}\n\nexport interface JWTPayload {\n [key: string]: any;\n iss?: string;\n sub?: string;\n aud?: string | string[];\n exp?: number;\n nbf?: number;\n iat?: number;\n jti?: string;\n}\n\nexport const parseJWT = (token: string): {\n header: JWTHeader;\n payload: JWTPayload;\n signature: string;\n} | null => {\n try {\n const parts = token.split('.');\n if (parts.length !== 3) return null;\n\n const header = JSON.parse(base64UrlDecode(parts[0]));\n const payload = JSON.parse(base64UrlDecode(parts[1]));\n const signature = parts[2];\n\n return { header, payload, signature };\n } catch {\n return null;\n }\n};\n\nexport const isJWTExpired = (token: string): boolean => {\n const parsed = parseJWT(token);\n if (!parsed || !parsed.payload.exp) return true;\n\n const now = Math.floor(Date.now() / 1000);\n return parsed.payload.exp < now;\n};\n\nexport const getJWTExpiration = (token: string): Date | null => {\n const parsed = parseJWT(token);\n if (!parsed || !parsed.payload.exp) return null;\n\n return new Date(parsed.payload.exp * 1000);\n};\n\n// WebAuthn/Passkey utilities\nexport const arrayBufferToBase64 = (buffer: ArrayBuffer): string => {\n const bytes = new Uint8Array(buffer);\n let binary = '';\n for (let i = 0; i < bytes.byteLength; i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n return base64Encode(binary);\n};\n\nexport const base64ToArrayBuffer = (base64: string): ArrayBuffer => {\n const binary = base64Decode(base64);\n const buffer = new ArrayBuffer(binary.length);\n const view = new Uint8Array(buffer);\n for (let i = 0; i < binary.length; i++) {\n view[i] = binary.charCodeAt(i);\n }\n return buffer;\n};\n\nexport const uint8ArrayToBase64 = (array: Uint8Array): string => {\n return arrayBufferToBase64(array.buffer);\n};\n\nexport const base64ToUint8Array = (base64: string): Uint8Array => {\n return new Uint8Array(base64ToArrayBuffer(base64));\n};\n\n// Convert WebAuthn credential for transport\nexport const credentialToJSON = (credential: PublicKeyCredential): any => {\n return {\n id: credential.id,\n rawId: arrayBufferToBase64(credential.rawId),\n type: credential.type,\n response: {\n clientDataJSON: arrayBufferToBase64(credential.response.clientDataJSON),\n attestationObject: credential.response instanceof AuthenticatorAttestationResponse\n ? arrayBufferToBase64(credential.response.attestationObject)\n : undefined,\n authenticatorData: credential.response instanceof AuthenticatorAssertionResponse\n ? arrayBufferToBase64(credential.response.authenticatorData)\n : undefined,\n signature: credential.response instanceof AuthenticatorAssertionResponse\n ? arrayBufferToBase64(credential.response.signature)\n : undefined,\n userHandle: credential.response instanceof AuthenticatorAssertionResponse && credential.response.userHandle\n ? arrayBufferToBase64(credential.response.userHandle)\n : undefined,\n },\n };\n};\n\n// Convert JSON back to WebAuthn credential format for processing\nexport const jsonToCredentialCreationOptions = (options: any): PublicKeyCredentialCreationOptions => {\n return {\n ...options,\n challenge: base64ToArrayBuffer(options.challenge),\n user: {\n ...options.user,\n id: base64ToArrayBuffer(options.user.id),\n },\n excludeCredentials: options.excludeCredentials?.map((cred: any) => ({\n ...cred,\n id: base64ToArrayBuffer(cred.id),\n })),\n };\n};\n\nexport const jsonToCredentialRequestOptions = (options: any): PublicKeyCredentialRequestOptions => {\n return {\n ...options,\n challenge: base64ToArrayBuffer(options.challenge),\n allowCredentials: options.allowCredentials?.map((cred: any) => ({\n ...cred,\n id: base64ToArrayBuffer(cred.id),\n })),\n };\n};\n\n// Password hashing utilities (client-side, for display purposes only)\nexport const hashPassword = async (password: string, salt: string): Promise<string> => {\n // This is for client-side display only, NOT for security\n const combined = password + salt;\n return await sha256(combined);\n};\n\nexport const generateSalt = (): string => {\n return generateRandomString(16);\n};\n\n// Device fingerprinting utilities\nexport const generateDeviceFingerprintPromise = async (): Promise<string> => {\n const components = [\n navigator.userAgent,\n navigator.language,\n screen.width + 'x' + screen.height,\n screen.colorDepth,\n new Date().getTimezoneOffset(),\n navigator.hardwareConcurrency || 0,\n navigator.deviceMemory || 0,\n navigator.cookieEnabled,\n ];\n\n // Add canvas fingerprint\n try {\n const canvas = document.createElement('canvas');\n const ctx = canvas.getContext('2d');\n if (ctx) {\n ctx.textBaseline = 'top';\n ctx.font = '14px Arial';\n ctx.fillText('Frank Auth fingerprint', 2, 2);\n components.push(canvas.toDataURL());\n }\n } catch {\n // Canvas fingerprinting failed, skip\n }\n\n const fingerprint = components.join('|');\n return await sha256(fingerprint);\n};\n\n\nexport const generateDeviceFingerprint = (): string => {\n const canvas = document.createElement('canvas');\n const ctx = canvas.getContext('2d');\n ctx?.fillText('fingerprint', 0, 0);\n\n const fingerprint = [\n navigator.userAgent,\n navigator.language,\n screen.width + 'x' + screen.height,\n new Date().getTimezoneOffset(),\n canvas.toDataURL(),\n navigator.hardwareConcurrency,\n navigator.deviceMemory,\n ].join('|');\n\n // Simple hash function\n let hash = 0;\n for (let i = 0; i < fingerprint.length; i++) {\n const char = fingerprint.charCodeAt(i);\n hash = ((hash << 5) - hash) + char;\n hash = hash & hash; // Convert to 32-bit integer\n }\n\n return Math.abs(hash).toString(36);\n};\n\n// Secure random utilities\nexport const generateSecureToken = (length = 32): string => {\n const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\n return generateRandomString(length, chars);\n};\n\nexport const generateApiKey = (): string => {\n const prefix = 'pk_';\n const env = 'test_';\n const randomPart = generateRandomString(32);\n return `${prefix}${env}${randomPart}`;\n};\n\n// Validation utilities\nexport const isValidBase64 = (str: string): boolean => {\n try {\n return base64Encode(base64Decode(str)) === str;\n } catch {\n return false;\n }\n};\n\nexport const isValidJWT = (token: string): boolean => {\n return parseJWT(token) !== null;\n};\n\n// Time-based utilities\nexport const generateTOTPSecret = (): string => {\n // Generate a 32-character base32 secret for TOTP\n const base32Chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567';\n return generateRandomString(32, base32Chars);\n};\n\nexport const generateBackupCodes = (count = 10): string[] => {\n const codes: string[] = [];\n for (let i = 0; i < count; i++) {\n codes.push(generateRandomString(8, '0123456789ABCDEF'));\n }\n return codes;\n};\n\n// URL safe encoding\nexport const urlSafeEncode = (data: string): string => {\n return base64UrlEncode(data);\n};\n\nexport const urlSafeDecode = (encoded: string): string => {\n return base64UrlDecode(encoded);\n};\n\n// Checksum utilities\nexport const calculateChecksum = (data: string): string => {\n let checksum = 0;\n for (let i = 0; i < data.length; i++) {\n checksum += data.charCodeAt(i);\n }\n return checksum.toString(16);\n};\n\nexport const verifyChecksum = (data: string, expectedChecksum: string): boolean => {\n return calculateChecksum(data) === expectedChecksum;\n};\n\n// Key derivation utilities (for client-side use only)\nexport const deriveKey = async (password: string, salt: string, iterations = 1000): Promise<string> => {\n if (typeof crypto !== 'undefined' && crypto.subtle) {\n const encoder = new TextEncoder();\n const keyMaterial = await crypto.subtle.importKey(\n 'raw',\n encoder.encode(password),\n { name: 'PBKDF2' },\n false,\n ['deriveBits']\n );\n\n const derivedBits = await crypto.subtle.deriveBits(\n {\n name: 'PBKDF2',\n salt: encoder.encode(salt),\n iterations,\n hash: 'SHA-256',\n },\n keyMaterial,\n 256\n );\n\n const array = new Uint8Array(derivedBits);\n return Array.from(array)\n .map(b => b.toString(16).padStart(2, '0'))\n .join('');\n }\n\n // Fallback: simple hash-based derivation\n let derived = password + salt;\n for (let i = 0; i < iterations; i++) {\n derived = await sha256(derived);\n }\n return derived;\n};\n\n// Export utilities for use in other modules\nexport const CryptoUtils = {\n // Encoding\n base64Encode,\n base64Decode,\n base64UrlEncode,\n base64UrlDecode,\n urlSafeEncode,\n urlSafeDecode,\n\n // Random generation\n generateRandomBytes,\n generateRandomString,\n generateSecureId,\n generateNonce,\n generateState,\n generateSecureToken,\n\n // Hashing\n sha256,\n md5,\n calculateChecksum,\n verifyChecksum,\n\n // JWT\n parseJWT,\n isJWTExpired,\n getJWTExpiration,\n isValidJWT,\n\n // WebAuthn\n arrayBufferToBase64,\n base64ToArrayBuffer,\n uint8ArrayToBase64,\n base64ToUint8Array,\n credentialToJSON,\n jsonToCredentialCreationOptions,\n jsonToCredentialRequestOptions,\n\n // PKCE\n generateCodeVerifier,\n generateCodeChallenge,\n generatePKCEPair,\n\n // Device fingerprinting\n generateDeviceFingerprint,\n\n // Authentication codes\n generateTOTPSecret,\n generateBackupCodes,\n\n // Key derivation\n deriveKey,\n\n // Simple encryption (for obfuscation only)\n simpleEncrypt,\n simpleDecrypt,\n\n // Validation\n isValidBase64,\n};"],"names":["base64Encode","data","base64Decode","encoded","base64UrlEncode","base64UrlDecode","padded","generateRandomBytes","length","array","i","generateRandomString","charset","chars","randomBytes","result","generateSecureId","timestamp","randomPart","generateNonce","generateState","generateCodeVerifier","generateCodeChallenge","verifier","digest","generatePKCEPair","codeVerifier","codeChallenge","sha256","dataBuffer","hashBuffer","hashArray","b","hash","char","md5","simpleEncrypt","key","encrypted","dataChar","keyChar","simpleDecrypt","decrypted","parseJWT","token","parts","header","payload","signature","isJWTExpired","parsed","now","getJWTExpiration","arrayBufferToBase64","buffer","bytes","binary","base64ToArrayBuffer","base64","view","uint8ArrayToBase64","base64ToUint8Array","credentialToJSON","credential","jsonToCredentialCreationOptions","options","cred","jsonToCredentialRequestOptions","hashPassword","password","salt","combined","generateSalt","generateDeviceFingerprintPromise","components","canvas","ctx","fingerprint","generateDeviceFingerprint","generateSecureToken","generateApiKey","prefix","env","isValidBase64","str","isValidJWT","generateTOTPSecret","generateBackupCodes","count","codes","urlSafeEncode","urlSafeDecode","calculateChecksum","checksum","verifyChecksum","expectedChecksum","deriveKey","iterations","encoder","keyMaterial","derivedBits","derived","CryptoUtils"],"mappings":"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"}