README.md

  1<!--
  2SPDX-FileCopyrightText: 2022 Amolith <amolith@secluded.site>
  3
  4SPDX-License-Identifier: CC0-1.0
  5-->
  6
  7# earl
  8
  9[![REUSE status][reuse-shield]][reuse]
 10[![Donate with fosspay][fosspay-shield]][fosspay]
 11![Time spent on project][wakapi-shield]
 12
 13Personal shortlink generator
 14
 15## Features
 16
 17Links are …
 18
 19- Editable
 20- Removable
 21- Four characters long (26 uppercase letters + 26 lowercase letters + 10 numbers
 22  = 14,776,336 possible shortened URLs)
 23
 24Service has …
 25
 26- A simple API
 27- A simple web UI
 28- A simple backup procedure (database is a single directory)
 29- No user management (this is a _personal_ service after all)
 30
 31## Installation
 32
 33- Download the binary appropriate for your system or build from source with `go build .`
 34  <details>
 35    <summary>List of latest binaries</summary>
 36    <ul>
 37      <li><a href="https://earl.run/earl-darwin-amd64">earl-darwin-amd64</a></li>
 38      <li><a href="https://earl.run/earl-darwin-arm64">earl-darwin-arm64</a></li>
 39      <li><a href="https://earl.run/earl-dragonfly-amd64">earl-dragonfly-amd64</a></li>
 40      <li><a href="https://earl.run/earl-freebsd-amd64">earl-freebsd-amd64</a></li>
 41      <li><a href="https://earl.run/earl-freebsd-arm">earl-freebsd-arm</a></li>
 42      <li><a href="https://earl.run/earl-freebsd-i386">earl-freebsd-i386</a></li>
 43      <li><a href="https://earl.run/earl-illumos-amd64">earl-illumos-amd64</a></li>
 44      <li><a href="https://earl.run/earl-linux-amd64">earl-linux-amd64</a></li>
 45      <li><a href="https://earl.run/earl-linux-arm">earl-linux-arm</a></li>
 46      <li><a href="https://earl.run/earl-linux-arm64">earl-linux-arm64</a></li>
 47      <li><a href="https://earl.run/earl-linux-i386">earl-linux-i386</a></li>
 48      <li><a href="https://earl.run/earl-linux-mips">earl-linux-mips</a></li>
 49      <li><a href="https://earl.run/earl-linux-mips64">earl-linux-mips64</a></li>
 50      <li><a href="https://earl.run/earl-linux-mips64le">earl-linux-mips64le</a></li>
 51      <li><a href="https://earl.run/earl-linux-mipsle">earl-linux-mipsle</a></li>
 52      <li><a href="https://earl.run/earl-linux-ppc64">earl-linux-ppc64</a></li>
 53      <li><a href="https://earl.run/earl-linux-ppc64le">earl-linux-ppc64le</a></li>
 54      <li><a href="https://earl.run/earl-linux-riscv64">earl-linux-riscv64</a></li>
 55      <li><a href="https://earl.run/earl-linux-s390x">earl-linux-s390x</a></li>
 56      <li><a href="https://earl.run/earl-netbsd-amd64">earl-netbsd-amd64</a></li>
 57      <li><a href="https://earl.run/earl-netbsd-arm">earl-netbsd-arm</a></li>
 58      <li><a href="https://earl.run/earl-netbsd-i386">earl-netbsd-i386</a></li>
 59      <li><a href="https://earl.run/earl-openbsd-amd64">earl-openbsd-amd64</a></li>
 60      <li><a href="https://earl.run/earl-openbsd-arm">earl-openbsd-arm</a></li>
 61      <li><a href="https://earl.run/earl-openbsd-arm64">earl-openbsd-arm64</a></li>
 62      <li><a href="https://earl.run/earl-openbsd-i386">earl-openbsd-i386</a></li>
 63      <li><a href="https://earl.run/earl-plan9-amd64">earl-plan9-amd64</a></li>
 64      <li><a href="https://earl.run/earl-plan9-arm">earl-plan9-arm</a></li>
 65      <li><a href="https://earl.run/earl-plan9-i386">earl-plan9-i386</a></li>
 66      <li><a href="https://earl.run/earl-solaris-amd64">earl-solaris-amd64</a></li>
 67      <li><a href="https://earl.run/earl-windows-amd64.exe">earl-windows-amd64.exe</a></li>
 68      <li><a href="https://earl.run/earl-windows-arm64.exe">earl-windows-arm64.exe</a></li>
 69      <li><a href="https://earl.run/earl-windows-arm.exe">earl-windows-arm.exe</a></li>
 70      <li><a href="https://earl.run/earl-windows-i386.exe">earl-windows-i386.exe</a></li>
 71    </ul>
 72  </details>
 73- On Unix-based OSes (which includes macOS), mark the binary as executable with
 74  `chmod u+x path/to/binary`
 75  - I don't _think_ this is necessary with Windows.
 76- On Unix-based OSes, execute the binary with `./path/to/binary`
 77  - No clue how to execute the Windows binaries. Feel free to [send a
 78    patch](#questions-amp-contributions) with this information!
 79- Edit `./config.yaml` and modify `accessToken` to something secure; earl won't
 80  start until the access token is changed.
 81- Re-execute the binary and earl should be accessible on
 82  [localhost:1313](http://localhost:1313)!
 83- To make it accessible over the internet on a short domain, you'll need said
 84  short domain, a server, a reverse proxy, and a TLS certificate. How to
 85  obtain/configure those components is out-of-scope though.
 86  - Contributions adding a Caddyfile, an NGINX vhost, systemd/OpenRC/runit/etc.
 87    units are welcome.
 88
 89## API documentation
 90
 91### `/create`
 92
 93#### Required parameters
 94
 95- `url`: percent-encoded URL being shortened
 96
 97#### Optional parameters
 98
 99- `name`: percent-encoded short link the `url` will be mapped to. If this is not
100  provided, a random, 4-character code will be generated instead.
101
102#### Output
103
104- `401 Unauthorized: You do not have permission to create shortlinks` if access
105  token provided in `Authorization` header does not match the configured access
106  token
107- `400 Bad Request: URL parameter is required`
108- `406 Not Acceptable: A shortened URL with this name already exists` if
109  provided name already exists in the database
110- `URL mapped to $NAME` (200 OK)
111
112### `/read`
113
114#### Required parameters
115
116- None
117
118#### Optional parameters
119
120- None
121
122#### Output
123
124- `401 Unauthorized: You do not have permission to view shortlinks` if access
125  token provided in `Authorization` header does not match the configured access
126  token
127- JSON representation of the key/value database (200 OK)
128  ```json
129  {
130    "6H1g": "https://git.sr.ht/~amolith/earl/tree/dev",
131    "N3yg": "https://secluded.site/"
132  }
133  ```
134
135### `/update`
136
137#### Required parameters:
138
139- `oldName`: percent-encoded name the URL is _currently_ referred to with
140- `name`: percent-encoded name the URL _will_ be referred to with
141- `url`: percent-encoded URL being shortened
142
143`name` and `url` are first set as a key/value pair. If `name` already exists,
144`url` is updated. If `name` does _not_ already exist, it's created and `oldName`
145is deleted. If the user is only modifying `url`, `oldName` and `name` should
146both be submitted but their values should be identical.
147
148#### Optional parameters:
149
150- None
151
152#### Output:
153
154- `401 Unauthorized: You do not have permission to create shortlinks` if access
155  token provided in `Authorization` header does not match the configured access
156  token
157- `400 Bad Request: oldName parameter is required`
158- `400 Bad Request: name parameter is required`
159- `400 Bad Request: URL parameter is required`
160- `406 Not Acceptable: A shortened URL with this name already exists` if
161  provided name already exists in the database
162- `$URL mapped to $NAME` (200 OK)
163
164### `/delete`
165
166#### Required parameters:
167
168- `name`: percent-encoded short link
169
170#### Optional parameters:
171
172- None
173
174#### Output:
175
176- `401 Unauthorized: You do not have permission to create shortlinks` if access
177  token provided in `Authorization` header does not match the configured access
178  token
179- `400 Bad Request: name parameter is required`
180- `$URL has been deleted` (200 OK)
181
182## But … why?
183
184Good question. URL shorteners are (usually) terrible and useless. Except when
185used correctly :thinkingsmart:
186
187I take a lot of hand-written notes on things and, having both a passion for and
188job in IT, my notes would be much more useful if they included links to the
189things I'm writing about. However, there's no way I'm going to hand-write a 50+
190character URL.
191
192That's where URL shorteners come in!
193
194Most shortener services I've found that are both open source and self-hosted use
195something like 6-character-long paths for the links as they're meant for use by
196multiple people; 14.8m possible URLs (your cap with 4 character paths) aren't
197enough for public services.
198
199Now six characters is _fine_ but why write six characters when you could write
200four :D
201
202And why deal with user management and a relational database when you're only
203going to have one user and a bunch of keys with values :D
204
205I was also unsatisfied with the tech stack and feature sets of the alternatives;
206they were all either a pain to set up and update or they had click counters and
207link tracking and a bunch of other crap I have no use for.
208
209So I decided to make my own that has exactly what I want and nothing more :D
210
211## Questions & Contributions
212
213Questions, comments, and patches can always be sent to my public inbox, but I'm
214also in my IRC channel/XMPP room pretty much 24/7. However, I might not see
215messages right away because I'm working on something else (or sleeping) so
216please stick around!
217
218If you're wanting to introduce a new feature and I don't feel like it fits with
219this project's goal, I encourage you to fork the repo and make whatever changes
220you like!
221
222- Email: [~amolith/public-inbox@lists.sr.ht][email]
223- IRC: [irc.nixnet.services/#secluded][irc]
224- XMPP: [secluded@muc.secluded.site][xmpp]
225
226_If you haven't used mailing lists before, please take a look at [SourceHut's
227documentation](https://man.sr.ht/lists.sr.ht/), especially the etiquette
228section._
229
230[reuse]: https://api.reuse.software/info/git.sr.ht/~amolith/earl
231[reuse-shield]: https://shields.io/reuse/compliance/git.sr.ht/~amolith/earl
232[fosspay]: https://secluded.site/donate/
233[fosspay-shield]: https://shields.io/badge/donate-fosspay-yellow
234[wakapi-shield]: https://img.shields.io/endpoint?url=https://waka.secluded.site/api/compat/shields/v1/amolith/interval:any/project:earl&color=blue&label=time%20spent
235[email]: mailto:~amolith/public-inbox@lists.sr.ht
236[irc]: irc://irc.nixnet.services/#secluded
237[xmpp]: xmpp:secluded@muc.secluded.site?join