website/pkg/config/config.go
Noah Petherbridge b12390563e Forum Creation Quotas
Add minimum quotas for users to earn the ability to create custom forums.

The entry requirements that could earn the first forum include:
1. Having a Certified account status for at least 45 days.
2. Having written 10 posts or replies in the forums.

Additional quota is granted in increasing difficulty based on the count of
forum posts created.

Other changes:

* Admin view of Manage Forums can filter for official/community.
* "Certified Since" now shown on profile pages.
* Update FAQ page for Forums feature.
2024-08-23 22:56:40 -07:00

175 lines
5.3 KiB
Go

// Package config holds some (mostly static) configuration for the app.
package config
import (
"regexp"
"time"
)
// Branding
const (
Title = "nonshy"
Subtitle = "A social network for nudists and exhibitionists."
)
// Paths and layouts
const (
TemplatePath = "./web/templates"
StaticPath = "./web/static"
SettingsPath = "./settings.json"
// Web path where photos are kept. Photos in DB store only their filenames, this
// is the base URL that goes in front. TODO: support setting a CDN URL prefix.
JpegQuality = 90
PhotoWebPath = "/static/photos"
PhotoDiskPath = "./web/static/photos"
)
// Security
const (
BcryptCost = 14
SessionCookieName = "session_id"
CSRFCookieName = "xsrf_token"
CSRFInputName = "_csrf" // html input name
SessionCookieMaxAge = 60 * 60 * 24 * 30
SessionRedisKeyFormat = "session/%s"
MaxBodySize = 1024 * 1024 * 8 // max upload file (e.g., 8 MB gifs)
MultipartMaxMemory = 1024 * 1024 * 1024 * 20 // 20 MB
TwoFactorBackupCodeCount = 12
TwoFactorBackupCodeLength = 8 // characters a-z0-9
)
// Authentication
const (
// Skip the email verification step. The signup page will directly ask for
// email+username+password rather than only email and needing verification.
SkipEmailVerification = false
SignupTokenRedisKey = "signup-token/%s"
ResetPasswordRedisKey = "reset-password/%s"
ChangeEmailRedisKey = "change-email/%s"
SignupTokenExpires = 24 * time.Hour // used for all tokens so far
// Rate limits
RateLimitRedisKey = "rate-limit/%s/%s" // namespace, id
LoginRateLimitWindow = 1 * time.Hour
LoginRateLimit = 10 // 10 failed login attempts = locked for full hour
LoginRateLimitCooldownAt = 3 // 3 failed attempts = start throttling
LoginRateLimitCooldown = 30 * time.Second
// Contact form rate limits for logged-out users to curb spam robots:
// - One message can be submitted every 2 minutes
// - If they post 10 minutes in an hour they are paused for one hour.
ContactRateLimitWindow = 1 * time.Hour
ContactRateLimit = 10
ContactRateLimitCooldownAt = 1
ContactRateLimitCooldown = 2 * time.Minute
// "Mark Explicit" rate limit to curb a mischievous user just bulk marking the
// whole gallery as explicit.
MarkExplicitRateLimitWindow = 1 * time.Hour
MarkExplicitRateLimit = 20 // 10 failed MarkExplicit attempts = locked for full hour
MarkExplicitRateLimitCooldownAt = 10 // 10 photos in an hour, start throttling.
MarkExplicitRateLimitCooldown = time.Minute
// How frequently to refresh LastLoginAt since sessions are long-lived.
LastLoginAtCooldown = time.Hour
// Chat room status refresh interval.
ChatStatusRefreshInterval = 30 * time.Second
)
var (
UsernameRegexp = regexp.MustCompile(`^[a-z0-9_.-]{3,32}$`)
ReservedUsernames = []string{
"admin",
"admins",
"administrator",
"moderator",
"support",
"staff",
"nonshy",
"here",
"all",
"everyone",
"everybody",
}
)
// Photo Galleries
const (
MaxPhotoWidth = 1280
ProfilePhotoWidth = 512
AltTextMaxLength = 5000
// Quotas for uploaded photos.
PhotoQuotaUncertified = 6
PhotoQuotaCertified = 100
// Rate limit for too many Site Gallery pictures.
// Some users sign up and immediately max out their gallery and spam
// the Site Gallery page. These limits can ensure only a few Site Gallery
// pictures can be posted per day.
SiteGalleryRateLimitMax = 5
SiteGalleryRateLimitInterval = 24 * time.Hour
)
// Forum settings
const (
// Only ++ the Views count per user per thread within a small
// window of time - if a user keeps reloading the same thread
// rapidly it does not increment the view counter more.
ThreadViewDebounceRedisKey = "debounce-view/user=%d/thr=%d"
ThreadViewDebounceCooldown = 1 * time.Hour
// Enable user-owned forums (feature flag)
UserForumsEnabled = true
)
// User-Owned Forums: Quota settings for how many forums a user can own.
var (
// They get one forum after they've been Certified for 45 days.
UserForumQuotaCertLifetimeDays = time.Hour * 24 * 45
// Schedule for gaining additional quota for a number of comments written
// on any forum thread. The user must have the sum of all of these post
// counts to gain one forum per level.
UserForumQuotaCommentCountSchedule = []int64{
10, // Get a forum after your first 10 posts.
20, // Get a 2nd forum after 20 additional posts (30 total)
30, // 30 more posts (60 total)
60, // 60 more posts (120 total)
80, // 80 more posts (200 total)
100, // and then one new forum for every 100 additional posts
}
)
// Poll settings
var (
// Max number of responses to accept for a poll (how many form
// values the app will read in). NOTE: also enforced in frontend
// UX in new_post.html, update there if you change this.
PollMaxAnswers = 100
// Poll color CSS classes (Bulma). Plugged in to templates like:
// <progress class="$CLASS">
// Values will wrap around for long polls.
PollProgressBarClasses = []string{
"progress is-success",
"progress is-link",
"progress is-warning",
"progress is-danger",
"progress is-primary",
"progress is-info",
}
)
// Variables set by main.go to make them readily available.
var (
RuntimeVersion string
RuntimeBuild string
RuntimeBuildDate string
Debug bool // app is in debug mode
)