From fa9d6444f5318c040b803c1a0fd785f6f99e15dc Mon Sep 17 00:00:00 2001
From: Philipp Heckel <pheckel@datto.com>
Date: Sat, 18 Dec 2021 22:02:36 -0500
Subject: [PATCH] Move config files and folders

---
 .goreleaser.yml                        | 18 +++++++++++++-----
 Makefile                               |  2 +-
 client/client.go                       |  3 ++-
 {config => client}/ntfy-client.service |  0
 cmd/serve.go                           | 23 +++++++++++------------
 cmd/subscribe.go                       | 14 ++++++++------
 docs/config.md                         | 12 ++++++------
 docs/faq.md                            |  2 +-
 docs/install.md                        |  6 +++---
 scripts/postinst.sh                    |  2 +-
 scripts/postrm.sh                      |  2 +-
 scripts/preinst.sh                     | 11 +++++++++++
 {config => server}/config.go           |  5 ++---
 {config => server}/config_test.go      |  6 +++---
 {config => server}/ntfy.service        |  0
 server/server.go                       |  9 ++++-----
 config/config.yml => server/server.yml |  2 +-
 server/visitor.go                      |  5 ++---
 18 files changed, 70 insertions(+), 52 deletions(-)
 rename {config => client}/ntfy-client.service (100%)
 create mode 100755 scripts/preinst.sh
 rename {config => server}/config.go (96%)
 rename {config => server}/config_test.go (64%)
 rename {config => server}/ntfy.service (100%)
 rename config/config.yml => server/server.yml (98%)

diff --git a/.goreleaser.yml b/.goreleaser.yml
index 7148ef6..d0cc958 100644
--- a/.goreleaser.yml
+++ b/.goreleaser.yml
@@ -47,14 +47,20 @@ nfpms:
       - rpm
     bindir: /usr/bin
     contents:
-      - src: config/config.yml
-        dst: /etc/ntfy/config.yml
+      - src: server/server.yml
+        dst: /etc/ntfy/server.yml
         type: config
-      - src: config/ntfy.service
+      - src: server/ntfy.service
         dst: /lib/systemd/system/ntfy.service
+      - src: client/client.yml
+        dst: /etc/ntfy/client.yml
+        type: config
+      - src: client/ntfy-client.service
+        dst: /lib/systemd/system/ntfy-client.service
       - dst: /var/cache/ntfy
         type: dir
     scripts:
+      preinstall: "scripts/preinst.sh"
       postinstall: "scripts/postinst.sh"
       preremove: "scripts/prerm.sh"
       postremove: "scripts/postrm.sh"
@@ -64,8 +70,10 @@ archives:
     files:
       - LICENSE
       - README.md
-      - config/config.yml
-      - config/ntfy.service
+      - server/server.yml
+      - server/ntfy.service
+      - client/client.yml
+      - client/ntfy-client.service
     replacements:
       386: i386
       amd64: x86_64
diff --git a/Makefile b/Makefile
index 006e638..1744dfd 100644
--- a/Makefile
+++ b/Makefile
@@ -115,7 +115,7 @@ build-simple: clean
 		"-linkmode=external -extldflags=-static -s -w -X main.version=$(VERSION) -X main.commit=$(shell git rev-parse --short HEAD) -X main.date=$(shell date +%s)"
 
 clean: .PHONY
-	rm -rf dist build
+	rm -rf dist build server/docs
 
 
 # Releasing targets
diff --git a/client/client.go b/client/client.go
index 31e7c89..3b83f28 100644
--- a/client/client.go
+++ b/client/client.go
@@ -50,7 +50,8 @@ func New(config *Config) *Client {
 	}
 }
 
-func (c *Client) Publish(topicURL, message string, options ...PublishOption) error {
+func (c *Client) Publish(topic, message string, options ...PublishOption) error {
+	topicURL := c.expandTopicURL(topic)
 	req, _ := http.NewRequest("POST", topicURL, strings.NewReader(message))
 	for _, option := range options {
 		if err := option(req); err != nil {
diff --git a/config/ntfy-client.service b/client/ntfy-client.service
similarity index 100%
rename from config/ntfy-client.service
rename to client/ntfy-client.service
diff --git a/cmd/serve.go b/cmd/serve.go
index 2cdc842..ef963eb 100644
--- a/cmd/serve.go
+++ b/cmd/serve.go
@@ -5,7 +5,6 @@ import (
 	"errors"
 	"github.com/urfave/cli/v2"
 	"github.com/urfave/cli/v2/altsrc"
-	"heckel.io/ntfy/config"
 	"heckel.io/ntfy/server"
 	"heckel.io/ntfy/util"
 	"log"
@@ -13,20 +12,20 @@ import (
 )
 
 var flagsServe = []cli.Flag{
-	&cli.StringFlag{Name: "config", Aliases: []string{"c"}, EnvVars: []string{"NTFY_CONFIG_FILE"}, Value: "/etc/ntfy/config.yml", DefaultText: "/etc/ntfy/config.yml", Usage: "config file"},
-	altsrc.NewStringFlag(&cli.StringFlag{Name: "listen-http", Aliases: []string{"l"}, EnvVars: []string{"NTFY_LISTEN_HTTP"}, Value: config.DefaultListenHTTP, Usage: "ip:port used to as HTTP listen address"}),
+	&cli.StringFlag{Name: "config", Aliases: []string{"c"}, EnvVars: []string{"NTFY_CONFIG_FILE"}, Value: "/etc/ntfy/server.yml", DefaultText: "/etc/ntfy/server.yml", Usage: "config file"},
+	altsrc.NewStringFlag(&cli.StringFlag{Name: "listen-http", Aliases: []string{"l"}, EnvVars: []string{"NTFY_LISTEN_HTTP"}, Value: server.DefaultListenHTTP, Usage: "ip:port used to as HTTP listen address"}),
 	altsrc.NewStringFlag(&cli.StringFlag{Name: "listen-https", Aliases: []string{"L"}, EnvVars: []string{"NTFY_LISTEN_HTTPS"}, Usage: "ip:port used to as HTTPS listen address"}),
 	altsrc.NewStringFlag(&cli.StringFlag{Name: "key-file", Aliases: []string{"K"}, EnvVars: []string{"NTFY_KEY_FILE"}, Usage: "private key file, if listen-https is set"}),
 	altsrc.NewStringFlag(&cli.StringFlag{Name: "cert-file", Aliases: []string{"E"}, EnvVars: []string{"NTFY_CERT_FILE"}, Usage: "certificate file, if listen-https is set"}),
 	altsrc.NewStringFlag(&cli.StringFlag{Name: "firebase-key-file", Aliases: []string{"F"}, EnvVars: []string{"NTFY_FIREBASE_KEY_FILE"}, Usage: "Firebase credentials file; if set additionally publish to FCM topic"}),
 	altsrc.NewStringFlag(&cli.StringFlag{Name: "cache-file", Aliases: []string{"C"}, EnvVars: []string{"NTFY_CACHE_FILE"}, Usage: "cache file used for message caching"}),
-	altsrc.NewDurationFlag(&cli.DurationFlag{Name: "cache-duration", Aliases: []string{"b"}, EnvVars: []string{"NTFY_CACHE_DURATION"}, Value: config.DefaultCacheDuration, Usage: "buffer messages for this time to allow `since` requests"}),
-	altsrc.NewDurationFlag(&cli.DurationFlag{Name: "keepalive-interval", Aliases: []string{"k"}, EnvVars: []string{"NTFY_KEEPALIVE_INTERVAL"}, Value: config.DefaultKeepaliveInterval, Usage: "interval of keepalive messages"}),
-	altsrc.NewDurationFlag(&cli.DurationFlag{Name: "manager-interval", Aliases: []string{"m"}, EnvVars: []string{"NTFY_MANAGER_INTERVAL"}, Value: config.DefaultManagerInterval, Usage: "interval of for message pruning and stats printing"}),
-	altsrc.NewIntFlag(&cli.IntFlag{Name: "global-topic-limit", Aliases: []string{"T"}, EnvVars: []string{"NTFY_GLOBAL_TOPIC_LIMIT"}, Value: config.DefaultGlobalTopicLimit, Usage: "total number of topics allowed"}),
-	altsrc.NewIntFlag(&cli.IntFlag{Name: "visitor-subscription-limit", Aliases: []string{"V"}, EnvVars: []string{"NTFY_VISITOR_SUBSCRIPTION_LIMIT"}, Value: config.DefaultVisitorSubscriptionLimit, Usage: "number of subscriptions per visitor"}),
-	altsrc.NewIntFlag(&cli.IntFlag{Name: "visitor-request-limit-burst", Aliases: []string{"B"}, EnvVars: []string{"NTFY_VISITOR_REQUEST_LIMIT_BURST"}, Value: config.DefaultVisitorRequestLimitBurst, Usage: "initial limit of requests per visitor"}),
-	altsrc.NewDurationFlag(&cli.DurationFlag{Name: "visitor-request-limit-replenish", Aliases: []string{"R"}, EnvVars: []string{"NTFY_VISITOR_REQUEST_LIMIT_REPLENISH"}, Value: config.DefaultVisitorRequestLimitReplenish, Usage: "interval at which burst limit is replenished (one per x)"}),
+	altsrc.NewDurationFlag(&cli.DurationFlag{Name: "cache-duration", Aliases: []string{"b"}, EnvVars: []string{"NTFY_CACHE_DURATION"}, Value: server.DefaultCacheDuration, Usage: "buffer messages for this time to allow `since` requests"}),
+	altsrc.NewDurationFlag(&cli.DurationFlag{Name: "keepalive-interval", Aliases: []string{"k"}, EnvVars: []string{"NTFY_KEEPALIVE_INTERVAL"}, Value: server.DefaultKeepaliveInterval, Usage: "interval of keepalive messages"}),
+	altsrc.NewDurationFlag(&cli.DurationFlag{Name: "manager-interval", Aliases: []string{"m"}, EnvVars: []string{"NTFY_MANAGER_INTERVAL"}, Value: server.DefaultManagerInterval, Usage: "interval of for message pruning and stats printing"}),
+	altsrc.NewIntFlag(&cli.IntFlag{Name: "global-topic-limit", Aliases: []string{"T"}, EnvVars: []string{"NTFY_GLOBAL_TOPIC_LIMIT"}, Value: server.DefaultGlobalTopicLimit, Usage: "total number of topics allowed"}),
+	altsrc.NewIntFlag(&cli.IntFlag{Name: "visitor-subscription-limit", Aliases: []string{"V"}, EnvVars: []string{"NTFY_VISITOR_SUBSCRIPTION_LIMIT"}, Value: server.DefaultVisitorSubscriptionLimit, Usage: "number of subscriptions per visitor"}),
+	altsrc.NewIntFlag(&cli.IntFlag{Name: "visitor-request-limit-burst", Aliases: []string{"B"}, EnvVars: []string{"NTFY_VISITOR_REQUEST_LIMIT_BURST"}, Value: server.DefaultVisitorRequestLimitBurst, Usage: "initial limit of requests per visitor"}),
+	altsrc.NewDurationFlag(&cli.DurationFlag{Name: "visitor-request-limit-replenish", Aliases: []string{"R"}, EnvVars: []string{"NTFY_VISITOR_REQUEST_LIMIT_REPLENISH"}, Value: server.DefaultVisitorRequestLimitReplenish, Usage: "interval at which burst limit is replenished (one per x)"}),
 	altsrc.NewBoolFlag(&cli.BoolFlag{Name: "behind-proxy", Aliases: []string{"P"}, EnvVars: []string{"NTFY_BEHIND_PROXY"}, Value: false, Usage: "if set, use X-Forwarded-For header to determine visitor IP address (for rate limiting)"}),
 }
 
@@ -39,7 +38,7 @@ var cmdServe = &cli.Command{
 	Before:    initConfigFileInputSource("config", flagsServe),
 	Description: `Run the ntfy server and listen for incoming requests
 
-The command will load the configuration from /etc/ntfy/config.yml. Config options can 
+The command will load the configuration from /etc/ntfy/server.yml. Config options can 
 be overridden using the command line options.
 
 Examples:
@@ -82,7 +81,7 @@ func execServe(c *cli.Context) error {
 	}
 
 	// Run server
-	conf := config.New(listenHTTP)
+	conf := server.NewConfig(listenHTTP)
 	conf.ListenHTTPS = listenHTTPS
 	conf.KeyFile = keyFile
 	conf.CertFile = certFile
diff --git a/cmd/subscribe.go b/cmd/subscribe.go
index bbc36d2..a967dae 100644
--- a/cmd/subscribe.go
+++ b/cmd/subscribe.go
@@ -20,10 +20,14 @@ var cmdSubscribe = &cli.Command{
 	Usage:     "Subscribe to one or more topics on a ntfy server",
 	UsageText: "ntfy subscribe [OPTIONS..] [TOPIC]",
 	Action:    execSubscribe,
+	OnUsageError: func(context *cli.Context, err error, isSubcommand bool) error {
+		println("ee")
+		return nil
+	},
+
 	Flags: []cli.Flag{
-		&cli.StringFlag{Name: "config", Aliases: []string{"c"}, Usage: "config file"},
-		&cli.StringFlag{Name: "exec", Aliases: []string{"e"}, Usage: "execute command for each message event"},
-		&cli.StringFlag{Name: "since", Aliases: []string{"s"}, Usage: "return events since (Unix timestamp, or all)"},
+		&cli.StringFlag{Name: "config", Aliases: []string{"c"}, Usage: "config file `FILE`"},
+		&cli.StringFlag{Name: "since", Aliases: []string{"s"}, Usage: "return events since `SINCE` (Unix timestamp, or all)"},
 		&cli.BoolFlag{Name: "from-config", Aliases: []string{"C"}, Usage: "read subscriptions from config file (service mode)"},
 		&cli.BoolFlag{Name: "poll", Aliases: []string{"p"}, Usage: "return events and exit, do not listen for new events"},
 		&cli.BoolFlag{Name: "scheduled", Aliases: []string{"sched", "S"}, Usage: "also return scheduled/delayed events"},
@@ -72,8 +76,6 @@ ntfy subscribe --from-config
 }
 
 func execSubscribe(c *cli.Context) error {
-	fmt.Fprintln(c.App.ErrWriter, "\x1b[1;33mThis command is incubating. The interface may change without notice.\x1b[0m")
-
 	// Read config and options
 	conf, err := loadConfig(c)
 	if err != nil {
@@ -100,7 +102,7 @@ func execSubscribe(c *cli.Context) error {
 		options = append(options, client.WithScheduled())
 	}
 	if topic == "" && len(conf.Subscribe) == 0 {
-		return errors.New("must specify topic, or have at least one topic defined in config")
+		return errors.New("must specify topic, type 'ntfy subscribe --help' for help")
 	}
 
 	// Execute poll or subscribe
diff --git a/docs/config.md b/docs/config.md
index 4f83e96..3917825 100644
--- a/docs/config.md
+++ b/docs/config.md
@@ -1,6 +1,6 @@
 # Configuring the ntfy server
-The ntfy server can be configured in three ways: using a config file (typically at `/etc/ntfy/config.yml`, 
-see [config.yml](https://github.com/binwiederhier/ntfy/blob/main/config/config.yml)), via command line arguments 
+The ntfy server can be configured in three ways: using a config file (typically at `/etc/ntfy/server.yml`, 
+see [server.yml](https://github.com/binwiederhier/ntfy/blob/main/config/server.yml)), via command line arguments 
 or using environment variables.
 
 ## Quick start
@@ -50,7 +50,7 @@ flag. This will instruct the [rate limiting](#rate-limiting) logic to use the `X
 identifier for a visitor, as opposed to the remote IP address. If the `behind-proxy` flag is not set, all visitors will
 be counted as one, because from the perspective of the ntfy server, they all share the proxy's IP address.
 
-=== "/etc/ntfy/config.yml"
+=== "/etc/ntfy/server.yml"
     ```
     # Tell ntfy to use "X-Forwarded-For" to identify visitors
     behind-proxy: true
@@ -200,7 +200,7 @@ To configure FCM for your self-hosted instance of the ntfy server, follow these
 
 1. Sign up for a [Firebase account](https://console.firebase.google.com/)
 2. Create a Firebase app and download the key file (e.g. `myapp-firebase-adminsdk-...json`)
-3. Place the key file in `/etc/ntfy`, set the `firebase-key-file` in `config.yml` accordingly and restart the ntfy server
+3. Place the key file in `/etc/ntfy`, set the `firebase-key-file` in `server.yml` accordingly and restart the ntfy server
 4. Build your own Android .apk following [these instructions](develop.md#android-app)
 
 Example:
@@ -294,7 +294,7 @@ to maintain the client connection and the connection to ntfy.
     ```
 
 ## Config options
-Each config option can be set in the config file `/etc/ntfy/config.yml` (e.g. `listen-http: :80`) or as a
+Each config option can be set in the config file `/etc/ntfy/server.yml` (e.g. `listen-http: :80`) or as a
 CLI option (e.g. `--listen-http :80`. Here's a list of all available options. Alternatively, you can set an environment
 variable before running the `ntfy` command (e.g. `export NTFY_LISTEN_HTTP=:80`).
 
@@ -327,7 +327,7 @@ USAGE:
    ntfy [OPTION..]
 
 GLOBAL OPTIONS:
-   --config value, -c value                           config file (default: /etc/ntfy/config.yml) [$NTFY_CONFIG_FILE]
+   --config value, -c value                           config file (default: /etc/ntfy/server.yml) [$NTFY_CONFIG_FILE]
    --listen-http value, -l value                      ip:port used to as listen address (default: ":80") [$NTFY_LISTEN_HTTP]
    --firebase-key-file value, -F value                Firebase credentials file; if set additionally publish to FCM topic [$NTFY_FIREBASE_KEY_FILE]
    --cache-file value, -C value                       cache file used for message caching [$NTFY_CACHE_FILE]
diff --git a/docs/faq.md b/docs/faq.md
index 351ad5e..5105cc8 100644
--- a/docs/faq.md
+++ b/docs/faq.md
@@ -17,7 +17,7 @@ subscribed to a topic.
 ## Will you know what topics exist, can you spy on me?
 If you don't trust me or your messages are sensitive, run your own server. It's <a href="https://github.com/binwiederhier/ntfy">open source</a>.
 That said, the logs do not contain any topic names or other details about you.
-Messages are cached for the duration configured in `config.yml` (12h by default) to facilitate service restarts, message polling and to overcome
+Messages are cached for the duration configured in `server.yml` (12h by default) to facilitate service restarts, message polling and to overcome
 client network disruptions.
 
 ## Can I self-host it?
diff --git a/docs/install.md b/docs/install.md
index 4f3eea1..379f855 100644
--- a/docs/install.md
+++ b/docs/install.md
@@ -13,7 +13,7 @@ The ntfy server comes as a statically linked binary and is shipped as tarball, d
 We support amd64, armv7 and arm64.
 
 1. Install ntfy using one of the methods described below
-2. Then (optionally) edit `/etc/ntfy/config.yml` (see [configuration](config.md))
+2. Then (optionally) edit `/etc/ntfy/server.yml` (see [configuration](config.md))
 
 To run the ntfy server, then just run `ntfy serve` (or `systemctl start ntfy` when using the deb/rpm).
 To send messages, use `ntfy publish`. To subscribe to topics, use `ntfy subscribe` (see [subscribing via CLI][subscribe/cli.md]
@@ -138,7 +138,7 @@ straight forward to use.
 
 The server exposes its web UI and the API on port 80, so you need to expose that in Docker. To use the persistent 
 [message cache](config.md#message-cache), you also need to map a volume to `/var/cache/ntfy`. To change other settings, 
-you should map `/etc/ntfy`, so you can edit `/etc/ntfy/config.yml`.
+you should map `/etc/ntfy`, so you can edit `/etc/ntfy/server.yml`.
 
 Basic usage (no cache or additional config):
 ```
@@ -156,7 +156,7 @@ docker run \
     serve
 ```
 
-With other config options (configured via `/etc/ntfy/config.yml`, see [configuration](config.md) for details):
+With other config options (configured via `/etc/ntfy/server.yml`, see [configuration](config.md) for details):
 ```bash
 docker run \
   -v /etc/ntfy:/etc/ntfy \
diff --git a/scripts/postinst.sh b/scripts/postinst.sh
index 843805c..dabc0a1 100755
--- a/scripts/postinst.sh
+++ b/scripts/postinst.sh
@@ -13,7 +13,7 @@ if [ "$1" = "configure" ] && [ -d /run/systemd/system ]; then
   chmod 700 /var/cache/ntfy
 
   # Hack to change permissions on cache file
-  configfile="/etc/ntfy/config.yml"
+  configfile="/etc/ntfy/server.yml"
   if [ -f "$configfile" ]; then
     cachefile="$(cat "$configfile" | perl -n -e'/^\s*cache-file: ["'"'"']?([^"'"'"']+)["'"'"']?/ && print $1')" # Oh my, see #47
     if [ -n "$cachefile" ]; then
diff --git a/scripts/postrm.sh b/scripts/postrm.sh
index 78db62e..696e8a1 100755
--- a/scripts/postrm.sh
+++ b/scripts/postrm.sh
@@ -4,7 +4,7 @@ set -e
 # Delete the config if package is purged
 if [ "$1" = "purge" ]; then
   id ntfy >/dev/null 2>&1 && userdel ntfy
-  rm -f /etc/ntfy/config.yml
+  rm -f /etc/ntfy/server.yml
   rmdir /etc/ntfy || true
 fi
 
diff --git a/scripts/preinst.sh b/scripts/preinst.sh
new file mode 100755
index 0000000..d09528c
--- /dev/null
+++ b/scripts/preinst.sh
@@ -0,0 +1,11 @@
+#!/bin/sh
+set -e
+
+if [ "$1" = "install" ] || [ "$1" = "upgrade" ]; then
+  # Migration of old to new config file name
+  oldconfigfile="/etc/ntfy/config.yml"
+  configfile="/etc/ntfy/server.yml"
+  if [ -f "$oldconfigfile" ] && [ ! -f "$configfile" ]; then
+    mv "$oldconfigfile" "$configfile" || true
+  fi
+fi
diff --git a/config/config.go b/server/config.go
similarity index 96%
rename from config/config.go
rename to server/config.go
index a78ec5a..fac1658 100644
--- a/config/config.go
+++ b/server/config.go
@@ -1,5 +1,4 @@
-// Package config provides the main configuration
-package config
+package server
 
 import (
 	"time"
@@ -53,7 +52,7 @@ type Config struct {
 }
 
 // New instantiates a default new config
-func New(listenHTTP string) *Config {
+func NewConfig(listenHTTP string) *Config {
 	return &Config{
 		ListenHTTP:                   listenHTTP,
 		ListenHTTPS:                  "",
diff --git a/config/config_test.go b/server/config_test.go
similarity index 64%
rename from config/config_test.go
rename to server/config_test.go
index d728251..902549d 100644
--- a/config/config_test.go
+++ b/server/config_test.go
@@ -1,12 +1,12 @@
-package config_test
+package server_test
 
 import (
 	"github.com/stretchr/testify/assert"
-	"heckel.io/ntfy/config"
+	"heckel.io/ntfy/server"
 	"testing"
 )
 
 func TestConfig_New(t *testing.T) {
-	c := config.New(":1234")
+	c := server.NewConfig(":1234")
 	assert.Equal(t, ":1234", c.ListenHTTP)
 }
diff --git a/config/ntfy.service b/server/ntfy.service
similarity index 100%
rename from config/ntfy.service
rename to server/ntfy.service
diff --git a/server/server.go b/server/server.go
index 3034209..d4b9f93 100644
--- a/server/server.go
+++ b/server/server.go
@@ -9,7 +9,6 @@ import (
 	"firebase.google.com/go/messaging"
 	"fmt"
 	"google.golang.org/api/option"
-	"heckel.io/ntfy/config"
 	"heckel.io/ntfy/util"
 	"html/template"
 	"io"
@@ -28,7 +27,7 @@ import (
 
 // Server is the main server, providing the UI and API for ntfy
 type Server struct {
-	config   *config.Config
+	config   *Config
 	topics   map[string]*topic
 	visitors map[string]*visitor
 	firebase subscriber
@@ -112,7 +111,7 @@ const (
 
 // New instantiates a new Server. It creates the cache and adds a Firebase
 // subscriber (if configured).
-func New(conf *config.Config) (*Server, error) {
+func New(conf *Config) (*Server, error) {
 	var firebaseSubscriber subscriber
 	if conf.FirebaseKeyFile != "" {
 		var err error
@@ -138,7 +137,7 @@ func New(conf *config.Config) (*Server, error) {
 	}, nil
 }
 
-func createCache(conf *config.Config) (cache, error) {
+func createCache(conf *Config) (cache, error) {
 	if conf.CacheDuration == 0 {
 		return newNopCache(), nil
 	} else if conf.CacheFile != "" {
@@ -147,7 +146,7 @@ func createCache(conf *config.Config) (cache, error) {
 	return newMemCache(), nil
 }
 
-func createFirebaseSubscriber(conf *config.Config) (subscriber, error) {
+func createFirebaseSubscriber(conf *Config) (subscriber, error) {
 	fb, err := firebase.NewApp(context.Background(), nil, option.WithCredentialsFile(conf.FirebaseKeyFile))
 	if err != nil {
 		return nil, err
diff --git a/config/config.yml b/server/server.yml
similarity index 98%
rename from config/config.yml
rename to server/server.yml
index 0829778..1ecc5de 100644
--- a/config/config.yml
+++ b/server/server.yml
@@ -1,4 +1,4 @@
-# ntfy config file
+# ntfy server config file
 
 # Listen address for the HTTP & HTTPS web server. If "listen-https" is set, you must also
 # set "key-file" and "cert-file".
diff --git a/server/visitor.go b/server/visitor.go
index 7c23f89..9d99e94 100644
--- a/server/visitor.go
+++ b/server/visitor.go
@@ -2,7 +2,6 @@ package server
 
 import (
 	"golang.org/x/time/rate"
-	"heckel.io/ntfy/config"
 	"heckel.io/ntfy/util"
 	"sync"
 	"time"
@@ -14,14 +13,14 @@ const (
 
 // visitor represents an API user, and its associated rate.Limiter used for rate limiting
 type visitor struct {
-	config        *config.Config
+	config        *Config
 	limiter       *rate.Limiter
 	subscriptions *util.Limiter
 	seen          time.Time
 	mu            sync.Mutex
 }
 
-func newVisitor(conf *config.Config) *visitor {
+func newVisitor(conf *Config) *visitor {
 	return &visitor{
 		config:        conf,
 		limiter:       rate.NewLimiter(rate.Every(conf.VisitorRequestLimitReplenish), conf.VisitorRequestLimitBurst),
-- 
GitLab