UNPKG

@universis/candidates

Version:

Universis api server plugin for study program candidates, internship selection etc

155 lines (153 loc) 7.37 kB
import { DataObjectState } from "@themost/data"; import { DataError, TraceUtils } from '@themost/common'; import { getMailer } from '@themost/mailer'; /** * @param {DataEventArgs} event */ async function afterSaveAsync(event) { const context = event.model.context; const actionStatus = await context.model('CreateCandidateUserAction') .where('id').equal(event.target.id).select('actionStatus/alternateName') .silent().value(); let previousStatus = 'UnknownActionStatus'; if (event.state === DataObjectState.Insert) { previousStatus = 'UnknownActionStatus' } else if (event.state === DataObjectState.Update) { if (event.previous) { previousStatus = event.previous.actionStatus.alternateName; } else { throw new DataError('E_STATE', 'The previous state of an object cannot be determined', null, 'StudyProgramRegisterAction'); } } if (actionStatus === 'ActiveActionStatus' && previousStatus !== 'ActiveActionStatus') { const service = context.getApplication().getService(function OAuth2ClientService() {}); if (typeof service.createUser !== 'function') { throw new Error('The operation is not supported by a service.'); } // get access token (for admin account) const adminAccount = service.settings.adminAccount; if (adminAccount == null) { throw new Error('The operation cannot be completed due to invalid or missing configuration.'); } const authorizeUser = await service.authorize(adminAccount); // get user TraceUtils.debug('CreateCandidateUserAction', 'get', JSON.stringify(event.target.object)); const object = await context.model('CreateCandidateUserAction') .where('id').equal(event.target.id).select('object') .silent().value(); const user = await context.model('User').where('id').equal(object).silent().getItem(); if (user == null) { throw new DataError('E_NOENT', 'User cannot be found', null, 'CreateCandidateUserAction', 'object'); } // check if user already exists and is disabled const userExists = await service.getUser(user.name, authorizeUser); if (userExists) { const updateAction = { id: event.target.id, actionStatus: { alternateName: 'CompletedActionStatus' } } if (userExists.enabled === false) { updateAction.description = 'User already exists at the OAuth2 server and is disabled.' } else { updateAction.description = 'User already exists at the OAuth2 server and is enabled.' } await event.model.silent().save(updateAction); return; } // get candidate for extra data const candidate = await context.model('CandidateStudent') .where('user').equal(user).expand('person').silent().getItem(); // get activation code as new password const newPassword = await context.model('CandidateUser') .where('id').equal(object).select('activationCode') .silent().value(); if (newPassword == null) { throw new DataError('E_EMPTY','An error occurred while validating user data', null, 'CandidateUser', 'activationCode'); } await service.createUser({ name: user.name, description: `${candidate.person.givenName} ${candidate.person.familyName}`, alternateName: candidate.person.email, enabled: true, familyName: candidate.person.familyName, givenName: candidate.person.givenName, userCredentials: { userPassword: `{clear}${newPassword}` } }, authorizeUser); try { // send notification for the newly created user const mailer = getMailer(context); let mailTemplate = await context.model('MailConfiguration') .where('target').equal('CreateCandidateUserAction') .and('state').equal(DataObjectState.Update) .silent().getItem(); // if mail template is null do nothing and exit // otherwise send mail if (mailTemplate != null) { // get candidate const candidateUser = await context.model('CandidateUser') .where('id').equal(user).silent().getItem(); Object.assign(candidate, { user: candidateUser }); // get register application const application = await context.model('WebApplication') .where('alternateName').equal('register') .and('applicationSuite').equal('universis') .silent().getItem(); if (application == null) { TraceUtils.warn('CreateCandidateUserAction', 'Universis register is missing from application collection. User notification for account activation cannot include information about this app.'); } await new Promise((resolve) => { mailer.template(mailTemplate.template) .subject(mailTemplate.subject) .to(candidate.person.email) .send({ model: { candidate, application } }, (err) => { if (err) { try { TraceUtils.error('CreateCandidateUserAction', 'An error occurred while trying to send an email notification for account activation.'); TraceUtils.error('CreateCandidateUserAction', 'Candidate' , `${candidate.id}`, 'Email Address', `${candidate.person.email || 'empty'}`); TraceUtils.error(err); } catch (err1) { // do nothing } return resolve(); } return resolve(); }); }); } else { TraceUtils.warn('CreateCandidateUserAction', 'A mail template for account activation notification is missing. User cannot be notified for this action.') } } catch (err) { TraceUtils.error('CreateCandidateUserAction', 'An error occurred while trying to send an email notification for account activation.'); TraceUtils.error(err); } // complete action await context.model('CreateCandidateUserAction').silent().save({ id: event.target.id, actionStatus: { alternateName: 'CompletedActionStatus' } }); } } /** * @param {DataEventArgs} event * @param {Function} callback */ export function afterSave(event, callback) { return afterSaveAsync(event).then(() => { return callback(); }).catch((err) => { return callback(err); }); }