UNPKG

4.34 kBJavaScriptView Raw
1'use strict'
2
3const AuthRequest = require('./auth-request')
4const debug = require('./../debug').accounts
5const fs = require('fs-extra')
6
7class DeleteAccountConfirmRequest extends AuthRequest {
8 /**
9 * @constructor
10 * @param options {Object}
11 * @param options.accountManager {AccountManager}
12 * @param options.userStore {UserStore}
13 * @param options.response {ServerResponse} express response object
14 * @param [options.token] {string} One-time reset password token (from email)
15 */
16 constructor (options) {
17 super(options)
18
19 this.token = options.token
20 this.validToken = false
21 }
22
23 /**
24 * Factory method, returns an initialized instance of DeleteAccountConfirmRequest
25 * from an incoming http request.
26 *
27 * @param req {IncomingRequest}
28 * @param res {ServerResponse}
29 *
30 * @return {DeleteAccountConfirmRequest}
31 */
32 static fromParams (req, res) {
33 let locals = req.app.locals
34 let accountManager = locals.accountManager
35 let userStore = locals.oidc.users
36
37 let token = this.parseParameter(req, 'token')
38
39 let options = {
40 accountManager,
41 userStore,
42 token,
43 response: res
44 }
45
46 return new DeleteAccountConfirmRequest(options)
47 }
48
49 /**
50 * Handles a Change Password GET request on behalf of a middleware handler.
51 *
52 * @param req {IncomingRequest}
53 * @param res {ServerResponse}
54 *
55 * @return {Promise}
56 */
57 static async get (req, res) {
58 const request = DeleteAccountConfirmRequest.fromParams(req, res)
59
60 try {
61 await request.validateToken()
62 return request.renderForm()
63 } catch (error) {
64 return request.error(error)
65 }
66 }
67
68 /**
69 * Handles a Change Password POST request on behalf of a middleware handler.
70 *
71 * @param req {IncomingRequest}
72 * @param res {ServerResponse}
73 *
74 * @return {Promise}
75 */
76 static post (req, res) {
77 const request = DeleteAccountConfirmRequest.fromParams(req, res)
78
79 return DeleteAccountConfirmRequest.handlePost(request)
80 }
81
82 /**
83 * Performs the 'Change Password' operation, after the user submits the
84 * password change form. Validates the parameters (the one-time token,
85 * the new password), changes the password, and renders the success view.
86 *
87 * @param request {DeleteAccountConfirmRequest}
88 *
89 * @return {Promise}
90 */
91 static async handlePost (request) {
92 try {
93 const tokenContents = await request.validateToken()
94 await request.deleteAccount(tokenContents)
95 return request.renderSuccess()
96 } catch (error) {
97 return request.error(error)
98 }
99 }
100
101 /**
102 * Validates the one-time Password Reset token that was emailed to the user.
103 * If the token service has a valid token saved for the given key, it returns
104 * the token object value (which contains the user's WebID URI, etc).
105 * If no token is saved, returns `false`.
106 *
107 * @return {Promise<Object|false>}
108 */
109 async validateToken () {
110 try {
111 if (!this.token) {
112 return false
113 }
114 const validToken = await this.accountManager.validateDeleteToken(this.token)
115 if (validToken) {
116 this.validToken = true
117 }
118 return validToken
119 } catch (error) {
120 this.token = null
121 throw error
122 }
123 }
124
125 /**
126 * Removes the user's account and all their data from the store.
127 *
128 * @param tokenContents {Object}
129 *
130 * @return {Promise}
131 */
132 async deleteAccount (tokenContents) {
133 let user = this.accountManager.userAccountFrom(tokenContents)
134 let accountDir = this.accountManager.accountDirFor(user.username)
135
136 debug('Preparing removal of account for user:', user)
137
138 await this.userStore.deleteUser(user)
139 await fs.remove(accountDir)
140 debug('Removed user' + user.username)
141 }
142
143 /**
144 * Renders the 'change password' form.
145 *
146 * @param [error] {Error} Optional error to display
147 */
148 renderForm (error) {
149 let params = {
150 validToken: this.validToken,
151 token: this.token
152 }
153
154 if (error) {
155 params.error = error.message
156 this.response.status(error.statusCode)
157 }
158
159 this.response.render('account/delete-confirm', params)
160 }
161
162 /**
163 * Displays the 'password has been changed' success view.
164 */
165 renderSuccess () {
166 this.response.render('account/account-deleted')
167 }
168}
169
170module.exports = DeleteAccountConfirmRequest