fix(frontend): CLI curl-command copy bug, stale/missing content, and Fido attribution cleanup

- CliHandoff: the visible curl install command was a hardcoded truncated
  placeholder ("...install.sh"), so the copy button worked but manually
  selecting/copying the text gave a broken command. Now shows the real URL
  and lets CSS `truncate` handle the visual clipping.
- Dock: adds a full-width backdrop-blur shelf under the floating desktop
  dock so it doesn't visually blend into scrolled content (page bg is
  near-black, so plain color gradients were invisible -- blur is what
  actually reads). Desktop only; the mobile dock is already a flush bar.
- HomePage: hero now mentions "Open source" (linked, dotted underline) --
  previously absent anywhere on the landing page.
- StatsBar: "releases available" count now includes eval/enterprise
  editions, not just the consumer catalog (17 -> combined total).
- About/Privacy/Disclaimer: these hadn't been updated since the CLI
  shipped. Privacy Policy now discloses the CLI's anonymous telemetry and
  crowdsourced link-contribution behavior (previously undisclosed). About
  page's stale hardcoded product list replaced with a link to the catalog,
  plus a new section explaining the CLI. Disclaimer now covers the CLI
  binary under the same terms.
- Fido/Rufus attribution was scattered with duplicate linked mentions on
  the same pages; consolidated to one canonical linked credit per surface
  (About's Credits section, README's intro) instead of repeating it.
- FAQAccordion: fixed a factual error ("ported to Go and Node.js" -- no
  Node.js backend exists), and linked the actual repo in the open-source
  FAQ answer (previously just asserted it with no link).
- sitemap.xml: removed a dead entry for product 48, which was already
  removed from the catalog (Microsoft returns 502 for it).
- README: fixed three inaccuracies in the /contribute API doc (wrong auth
  header, wrong body field name, wrong status codes) against the actual
  backend/main.go implementation, and added the missing telemetry/sentinel
  fields to the /metrics example response.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Shekhar Vaidya 2026-07-21 10:10:38 +05:30
parent b516804541
commit 73eee730c9
10 changed files with 109 additions and 37 deletions

View file

@ -134,8 +134,6 @@ Browser → Backend → (CF Worker) → Microsoft API → Signed CDN URL
5. Cache result → return to browser
```
The flow mirrors [Fido.ps1](https://github.com/pbatard/Fido) by Pete Batard — the same script bundled with Rufus.
Outbound requests to Microsoft are optionally routed through a Cloudflare Worker (`cloudflare-worker/worker.js`). This distributes requests across Cloudflare's global edge IPs instead of a single server IP, preventing Microsoft's rate-limit block (error 715-123130) under high traffic. The Worker is opt-in via environment variables — omit them to go direct to Microsoft.
### Caching layer
@ -249,17 +247,17 @@ Valid slugs: `server-2025`, `server-2022`, `server-2019`, `server-2016`, `win11-
### `POST /contribute`
Accepts a crowdsourced link from the CLI tool to warm the cache. Requires `Authorization: Bearer <CONTRIBUTE_SECRET>` header.
Accepts a crowdsourced link from the CLI tool to warm the cache. Requires an `X-Contribute-Secret: <CONTRIBUTE_SECRET>` header.
```json
{
"product_id": "3262",
"sku_id": "0x0409",
"response": { /* raw Microsoft JSON */ }
"raw_json": { /* raw Microsoft JSON */ }
}
```
Returns `200 OK` on acceptance, `400` on validation failure (expired link, unknown product), `429` on rate limit (~5 req/min per IP).
Returns `204 No Content` on acceptance; `422` on validation failure (unknown product, invalid SKU, expiry under 1 hour, disallowed download host); `400` on a malformed request body; `401` if the secret header doesn't match; `429` on rate limit (~5 req/min per IP).
### `GET /metrics?secret=<secret>`
@ -271,10 +269,22 @@ Returns real-time cache statistics for the running instance. Auth via `?secret=`
"link": { "requests": 38, "cache_hits": 35, "ms_fetches": 3, "neg_hits": 0, "stale": 0, "hit_rate": "92.1%", "cache_size": 6 },
"eval": { "requests": 12, "cache_hits": 12, "stale": 0, "hit_rate": "100.0%", "cache_size": 5 },
"neg_cache_size": 0,
"total_ms_fetches": 6
"total_ms_fetches": 6,
"sentinel_errors": 0,
"sentinel_distinct_sources_est": 0,
"telemetry": {
"actions": { "fetch": 364, "eval": 40, "interactive": 14 },
"platforms": { "windows": 176, "darwin": 70, "linux": 132 },
"products": { "3262": 109, "2618": 95 },
"results": { "success": 197, "failed": 221 },
"versions": { "0.3.6": 41 },
"errors": { "fetching download links: Sentinel marked this request as rejected.": 90 }
}
}
```
`sentinel_errors` / `sentinel_distinct_sources_est` track how often Microsoft's Sentinel WAF has blocked the backend's own outbound Microsoft calls. `telemetry` aggregates anonymous CLI usage events (see [Usage telemetry](#usage-telemetry) below) — omitted entirely if no CLI events have been recorded yet.
---
## Supported Products
@ -292,7 +302,6 @@ Returns real-time cache statistics for the running instance. Auth via `?secret=`
| Windows 10 22H2 | 2618 | x64 / x86 |
| Windows 10 22H2 Home China | 2378 | x64 |
| Windows 8.1 | 52 | x64 / x86 |
| Windows 8.1 Single Language | 48 | x64 / x86 |
### Evaluation editions (Server & Enterprise)

View file

@ -46,7 +46,6 @@
<url><loc>https://msdl.tech-latest.com/product/win11-ent</loc><lastmod>2026-05-18</lastmod><priority>0.8</priority><changefreq>monthly</changefreq></url>
<!-- Product Pages -->
<url><loc>https://msdl.tech-latest.com/product/48</loc><lastmod>2026-05-12</lastmod><priority>0.8</priority><changefreq>monthly</changefreq></url>
<url><loc>https://msdl.tech-latest.com/product/52</loc><lastmod>2026-05-12</lastmod><priority>0.8</priority><changefreq>monthly</changefreq></url>
<url><loc>https://msdl.tech-latest.com/product/2378</loc><lastmod>2026-05-12</lastmod><priority>0.8</priority><changefreq>monthly</changefreq></url>
<url><loc>https://msdl.tech-latest.com/product/2618</loc><lastmod>2026-05-12</lastmod><priority>0.8</priority><changefreq>monthly</changefreq></url>

View file

@ -64,7 +64,7 @@ function InstallSteps() {
</div>
</div>
<div className="flex items-center justify-between gap-2 rounded-lg bg-white/4 border border-white/7 px-3 py-2">
<code className="text-[11px] font-mono text-zinc-400 truncate">curl -fsSL .../install.sh | bash</code>
<code className="text-[11px] font-mono text-zinc-400 truncate">curl -fsSL https://api.msdl.tech-latest.com/install.sh | bash</code>
<button onClick={handleCurlCopy} className="flex-shrink-0 text-zinc-500 hover:text-white transition-colors">
{curlCopied ? <Check size={12} className="text-green-400" /> : <Copy size={12} />}
</button>

View file

@ -45,6 +45,11 @@ export default function Dock() {
return (
<>
{/* Full-width shelf so the floating desktop dock separates from scrolled content page bg is
near-black (zinc-950), so plain color gradients are invisible; backdrop-blur is what reads.
Desktop only: the mobile dock is already a flush full-width bar with no gap to bridge. */}
<div className="hidden sm:block fixed inset-x-0 bottom-0 h-24 backdrop-blur-md bg-gradient-to-t from-zinc-950/90 via-zinc-950/60 to-transparent pointer-events-none z-40" />
{/* ── DESKTOP DOCK (sm+) — centered floating pill ── */}
<div className="hidden sm:flex fixed bottom-5 left-0 right-0 justify-center z-50 pointer-events-none">
<motion.div

View file

@ -1,12 +1,23 @@
import { useState } from 'react'
import { useState, type ReactNode } from 'react'
import { motion, AnimatePresence } from 'motion/react'
import { ChevronRight } from 'lucide-react'
interface FaqItem {
q: string
a: string
a: ReactNode
}
const repoLink = (
<a
href="https://github.com/starkSV/windows-iso-downloader"
target="_blank"
rel="noopener noreferrer"
className="text-blue-400 hover:text-blue-300 transition-colors"
>
GitHub
</a>
)
const faqs: FaqItem[] = [
{
q: 'Is this legal?',
@ -34,7 +45,13 @@ const faqs: FaqItem[] = [
},
{
q: 'Is MSDL open source?',
a: 'Yes. Both the frontend and the backend proxy are fully open source. The backend implements the same session-based flow as the Fido PowerShell script, ported to Go and Node.js. You can self-host the entire stack.',
a: (
<>
Yes. Both the frontend and the backend proxy are fully open source, on {repoLink}. The
backend and the standalone CLI both implement the same session-based flow as the Fido
PowerShell script, ported to Go. You can self-host the entire stack.
</>
),
},
]

View file

@ -1,5 +1,6 @@
import { motion } from 'motion/react'
import { useState, useEffect } from 'react'
import { evalProducts } from '../data/evalProducts'
interface Stat {
value: string
@ -7,14 +8,14 @@ interface Stat {
}
export default function StatsBar() {
const [totalReleases, setTotalReleases] = useState('17')
const [totalReleases, setTotalReleases] = useState((17 + evalProducts.length).toString())
useEffect(() => {
fetch('/data/products.json')
.then(r => r.json())
.then((data: Record<string, { active?: boolean }>) => {
const activeCount = Object.values(data).filter(p => p.active !== false).length
setTotalReleases(activeCount.toString())
setTotalReleases((activeCount + evalProducts.length).toString())
})
.catch(() => {})
}, [])

View file

@ -49,16 +49,8 @@ export default function AboutPage() {
<Section title="How it works">
<p>
Our backend replicates the session-based authentication flow that Microsoft uses to
serve download links to end users. The same approach is used by{' '}
<a
href="https://github.com/pbatard/Fido"
target="_blank"
rel="noopener noreferrer"
className="text-blue-400 hover:text-blue-300 transition-colors"
>
Fido
</a>{' '}
(the PowerShell script bundled with Rufus). The flow is:
serve download links to end users the same technique used by Rufus (credited below).
The flow is:
</p>
<ol className="list-decimal list-inside space-y-1 text-zinc-500 text-sm">
<li>Register a session with Microsoft's tracking endpoint</li>
@ -87,9 +79,22 @@ export default function AboutPage() {
</code>
</p>
<p>
Product IDs are maintained manually based on Microsoft's release cadence.
Windows 11 25H2, 24H2, Windows 10 22H2, and Windows 8.1 are currently listed.
New releases are added as Microsoft publishes them.
Product IDs are maintained manually based on Microsoft's release cadence, covering
consumer Windows (11, 10, 8.1) as well as Windows Server (20162025) and Windows 11
Enterprise evaluation editions. New releases are added as Microsoft publishes them
see the <a href="/products" className="text-blue-400 hover:text-blue-300 transition-colors">full catalog</a>.
</p>
</Section>
<Section title="CLI tool">
<p>
MSDL also ships as a standalone command-line tool,{' '}
<code className="text-[11px] font-mono bg-white/5 border border-white/7 px-1.5 py-0.5 rounded text-zinc-400">msdl</code>.
It runs the same Microsoft session flow directly from your own machine instead of through
our backend useful when Microsoft is rate-limiting our server, since a request from
your own connection isn't affected by that. See the{' '}
<a href="/cli" className="text-blue-400 hover:text-blue-300 transition-colors">CLI page</a> for
install instructions.
</p>
</Section>

View file

@ -31,7 +31,7 @@ export default function DisclaimerPage() {
>
<div>
<h1 className="text-2xl font-bold text-white mb-1">Disclaimer</h1>
<p className="text-xs font-mono text-zinc-600">Last updated: May 18, 2026</p>
<p className="text-xs font-mono text-zinc-600">Last updated: July 16, 2026</p>
</div>
<div className="p-4 rounded-xl border border-amber-500/15 bg-amber-500/6 text-amber-400/80 text-[12px] leading-relaxed">
@ -43,7 +43,9 @@ export default function DisclaimerPage() {
<p>
MSDL is an independent, open-source project. It is not produced, approved, or supported
by Microsoft Corporation. The name "Windows" and the Windows logo are registered
trademarks of Microsoft Corporation.
trademarks of Microsoft Corporation. This applies equally to the website and the{' '}
<code className="text-zinc-400 text-[11px] font-mono bg-white/5 px-1 py-0.5 rounded">msdl</code>{' '}
command-line tool.
</p>
</Section>
@ -76,8 +78,9 @@ export default function DisclaimerPage() {
<Section title="Open source">
<p>
The source code is publicly available. You are free to inspect, fork, and self-host
this project under the terms of its open-source license. The project credits the
open-source Fido script by Pete Batard for the underlying session flow.
this project under the terms of its open-source license. See the{' '}
<a href="/about" className="text-blue-400 hover:text-blue-300 transition-colors">About page</a>{' '}
for credits.
</p>
</Section>
</motion.div>

View file

@ -121,7 +121,7 @@ export default function HomePage() {
<p className="text-zinc-400 text-base max-w-sm mx-auto mb-6 leading-relaxed">
Direct links from Microsoft's CDN. No ads. No registration.
</p>
<div className="flex items-center justify-center gap-4 text-[12px] text-zinc-500">
<div className="flex items-center justify-center flex-wrap gap-x-4 gap-y-1.5 text-[12px] text-zinc-500">
<span className="flex items-center gap-1.5">
<span className="w-1.5 h-1.5 rounded-full bg-green-500 inline-block" />
Always official
@ -136,6 +136,16 @@ export default function HomePage() {
<span className="w-1.5 h-1.5 rounded-full bg-zinc-600 inline-block" />
Free forever
</span>
<span className="text-zinc-700">·</span>
<a
href="https://github.com/starkSV/windows-iso-downloader"
target="_blank"
rel="noopener noreferrer"
className="flex items-center gap-1.5 hover:text-zinc-300 transition-colors"
>
<span className="w-1.5 h-1.5 rounded-full bg-purple-500 inline-block" />
<span className="underline decoration-dotted decoration-zinc-600 underline-offset-4">Open source</span>
</a>
</div>
</motion.div>

View file

@ -31,14 +31,37 @@ export default function PrivacyPolicyPage() {
>
<div>
<h1 className="text-2xl font-bold text-white mb-1">Privacy Policy</h1>
<p className="text-xs font-mono text-zinc-600">Last updated: May 18, 2026</p>
<p className="text-xs font-mono text-zinc-600">Last updated: July 16, 2026</p>
</div>
<Section title="No data collected">
<Section title="No data collected on the website">
<p>
MSDL does not collect, store, log, or share any personally identifiable information.
There are no user accounts, no cookies, no analytics trackers, and no third-party
advertising scripts of any kind.
The MSDL website does not collect, store, log, or share any personally identifiable
information. There are no user accounts, no cookies, no analytics trackers, and no
third-party advertising scripts of any kind.
</p>
</Section>
<Section title="CLI tool: anonymous telemetry and link sharing">
<p>
The <code className="text-zinc-400 text-[11px] font-mono bg-white/5 px-1 py-0.5 rounded">msdl</code>{' '}
CLI is a separate, optional download and sends two kinds of anonymous data by default,
both of which you can disable:
</p>
<p>
<strong className="text-zinc-400">Usage telemetry</strong> action type (fetch, eval, list,
interactive), platform (Windows/macOS/Linux), CLI version, and whether the run succeeded
or failed. No personal data, IP address, or product-key information is included. Disable
with <code className="text-zinc-400 text-[11px] font-mono bg-white/5 px-1 py-0.5 rounded">--no-telemetry</code>{' '}
or the <code className="text-zinc-400 text-[11px] font-mono bg-white/5 px-1 py-0.5 rounded">MSDL_NO_TELEMETRY=1</code> environment variable.
</p>
<p>
<strong className="text-zinc-400">Link contribution</strong> after a successful fetch, the
CLI can share the product ID, SKU ID, and Microsoft's raw signed-link response back to our
backend, so the next website visitor gets a cached hit instead of a fresh Microsoft request.
Only that Microsoft response is shared nothing about you or your machine. Disable with{' '}
<code className="text-zinc-400 text-[11px] font-mono bg-white/5 px-1 py-0.5 rounded">--no-contribute</code>{' '}
or <code className="text-zinc-400 text-[11px] font-mono bg-white/5 px-1 py-0.5 rounded">MSDL_NO_CONTRIBUTE=1</code>.
</p>
</Section>