JMR-devandClaude Opus 4.8 1f63773faa Add Outlook / Microsoft account support (OAuth)
Outlook signs in through the Microsoft identity platform via AppAuth (Authorization Code +
PKCE, no secret). One consent requests the outlook.office.com IMAP and SMTP scopes; because
they share a single resource, the resulting access token authenticates both IMAP receive and
SMTP send over XOAUTH2 — reusing the existing ImapClient and SmtpSender, with no Graph call or
second token. The "common" tenant covers personal and work/school accounts.

- OutlookAuthManager (mirrors GmailAuthManager) + AuthType.OAUTH_OUTLOOK + Account.outlook()
  with the unified outlook.office365.com / smtp.office365.com endpoints.
- MailConnectionFactory refreshes either OAuth provider's token; XOAUTH2 now applies to any
  non-password account. AccountRepository.addOutlookAccount verifies via IMAP, then persists.
- "Sign in with Microsoft" on the account-setup screen; the manifest registers the
  org.libremail.outlook:// redirect. The client id ships in the build, overridable via
  secrets.properties (OUTLOOK_OAUTH_CLIENT_ID); README documents the Azure app registration.
- Verified: assemble/lint/test green; on the emulator the button launches AppAuth and
  Microsoft renders its live sign-in page (client id, redirect, and scopes all accepted).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 18:20:41 -05:00

LibreMail

A free and open-source email client for Android, built with Kotlin, Jetpack Compose and Material 3 (Material You). LibreMail aims for a friendly default experience with power-user features tucked under an Advanced Settings group.

Status: in development. Material You shell; account setup (Gmail OAuth via AppAuth/PKCE and generic IMAP/SMTP, with a live connection test and Keystore- encrypted credentials); IMAP receive — background sync (WorkManager) into a local Room cache with pull-to-refresh; and reading — message bodies fetched on open and rendered in a hardened WebView (JavaScript off, remote images blocked by default), with mark-read, star, and delete; and composing — a compose screen with device- contacts autocomplete that sends via a reliable background outbox (WorkManager-queued and retried, with a viewable outbox folder), plus reply and drafts saved for later; on-device new-mail notifications (no push service) with persisted settings; instant push via a foreground IMAP IDLE service; attachments — downloaded on demand and opened in a system viewer, and attach files when composing; multiple accounts — a unified inbox with per-account filtering; and search across cached mail and the server (IMAP SEARCH); and Outlook/Microsoft accounts (OAuth 2.0 sign-in, IMAP receive + SMTP send over XOAUTH2).

Features (target MVP)

  • Send and receive email with Gmail and Outlook/Microsoft (OAuth 2.0) and any IMAP/SMTP provider.
  • Material You dynamic theming, light/dark, edge-to-edge.
  • Clean compose screen with phone/account contacts integration.
  • Modern security: OAuth 2.0 Authorization Code + PKCE, no stored passwords for Gmail.

Tech stack

Area Choice
Language / UI Kotlin, Jetpack Compose, Material 3
Min / target SDK 33 (Android 13) / 37 (Android 17)
Build Gradle 9.6, AGP 9.2, Kotlin 2.4.0 (KSP, no KAPT)
DI Hilt
Local cache Room (single source of truth) + DataStore
Async / sync Coroutines + Flow, WorkManager
Email transport Jakarta / Angus Mail (IMAP + SMTP, XOAUTH2)
OAuth AppAuth-Android

Building

Prerequisites

  • Android Studio (latest) or the command-line Android SDK.
  • JDK 17–21 for the Gradle daemon. AGP 9.2 does not yet support JDK 25, so if your JAVA_HOME points at JDK 25, run Gradle with a 17–21 JDK (Android Studio's bundled JBR is fine; from the CLI, set JAVA_HOME to a JDK 21 install).
  • Android SDK Platform 37 (platforms;android-37.0) and Build-Tools 37.
# Install the required SDK packages (accept licenses when prompted):
sdkmanager "platforms;android-37.0" "build-tools;37.0.0"

# Build, test and lint the debug variant:
./gradlew :app:assembleDebug
./gradlew :app:testDebugUnitTest
./gradlew :app:lintDebug

# Install on a connected device / emulator:
./gradlew :app:installDebug

local.properties (git-ignored) must point sdk.dir at your Android SDK; Android Studio creates it automatically.

Gmail account setup (OAuth client)

Gmail IMAP/SMTP requires the restricted https://mail.google.com/ scope. While the app is unpublished you can use it in Testing mode with up to 100 test users and no security assessment; a public Play Store release later requires a Google CASA assessment for the restricted scope.

  1. In the Google Cloud Console, create a project (e.g. LibreMail).
  2. APIs & Services → Library → enable the Gmail API.
  3. OAuth consent screen: user type External; add the scope https://mail.google.com/; under Test users, add your Google address. Leave the app in Testing.
  4. Credentials → Create credentials → OAuth client ID → Android. Use package name org.libremail.app and your debug keystore SHA-1:
    keytool -list -v -keystore "$HOME/.android/debug.keystore" \
      -alias androiddebugkey -storepass android -keypass android
    
  5. Copy secrets.properties.example to secrets.properties (git-ignored) and set GMAIL_OAUTH_CLIENT_ID to your client ID. The build injects it via BuildConfig.

Outlook / Microsoft account setup (OAuth client)

Outlook uses the Microsoft identity platform with OAuth 2.0 + PKCE (no client secret), requesting the outlook.office.com IMAP and SMTP scopes — a single token authenticates both IMAP receive and SMTP send over XOAUTH2. A working client ID ships with the build; to use your own Azure app registration instead:

  1. Azure portal → App registrations → New registration. Supported account types: Accounts in any organizational directory and personal Microsoft accounts.
  2. Authentication → Add a platform → Mobile and desktop applications; add the redirect URI org.libremail.outlook://oauth2redirect and enable Allow public client flows.
  3. API permissions: add the delegated Office 365 Exchange Online scopes IMAP.AccessAsUser.All and SMTP.Send (openid/email/offline_access come from OIDC).
  4. Copy the Application (client) ID into secrets.properties as OUTLOOK_OAUTH_CLIENT_ID (it overrides the built-in default).

Architecture

Offline-first, unidirectional, layered:

ui/        Compose screens + ViewModels (MVVM), Navigation Compose, Material You theme
domain/    Models + repository interfaces
data/      Room (entities, DAOs, database) + repository implementation (source of truth)
di/        Hilt modules

The UI observes Room via Flow; later increments add a sync engine (Angus Mail over IMAP/SMTP) that writes into Room, and an auth layer (AppAuth + an Android Keystore-backed credential store).

License

LibreMail is licensed under the GNU General Public License v3.0 — see LICENSE. SPDX identifier: GPL-3.0-or-later.

S
Description
No description provided
Readme GPL-3.0
4.5 MiB
Languages
Kotlin 91.3%
Python 8.7%