Merge pull request #12137 from ToolJet/bugfixes/branch-2-platform

Bulk upload bugfix
This commit is contained in:
Muhsin Shah C P 2025-03-06 17:14:35 +05:30 committed by GitHub
commit fabc6e10b8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -193,138 +193,136 @@ export class OrganizationUsersService implements IOrganizationUsersService {
let invalidGroups = [];
const emailPattern = /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i;
const invalidRoles = [];
await dbTransactionWrap(async (manager: EntityManager) => {
const groupPermissions = (
await this.groupPermissionsUtilService.getAllGroupByOrganization(currentUser.organizationId)
).groupPermissions?.filter((gp) => !gp.disabled);
const existingGroups = groupPermissions.map((groupPermission) => groupPermission.name);
csv
.parseString(fileStream.toString(), {
headers: ['first_name', 'last_name', 'email', 'user_role', 'groups', 'metadata'],
renameHeaders: true,
ignoreEmpty: true,
})
.transform((row: UserCsvRow, next) => {
const groupNames = this.organizationUsersUtilService.createGroupsList(row?.groups);
invalidGroups = [...invalidGroups, ...groupNames.filter((group) => !existingGroups.includes(group))];
const groups = groupPermissions.filter((group) => groupNames.includes(group.name)).map((group) => group.id);
return next(null, {
...row,
groups: groups,
user_role: this.organizationUsersUtilService.convertUserRolesCasing(row?.user_role),
userMetadata: row?.metadata ? JSON.parse(row.metadata) : null,
email: row?.email?.toLowerCase(),
});
})
.validate(async (data: UserCsvRow, next) => {
await dbTransactionWrap(async (manager: EntityManager) => {
//Check for existing users
let isInvalidRole = false;
const user = await this.userRepository.findByEmail(data?.email, undefined, undefined, manager);
if (user?.status === USER_STATUS.ARCHIVED) {
archivedUsers.push(data?.email);
} else if (user?.organizationUsers?.some((ou) => ou.organizationId === currentUser.organizationId)) {
existingUsers.push(data?.email);
} else {
const user = {
firstName: data?.first_name,
lastName: data?.last_name,
email: data?.email,
role: data?.user_role,
groups: data?.groups,
userMetadata: data?.metadata,
};
users.push(user);
}
//Check for invalid groups
if (!Object.values(USER_ROLE).includes(data?.user_role as USER_ROLE)) {
invalidRoles.push(data?.user_role);
isInvalidRole = true;
}
data.first_name = data.first_name?.trim();
data.last_name = data.last_name?.trim();
const isValidName = data.first_name !== '' || data.last_name !== '';
return next(null, isValidName && emailPattern.test(data.email) && !isInvalidRole);
}, manager);
})
.on('data', function () {})
.on('data-invalid', (row, rowNumber) => {
const invalidField = Object.keys(row).filter((key) => {
if (Array.isArray(row[key])) {
return row[key].length === 0;
}
return !row[key] || row[key] === '';
});
invalidRows.push(rowNumber);
invalidFields.add(invalidField);
})
.on('end', async (rowCount: number) => {
try {
if (rowCount > MAX_ROW_COUNT) {
throw new BadRequestException('Row count cannot be greater than 500');
}
if (invalidRows.length) {
const invalidFieldsArray = invalidFields.entries().next().value[1];
const errorMsg = `Missing ${[invalidFieldsArray.join(',')]} information in ${
invalidRows.length
} row(s);. No users were uploaded, please update and try again.`;
throw new BadRequestException(errorMsg);
}
if (invalidGroups.length) {
throw new BadRequestException(
`${invalidGroups.length} group${isPlural(invalidGroups)} doesn't exist. No users were uploaded`
);
}
if (invalidRoles.length > 0) {
throw new BadRequestException('Invalid role present for the users');
}
if (archivedUsers.length) {
throw new BadRequestException(
`User${isPlural(archivedUsers)} with email ${archivedUsers.join(
', '
)} is archived. No users were uploaded`
);
}
if (existingUsers.length) {
throw new BadRequestException(
`${existingUsers.length} users with same email already exist. No users were uploaded `
);
}
if (users.length === 0) {
throw new BadRequestException('No users were uploaded');
}
if (users.length > 250) {
throw new BadRequestException(`You can only invite 250 users at a time`);
}
await this.organizationUsersUtilService.inviteUserswrapper(users, currentUser);
res.status(201).send({ message: `${rowCount} user${isPlural(users)} are being added` });
} catch (error) {
const { status, response } = error;
if (status === 451) {
res.status(status).send({ message: response, statusCode: status });
return;
}
res.status(status).send(JSON.stringify(response));
}
})
.on('error', (error) => {
throw error.message;
const groupPermissions = (
await this.groupPermissionsUtilService.getAllGroupByOrganization(currentUser.organizationId)
).groupPermissions?.filter((gp) => !gp.disabled);
const existingGroups = groupPermissions.map((groupPermission) => groupPermission.name);
csv
.parseString(fileStream.toString(), {
headers: ['first_name', 'last_name', 'email', 'user_role', 'groups', 'metadata'],
renameHeaders: true,
ignoreEmpty: true,
})
.transform((row: UserCsvRow, next) => {
const groupNames = this.organizationUsersUtilService.createGroupsList(row?.groups);
invalidGroups = [...invalidGroups, ...groupNames.filter((group) => !existingGroups.includes(group))];
const groups = groupPermissions.filter((group) => groupNames.includes(group.name)).map((group) => group.id);
return next(null, {
...row,
groups: groups,
user_role: this.organizationUsersUtilService.convertUserRolesCasing(row?.user_role),
userMetadata: row?.metadata ? JSON.parse(row.metadata) : null,
email: row?.email?.toLowerCase(),
});
});
})
.validate(async (data: UserCsvRow, next) => {
await dbTransactionWrap(async (manager: EntityManager) => {
//Check for existing users
let isInvalidRole = false;
const user = await this.userRepository.findByEmail(data?.email, undefined, undefined, manager);
if (user?.status === USER_STATUS.ARCHIVED) {
archivedUsers.push(data?.email);
} else if (user?.organizationUsers?.some((ou) => ou.organizationId === currentUser.organizationId)) {
existingUsers.push(data?.email);
} else {
const user = {
firstName: data?.first_name,
lastName: data?.last_name,
email: data?.email,
role: data?.user_role,
groups: data?.groups,
userMetadata: data?.metadata,
};
users.push(user);
}
//Check for invalid groups
if (!Object.values(USER_ROLE).includes(data?.user_role as USER_ROLE)) {
invalidRoles.push(data?.user_role);
isInvalidRole = true;
}
data.first_name = data.first_name?.trim();
data.last_name = data.last_name?.trim();
const isValidName = data.first_name !== '' || data.last_name !== '';
return next(null, isValidName && emailPattern.test(data.email) && !isInvalidRole);
});
})
.on('data', function () {})
.on('data-invalid', (row, rowNumber) => {
const invalidField = Object.keys(row).filter((key) => {
if (Array.isArray(row[key])) {
return row[key].length === 0;
}
return !row[key] || row[key] === '';
});
invalidRows.push(rowNumber);
invalidFields.add(invalidField);
})
.on('end', async (rowCount: number) => {
try {
if (rowCount > MAX_ROW_COUNT) {
throw new BadRequestException('Row count cannot be greater than 500');
}
if (invalidRows.length) {
const invalidFieldsArray = invalidFields.entries().next().value[1];
const errorMsg = `Missing ${[invalidFieldsArray.join(',')]} information in ${
invalidRows.length
} row(s);. No users were uploaded, please update and try again.`;
throw new BadRequestException(errorMsg);
}
if (invalidGroups.length) {
throw new BadRequestException(
`${invalidGroups.length} group${isPlural(invalidGroups)} doesn't exist. No users were uploaded`
);
}
if (invalidRoles.length > 0) {
throw new BadRequestException('Invalid role present for the users');
}
if (archivedUsers.length) {
throw new BadRequestException(
`User${isPlural(archivedUsers)} with email ${archivedUsers.join(
', '
)} is archived. No users were uploaded`
);
}
if (existingUsers.length) {
throw new BadRequestException(
`${existingUsers.length} users with same email already exist. No users were uploaded `
);
}
if (users.length === 0) {
throw new BadRequestException('No users were uploaded');
}
if (users.length > 250) {
throw new BadRequestException(`You can only invite 250 users at a time`);
}
await this.organizationUsersUtilService.inviteUserswrapper(users, currentUser);
res.status(201).send({ message: `${rowCount} user${isPlural(users)} are being added` });
} catch (error) {
const { status, response } = error;
if (status === 451) {
res.status(status).send({ message: response, statusCode: status });
return;
}
res.status(status).send(JSON.stringify(response));
}
})
.on('error', (error) => {
throw error.message;
});
}
async fetchUsersByValue(organizationId: string, searchInput: string) {