docs: fix broken star history chart in READMEs and docs
The star history chart in the READMEs and vitepress docs is currently broken because the upstream service no longer works due to GitHub stargazer API restrictions. Switch the chart images to the star-history.dera.page mirror, which uses a different data source that requires no API token, so the chart renders correctly again.
Co-authored-by: SimonFoobar648 <245426116+SimonFoobar648@users.noreply.github.com>
Refresh dependencies and lockfiles across frontend, Worker, Pages, and VitePress documentation packages. Update Wrangler to 4.114.0 and align Cloudflare Workers types with its peer requirements.
Validated with frontend tests/build, Worker build/lint, docs build, and repository E2E.
Fix IMAP flag persistence so read/unread state survives reconnects, and align SEARCH/FETCH behavior with persisted flags.
Co-authored-by: bounce12340 <bounce12340@users.noreply.github.com>
docs: add Resend DNS-only proxy warning to send-mail config
Resend domain verification CNAME records must use DNS-only (gray
cloud) on Cloudflare. Proxied (orange cloud) records prevent
verification, and a single failed attempt can take hours before
retry. This is a recurring issue (#515) that the Resend setup
docs did not warn about.
Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
feat: add regex fallback for verification code extraction without Workers AI
When AI email extraction is enabled but no Workers AI binding is available,
fall back to a built-in, zero-dependency regex extractor so self-hosted
deployments without Workers AI still surface verification codes in Telegram
notifications and webhooks.
- Add worker/src/email/extract_code.ts: rule-based multilingual
(English / Chinese / Japanese / Korean) verification-code extractor with
year and YYYYMMDD date rejection to avoid false positives.
- ai_extract.ts: share the allowlist check and content parsing across both
paths, extract a saveExtractMetadata helper, and use the regex fallback
when env.AI is absent.
- Reuse the existing aiExtractResult pipeline (auth_code type), so Telegram
and webhook output need no changes.
- Update bilingual CHANGELOG and AI-extract feature docs.
Random subdomain mailbox creation only generates addresses; mail delivery
depends on DNS / Cloudflare Email Routing covering *.<base-domain>.
Cloudflare Email Routing does not inherit apex configuration onto
subdomains, so a wildcard `*` MX record on the base domain is required
for random subdomains to actually receive mail.
- Add `[!IMPORTANT]` block in subdomain.md (zh/en) explaining the two
deliverable paths: DNS-only wildcard MX (recommended for random
subdomains) vs Cloudflare dashboard "Add subdomain"
- Link to Cloudflare Email Routing — Subdomains official docs from
worker-vars.md and subdomain.md
- Instruct copying apex MX records to host `*` preserving each record's
priority/target, instead of hardcoding specific MX targets
- Shorten frontend `randomSubdomainTip` for CreateAccount and Login
views (6 locales: zh/en/de/es/ja/pt-BR), drop Markdown backticks
(Vue text interpolation renders them literally), and point users to
the docs instead of embedding DNS instructions
- Trim overlap between existing `[!NOTE]` and new `[!IMPORTANT]` in
subdomain.md
- Update CHANGELOG.md / CHANGELOG_EN.md under v1.9.0(main)
Closes#1035Closes#1026
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
* fix: update AI extract default model
* fix: update e2e worker node version
* fix: use node lts for e2e worker
* fix: align AI model and CI node version
- bump project version metadata to v1.9.0
- refresh npm dependencies and lockfiles across frontend, worker, pages, and docs
- link .agents/skills to .claude/skills
In quick-start / worker-vars / email-routing (zh + en), explicitly
call out that a Cloudflare-hosted domain with Email Routing + Catch-all
must be set up before deploying, and that subdomains do not inherit
the parent domain's Email Routing. Closes#1004.
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat: add cf-temp-mail-usage skill and parsed mail API for AI agents
- feat: new /api/parsed_mails and /api/parsed_mail/:id endpoints returning
server-parsed subject/text/html/attachments metadata (reuses commonParseMail)
- feat: add .claude/skills/cf-temp-mail-usage read-only skill so AI agents
(OpenClaw / Codex / Cursor) can consume a mailbox with a user-supplied JWT,
bypassing the Turnstile challenge required for mailbox creation
- refactor: split mails_api/index.ts and admin_api/index.ts into thin route
shells; move business logic into dedicated *_api.ts files
- docs: update README / README_EN / CHANGELOG with agent-email feature and
npx degit install instructions for the skill
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* feat: rename skill to cf-temp-mail-agent-mail, add agent-email docs, fix sender trim
- Rename skill from cf-temp-mail-usage to cf-temp-mail-agent-mail
- Rewrite SKILL.md: parsed API primary, local fallback, prerequisites, multi-agent install
- Add vitepress docs (zh + en) for AI Agent mailbox usage
- Fix leading space in parsed_mail_api sender field via .trim()
- Update README install section with 3 install methods
- Update changelogs (zh + en)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* docs: simplify README agent skill section to one-liner with links
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* feat: add send mail API to skill, credential persistence, remove poll example
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
- Upgrade version to 1.8.0 in all package.json files
- Add cf-temp-mail-release-notify skill with MarkdownV2 Telegram posting
- Optimize docs_deploy.yml to auto-trigger on Tag Build CI completion
- Add v1.8.0 placeholder in CHANGELOG.md and CHANGELOG_EN.md
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
* fix: auto initialize default send balance
* fix: tighten send access auto init flow
* refactor: centralize send balance state
* fix: separate legacy repair from admin control in send balance
Add an `address_sender.source` column to distinguish legacy / auto /
user / admin rows. `ensureDefaultSendBalance` now only repairs rows
with `source IS NULL`, so admin-disabled and user-requested rows are
never overwritten. Admin POST writes tag `source = 'admin'`; new
auto-init inserts tag `'auto'`; `requestSendMailAccess` inserts tag
`'user'`.
Bumps DB_VERSION to v0.0.8 with the usual `PRAGMA table_info` guarded
ALTER, plus a standalone SQL patch under db/.
Adds E2E regressions: legacy repair path, admin-disabled rows stay
disabled across settings and send, send after admin deletion
auto-initializes a fresh row.
* fix: drop runtime legacy repair; backfill source='legacy' on migrate
Pre-v0.0.8 schema cannot distinguish legacy request-send-access
remnants from admin-disabled rows — both share `balance = 0,
enabled = 0`. Letting ensureDefaultSendBalance repair that shape on
upgrade could silently re-enable an admin-disabled row.
Remove the runtime repair path entirely:
- `ensureDefaultSendBalance` now uses `ON CONFLICT(address) DO NOTHING`;
existing rows are never touched.
- The v0.0.8 migration (and the matching SQL patch) backfills every
pre-existing row with `source = 'legacy'`, making pre-migration
state explicitly off-limits to runtime auto-init.
- E2E: flip the legacy test to the negative direction — a
`source='legacy'` zero-balance row stays untouched by settings
reads and send attempts. Harden `resetSenderToLegacy` to return
404 when `meta.changes < 1`.
- Update changelog and docs: legacy/admin-disabled rows must be
restored manually via the admin UI.
* refactor: collapse send balance auto-init to missing-row insert
Per review feedback: the runtime guarantee we actually need is
"create an address_sender row when one is missing, leave existing
rows alone". Once `ensureDefaultSendBalance` switched to
`ON CONFLICT DO NOTHING`, the `source` column, the v0.0.8 migration,
and the `resetSenderToLegacy` test endpoint became dead weight —
the DO NOTHING path already protects admin-disabled and admin-edited
rows without any provenance metadata.
- Drop `address_sender.source` and the v0.0.8 migration; revert
DB_VERSION to v0.0.7. No schema change ships with this PR.
- Strip the `source` field from `ensureDefaultSendBalance`,
`requestSendMailAccess`, and the admin-update path.
- Remove the `/admin/test/reset_sender_to_legacy` test endpoint and
its E2E helper; the negative legacy-repair test it served is no
longer needed because the runtime no longer touches existing rows.
- E2E coverage stays focused on the three guardrails: missing-row
auto-init, admin-disabled rows stay disabled, admin deletion
triggers a fresh re-insert.
- Tighten changelog and docs to "auto-initialize missing rows".
* docs: align common-issues with missing-row-only auto-init
The FAQ entries for "DEFAULT_SEND_BALANCE set but still No balance"
still described the old behaviour of repairing legacy
`balance = 0 && enabled = 0` rows. Rewrite both zh and en rows to
match the current runtime: only addresses with no existing
`address_sender` row get auto-initialised; legacy, admin-disabled,
and admin-edited rows must be restored manually through the admin
console.
- Upgrade deps across frontend/worker/pages/vitepress-docs (wrangler 4.82.2, dompurify 3.4.0, resend 6.11.0, etc.)
- Bump version to v1.7.0 in all package.json and worker constants
- Add v1.7.0 CHANGELOG placeholder; move #978/#930 Bug Fixes from v1.6.0 to v1.7.0 (merged after v1.6.0 tag)
- Add upgrade-dependencies skill; translate version-upgrade skill to English
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(admin): add IP whitelist (strict allowlist mode) (#920)
- Add enableWhitelist/whitelist fields to IpBlacklistSettings
- Implement three-layer access control: whitelist → blacklist → daily limit
- Whitelist uses exact match for IPv4/IPv6, regex for patterns
- Whitelisted IPs skip blacklist checks (trusted)
- Fail-closed when cf-connecting-ip missing under whitelist mode
- Frontend: independent whitelist toggle + empty list protection
- Backend: backward compatible (old frontends get defaults)
- E2E tests: config validation + runtime behavior
- Docs: CHANGELOG zh/en updated
Closes#920
* fix(admin): address PR review feedback on IP whitelist
- Add IPv4-mapped IPv6 (::ffff:x.x.x.x) exact match in isWhitelisted
- Include error.message in whitelist regex parse failure log
- Include actual/max size in whitelist size limit error message
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(admin): validate whitelist regex on save and preserve existing whitelist on partial update
- Reject invalid regex patterns in whitelist at save time to prevent runtime lockout
- Preserve existing enableWhitelist/whitelist from DB when older clients omit these fields
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(admin): revert P2 - keep simple ?? defaults for backward compat
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(admin): validate whitelist elements are strings before trimming
Prevents 500 error when whitelist contains non-string elements (e.g. numbers, null)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* docs(admin): add IP blacklist/whitelist documentation (zh + en)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(admin): fix fingerprint blacklist bypass when cf-connecting-ip absent, improve e2e tests
- Split checkBlacklist into checkFingerprintBlacklist (IP-independent) and checkIpAsnBlacklist
- Fingerprint check now runs before the !reqIp early-return to prevent bypass
- Add afterEach reset to config test group, extract RESET_SETTINGS constant
- Strengthen whitelist-blocks test to deterministic 403 assertion
- Add e2e tests: invalid regex rejection, non-string element rejection, fingerprint-blocks-without-IP
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(admin): suppress no-useless-escape lint warning in whitelist regex check
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Subdomains do not inherit Email Routing from the apex domain;
each subdomain must enable Email Routing and configure its own
DNS records and Catch-all rule.
Refs #969
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* docs: restructure sidebar, expand FAQ, enhance send mail docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* docs: remove specific example domain reference in FAQ per review
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>