This is the source code to the main nonshy.com website. It is written in Go and released under the GNU General Public License.
This website is open source and if you'd like to help work on it (fix bugs or contribute new features), you may sign up an account on the code.nonshy.com server. See the CONTRIBUTING.md file for details.
You may need to run the following services along with this app:
The website can also run out of a local SQLite database which is convenient for local development. The production server runs on PostgreSQL and the web app is primarily designed for that.
PostGIS Extension for PostgreSQL
For the "Who's Nearby" feature to work you will need a PostgreSQL
database with the PostGIS geospatial extension installed. Usually
it might be a matter of
dnf install postgis and activating the
extension on your nonshy database as your superuser (postgres):
create extension postgis;
If you get errors like "Type geography not found" from Postgres when running distance based searches, this is the likely culprit.
Building the App
This app is written in Go: go.dev. You can probably get it from your package manager, e.g.
brew install golangwith homebrew: brew.sh
- Linux: it's in your package manager, e.g.
apt install golang
Use the Makefile (with GNU
make or similar):
make setup: install Go dependencies
make build: builds the program to ./nonshy
make run: run the app from Go sources in debug mode
Or read the Makefile to see what the underlying
go commands are,
go run cmd/nonshy/main.go web
On first run it will generate a
settings.json file in the current
working directory (which is intended to be the root of the git clone,
with the ./web folder). Edit it to configure mail settings or choose
For simple local development, just set
"UseSQLite": true and the
app will run with a SQLite database.
nonshy binary has sub-commands to either run the web server
or perform maintenance tasks such as creating admin user accounts.
nonshy --help for its documentation.
nonshy web to start the web server.
nonshy web --host 0.0.0.0 --port 8080 --debug
Create Admin User Accounts
nonshy user add command like so:
$ nonshy user add --admin \ --email firstname.lastname@example.org \ --password secret \ --username admin
-u can work in place of the longer
After the first admin user is created, you may promote other users thru the web app by using the admin controls on their profile page.
A Brief Tour of the Code
cmd/nonshy/main.go: the entry point for the Go program.
pkg/webserver.go: the entry point for the web server.
pkg/config: mostly hard-coded configuration values - all of the page sizes and business logic controls are in here, set at compile time. For ease of local development you may want to toggle SkipEmailValidation in here - the signup form will then directly allow full signup with a user and password.
pkg/controller: the various web endpoint controllers are here, categorized into subpackages (account, forum, inbox, photo, etc.)
pkg/log: the logging to terminal functions.
pkg/mail: functions for delivering HTML email messages.
pkg/markdown: functions to render GitHub Flavored Markdown.
pkg/middleware: HTTP middleware functions, for things such as:
- Session cookies
- Authentication (LoginRequired, AdminRequired)
- CSRF protection
- Logging HTTP requests
- Panic recovery for unhandled server errors
pkg/models: the SQL database models and query functions are here.
pkg/models/deletion: the code to fully scrub wipe data for user deletion (GDPR/CCPA compliance).
pkg/photo: photo management functions: handle uploads, scale and crop, generate URLs and deletion.
pkg/ratelimit: rate limiter for login attempts etc.
pkg/redis: Redis cache functions - get/set JSON values for things like session cookie storage and temporary rate limits.
pkg/router: the HTTP route URLs for the controllers are here.
pkg/session: functions to read/write the user's session cookie (log in/out, get current user, flash messages)
pkg/templates: functions to handle HTTP responses - render HTML templates, issue redirects, error pages, ...
pkg/utility: miscellaneous useful functions for the app.
Cron API Endpoints
In settings.json get or configure the CronAPIKey (a UUID4 value is good and the app generates a fresh one by default). The following are the cron API endpoints that you may want to configure to run periodic maintenance tasks on the app, such as to remove orphaned comment photos.
apiKey which is the CronAPIKey.
This endpoint removes orphaned CommentPhotos (photo attachments to forum posts). An orphaned photo is one that has no CommentID and was uploaded older than 24 hours ago; e.g. a user uploaded a picture but then did not complete the posting of their comment.
0 2 * * * curl "http://localhost:8080/v1/comment-photos/remove-orphaned?apiKey=X"