Add the UploadAvatars permission.

Let users revoke their own avatars, work in progress.
Reduce boilerplate in debug.go

Add the UploadAvatars phrase.
Add the account_penalties phrase.
Add the account_menu_penalties phrase.
Add the account_avatar_revoke_button phrase.

More Vue and Conversations Work.
This commit is contained in:
Azareal 2019-06-09 13:21:48 +10:00
parent 9c19fc92ca
commit 199a841bc3
20 changed files with 4066 additions and 264 deletions

1
.gitignore vendored
View File

@ -13,6 +13,7 @@ backups/*.sql
logs/*.log logs/*.log
config/config.json config/config.json
node_modules/* node_modules/*
samples/vue/node_modules/*
bin/* bin/*
out/* out/*
*.exe *.exe

View File

@ -155,6 +155,7 @@ func seedTables(adapter qgen.Adapter) error {
Non-staff Global Permissions: Non-staff Global Permissions:
UploadFiles UploadFiles
UploadAvatars
Forum Permissions: Forum Permissions:
ViewTopic ViewTopic
@ -171,11 +172,11 @@ func seedTables(adapter qgen.Adapter) error {
*/ */
// TODO: Set the permissions on a struct and then serialize the struct and insert that instead of writing raw JSON // TODO: Set the permissions on a struct and then serialize the struct and insert that instead of writing raw JSON
qgen.Install.SimpleInsert("users_groups", "name, permissions, plugin_perms, is_mod, is_admin, tag", `'Administrator','{"BanUsers":true,"ActivateUsers":true,"EditUser":true,"EditUserEmail":true,"EditUserPassword":true,"EditUserGroup":true,"EditUserGroupSuperMod":true,"EditUserGroupAdmin":false,"EditGroup":true,"EditGroupLocalPerms":true,"EditGroupGlobalPerms":true,"EditGroupSuperMod":true,"EditGroupAdmin":false,"ManageForums":true,"EditSettings":true,"ManageThemes":true,"ManagePlugins":true,"ViewAdminLogs":true,"ViewIPs":true,"UploadFiles":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"EditTopic":true,"DeleteTopic":true,"CreateReply":true,"EditReply":true,"DeleteReply":true,"PinTopic":true,"CloseTopic":true,"MoveTopic":true}','{}',1,1,"Admin"`) qgen.Install.SimpleInsert("users_groups", "name, permissions, plugin_perms, is_mod, is_admin, tag", `'Administrator','{"BanUsers":true,"ActivateUsers":true,"EditUser":true,"EditUserEmail":true,"EditUserPassword":true,"EditUserGroup":true,"EditUserGroupSuperMod":true,"EditUserGroupAdmin":false,"EditGroup":true,"EditGroupLocalPerms":true,"EditGroupGlobalPerms":true,"EditGroupSuperMod":true,"EditGroupAdmin":false,"ManageForums":true,"EditSettings":true,"ManageThemes":true,"ManagePlugins":true,"ViewAdminLogs":true,"ViewIPs":true,"UploadFiles":true,"UploadAvatars":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"EditTopic":true,"DeleteTopic":true,"CreateReply":true,"EditReply":true,"DeleteReply":true,"PinTopic":true,"CloseTopic":true,"MoveTopic":true}','{}',1,1,"Admin"`)
qgen.Install.SimpleInsert("users_groups", "name, permissions, plugin_perms, is_mod, tag", `'Moderator','{"BanUsers":true,"ActivateUsers":false,"EditUser":true,"EditUserEmail":false,"EditUserGroup":true,"ViewIPs":true,"UploadFiles":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"EditTopic":true,"DeleteTopic":true,"CreateReply":true,"EditReply":true,"DeleteReply":true,"PinTopic":true,"CloseTopic":true,"MoveTopic":true}','{}',1,"Mod"`) qgen.Install.SimpleInsert("users_groups", "name, permissions, plugin_perms, is_mod, tag", `'Moderator','{"BanUsers":true,"ActivateUsers":false,"EditUser":true,"EditUserEmail":false,"EditUserGroup":true,"ViewIPs":true,"UploadFiles":true,"UploadAvatars":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"EditTopic":true,"DeleteTopic":true,"CreateReply":true,"EditReply":true,"DeleteReply":true,"PinTopic":true,"CloseTopic":true,"MoveTopic":true}','{}',1,"Mod"`)
qgen.Install.SimpleInsert("users_groups", "name, permissions, plugin_perms", `'Member','{"UploadFiles":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"CreateReply":true}','{}'`) qgen.Install.SimpleInsert("users_groups", "name, permissions, plugin_perms", `'Member','{"UploadFiles":true,"UploadAvatars":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"CreateReply":true}','{}'`)
qgen.Install.SimpleInsert("users_groups", "name, permissions, plugin_perms, is_banned", `'Banned','{"ViewTopic":true}','{}',1`) qgen.Install.SimpleInsert("users_groups", "name, permissions, plugin_perms, is_banned", `'Banned','{"ViewTopic":true}','{}',1`)

View File

@ -8,13 +8,41 @@ conversations
conversations_posts conversations_posts
*/ */
var convoStmts ConvoStmts
type ConvoStmts struct {
edit *sql.Stmt
create *sql.Stmt
}
func init() {
/*DbInits.Add(func(acc *qgen.Accumulator) error {
convoStmts = ConvoStmts{
edit: acc.Update("conversations").Set("participants = ?").Where("cid = ?").Prepare(),
create: acc.Insert("conversations").Columns("participants").Fields("?").Prepare(),
}
return acc.FirstError()
})*/
}
type Conversation struct { type Conversation struct {
ID int ID int
Participants string Participants string
} }
func (co *Conversation) Update() error {
_, err := convoStmts.edit.Exec(co.Participants, co.ID)
return err
}
func (co *Conversation) Create() (int, error) { func (co *Conversation) Create() (int, error) {
return 0, sql.ErrNoRows res, err := convoStmts.create.Exec(co.Participants)
if err != nil {
return 0, err
}
lastID, err := res.LastInsertId()
return int(lastID), err
} }
type ConversationPost struct { type ConversationPost struct {

View File

@ -38,6 +38,7 @@ var GlobalPermList = []string{
"ViewAdminLogs", "ViewAdminLogs",
"ViewIPs", "ViewIPs",
"UploadFiles", "UploadFiles",
"UploadAvatars",
} }
// Permission Structure: ActionComponent[Subcomponent]Flag // Permission Structure: ActionComponent[Subcomponent]Flag
@ -65,7 +66,7 @@ type Perms struct {
// Global non-staff permissions // Global non-staff permissions
UploadFiles bool UploadFiles bool
// TODO: Add a permission for enabling avatars UploadAvatars bool
// Forum permissions // Forum permissions
ViewTopic bool ViewTopic bool
@ -120,6 +121,7 @@ func init() {
ViewIPs: true, ViewIPs: true,
UploadFiles: true, UploadFiles: true,
UploadAvatars: true,
ViewTopic: true, ViewTopic: true,
LikeItem: true, LikeItem: true,

View File

@ -18,6 +18,7 @@ func ThumbTask(thumbChan chan bool) {
<-thumbChan <-thumbChan
// TODO: Use a real queue // TODO: Use a real queue
// TODO: Transactions? Self-repairing?
acc := qgen.NewAcc() acc := qgen.NewAcc()
err := acc.Select("users_avatar_queue").Columns("uid").Limit("0,5").EachInt(func(uid int) error { err := acc.Select("users_avatar_queue").Columns("uid").Limit("0,5").EachInt(func(uid int) error {
// TODO: Do a bulk user fetch instead? // TODO: Do a bulk user fetch instead?

View File

@ -198,7 +198,7 @@ func (s *DefaultTopicStore) Exists(id int) bool {
return s.exists.QueryRow(id).Scan(&id) == nil return s.exists.QueryRow(id).Scan(&id) == nil
} }
func (mts *DefaultTopicStore) Create(fid int, topicName string, content string, uid int, ipaddress string) (tid int, err error) { func (s *DefaultTopicStore) Create(fid int, topicName string, content string, uid int, ipaddress string) (tid int, err error) {
if topicName == "" { if topicName == "" {
return 0, ErrNoTitle return 0, ErrNoTitle
} }
@ -214,7 +214,7 @@ func (mts *DefaultTopicStore) Create(fid int, topicName string, content string,
wcount := WordCount(content) wcount := WordCount(content)
// TODO: Move this statement into the topic store // TODO: Move this statement into the topic store
res, err := mts.create.Exec(fid, topicName, content, parsedContent, uid, ipaddress, wcount, uid) res, err := s.create.Exec(fid, topicName, content, parsedContent, uid, ipaddress, wcount, uid)
if err != nil { if err != nil {
return 0, err return 0, err
} }

View File

@ -113,6 +113,7 @@ var RouteMap = map[string]interface{}{
"routes.AccountEditPassword": routes.AccountEditPassword, "routes.AccountEditPassword": routes.AccountEditPassword,
"routes.AccountEditPasswordSubmit": routes.AccountEditPasswordSubmit, "routes.AccountEditPasswordSubmit": routes.AccountEditPasswordSubmit,
"routes.AccountEditAvatarSubmit": routes.AccountEditAvatarSubmit, "routes.AccountEditAvatarSubmit": routes.AccountEditAvatarSubmit,
"routes.AccountEditRevokeAvatarSubmit": routes.AccountEditRevokeAvatarSubmit,
"routes.AccountEditUsernameSubmit": routes.AccountEditUsernameSubmit, "routes.AccountEditUsernameSubmit": routes.AccountEditUsernameSubmit,
"routes.AccountEditMFA": routes.AccountEditMFA, "routes.AccountEditMFA": routes.AccountEditMFA,
"routes.AccountEditMFASetup": routes.AccountEditMFASetup, "routes.AccountEditMFASetup": routes.AccountEditMFASetup,
@ -263,62 +264,63 @@ var routeMapEnum = map[string]int{
"routes.AccountEditPassword": 87, "routes.AccountEditPassword": 87,
"routes.AccountEditPasswordSubmit": 88, "routes.AccountEditPasswordSubmit": 88,
"routes.AccountEditAvatarSubmit": 89, "routes.AccountEditAvatarSubmit": 89,
"routes.AccountEditUsernameSubmit": 90, "routes.AccountEditRevokeAvatarSubmit": 90,
"routes.AccountEditMFA": 91, "routes.AccountEditUsernameSubmit": 91,
"routes.AccountEditMFASetup": 92, "routes.AccountEditMFA": 92,
"routes.AccountEditMFASetupSubmit": 93, "routes.AccountEditMFASetup": 93,
"routes.AccountEditMFADisableSubmit": 94, "routes.AccountEditMFASetupSubmit": 94,
"routes.AccountEditEmail": 95, "routes.AccountEditMFADisableSubmit": 95,
"routes.AccountEditEmailTokenSubmit": 96, "routes.AccountEditEmail": 96,
"routes.AccountLogins": 97, "routes.AccountEditEmailTokenSubmit": 97,
"routes.LevelList": 98, "routes.AccountLogins": 98,
"routes.ViewProfile": 99, "routes.LevelList": 99,
"routes.BanUserSubmit": 100, "routes.ViewProfile": 100,
"routes.UnbanUser": 101, "routes.BanUserSubmit": 101,
"routes.ActivateUser": 102, "routes.UnbanUser": 102,
"routes.IPSearch": 103, "routes.ActivateUser": 103,
"routes.CreateTopicSubmit": 104, "routes.IPSearch": 104,
"routes.EditTopicSubmit": 105, "routes.CreateTopicSubmit": 105,
"routes.DeleteTopicSubmit": 106, "routes.EditTopicSubmit": 106,
"routes.StickTopicSubmit": 107, "routes.DeleteTopicSubmit": 107,
"routes.UnstickTopicSubmit": 108, "routes.StickTopicSubmit": 108,
"routes.LockTopicSubmit": 109, "routes.UnstickTopicSubmit": 109,
"routes.UnlockTopicSubmit": 110, "routes.LockTopicSubmit": 110,
"routes.MoveTopicSubmit": 111, "routes.UnlockTopicSubmit": 111,
"routes.LikeTopicSubmit": 112, "routes.MoveTopicSubmit": 112,
"routes.AddAttachToTopicSubmit": 113, "routes.LikeTopicSubmit": 113,
"routes.RemoveAttachFromTopicSubmit": 114, "routes.AddAttachToTopicSubmit": 114,
"routes.ViewTopic": 115, "routes.RemoveAttachFromTopicSubmit": 115,
"routes.CreateReplySubmit": 116, "routes.ViewTopic": 116,
"routes.ReplyEditSubmit": 117, "routes.CreateReplySubmit": 117,
"routes.ReplyDeleteSubmit": 118, "routes.ReplyEditSubmit": 118,
"routes.ReplyLikeSubmit": 119, "routes.ReplyDeleteSubmit": 119,
"routes.AddAttachToReplySubmit": 120, "routes.ReplyLikeSubmit": 120,
"routes.RemoveAttachFromReplySubmit": 121, "routes.AddAttachToReplySubmit": 121,
"routes.ProfileReplyCreateSubmit": 122, "routes.RemoveAttachFromReplySubmit": 122,
"routes.ProfileReplyEditSubmit": 123, "routes.ProfileReplyCreateSubmit": 123,
"routes.ProfileReplyDeleteSubmit": 124, "routes.ProfileReplyEditSubmit": 124,
"routes.PollVote": 125, "routes.ProfileReplyDeleteSubmit": 125,
"routes.PollResults": 126, "routes.PollVote": 126,
"routes.AccountLogin": 127, "routes.PollResults": 127,
"routes.AccountRegister": 128, "routes.AccountLogin": 128,
"routes.AccountLogout": 129, "routes.AccountRegister": 129,
"routes.AccountLoginSubmit": 130, "routes.AccountLogout": 130,
"routes.AccountLoginMFAVerify": 131, "routes.AccountLoginSubmit": 131,
"routes.AccountLoginMFAVerifySubmit": 132, "routes.AccountLoginMFAVerify": 132,
"routes.AccountRegisterSubmit": 133, "routes.AccountLoginMFAVerifySubmit": 133,
"routes.AccountPasswordReset": 134, "routes.AccountRegisterSubmit": 134,
"routes.AccountPasswordResetSubmit": 135, "routes.AccountPasswordReset": 135,
"routes.AccountPasswordResetToken": 136, "routes.AccountPasswordResetSubmit": 136,
"routes.AccountPasswordResetTokenSubmit": 137, "routes.AccountPasswordResetToken": 137,
"routes.DynamicRoute": 138, "routes.AccountPasswordResetTokenSubmit": 138,
"routes.UploadedFile": 139, "routes.DynamicRoute": 139,
"routes.StaticFile": 140, "routes.UploadedFile": 140,
"routes.RobotsTxt": 141, "routes.StaticFile": 141,
"routes.SitemapXml": 142, "routes.RobotsTxt": 142,
"routes.OpenSearchXml": 143, "routes.SitemapXml": 143,
"routes.BadRoute": 144, "routes.OpenSearchXml": 144,
"routes.HTTPSRedirect": 145, "routes.BadRoute": 145,
"routes.HTTPSRedirect": 146,
} }
var reverseRouteMapEnum = map[int]string{ var reverseRouteMapEnum = map[int]string{
0: "routes.Overview", 0: "routes.Overview",
@ -411,62 +413,63 @@ var reverseRouteMapEnum = map[int]string{
87: "routes.AccountEditPassword", 87: "routes.AccountEditPassword",
88: "routes.AccountEditPasswordSubmit", 88: "routes.AccountEditPasswordSubmit",
89: "routes.AccountEditAvatarSubmit", 89: "routes.AccountEditAvatarSubmit",
90: "routes.AccountEditUsernameSubmit", 90: "routes.AccountEditRevokeAvatarSubmit",
91: "routes.AccountEditMFA", 91: "routes.AccountEditUsernameSubmit",
92: "routes.AccountEditMFASetup", 92: "routes.AccountEditMFA",
93: "routes.AccountEditMFASetupSubmit", 93: "routes.AccountEditMFASetup",
94: "routes.AccountEditMFADisableSubmit", 94: "routes.AccountEditMFASetupSubmit",
95: "routes.AccountEditEmail", 95: "routes.AccountEditMFADisableSubmit",
96: "routes.AccountEditEmailTokenSubmit", 96: "routes.AccountEditEmail",
97: "routes.AccountLogins", 97: "routes.AccountEditEmailTokenSubmit",
98: "routes.LevelList", 98: "routes.AccountLogins",
99: "routes.ViewProfile", 99: "routes.LevelList",
100: "routes.BanUserSubmit", 100: "routes.ViewProfile",
101: "routes.UnbanUser", 101: "routes.BanUserSubmit",
102: "routes.ActivateUser", 102: "routes.UnbanUser",
103: "routes.IPSearch", 103: "routes.ActivateUser",
104: "routes.CreateTopicSubmit", 104: "routes.IPSearch",
105: "routes.EditTopicSubmit", 105: "routes.CreateTopicSubmit",
106: "routes.DeleteTopicSubmit", 106: "routes.EditTopicSubmit",
107: "routes.StickTopicSubmit", 107: "routes.DeleteTopicSubmit",
108: "routes.UnstickTopicSubmit", 108: "routes.StickTopicSubmit",
109: "routes.LockTopicSubmit", 109: "routes.UnstickTopicSubmit",
110: "routes.UnlockTopicSubmit", 110: "routes.LockTopicSubmit",
111: "routes.MoveTopicSubmit", 111: "routes.UnlockTopicSubmit",
112: "routes.LikeTopicSubmit", 112: "routes.MoveTopicSubmit",
113: "routes.AddAttachToTopicSubmit", 113: "routes.LikeTopicSubmit",
114: "routes.RemoveAttachFromTopicSubmit", 114: "routes.AddAttachToTopicSubmit",
115: "routes.ViewTopic", 115: "routes.RemoveAttachFromTopicSubmit",
116: "routes.CreateReplySubmit", 116: "routes.ViewTopic",
117: "routes.ReplyEditSubmit", 117: "routes.CreateReplySubmit",
118: "routes.ReplyDeleteSubmit", 118: "routes.ReplyEditSubmit",
119: "routes.ReplyLikeSubmit", 119: "routes.ReplyDeleteSubmit",
120: "routes.AddAttachToReplySubmit", 120: "routes.ReplyLikeSubmit",
121: "routes.RemoveAttachFromReplySubmit", 121: "routes.AddAttachToReplySubmit",
122: "routes.ProfileReplyCreateSubmit", 122: "routes.RemoveAttachFromReplySubmit",
123: "routes.ProfileReplyEditSubmit", 123: "routes.ProfileReplyCreateSubmit",
124: "routes.ProfileReplyDeleteSubmit", 124: "routes.ProfileReplyEditSubmit",
125: "routes.PollVote", 125: "routes.ProfileReplyDeleteSubmit",
126: "routes.PollResults", 126: "routes.PollVote",
127: "routes.AccountLogin", 127: "routes.PollResults",
128: "routes.AccountRegister", 128: "routes.AccountLogin",
129: "routes.AccountLogout", 129: "routes.AccountRegister",
130: "routes.AccountLoginSubmit", 130: "routes.AccountLogout",
131: "routes.AccountLoginMFAVerify", 131: "routes.AccountLoginSubmit",
132: "routes.AccountLoginMFAVerifySubmit", 132: "routes.AccountLoginMFAVerify",
133: "routes.AccountRegisterSubmit", 133: "routes.AccountLoginMFAVerifySubmit",
134: "routes.AccountPasswordReset", 134: "routes.AccountRegisterSubmit",
135: "routes.AccountPasswordResetSubmit", 135: "routes.AccountPasswordReset",
136: "routes.AccountPasswordResetToken", 136: "routes.AccountPasswordResetSubmit",
137: "routes.AccountPasswordResetTokenSubmit", 137: "routes.AccountPasswordResetToken",
138: "routes.DynamicRoute", 138: "routes.AccountPasswordResetTokenSubmit",
139: "routes.UploadedFile", 139: "routes.DynamicRoute",
140: "routes.StaticFile", 140: "routes.UploadedFile",
141: "routes.RobotsTxt", 141: "routes.StaticFile",
142: "routes.SitemapXml", 142: "routes.RobotsTxt",
143: "routes.OpenSearchXml", 143: "routes.SitemapXml",
144: "routes.BadRoute", 144: "routes.OpenSearchXml",
145: "routes.HTTPSRedirect", 145: "routes.BadRoute",
146: "routes.HTTPSRedirect",
} }
var osMapEnum = map[string]int{ var osMapEnum = map[string]int{
"unknown": 0, "unknown": 0,
@ -624,7 +627,7 @@ type HTTPSRedirect struct {
func (red *HTTPSRedirect) ServeHTTP(w http.ResponseWriter, req *http.Request) { func (red *HTTPSRedirect) ServeHTTP(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Connection", "close") w.Header().Set("Connection", "close")
counters.RouteViewCounter.Bump(145) counters.RouteViewCounter.Bump(146)
dest := "https://" + req.Host + req.URL.String() dest := "https://" + req.Host + req.URL.String()
http.Redirect(w, req, dest, http.StatusTemporaryRedirect) http.Redirect(w, req, dest, http.StatusTemporaryRedirect)
} }
@ -828,7 +831,7 @@ func (r *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
counters.GlobalViewCounter.Bump() counters.GlobalViewCounter.Bump()
if prefix == "/static" { if prefix == "/static" {
counters.RouteViewCounter.Bump(140) counters.RouteViewCounter.Bump(141)
req.URL.Path += extraData req.URL.Path += extraData
routes.StaticFile(w, req) routes.StaticFile(w, req)
return return
@ -1669,7 +1672,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
counters.RouteViewCounter.Bump(89) counters.RouteViewCounter.Bump(89)
err = routes.AccountEditAvatarSubmit(w,req,user) err = routes.AccountEditAvatarSubmit(w,req,user)
case "/user/edit/username/submit/": case "/user/edit/avatar/revoke/submit/":
err = c.NoSessionMismatch(w,req,user) err = c.NoSessionMismatch(w,req,user)
if err != nil { if err != nil {
return err return err
@ -1681,6 +1684,19 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
} }
counters.RouteViewCounter.Bump(90) counters.RouteViewCounter.Bump(90)
err = routes.AccountEditRevokeAvatarSubmit(w,req,user)
case "/user/edit/username/submit/":
err = c.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = c.MemberOnly(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(91)
err = routes.AccountEditUsernameSubmit(w,req,user) err = routes.AccountEditUsernameSubmit(w,req,user)
case "/user/edit/mfa/": case "/user/edit/mfa/":
err = c.MemberOnly(w,req,user) err = c.MemberOnly(w,req,user)
@ -1688,7 +1704,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err return err
} }
counters.RouteViewCounter.Bump(91) counters.RouteViewCounter.Bump(92)
head, err := c.UserCheck(w,req,&user) head, err := c.UserCheck(w,req,&user)
if err != nil { if err != nil {
return err return err
@ -1700,7 +1716,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err return err
} }
counters.RouteViewCounter.Bump(92) counters.RouteViewCounter.Bump(93)
head, err := c.UserCheck(w,req,&user) head, err := c.UserCheck(w,req,&user)
if err != nil { if err != nil {
return err return err
@ -1717,7 +1733,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err return err
} }
counters.RouteViewCounter.Bump(93) counters.RouteViewCounter.Bump(94)
err = routes.AccountEditMFASetupSubmit(w,req,user) err = routes.AccountEditMFASetupSubmit(w,req,user)
case "/user/edit/mfa/disable/submit/": case "/user/edit/mfa/disable/submit/":
err = c.NoSessionMismatch(w,req,user) err = c.NoSessionMismatch(w,req,user)
@ -1730,7 +1746,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err return err
} }
counters.RouteViewCounter.Bump(94) counters.RouteViewCounter.Bump(95)
err = routes.AccountEditMFADisableSubmit(w,req,user) err = routes.AccountEditMFADisableSubmit(w,req,user)
case "/user/edit/email/": case "/user/edit/email/":
err = c.MemberOnly(w,req,user) err = c.MemberOnly(w,req,user)
@ -1738,14 +1754,14 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err return err
} }
counters.RouteViewCounter.Bump(95) counters.RouteViewCounter.Bump(96)
head, err := c.UserCheck(w,req,&user) head, err := c.UserCheck(w,req,&user)
if err != nil { if err != nil {
return err return err
} }
err = routes.AccountEditEmail(w,req,user,head) err = routes.AccountEditEmail(w,req,user,head)
case "/user/edit/token/": case "/user/edit/token/":
counters.RouteViewCounter.Bump(96) counters.RouteViewCounter.Bump(97)
err = routes.AccountEditEmailTokenSubmit(w,req,user,extraData) err = routes.AccountEditEmailTokenSubmit(w,req,user,extraData)
case "/user/edit/logins/": case "/user/edit/logins/":
err = c.MemberOnly(w,req,user) err = c.MemberOnly(w,req,user)
@ -1753,7 +1769,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err return err
} }
counters.RouteViewCounter.Bump(97) counters.RouteViewCounter.Bump(98)
head, err := c.UserCheck(w,req,&user) head, err := c.UserCheck(w,req,&user)
if err != nil { if err != nil {
return err return err
@ -1765,7 +1781,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err return err
} }
counters.RouteViewCounter.Bump(98) counters.RouteViewCounter.Bump(99)
head, err := c.UserCheck(w,req,&user) head, err := c.UserCheck(w,req,&user)
if err != nil { if err != nil {
return err return err
@ -1773,7 +1789,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
err = routes.LevelList(w,req,user,head) err = routes.LevelList(w,req,user,head)
default: default:
req.URL.Path += extraData req.URL.Path += extraData
counters.RouteViewCounter.Bump(99) counters.RouteViewCounter.Bump(100)
head, err := c.UserCheck(w,req,&user) head, err := c.UserCheck(w,req,&user)
if err != nil { if err != nil {
return err return err
@ -1793,7 +1809,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err return err
} }
counters.RouteViewCounter.Bump(100) counters.RouteViewCounter.Bump(101)
err = routes.BanUserSubmit(w,req,user,extraData) err = routes.BanUserSubmit(w,req,user,extraData)
case "/users/unban/": case "/users/unban/":
err = c.NoSessionMismatch(w,req,user) err = c.NoSessionMismatch(w,req,user)
@ -1806,7 +1822,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err return err
} }
counters.RouteViewCounter.Bump(101) counters.RouteViewCounter.Bump(102)
err = routes.UnbanUser(w,req,user,extraData) err = routes.UnbanUser(w,req,user,extraData)
case "/users/activate/": case "/users/activate/":
err = c.NoSessionMismatch(w,req,user) err = c.NoSessionMismatch(w,req,user)
@ -1819,7 +1835,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err return err
} }
counters.RouteViewCounter.Bump(102) counters.RouteViewCounter.Bump(103)
err = routes.ActivateUser(w,req,user,extraData) err = routes.ActivateUser(w,req,user,extraData)
case "/users/ips/": case "/users/ips/":
err = c.MemberOnly(w,req,user) err = c.MemberOnly(w,req,user)
@ -1827,7 +1843,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err return err
} }
counters.RouteViewCounter.Bump(103) counters.RouteViewCounter.Bump(104)
head, err := c.UserCheck(w,req,&user) head, err := c.UserCheck(w,req,&user)
if err != nil { if err != nil {
return err return err
@ -1851,7 +1867,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err return err
} }
counters.RouteViewCounter.Bump(104) counters.RouteViewCounter.Bump(105)
err = routes.CreateTopicSubmit(w,req,user) err = routes.CreateTopicSubmit(w,req,user)
case "/topic/edit/submit/": case "/topic/edit/submit/":
err = c.NoSessionMismatch(w,req,user) err = c.NoSessionMismatch(w,req,user)
@ -1864,7 +1880,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err return err
} }
counters.RouteViewCounter.Bump(105) counters.RouteViewCounter.Bump(106)
err = routes.EditTopicSubmit(w,req,user,extraData) err = routes.EditTopicSubmit(w,req,user,extraData)
case "/topic/delete/submit/": case "/topic/delete/submit/":
err = c.NoSessionMismatch(w,req,user) err = c.NoSessionMismatch(w,req,user)
@ -1878,7 +1894,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
} }
req.URL.Path += extraData req.URL.Path += extraData
counters.RouteViewCounter.Bump(106) counters.RouteViewCounter.Bump(107)
err = routes.DeleteTopicSubmit(w,req,user) err = routes.DeleteTopicSubmit(w,req,user)
case "/topic/stick/submit/": case "/topic/stick/submit/":
err = c.NoSessionMismatch(w,req,user) err = c.NoSessionMismatch(w,req,user)
@ -1891,7 +1907,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err return err
} }
counters.RouteViewCounter.Bump(107) counters.RouteViewCounter.Bump(108)
err = routes.StickTopicSubmit(w,req,user,extraData) err = routes.StickTopicSubmit(w,req,user,extraData)
case "/topic/unstick/submit/": case "/topic/unstick/submit/":
err = c.NoSessionMismatch(w,req,user) err = c.NoSessionMismatch(w,req,user)
@ -1904,7 +1920,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err return err
} }
counters.RouteViewCounter.Bump(108) counters.RouteViewCounter.Bump(109)
err = routes.UnstickTopicSubmit(w,req,user,extraData) err = routes.UnstickTopicSubmit(w,req,user,extraData)
case "/topic/lock/submit/": case "/topic/lock/submit/":
err = c.NoSessionMismatch(w,req,user) err = c.NoSessionMismatch(w,req,user)
@ -1918,7 +1934,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
} }
req.URL.Path += extraData req.URL.Path += extraData
counters.RouteViewCounter.Bump(109) counters.RouteViewCounter.Bump(110)
err = routes.LockTopicSubmit(w,req,user) err = routes.LockTopicSubmit(w,req,user)
case "/topic/unlock/submit/": case "/topic/unlock/submit/":
err = c.NoSessionMismatch(w,req,user) err = c.NoSessionMismatch(w,req,user)
@ -1931,7 +1947,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err return err
} }
counters.RouteViewCounter.Bump(110) counters.RouteViewCounter.Bump(111)
err = routes.UnlockTopicSubmit(w,req,user,extraData) err = routes.UnlockTopicSubmit(w,req,user,extraData)
case "/topic/move/submit/": case "/topic/move/submit/":
err = c.NoSessionMismatch(w,req,user) err = c.NoSessionMismatch(w,req,user)
@ -1944,7 +1960,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err return err
} }
counters.RouteViewCounter.Bump(111) counters.RouteViewCounter.Bump(112)
err = routes.MoveTopicSubmit(w,req,user,extraData) err = routes.MoveTopicSubmit(w,req,user,extraData)
case "/topic/like/submit/": case "/topic/like/submit/":
err = c.NoSessionMismatch(w,req,user) err = c.NoSessionMismatch(w,req,user)
@ -1957,7 +1973,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err return err
} }
counters.RouteViewCounter.Bump(112) counters.RouteViewCounter.Bump(113)
err = routes.LikeTopicSubmit(w,req,user,extraData) err = routes.LikeTopicSubmit(w,req,user,extraData)
case "/topic/attach/add/submit/": case "/topic/attach/add/submit/":
err = c.MemberOnly(w,req,user) err = c.MemberOnly(w,req,user)
@ -1974,7 +1990,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err return err
} }
counters.RouteViewCounter.Bump(113) counters.RouteViewCounter.Bump(114)
err = routes.AddAttachToTopicSubmit(w,req,user,extraData) err = routes.AddAttachToTopicSubmit(w,req,user,extraData)
case "/topic/attach/remove/submit/": case "/topic/attach/remove/submit/":
err = c.NoSessionMismatch(w,req,user) err = c.NoSessionMismatch(w,req,user)
@ -1987,10 +2003,10 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err return err
} }
counters.RouteViewCounter.Bump(114) counters.RouteViewCounter.Bump(115)
err = routes.RemoveAttachFromTopicSubmit(w,req,user,extraData) err = routes.RemoveAttachFromTopicSubmit(w,req,user,extraData)
default: default:
counters.RouteViewCounter.Bump(115) counters.RouteViewCounter.Bump(116)
head, err := c.UserCheck(w,req,&user) head, err := c.UserCheck(w,req,&user)
if err != nil { if err != nil {
return err return err
@ -2014,7 +2030,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err return err
} }
counters.RouteViewCounter.Bump(116) counters.RouteViewCounter.Bump(117)
err = routes.CreateReplySubmit(w,req,user) err = routes.CreateReplySubmit(w,req,user)
case "/reply/edit/submit/": case "/reply/edit/submit/":
err = c.NoSessionMismatch(w,req,user) err = c.NoSessionMismatch(w,req,user)
@ -2027,7 +2043,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err return err
} }
counters.RouteViewCounter.Bump(117) counters.RouteViewCounter.Bump(118)
err = routes.ReplyEditSubmit(w,req,user,extraData) err = routes.ReplyEditSubmit(w,req,user,extraData)
case "/reply/delete/submit/": case "/reply/delete/submit/":
err = c.NoSessionMismatch(w,req,user) err = c.NoSessionMismatch(w,req,user)
@ -2040,7 +2056,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err return err
} }
counters.RouteViewCounter.Bump(118) counters.RouteViewCounter.Bump(119)
err = routes.ReplyDeleteSubmit(w,req,user,extraData) err = routes.ReplyDeleteSubmit(w,req,user,extraData)
case "/reply/like/submit/": case "/reply/like/submit/":
err = c.NoSessionMismatch(w,req,user) err = c.NoSessionMismatch(w,req,user)
@ -2053,7 +2069,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err return err
} }
counters.RouteViewCounter.Bump(119) counters.RouteViewCounter.Bump(120)
err = routes.ReplyLikeSubmit(w,req,user,extraData) err = routes.ReplyLikeSubmit(w,req,user,extraData)
case "/reply/attach/add/submit/": case "/reply/attach/add/submit/":
err = c.MemberOnly(w,req,user) err = c.MemberOnly(w,req,user)
@ -2070,7 +2086,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err return err
} }
counters.RouteViewCounter.Bump(120) counters.RouteViewCounter.Bump(121)
err = routes.AddAttachToReplySubmit(w,req,user,extraData) err = routes.AddAttachToReplySubmit(w,req,user,extraData)
case "/reply/attach/remove/submit/": case "/reply/attach/remove/submit/":
err = c.NoSessionMismatch(w,req,user) err = c.NoSessionMismatch(w,req,user)
@ -2083,7 +2099,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err return err
} }
counters.RouteViewCounter.Bump(121) counters.RouteViewCounter.Bump(122)
err = routes.RemoveAttachFromReplySubmit(w,req,user,extraData) err = routes.RemoveAttachFromReplySubmit(w,req,user,extraData)
} }
case "/profile": case "/profile":
@ -2099,7 +2115,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err return err
} }
counters.RouteViewCounter.Bump(122) counters.RouteViewCounter.Bump(123)
err = routes.ProfileReplyCreateSubmit(w,req,user) err = routes.ProfileReplyCreateSubmit(w,req,user)
case "/profile/reply/edit/submit/": case "/profile/reply/edit/submit/":
err = c.NoSessionMismatch(w,req,user) err = c.NoSessionMismatch(w,req,user)
@ -2112,7 +2128,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err return err
} }
counters.RouteViewCounter.Bump(123) counters.RouteViewCounter.Bump(124)
err = routes.ProfileReplyEditSubmit(w,req,user,extraData) err = routes.ProfileReplyEditSubmit(w,req,user,extraData)
case "/profile/reply/delete/submit/": case "/profile/reply/delete/submit/":
err = c.NoSessionMismatch(w,req,user) err = c.NoSessionMismatch(w,req,user)
@ -2125,7 +2141,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err return err
} }
counters.RouteViewCounter.Bump(124) counters.RouteViewCounter.Bump(125)
err = routes.ProfileReplyDeleteSubmit(w,req,user,extraData) err = routes.ProfileReplyDeleteSubmit(w,req,user,extraData)
} }
case "/poll": case "/poll":
@ -2141,23 +2157,23 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err return err
} }
counters.RouteViewCounter.Bump(125) counters.RouteViewCounter.Bump(126)
err = routes.PollVote(w,req,user,extraData) err = routes.PollVote(w,req,user,extraData)
case "/poll/results/": case "/poll/results/":
counters.RouteViewCounter.Bump(126) counters.RouteViewCounter.Bump(127)
err = routes.PollResults(w,req,user,extraData) err = routes.PollResults(w,req,user,extraData)
} }
case "/accounts": case "/accounts":
switch(req.URL.Path) { switch(req.URL.Path) {
case "/accounts/login/": case "/accounts/login/":
counters.RouteViewCounter.Bump(127) counters.RouteViewCounter.Bump(128)
head, err := c.UserCheck(w,req,&user) head, err := c.UserCheck(w,req,&user)
if err != nil { if err != nil {
return err return err
} }
err = routes.AccountLogin(w,req,user,head) err = routes.AccountLogin(w,req,user,head)
case "/accounts/create/": case "/accounts/create/":
counters.RouteViewCounter.Bump(128) counters.RouteViewCounter.Bump(129)
head, err := c.UserCheck(w,req,&user) head, err := c.UserCheck(w,req,&user)
if err != nil { if err != nil {
return err return err
@ -2174,7 +2190,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err return err
} }
counters.RouteViewCounter.Bump(129) counters.RouteViewCounter.Bump(130)
err = routes.AccountLogout(w,req,user) err = routes.AccountLogout(w,req,user)
case "/accounts/login/submit/": case "/accounts/login/submit/":
err = c.ParseForm(w,req,user) err = c.ParseForm(w,req,user)
@ -2182,10 +2198,10 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err return err
} }
counters.RouteViewCounter.Bump(130) counters.RouteViewCounter.Bump(131)
err = routes.AccountLoginSubmit(w,req,user) err = routes.AccountLoginSubmit(w,req,user)
case "/accounts/mfa_verify/": case "/accounts/mfa_verify/":
counters.RouteViewCounter.Bump(131) counters.RouteViewCounter.Bump(132)
head, err := c.UserCheck(w,req,&user) head, err := c.UserCheck(w,req,&user)
if err != nil { if err != nil {
return err return err
@ -2197,7 +2213,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err return err
} }
counters.RouteViewCounter.Bump(132) counters.RouteViewCounter.Bump(133)
err = routes.AccountLoginMFAVerifySubmit(w,req,user) err = routes.AccountLoginMFAVerifySubmit(w,req,user)
case "/accounts/create/submit/": case "/accounts/create/submit/":
err = c.ParseForm(w,req,user) err = c.ParseForm(w,req,user)
@ -2205,10 +2221,10 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err return err
} }
counters.RouteViewCounter.Bump(133) counters.RouteViewCounter.Bump(134)
err = routes.AccountRegisterSubmit(w,req,user) err = routes.AccountRegisterSubmit(w,req,user)
case "/accounts/password-reset/": case "/accounts/password-reset/":
counters.RouteViewCounter.Bump(134) counters.RouteViewCounter.Bump(135)
head, err := c.UserCheck(w,req,&user) head, err := c.UserCheck(w,req,&user)
if err != nil { if err != nil {
return err return err
@ -2220,10 +2236,10 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err return err
} }
counters.RouteViewCounter.Bump(135) counters.RouteViewCounter.Bump(136)
err = routes.AccountPasswordResetSubmit(w,req,user) err = routes.AccountPasswordResetSubmit(w,req,user)
case "/accounts/password-reset/token/": case "/accounts/password-reset/token/":
counters.RouteViewCounter.Bump(136) counters.RouteViewCounter.Bump(137)
head, err := c.UserCheck(w,req,&user) head, err := c.UserCheck(w,req,&user)
if err != nil { if err != nil {
return err return err
@ -2235,7 +2251,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err return err
} }
counters.RouteViewCounter.Bump(137) counters.RouteViewCounter.Bump(138)
err = routes.AccountPasswordResetTokenSubmit(w,req,user) err = routes.AccountPasswordResetTokenSubmit(w,req,user)
} }
/*case "/sitemaps": // TODO: Count these views /*case "/sitemaps": // TODO: Count these views
@ -2251,7 +2267,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
w.Header().Del("Content-Type") w.Header().Del("Content-Type")
w.Header().Del("Content-Encoding") w.Header().Del("Content-Encoding")
} }
counters.RouteViewCounter.Bump(139) counters.RouteViewCounter.Bump(140)
req.URL.Path += extraData req.URL.Path += extraData
// TODO: Find a way to propagate errors up from this? // TODO: Find a way to propagate errors up from this?
r.UploadHandler(w,req) // TODO: Count these views r.UploadHandler(w,req) // TODO: Count these views
@ -2261,7 +2277,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
// TODO: Add support for favicons and robots.txt files // TODO: Add support for favicons and robots.txt files
switch(extraData) { switch(extraData) {
case "robots.txt": case "robots.txt":
counters.RouteViewCounter.Bump(141) counters.RouteViewCounter.Bump(142)
return routes.RobotsTxt(w,req) return routes.RobotsTxt(w,req)
case "favicon.ico": case "favicon.ico":
req.URL.Path = "/static"+req.URL.Path+extraData req.URL.Path = "/static"+req.URL.Path+extraData
@ -2269,10 +2285,10 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
routes.StaticFile(w,req) routes.StaticFile(w,req)
return nil return nil
case "opensearch.xml": case "opensearch.xml":
counters.RouteViewCounter.Bump(143) counters.RouteViewCounter.Bump(144)
return routes.OpenSearchXml(w,req) return routes.OpenSearchXml(w,req)
/*case "sitemap.xml": /*case "sitemap.xml":
counters.RouteViewCounter.Bump(142) counters.RouteViewCounter.Bump(143)
return routes.SitemapXml(w,req)*/ return routes.SitemapXml(w,req)*/
} }
return c.NotFound(w,req,nil) return c.NotFound(w,req,nil)
@ -2283,7 +2299,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
r.RUnlock() r.RUnlock()
if ok { if ok {
counters.RouteViewCounter.Bump(138) // TODO: Be more specific about *which* dynamic route it is counters.RouteViewCounter.Bump(139) // TODO: Be more specific about *which* dynamic route it is
req.URL.Path += extraData req.URL.Path += extraData
return handle(w,req,user) return handle(w,req,user)
} }
@ -2294,7 +2310,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
} else { } else {
r.DumpRequest(req,"Bad Route") r.DumpRequest(req,"Bad Route")
} }
counters.RouteViewCounter.Bump(144) counters.RouteViewCounter.Bump(145)
return c.NotFound(w,req,nil) return c.NotFound(w,req,nil)
} }
return err return err

View File

@ -28,7 +28,8 @@
"ViewAdminLogs": "Can view the administrator action logs", "ViewAdminLogs": "Can view the administrator action logs",
"ViewIPs": "Can view IP addresses", "ViewIPs": "Can view IP addresses",
"UploadFiles": "Can upload files" "UploadFiles": "Can upload files",
"UploadAvatars": "Can upload avatars"
}, },
"LocalPerms": { "LocalPerms": {
@ -140,6 +141,7 @@
"account_mfa_setup":"Setup 2FA", "account_mfa_setup":"Setup 2FA",
"account_email":"Email Manager", "account_email":"Email Manager",
"account_logins":"Logins", "account_logins":"Logins",
"account_penalties":"Penalties",
"account_level_list":"Level Progress", "account_level_list":"Level Progress",
"panel_dashboard":"Control Panel Dashboard", "panel_dashboard":"Control Panel Dashboard",
@ -489,6 +491,7 @@
"account_menu_security":"Security", "account_menu_security":"Security",
"account_menu_notifications":"Notifications", "account_menu_notifications":"Notifications",
"account_menu_logins":"Logins", "account_menu_logins":"Logins",
"account_menu_penalties":"Penalties",
"account_coming_soon":"Coming Soon", "account_coming_soon":"Coming Soon",
@ -498,6 +501,7 @@
"account_username_save":"Save", "account_username_save":"Save",
"account_avatar_select":"Select", "account_avatar_select":"Select",
"account_avatar_update_button":"Upload", "account_avatar_update_button":"Upload",
"account_avatar_revoke_button":"Remove",
"account_email_head":"Emails", "account_email_head":"Emails",
"account_email_primary":"Primary", "account_email_primary":"Primary",

View File

@ -53,6 +53,7 @@ func userRoutes() *RouteGroup {
MemberView("routes.AccountEditPassword", "/user/edit/password/"), MemberView("routes.AccountEditPassword", "/user/edit/password/"),
Action("routes.AccountEditPasswordSubmit", "/user/edit/password/submit/"), // TODO: Full test this Action("routes.AccountEditPasswordSubmit", "/user/edit/password/submit/"), // TODO: Full test this
UploadAction("routes.AccountEditAvatarSubmit", "/user/edit/avatar/submit/").MaxSizeVar("int(c.Config.MaxRequestSize)"), UploadAction("routes.AccountEditAvatarSubmit", "/user/edit/avatar/submit/").MaxSizeVar("int(c.Config.MaxRequestSize)"),
Action("routes.AccountEditRevokeAvatarSubmit", "/user/edit/avatar/revoke/submit/"),
Action("routes.AccountEditUsernameSubmit", "/user/edit/username/submit/"), // TODO: Full test this Action("routes.AccountEditUsernameSubmit", "/user/edit/username/submit/"), // TODO: Full test this
MemberView("routes.AccountEditMFA", "/user/edit/mfa/"), MemberView("routes.AccountEditMFA", "/user/edit/mfa/"),
MemberView("routes.AccountEditMFASetup", "/user/edit/mfa/setup/"), MemberView("routes.AccountEditMFASetup", "/user/edit/mfa/setup/"),

View File

@ -427,6 +427,9 @@ func AccountEditAvatarSubmit(w http.ResponseWriter, r *http.Request, user c.User
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
if !user.Perms.UploadAvatars {
return c.NoPermissions(w, r, user)
}
// We don't want multiple files // We don't want multiple files
// TODO: Are we doing this correctly? // TODO: Are we doing this correctly?
@ -522,6 +525,37 @@ func AccountEditAvatarSubmit(w http.ResponseWriter, r *http.Request, user c.User
return nil return nil
} }
func AccountEditRevokeAvatarSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
_, ferr := c.SimpleUserCheck(w, r, &user)
if ferr != nil {
return ferr
}
err := user.ChangeAvatar("")
if err != nil {
return c.InternalError(err, w, r)
}
// Clean up the old avatar data, so we don't end up with too many dead files in /uploads/
if len(user.RawAvatar) > 2 {
if user.RawAvatar[0] == '.' && user.RawAvatar[1] == '.' {
err := os.Remove("./uploads/avatar_" + strconv.Itoa(user.ID) + "_tmp" + user.RawAvatar[1:])
if err != nil && !os.IsNotExist(err) {
c.LogWarning(err)
return c.LocalError("Something went wrong", w, r, user)
}
err = os.Remove("./uploads/avatar_" + strconv.Itoa(user.ID) + "_w48" + user.RawAvatar[1:])
if err != nil && !os.IsNotExist(err) {
c.LogWarning(err)
return c.LocalError("Something went wrong", w, r, user)
}
}
}
http.Redirect(w, r, "/user/edit/?avatar_updated=1", http.StatusSeeOther)
return nil
}
func AccountEditUsernameSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { func AccountEditUsernameSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
_, ferr := c.SimpleUserCheck(w, r, &user) _, ferr := c.SimpleUserCheck(w, r, &user)
if ferr != nil { if ferr != nil {

View File

@ -62,91 +62,58 @@ func Debug(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
debugCache := c.DebugPageCache{tlen, ulen, rlen, tcap, ucap, rcap, topicListThawed} debugCache := c.DebugPageCache{tlen, ulen, rlen, tcap, ucap, rcap, topicListThawed}
var count = func(tbl string) (int, error) { var fErr error
return qgen.NewAcc().Count(tbl).Total() var count = func(tbl string) int {
} if fErr != nil {
// TODO: Call Count on an attachment store return 0
attachs, err := count("attachments") }
if err != nil { c, err := qgen.NewAcc().Count(tbl).Total()
return c.InternalError(err,w,r) fErr = err
} return c
// TODO: Implement a PollStore and call Count on that instead
polls, err := count("polls")
if err != nil {
return c.InternalError(err,w,r)
} }
loginLogs, err := count("login_logs") // TODO: Call Count on an attachment store
if err != nil { attachs := count("attachments")
return c.InternalError(err,w,r) // TODO: Implement a PollStore and call Count on that instead
} polls := count("polls")
regLogs, err := count("registration_logs")
if err != nil { loginLogs := count("login_logs")
return c.InternalError(err,w,r) regLogs := count("registration_logs")
} modLogs := count("moderation_logs")
modLogs, err := count("moderation_logs") adminLogs := count("administration_logs")
if err != nil {
return c.InternalError(err,w,r)
}
adminLogs, err := count("administration_logs")
if err != nil {
return c.InternalError(err,w,r)
}
views, err := count("viewchunks") views := count("viewchunks")
if err != nil { viewsAgents := count("viewchunks_agents")
return c.InternalError(err,w,r) viewsForums := count("viewchunks_forums")
} viewsLangs := count("viewchunks_langs")
viewsAgents, err := count("viewchunks_agents") viewsReferrers := count("viewchunks_referrers")
if err != nil { viewsSystems := count("viewchunks_systems")
return c.InternalError(err,w,r) postChunks := count("postchunks")
} topicChunks := count("topicchunks")
viewsForums, err := count("viewchunks_forums") if fErr != nil {
if err != nil { return c.InternalError(fErr,w,r)
return c.InternalError(err,w,r)
}
viewsLangs, err := count("viewchunks_langs")
if err != nil {
return c.InternalError(err,w,r)
}
viewsReferrers, err := count("viewchunks_referrers")
if err != nil {
return c.InternalError(err,w,r)
}
viewsSystems, err := count("viewchunks_systems")
if err != nil {
return c.InternalError(err,w,r)
}
postChunks, err := count("postchunks")
if err != nil {
return c.InternalError(err,w,r)
}
topicChunks, err := count("topicchunks")
if err != nil {
return c.InternalError(err,w,r)
} }
debugDatabase := c.DebugPageDatabase{c.Topics.Count(),c.Users.Count(),c.Rstore.Count(),c.Prstore.Count(),c.Activity.Count(),c.Likes.Count(),attachs,polls,loginLogs,regLogs,modLogs,adminLogs,views,viewsAgents,viewsForums,viewsLangs,viewsReferrers,viewsSystems,postChunks,topicChunks} debugDatabase := c.DebugPageDatabase{c.Topics.Count(),c.Users.Count(),c.Rstore.Count(),c.Prstore.Count(),c.Activity.Count(),c.Likes.Count(),attachs,polls,loginLogs,regLogs,modLogs,adminLogs,views,viewsAgents,viewsForums,viewsLangs,viewsReferrers,viewsSystems,postChunks,topicChunks}
staticSize, err := c.DirSize("./public/") var dirSize = func(path string) int {
if err != nil { if fErr != nil {
return c.InternalError(err,w,r) return 0
}
c, err := c.DirSize(path)
fErr = err
return c
} }
attachSize, err := c.DirSize("./attachs/")
if err != nil { staticSize := dirSize("./public/")
return c.InternalError(err,w,r) attachSize := dirSize("./attachs/")
} uploadsSize := dirSize("./uploads/")
uploadsSize, err := c.DirSize("./uploads/") logsSize := dirSize("./logs/")
if err != nil { backupsSize := dirSize("./backups/")
return c.InternalError(err,w,r) if fErr != nil {
} return c.InternalError(fErr,w,r)
logsSize, err := c.DirSize("./logs/")
if err != nil {
return c.InternalError(err,w,r)
}
backupsSize, err := c.DirSize("./backups/")
if err != nil {
return c.InternalError(err,w,r)
} }
debugDisk := c.DebugPageDisk{staticSize,attachSize,uploadsSize,logsSize,backupsSize} debugDisk := c.DebugPageDisk{staticSize,attachSize,uploadsSize,logsSize,backupsSize}
pi := c.PanelDebugPage{basePage, goVersion, dbVersion, uptime, openConnCount, qgen.Builder.GetAdapter().GetName(), goroutines, cpus, memStats, debugCache, debugDatabase, debugDisk} pi := c.PanelDebugPage{basePage, goVersion, dbVersion, uptime, openConnCount, qgen.Builder.GetAdapter().GetName(), goroutines, cpus, memStats, debugCache, debugDatabase, debugDisk}

View File

@ -184,6 +184,7 @@ func GroupsEditPerms(w http.ResponseWriter, r *http.Request, user c.User, sgid s
addGlobalPerm("ViewAdminLogs", group.Perms.ViewAdminLogs) addGlobalPerm("ViewAdminLogs", group.Perms.ViewAdminLogs)
addGlobalPerm("ViewIPs", group.Perms.ViewIPs) addGlobalPerm("ViewIPs", group.Perms.ViewIPs)
addGlobalPerm("UploadFiles", group.Perms.UploadFiles) addGlobalPerm("UploadFiles", group.Perms.UploadFiles)
addGlobalPerm("UploadAvatars", group.Perms.UploadAvatars)
pi := c.PanelEditGroupPermsPage{basePage, group.ID, group.Name, localPerms, globalPerms} pi := c.PanelEditGroupPermsPage{basePage, group.ID, group.Name, localPerms, globalPerms}
return renderTemplate("panel_group_edit_perms", w, r, basePage.Header, pi) return renderTemplate("panel_group_edit_perms", w, r, basePage.Header, pi)

3697
samples/vue/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

24
samples/vue/package.json Normal file
View File

@ -0,0 +1,24 @@
{
"name": "gosora-vue",
"version": "0.3.0-dev",
"description": "",
"private": true,
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build":"webpack"
},
"repository": {
"type": "git",
"url": "https://github.com/Azareal/Gosora.git"
},
"keywords": [],
"author": "Azareal",
"license": "MIT",
"homepage": "https://gosora-project.com",
"devDependencies": {
"webpack-cli": "^3.3.3"
},
"dependencies": {
"webpack": "^4.33.0"
}
}

View File

@ -7,9 +7,9 @@ INSERT INTO [settings] ([name],[content],[type]) VALUES ('rapid_loading','1','bo
INSERT INTO [settings] ([name],[content],[type]) VALUES ('google_site_verify','','html-attribute'); INSERT INTO [settings] ([name],[content],[type]) VALUES ('google_site_verify','','html-attribute');
INSERT INTO [themes] ([uname],[default]) VALUES ('cosora',1); INSERT INTO [themes] ([uname],[default]) VALUES ('cosora',1);
INSERT INTO [emails] ([email],[uid],[validated]) VALUES ('admin@localhost',1,1); INSERT INTO [emails] ([email],[uid],[validated]) VALUES ('admin@localhost',1,1);
INSERT INTO [users_groups] ([name],[permissions],[plugin_perms],[is_mod],[is_admin],[tag]) VALUES ('Administrator','{"BanUsers":true,"ActivateUsers":true,"EditUser":true,"EditUserEmail":true,"EditUserPassword":true,"EditUserGroup":true,"EditUserGroupSuperMod":true,"EditUserGroupAdmin":false,"EditGroup":true,"EditGroupLocalPerms":true,"EditGroupGlobalPerms":true,"EditGroupSuperMod":true,"EditGroupAdmin":false,"ManageForums":true,"EditSettings":true,"ManageThemes":true,"ManagePlugins":true,"ViewAdminLogs":true,"ViewIPs":true,"UploadFiles":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"EditTopic":true,"DeleteTopic":true,"CreateReply":true,"EditReply":true,"DeleteReply":true,"PinTopic":true,"CloseTopic":true,"MoveTopic":true}','{}',1,1,'Admin'); INSERT INTO [users_groups] ([name],[permissions],[plugin_perms],[is_mod],[is_admin],[tag]) VALUES ('Administrator','{"BanUsers":true,"ActivateUsers":true,"EditUser":true,"EditUserEmail":true,"EditUserPassword":true,"EditUserGroup":true,"EditUserGroupSuperMod":true,"EditUserGroupAdmin":false,"EditGroup":true,"EditGroupLocalPerms":true,"EditGroupGlobalPerms":true,"EditGroupSuperMod":true,"EditGroupAdmin":false,"ManageForums":true,"EditSettings":true,"ManageThemes":true,"ManagePlugins":true,"ViewAdminLogs":true,"ViewIPs":true,"UploadFiles":true,"UploadAvatars":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"EditTopic":true,"DeleteTopic":true,"CreateReply":true,"EditReply":true,"DeleteReply":true,"PinTopic":true,"CloseTopic":true,"MoveTopic":true}','{}',1,1,'Admin');
INSERT INTO [users_groups] ([name],[permissions],[plugin_perms],[is_mod],[tag]) VALUES ('Moderator','{"BanUsers":true,"ActivateUsers":false,"EditUser":true,"EditUserEmail":false,"EditUserGroup":true,"ViewIPs":true,"UploadFiles":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"EditTopic":true,"DeleteTopic":true,"CreateReply":true,"EditReply":true,"DeleteReply":true,"PinTopic":true,"CloseTopic":true,"MoveTopic":true}','{}',1,'Mod'); INSERT INTO [users_groups] ([name],[permissions],[plugin_perms],[is_mod],[tag]) VALUES ('Moderator','{"BanUsers":true,"ActivateUsers":false,"EditUser":true,"EditUserEmail":false,"EditUserGroup":true,"ViewIPs":true,"UploadFiles":true,"UploadAvatars":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"EditTopic":true,"DeleteTopic":true,"CreateReply":true,"EditReply":true,"DeleteReply":true,"PinTopic":true,"CloseTopic":true,"MoveTopic":true}','{}',1,'Mod');
INSERT INTO [users_groups] ([name],[permissions],[plugin_perms]) VALUES ('Member','{"UploadFiles":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"CreateReply":true}','{}'); INSERT INTO [users_groups] ([name],[permissions],[plugin_perms]) VALUES ('Member','{"UploadFiles":true,"UploadAvatars":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"CreateReply":true}','{}');
INSERT INTO [users_groups] ([name],[permissions],[plugin_perms],[is_banned]) VALUES ('Banned','{"ViewTopic":true}','{}',1); INSERT INTO [users_groups] ([name],[permissions],[plugin_perms],[is_banned]) VALUES ('Banned','{"ViewTopic":true}','{}',1);
INSERT INTO [users_groups] ([name],[permissions],[plugin_perms]) VALUES ('Awaiting Activation','{"ViewTopic":true}','{}'); INSERT INTO [users_groups] ([name],[permissions],[plugin_perms]) VALUES ('Awaiting Activation','{"ViewTopic":true}','{}');
INSERT INTO [users_groups] ([name],[permissions],[plugin_perms],[tag]) VALUES ('Not Loggedin','{"ViewTopic":true}','{}','Guest'); INSERT INTO [users_groups] ([name],[permissions],[plugin_perms],[tag]) VALUES ('Not Loggedin','{"ViewTopic":true}','{}','Guest');

View File

@ -15,9 +15,9 @@ INSERT INTO `settings`(`name`,`content`,`type`) VALUES ('rapid_loading','1','boo
INSERT INTO `settings`(`name`,`content`,`type`) VALUES ('google_site_verify','','html-attribute'); INSERT INTO `settings`(`name`,`content`,`type`) VALUES ('google_site_verify','','html-attribute');
INSERT INTO `themes`(`uname`,`default`) VALUES ('cosora',1); INSERT INTO `themes`(`uname`,`default`) VALUES ('cosora',1);
INSERT INTO `emails`(`email`,`uid`,`validated`) VALUES ('admin@localhost',1,1); INSERT INTO `emails`(`email`,`uid`,`validated`) VALUES ('admin@localhost',1,1);
INSERT INTO `users_groups`(`name`,`permissions`,`plugin_perms`,`is_mod`,`is_admin`,`tag`) VALUES ('Administrator','{"BanUsers":true,"ActivateUsers":true,"EditUser":true,"EditUserEmail":true,"EditUserPassword":true,"EditUserGroup":true,"EditUserGroupSuperMod":true,"EditUserGroupAdmin":false,"EditGroup":true,"EditGroupLocalPerms":true,"EditGroupGlobalPerms":true,"EditGroupSuperMod":true,"EditGroupAdmin":false,"ManageForums":true,"EditSettings":true,"ManageThemes":true,"ManagePlugins":true,"ViewAdminLogs":true,"ViewIPs":true,"UploadFiles":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"EditTopic":true,"DeleteTopic":true,"CreateReply":true,"EditReply":true,"DeleteReply":true,"PinTopic":true,"CloseTopic":true,"MoveTopic":true}','{}',1,1,'Admin'); INSERT INTO `users_groups`(`name`,`permissions`,`plugin_perms`,`is_mod`,`is_admin`,`tag`) VALUES ('Administrator','{"BanUsers":true,"ActivateUsers":true,"EditUser":true,"EditUserEmail":true,"EditUserPassword":true,"EditUserGroup":true,"EditUserGroupSuperMod":true,"EditUserGroupAdmin":false,"EditGroup":true,"EditGroupLocalPerms":true,"EditGroupGlobalPerms":true,"EditGroupSuperMod":true,"EditGroupAdmin":false,"ManageForums":true,"EditSettings":true,"ManageThemes":true,"ManagePlugins":true,"ViewAdminLogs":true,"ViewIPs":true,"UploadFiles":true,"UploadAvatars":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"EditTopic":true,"DeleteTopic":true,"CreateReply":true,"EditReply":true,"DeleteReply":true,"PinTopic":true,"CloseTopic":true,"MoveTopic":true}','{}',1,1,'Admin');
INSERT INTO `users_groups`(`name`,`permissions`,`plugin_perms`,`is_mod`,`tag`) VALUES ('Moderator','{"BanUsers":true,"ActivateUsers":false,"EditUser":true,"EditUserEmail":false,"EditUserGroup":true,"ViewIPs":true,"UploadFiles":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"EditTopic":true,"DeleteTopic":true,"CreateReply":true,"EditReply":true,"DeleteReply":true,"PinTopic":true,"CloseTopic":true,"MoveTopic":true}','{}',1,'Mod'); INSERT INTO `users_groups`(`name`,`permissions`,`plugin_perms`,`is_mod`,`tag`) VALUES ('Moderator','{"BanUsers":true,"ActivateUsers":false,"EditUser":true,"EditUserEmail":false,"EditUserGroup":true,"ViewIPs":true,"UploadFiles":true,"UploadAvatars":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"EditTopic":true,"DeleteTopic":true,"CreateReply":true,"EditReply":true,"DeleteReply":true,"PinTopic":true,"CloseTopic":true,"MoveTopic":true}','{}',1,'Mod');
INSERT INTO `users_groups`(`name`,`permissions`,`plugin_perms`) VALUES ('Member','{"UploadFiles":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"CreateReply":true}','{}'); INSERT INTO `users_groups`(`name`,`permissions`,`plugin_perms`) VALUES ('Member','{"UploadFiles":true,"UploadAvatars":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"CreateReply":true}','{}');
INSERT INTO `users_groups`(`name`,`permissions`,`plugin_perms`,`is_banned`) VALUES ('Banned','{"ViewTopic":true}','{}',1); INSERT INTO `users_groups`(`name`,`permissions`,`plugin_perms`,`is_banned`) VALUES ('Banned','{"ViewTopic":true}','{}',1);
INSERT INTO `users_groups`(`name`,`permissions`,`plugin_perms`) VALUES ('Awaiting Activation','{"ViewTopic":true}','{}'); INSERT INTO `users_groups`(`name`,`permissions`,`plugin_perms`) VALUES ('Awaiting Activation','{"ViewTopic":true}','{}');
INSERT INTO `users_groups`(`name`,`permissions`,`plugin_perms`,`tag`) VALUES ('Not Loggedin','{"ViewTopic":true}','{}','Guest'); INSERT INTO `users_groups`(`name`,`permissions`,`plugin_perms`,`tag`) VALUES ('Not Loggedin','{"ViewTopic":true}','{}','Guest');

View File

@ -7,9 +7,9 @@ INSERT INTO "settings"("name","content","type") VALUES ('rapid_loading','1','boo
INSERT INTO "settings"("name","content","type") VALUES ('google_site_verify','','html-attribute'); INSERT INTO "settings"("name","content","type") VALUES ('google_site_verify','','html-attribute');
INSERT INTO "themes"("uname","default") VALUES ('cosora',1); INSERT INTO "themes"("uname","default") VALUES ('cosora',1);
INSERT INTO "emails"("email","uid","validated") VALUES ('admin@localhost',1,1); INSERT INTO "emails"("email","uid","validated") VALUES ('admin@localhost',1,1);
INSERT INTO "users_groups"("name","permissions","plugin_perms","is_mod","is_admin","tag") VALUES ('Administrator','{"BanUsers":true,"ActivateUsers":true,"EditUser":true,"EditUserEmail":true,"EditUserPassword":true,"EditUserGroup":true,"EditUserGroupSuperMod":true,"EditUserGroupAdmin":false,"EditGroup":true,"EditGroupLocalPerms":true,"EditGroupGlobalPerms":true,"EditGroupSuperMod":true,"EditGroupAdmin":false,"ManageForums":true,"EditSettings":true,"ManageThemes":true,"ManagePlugins":true,"ViewAdminLogs":true,"ViewIPs":true,"UploadFiles":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"EditTopic":true,"DeleteTopic":true,"CreateReply":true,"EditReply":true,"DeleteReply":true,"PinTopic":true,"CloseTopic":true,"MoveTopic":true}','{}',1,1,'Admin'); INSERT INTO "users_groups"("name","permissions","plugin_perms","is_mod","is_admin","tag") VALUES ('Administrator','{"BanUsers":true,"ActivateUsers":true,"EditUser":true,"EditUserEmail":true,"EditUserPassword":true,"EditUserGroup":true,"EditUserGroupSuperMod":true,"EditUserGroupAdmin":false,"EditGroup":true,"EditGroupLocalPerms":true,"EditGroupGlobalPerms":true,"EditGroupSuperMod":true,"EditGroupAdmin":false,"ManageForums":true,"EditSettings":true,"ManageThemes":true,"ManagePlugins":true,"ViewAdminLogs":true,"ViewIPs":true,"UploadFiles":true,"UploadAvatars":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"EditTopic":true,"DeleteTopic":true,"CreateReply":true,"EditReply":true,"DeleteReply":true,"PinTopic":true,"CloseTopic":true,"MoveTopic":true}','{}',1,1,'Admin');
INSERT INTO "users_groups"("name","permissions","plugin_perms","is_mod","tag") VALUES ('Moderator','{"BanUsers":true,"ActivateUsers":false,"EditUser":true,"EditUserEmail":false,"EditUserGroup":true,"ViewIPs":true,"UploadFiles":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"EditTopic":true,"DeleteTopic":true,"CreateReply":true,"EditReply":true,"DeleteReply":true,"PinTopic":true,"CloseTopic":true,"MoveTopic":true}','{}',1,'Mod'); INSERT INTO "users_groups"("name","permissions","plugin_perms","is_mod","tag") VALUES ('Moderator','{"BanUsers":true,"ActivateUsers":false,"EditUser":true,"EditUserEmail":false,"EditUserGroup":true,"ViewIPs":true,"UploadFiles":true,"UploadAvatars":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"EditTopic":true,"DeleteTopic":true,"CreateReply":true,"EditReply":true,"DeleteReply":true,"PinTopic":true,"CloseTopic":true,"MoveTopic":true}','{}',1,'Mod');
INSERT INTO "users_groups"("name","permissions","plugin_perms") VALUES ('Member','{"UploadFiles":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"CreateReply":true}','{}'); INSERT INTO "users_groups"("name","permissions","plugin_perms") VALUES ('Member','{"UploadFiles":true,"UploadAvatars":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"CreateReply":true}','{}');
INSERT INTO "users_groups"("name","permissions","plugin_perms","is_banned") VALUES ('Banned','{"ViewTopic":true}','{}',1); INSERT INTO "users_groups"("name","permissions","plugin_perms","is_banned") VALUES ('Banned','{"ViewTopic":true}','{}',1);
INSERT INTO "users_groups"("name","permissions","plugin_perms") VALUES ('Awaiting Activation','{"ViewTopic":true}','{}'); INSERT INTO "users_groups"("name","permissions","plugin_perms") VALUES ('Awaiting Activation','{"ViewTopic":true}','{}');
INSERT INTO "users_groups"("name","permissions","plugin_perms","tag") VALUES ('Not Loggedin','{"ViewTopic":true}','{}','Guest'); INSERT INTO "users_groups"("name","permissions","plugin_perms","tag") VALUES ('Not Loggedin','{"ViewTopic":true}','{}','Guest');

View File

@ -4,14 +4,17 @@
<div class="rowitem"> <div class="rowitem">
<span id="dash_username"> <span id="dash_username">
<form id="dash_username_form" action="/user/edit/username/submit/?session={{.CurrentUser.Session}}" method="post"></form> <form id="dash_username_form" action="/user/edit/username/submit/?session={{.CurrentUser.Session}}" method="post"></form>
<form id="revoke_avatar_form" action="/user/edit/avatar/revoke/submit/?session={{.CurrentUser.Session}}" method="post"></form>
<input form="dash_username_form" name="account-new-username" value="{{.CurrentUser.Name}}" /> <input form="dash_username_form" name="account-new-username" value="{{.CurrentUser.Name}}" />
<button form="dash_username_form" class="formbutton">{{lang "account_username_save"}}</button> <button form="dash_username_form" class="formbutton">{{lang "account_username_save"}}</button>
</span> </span>
<img src="{{.CurrentUser.Avatar}}" height="128px" /> <img src="{{.CurrentUser.Avatar}}" height="128px" />
<span id="dash_avatar_buttons"> <span id="dash_avatar_buttons">
<input form="avatar_form" id="select_avatar" name="account-avatar" type="file" required style="display: none;" /> {{if .CurrentUser.Perms.UploadAvatars}}
<input form="avatar_form" id="select_avatar" name="account-avatar" type="file" required class="auto_hide" />
<label for="select_avatar" class="formbutton">{{lang "account_avatar_select"}}</label> <label for="select_avatar" class="formbutton">{{lang "account_avatar_select"}}</label>
<button form="avatar_form" name="account-button" class="formbutton">{{lang "account_avatar_update_button"}}</button> <button form="avatar_form" name="account-button" class="formbutton">{{lang "account_avatar_update_button"}}</button>
{{else if .CurrentUser.RawAvatar}}<button form="revoke_avatar_form" id="revoke_avatars" name="revoke-button" class="formbutton">{{lang "account_avatar_revoke_button"}}</button>{{end}}
</span> </span>
</div> </div>
</div> </div>

View File

@ -86,6 +86,9 @@
#dash_avatar_buttons button { #dash_avatar_buttons button {
margin-right: auto; margin-right: auto;
} }
#revoke_avatars {
margin-left: auto;
}
#dash_right { #dash_right {
width: 100%; width: 100%;
margin-left: 12px; margin-left: 12px;

View File

@ -114,7 +114,7 @@
padding: 12px; padding: 12px;
} }
.grid_item a { .grid_item a {
color: rgb(200,200,200); color: rgb(195,195,195);
} }
.stat_green { .stat_green {
background-color: rgb(68,88,68); background-color: rgb(68,88,68);
@ -125,6 +125,25 @@
.grid2 { .grid2 {
margin-top: 12px; margin-top: 12px;
} }
/*.panel_dashboard .grid_item {
text-align: center;
}
#dash-cpu, #dash-disk, #dash-ram, #dash-memused {
background-repeat: no-repeat;
padding-left: 61px;
background-position: left 12px top 50%;
background-size: 40px;
}
#dash-cpu {
background-image: url(./fa-svg/server-bg.svg);
background-size: 30px;
}
#dash-disk {
background-image: url(./fa-svg/hdd-bg.svg);
}
#dash-ram, #dash-memused {
background-image: url(./fa-svg/memory.svg);
}*/
.panel_buttons, .panel_floater { .panel_buttons, .panel_floater {
margin-left: auto; margin-left: auto;