Skip to content

feat(mailbox): add Gmail-connected email attachment workflow - #7666

Draft
Ludy87 wants to merge 22 commits into
mainfrom
mailbox
Draft

feat(mailbox): add Gmail-connected email attachment workflow#7666
Ludy87 wants to merge 22 commits into
mainfrom
mailbox

Conversation

@Ludy87

@Ludy87 Ludy87 commented Aug 24, 2026

Copy link
Copy Markdown
Collaborator

AI disclosure

This pull request was generated entirely by AI. The implementation, tests, configuration, security model, and UI require thorough human review before merging.

Summary

Adds a proprietary Gmail mailbox workflow for browsing messages with attachments and importing those attachments into the Stirling PDF workspace.

Included changes

  • Added Gmail OAuth authorization, callback validation, state protection, token exchange, token refresh, and account profile loading.
  • Added durable per-user Gmail connections in gmail_oauth_connections.
  • Encrypted Gmail access and refresh tokens at rest using the existing encrypted string converter.
  • Added Gmail disconnect handling that removes the local connection and attempts to revoke the Google grant.
  • Added an administrator-only Mailbox configuration section for:
    • OAuth client ID
    • Masked OAuth client secret
    • Redirect URI
    • Allowed Google account email addresses
  • Added Google-account allowlist enforcement. An empty allowlist permits all Google accounts; otherwise only listed accounts may connect.
  • Added a user-facing rejection status when a Google account is not allowed to connect.
  • Added Gmail message and attachment API endpoints with:
    • Inbox, Starred, and Trash folders
    • has:attachment filtering
    • Attachment file-type filtering
    • Search query support
    • Gmail label loading and display
    • Pagination through Gmail page tokens
    • Attachment download
  • Added the /mail inbox page with:
    • Gmail connection status
    • Configurable display name
    • Message search
    • Multi-select attachment-type filters
    • Label filtering
    • Incremental loading while scrolling
    • Duplicate-file confirmation before import
    • Import into the existing PDF file workflow
    • IndexedDB-backed local caching for email metadata and attachments
  • Added the /mail route and mailbox entry points in the file-source and sidebar navigation.
  • Kept the mailbox workflow unavailable in the Tauri desktop build.
  • Added translations and Open Graph metadata for the mailbox route.
  • Updated the project version to 2.15.0.

Configuration

Configure the Gmail OAuth values in the server settings:

  • mailbox.gmail.clientId
  • mailbox.gmail.clientSecret
  • mailbox.gmail.redirectUri
  • mailbox.gmail.allowedEmails

The redirect URI must also be registered in the Google OAuth client. Leave allowedEmails empty to allow all Google accounts, or provide the permitted Google account addresses.

Screenshots

Mailbox entry and account connection

Mailbox entry Mailbox connection Gmail inbox

Email inbox and attachment import

Email inbox with attachments

Mailbox administration

Mailbox configuration Mailbox configuration navigation

Validation

  • Added backend unit tests for OAuth configuration, authorization, callback validation, allowlist enforcement, token refresh, message parsing, attachment handling, persistence, and disconnect behavior.
  • Added controller tests for Gmail status, OAuth callbacks, authorization failures, message access, attachment access, and disconnect handling.
  • Manual Gmail OAuth, inbox, label, filter, pagination, and attachment-import flows were exercised.

Checklist

  • I have read the Contribution Guidelines.
  • I have read the Stirling-PDF Developer Guide where applicable.
  • I have performed a self-review of my own code.
  • My changes generate no new warnings.
  • I have run the complete project check successfully.

Ludy87 added 7 commits August 24, 2026 14:08
Adds a proprietary Gmail OAuth callback and config entries for mailbox credentials. This also introduces an email inbox UI with /mail routing, sidebar/file-source entry points, and an IndexedDB-backed email cache for connected accounts, messages, and attachments.
Update GmailOAuthController to redirect to /mail?gmail=connected instead of /editor/mail?gmail=connected. When a frontendUrl is configured the controller now appends "/mail?gmail=connected" (after trimming any trailing slash). This aligns the backend OAuth callback with the frontend route change.
Adds Gmail OAuth session-backed inbox listing and attachment download endpoints, including message metadata and attachment parsing in the proprietary backend. The email inbox page now recognizes Gmail callback state, loads real mailbox messages, and downloads attachments from the server instead of relying only on demo data.
Adds MIME metadata to demo email attachments and wires the inbox download action to fetch the attachment blob and import it via useFileHandler. This lets users add PDF and document files directly from email messages into the editor workflow.
Add in-memory per-user storage for Gmail OAuth connections and wire controller to use it. GmailOAuthService now holds a ConcurrentHashMap of GmailConnection records with saveConnection/getConnection APIs. GmailOAuthController records the current username in session, consults/saves the service-side connection as a fallback to session tokens/profiles, and persists the connection after successful OAuth. Also change EmailInboxPage back button to navigate to the editor route ("/editor") instead of history back. Note: connections are stored in-memory (ephemeral) in this change.
Add folder + pagination support to Gmail endpoints and wire it into the inbox UI. Backend: GmailOAuthController now accepts folder and pageToken; GmailOAuthService returns a GmailMessagePage (messages + nextPageToken) and queries labelIds/pageToken. Frontend: EmailInboxPage adds folder selection (inbox/starred/trash), incremental loading with nextPageToken, infinite-scroll handler, and duplicate-check against stored file stubs before import. Also wrap /mail route with RequireAuth guard. Small UI/button state updates to reflect active folder.
Add per-account display name settings and a loading-more spinner to the Email inbox UI; persist display name in localStorage. Use a ScrollArea viewportRef (useRef) for reliable infinite-scroll detection and show a small animated spinner when loading additional messages. Include a settings Modal to edit/save/cancel the display name and show the name in the account header (falls back to email). Small cleanup: remove an unused import (List) in GmailOAuthController.java.
@github-actions github-actions Bot added enhancement New feature or request Java Pull requests that update Java code Front End Issues or pull requests related to front-end development Back End Issues related to back-end development Translation Issues or pull requests related to translation labels Aug 24, 2026
@github-actions

Copy link
Copy Markdown
Contributor

🌐 TOML Translation Verification Summary

🔄 Reference Branch: pr-branch

📃 File Check: en-US/translation.toml

  1. Test Status:Passed
  2. Test Status:Passed
  3. Test Status:Passed

✅ Overall Check Status: Success

Thanks @Ludy87 for your help in keeping the translations up to date.

Ludy87 added 2 commits August 24, 2026 17:20
This change improves the email inbox by parsing sender names and addresses more robustly, adding a refresh action and attachment-type filter, and updating the unread badge to reflect the current inbox state. It also adds quick copy actions for subject and sender, and filters the attachment list to match the selected file type.
Add mailbox config and admin UI plus Gmail attachment-type filtering. Backend: add mailbox.gmail properties to ApplicationProperties, extend GmailOAuthController/Service to accept a `types` query (builds filename query) and expose mailbox in AdminSettingsController. Frontend: add AdminMailboxSection, include nav entry and VALID_NAV_KEYS, update EmailInboxPage (UI, CSS) to support multi-select attachment type filtering and pass types to API, and add OG metadata for /settings/adminMailbox. Note: mailbox changes require server restart.
@github-actions github-actions Bot added Security Security-related issues or pull requests API API-related issues or pull requests labels Aug 24, 2026
Introduce GmailConnectionEntity and GmailConnectionRepository to persist encrypted OAuth tokens. Extend GmailOAuthService to save/load connections, refresh access tokens, revoke grants (disconnect), and return a valid token via getValidToken. Update GmailOAuthController to remove session-token reliance, add a DELETE /api/v1/email/gmail/connection endpoint, and use the service token helpers. Include mail package in DatabaseConfig scans. Frontend: add disconnectAccount action and UI button in EmailInboxPage and adjust a placeholder text.
Ludy87 added 2 commits August 24, 2026 19:00
Backend: load Gmail label names, map message labelIds to human-readable names (excluding UNREAD), and add labels to GmailMessage record.

Frontend: add CSS for label chips and layout fixes; extend MailMessage with labels; track available/selected labels; add label MultiSelect filter and render label chips in message list and details. Also add custom attachment-type input and minor message-list sizing/auto-load adjustments.

This ties Gmail label metadata into the UI and enables filtering/display of message labels.
Adds a shared email mailbox availability flag and hides the /mail route and mailbox UI when the feature is unavailable. Core/web builds enable the inbox, while desktop disables it to avoid unsupported routes. This also updates the demo inbox text and labels to use clearer English copy.
@github-actions github-actions Bot added Gradle Pull requests that update Gradle code Tauri Pull requests that update Tauri code labels Aug 24, 2026
@github-actions

github-actions Bot commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

📦 Tauri Desktop Builds Ready!

The desktop applications have been built and are ready for testing.

Download Artifacts:

🍎 macOS Universal: Download Stirling-PDF-macos-universal (.dmg) - 340.5 MB
🪟 Windows x64: Download Stirling-PDF-windows-x86_64 (.exe, .msi) - 264.5 MB


Built from commit bfb0a9f
Artifacts expire in 7 days

Ludy87 added 2 commits August 24, 2026 21:53
Add localization entries for mailbox integration and admin mailbox settings. Adds admin.settings.mailbox (and gmail note) plus mailbox-related UI strings (connect, connectGmail, cancel, copySender/Subject, displayName & hints, file type/label filters, loadingMore, save, etc.) and registers "mailbox" in system settings list to enable UI for email attachment import and configuration.
Register the 'gmail_oauth_connections' table in the SaaS schema ownership list so it is included in ownership/management rules. Updated app/saas/src/main/java/stirling/software/saas/config/SaasSchemaOwnership.java to include the table name.
Ludy87 added 2 commits August 25, 2026 12:54
This change makes Gmail OAuth configuration checks null-safe so startup/configuration failures are handled predictably, keeps HttpClient replaceable for deterministic tests, and adds controller/service coverage for auth flow, token refresh, attachment queries, and disconnect behavior.
Add support for an allowlist of Google account emails for Gmail mailbox connections. Introduces ApplicationProperties.mailbox.gmail.allowedEmails, documents it in settings.yml.template, and exposes it in the admin mailbox settings UI. Server-side enforcement added to GmailOAuthService (throws 403) and GmailOAuthController now redirects the frontend to ?gmail=not-allowed on rejection. Frontend shows localized error messages and handles connect failures. Unit tests updated to cover allowlist behavior.
@github-actions

Copy link
Copy Markdown
Contributor

🚀 Auto-deploying V2 version for PR #7666...

This is an automated deployment for approved V2 contributors.

⚠️ Note: If new commits are pushed during deployment, this build will be cancelled and replaced with the latest version.

@stirlingbot

stirlingbot Bot commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

✅ Backend License Check Passed

All backend dependencies have valid and allowed licenses.

The backend license report has been updated successfully.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

API API-related issues or pull requests Back End Issues related to back-end development codex chatgpt AI generated code enhancement New feature or request Front End Issues or pull requests related to front-end development GitHub Issues or pull requests related to GitHub configuration and integrations Gradle Pull requests that update Gradle code Java Pull requests that update Java code Security Security-related issues or pull requests Tauri Pull requests that update Tauri code Test Testing-related issues or pull requests Translation Issues or pull requests related to translation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant