UNPKG

@teqed/interact-ibmi

Version:

Menus for interacting with IBMi AS400 using node-odbc.

324 lines (323 loc) 14.7 kB
/* eslint-disable func-style */ import chalk from 'chalk'; import { qualifyObject } from '../../../../util.js'; import { queryOdbc } from '../../../../util/odbc/odbc-util.js'; import CHGUSRPRF from '../../../../util/qcmdexc/chgusrprf.js'; import CPYNAVUSR from '../../../../util/qcmdexc/cpynavusr.js'; import executeCommand from '../../../../util/qcmdexc/execute-command.js'; import { parseErrorMessage } from '../../../../util/qcmdexc/qcmdexc-util.js'; import { genericGetCommand } from '../../../generic/generic.js'; import confirm from '../../../generic/inquirer-confirm.js'; import select from '../../../generic/inquirer-select.js'; /* If possiblyNullValue is null or undefined, return an empty string. Otherwise, return possiblyNullValue. */ // eslint-disable-next-line @typescript-eslint/ban-types function notNull(possiblyNullValue) { if (possiblyNullValue === null) { return ``; } if (typeof possiblyNullValue === `undefined`) { return ``; } if (typeof possiblyNullValue === `string`) { return possiblyNullValue; // Now definitely not null. } throw new Error(`Type unexpected`); } function convertUserInterface(copyUser, newUser, newDescription) { /* Setup user values for CRTUSRPRF. */ const userId = newUser; const userText = newDescription; const userPassword = `*NONE`; const userClass = copyUser.USER_CLASS_NAME; const userInitialProgram = qualifyObject({ library: copyUser.INITIAL_PROGRAM_LIBRARY_NAME, object: copyUser.INITIAL_PROGRAM_NAME, }); const userInitialProgramQualifiers = { library: copyUser.INITIAL_PROGRAM_LIBRARY_NAME, object: copyUser.INITIAL_PROGRAM_NAME, }; const userInitialMenu = qualifyObject({ library: copyUser.INITIAL_MENU_LIBRARY_NAME, object: copyUser.INITIAL_MENU_NAME, }); let userLimitCapabilities = `*YES`; switch (copyUser.LIMIT_CAPABILITIES) { case `*NO`: userLimitCapabilities = `*NO`; break; case `*PARTIAL`: userLimitCapabilities = `*PARTIAL`; break; case `*SAME`: userLimitCapabilities = `*SAME`; break; default: } const userSpecialAuthority = notNull(copyUser.SPECIAL_AUTHORITIES); const userJobDescription = qualifyObject({ library: copyUser.JOB_DESCRIPTION_LIBRARY_NAME, object: copyUser.JOB_DESCRIPTION_NAME, }); const userGroupProfile = copyUser.GROUP_PROFILE_NAME; const userGroupAuthority = copyUser.GROUP_AUTHORITY; const userAccountingCode = notNull(copyUser.ACCOUNTING_CODE); const userDelivery = copyUser.MESSAGE_QUEUE_DELIVERY_METHOD; const userOutqueue = qualifyObject({ library: copyUser.OUTPUT_QUEUE_LIBRARY_NAME, object: copyUser.OUTPUT_QUEUE_NAME, }); const userOutqueueQualifiers = { library: copyUser.OUTPUT_QUEUE_LIBRARY_NAME, object: copyUser.OUTPUT_QUEUE_NAME, }; const userAttentionProgram = qualifyObject({ library: copyUser.ATTENTION_KEY_HANDLING_PROGRAM_LIBRARY_NAME, object: copyUser.ATTENTION_KEY_HANDLING_PROGRAM_NAME, }); const userSupplementalGroups = notNull(copyUser.SUPPLEMENTAL_GROUP_LIST); let userPasswordExpirationInterval; let userMaximumAllowedStorage; let userCharacterCodeSetId; switch (copyUser.PASSWORD_EXPIRATION_INTERVAL) { case 0: userPasswordExpirationInterval = `*SYSVAL`; break; case -1: userPasswordExpirationInterval = `*NOMAX`; break; default: userPasswordExpirationInterval = copyUser.PASSWORD_EXPIRATION_INTERVAL.toString(); break; } switch (copyUser.MAXIMUM_ALLOWED_STORAGE) { // TODO These values need to be confirmed. case BigInt(-1): userMaximumAllowedStorage = `*NOMAX`; break; default: // TODO This value needs to be confirmed. userMaximumAllowedStorage = copyUser.MAXIMUM_ALLOWED_STORAGE.toString(); } switch (copyUser.CHARACTER_CODE_SET_ID) { // TODO These values need to be confirmed. case `-2`: userCharacterCodeSetId = `*SYSVAL`; break; case `QCCSID`: userCharacterCodeSetId = `*SYSVAL`; break; default: userCharacterCodeSetId = copyUser.CHARACTER_CODE_SET_ID; } return { userAccountingCode, userAttentionProgram, userCharacterCodeSetId, userClass, userDelivery, userGroupAuthority, userGroupProfile, userId, userInitialMenu, userInitialProgram, userInitialProgramQualifiers, userJobDescription, userLimitCapabilities, userMaximumAllowedStorage, userOutqueue, userOutqueueQualifiers, userPassword, userPasswordExpirationInterval, userSpecialAuthority, userSupplementalGroups, userText, }; } // ! Default export */ /* Copies an existing user and creates a new user with the same privileges. */ export default async (copyFromUser, newUser, userDescription) => { // ! Start now and await later. const fromUserRaw = queryOdbc(`SELECT * FROM QSYS2.USER_INFO WHERE AUTHORIZATION_NAME = '${copyFromUser.toUpperCase()}'`); /* If the result of query2 is not empty, then the new user already exists. */ const query2 = queryOdbc(`SELECT AUTHORIZATION_NAME FROM QSYS2.USER_INFO_BASIC WHERE AUTHORIZATION_NAME = '${newUser.toUpperCase()}'`); // ! Start of awaits... // Deconstruct the object // eslint-disable-next-line unicorn/no-await-expression-member const fromUser = (await fromUserRaw)[0]; /* If the result of query is empty, then the user does not exist. */ // eslint-disable-next-line unicorn/no-await-expression-member if ((await fromUserRaw).length === 0) { const confirmPrompt = await confirm({ message: `User ${copyFromUser} does not exist. Would you like to use the default user profile?`, }); if (confirmPrompt) { // CPYNAVUSR will handle it from here. } else { console.error(`User ${copyFromUser} does not exist.`); return `User ${copyFromUser} does not exist.`; } } const toUser = convertUserInterface(fromUser, newUser.toUpperCase(), userDescription); /* If the result of query2 is not empty, then the new user already exists. */ // eslint-disable-next-line unicorn/no-await-expression-member if ((await query2).length > 0) { const confirmPrompt = await confirm({ message: `User ${toUser.userId} already exists. Would you like to continue anyway?`, }); if (confirmPrompt) { // CPYNAVUSR will handle it from here. } else { console.error(`User ${copyFromUser} already exists.`); return `User ${copyFromUser} already exists.`; } } let changeAttributesBoo = true; let choicesObject = [ { value: `Continue` }, { value: `Email : ${chalk.bgBlue.whiteBright(toUser.userEmail ?? ``)}` }, { value: `Outqueue : ${chalk.bgBlue.whiteBright(toUser.userOutqueue)}` }, { value: `Initial Program : ${chalk.bgBlue.whiteBright(toUser.userInitialProgram)}` }, { value: `Text Description : ${chalk.bgBlue.whiteBright(toUser.userText)}` }, // eslint-disable-next-line prettier/prettier { value: `Limit Capabilities : ${chalk.bgBlue.whiteBright(toUser.userLimitCapabilities)}` }, { value: `Special Authorities : ${chalk.bgBlue.whiteBright(toUser.userSpecialAuthority)}` }, ]; while (changeAttributesBoo) { /* Create an inquirer prompt that has options for initial program, limit capabilities, text description, special authorities, and outqueue. */ // eslint-disable-next-line no-await-in-loop await select({ choices: choicesObject, message: `Change any user profile attributes?`, }) // eslint-disable-next-line @typescript-eslint/no-loop-func .then(async (answers) => { switch (answers) { case `Initial Program : ${chalk.bgBlue.whiteBright(toUser.userInitialProgram)}`: { await genericGetCommand({ default: toUser.userInitialProgram, message: `Enter new initial program for ${newUser}:`, }) // eslint-disable-next-line @typescript-eslint/no-shadow .then(async (answers) => { toUser.userInitialProgram = answers; }); break; } case `Limit Capabilities : ${chalk.bgBlue.whiteBright(toUser.userLimitCapabilities)}`: { await genericGetCommand({ default: toUser.userLimitCapabilities, message: `Enter new limit capabilities for ${newUser}:`, }) // eslint-disable-next-line @typescript-eslint/no-shadow .then(async (answers) => { // eslint-disable-next-line max-len // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-explicit-any toUser.userLimitCapabilities = answers; }); break; } case `Text Description : ${chalk.bgBlue.whiteBright(toUser.userText)}`: { await genericGetCommand({ default: toUser.userText, message: `Enter new text description for ${newUser}:`, }) // eslint-disable-next-line @typescript-eslint/no-shadow .then(async (answers) => { toUser.userText = answers; }); break; } case `Special Authorities : ${chalk.bgBlue.whiteBright(toUser.userSpecialAuthority)}`: { await genericGetCommand({ default: toUser.userSpecialAuthority, message: `Enter new special authorities for ${newUser}:`, }) // eslint-disable-next-line @typescript-eslint/no-shadow .then(async (answers) => { toUser.userSpecialAuthority = answers; }); break; } case `Outqueue : ${chalk.bgBlue.whiteBright(toUser.userOutqueue)}`: { await genericGetCommand({ default: toUser.userOutqueue, message: `Enter new outqueue for ${newUser}:`, }) // eslint-disable-next-line @typescript-eslint/no-shadow .then(async (answers) => { toUser.userOutqueue = answers; }); break; } // eslint-disable-next-line prettier/prettier case `Email : ${chalk.bgBlue.whiteBright(toUser.userEmail ?? ``)}`: { await genericGetCommand({ default: toUser.userEmail, message: `Enter email for ${newUser}:`, }) // eslint-disable-next-line @typescript-eslint/no-shadow .then(async (answers) => { toUser.userEmail = answers; }); break; } case `Continue`: { changeAttributesBoo = false; break; } default: { // Prompt again. } } choicesObject = [ { value: `Continue` }, // eslint-disable-next-line prettier/prettier { value: `Email : ${chalk.bgBlue.whiteBright(toUser.userEmail ?? ``)}` }, // eslint-disable-next-line prettier/prettier { value: `Outqueue : ${chalk.bgBlue.whiteBright(toUser.userOutqueue)}` }, // eslint-disable-next-line prettier/prettier { value: `Initial Program : ${chalk.bgBlue.whiteBright(toUser.userInitialProgram)}` }, { value: `Text Description : ${chalk.bgBlue.whiteBright(toUser.userText)}` }, // eslint-disable-next-line prettier/prettier { value: `Limit Capabilities : ${chalk.bgBlue.whiteBright(toUser.userLimitCapabilities)}` }, // eslint-disable-next-line prettier/prettier { value: `Special Authorities : ${chalk.bgBlue.whiteBright(toUser.userSpecialAuthority)}` }, ]; }); } /* Assemble the user variables into a string using template literals. */ await executeCommand(CPYNAVUSR(fromUser.AUTHORIZATION_NAME, toUser.userId, toUser.userText, toUser.userEmail)).catch(async (error) => { const parseError = await parseErrorMessage(error); throw new Error(`${parseError.errorIdentifier}: ${parseError.messageText}`); }); const query5 = await queryOdbc(`SELECT AUTHORIZATION_NAME FROM QSYS2.USER_INFO_BASIC WHERE AUTHORIZATION_NAME = '${newUser.toUpperCase()}'`); const AdjustUserParameters = executeCommand(CHGUSRPRF({ INLPGM: toUser.userInitialProgramQualifiers, LMTCPB: toUser.userLimitCapabilities, OUTQ: toUser.userOutqueueQualifiers, // TODO: SPCAUT USRPRF: toUser.userId, })).catch(async (error) => { console.log(error); const parseError = await parseErrorMessage(error); throw new Error(`${parseError.errorIdentifier}: ${parseError.messageText}`); }); /* If the result of query4 is empty, then the user failed to create. */ if (query5.length === 0) { console.error(`User ${newUser} failed to create.`); return `User ${newUser} failed to create.`; } else { console.log(`User ${newUser} created.`); } await AdjustUserParameters; return `Successfully completed user creation.`; };