OSDN Git Service

過去ログ表示機能を廃止した
[webchat/WebChat.git] / profile.js
1 var config = require("./configure.js");\r
2 var resource = require("./resources.js");\r
3 var util = require("util");\r
4 var async = require("async");\r
5 var security = require("./security.js");\r
6 var ejs = require("ejs");\r
7 require("date-utils");\r
8 \r
9 var collection = new ProfileCollection();\r
10 \r
11 module.exports = function(app){\r
12         app.get("/profile",list_proc);\r
13         app.get("/profile/admin",admin_proc);\r
14         app.post("/profile/admin",admin_postproc);\r
15         app.get("/profile/detail",detail_proc);\r
16         app.post("/profile/detail",detail_postproc);\r
17         app.post("/profile/edit",edit_postproc); \r
18         app.get("/profile/registor",registor_proc); \r
19         app.post("/profile/registor",registor_postproc); \r
20 };\r
21 \r
22 function admin_proc(req, res)\r
23 {\r
24         var info = new security.SessionInfomation(true);\r
25         req.session.items = info;\r
26         async.waterfall([\r
27                 function(callback){\r
28                         PrepaerListAsync(req,callback);\r
29                 }\r
30         ],function(err,result){\r
31                 if(err != null)\r
32                         RenderMessage(res,err,info);\r
33                 else{\r
34                         result.token = req.session._csrf;\r
35                         res.setHeader("X-FRAME-OPTIONS","DENY");\r
36                         res.render("profile/admin",result);\r
37                 }\r
38         });\r
39 }\r
40 \r
41 function admin_postproc(req,res)\r
42 {\r
43         async.waterfall([\r
44                 function(cb){\r
45                         if(typeof(req.body.removeall) != "undefined")\r
46                                 collection.ClearAsync(cb);\r
47                         if(typeof(req.body.remove) != "undefined")\r
48                                 collection.RemoveRangeAsync(req.body.names,cb);\r
49                 }\r
50         ],function(err,result){\r
51                 if(err != null)\r
52                         RenderMessage(res,err,req.session.items);\r
53                 else\r
54                         RenderMessage(res,resource.success_remove,req.session.items);\r
55         });\r
56 }\r
57 \r
58 function list_proc(req, res)\r
59 {\r
60         if(typeof(req.session.items) != "undefined")\r
61                 req.session.items.admin = false;\r
62         async.waterfall([\r
63                 function(cb){\r
64                         PrepaerListAsync(req,cb);\r
65                 }\r
66         ],function(err,result){\r
67                 if(err != null)\r
68                         RenderMessage(res,err,req.session.items);\r
69                 else\r
70                         res.render("profile/list",result);\r
71         });\r
72 }\r
73 \r
74 function PrepaerListAsync(req,callback)\r
75 {\r
76         var limit = config.db_limit;\r
77         var start = 0;\r
78         var parttern = "";\r
79         if(typeof(req.query.start) != "undefined")\r
80                 start = parseInt(req.query.start);\r
81         if(typeof(req.query.limit) != "undefined")\r
82                 limit = parseInt(req.query.limit);\r
83 \r
84         async.waterfall([\r
85                 function(cb){\r
86                         if(typeof(req.query.search) != "undefined")\r
87                         {\r
88                                 parttern = req.query.search;\r
89                                 collection.FindByNameAsync(parttern,start,limit,cb);\r
90                         }else{\r
91                                 collection.ToArrayAsync(start,limit,cb);\r
92                         }\r
93                 }\r
94         ],function(err,result){\r
95                 if(err != null){\r
96                         callback(err,null);\r
97                 }else{\r
98                         var next = start + limit;\r
99                         var prev = start - limit;\r
100                         if(prev < 0)\r
101                                 prev = 0;\r
102                         for(var i = 0; i < result.length; i++)\r
103                                 result[i].lastmodified = result[i].lastmodified.toFormat("YYYY/MM/DD HH:MI:SS");\r
104                         callback(null,{list:result,search:parttern,next:next,prev:prev,limit:limit});\r
105                 }\r
106         });\r
107 }\r
108 \r
109 function detail_proc(req, res)\r
110 {\r
111         if(typeof(req.query.name) == "undefined")\r
112         {\r
113                 RenderMessage(res,resource.invaild_parameter,req.session.items);\r
114                 return;\r
115         }\r
116 \r
117         if(typeof(req.session.items) == "undefined")\r
118                 req.session.items = new security.SessionInfomation(false);\r
119 \r
120         async.waterfall([\r
121                 function(cb){\r
122                         collection.GetAsync(req.query.name,cb);\r
123                 },\r
124         ],function(err,result){\r
125                 if(err != null)\r
126                         RenderMessage(res,err,req.session.items);\r
127                 else if(result.length == 0)\r
128                         RenderMessage(res,resource.notfound_name,req.session.items);\r
129                 else{\r
130                         res.setHeader("X-FRAME-OPTIONS","DENY");\r
131                         res.render("profile/detail",{list:result,alias:config.alias,token:req.session._csrf,admin:req.session.items.admin});\r
132                 }\r
133         });\r
134 }\r
135 \r
136 function detail_postproc(req, res)\r
137 {\r
138         if(typeof(req.body.remove) != "undefined"){\r
139                 async.waterfall([\r
140                         function(cb){\r
141                                 if(typeof(req.session.items) != "undefined" && req.session.items.admin)\r
142                                         cb(null,true);\r
143                                 else\r
144                                         collection.AuthAsync(req.body.name,req.body.password,cb);\r
145                         },\r
146                         function(result,cb){\r
147                                 if(result)\r
148                                         collection.RemoveAsync(req.body.name,cb);\r
149                                 else\r
150                                         cb(null,null);\r
151                         }\r
152                 ],function(err,result){\r
153                         if(err != null)\r
154                                 RenderMessage(res,err,req.session.items);\r
155                         else if(result == null)\r
156                                 RenderMessage(res,resource.unmatch_password,req.session.items);\r
157                         else\r
158                                 RenderMessage(res,resource.success_remove,req.session.items);\r
159                 });\r
160         }else if(typeof(req.body.edit) != "undefined"){\r
161                 async.waterfall([\r
162                         function(cb){\r
163                                 if(typeof(req.session.items) != "undefined" && req.session.items.admin)\r
164                                         cb(null,true);\r
165                                 else\r
166                                         collection.AuthAsync(req.body.name,req.body.password,cb);\r
167                         },\r
168                         function(result,cb){\r
169                                 if(result)\r
170                                         collection.GetAsync(req.body.name,cb);\r
171                                 else\r
172                                         cb(null,null);\r
173                         }\r
174                 ],function(err,result){\r
175                         if(err != null){\r
176                                 RenderMessage(res,err,req.session.items);\r
177                         }else if(result != null){\r
178                                 res.setHeader("X-FRAME-OPTIONS","DENY");\r
179                                 res.render("profile/edit",{list:result,token:req.session._csrf,alias:config.alias});\r
180                         }else{\r
181                                 RenderMessage(res,resource.unmatch_password,req.session.items);\r
182                         }\r
183                 });\r
184         }else{\r
185                 RenderMessage(res,resource.invaild_parameter,req.session.items);\r
186         }\r
187 }\r
188 \r
189 function edit_postproc(req, res)\r
190 {\r
191         if(typeof(req.body.name) == "undefined")\r
192         {\r
193                 RenderMessage(res,resource.invaild_parameter,req.session.items);\r
194                 return;\r
195         }else if(typeof(req.body.edit) != "undefined"){\r
196                 var validator = new Validator();\r
197                 var result = validator.Validate(req.body,config.alias,true);\r
198                 if(result.length > 0)\r
199                 {\r
200                         RenderMessage(res,result,req.session.items);\r
201                         return;\r
202                 }\r
203                 async.waterfall([\r
204                         function(cb){\r
205                                 collection.UpdatAsync(req.body.name,req.body,cb);\r
206                         },\r
207                 ],function(err,result){\r
208                         if(err != null)\r
209                                 RenderMessage(res,err,req.session.items);\r
210                         else\r
211                                 RenderMessage(res,resource.success_edit,req.session.items);\r
212                 });\r
213         }else{\r
214                 RenderMessage(res,resource.invaild_parameter,req.session.items);\r
215         }\r
216 }\r
217 \r
218 function registor_postproc(req, res)\r
219 {\r
220         if(typeof(req.body.registor) != "undefined"){\r
221                 var validator = new Validator();\r
222                 var result = validator.Validate(req.body,config.alias,false);\r
223                 if(result.length > 0)\r
224                 {\r
225                         RenderMessage(res,result,req.session.items);\r
226                         return;\r
227                 }\r
228                 async.waterfall([\r
229                         function(cb){\r
230                                 collection.AddAsync(req.body,cb);\r
231                         }\r
232                 ],function(err,result){\r
233                         if(err != null)\r
234                                 RenderMessage(res,err,req.session.items);\r
235                         else\r
236                                 RenderMessage(res,resource.success_registor,req.session.items);\r
237                 });\r
238         }else{\r
239                 RenderMessage(resource.invaild_parameter,req.session.items);\r
240         }\r
241 }\r
242 \r
243 function registor_proc(req, res)\r
244 {\r
245         if(typeof(req.session.items) == "undefined")\r
246                 req.session.items = new security.SessionInfomation(false);\r
247 \r
248         res.setHeader("X-FRAME-OPTIONS","DENY");\r
249         res.render("profile/registor",{token:req.session._csrf,alias:config.alias});\r
250 }\r
251 \r
252 function RenderMessage(res,msg,info)\r
253 {\r
254         if(typeof(msg) == "string")\r
255                 msg = new Array(msg);\r
256         if(typeof(info) == "undefined" || typeof(info.admin) == "undefined")\r
257                 res.render("profile/message",{message:msg,admin:false});\r
258         else\r
259                 res.render("profile/message",{message:msg,admin:info.admin});\r
260 }\r
261 \r
262 //\r
263 // ProfileCollectionクラス\r
264 //\r
265 function ProfileCollection()\r
266 {\r
267         var MySQLPool = new require("./mysql_pool.js");\r
268         var murmurhash = require("murmurhash");\r
269         var pool = new MySQLPool({\r
270                                 host     : config.db_host,\r
271                                 user     : config.db_user,\r
272                                 password : config.db_password,\r
273                                 port     : config.db_port,\r
274                                 database : config.db_name,\r
275                         });\r
276         this.AuthAsync = function(name,password,cb){\r
277                 async.waterfall([\r
278                         function(next){\r
279                                 pool.query("SELECT password FROM profilelist WHERE name_hash = ? and name = ?",[murmurhash.v3(name),name],next);\r
280                         },\r
281                         function(result,next){\r
282                                 if(result[0].password == md5_hex(password))\r
283                                         next(null,true);\r
284                                 else\r
285                                         next(null,false);\r
286                         }\r
287                 ],cb);\r
288         }\r
289         this.GetAsync = function(name,cb){\r
290                 pool.query("SELECT * FROM profilelist WHERE name_hash = ? and name = ?",[murmurhash.v3(name),name],cb);\r
291         }\r
292         this.AddAsync = function(data,cb){\r
293                 var item = GetItem(data);;\r
294                 pool.query("INSERT INTO profilelist SET ?",[item],cb);\r
295         }\r
296         this.UpdatAsync = function(name,data,cb){\r
297                 var item = GetItem(data);\r
298                 pool.query("UPDATE profilelist SET ? WHERE name_hash = ? and name = ?",[item,murmurhash.v3(name),name],cb);\r
299         }\r
300         this.ClearAsync = function(cb){\r
301                 pool.query("TRUNCATE TABLE profilelist",null,cb);\r
302         }\r
303         this.RemoveRangeAsync = function(names,cb){\r
304                 pool.query("DELETE FROM profilelist WHERE name IN (?)",[names],cb);\r
305         }\r
306         this.RemoveAsync = function(name,cb){\r
307                 pool.query("DELETE FROM profilelist WHERE name_hash = ? and name = ?",[murmurhash.v3(name),name],cb);\r
308         }\r
309         this.FindByNameAsync = function(pattern,start,count,cb){\r
310                 pool.query("SELECT * FROM profilelist WHERE name LIKE ? LIMIT ?,?",[pattern+"%",start,count],cb);\r
311         }\r
312         this.ToArrayAsync = function(start,count,cb){\r
313                 pool.query("SELECT name,lastmodified FROM profilelist LIMIT ?,?",[start,count],cb);\r
314         }\r
315 \r
316         var crypto = require("crypto");\r
317         function md5_hex(src)\r
318         {\r
319                 var md5 = crypto.createHash('md5');\r
320                 md5.update(src, 'utf8');\r
321         return md5.digest('hex');\r
322         }\r
323 \r
324         function GetItem(data,newpw)\r
325         {\r
326                 var item = {\r
327                         name_hash:murmurhash.v3(data.name),\r
328                         lastmodified:new Date(),\r
329                 };\r
330                 for(var key in config.alias)\r
331                 {\r
332                         if(typeof(config.alias[key].nodefinetable) != "undefined" && \r
333                                 config.alias[key].nodefinetable)\r
334                                 continue;\r
335                         if(config.alias[key].visible_edit)\r
336                         {\r
337                                 if(config.alias[key].type == "password")\r
338                                 {\r
339                                         if(data[key] != "")\r
340                                                 item[key] = md5_hex(data[key]);\r
341                                 }\r
342                                 else if(data[key] == "" && typeof(config.alias[key].defaultvalue) != "undefined")\r
343                                 {\r
344                                         item[key] = config.alias[key].defaultvalue;\r
345                                 }\r
346                                 else\r
347                                 {\r
348                                         item[key] = data[key];\r
349                                 }\r
350                         }\r
351                 }\r
352                 return item;\r
353         }\r
354 }\r
355 \r
356 //\r
357 // Validatorクラス\r
358 //\r
359 function Validator()\r
360 {\r
361         //\r
362         // バリテーションを行う。\r
363         // エラーがあった場合は真。そうでない場合は偽を返す\r
364         //\r
365         // @body バリテーションの対象となる連想配列\r
366         // @alias バリテーションを行う要素のリスト\r
367         // @editflag 編集時なら真\r
368         this.Validate = function(body,alias,editflag){\r
369                 var result = new Array();\r
370                 for(var key in alias)\r
371                 {\r
372                         if(alias[key].visible_edit == false)\r
373                                 continue;\r
374                         var message;\r
375                         if(typeof(alias[key].isnotempty) != "undefined" &&\r
376                                 alias[key].isnotempty && body[key] == "")\r
377                                         message = resource.is_not_empty;\r
378                         else if(typeof(alias[key].isnotemptyonregistor) != "undefined" &&\r
379                                 alias[key].isnotemptyonregistor && body[key] == "" &&\r
380                                 !editflag)\r
381                                         message = resource.is_not_empty;\r
382                         else if(typeof(alias[key].mustmatchitem) != "undefined" &&\r
383                                 body[key] != body[alias[key].mustmatchitem])\r
384                                         message = util.format(resource.must_match_item,alias[alias[key].mustmatchitem].name); \r
385                         else\r
386                                 message = IsValidate(body[key],alias[key].type,alias[key].rule);\r
387                         if(message != null)\r
388                                 result.push(alias[key].name + ":" + message);\r
389                 }\r
390                 return result;\r
391         }\r
392         function IsValidate(data,type,rule){\r
393                 if(typeof(data) == "undefined")\r
394                         throw "data is undefined";\r
395                 if(typeof(type) == "undefined")\r
396                         throw "type is undefined";\r
397 \r
398                 var result = null;\r
399 \r
400                 switch(type)\r
401                 {\r
402                         case "text":\r
403                         case "textarea":\r
404                         case "password":\r
405                                 if(typeof(data) != "string")\r
406                                         result = resource.is_not_string;\r
407                                 break;\r
408                         case "number":\r
409                                 if(data.match(/[^0-9]/g))\r
410                                         result = resource.is_not_number;\r
411                                 break;\r
412                         case "mail":\r
413                                 if(data != "" && !data.match(/^[A-Za-z0-9]+[\w\-\+]+@[\w\.-]+\.\w{2,}$/))\r
414                                         result = resource.is_not_mail;\r
415                                 break;\r
416                 }\r
417 \r
418                 if(typeof(rule) == "function")\r
419                         result = rule(data,type);\r
420 \r
421                 return result;\r
422         }\r
423 }\r