import { db } from '../app/src/infrastructure/mongodb.js' import minimist from 'minimist' import UserGetter from '../app/src/Features/User/UserGetter.js' import fs from 'node:fs' function usage() { console.log( 'Usage: node lowercase_institution_user_ids.mjs -i ' ) console.log( 'Converts external user IDs to lowercase for all users in an institute' ) console.log('Options:') console.log( ' --institution-id, -i Institution ID to update' ) console.log( ' --dry-run, -d Finds users with non-lowercase id but does not do any updates' ) console.log( ' --file, -f A file that contains external user ids to be updated' ) console.log( ' If not provided, the script will update all the users within the institution that have upper case external user id' ) console.log( ' -h, --help Show this help message' ) process.exit(0) } const { 'dry-run': dryRun, 'institution-id': providerId, help, file, } = minimist(process.argv.slice(2), { string: ['institution-id', 'file'], boolean: ['dry-run', 'help'], alias: { 'institution-id': 'i', 'dry-run': 'd', help: 'h', file: 'f', }, default: { 'dry-run': true, }, }) async function main() { if (help || !providerId) { usage() } let externalUserIdsToUpdate = null if (file) { const lines = fs.readFileSync(file, 'utf8').split('\n') externalUserIdsToUpdate = new Set(lines) } const users = await UserGetter.promises.getSsoUsersAtInstitution(providerId, { _id: 1, samlIdentifiers: 1, }) let userToUpdate = 0 let userUpdated = 0 for (const user of users) { const matchingIdentifier = user.samlIdentifiers.find( u => u.providerId === providerId ) const lowercaseId = matchingIdentifier.externalUserId.toLowerCase() // skip if external user id is already in lower case if (lowercaseId === matchingIdentifier.externalUserId) { continue } // skip if an id file is provided but current external user id is not in the file if (externalUserIdsToUpdate && !externalUserIdsToUpdate.has(lowercaseId)) { continue } userToUpdate = userToUpdate + 1 console.log( `${user._id},${matchingIdentifier.externalUserId},${lowercaseId}` ) if (dryRun) { continue } try { await db.users.updateOne( { _id: user._id, 'samlIdentifiers.providerId': providerId }, { $set: { 'samlIdentifiers.$.externalUserId': lowercaseId } } ) userUpdated = userUpdated + 1 } catch (error) { console.error(error) } } if (dryRun) { console.log(`DRY RUN: ${userToUpdate} users will be updated`) } else { console.log(`UPDATED: ${userUpdated}/${userToUpdate} users successfully`) } } try { await main() process.exit(0) } catch (error) { console.error(error) process.exit(1) }