require('dotenv').config(); const config = require('./config.js'); const axios = require('axios'); // Configure RightAnswers API client const rightAnswersApi = axios.create({ baseURL: process.env.RIGHTANSWERS_BASE_URL, auth: { username: process.env.RIGHTANSWERS_USERNAME, password: process.env.RIGHTANSWERS_PASSWORD }, headers: { 'Content-Type': 'application/json' } }); /** * Batches an array into smaller arrays of a specific size */ function chunkArray(array, size) { const result = []; for (let i = 0; i < array.length; i += size) { result.push(array.slice(i, i + size)); } return result; } /** * Simple delay helper, used between batches to avoid hammering the API */ function delay(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } /** * Perform batch deletion for a list of usernames * @param {string[]} usernames - Array of usernames/emails to delete * @param {string} companyCode - The company code the users belong to (default from config) * @param {number} batchSize - Number of users to delete per API request (default 50) * @returns {Promise<{succeeded: string[], failed: string[]}>} Usernames grouped by batch outcome */ async function batchDeleteUsers(usernames, companyCode = config.rightAnswers.companyCode, batchSize = 50) { const raConfig = config.rightAnswers; const chunks = chunkArray(usernames, batchSize); const succeeded = []; const failed = []; console.log(`Starting batch deletion for ${usernames.length} users in ${chunks.length} batches...`); for (let i = 0; i < chunks.length; i++) { const chunk = chunks[i]; console.log(`Processing batch ${i + 1}/${chunks.length} (${chunk.length} users)...`); // Prepare payload exactly as requested const payload = chunk.map(username => ({ username: username, platformUserCompanies: [ { companyCode: companyCode } ] })); try { const response = await rightAnswersApi.post('/api/rest/users/manage', payload, { params: { companyCode: companyCode, appInterface: raConfig.appInterface, operation: 'delete' } }); console.log(`Batch ${i + 1} completed. Response status:`, response.status); if (response.data) console.log(`Response data:`, JSON.stringify(response.data)); // NOTE: this assumes a non-error HTTP response means the whole batch succeeded. // If this endpoint can return 200 with a mix of per-user pass/fail results, // parse response.data here instead and split the chunk accordingly. succeeded.push(...chunk); } catch (error) { console.error(`Error deleting batch ${i + 1}:`, error.response ? JSON.stringify(error.response.data) : error.message); failed.push(...chunk); } if (i < chunks.length - 1) { await delay(500); } } console.log(`Batch deletion finished. Succeeded: ${succeeded.length}, Failed: ${failed.length}\n`); return { succeeded, failed }; } /** * Perform batch addition for a list of users * @param {Object[]} users - Array of user objects to add { email, firstName, lastName } * @param {string} companyCode - The company code the users belong to * @param {number} batchSize - Number of users to add per API request * @returns {Promise<{succeeded: string[], failed: string[]}>} Emails grouped by batch outcome */ async function batchAddUsers(users, companyCode = config.rightAnswers.companyCode, batchSize = 50) { const raConfig = config.rightAnswers; const chunks = chunkArray(users, batchSize); const succeeded = []; const failed = []; console.log(`Starting batch addition for ${users.length} users in ${chunks.length} batches...`); for (let i = 0; i < chunks.length; i++) { const chunk = chunks[i]; console.log(`Processing addition batch ${i + 1}/${chunks.length} (${chunk.length} users)...`); const payload = chunk.map(user => ({ username: user.email, password: process.env.TEST_USER_TEMP_PASSWORD, emailAddress: user.email, firstName: user.firstName || "Test", lastName: user.lastName || "User", phoneNumber: '', platformUserCompanies: [ { companyCode: companyCode, portalUserGroup: raConfig.defaultPortalUserGroup, portalIsCommunity: raConfig.portalIsCommunity, portalIsActive: raConfig.portalIsActive, portalisLocked: false, smisActive: false, smhasVideo: false, smwantAlerts: false, smuserRoleID: "Author" } ] })); try { const response = await rightAnswersApi.post('/api/rest/users/manage', payload, { params: { companyCode: companyCode, appInterface: raConfig.appInterface, operation: 'add' } }); console.log(`Addition batch ${i + 1} completed. Response status:`, response.status); if (response.data) console.log(`Response data:`, JSON.stringify(response.data)); succeeded.push(...chunk.map(u => u.email)); } catch (error) { console.error(`Error adding batch ${i + 1}:`, error.response ? JSON.stringify(error.response.data) : error.message); failed.push(...chunk.map(u => u.email)); } if (i < chunks.length - 1) { await delay(500); } } console.log(`Batch addition finished. Succeeded: ${succeeded.length}, Failed: ${failed.length}\n`); return { succeeded, failed }; } // ========================================================================= // USAGE: // 1. Add test user details to the array below // 2. Set 'performAddition' and/or 'performDeletion' flags // 3. If performAddition is true, set TEST_USER_TEMP_PASSWORD in your .env file // 4. Run this script via command line: `node batchDelete.js` // ========================================================================= const testUsers = [ { email: "automated_test_user_1@example.com", firstName: "Test1", lastName: "Automated" }, { email: "automated_test_user_2@example.com", firstName: "Test2", lastName: "Automated" } ]; const performAddition = false; // Set to true to add the test users const performDeletion = true; // Set to true to delete the test users if (require.main === module) { (async () => { if (testUsers.length === 0) { console.log("No users to process. Please populate the `testUsers` array."); return; } let addResult = null; if (performAddition) { if (!process.env.TEST_USER_TEMP_PASSWORD) { console.error("TEST_USER_TEMP_PASSWORD is not set in your .env file. Skipping addition step."); } else { console.log("=== STEP 1: ADDING TEST USERS ==="); addResult = await batchAddUsers(testUsers); } } if (performDeletion) { console.log("=== STEP 2: DELETING TEST USERS ==="); // If addition just ran, only delete users confirmed added — don't try to // delete accounts that never got created. const usernamesToDelete = addResult ? addResult.succeeded : testUsers.map(u => u.email); if (addResult && addResult.failed.length > 0) { console.warn(`Skipping deletion for ${addResult.failed.length} user(s) that failed to add:`, addResult.failed); } if (usernamesToDelete.length > 0) { await batchDeleteUsers(usernamesToDelete); } else { console.log("No successfully-added users to delete."); } } })(); } module.exports = { batchDeleteUsers, batchAddUsers };