Omahub
← All plugins
D

Shorten URL

by Dan Reiland

Shorten a URL (from input or the clipboard) using a self-hosted or cloud-hosted shortener: YOURLS, Shlink, Kutt, Polr, or Bitly. The shortened URL is written back to the clipboard.

Security review

No obvious issues detected

Deterministic scan — not a security guarantee

None
Risk level
None
Analyzed commit
0233310
Scanned
1 month ago

No potentially dangerous behavior detected in the analyzed commit.

Automated analysis only — not a security guarantee.

AI advisory review

No obvious issues detected

Language-model assessment · ~deepseek/deepseek-v4-flash-latest — advisory only

Low
AI risk level
Low
Recommendation
install
Model
~deepseek/deepseek-v4-flash-latest
Analyzed commit
0233310
Reviewed
1 month ago

The plugin is a straightforward URL-shortening utility that stores provider credentials in a state file and sends them to the configured shortener service. The code is well-structured, avoids shell interpolation of user input, keeps credentials out of the process list via curl config files, and includes defensive file-handling (O_NOFOLLOW, ownership checks, size caps). No malicious behavior, hidden persistence, or destructive actions were found.

  • Credentials are stored in plaintext in config.json (permission-tightened to 600), so a local attacker with the same user account could read them.
  • The plugin sends the user's clipboard contents to the configured URL shortener service; users should only configure services they trust.
  • The deterministic scan found no issues; the low rating reflects the inherent credential-handling nature of the plugin rather than any specific defect.
How this check works

This review combines the deterministic scan (the rule-based results above) with an independent look at the plugin's code by a language model. The model reads a trimmed sample of the repository's files, the manifest, and the README, then gives a plain-language risk level and a recommendation: install (no notable danger), review (look closer first), or avoid (clearly dangerous).

It runs on the same analyzed commit as the deterministic scan and is strictly advisory — it is not a security guarantee and never blocks a plugin by itself. A human moderator still reviews plugins before they are listed.

AI advisory only — automated analysis, not a security guarantee.

Install
$ omarchy plugin add https://github.com/dmreiland/shorten-url --enable
Productivity #quickshell

omarchy-shorten-url

An Omarchy Quattro plugin that shortens URLs using a self-hosted or cloud-hosted URL shortener: YOURLS, Shlink, Kutt, Polr, or Bitly.

Setup

  1. Create the state directory and copy the config template there, then fill in credentials for the provider profiles you use:

    mkdir -p "${XDG_STATE_HOME:-$HOME/.local/state}/omarchy-shorten-url"
    cp config.example.json "${XDG_STATE_HOME:-$HOME/.local/state}/omarchy-shorten-url/config.json"
    

    The config file holds API keys/passwords and is permission-tightened to 600 (owner read/write only) on every run. Each profile has a user-defined name and an immutable provider type. The panel can add, edit, rename, delete, and select the default profile.

  2. Install the plugin:

    omarchy plugin add https://github.com/dmreiland/shorten-url.git --enable
    

    or clone it directly into ~/.config/omarchy/plugins/io.github.dmreiland.shorten-url/.

  3. Validate:

    omarchy plugin validate ~/.config/omarchy/plugins/io.github.dmreiland.shorten-url
    

Remove the plugin and its data

Remove the plugin with the Omarchy CLI, then remove its stored provider credentials and URL history. The cleanup command asks for explicit confirmation and does not remove the plugin source:

bin/omarchy-shorten-url-config --remove-data
omarchy plugin remove io.github.dmreiland.shorten-url

Run the cleanup helper before removing the plugin, while its source is still available. It removes ${XDG_STATE_HOME:-~/.local/state}/omarchy-shorten-url/config.json and history.json.

Using the script standalone

bin/omarchy-shorten-url                      # shorten whatever is on the clipboard
bin/omarchy-shorten-url https://example.com  # shorten an explicit URL
bin/omarchy-shorten-url --profile "Acme Links" https://example.com

On success it prints the shortened URL, copies it to the clipboard (wl-copy), sends a desktop notification if notify-send is available, and records the result in a history file. On failure it prints an error to stderr and exits non-zero.

bin/omarchy-shorten-url --history        # last 5 shortened URLs, most recent first, as JSON
bin/omarchy-shorten-url --history 10     # override the count
bin/omarchy-shorten-url --copy "text"    # copy arbitrary text to the clipboard

History is stored at ${XDG_STATE_HOME:-~/.local/state}/omarchy-shorten-url/history.json (override with $OMARCHY_SHORTEN_URL_HISTORY), capped at the 5 most recent entries, and permission-tightened to 600 the same way config.json is. The panel shows this list under "Recent" and refreshes it after every successful shorten; clicking an entry re-copies it to the clipboard. A successful submission clears the input field.

Open the URL shortening popover

A URL entry popover can be summoned through the Omarchy shell:

omarchy-shell shell summon io.github.dmreiland.shorten-url '{}'

Open the bar panel

The full panel attached to the Shorten URL bar widget can be opened or toggled through its direct IPC target. It is routed to the active display:

omarchy-shell io.github.dmreiland.shorten-url toggle

Provider notes

Provider Auth Endpoint used
YOURLS signature, or username+password POST {apiUrl}/yourls-api.php (action=shorturl)
Shlink X-Api-Key header POST {apiUrl}/rest/v3/short-urls
Kutt X-API-KEY header POST {apiUrl}/api/v2/links
Polr key POST parameter POST {apiUrl}/api/v2/action/shorten
Bitly Authorization: Bearer header POST https://api-ssl.bitly.com/v4/shorten

Security notes

config.json and history.json hold plaintext credentials and URL history; the script auto-tightens both to 600 on every run. User input (URLs, profile names, and provider selection) is validated and passed without shell interpolation. Provider credentials and complete request data are supplied to curl through a private file descriptor rather than command-line arguments, so they are not exposed in the process list. Every provider request has a 5-second connection timeout and 20-second overall timeout, and provider responses are capped at 64 KiB before JSON parsing. config.json has exactly one shape: a top-level profiles object; both scripts validate it against the same schema (canonicalize_config/assert_config_schema in bin/omarchy-shorten-url-lib) before trusting anything in it.

Both bin/omarchy-shorten-url and bin/omarchy-shorten-url-config read config.json/history.json through the shared bin/omarchy-shorten-url-lib helper, which shells out to the bin/omarchy-shorten-url-safe-read Perl helper for the actual open — Bash's own redirection can't request O_NOFOLLOW/O_NONBLOCK, so the helper opens with both flags in one syscall (refusing a symlink and never blocking on a FIFO), verifies it opened a regular file it owns via fstat on the descriptor, and reads at most 64 KiB, rejecting outright rather than truncating if that's exceeded. All four files (omarchy-shorten-url, omarchy-shorten-url-config, omarchy-shorten-url-lib, omarchy-shorten-url-safe-read) must stay together for the plugin to run; perl is a required runtime dependency alongside jq and curl.