import "dotenv/config"; import { AppDataSource } from "../src/database/data-source"; import { KeycloakAttributeService } from "../src/services/KeycloakAttributeService"; import * as keycloak from "../src/keycloak/index"; /** * Main function */ async function main() { const args = process.argv.slice(2); const dryRun = args.includes("--dry-run"); const limitArg = args.find((arg) => arg.startsWith("--limit=")); const limit = limitArg ? parseInt(limitArg.split("=")[1], 10) : undefined; console.log("=".repeat(60)); console.log("Ensure Keycloak Users Script"); console.log("=".repeat(60)); console.log(`Mode: ${dryRun ? "DRY-RUN (no changes)" : "LIVE"}`); if (limit !== undefined) { console.log(`Limit: ${limit} profiles per table (for testing)`); } console.log(""); // Initialize database try { await AppDataSource.initialize(); console.log("Database connected"); } catch (error) { console.error("Failed to connect to database:", error); process.exit(1); } // Validate Keycloak connection try { await keycloak.getToken(); console.log("Keycloak connected"); } catch (error) { console.error("Failed to connect to Keycloak:", error); await AppDataSource.destroy(); process.exit(1); } console.log(""); // Verify USER role exists console.log("Verifying USER role in Keycloak..."); const userRole = await keycloak.getRoles("USER"); if (!userRole || typeof userRole === "boolean" || userRole === null || !("id" in userRole)) { console.error("ERROR: USER role not found in Keycloak"); await AppDataSource.destroy(); process.exit(1); } console.log("USER role found"); console.log(""); // Run the ensure users operation const service = new KeycloakAttributeService(); console.log("Ensuring Keycloak users for all profiles..."); console.log(""); const result = await service.batchEnsureKeycloakUsers(); // Summary console.log(""); console.log("=".repeat(60)); console.log("Summary:"); console.log(` Total profiles: ${result.total}`); console.log(` Created: ${result.created}`); console.log(` Verified: ${result.verified}`); console.log(` Skipped: ${result.skipped}`); console.log(` Failed: ${result.failed}`); console.log("=".repeat(60)); if (result.failed > 0) { console.log(""); console.log("Failed Details:"); const failedDetails = result.details.filter((d) => d.action === "error" || !!d.error); for (const detail of failedDetails) { console.log( ` [${detail.profileType}] ${detail.profileId}: ${detail.error || "Unknown error"}`, ); } } // Cleanup await AppDataSource.destroy(); } main().catch(console.error);