- Rust 96.1%
- Just 3.9%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| .sqlx | ||
| migrations | ||
| src | ||
| systemd | ||
| .env.template | ||
| .gitignore | ||
| agpl-3.0.txt | ||
| Cargo.lock | ||
| Cargo.toml | ||
| justfile | ||
| LICENSE | ||
| README.md | ||
Fleck
A self-hosted link shortener
CLI Usage
Run Server
Make sure to set up .env as a fully filled copy of .env.template or otherwise provide the necessary env variables like HOST_ROOT, PORT, SOURCE_URL, and DATABASE_URL.
fleck serve
Add API User
fleck add-user USER_NAME
Add API Key for User
fleck add-key --user-name USER_NAME --key-name KEY_NAME --key-secret KEY_SECRET
This will generate a TOTP QR code in ASCII and print it out to the terminal. It will also print out the necessary url in plain text. I suggest using your password manager of choice to generate a good random KEY_SECRET to use.
Add Link
fleck put-link TARGET --short-code SHORT_CODE
Note: --short-code SHORT_CODE is optional. The system will generate one for you.
API Usage
Example
See project justfile for some examples of how to call the API with a valid HMAC generated by openSSL
Authenticate
-H 'Authorization: {"name":"API_KEY_NAME","nonce":"2FA_CODE","hash":"HMAC_OF_NONCE_WITH_SECRET"}'
- Provide "name" to identify which api_key we are authenticating as.
- Provide "nonce" as a time based 2FA code to make this request unrepeatable.
- Must be timely (+-30s)
- Must not be reused between requests
- Provide "secret" as a sha512 hmac of the nonce utilizing the shared api_secret
All endpoints may produce the following error if this is incorrectly applied.
401 UNAUTHORIZED text/plain
Authorization Not Recognized
PUT (Add) link
curl -X PUT https://host/api/link/{SHORT_CODE} -H 'Authorization: ...' -H 'Content-Type: text/plain' -d 'TARGET_LINK'
OR
curl -X PUT https://host/api/link -H 'Authorization: ...' -H 'Content-Type: text/plain' -d 'TARGET_LINK'
200 OK text/plain
https://host/{SHORT_CODE}
400 BAD_REQUEST text/plain
Shortcode Already Exists
DELETE link
curl -X DELETE https://host/api/link/{SHORT_CODE} -H 'Authorization: ...'
200 OK application/json
{"short_url": "https://host/{SHORT_CODE}", "url": "TARGET_URL"}
404 NOT_FOUND text/plain
Not Found
GET link (redirect)
curl -X GET https://host/{SHORT_CODE}
303 SEE OTHER
404 NOT_FOUND text/plain
Not Found