Skip to content

Commit bcbb8c6

Browse files
committed
Add note export function
This function is the first step to get out data following GDPR about the transportability of data. Details: https://gdpr-info.eu/art-20-gdpr/ Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
1 parent 70df297 commit bcbb8c6

1 file changed

Lines changed: 56 additions & 0 deletions

File tree

lib/web/userRouter.js

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
'use strict'
22

3+
const archiver = require('archiver')
4+
const async = require('async')
35
const Router = require('express').Router
46

57
const response = require('../response')
@@ -64,6 +66,60 @@ UserRouter.get('/me/delete/:token?', function (req, res) {
6466
}
6567
})
6668

69+
// export the data of the authenticated user
70+
UserRouter.get('/me/export', function (req, res) {
71+
if (req.isAuthenticated()) {
72+
// let output = fs.createWriteStream(__dirname + '/example.zip');
73+
let archive = archiver('zip', {
74+
zlib: { level: 3 } // Sets the compression level.
75+
})
76+
res.setHeader('Content-Type', 'application/zip')
77+
res.attachment('archive.zip')
78+
archive.pipe(res)
79+
archive.on('error', function (err) {
80+
logger.error('export user data failed: ' + err)
81+
return response.errorInternalError(res)
82+
})
83+
models.User.findOne({
84+
where: {
85+
id: req.user.id
86+
}
87+
}).then(function (user) {
88+
models.Note.findAll({
89+
where: {
90+
ownerId: user.id
91+
}
92+
}).then(function (notes) {
93+
let list = []
94+
async.each(notes, function (note, callback) {
95+
let title
96+
let extension = ''
97+
do {
98+
title = note.title + extension
99+
extension++
100+
} while (list.indexOf(title) !== -1)
101+
102+
list.push(title)
103+
logger.debug('Write: ' + title + '.md')
104+
archive.append(Buffer.from(note.content), { name: title + '.md', date: note.lastchangeAt })
105+
callback(null, null)
106+
}, function (err) {
107+
if (err) {
108+
return response.errorInternalError(res)
109+
}
110+
111+
archive.finalize()
112+
})
113+
})
114+
}).catch(function (err) {
115+
logger.error('export user data failed: ' + err)
116+
return response.errorInternalError(res)
117+
})
118+
} else {
119+
return response.errorForbidden(res)
120+
}
121+
})
122+
67123
UserRouter.get('/user/:username/avatar.svg', function (req, res, next) {
68124
res.setHeader('Content-Type', 'image/svg+xml')
69125
res.setHeader('Cache-Control', 'public, max-age=86400')

0 commit comments

Comments
 (0)