Add support for .env configuration and privacy page (closes #44)

This commit is contained in:
video-prize-ranch 2022-08-04 19:41:55 -04:00
parent 4da9b74949
commit d50cf2da86
No known key found for this signature in database
GPG Key ID: D8EAA4C5B12A7281
11 changed files with 306 additions and 13 deletions

35
.env.example Normal file
View File

@ -0,0 +1,35 @@
ADDRESS=0.0.0.0
PORT=3000
FIBER_PREFORK=false
IMGUR_CLIENT_ID=546c25a59c58ad7
# Instance privacy
# For more information, see https://codeberg.org/librarian/librarian/wiki/Instance-privacy
# Required to be on the instance list.
# Link to a privacy policy (optional)
PRIVACY_POLICY=
# Explain how this data is used/why it is collected (optional)
PRIVACY_MESSAGE=
# Country where instance is located. Leave blank if running on Tor without clearnet.
PRIVACY_COUNTRY=
# Hosting provider or ISP name. Leave blank if running on Tor without clearnet.
PRIVACY_PROVIDER=
# Set to true if you use Cloudflare (using Cloudflare only as DNS (gray cloud icon), set to false)
PRIVACY_CLOUDFLARE=false
# These settings are for NGINX without data collection disabled.
# Instructions for other reverse proxies and to disable data collection:
# https://codeberg.org/librarian/librarian/wiki/Instance-privacy
# Set to true if no data is collected. (overrides all other options)
PRIVACY_NOT_COLLECTED=false
# IP address
PRIVACY_IP=true
# Request URL
PRIVACY_URL=true
# Device Type (User agent)
PRIVACY_DEVICE=true
# If the data collection is only collected when there is an error and only stored for
# a short amount of time while diagnosing an issue.
PRIVACY_DIAGNOSTICS=false

1
.gitignore vendored
View File

@ -1,2 +1,3 @@
dist dist
node_modules node_modules
.env

View File

@ -3,11 +3,11 @@ FROM --platform=$BUILDPLATFORM golang:alpine AS build
ARG TARGETARCH ARG TARGETARCH
WORKDIR /src WORKDIR /src
RUN apk --no-cache add ca-certificates RUN apk --no-cache add ca-certificates git
COPY . . COPY . .
RUN go mod download RUN go mod download
RUN GOOS=linux GOARCH=$TARGETARCH CGO_ENABLED=0 go build RUN GOOS=linux GOARCH=$TARGETARCH CGO_ENABLED=0 go build -ldflags "-X codeberg.org/video-prize-ranch/rimgo/pages.VersionInfo=$(date '+%Y-%m-%d')-$(git rev-list --abbrev-commit -1 HEAD)"
FROM scratch as bin FROM scratch as bin

View File

@ -111,18 +111,39 @@ You can now run rimgo.
./rimgo ./rimgo
``` ```
To include version information use:
```
go build -ldflags "-X codeberg.org/librarian/librarian/pages.VersionInfo=$(date '+%Y-%m-%d')-$(git rev-list --abbrev-commit -1 HEAD)"
```
(optional) You can use a .env file to set environment variables for configuration.
```
cp .env.example .env
nvim .env
```
## Configuration ## Configuration
rimgo can be configured using environment variables. rimgo can be configured using environment variables. The path to the .env file can be changed the -c flag.
### Environment variables ### Environment variables
| Name | Default | | Name | Default |
|-----------------|-----------------| |-----------------------|-----------------|
| PORT | 3000 | | PORT | 3000 |
| ADDRESS | 0.0.0.0 | | ADDRESS | 0.0.0.0 |
| IMGUR_CLIENT_ID | 546c25a59c58ad7 | | IMGUR_CLIENT_ID | 546c25a59c58ad7 |
| FORCE_WEBP | 0 | | FORCE_WEBP | 0 |
| PRIVACY_POLICY | |
| PRIVACY_MESSAGE | |
| PRIVACY_COUNTRY | |
| PRIVACY_PROVIDER | |
| PRIVACY_CLOUDFLARE | |
| PRIVACY_NOT_COLLECTED | |
| PRIVACY_IP | |
| PRIVACY_URL | |
| PRIVACY_DEVICE | |
| PRIVACY_DIAGNOSTICS | |
## Contributing ## Contributing

1
go.mod
View File

@ -6,6 +6,7 @@ require (
github.com/dustin/go-humanize v1.0.0 github.com/dustin/go-humanize v1.0.0
github.com/gofiber/fiber/v2 v2.32.0 github.com/gofiber/fiber/v2 v2.32.0
github.com/gofiber/template v1.6.27 github.com/gofiber/template v1.6.27
github.com/joho/godotenv v1.4.0
github.com/patrickmn/go-cache v2.1.0+incompatible github.com/patrickmn/go-cache v2.1.0+incompatible
github.com/tidwall/gjson v1.14.1 github.com/tidwall/gjson v1.14.1
) )

2
go.sum
View File

@ -241,6 +241,8 @@ github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/joho/godotenv v1.4.0 h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg=
github.com/joho/godotenv v1.4.0/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=

View File

@ -1,6 +1,7 @@
package main package main
import ( import (
"flag"
"fmt" "fmt"
"net/http" "net/http"
@ -12,9 +13,15 @@ import (
"github.com/gofiber/fiber/v2/middleware/filesystem" "github.com/gofiber/fiber/v2/middleware/filesystem"
"github.com/gofiber/fiber/v2/middleware/recover" "github.com/gofiber/fiber/v2/middleware/recover"
"github.com/gofiber/template/handlebars" "github.com/gofiber/template/handlebars"
"github.com/joho/godotenv"
) )
func main() { func main() {
envPath := flag.String("c", ".env", "Path to env file")
err := godotenv.Load(*envPath)
if err != nil {
fmt.Println(err)
}
utils.LoadConfig() utils.LoadConfig()
engine := handlebars.NewFileSystem(http.FS(views.GetFiles()), ".hbs") engine := handlebars.NewFileSystem(http.FS(views.GetFiles()), ".hbs")
@ -51,6 +58,7 @@ func main() {
}) })
app.Get("/", pages.HandleFrontpage) app.Get("/", pages.HandleFrontpage)
app.Get("/privacy", pages.HandlePrivacy)
app.Get("/:postID.gifv", pages.HandleGifv) app.Get("/:postID.gifv", pages.HandleGifv)
app.Get("/:baseName.:extension", pages.HandleMedia) app.Get("/:baseName.:extension", pages.HandleMedia)
app.Get("/:postID", pages.HandlePost) app.Get("/:postID", pages.HandlePost)

19
pages/privacy.go Normal file
View File

@ -0,0 +1,19 @@
package pages
import (
"github.com/gofiber/fiber/v2"
"codeberg.org/video-prize-ranch/rimgo/utils"
)
var VersionInfo string
func HandlePrivacy(c *fiber.Ctx) error {
utils.SetHeaders(c)
c.Set("X-Frame-Options", "DENY")
return c.Render("privacy", fiber.Map{
"config": utils.Config,
"version": VersionInfo,
})
}

58
static/css/privacy.css Normal file
View File

@ -0,0 +1,58 @@
main {
margin: 0 24vw
}
p {
margin: 1em 0
}
ul {
list-style: outside none none;
padding: 0;
margin: 0.25em;
text-align: left;
}
.largeIcon {
font-size: 36px;
color: #2b95f2;
}
.badgeWrapper {
margin: 0 10vw
}
.badge {
background-color: #3b3b3b;
border-radius: 8px;
display: flex;
flex-direction: column;
align-items: center;
gap: 0.25em;
padding: 1em;
text-align: center;
}
.badge h3,
.badge p,
.largeIcon {
margin: 0;
}
.privacyDetails summary {
cursor: pointer;
user-select: none;
color: #2b95f2;
font-weight: 700;
}
.addInfo {
margin-top: 1em;
}
@media only screen and (max-width: 812px) {
.badgeWrapper,
main {
margin: 0
}
}

View File

@ -39,5 +39,18 @@ func LoadConfig() {
"addr": addr, "addr": addr,
"imgurId": imgurId, "imgurId": imgurId,
"fiberPrefork": fiberPrefork, "fiberPrefork": fiberPrefork,
"privacy": map[string]interface{}{
"set": os.Getenv("PRIVACY_NOT_COLLECTED") != "",
"policy": os.Getenv("PRIVACY_POLICY"),
"message": os.Getenv("PRIVACY_MESSAGE"),
"country": os.Getenv("PRIVACY_COUNTRY"),
"provider": os.Getenv("PRIVACY_PROVIDER"),
"cloudflare": os.Getenv("PRIVACY_CLOUDFLARE") == "true",
"not_collected": os.Getenv("PRIVACY_NOT_COLLECTED") == "true",
"ip": os.Getenv("PRIVACY_IP") == "true",
"url": os.Getenv("PRIVACY_URL") == "true",
"device": os.Getenv("PRIVACY_DEVICE") == "true",
"diagnostics": os.Getenv("PRIVACY_DIAGNOSTICS") == "true",
},
} }
} }

135
views/privacy.hbs Normal file
View File

@ -0,0 +1,135 @@
<!DOCTYPE html>
<html lang="en">
<head>
{{> 'partials/head' }}
<link rel="stylesheet" href="/static/css/privacy.css">
<title>Instance privacy - rimgo</title>
</head>
<body>
{{> 'partials/header' }}
<main>
<h1>Instance Privacy</h1>
{{#if config.privacy.policy}}
<p>The instance operator has indicated their instance's privacy practices below. For more information, see the
instance operator's <a href="{{config.privacy.policy}}">privacy policy</a>.</p>
{{else}}
<p>The instance operator has indicated their instance's privacy practices below.</p>
{{/if}}
{{#if config.privacy.message}}
<p>{{{config.privacy.message}}}</p>
{{/if}}
{{#if config.privacy.not_collected}}
<div class="badgeWrapper">
<div class="badge">
<span class="material-icons-outlined largeIcon">
check_circle
</span>
<h3>Data Not Collected</h3>
<p>The instance operator does not collect any data from this instance.</p>
</div>
</div>
{{/if}}
{{#unless config.privacy.set}}
<div class="badgeWrapper">
<div class="badge">
<span class="material-icons-outlined largeIcon">
report_problem
</span>
<h3>No Details Provided</h3>
<p>The operator of this instance will be required to provide privacy details to be added to the instance list.
</p>
</div>
</div>
{{else}}
{{#unless config.privacy.not_collected}}
<div class="badgeWrapper">
<div class="badge">
<span class="material-icons-outlined largeIcon">
error_outline
</span>
<h3>Data Collected</h3>
<p>The following data may be collected:</p>
<ul>
{{#if config.privacy.ip}}
<li>
<span class="material-icons-outlined">password</span>
Internet address (IP Address)
</li>
{{/if}}
{{#if config.privacy.url}}
<li>
<span class="material-icons-outlined">link</span>
Page viewed (Request URL)
</li>
{{/if}}
{{#if config.privacy.device}}
<li>
<span class="material-icons-outlined">phonelink</span>
Device Type (User agent)
</li>
{{/if}}
{{#if config.privacy.diagnostics}}
<li>
<span class="material-icons-outlined">settings</span>
Diagnostics
</li>
{{/if}}
</ul>
</div>
</div>
{{/unless}}
{{/unless}}
<details class="privacyDetails">
<summary>What's this?</summary>
<p>
Instance privacy aims to bring transparency to the data collected by frontends and encourage privacy friendly practices. There is often no privacy policy and users are forced to trust that the instance operator is not collecting data. However, there is a possibility that the instance operator can put false information so we encourage looking at other factors when selecting an instance.
</p>
<ul>
<li>
<span class="material-icons-outlined">password</span>
Internet address (IP Address) - This is an address that is given to your computer or internet connection.
This can be used to find your city or region and internet provider but can change depending on your connection.
</li>
<li>
<span class="material-icons-outlined">link</span>
Page viewed (Request URL) - This is what page you are viewing. Searches are kept private.
</li>
<li>
<span class="material-icons-outlined">phonelink</span>
Device Type (User agent) - This is what browser, device, and operating system you are using.
Advanced users can change this with an extension or browser setting.
</li>
<li>
<span class="material-icons-outlined">settings</span>
Diagnostics - When this data is only collected when there is an error or only a short amount of time while
diagnosing an issue.
</li>
</ul>
</details>
<h2 class="addInfo">Additional information</h2>
<ul>
<li>Version: {{version}}</li>
<li>Country: {{config.privacy.country}}</li>
<li>Provider: {{config.privacy.provider}}</li>
{{#if config.privacy.cloudflare}}
<li>Using Cloudflare?: Yes</li>
{{else}}
<li>Using Cloudflare?: No</li>
{{/if}}
</ul>
</main>
{{> 'partials/footer' }}
</body>
</html>