forked from nodeSolidServer/node-solid-server
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathaccount-recovery.js
More file actions
119 lines (99 loc) · 3.55 KB
/
Copy pathaccount-recovery.js
File metadata and controls
119 lines (99 loc) · 3.55 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
module.exports = AccountRecovery
const express = require('express')
const TokenService = require('./token-service')
const bodyParser = require('body-parser')
const path = require('path')
const debug = require('debug')('solid:account-recovery')
const utils = require('./utils')
const sym = require('rdflib').sym
const url = require('url')
function AccountRecovery (corsSettings, options = {}) {
const router = express.Router('/')
const tokenService = new TokenService()
const generateEmail = function (host, account, email, token) {
return {
from: '"Account Recovery" <no-reply@' + account + '>',
to: email,
subject: 'Recover your account',
text: 'Hello,\n' +
'You asked to retrieve your account: ' + account + '\n' +
'Copy this address in your browser addressbar:\n\n' +
'https://' + path.join(host, '/recovery/confirm?token=' + token) // TODO find a way to get the full url
// html: ''
}
}
if (corsSettings) {
router.use(corsSettings)
}
router.get('/request', function (req, res, next) {
res.set('Content-Type', 'text/html')
res.sendFile(path.join(__dirname, '../static/account-recovery.html'))
})
router.post('/request', bodyParser.urlencoded({ extended: false }), function (req, res, next) {
debug('getting request for account recovery', req.body.webid)
const ldp = req.app.locals.ldp
const emailService = req.app.locals.email
const baseUri = utils.uriAbs(req)
// if (!req.body.webid) {
// res.status(406).send('You need to pass an account')
// return
// }
// Check if account exists
let webid = url.parse(req.body.webid)
let hostname = webid.hostname
ldp.graph(hostname, '/' + ldp.suffixAcl, baseUri, function (err, graph) {
if (err) {
debug('cannot find graph of the user', req.body.webid || ldp.root, err)
res.status(err.status || 500).send('Fail to find user')
return
}
// TODO do a query
let emailAddress
graph
.statementsMatching(undefined, sym('http://www.w3.org/ns/auth/acl#agent'))
.some(function (statement) {
if (statement.object.uri.startsWith('mailto:')) {
emailAddress = statement.object.uri
return true
}
})
if (!emailAddress) {
res.status(406).send('No emailAddress registered in your account')
return
}
const token = tokenService.generate({ webid: req.body.webid })
const email = generateEmail(req.get('host'), req.body.webid, emailAddress, token)
emailService.sendMail(email, function (err, info) {
if (err) {
res.send(500, 'Failed to send the email for account recovery, try again')
return
}
res.send('Requested')
})
})
})
router.get('/confirm', function (req, res, next) {
if (!req.query.token) {
res.status(406).send('Token is required')
return
}
const tokenContent = tokenService.verify(req.query.token)
if (!tokenContent) {
debug('token was not found', tokenContent)
res.status(401).send('Token not valid')
return
}
if (tokenContent && !tokenContent.webid) {
debug('token does not match account', tokenContent)
res.status(401).send('Token not valid')
return
}
debug('token was valid', tokenContent)
tokenService.remove(req.query.token)
req.session.userId = tokenContent.webid // TODO add the full path
req.session.identified = true
res.set('User', tokenContent.webid)
res.redirect(options.redirect)
})
return router
}