From 6752c05cd912b3029a7f3f7e6b0f839ce1c55d73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marvin=20=C3=96hlerking?= <103562092+MarvinOehlerkingCap@users.noreply.github.com> Date: Mon, 14 Oct 2024 16:25:14 +0200 Subject: [PATCH] N21-2216 Fix outdated users for team invitations (#5286) --- src/services/teams/index.js | 131 ++++++++++++---------- src/services/user/hooks/publicTeachers.js | 2 +- 2 files changed, 71 insertions(+), 62 deletions(-) diff --git a/src/services/teams/index.js b/src/services/teams/index.js index 693b7c37a90..119147cfa33 100644 --- a/src/services/teams/index.js +++ b/src/services/teams/index.js @@ -1,8 +1,8 @@ // eslint-disable-next-line max-classes-per-file -const service = require('../../utils/feathers-mongoose'); const { Configuration } = require('@hpi-schul-cloud/commons'); const { static: staticContent } = require('@feathersjs/express'); const path = require('path'); +const service = require('../../utils/feathers-mongoose'); const { NotFound, BadRequest, GeneralError } = require('../../errors'); const hooks = require('./hooks'); @@ -29,6 +29,7 @@ const { equal: equalIds } = require('../../helper/compare').ObjectId; const HOST = Configuration.get('HOST'); const { AdminOverview } = require('./services'); +const { SCHOOL_FEATURES } = require('../school/model'); class Get { constructor(options) { @@ -94,14 +95,20 @@ class Add { * @param {String} email * @return {Promise::User} */ - async _getUsersByEmail(email) { + async _getUsersByEmail(email, school) { + const query = { + email, + $populate: [{ path: 'roles' }, { path: 'schoolId' }], + }; + + if (!school.features?.includes(SCHOOL_FEATURES.SHOW_OUTDATED_USERS)) { + query.outdatedSince = null; + } + return this.app .service('users') .find({ - query: { - email, - $populate: [{ path: 'roles' }], - }, + query, }) .then((users) => extractOne(users)) .catch((err) => { @@ -154,62 +161,64 @@ class Add { * }} */ async _collectUserAndLinkData({ email, role, teamId }) { - return Promise.all([ - // eslint-disable-next-line no-underscore-dangle - this._getUsersByEmail(email), - // eslint-disable-next-line no-underscore-dangle - this._getExpertSchoolId(), - // eslint-disable-next-line no-underscore-dangle - this._getExpertRoleId(), - getTeam(this, teamId), - ]) - .then(async ([user, schoolId, expertRoleId, team]) => { - let isUserCreated = false; - let isResend = false; - let userRoleName; - if (isUndefined(user) && role === 'teamexpert') { - const newUser = { - email, - schoolId, - roles: [expertRoleId], - firstName: 'Experte', - lastName: 'Experte', - }; - // eslint-disable-next-line no-param-reassign - user = await userModel.create(newUser); - isUserCreated = true; - } - - if (isUserCreated || isDefined(role)) { - userRoleName = role; - } else { - const teamUser = team.invitedUserIds.find((invited) => invited.email === email); - isResend = true; - userRoleName = (teamUser || {}).role || role; - } - - // if role teamadmin by import from teacher over email and - // no user exist, the user is undefined - if (isUndefined(user)) { - throw new BadRequest('User must exist.'); - } - if (isUndefined(userRoleName)) { - throw new BadRequest('For this case the team role for user must be set.'); - } - return { - esid: schoolId, - isUserCreated, - isResend, - user, - team, - userRoleName, - importHash: user.importHash, + try { + const team = await getTeam(this, teamId); + const school = await this.app.service('schools').get(team.schoolId); + // eslint-disable-next-line prefer-const + let [user, schoolId, expertRoleId] = await Promise.all([ + // eslint-disable-next-line no-underscore-dangle + this._getUsersByEmail(email, school), + // eslint-disable-next-line no-underscore-dangle + this._getExpertSchoolId(), + // eslint-disable-next-line no-underscore-dangle + this._getExpertRoleId(), + ]); + let isUserCreated = false; + let isResend = false; + let userRoleName; + if (isUndefined(user) && role === 'teamexpert') { + const newUser = { + email, + schoolId, + roles: [expertRoleId], + firstName: 'Experte', + lastName: 'Experte', }; - }) - .catch((err) => { - warning(err); - throw new BadRequest('Can not resolve the user information.'); - }); + // eslint-disable-next-line no-param-reassign + user = await userModel.create(newUser); + isUserCreated = true; + } + + if (isUserCreated || isDefined(role)) { + userRoleName = role; + } else { + const teamUser = team.invitedUserIds.find((invited) => invited.email === email); + isResend = true; + userRoleName = (teamUser || {}).role || role; + } + + // if role teamadmin by import from teacher over email and + // no user exist, the user is undefined + if (isUndefined(user)) { + throw new BadRequest('User must exist.'); + } + if (isUndefined(userRoleName)) { + throw new BadRequest('For this case the team role for user must be set.'); + } + + return { + esid: schoolId, + isUserCreated, + isResend, + user, + team, + userRoleName, + importHash: user.importHash, + }; + } catch (err) { + warning(err); + throw new BadRequest('Can not resolve the user information.'); + } } /** diff --git a/src/services/user/hooks/publicTeachers.js b/src/services/user/hooks/publicTeachers.js index 9a59e3a6fdd..3c57290b712 100644 --- a/src/services/user/hooks/publicTeachers.js +++ b/src/services/user/hooks/publicTeachers.js @@ -26,7 +26,7 @@ const mapRoleFilterQuery = (hook) => { const filterForPublicTeacher = (hook) => { // Limit accessible fields - hook.params.query.$select = ['_id', 'firstName', 'lastName', 'schoolId']; + hook.params.query.$select = ['_id', 'firstName', 'lastName', 'schoolId', 'outdatedSince']; // Limit accessible user (only teacher which are discoverable) hook.params.query.roles = ['teacher'];