users.js 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630
  1. var express = require('express');
  2. var router = express.Router();
  3. var url = require('url');
  4. //验证
  5. var validator = require("validator");
  6. //文章类别对象
  7. var ContentCategory = require("../models/ContentCategory");
  8. //用户实体类
  9. var User = require("../models/User");
  10. var AdminUser = require("../models/AdminUser");
  11. //留言实体类
  12. var Message = require("../models/Message");
  13. // 文档对象
  14. var Content = require("../models/Content");
  15. //数据库操作对象
  16. var DbOpt = require("../models/Dbopt");
  17. //加密类
  18. var crypto = require("crypto");
  19. //系统相关操作
  20. var system = require("../util/system");
  21. //时间格式化
  22. var moment = require('moment');
  23. //站点配置
  24. var settings = require("../models/db/settings");
  25. var siteFunc = require("../models/db/siteFunc");
  26. var shortid = require('shortid');
  27. //数据校验
  28. var filter = require('../util/filter');
  29. //系统消息
  30. var UserNotify = require("../models/UserNotify");
  31. var Notify = require("../models/Notify");
  32. var returnUsersRouter = function(io) {
  33. //校验是否登录
  34. function isLogined(req){
  35. return req.session.logined;
  36. }
  37. //用户登录
  38. router.get('/login', function(req, res, next) {
  39. if(isLogined(req)){
  40. siteFunc.renderToTargetPageByType(req,res,'index');
  41. }else{
  42. siteFunc.renderToTargetPageByType(req,res,'user',{title : '用户登录',page : 'userLogin'});
  43. }
  44. });
  45. // 用户登录提交请求
  46. router.post('/doLogin', function(req, res, next) {
  47. var email = req.body.email;
  48. var password = req.body.password;
  49. var errors;
  50. var newPsd = DbOpt.encrypt(password,settings.encrypt_key);
  51. if(!validator.isEmail(email)){
  52. errors = '邮箱格式不正确';
  53. }
  54. if(!validator.isPsd(password) || !validator.isLength(password,6,12)){
  55. errors = "密码6-12个字符";
  56. }
  57. if(errors){
  58. res.end(errors);
  59. }else{
  60. User.findOne({email:email,password:newPsd},function(err,user){
  61. if(user){
  62. // 将cookie存入缓存
  63. filter.gen_session(user, res);
  64. res.end("success");
  65. }
  66. else
  67. {
  68. res.end("用户名或密码错误!");
  69. }
  70. })
  71. }
  72. });
  73. //用户注册
  74. router.get('/reg', function(req, res, next) {
  75. siteFunc.renderToTargetPageByType(req,res,'user',{title : '用户注册',page : 'userReg'});
  76. });
  77. // 用户注册
  78. router.post('/doReg', function(req, res, next) {
  79. var errors;
  80. var userName = req.body.userName;
  81. var email = req.body.email;
  82. var password = req.body.password;
  83. var confirmPsd = req.body.confirmPassword;
  84. // 数据校验
  85. if(!validator.isUserName(userName)){
  86. errors = "用户名5-12个英文数字组合";
  87. }
  88. if(!validator.isPsd(password) || !validator.isLength(password,6,12)){
  89. errors = "6-12位,只能包含字母、数字和下划线";
  90. }
  91. if(password !== confirmPsd)
  92. {
  93. errors = "密码不匹配,请重新输入";
  94. }
  95. if(!validator.isEmail(email)){
  96. errors = "请填写正确的邮箱地址";
  97. }
  98. if(errors){
  99. res.end(errors);
  100. }else{
  101. var regMsg = {
  102. email : email,
  103. userName : userName
  104. };
  105. // 邮箱和用户名都必须唯一
  106. var query=User.find().or([{'email' : email},{userName : userName}]);
  107. query.exec(function(err,user){
  108. if(user.length > 0){
  109. errors = "邮箱或用户名已存在!";
  110. res.end(errors);
  111. }else{
  112. system.sendEmail(settings.email_notice_user_reg,regMsg,function(err){
  113. if(err && err == 'notCurrentEmail'){
  114. res.end('乱写邮箱被我发现了吧!');
  115. }else{
  116. var newPsd = DbOpt.encrypt(password,settings.encrypt_key);
  117. req.body.password = newPsd;
  118. //发送系统消息给管理员
  119. siteFunc.sendSystemNoticeByType(req,res,'reg',userName);
  120. DbOpt.addOne(User,req, res)
  121. }
  122. });
  123. }
  124. });
  125. }
  126. });
  127. //忘记密码页面
  128. router.get('/lostPassword', function(req, res, next) {
  129. siteFunc.renderToTargetPageByType(req,res,'user',{title : '确认邮箱',page : 'userConfirmEmail'});
  130. });
  131. //提交验证邮箱
  132. router.post('/sentConfirmEmail',function(req, res, next){
  133. var targetEmail = req.body.email;
  134. // 获取当前发送邮件的时间
  135. var retrieveTime = new Date().getTime();
  136. if(!validator.isEmail(targetEmail)){
  137. res.end(settings.system_illegal_param)
  138. }else{
  139. User.findOne({'email' : targetEmail},function(err,user){
  140. if(err){
  141. res.end(err)
  142. }else{
  143. if(user && user._id){
  144. user.retrieve_time = retrieveTime;
  145. user.save(function(err){
  146. if(err){
  147. return next(err);
  148. }else{
  149. system.sendEmail(settings.email_findPsd,user,function(err){
  150. if(err){
  151. res.end(err)
  152. }else{
  153. console.log('-------邮件发送成功-------');
  154. res.end("success");
  155. }
  156. });
  157. }
  158. })
  159. }else{
  160. res.end('错误:未能通过电子邮件地址找到用户。');
  161. }
  162. }
  163. })
  164. }
  165. });
  166. //点击找回密码链接跳转页面
  167. router.get('/reset_pass',function(req,res){
  168. var params = url.parse(req.url,true);
  169. var tokenId = params.query.key;
  170. var keyArr = DbOpt.getKeyArrByTokenId(tokenId);
  171. if(keyArr && validator.isEmail(keyArr[1])){
  172. User.findOne({'email' : keyArr[1]},function(err,user){
  173. if(err){
  174. res.end(err);
  175. }else{
  176. if(user && user._id){
  177. if(user.password == keyArr[0] && keyArr[2] == settings.session_secret){
  178. // 校验链接是否过期
  179. var now = new Date().getTime();
  180. var oneDay = 1000 * 60 * 60 * 24;
  181. if (!user.retrieve_time || now - user.retrieve_time > oneDay) {
  182. siteFunc.renderToTargetPageByType(req,res,'userInfo',{key : 'warning' ,value : '链接超时,密码无法重置。',page : 'userNotice'});
  183. }
  184. siteFunc.renderToTargetPageByType(req,res,'user',{title : '重设密码',page : 'userResetPsd',tokenId : tokenId});
  185. }else{
  186. siteFunc.renderToTargetPageByType(req,res,'userInfo',{key : 'warning' ,value : '信息有误,密码无法重置。',page : 'userNotice'});
  187. }
  188. }
  189. }
  190. })
  191. }else{
  192. res.end(settings.system_illegal_param)
  193. }
  194. });
  195. router.post('/updateNewPsd',function(req,res){
  196. var keyArr = DbOpt.getKeyArrByTokenId(req.body.tokenId);
  197. if(keyArr && validator.isEmail(keyArr[1])){
  198. User.findOne({'email' : keyArr[1]},function(err,user){
  199. if(err){
  200. res.end(err);
  201. }else{
  202. if(user.password == keyArr[0] && keyArr[2] == settings.session_secret
  203. && validator.isPsd(req.body.password) && validator.isLength(req.body.password,6,12)){
  204. user.password = DbOpt.encrypt(req.body.password,settings.encrypt_key);
  205. user.save(function(err){
  206. if(err){
  207. res.end(err)
  208. }else{
  209. user.retrieve_time = null;
  210. res.end('success');
  211. }
  212. })
  213. }else{
  214. res.end(settings.system_illegal_param);
  215. }
  216. }
  217. })
  218. }else{
  219. res.end(settings.system_illegal_param)
  220. }
  221. });
  222. //用户中心
  223. router.get('/userCenter', function(req, res, next) {
  224. if(isLogined(req)){
  225. siteFunc.renderToTargetPageByType(req,res,'user',{title : '用户中心',page : 'userCenter'});
  226. }
  227. else{
  228. siteFunc.renderToTargetPageByType(req,res,'user',{title : '用户登录',page : 'userLogin'});
  229. }
  230. });
  231. //用户消息
  232. router.get('/userMessage', function(req, res, next) {
  233. if(isLogined(req)){
  234. siteFunc.renderToTargetPageByType(req,res,'userNotice',{title : '我的消息',page : 'userMessage'});
  235. }
  236. else{
  237. siteFunc.renderToTargetPageByType(req,res,'user',{title : '用户登录',page : 'userLogin'});
  238. }
  239. });
  240. // 修改用户密码页面
  241. router.get('/setUserPsd', function(req, res, next) {
  242. if(isLogined(req)){
  243. siteFunc.renderToTargetPageByType(req,res,'user',{title : '密码重置',page : 'userSetPsd'});
  244. }
  245. else{
  246. siteFunc.renderToTargetPageByType(req,res,'user',{title : '用户登录',page : 'userLogin'});
  247. }
  248. });
  249. //用户参与话题
  250. router.get('/userReplies', function(req, res, next) {
  251. if(isLogined(req)){
  252. siteFunc.renderToTargetPageByType(req,res,'userReply',{title : '参与话题',page : 'userReplies'});
  253. }
  254. else{
  255. siteFunc.renderToTargetPageByType(req,res,'user',{title : '用户登录',page : 'userLogin'});
  256. }
  257. });
  258. //参与话题分页
  259. router.get('/userReplies/:defaultUrl',function(req, res){
  260. if(isLogined(req)){
  261. var defaultUrl = req.params.defaultUrl;
  262. var replyUrl = defaultUrl.split('—')[0];
  263. var replyPage = defaultUrl.split('—')[1];
  264. if (replyUrl == 'p') {
  265. replyPage = defaultUrl.split('—')[1].split(".")[0];
  266. if(replyPage && validator.isNumeric(replyPage)){
  267. req.query.page = replyPage;
  268. }
  269. siteFunc.renderToTargetPageByType(req,res,'userReply',{title : '参与话题',page : 'userReplies'});
  270. }else{
  271. siteFunc.renderToTargetPageByType(req,res,'error',{info : '非法操作!',message :settings.system_illegal_param, page : 'do500'});
  272. }
  273. }
  274. else{
  275. siteFunc.renderToTargetPageByType(req,res,'user',{title : '用户登录',page : 'userLogin'});
  276. }
  277. });
  278. // 用户退出
  279. router.get('/logout', function(req, res, next) {
  280. req.session.destroy();
  281. res.clearCookie(settings.auth_cookie_name, { path: '/' });
  282. res.end("success");
  283. });
  284. //查找指定注册用户
  285. router.get('/userInfo', function(req, res, next) {
  286. var params = url.parse(req.url,true);
  287. var currentId = params.query.uid;
  288. if(shortid.isValid(currentId)){
  289. User.findOne({_id : currentId}, function (err,result) {
  290. if(err){
  291. }else{
  292. // 针对有密码的记录,需要解密后再返回
  293. if(result && result.password){
  294. var decipher = crypto.createDecipher("bf",settings.encrypt_key);
  295. var oldPsd = "";
  296. oldPsd += decipher.update(result.password,"hex","utf8");
  297. oldPsd += decipher.final("utf8");
  298. result.password = oldPsd;
  299. }
  300. return res.json(result);
  301. }
  302. })
  303. }else{
  304. return res.json({});
  305. }
  306. });
  307. //修改用户信息
  308. router.post('/userInfo/modify', function(req, res, next) {
  309. var errors;
  310. var email = req.body.email;
  311. var password = req.body.password;
  312. var userName = req.body.userName;
  313. var name = req.body.name;
  314. var city = req.body.city;
  315. var company = req.body.company;
  316. var qq = req.body.qq;
  317. var phoneNum = req.body.phoneNum;
  318. // 数据校验
  319. if(!validator.isUserName(userName)){
  320. errors = "用户名5-12个英文字符";
  321. }
  322. if(name && (!validator.isGBKName(name) || !validator.isLength(name,1,5))){
  323. errors = "姓名格式不正确";
  324. }
  325. if(!validator.isEmail(email)){
  326. errors = "请填写正确的邮箱地址";
  327. }
  328. if(city && (!validator.isGBKName(city) || !validator.isLength(city,0,12))){
  329. errors = "请填写正确的城市名称";
  330. }
  331. if(company && (!validator.isGBKName(company) || !validator.isLength(company,0,12))){
  332. errors = "请填写正确的学校中文名称";
  333. }
  334. if(qq && !validator.isQQ(qq)){
  335. errors = "请填写正确的QQ号码";
  336. }
  337. if(phoneNum && !validator.isMobilePhone(phoneNum, 'zh-CN')){
  338. errors = "请填写正确的手机号码";
  339. }
  340. if(errors){
  341. res.end(errors)
  342. }else{
  343. var newPsd = DbOpt.encrypt(password,settings.encrypt_key);
  344. req.body.password = newPsd;
  345. DbOpt.updateOneByID(User,req, res,"modify regUser");
  346. }
  347. });
  348. //密码修改
  349. router.post('/resetMyPsd', function(req, res, next) {
  350. var params = url.parse(req.url,true);
  351. var userId = params.query.uid;
  352. var oldPassword = req.body.oldPassword;
  353. var userPsd = req.body.password;
  354. var errors;
  355. if(!validator.isPsd(oldPassword) || !validator.isLength(oldPassword,6,12)){
  356. errors = "6-12位,只能包含字母、数字和下划线";
  357. }
  358. if(!validator.isPsd(userPsd) || !validator.isLength(userPsd,6,12)){
  359. errors = "6-12位,只能包含字母、数字和下划线";
  360. }
  361. if(userPsd === oldPassword){
  362. errors = "新密码和原密码不能相同";
  363. }
  364. if(errors){
  365. res.end(errors)
  366. }else{
  367. // 密码加密
  368. var oldPsd = DbOpt.encrypt(oldPassword,settings.encrypt_key);
  369. var newPsd = DbOpt.encrypt(userPsd,settings.encrypt_key);
  370. if(shortid.isValid(userId)){
  371. User.findOne({_id:userId},function(err,user){
  372. if(user){
  373. // 验证是否是本人操作,提高安全性
  374. if(oldPsd === user.password){
  375. // 更新密码
  376. User.update({_id:userId}, {password : newPsd}, function (err,result) {
  377. if(err){
  378. res.end(err);
  379. }else{
  380. res.end("success");
  381. }
  382. })
  383. }
  384. else{
  385. res.end("数据有误,请稍后重试");
  386. }
  387. }
  388. else
  389. {
  390. res.end("该用户不存在");
  391. }
  392. })
  393. }else{
  394. res.end(settings.system_illegal_param);
  395. }
  396. }
  397. });
  398. //-------------------------------------留言模块开始
  399. // 用户留言
  400. router.post('/message/sent', function(req, res, next) {
  401. var errors;
  402. var contentId = req.body.contentId;
  403. var contentTitle = req.body.contentTitle;
  404. var authorId = req.session.user._id;
  405. var replyId = req.body.replyId;
  406. var replyEmail = req.body.replyEmail;
  407. var relationMsgId = req.body.relationMsgId;
  408. if(!shortid.isValid(contentId) || !contentTitle){
  409. errors = settings.system_illegal_param;
  410. }
  411. if(!authorId){
  412. errors = settings.system_illegal_param;
  413. }
  414. if(replyEmail && !validator.isEmail(replyEmail)){
  415. errors = settings.system_illegal_param;
  416. }
  417. if(errors){
  418. res.end(errors);
  419. }else{
  420. if(replyId){
  421. req.body.replyAuthor = new User({_id : replyId,email : replyEmail});
  422. req.body.relationMsgId = relationMsgId;
  423. }
  424. req.body.author = new User({_id : authorId,userName : req.session.user.userName});
  425. var newMsg = new Message(req.body);
  426. newMsg.save(function(){
  427. // 更新评论数
  428. Content.updateCommentNum(contentId,'add',function(){
  429. // 如果被评论用户存在邮箱,则发送提醒邮件
  430. if(newMsg.replyAuthor && newMsg.replyAuthor.email){
  431. system.sendEmail(settings.email_notice_user_contentMsg,newMsg,function(err){
  432. if(err){
  433. res.end(err);
  434. }
  435. console.log('-----sent user email success--------')
  436. });
  437. }else{
  438. // 给管理员发送消息,这里异步就可以,不用等到邮件发送成功再返回结果
  439. // system.sendEmail(settings.email_notice_contentMsg,newMsg,function(err){
  440. // if(err){
  441. // res.end(err);
  442. // }
  443. // console.log('-----sent notice admin email success--------')
  444. // });
  445. siteFunc.sendSystemNoticeByType(req,res,'msg',newMsg);
  446. }
  447. res.end("success");
  448. });
  449. });
  450. }
  451. });
  452. //-------------------------------------留言模块结束
  453. //-------------------------------------消息通知模块开始
  454. router.get('/userNotify/setHasRead',function(req,res){
  455. var params = url.parse(req.url,true);
  456. var currentId = params.query.msgId;
  457. if(currentId){
  458. if(isLogined(req)){
  459. UserNotify.setHasRead(currentId,function(err){
  460. if(err){
  461. res.end(err);
  462. }else{
  463. UserNotify.getNoReadNotifyCountByUserId(req.session.user._id,'user',function(err,count){
  464. req.session.user.msg_count = count;
  465. io.sockets.emit('notifyNum', {msg_count: count });
  466. res.end('success');
  467. });
  468. }
  469. });
  470. }else{
  471. siteFunc.renderToTargetPageByType(req,res,'user',{title : '用户登录',page : 'userLogin'});
  472. }
  473. }else{
  474. res.end(settings.system_illegal_param);
  475. }
  476. });
  477. // 批量删除消息
  478. router.get('/userNotify/batchDel',function(req,res){
  479. var params = url.parse(req.url,true);
  480. var ids = params.query.ids;
  481. var idsArr = ids.split(',');
  482. if(isLogined(req)){
  483. if(idsArr.length > 0){
  484. UserNotify.remove({'_id':{$in: idsArr}},function(err){
  485. if(err){
  486. res.end(err);
  487. }else{
  488. res.end("success");
  489. }
  490. });
  491. }else{
  492. res.end('请选择至少一项后再执行删除操作!');
  493. }
  494. }else{
  495. siteFunc.renderToTargetPageByType(req,res,'user',{title : '用户登录',page : 'userLogin'});
  496. }
  497. });
  498. // 消息通知分页
  499. router.get('/userNotifies/:defaultUrl',function(req, res){
  500. if(isLogined(req)){
  501. var defaultUrl = req.params.defaultUrl;
  502. var notifyUrl = defaultUrl.split('—')[0];
  503. var replyPage = defaultUrl.split('—')[1];
  504. if (notifyUrl == 'p') {
  505. replyPage = defaultUrl.split('—')[1].split(".")[0];
  506. if(replyPage && validator.isNumeric(replyPage)){
  507. req.query.page = replyPage;
  508. }
  509. siteFunc.renderToTargetPageByType(req,res,'userNotice',{title : '我的消息',page : 'userMessage'});
  510. }else{
  511. siteFunc.renderToTargetPageByType(req,res,'error',{info : '非法操作!',message :settings.system_illegal_param, page : 'do500'});
  512. }
  513. }
  514. else{
  515. siteFunc.renderToTargetPageByType(req,res,'user',{title : '用户登录',page : 'userLogin'});
  516. }
  517. });
  518. //-------------------------------------消息通知模块结束
  519. return router;
  520. };
  521. module.exports = returnUsersRouter;