Skip to content

Commit 376b158

Browse files
JacksonTianatian25
authored andcommitted
refactor: sign (#12)
1 parent 1dbf310 commit 376b158

File tree

17 files changed

+486
-29
lines changed

17 files changed

+486
-29
lines changed

README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
[snyk-image]: https://snyk.io/test/github/cnodejs/egg-cnode/badge.svg?style=flat-square
1515
[snyk-url]: https://snyk.io/test/github/cnodejs/egg-cnode
1616

17-
1817
## QuickStart
1918

2019
<!-- add docs here for user -->

app.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ module.exports = app => {
2222
}
2323

2424
const passhash = existUser.pass;
25-
const equal = tools.compare(passhash, password);
25+
// TODO: change to async compare
26+
const equal = tools.bcompare(passhash, password);
2627

2728
// 密码不匹配
2829
if (!equal) {

app/controller/sign.js

Lines changed: 70 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,89 @@
11
'use strict';
22

3+
const validator = require('validator');
34
const Controller = require('egg').Controller;
45

6+
const tools = require('../common/tools');
7+
58
class SignController extends Controller {
69
async showLogin() {
710
const { ctx } = this;
8-
const locals = {};
9-
await ctx.render('/sign/signin', locals);
11+
await ctx.render('/sign/signin', {});
12+
}
13+
14+
// sign up
15+
async showSignup() {
16+
const { ctx } = this;
17+
await ctx.render('/sign/signup', {});
1018
}
1119

1220
async signup() {
13-
this.ctx.render('sign/signup');
21+
const { ctx, service, config } = this;
22+
const loginname = validator.trim(ctx.request.body.loginname).toLowerCase();
23+
const email = validator.trim(ctx.request.body.email).toLowerCase();
24+
const pass = validator.trim(ctx.request.body.pass);
25+
const rePass = validator.trim(ctx.request.body.re_pass);
26+
27+
let msg;
28+
// 验证信息的正确性
29+
if ([ loginname, pass, rePass, email ].some(item => {
30+
return item === '';
31+
})) {
32+
msg = '信息不完整。';
33+
} else if (loginname.length < 5) {
34+
msg = '用户名至少需要5个字符。';
35+
} else if (!tools.validateId(loginname)) {
36+
msg = '用户名不合法。';
37+
} else if (!validator.isEmail(email)) {
38+
msg = '邮箱不合法。';
39+
} else if (pass !== rePass) {
40+
msg = '两次密码输入不一致。';
41+
}
42+
// END 验证信息的正确性
43+
44+
if (msg) {
45+
ctx.status = 422;
46+
await ctx.render('sign/signup', {
47+
error: msg,
48+
loginname,
49+
email,
50+
});
51+
return;
52+
}
53+
54+
const users = await service.user.getUsersByQuery({ $or: [
55+
{ loginname },
56+
{ email },
57+
] }, {});
58+
59+
if (users.length > 0) {
60+
ctx.status = 422;
61+
await ctx.render('sign/signup', {
62+
error: '用户名或邮箱已被使用。',
63+
loginname,
64+
email,
65+
});
66+
return;
67+
}
68+
69+
const passhash = tools.bhash(pass);
70+
71+
// create gravatar
72+
const avatarUrl = service.user.makeGravatar(email);
73+
74+
await service.user.newAndSave(loginname, loginname, passhash, email, avatarUrl, false);
75+
// 发送激活邮件
76+
// await mail.sendActiveMail(email, utility.md5(email + passhash + config.session_secret), loginname);
77+
await ctx.render('sign/signup', {
78+
success: '欢迎加入 ' + config.name + '!我们已给您的注册邮箱发送了一封邮件,请点击里面的链接来激活您的帐号。',
79+
});
1480
}
1581

1682
async signout() {
1783
const { ctx } = this;
1884
ctx.session = null;
1985
ctx.logout();
20-
ctx.body = 'signout';
86+
ctx.redirect('/');
2187
}
2288
}
2389

app/router.js

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* @param {Egg.Application} app - egg application
55
*/
66
module.exports = app => {
7-
const { router, controller } = app;
7+
const { router, controller, config } = app;
88

99
const { site, sign, user, topic, rss, search, page } = controller;
1010

@@ -15,16 +15,16 @@ module.exports = app => {
1515
// mobile app download
1616
router.get('/app/download', site.appDownload);
1717

18-
// // sign controller
19-
// if (config.allow_sign_up) {
20-
// router.get('/signup', sign.showSignup); // 跳转到注册页面
21-
// router.post('/signup', sign.signup); // 提交注册信息
22-
// } else {
23-
// // 进行github验证
24-
// router.get('/signup', function (req, res, next) {
25-
// return res.redirect('/auth/github');
26-
// });
27-
// }
18+
// sign controller
19+
if (config.allow_sign_up) {
20+
router.get('/signup', sign.showSignup); // 跳转到注册页面
21+
router.post('/signup', sign.signup); // 提交注册信息
22+
} else {
23+
// 进行github验证
24+
router.get('/signup', async function() {
25+
this.ctx.redirect('/auth/github');
26+
});
27+
}
2828

2929
const localStrategy = app.passport.authenticate('local', {
3030
successRedirect: '/',

app/service/user.js

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ class UserService extends Service {
1515
return [];
1616
}
1717

18-
return this.ctx.model.User.find({ loginname: { $in: names } }).exec();
18+
const query = { loginname: { $in: names } };
19+
return this.ctx.model.User.find(query).exec();
1920
}
2021

2122
/*
@@ -74,15 +75,13 @@ class UserService extends Service {
7475

7576
/*
7677
* 根据查询条件,获取一个用户
77-
* Callback:
78-
* - err, 数据库异常
79-
* - user, 用户
8078
* @param {String} name 用户名
8179
* @param {String} key 激活码
82-
* @return {Promise[users]} 承载用户列表的 Promise 对象
80+
* @return {Promise[user]} 承载用户的 Promise 对象
8381
*/
8482
getUserByNameAndKey(loginname, key) {
85-
return this.ctx.model.User.findOne({ loginname, retrieve_key: key }).exec();
83+
const query = { loginname, retrieve_key: key };
84+
return this.ctx.model.User.findOne(query).exec();
8685
}
8786

8887
newAndSave(name, loginname, pass, email, avatar_url, active) {
@@ -107,7 +106,7 @@ class UserService extends Service {
107106
}
108107

109108
getGravatar(user) {
110-
return user.avatar || this.makeGravatar(user);
109+
return user.avatar || this.makeGravatar(user.email);
111110
}
112111
}
113112

app/view/sidebar.html

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,9 @@
6969
<div class='inner'>
7070
<% if (tops.length > 0) { %>
7171
<ol>
72-
<%- include('user/top', { collection: tops, as: 'user' }) %>
72+
<% tops.forEach((user) => { %>
73+
<%- include('user/top.html', { user }) %>
74+
<% }) %>
7375
</ol>
7476
<% } else { %>
7577
<p></p>

app/view/sign/new_oauth.html

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<div id='content'>
2+
<div class='panel'>
3+
<div class='header'>
4+
<ul class='breadcrumb'>
5+
<li><a href='/'>主页</a><span class='divider'>/</span></li>
6+
<li class='active'>注册新账号</li>
7+
</ul>
8+
</div>
9+
<div class='inner'>
10+
<form id='signin_form' class='form-horizontal' action=<%= actionPath
11+
%> method='post'>
12+
<input type='hidden' name='_csrf' value='<%= csrf %>'/>
13+
<input type='hidden' name='isnew' value='1'/>
14+
15+
<div class='control-group'>
16+
<label class='control-label'>通过 GitHub 帐号</label>
17+
18+
<div class='controls'>
19+
<input type='submit' class='span-info' value="注册新账号">
20+
</div>
21+
</div>
22+
</form>
23+
24+
<form id='signin_form' class='form-horizontal' action=<%= actionPath
25+
%> method='post'>
26+
<div class='control-group'>
27+
<label class='controls'>或者</label>
28+
</div>
29+
<div class='control-group'>
30+
<label class='control-label' for='name'>用户名</label>
31+
32+
<div class='controls'>
33+
<input class='input-xlarge' id='name' name='name' size='30' type='text'/>
34+
</div>
35+
</div>
36+
<div class='control-group'>
37+
<label class='control-label' for='pass'>密码</label>
38+
39+
<div class='controls'>
40+
<input class='input-xlarge' id='pass' name='pass' size='30' type='password'/>
41+
</div>
42+
</div>
43+
<input type='hidden' name='_csrf' value='<%= csrf %>'/>
44+
45+
<div class='form-actions'>
46+
<input type='submit' class='span-primary' value='关联旧账号'/>
47+
</div>
48+
</form>
49+
</div>
50+
</div>
51+
</div>

app/view/sign/no_github_email.html

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
GitHub 登陆出错
2+
3+
<ul>
4+
<li>您 GitHub 账号的 Email 与之前在 CNodejs 注册的 Email 重复了。</li>
5+
<li>
6+
<p>也可能是您的 GitHub 没有提供公开的 Profile Email 导致注册失败。</p>
7+
8+
<p>请访问:https://github.com/settings/profile 设置您的公开 Email 地址。请确保您 GitHub 的个人主页有可见的 Email,如下图:</p></li>
9+
<a href="https://github.com/alsotang" target="_blank"><img src="http://alsotang.u.qiniudn.com/QQ20140807-1.png"></a>
10+
</ul>
11+
12+

app/view/sign/reset.html

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<%- partial('../sign/sidebar') %>
2+
3+
<div id='content'>
4+
<div class='panel'>
5+
<div class='header'>
6+
<ul class='breadcrumb'>
7+
<li><a href='/'>主页</a><span class='divider'>/</span></li>
8+
<li class='active'>重置密码</li>
9+
</ul>
10+
</div>
11+
<div class='inner'>
12+
<% if(typeof(error) !== 'undefined' && error){ %>
13+
<div class="alert alert-error">
14+
<a class="close" data-dismiss="alert" href="#">&times;</a>
15+
<strong><%= error %></strong>
16+
</div>
17+
<% } %>
18+
<form id='signin_form' class='form-horizontal' action='/reset_pass' method='post'>
19+
<div class='control-group'>
20+
<label class='control-label' for='psw'>新密码</label>
21+
22+
<div class='controls'>
23+
<input class='input-xlarge' id='psw' name='psw' size='30' type='password'/>
24+
</div>
25+
</div>
26+
<div class='control-group'>
27+
<label class='control-label' for='repsw'>确认密码</label>
28+
29+
<div class='controls'>
30+
<input class='input-xlarge' id='repsw' name='repsw' size='30' type='password'/>
31+
</div>
32+
</div>
33+
<input type='hidden' name='_csrf' value='<%= csrf %>'/>
34+
<input type='hidden' name='name' id='name' value='<%= name%>'>
35+
<input type='hidden' name='key' id='key' value='<%= key%>'>
36+
37+
<div class='form-actions'>
38+
<input type='submit' class='span-primary' value='确定'/>
39+
</div>
40+
</form>
41+
</div>
42+
</div>
43+
</div>

app/view/sign/search_pass.html

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<%- partial('../sign/sidebar') %>
2+
3+
<div id='content'>
4+
<div class='panel'>
5+
<div class='header'>
6+
<ul class='breadcrumb'>
7+
<li><a href='/'>主页</a><span class='divider'>/</span></li>
8+
<li class='active'>找回密码</li>
9+
</ul>
10+
</div>
11+
<div class='inner'>
12+
<% if (typeof(error) !== 'undefined' && error) { %>
13+
<div class="alert alert-error">
14+
<a class="close" data-dismiss="alert" href="#">&times;</a>
15+
<strong><%= error %></strong>
16+
</div>
17+
<% } %>
18+
<form id='search_pass_form' class='form-horizontal' action='/search_pass' method='post'>
19+
<div class='control-group'>
20+
<label class='control-label' for='email'>电子邮箱</label>
21+
22+
<div class='controls'>
23+
<% if (typeof(email) !== 'undefined') { %>
24+
<input class='input-xlarge' id='email' name='email' size='30' type='text' value='<%= email %>'/>
25+
<% } else { %>
26+
<input class='input-xlarge' id='email' name='email' size='30' type='text'/>
27+
<% } %>
28+
<p class='help-block'>请输入您注册帐户时使用的电子邮箱</p>
29+
</div>
30+
<input type='hidden' name='_csrf' value='<%= csrf %>'/>
31+
</div>
32+
<div class='form-actions'>
33+
<input type='submit' class='span-primary' value='提交'/>
34+
</div>
35+
</form>
36+
</div>
37+
</div>
38+
</div>

0 commit comments

Comments
 (0)