# TempFox Multi Mail + OTP — Web Edition

The official companion **website** for the **TempFox Multi Mail + OTP** Firefox extension (v4.5.3). This is a fully static, single-page web app that ports the extension's entire engine to the browser: **12 live mail APIs** (the extension's core providers plus ThrowawayMail, TempInbox, Harakirimail and Inboxes — web-only additions), automatic fallback, domain rotation, verification-code detection, and the local signup-credential generator. Every listed provider was verified working at build time; providers that died (Mail.gw — server down, 1secmail — API blocked, Emailfake — API removed, DropMail.me — free tokens now captcha-gated) were removed rather than left as dead entries.

Open `index.html` in any modern browser, or host the folder on any static server (GitHub Pages, Netlify, Vercel, nginx, …). No backend, no build step, no API keys.

## Works on ANY static host — all 12 APIs, zero config

**No relay function is required.** The app's relay chain includes a verified public CORS proxy (`corsfix`) that handles GET **and** POST from real browsers. On a pure static host (Netlify Drop, GitHub Pages, Vercel static, any file server) the app self-heals to **12/12 providers online in ~10 seconds** and creates inboxes on every provider — verified against a static-only simulation of the packaged zip.

- **5 providers connect directly** (open CORS): Mail.tm, Guerrilla Mail, Maildrop, InboxKitten, MailboxTemp.
- **7 providers go through the public relay chain**: Catchmail, TempMail.lol, Getnada, ThrowawayMail, TempInbox, Harakirimail, Inboxes. The primary public relay (corsfix) supports GET + POST; direct providers are tried first and **Auto mode creates an address instantly** either way.
- **Optionally deploy your own relay** for reliability/privacy: `netlify.toml` + `netlify/functions/relay.js` ship in the folder (auto-detected at `/.netlify/functions/relay`), or use the included Cloudflare Worker / Node / Vercel variants.

**Deploy in two clicks (drag & drop to Netlify):**
1. Unzip the package → you get a `tempfox-web/` folder.
2. Go to [app.netlify.com/drop](https://app.netlify.com/drop) and drag the `tempfox-web/` folder in. That's it — the static app alone makes all 12 providers work (the included function is optional).

**Or deploy from git:**
1. Push the `tempfox-web/` folder as a repo (or as the site root of an existing repo).
2. Netlify → **Add new site → Import an existing project** → pick the repo.
3. Build command: *(none)* · Publish directory: `.` (netlify.toml already sets this). Git-connected deploys also run the relay function automatically.

**Verify it works:** open the deployed site — the health check runs automatically and re-checks until providers are online (all 12 typically green in ~10 seconds on any static host). The API card shows which connect directly (green) and which go through the relay chain (green, marked "via relay").

**Reliability options (all optional):** for extra reliability or privacy you can still deploy your own relay — git-connected Netlify runs `netlify/functions/relay.js` automatically (auto-detected at `/.netlify/functions/relay`), or use the Cloudflare Worker / Node / Vercel variants in `relay/` and paste the URL into **Settings → Connection & CORS relay** as a Custom relay URL. Use **Settings → Test relay** anytime to see exactly which paths answer.

> **Cold-start / concurrency safe — self-healing:** the app staggers its provider health checks in small batches, retries transient failures, gives its own relay two longer attempts, and **automatically re-runs the whole health check every few seconds until every provider is online**. It never bans its own (same-origin/custom) relay after a momentary timeout. Even on hosts where the public relay is temporarily slow, Auto mode creates an address instantly on a direct provider.

## What is ported from the XPI

Every provider API and every feature in the extension's `background.js` / `popup.js` / `options.js` is reproduced here:

| Feature | Extension (XPI) | Web Edition |
| --- | --- | --- |
| **Provider APIs** | `background.js` `PROVIDERS` map | `js/core.js` — identical endpoints |
| Catchmail | `catchmail.io/api/v1` + `api.catchmail.io/api/v1` route fallback, domains `catchmail.io`, `mailistry.com`, `zeppost.com` | ✅ identical, incl. two-route fallback |
| Mail.tm | `api.mail.tm` account/token API | ✅ identical (`hydra` kind) |
| Guerrilla Mail | `api.guerrillamail.com` session API, 11 domains | ✅ identical |
| TempMail.lol | `api.tempmail.lol/v2` token inbox, 31 domains | ✅ identical |
| Maildrop | `api.maildrop.cc/graphql` no-auth GraphQL | ✅ identical (list, read, delete) |
| InboxKitten | `inboxkitten.com/api/v1/mail` public API | ✅ identical |
| MailboxTemp | `mailboxtemp.com` REST API | ✅ identical endpoint set |
| Getnada | `getnada.net` guest REST API, token inboxes | ✅ identical |
| ThrowawayMail | — (web-only) | ✅ keyless `throwawaymail.app` REST API, 10-minute mailboxes |
| TempInbox | — (web-only) | ✅ documented `endpoint.tempinbox.xyz` REST API, create/fetch/delete |
| Harakirimail | — (web-only) | ✅ public `harakirimail.com/api/v1` REST, implicit inboxes, read |
| Inboxes | — (web-only) | ✅ public `inboxes.com/api/v2` REST, list/read/delete |
| Auto mode rotates all domain endings, preferred-provider ranking, domain scoring (.net/.org/.com/variety) | ✅ | ✅ |
| Automatic API fallback (`allowFallback`) | ✅ | ✅ |
| Custom-prefix addresses + explicit provider/domain picker | ✅ | ✅ |
| 8 recent inboxes, read/unread tracking (badge equivalent) | ✅ storage API | ✅ `localStorage` (+ in-memory fallback in sandboxed iframes) + header unread chip |
| CORS handling | ✅ `host_permissions` | ✅ direct → JSONP → relay chain (same-origin / custom / public), toggleable in Settings |
| Refresh: popup 10 s + optional 1/5/15/30 min background alarm | ✅ `alarms` | ✅ timers while the tab is open |
| New-mail notifications | ✅ `notifications` API | ✅ Web Notification API (permission-gated) |
| Verification-code detection (numeric, alphanumeric, `ABCDEF`, year filtering) | ✅ | ✅ (identical engine + 2 fixes below) |
| Signup credential generator (`crypto.getRandomValues`) | ✅ | ✅ |
| Settings: preferred provider, domain preference, fallback, refresh interval, notifications, password length/symbols | ✅ | ✅ (OTP auto-paste setting becomes "show detected codes") |
| Test all APIs | ✅ | ✅ |
| Reset local data | ✅ | ✅ |

## What cannot exist on a website (browser privileges)

A web page has no `tabs`, `scripting`, or `permissions` APIs, so three extension-only behaviors are substituted honestly:

- **OTP auto-paste** → websites cannot read or fill other tabs. The web edition surfaces detected codes as one-tap **copy** cards. Auto-paste remains a Firefox-extension feature.
- **Fill signup** (email/username/password injection) → replaced with copy buttons for the generated address and credentials.
- **`activeTab` / optional host permissions** → not needed; the extension's `host_permissions` are what let it call every API even if the provider blocks cross-origin requests. In the web app, providers that block browser CORS are skipped by the same fallback machinery, and the **Test all APIs** panel shows which are reachable from the browser right now.

### Verification-code detection — two fixes over the extension

The detector is ported verbatim except for two correctness fixes that make the documented behavior actually hold:

1. **Calendar-year filtering now applies everywhere.** In the extension, the strict path (`pin is 2026`) bypassed the year filter and flagged `2026` as an OTP; the web edition filters years on every path.
2. **Six-letter codes like `ABCDEF` now match.** The extension's contextual pattern let the greedy gap `\D{0,30}` swallow the code (`Use code ABCDEF to verify` matched `VERIFY` instead of `ABCDEF`). The web edition bounds the gap to whitespace plus connector words (`is`, `to`, `your`, …) with word boundaries, so `ABCDEF`/`abcdef` and mixed codes like `ABCD12` are detected, while common words are not.

## Installing the Firefox extension (the "official" pair)

The web app is the companion to the extension itself:

1. Unzip the `.xpi` (`temp_ext.xpi`).
2. Open `about:debugging#/runtime/this-firefox`.
3. Click **Load Temporary Add-on…** and select `manifest.json`.
4. Pin **TempFox Multi Mail + OTP** to the toolbar. Firefox 140+ required.

## Providers

- **Catchmail** — `catchmail.io/api/v1` with `api.catchmail.io/api/v1` route fallback; domains `catchmail.io`, `mailistry.com`, `zeppost.com`
- **Mail.tm** — account/token API with live domains, currently including `.net`
- **Guerrilla Mail** — anonymous session API with 11 domains
- **TempMail.lol** — free token-based inbox API with random standard and community domains
- **Maildrop** — official no-auth GraphQL API on `maildrop.cc`, including message reading and deletion
- **InboxKitten** — open-source GitHub project with a live public API on `inboxkitten.com`
- **MailboxTemp** — GitHub-documented REST API with random domains and server-side OTP extraction
- **Getnada** — official guest REST API with token-protected inbox sessions and ~22 public domains
- **ThrowawayMail** *(web-only addition)* — keyless REST API for agents; mailboxes auto-expire after 10 minutes
- **TempInbox** *(web-only addition)* — documented public REST API (`endpoint.tempinbox.xyz`) with domains, create, message fetch and message deletion
- **Harakirimail** *(web-only addition)* — public REST API (`harakirimail.com/api/v1`); implicit `name@harakirimail.com` inboxes, full message bodies
- **Inboxes** *(web-only addition)* — public v2 API (`inboxes.com/api/v2`); implicit `name@inboxes.com` inboxes with message deletion

No developer API key is required. TempMail.lol, InboxKitten, Getnada, ThrowawayMail and Harakirimail do not expose individual message-deletion endpoints, so their delete controls are hidden and inboxes expire according to provider policy (identical to the extension). ThrowawayMail mailboxes expire after 10 minutes.

## CORS & relays — how blocked APIs are reached

A web page cannot ask Firefox for `host_permissions`, so providers that refuse cross-origin browser requests must be reached differently. TempFox Web uses a three-tier strategy, in order:

1. **Direct fetch** — open-CORS providers (Mail.tm, Guerrilla Mail, InboxKitten, Maildrop) connect straight from any origin, including sandboxed iframes.
2. **JSONP** — Guerrilla Mail's entire API is GET-based and supports a `callback` parameter, so it keeps working even under strict CSPs that block `fetch()` entirely. No proxy involved.
3. **CORS relay** — for every other provider (Catchmail, TempMail.lol, MailboxTemp, Getnada, ThrowawayMail, TempInbox, Harakirimail, Inboxes), a blocked request is retried through the relay chain: a **same-origin relay** if you deploy the included `relay/` folder, then your **custom relay** (Settings → Connection & CORS relay), then public relays. Direct attempts always come first, HTTP error statuses are never relayed, and dead relays are remembered and skipped for 10 minutes.

> **Note:** free public relays are frequently rate-limited or offline. The reliable "official" setup is to deploy the tiny included relay to your own host — instructions in `relay/README.md`. Without a relay of your own, providers that block browsers are reported by **Test all APIs** (marked "via relay" when a relay succeeds) and skipped by Auto mode.

### Network-isolated hosts (e.g. sandboxed web previews)

Some preview/hosting sandboxes block *all* outbound browser requests (CSP `connect-src`/`default-src` restrictions or egress filtering). When that happens the app cannot reach any mail API from the browser, and no client-side code can change that. TempFox detects this case — the API card shows a **Network channels** report (Direct / JSONP / Relay) and the error banner explains that the *host* is blocking connections, with three options: open the app on a regular web host, deploy the included relay, or use the Firefox extension. The app never crashes in such environments; it reports exactly what is unreachable and why.

## Storage in restricted environments

`localStorage` is blocked inside sandboxed iframes (opaque origins) such as some web-previews. TempFox detects that and transparently falls back to an in-memory store, so the app still works — state then lasts only for the session. On normal hosting, state persists in `localStorage` (the web equivalent of `browser.storage.local`); delete it with **Settings → Reset local data** or by clearing site data.

## Local data

Generated addresses, provider tokens, history, read state, signup credentials, and settings are stored in this browser's `localStorage` (the web equivalent of `browser.storage.local`). Delete them with **Settings → Reset local data** or by clearing site data.

## Files

```
tempfox-web/
├── index.html            # single-page app (inbox + settings)
├── css/style.css         # responsive light/dark stylesheet
├── js/core.js            # port of background.js — providers, APIs, fallback, OTP engine, relay layer
├── js/app.js             # port of popup.js + options.js — UI controller
├── icons/                # extension icons (32/48/96/128)
├── manifest.webmanifest  # installable PWA manifest
├── relay/                # optional self-hosted CORS relay (unlocks all 12 APIs from any host)
│   ├── README.md
│   ├── worker.js         # Cloudflare Worker
│   ├── index.js          # zero-dependency Node server
│   ├── vercel/api/relay.js
│   └── netlify/functions/relay.js
├── README.md             # this file
├── PRIVACY.md            # privacy policy
└── LICENSE               # MIT
```

## Validation

```bash
node --check js/core.js
node --check js/app.js
```

TempFox is an independent API client and is not an official web app of any listed provider.
