import type { LoaderFunctionArgs } from "@remix-run/node"; import { json } from "@remix-run/node"; import { useLoaderData } from "@remix-run/react"; import { requireAuthLevel } from "~/utils/auth.server"; import DashboardLayout from "~/components/DashboardLayout"; import { testEncryption, encrypt, decrypt, migrateEncryption, isEncrypted, isLegacyEncrypted } from "~/utils/encryption.server"; export async function loader({ request }: LoaderFunctionArgs) { // Require auth level 3 to access encryption test const user = await requireAuthLevel(request, 3); // Test encryption with sample data const testResults = testEncryption("sample-smtp-password-123"); // Test with different types of data const tests = [ { name: "Simple Password", data: "mypassword123" }, { name: "Complex Password", data: "P@ssw0rd!@#$%^&*()" }, { name: "Email Password", data: "smtp.gmail.app.password" }, { name: "Special Characters", data: "test!@#$%^&*()_+-=[]{}|;:,.<>?" } ]; const testResults2 = tests.map(test => { try { const encrypted = encrypt(test.data); const decrypted = decrypt(encrypted); const migrated = migrateEncryption(test.data); const migratedDecrypted = decrypt(migrated); return { ...test, encrypted, decrypted, success: decrypted === test.data, encryptedLength: encrypted.length, migrationSuccess: migratedDecrypted === test.data, isNewFormat: isEncrypted(encrypted), isLegacyFormat: isLegacyEncrypted(test.data) }; } catch (error) { return { ...test, error: error instanceof Error ? error.message : 'Unknown error', success: false }; } }); return json({ user, basicTest: testResults, detailedTests: testResults2 }); } export default function TestEncryption() { const { user, basicTest, detailedTests } = useLoaderData(); return (

Encryption Test Results

{/* Basic Test */}

Basic Encryption Test

Status: {basicTest.success ? 'PASSED' : 'FAILED'}
{basicTest.success ? ( <>
Original: {basicTest.original}
Encrypted: {basicTest.encrypted}
Decrypted: {basicTest.decrypted}
Valid: {basicTest.isValid ? '✅' : '❌'}
) : (
Error: {basicTest.error}
)}
{/* Detailed Tests */}

Detailed Encryption Tests

{detailedTests.map((test, index) => ( ))}
Test Name Status Original Encrypted Length Match Migration
{test.name} {test.success ? 'PASS' : 'FAIL'} {test.data.length > 20 ? test.data.substring(0, 20) + '...' : test.data} {test.encryptedLength || 'N/A'} {test.success ? '✅' : '❌'} {test.error &&
{test.error}
}
{test.migrationSuccess ? '✅' : '❌'}
Format: {test.isNewFormat ? 'New' : test.isLegacyFormat ? 'Legacy' : 'Plain'}
{/* Security Notes */}

Security Notes

  • • Passwords are encrypted using AES-256-CBC algorithm
  • • Each encryption uses a random IV (Initialization Vector)
  • • Encrypted data format: IV:EncryptedData (hex)
  • • Migration support for legacy encrypted data
  • • Encryption key should be set via ENCRYPTION_KEY environment variable
  • • This test page should only be accessible to Super Admins
{/* Node.js Version Info */}

Environment Info

• Node.js Version: {process.version}
• Platform: {process.platform}
• Architecture: {process.arch}
• Encryption Format: New (createCipheriv/createDecipheriv)
); }