* 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>
* 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>
- Add warning notes in new-address-api and mail-api docs
- Explain the difference between Address JWT and User JWT
- Create dedicated 'API Endpoints' section in sidebar
- Update both zh and en documentation
Refs #910
* feat: support attachment push for Telegram and Webhook (#894)
- Parse email attachments via postal-mime in commonParseMail
- Send attachments via Telegram Bot API sendDocument after text message
- Include base64-encoded attachments in webhook payload
- Add e2e tests for webhook attachment push
- Add i18n messages for attachment-related notifications
Closes#894
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor: remove user-facing error message for failed attachment send
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor: remove unused i18n attachment messages
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor: use sendMediaGroup for batch attachment sending
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor: remove redundant commonParseMail call, use cached result
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor: remove webhook attachment support, raw already contains attachments
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: use sendDocument for single attachment, sendMediaGroup for 2+
Telegram sendMediaGroup requires 2-10 items minimum. Use sendDocument
for single attachment case. Update CHANGELOG with 50MB limit info.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: batch sendMediaGroup in groups of 9, add attachments to wasm parser
Telegram sendMediaGroup supports 2-10 items. Batch large attachment
lists into groups of 9. Also add attachments field to commented-out
wasm parser for future compatibility.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add caption to attachment messages, update wasm patch
Add email sender and subject as caption on Telegram attachment messages.
Caption is shown on the first attachment only for sendMediaGroup.
Update wasm parser patch to include attachments field mapping, and fix
wasm comment to use correct field names (content_type, content as
Uint8Array directly).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor: unify attachment sending with sendMediaGroup for all cases
sendMediaGroup works with 1+ files (tested). Remove sendDocument
special case and always use sendMediaGroup with batching.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* chore: reduce sendMediaGroup batch size to 6
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* chore: change WASM parse email comment from TODO to NOTE
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* chore: regenerate wasm parser patch with attachments support
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add ENABLE_TG_PUSH_ATTACHMENT env var to control attachment push
Add environment variable to enable/disable Telegram attachment push
(default disabled). Update type definitions, wrangler template,
worker-vars docs (zh/en), telegram feature docs (zh/en), and
changelogs.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
docs: add webhook preset templates and Telegram per-user push docs (#769)
Add Telegram Bot, WeChat Work, Discord webhook preset templates to
frontend and documentation. Add per-user mail push and global push
documentation for Telegram Bot.
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add STARTTLS support for SMTP proxy server
Add smtp_tls_cert and smtp_tls_key environment variables to enable
STARTTLS on the SMTP proxy server, matching existing IMAP TLS support.
Closes#249
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* test: add E2E tests for SMTP/IMAP STARTTLS
- Add smtp-proxy-tls service with self-signed certs in docker-compose
- Add smtp-tls.spec.ts: SMTP STARTTLS send plain/HTML/auth tests
- Add imap-tls.spec.ts: IMAP STARTTLS login/list/select/fetch tests
- Register smtp-proxy project in playwright.config.ts
- Wait for TLS proxy readiness in docker-entrypoint.sh
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: enforce auth over TLS when STARTTLS is configured
- Set auth_require_tls conditionally based on tls_context presence
- Disable insecure SSLv2/SSLv3 protocols in TLS context
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: replace cert-gen service with inline cert generation
The cert-gen one-shot container was exiting immediately after
generating certificates, triggering --abort-on-container-exit
and stopping all services before tests could run.
Replace with an entrypoint script in smtp-proxy-tls that generates
the self-signed cert before starting the proxy server.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
refactor: modularize IMAP server with fixes and E2E tests
- Modularize IMAP server into imap_server, imap_mailbox, imap_message,
imap_http_client, parse_email, config, models
- Support dual login: JWT token and address+password via backend
- Add STARTTLS support with configurable TLS cert/key
- Fix FETCH/STORE returning UID instead of sequence number (RFC 3501)
- Implement IMessageFile.open() for correct BODY[] raw MIME delivery
- Add UIDNEXT to SELECT response via _cbSelectWork override
- Use per-restart UIDVALIDITY to force client resync
- Pass raw MIME to SimpleMessage for accurate RFC822.SIZE
- Fix SENT mailbox returning empty source
- Handle CREATE command gracefully for Thunderbird compatibility
- Add IMAP E2E tests: auth, LIST, SELECT, STATUS, FETCH, SEARCH,
STORE, UID FETCH, BODY[] integrity, size, seq numbers, SENT mailbox
- Add SMTP E2E tests using nodemailer: send plain/HTML, auth failure,
sendbox verification
- Add sendTestMail helper using admin/send_mail
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat(oauth2): add email format transformation support
- Add enableEmailFormat, userEmailFormat, userEmailReplace fields
- Support regex pattern matching and replacement template ($1, $2, etc.)
- Add Linux Do OAuth2 template with email format pre-configured
- Add input length limit (256 chars) to prevent ReDoS attacks
- Update admin UI with conditional display and tooltips
- Update documentation (zh/en) with configuration examples
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* chore: update lock files and version
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: restore accessTokenFormat as optional field
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
- Add TG_ALLOW_USER_LANG variable to worker-vars.md (zh/en)
- Add SUBDOMAIN_FORWARD_ADDRESS_LIST with sourcePatterns docs (zh/en)
- Add /lang command and language switching docs to telegram.md (zh/en)
- Add TG_ALLOW_USER_LANG example to wrangler.toml.template
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* feat: optimize email filtering with frontend-only search
- Remove backend keyword parameter from mail APIs (breaking change)
- Implement frontend filtering on current page (20-100 items)
- Add message_id database index for UPDATE performance
- Support desktop and mobile responsive layouts
- Update API documentation and CHANGELOG
BREAKING CHANGE: /admin/mails and /user_api/mails no longer accept keyword parameter
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
* fix: restore Mail ID query input in Index.vue
- Keep showMailIdQuery UI input for querying specific mail by ID
- Triggered when URL contains mail_id parameter
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
Add AI-powered email content extraction feature using Cloudflare Workers AI to automatically identify and extract important information from emails including verification codes, authentication links, service links, and subscription links.
Features:
- AI extraction with priority-based logic (auth_code > auth_link > service_link > subscription_link > other_link)
- Admin allowlist configuration with wildcard support (*@example.com)
- Frontend display in both email list (compact) and detail view (full mode)
- Bilingual documentation (Chinese/English)
- Database migration: add metadata field to raw_mails (v0.0.3 -> v0.0.4)
Technical highlights:
- Proper regex escaping for wildcard pattern matching
- Content truncation to avoid AI token limits
- Error handling that won't affect email receiving
- JSON schema validation for AI responses
- Type-safe TypeScript implementation
- Vue I18n support with special character escaping
References:
- Inspired by Alle Project: https://github.com/bestruirui/Alle
- Uses Cloudflare Workers AI JSON Mode
🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
- Add daily request limit per IP in blacklist settings (1-1,000,000/day)
- Refactor access control logic: merge blacklist and rate limit checks
- Remove RATE_LIMIT_API_DAILY_REQUESTS env var, use database config instead
- Move x-custom-auth check earlier in middleware chain
- Add comprehensive English documentation (31 new guide pages)
- Improve code structure and error handling
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-authored-by: Claude <noreply@anthropic.com>
* feat: add var DISABLE_CUSTOM_ADDRESS_NAME and CREATE_ADDRESS_DEFAULT_DOMAIN_FIRST
* fix: enhance input validation with trim() for address creation
- Add trim() handling in newAddress() function to prevent whitespace issues
- Add trim() handling for address prefixes to ensure consistent formatting
- Add trim() handling in Telegram API address parsing for robustness
- Prevents edge cases with whitespace-only or padded input strings
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
---------
Co-authored-by: Claude <noreply@anthropic.com>