您好:
+ +您在 {{.SITE_NAME}} 提交了找回密码申请。
如果您没有提交修改密码的申请, 请忽略本邮件
+ 请点击链接继续: {{.url}} +
++ 好的密码,不但应该容易记住,还要尽量符合以下强度标准: +
-
+
- 包含大小写字母、数字和符号 +
- 不少于 10 位 +
- 不包含生日、手机号码等易被猜出的信息 +
diff --git a/.gitignore b/.gitignore index 25e241ae..a35248b0 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,4 @@ _testmain.go *.test *.prof .idea +/conf/app.conf diff --git a/commands/command.go b/commands/command.go index 5c50d3ca..e76731f7 100644 --- a/commands/command.go +++ b/commands/command.go @@ -26,7 +26,7 @@ func RegisterDataBase() { port := beego.AppConfig.String("db_port") - dataSource := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8&parseTime=true&loc=%s",username,password,host,port,database,url.QueryEscape(timezone)) + dataSource := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8mb4&parseTime=true&loc=%s",username,password,host,port,database,url.QueryEscape(timezone)) orm.RegisterDataBase("default", "mysql", dataSource) @@ -47,22 +47,23 @@ func RegisterModel() { new(models.Attachment), new(models.Logger), new(models.CommentVote), + new(models.MemberToken), ) } func Initialization() { - o := orm.NewOrm() - o.Raw("alter table "+models.NewMember().TableNameWithPrefix()+" convert to character set utf8mb4_general_ci;").Exec() - o.Raw("alter table "+models.NewBook().TableNameWithPrefix()+" convert to character set utf8mb4_general_ci;").Exec() - o.Raw("alter table "+models.NewRelationship().TableNameWithPrefix()+" convert to character set utf8mb4_general_ci;").Exec() - o.Raw("alter table "+models.NewComment().TableNameWithPrefix()+" convert to character set utf8mb4_general_ci;").Exec() - o.Raw("alter table " +models.NewOption().TableNameWithPrefix()+" convert to character set utf8mb4_general_ci;").Exec() - o.Raw("alter table "+models.NewDocument().TableNameWithPrefix()+" convert to character set utf8mb4_general_ci;").Exec() - o.Raw("alter table "+models.NewAttachment().TableNameWithPrefix()+" convert to character set utf8mb4_general_ci;").Exec() - o.Raw("alter table "+models.NewLogger().TableNameWithPrefix()+" convert to character set utf8mb4_general_ci;").Exec() - o.Raw("alter table "+models.NewCommentVote().TableNameWithPrefix()+" convert to character set utf8mb4_general_ci;").Exec() + //o := orm.NewOrm() + //o.Raw("alter table "+models.NewMember().TableNameWithPrefix()+" convert to character set utf8mb4_general_ci;").Exec() + //o.Raw("alter table "+models.NewBook().TableNameWithPrefix()+" convert to character set utf8mb4_general_ci;").Exec() + //o.Raw("alter table "+models.NewRelationship().TableNameWithPrefix()+" convert to character set utf8mb4_general_ci;").Exec() + //o.Raw("alter table "+models.NewComment().TableNameWithPrefix()+" convert to character set utf8mb4_general_ci;").Exec() + //o.Raw("alter table " +models.NewOption().TableNameWithPrefix()+" convert to character set utf8mb4_general_ci;").Exec() + //o.Raw("alter table "+models.NewDocument().TableNameWithPrefix()+" convert to character set utf8mb4_general_ci;").Exec() + //o.Raw("alter table "+models.NewAttachment().TableNameWithPrefix()+" convert to character set utf8mb4_general_ci;").Exec() + //o.Raw("alter table "+models.NewLogger().TableNameWithPrefix()+" convert to character set utf8mb4_general_ci;").Exec() + //o.Raw("alter table "+models.NewCommentVote().TableNameWithPrefix()+" convert to character set utf8mb4_general_ci;").Exec() options := []models.Option { { OptionName: "ENABLED_CAPTCHA", OptionValue: "false", OptionTitle:"是否启用验证码"}, @@ -91,7 +92,6 @@ func RegisterLogger() { logs.EnableFuncCallDepth(true) logs.Async() - //beego.BeeLogger.DelLogger("console") if _,err := os.Stat("logs/log.log"); os.IsNotExist(err) { if f,err := os.Create("logs/log.log");err == nil { f.Close() diff --git a/conf/app.conf b/conf/app.conf deleted file mode 100644 index 718773cb..00000000 --- a/conf/app.conf +++ /dev/null @@ -1,31 +0,0 @@ -appname = godoc -httpport = 8181 -runmode = dev -sessionon = true -sessionname = mindoc_id -copyrequestbody = true - -#默认Session生成Key的秘钥 -beegoserversessionkey=123456 -#Session储存方式 -sessionprovider=file -sessionproviderconfig=./logs - -#时区设置 -timezone = Asia/Shanghai - -#数据库配置 -db_host=127.0.0.1 -db_port=3306 -db_database=mindoc_db -db_username=root -db_password=123456 - -#项目默认封面 -cover=/static/images/book.jpg - -#默认编辑器 -editor=markdown - -#上传文件的后缀 -upload_file_ext=txt|doc|docx|xls|xlsx|ppt|pptx|pdf|7z|rar|jpg|jpeg|png|gif \ No newline at end of file diff --git a/conf/app.conf.example b/conf/app.conf.example index 0cbd5ea5..0d8d8e7d 100644 --- a/conf/app.conf.example +++ b/conf/app.conf.example @@ -34,4 +34,22 @@ avatar=/static/images/headimgurl.jpg token_size=12 #上传文件的后缀 -upload_file_ext=txt|doc|docx|xls|xlsx|ppt|pptx|pdf|7z|rar|jpg|jpeg|png|gif \ No newline at end of file +upload_file_ext=txt|doc|docx|xls|xlsx|ppt|pptx|pdf|7z|rar|jpg|jpeg|png|gif + +####################邮件配置###################### +#是否启用邮件 +enable_mail=false +#每小时限制指定邮箱邮件发送次数 +mail_number=5 +#smtp服务用户名 +smtp_user_name=admin@iminho.me +#smtp服务器地址 +smtp_host=smtp.ym.163.com +#smtp密码 +smtp_password= +#端口号 +smtp_port=25 +#发送邮件的显示名称 +form_user_name=admin@iminho.me +#邮件有效期30分钟 +mail_expired=30 \ No newline at end of file diff --git a/conf/enumerate.go b/conf/enumerate.go index 2778b592..9d2ae5fd 100644 --- a/conf/enumerate.go +++ b/conf/enumerate.go @@ -52,14 +52,17 @@ func GetDefaultAvatar() string { return beego.AppConfig.DefaultString("avatar","/static/images/headimgurl.jpg") } +//获取阅读令牌长度. func GetTokenSize() int { return beego.AppConfig.DefaultInt("token_size",12) } +//获取默认文档封面. func GetDefaultCover() string { return beego.AppConfig.DefaultString("cover","/static/images/book.jpg") } +//获取允许的商城文件的类型. func GetUploadFileExt() []string { ext := beego.AppConfig.DefaultString("upload_file_ext","png|jpg|jpeg|gif|txt|doc|docx|pdf") @@ -76,7 +79,7 @@ func GetUploadFileExt() []string { } return exts } - +//判断是否是允许商城的文件类型. func IsAllowUploadFileExt(ext string) bool { if strings.HasPrefix(ext,".") { @@ -90,4 +93,9 @@ func IsAllowUploadFileExt(ext string) bool { } } return false +} + +//获取当前版本. +func Version() string { + return "v0.1" } \ No newline at end of file diff --git a/conf/mail.go b/conf/mail.go new file mode 100644 index 00000000..69304f03 --- /dev/null +++ b/conf/mail.go @@ -0,0 +1,38 @@ +package conf + +import ( + "github.com/astaxie/beego" + "strings" +) + +type SmtpConf struct { + EnableMail bool + MailNumber int + SmtpUserName string + SmtpHost string + SmtpPassword string + SmtpPort int + FormUserName string + MailExpired int +} + +func GetMailConfig() *SmtpConf { + user_name := beego.AppConfig.String("smtp_user_name") + password := beego.AppConfig.String("smtp_password") + smtp_host := beego.AppConfig.String("smtp_host") + smtp_port := beego.AppConfig.DefaultInt("smtp_port",25) + form_user_name := beego.AppConfig.String("form_user_name") + enable_mail := beego.AppConfig.String("enable_mail") + mail_number := beego.AppConfig.DefaultInt("mail_number",5) + + c := &SmtpConf{ + EnableMail : strings.EqualFold(enable_mail,"true"), + MailNumber: mail_number, + SmtpUserName:user_name, + SmtpHost:smtp_host, + SmtpPassword:password, + FormUserName:form_user_name, + SmtpPort:smtp_port, + } + return c +} \ No newline at end of file diff --git a/controllers/account.go b/controllers/account.go index c5f3a72e..ad0f461e 100644 --- a/controllers/account.go +++ b/controllers/account.go @@ -3,15 +3,16 @@ package controllers import ( "time" "strings" + "regexp" + "net/smtp" "github.com/lifei6671/godoc/conf" "github.com/lifei6671/godoc/models" "github.com/lifei6671/godoc/utils" "github.com/astaxie/beego" "github.com/astaxie/beego/logs" "github.com/lifei6671/gocaptcha" - - "regexp" + "strconv" ) // AccountController 用户登录与注册. @@ -30,10 +31,7 @@ func (c *AccountController) Login() { if cookie,ok := c.GetSecureCookie(conf.GetAppKey(),"login");ok{ if err := utils.Decode(cookie,&remember); err == nil { - member := models.NewMember() - member.MemberId = remember.MemberId - - if err := models.NewMember().Find(remember.MemberId); err == nil { + if member,err := models.NewMember().Find(remember.MemberId); err == nil { c.SetMember(*member) c.Redirect(beego.URLFor("HomeController.Index"), 302) @@ -137,9 +135,193 @@ func (c *AccountController) Register() { } } -func (p *AccountController) FindPassword() { - p.TplName = "account/find_password.tpl" +//找回密码. +func (c *AccountController) FindPassword() { + c.TplName = "account/find_password_setp1.tpl" + mail_conf := conf.GetMailConfig() + + if c.Ctx.Input.IsPost() { + + email := c.GetString("email") + captcha := c.GetString("code") + + if email == "" { + c.JsonResult(6005,"邮箱地址不能为空") + } + if !mail_conf.EnableMail { + c.JsonResult(6004,"未启用邮件服务") + } + + //如果开启了验证码 + if v,ok := c.Option["ENABLED_CAPTCHA"]; ok && strings.EqualFold(v,"true") { + v,ok := c.GetSession(conf.CaptchaSessionName).(string); + if !ok || !strings.EqualFold(v,captcha){ + c.JsonResult(6001,"验证码不正确") + } + } + + member ,err := models.NewMember().FindByFieldFirst("email",email) + if err != nil { + c.JsonResult(6006,"邮箱不存在") + } + if member.Status != 0 { + c.JsonResult(6007,"账号已被禁用") + } + + + count,err := models.NewMemberToken().FindSendCount(email,time.Now().Add(-1*time.Hour),time.Now()) + + if err != nil { + beego.Error(err) + c.JsonResult(6008,"发送邮件失败") + } + if count > mail_conf.MailNumber { + c.JsonResult(6008,"发送次数太多,请稍候再试") + } + + member_token := models.NewMemberToken() + + member_token.Token = string(utils.Krand(32,utils.KC_RAND_KIND_ALL)) + member_token.Email = email + member_token.MemberId = member.MemberId + member_token.IsValid = false + if _,err := member_token.InsertOrUpdate(); err != nil { + c.JsonResult(6009,"邮件发送失败") + } + + data := map[string]interface{}{ + "SITE_NAME" : c.Option["SITE_NAME"], + "url" : c.BaseUrl() + beego.URLFor("AccountController.FindPassword", "token",member_token.Token,"mail",email), + } + + body,err := c.ExecuteViewPathTemplate("account/mail_template.tpl",data) + if err != nil { + beego.Error(err) + c.JsonResult(6003,"邮件发送失败") + } + + go func(mail_conf *conf.SmtpConf,email string,body string) { + auth := smtp.PlainAuth( + "", + mail_conf.SmtpUserName, + mail_conf.SmtpPassword, + mail_conf.SmtpHost, + ) + + mime := "MIME-version: 1.0;\nContent-Type: text/html; charset=\"UTF-8\";\n\n"; + subject := "Subject: 找回密码!\n" + + err = smtp.SendMail( + mail_conf.SmtpHost + ":" + strconv.Itoa(mail_conf.SmtpPort), + auth, + mail_conf.FormUserName, + []string{ email }, + []byte(subject + mime +"\n" +body), + ) + if err != nil { + beego.Error("邮件发送失败 => ",email,err) + } + }(mail_conf,email,body) + + + c.JsonResult(0,"ok", c.BaseUrl() + beego.URLFor("AccountController.Login")) + } + + token := c.GetString("token") + mail := c.GetString("mail") + + if token != "" && mail != "" { + member_token,err := models.NewMemberToken().FindByFieldFirst("token",token) + + if err != nil { + beego.Error(err) + c.Data["ErrorMessage"] = "邮件已失效" + c.TplName = "errors/error.tpl" + return + } + sub_time := member_token.SendTime.Sub(time.Now()) + + if !strings.EqualFold(member_token.Email,mail) || sub_time.Minutes() > float64(mail_conf.MailExpired) || !member_token.ValidTime.IsZero() { + c.Data["ErrorMessage"] = "验证码已过期,请重新操作。" + c.TplName = "errors/error.tpl" + return + } + c.Data["Email"] = member_token.Email + c.Data["Token"] = member_token.Token + c.TplName = "account/find_password_setp2.tpl" + + } } + +//校验邮件并修改密码. +func (c *AccountController) ValidEmail() { + c.Prepare() + password1 := c.GetString("password1") + password2 := c.GetString("password2") + captcha := c.GetString("code") + token := c.GetString("token") + mail := c.GetString("mail") + + if password1 == "" { + c.JsonResult(6001,"密码不能为空") + } + if l := strings.Count(password1,""); l <6 || l > 50{ + c.JsonResult(6001,"密码不能为空且必须在6-50个字符之间") + } + if password2 == ""{ + c.JsonResult(6002,"确认密码不能为空") + } + if password1 != password2 { + c.JsonResult(6003,"确认密码输入不正确") + } + if captcha == "" { + c.JsonResult(6004,"验证码不能为空") + } + v,ok := c.GetSession(conf.CaptchaSessionName).(string); + if !ok || !strings.EqualFold(v,captcha){ + c.JsonResult(6001,"验证码不正确") + } + + mail_conf := conf.GetMailConfig() + member_token,err := models.NewMemberToken().FindByFieldFirst("token",token) + + if err != nil { + beego.Error(err) + c.JsonResult(6007,"邮件已失效") + } + sub_time := member_token.SendTime.Sub(time.Now()) + + if !strings.EqualFold(member_token.Email,mail) || sub_time.Minutes() > float64(mail_conf.MailExpired) || !member_token.ValidTime.IsZero() { + + c.JsonResult(6008,"验证码已过期,请重新操作。") + } + member ,err := models.NewMember().Find(member_token.MemberId) + if err != nil{ + beego.Error(err) + c.JsonResult(6005,"用户不存在") + } + hash ,err := utils.PasswordHash(password1); + + if err != nil { + beego.Error(err) + c.JsonResult(6006,"保存密码失败") + } + + member.Password = hash + + err = member.Update("password") + member_token.ValidTime = time.Now() + member_token.IsValid = true + member_token.InsertOrUpdate() + + if err != nil { + beego.Error(err) + c.JsonResult(6006,"保存密码失败") + } + c.JsonResult(0,"ok",c.BaseUrl() + beego.URLFor("AccountController.Login")) +} + + // Logout 退出登录. func (c *AccountController) Logout(){ c.SetMember(models.Member{}); diff --git a/controllers/base.go b/controllers/base.go index df84560b..fd5616cb 100644 --- a/controllers/base.go +++ b/controllers/base.go @@ -8,6 +8,8 @@ import ( "github.com/lifei6671/godoc/conf" "github.com/astaxie/beego" "strings" + "encoding/json" + "io" ) @@ -62,17 +64,25 @@ func (c *BaseController) SetMember(member models.Member) { // JsonResult 响应 json 结果 func (c *BaseController) JsonResult(errCode int,errMsg string,data ...interface{}){ - json := make(map[string]interface{},3) + jsonData := make(map[string]interface{},3) - json["errcode"] = errCode - json["message"] = errMsg + jsonData["errcode"] = errCode + jsonData["message"] = errMsg if len(data) > 0 && data[0] != nil{ - json["data"] = data[0] + jsonData["data"] = data[0] } - c.Data["json"] = json - c.ServeJSON(true) + returnJSON, err := json.Marshal(jsonData) + + if err != nil { + beego.Error(err) + } + + c.Ctx.ResponseWriter.Header().Set("Content-Type", "application/json; charset=utf-8") + + io.WriteString(c.Ctx.ResponseWriter,string(returnJSON)) + c.StopRun() } diff --git a/controllers/book_member.go b/controllers/book_member.go index 9f474d1f..1d406515 100644 --- a/controllers/book_member.go +++ b/controllers/book_member.go @@ -88,7 +88,7 @@ func (c *BookMemberController) ChangeRole() { member := models.NewMember() - if err := member.Find(member_id); err != nil { + if _,err := member.Find(member_id); err != nil { c.JsonResult(6003,"用户不存在") } if member.Status == 1 { diff --git a/controllers/error.go b/controllers/error.go new file mode 100644 index 00000000..f45cd51f --- /dev/null +++ b/controllers/error.go @@ -0,0 +1,17 @@ +package controllers + +type ErrorController struct { + BaseController +} + +func (c *ErrorController) Error404() { + c.TplName = "errors/404.tpl" +} + +func (c *ErrorController) Error403() { + c.TplName = "errors/403.tpl" +} + +func (c *ErrorController) Error500() { + c.TplName = "errors/error.tpl" +} diff --git a/controllers/manager.go b/controllers/manager.go index ce98cd0c..0bd8a4e0 100644 --- a/controllers/manager.go +++ b/controllers/manager.go @@ -139,7 +139,7 @@ func (c *ManagerController) UpdateMemberStatus() { } member := models.NewMember() - if err := member.Find(member_id); err != nil { + if _,err := member.Find(member_id); err != nil { c.JsonResult(6002,"用户不存在") } member.Status = status @@ -168,7 +168,7 @@ func (c *ManagerController) ChangeMemberRole() { } member := models.NewMember() - if err := member.Find(member_id); err != nil { + if _,err := member.Find(member_id); err != nil { c.JsonResult(6002,"用户不存在") } member.Role = role diff --git a/controllers/setting.go b/controllers/setting.go index 98be7ec8..cc7ae727 100644 --- a/controllers/setting.go +++ b/controllers/setting.go @@ -141,8 +141,7 @@ func (c *SettingController) Upload() { url := "/" + filePath - member := models.NewMember() - if err := member.Find(c.Member.MemberId);err == nil { + if member,err := models.NewMember().Find(c.Member.MemberId);err == nil { member.Avatar = url member.Update() c.SetMember(*member) diff --git a/main.go b/main.go index c495ae8e..60f7be08 100644 --- a/main.go +++ b/main.go @@ -7,6 +7,7 @@ import ( "github.com/lifei6671/godoc/commands" "fmt" "os" + "github.com/lifei6671/godoc/controllers" ) func main() { @@ -21,5 +22,7 @@ func main() { fmt.Println(os.Args[0]) + beego.ErrorController(&controllers.ErrorController{}) beego.Run() } + diff --git a/models/book_result.go b/models/book_result.go index 945744ee..6b05178b 100644 --- a/models/book_result.go +++ b/models/book_result.go @@ -73,9 +73,7 @@ func (m *BookResult) FindByIdentify(identify string,member_id int) (*BookResult, return m, ErrPermissionDenied } - member := NewMember() - - err = member.Find(relationship2.MemberId) + member, err := NewMember().Find(relationship2.MemberId) if err != nil { return m, err } diff --git a/models/comment.go b/models/comment.go index 27f4104a..fff779d9 100644 --- a/models/comment.go +++ b/models/comment.go @@ -118,7 +118,7 @@ func (m *Comment) Insert() error { if m.MemberId > 0 { member := NewMember() //如果用户不存在 - if err := member.Find(m.MemberId) ; err != nil { + if _,err := member.Find(m.MemberId) ; err != nil { return ErrMemberNoExist } //如果用户被禁用 diff --git a/models/member.go b/models/member.go index 1188ae64..26a598a0 100644 --- a/models/member.go +++ b/models/member.go @@ -7,6 +7,9 @@ import ( "github.com/lifei6671/godoc/utils" "github.com/lifei6671/godoc/conf" "github.com/astaxie/beego/logs" + "errors" + "regexp" + "strings" ) type Member struct { @@ -14,7 +17,7 @@ type Member struct { Account string `orm:"size(100);unique;column(account)" json:"account"` Password string `orm:"size(1000);column(password)" json:"-"` Description string `orm:"column(description);size(2000)" json:"description"` - Email string `orm:"size(255);column(email);null;default(null)" json:"email"` + Email string `orm:"size(255);column(email);unique" json:"email"` Phone string `orm:"size(255);column(phone);null;default(null)" json:"phone"` Avatar string `orm:"size(1000);column(avatar)" json:"avatar"` //用户角色:0 超级管理员 /1 管理员/ 2 普通用户 . @@ -71,6 +74,22 @@ func (m *Member) Login(account string,password string) (*Member,error) { func (m *Member) Add () (error) { o := orm.NewOrm() + if ok,err := regexp.MatchString(conf.RegexpAccount,m.Account); m.Account == "" || !ok || err != nil { + return errors.New("账号只能由英文字母数字组成,且在3-50个字符") + } + if m.Email == "" { + return errors.New("邮箱不能为空") + } + if ok,err := regexp.MatchString(conf.RegexpEmail,m.Email); !ok || err != nil || m.Email == "" { + return errors.New("邮箱格式不正确") + } + if l := strings.Count(m.Password,""); l <6 || l > 50{ + return errors.New("密码不能为空且必须在6-50个字符之间") + } + if c,err := o.QueryTable(m.TableNameWithPrefix()).Filter("email",m.Email).Count(); err == nil || c > 0 { + return errors.New("邮箱已被使用") + } + hash ,err := utils.PasswordHash(m.Password); if err != nil { @@ -92,21 +111,24 @@ func (m *Member) Add () (error) { func (m *Member) Update(cols... string) (error) { o := orm.NewOrm() + if m.Email == "" { + return errors.New("邮箱不能为空") + } if _,err := o.Update(m,cols...);err != nil { return err } return nil } -func (m *Member) Find(id int) error{ +func (m *Member) Find(id int) (*Member,error){ o := orm.NewOrm() m.MemberId = id if err := o.Read(m); err != nil { - return err + return m,err } m.ResolveRoleName() - return nil + return m,nil } func (m *Member) ResolveRoleName (){ @@ -163,7 +185,13 @@ func (c *Member) IsAdministrator() bool { return c.Role == 0 || c.Role == 1 } - +func (m *Member) FindByFieldFirst(field string,value interface{}) (*Member,error) { + o := orm.NewOrm() + + err := o.QueryTable(m.TableNameWithPrefix()).Filter(field,value).OrderBy("-member_id").One(m) + + return m,err +} diff --git a/models/member_token.go b/models/member_token.go new file mode 100644 index 00000000..cdf97731 --- /dev/null +++ b/models/member_token.go @@ -0,0 +1,66 @@ +package models + +import ( + "time" + "github.com/lifei6671/godoc/conf" + "github.com/astaxie/beego/orm" +) + +type MemberToken struct { + TokenId int `orm:"column(token_id);pk;auto;unique" json:"token_id"` + MemberId int `orm:"column(member_id);type(int)" json:"member_id"` + Token string `orm:"column(token);size(255);index" json:"token"` + Email string `orm:"column(email);size(255)" json:"email"` + IsValid bool `orm:"column(is_valid)" json:"is_valid"` + ValidTime time.Time `orm:"column(valid_time);null" json:"valid_time"` + SendTime time.Time `orm:"column(send_time);auto_now_add;type(datetime)" json:"send_time"` +} + + +// TableName 获取对应数据库表名. +func (m *MemberToken) TableName() string { + return "member_token" +} +// TableEngine 获取数据使用的引擎. +func (m *MemberToken) TableEngine() string { + return "INNODB" +} + +func (m *MemberToken)TableNameWithPrefix() string { + return conf.GetDatabasePrefix() + m.TableName() +} + +func NewMemberToken() *MemberToken { + return &MemberToken{} +} + +func (m *MemberToken) InsertOrUpdate() (*MemberToken,error){ + o := orm.NewOrm() + + if m.TokenId > 0 { + _,err := o.Update(m) + return m,err + } + _,err := o.Insert(m) + + return m,err +} + +func (m *MemberToken) FindByFieldFirst(field string,value interface{}) (*MemberToken,error) { + o := orm.NewOrm() + + err := o.QueryTable(m.TableNameWithPrefix()).Filter(field,value).OrderBy("-token_id").One(m) + + return m,err +} + +func (m *MemberToken) FindSendCount(mail string,start_time time.Time,end_time time.Time) (int ,error) { + o := orm.NewOrm() + + c,err := o.QueryTable(m.TableNameWithPrefix()).Filter("send_time__gte",start_time.Format("2006-01-02 15:04:05")).Filter("send_time__lte",end_time.Format("2006-01-02 15:04:05")).Count() + + if err != nil { + return 0,err + } + return int(c),nil +} \ No newline at end of file diff --git a/routers/filter.go b/routers/filter.go index 69108edc..5a61d5cf 100644 --- a/routers/filter.go +++ b/routers/filter.go @@ -22,4 +22,11 @@ func init() { beego.InsertFilter("/book",beego.BeforeRouter,FilterUser) beego.InsertFilter("/book/*",beego.BeforeRouter,FilterUser) beego.InsertFilter("/api/*",beego.BeforeRouter,FilterUser) + + var FinishRouter = func(ctx *context.Context) { + ctx.ResponseWriter.Header().Add("MinDoc-Version",conf.Version()) + ctx.ResponseWriter.Header().Add("MinDoc-Site","http://www.iminho.me") + } + + beego.InsertFilter("/*",beego.BeforeRouter ,FinishRouter, false) } diff --git a/routers/router.go b/routers/router.go index a36fcc35..0ed0fab0 100644 --- a/routers/router.go +++ b/routers/router.go @@ -12,6 +12,7 @@ func init() { beego.Router("/logout", &controllers.AccountController{},"*:Logout") beego.Router("/register", &controllers.AccountController{},"*:Register") beego.Router("/find_password", &controllers.AccountController{},"*:FindPassword") + beego.Router("/valid_email", &controllers.AccountController{},"post:ValidEmail") beego.Router("/captcha", &controllers.AccountController{},"*:Captcha") beego.Router("/manager", &controllers.ManagerController{},"*:Index") diff --git a/static/fonts/3Dumb.ttf b/static/fonts/3Dumb.ttf deleted file mode 100644 index 978409ae..00000000 Binary files a/static/fonts/3Dumb.ttf and /dev/null differ diff --git a/static/fonts/BigBlocko.ttf b/static/fonts/BigBlocko.ttf new file mode 100644 index 00000000..614b89c8 Binary files /dev/null and b/static/fonts/BigBlocko.ttf differ diff --git a/static/fonts/Bitsumishi.ttf b/static/fonts/Bitsumishi.ttf new file mode 100644 index 00000000..6d59a26b Binary files /dev/null and b/static/fonts/Bitsumishi.ttf differ diff --git a/static/fonts/Comismsh.ttf b/static/fonts/Comismsh.ttf deleted file mode 100644 index 0c4a3846..00000000 Binary files a/static/fonts/Comismsh.ttf and /dev/null differ diff --git a/static/fonts/DENNEthree-dee.ttf b/static/fonts/DENNEthree-dee.ttf deleted file mode 100644 index 0350b4d3..00000000 Binary files a/static/fonts/DENNEthree-dee.ttf and /dev/null differ diff --git a/static/fonts/Esquisito.ttf b/static/fonts/Esquisito.ttf deleted file mode 100644 index 64567c0c..00000000 Binary files a/static/fonts/Esquisito.ttf and /dev/null differ diff --git a/static/fonts/KREMLINGEORGIANI3D.ttf b/static/fonts/KREMLINGEORGIANI3D.ttf deleted file mode 100644 index 00be4a96..00000000 Binary files a/static/fonts/KREMLINGEORGIANI3D.ttf and /dev/null differ diff --git a/static/fonts/Pointy.ttf b/static/fonts/Pointy.ttf new file mode 100644 index 00000000..afa4f79e Binary files /dev/null and b/static/fonts/Pointy.ttf differ diff --git a/static/fonts/chromohv.ttf b/static/fonts/chromohv.ttf deleted file mode 100644 index 52ce0da6..00000000 Binary files a/static/fonts/chromohv.ttf and /dev/null differ diff --git a/static/fonts/lato-100.css b/static/fonts/lato-100.css new file mode 100644 index 00000000..fc802666 --- /dev/null +++ b/static/fonts/lato-100.css @@ -0,0 +1,16 @@ +/* latin-ext */ +@font-face { + font-family: 'Lato'; + font-style: normal; + font-weight: 100; + src: local('Lato Hairline'), local('Lato-Hairline'), url(lato/v11/eFRpvGLEW31oiexbYNx7Y_esZW2xOQ-xsNqO47m55DA.woff2) format('woff2'); + unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF; +} +/* latin */ +@font-face { + font-family: 'Lato'; + font-style: normal; + font-weight: 100; + src: local('Lato Hairline'), local('Lato-Hairline'), url(lato/v11/GtRkRNTnri0g82CjKnEB0Q.woff2) format('woff2'); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215; +} \ No newline at end of file diff --git a/static/fonts/lato/v11/GtRkRNTnri0g82CjKnEB0Q.woff2 b/static/fonts/lato/v11/GtRkRNTnri0g82CjKnEB0Q.woff2 new file mode 100644 index 00000000..536b618e Binary files /dev/null and b/static/fonts/lato/v11/GtRkRNTnri0g82CjKnEB0Q.woff2 differ diff --git a/static/fonts/lato/v11/eFRpvGLEW31oiexbYNx7Y_esZW2xOQ-xsNqO47m55DA.woff2 b/static/fonts/lato/v11/eFRpvGLEW31oiexbYNx7Y_esZW2xOQ-xsNqO47m55DA.woff2 new file mode 100644 index 00000000..bc79ca66 Binary files /dev/null and b/static/fonts/lato/v11/eFRpvGLEW31oiexbYNx7Y_esZW2xOQ-xsNqO47m55DA.woff2 differ diff --git a/views/account/find_password_setp1.tpl b/views/account/find_password_setp1.tpl new file mode 100644 index 00000000..f6ee1f56 --- /dev/null +++ b/views/account/find_password_setp1.tpl @@ -0,0 +1,130 @@ + + +
+ + + + + + +