mirror of
https://github.com/taobataoma/meanTorrent.git
synced 2026-02-27 16:50:59 +01:00
feat(users): add feature for verify mail address and active account by mail
This commit is contained in:
1
config/env/torrents.js
vendored
1
config/env/torrents.js
vendored
@@ -156,6 +156,7 @@ module.exports = {
|
||||
*/
|
||||
sign: {
|
||||
openSignup: true,
|
||||
signUpActiveTokenExpires: 60 * 60 * 1000 * 2,
|
||||
allowSocialSignin: false,
|
||||
showDemoSignMessage: true
|
||||
},
|
||||
|
||||
@@ -144,6 +144,7 @@
|
||||
|
||||
//page title
|
||||
PAGETITLE: {
|
||||
ACCOUNT_ACTIVE: 'Account Active',
|
||||
UPLOAD: 'Upload',
|
||||
MOVIE_LIST: 'Movie List',
|
||||
TV_LIST: 'TV List',
|
||||
@@ -229,7 +230,12 @@
|
||||
ENTER_USERNAME: 'Enter your account username or email.',
|
||||
RESET_PASS_OK: 'Password successfully reset',
|
||||
RESET_PASS_INVALID: 'Password reset is invalid',
|
||||
RE_RESET_PASSWORD: 'Ask for a new password reset?'
|
||||
RE_RESET_PASSWORD: 'Ask for a new password reset?',
|
||||
|
||||
ACTIVE_INVALID: 'Can not active your account, maybe this token already used or this token is expired.',
|
||||
ACTIVE_ERROR: 'Account active ERROR!',
|
||||
ACTIVE_FAILED: 'Account active and login failed',
|
||||
ACTIVE_SUCCESSFULLY: 'Account active successfully, will redirect to home after 3 seconds automate.'
|
||||
},
|
||||
|
||||
//TorrentsController & views
|
||||
@@ -1143,6 +1149,11 @@
|
||||
ANDROID: 'Android',
|
||||
CAR: 'Car'
|
||||
}
|
||||
},
|
||||
|
||||
//server returned string
|
||||
SERVER: {
|
||||
SENDING_ACTIVE_MAIL_SUCCESSFULLY: 'Welcome join <strong>{{site}}</strong>, We`ve sent you an email to <strong>{{mail}}</strong>, please check you mail box and click the active url to verify you mail address and active you account in <strong>{{hours}}</strong> hours, thanks!'
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -144,6 +144,7 @@
|
||||
|
||||
//page title
|
||||
PAGETITLE: {
|
||||
ACCOUNT_ACTIVE: '帐号激活',
|
||||
UPLOAD: '上传',
|
||||
MOVIE_LIST: '电影列表',
|
||||
TV_LIST: '电视剧列表',
|
||||
@@ -229,7 +230,12 @@
|
||||
ENTER_USERNAME: '请输入你的帐号用户名或注册邮箱',
|
||||
RESET_PASS_OK: '密码重置成功',
|
||||
RESET_PASS_INVALID: '密码重置失败',
|
||||
RE_RESET_PASSWORD: '再次请求重置密码?'
|
||||
RE_RESET_PASSWORD: '再次请求重置密码?',
|
||||
|
||||
ACTIVE_INVALID: '帐户激活失败, 可能该链接已被使用或者已失效.',
|
||||
ACTIVE_ERROR: '帐户激活错误!',
|
||||
ACTIVE_FAILED: '帐户激活与登录失败',
|
||||
ACTIVE_SUCCESSFULLY: '帐户激活成功, 3秒钟后将自动跳转到首页.'
|
||||
},
|
||||
|
||||
//TorrentsController & views
|
||||
@@ -1143,6 +1149,11 @@
|
||||
ANDROID: 'Android',
|
||||
CAR: 'Car'
|
||||
}
|
||||
},
|
||||
|
||||
//server returned string
|
||||
SERVER: {
|
||||
SENDING_ACTIVE_MAIL_SUCCESSFULLY: '欢迎加入 <strong>{{site}}</strong>, 我们已向你的邮箱 <strong>{{mail}}</strong> 发送了一封电子邮件, 请在 <strong>{{hours}}</strong> 小时内检查您的邮箱并点击邮件中的链接地址来验证您的邮箱地址并激您的帐号,谢谢!'
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -30,6 +30,10 @@
|
||||
margin-top: 50px;
|
||||
}
|
||||
|
||||
.margin-top-100 {
|
||||
margin-top: 100px;
|
||||
}
|
||||
|
||||
.margin-bottom-5 {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
@@ -114,6 +118,10 @@
|
||||
padding-top: 50px;
|
||||
}
|
||||
|
||||
.padding-top-100 {
|
||||
padding-top: 100px;
|
||||
}
|
||||
|
||||
.padding-bottom-10 {
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
@@ -40,6 +40,10 @@ body {
|
||||
}
|
||||
}
|
||||
|
||||
.active-notice {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.backdrop {
|
||||
background-image: url("http://image.tmdb.org/t/p/w1280/5pAGnkFYSsFJ99ZxDIYnhQbQFXs.jpg");
|
||||
background-position: center;
|
||||
|
||||
@@ -149,6 +149,15 @@
|
||||
pageTitle: 'SIGNIN'
|
||||
}
|
||||
})
|
||||
.state('authentication.active', {
|
||||
url: '/active?method',
|
||||
templateUrl: '/modules/users/client/views/authentication/active.client.view.html',
|
||||
controller: 'AuthenticationController',
|
||||
controllerAs: 'vm',
|
||||
data: {
|
||||
pageTitle: 'PAGETITLE.ACCOUNT_ACTIVE'
|
||||
}
|
||||
})
|
||||
.state('authentication.invite', {
|
||||
abstract: true,
|
||||
url: '/invite',
|
||||
|
||||
@@ -5,15 +5,16 @@
|
||||
.module('users')
|
||||
.controller('AuthenticationController', AuthenticationController);
|
||||
|
||||
AuthenticationController.$inject = ['$scope', '$state', 'UsersService', '$location', '$window', 'Authentication', 'PasswordValidator', 'Notification',
|
||||
AuthenticationController.$inject = ['$scope', '$state', 'UsersService', '$location', '$window', '$timeout', 'Authentication', 'PasswordValidator', 'Notification',
|
||||
'MeanTorrentConfig', 'getStorageLangService', '$rootScope', '$stateParams', 'InvitationsService'];
|
||||
|
||||
function AuthenticationController($scope, $state, UsersService, $location, $window, Authentication, PasswordValidator, Notification, MeanTorrentConfig,
|
||||
function AuthenticationController($scope, $state, UsersService, $location, $window, $timeout, Authentication, PasswordValidator, Notification, MeanTorrentConfig,
|
||||
getStorageLangService, $rootScope, $stateParams, InvitationsService) {
|
||||
var vm = this;
|
||||
|
||||
vm.lang = getStorageLangService.getLang();
|
||||
vm.signConfig = MeanTorrentConfig.meanTorrentConfig.sign;
|
||||
vm.appConfig = MeanTorrentConfig.meanTorrentConfig.app;
|
||||
vm.authentication = Authentication;
|
||||
vm.getPopoverMsg = PasswordValidator.getPopoverMsg;
|
||||
vm.signup = signup;
|
||||
@@ -22,14 +23,19 @@
|
||||
vm.usernameRegex = /^(?=[\w.-]+$)(?!.*[._-]{2})(?!\.)(?!.*\.$).{3,34}$/;
|
||||
vm.credentials = {};
|
||||
|
||||
vm.activeMethod = $state.params.method;
|
||||
// Get an eventual error defined in the URL query string:
|
||||
if ($location.search().err) {
|
||||
Notification.error({message: $location.search().err});
|
||||
}
|
||||
|
||||
// If user is signed in then redirect back home
|
||||
if (vm.authentication.user) {
|
||||
$location.path('/');
|
||||
/**
|
||||
* account active successfully, redirect to home after 2 seconds
|
||||
*/
|
||||
if (vm.activeMethod === 'successfully') {
|
||||
$timeout(function () {
|
||||
$state.go('home');
|
||||
}, 3000);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -69,6 +75,16 @@
|
||||
UsersService.userSignup(vm.credentials)
|
||||
.then(onUserSignupSuccess)
|
||||
.catch(onUserSignupError);
|
||||
|
||||
function onUserSignupSuccess(response) {
|
||||
vm.waitToActive = true;
|
||||
vm.waitToActiveTranslate = response.message;
|
||||
}
|
||||
|
||||
function onUserSignupError(response) {
|
||||
Notification.error({message: response.data.message, title: '<i class="glyphicon glyphicon-remove"></i> Signup Error!', delay: 6000});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -87,6 +103,20 @@
|
||||
UsersService.userSignin(vm.credentials)
|
||||
.then(onUserSigninSuccess)
|
||||
.catch(onUserSigninError);
|
||||
|
||||
function onUserSigninSuccess(response) {
|
||||
// If successful we assign the response to the global user model
|
||||
vm.authentication.user = response;
|
||||
$rootScope.$broadcast('auth-user-changed');
|
||||
$rootScope.$broadcast('user-invitations-changed');
|
||||
Notification.info({message: 'Welcome ' + response.firstName});
|
||||
// And redirect to the previous or home page
|
||||
$state.go($state.previous.state.name || 'home', $state.previous.params);
|
||||
}
|
||||
|
||||
function onUserSigninError(response) {
|
||||
Notification.error({message: response.data.message, title: '<i class="glyphicon glyphicon-remove"></i> Signin Error!', delay: 6000});
|
||||
}
|
||||
}
|
||||
|
||||
// OAuth provider request
|
||||
@@ -103,51 +133,6 @@
|
||||
$window.location.href = url;
|
||||
}
|
||||
|
||||
// Authentication Callbacks
|
||||
/**
|
||||
* onUserSignupSuccess
|
||||
* @param response
|
||||
*/
|
||||
function onUserSignupSuccess(response) {
|
||||
// If successful we assign the response to the global user model
|
||||
vm.authentication.user = response;
|
||||
$rootScope.$broadcast('auth-user-changed');
|
||||
$rootScope.$broadcast('user-invitations-changed');
|
||||
Notification.success({message: '<i class="glyphicon glyphicon-ok"></i> Signup successful!'});
|
||||
// And redirect to the previous or home page
|
||||
$state.go($state.previous.state.name || 'home', $state.previous.params);
|
||||
}
|
||||
|
||||
/**
|
||||
* onUserSignupError
|
||||
* @param response
|
||||
*/
|
||||
function onUserSignupError(response) {
|
||||
Notification.error({message: response.data.message, title: '<i class="glyphicon glyphicon-remove"></i> Signup Error!', delay: 6000});
|
||||
}
|
||||
|
||||
/**
|
||||
* onUserSigninSuccess
|
||||
* @param response
|
||||
*/
|
||||
function onUserSigninSuccess(response) {
|
||||
// If successful we assign the response to the global user model
|
||||
vm.authentication.user = response;
|
||||
$rootScope.$broadcast('auth-user-changed');
|
||||
$rootScope.$broadcast('user-invitations-changed');
|
||||
Notification.info({message: 'Welcome ' + response.firstName});
|
||||
// And redirect to the previous or home page
|
||||
$state.go($state.previous.state.name || 'home', $state.previous.params);
|
||||
}
|
||||
|
||||
/**
|
||||
* onUserSigninError
|
||||
* @param response
|
||||
*/
|
||||
function onUserSigninError(response) {
|
||||
Notification.error({message: response.data.message, title: '<i class="glyphicon glyphicon-remove"></i> Signin Error!', delay: 6000});
|
||||
}
|
||||
|
||||
/**
|
||||
* markLinkClick
|
||||
* @param evt
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
<div>
|
||||
<div class="col-sm-10 col-sm-offset-1 margin-top-100 padding-top-20">
|
||||
<div ng-if="vm.activeMethod === 'invalid'">
|
||||
<span class="active-notice text-danger" translate="SIGN.ACTIVE_INVALID"></span>
|
||||
</div>
|
||||
<div ng-if="vm.activeMethod === 'error'">
|
||||
<span class="active-notice text-danger" translate="SIGN.ACTIVE_ERROR"></span>
|
||||
</div>
|
||||
<div ng-if="vm.activeMethod === 'failed'">
|
||||
<span class="active-notice text-danger" translate="SIGN.ACTIVE_FAILED"></span>
|
||||
</div>
|
||||
<div ng-if="vm.activeMethod === 'successfully'">
|
||||
<span class="active-notice text-success" translate="SIGN.ACTIVE_SUCCESSFULLY"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -4,74 +4,82 @@
|
||||
</div>
|
||||
</div>
|
||||
<div ng-if="vm.signConfig.openSignup || vm.validToken">
|
||||
<legend class="col-sm-10 col-sm-offset-1 small-legend margin-top-40">{{ 'SIGN.SIGN_UP' | translate}}</legend>
|
||||
<div ng-if="!vm.waitToActive">
|
||||
<legend class="col-sm-10 col-sm-offset-1 small-legend margin-top-40">{{ 'SIGN.SIGN_UP' | translate}}</legend>
|
||||
|
||||
<div class="col-sm-8 col-sm-offset-2">
|
||||
<form name="vm.userForm" ng-submit="vm.signup(vm.userForm.$valid)" class="signin" novalidate autocomplete="off">
|
||||
<fieldset>
|
||||
<div class="form-group" show-errors>
|
||||
<input type="text" id="firstName" name="firstName" class="form-control" ng-model="vm.credentials.firstName"
|
||||
placeholder="{{ 'STATUS_FIELD.FIRST_NAME' | translate}}" required autofocus>
|
||||
<div class="col-sm-8 col-sm-offset-2">
|
||||
<form name="vm.userForm" ng-submit="vm.signup(vm.userForm.$valid)" class="signin" novalidate autocomplete="off">
|
||||
<fieldset>
|
||||
<div class="form-group" show-errors>
|
||||
<input type="text" id="firstName" name="firstName" class="form-control" ng-model="vm.credentials.firstName"
|
||||
placeholder="{{ 'STATUS_FIELD.FIRST_NAME' | translate}}" required autofocus>
|
||||
|
||||
<div ng-messages="vm.userForm.firstName.$error" role="alert">
|
||||
<p class="help-block error-text" ng-message="required">{{ 'SIGN.FN_REQUIRED' | translate}}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group" show-errors>
|
||||
<input type="text" id="lastName" name="lastName" class="form-control" ng-model="vm.credentials.lastName"
|
||||
placeholder="{{ 'STATUS_FIELD.LAST_NAME' | translate}}" required>
|
||||
|
||||
<div ng-messages="vm.userForm.lastName.$error" role="alert">
|
||||
<p class="help-block error-text" ng-message="required">{{ 'SIGN.LN_REQUIRED' | translate}}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group" show-errors>
|
||||
<input type="email" id="email" name="email" class="form-control" ng-model="vm.credentials.email" lowercase
|
||||
placeholder="{{ 'STATUS_FIELD.EMAIL' | translate}}" required ng-readonly="vm.emailReadonly">
|
||||
|
||||
<div ng-messages="vm.userForm.email.$error" role="alert">
|
||||
<p class="help-block error-text" ng-message="required">{{ 'SIGN.E_REQUIRED' | translate}}</p>
|
||||
|
||||
<p class="help-block error-text" ng-message="email">{{ 'SIGN.E_INVALID' | translate}}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group" show-errors>
|
||||
<input type="text" id="username" name="username" class="form-control" ng-model="vm.credentials.username"
|
||||
placeholder="{{ 'STATUS_FIELD.USERNAME' | translate}}" ng-pattern="vm.usernameRegex" lowercase required>
|
||||
|
||||
<div ng-messages="vm.userForm.username.$error" role="alert">
|
||||
<p class="help-block error-text" ng-message="required">{{ 'SIGN.U_REQUIRED' | translate}}</p>
|
||||
|
||||
<p class="help-block error-text"
|
||||
ng-message="pattern">{{ 'SIGN.U_PATTERN' | translate}}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group" show-errors>
|
||||
<input type="password" id="password" name="password" class="form-control" ng-model="vm.credentials.password"
|
||||
placeholder="{{ 'SIGN.PASSWORD' | translate}}"
|
||||
uib-popover="{{vm.getPopoverMsg()}}" popover-trigger="'outsideClick'"
|
||||
popover-placement="top-right" password-validator required>
|
||||
|
||||
<div ng-messages="vm.userForm.password.$error" role="alert">
|
||||
<p class="help-block error-text" ng-message="required">{{ 'SIGN.P_REQUIRED' | translate}}</p>
|
||||
|
||||
<div ng-repeat="passwordError in passwordErrors">
|
||||
<p class="help-block error-text" ng-show="vm.userForm.password.$error.requirements">{{passwordError}}</p>
|
||||
<div ng-messages="vm.userForm.firstName.$error" role="alert">
|
||||
<p class="help-block error-text" ng-message="required">{{ 'SIGN.FN_REQUIRED' | translate}}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group" ng-show="!vm.userForm.password.$error.required">
|
||||
<label>{{ 'SIGN.PASSWORD_REQ' | translate}}</label>
|
||||
<uib-progressbar value="requirementsProgress" type="{{requirementsColor}}"><span
|
||||
style="color:white; white-space:nowrap;">{{requirementsProgress}}%</span></uib-progressbar>
|
||||
</div>
|
||||
<div class="text-center form-group">
|
||||
<button type="submit" class="btn btn-primary">{{ 'SIGN.BTN_SIGN_UP' | translate}}</button>
|
||||
or
|
||||
<a ui-sref="authentication.signin" class="show-signup">{{ 'SIGN.BTN_SIGN_IN' | translate}}</a>
|
||||
</div>
|
||||
</fieldset>
|
||||
</form>
|
||||
<div class="form-group" show-errors>
|
||||
<input type="text" id="lastName" name="lastName" class="form-control" ng-model="vm.credentials.lastName"
|
||||
placeholder="{{ 'STATUS_FIELD.LAST_NAME' | translate}}" required>
|
||||
|
||||
<div ng-messages="vm.userForm.lastName.$error" role="alert">
|
||||
<p class="help-block error-text" ng-message="required">{{ 'SIGN.LN_REQUIRED' | translate}}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group" show-errors>
|
||||
<input type="email" id="email" name="email" class="form-control" ng-model="vm.credentials.email" lowercase
|
||||
placeholder="{{ 'STATUS_FIELD.EMAIL' | translate}}" required ng-readonly="vm.emailReadonly">
|
||||
|
||||
<div ng-messages="vm.userForm.email.$error" role="alert">
|
||||
<p class="help-block error-text" ng-message="required">{{ 'SIGN.E_REQUIRED' | translate}}</p>
|
||||
|
||||
<p class="help-block error-text" ng-message="email">{{ 'SIGN.E_INVALID' | translate}}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group" show-errors>
|
||||
<input type="text" id="username" name="username" class="form-control" ng-model="vm.credentials.username"
|
||||
placeholder="{{ 'STATUS_FIELD.USERNAME' | translate}}" ng-pattern="vm.usernameRegex" lowercase required>
|
||||
|
||||
<div ng-messages="vm.userForm.username.$error" role="alert">
|
||||
<p class="help-block error-text" ng-message="required">{{ 'SIGN.U_REQUIRED' | translate}}</p>
|
||||
|
||||
<p class="help-block error-text"
|
||||
ng-message="pattern">{{ 'SIGN.U_PATTERN' | translate}}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group" show-errors>
|
||||
<input type="password" id="password" name="password" class="form-control" ng-model="vm.credentials.password"
|
||||
placeholder="{{ 'SIGN.PASSWORD' | translate}}"
|
||||
uib-popover="{{vm.getPopoverMsg()}}" popover-trigger="'outsideClick'"
|
||||
popover-placement="top-right" password-validator required>
|
||||
|
||||
<div ng-messages="vm.userForm.password.$error" role="alert">
|
||||
<p class="help-block error-text" ng-message="required">{{ 'SIGN.P_REQUIRED' | translate}}</p>
|
||||
|
||||
<div ng-repeat="passwordError in passwordErrors">
|
||||
<p class="help-block error-text" ng-show="vm.userForm.password.$error.requirements">{{passwordError}}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group" ng-show="!vm.userForm.password.$error.required">
|
||||
<label>{{ 'SIGN.PASSWORD_REQ' | translate}}</label>
|
||||
<uib-progressbar value="requirementsProgress" type="{{requirementsColor}}"><span
|
||||
style="color:white; white-space:nowrap;">{{requirementsProgress}}%</span></uib-progressbar>
|
||||
</div>
|
||||
<div class="text-center form-group">
|
||||
<button type="submit" class="btn btn-primary">{{ 'SIGN.BTN_SIGN_UP' | translate}}</button>
|
||||
or
|
||||
<a ui-sref="authentication.signin" class="show-signup">{{ 'SIGN.BTN_SIGN_IN' | translate}}</a>
|
||||
</div>
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div ng-if="vm.waitToActive">
|
||||
<div class="col-sm-10 col-sm-offset-1 margin-top-100 padding-top-20">
|
||||
<span class="active-notice" translate="SERVER.{{vm.waitToActiveTranslate}}"
|
||||
translate-values="{site: vm.appConfig.name, mail: vm.credentials.email, hours: vm.signConfig.signUpActiveTokenExpires / (60*60*1000)}"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -10,8 +10,12 @@ var path = require('path'),
|
||||
passport = require('passport'),
|
||||
User = mongoose.model('User'),
|
||||
Invitation = mongoose.model('Invitation'),
|
||||
nodemailer = require('nodemailer'),
|
||||
traceLogCreate = require(path.resolve('./config/lib/tracelog')).create;
|
||||
|
||||
var smtpTransport = nodemailer.createTransport(config.mailer.options);
|
||||
var mtConfig = config.meanTorrentConfig;
|
||||
|
||||
// URLs for which user can't be redirected on signin
|
||||
var noReturnUrls = [
|
||||
'/authentication/signin',
|
||||
@@ -33,6 +37,9 @@ exports.signup = function (req, res) {
|
||||
user.displayName = user.firstName + ' ' + user.lastName;
|
||||
user.passkey = user.randomAsciiString(32);
|
||||
|
||||
user.signUpActiveToken = user.randomAsciiString(32);
|
||||
user.signUpActiveExpires = Date.now() + mtConfig.sign.signUpActiveTokenExpires;
|
||||
|
||||
// Then save the user
|
||||
user.save(function (err) {
|
||||
if (err) {
|
||||
@@ -59,14 +66,45 @@ exports.signup = function (req, res) {
|
||||
user.password = undefined;
|
||||
user.salt = undefined;
|
||||
|
||||
req.login(user, function (err) {
|
||||
/* send an account active mail */
|
||||
var httpTransport = 'http://';
|
||||
if (config.secure && config.secure.ssl === true) {
|
||||
httpTransport = 'https://';
|
||||
}
|
||||
var baseUrl = req.app.get('domain') || httpTransport + req.headers.host;
|
||||
res.render(path.resolve('modules/users/server/templates/sign-up-active-email'), {
|
||||
name: user.displayName,
|
||||
appName: config.app.title,
|
||||
hours: mtConfig.sign.signUpActiveTokenExpires / (60 * 60 * 1000),
|
||||
url: baseUrl + '/api/auth/active/' + user.signUpActiveToken
|
||||
}, function (err, emailHTML) {
|
||||
if (err) {
|
||||
res.status(400).send(err);
|
||||
return res.status(400).send({
|
||||
message: 'ACTIVE_MAIL_RENDER_ERROR'
|
||||
});
|
||||
} else {
|
||||
res.json(user);
|
||||
var mailOptions = {
|
||||
to: user.email,
|
||||
from: config.mailer.from,
|
||||
subject: 'Sign up account active of ' + config.app.title,
|
||||
html: emailHTML
|
||||
};
|
||||
smtpTransport.sendMail(mailOptions, function (err) {
|
||||
if (!err) {
|
||||
res.send({
|
||||
message: 'SENDING_ACTIVE_MAIL_SUCCESSFULLY'
|
||||
});
|
||||
} else {
|
||||
return res.status(400).send({
|
||||
message: 'SENDING_ACTIVE_MAIL_FAILED'
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
//create trace log
|
||||
traceLogCreate(req, traceConfig.action.userSignUp, {
|
||||
user: user._id,
|
||||
@@ -77,6 +115,43 @@ exports.signup = function (req, res) {
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* active sign up from email token
|
||||
*/
|
||||
exports.active = function (req, res, next) {
|
||||
User.findOne({
|
||||
signUpActiveToken: req.params.token,
|
||||
status: 'inactive',
|
||||
signUpActiveExpires: {
|
||||
$gt: Date.now()
|
||||
}
|
||||
}, function (err, u) {
|
||||
if (err || !u) {
|
||||
return res.redirect('/authentication/active?method=invalid');
|
||||
} else {
|
||||
u.update({
|
||||
$set: {
|
||||
status: 'normal',
|
||||
signUpActiveToken: undefined,
|
||||
signUpActiveExpires: undefined
|
||||
}
|
||||
}).exec(function (err) {
|
||||
if (err) {
|
||||
return res.redirect('/authentication/active?method=error');
|
||||
} else {
|
||||
req.login(u, function (err) {
|
||||
if (err) {
|
||||
return res.redirect('/authentication/active?method=failed');
|
||||
} else {
|
||||
return res.redirect('/authentication/active?method=successfully');
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Signin after passport authentication
|
||||
*/
|
||||
|
||||
@@ -126,7 +126,6 @@ exports.validateResetToken = function (req, res) {
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* invite sign up from email token
|
||||
*/
|
||||
|
||||
@@ -129,7 +129,7 @@ var UserSchema = new Schema({
|
||||
},
|
||||
status: {
|
||||
type: String,
|
||||
default: 'normal'
|
||||
default: 'inactive'
|
||||
},
|
||||
vip_start_at: {
|
||||
type: Date,
|
||||
@@ -213,6 +213,13 @@ var UserSchema = new Schema({
|
||||
type: Date,
|
||||
default: Date.now
|
||||
},
|
||||
/* for sing up active */
|
||||
signUpActiveToken: {
|
||||
type: String
|
||||
},
|
||||
signUpActiveExpires: {
|
||||
type: Date
|
||||
},
|
||||
/* For reset password */
|
||||
resetPasswordToken: {
|
||||
type: String
|
||||
|
||||
@@ -15,6 +15,7 @@ module.exports = function (app) {
|
||||
app.route('/api/auth/reset/:token').post(users.reset);
|
||||
|
||||
app.route('/api/auth/invite/:token').get(users.invite);
|
||||
app.route('/api/auth/active/:token').get(users.active);
|
||||
|
||||
// Setting up the users authentication api
|
||||
app.route('/api/auth/signup').post(users.signup);
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
|
||||
|
||||
<head>
|
||||
<title></title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<p>Dear {{name}},</p>
|
||||
<br />
|
||||
<p>
|
||||
You have requested to sign up and register for your account at {{appName}}
|
||||
</p>
|
||||
<p>We should verify your email address, Please visit this url to active your account in {{hours}} hours:</p>
|
||||
<p>{{url}}</p>
|
||||
<strong>If you didn't make this request, you can ignore this email.</strong>
|
||||
<br />
|
||||
<br />
|
||||
<p>The {{appName}} Support Team</p>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
Reference in New Issue
Block a user