-$db_user = "user";\r
-$db_password = "user";\r
-$db_limit = 50;\r
-\r
-$unmatch_password = "パスワードが一致しません";\r
-$invaild_parameter = "パラメーターが正しくありません";\r
-$success_registor = "登録に成功しました";\r
-$success_remove = "削除に成功しました";\r
-$success_edit = "編集に成功しました";\r
-$notfound_name = "該当名が存在しません";\r
-\r
+var config = require("./configure.js");\r
+var resource = require("./resources.js");\r
var util = require("util");\r
-\r
var async = require("async");\r
-\r
var security = require("./security.js");\r
-\r
var ejs = require("ejs");\r
+require("date-utils");\r
\r
var collection = new ProfileCollection();\r
\r
module.exports = function(app){\r
app.get("/profile",list_proc);\r
+ app.get("/profile/admin",admin_proc);\r
+ app.post("/profile/admin",admin_postproc);\r
app.get("/profile/detail",detail_proc);\r
app.post("/profile/detail",detail_postproc);\r
app.post("/profile/edit",edit_postproc); \r
app.post("/profile/registor",registor_postproc); \r
};\r
\r
+function admin_proc(req, res)\r
+{\r
+ var info = new security.SessionInfomation(true);\r
+ req.session.items = info;\r
+ async.waterfall([\r
+ function(callback){\r
+ PrepaerListAsync(req,callback);\r
+ }\r
+ ],function(err,result){\r
+ if(err != null)\r
+ RenderMessage(res,err,info);\r
+ else{\r
+ result.token = req.session._csrf;\r
+ res.setHeader("X-FRAME-OPTIONS","DENY");\r
+ res.render("profile/admin",result);\r
+ }\r
+ });\r
+}\r
+\r
+function admin_postproc(req,res)\r
+{\r
+ async.waterfall([\r
+ function(cb){\r
+ if(typeof(req.body.removeall) != "undefined")\r
+ collection.ClearAsync(cb);\r
+ if(typeof(req.body.remove) != "undefined")\r
+ collection.RemoveRangeAsync(req.body.names,cb);\r
+ }\r
+ ],function(err,result){\r
+ if(err != null)\r
+ RenderMessage(res,err,req.session.items);\r
+ else\r
+ RenderMessage(res,resource.success_remove,req.session.items);\r
+ });\r
+}\r
+\r
function list_proc(req, res)\r
{\r
- var limit = $db_limit;\r
+ if(typeof(req.session.items) != "undefined")\r
+ req.session.items.admin = false;\r
+ async.waterfall([\r
+ function(cb){\r
+ PrepaerListAsync(req,cb);\r
+ }\r
+ ],function(err,result){\r
+ if(err != null)\r
+ RenderMessage(res,err,req.session.items);\r
+ else\r
+ res.render("profile/list",result);\r
+ });\r
+}\r
+\r
+function PrepaerListAsync(req,callback)\r
+{\r
+ var limit = config.db_limit;\r
var start = 0;\r
var parttern = "";\r
if(typeof(req.query.start) != "undefined")\r
}\r
],function(err,result){\r
if(err != null){\r
- res.render("profile\\message",{message:err});\r
+ callback(err,null);\r
}else{\r
var next = start + limit;\r
var prev = start - limit;\r
if(prev < 0)\r
prev = 0;\r
- res.render("profile\\list",{list:result,search:parttern,next:next,prev:prev,limit:limit});\r
+ for(var i = 0; i < result.length; i++)\r
+ result[i].lastmodified = result[i].lastmodified.toFormat("YYYY/MM/DD HH:MI:SS");\r
+ callback(null,{list:result,search:parttern,next:next,prev:prev,limit:limit});\r
}\r
});\r
}\r
{\r
if(typeof(req.query.name) == "undefined")\r
{\r
- res.render("profile\\message",{message:$invaild_parameter});\r
+ RenderMessage(res,resource.invaild_parameter,req.session.items);\r
return;\r
}\r
\r
- var info = new security.SessionInfomation(false);\r
- req.session.items = info;\r
+ if(typeof(req.session.items) == "undefined")\r
+ req.session.items = new security.SessionInfomation(false);\r
\r
async.waterfall([\r
function(cb){\r
},\r
],function(err,result){\r
if(err != null)\r
- res.render("profile\\message",{message:err});\r
+ RenderMessage(res,err,req.session.items);\r
else if(result.length == 0)\r
- res.render("profile\\message",{message:$notfound_name});\r
+ RenderMessage(res,resource.notfound_name,req.session.items);\r
else{\r
- res.render("profile\\detail",{list:result,token:info.token});\r
+ res.setHeader("X-FRAME-OPTIONS","DENY");\r
+ res.render("profile/detail",{list:result,alias:config.alias,token:req.session._csrf,admin:req.session.items.admin});\r
}\r
});\r
}\r
\r
function detail_postproc(req, res)\r
{\r
- if(req.session.items.token != req.body.token){\r
- res.render("profile\\message",{message:$invaild_parameter});\r
- return;\r
- }\r
if(typeof(req.body.remove) != "undefined"){\r
async.waterfall([\r
function(cb){\r
- collection.AuthAsync(req.body.name,req.body.password,cb);\r
+ if(typeof(req.session.items) != "undefined" && req.session.items.admin)\r
+ cb(null,true);\r
+ else\r
+ collection.AuthAsync(req.body.name,req.body.password,cb);\r
},\r
function(result,cb){\r
if(result)\r
}\r
],function(err,result){\r
if(err != null)\r
- res.render("profile\\message",{message:err});\r
+ RenderMessage(res,err,req.session.items);\r
else if(result == null)\r
- res.render("profile\\message",{message:$unmatch_password});\r
+ RenderMessage(res,resource.unmatch_password,req.session.items);\r
else\r
- res.render("profile\\message",{message:$success_remove});\r
+ RenderMessage(res,resource.success_remove,req.session.items);\r
});\r
}else if(typeof(req.body.edit) != "undefined"){\r
async.waterfall([\r
function(cb){\r
- collection.AuthAsync(req.body.name,req.body.password,cb);\r
+ if(typeof(req.session.items) != "undefined" && req.session.items.admin)\r
+ cb(null,true);\r
+ else\r
+ collection.AuthAsync(req.body.name,req.body.password,cb);\r
},\r
function(result,cb){\r
if(result)\r
}\r
],function(err,result){\r
if(err != null){\r
- res.render("profile\\message",{message:err});\r
+ RenderMessage(res,err,req.session.items);\r
}else if(result != null){\r
- res.render("profile\\edit",{list:result,token:req.body.token});\r
+ res.setHeader("X-FRAME-OPTIONS","DENY");\r
+ res.render("profile/edit",{list:result,token:req.session._csrf,alias:config.alias});\r
}else{\r
- res.render("profile\\message",{message:$unmatch_password});\r
+ RenderMessage(res,resource.unmatch_password,req.session.items);\r
}\r
});\r
}else{\r
- res.render("profile\\message",{message:$invaild_parameter});\r
+ RenderMessage(res,resource.invaild_parameter,req.session.items);\r
}\r
}\r
\r
function edit_postproc(req, res)\r
{\r
- if(req.session.items.token != req.body.token){\r
- res.render("profile\\message",{message:$invaild_parameter});\r
- return;\r
- }\r
if(typeof(req.body.name) == "undefined")\r
{\r
- res.render("profile\\message",{message:$invaild_parameter});\r
+ RenderMessage(res,resource.invaild_parameter,req.session.items);\r
return;\r
}else if(typeof(req.body.edit) != "undefined"){\r
+ var validator = new Validator();\r
+ var result = validator.Validate(req.body,config.alias,true);\r
+ if(result.length > 0)\r
+ {\r
+ RenderMessage(res,result,req.session.items);\r
+ return;\r
+ }\r
async.waterfall([\r
function(cb){\r
collection.UpdatAsync(req.body.name,req.body,cb);\r
- }\r
+ },\r
],function(err,result){\r
if(err != null)\r
- res.render("profile\\message",{message:err});\r
+ RenderMessage(res,err,req.session.items);\r
else\r
- res.render("profile\\message",{message:$success_edit});\r
+ RenderMessage(res,resource.success_edit,req.session.items);\r
});\r
}else{\r
- res.render("profile\\message",{message:$invaild_parameter});\r
+ RenderMessage(res,resource.invaild_parameter,req.session.items);\r
}\r
}\r
\r
function registor_postproc(req, res)\r
{\r
- if(req.session.items.token != req.body.token){\r
- res.render("profile\\message",{message:$invaild_parameter});\r
- return;\r
- }\r
if(typeof(req.body.registor) != "undefined"){\r
+ var validator = new Validator();\r
+ var result = validator.Validate(req.body,config.alias,false);\r
+ if(result.length > 0)\r
+ {\r
+ RenderMessage(res,result,req.session.items);\r
+ return;\r
+ }\r
async.waterfall([\r
function(cb){\r
collection.AddAsync(req.body,cb);\r
}\r
],function(err,result){\r
if(err != null)\r
- res.render("profile\\message",{message:err});\r
+ RenderMessage(res,err,req.session.items);\r
else\r
- res.render("profile\\message",{message:$success_registor});\r
+ RenderMessage(res,resource.success_registor,req.session.items);\r
});\r
}else{\r
- res.render("profile\\message",{message:$invaild_parameter});\r
+ RenderMessage(resource.invaild_parameter,req.session.items);\r
}\r
}\r
+\r
function registor_proc(req, res)\r
{\r
- var info = new security.SessionInfomation(false);\r
- req.session.items = info;\r
+ if(typeof(req.session.items) == "undefined")\r
+ req.session.items = new security.SessionInfomation(false);\r
+\r
+ res.setHeader("X-FRAME-OPTIONS","DENY");\r
+ res.render("profile/registor",{token:req.session._csrf,alias:config.alias});\r
+}\r
\r
- res.render("profile\\registor",{token:info.token});\r
+function RenderMessage(res,msg,info)\r
+{\r
+ if(typeof(msg) == "string")\r
+ msg = new Array(msg);\r
+ if(typeof(info) == "undefined" || typeof(info.admin) == "undefined")\r
+ res.render("profile/message",{message:msg,admin:false});\r
+ else\r
+ res.render("profile/message",{message:msg,admin:info.admin});\r
}\r
\r
//\r
//\r
function ProfileCollection()\r
{\r
- var pool = new MySQLPool();\r
+ var MySQLPool = new require("./mysql_pool.js");\r
+ var murmurhash = require("murmurhash");\r
+ var pool = new MySQLPool({\r
+ host : config.db_host,\r
+ user : config.db_user,\r
+ password : config.db_password,\r
+ port : config.db_port,\r
+ database : config.db_name,\r
+ });\r
this.AuthAsync = function(name,password,cb){\r
async.waterfall([\r
- function(callback){\r
- pool.acquire(callback);\r
+ function(next){\r
+ pool.query("SELECT password FROM profilelist WHERE name_hash = ? and name = ?",[murmurhash.v3(name),name],next);\r
},\r
- function(client,callback){\r
- client.query("SELECT * FROM list WHERE name = ?",[name],function(err,result){\r
- callback(err,result,client);\r
- });\r
- },\r
- function(result,client,callback){\r
- pool.release(client);\r
- if(result[0].password == password)\r
- callback(null,true);\r
+ function(result,next){\r
+ if(result[0].password == md5_hex(password))\r
+ next(null,true);\r
else\r
- callback(null,false);\r
+ next(null,false);\r
}\r
],cb);\r
}\r
this.GetAsync = function(name,cb){\r
- async.waterfall([\r
- function(callback){\r
- pool.acquire(callback);\r
- },\r
- function(client,callback){\r
- client.query("SELECT * FROM list WHERE name = ?",[name],function(err,result){\r
- callback(err,result,client);\r
- });\r
- },\r
- function(result,client,callback){\r
- pool.release(client);\r
- callback(null,result);\r
- }\r
- ],cb);\r
+ pool.query("SELECT * FROM profilelist WHERE name_hash = ? and name = ?",[murmurhash.v3(name),name],cb);\r
}\r
this.AddAsync = function(data,cb){\r
- var item = {\r
- name:data.name,\r
- age:data.age,\r
- gender:data.gender,\r
- height:data.height,\r
- weight:data.weight,\r
- race:data.race,\r
- password:data.password,\r
- lastmodified:new Date(),\r
- etc:data.etc\r
- };\r
- async.waterfall([\r
- function(callback){\r
- pool.acquire(callback);\r
- },\r
- function(client,callback){\r
- client.query("INSERT INTO list SET ?",[item],function(err,result){\r
- callback(err,result,client);\r
- });\r
- },\r
- function(result,client,callback){\r
- pool.release(client);\r
- callback(null,result);\r
- }\r
- ],cb);\r
+ var item = GetItem(data);;\r
+ pool.query("INSERT INTO profilelist SET ?",[item],cb);\r
}\r
this.UpdatAsync = function(name,data,cb){\r
- var item = {\r
- name:data.name,\r
- age:data.age,\r
- gender:data.gender,\r
- height:data.height,\r
- weight:data.weight,\r
- race:data.race,\r
- password:data.password,\r
- lastmodified:new Date(),\r
- etc:data.etc\r
- };\r
- async.waterfall([\r
- function(callback){\r
- pool.acquire(callback);\r
- },\r
- function(client,callback){\r
- client.query("UPDATE list SET ? WHERE name = ?",[item,name],function(err,result){\r
- callback(err,result,client);\r
- });\r
- },\r
- function(result,client,callback){\r
- pool.release(client);\r
- callback(null,result);\r
- }\r
- ],cb);\r
+ var item = GetItem(data);\r
+ pool.query("UPDATE profilelist SET ? WHERE name_hash = ? and name = ?",[item,murmurhash.v3(name),name],cb);\r
+ }\r
+ this.ClearAsync = function(cb){\r
+ pool.query("TRUNCATE TABLE profilelist",null,cb);\r
+ }\r
+ this.RemoveRangeAsync = function(names,cb){\r
+ pool.query("DELETE FROM profilelist WHERE name IN (?)",[names],cb);\r
}\r
this.RemoveAsync = function(name,cb){\r
- async.waterfall([\r
- function(callback){\r
- pool.acquire(callback);\r
- },\r
- function(client,callback){\r
- client.query("DELETE FROM list WHERE name = ?",[name],function(err,result){\r
- callback(err,result,client);\r
- });\r
- },\r
- function(result,client,callback){\r
- pool.release(client);\r
- callback(null,result);\r
- }\r
- ],cb);\r
+ pool.query("DELETE FROM profilelist WHERE name_hash = ? and name = ?",[murmurhash.v3(name),name],cb);\r
}\r
this.FindByNameAsync = function(pattern,start,count,cb){\r
- async.waterfall([\r
- function(callback){\r
- pool.acquire(callback);\r
- },\r
- function(client,callback){\r
- client.query("SELECT * FROM list WHERE name LIKE ? LIMIT ?,?",[pattern+"%",start,count],function(err,result){\r
- callback(err,result,client);\r
- });\r
- },\r
- function(result,client,callback){\r
- pool.release(client);\r
- callback(null,result);\r
- }\r
- ],cb);\r
+ pool.query("SELECT * FROM profilelist WHERE name LIKE ? LIMIT ?,?",[pattern+"%",start,count],cb);\r
}\r
this.ToArrayAsync = function(start,count,cb){\r
- async.waterfall([\r
- function(callback){\r
- pool.acquire(callback);\r
- },\r
- function(client,callback){\r
- client.query("SELECT * FROM list LIMIT ?,?",[start,count],function(err,result){\r
- callback(err,result,client);\r
- });\r
- },\r
- function(result,client,callback){\r
- pool.release(client);\r
- callback(null,result);\r
+ pool.query("SELECT name,lastmodified FROM profilelist LIMIT ?,?",[start,count],cb);\r
+ }\r
+\r
+ var crypto = require("crypto");\r
+ function md5_hex(src)\r
+ {\r
+ var md5 = crypto.createHash('md5');\r
+ md5.update(src, 'utf8');\r
+ return md5.digest('hex');\r
+ }\r
+\r
+ function GetItem(data,newpw)\r
+ {\r
+ var item = {\r
+ name_hash:murmurhash.v3(data.name),\r
+ lastmodified:new Date(),\r
+ };\r
+ for(var key in config.alias)\r
+ {\r
+ if(typeof(config.alias[key].nodefinetable) != "undefined" && \r
+ config.alias[key].nodefinetable)\r
+ continue;\r
+ if(config.alias[key].visible_edit)\r
+ {\r
+ if(config.alias[key].type == "password")\r
+ {\r
+ if(data[key] != "")\r
+ item[key] = md5_hex(data[key]);\r
+ }\r
+ else if(data[key] == "" && typeof(config.alias[key].defaultvalue) != "undefined")\r
+ {\r
+ item[key] = config.alias[key].defaultvalue;\r
+ }\r
+ else\r
+ {\r
+ item[key] = data[key];\r
+ }\r
}\r
- ],cb);\r
+ }\r
+ return item;\r
}\r
}\r
\r
-function MySQLPool()\r
+//\r
+// Validatorクラス\r
+//\r
+function Validator()\r
{\r
- var generic_pool = require("generic-pool");\r
- var mysql = require("mysql");\r
- return generic_pool.Pool({\r
- name : "mysql",\r
- max : 10,\r
- create : function(cb){\r
- var connection = mysql.createConnection({\r
- host : "localhost",\r
- user : $db_user,\r
- password : $db_password,\r
- database : "profile",\r
- });\r
- connection.connect();\r
- cb(null,connection);\r
- },\r
- destroy : function(db){\r
- db.end();\r
+ //\r
+ // バリテーションを行う。\r
+ // エラーがあった場合は真。そうでない場合は偽を返す\r
+ //\r
+ // @body バリテーションの対象となる連想配列\r
+ // @alias バリテーションを行う要素のリスト\r
+ // @editflag 編集時なら真\r
+ this.Validate = function(body,alias,editflag){\r
+ var result = new Array();\r
+ for(var key in alias)\r
+ {\r
+ if(alias[key].visible_edit == false)\r
+ continue;\r
+ var message;\r
+ if(typeof(alias[key].isnotempty) != "undefined" &&\r
+ alias[key].isnotempty && body[key] == "")\r
+ message = resource.is_not_empty;\r
+ else if(typeof(alias[key].isnotemptyonregistor) != "undefined" &&\r
+ alias[key].isnotemptyonregistor && body[key] == "" &&\r
+ !editflag)\r
+ message = resource.is_not_empty;\r
+ else if(typeof(alias[key].mustmatchitem) != "undefined" &&\r
+ body[key] != body[alias[key].mustmatchitem])\r
+ message = util.format(resource.must_match_item,alias[alias[key].mustmatchitem].name); \r
+ else\r
+ message = IsValidate(body[key],alias[key].type,alias[key].rule);\r
+ if(message != null)\r
+ result.push(alias[key].name + ":" + message);\r
}\r
- });\r
+ return result;\r
+ }\r
+ function IsValidate(data,type,rule){\r
+ if(typeof(data) == "undefined")\r
+ throw "data is undefined";\r
+ if(typeof(type) == "undefined")\r
+ throw "type is undefined";\r
+\r
+ var result = null;\r
+\r
+ switch(type)\r
+ {\r
+ case "text":\r
+ case "textarea":\r
+ case "password":\r
+ if(typeof(data) != "string")\r
+ result = resource.is_not_string;\r
+ break;\r
+ case "number":\r
+ if(data.match(/[^0-9]/g))\r
+ result = resource.is_not_number;\r
+ break;\r
+ case "mail":\r
+ if(data != "" && !data.match(/^[A-Za-z0-9]+[\w\-\+]+@[\w\.-]+\.\w{2,}$/))\r
+ result = resource.is_not_mail;\r
+ break;\r
+ }\r
+\r
+ if(typeof(rule) == "function")\r
+ result = rule(data,type);\r
+\r
+ return result;\r
+ }\r
}\r