From 96c885a46523720606772b1f19e7663a0e75c0fb Mon Sep 17 00:00:00 2001 From: cabbagec Date: Wed, 18 Mar 2026 04:06:04 +0800 Subject: [PATCH] remove API key requirement from POST /api/shorten --- README.md | 11 +++++------ static/app.js | 28 ++++++++++++++++++---------- urlshort.py | 6 +----- 3 files changed, 24 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index 1351d6e..8180cfa 100644 --- a/README.md +++ b/README.md @@ -124,15 +124,14 @@ Health check endpoint. --- -### `POST /api/shorten` 🔒 -Create a new short URL. +### `POST /api/shorten` +Create a new short URL. No API key required. Fields can be passed as **query parameters** (URL-encoded) or in a **JSON request body**. Query parameters take precedence over body fields. | Field | Required | Description | |------------------|----------|-----------------------------------------------------------| -| `api_key` | ✅ | API key for authentication | | `url` | ✅ | The URL to shorten (must start with `http://` or `https://`) | | `retention_days` | | Override the default retention period for this URL | @@ -221,10 +220,10 @@ Increments `visit_count` on each hit. # Shorten a URL (JSON body) curl -X POST http://localhost:8080/s/api/shorten \ -H "Content-Type: application/json" \ - -d '{"api_key": "change-this-secret-key", "url": "https://github.com"}' + -d '{"url": "https://github.com"}' # Shorten a URL (query parameters) -curl -X POST "http://localhost:8080/s/api/shorten?api_key=change-this-secret-key&url=https%3A%2F%2Fgithub.com&retention_days=30" +curl -X POST "http://localhost:8080/s/api/shorten?url=https%3A%2F%2Fgithub.com&retention_days=30" # Follow the redirect curl -L http://localhost:8080/s/aB3xYz @@ -248,7 +247,7 @@ curl "http://localhost:8080/s/api/lookup?url=https%3A%2F%2Fexample.com" A clean single-page frontend is included in `static/`. It provides: -- **URL shortening** — paste a URL and press Enter to create a short URL (requires API key) +- **URL shortening** — paste a URL and press Enter to create a short URL - **Existing URL lookup** — as you type a URL, the frontend checks if it already exists and shows its metadata - **Admin table** — enter a valid API key to see all shortened URLs in a sortable, paginated table - **Copy & Delete** — per-row copy and delete buttons (delete on hover only) diff --git a/static/app.js b/static/app.js index fd1476f..892fffd 100644 --- a/static/app.js +++ b/static/app.js @@ -218,6 +218,7 @@ async function lookupUrl(url) { } async function handleEnter() { + clearTimeout(_lookupTimer); // cancel any pending debounced lookup const input = document.getElementById('url-input'); const url = input.value.trim(); if (!url || !isValidUrl(url)) { @@ -225,17 +226,27 @@ async function handleEnter() { setStatus('', ''); return; } - if (!state.apiKey) { - // No API key — just do a lookup - await lookupUrl(url); - return; - } + + // First, check if this URL already exists + setStatus('checking…', ''); + try { + const lookupRes = await apiGet('/api/lookup?url=' + encodeURIComponent(url)); + if (lookupRes.ok) { + // URL already exists — just show its metadata + const data = await lookupRes.json(); + state.currentMeta = data; + renderMeta(data); + setStatus('exists', 'ok'); + return; + } + } catch { /* lookup failed, proceed to create */ } + + // URL does not exist — attempt to create setStatus('creating…', ''); try { - const res = await apiPost('/api/shorten', { api_key: state.apiKey, url: url }); + const res = await apiPost('/api/shorten', { url: url }); if (res.status === 201) { const shortUrl = await res.text(); - // Fetch metadata for the newly created URL const code = shortUrl.split('/').pop(); const metaRes = await apiGet('/api/urls/' + encodeURIComponent(code)); if (metaRes.ok) { @@ -243,11 +254,8 @@ async function handleEnter() { state.currentMeta = data; renderMeta(data); setStatus('created ✓', 'ok'); - // Refresh admin list if (state.isAdmin) fetchAdminUrls(); } - } else if (res.status === 403) { - setStatus('invalid key', 'err'); } else { const err = await res.json().catch(() => null); setStatus(err?.error || 'error', 'err'); diff --git a/urlshort.py b/urlshort.py index 033aa11..85d91d4 100644 --- a/urlshort.py +++ b/urlshort.py @@ -6,7 +6,7 @@ Usage: python urlshort.py API (all routes are prefixed with base_path, e.g. /s): GET / Frontend (or health check if no static/) GET /api/health Health check - POST /api/shorten Create a short URL (API key required) + POST /api/shorten Create a short URL (no API key required) GET /api/urls List all short URLs (API key required) GET /api/urls/ Get info for a code (no API key required) GET /api/lookup?url= Look up by original URL (no API key required) @@ -433,10 +433,6 @@ class Handler(BaseHTTPRequestHandler): self._error(400, "Invalid JSON body") return - # Auth: check api_key from query param or body - if not self._check_api_key(body): - self._send_empty(403) - return # url: query param takes precedence, then body original_url = qs.get("url", [""])[0] or str(body.get("url", "")).strip()