From a455ff54bc37d4f1115777d8f56490593ed731c6 Mon Sep 17 00:00:00 2001 From: Adhityaa Chandrasekar Date: Fri, 19 Apr 2019 19:03:34 -0400 Subject: [PATCH] frontend, api: allow disabling login methods individually --- api/comment_list.go | 8 ++- api/domain.go | 5 ++ api/domain_get.go | 36 ++++++++++- api/domain_list.go | 47 +++++++++++++- api/domain_update.go | 29 ++++++++- api/oauth.go | 7 ++- api/oauth_github.go | 2 +- api/oauth_gitlab.go | 2 +- api/oauth_google.go | 2 +- api/oauth_twitter.go | 4 +- db/20190418210855-configurable-auth.sql | 16 +++++ frontend/dashboard.html | 82 ++++++++++++++++++------- frontend/js/commento.js | 40 +++++++----- frontend/js/dashboard-domain.js | 2 + frontend/js/dashboard.js | 5 +- frontend/sass/commento-login.scss | 2 +- frontend/sass/dashboard-main.scss | 25 +++++++- 17 files changed, 258 insertions(+), 56 deletions(-) create mode 100644 db/20190418210855-configurable-auth.sql diff --git a/api/comment_list.go b/api/comment_list.go index dfc9047..663b75a 100644 --- a/api/comment_list.go +++ b/api/comment_list.go @@ -167,6 +167,12 @@ func commentListHandler(w http.ResponseWriter, r *http.Request) { "isFrozen": d.State == "frozen", "isModerator": isModerator, "attributes": p, - "configuredOauths": configuredOauths, + "configuredOauths": map[string]bool{ + "commento": d.CommentoProvider, + "google": googleConfigured && d.GoogleProvider, + "twitter": twitterConfigured && d.TwitterProvider, + "github": githubConfigured && d.GithubProvider, + "gitlab": gitlabConfigured && d.GitlabProvider, + }, }) } diff --git a/api/domain.go b/api/domain.go index c5f7a51..1316ca3 100644 --- a/api/domain.go +++ b/api/domain.go @@ -17,4 +17,9 @@ type domain struct { ModerateAllAnonymous bool `json:"moderateAllAnonymous"` Moderators []moderator `json:"moderators"` EmailNotificationPolicy string `json:"emailNotificationPolicy"` + CommentoProvider bool `json:"commentoProvider"` + GoogleProvider bool `json:"googleProvider"` + TwitterProvider bool `json:"twitterProvider"` + GithubProvider bool `json:"githubProvider"` + GitlabProvider bool `json:"gitlabProvider"` } diff --git a/api/domain_get.go b/api/domain_get.go index b0c036f..4f38b90 100644 --- a/api/domain_get.go +++ b/api/domain_get.go @@ -8,7 +8,23 @@ func domainGet(dmn string) (domain, error) { } statement := ` - SELECT domain, ownerHex, name, creationDate, state, importedComments, autoSpamFilter, requireModeration, requireIdentification, moderateAllAnonymous, emailNotificationPolicy + SELECT + domain, + ownerHex, + name, + creationDate, + state, + importedComments, + autoSpamFilter, + requireModeration, + requireIdentification, + moderateAllAnonymous, + emailNotificationPolicy, + commentoProvider, + googleProvider, + twitterProvider, + githubProvider, + gitlabProvider FROM domains WHERE domain = $1; ` @@ -16,7 +32,23 @@ func domainGet(dmn string) (domain, error) { var err error d := domain{} - if err = row.Scan(&d.Domain, &d.OwnerHex, &d.Name, &d.CreationDate, &d.State, &d.ImportedComments, &d.AutoSpamFilter, &d.RequireModeration, &d.RequireIdentification, &d.ModerateAllAnonymous, &d.EmailNotificationPolicy); 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, + &d.EmailNotificationPolicy, + &d.CommentoProvider, + &d.GoogleProvider, + &d.TwitterProvider, + &d.GithubProvider, + &d.GitlabProvider); err != nil { return d, errorNoSuchDomain } diff --git a/api/domain_list.go b/api/domain_list.go index f1eca8c..8a48d4c 100644 --- a/api/domain_list.go +++ b/api/domain_list.go @@ -10,7 +10,23 @@ func domainList(ownerHex string) ([]domain, error) { } statement := ` - SELECT domain, ownerHex, name, creationDate, state, importedComments, autoSpamFilter, requireModeration, requireIdentification, moderateAllAnonymous, emailNotificationPolicy + SELECT + domain, + ownerHex, + name, + creationDate, + state, + importedComments, + autoSpamFilter, + requireModeration, + requireIdentification, + moderateAllAnonymous, + emailNotificationPolicy, + commentoProvider, + googleProvider, + twitterProvider, + githubProvider, + gitlabProvider FROM domains WHERE ownerHex=$1; ` @@ -24,7 +40,23 @@ func domainList(ownerHex string) ([]domain, error) { domains := []domain{} for rows.Next() { d := domain{} - if err = rows.Scan(&d.Domain, &d.OwnerHex, &d.Name, &d.CreationDate, &d.State, &d.ImportedComments, &d.AutoSpamFilter, &d.RequireModeration, &d.RequireIdentification, &d.ModerateAllAnonymous, &d.EmailNotificationPolicy); 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, + &d.EmailNotificationPolicy, + &d.CommentoProvider, + &d.GoogleProvider, + &d.TwitterProvider, + &d.GithubProvider, + &d.GitlabProvider); err != nil { logger.Errorf("cannot Scan domain: %v", err) return nil, errorInternal } @@ -63,5 +95,14 @@ func domainListHandler(w http.ResponseWriter, r *http.Request) { return } - bodyMarshal(w, response{"success": true, "domains": domains}) + bodyMarshal(w, response{ + "success": true, + "domains": domains, + "configuredOauths": map[string]bool{ + "google": googleConfigured, + "twitter": twitterConfigured, + "github": githubConfigured, + "gitlab": gitlabConfigured, + }, + }) } diff --git a/api/domain_update.go b/api/domain_update.go index c1a87ff..a60fcca 100644 --- a/api/domain_update.go +++ b/api/domain_update.go @@ -7,11 +7,36 @@ import ( func domainUpdate(d domain) error { statement := ` UPDATE domains - SET name=$2, state=$3, autoSpamFilter=$4, requireModeration=$5, requireIdentification=$6, moderateAllAnonymous=$7, emailNotificationPolicy=$8 + SET + name=$2, + state=$3, + autoSpamFilter=$4, + requireModeration=$5, + requireIdentification=$6, + moderateAllAnonymous=$7, + emailNotificationPolicy=$8, + commentoProvider=$9, + googleProvider=$10, + twitterProvider=$11, + githubProvider=$12, + gitlabProvider=$13 WHERE domain=$1; ` - _, err := db.Exec(statement, d.Domain, d.Name, d.State, d.AutoSpamFilter, d.RequireModeration, d.RequireIdentification, d.ModerateAllAnonymous, d.EmailNotificationPolicy) + _, err := db.Exec(statement, + d.Domain, + d.Name, + d.State, + d.AutoSpamFilter, + d.RequireModeration, + d.RequireIdentification, + d.ModerateAllAnonymous, + d.EmailNotificationPolicy, + d.CommentoProvider, + d.GoogleProvider, + d.TwitterProvider, + d.GithubProvider, + d.GitlabProvider) if err != nil { logger.Errorf("cannot update non-moderators: %v", err) return errorInternal diff --git a/api/oauth.go b/api/oauth.go index 5e324a0..c221326 100644 --- a/api/oauth.go +++ b/api/oauth.go @@ -2,11 +2,12 @@ package main import () -var configuredOauths []string +var googleConfigured bool +var twitterConfigured bool +var githubConfigured bool +var gitlabConfigured bool func oauthConfigure() error { - configuredOauths = []string{} - if err := googleOauthConfigure(); err != nil { return err } diff --git a/api/oauth_github.go b/api/oauth_github.go index d92a017..b3b565c 100644 --- a/api/oauth_github.go +++ b/api/oauth_github.go @@ -37,7 +37,7 @@ func githubOauthConfigure() error { Endpoint: github.Endpoint, } - configuredOauths = append(configuredOauths, "github") + githubConfigured = true return nil } diff --git a/api/oauth_gitlab.go b/api/oauth_gitlab.go index ba882c2..495ba58 100644 --- a/api/oauth_gitlab.go +++ b/api/oauth_gitlab.go @@ -36,7 +36,7 @@ func gitlabOauthConfigure() error { Endpoint: gitlab.Endpoint, } - configuredOauths = append(configuredOauths, "gitlab") + gitlabConfigured = true return nil } diff --git a/api/oauth_google.go b/api/oauth_google.go index 6eb53e8..d50dc08 100644 --- a/api/oauth_google.go +++ b/api/oauth_google.go @@ -37,7 +37,7 @@ func googleOauthConfigure() error { Endpoint: google.Endpoint, } - configuredOauths = append(configuredOauths, "google") + googleConfigured = true return nil } diff --git a/api/oauth_twitter.go b/api/oauth_twitter.go index 753df2a..a600917 100644 --- a/api/oauth_twitter.go +++ b/api/oauth_twitter.go @@ -43,9 +43,9 @@ func twitterOauthConfigure() error { }, } - configuredOauths = append(configuredOauths, "twitter") - twitterCredMap = make(map[string]twitterOauthState, 1e3) + twitterConfigured = true + return nil } diff --git a/db/20190418210855-configurable-auth.sql b/db/20190418210855-configurable-auth.sql new file mode 100644 index 0000000..9dab0f5 --- /dev/null +++ b/db/20190418210855-configurable-auth.sql @@ -0,0 +1,16 @@ +-- Make all login providers optional (but enabled by default) + +ALTER TABLE domains + ADD commentoProvider BOOLEAN NOT NULL DEFAULT true; + +ALTER TABLE domains + ADD googleProvider BOOLEAN NOT NULL DEFAULT true; + +ALTER TABLE domains + ADD twitterProvider BOOLEAN NOT NULL DEFAULT true; + +ALTER TABLE domains + ADD githubProvider BOOLEAN NOT NULL DEFAULT true; + +ALTER TABLE domains + ADD gitlabProvider BOOLEAN NOT NULL DEFAULT true; diff --git a/frontend/dashboard.html b/frontend/dashboard.html index 2277697..893cb94 100644 --- a/frontend/dashboard.html +++ b/frontend/dashboard.html @@ -181,14 +181,6 @@
- - -
- Enabling this would allow your readers to comment anonymously. Disabling would require the to authenticate themselves (using their Google account, for example). Recommended. -
-
- -
@@ -228,21 +220,27 @@
You can enable email notifications to notify your moderators when a new comment is posted or when a comment is pending moderation. Commento tries to be smart about how often an email is sent. Emails will be delayed and batched until you go 10 minutes without one. This requires valid SMTP settings in order to send emails.

+
- When do you want emails sent to moderators? -
-
- - -
-
- - -
-
- - +
+ Email Schedule +
+
+
+ + +
+
+ + +
+
+ + +
+
+
@@ -272,6 +270,48 @@
+ +
+
+ Authentication Options +
+
+
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ You have disabled all authentication options. Your readers will not be able to login, create comments, or vote. +
+
+
+
diff --git a/frontend/js/commento.js b/frontend/js/commento.js index 8f464fc..bbb59ab 100644 --- a/frontend/js/commento.js +++ b/frontend/js/commento.js @@ -73,7 +73,7 @@ var isLocked = false; var stickyCommentHex = "none"; var shownReply = {}; - var configuredOauths = []; + var configuredOauths = {}; var popupBoxType = "login"; var oauthButtonsShown = false; var selfHex = undefined; @@ -1266,37 +1266,49 @@ attrSet(emailInput, "placeholder", "Email address"); attrSet(emailInput, "type", "text"); - for (var i = 0; i < configuredOauths.length; i++) { - var button = create("button"); + var numOauthConfigured = 0; + var oauthProviders = ["google", "twitter", "github", "gitlab"]; + oauthProviders.forEach(function(provider) { + console.log(provider); + if (configuredOauths[provider]) { + var button = create("button"); - classAdd(button, "button"); - classAdd(button, configuredOauths[i] + "-button"); + classAdd(button, "button"); + classAdd(button, provider+ "-button"); - button.innerText = configuredOauths[i]; + button.innerText = provider; - onclick(button, global.commentoAuth, {"provider": configuredOauths[i], "id": id}); + onclick(button, global.commentoAuth, {"provider": provider, "id": id}); - append(oauthButtons, button); - } + append(oauthButtons, button); + numOauthConfigured++; + } + }); - if (configuredOauths.length > 0) { + if (numOauthConfigured > 0) { append(loginBox, oauthSubtitle); append(oauthButtonsContainer, oauthButtons); append(loginBox, oauthButtonsContainer); - append(loginBox, hr); oauthButtonsShown = true; } else { oauthButtonsShown = false; } - append(loginBox, emailSubtitle); append(email, emailInput); append(email, emailButton); append(emailContainer, email); - append(loginBox, emailContainer); append(loginLinkContainer, loginLink); - append(loginBox, loginLinkContainer); + + if (numOauthConfigured > 0 && configuredOauths["commento"]) { + append(loginBox, hr); + } + + if (configuredOauths["commento"]) { + append(loginBox, emailSubtitle); + append(loginBox, emailContainer); + append(loginBox, loginLinkContainer); + } append(loginBox, close); diff --git a/frontend/js/dashboard-domain.js b/frontend/js/dashboard-domain.js index d7a4404..5b996d7 100644 --- a/frontend/js/dashboard-domain.js +++ b/frontend/js/dashboard-domain.js @@ -102,6 +102,8 @@ global.vs("domains", resp.domains); + global.vs("configuredOauths", resp.configuredOauths); + if (callback !== undefined) { callback(); } diff --git a/frontend/js/dashboard.js b/frontend/js/dashboard.js index bf68905..6382675 100644 --- a/frontend/js/dashboard.js +++ b/frontend/js/dashboard.js @@ -31,7 +31,7 @@ { "id": "general", "text": "General", - "meaning": "Email settings, data export", + "meaning": "Names, authentication, and export", "selected": false, "open": global.generalOpen, }, @@ -72,6 +72,9 @@ // list of domains dynamically loaded; obviously mutable domains: [{show: false, viewsLast30Days: global.numberify(0), commentsLast30Days: global.numberify(0), moderators: []}], + // configured oauth providers that will be filled in after a backend request + configuredOauths: {}, + // whether or not to show the settings column; mutable because we do not // show the column until a domain has been selected showSettings: false, diff --git a/frontend/sass/commento-login.scss b/frontend/sass/commento-login.scss index c66e0fe..da678b1 100644 --- a/frontend/sass/commento-login.scss +++ b/frontend/sass/commento-login.scss @@ -11,7 +11,7 @@ .commento-login-box { width: 90%; max-width: 500px; - min-height: 125px; + min-height: 100px; background: $gray-1; box-shadow: 0 4px 6px rgba(50,50,93,.11),0 1px 3px rgba(0,0,0,.08); border: 1px solid transparent; diff --git a/frontend/sass/dashboard-main.scss b/frontend/sass/dashboard-main.scss index 3d64f2f..6a1fcd3 100644 --- a/frontend/sass/dashboard-main.scss +++ b/frontend/sass/dashboard-main.scss @@ -372,9 +372,28 @@ body { } .question { - font-size: 15px; - color: $gray-7; - margin-bottom: 10px; + padding: 8px 0px 8px 0px; + margin: 8px 0px 8px 0px; + display: flex; + width: 100%; + + .title { + font-weight: bold; + color: $gray-7; + font-size: 14px; + width: 35%; + padding-top: 12px; + } + + .answer { + font-size: 14px; + width: 100%; + } +} + +.warning { + color: $orange-8; + font-weight: bold; } .float-right {