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