From 5dc1b9e3a8b3bd23a11b71093c742dab96dc5d52 Mon Sep 17 00:00:00 2001 From: OldHawk Date: Sun, 3 Dec 2017 20:17:51 +0800 Subject: [PATCH] feat(users): user can active idle account by score numbers in account status page #20 --- config/env/torrents.js | 10 ++-- modules/core/client/app/trans-string-en.js | 6 +++ modules/core/client/app/trans-string-zh.js | 6 +++ .../reset-passkey.client.controller.js | 3 ++ .../status/status.client.controller.js | 38 +++++++++++++- .../client/services/users.client.service.js | 7 +++ .../views/status/account.client.view.html | 2 +- .../users.authentication.server.controller.js | 6 +++ .../users/users.profile.server.controller.js | 50 ++++++++++++++++++- .../server/routes/users.server.routes.js | 1 + 10 files changed, 122 insertions(+), 7 deletions(-) diff --git a/config/env/torrents.js b/config/env/torrents.js index 22d4412f..78af8176 100644 --- a/config/env/torrents.js +++ b/config/env/torrents.js @@ -152,21 +152,23 @@ module.exports = { * @openSignup: set whether open the signup, if true, the user can signup(register) by herself, * if you create a private web site, and only accept invite to join, please set it to false. * @signUpActiveTokenExpires: sign up account active expires time setting. - * @accountIdleForTime: setting for how many time not login then change account status to idle * @allowSocialSignin: meanTorrent can accept social account to signin, like google, twitter, facebook etc. * if you do not want them to login, please set it to false * @showMenuHeaderForGuest: set whether show menu header for guest user(not sign in) * @showFooterCountInfoForGuest: set whether show count info at home footer for guest user(not sign in) * @showDemoSignMessage: if true, will show demo sign in message in sign in page, if your site is not demo site, please set it to false + * @accountIdleForTime: setting for how many time not login then change account status to idle + * @activeIdleAccountScore: user active idle account need score numbers */ sign: { openSignup: true, signUpActiveTokenExpires: 60 * 60 * 1000 * 24, - accountIdleForTime: 60 * 60 * 1000 * 30, //30 days allowSocialSignin: false, showMenuHeaderForGuest: true, showFooterCountInfoForGuest: true, - showDemoSignMessage: true + showDemoSignMessage: true, + accountIdleForTime: 60 * 60 * 1000 * 30, //30 days + activeIdleAccountScore: 50000 }, /** @@ -287,6 +289,8 @@ module.exports = { AdminUserEdit: {name: 'AdminUserEdit', enable: true}, userPasswordReset: {name: 'userPasswordReset', enable: true}, userSignUp: {name: 'userSignUp', enable: true}, + userActiveAccount: {name: 'userActiveAccount', enable: true}, + userUnIdle: {name: 'userUnIdle', enable: true}, AdminTorrentDelete: {name: 'AdminTorrentDelete', enable: true}, AdminTorrentSetSaleType: {name: 'AdminTorrentSetSaleType', enable: true}, diff --git a/modules/core/client/app/trans-string-en.js b/modules/core/client/app/trans-string-en.js index 575a66b5..f0b1fff1 100644 --- a/modules/core/client/app/trans-string-en.js +++ b/modules/core/client/app/trans-string-en.js @@ -645,6 +645,12 @@ SEEDING_LIST_ERROR: 'Get seeding list info failed', WARNING_LIST_ERROR: 'Get warning list info failed', DOWNLOADING_LIST_ERROR: 'Get downloading list info failed', + ACTIVE_IDLE_CONFIRM_OK: 'Active', + ACTIVE_IDLE_CONFIRM_CANCEL: 'Cancel', + ACTIVE_IDLE_CONFIRM_HEADER_TEXT: 'Active Confirm', + ACTIVE_IDLE_CONFIRM_BODY_TEXT: 'Are you sure want to active your account with {{score}} scores?', + ACTIVE_IDLE_SUCCESSFULLY: 'Active account successfully', + ACTIVE_IDLE_ERROR: 'Active account failed', STATUS_FIELD: { PICTURE: 'Profile picture', RESET_DEFAULT_PICTURE: 'Reset to default picture', diff --git a/modules/core/client/app/trans-string-zh.js b/modules/core/client/app/trans-string-zh.js index 9cc92fe6..30d8a384 100644 --- a/modules/core/client/app/trans-string-zh.js +++ b/modules/core/client/app/trans-string-zh.js @@ -645,6 +645,12 @@ SEEDING_LIST_ERROR: '获取我正做种的列表失败', WARNING_LIST_ERROR: '获取正被警告种子列表失败', DOWNLOADING_LIST_ERROR: '获取我正下载的列表失败', + ACTIVE_IDLE_CONFIRM_OK: '激活', + ACTIVE_IDLE_CONFIRM_CANCEL: '取消', + ACTIVE_IDLE_CONFIRM_HEADER_TEXT: '激活确认', + ACTIVE_IDLE_CONFIRM_BODY_TEXT: '您确认要使用 {{score}} 积分来重新激活您的帐户?', + ACTIVE_IDLE_SUCCESSFULLY: '激活帐户成功', + ACTIVE_IDLE_ERROR: '激活帐户失败', STATUS_FIELD: { PICTURE: '头像', RESET_DEFAULT_PICTURE: '重置为默认图片', diff --git a/modules/users/client/controllers/settings/reset-passkey.client.controller.js b/modules/users/client/controllers/settings/reset-passkey.client.controller.js index 0d1a328f..f98d5530 100644 --- a/modules/users/client/controllers/settings/reset-passkey.client.controller.js +++ b/modules/users/client/controllers/settings/reset-passkey.client.controller.js @@ -11,6 +11,9 @@ var vm = this; vm.user = Authentication.user; + /** + * resetPasskey + */ vm.resetPasskey = function () { var modalOptions = { closeButtonText: $translate.instant('RESET_PASSKEY_CONFIRM_CANCEL'), diff --git a/modules/users/client/controllers/status/status.client.controller.js b/modules/users/client/controllers/status/status.client.controller.js index 8cce2f76..5074a24f 100644 --- a/modules/users/client/controllers/status/status.client.controller.js +++ b/modules/users/client/controllers/status/status.client.controller.js @@ -5,13 +5,47 @@ .module('users') .controller('StatusController', StatusController); - StatusController.$inject = ['$scope', '$state', '$translate', '$timeout', 'Authentication', '$window', 'ScoreLevelService', 'MeanTorrentConfig']; + StatusController.$inject = ['$scope', '$state', '$timeout', '$translate', 'Authentication', 'UsersService', 'ScoreLevelService', 'MeanTorrentConfig', 'ModalConfirmService', + 'NotifycationService']; - function StatusController($scope, $state, $translate, $timeout, Authentication, $window, ScoreLevelService, MeanTorrentConfig) { + function StatusController($scope, $state, $timeout, $translate, Authentication, UsersService, ScoreLevelService, MeanTorrentConfig, ModalConfirmService, + NotifycationService) { var vm = this; vm.user = Authentication.user; vm.scoreLevelData = ScoreLevelService.getScoreLevelJson(vm.user.score); vm.announce = MeanTorrentConfig.meanTorrentConfig.announce; + vm.signConfig = MeanTorrentConfig.meanTorrentConfig.sign; + /** + * unIdle + */ + vm.unIdle = function () { + var modalOptions = { + closeButtonText: $translate.instant('ACTIVE_IDLE_CONFIRM_CANCEL'), + actionButtonText: $translate.instant('ACTIVE_IDLE_CONFIRM_OK'), + headerText: $translate.instant('ACTIVE_IDLE_CONFIRM_HEADER_TEXT'), + bodyText: $translate.instant('ACTIVE_IDLE_CONFIRM_BODY_TEXT', {score: vm.signConfig.activeIdleAccountScore}) + }; + + ModalConfirmService.showModal({}, modalOptions) + .then(function (result) { + UsersService.userUnIdle() + .then(onChangePasswordSuccess) + .catch(onChangePasswordError); + + function onChangePasswordSuccess(response) { + vm.user = Authentication.user = response; + + NotifycationService.showSuccessNotify('ACTIVE_IDLE_SUCCESSFULLY'); + $timeout(function () { + $state.go('home'); + }, 100); + } + + function onChangePasswordError(response) { + NotifycationService.showErrorNotify(response.data.message, 'ACTIVE_IDLE_ERROR'); + } + }); + }; } }()); diff --git a/modules/users/client/services/users.client.service.js b/modules/users/client/services/users.client.service.js index 77668eb1..fa7243bb 100644 --- a/modules/users/client/services/users.client.service.js +++ b/modules/users/client/services/users.client.service.js @@ -51,6 +51,10 @@ signin: { method: 'POST', url: '/api/auth/signin' + }, + unIdle: { + method: 'POST', + url: '/api/users/unIdle' } }); @@ -85,6 +89,9 @@ }, userSignin: function (credentials) { return this.signin(credentials).$promise; + }, + userUnIdle: function () { + return this.unIdle().$promise; } }); diff --git a/modules/users/client/views/status/account.client.view.html b/modules/users/client/views/status/account.client.view.html index 8f0281d4..3ed0cb8c 100644 --- a/modules/users/client/views/status/account.client.view.html +++ b/modules/users/client/views/status/account.client.view.html @@ -64,7 +64,7 @@
- {{ 'STATUS_FIELD.ACTIVE' | translate }} +
diff --git a/modules/users/server/controllers/users/users.authentication.server.controller.js b/modules/users/server/controllers/users/users.authentication.server.controller.js index f489d1e0..9a90faab 100644 --- a/modules/users/server/controllers/users/users.authentication.server.controller.js +++ b/modules/users/server/controllers/users/users.authentication.server.controller.js @@ -146,6 +146,12 @@ exports.active = function (req, res, next) { return res.redirect('/authentication/active?method=successfully'); } }); + + //create trace log + traceLogCreate(req, traceConfig.action.userActiveAccount, { + user: u._id, + token: req.params.token + }); } }); } diff --git a/modules/users/server/controllers/users/users.profile.server.controller.js b/modules/users/server/controllers/users/users.profile.server.controller.js index d9c5755b..ae06cc4c 100644 --- a/modules/users/server/controllers/users/users.profile.server.controller.js +++ b/modules/users/server/controllers/users/users.profile.server.controller.js @@ -14,10 +14,13 @@ var _ = require('lodash'), amazonS3URI = require('amazon-s3-uri'), config = require(path.resolve('./config/config')), User = mongoose.model('User'), - validator = require('validator'); + validator = require('validator'), + traceLogCreate = require(path.resolve('./config/lib/tracelog')).create; var whitelistedFields = ['firstName', 'lastName', 'email', 'username', 'hideMoreDetail']; var mtDebug = require(path.resolve('./config/lib/debug')); +var signConfig = config.meanTorrentConfig.sign; +var traceConfig = config.meanTorrentConfig.trace; var useS3Storage = config.uploads.storage === 's3' && config.aws.s3; var s3; @@ -243,3 +246,48 @@ exports.warningNumber = function (req, res, next) { }); } }; + +/** + * unIdle + * @param req + * @param res + * @param next + */ +exports.unIdle = function (req, res, next) { + var user = req.user; + + if (user) { + if (user.score < signConfig.activeIdleAccountScore) { + return res.status(422).send({ + message: 'SERVER.SCORE_NOT_ENOUGH' + }); + } else { + //update score + user.update({ + $set: { + score: req.user.score - signConfig.activeIdleAccountScore, + status: 'normal' + } + }).exec(); + + user.status = 'normal'; + req.login(user, function (err) { + if (err) { + res.status(400).send(err); + } else { + res.json(user); + } + }); + + //create trace log + traceLogCreate(req, traceConfig.action.userUnIdle, { + user: req.user._id, + score: signConfig.activeIdleAccountScore + }); + } + } else { + res.status(401).send({ + message: 'User is not signed in' + }); + } +}; diff --git a/modules/users/server/routes/users.server.routes.js b/modules/users/server/routes/users.server.routes.js index c6226eaa..0e96650a 100644 --- a/modules/users/server/routes/users.server.routes.js +++ b/modules/users/server/routes/users.server.routes.js @@ -10,6 +10,7 @@ module.exports = function (app) { app.route('/api/users/accounts').delete(users.removeOAuthProvider); app.route('/api/users/password').post(users.changePassword); app.route('/api/users/passkey').post(users.resetPasskey); + app.route('/api/users/unIdle').post(users.unIdle); app.route('/api/users/warningNumber').get(users.warningNumber); app.route('/api/users/picture').post(users.changeProfilePicture); app.route('/api/users/signature').post(users.changeSignature);