Cocoanetics / Cocoanetics/Post
Support OAuth2/XOAUTH2 authentication for Gmail and other providers
Nobody has claimed this yet.
- Dominant language
- Swift
- Stars
- 5
- Forks
- 0
- PR merge metrics
- No merged PRs in 30d
Description
Problem
Post currently only supports username/password authentication stored in the keychain. Many modern email providers (Gmail, Outlook, Yahoo) are deprecating password-based IMAP access in favor of OAuth2.
SwiftMail already has XOAUTH2 support built in:
IMAPConnection.authenticateXOAUTH2(email:accessToken:)IMAPServer.AuthenticationMethod.xoauth2(email:accessToken:)
But Post doesn't expose this to users.
Proposed Solution
Add OAuth2/XOAUTH2 support to Post's credential system:
1. Keychain Storage
Extend KeychainCredentialStore to support OAuth tokens:
// New storage method
func storeOAuth(id: String, host: String, port: Int, email: String,
accessToken: String, refreshToken: String?,
expiresAt: Date?) throws
// Retrieval includes token refresh logic
func oauthCredentials(forLabel id: String) throws -> OAuthCredentials?
Store OAuth credentials with:
- Access token
- Refresh token (for automatic renewal)
- Expiry timestamp
- Token endpoint URL
2. CLI Commands
# Interactive OAuth flow (opens browser)
post keychain add-oauth gmail --host imap.gmail.com --port 993 \
--email you@gmail.com \
--client-id YOUR_CLIENT_ID \
--client-secret YOUR_SECRET
# Manual token entry (for CI/automation)
post keychain add-oauth gmail --host imap.gmail.com --port 993 \
--email you@gmail.com \
--access-token TOKEN \
--refresh-token REFRESH_TOKEN
3. Token Refresh
Implement automatic token refresh before expiry:
- Check token expiry on connection
- Use refresh token to get new access token
- Update keychain with new credentials
- Transparent to the user
4. Configuration
Extend ServerConfiguration to indicate auth type:
{
"servers": {
"gmail": {
"auth": "oauth2" // vs "password" (default)
}
}
}
Or auto-detect from keychain credential type.
Benefits
- ✅ Support modern email providers (Gmail, Outlook, Yahoo)
- ✅ More secure than app-specific passwords
- ✅ Automatic token refresh (no manual re-auth)
- ✅ Future-proof as providers deprecate passwords
- ✅ SwiftMail already has the foundation
Implementation Notes
- Token refresh: Use provider's token endpoint to refresh access tokens
- OAuth flow: Launch local web server for OAuth callback (port 8080)
- Storage: Keychain stores tokens with
kSecAttrComment= "oauth" for type detection - Backward compat: Existing password-based credentials continue working
Related Providers
- Gmail: Requires OAuth2 for new apps
- Outlook/Office 365: OAuth2 preferred
- Yahoo Mail: OAuth2 required since 2020
- ProtonMail Bridge: Still uses password (OK)
References
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by tracing KeychainCredentialStore, ServerConfiguration, and the existing keychain CLI commands, then compare their credential flow with SwiftMail's IMAPConnection.authenticateXOAUTH2 and IMAPServer.AuthenticationMethod.xoauth2 APIs. Done means OAuth credentials can be stored and retrieved, the add-oauth commands support the described flows, token refresh is handled, and existing password authentication remains compatible.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- swift
- Domain
- authentication, backend, cli
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100