Commit Graph

41 Commits

Author SHA1 Message Date
Dream Hunter
e6cc8e2ffd feat: add Turnstile CAPTCHA for login forms (#767) (#885)
* feat: add Turnstile CAPTCHA for login forms (#767)

Add optional Turnstile verification for admin login, user login, and
address password login via ENABLE_LOGIN_TURNSTILE_CHECK env var.
Does not affect existing Turnstile on address creation / registration.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: add ENABLE_LOGIN_TURNSTILE_CHECK to wrangler.toml.template

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: ensure openSettings loaded before admin login modal

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: add Turnstile to site access password and fix settings field name

- Add Turnstile to site access password modal in Header.vue
- Add /open_api/site_login endpoint for password + Turnstile verification
- Fix settings field name from enableTurnstileLogin to enableLoginTurnstileCheck

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor: move login endpoints to open_api/auth.ts

Move /open_api/site_login and /open_api/admin_login from commom_api.ts
to a dedicated open_api/auth.ts file for better code organization.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: change Turnstile check failure status from 500 to 400

Turnstile validation failure is a client error, not a server error.
Change all Turnstile check error responses from 500 to 400.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: use unique IDs for multiple Turnstile instances

When multiple modals with Turnstile appear simultaneously (e.g., site
access + admin login), the hardcoded id="cf-turnstile" causes conflicts.
Generate a unique container ID per Turnstile instance to fix this.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: review fixes - cfToken separation, register Turnstile, error codes

- Separate cfToken refs in Login.vue to avoid token sharing between
  login and new address creation Turnstile instances
- Add Turnstile check to user registration endpoint (not just verify_code)
- Show Turnstile on register tab regardless of enableMailVerify
- Pass cf_token in register request body
- Fix site_login error message to use CustomAuthPasswordMsg
- Fix verifyCode Turnstile error status from 500 to 400
- Restore empty line in commom_api.ts

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: separate register Turnstile logic for with/without mail verify

- With mail verify: verify_code already checks Turnstile, register
  skips Turnstile (token is one-time use)
- Without mail verify: register checks Turnstile directly
- Separate loginCfToken for login tab to avoid token sharing with
  register tab Turnstile

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: add enableLoginTurnstileCheck to store defaults, simplify changelog

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: add /open_api/credential_login for credential login verification

Add credential_login endpoint that verifies both Turnstile token and
JWT credential server-side, replacing the generic verify_turnstile
endpoint. Credential login now validates the JWT before accepting it.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: improve login endpoints - hash passwords, expose Turnstile refresh, fix status codes

- site_login/admin_login: always called, verify hashed password + optional Turnstile
- credential_login: always called, verify JWT + optional Turnstile
- Frontend sends hashed passwords instead of plaintext
- Turnstile component exposes refresh method via defineExpose
- Fix Turnstile error status 500→400 in mails_api and telegram_api

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor: rename to ENABLE_GLOBAL_TURNSTILE_CHECK and add isGlobalTurnstileEnabled helper

- Rename ENABLE_LOGIN_TURNSTILE_CHECK -> ENABLE_GLOBAL_TURNSTILE_CHECK
- Add isGlobalTurnstileEnabled() in utils.ts: checks env var + Turnstile keys all present
- Backend settings returns enableGlobalTurnstileCheck computed from the helper
- All backend endpoints use isGlobalTurnstileEnabled(c) instead of raw env check
- Update all frontend refs, docs, changelog, and wrangler template

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor: use utils.isGlobalTurnstileEnabled instead of named import

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* test: add E2E tests for turnstile login endpoints

- Test all 3 new /open_api/* endpoints when ENABLE_GLOBAL_TURNSTILE_CHECK is disabled
- Verify settings returns enableGlobalTurnstileCheck: false
- Test admin_login with correct/wrong/empty hashed password
- Test site_login returns 401 when no PASSWORDS configured
- Test credential_login with valid JWT, invalid JWT, empty credential
- Test address_login with empty cf_token works when turnstile disabled
- Add ADMIN_PASSWORDS to E2E wrangler config for admin_login tests

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* test: rename test file to login-endpoints.spec.ts

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: validate JWT payload has address field in credential_login

Prevents user tokens or challenge tokens from being accepted as
address credentials since they share the same JWT_SECRET.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: refresh Turnstile token on login failure to allow retry

After a failed login attempt, the consumed Turnstile token is now
refreshed so users can retry without manually refreshing.
Also adds ref to signup Turnstile in UserLogin.vue to refresh after
verification code is sent (single-use token consumed).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: separate Turnstile tokens for signup and reset password flows

Split shared cfToken into signupCfToken and resetCfToken to prevent
single-use Turnstile token conflicts between signup tab and reset
password modal. Each flow now has its own token ref and refreshes
the correct Turnstile widget after use.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: update comments from "login turnstile" to "global turnstile"

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 00:47:26 +08:00
Dream Hunter
94c606959f docs: add webhook preset templates and Telegram push docs (#884)
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>
2026-03-09 21:45:05 +08:00
Bowl42
fca9bade48 feat: add webhook preset templates for Message Pusher, Bark, and ntfy (#877) 2026-03-06 19:53:08 +08:00
Bowl42
372f7b4149 fix: preserve HTML content when replying to HTML emails (#856)
* fix: preserve HTML content when replying to HTML emails (#728)

Reply was using curMail.text (plain text) instead of curMail.message (HTML),
causing loss of original email formatting. Forward already used HTML correctly.

Now reply prefers HTML content with plain text fallback, matching forward behavior.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* test: add vitest unit tests for reply/forward mail logic

Extract buildReplyModel and buildForwardModel into testable utility
functions and add 13 unit tests covering HTML content preservation,
plain text fallback, sender parsing, and subject formatting.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor: remove unnecessary vitest exclude config

The e2e files have been deleted, so the test.exclude config in
vite.config.js is no longer needed.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor: revert unnecessary trailing comma in vite.config.js

Restore vite.config.js to match main exactly — no changes needed
for this PR.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* test: add e2e screenshots for PR review

Screenshots from local Playwright test showing:
1. HTML email rendered correctly in inbox
2. Reply editor preserving HTML content in blockquote

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: remove temporary test screenshots

Screenshots have been posted as PR comment, no longer needed in tree.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: use html contentType for HTML email replies instead of rich

wangEditor (rich text editor) strips block-level HTML tags inside
blockquote, losing all formatting. Use contentType 'html' for HTML
email replies (matching forward behavior) so content is edited as
raw HTML in a textarea, preserving all formatting.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* test: update e2e screenshots showing HTML formatting preserved

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: remove temporary screenshots from tree

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* test: add SMTP send flow E2E screenshots with mailpit

Screenshots showing complete SMTP HTML email reply flow:
1. View rich HTML email (gradient headers, tables, badges)
2. Reply compose with HTML mode (textarea, not wangEditor)
3. Sent box showing preserved HTML formatting
4. Mailpit inbox receiving the SMTP email
5. Mailpit email detail with full HTML rendering

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: remove temporary SMTP test screenshots from tree

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 22:51:27 +08:00
Bowl42
abad88b986 fix: improve email content readability in dark mode (#855) 2026-03-04 20:52:19 +08:00
Dream Hunter
56351ed963 style: improve empty state display for inbox and sent box (#831)
- Add different messages based on mail count (empty vs select)
- Add semantic icons (InboxRound for inbox, SendRound for sent)
- Unify list container height to min-height: 60vh; max-height: 100vh
- Update CHANGELOG for v1.4.0

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 23:47:49 +08:00
Dream Hunter
e4c96c9868 style: use softer blue for AI extraction info in dark mode (#817)
- Use Gmail's #A8C7FA color for AI extraction alert and tag in dark mode
- Update CHANGELOG.md and CHANGELOG_EN.md for v1.2.1

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-19 20:20:06 +08:00
Dream Hunter
8964d4461d feat: add admin account page with logout and responsive address bar (#803)
- Add admin account tab to display current login method
- Support logout for admin password login only
- Show login method (password/user admin/disabled check)
- Improve address bar responsive layout with auto-wrap
- Update changelog for new features

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 19:16:39 +08:00
Dream Hunter
a771446b9b Unify address selection UI (#801)
* feat: unify address selection UI

* docs: update changelog for address UI

* feat: restore user mailbox tab
2026-01-01 21:14:07 +08:00
Dream Hunter
24366e2bff feat: improve mailbox UI spacing and email display (#788) 2025-12-15 13:35:03 +08:00
Dream Hunter
e5f62d4713 feat: optimize email filtering with frontend-only search (#787)
* 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>
2025-12-15 02:55:50 +08:00
Dream Hunter
abe812666f fix: display auth_code result directly without result_text (#777)
- Ensure verification codes always show the raw result value
- Links continue to prefer result_text as display label
- Fixes display logic in both compact and full modes
2025-12-06 16:37:01 +08:00
Dream Hunter
dbb55d948f feat: add AI email extraction with Cloudflare Workers AI
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>
2025-12-06 16:28:19 +08:00
Dream Hunter
ab2bfdd00f feat: 邮件页面增加 上一封/下一封 按钮 (#712) 2025-08-24 19:14:50 +08:00
Dream Hunter
4084771621 feat: |UI| Optimized minimalist mode homepage, added all email page f… (#708)
feat: |UI| Optimized minimalist mode homepage, added all email page functions (delete/download/attachments/...)
2025-08-23 00:23:47 +08:00
Dream Hunter
31eb6c23d1 feat: admin portal user page add user address manangement (#623) 2025-04-07 19:47:44 +08:00
Dream Hunter
908fc0cc86 feat: |Doc| use shadow DOM render mail html (#604) 2025-03-08 10:53:45 +08:00
Dream Hunter
844fc52bbc feat: |UI| add configAutoRefreshInterval && autoRefresh useStorage (#549)
* feat: |UI| add configAutoRefreshInterval && autoRefresh useStorage

* Update MailBox.vue

* Update MailBox.vue
2025-01-09 22:49:25 +08:00
Dream Hunter
8f6793402c feat: |UI| add forward in mail page (#502) 2024-11-30 15:53:48 +08:00
Dream Hunter
c102004f4d feat: |UI| show local datetime string and add useUTCDate option (#483) 2024-11-15 00:04:17 +08:00
Dream Hunter
621476cb79 feat: update webhook to support global webhook (#407) 2024-08-15 00:23:31 +08:00
Dream Hunter
b57d46244a feat: add loading when process mails (#364) 2024-07-27 22:30:38 +08:00
Dream Hunter
80a8848ed8 feat: remove apiV1 and tables && update admin/statistics (#337) 2024-07-08 12:33:43 +08:00
Dream Hunter
d152a7ce9f feat: allow admin and user delete mail, sendbox, send access(only admin) (#331) 2024-07-04 13:31:33 +08:00
Dream Hunter
21fed3fb00 feat: allow admin and user delete mail, sendbox, send access(only admin) (#329) 2024-07-04 13:25:14 +08:00
Dream Hunter
77155299e0 feat: add mailbox multi delete and download (#292) 2024-06-01 21:23:17 +08:00
Dream Hunter
9725407c77 feat: add s3 attachment (#291) 2024-06-01 20:08:42 +08:00
Dream Hunter
b792c196c1 feat: UI i18n depends on router (#289) 2024-06-01 12:12:13 +08:00
Dream Hunter
1f8edbc295 feat: add TITLE in worker for custom website title (#276) 2024-05-26 16:21:27 +08:00
Dream Hunter
3b6736924b feat: add resend for send mail (#274) 2024-05-26 12:37:11 +08:00
Dream Hunter
a5ff4f2d90 feat: SMTP IMAP Proxy: add sendbox && UI: sendbox use split view (#248) 2024-05-18 17:02:21 +08:00
Dream Hunter
46e04fd94a fix: name max 30 && /external/api/send_mail not return result (#222) 2024-05-10 22:57:31 +08:00
Dream Hunter
58c3fdb5b4 feat: use common function handleListQuery when query by page (#220) 2024-05-09 23:31:13 +08:00
Dream Hunter
1fa56dfe98 feat: add UserLogin (#209) 2024-05-08 23:14:44 +08:00
Dream Hunter
f63c4ebd9c feat: add CF Turnstile when new address (#200) 2024-05-04 23:14:23 +08:00
Dream Hunter
7f456078ea feat: quote content when reply message (#197) 2024-05-04 18:18:12 +08:00
Dream Hunter
6e02e9b20b feat: UI: MailBox add reply button (#187) 2024-05-02 20:32:15 +08:00
Dream Hunter
e81142f5ef feat: UI: add user page: useIframeShowMail && mailboxSplitSize (#184) 2024-05-01 18:09:21 +08:00
Dream Hunter
0366699fec fix: UI mailbox 100vh to 80vh (#179) 2024-04-29 23:40:58 +08:00
Dream Hunter
23d1709ca1 feat: support admin create address && add ENABLE_USER_CREATE_EMAIL config (#175) 2024-04-29 00:09:53 +08:00
Dream Hunter
c0e870ce54 feat: all mail use MailBox Component (#173) 2024-04-28 15:58:26 +08:00