diff --git a/api/app.js b/api/app.js index 875fe0f..45e8ef9 100644 --- a/api/app.js +++ b/api/app.js @@ -63,6 +63,7 @@ router.get('/user/token', auth, user.token); router.get('/token', auth, user.token); router.get('/user/transaction', auth, user.transaction); router.post('/user/settings', auth, user.settings); +router.post('/user/delete', auth, user.deleteUser); router.post('/user/pro', auth, pro.create); router.delete('/user/pro', auth, pro.cancel); router.get('/file', auth, file.list); diff --git a/api/routes/user.js b/api/routes/user.js index d2ceae3..fe2f9f9 100644 --- a/api/routes/user.js +++ b/api/routes/user.js @@ -64,6 +64,24 @@ export async function settings(ctx) { ctx.body = {}; } +export async function deleteUser(ctx) { + ctx.assert( + ctx.request.body, 400, + '{"error": {"message": "Current Password required to update account.", "code": 612}}', + ); + ctx.assert( + ctx.request.body.current_password, 400, + '{"error": {"message": "Current Password required to update account.", "code": 612}}', + ); + const user = await models.user.findByPk(ctx.user.id); + ctx.assert( + await passwords.match(ctx.request.body.current_password, user.password), 400, + '{"error": {"message": "Incorrect password", "code": 606}}', + ); + await user.destroy(); + ctx.body = '{"action":"logout", "message": "Account deleted"}'; +} + export async function events(ctx) { const pubsub = redis.createClient(redisUrl); pubsub.on('message', (channel, message) => { diff --git a/docker-compose.yml b/docker-compose.yml index a6a05d6..4e4e8f8 100755 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -30,7 +30,7 @@ services: - export:/export ports: - "3000:3000" - command: yarn run start + command: yarn run watch-server worker: build: ./ environment: diff --git a/package.json b/package.json index b9a7f6d..1d04718 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,7 @@ "test": "yarn run test-seed && mocha -r babel-register test/**/*.spec.js", "test-seed": "babel-node test/fixtures/user.js", "watch": "concurrently -k -n watch-js,watch-sass \"yarn run watch-js\" \"yarn run watch-sass\"", - "watch-js": "webpack --mode=development --progress -c webpack.config.js", + "watch-js": "webpack -w --mode=development --progress -c webpack.config.js", "watch-server": "nodemon -r babel-register -i web/public", "watch-sass": "node-sass --include-path ./node_modules/ -w -r -o web/public/styles/ web/public/styles/" }, diff --git a/test/fixtures/user.js b/test/fixtures/user.js index 6de7f59..1eaeadd 100644 --- a/test/fixtures/user.js +++ b/test/fixtures/user.js @@ -1,4 +1,5 @@ import co from 'co'; +import passwords from 'passwords'; import models from '../../models'; @@ -6,9 +7,10 @@ import debugname from 'debug'; const debug = debugname('hostr:db'); function *createUser() { + const password = yield passwords.hash('test-password'); const user = yield models.user.create({ 'email': 'test@hostr.co', - 'password': '$pbkdf2-256-1$2$kBhIDRqFwnF/1ms6ZHfME2o2$a48e8c350d26397fcc88bf0a7a2817b1cdcd1ffffe0521a5', + 'password': password, 'ip': '127.0.0.1', 'plan': 'Free', 'activated': true, diff --git a/web/public/src/app/controllers.js b/web/public/src/app/controllers.js index 6266cdb..0e894e7 100644 --- a/web/public/src/app/controllers.js +++ b/web/public/src/app/controllers.js @@ -91,6 +91,16 @@ export class AccountController { $scope.error = response.data.error.message; }); }; + $scope.delete = (form) => { + $scope.updated = false; + $scope.error = false; + SettingService.delete(form).then(() => { + delete $scope.user.current_password; + window.location = '/logout'; + }, (response) => { + $scope.error = response.data.error.message; + }); + }; } } AccountController.$inject = ['$scope', 'UserService', 'SettingService']; diff --git a/web/public/src/app/services.js b/web/public/src/app/services.js index cb11391..0399a72 100644 --- a/web/public/src/app/services.js +++ b/web/public/src/app/services.js @@ -84,6 +84,9 @@ export class SettingService { service.update = (data) => { return $http.post(window.settings.apiURL + '/user/settings', data); }; + service.delete = (data) => { + return $http.post(window.settings.apiURL + '/user/delete', data); + }; return service; } diff --git a/web/public/src/partials/account.html b/web/public/src/partials/account.html index 46e6fe3..d21cb17 100644 --- a/web/public/src/partials/account.html +++ b/web/public/src/partials/account.html @@ -39,16 +39,16 @@
{{error}}
Updated your details successfully
- - + + Required. Password resets will be sent to this address.
- - + + Leave this field blank unless you want to update your password.
@@ -56,17 +56,43 @@
- - + + Required. When updating your details we require your current password.
- - +
+ +
+
+

Danger Zone

+ + +
+
{{error}}
+ +
+ + + + + Required. When deleting your account we require your current password. +
+ +
+ + +
+ + + +
+
+
diff --git a/web/public/styles/app.scss b/web/public/styles/app.scss index 893d80a..418e8a7 100644 --- a/web/public/styles/app.scss +++ b/web/public/styles/app.scss @@ -917,8 +917,11 @@ a { color: #FF524F; } - .btn-danger { - float: right; + .panel-danger { + margin-top: 75px; + h3 { + color: #FF524F; + } } form {