From fd5877347291fc7f43e459967ab755f387b934ce Mon Sep 17 00:00:00 2001 From: erin Date: Thu, 15 Jun 2023 18:29:49 -0400 Subject: [PATCH 1/8] fix: treat 'gotosocial' software as mastodon --- backend/db/fediverse.go | 2 +- backend/routes/auth/fediverse.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/db/fediverse.go b/backend/db/fediverse.go index d319cad..eeadd79 100644 --- a/backend/db/fediverse.go +++ b/backend/db/fediverse.go @@ -48,7 +48,7 @@ func (f FediverseApp) ClientConfig() *oauth2.Config { } func (f FediverseApp) MastodonCompatible() bool { - return f.InstanceType == "mastodon" || f.InstanceType == "pleroma" || f.InstanceType == "akkoma" || f.InstanceType == "pixelfed" + return f.InstanceType == "mastodon" || f.InstanceType == "pleroma" || f.InstanceType == "akkoma" || f.InstanceType == "pixelfed" || f.InstanceType == "gotosocial" } func (f FediverseApp) Misskey() bool { diff --git a/backend/routes/auth/fediverse.go b/backend/routes/auth/fediverse.go index 0f0511c..b3f2f62 100644 --- a/backend/routes/auth/fediverse.go +++ b/backend/routes/auth/fediverse.go @@ -67,7 +67,7 @@ func (s *Server) noAppFediverseURL(ctx context.Context, w http.ResponseWriter, r switch softwareName { case "misskey", "foundkey", "calckey": return s.noAppMisskeyURL(ctx, w, r, softwareName, instance) - case "mastodon", "pleroma", "akkoma", "pixelfed": + case "mastodon", "pleroma", "akkoma", "pixelfed", "gotosocial": case "glitchcafe": // plural.cafe (potentially other instances too?) runs Mastodon but changes the software name // changing it back to mastodon here for consistency From 0140265912075547209d5e996548b692d29afd8a Mon Sep 17 00:00:00 2001 From: Erin Date: Thu, 15 Jun 2023 23:13:29 -0400 Subject: [PATCH 2/8] clarify note on MINIO_ENDPOINT --- .env.example | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.env.example b/.env.example index b6566ff..74a5b0a 100644 --- a/.env.example +++ b/.env.example @@ -15,7 +15,7 @@ BASE_URL=http://localhost:5173 # S3/MinIO configuration, required for avatars, pride flags, and data exports # Note: MINIO_ENDPOINT must be set and look like a minio endpoint, but doesn't -# have to actually point to one you have access to +# have to actually point to anything real MINIO_ENDPOINT=example.com MINIO_BUCKET= MINIO_ACCESS_KEY_ID= From dad6bc042d34503098c8995e54e667655753c4f1 Mon Sep 17 00:00:00 2001 From: Erin Date: Thu, 15 Jun 2023 23:13:43 -0400 Subject: [PATCH 3/8] clarify how to generate HMAC_KEY --- docs/production.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/production.md b/docs/production.md index 86f06ab..9afe530 100644 --- a/docs/production.md +++ b/docs/production.md @@ -22,7 +22,7 @@ one in the repository root (for the backend) and one in the frontend directory. ### Backend keys -- `HMAC_KEY`: the key used to sign tokens. This should be a base64 string, you can generate one with `scripts/genkey`. +- `HMAC_KEY`: the key used to sign tokens. This should be a base64 string, you can generate one with `go run -v . generate key` (or `./pronouns generate key` after building). - `DATABASE_URL`: the URL for the PostgreSQL database. - `REDIS`: the URL for the Redis database. - `PORT` (int): the port the backend will listen on. From 37e5c78e35d0531d67619cc2006fd6d2e1a458d8 Mon Sep 17 00:00:00 2001 From: Erin Date: Thu, 15 Jun 2023 23:31:15 -0400 Subject: [PATCH 4/8] fix: typo --- .env.example | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.env.example b/.env.example index 74a5b0a..ad1d1e6 100644 --- a/.env.example +++ b/.env.example @@ -40,5 +40,5 @@ TUMBLR_CLIENT_ID= TUMBLR_CLIENT_SECRET= # Discord bot config - provide the app's public key in addition to client ID/ -# secret from above to let the bot to respond to command interactions over HTTP +# secret above to let the bot respond to command interactions over HTTP DISCORD_PUBLIC_KEY= From c61186b22a73697119e3bbdd1e3e3064788d0171 Mon Sep 17 00:00:00 2001 From: Sam Date: Fri, 23 Jun 2023 03:27:09 +0200 Subject: [PATCH 5/8] feat(backend): add request latency tracking --- backend/server/server.go | 7 +++++++ go.mod | 1 + go.sum | 6 ++++++ 3 files changed, 14 insertions(+) diff --git a/backend/server/server.go b/backend/server/server.go index 7da468a..399ead0 100644 --- a/backend/server/server.go +++ b/backend/server/server.go @@ -14,6 +14,7 @@ import ( "github.com/go-chi/cors" "github.com/go-chi/httprate" "github.com/go-chi/render" + chiprometheus "github.com/toshi0607/chi-prometheus" ) // Revision is the git commit, filled at build time @@ -59,6 +60,12 @@ func New() (*Server, error) { MaxAge: 300, })) + // enable request latency tracking + os.Setenv(chiprometheus.EnvChiPrometheusLatencyBuckets, "10,25,50,100,300,500,1000,5000") + prom := chiprometheus.New("pronouns.cc") + s.Router.Use(prom.Handler) + prom.MustRegisterDefault() + // enable authentication for all routes (but don't require it) s.Router.Use(s.maybeAuth) diff --git a/go.mod b/go.mod index 989313c..f576cd2 100644 --- a/go.mod +++ b/go.mod @@ -62,6 +62,7 @@ require ( github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/sirupsen/logrus v1.9.0 // indirect github.com/tilinna/clock v1.1.0 // indirect + github.com/toshi0607/chi-prometheus v0.1.3 // indirect github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect go.opencensus.io v0.24.0 // indirect go.uber.org/atomic v1.10.0 // indirect diff --git a/go.sum b/go.sum index 1df87f9..aa792d6 100644 --- a/go.sum +++ b/go.sum @@ -145,6 +145,7 @@ github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2 github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= @@ -291,6 +292,7 @@ github.com/jackc/puddle/v2 v2.2.0/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFr github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= @@ -298,6 +300,7 @@ github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1 github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/karrick/godirwalk v1.16.1 h1:DynhcF+bztK8gooS0+NDJFrdNZjJ3gzVzC545UNA9iw= github.com/karrick/godirwalk v1.16.1/go.mod h1:j4mkqPuvaLI8mp1DroR3P6ad7cyYd4c1qeJ3RV7ULlk= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= @@ -385,6 +388,7 @@ github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3Rllmb github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/nelsam/hel/v2 v2.3.2/go.mod h1:1ZTGfU2PFTOd5mx22i5O0Lc2GY933lQ2wb/ggy+rL3w= github.com/nelsam/hel/v2 v2.3.3/go.mod h1:1ZTGfU2PFTOd5mx22i5O0Lc2GY933lQ2wb/ggy+rL3w= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= @@ -484,6 +488,8 @@ github.com/tilinna/clock v1.0.2/go.mod h1:ZsP7BcY7sEEz7ktc0IVy8Us6boDrK8VradlKRU github.com/tilinna/clock v1.1.0 h1:6IQQQCo6KoBxVudv6gwtY8o4eDfhHo8ojA5dP0MfhSs= github.com/tilinna/clock v1.1.0/go.mod h1:ZsP7BcY7sEEz7ktc0IVy8Us6boDrK8VradlKRUGfOao= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/toshi0607/chi-prometheus v0.1.3 h1:KL0+MmVISNyKHsmvlU4fw00NDEUTB9K+OQt4scgD19U= +github.com/toshi0607/chi-prometheus v0.1.3/go.mod h1:2jErPypCR/0jMc4MTnEbjkWmJ3nkh5wmOVO9icayOaM= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/urfave/cli/v2 v2.25.1 h1:zw8dSP7ghX0Gmm8vugrs6q9Ku0wzweqPyshy+syu9Gw= github.com/urfave/cli/v2 v2.25.1/go.mod h1:GHupkWPMM0M/sj1a2b4wUrWBPzazNrIjouW6fmdJLxc= From af1403d0c9d63df3e22c5d6a3c25b18a6d000694 Mon Sep 17 00:00:00 2001 From: Sam Date: Sun, 25 Jun 2023 14:11:49 +0200 Subject: [PATCH 6/8] feat(frontend): add disclaimer to report modal --- frontend/src/routes/@[username]/ReportButton.svelte | 3 +++ 1 file changed, 3 insertions(+) diff --git a/frontend/src/routes/@[username]/ReportButton.svelte b/frontend/src/routes/@[username]/ReportButton.svelte index 4f55f9d..79dbc82 100644 --- a/frontend/src/routes/@[username]/ReportButton.svelte +++ b/frontend/src/routes/@[username]/ReportButton.svelte @@ -45,6 +45,9 @@ terms of service. +
+ Note that we cannot take action on any reports that cannot be proven with just + the reported profile and any external pages linked on it.

From 80cf699a732117151dca13c02e6f7fc2ee52343c Mon Sep 17 00:00:00 2001 From: Sam Date: Sun, 25 Jun 2023 15:49:19 +0200 Subject: [PATCH 7/8] feat(backend): cache user/member counts --- backend/db/db.go | 5 +++++ backend/db/metrics.go | 41 +++++++++++++++++++++++++++++++++++++ backend/routes/meta/meta.go | 27 +----------------------- 3 files changed, 47 insertions(+), 26 deletions(-) diff --git a/backend/db/db.go b/backend/db/db.go index 5f7af5a..13e12f2 100644 --- a/backend/db/db.go +++ b/backend/db/db.go @@ -6,6 +6,7 @@ import ( "fmt" "net/url" "os" + "sync" "codeberg.org/pronounscc/pronouns.cc/backend/log" "emperror.dev/errors" @@ -41,6 +42,10 @@ type DB struct { baseURL *url.URL TotalRequests prometheus.Counter + + activeUsersDay, activeUsersWeek, activeUsersMonth int64 + usersTotal, membersTotal int64 + countMu sync.RWMutex } func New() (*DB, error) { diff --git a/backend/db/metrics.go b/backend/db/metrics.go index c2a4cf9..e9e34ef 100644 --- a/backend/db/metrics.go +++ b/backend/db/metrics.go @@ -21,6 +21,11 @@ func (db *DB) initMetrics() (err error) { if err != nil { log.Errorf("getting user count for metrics: %v", err) } + + db.countMu.Lock() + db.usersTotal = count + db.countMu.Unlock() + return float64(count) })) if err != nil { @@ -35,6 +40,11 @@ func (db *DB) initMetrics() (err error) { if err != nil { log.Errorf("getting member count for metrics: %v", err) } + + db.countMu.Lock() + db.membersTotal = count + db.countMu.Unlock() + return float64(count) })) if err != nil { @@ -49,6 +59,11 @@ func (db *DB) initMetrics() (err error) { if err != nil { log.Errorf("getting active user count for metrics: %v", err) } + + db.countMu.Lock() + db.activeUsersMonth = count + db.countMu.Unlock() + return float64(count) })) if err != nil { @@ -63,6 +78,11 @@ func (db *DB) initMetrics() (err error) { if err != nil { log.Errorf("getting active user count for metrics: %v", err) } + + db.countMu.Lock() + db.activeUsersWeek = count + db.countMu.Unlock() + return float64(count) })) if err != nil { @@ -77,6 +97,11 @@ func (db *DB) initMetrics() (err error) { if err != nil { log.Errorf("getting active user count for metrics: %v", err) } + + db.countMu.Lock() + db.activeUsersDay = count + db.countMu.Unlock() + return float64(count) })) if err != nil { @@ -107,6 +132,22 @@ func (db *DB) initMetrics() (err error) { return nil } +func (db *DB) Counts(ctx context.Context) (numUsers, numMembers, usersDay, usersWeek, usersMonth int64) { + db.countMu.Lock() + if numUsers != 0 { + defer db.countMu.Unlock() + return db.usersTotal, db.membersTotal, db.activeUsersDay, db.activeUsersWeek, db.activeUsersMonth + } + db.countMu.Unlock() + + numUsers, _ = db.TotalUserCount(ctx) + numMembers, _ = db.TotalMemberCount(ctx) + usersDay, _ = db.ActiveUsers(ctx, ActiveDay) + usersWeek, _ = db.ActiveUsers(ctx, ActiveWeek) + usersMonth, _ = db.ActiveUsers(ctx, ActiveMonth) + return numUsers, numMembers, usersDay, usersWeek, usersMonth +} + func (db *DB) TotalUserCount(ctx context.Context) (numUsers int64, err error) { err = db.QueryRow(ctx, "SELECT COUNT(*) FROM users WHERE deleted_at IS NULL").Scan(&numUsers) if err != nil { diff --git a/backend/routes/meta/meta.go b/backend/routes/meta/meta.go index da59f8d..ebae428 100644 --- a/backend/routes/meta/meta.go +++ b/backend/routes/meta/meta.go @@ -4,9 +4,7 @@ import ( "net/http" "os" - "codeberg.org/pronounscc/pronouns.cc/backend/db" "codeberg.org/pronounscc/pronouns.cc/backend/server" - "emperror.dev/errors" "github.com/go-chi/chi/v5" "github.com/go-chi/render" ) @@ -39,30 +37,7 @@ type MetaUsers struct { func (s *Server) meta(w http.ResponseWriter, r *http.Request) error { ctx := r.Context() - numUsers, err := s.DB.TotalUserCount(ctx) - if err != nil { - return errors.Wrap(err, "querying user count") - } - - activeMonth, err := s.DB.ActiveUsers(ctx, db.ActiveMonth) - if err != nil { - return errors.Wrap(err, "querying user count") - } - - activeWeek, err := s.DB.ActiveUsers(ctx, db.ActiveWeek) - if err != nil { - return errors.Wrap(err, "querying user count") - } - - activeDay, err := s.DB.ActiveUsers(ctx, db.ActiveDay) - if err != nil { - return errors.Wrap(err, "querying user count") - } - - numMembers, err := s.DB.TotalMemberCount(ctx) - if err != nil { - return errors.Wrap(err, "querying user count") - } + numUsers, numMembers, activeDay, activeWeek, activeMonth := s.DB.Counts(ctx) render.JSON(w, r, MetaResponse{ GitRepository: server.Repository, From 969e06e31e610897aaef8ef24190e4cbd276c3ac Mon Sep 17 00:00:00 2001 From: Sam Date: Sun, 25 Jun 2023 15:55:44 +0200 Subject: [PATCH 8/8] *actually* cache counts --- backend/db/metrics.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/db/metrics.go b/backend/db/metrics.go index e9e34ef..96661dd 100644 --- a/backend/db/metrics.go +++ b/backend/db/metrics.go @@ -134,7 +134,7 @@ func (db *DB) initMetrics() (err error) { func (db *DB) Counts(ctx context.Context) (numUsers, numMembers, usersDay, usersWeek, usersMonth int64) { db.countMu.Lock() - if numUsers != 0 { + if db.usersTotal != 0 { defer db.countMu.Unlock() return db.usersTotal, db.membersTotal, db.activeUsersDay, db.activeUsersWeek, db.activeUsersMonth }