1<!--
2SPDX-FileCopyrightText: 2022 Amolith <amolith@secluded.site>
3
4SPDX-License-Identifier: CC0-1.0
5-->
6
7# umu
8[![REUSE status][reuse-shield]][reuse]
9[![Donate with fosspay][fosspay-shield]][fosspay]
10![Time spent on project][wakapi-shield]
11
12Personal shortlink generator
13
14## Features
15Links are …
16- Editable
17- Removable
18- Four characters long (26 uppercase letters + 26 lowercase letters + 10 numbers
19 = 14,776,336 possible shortened URLs)
20
21Service has …
22- A simple API
23- A simple web UI
24- A simple backup procedure (database is a single directory)
25- No user management (this is a *personal* service after all)
26
27## API documentation
28
29### `/create`
30
31#### Required parameters
32- `url`: percent-encoded URL being shortened
33
34#### Optional parameters
35- `name`: percent-encoded short link the `url` will be mapped to. If this is not
36 provided, a random, 4-character code will be generated instead.
37
38#### Output
39- `401 Unauthorized: You do not have permission to create shortlinks` if access
40 token provided in `Authorization` header does not match the configured access
41 token
42- `400 Bad Request: URL parameter is required`
43- `406 Not Acceptable: A shortened URL with this name already exists` if
44 provided name already exists in the database
45- `URL mapped to $NAME` (200 OK)
46
47### `/read`
48
49#### Required parameters
50- None
51
52#### Optional parameters
53- None
54
55#### Output
56- `401 Unauthorized: You do not have permission to view shortlinks` if access
57 token provided in `Authorization` header does not match the configured access
58 token
59- JSON representation of the key/value database (200 OK)
60 ``` json
61 {
62 "6H1g": "https://git.sr.ht/~amolith/umu/tree/dev",
63 "N3yg": "https://secluded.site/"
64 }
65 ```
66
67### `/update`
68
69#### Required parameters:
70- `oldName`: percent-encoded name the URL is *currently* referred to with
71- `name`: percent-encoded name the URL *will* be referred to with
72- `url`: percent-encoded URL being shortened
73
74`name` and `url` are first set as a key/value pair. If `name` already exists,
75`url` is updated. If `name` does *not* already exist, it's created and `oldName`
76is deleted. If the user is only modifying `url`, `oldName` and `name` should
77both be submitted but their values should be identical.
78
79#### Optional parameters:
80- None
81
82#### Output:
83- `401 Unauthorized: You do not have permission to create shortlinks` if access
84 token provided in `Authorization` header does not match the configured access
85 token
86- `400 Bad Request: oldName parameter is required`
87- `400 Bad Request: name parameter is required`
88- `400 Bad Request: URL parameter is required`
89- `406 Not Acceptable: A shortened URL with this name already exists` if
90 provided name already exists in the database
91- `$URL mapped to $NAME` (200 OK)
92
93### `/delete`
94
95#### Required parameters:
96- `name`: percent-encoded short link
97
98#### Optional parameters:
99- None
100
101#### Output:
102- `401 Unauthorized: You do not have permission to create shortlinks` if access
103 token provided in `Authorization` header does not match the configured access
104 token
105- `400 Bad Request: name parameter is required`
106- `$URL has been deleted` (200 OK)
107
108## But … why?
109Good question. URL shorteners are (usually) terrible and useless. Except when
110used correctly :thinkingsmart:
111
112I take a lot of hand-written notes on things and, having both a passion for and
113job in IT, my notes would be much more useful if they included links to the
114things I'm writing about. However, there's no way I'm going to hand-write a 50+
115character URL.
116
117That's where URL shorteners come in!
118
119Most shortener services I've found that are both open source and self-hosted use
120something like 6-character-long paths for the link as they're meant for use by
121multiple people; 14.8m possible URLs (your cap with 4 character paths) aren't
122enough for public services.
123
124Six characters is *fine* but why write six characters when you could write four :D
125
126Also, why deal with user management and a relational database when you're only
127going to have one user and a bunch of keys with values :D
128
129I also had a case of the typical "programmer unsatisfied with the {language|tech
130stack|license|feature set|all of the above}, wants to make something better"
131problem. I'm not a big fan of Node, PHP is ok, Python is meh, big relational
132database is unnecessary, heavy frontend is unnecessary, complex backend is
133unnecessary, I don't care about link tracking, click counts, link referrers,
134geo-location of visitors, etc., etc., etc.
135
136All this put together, I decided I would be best served by using this as an
137opportunity to learn more Go and write my own thing that does nothing more than
138what I want need :)