forked from cnodejs/egg-cnode
-
Notifications
You must be signed in to change notification settings - Fork 0
/
app.js
155 lines (131 loc) · 4.33 KB
/
app.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
'use strict';
const uuid = require('uuid');
module.exports = app => {
if (app.config.debug) {
app.config.coreMiddleware.unshift('less');
}
if (app.config.env === 'local' || app.config.env === 'unittest') {
app.beforeStart(async () => {
await app.model.sync({ force: true });
});
}
const localHandler = async (ctx, { username, password }) => {
const getUser = username => {
if (username.indexOf('@') > 0) {
return ctx.service.user.getUserByMail(username);
}
return ctx.service.user.getUserByLoginName(username);
};
const existUser = await getUser(username);
// 用户不存在
if (!existUser) {
return null;
}
const passhash = existUser.pass;
// TODO: change to async compare
const equal = ctx.helper.bcompare(password, passhash);
// 密码不匹配
if (!equal) {
return null;
}
// 用户未激活
// if (!existUser.active) {
// // 发送激活邮件
// return null;
// }
// 验证通过
return existUser;
};
const githubHandler = async (ctx, { profile }) => {
const email = profile.emails && profile.emails[0] && profile.emails[0].value;
ctx.logger.info(email, profile);
let [ existUser, existRelatedUser ] = await Promise.all([
ctx.service.user.getUserByGithubId(profile.id),
ctx.service.user.getUserByLoginNameOrEmail(profile.username, email),
]);
if (!existUser) {
if (!existRelatedUser) {
// 用户不存在则创建
existUser = ctx.model.User.build({
githubId: profile.id,
});
existUser.githubId = profile.id;
existUser.accessToken = uuid.v4();
} else {
// 存在但尚未进行 github 认证,认证上
existUser = existRelatedUser;
await ctx.service.message.sendBindMessage(existUser.loginname);
}
}
// 用户存在,更新字段
existUser.active = true;
existUser.loginname = profile.username;
existUser.email = email || existUser.email;
existUser.avatar = profile._json.avatar_url;
existUser.githubUsername = profile.username;
existUser.githubAccessToken = profile.accessToken;
try {
await existUser.save();
} catch (ex) {
// if (ex.message.indexOf('duplicate key error') !== -1) {
// let err;
// if (ex.message.indexOf('email') !== -1) {
// err = new Error('您 GitHub 账号的 Email 与之前在 CNodejs 注册的 Email 重复了');
// err.code = 'duplicate_email';
// throw err;
// }
// if (ex.message.indexOf('loginname') !== -1) {
// err = new Error('您 GitHub 账号的用户名与之前在 CNodejs 注册的用户名重复了');
// err.code = 'duplicate_loginname';
// throw err;
// }
// }
throw ex;
}
return existUser;
};
app.passport.verify(async (ctx, user) => {
ctx.logger.debug('鉴权.verify', user);
const handler = user.provider === 'github' ? githubHandler : localHandler;
const existUser = await handler(ctx, user);
if (existUser) {
// id存入Cookie, 用于验证过期.
const auth_token = existUser.accessToken + '$$$$'; // 以后可能会存储更多信息,用 $$$$ 来分隔
const opts = {
path: '/',
maxAge: 1000 * 60 * 60 * 24 * 30,
signed: true,
httpOnly: true,
};
ctx.cookies.set(app.config.auth_cookie_name, auth_token, opts); // cookie 有效期30天
if (!user.active) ctx.redirect('/resend_activate');
}
return existUser;
});
app.passport.serializeUser(async (ctx, user) => {
ctx.logger.debug('鉴权.serialize', user);
return user;
});
app.passport.deserializeUser(async (ctx, user) => {
ctx.logger.debug('鉴权.deserialize', user);
if (user) {
// 提供 auth_token 可以通过 api 爬取信息
const auth_token = ctx.cookies.get(ctx.app.config.auth_cookie_name, {
signed: true,
});
if (!auth_token) {
return user;
}
const auth = auth_token.split('$$$$');
const user_token = auth[0];
user = await ctx.service.user.getUserByAccessToken(user_token);
if (!user) {
return user;
}
if (ctx.app.config.admins.hasOwnProperty(user.loginname)) {
user.is_admin = true;
}
}
return user;
});
};