save bytes

This commit is contained in:
Azareal 2020-04-05 13:18:36 +10:00
parent 22af6f19cd
commit 709b0d5541
13 changed files with 91 additions and 91 deletions

View File

@ -17,7 +17,7 @@ import (
"strings"
"github.com/Azareal/Gosora/common/gauth"
"github.com/Azareal/Gosora/query_gen"
qgen "github.com/Azareal/Gosora/query_gen"
//"golang.org/x/crypto/argon2"
"golang.org/x/crypto/bcrypt"
@ -66,16 +66,16 @@ var HashPrefixes = map[string]string{
// AuthInt is the main authentication interface.
type AuthInt interface {
Authenticate(username string, password string) (uid int, err error, requiresExtraAuth bool)
Authenticate(name, password string) (uid int, err error, requiresExtraAuth bool)
ValidateMFAToken(mfaToken string, uid int) error
Logout(w http.ResponseWriter, uid int)
ForceLogout(uid int) error
SetCookies(w http.ResponseWriter, uid int, session string)
SetProvisionalCookies(w http.ResponseWriter, uid int, session string, signedSession string) // To avoid logging someone in until they've passed the MFA check
SetProvisionalCookies(w http.ResponseWriter, uid int, session, signedSession string) // To avoid logging someone in until they've passed the MFA check
GetCookies(r *http.Request) (uid int, session string, err error)
SessionCheck(w http.ResponseWriter, r *http.Request) (user *User, halt bool)
SessionCheck(w http.ResponseWriter, r *http.Request) (u *User, halt bool)
CreateSession(uid int) (session string, err error)
CreateProvisionalSession(uid int) (provSession string, signedSession string, err error) // To avoid logging someone in until they've passed the MFA check
CreateProvisionalSession(uid int) (provSession, signedSession string, err error) // To avoid logging someone in until they've passed the MFA check
}
// DefaultAuth is the default authenticator used by Gosora, may be swapped with an alternate authenticator in some situations. E.g. To support LDAP.
@ -98,9 +98,9 @@ func NewDefaultAuth() (*DefaultAuth, error) {
// Authenticate checks if a specific username and password is valid and returns the UID for the corresponding user, if so. Otherwise, a user safe error.
// IF MFA is enabled, then pass it back a flag telling the caller that authentication isn't complete yet
// TODO: Find a better way of handling errors we don't want to reach the user
func (auth *DefaultAuth) Authenticate(username string, password string) (uid int, err error, requiresExtraAuth bool) {
func (auth *DefaultAuth) Authenticate(name string, password string) (uid int, err error, requiresExtraAuth bool) {
var realPassword, salt string
err = auth.login.QueryRow(username).Scan(&uid, &realPassword, &salt)
err = auth.login.QueryRow(name).Scan(&uid, &realPassword, &salt)
if err == ErrNoRows {
return 0, ErrNoUserByName, false
} else if err != nil {
@ -145,7 +145,7 @@ func (auth *DefaultAuth) ValidateMFAToken(mfaToken string, uid int) error {
if ok {
return nil
}
for i, scratch := range mfaItem.Scratch {
if subtle.ConstantTimeCompare([]byte(scratch), []byte(mfaToken)) == 1 {
err = mfaItem.BurnScratch(i)
@ -295,7 +295,7 @@ func (auth *DefaultAuth) CreateProvisionalSession(uid int) (provSession string,
return provSession, hex.EncodeToString(h.Sum(nil)), nil
}
func CheckPassword(realPassword string, password string, salt string) (err error) {
func CheckPassword(realPassword, password, salt string) (err error) {
blasted := strings.Split(realPassword, "$")
prefix := blasted[0]
if len(blasted) > 1 {
@ -309,7 +309,7 @@ func CheckPassword(realPassword string, password string, salt string) (err error
return checker(realPassword, password, salt)
}
func GeneratePassword(password string) (hash string, salt string, err error) {
func GeneratePassword(password string) (hash, salt string, err error) {
gen, ok := GeneratePasswordFuncs[DefaultHashAlgo]
if !ok {
return "", "", ErrHashNotExist
@ -317,12 +317,12 @@ func GeneratePassword(password string) (hash string, salt string, err error) {
return gen(password)
}
func BcryptCheckPassword(realPassword string, password string, salt string) (err error) {
func BcryptCheckPassword(realPassword, password, salt string) (err error) {
return bcrypt.CompareHashAndPassword([]byte(realPassword), []byte(password+salt))
}
// Note: The salt is in the hash, therefore the salt parameter is blank
func BcryptGeneratePassword(password string) (hash string, salt string, err error) {
func BcryptGeneratePassword(password string) (hash, salt string, err error) {
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
if err != nil {
return "", "", err
@ -337,7 +337,7 @@ func BcryptGeneratePassword(password string) (hash string, salt string, err erro
argon2KeyLen uint32 = 32
)
func Argon2CheckPassword(realPassword string, password string, salt string) (err error) {
func Argon2CheckPassword(realPassword, password, salt string) (err error) {
split := strings.Split(realPassword, "$")
// TODO: Better validation
if len(split) < 5 {
@ -355,7 +355,7 @@ func Argon2CheckPassword(realPassword string, password string, salt string) (err
return nil
}
func Argon2GeneratePassword(password string) (hash string, salt string, err error) {
func Argon2GeneratePassword(password string) (hash, salt string, err error) {
sbytes := make([]byte, SaltLength)
_, err = rand.Read(sbytes)
if err != nil {
@ -380,7 +380,7 @@ func FriendlyGAuthSecret(secret string) (out string) {
func GenerateGAuthSecret() (string, error) {
return GenerateStd32SafeString(14)
}
func VerifyGAuthToken(secret string, token string) (bool, error) {
func VerifyGAuthToken(secret, token string) (bool, error) {
trueToken, err := gauth.GetTOTPToken(secret)
return subtle.ConstantTimeCompare([]byte(trueToken), []byte(token)) == 1, err
}

View File

@ -4,19 +4,19 @@
// TODO: Move this into a JS file to reduce the number of possible problems
var menuItems = {};
let items = document.getElementsByClassName("panel_menu_item");
for(let i = 0; item = items[i]; i++) menuItems[i] = item.getAttribute("data-miid");
for(let i=0; item=items[i]; i++) menuItems[i] = item.getAttribute("data-miid");
Sortable.create(document.getElementById("panel_menu_item_holder"), {
sort: true,
onEnd: (evt) => {
console.log("pre menuItems", menuItems)
console.log("evt", evt)
onEnd: evt => {
console.log("pre menuItems",menuItems)
console.log("evt",evt)
let oldMiid = menuItems[evt.newIndex];
menuItems[evt.oldIndex] = oldMiid;
let newMiid = evt.item.getAttribute("data-miid");
console.log("newMiid", newMiid);
console.log("newMiid",newMiid);
menuItems[evt.newIndex] = newMiid;
console.log("post menuItems", menuItems);
console.log("post menuItems",menuItems);
}
});
@ -32,22 +32,22 @@ document.getElementById("panel_menu_items_order_button").addEventListener("click
// TODO: Signal the error with a notice
if(req.status===200) {
let resp = JSON.parse(req.responseText);
console.log("resp", resp);
console.log("resp",resp);
// TODO: Should we move other notices into TmplPhrases like this one?
pushNotice(phraseBox["panel"]["panel.themes_menus_items_order_updated"]);
if(resp.success==1) return;
}
} catch(ex) {
console.error("ex", ex)
} catch(e) {
console.error("e",e)
}
console.trace();
}
// ? - Is encodeURIComponent the right function for this?
let spl = document.location.pathname.split("/");
req.open("POST","/panel/themes/menus/item/order/edit/submit/"+parseInt(spl[spl.length-1],10)+"?s=" + encodeURIComponent(me.User.S));
req.open("POST","/panel/themes/menus/item/order/edit/submit/"+parseInt(spl[spl.length-1],10)+"?s="+encodeURIComponent(me.User.S));
req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
let items = "";
for(let i = 0; item = menuItems[i];i++) items += item+",";
for(let i=0; item=menuItems[i];i++) items += item+",";
if(items.length > 0) items = items.slice(0,-1);
req.send("js=1&amp;items={"+items+"}");
});

View File

@ -2,11 +2,11 @@
<div class="formitem formlabel"><a>{{lang "panel_themes_widgets_type"}}</a></div>
<div class="formitem">
<select class="wtype_sel" name="wtype">
<option value="about"{{if eq .Type "about"}} selected{{end}}>{{lang "panel_themes_widgets_type_about"}}</option>
<option value="simple"{{if eq .Type "simple"}} selected{{end}}>{{lang "panel_themes_widgets_type_simple"}}</option>
<option value="wol"{{if eq .Type "wol"}} selected{{end}}>{{lang "panel_themes_widgets_type_wol"}}</option>
<option value="wol_context"{{if eq .Type "wol_context"}} selected{{end}}>{{lang "panel_themes_widgets_type_wol_context"}}</option>
<option value="search_and_filter"{{if eq .Type "search_and_filter"}} selected{{end}}>{{lang "panel_themes_widgets_type_search_and_filter"}}</option>
<option value="about"{{if eq .Type "about"}}selected{{end}}>{{lang "panel_themes_widgets_type_about"}}</option>
<option value="simple"{{if eq .Type "simple"}}selected{{end}}>{{lang "panel_themes_widgets_type_simple"}}</option>
<option value="wol"{{if eq .Type "wol"}}selected{{end}}>{{lang "panel_themes_widgets_type_wol"}}</option>
<option value="wol_context"{{if eq .Type "wol_context"}}selected{{end}}>{{lang "panel_themes_widgets_type_wol_context"}}</option>
<option value="search_and_filter"{{if eq .Type "search_and_filter"}}selected{{end}}>{{lang "panel_themes_widgets_type_search_and_filter"}}</option>
</select>
</div>
</div>
@ -47,9 +47,9 @@
</div>
<div class="formrow form_button_row">
<div class="formitem">
<button name="panel-button" class="formbutton widget_save">{{lang "panel_themes_widgets_save"}}</button>
<button name="panel-button"class="formbutton widget_save">{{lang "panel_themes_widgets_save"}}</button>
<a href="/panel/themes/widgets/delete/submit/{{.ID}}">
<button name="panel-button" class="formbutton widget_delete">{{lang "panel_themes_widgets_delete"}}</button>
<button name="panel-button"class="formbutton widget_delete">{{lang "panel_themes_widgets_delete"}}</button>
</a>
</div>
</div>

View File

@ -1,14 +1,14 @@
{{template "header.html" . }}
<div id="profile_container" class="colstack">
<div id="profile_container"class="colstack">
<div id="profile_left_lane" class="colstack_left">
<div id="profile_left_pane" class="rowmenu">
<div id="profile_left_lane"class="colstack_left">
<div id="profile_left_pane"class="rowmenu">
<div class="topBlock">
<div class="rowitem avatarRow">
<a href="{{.ProfileOwner.Avatar}}"><img src="{{.ProfileOwner.Avatar}}"class="avatar"alt="Avatar"title="{{.ProfileOwner.Name}}'s Avatar"aria-hidden="true"></a>
</div>
<div class="rowitem nameRow">
<span class="profileName" title="{{.ProfileOwner.Name}}">{{.ProfileOwner.Name}}</span>{{if .ProfileOwner.Tag}}<span class="username" title="{{.ProfileOwner.Tag}}">{{.ProfileOwner.Tag}}</span>{{end}}
<span class="profileName"title="{{.ProfileOwner.Name}}">{{.ProfileOwner.Name}}</span>{{if .ProfileOwner.Tag}}<span class="username"title="{{.ProfileOwner.Tag}}">{{.ProfileOwner.Tag}}</span>{{end}}
</div>
</div>
<div class="levelBlock">
@ -17,7 +17,7 @@
<div class="levelBit">
<a>{{level .ProfileOwner.Level}}</a>
</div>
<div class="progressWrap"{{if ne .CurrentScore 0}} style="width:40%"{{end}}>
<div class="progressWrap"{{if ne .CurrentScore 0}}style="width:40%"{{end}}>
<div>{{.CurrentScore}} / {{.NextScore}}</div>
</div>
</div>
@ -36,25 +36,25 @@
{{if (.CurrentUser.IsSuperMod) and not (.ProfileOwner.IsSuperMod)}}<div class="rowitem passive">
{{if .ProfileOwner.IsBanned}}<a href="/users/unban/{{.ProfileOwner.ID}}?s={{.CurrentUser.Session}}" class="profile_menu_item">{{lang "profile.unban"}}</a>
{{else}}<a href="#ban_user" class="profile_menu_item">{{lang "profile.ban"}}</a>{{end}}
{{else}}<a href="#ban_user"class="profile_menu_item">{{lang "profile.ban"}}</a>{{end}}
</div>
<div class="rowitem passive">
<a href="#delete_posts" class="profile_menu_item">{{lang "profile.delete_posts"}}</a>
<a href="#delete_posts"class="profile_menu_item">{{lang "profile.delete_posts"}}</a>
</div>
{{end}}
<div class="rowitem passive">
{{if .Blocked}}<a href="/user/block/remove/{{.ProfileOwner.ID}}" class="profile_menu_item">{{lang "profile.unblock"}}</a>{{else}}<a href="/user/block/create/{{.ProfileOwner.ID}}" class="profile_menu_item">{{lang "profile.block"}}</a>{{end}}
{{if .Blocked}}<a href="/user/block/remove/{{.ProfileOwner.ID}}"class="profile_menu_item">{{lang "profile.unblock"}}</a>{{else}}<a href="/user/block/create/{{.ProfileOwner.ID}}"class="profile_menu_item">{{lang "profile.block"}}</a>{{end}}
</div>
<div class="rowitem passive">
<a href="/report/submit/{{.ProfileOwner.ID}}?s={{.CurrentUser.Session}}&type=user" class="profile_menu_item report_item" aria-label="{{lang "profile.report_user_aria"}}" title="{{lang "profile.report_user_tooltip"}}"></a>
<a href="/report/submit/{{.ProfileOwner.ID}}?s={{.CurrentUser.Session}}&type=user"class="profile_menu_item report_item"aria-label="{{lang "profile.report_user_aria"}}"title="{{lang "profile.report_user_tooltip"}}"></a>
</div>
{{end}}
</div>
</div>
</div>
<div id="profile_right_lane" class="colstack_right">
<div id="profile_right_lane"class="colstack_right">
{{if .CurrentUser.Loggedin}}
{{if .CurrentUser.Perms.BanUsers}}
<!-- TODO: Inline the display:none; CSS -->
@ -69,19 +69,19 @@
<div class="formrow real_first_child">
<div class="formitem formlabel"><a>{{lang "profile.ban_user_days"}}</a></div>
<div class="formitem">
<input name="dur-days" type="number" value=0 min=0>
<input name="dur-days"type="number"value=0 min=0>
</div>
</div>
<div class="formrow">
<div class="formitem formlabel"><a>{{lang "profile.ban_user_weeks"}}</a></div>
<div class="formitem">
<input name="dur-weeks" type="number" value=0 min=0>
<input name="dur-weeks"type="number"value=0 min=0>
</div>
</div>
<div class="formrow">
<div class="formitem formlabel"><a>{{lang "profile.ban_user_months"}}</a></div>
<div class="formitem">
<input name="dur-months" type="number" value=0 min=0>
<input name="dur-months"type="number"value=0 min=0>
</div>
</div>
<div class="formrow">
@ -93,16 +93,16 @@
</div>
{{/**<!--<div class="formrow">
<div class="formitem formlabel"><a>{{lang "profile.ban_user_reason"}}</a></div>
<div class="formitem"><textarea name="ban-reason" placeholder="A really horrible person" required></textarea></div>
<div class="formitem"><textarea name="ban-reason" placeholder="A really horrible person"required></textarea></div>
</div>-->**/}}
<div class="formrow">
<div class="formitem"><button name="ban-button" class="formbutton form_middle_button">{{lang "profile.ban_user_button"}}</button></div>
<div class="formitem"><button name="ban-button"class="formbutton form_middle_button">{{lang "profile.ban_user_button"}}</button></div>
</div>
</div>
</div>
</form>
<div id="delete_posts_head" class="colstack_item colstack_head hash_hide delete_posts_hash" style="display:none;">
<div id="delete_posts_head"class="colstack_item colstack_head hash_hide delete_posts_hash"style="display:none;">
<div class="rowitem"><h1><a>{{lang "profile.delete_posts_head"}}</a></h1></div>
</div>
<form id="delete_posts_form" class="hash_hide delete_posts_hash" action="/users/delete-posts/submit/{{.ProfileOwner.ID}}?s={{.CurrentUser.Session}}" method="post" style="display:none;">
@ -110,7 +110,7 @@
<div class="colline">{{langf "profile.delete_posts_notice" .ProfileOwner.Posts}}</div>
<div class="colstack_item">
<div class="formrow real_first_child">
<div class="formitem"><button name="delete-posts-button" class="formbutton form_middle_button">{{lang "profile.delete_posts_button"}}</button></div>
<div class="formitem"><button name="delete-posts-button"class="formbutton form_middle_button">{{lang "profile.delete_posts_button"}}</button></div>
</div>
</div>
</div>
@ -118,27 +118,27 @@
{{end}}
{{end}}
<div id="profile_comments_head" class="colstack_item colstack_head hash_hide">
<div id="profile_comments_head"class="colstack_item colstack_head hash_hide">
<div class="rowitem"><h1><a>{{lang "profile.comments_head"}}</a></h1></div>
</div>
<div id="profile_comments" class="colstack_item hash_hide">{{template "profile_comments_row.html" . }}</div>
<div id="profile_comments"class="colstack_item hash_hide">{{template "profile_comments_row.html" . }}</div>
{{if .CurrentUser.Loggedin}}
{{if .CanComment}}
<form id="profile_comments_form" class="hash_hide" action="/profile/reply/create/?s={{.CurrentUser.Session}}" method="post">
<form id="profile_comments_form"class="hash_hide"action="/profile/reply/create/?s={{.CurrentUser.Session}}"method="post">
<input name="uid"value='{{.ProfileOwner.ID}}'type="hidden">
<div class="colstack_item topic_reply_form" style="border-top:none;">
<div class="colstack_item topic_reply_form"style="border-top:none;">
<div class="formrow">
<div class="formitem"><textarea class="input_content" name="content" placeholder="{{lang "profile.comments_form_content"}}"></textarea></div>
<div class="formitem"><textarea class="input_content"name="content"placeholder="{{lang "profile.comments_form_content"}}"></textarea></div>
</div>
<div class="formrow quick_button_row">
<div class="formitem"><button name="reply-button" class="formbutton">{{lang "profile.comments_form_button"}}</button></div>
<div class="formitem"><button name="reply-button"class="formbutton">{{lang "profile.comments_form_button"}}</button></div>
</div>
</div>
</form>
{{end}}
{{else}}
<div class="colstack_item" style="border-top:none;">
<div class="colstack_item"style="border-top:none;">
<div class="rowitem passive">{{lang "profile.comments_form_guest"}}</div>
</div>
{{end}}

View File

@ -6,11 +6,11 @@
<span class="controls">
<a href="{{.UserLink}}"class="real_username username">{{.CreatedByName}}</a>&nbsp;&nbsp;
{{if $.CurrentUser.IsMod}}<a href="/profile/reply/edit/submit/{{.ID}}?s={{$.CurrentUser.Session}}"class="mod_button"title="{{lang "profile.comments_edit_tooltip"}}" aria-label="{{lang "profile.comments_edit_aria"}}"><button class="username edit_item edit_label"></button></a>
{{if $.CurrentUser.IsMod}}<a href="/profile/reply/edit/submit/{{.ID}}?s={{$.CurrentUser.Session}}"class="mod_button"title="{{lang "profile.comments_edit_tooltip"}}"aria-label="{{lang "profile.comments_edit_aria"}}"><button class="username edit_item edit_label"></button></a>
<a href="/profile/reply/delete/submit/{{.ID}}?s={{$.CurrentUser.Session}}"class="mod_button"title="{{lang "profile.comments_delete_tooltip"}}" aria-label="{{lang "profile.comments_delete_aria"}}"><button class="username delete_item delete_label"></button></a>{{end}}
<a href="/profile/reply/delete/submit/{{.ID}}?s={{$.CurrentUser.Session}}"class="mod_button"title="{{lang "profile.comments_delete_tooltip"}}"aria-label="{{lang "profile.comments_delete_aria"}}"><button class="username delete_item delete_label"></button></a>{{end}}
<a class="mod_button"href="/report/submit/{{.ID}}?s={{$.CurrentUser.Session}}&type=user-reply"><button class="username report_item flag_label"title="{{lang "profile.comments_report_tooltip"}}" aria-label="{{lang "profile.comments_report_aria"}}"></button></a>
<a class="mod_button"href="/report/submit/{{.ID}}?s={{$.CurrentUser.Session}}&type=user-reply"><button class="username report_item flag_label"title="{{lang "profile.comments_report_tooltip"}}"aria-label="{{lang "profile.comments_report_aria"}}"></button></a>
{{if .Tag}}<a class="username hide_on_mobile user_tag"style="float:right;">{{.Tag}}</a>{{end}}
</span>

View File

@ -7,31 +7,31 @@
<form action="/accounts/create/submit/" method="post">
<div class="formrow">
<div class="formitem formlabel"><a id="name_label">{{lang "register_account_name"}}</a></div>
<div class="formitem"><input name="name" type="text" placeholder="{{lang "register_account_name"}}" aria-labelledby="name_label" required></div>
<div class="formitem"><input name="name"type="text"placeholder="{{lang "register_account_name"}}" aria-labelledby="name_label"required></div>
</div>
<div class="formrow">
<div class="formitem formlabel"><a id="email_label">{{if not .Something}}{{lang "register_account_email"}}{{else}}{{lang "register_account_email_optional"}}{{end}}</a></div>
<div class="formitem"><input name="email" type="email" placeholder="joe.doe@example.com" aria-labelledby="email_label"{{if not .Something}} required{{end}}></div>
<div class="formitem"><input name="email"type="email"placeholder="joe.doe@example.com"aria-labelledby="email_label"{{if not .Something}}required{{end}}></div>
</div>
<div class="formrow">
<div class="formitem formlabel"><a id="password_label">{{lang "register_account_password"}}</a></div>
<div class="formitem"><input name="password" type="password" autocomplete="new-password" placeholder="*****" aria-labelledby="password_label" required></div>
<div class="formitem"><input name="password"type="password"autocomplete="new-password"placeholder="*****"aria-labelledby="password_label"required></div>
</div>
<div class="formrow">
<div class="formitem formlabel"><a id="confirm_password_label">{{lang "register_account_confirm_password"}}</a></div>
<div class="formitem"><input name="confirm_password" type="password" placeholder="*****" autocomplete="new-password" aria-labelledby="confirm_password_label" required></div>
<div class="formitem"><input name="confirm_password"type="password"placeholder="*****"autocomplete="new-password"aria-labelledby="confirm_password_label"required></div>
</div>
<div class="formrow">{{/** This is not a TOS, that text is there to fool the spambots **/}}
<div class="formitem formlabel"><a id="accept_tos_label">{{lang "register_account_anti_spam"}}</a></div>
<div class="formitem"><select name="tos" aria-labelledby="accept_tos_label" required>
<option value="1" selected>{{lang "option_yes"}}</option>
<div class="formitem"><select name="tos"aria-labelledby="accept_tos_label"required>
<option value="1"selected>{{lang "option_yes"}}</option>
<option value="0">{{lang "option_no"}}</option>
</select></div>
</div>
<div class="formrow register_button_row form_button_row">
<div class="formitem"><button name="register-button" class="formbutton">{{lang "register_submit_button"}}</button></div>
<div class="formitem"><button name="register-button"class="formbutton">{{lang "register_submit_button"}}</button></div>
</div>
<input id="golden-watch" name="golden-watch" value="$500" type="hidden">
<input id="golden-watch"name="golden-watch"value="$500"type="hidden">
</form>
</div>
</main>

View File

@ -1,4 +1,4 @@
<div id="back" class="zone_{{.Header.Zone}}{{if hasWidgets "rightSidebar" .Header }} shrink_main{{end}}">
<div id="back"class="zone_{{.Header.Zone}}{{if hasWidgets "rightSidebar" .Header }} shrink_main{{end}}">
<div id="main">
<div class="alertbox initial_alertbox">{{range .Header.NoticeList}}{{template "notice.html" . }}{{end}}</div>
{{template "topic_alt_inner.html" . }}

View File

@ -1,8 +1,8 @@
<div class="rowblock topic_reply_container">
<div class="userinfo" aria-label="{{lang "topic.your_information"}}">
<div class="userinfo"aria-label="{{lang "topic.your_information"}}">
<img class="aitem"src="{{.CurrentUser.Avatar}}"alt="Avatar">
<div class="user_meta">
<a href="{{.CurrentUser.Link}}" class="the_name" rel="author">{{.CurrentUser.Name}}</a>
<a href="{{.CurrentUser.Link}}"class="the_name"rel="author">{{.CurrentUser.Name}}</a>
<div class="tag_block">
<div class="tag_pre"></div>
{{if .CurrentUser.Tag}}<div class="post_tag">{{.CurrentUser.Tag}}</div>{{else}}<div class="post_tag post_level">{{level .CurrentUser.Level}}</div>{{end}}
@ -10,31 +10,31 @@
</div>
</div>
</div>
<div class="rowblock topic_reply_form quick_create_form" aria-label="{{lang "topic.reply_aria"}}">
<form id="quick_post_form" enctype="multipart/form-data" action="/reply/create/?s={{.CurrentUser.Session}}" method="post"></form>
<input form="quick_post_form" name="tid" value='{{.Topic.ID}}' type="hidden">
<input form="quick_post_form" id="has_poll_input" name="has_poll" value=0 type="hidden">
<div class="rowblock topic_reply_form quick_create_form"aria-label="{{lang "topic.reply_aria"}}">
<form id="quick_post_form"enctype="multipart/form-data"action="/reply/create/?s={{.CurrentUser.Session}}"method="post"></form>
<input form="quick_post_form"name="tid"value='{{.Topic.ID}}'type="hidden">
<input form="quick_post_form"id="has_poll_input"name="has_poll"type="hidden"value=0>
<div class="formrow real_first_child">
<div class="formitem">
<textarea id="input_content" form="quick_post_form" name="content" placeholder="{{lang "topic.reply_content_alt"}}" required></textarea>
<textarea id="input_content"form="quick_post_form"name="content"placeholder="{{lang "topic.reply_content_alt"}}" required></textarea>
</div>
</div>
<div class="formrow poll_content_row auto_hide">
<div class="formitem">
<div class="pollinput" data-pollinput=0>
<input type="checkbox" disabled>
<div class="pollinput"data-pollinput=0>
<input type="checkbox"disabled>
<label class="pollinputlabel"></label>
<input form="quick_post_form" name="pollinputitem[0]" class="pollinputinput" type="text" placeholder="{{lang "topic.reply_add_poll_option_first"}}">
<input form="quick_post_form"name="pollinputitem[0]"class="pollinputinput"type="text"placeholder="{{lang "topic.reply_add_poll_option_first"}}">
</div>
</div>
</div>
<div class="formrow quick_button_row">
<div class="formitem">
<button form="quick_post_form" name="reply-button" class="formbutton">{{lang "topic.reply_button"}}</button>
<button form="quick_post_form" class="formbutton" id="add_poll_button">{{lang "topic.reply_add_poll_button"}}</button>
<button form="quick_post_form"name="reply-button"class="formbutton">{{lang "topic.reply_button"}}</button>
<button form="quick_post_form"class="formbutton"id="add_poll_button">{{lang "topic.reply_add_poll_button"}}</button>
{{if .CurrentUser.Perms.UploadFiles}}
<input name="upload_files" form="quick_post_form" id="upload_files" multiple type="file" class="auto_hide">
<label for="upload_files" class="formbutton add_file_button">{{lang "topic.reply_add_file_button"}}</label>
<input name="upload_files"form="quick_post_form"id="upload_files"multiple type="file" class="auto_hide">
<label for="upload_files"class="formbutton add_file_button">{{lang "topic.reply_add_file_button"}}</label>
<div id="upload_file_dock"></div>{{end}}
</div>
</div>

View File

@ -1,5 +1,5 @@
<div class='pollinput'data-pollinput={{.Index}}>
<input type='checkbox' disabled>
<input type='checkbox'disabled>
<label class='pollinputlabel'></label>
<input form='quick_post_form'name='pollinputitem[{{.Index}}]'class='pollinputinput'type='text'placeholder='{{.Place}}'>
</div>

View File

@ -1,4 +1,4 @@
<div id="back" class="zone_{{.Header.Zone}}{{if hasWidgets "rightSidebar" .Header }} shrink_main{{end}}">
<div id="back"class="zone_{{.Header.Zone}}{{if hasWidgets "rightSidebar" .Header }} shrink_main{{end}}">
<div id="main">
<div class="alertbox initial_alertbox">{{range .Header.NoticeList}}{{template "notice.html" . }}{{end}}</div>
{{template "topic_inner.html" . }}

View File

@ -1,6 +1,6 @@
{{template "header.html" . }}
<main id="topicsItemList" itemscope itemtype="http://schema.org/ItemList">
{{if not .CurrentUser.Loggedin}}<link rel="canonical"href="//{{.Site.URL}}/topics/{{if eq .Sort.SortBy "mostviewed"}}most-viewed/{{end}}{{if gt .Page 1}}?page={{.Page}}{{end}}"/>{{end}}
{{if not .CurrentUser.Loggedin}}<link rel="canonical"href="//{{.Site.URL}}/topics/{{if eq .Sort.SortBy "mostviewed"}}most-viewed/{{end}}{{if gt .Page 1}}?page={{.Page}}{{end}}">{{end}}
<div class="rowblock rowhead topic_list_title_block{{if .CurrentUser.Loggedin}} has_opt{{end}}">
<div class="rowitem topic_list_title"><h1 itemprop="name">{{.Title}}</h1></div>
@ -59,7 +59,7 @@
<div class="topic_meta">
<div class="formrow topic_board_row real_first_child">
<div class="formitem"><select form="quick_post_form" id="topic_board_input" name="board">
{{range .ForumList}}<option{{if eq .ID $.DefaultForum}} selected{{end}} value="{{.ID}}">{{.Name}}</option>{{end}}
{{range .ForumList}}<option value="{{.ID}}"{{if eq .ID $.DefaultForum}}selected{{end}}>{{.Name}}</option>{{end}}
</select></div>
</div>
<div class="formrow topic_name_row">
@ -76,7 +76,7 @@
<div class="rowblock more_topic_block more_topic_block_initial">
<div class="rowitem rowmsg"><a href=""class="more_topics"></a></div>
</div>
<div id="topic_list" class="rowblock topic_list topic_list_{{.Sort.SortBy}}" aria-label="{{lang "topics_list_aria"}}">
<div id="topic_list"class="rowblock topic_list topic_list_{{.Sort.SortBy}}"aria-label="{{lang "topics_list_aria"}}">
{{range .TopicList}}{{template "topics_topic.html" . }}{{else}}<div class="rowitem passive rowmsg">{{lang "topics_no_topics"}}{{if .CurrentUser.Loggedin}}{{if .CurrentUser.Perms.CreateTopic}}&nbsp;<a href="/topics/create/">{{lang "topics_start_one"}}</a>{{end}}{{end}}</div>{{end}}
</div>

View File

@ -7,11 +7,11 @@
<form action="/accounts/login/submit/" method="post">
<div class="formrow login_name_row">
<div class="formitem formlabel"><a id="login_name_label">{{lang "login_account_name"}}</a></div>
<div class="formitem"><input name="username"type="text"placeholder="{{lang "login_account_name"}}" aria-labelledby="login_name_label" required></div>
<div class="formitem"><input name="username"type="text"placeholder="{{lang "login_account_name"}}" aria-labelledby="login_name_label"required></div>
</div>
<div class="formrow login_password_row">
<div class="formitem formlabel"><a id="login_password_label">{{lang "login_account_password"}}</a></div>
<div class="formitem"><input name="password"type="password"autocomplete="current-password"placeholder="*****"aria-labelledby="login_password_label" required></div>
<div class="formitem"><input name="password"type="password"autocomplete="current-password"placeholder="*****"aria-labelledby="login_password_label"required></div>
</div>
<div class="formrow login_button_row form_button_row">
<div class="formitem"><button name="login-button" class="formbutton">{{lang "login_submit_button"}}</button></div>

View File

@ -1,6 +1,6 @@
<div class="above_right">
<div class="left_bit"><a href="/">{{lang "panel_back_to_site"}}</a></div>
<div class="right_bit">
<img src="{{.CurrentUser.MicroAvatar}}" height=32 width=32>
<img src="{{.CurrentUser.MicroAvatar}}"height=32 width=32>
<span>{{lang "panel_welcome"}}{{.CurrentUser.Name}}</span></div>
</div>