Fix: Impersonate user can now export Excel/CSV/TSV/JSON.

Impersonate user and export Excel/CSV/TSV/JSON is now logged into
database table impersonatedUsers.

Thanks to xet7 !

Fixes #3827,
fixes #3284
This commit is contained in:
Lauri Ojansivu 2021-05-29 00:19:12 +03:00
parent 6be1a33093
commit 3908cd5413
5 changed files with 559 additions and 213 deletions

View file

@ -21,16 +21,21 @@ if (Meteor.isServer) {
* @param {string} authToken the loginToken
*/
const Excel = require('exceljs');
Picker.route('/api/boards/:boardId/exportExcel', function(params, req, res) {
Picker.route('/api/boards/:boardId/exportExcel', function (params, req, res) {
const boardId = params.boardId;
let user = null;
let impersonateDone = false;
let adminId = null;
const loginToken = params.query.authToken;
if (loginToken) {
const hashToken = Accounts._hashLoginToken(loginToken);
user = Meteor.users.findOne({
'services.resume.loginTokens.hashedToken': hashToken,
});
adminId = user._id.toString();
impersonateDone = ImpersonatedUsers.findOne({
adminId: adminId,
});
} else if (!Meteor.settings.public.sandstorm) {
Authentication.checkUserId(req.userId);
user = Users.findOne({
@ -39,7 +44,14 @@ if (Meteor.isServer) {
});
}
const exporterExcel = new ExporterExcel(boardId);
if (exporterExcel.canExport(user)) {
if (exporterExcel.canExport(user) || impersonateDone) {
if (impersonateDone) {
ImpersonatedUsers.insert({
adminId: adminId,
boardId: boardId,
reason: 'exportExcel',
});
}
exporterExcel.build(res);
} else {
res.end(TAPi18n.__('user-can-not-export-excel'));
@ -108,7 +120,7 @@ export class ExporterExcel {
result.subtaskItems = [];
result.triggers = [];
result.actions = [];
result.cards.forEach(card => {
result.cards.forEach((card) => {
result.checklists.push(
...Checklists.find({
cardId: card._id,
@ -125,7 +137,7 @@ export class ExporterExcel {
}).fetch(),
);
});
result.rules.forEach(rule => {
result.rules.forEach((rule) => {
result.triggers.push(
...Triggers.find(
{
@ -149,32 +161,32 @@ export class ExporterExcel {
// 1- only exports users that are linked somehow to that board
// 2- do not export any sensitive information
const users = {};
result.members.forEach(member => {
result.members.forEach((member) => {
users[member.userId] = true;
});
result.lists.forEach(list => {
result.lists.forEach((list) => {
users[list.userId] = true;
});
result.cards.forEach(card => {
result.cards.forEach((card) => {
users[card.userId] = true;
if (card.members) {
card.members.forEach(memberId => {
card.members.forEach((memberId) => {
users[memberId] = true;
});
}
if (card.assignees) {
card.assignees.forEach(memberId => {
card.assignees.forEach((memberId) => {
users[memberId] = true;
});
}
});
result.comments.forEach(comment => {
result.comments.forEach((comment) => {
users[comment.userId] = true;
});
result.activities.forEach(activity => {
result.activities.forEach((activity) => {
users[activity.userId] = true;
});
result.checklists.forEach(checklist => {
result.checklists.forEach((checklist) => {
users[checklist.userId] = true;
});
const byUserIds = {
@ -194,7 +206,7 @@ export class ExporterExcel {
};
result.users = Users.find(byUserIds, userFields)
.fetch()
.map(user => {
.map((user) => {
// user avatar is stored as a relative url, we export absolute
if ((user.profile || {}).avatarUrl) {
user.profile.avatarUrl = FlowRouter.url(user.profile.avatarUrl);
@ -389,7 +401,7 @@ export class ExporterExcel {
const jlabel = {};
var isFirst = 1;
for (const klabel in result.labels) {
console.log(klabel);
// console.log(klabel);
if (isFirst == 0) {
jlabel[result.labels[klabel]._id] = `,${result.labels[klabel].name}`;
} else {
@ -589,7 +601,7 @@ export class ExporterExcel {
//get parent name
if (jcard.parentId) {
const parentCard = result.cards.find(
card => card._id === jcard.parentId,
(card) => card._id === jcard.parentId,
);
jcard.parentCardTitle = parentCard ? parentCard.title : '';
}
@ -653,7 +665,7 @@ export class ExporterExcel {
wrapText: true,
};
}
workbook.xlsx.write(res).then(function() {});
workbook.xlsx.write(res).then(function () {});
}
canExport(user) {