add reset password feature

This commit is contained in:
Yudong Li
2015-04-30 10:46:31 +08:00
parent 507c1521fd
commit af93acafcd
6 changed files with 135 additions and 3 deletions

View File

@@ -50,12 +50,14 @@
"": "Account",
"register": "Register",
"login": "Login",
"forget": "Forget",
"username": "Username",
"email": "Email",
"password": "Password",
"logout": "Logout",
"preferences": "Preferences",
"financials": "Financials"
"financials": "Financials",
"send": "Send"
},
"panel": {
"": "Panel",

View File

@@ -14,7 +14,7 @@ Token = mabolo.model 'Token',
type:
required: true
type: String
enum: ['full_access']
enum: ['full_access', 'reset_access']
# Public: Code of token, a sha256 string
code:
@@ -269,6 +269,27 @@ Account::createToken = (type, options) ->
).then ->
return token
###
Public: Remove all token and create a new one just for reset password.
* `options` {Object} Options of {Token}
Return {Promise} resolve with the new token.
###
Account::forgetPassword = (options) ->
token = new Token
type: 'reset_access'
code: utils.randomSalt()
options: options
created_at: new Date()
updated_at: new Date()
@update(
$set:
tokens: [token]
).then ->
return token
###
Section: Interaction with account instance
###

View File

@@ -65,7 +65,7 @@ Notification::isGroupNotice = ->
Notification::sendMail = ->
sendMail = (to, subject, html) ->
Q.Promise (resolve, reject) ->
app.mailer.sendMail
root.mailer.sendMail
from: config.email.from
replyTo: config.email.reply_to
to: to

View File

@@ -32,6 +32,31 @@ router.get '/register', (req, res) ->
router.get '/login', (req, res) ->
res.render 'account/login'
###
Router: GET /account/forget
Response HTML
###
router.get '/forget', (req, res) ->
res.render 'account/forget'
###
Router: GET /account/reset/:email/:token
Response HTML
###
router.get '/reset/:email/:token', (req, res) ->
Account.search(req.params.email).then (account) ->
unless account
throw new Error 'no account'
if account.token.length != 1 or account.token[0] != token
throw new Error 'illegal action'
res.render 'account/reset', {req.params}
.catch (err) ->
res.error err
###
Router: GET /account/translations/:language?
@@ -72,6 +97,48 @@ router.post '/register', (req, res, next) ->
else
next err
###
Router: POST /account/forget
Request {Object}
* `email` {String}
Response HTML send mail result page (success or failed)
###
router.post '/forget', (req, res) ->
Account.search(req.body.email).then (account) ->
account.forgetPassword(req.getClientInfo()).then (token) ->
# the send mail module can't work
# todo: send email with a url like: /account/reset/:email/:token
# return the success or ...
res.sendStatus 200
###
Router: POST /account/forget
Request {Object}
* `email` {String}
Response HTML send mail result page (success or failed)
###
router.post '/reset', (req, res) ->
Account.search(req.body.email).then (account) ->
# TODO: check token type
if account and account.token.length is 1 and account.token[0] is req.body.token
account.setPassword(req.body.password).then ->
account.update
@set:
token: []
.then ->
res.json account
else
throw new Error 'illegal action'
.catch (err) ->
res.error err
###
Router: POST /account/login

View File

@@ -0,0 +1,18 @@
extends ../layout
prepend header
title #{t('account.forget')} | #{site_name}
block main
header= t('account.forget')
form.form-horizontal
.form-group
label.col-sm-2.col-md-offset-1.control-label= t('account.email')
.col-sm-5
input.form-control(name='email', type='text', required)
.form-group
.col-sm-offset-3
button.action-login.btn.btn-lg.btn-primary(type='button')= t('account.send')
append footer
script(src='/script/account.js')

View File

@@ -0,0 +1,24 @@
extends ../layout
prepend header
title #{t('account.reset')} | #{site_name}
block main
header= t('account.reset')
form.form-horizontal
input(type='hidden', name='token', value=#{token})
input(type='hidden', name='email', value=#{email})
.form-group
label.col-sm-2.col-md-offset-1.control-label= t('account.password')
.col-sm-5
input.form-control(name='password', type='password')
.form-group
label.col-sm-2.col-md-offset-1.control-label= t('view.account.password2')
.col-sm-5
input.form-control(name='password2', type='password')
.form-group
.col-sm-offset-3
button.action-login.btn.btn-lg.btn-primary(type='button')= t('account.reset')
append footer
script(src='/script/account.js')