everywhere: improve anonymous comments logic

This commit is contained in:
Adhityaa Chandrasekar 2019-01-23 00:26:22 -05:00
parent 61bc73e705
commit 022fc06257
10 changed files with 52 additions and 35 deletions

View File

@ -78,12 +78,13 @@ func commentNewHandler(w http.ResponseWriter, r *http.Request) {
} }
// logic: (empty column indicates the value doesn't matter) // logic: (empty column indicates the value doesn't matter)
// | anonymous | moderator | requireIdentification | requireModeration | approved? | // | anonymous | moderator | requireIdentification | requireModeration | moderateAllAnonymous | approved? |
// |-----------+-----------+-----------------------+-------------------+-----------| // |-----------+-----------+-----------------------+-------------------+----------------------+-----------|
// | yes | | | | no | // | yes | | | | no | yes |
// | no | yes | | | yes | // | yes | | | | yes | no |
// | no | no | | yes | yes | // | no | yes | | | | yes |
// | no | no | | no | no | // | no | no | | yes | | yes |
// | no | no | | no | | no |
var commenterHex string var commenterHex string
var state string var state string
@ -93,7 +94,11 @@ func commentNewHandler(w http.ResponseWriter, r *http.Request) {
if isSpam(*x.Domain, getIp(r), getUserAgent(r), "Anonymous", "", "", *x.Markdown) { if isSpam(*x.Domain, getIp(r), getUserAgent(r), "Anonymous", "", "", *x.Markdown) {
state = "flagged" state = "flagged"
} else { } else {
if d.ModerateAllAnonymous {
state = "unapproved" state = "unapproved"
} else {
state = "approved"
}
} }
} else { } else {
c, err := commenterGetByCommenterToken(*x.CommenterToken) c, err := commenterGetByCommenterToken(*x.CommenterToken)

View File

@ -14,5 +14,6 @@ type domain struct {
AutoSpamFilter bool `json:"autoSpamFilter"` AutoSpamFilter bool `json:"autoSpamFilter"`
RequireModeration bool `json:"requireModeration"` RequireModeration bool `json:"requireModeration"`
RequireIdentification bool `json:"requireIdentification"` RequireIdentification bool `json:"requireIdentification"`
ModerateAllAnonymous bool `json:"moderateAllAnonymous"`
Moderators []moderator `json:"moderators"` Moderators []moderator `json:"moderators"`
} }

View File

@ -8,7 +8,7 @@ func domainGet(dmn string) (domain, error) {
} }
statement := ` statement := `
SELECT domain, ownerHex, name, creationDate, state, importedComments, autoSpamFilter, requireModeration, requireIdentification SELECT domain, ownerHex, name, creationDate, state, importedComments, autoSpamFilter, requireModeration, requireIdentification, moderateAllAnonymous
FROM domains FROM domains
WHERE domain = $1; WHERE domain = $1;
` `
@ -16,7 +16,7 @@ func domainGet(dmn string) (domain, error) {
var err error var err error
d := domain{} d := domain{}
if err = row.Scan(&d.Domain, &d.OwnerHex, &d.Name, &d.CreationDate, &d.State, &d.ImportedComments, &d.AutoSpamFilter, &d.RequireModeration, &d.RequireIdentification); err != nil { if err = row.Scan(&d.Domain, &d.OwnerHex, &d.Name, &d.CreationDate, &d.State, &d.ImportedComments, &d.AutoSpamFilter, &d.RequireModeration, &d.RequireIdentification, &d.ModerateAllAnonymous); err != nil {
return d, errorNoSuchDomain return d, errorNoSuchDomain
} }

View File

@ -10,7 +10,7 @@ func domainList(ownerHex string) ([]domain, error) {
} }
statement := ` statement := `
SELECT domain, ownerHex, name, creationDate, state, importedComments, autoSpamFilter, requireModeration, requireIdentification SELECT domain, ownerHex, name, creationDate, state, importedComments, autoSpamFilter, requireModeration, requireIdentification, moderateAllAnonymous
FROM domains FROM domains
WHERE ownerHex=$1; WHERE ownerHex=$1;
` `
@ -24,7 +24,7 @@ func domainList(ownerHex string) ([]domain, error) {
domains := []domain{} domains := []domain{}
for rows.Next() { for rows.Next() {
d := domain{} d := domain{}
if err = rows.Scan(&d.Domain, &d.OwnerHex, &d.Name, &d.CreationDate, &d.State, &d.ImportedComments, &d.AutoSpamFilter, &d.RequireModeration, &d.RequireIdentification); err != nil { if err = rows.Scan(&d.Domain, &d.OwnerHex, &d.Name, &d.CreationDate, &d.State, &d.ImportedComments, &d.AutoSpamFilter, &d.RequireModeration, &d.RequireIdentification, &d.ModerateAllAnonymous); err != nil {
logger.Errorf("cannot Scan domain: %v", err) logger.Errorf("cannot Scan domain: %v", err)
return nil, errorInternal return nil, errorInternal
} }

View File

@ -7,11 +7,11 @@ import (
func domainUpdate(d domain) error { func domainUpdate(d domain) error {
statement := ` statement := `
UPDATE domains UPDATE domains
SET name=$2, state=$3, autoSpamFilter=$4, requireModeration=$5, requireIdentification=$6 SET name=$2, state=$3, autoSpamFilter=$4, requireModeration=$5, requireIdentification=$6, moderateAllAnonymous=$7
WHERE domain=$1; WHERE domain=$1;
` `
_, err := db.Exec(statement, d.Domain, d.Name, d.State, d.AutoSpamFilter, d.RequireModeration, d.RequireIdentification) _, err := db.Exec(statement, d.Domain, d.Name, d.State, d.AutoSpamFilter, d.RequireModeration, d.RequireIdentification, d.ModerateAllAnonymous)
if err != nil { if err != nil {
logger.Errorf("cannot update non-moderators: %v", err) logger.Errorf("cannot update non-moderators: %v", err)
return errorInternal return errorInternal

View File

@ -0,0 +1,4 @@
-- Allow the owner to change whether anonymous comments are put into moderation by default.
ALTER TABLE domains
ADD COLUMN moderateAllAnonymous BOOLEAN DEFAULT true;

View File

@ -205,13 +205,21 @@
</div> </div>
<div class="row no-border round-check"> <div class="row no-border round-check">
<input type="checkbox" class="switch" v-model="domains[cd].requireIdentification" id="require-identification"> <input type="checkbox" class="switch" v-model="domains[cd].allowAnonymous" id="allow-anonymous">
<label for="require-identification">Allow anonymous comments</label> <label for="allow-anonymous">Allow anonymous comments</label>
<div class="pitch"> <div class="pitch">
Enabling this would require all commenters to authenticate themselves (using their Google account, for example). Disabling would allow anonymous comments. Enabling this would require all commenters to authenticate themselves (using their Google account, for example). Disabling would allow anonymous comments.
</div> </div>
</div> </div>
<div class="row no-border round-check indent" v-if="domains[cd].allowAnonymous">
<input type="checkbox" class="switch" v-model="domains[cd].moderateAllAnonymous" id="moderate-all-anonymous">
<label for="moderate-all-anonymous">Require anonymous comments to be approved manually</label>
<div class="pitch">
Enabling this would require a moderator to approve anonymous comments. This is recommended as a lot of spam is often from anonymous comments.
</div>
</div>
<div id="new-domain-error" class="modal-error-box"></div> <div id="new-domain-error" class="modal-error-box"></div>
</div> </div>
<div class="center"> <div class="center">

View File

@ -465,7 +465,7 @@
commentsArea.innerHTML = ""; commentsArea.innerHTML = "";
if (isLocked || isFrozen) { if (isLocked || isFrozen) {
if (isAuthenticated) { if (isAuthenticated || chosenAnonymous) {
append(mainArea, messageCreate("This thread is locked. You cannot add new comments.")); append(mainArea, messageCreate("This thread is locked. You cannot add new comments."));
} else { } else {
append(mainArea, textareaCreate("root")); append(mainArea, textareaCreate("root"));
@ -1408,15 +1408,9 @@
isLocked = !isLocked; isLocked = !isLocked;
lock.disabled = true; lock.disabled = true;
pageUpdate(function(success) { pageUpdate(function() {
if (success) {
lock.disabled = false; lock.disabled = false;
if (isLocked) { refreshAll();
lock.innerHTML = "Unlock Thread";
} else {
lock.innerHTML = "Lock Thread";
}
}
}); });
} }
@ -1434,8 +1428,7 @@
stickyCommentHex = commentHex; stickyCommentHex = commentHex;
} }
pageUpdate(function(success) { pageUpdate(function() {
if (success) {
var sticky = $(ID_STICKY + commentHex); var sticky = $(ID_STICKY + commentHex);
if (stickyCommentHex === commentHex) { if (stickyCommentHex === commentHex) {
classRemove(sticky, "option-sticky"); classRemove(sticky, "option-sticky");
@ -1444,7 +1437,6 @@
classRemove(sticky, "option-unsticky"); classRemove(sticky, "option-unsticky");
classAdd(sticky, "option-sticky"); classAdd(sticky, "option-sticky");
} }
}
}); });
} }

View File

@ -92,6 +92,8 @@
resp.domains[i].viewsLast30Days = global.numberify(0); resp.domains[i].viewsLast30Days = global.numberify(0);
resp.domains[i].commentsLast30Days = global.numberify(0); resp.domains[i].commentsLast30Days = global.numberify(0);
resp.domains[i].allowAnonymous = !resp.domains[i].requireIdentification;
for (var j = 0; j < resp.domains[i].moderators.length; j++) { for (var j = 0; j < resp.domains[i].moderators.length; j++) {
resp.domains[i].moderators[j].timeAgo = global.timeSince( resp.domains[i].moderators[j].timeAgo = global.timeSince(
Date.parse(resp.domains[i].moderators[j].addDate)); Date.parse(resp.domains[i].moderators[j].addDate));
@ -109,6 +111,7 @@
// Updates a domain with the backend. // Updates a domain with the backend.
global.domainUpdate = function(domain, callback) { global.domainUpdate = function(domain, callback) {
domain.requireIdentification = !domain.allowAnonymous;
var json = { var json = {
"ownerToken": global.cookieGet("commentoOwnerToken"), "ownerToken": global.cookieGet("commentoOwnerToken"),
"domain": domain, "domain": domain,

View File

@ -623,6 +623,10 @@ body {
border: none; border: none;
} }
.indent {
padding-left: 32px;
}
.button { .button {
@extend .shadow; @extend .shadow;
height: 40px; height: 40px;