diff --git a/test/api/v3/integration/dataexport/GET-export_userdata.xml.test.js b/test/api/v3/integration/dataexport/GET-export_userdata.xml.test.js index 5973f439f7..f99b34d869 100644 --- a/test/api/v3/integration/dataexport/GET-export_userdata.xml.test.js +++ b/test/api/v3/integration/dataexport/GET-export_userdata.xml.test.js @@ -23,6 +23,17 @@ describe('GET /export/userdata.xml', () => { ]); + // add pinnedItem + await user.get('/user/toggle-pinned-item/marketGear/gear.flat.shield_rogue_5'); + + // add a private message + let receiver = await generateUser(); + + user.post('/members/send-private-message', { + message: 'Your first message, hi!', + toUserId: receiver._id, + }); + let response = await user.get('/export/userdata.xml'); let {user: res} = await parseStringAsync(response, {explicitArray: false}); diff --git a/webpack/config/index.js b/webpack/config/index.js index 35fa37adc8..ca098d0a95 100644 --- a/webpack/config/index.js +++ b/webpack/config/index.js @@ -66,6 +66,10 @@ module.exports = { target: DEV_BASE_URL, changeOrigin: true, }, + '/export': { + target: DEV_BASE_URL, + changeOrigin: true, + }, }, // CSS Sourcemaps off by default because relative paths are "buggy" // with this option, according to the CSS-Loader README diff --git a/website/server/controllers/top-level/dataexport.js b/website/server/controllers/top-level/dataexport.js index 7943355bb2..af59996f4f 100644 --- a/website/server/controllers/top-level/dataexport.js +++ b/website/server/controllers/top-level/dataexport.js @@ -83,7 +83,7 @@ api.exportUserHistory = { // Convert user to json and attach tasks divided by type // at user.tasks[`${taskType}s`] (user.tasks.{dailys/habits/...}) -async function _getUserDataForExport (user) { +async function _getUserDataForExport (user, xmlMode = false) { let userData = user.toJSON(); userData.tasks = {}; @@ -98,6 +98,33 @@ async function _getUserDataForExport (user) { userData.tasks[`${taskType}s`] = tasksPerType; }); + if (xmlMode) { + // object maps cant be parsed + userData.inbox.messages = _(userData.inbox.messages) + .map(m => { + const flags = Object.keys(m.flags); + m.flags = flags; + + return m; + }) + .value(); + + // _id gets parsed as an bytearray => which gets casted to a chararray => "weird chars" + userData.unpinnedItems = userData.unpinnedItems.map(i => { + return { + path: i.path, + type: i.type, + }; + }); + + userData.pinnedItems = userData.pinnedItems.map(i => { + return { + path: i.path, + type: i.type, + }; + }); + } + return userData; } @@ -137,7 +164,7 @@ api.exportUserDataXml = { url: '/export/userdata.xml', middlewares: [authWithSession], async handler (req, res) { - let userData = await _getUserDataForExport(res.locals.user); + let userData = await _getUserDataForExport(res.locals.user, true); res.set({ 'Content-Type': 'text/xml',